Можно ли передать команды vim в vim?


18

Я хочу запустить следующую оболочку.

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

Я надеялся, что это будет wнаправлять нажатия клавиш (двигаться вперед по слову), затем e(конец слова), затем a(добавлять), затем -this is the end of the second word(текст) в документ Vim с именем, в jкотором уже есть слова.

Следующая ошибка произошла, когда я запустил скрипт оболочки.

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

Я использую Ubuntu 14.04. Будут оценены два типа ответов:

  1. Как использовать трубопровод для достижения желаемого результата.
  2. Другой метод, с помощью которого я могу использовать «команды Vim» (не команды ed или sed) для редактирования текстового документа из сценария оболочки.

1
На |характер трубы вывода одной команды к другой. wea-thisэто не команда. Трубопровод не может быть использован для достижения того, что вы хотите сделать; это приведет к тому, что стандартный ввод Vim будет левой рукой, а не клавиатурой. Если вы хотите , чтобы получить стандартный ввод в буфер в Vim, запустите его с минусом для имени файла: echo Hello, world! | vim -.
dash-tom-bang

Ответы:


15

Чтобы вставить строку "hello"в первую строку файла j, вы можете набрать в своей оболочке следующую команду:

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

  • :1 перемещает курсор на первую строку буфера
  • :put! ='hello' вставляет строку "привет" над текущей строкой

Чтобы вставить строку, "hello"а затем сохранить и выйти из файла:

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

То же самое, что и раньше, мы только что добавили команду Ex, :xкоторая сохраняет и выходит.

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

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

Если у вас много Ex-команд, вы можете написать их все внутри выделенного файла (например myExCommands.vim, по одному), по одной команде на строку, а затем из оболочки или сценария вы можете получить его (с помощью команды Ex :sourceили краткой версии). :so) как это:

vim +'so myExCommands.vim' file

редактировать

Я вижу, вы редактировали свой вопрос.
Я думаю, что предыдущий ответ все еще применим, потому что вы можете выполнить любую обычную команду из режима Ex с помощью команд Ex :normalи :execute.

Например, допустим, вы хотите:

  • переместите курсор на первую строку буфера ( 1G)
  • переместите курсор к первому непробельному символу в строке ( _)
  • переместите курсор на одно слово вперед ( w)
  • переместите курсор в конец нового слова ( e)
  • перейти в режим вставки после символа под курсором ( a)
  • вставить строку hello
  • сохранить и выйти ( :x)

Чтобы сделать это в файле j, введите из оболочки:

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

Для получения дополнительной информации см .:

:help +cmd
:help :normal
:help :execute

Я не смог полностью уточнить мою цель. Я хочу иметь возможность использовать команды vims, такие как w, чтобы переместить слово вперед и тому подобное. Я отредактирую свой вопрос, чтобы исправить.
Джейсон Басанезе

@JasonBasanese Я отредактировал свой ответ, делай команды Ex :normalи :executeделай что хочешь?
сагино

9

Вот способ, которым вы можете использовать команды обычного режима, а не только команды ex, чтобы редактировать поток, представленный Vim из stdin. Это не очень полезный пример, но он иллюстрирует используемые методы. Предполагается, что ваша оболочка bash.

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

В -конце команда Vim сообщает текст (не команды) из стандартного ввода. -sГоворит Vim выполнять нажатия клавиш из указанного файла. В этом случае файл является результатом подстановки процесса bash. <(...)Заменяется именем именованного канала. Вывод канала является выводом команды в скобках. В wcwred\eперемещает курсор на одно слово и изменения , которые в следующем слово red. :wq! foo\nСохраняет результат в файл , fooдаже если этот файл уже существует. Конечным результатом является файл с именем, fooсодержащим текстThe red fox jumped.

Подробнее о некоторых из этих тем см.

:help -file
:help -s

Смотрите также Process Substitutionраздел bash(1)справочной страницы.


Добавлено в мой ~ / .zshrc: vimx () { vi -s <(echo "$1"':wq') "$2" &> /dev/null; }. Теперь я могу vimx 'iThe brow fox jumped.\e' foo; vimx 'wcwred\efjdwiclimbed\e' foo; cat foo. Ухоженная!
Леонард Паули

4

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

vim <( program )

Пример:

 vim <( grep -nH  hello  myFile.cpp )
 vim <( find . -name '*.cpp' -exec grep -nH code_expr {} \+ )

4

У меня было то же самое желание, что и у вас: я хотел написать обычные команды vim, чтобы они редактировали поток конвейера. Я был разочарован трудностью использования обычного vim таким образом (так много флагов!), Как это предусмотрено параметрами vim по умолчанию.

Поэтому я написал небольшую оболочку для vim, чтобы сделать это: https://github.com/MilesCranmer/vim-stream/ . Это называется vims.

Сердцем оболочки является следующая команда:

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

Используя это, с генерацией команд, которые я делаю, получается довольно лаконично, и поскольку vim является модальным редактором, я создал vimsмодальный потоковый редактор. Есть три основных режима, которые полезны для менталитета редактирования конвейера:

[-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

Смотри:

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

Итак, eдоходит до конца Hello, затем aначинается добавление.

Что-то более необычное в exe-режиме, чтобы закомментировать строки, содержащие my_bad_var, и удалить предыдущую строку.

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

Что переводится как vims '%g/my_bad_var/exe "norm I//\<esc>kdd"'- Iналичие команды на начало вставки в начале строки и //последовательность комментариев. \<esc>kddнажимает клавишу escape, перемещается вверх по строке, затем удаляет строку.

У меня есть всего 11 примеров по репо, я призываю вас проверить их. Опять же, это работает поверх vim, это просто способ сделать vim более похожим на sed для потокового ввода (но сохранив все ваши любимые макросы vim!)


3

Это довольно старый вопрос, но я чувствовал, что стоит добавить, что если у вашего дистрибутива / ОС есть доступ moreutils, вы можете установить его и просто использовать vipeкак стандартное дополнение к vim:

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

moreutilsочень удобен и для других инструментов, и я очень рекомендую их, если вы серьезный пользователь командной строки! :) Посмотрите на введение автора (предыдущая ссылка) для более подробной информации.

moreutilsдолжен быть общедоступен для большинства * nix-подобных дистрибутивов через менеджер пакетов и через Homebrew на Mac . Например...

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


# Mac OS and Homebrew
brew install moreutils

moreutilsтакже является частью репозитория MSYS2 , так что вы можете технически использовать его и в Windows. :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.