github.com/elves/elvish@v0.15.0/website/learn/cookbook.md (about) 1 <!-- toc --> 2 3 If you come from other shells, hopefully the following recipes will get you 4 started quickly: 5 6 # UI Recipes 7 8 - Put your startup script in `~/.elvish/rc.elv`. There is no `alias` yet, but 9 you can achieve the goal by defining a function: 10 11 ```elvish 12 fn ls [@a]{ e:ls --color $@a } 13 ``` 14 15 The `e:` prefix (for "external") ensures that the external command named 16 `ls` will be called. Otherwise this definition will result in infinite 17 recursion. 18 19 - The left and right prompts can be customized by assigning functions to 20 `edit:prompt` and `edit:rprompt`. Their outputs are concatenated (with no 21 spaces in between) before being used as the respective prompts. The 22 following simulates the default prompts but uses fancy Unicode: 23 24 ```elvish 25 # "tilde-abbr" abbreviates home directory to a tilde. 26 edit:prompt = { tilde-abbr $pwd; put '❱ ' } 27 # "constantly" returns a function that always writes the same value(s) to 28 # output; "styled" writes styled output. 29 edit:rprompt = (constantly (styled (whoami)✸(hostname) inverse)) 30 ``` 31 32 Here is a terminalshot of the alternative prompts: 33 34 @ttyshot unicode-prompts 35 36 - Press <span class="key">▲︎</span> to search through history. It uses 37 what you have typed to do prefix match. To cancel, press <span 38 class="key">Escape</span>. 39 40 @ttyshot history-mode 41 42 - Press <span class="key">Tab</span> to start completion. 43 44 - To navigate the candidate list, use arrow keys 45 <span class="key">▲︎</span> <span class="key">▼︎</span> 46 <span class="key">◀︎</span> <span class="key">▶︎</span> or 47 <span class="key">Tab</span> and <span class="key">Shift-Tab</span>. 48 49 - To filter candidates, continue typing. 50 51 - To accept the selected candidate, press <span class="key">Enter</span>. 52 53 - To cancel, press <span class="key">Escape.</span> 54 55 The candidate list also comes with a scrollbar. In fact, all interactive 56 modes show a scrollbar when there is more output to see. 57 58 @ttyshot completion-mode 59 60 - You can make completion case-insensitive with the following code: 61 62 ```elvish 63 edit:completion:matcher[''] = [p]{ edit:match-prefix &ignore-case $p } 64 ``` 65 66 You can also make the completion use "smart case" by changing `&ignore-case` 67 to `&smart-case`. This means that if your pattern is entirely lower case it 68 ignores case, otherwise it's case sensitive. 69 70 - <a name="navigation-mode"></a>Press <span class="key">Ctrl-N</span> to start 71 the builtin filesystem navigator, aptly named "navigation mode." Use arrow 72 keys to navigate. <span class="key">Enter</span> inserts the selected 73 filename to your command line. If you want to insert the filename and stay 74 in the mode (e.g. when you want to insert several filenames), use <span 75 class="key">Alt-Enter</span>. 76 77 You can continue typing your command when you are in navigation mode. Press 78 <span class="key">Ctrl-H</span> to toggle hidden files; and like in other 79 modes, <span class="key">Escape</span> gets you back to the default (insert) 80 mode. 81 82 @ttyshot navigation-mode 83 84 - Try typing `echo [` and press <span class="key">Enter</span>. Elvish knows 85 that the command is unfinished due to the unclosed `[` and inserts a newline 86 instead of accepting the command. Moreover, common errors like syntax errors 87 and missing variables are highlighted in real time. 88 89 - Elvish remembers which directories you have visited. Press <span 90 class="key">Ctrl-L</span> to list visited directories. Like in completion, 91 use arrow keys <span class="key">▲︎</span> 92 <span class="key">▼︎</span> or <span class="key">Tab</span> and 93 <span class="key">Shift-Tab</span> to select a directory and use Enter to 94 `cd` into it. Press <span 95 class="key">Escape</span> to cancel. 96 97 @ttyshot location-mode 98 99 Type to filter: 100 101 @ttyshot location-mode-filter 102 103 The filtering algorithm is tailored for matching paths; you need only type a 104 prefix of each component. In the screenshot, x/p/v matches 105 **x**iaq/**p**ersistent/**v**ector. 106 107 - Elvish doesn't support history expansion like `!!`. Instead, it has a "last 108 command mode" offering the same functionality, triggered by <span 109 class="key">Alt-,</span> by default. In this mode, you can pick individual 110 arguments from the last command using numbers, or the entire command by 111 typing <span class="key">Alt-,</span> again. 112 113 This is showing me trying to fix a forgotten `sudo`: 114 115 @ttyshot lastcmd 116 117 # Language Recipes 118 119 - Lists look like `[a b c]`, and maps look like `[&key1=value1 &key2=value2]`. 120 Unlike other shells, a list never expands to multiple words, unless you 121 explicitly explode it by prefixing the variable name with `@`: 122 123 ```elvish-transcript 124 ~> li = [1 2 3] 125 ~> put $li 126 ▶ [1 2 3] 127 ~> put $@li 128 ▶ 1 129 ▶ 2 130 ▶ 3 131 ~> map = [&k1=v1 &k2=v2] 132 ~> echo $map[k1] 133 v1 134 ``` 135 136 - Environment variables live in a separate `E:` (for "environment") namespace 137 and must be explicitly qualified: 138 139 ```elvish-transcript 140 ~> put $E:HOME 141 ▶ /home/xiaq 142 ~> E:PATH = $E:PATH":/bin" 143 ``` 144 145 - You can manipulate search paths through the special list `$paths`, which is 146 synced with `$E:PATH`: 147 148 ```elvish-transcript 149 ~> echo $paths 150 [/bin /sbin] 151 ~> paths = [/opt/bin $@paths /usr/bin] 152 ~> echo $paths 153 [/opt/bin /bin /sbin /usr/bin] 154 ~> echo $E:PATH 155 /opt/bin:/bin:/sbin:/usr/bin 156 ``` 157 158 - You can manipulate the keybinding in the default insert mode through the map 159 `$edit:insert:binding`. For example, this binds 160 <span class="key">Ctrl-L</span> to clearing the terminal: 161 162 ```elvish 163 edit:insert:binding[Ctrl-L] = { clear > /dev/tty } 164 ``` 165 166 Use `pprint $edit:insert:binding` to get a nice (albeit long) view of the 167 current keybinding. 168 169 **NOTE**: Bindings for letters modified by Alt are case-sensitive. For 170 instance, `Alt-a` means pressing `Alt` and `A`, while `Alt-A` means pressing 171 `Alt`, `Shift` and `A`. This will probably change in the future. 172 173 - There is no interpolation inside double quotes (yet). For example, the 174 output of `echo "$user"` is simply the string `$user`. Use implicit string 175 concatenation to build strings: 176 177 ```elvish-transcript 178 ~> name = xiaq 179 ~> echo "My name is "$name"." 180 My name is xiaq. 181 ``` 182 183 Sometimes string concatenation will force you to use string literals instead 184 of barewords: 185 186 ```elvish-transcript 187 ~> noun = language 188 ~> echo $noun's' 189 languages 190 ``` 191 192 You cannot write `s` as a bareword because Elvish would think you are trying 193 to write the variable `$nouns`. It's hard to make such mistakes when working 194 interactively, as Elvish highlights variables and complains about 195 nonexistent variables as you type. 196 197 - Double quotes support C-like escape sequences (`\n` for newline, etc.): 198 199 ```elvish-transcript 200 ~> echo "a\nb" 201 a 202 b 203 ``` 204 205 **NOTE**: If you run `echo "a\nb"` in bash or zsh, you might get the same 206 result (depending on the value of some options), and this might lead you to 207 believe that they support C-like escape sequences in double quotes as well. 208 This is not the case; bash and zsh preserve the backslash in double quotes, 209 and it is the `echo` builtin command that interpret the escape sequences. 210 This difference becomes apparent if you change `echo` to `touch`: In Elvish, 211 `touch "a\nb"` creates a file whose name has a newline; while in bash or 212 zsh, it creates a file whose name contains a backslash followed by `n`. 213 214 - Elementary floating-point arithmetic as well as comparisons are builtin, 215 with a prefix syntax: 216 217 ```elvish-transcript 218 ~> + 1 2 219 ▶ 3 220 ~> / (* 2 3) 4 221 ▶ 1.5 222 ~> > 1 2 223 ▶ $false 224 ~> < 1 2 225 ▶ $true 226 ``` 227 228 **NOTE**: Elvish has special parsing rules to recognize `<` and `>` as 229 command names. That means that you cannot put redirections in the beginning; 230 bash and zsh allows `< input cat`, which is equivalent to `cat < input`; in 231 Elvish, you can only use the latter syntax. 232 233 - Functions are defined with `fn`. You can name arguments: 234 235 ```elvish-transcript 236 ~> fn square [x]{ 237 * $x $x 238 } 239 ~> square 4 240 ▶ 16 241 ``` 242 243 - Output of some builtin commands start with a funny `▶`. It is not part of 244 the output itself, but shows that such commands output a stream of values 245 instead of bytes. As such, their internal structures as well as boundaries 246 between values are preserved. This allows us to manipulate structured data 247 in the shell. 248 249 Read [unique semantics](unique-semantics.html) for details. 250 251 - When calling Elvish commands, options use the special `&option=value` 252 syntax. For instance, the `echo` builtin command supports a `sep` option for 253 specifying an alternative separator: 254 255 ```elvish-transcript 256 ~> echo &sep="," a b c 257 a,b,c 258 ``` 259 260 The mixture of options and arguments is a classical problem in traditional 261 shell programming. For instance, if you want to print a file whose name is 262 in `$x`, `cat $x` is the obvious thing to do, but it does not do this 263 reliably -- if `$x` starts with `-` (e.g. `-v`), `cat` thinks that it is an 264 option. The correct way is `cat -- $x`. 265 266 Elvish commands are free from this problem. However, the option facility is 267 only available to builtin commands and user-defined functions, not external 268 commands, meaning that you still need to do `cat -- $x`. 269 270 In principle, it is possible to write safe wrapper for external commands and 271 there is a [plan](https://github.com/elves/elvish/issues/371) for this.