Jak wstawiać powtarzający się tekst z niewielką różnicą w vimie?

11

Chcę wstawić tekst w ten sposób:

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

Wiem, że mogę wkleić tekst wiele razy, a następnie użyć podstawienia, aby zmienić pojedyncze słowo dla każdej linii, jednak nadal uważam tę metodę za bardzo niewygodną.

Czy istnieje sposób, aby zapisać słowo lub listę słów w „zmiennej”, a następnie użyć tej zmiennej do wygenerowania podobnego tekstu?


EDYCJA Zrobiłem coś niejasnego w pierwotnym pytaniu, w rzeczywistości staram się stworzyć bardzo podobne definicje funkcji, więc wordA wordB... może pojawić się wiele razy w każdym klonie tekstu, a tekst może zawierać wiele wierszy. wzór jest dokładnie taki:

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

(tekst może zawierać nowe wiersze, a słowo A, słowo B ... może istnieć wiele razy)


2. EDYCJA Części „podobnego_tekstu” mogą być inne za każdym razem, gdy wykonuję taką pracę, więc rozwiązaniem dla tej pracy jest lepsze wykorzystanie. Ponieważ próbuję stworzyć bardzo podobne definicje funkcji lub ciąg znaków do tabeli mapowania funkcji.

Po przeczytaniu odpowiedzi i pewnej praktyce uznaję, że wygodniej jest myśleć o tym zadaniu jako pewnego rodzaju zamianie, ponieważ oddzielne „część 1”, „część 2” ... „część N”, która może zawierać znaki nowej linii, jest trudne do napisania, więc napisz najpierw szablon:

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

Następnie próba umieszczenia klonów tekstu, ale zamiana $ WORD na listę słów jest bardziej prosta.

Wygląda więc na to, że mój problem zmienił się na „jak sklonować blok tekstowy wiele razy, ale za każdym razem, zastępując w nim słowo kluczowe słowem z listy?”

social_loser
źródło
Dlatego wykorzystywane są rejestry. Możesz przeciągnąć (skopiować) tekst do rejestru, a następnie użyć tego rejestru. Makra mogą służyć do wykonywania podobnych, a także powtarzalnych zadań.
SibiCoder,

Odpowiedzi:

7

Możesz użyć następującej funkcji:

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

W zmiennych firstparti secondpartwstaw tekst do powtórzenia przed słowami i po nich, a na liście wordswstaw słowa, które powinny się zmienić.

Następnie pętla utworzy zawartość wiersza dla każdego słowa listy, wstawi wiersz do bufora i przejdzie do tego nowego wiersza.

Następnie można po prostu wywołać funkcję: call GenerateLines().


Edycja Aby ułatwić manipulację, możesz również przekazywać różne części jako argumenty, funkcja powinna wyglądać następująco:

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

Możesz to tak nazwać:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])
statox
źródło
Można uniknąć pętli za pomocą call map(a:words, 'a:firstpart . v:val . a:secondpart')i call append(line('.'), a:words).
Antony
Ponieważ często dokonuję tego rodzaju edycji przy użyciu bardzo długich „pierwszej części” i „drugiej części”, a nawet „trzeciej części”, a te części mogą zawierać znaki nowej linii, wydaje się, że wpisywanie takiej liczby w trybie poleceń wydaje się zbyt długie, więc może jest to bardziej wygodne szarpać tekst do rejestrów, a następnie używać funkcji do generowania tekstu z rejestrów?
social_loser
Zredagowałem pytanie, bardzo się zmienia, przepraszam za niedogodności.
social_loser
5

Moja strategia w takich przypadkach będzie się różnić, ale często obejmuje następujące kroki:

  1. Wpisz unikalne słowo (słowa), np

    wordA
    wordB
    ...
    wordK
    
  2. Zarówno

    a) przeszukaj i zamień, np

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

    b) lub użyj trybu blokowania wizualnego, patrz :h blockwise-visual. W szczególności wybieram słowa i używam Ido wstawiania podobnego tekstu na początku lub Adodawania podobnego tekstu po.

Twierdziłbym, że ta strategia ma sens, gdy wykonuje się tego rodzaju zadania edycyjne stosunkowo rzadko. Jeśli jednak często musisz to robić, postępuj zgodnie z sugestią @ statox za pomocą funkcji, która rozszerza listę słów.

Karl Yngve Lervåg
źródło
Myślę, że rozwiązanie zależy od tego, skąd pochodzi lista słów. Jeśli pochodzi z pliku, to :readzastąpienie go ma sens.
Antony
twoje rozwiązanie jest łatwe do zrobienia i łatwo rozwiązujesz problem, który zadałem w pierwotnym pytaniu. Jednak w moim oryginalnym poście są pewne błędy, dokonałem 2 edycji i wiele się zmienia, dziękuję za odpowiedź, przepraszam za mój zmienny i zły angielski :)
social_loser
@social_loser możesz dostosować to rozwiązanie, używając „\ r” w celu zastąpienia nowego wiersza w części zastępczej zamiany
frangio
2

Będę argumentować, że jest to zadanie dla bloku wizualnego ( Ctrl+ v). Najpierw napiszę wszystkie wyraźne słowa:

wordA
wordB
wordC
wordD
wordE

Zaczynając od pierwszego kursora, wwykonałbym:

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

Mogę kontrolować, ile kolumn potrzebuję, naciskając A <esc>ptyle razy, ile chcę. Załóżmy, że potrzebowałem trzech kolumn, tak jak pokazuje powyższe polecenie. Teraz mamy to:

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

I kursor znajduje się na początku 3. wordAw pierwszym wierszu. Następnie zablokowałbym wybranie kolumny białych znaków między kolumnami cofającymi się i dodającymi tekst pomiędzy nimi. Z bieżącej lokalizacji kursora:

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

Powoduje to (% oznacza pozycję kursora):

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

Powtórz dla następnej kolumny:

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

I ostatnia / pierwsza (ta po lewej stronie) kolumna:

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

Ostatecznie skutkując:

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

Aktualizacja: dodano screencast

wprowadź opis zdjęcia tutaj


Wydaje się, że to dużo pisania, ale w rzeczywistości bardzo łatwo się przyzwyczaić. Zapewnia swobodę zmiany liczby słów, liczby kolumn, a nawet odstępów między kolumnami.

Wadą jest to, że musisz znać liczbę różnych słów, których używasz. Mam na 5stałe wszystkie polecenia powyżej, ponieważ jest to liczba wierszy, na których działają polecenia.

Uwaga debugowania: wszystkie polecenia zaczynają się i kończą w trybie normalnym, jeśli znajdziesz się w trybie wizualnym lub wstawisz na końcu polecenia, robisz coś źle.

grochmal
źródło