Jak wstawić wynik polecenia do tekstu w vimie?

42

Na przykład :echo strftime(%c)pokaże aktualny czas na dole, ale jak wstawić ten ciąg czasu do tekstu (zaraz za kursorem)?

xzhu
źródło
1
Wierzę, że PO oznacza „Jak wstawić wynik wyrażenia Vima do tekstu?”
Alastair Irvine,
Warto również wspomnieć, że nie jest to to samo pytanie, co napisanie funkcji vim w celu wstawienia bloku statycznego tekstu , jednak niektóre odpowiedzi nadal obowiązują.
Alastair Irvine,
Twój przykład jest dosłownie moim przypadkiem użycia i pozdrawiam Cię za to.
Joe
Zobacz także przekierowanie do rejestru: stackoverflow.com/questions/2573021/…
NeilG

Odpowiedzi:

49

Możesz użyć rejestru wyrażeń "=, z p(lub P) w trybie normalnym lub <C-R>w trybie wstawiania:

W trybie normalnym:
( <C-M>tutaj oznacza Control+ Mlub po prostu naciśnij Enter/ Return)

"=strftime('%c')<C-M>p

W trybie wstawiania:
( <C-M>ma takie samo znaczenie jak powyżej, <C-R>oznacza Control+ R)

<C-R>=strftime('%c')<C-M>

Jeśli chcesz wstawić wynik tego samego wyrażenia wiele razy, możesz chcieć zamapować je na klucze w swoim .vimrc:
(tutaj <C-M>i <C-R>należy wpisać dosłownie (ciąg pięciu znaków do wydrukowania - Vim przetłumaczy je wewnętrznie))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>
Chris Johnsen
źródło
2
+1 Zejście z kursu! "=Rejestr. : - /
Eelvex
2
aby uzyskać wartość zmiennej vim (na przykład opcje sesji): <C-R>=&sessionoptions- wykonuje nawet tabulację wildmode!
Justin M. Keyes
2
: put = strftime ('% c') <CM>
brunch875,
W trybie wstawiania użycie polecenia <c-r>=jest powolne dla polecenia, które może mieć dużo danych wyjściowych, a także może przerwać wcięcie, tak że tekst wyjściowy jest nieczytelny. Na przykład <c-r>=execute('nmap')dane wyjściowe będą zapisywane wiersz po wierszu, co jest bardzo wolne.
jdhao
22

:r!date +\%c

widzieć :help :r!

Glenn Jackman
źródło
1
datejest poleceniem zewnętrznym i !wywołuje polecenia zewnętrzne, podczas gdy OP prosi o polecenia vim.
Eelvex
@eelvex nie, nie zrobił tego. i! jest poleceniem vim i vi. To jest metoda kanoniczna. Działa również w wielu innych sprawach.
Keith
5
@Keith: yes !to polecenie vi (m), które wywołuje polecenia zewnętrzne . Możesz mieć rację, że OP nie chce wypisywać tylko poleceń vima, ale jeśli tak zrobi, !nie zrobi tego.
Eelvex
11

Te polecenia wstawią wynik w strftime("%c")miejscu, w którym znajduje się kursor:

:exe ":normal i" . strftime("%c")

i

:call feedkeys("i". strftime("%c"))

Istnieją inne sposoby robienia tego, co chcesz (na przykład te z odpowiedzią Mikela ).

Edycja : Jeszcze lepiej, aby wstawić w miejscu, użyj =rejestru, jak opisuje Chris Johnsen

Eelvex
źródło
10

Jeśli chcesz wstawić wynik polecenia vim (w przeciwieństwie do zwracanej wartości wywołania funkcji ), musisz go przechwycić. Odbywa się to za pomocą :redirpolecenia, które pozwala przekierować odpowiednik standardowego wyjścia vima do zmiennej, pliku, rejestru lub innego celu.

:redirjest nieco boleśnie niewygodny w użyciu; Chciałbym napisać funkcję, aby hermetyzować jej funkcjonalność w bardziej wygodny sposób, coś w rodzaju

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

Po zadeklarowaniu takiej funkcji można użyć rejestru wyrażeń (jak wyjaśnił Chris Johnsen), aby wstawić wynik polecenia w pozycji kursora. Tak więc, z trybu normalnego, naciśnij, i^R=Exec('ls')aby wstawić listę bieżących buforów vima.

Pamiętaj, że polecenie zostanie wykonane w przestrzeni nazw funkcji, więc jeśli używasz zmiennej globalnej, będziesz musiał jawnie ją nazwać, poprzedzając ją znakiem g:. Zauważ również, że Exec(), jak napisano powyżej, dołącza kończącą linię nowego wiersza nawet do wyjścia jednowierszowego. Możesz chcieć dodać wywołanie do substitute()funkcji, aby tego uniknąć.

Zobacz także https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054, aby uzyskać więcej informacji na temat blatowania rediri link do powiązane polecenie.

intuicyjny
źródło
2
To działa świetnie. Dodałem set pastepolecenie przed zwróceniem danych wyjściowych i set nopastepo, aby uniknąć wcięcia na klatce schodowej, gdy linie zaczynają się spacjami. Właściwie chciałem zapisać wartość bieżącej opcji wklejania i ją zwrócić, ale nie byłem w stanie tego zrobić.
Juan Lanus,
1
@JuanLanus Nie set nopastepowinno działać później return output, ponieważ instrukcja return jest punktem wyjścia z funkcji. Rozwiązałem ten problem jako osobną odpowiedź na tej stronie.
Jewgienij Siergiejew
4
:call append(line('.'), strftime("%c"))

Umieści go w następnym wierszu, a następnie możesz nacisnąć J( Shift+ J), aby dołączyć go do bieżącej pozycji.

Lub jeśli potrzebujesz tego wszystkiego w jednym poleceniu, możesz to zrobić

:call setline(line('.'), getline(line('.')) . strftime("%c"))

lub

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

w zależności od tego, czy chcesz wstawić spację przed datą, czy nie.

Mikel
źródło
4

Poprawiona @intuitowana odpowiedź, aby uniknąć problemu z wiodącymi białymi znakami i rosnącym wcięciem:

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

To po prostu wstawi w bieżącej lokalizacji do pliku, gdy przejdziesz :call Exec('command')z trybu normalnego. Jak zauważono w komentarzu , oryginalne =Exec('command')podejście Ctrl + R ( Exec(..)zwracanie ciągu) z zwracaniem łańcucha można częściowo poprawić za pomocą set paste, ale nie oferuje możliwości umieszczenia set nopastegdziekolwiek.

let @o = outputSkładnia ustawia rejestr odo zawartości zmiennej output, jak wyjaśniono tutaj: https://stackoverflow.com/a/22738310/1143274

return ''Linia jest tak, że wartość domyślna zwrot 0nie zostanie wstawiony do bufora.

Jewgienij Siergiejew
źródło
2

Tak to robię. Umieszcza go zaraz za kursorem, ponieważ używa p.

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

" restore previous yank
let @@ = reg_save
Juan Ibiapina
źródło