In vim, how do I define a function that can be called without :call? - function

How do I define a function so that I can call it from command-line mode without :call in front of it?
Right now, I have to do this: :call TrimWhitespace()
I want to define it so that I can do this: :TrimWhitespace

This won't be a function, you should create a command instead. Check the documentation for commands (:help user-commands in Vim).
The simplest case is of a command to call a function:
command! TrimWhitespace call TrimWhitespace()

Related

Glob as the argument of a shell function

I'm writing a reusable function, so I need the argument to be as flexible as possible.
Consider a simple example:
function testf(){
print ./*.$1
}
This works. For example, with testf mp3 it lists all the files ending with .mp3 in an array, making possible the use of for loops. But this way it only allows me to work with the extension name.
Therefore, I tried:
function testf(){
print ./$1
}
However, it doesn't work. Using testf *.mp3, unlike using print *.mp3 in the terminal, it will only pass the first matching string instead of the whole array.
Any suggestion?
ists all the files ending with .mp3 in an array ... there is no array involved in your question.
But to your problem: First, you want to pass to your function a wildcard pattern, but this is not what you are actually doing. testf *.mp3 expands the pattern before the function is invoked (this process is called filename generation), and your testf gets just a list of files as parameters. You can pass a pattern, but you have to ask the shell not to expand it:
testf '*.mp3'
In this case, your $1 indeed will contain the string *.mp3. However, your print ./$1 will still not work. The reason is that filename generation occurs before parameter expansion (which is the process where $1 is replaced by the string it contains). Again, you have to ask the shell to do it the other way round:
print ./${~1}
The shell performs several types of expansions before launching the command. When you enter
testf *.mp3
the shell will expand the glob first, and pass each filename as a separate argument to the function
Your function could look like this:
function testf(){
printf './%s\n' "$#"
}

How to execute a normal mode command in a vim function?

I am writing a vim function to insert some text in a c++ file, please see the following function:
function! InsertDebugInfo()
let i = line('.')
call append(i+1, '#ifdef DEBUG')
call append(i+2, 'std::cout << "" << std::endl;')
call append(i+3, '#endif')
call append(i+4, '')
call cursor(i+3, 0)
endfunction
In normal mode, I use == to re-indent one code line. My question is
how to call == in the above function. Furthermore, how to execute the
command such as 2f" which move the cursor to the second ".
To indent, you can just use
normal ==
To find also you can use
normal 2f"
or even shorter
norm <whatever you do in normal mode>
Now you might be getting what I'm trying to say.
If not, read documentation :h normal.
Try this in your function:
execute 'normal 2f"'

What (precisely) is a command?

Which of the following is most appropriately called a "command," and what should the other be called?
changeDirectoryTo
changeDirectoryTo /home/peter
The command is changeDirectoryTo. /home/peter is the argument to that command

Vim function to copy a code function to clipboard

I want to have keyboard shortcut in Vim to copy a whole function from a Powershell file to the Windows clipboard. Here is the command for it:
1) va{Vok"*y - visual mode, select {} block, visual line mode, go to selection top, include header line, yank to Windows clipboard.
But it would work only for functions without an inner {} block. Here is a valid workaround for it:
2) va{a{a{a{a{a{a{Vok"*y - the same as (1), but selecting {} block is done multiple times - would work for code blocks that have 7 inner {} braces.
But the thing is - the (1) command works fine when called from a vim function, but (2) misbehaves and selects wrong code block when called from a vim function:
function! CopyCodeBlockToClipboard ()
let cursor_pos = getpos('.')
execute "normal" 'va{a{a{a{a{a{a{Vok"*y'
call setpos('.', cursor_pos)
endfunction
" Copy code block to clipboard
map <C-q> :call CopyCodeBlockToClipboard()<CR>
What am I doing wrong here in the CopyCodeBlockToClipboard?
The (2) command works as expected when executed directly in vim.
UPDATE:
I've noticed that:
if there are more a{ then the included blocks in the function
then vim wouldn't execute V
Looks like vim handles errors differently here. Extra a{ produces some error and regular command execution just ignores it. But execution from withing a function via :normal fails and wouldn't call V (or probably any command that follows the error).
Any workaround for this?
Try this function
function! CopyCodeBlockToClipboard()
let cursor_pos = getpos('.')
let i = 1
let done = 0
while !done
call setpos('.', cursor_pos)
execute "normal" 'v' . i . 'aBVok"*y'
if mode() =~ "^[vV]"
let done = 1
else
let i = i + 1
endif
endwhile
execute "normal \<ESC>"
call setpos('.', cursor_pos)
endfunction
This preforms a execute command to select blocks until it fails to select a block larger block. ([count]aB selects [count] blocks) It seems when the selection fails we end up in visual mode. So we can use mode() to check this.
When this function exits you should be in normal mode and the cursor should be restored to where you started. And the function will be in the * register.
This macro should come close to what you want to achieve:
?Function<CR> jump to first Function before the cursor position
v enter visual mode
/{<CR> extend it to next {
% extend it to the closing }
"*y yank into the system clipboard

octave history command - variable as filename

i want to write little helper functions that stores and loads the octave session.
function restoreSession(filename)
history -r strcat('./states/',filename,'.history');
load("-binary", strcat('./states/',filename,'.data'))
endfunction
function saveSession(filename)
history -w strcat('./states/',filename,'.history');
save("-binary", strcat('./states/',filename,'.data'))
endfunction
The save/load command works well.
My Problem is that the history command seems not to evaulate the argument.
it prodces the following error:
syntax error
>>> history -r strcat('./states/',filename,'.history');
^
I already tried to use a temporary var for the path but in this case it only interprets the variable name as filename and complains about the missing file.
Does anybody has an idea how to solve this?
Use history with the function syntax instead of a command.
history ("-r", strcat ("./states/", filename, ".history"));
All commands are actually functions. The command syntax (when you don't use parentheses) is available to all functions, it just happens that for some it looks more natural. When you omit the parentheses, all the arguments are interpreted as strings, even variable names. If you want to do something fancier, call them as functions.