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">▲&#xfe0e;</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">▲&#xfe0e;</span> <span class="key">▼&#xfe0e;</span>
    46          <span class="key">◀&#xfe0e;</span> <span class="key">▶&#xfe0e;</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">▲&#xfe0e;</span>
    92      <span class="key">▼&#xfe0e;</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.