How do I actually use the value of an argument to a Vim function? - vim

I'm trying to write a simple Vim function that takes the name of a file as an argument and reads the contents of that file into the current document (related to this question).
Here's my first stab at it:
fun! Tpl(tplfile)
r c:\tpl\a:tplfile
endfun
That just gives me the following error:
E484: Can't open file c:\tpl\a:tplfile
How do I make the function actually use the value of the tplfile argument?

Replace the line with:
exe 'r c:\tpl\' . a:tplfile
The a:tplfile is a string variable, so to include it in a command, you have to combine the whole lot into one string (with the '.' operator) and then use exe to run the command
:help exe
On a related note (and a shameless plug), if you're trying to add templates (as implied by the post you linked to), my file templates plugin has a command AddTemplate to add a template from your vimfiles/templates directory at the current cursor location. However, the documentation is currently rather poor, so if you decide to use it and have any difficulties, feel free to drop me an email at the address on my website.

Related

In Vim how to know if function is defined

I am using Vim editor v7.4 .
I have a huge C Code library , and i make constant changes to it.
Is there a way ( before compilation) to know if a function i am adding to some file is defined for this file.
Thanks
I'm not sure to correctly understand your need. In my definition, when I add a function to a file, I add its definition, so it's defined. But when I'm using a function in a file, I only need its declaration. Then there is also the problem of being sure that a function defined in a translation unit is declared somewhere (privately in the same TU as a static function, or in a header file).
For the latter, I have a solution (that checks functions definitions and declarations are balanced in lh-cpp). For the case of being sure a function is declared in the UT it's used, it won't be that simple: we need to do the preprocessor work (and recursively follow includes) and search whether a function is indeed declared. It's not impossible, but it's best to have vim know the paths where header files are in order to look for them.
Look at a tool like exuberant ctags. It parses C-style files to find any identifier and store them in a tag file, so that each of them can be accessed quickly, inside Vim for example.
Once installed, in the shell command line, you have to create a tag file with this kind of command:
$ ctags *.c *.h
This will create an new file called tags, where all the c files and header files in the current directory are parsed. Please note that there are many options for this tool (like recursively include all lib headers, which can lead to a huge file, though), you may look at the doc for more details.
Once done, in Vim, there are several commands to use transparently the infos in this file. First check your current directory is the same as the tag file; then, to check if an identifier (like a function name) is already present in the tag file, you can use:
:ts myFunctionName
I don't think tag is a good enough solution to check whether function is defined. The flexibility of C syntax make it worse, because most tag tool is syntax-based other than semantics-based.
For example, at present, the most powerful code-completion plug-in for vim is
YouCompleteMe, which is semantic-based by virtue of Clang.
So IMHO, the answer to your question is: compile it!
In order to do compiling more convenience, you can add the following configuration in your .vimrc.
map <F6> :make install<CR>
After this, when you press F6, compiler will be launched to check your code.

Navigation of vim autoload functions without ctags

