How to use a template in vim
The command that you've suggested is not going to work: what this will do is run no Vim command whenever you open ~/.vim/skeleton.R
A crude way of achieving what you want would be to use:
:au BufNewFile *.R r ~/.vim/skeleton.R
This will read (:r
) your file whenever a new *.R
file is created. You want to avoid having BufRead
in the autocmd, or it will read the skeleton file into your working file every time you open the file!
There are many plugins that add a lot more control to this process. Being the author and therefore completely biased, I'd recommend this one, but there are plenty of others listed here.
Shameless plug:
They all work in a relatively similar way, but to explain my script:
You install the plugin as described on the linked page and then create some templates in ~/.vim/templates
. These templates should have the same extension as the 'target' file, so if it's a template for .R
files, call it something like skeleton.R
. In your .vimrc
, add something like this:
let g:file_template_default = {}
let g:file_template_default['R'] = 'skeleton'
Then create your new .R
file (with a filename, so save it if it's new) and enter:
:LoadFileTemplate
You can also skip the .vimrc
editing and just do:
:LoadFileTemplate skeleton
See the website for more details.
How to write vim function to paste a template text into current file?
You can create a template as follow:
First, create a file (for example base.go
) which will be your template with inside the snippet you typed in your question (I store my templates in $HOME/.vim/templates/<language>/
, so in your case, it would be $HOME/.vim/templates/go/base.go
, but the location is up to you really),
Then, in your .vimrc
, add the following mapping:
nnoremap <space>t :-1read $HOME/.vim/templates/go/base.go<CR>/{<CR>o
This mapping does the following when you press space-t
in normal mode:
- the content of the file
$HOME/.vim/templates/go/base.go
is inserted where your cursor is, - the cursor is moved to the opening
{
, - you are put in insert mode in the brackets.
So when you open a new go file, press space-t
and it will insert your template and place you where you need to be to start coding.
EDIT:-1
indicate the position of where to insert the content of the file(:.read file
inserts it just after the current (.
) line. -1
inserts it just after the current line -1. So effectively, it is to insert it where your cursor is and move down the lines including the one you are on. For more about it, you can read :help range
.
The jump is done with the part /{<CR>o
which looks for a {
(/{
), goes to it (<CR>
) and goes in insert mode just after (o
).
How to auto insert a template code into a new file of particular extension, that is created in a particular directory?
First of all: There are template plugins, you should search the net for "vim template plugin". Perhaps you find something useful.
If you want to do it yourself:
Create your template file like this (I assume ~/tmpl/tmpl.cpp
as name):
/*
* Author : <<name>>
* Date : <<date>>
*/
and in your vimrc:
function AddTemplate(tmpl_file)
exe "0read " . a:tmpl_file
let substDict = {}
let substDict["name"] = $USER
let substDict["date"] = strftime("%Y %b %d %X")
exe '%s/<<\([^>]*\)>>/\=substDict[submatch(1)]/g'
set nomodified
normal G
endfunction
autocmd BufNewFile *.c,*.cc,*.cpp,*.h call AddTemplate("~/tmpl/tmpl.cpp")
The set nomodified
tells Vim that the file was not modified. That way you can exit the file with :q
as long as you don't add additional text. Usefull if you typed the wrong file name.
If you only want to act on files within a special directory ~/project
, you can add the following at the start of the function AddTemplate
:
let fully_qualified_file = expand('%:p')
if 0 != match(fully_qualified_file, $HOME . '/project/.*')
return
endif
how can I run some commands to select template for new created file in vim?
Let's start with a list of requirements:
- each time we edit a new C file, we want to…
- insert a template…
- selected from a list…
- constructed from the content of a specific directory.
Let's do it, from the bottom up.
Directory layout
~/.vim/templates/skeleton.<extension>
allows us to have several "skeletons" for a given extension. I tend to prefer doing things based on filetype instead but the extension makes more sense in this case so we will keep your layout.
List the files in a given directory
Whenever we need a built-in function, our first stop should be either :help function-list
, which groups every built-in function by topic, or directly :help <topic>-functions
if we are familiar with that grouping. In this case, we find the following line under :help file-function
:
readdir() get a List of file names in a directory
Indeed, :help readdir()
is just what we need but, unfortunately (and undocumentedly), it doesn't expand environment variables or tildes on its own so we we have to :help expand()
our directory path.
We can do:
:let templates = readdir(expand('~/.vim/templates/'))
:echo templates
to get something like:
['foo.c', 'bar.c', 'baz.h']
or we can only return the files with a .c
extension:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.c$'})
:echo templates
['foo.c', 'bar.c']
or we can use the extension of the file associated with the current buffer:
:let templates readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo templates
['foo.c', 'bar.c']
Done.
Select from the list
Again we turn to Vim for a clue. Under :help interactive-functions
we find the following promising function:
inputlist() let the user pick an entry from a list
First, let's get acquainted with :help inputlist()
.
:echo inputlist(['Choose:', '1. foo', '2. bar', '3. baz'])
which looks like:
Choose:
1. foo
2. bar
3. baz
Type number and <Enter> or click with the mouse (q or empty cancels):
and prints the chosen number.
Let's make it more useful by using the file listing command from before:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:echo inputlist(['Choose a template:'] + templates)
which looks like:
Choose a template:
bar.c
foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
and still prints the chosen number but we don't have a number before each entry. This can be solved with :help mapnew()
:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:echo inputlist(['Choose a template:'] + templates_for_display)
which looks like:
Choose a template:
1. bar.c
2. foo.c
Type number and <Enter> or click with the mouse (q or empty cancels):
and still prints the chosen number. What is left at this stage is to print the actual item in templates
. Since lists are zero-based and we had to offset by one to get an intuitive display, we only need to subtract 1 to the number returned by inputlist()
:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:echo templates[choice - 1]
which correctly prints bar.c
or foo.c
.
We are making huge progress!
Insert the template
:help :read
is a crude way to insert text from an external source. Here, we will prefer a slightly cleaner way using :help setline()
and :help readfile()
.
But first, let's build a full path from the selected template name:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:echo chosen_template
which should print something like:
~/.vim/templates/foo.c
We can now read the file:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:echo template_content
and, finally, insert it in the buffer:
:let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
:let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
:let choice = inputlist(['Choose a template:'] + templates_for_display)
:let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
:let template_content = readfile(chosen_template)
:call setline(1, template_content)
Let's put it all together in a function in our vimrc
:
function SelectTemplate()
let templates = readdir(expand('~/.vim/templates/'), {name -> name =~ '.' . expand('%:e') . '$'})
let templates_for_display = templates->mapnew({idx, val -> 1 + idx . '. ' . val})
let choice = inputlist(['Choose a template:'] + templates_for_display)
let chosen_template = expand('~/.vim/templates/' . templates[choice - 1])
let template_content = readfile(chosen_template)
call setline(1, template_content)
endfunction
and test it from a c
file:
:call SelectTemplate()
Great! We are almost done!
Automatisation
For the last step, we can simply use your snippet with a couple of minor changes:
if has("autocmd")
augroup templates
autocmd!
autocmd BufNewFile *.c call SelectTemplate()
augroup END
endif
Phew! What a ride!
What, now?
- The function could be refined a little by removing duplication and adding checks here and there.
- Which should make it possible to use
*
in the autocommand so that it works on any file extension.
Writing a vim function to insert a block of static text
I do that by keeping under my vim folder a set of files which then I insert using the r
command (which inserts the contents of a file, at the current location if no line number is passed) from some function:
function! Class()
" ~/vim/cpp/new-class.txt is the path to the template file
r~/vim/cpp/new-class.txt
endfunction
This is very practical - in my opinion - when you want to insert multi-line text. Then you can, for example, map a keyboard shortcut to call your function:
nmap ^N :call Class()<CR>
generate template in vim
yes, you can.
1) create a file, with that content, say, foo.html
2) create a mapping E.g nnoremap <F9> :r /path/to/foo.html<cr>
3) when you want to get that template, press <F9>
in normal mode. The content of your foo.html will be inserted into your current buffer.
Vim templates, get filename and use it
I believe that this might help? http://vim.wikia.com/wiki/Insert_current_filename
With this you can get the current filename:
expand("%:t:r")
Specifically, you are probably looking for this:
%s/TODO/\=expand("%:t:r")/g
A full example:
function! NewFile()
silent! 0r $HOME/vimfiles/templates/%:e.vim_template
s/FILENAME/\=expand("%:t:r")
endfunction
autocmd BufNewFile * call NewFile()
You could also give something like tSkeleton a try, I've never tried myself but it seems to solve this problem for you.
Related Topics
How to Do a Data.Table Merge Operation
Extracting Coefficient Variable Names from Glmnet into a Data.Frame
Row/Column Counter in 'Apply' Functions
Subtract a Constant Vector from Each Row in a Matrix in R
How to Make a Dummy Variable in R
Data.Table in R - Multiple Filters Using Multiple Keys - Binary Search
How to Fill a Geom_Area() Plot Using Ggplot
R Shiny Conditionalpanel Output Value
Plotting Data from an Svm Fit - Hyperplane
How to Draw Gridlines Using Abline() That Are Behind the Data
Group by in R, Ddply with Weighted.Mean
Fastest Way to Read in 100,000 .Dat.Gz Files