VIM: how to put result of a colon command into a variable? - vim

In VIM script, i want to check if VIM was started with command-line arguments or wthout. For this, i want to check a result of :args command that prints arguments. But how to put a result of :args inside an if() or a variable. Following wll not work:
let s:MyArgs = execute( "args" )

You need to play with :redir. I have encapsulated this operation in a function there.
BTW, argc() should also answer your original need in a simpler way. (:h argc())

Related

Is it possible to do something like `:normal :` to enter command line during the execution of a vimscript function?

I am writing a vim script function. During its execution, I want to enter the command line to provide some arguments that cannot be decided in advance, for some specific commands. I want something like
:startinsert
But should goes like
:startcmd
Is it possible? Or some other ways around?
input() is what you want.
Here is an example:
let myFile = input("Choose a file: ", "", "file")
execute 'edit ' . myFile
and another one:
buffer `=input("Choose a buffer: ", "", "buffer")`
See :help input().
You can also allow your user to choose from a predefined set of options with inputlist().
There is a way around, we can use following code to mimic the command line.
exec input(prompt, text, completion)
text and completion are optional, :h input() for more
But one thing to note:
the built-in completions of vim (:h command-completion for more) indicated by the completion argument complete with entire preceding line before the cursor when you hit <tab> in input(). This may be not what you want, e.g., I just want to complete the last word instead of the entire preceding line.
To solve this problem, you have to write your own completion function, please refer to :h command-completion-custom and :h command-completion-customlist

Calling another user command inside the user defined command

Is it not possible to call another user defined command in a user defined command?
I tried the following two lines but neither of them worked:
command! GetRapidLinks FindRapidLinks|MatchesOnly
command! GetRapidLinks :FindRapidLinks|:MatchesOnly
The Vim help reads:
You cannot use ":X", ":Next" and ":Print"
The context of this restriction is not clear. I guess one cannot use those in a user defined command, right?
This is probably because you didn't define the :FindRapidLinks command with -bar; without it, the command "eats" the entire remaining arguments (cp. :help command-bar). So, either redefine:
:command! -bar FindRapidLinks ...
:command! GetRapidLinks FindRapidLinks|MatchesOnly
or work around this (for cases when you cannot redefine the other command) via :execute:
:command! GetRapidLinks execute 'FindRapidLinks'|MatchesOnly
As a general rule, use -bar unless your custom command needs to be passed arguments that contain special characters like |.
Actually, what the help means is, you can't call a user command :Next or :X, because those are the few builtin commands, that start with a capital letter. I am not sure, why your vim actually says, you can't define a :Print command, as it is possible to define your own custom :Print command (since the builtin command is only an alias for :print anyhow)
I am not sure, what exactly you are trying to achieve here, so I can't answer the first part of your question. You can however in a function or in a custom command call another custom command.
Perhaps try backticks ` (not to be mistaken with quotes ' or ")
for e.g.
command! GetRapidLinks `FindRapidLinks` | MatchesOnly
or
command! GetRapidLinks $(FindRapidLinks) | MatchesOnly

Pass a variable to sleep in vimscript

I've been using vim for too many years to count, but I never have really learned vimscript very well. I'm trying now.
Anyway, I would like to pass a variable amount of time to the sleep function. I also want to manipulate that value before I pass it along. Here's a simple example.
function! wait(mil)
let timetowait = mil . "m"
sleep timetowait
endfunction
Even if I try prefixing timetowait with l: it says, "Invalid argument: l:timetowait".
What's the right way of passing the value of a variable to sleep?
There are a couple of problems:
Your method should start with a capitalized name
You need to access your argument with a:
You have to have a space between the time to sleep and m
You have to execute the sleep indirectly using execute
Here's an example on how one could do this:
function! Wait(mil)
let timetowait = a:mil . " m"
exe 'sleep '.timetowait
endfunction
Daan's answer is correct; here's some more background info:
Vimscript is evaluated exactly like the Ex commands typed in the : command-line. There were no variables in ex, so there's no way to specify them. When typing a command interactively, you'd probably use <C-R>= to insert variable contents:
:sleep <C-R>=timetowait<CR>m<CR>
... but in a script, :execute must be used. All the literal parts of the Ex command must be quoted (single or double quotes), and then concatenated with the variables:
execute 'sleep' timetowait . 'm'

How to expand function arguments in Vim command line?

Vim's Utl plugin offers a convenient way for doing web queries from within the editor. When called directly from the command line, a dictionary lookup can be done like this:
:Utl ol http://dict.leo.org/?search=my+search+term
What's the correct way for defining a custom command with the same purpose (my+search+term being user input)? I can't seem to get <f-args> right with this one:
command -nargs=1 SearchLeo :exe ":Utl ol http://dict.leo.org/?search=" . expand("<f-args>")
What's the correct way of defining function arguments here? Or should I turn this into a more complete function? Thanks!
You probably don't need expand() here; it's just for expanding globs (like *.txt) or the special variables like % for the current file.
You're quoting the argument twice, once through <f-args> (<q-args> would be slightly more correct, though it only matters with a variable number of arguments), once literally.
Use this:
command -nargs=1 SearchLeo :exe ":Utl ol http://dict.leo.org/?search=" . <q-args>

vim: how to replace a variable with its value in ~/.vimrc

I would like something similar too this in my .vimrc.
let dir=“/home/user/Downloads/”
set path=$dir
nnoremap gr :grep '\b<cword>\b' $dir/*<CR>
The code above is wrong of course, but maybe you can understand what I am trying to do. I would like to set path to the value of dir to /home/user/Downloads/, and replace the word dir in the third line with the value of dir. I tried and failed, can anyone tell help me out, any help appreciated!
First of all, there are fancy quotes; you need to use plain (") ones. Other than that, the :let is okay.
let dir = "/home/user/Downloads/"
You could use :execute to evaluate the defined variable with :set, but it's easier to use :let, because it can change Vim options, too, with the special notation &{optionname}:
let &path = dir
For the mapping, if dir doesn't change during runtime, it's easiest to use :execute. Note how the quoted backslashes must be escaped (i.e. doubled):
execute "nnoremap gr :grep '\\b<cword>\\b' " . dir . "/*<CR>"
All that information is part of :help eval. Learn how the excellent and comprehensive help is structured; all the information is in there (you just need to know how to find it)!
You must use this notation:
let variable_name = "value"
and use straight quotes.
To set path:
set path=/home/user/Downloads/
or to append a directory to path.
set path+=/home/user/Downloads/
Path is an Vim variable which does not seem very appropriate to use if you are going to only use it for this one remapping. It would be better to declare you own variable, as path can also have many directories within it which will not work with grep.
let g:search_path="/path/to/your/dir"
nnoremap gr :grep '\<<cword>\>' <C-R>=eval("g:search_path")<CR>
Ctrl+R lets us insert a register here, when then use that to call the expression register, which we use to evaluate g:search_path.
Check out :help expr-register for more on that!
This will evaluate your g:search_path variable on every execution of the mapping, allowing you to change the path and not have to remap gr each time.

Resources