Is there any vim command or plugin which can jump from a reference of a function to its definition in a script file which is in one of the "autoload" directories except using ctags?
For example, put the cursor above "call xyz#abc#foo()" and enter such command will open file ".../autoload/xyz/abc.vim" and set the cursor position at "function xyz#abc#foo()"
I do not bother with generating tags file every time a new plugin is insalled.
(Sorry for the very late answer)
I use tags to navigate my autoloaded functions.
But I also have an old :SearchInRuntime sp autoload/xyz/abc.vim command that'll split open the autoload file we're looking for, if not already open.
But it shouldn't be to hard to implement the feature. Once you have the function name obtained with expand('<cword>') or whatever, you could
build the plugin name: let plgname = 'autoload/'.substitute(matchstr(fnname, '.*\ze#'), '#', '/', 'g').'.vim'
search for it: let matches = globpath('&rtp', plgname, 1, 1)
check you have only one match, ...
open the file: exe 'sp '.matches[0] -- more subtitle approaches may be required to avoid to open it several times.
and then search the function definition: call search('^\s*fun\%[ction]:\=\s\+'.fnname', ....)

Own simple template system in vim - include file

I've read vim-wiki about dynamic templates and I want similar, simple "template-system". I've created a function:
function! Read_template(file)
execute '0r /home/zsolt/.vim/skeletons/'.a:file
%substitute#\[:EVAL:\]\(.\{-\}\)\[:END:\]#\=eval(submatch(1))#ge
%substitute#\[:READ:\]\(.\{-\}\)\[:END:\]#??????#ge
endfunction
I want to include a file from a template. The EVAL works well but how can I solve the READ function? It isn't important to eval the included file.
An example:
main.tex:
\documentclass[a4paper]{article}
....
exam.tex:
% Created [:EVAL:]strftime('%Y. %B. %d.')[:END:]
[:READ:]/path/of/main/main.tex[:READ:]
I exec Read_template("exam.tex") and want that exam.tex includes main.tex.
How can I do this?
You'll need to read the file and insert its contents. As you cannot use :read (it will read entire lines and cannot be called from within a substitution), you have to use the lower-level readfile() Vimscript function, like this:
%substitute#\[:READ:\]\(.\{-\}\)\[:END:\]#\=join(readfile(submatch(1)),"\n")/#ge
You'll have to parse each line imported and apply what needs be :
- expression substitution
- inclusion of other templates, etc. (which will mean that you'll have to remove and add lines on the fly. In the last version of mu-template template expansion engine, the expansion is done in-memory)
FYI, my work of mu-template already has this feature: http://code.google.com/p/lh-vim/wiki/muTemplate#Completely_useless_recursive_example

What is the easiest way to rename the file you're currently editing in Vim?

What would be the most practical way to rename the file you're currently editing in Vim without messing up your current splits configuration?
Generally, one would need to ... save the file under a different name, delete the original one, and re-open the new one without making a mess of the current layout.
Anyone have any idea how to do that in one command (function) or less?
:saveas newname will save the buffer with the new name, make that name the current buffer, and set the alternate buffer to the old file.
:call delete(expand('#')) will then delete the file associated with the alternate buffer.
You can easily turn that into a command with something like
:command! -bang -complete=file -nargs=+ Rename saveas<bang> <args> | call delete(expand('#'))`
The user manual provides a thorough description of how to create user commands. Here's an explanation of the elements I'm using above.
-bang allows the command to called as either Rename or Rename! and <bang> in the constructed command is replaced by either an empty string or !, depending on how it is called. This is used to support the same functionality in the :saveas command.
-complete=file will let you tab-complete the path that will be used for the new file, similar to :e and :saveas do.
-nargs=+ specifies that :Rename requires at least one argument (the filename), but can take more. <args> is replaced with whatever arguments are given to :Rename. This allows you to specify the extra arguments that :saveas accepts, so you could do something like :Rename ++enc=latin1 newfile to rename the file to newfile and change the encoding to latin1.
Tim Pope has a plugin that has a function :Rename that does this: vim-eunuch.
You can also do the following sequence of steps:
:saveas newfile
:bw <buffer_for_the_old_file>
:!rm old_file
of course this is not as nice as renaming the file in the shell.
Call up the explorer with :Explorer or just :E, select your file, and then press r to rename.
Use :Move provided by eunuch.
eunuch also provides other useful file operations, like :Remove, sudoedit.

Get the file name without file extension in a Vim function

I want to get the file name without the file extension in Vim.
I wrote the following function in my .vimrc file to compile and run the Java program:
:function! JAVA_RUN()
:!javac %^M
:endfunction
map <F3> :execute JAVA_RUN()<CR> :source $HOME/.vimrc<CR>
How can I get the file name without the extension inside the function?
:help expand() should give you the answer, see expand().
You should use the r modifier for %, with %:r instead of % to get the file name without extension.
If you want to write functions to build and execute files, you should also have a look at the documentation for shellescape, in order to prevent problems with spaces in file name or path.
If you want to expand a filename (other than % etc) take a look at fnamemodify()
fnamemodify({fname}, {mods}) *fnamemodify()*
Modify file name {fname} according to {mods}. {mods} is a
string of characters like it is used for file names on the
command line. See |filename-modifiers|.
fnamemodify("main.java", ":r") returns main.
I literally just read a similar question to this (in that someone else seemed to be trying to configure vim to build automagically for them with the F-key), and wrote an answer about how you can leverage the power of vim's :make command without even needing to write a Makefile. In your case, it's less directly related to the question, but I thought I'd mention it in case you were interested.
Furthermore, someone seems to have written something on Vim Tips Wiki about how to set up vim's :make command to specifically work with Java projects built with ant. I haven't worked with Java in a while myself, but in your case specifically it might be a good place to get started.
I came here looking for an answer for a similar question. I wanted to be able to extract the current class name from the java file being edited. I found a very neat way to do this in vim with an abbreviation:
ab xclass <C-R>=expand('%:t:r')<CR>
Place this line in your .vimrc (or similar) for this to work. An abbreviation will auto-trigger as soon as you press space, and so I usually prefix them with 'x' to avoid their accidental expansion.
The trick here is the combination of :t and :r in the argument to expand(). % is the "current file name", :t selects just the tail of the path ("last path component only") and :r selects just the root ("one extension removed"). (quoted parts are from the official expand() documentation.)
So when you are creating a new class in file /a/b/ClassIAmAboutToCreate.java you would type:
public class xclass {
the moment you press space after "xclass", the abbreviation will be expanded to public class ClassIAmAboutToCreate, which is exactly what you need.
Also, note that an abbreviation can be triggered by pressing Ctrl+] which avoids inserting a space after the class name.

Resources