I want to pass for loop as substitute command range:
for i in range(x, y) | is/$/foo/ | endfor
but i'm hit with Trailing characters: foo/ | endfor
The error reported by Vim is a bit misleading with regard to the actual problem in your command.
The actual problem is that the variable i can't be used like that. The whole substitution must be concatenated with :help expr-.. and passed to :help :execute. In this case:
for i in range(x, y) | execute i .. 's/$/foo/' | endfor
If you don't do that, the i in is/$/foo/ is interpreted as a literal i so the command you are using is :help :isearch, not :help :s. Vim thus reports a misuse of :is and completely—and rightfully—ignores your original intent.
Then there is another issue, not related to the problem at hand: :help :s already works on a range so there is no real need for a loop:
execute x .. ',' .. y .. 's/$/foo/'
Related
I am extracting information from several files and I wrote the following command:
:g!/Value/d | %s/.*=//ge | %s/\;//ge | %y
and it basically does:
'delete lines without "Value" | delete everything up to the = sign | remove ";" | copy all to register'
but the first :g!/Value/d is being ignored, it seems the %y is somehow causing it to be ignored as
:g!/Value/d | %s/.*=//ge | %s/\;//ge
properly cleans the document.
I also tried to get a log from the command execution there was nothing helpful there.
I don't see how the last command could affect the first one.
The | command separator has different precedence depending on the command, as :help :bar explains. For the :global command, it (and following commands) is considered to be part of the command arguments itself. That means that your substitutions and yank is not executed once (after the :global), but actually on every line that :global picks!
You've already found the correct workaround: By wrapping the command in :execute (which respects the | command separation) and quoting it, the following commands are only evaluated after the first command.
So I found a way to work around this
execute 'g!/\.Value/de' | %s/.*=//ge | %s/\;//ge | %y
This will produce the expected behavior, still it is unclear why the bar would not work for the :g command.
I'd like to map vim's 'keywordprg' to Dash, namely, use K to do !open dash://word-unser-curse.
Currently, I'm doing this:
:let &keywordprg '!open dash://'
but it says E34: No previous command.
from :h E34:
Any '!' in {cmd} is replaced with the previous
external command (see also 'cpoptions'). But not when
there is a backslash before the '!', then that
backslash is removed. Example: ":!ls" followed by
":!echo ! \! \\!" executes "echo ls ! \!".
Thus you have to escape ! in order to have vim treat as it is, otherwise vim tries to replace it with the "previous command", resulting in the error.
Additionally, I don't think you need that ! in your keywordprg. Vim calls it as an external command anyway (the default value is man, not !man).
I am new to Linux.
I was debugging some code. I encountered the following command:
PROGRAM_ID=$(echo $PROGRAM_ID|sed 's/-/,/g')
Can anybody explain what the g represents here?
I understand hyphen is being replaced with comma.
The /g flag means, perform the substitution globally on a line. Without that flag, only the first hyphen on every line would get substituted.
A better way with Bash would be
PROGRAM_ID=${PROGRAM_ID//-/,}
but if you have to be portable to Bourne shell in general, this replacement facility is not available.
(In which case you should take care to keep "$PROGRAM_ID" in double quotes in the echo.)
Its easy to see how g (global) works with these two example:
echo "test-one-two-three" | sed 's/-/,/g'
test,one,two,three
echo "test-one-two-three" | sed 's/-/,/'
test,one-two-three
Without the g it only replace the first hit.
How can I use functions in a user defined command? As a simple specific example:
How would I write a command that echos the argument passed to it?
I have this:
command -nargs=1 FW execute ":echo ".<args>
But when I run:
:FW something
I get:
E121: Undefined variable: something
E15: Invalid expression: ":echo".something
Because :echo takes an expression, a string must be quoted. This
is so common that Vim has a special notation for it; See :help <q-args>. Now, for
:execute, you'd need another level of quoting (and based on your comments it seems you went down that road):
:command! -nargs=1 FW execute "echo" string(<q-args>)
Also, you don't need to concatenate explicitly with .; the :execute command does that implicitly, and you can leave off the :.
But this double-quoting isn't necessary; you can skip the :execute:
:command! -nargs=1 FW echo <q-args>
You don't need a colon when you pass commands to "execute", it executes as if you were already in command mode.
You also don't need to concatenate strings with "." with execute if you want spaces between them, by default it concatenates multiple arguments with spaces.
I tried escaping args so that it would be concatenated as a string, this seems to work:
command -nargs=1 FW execute "echo" '<args>'
Is this what you were trying to achieve?
:h execute and :h user-commands are good reading.
edit:
some tests on this:
:FW "test"
test
:FW &shellslash
1
:FW 45
45
:FW "2+2"
"2+2"
:FW 2+2
4
As always, "execute" will execute anything you pass to it, so be careful.
A vim command confuses me. I have read and re-read :help shellescape() several times. I still don't understand the meaning of the number 1 in shellescape(expand('%:p'), 1).
Here's the full command I'm trying to understand:
:nnoremap <F4> :exe ':silent !"c:\Program Files\Mozilla Firefox\firefox.exe"'shellescape(expand('%:p'), 1)<CR>
Let's break down this long command piece by piece.
the command is to map an exe command into F4 in the whole.
:exe is to execute some command.
:silent ! is to execute a shell command silently
"c:\Program Files\Mozilla Firefox\firefox.exe" can call my firefox program.
shellescape(), there are blanks to be escaped.
expand('%:p') can get current file name in full expression that is path + filename.
What does this excerpt from the help page mean?
With a |non-zero-arg| {special} and 'shell' containing "csh" in the tail it's
escaped a second time.
Is there some meaning such the same as 1 or 2 in s/(ha.*)(world)/\2\1/g?
please take a simple example in detail.
And i have two questions related to the topic.
1.In which way i can get how many type of shells in my gvim?
2.In which situation can i change 1 into 2 in shellescape()?
:nnoremap <F4> :exe ':silent !"c:\Program Files\Mozilla Firefox\firefox.exe"'shellescape(expand('%:p'), 2)<CR>
There are basically two different uses for shellescape(); one is the Vimscript system() function, the other the :! Ex command. While most escaping needs are identical in both uses (e.g. to deal with whitespace, arguments must be enclosed in quotes), the :! command requires some additional escaping, because on the command-line, Vim assigns special meaning to symbols like % (replacing it with the current file name). This does not happen for system().
Therefore, to tell shellescape() which escaping mode to use, it has the additional {special} argument; if you pass 1 (or any other value that evaluates to "true"), the additional characters are escaped, too.
TL;DR: Pass 1 for :! commands, 0 or omit the argument for use with system().
From the help for shellescape():
shellescape({string} [, {special}]) shellescape()
Escape {string} for use as a shell command argument.
On MS-Windows and MS-DOS, when 'shellslash' is not set, it
will enclose {string} in double quotes and double all double
quotes within {string}.
For other systems, it will enclose {string} in single quotes
and replace all "'" with "'\''".
When the {special} argument is present and it's a non-zero
Number or a non-empty String (non-zero-arg), then special
items such as "!", "%", "#" and "<cword>" will be preceded by
a backslash. This backslash will be removed again by the :!
command.
The 1 in your example simply tells shellescape() to escape special characters with a backslash. If you were to have (say) a ! in the path returned by expand(), it’d be replaced with \!.
shell is an option:
'shell' 'sh' E91
'shell' 'sh' string (default $SHELL or "sh",
MS-DOS and Win32: "command.com" or
"cmd.exe", OS/2: "cmd")
global
Name of the shell to use for ! and :! commands.
— :help 'shell'
“With a non-zero-arg {special} and 'shell' containing "csh" in the tail it's escaped a second time” means that if, as in your example, shellescape() is given a non-zero argument for special (your example has a 1), it will check shell for that "csh", and if it finds it (if your shell is set to something containing csh) it will double-escape it.
EDIT to specifically answer two questions added to (edited) original post:
You can get your shell setting (referred to in the shellescape() help quote) using :echo &shell.
2 is a Number and is non-zero. You should therefore be able to substitute 2 for the 1 in your example and get the same result.