Czy można vim'ować polecenia vim?

18

Chcę uruchomić następującą powłokę.

wea-this is the end of the second word | vim j
exit 0

Miałem nadzieję, że wprzesunie naciśnięcia klawiszy (przesunie słowo do przodu), potem e(koniec słowa), potem a(dopisze), a następnie -this is the end of the second word(tekst) do określonego dokumentu Vima, jktóry już zawiera słowa.

Podczas uruchamiania skryptu powłoki wystąpił następujący błąd.

/root/bin/tt.sh: line 1: wea-this: command not found
Vim: Warning: Input is not from a terminal

Używam Ubuntu 14.04. Docenione zostaną dwa rodzaje odpowiedzi:

  1. Jak korzystać z orurowania, aby osiągnąć pożądany rezultat.
  2. Inna metoda, za pomocą której mogę użyć „poleceń Vima” (nie poleceń ed i sed) do edycji dokumentu tekstowego ze skryptu powłoki.
Jason Basanese
źródło
1
Te |rury postać wyjście jednego polecenia do drugiego. wea-thisnie jest rozkazem. Rurociągów nie można również wykorzystać do osiągnięcia tego, co chcesz zrobić; spowoduje, że stimin Vima będzie aplikacją na lewą rękę, a nie na klawiaturze. Jeśli chcesz się stdin do bufora w vim, uruchom go z minusem do pliku: echo Hello, world! | vim -.
dash-tom-bang

Odpowiedzi:

15

Aby wstawić ciąg "hello"w pierwszym wierszu pliku j, możesz wpisać w powłoce następujące polecenie:

vim +"1 | put! ='hello'" j

  • :1 przesuwa kursor do pierwszego wiersza bufora
  • :put! ='hello' wkleja ciąg „hello” powyżej bieżącej linii

Aby wstawić ciąg, "hello"a następnie zapisać i zamknąć plik:

vim +"1 | put! ='hello' | x" j

Tak samo jak poprzednio, właśnie dodaliśmy polecenie Ex, :xktóre zapisuje i wychodzi.

Mówiąc bardziej ogólnie, możesz wykonać dowolną sekwencję poleceń Ex na pliku, z interaktywnej powłoki lub ze skryptu bash, jak poniżej:

vim +'Ex command1 | Ex command2 | ...' file

Jeśli masz wiele poleceń Ex, możesz zapisać je wszystkie w dedykowanym pliku (wywoływanym na przykład myExCommands.vim), po jednym poleceniu w wierszu, a następnie z powłoki lub skryptu, z którego możesz je uzyskać (za pomocą polecenia Ex :sourcelub wersji skróconej) :so) lubię to:

vim +'so myExCommands.vim' file

Edytować

Widzę, że zredagowałeś swoje pytanie.
Myślę, że poprzednia odpowiedź nadal obowiązuje, ponieważ można wykonać dowolne normalne polecenie z trybu Ex za pomocą poleceń Ex :normali :execute.

Załóżmy na przykład, że chcesz:

  • przesuń kursor w pierwszym wierszu bufora ( 1G)
  • przesuń kursor na pierwszy znak spacji w wierszu ( _)
  • przesuń kursor o jedno słowo do przodu ( w)
  • przesuń kursor na koniec nowego słowa ( e)
  • przejść do trybu wstawiania po znaku pod kursorem ( a)
  • wstaw ciąg hello
  • zapisz i wyjdź ( :x)

Aby to zrobić w pliku j, wpisz z powłoki:

vim +"execute 'normal! 1G_weahello' | x" j

Aby uzyskać więcej informacji, zobacz:

:help +cmd
:help :normal
:help :execute
saginaw
źródło
Nie udało mi się w pełni wyjaśnić mojego celu. Chcę mieć możliwość korzystania z poleceń vims, takich jak w, aby przejść o słowo do przodu i tak dalej. Zmodyfikuję moje pytanie, aby je poprawić.
Jason Basanese
@JasonBasanese Zredagowałem moją odpowiedź, wykonuję polecenia Ex :normali :executerób co chcesz?
saginaw
9

Oto sposób, w jaki możesz użyć poleceń trybu normalnego, a nie tylko poleceń ex, aby edytować strumień prezentowany Vimowi ze standardowego wejścia. To nie jest bardzo przydatny przykład, ale ilustruje zastosowane techniki. Zakłada, że ​​twoja skorupa to bash.

echo "The brown fox jumped." | vim -s <(printf 'wcwred\e:wq! foo\n') -

