vim r! w pozycji kursora

17

z vimem, jeśli użyję

:r!date

vim wstaw datę w następnym wierszu, podobnie jak

:r!pwd

jak mogę wstawić polecenie wyjściowe pod pozycją kursora, a nie w nowym wierszu?

juanpablo
źródło
1
vi.stackexchange.com/questions/862/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

16

Za pomocą „ :read” Vim zawsze wstawia dane wyjściowe w nowym wierszu. Rozwiązanie nie jest niestety proste.

Możesz wstawić wynik polecenia w bieżącej pozycji kursora, gdy jesteś w trybie wstawiania, naciskając, ControlRa następnie pisząc =system('command')Enter. Niestety, jeśli wynik polecenia ma końcową nową linię (jak większość woli), która również zostanie wstawiona, więc twoja linia zostanie przerwana.

Można to naprawić, dodając substitute()wywołanie usuwające końcowe znaki nowej linii, ale sprawia to, że polecenie jest bardziej kłopotliwe niż warto pisać ręcznie.

Ostatecznym rozwiązaniem jest stworzenie pewnego rodzaju mapowania, ale staje się to jeszcze bardziej skomplikowane ze względu na to, jak Vim radzi sobie z tym, co nazywa „pisz z wyprzedzeniem”; podczas gdy możesz zrobić coś takiego:

:nmap \e i<c-r>=substitute(system('date'),'[\r\n]*$','','')<cr><esc>

Tam, gdzie polecenie jest „zapisane na stałe” w mapowaniu, nie można zrobić czegoś takiego:

:nmap \e i<c-r>=substitute(system(input('Command: ')),'[\r\n]*$','','')<cr><esc>

Gdzie próbujesz zachęcić użytkownika do uruchomienia polecenia, ponieważ Vim po prostu się zdezorientuje, wyda dźwięk i przejdzie w tryb wstawiania.

Musisz najpierw poprosić o uruchomienie polecenia, zapisać je w zmiennej, a następnie wstawić przetworzone dane wyjściowe. W tym momencie prawdopodobnie potrzebna jest funkcja pomocnika, aby samo mapowanie nie stało się nieporządnie nieuporządkowane, więc otrzymujemy coś takiego:

function InlineCommand()
    let l:cmd = input('Command: ')
    let l:output = system(l:cmd)
    let l:output = substitute(l:output, '[\r\n]*$', '', '')
    execute 'normal i' . l:output
endfunction

nmap <silent> \e :call InlineCommand()<CR>

Zauważ, że nmaptworzy mapowania, które są wykonywane tylko po wpisaniu w trybie normalnym.

Nawiasem mówiąc, jeśli chcesz tylko wstawić datę lub bieżący katalog roboczy, początkowa odpowiedź, którą podałem, jest wykonalna. Wystarczy wejść w tryb wstawiania i wpisać ControlR=strftime('%c')Enterlub ControlR=getcwd()Enter.

Heptyt
źródło
Czy byłoby możliwe połączenie poleceń w celu rozwiązania tego problemu? : r! data | : - | J or i \ n \ n ^ [-:.! Date \ n -JJ
Alexx Roche,
4

Jeśli chcesz to w bieżącym wierszu, spróbuj po prostu, ale pamiętaj, że stara zawartość wiersza zostanie usunięta:

:.!date

Jeśli chcesz dokładną pozycję kursora, możesz:

:let a=system("date") | let b=substitute(a,"[\r\n]*$","","g") | exec 'normal i'.b

Krótko mówiąc: musisz podstawić, ponieważ chcesz pozbyć się ^ @ (znaków zerowych), które możesz również zastąpić .s / \% x00 // g. To jest krótsza wersja z mniejszą ilością rur:

:exec 'normal i'.substitute(system("date"),"[\n]*$","","")

Możesz także ustawić tagi, jeśli chcesz zamienić w różnych punktach tej samej linii:

Biorąc pod uwagę tę linię 1:

1 Date: <datehere> and also <datehere>

Wykonać:

:let a=system("date") | exec ".s/<datehere>/".a."/g" | .s/\%x00//g

Po wymianie:

1 Date: jue ago 9 02:34:52 ART 2012 and also jue ago 9 02:34:52 ART 2012

Testowane na Vimie 7.2

Crisboot
źródło
1

Możesz dodać tego rodzaju rzeczy w swoim .vimrc:

" Insert the date in YYYY-MM-DD format inline just before cursor position (normal mode)
nnoremap <Leader>di me:r !date +\%F<CR>A <Esc>0D`ePJx
  • me oznacza bieżącą pozycję.
  • :r !date +\%F<CR>wstawia datę w następnym wierszu w formacie RRRR-MM-DD (możesz to zmienić, jak chcesz, po prostu unikaj każdego %z nich \).
  • A <Esc> dodaje spację na końcu danych wyjściowych daty.
  • 0Dusuwa datę, `eprzenosi z powrotem do zaznaczonej pozycji i PJxumieszcza datę przed kursorem, łączy linie (aby pozbyć się pustej poniżej) i zabija końcowe miejsce. Zmodyfikuj mapowanie według własnego uznania.

Jeśli chcesz to zrobić w trybie wstawiania, przeczytałem ten klejnot dzisiaj na https://vimways.org/2018/the-mapping-business/

inoremap <C-g><C-t> <C-r>=strftime("%F")<CR>

Możesz zmodyfikować wyjście daty zgodnie z własnymi potrzebami ( man datemoże ci w tym pomóc).

Tristan Chase
źródło
0

W trybie normalnym (tryb ucieczki / bleep) wklej

:exec 'normal i'.system("date \| tr '\n' ' '")

aby wstawić datę w bieżącej pozycji. Jeśli skopiujesz ten wiersz ze znakiem powrotu karetki, wówczas Shift + Insert stanie się poleceniem DateTime-Here.

Dodatkowo możesz powiązać F12 z poleceniem za pomocą

:inoremap <F12> <C-r>=system("date \| tr '\n' ' '")<CR>

następnie możesz wstawić datę za pomocą klawisza funkcyjnego-12, gdy aktywny jest tryb wstawiania. używam

:inoremap DHRE <C-r>=system("date \| tr '\n' ' '")<CR>

(Zmieniłem z DHERE po odkryciu, że uruchomiło się wklejanie ADHERE), ponieważ już używam F12 do innych rzeczy.

używam

grep -iE "dhere" /usr/share/dict/words

aby sprawdzić oczywiste kolizje z istniejącymi słowami, które sugerują, że możesz względnie bezpiecznie używać:

:inoremap PWD <C-r>=system("pwd \| tr '\n' ' '")<CR>

(chyba że piszesz pewną dokumentację).

Alexx Roche
źródło