#StackBounty: #key-bindings #command-line #escape #map-operator #command Why does `<Bar>` behave like `|` in the `:command` comma…

Bounty: 50

Here is the list of experiments I performed that shows that <Bar> is treated as literal <Bar> in some commands but it is treated as | in the :command command.

I am trying to understand why or what in the documentation dictates that <Bar> should be treated as | in the :command command.

Case 1: :! and <Bar>

Enter this command-line mode command in Vim:

:!uname <Bar> grep i

We get this error:

/bin/bash: Bar: No such file or directory

This error occurred because the following shell command was invoked: uname < Bar > grep i and there is no file named Bar to redirect the standard input of uname to.

We see that the string <Bar> was literally sent to the shell.

Case 2: :echo and <Bar>

Enter this command-line mode command in Vim:

:echo 'hi' <Bar> echo 'bye'

We get this error:

E121: Undefined variable: Bar
E15: Invalid expression: 'hi' <Bar> echo 'bye'

Once again <Bar> was literally used as argument in the :echo command.

Case 3: :command, :! and <Bar>

Enter these command-line mode commands in Vim:

:command! A !uname <Bar> grep i

I get this output:


You may get Linux in your output.

The argument <Bar> was interpreted as |.

Case 4: :command, :echo and <Bar>

Enter these command-line mode commands in Vim:

:command! A echo 'hi' <Bar> echo 'bye'

We get this output:

Press ENTER or type command to continue

Again, the argument <Bar> was interpreted as |.


Why is <Bar> treated as 5-character literal argument in case of :!, :echo, etc. but it is treated as | in :command? I searched the documentation but I can’t seem to find anything.

The documentation does mention that <Bar> can be treated as | in the :map and some other commands, but it never mentions anything about it being treated as | in the :command command.

Here are some excerpts from the documentation that one can find by entering :helpgrep <Bar>:

  1. This talks about usage of <Bar> in the :map command. See :help :bar.
     There is one exception: When the 'b' flag is present in 'cpoptions', with the
     ":map" and ":abbr" commands and friends CTRL-V needs to be used instead of
     ''.  You can also use "<Bar>" instead.  See also |map_bar|.
  2. This talks about the usage of many keycodes including <Bar> in :map command and a few other commands but no mention of the :command command. See :help keycodes.
                                             *key-notation* *key-codes* *keycodes*
     These names for keys are used in the documentation.  They can also be used
     with the ":map" command (insert the key name by pressing CTRL-K and then the
     key you want the name for).
     <Bslash>        backslash                       92     *backslash* *<Bslash>*
     <Bar>           vertical bar            |       124     *<Bar>*
     <Del>           delete                          127
     For mapping, abbreviation and menu commands you can then copy-paste the
     examples and use them directly.  Or type them literally, including the '<' and
     '>' characters.  This does NOT work for other commands, like ":set" and
  3. This one also talks about usage of <Bar> in the :map command. See :help map-bar.
                                                         *map_bar* *map-bar*
     Since the '|' character is used to separate a map command from the next
     command, you will have to do something special to include  a '|' in {rhs}.
     There are three methods:
        use       works when                    example      ~
        <Bar>     '<' is not in 'cpoptions'     :map _l :!ls <Bar> more^M
        |        'b' is not in 'cpoptions'     :map _l :!ls | more^M
        ^V|       always, in Vim and Vi         :map _l :!ls ^V| more^M
     (here ^V stands for CTRL-V; to get one CTRL-V you have to type it twice; you
     cannot use the <> notation "<C-V>" here).
  4. Again, this talks about the :map command only. See :help usr_40.
     The ":map" command can be followed by another command.  A | character
     separates the two commands.  This also means that a | character can't be used
     inside a map command.  To include one, use <Bar> (five characters).  Example:
             :map <F8> :write <Bar> !checkin %:S<CR>

How can we explain the treatment of <Bar> as | in the :command command then?

Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.