|
|
|||||||||||||
All the settings below are included in the sample .vimrc configuration file.
nnoremap \hc :call InsertCloseTag()<CR> imap <F8> <Space><BS><Esc>\hcaWith the above mapping and the following function, while typing in insert mode, you can simply press <F8> to have any close tag typed tag for you. (If function keys don’t work in your terminal, then use \hc in normal mode instead.)
function! InsertCloseTag()
" inserts the appropriate closing HTML tag; used for the \hc operation defined
" above;
" requires ignorecase to be set, or to type HTML tags in exactly the same case
" that I do;
" doesn't treat <P> as something that needs closing;
" clobbers register z and mark z
"
" by Smylers http://www.stripey.com/vim/
" 2000 May 3
if &filetype == 'html'
" list of tags which shouldn't be closed:
let UnaryTags = ' Area Base Br DD DT HR Img Input LI Link Meta P Param '
" remember current position:
normal mz
" loop backwards looking for tags:
let Found = 0
while Found == 0
" find the previous <, then go forwards one character and grab the first
" character plus the entire word:
execute "normal ?\<LT>\<CR>l"
normal "zyl
let Tag = expand('<cword>')
" if this is a closing tag, skip back to its matching opening tag:
if @z == '/'
execute "normal ?\<LT>" . Tag . "\<CR>"
" if this is a unary tag, then position the cursor for the next
" iteration:
elseif match(UnaryTags, ' ' . Tag . ' ') > 0
normal h
" otherwise this is the tag that needs closing:
else
let Found = 1
endif
endwhile " not yet found match
" create the closing tag and insert it:
let @z = '</' . Tag . '>'
normal `z"zp
else " filetype is not HTML
echohl ErrorMsg
echo 'The InsertCloseTag() function is only intended to be used in HTML ' .
\ 'files.'
sleep
echohl None
endif " check on filetype
endfunction " InsertCloseTag()
<Div Class=light>.
Vim can be made to repeat tags from elsewhere with these
mappings and the function below:
nnoremap \hp :call RepeatTag(0)<CR> imap <F9> <Space><BS><Esc>\hpa nnoremap \hn :call RepeatTag(1)<CR> imap <F10> <Space><BS><Esc>\hnaWhile typing, simply pressing <F9> will insert at the cursor position a copy of the previously-used HTML tag. Pressing <F9> again will delete the tag just inserted and replace it with the one previous to it. Repeated pressings of <F9> will continue to cycle backwards through all previous HTML tags in the file, and <F9> will cycle forwards (like <Ctrl>+P/<Ctrl>+N do with insert mode completion). (Closing tags will never be copied, since they can be inserted with the function above.) Where function keys don’t work, \hp and \hn can be used in normal mode instead.) In practice I’ve found this to be much more useful than having various key mappings ‘hard-coded’ to produce different HTML tags.
function! RepeatTag(Forward)
" repeats a (non-closing) HTML tag from elsewhere in the document; call
" repeatedly until the correct tag is inserted (like with insert mode <Ctrl>+P
" and <Ctrl>+N completion), with Forward determining whether to copy forwards
" or backwards through the file; used for the \hp and \hn operations defined
" above;
" requires preservation of marks i and j;
" clobbers register z
"
" by Smylers http://www.stripey.com/vim/
" 2000 Apr 30
if &filetype == 'html'
" if the cursor is where this function left it, then continue from there:
if line('.') == line("'i") && col('.') == col("'i")
" delete the tag inserted last time:
if col('.') == strlen(getline('.'))
normal dF<x
else
normal dF<x
if col('.') != 1
normal h
endif
endif
" note the cursor position, then jump to where the deleted tag was found:
normal mi`j
" otherwise, just store the cursor position (in mark i):
else
normal mi
endif
if a:Forward
let SearchCmd = '/'
else
let SearchCmd = '?'
endif
" find the next non-closing tag (in the appropriate direction), note where
" it is (in mark j) in case this function gets called again, then yank it
" and paste a copy at the original cursor position, and store the final
" cursor position (in mark i) for use next time round:
execute "normal " . SearchCmd . "<[^/>].\\{-}>\<CR>mj\"zyf>`i\"zpmi"
else " filetype is not HTML
echohl ErrorMsg
echo 'The RepeatTag() function is only intended to be used in HTML files.'
sleep
echohl None
endif
endfunction " RepeatTag()
\ isn’t needed very
often, the key to produce it is overloaded. First pressing it twice
(\\) is mapped to inserting a single \, so that
it is still there if needed. Then backslash followed by other keys can
be made to do other things.
So \& can then be used to insert &,
the character code for the “&” symbol. Any non-Ascii
characters you often type can be mapped. This table shows the ones I
have set up:
| Keys | Insert | For | Comment |
|---|---|---|---|
| \& | & |
& | ampersand |
| \< | < |
< | less-than sign |
| \> | > |
> | greater-than sign |
| \. | · |
· | middle dot (decimal point) |
| \— | — |
— | em-dash |
| \2 | “ |
“ | open curved double quote |
| \" | ” |
” | close curved double quote |
| ` | ‘ |
‘ | open curved single quote |
| ' | ’ |
’ | close curved single quote (apostrophe) |
| \` | ` |
` | OS-dependent open single quote |
| \' | ' |
' | OS-dependent close or vertical single quote |
| \<Space> | |
non-breaking space |
I also have <Ctrl>+<Space> set up to produce
, though this doesn’t work in most terminals.
Underscores are rarely required as words in their own right (rather than as
separators in e-mail addresses, etc), whereas em-dashes are nearly always
surrounded by spaces. Therefore I have an abbreviation which converts
isolated underscores into em-dashes; effectively this makes _
(<Shift>+-) the key for em-dashes. Here’s the
commands to set up all of this:
autocmd BufEnter * if &filetype == "html" | call MapHTMLKeys() | endif
function! MapHTMLKeys(...)
" sets up various insert mode key mappings suitable for typing HTML, and
" automatically removes them when switching to a non-HTML buffer
" if no parameter, or a non-zero parameter, set up the mappings:
if a:0 == 0 || a:1 != 0
" require two backslashes to get one:
inoremap \\ \
" then use backslash followed by various symbols insert HTML characters:
inoremap \& &
inoremap \< <
inoremap \> >
inoremap \. ·
" em dash -- have \- always insert an em dash, and also have _ do it if
" ever typed as a word on its own, but not in the middle of other words:
inoremap \- —
iabbrev _ —
" hard space with <Ctrl>+Space, and \<Space> for when that doesn't work:
inoremap \<Space>
imap <C-Space> \<Space>
" have the normal open and close single quote keys producing the character
" codes that will produce nice curved quotes (and apostophes) on both Unix
" and Windows:
inoremap ` ‘
inoremap ' ’
" then provide the original functionality with preceding backslashes:
inoremap \` `
inoremap \' '
" curved double open and closed quotes (2 and " are the same key for me):
inoremap \2 “
inoremap \" ”
" when switching to a non-HTML buffer, automatically undo these mappings:
autocmd! BufLeave * call MapHTMLKeys(0)
" parameter of zero, so want to unmap everything:
else
iunmap \\
iunmap \&
iunmap \<
iunmap \>
iunmap \-
iunabbrev _
iunmap \<Space>
iunmap <C-Space>
iunmap `
iunmap '
iunmap \`
iunmap \'
iunmap \2
iunmap \"
" once done, get rid of the autocmd that called this:
autocmd! BufLeave *
endif " test for mapping/unmapping
endfunction " MapHTMLKeys()
autocmd FileType html set formatoptions+=tl(and assuming these general paragraph formatting settings) line breaks are normally inserted as text is typed, but if this is ever ‘corrected’ manually to produce a longer line, Vim will leave it alone.
autocmd FileType css set smartindentAlso, a few bytes can be saved by indenting with genuine tab characters, rather than spaces:
autocmd FileType html,css set noexpandtab tabstop=2