Na -końcu mówi Vimowi, aby czytał tekst (nie polecenia) ze standardowego wejścia. -sMówi Vima wykonać klawiszy z określonego pliku. W tym przypadku plik jest wynikiem podstawienia procesu bash. <(...)Zastępuje nazwy nazwanego potoku. Dane wyjściowe potoku są danymi wyjściowymi polecenia w nawiasach. W wcwred\eprzesuwa kursor o jedno słowo i zmiany, które w przyszłym słowo red. :wq! foo\nZapisuje wynik do pliku foo, nawet jeśli plik już istnieje. Wynik końcowy to plik o nazwie foozawierającej tekstThe red fox jumped.

Aby uzyskać więcej informacji na temat niektórych z tych tematów, zobacz

:help -file
:help -s

Zobacz także Process Substitutionsekcję strony bash(1)man.

garyjohn
źródło
Dodane do moich ~ / .zshrc: vimx () { vi -s <(echo "$1"':wq') "$2" &> /dev/null; }. Teraz mogę vimx 'iThe brow fox jumped.\e' foo; vimx 'wcwred\efjdwiclimbed\e' foo; cat foo. Schludny!
Leonard Pauli,
4

Odkryłem, że metoda pobierania danych wyjściowych programu jako przekierowanej z podpowłoki jest bardzo łatwa:

vim <( program )

Przykład:

 vim <( grep -nH  hello  myFile.cpp )
 vim <( find . -name '*.cpp' -exec grep -nH code_expr {} \+ )
J Jorgenson
źródło
4

Miałem dokładnie takie samo pragnienie jak ty: chciałem napisać normalne polecenia vima i umożliwić im edycję strumienia potokowego. Byłem rozczarowany trudnością korzystania z normalnego vima w ten sposób (tak wielu flag!), Jak zapewniają domyślne opcje vim.

Dlatego napisałem małe opakowanie na vimie, aby to zrobić: https://github.com/MilesCranmer/vim-stream/ . To się nazywa vims.

Sercem opakowania jest następujące polecenie:

vim - -nes "${vim_cmds[@]}" -c ':q!' | tail -n +2

Używając tego, przy generowaniu poleceń, które wykonuję, okazuje się, że jest dość zwięzły, a ponieważ vim jest edytorem modalnym, stworzyłem vimsedytor modalnych strumieni. Istnieją trzy główne tryby przydatne w mentalności edycji potokowej:

[-t|--turn-off-mode] - (Default mode)
                       Every string is a vim command line, e.g., '%g/foo/d' deletes
                       all lines with foo.
[-e|--exe-mode] -      Translated to '%g/$1/exe "norm $2"', see examples below
[-s|--simple-mode] -   Like exe-mode, but runs on 1st line only

Patrz na to:

$ echo "Hello World" | vims -s "ea Beautiful"
Hello Beautiful World

Więc eidzie do końca Hello, a potem azacznie dołączanie.

Coś bardziej fantazyjnego, w trybie exe, do komentowania linii zawierających my_bad_vari usuwających poprzednią linię.

cat my_script.cpp | vims -e 'my_bad_var' 'I//\<esc>kdd'

Co przekłada się na vims '%g/my_bad_var/exe "norm I//\<esc>kdd"'- Ijest to polecenie, aby rozpocząć wstawianie na początku wiersza, i //jest sekwencją komentarzy. \<esc>kddnaciska klawisz Escape, przesuwa się w górę linii, a następnie usuwa linię.

Mam 11 przykładów na repo, zachęcam do ich sprawdzenia. Znowu działa to na vimie, to tylko sposób, aby vim bardziej przypominał sed do wprowadzania strumieniowego (ale zachowując wszystkie twoje ukochane makra vim!)

Miles
źródło
3

To dość stare pytanie, ale czułem, że warto było wnieść wkład, że jeśli dana dystrybucja / system operacyjny ma dostęp moreutils, możesz go zainstalować i po prostu użyć vipejako standardowego dodatku do vim:

echo foo | vipe # Now you can edit "foo" to be "bar"!

moreutilsjest także bardzo przydatny w przypadku innych narzędzi i bardzo polecam je, jeśli jesteś poważnym użytkownikiem wiersza poleceń! :) Spójrz na wstęp autora (poprzedni link), aby uzyskać więcej informacji.

moreutilspowinny być ogólnie dostępne dla większości * podobnych do nix dystrybucji za pośrednictwem menedżera pakietów i Homebrew na Macu . Na przykład...

# Arch Linux and MSYS2 (more below) as part of the `community` repo
pacman -Sy moreutils


# Mac OS and Homebrew
brew install moreutils

moreutilsjest również częścią repozytorium pakietów MSYS2 , więc możesz technicznie używać go również w systemie Windows. :)

Erich Gubler
źródło