r-lib / cli
1

2
#' A simple CLI theme
3
#'
4
#' Note that this is in addition to the builtin theme. To use this theme,
5
#' you can set it as the `cli.theme` option:
6
#'
7
#' ```
8
#' options(cli.theme = cli::simple_theme())
9
#' ```
10
#'
11
#' and then CLI apps started after this will use it as the default theme.
12
#' You can also use it temporarily, in a div element:
13
#'
14
#' ```
15
#' cli_div(theme = cli::simple_theme())
16
#' ```
17
#'
18
#' @param dark Whether the theme should be optiomized for a dark
19
#'   background. If `"auto"`, then cli will try to detect this.
20
#'   Detection usually works in recent RStudio versions, and in iTerm
21
#'   on macOS, but not on other platforms.
22
#'
23
#' @seealso [themes], [builtin_theme()].
24
#' @export
25
#' @examples
26
#' cli_div(theme = cli::simple_theme())
27
#'
28
#' cli_h1("Heading 1")
29
#' cli_h2("Heading 2")
30
#' cli_h3("Heading 3")
31
#'
32
#' cli_alert_danger("Danger alert")
33
#' cli_alert_warning("Warning alert")
34
#' cli_alert_info("Info alert")
35
#' cli_alert_success("Success alert")
36
#' cli_alert("Alert for starting a process or computation",
37
#'   class = "alert-start")
38
#'
39
#' cli_text("Packages and versions: {.pkg cli} {.version 1.0.0}.")
40
#' cli_text("Time intervals: {.timestamp 3.4s}")
41
#'
42
#' cli_text("{.emph Emphasis} and  {.strong strong emphasis}")
43
#'
44
#' cli_text("This is a piece of code: {.code sum(x) / length(x)}")
45
#' cli_text("Function names: {.fn cli::simple_theme}")
46
#'
47
#' cli_text("Files: {.file /usr/bin/env}")
48
#' cli_text("URLs: {.url https://r-project.org}")
49
#'
50
#' cli_h2("Longer code chunk")
51
#' cli_par(class = "code R")
52
#' cli_verbatim(
53
#'   '# window functions are useful for grouped mutates',
54
#'   'mtcars %>%',
55
#'   '  group_by(cyl) %>%',
56
#'   '  mutate(rank = min_rank(desc(mpg)))')
57
#' cli_end()
58
#'
59
#' cli_h2("Even longer code chunk")
60
#' cli_par(class = "code R")
61
#' cli_verbatim(format(ls))
62
#' cli_end()
63
#'
64
#' cli_end()
65

66
simple_theme <- function(dark = getOption("cli_theme_dark", "auto")) {
67

68 1
  dark <- detect_dark_theme(dark)
69

70 1
  list(
71 1
    h1 = list(
72 1
      "margin-top" = 1,
73 1
      "margin-bottom" = 0,
74 1
      color = "cyan",
75 1
      fmt = function(x) cli::rule(x, line_col = "cyan")),
76

77 1
    h2 = list(
78 1
      "margin-top" = 1,
79 1
      "margin-bottom" = 0,
80 1
      color = "cyan",
81 1
      fmt = function(x) paste0(symbol$line, " ", x, " ", symbol$line, symbol$line)),
82

83 1
    h3 = list(
84 1
      "margin-top" = 1,
85 1
      "margin-bottom" = 0,
86 1
      color = "cyan"),
87

88 1
    par = list("margin-top" = 0, "margin-bottom" = 1),
89

90 1
    ".alert-danger" = list(
91 1
      "background-color" = "red",
92 1
      color = "white",
93 1
      before = paste0(symbol$cross, " ")
94
    ),
95

96 1
    ".alert-warning" = list(
97 1
      color = "orange",
98 1
      "font-weight" = "bold",
99 1
      before = paste0("!", " ")
100
    ),
101

102 1
    ".alert-success" = list(
103 1
      before = paste0(crayon::green(symbol$tick), " ")
104
    ),
105 1
    ".alert-info" = list(
106 1
      before = paste0(crayon::cyan(symbol$info), " ")
107
    ),
108

109 1
    ".alert-start" = list(
110 1
      before = paste0(symbol$arrow_right, " ")),
111

112 1
    span.pkg = list(
113 1
      color = "blue",
114 1
      "font-weight" = "bold"),
115 1
    span.version = list(color = "blue"),
116

117 1
    span.emph = simple_theme_emph(),
118 1
    span.strong = list("font-weight" = "bold", "font-style" = "italic"),
119

120 1
    span.fun = modifyList(simple_theme_code(dark), list(after = "()")),
121 1
    span.fn = modifyList(simple_theme_code(dark), list(after = "()")),
122 1
    span.arg = simple_theme_code(dark),
123 1
    span.kbd = modifyList(simple_theme_code(dark),
124 1
                          list(before = "<", after = ">")),
125 1
    span.key = modifyList(simple_theme_code(dark),
126 1
                          list(before = "<", after = ">")),
127 1
    span.file = simple_theme_file(),
128 1
    span.path = simple_theme_file(),
129 1
    span.email = simple_theme_url(),
130 1
    span.url = modifyList(simple_theme_url(),
131 1
                          list(before = "<", after = ">")),
132 1
    span.var = simple_theme_code(dark),
133 1
    span.envvar = simple_theme_code(dark),
134

135 1
    span.timestamp = list(before = "[", after = "]", color = "grey")
136
  )
137
}
138

139
simple_theme_emph <- function() {
140 1
  list("font-style" = "italic")
141
}
142

143
simple_theme_url <- function() {
144 1
  list(color = "blue")
145
}
146

147
simple_theme_code <- function(dark) {
148 1
  if (dark) {
149 0
    list("background-color" = "#232323", color = "#f0f0f0")
150
  } else{
151 1
    list("background-color" = "#f8f8f8", color = "#202020")
152
  }
153
}
154

155
simple_theme_file <- function() {
156 1
  list(color = "blue")
157
}
158

159
simple_theme_r_code <- function(dark) {
160 0
  dark <- dark
161 0
  style <- if (dark) {
162 0
    crayon::make_style("#f0f0f0")
163
  } else {
164 0
    crayon::make_style("#202020")
165
  }
166 0
  function(x) {
167 0
    x <- crayon::strip_style(x)
168 0
    lines <- strsplit(x, "\n", fixed = TRUE)[[1]]
169 0
    fmd <- tryCatch(prettycode::highlight(lines), error = function(x) lines)
170 0
    style(fmd)
171
  }
172
}
173

174
is_iterm <- function() {
175 1
  isatty(stdout()) && Sys.getenv("TERM_PROGRAM", "") == "iTerm.app"
176
}
177

178
is_iterm_dark <- function() {
179 0
  if (is.null(clienv[["is_iterm_dark"]])) {
180 0
    clienv$is_iterm_dark <-
181 0
      tryCatch(
182 0
        error = function(x) FALSE, {
183 0
          osa <- '
184 0
            tell application "iTerm2"
185 0
              tell current session of current window
186 0
                get background color
187 0
              end tell
188 0
            end tell
189
          '
190 0
          out <- system2("osascript", c("-e", shQuote(osa)), stdout = TRUE)
191 0
          nums <- scan(text = gsub(",", "", out), quiet = TRUE)
192 0
          mean(nums) < 20000
193
        })
194
  }
195 0
  clienv[["is_iterm_dark"]]
196
}

Read our documentation on viewing source code .

Loading