:!<command>
може використовуватися для виконання команди в оболонці. Але це "переймає" мій термінал і заповнює його stdout
саме цією командою.
Як виконати команду у фоновому режимі, яка повідомляє мене лише про ненульовий код виходу?
:!<command>
може використовуватися для виконання команди в оболонці. Але це "переймає" мій термінал і заповнює його stdout
саме цією командою.
Як виконати команду у фоновому режимі, яка повідомляє мене лише про ненульовий код виходу?
Відповіді:
:silent exec "!command"
Зауважте, що ваш сеанс vim все ще буде зайнятий під час виконання вашої команди. Це пояснюється синхронним характером Віма. Ви все ще можете повернутися до своєї оболонки, натиснувши CTRL + z (щоб надіслати Vim на задній план), а потім відновити vim з командою, fg
як зазвичай.
Щоб робити справи асинхронно, погляньте на vim-dispatch плагіна Тіма Попа або проект NeoVim, який має вбудовану підтримку для асинхронного виконання команд, яку ви можете легко використовувати за допомогою плагіна NeoMake. Остання версія Vim також має підтримку асинхронних завдань.
Див . : h: мовчати
:silent !ls
) ... Це також не робить Я не даю належного виводу на код виходу без 0 ... Тому я боюся, що це трохи більше, ніж просто використання :silent
...
:silent exec "!ls"
не :silent !ls
відображається жоден вихід
:silent !ls
: i.stack.imgur.com/1XvS6.png ... Мені потрібно натиснути, ^L
щоб виправити це знову ...
Для виконання команди без запуску повідомлення Enter, наприклад:
Натисніть ENTER або введіть команду, щоб продовжити
спробуйте наступний простий приклад:
:silent !echo Hello
Потім натисніть Ctrl+ L(або :redraw!
), щоб оновити екран, повернувшись до Vim.
Щоб уникнути необхідності оновлення, ви можете визначити власну власну команду, наприклад:
:command! -nargs=1 Silent execute ':silent !'.<q-args> | execute ':redraw!'
Тепер ви можете використовувати нову команду Vim для запуску команди оболонки (зверніть увагу: без ! Та з великої літери S ):
:Silent ps
Джерело: Уникнення підказки "Натисніть ENTER для продовження" на сайті Vim Wikia
:Silent ctags -R . > /dev/null &
запускатись у фоновому режимі. Надсилання stdout в / dev / null не дозволяє відображати вихід у буфері vim.
Це може запустити процес у фоновому режимі:
:!slow_command_here > /tmp/output 2>&1 &
Але Vim потрібен спосіб з'ясувати, коли процес закінчився, і як, тому давайте скористаємося файлом маркера:
:!(rm -f /tmp/finished; slow_command_here > /tmp/output 2>&1; echo "$?" > /tmp/finished) &
Тепер ми можемо попросити Vim так часто перевіряти, чи завершився процес:
:augroup WaitForCompletion
:autocmd!
:autocmd CursorHold * if filereadable('/tmp/finished') | exec "augroup WaitForCompletion" | exec "au!" | exec "augroup END" | echo "Process completed with exit code ".readfile('/tmp/finished')[0] | end
:augroup END
Гей, це не дуже, але це начебто працює!
На жаль, autocmd вище не спрацьовує, поки ви не перемістите курсор. І якщо ви хочете запустити декілька фонових процесів одночасно, вам потрібно буде додати унікальні ідентифікатори до цих файлів та до імені групи autocmd.
Отже, якщо ви можете впоратися з додатковою залежністю, вам може бути краще використовувати перевірене рішення, як плагін vim-dispatch, згаданий в іншій відповіді.
Якщо ви хочете побачити вихід процесу, а не просто вихідний код , то замініть остаточний echo
вище на:
silent botright pedit /tmp/output
Це відкриє вікно попереднього перегляду. Щоб скористатися списком помилок швидкого виправлення:
silent cget /tmp/output | copen
Список швидких виправлень дозволяє легко переходити до помилок за допомогою :cnext
. Однак copen
переміщує курсор у вікно швидкого виправлення, коли воно відкриється, що, ймовірно, буде дивовижним / дратує.
(Приблизним рішенням цього може бути відкриття вікна QF :copen
при первинному запуску процесу, тому вам не потрібно буде називати його в кінці.)
Я запускав команду, яка трохи блокувалась, і мене не дуже хвилювало вихід. Для цього можна переконатися, запустивши процес, приєднаний не до терміналу / емулятора, а до системи та перенаправляючи весь вихід на / dev / null. Наприклад:
:silent exec "!(espeak 'speaking in background'&) > /dev/null"
(...&)
працює в фоновому режимі і > /dev/null
перенаправляє весь висновок /dev/null
(нічого).
В дужках уловлюється вихід у підрозділ (або щось подібне), але він має побічний ефект від того, що він не буде приєднаний до поточної оболонки (не велика справа).
Я просто зрозумів , що якщо ви перебуваєте на самому ділі, відображення його, ви можете зробити що - щось на зразок
nnoremap <silent> <leader>e :!$(espeak 'speaking in the background'&) > /dev/null
Вищезазначене нічого не відображатиме в командному рядку і, крім того, нічого не відображатиме в терміналі поза vim. Це буде відображено <leader>
e, що \ eза замовчуванням.
(Ще одна редакція - і, можливо, найновіша). Це один буде відображатися на виході з команди , якщо ви так вибираєте:
ВНУТРИ НОВИЙ ТАБЛИЦЯ
silent exec "!(echo 'hello. I'm a process! :)') > /tmp/vim_process" | :tabedit /tmp/vim_process
ВНУТЬСЯ ВЕРТИКАЛЬНИЙ СПЛІТ:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :vs /tmp/vim_process
ВНУТЬ ГОРИЗОНТАЛЬНУ СПЛІТУ:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :sp /tmp/vim_process
... робити все, що ви хочете
Якщо ви не переймаєтесь кодом виходу, можете перейти до цього:
:call system('/usr/bin/zathura using-docker.pdf &')
v:shell_error
змінна скаже вам
Не впевнений, чи відповідає це вашим потребам, (не обробляє фонові процеси як у foo &
- не впевнений, що це ви маєте на увазі під "у фоновому режимі" ), але спеціальна команда може використовуватися як у:
fun! s:PraeceptumTacet(cmd)
silent let f = systemlist(a:cmd)
if v:shell_error
echohl Error
echom "ERROR #" . v:shell_error
echohl WarningMsg
for e in f
echom e
endfor
echohl None
endif
endfun
command! -nargs=+ PT call s:PraeceptumTacet(<q-args>)
Потім використовуйте як:
:PT ls -l
:PT foobar
ERROR #127
/bin/bash: foobar: command not found
Якщо вам не потрібно / хочете, щоб повідомлення про помилку system()
було достатньо простого , тоді перевірте їх v:shell_error
та повідомте, наприклад echo Error!
.
З довідки v: shell_error :
v:shell_error shell_error-variable
v:shell_error Result of the last shell command. When non-zero, the last
shell command had an error. When zero, there was no problem.
This only works when the shell returns the error code to Vim.
The value -1 is often used when the command could not be
executed. Read-only.
Example: >
:!mv foo bar
:if v:shell_error
: echo 'could not rename "foo" to "bar"!'
:endif
"shell_error" also works, for backwards compatibility.
foo &
..." . З тексту Q в цілому я трактував це як або. Або "Виконати як зовнішню команду AKA background", або "Виконати як зовнішню команду _and_ як фоновий процес" . Я відповідав головним чином на основі назви Q тощо - і додав коментар до “Не впевнений…” - і залишив це ОП, щоб уточнити, чи є, чи.
Vim 8 представив підтримку робочих місць. Можна виконувати зовнішню команду у фоновому режимі, не покладаючись на плагіни. Наприклад, запустити сервер розмітки ( markserv ) у поточному місці та не блокувати сеанс vim:
:call job_start('markserv .')
Це запускає процес markserv як підпроцес поточного процесу vim. Ви можете підтвердити це за допомогою pstree
.
Дивіться роботу_стар
Я використовую такий код:
command! -nargs=1 Silent call SilentExec(<q-args>)
function! SilentExec(cmd)
let cmd = substitute(a:cmd, '^!', '', '')
let cmd = substitute(cmd, '%', shellescape(expand('%')), '')
call system(cmd)
endfunction
Тепер ви можете набрати наступне
:Silent !your_command
Це виглядає майже як вбудована silent !
команда Vim , за винятком столиці S
. Це навіть дозволяє необов'язково !
зробити так, щоб він виглядав ще більш схожим. Заклик до system()
команди оболонки по-справжньому беззвучний: жоден екран не блимає і не перемальовується.
(і якщо вам коли-небудь потрібен код статусу, ви можете перевірити v:shell_error
змінну, див. довідку для отримання додаткової інформації)
AsyncRun плагін , якщо вони призначені для цього, вона дозволяє запускати команди оболонки в фоновому режимі в Vim8 / NeoVim і виведення зображення в QuickFix вікна.
Так само як заміна !
команди:
:AsyncRun ls -la /
Ви також можете повністю приховати вихід у вікні швидкого виправлення:
:AsyncRun -mode=3 ls -la /
Коли робота закінчена, AsyncRun сповістить вас, передавши варіант -post
:
:AsyncRun -post=some_vim_script ls -la /
Сценарій vim, визначений програмою, -post
буде виконаний після завершення завдання.