Задача «Простое редактирование текста с помощью Vim» на VimGolf: как работает решение №1? - PullRequest
22 голосов
/ 13 июля 2011

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

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

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

1 Ответ

41 голосов
/ 13 июля 2011

Решение сосредоточено на команде :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
^     ^     ^

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

qa3jYjVpq3@aZZ

Решение с использованием команды :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 начинает позиционировать курсор на первой строке и уменьшается до $. Но если команды изменяют текущую строку, :g продолжается оттуда. Итак:

:g/V/

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

t.

Перемещает курсор на строку 5. А затем:

+d

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...