Как вставить повторяющийся текст с разницей в незначительной Vim?

11

Я хочу вставить текст так:

similar text wordA similar text ...
similar text wordB similar text ...
similar text wordC similar text ...

Я знаю, что могу вставить текст много раз, а затем использовать подстановку, чтобы изменить одно слово для каждой строки, однако я все еще нахожу этот метод очень неудобным.

Есть ли способ сохранить слово или список слов в «переменную», а затем использовать эту переменную для создания аналогичного текста?


EDIT Я сделал что - то неясное в оригинальном вопросе, на самом деле я пытаюсь сделать некоторые очень похожи определения функций, так что wordA wordB... могут появляться несколько раз в каждом клоне текста и текст может содержать много строк. шаблон в точности такой:

similar_text1 wordA similar_text2 wordA similar_text3 ...
similar_text1 wordB similar_text2 wordB similar_text3 ...
similar_text1 wordC similar_text2 wordC similar_text3 ...

(текст может содержать новые строки, а wordA, wordB ... могут существовать много раз)


2-е РЕДАКТИРОВАНИЕ Части «Similar_text» могут отличаться каждый раз, когда я делаю такую ​​работу, поэтому решение для этой работы лучше использовать повторно. Потому что я пытаюсь сделать очень похожие определения функций или таблицу сопоставления строк и функций.

После прочтения ответов и некоторой практики, я обнаружил, что удобнее думать об этой работе как о некой замене, потому что отдельные "part1", "part2" ... "partN", которые могут содержать переводы строк, трудно писать, поэтому пишите сначала шаблон:

similar_text1 $WORD similar_text2 $WORD similar_text3 ...
(text may contain <ENTER>, make sure $WORD not exist in "similar_text" parts )

Тогда попытка поместить клоны текста, но замена $ WORD списком слов, является более прямым мышлением.

Так что, похоже, моя проблема изменилась так: «Как много раз клонировать текстовый блок, но каждый раз, подставляя в нем ключевое слово словом из списка?»

social_loser
источник
Вот почему регистры используются для. Вы можете восстановить (скопировать) текст в регистр, а затем использовать этот регистр. Макросы можно использовать для выполнения как похожих, так и повторяющихся задач.
СибиКодер

Ответы:

7

Вы можете использовать следующую функцию:

function! GenerateLines()
    let firstpart="similar text part 1"
    let secondpart="similar text part 2"

    let words=["wordA","wordB","wordC","wordD","wordE"]

    for word in words
        let line = firstpart . word . secondpart
        call append(line('.')+1, line)
        normal j
    endfor
endfunction

В переменных firstpartи secondpartпоместите текст для повторения до и после слов, а в списке words- слова, которые должны измениться.

Затем цикл создаст содержимое строки для каждого слова списка, вставит строку в буфер и перейдет к этой новой строке.

Вы можете просто вызвать функцию: call GenerateLines().


Редактирование Чтобы упростить манипулирование, вы также можете передавать различные части в качестве аргументов, функция должна выглядеть следующим образом:

function! GenerateLines(firstpart, secondpart, words)
    for word in a:words
        call append(line('.')+1, a:firstpart . word . a:secondpart)
        normal j
    endfor
endfunction

И вы можете назвать это так:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])
statox
источник
Вы можете избежать цикла с call map(a:words, 'a:firstpart . v:val . a:secondpart')и call append(line('.'), a:words).
Антоний
Так как я часто делаю такого рода редактирование с очень длинными «firstpart» и «secondpart», даже «thirdpart», и эти части могут содержать переводы строк, кажется, что вводить слишком много в командном режиме слишком долго, поэтому, возможно, это более удобно вернуть текст в регистры, а затем использовать функции для генерации текста из регистров?
social_loser
Я отредактировал вопрос, он сильно изменился, извините за неудобства.
social_loser
5

Моя стратегия в таких случаях будет разной, но часто она состоит из следующих шагов:

  1. Напишите уникальное слово (слова), например

    wordA
    wordB
    ...
    wordK
    
  2. Или

    а) выполнить поиск и заменить, например,

    :%s/\w\+/similar text \0 similar text .../
    

    б) или используйте режим визуального блока, см :h blockwise-visual. В частности, я выберу слова и использую, Iчтобы вставить аналогичный текст впереди или Aдобавить аналогичный текст после.

Я бы сказал, что эта стратегия имеет смысл, когда вы делаете такие задачи редактирования относительно редко. Однако, если вы обнаружите, что вам нужно делать это часто, вы должны следовать предложению @ statox с функцией, которая расширяет список слов.

Карл Ингве Лерваг
источник
Я думаю, что решение зависит от того, откуда приходит список слов. Если это из файла, то :readпосле вашей замены имеет большой смысл.
Антоний
ваше решение легко сделать , и решить эту проблему , я спросил в оригинальном вопросе легко. Однако есть некоторые ошибки в моей должности, я сделал 2 правок и изменений много, спасибо за ответ, извините за мой изменять и плохой английский :)
social_loser
@social_loser вы можете адаптировать данное решение с помощью «\ г» стоять на новую строку в сменной части замещения
frangio
2

Я буду утверждать , что это работа для визуального блока ( Ctrl+ v). Сначала я бы написал все разные слова:

wordA
wordB
wordC
wordD
wordE

Начиная с курсора на первом, wя бы затем выполнил:

<c-v>5j$yA <esc>pA <esc>p

Я могу контролировать, сколько столбцов мне нужно, нажимая A <esc>pстолько раз, сколько я хочу. Давайте предположим, что мне нужно три столбца, как показано в приведенной выше команде. Теперь у нас есть это:

wordA wordA wordA
wordB wordB wordB
wordC wordC wordC
wordD wordD wordD
wordE wordE wordE

И курсор находится в начале 3-го wordAв первой строке. Далее я бы выделил столбец пробелов между столбцами, идущими назад и добавив текст между ними. Из текущего местоположения курсора:

h<c-v>5jI similar text 3<esc>

Это приводит к (% отмечает положение курсора):

wordA wordA%similar text 3 wordA
wordB wordB similar text 3 wordB
wordC wordC similar text 3 wordC
wordD wordD similar text 3 wordD
wordE wordE similar text 3 wordE

Повторите для следующего столбца:

bh<c-v>5jI similar text 2<esc>

И последний / первым (один слева) колонок:

b<c-v>5jIsimilar text 1 <esc>

В итоге получается:

similar text 1 wordA similar text 2 wordA similar text 3 wordA
similar text 1 wordB similar text 2 wordB similar text 3 wordB
similar text 1 wordC similar text 2 wordC similar text 3 wordC
similar text 1 wordD similar text 2 wordD similar text 3 wordD
similar text 1 wordE similar text 2 wordE similar text 3 wordE

Обновление: добавлен скринкаст

введите описание изображения здесь


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

Недостатком является то, что вам нужно знать количество отдельных слов, которые вы используете. У меня есть 5жестко закодированные во всех командах выше, потому что это число строк, над которыми работают команды.

Примечание по отладке: все команды начинаются и заканчиваются в обычном режиме, если вы оказались в визуальном режиме или в режиме вставки в конце команды, вы делаете что-то не так.

grochmal
источник