When you use ! or :! Vim builds the invoking command based on whatever is specified in the various 'shell...' settings (i.e. 'shell', 'shellcmdflag', 'shellquote', to name three). On Unix systems the defaults for the first two are usually the default shell ($SHELL) and -c so if I'm using Bash and I do :!foo bar the call Vim makes will look like:
/bin/bash -c ...
!! (and more generally the ! operator) provides vim builtin support for all the unix filters that have evolved over the ages: this includes cut, paste, sort, uniq, awk, sed, even bash. Basically a filter is anything that can transform stdin to stdout (possibly doing something meaningful—the identity filter is just cat).
By providing access to these tools, ...
Is there a way to see exactly what shell command is being called out?
To see what exactly is run,
will show vim's PID, e.g. 1234, with which you can then in another terminal run:
sudo strace -fe trace=execve -p 1234
then in vim you can use any shell-invoking command like:
and in the terminal running strace see something like:
It is a little bit faster to use a string expression than a lambda (and arguably easier to understand in this case),
call filter(a, 'index(b, v:val)<0')
This naive implementation is O(N^2) but is still fairly fast in practice as index() is implemented in C. If you have a very large number of elements in the RHS, it may be faster to use a pre-computed ...
consider every program that reads stdin and writes stdout a filter.
What is available is out of scope of vim. It largely depends on your OS and installation. The sort of the example in the vim-docu is not part of vim.
Besides, it is a bad example, since quite a while vim has inbuild-sort.
sed, perl, python, node, cat, tail, less .... are all valid filters
An easy check is :!foo that (probably) will print something like bash: line 1: foo: command not found. Also see :h job_start() (or :h jobstart() for Neovim) and so on.
:! always uses &shell (as well as &shellcmdflag, &shellquote, &shellxqoute and so on);
:h system() and :h systemlist() use &shell in Vim; in Neovim it ...
When using a relative path, awk assumes the path is relative to the current directory. In the comments, you note that :pwd gives /home/user; that means you need to give either
an absolute path to denorm.awk, or
a path relative to /home/user (in general, relative to the :pwd)
As far as keeping the existing csv, you should use the filter syntax (:%!awk -f ...
but I don't have the option of piping the output to an external command
Actually you do:
echo system('wc -l', execute('g/http/'))
However, note that execute() prepends a newline to the resulting string, while not appending a newline after it. Hence the result of wc -l remains the same, but it could matter under different circumstances.
A classic example for this filter is to sort the input using the Shell command sort. So vi does not have to implement its own sorting algorithm but could plugin external commands to do that.
Nowadays, Vim comes with its own sort implementation as :sort command, mainly because some systems did not provide a sort binary.
I'm not aware of any builtin, compact functionality that let's you filter the output of any vim command through any external command. With a little one-time scripting, though, you could get something like this...
:MyFilt g/http/ | wc -l
To start, put this in your vimrc...
let parts = split(a:cmd, '|')
let vimcmd = trim(parts)
Just (yesterday) bought a Lenovo Duet Chromebook to replace my Android tablet. Immediately swithed on the Linux Beta option in the setting menu. Turned out the linux environment comes with Vim (not gvim) preinstalled!
If you have a recent enough and powerful enough Chromebook, then you should consider Crostini, which can give you a Linux container running in a lean virtual machine in your Chromebook.
If you have an older Chromebook, you can consider Crouton, which can give you a chroot with a Linux distribution into your Chromebook.
Both approaches will allow you to ...
To apply Ex command to an arbitrary selection you can do the following:
Copy selection to the end of file
Select those new lines and run the command
Cut the result
Replace old selection with the result
Of course, it's no good in doing this manually, so the plugins exist.
I know of VIS (written by DrChip), and vim-opera (that one is mine; it also provides ...
is there another way to run an external command on the alternate screen, that doesn't involve passing it lines from the current buffer as standard input?
Try to remove ^[[?1049h from 't_ti' and ^[[?1049l from 't_te':
au VimEnter * call s:altscreen(v:true)
au VimLeave * call s:altscreen(v:false)
As an example, consider this text:
one zwei three
four fünf six
Visually select the block containing the german numbers zwei and fünf, and run this command:
:'<,'>s/\%V.*\%V./\=system('trans -brief', submatch(0))[:-2]/
It should translate the numbers into english:
one two three