В поисках единой теории для интерпретации |, <Bar>и \ |в Vim - PullRequest
0 голосов
/ 01 июня 2018

Вот несколько экспериментов, чтобы продемонстрировать, как |, <Bar> и \| ведут себя в различных сценариях в командах Vim.

Приведенные ниже кодовые блоки показывают несколько команд Vim с каждой командой (или набор команд) с последующим кратким комментарием о поведении команды.

Случай 1: Команды оболочки

:!uname | new
/bin/bash: new: command not found

:!uname <Bar> new
/bin/bash: Bar: no such file or directory

:!uname \| new
usage: uname [-amnprsv]

:!uname | grep i
Darwin

Выводы:

  • |передается как литерал | в оболочку.
  • <Bar> передается как литерал <Bar> перенаправлению ввода / вывода.
  • \| передается как литерал |в оболочку.

Таким образом, в этом случае все три команды ведут себя одинаково, в том смысле, что вы видите то, что передается в оболочку.Так что это легко понять.

Случай 2: Пользовательские команды для команд оболочки

:command! A !uname | new
:A
/bin/bash: new: command not found

:command! A !uname <Bar> new
:A
/bin/bash: new: command not found

:command! A !uname \| new
:A
usage: uname [-amnprsv]

:command! A !uname | grep i
:A
Darwin

:command! A !uname <Bar> grep i
:A
Darwin

Выводы:

  • | и <Bar>ведут себя аналогично (передаются как | в оболочку).
  • \| ведут себя по-разному (передаются как литерал \| в оболочку).

Случай 3: Карты дляКоманды оболочки

:map ,a :!uname | new<CR>
,a
Creates a new window when the `:map` command is executed.
Enters `!uname` in the command-line-mode when `,a` is pressed.

:map ,a :!uname <Bar> new
,a
Enters `:!uname | new` in the command mode.

:map ,a :!uname \| new
,a
Enters `:!uname | new` in the command mode.

Выводы:

  • | ведет себя по-разному (разделитель команд между :map и другой командой Vim, в данном случае new).
  • <Bar> и \| ведут себя аналогично (они становятся | при выполнении map-rhs).

Случай 4: команды Vim, принимающие аргументы

:new | vnew
Creates split windows

:new <Bar> vnew
Creates a single split window with file named `<Bar> vnew`

:new \| vnew
Creates a single split window with file named `| vnew`

Выводы:

  • | ведет себя по-разному (как разделитель команд).
  • \| и <Bar> ведут себя аналогично (как буквальный аргумент).

Случай 5: пользовательские команды для команд Vim, которые принимают аргументы.

:command! A new | vnew
:A
Creates split windows.

:command! A new <Bar> vnew
:A
Creates split windows

:command! A new \| vnew
:A
Creates a single split window with file named `| vnew`

Выводы

  • | и <Bar> ведут себя аналогично(в качестве разделителей команд во время выполнения команды).
  • \| ведет себя по-разному (как буквальный аргумент для new во время выполнения команды).

Это согласуется с вариантом 2 выше.

Пример 6. Карты для команд Vim, принимающих аргументы.

:map ,a :new | vnew
,a
Creates a new window when the `:map` command is executed.
Enters `new` in the command-line-mode when `,a` is pressed.

:map ,a :new <Bar> vnew
,a
Enters `:new | vnew` in the command-line-mode when `,a` is pressed.

:map ,a :new \| vnew
,a
Enters `:new | vnew` in the command-line-mode when `,a` is pressed.

Выводы:

  • | ведет себя по-разному (разделитель команд между :map идругая команда Vim, new в данном случае).
  • <Bar> и \| ведут себя аналогично (они становятся | при выполнении map-rhs)

Это согласуется с делом 3 выше.Это имеет смысл, потому что этот случай по сути такой же, как и в случае 2, т. Е. :map для переназначения нажатий клавиш для команд режима командной строки.

Случай 7: команды Vim, которые не принимают аргументы

:bn | bn
Goes to the 2nd next buffer.

:bn <Bar> bn
E488: Trailing characters

:bn \| bn
Goes to the 1st next buffer. What happened to `\| bn`?!

Выводы:

  • Все три из |, <Bar> и \| ведут себя по-разному.

Случай 8: пользователь-определенные команды для команд Vim, которые не принимают аргументы.

:command! A bn | bn
:A
Goes to the 2nd next buffer.

:command! A bn <Bar> bn
:A
Goes to the 2nd next buffer.

