53

I'd like to be able to do something like this in vim (you can assume v7+ if it helps).

Type in a command like this (or something close)

:inshtml

and have vim dump the following into the current file at the current cursor location

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body>
    </body>
</html>

Can I write a vim function do this is? Is there a better way?

Mark Biek
  • 146,731
  • 54
  • 156
  • 201
  • Look at the UltiSnips plugin: https://github.com/SirVer/ultisnips. – lwassink Aug 01 '16 at 01:55
  • If you'd like a certain template or format every time you open a new file of a type, check out [`skeleton` or `template`](http://vimhelp.appspot.com/autocmd.txt.html#skeleton) in vim's `:help` – JKirchartz Oct 16 '17 at 19:32
  • I supose only need to add when make a new file. Then you can add this line to a vimrc file `autocmd BufNewFile *.html 0r ~/.config/vim/templates/skeleton.html ` BufNewFile execute when make a new file. *.html when file is *.html 0r insert in the begin the content of file template.html – Wallebot Oct 18 '19 at 22:52
  • You can add a abreviation with :ab or in then vimrc Examples. `:ab title ` or inserting from template. `ab pyclass:r ~/.config/vim/templates/class.py` when you write pyclass(return) insert file class.py. exit from write mode :r insert the content of file class.py I have this line in my vimrc ` autocmd BufNewFile,BufRead *.py ab pyclass:r ~/.config/vim/templates/class.py` – Wallebot Oct 18 '19 at 23:03

10 Answers10

44

Late to the party, just for future reference, but another way of doing it is to create a command, e.g.

:command Inshtml :normal i your text here^V<ESC>

The you can call it as

:Inshtml

Explanation: the command runs in command mode, and you switch to normal mode with :normal, then to insert mode with 'i', what follows the 'i' is your text and you finish with escape, which is entered as character by entering ^V

It is also possible to add arguments, e.g.

:command -nargs=1 Inshtml :normal i You entered <args>^V<ESC>

where <args> (entered literally as is) will be replaced with the actual arguments, and you call it with

:Inshtml blah
Dan Andreatta
  • 3,611
  • 1
  • 22
  • 15
