Подтвердить что ты не робот

Задача "Простое редактирование текста с Vim" в VimGolf: как работает решение №1?

Простое редактирование текста с помощью Vim: http://vimgolf.com/challenges/4d1a34ccfa85f32065000004

Мне трудно понять решение № 1 (Оценка 13).

Извините, в этом сообщении не вставлено решение, потому что я не знаю, подходит ли это для этого.

4b9b3361

Ответ 1

Решение сосредоточено на команде :g. С помощью:

                                             :g   :global   E147   E148 
:[range]g[lobal]/{pattern}/[cmd]
                        Execute the Ex command [cmd] (default ":p") on the
                        lines within [range] where {pattern} matches.

Таким образом, в основном, решение выполняет некоторые ex-команды на строках с "V", которые являются именно теми, которые нуждаются в редактировании. Вы, наверное, заметили, что более ранние решения полагаются на дублирование строк, а не на изменение их. Это решение специально показывает интересный образец:

3jYjVp3jYjVp3jYjVpZZ
^     ^     ^

Что можно уменьшить с помощью макроса:

[email protected]

Решение, использующее команду :g, выполняет в основном одно и то же. Первый Выполняется команда t.. С помощью:

                                                         :t 
:t                  Synonym for copy.

:[range]co[py] {address}                             :co   :copy 
                        Copy the lines given by [range] to below the line
                        given by {address}.

Указанный адрес был ., что означает текущую строку:

Line numbers may be specified with:          :range   E14   {address} 
        {number}            an absolute line number
        .                   the current line                           :. 
        $                   the last line in the file                  :$ 
        %                   equal to 1,$ (the entire file)             :% 
        't                  position of mark t (lowercase)             :' 
        'T                  position of mark T (uppercase); when the mark is in
                            another file it cannot be used in a range
        /{pattern}[/]       the next line where {pattern} matches      :/ 
        ?{pattern}[?]       the previous line where {pattern} matches  :? 
        \/                  the next line where the previously used search
                            pattern matches
        \?                  the previous line where the previously used search
                            pattern matches
        \&                  the next line where the previously used substitute
                            pattern matches

Таким образом, команда ex t. означает "скопировать текущую строку ниже текущей строки". Затем есть панель, которая:

                                                     :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 '\'.

И команда d, которая явно удаляет строку. Было дано множество +, что означает "текущая строка + 1". Вы можете передать .+1, но + для краткости. Эта информация может быть прочитана вокруг справки для :range:

The default line specifier for most commands is the cursor position, but the
commands ":write" and ":global" have the whole file (1,$) as default.

Each may be followed (several times) by '+' or '-' and an optional number.
This number is added or subtracted from the preceding line number.  If the
number is omitted, 1 is used.

И что это.

:g/V/t.|+d<CR>ZZ

В каждой строке, содержащей "V", скопируйте ее и удалите следующую строку. Написать и выйти.


Одна вещь, о которой я не упоминал, - это то, почему команды :g выполняются три раза вместо 6 или даже больше (строки дублируются вдоль процесса). Команда :g начинает позиционировать курсор в строке 1 и переходит на $. Но если команды меняют текущую строку, :g продолжается оттуда. Итак:

:g/V/

Текущая строка - 4. Теперь:

t.

Это перемещает курсор в строку 5. И затем:

+d

Удаляет строку 6, курсор остается в 5. Итак, следующее соответствие :g будет в строке 8.