:command! A bn \| bn
:A
Goes to the 1st next buffer.

Выводы: - | и <Bar> ведут себя аналогично (как разделители команд во время выполнения команды).- \| ведет себя так, как если бы \| буквально использовался как \| в bn \| bn, что приводит к сбивающему с толку поведению, как показано в предыдущем случае.

Это поведение согласуется с делом 2 и делом 5.

Случай 9: карты для команд Vim, которые не принимают аргументы.

:map ,a :bn | bn
,a
Switches to the next buffer when `:map` command is executed.
Enters `:bn` in the command-line-mode.

:map ,a :bn <Bar> bn
,a
Enters `:bn | bn` in the command-line-mode.

:map ,a :bn \| bn
,a
Enters `:bn | bn` in the command-line-mode

Это согласуется с вариантами 3 и 6 выше.

Мой вопрос

Каковы окончательные правила (согласно авторитетной документации или справке Vim) в отношении того, как |, <Bar> и \| интерпретируются в различных командах, принимая настройки по умолчанию Vim (по умолчанию cpoptions, обычный * 1149)* и :command команды и т. д.)?

1 Ответ

0 голосов
/ 01 июня 2018

После публикации этого вопроса я исследовал Vim :help, чтобы собрать как можно больше подсказок.Вот теория, которая, кажется, почти работает.Я включаю соответствующую документацию Vim's :help, которую я смог найти для поддержки каждой точки.

  1. С :!, |, <Bar> и \|передается буквально командам оболочки.

                                                            *:!cmd* *:!* *E34*
    :!{cmd}                 Execute {cmd} with the shell.  See also the 'shell'
                            and 'shelltype' option.
    
                            ...
    
                            A '|' in {cmd} is passed to the shell, you cannot use
                            it to append a Vim command.  See |:bar|.
    
  2. Многие команды режима командной строки (такие как map, но не :command или :!) заканчиваются, когда |встречается, потому что это разделитель команд.

                                                            *:bar* *:\bar*
    '|' can be used to separate commands, so you can give multiple commands in one
    line.  If you want to use '|' in an argument, precede it with '\'.
    
    These commands see the '|' as their argument, and can therefore not be
    followed by another Vim command:
    
        :argdo
        :autocmd
        :bufdo
        :cdo
        :cfdo
        :command
        ...
        :make
        :normal
        ...
        :[range]!
    

    В приведенном выше списке важно отметить, что хотя :command и :! принимают | в качестве аргумента, :map - нет.Это будет важно в пункте 4 ниже.

  3. Если в документации не указано какое-либо специальное поведение в отношении <Bar> и \| для некоторых команд режима командной строки в документации, этопотребляется буквально.Это может объяснить поведение <Bar> и \| в пункте 1 выше.Но это не объясняет поведение <Bar> в пункте 4 ниже.

  4. С :command, | и <Bar> ведут себя как разделитель команд в тексте команды заменыво время выполнения, когда выполняется пользовательская команда.

                                                            *:bar* *:\bar*
    
    ...
    
    These commands see the '|' as their argument, and can therefore not be
    followed by another Vim command:
        :argdo
        :autocmd
        :bufdo
        :cdo
        :cfdo
        :command
        ...
        :make
        :normal
        ...
        :[range]!
    

    Не ясно, почему <Bar> также ведет себя как | в :command из этой документации.

  5. С :command, \| передается как буквальный аргумент \| в тексте команды замены во время выполнения, когда выполняется пользовательская команда.

                                                            *:bar* *:\bar*
    '|' can be used to separate commands, so you can give multiple commands in one
    line.  If you want to use '|' in an argument, precede it with '\'.
    
  6. С :map, | является разделителем команд между командой map и второй командой Vim.Вторая команда Vim выполняется, как только команда map выполняется и определяется пользовательская команда.Он не выполняется при выполнении пользовательской команды.Это следует непосредственно из документации Vim, приведенной выше в пункте 2.

  7. С :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).
    
    All three work when you use the default setting for 'cpoptions'.
    

    Кроме того,

                                            *key-notation* *key-codes* *keycodes*
    These names for keys are used in the documentation. ...
    
    ...
    
    <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
    ":autocmd"!
    

    Кроме того,

    SPECIAL CHARACTERS
    
    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>
    

Поведение, которое все еще остается необъяснимым:

  • Почему <Bar> ведет себя как | в :command?(Обратите внимание, что <Bar> передается буквально как <Bar> в оболочку в команде :!. Я не понимаю, почему она должна вести себя как | в :command.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...