41

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>
Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
  • 1
    Can you think of a good cross-platform way to handle looking for the template files? I like this idea but I'd love to us it on Windows, Linux, & OSX – Mark Biek Mar 27 '09 at 17:17
  • 1
    OK, this is my favorite of all of them. iab is nice but it's hard to set up for complicated file templates. A cross-platform way to handle paths would still be nice though. – Mark Biek Mar 27 '09 at 18:27
  • 1
    For newbies like me: note that the file path is NOT a string; to use Class function arguments in the file path, [do like this](http://stackoverflow.com/questions/1103715/how-do-i-actually-use-the-value-of-an-argument-to-a-vim-function?lq=1) and use `exe 'r' . filepath`, where filepath is a string you can build however you want – aidan Nov 29 '14 at 01:02
  • @MarkBiek I'm pretty sure this *is* cross-platform. I use Vim on Windows, and it interprets `~` and `/` correctly. Using `~` instead of `/home/me` or `C:\User\me` is actually this function's saving grace, because Vim can figure it out. – jpaugh Jul 14 '16 at 03:31
  • The class doesn't seem to have a name. No? – mr.zog Jul 12 '17 at 20:57
16

i have created a new file generate_html.vim in ~/.vim/plugins/ with the following code

"
" <This plugin generates html tags to new html files>
"

autocmd BufNewFile  *.html  call    Generate_html()

function! Generate_html()
    call append(0, "<!DOCTYPE HTML>")
    call append(1, "<html><head>")
    call append(2, "    <title></title>")
    call append(3, '    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
    call append(4, '    <style type="text/css">')
    call append(5, '    </style>')
    call append(6, '</head>')
    call append(7, '<body>')
    call append(8, '</body>')
    call append(9, '</html>')
endfunction

this way, everytime I open a new .html file in vim, it prints that text to the new file

uromay
  • 329
  • 3
  • 11
  • 3
    This seems the only answer on how to do this as part of a Vim plugin. I realize all the other answers address the original problem but this is the only one that uses Vim Script and is the correct answer for anyone making a Vim Plugin. – Sukima Mar 29 '16 at 05:17
  • 1
    Instead of using exact line number in `append` call you do `append("$", "some text")` to add line to the end of a buffer. It will allow to modify pre-defined text much easier. – Alex Apr 29 '16 at 16:54
8

Can you define an abbreviation. e.g.

:ab insh 'your html here'

as nothing in the above appears to be parameterised ?

In fact, looking at my VIM configs, I detect a new .html file being loaded thus:

autocmd BufNewFile *.html call GenerateHeader()

and define a function GenerateHeader() to insert my required template (I do the same for Java/Perl etc.).

It's worth getting the Vim Cookbook for this sort of stuff. It's a sound investment.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
8

snippetsEmu

I like to use the snippetsEmu vim plugin to insert code snippets like your.

The advantage of snippetsEmu is that you can specify place holders and jump directly to them in order to insert a value. In your case you could for example add a place holder between the title tags so you can easily add a title to the document when inserting this snippet.

snippetsEmu comes with various snippets (also for HTML) and new snippets can be esaily added.


EDIT

snipMate

Today I revisited my VIM confiugration + installed plugins and found the snipMate plugin, which is IMHO even better than snippetsEmu. snipMate updates just like TextMate all placeholders on the fly.

f3lix
  • 29,500
  • 10
  • 66
  • 86
  • I liked the sound of this plugin but I could never actually get it to work. – Mark Biek Mar 27 '09 at 17:09
  • It looks like your link to snipMate is out of date? Or a typo? This looks like the right one: http://www.vim.org/scripts/script.php?script_id=2540 – jpaugh Jul 14 '16 at 03:35
4

This should be possible. I use auto-replacement. In my .vimrc I have this line:

iab _perls #!/usr/bin/perl<CR><BS><CR>use strict;<CR>use warnings;<CR>

And whenever I start a Perl script, I just type _perls and hit Enter.

innaM
  • 47,505
  • 4
  • 67
  • 87
4

You can use Python (or any other program) if like me you haven't quite grasped vimScript

This guy talks about the vim expression register. Essentially you put something like this in your .vimrc file

:imap <C-j> <C-r>=system('/home/BennyHill/htmlScript.py')<CR>

So that every time in insert mode you press Ctrlj it calls the script htmlScript.py which has something like this in it (NOTE I haven't actually tested this)

#!/usr/bin/env python
import sys

snippet="""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body>
    </body>
</html>"""

sys.stdout.write(snippet)

Then just remember to make the file executable (chmod 0755 /home/BennyHill/htmlScript.py). It might be overkill, but I am far more comfortable with Python than I am with vim's syntax.

puk
  • 16,318
  • 29
  • 119
  • 199
  • That's an interesting idea. I'll have to give that a look. – Mark Biek Feb 24 '12 at 13:37
  • @MarkBiek It's much easier to use already established scripting languages, and it would be really simple to use mnemonic maps like `html` or `Cif`, `Pyif`... – puk Feb 24 '12 at 22:58
  • this works just fine but you forgot to chmod 755 /home/BennyHill/htmlScript.py and the first line should read #!/usr/bin/env python – silviud Mar 13 '12 at 00:40
  • @puk How to automate this process so that when I open a new python file it add these text? – alhelal Feb 24 '18 at 09:53
  • @alhelal you should used `autocmd`. I am not very good at vim but this answer should point you in the direction https://vi.stackexchange.com/a/11294 – puk Feb 24 '18 at 19:56
1

You can once copy this text to some ( for example 'a' ) register. And paste it every time you need unless you overwrite register 'a'.

To copy to register a in visual mode: "ay
To paste from register a in normal mode: "ap
To paste from register a in insert mode: a

Or if you have this template already copied you can use

let @a = @*

To put this template to register a.

Mykola Golubyev
  • 57,943
  • 15
  • 89
  • 102
1

There are many template expander plugins for vim.

NB: I'm maintaining the fork of muTemplate. Just dump your code into {rtp}/template/html.template or into $VIMTEMPLATES/html.template. And that's all. If you don't want the snippet to be implicitly loaded when opening a new HTML file, then name the template-file html/whatever.template (instead of html.template), and load it with :MuTemplate html/whatever of with whatever^r<tab> in INSERT mode (in an HTML buffer).

All the path issues, portability issues, etc are already taken care of. And unlike snippetEmu that supports (and somehow expects) several (hard to maintain, IMO) snippets in a same snippets definition file, Mu-template requires one template-file per snippet.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83
0

Put your text in a file (e.g.,html). Then put the following in your .vimrc.
command Inshtml r html

I use Inshtml instead of inshtml because vim doesn't support user defined command starting with small letter.

Then if can type Inshtml in command mode (i.e., :Inshtml).

alhelal
  • 916
  • 11
  • 27