Luc Hermitte's VIM General Macros | Monday 22nd November 2004 |
Here are several script files that I've put in $VIM/plugin/
. They can be used with both
versions of VIM.
help.vim <raw file> |
This little file helps to prepare help messages and to map
them to a sequence of keys. I use it to comment my mappings.
Then, I hit <S-F1> for example
and see all the mappings that I have defined in
vimrc_core.vim .
|
|
fileuptodate.vim <raw file> |
Tool for plugins programmers This file defines a little function that helps to determine if a file exists and is more recent than an other file. Needed by my patch for buffoptions.vim and for Triggers.vim .
|
|
ensure_path.vim <raw file> |
Tool for plugins programmers Defines the function EnsurePath({path})
that checks if its parameter points to a valid directory. If it
points to a file, an error is raised ; if it points to nothing,
the directory is created.
system_utils.vim .
|
|
fix_d_name.vim <raw file> |
Tool for plugins programmers Defines the function FixDname({path}) that returns a corrected
pathname respecting the value of the 'shellslash' option.
The objective is to propose a portable help to access
files or directories.
It has been tested so far on the following configurations PC/WinMe+command.com, PC/WinME+Cygwin_bash, PC/WinNT+cmd32, PC/WinNT+unixtools_zsh, Sun/Solaris/tcsh.
system_utils.vim .
|
|
words_tools.vim <raw file> |
Tool for plugins programmers This file defines the four alternative functions to use instead of expand("<cword>")
|
|
Triggers.vim <raw file> Archive with required files: triggers.tar.gz |
Plugin that can toggle almost anything This big file helps to toggle definitions -- these definitions corresponding to either mappings, settings or abbreviations. The very simple application is to map (/ unmap) a macro when we hit (/re-hit) the trigger. A much more useful application is to map all the definitions from a function when hitting the trigger and unload them on a second hit and reload on a third, etc.. You can find an application of this with my shortcut file: fr-abbrv.vim present in the tarball archive.For the moment, I have still a little incompatibility problem with buffoptions2.vim Do not forget to customize Trigger_FileName({funcname}) in
regards of your installation.
Requires: system_utils.vim and
fileuptodate.vim .
|
|
misc_map.vim <raw file> |
Tool for plugins programmers This file defines the function MapNoContext({key},
{seq}) . This is required by several
other ftplugins of mine, like vim_set.vim , in
order to define smart mappings. The aim is for example to map
if to if<CR>endif only out of
comment zones and strings. It also define a function that ease
the definition of visual mappings.This plugin is shipped with lh-map-tools.tar.gz.
|
|
let-modeline.vim <raw file> let-modeline.vim <raw file> |
Extended Modelines. This file defines the function FirstModeLine() .
It extends VIM's modeline feature (restricted to options
settings) to affectations of variables --
let <variable> = <value>This is only required by my LaTeX ftplugins but could be very useful to any other file edited.
|
|
block-indent.vim <raw file> |
Quick reindentation This plugin redefines some keys in order in re-indent different things.
|
And here are my plugins that will only work with VIM 6.0, they go into
$HOME/vimfiles/plugin/
vim-spell.tar.gz
Vim help file: VS_help.txt |
Spell checker plugin for VIM. It wraps external tools like Ispell or Aspell and offers many interesting features. Requires: system_utils.vim .
|
|
searchInRuntime.vim <raw file> Vim help file: searchInRuntime.txt Archive with help: searchInRuntime.tar.gz |
This plugin defines three commands that search for files in
a list of directories like $PATH or 'runtimepath' , and execute a
command on them.
|
|
system_utils.vim <raw file> Vim help file: system_utils.txt Archive with help: system_utils.tar.gz |
Tool for plugins programmers The objective is to propose a portable set of functions: - to handle files and directories, - and to change the shell used on MsWindows boxes. 99% of this plugin can be seen as an API meant to help us writing portable VimL scripts. The script defines the functions:
|
|
menu-map.vim <raw file> |
Tool for plugins programmers This plugin defines functions to build mappings and menus at the same time ; the key-binding of the mappings being recalled within the menu. My ftplugins expect this file to be into the {rtp}/macros/
directory.
|
|
homeLikeVC++.vim <raw file> |
Smart <Home> key This plugin redefines <Home> to behave like it does
with Ms-VisualC++: Hitting <Home> once moves the cursor
to the first non blank character of the line ; twice: to the
first column of the line.I.e.: the position of the cursor is toggled between the first column and the first non blank character of the line. |
|
local_vimrc.vim <raw file> |
This plugin recursively sources files named
_vimrc_local.vim from $HOME to the current directory.
Note: the name of the files sourced can be overriden thanks to: g:local_vimrc .
|
|
compiler/
cygwin.vim <raw file> Perl filter: cygwin.pl Archive: compiler-cygwin.tar.gz |
Compiler plugin for Cygwin. This compiler-plugin translates the paths from error messages expressed in *nix form into MsWindows form. It is meant to make the cohabition between Cygwin's make and the win32 native version of Vim
painless.Reason: the filenames (for whom GCC reports errors) are expressed in the UNIX form, and Vim is unable to open them from the quickfix window. Hence the filtering used to replace / (root) by $(cygpath -m /) ,
/cygdrive/{drive}/ by
{drive}:/ , and to follow symbolic links.
In order to correctly recognize Cygwin, $TERM or $OSTYPE should value "cygwin". The plugin comes in two parts: the main VimL script and an external Perl filter. However, if you do not have Perl installed on your box, you will find within the main script a tricky method you should be able to use: comment the part of the code that configure the tool to use the Perl filter, and comment the calls to :finish .
|
The functions defined in this file serve a very simple purpose: to
associate to an identifier a set of line describing any thing one wants to.
The best example of one application could be found in
vimrc_core.vim
.
At first, an identifier must be reserved with
ClearHelp({id})
. [Internals: the global variable
g:{id}_help
is reset and will be used in the
following steps]
Then, all the help lines can be added thanks to
BuildHelp({id},{line})
.
Finally, all the lines can be echoed with
ShowHelp({id})
. Personally, for vimrc
I
use the mapping:
noremap <S-F1>:call ShowHelp("vimrc")<cr>
This file defines the function:
IfFileUpToDate({f1},{f2})
. Its raison
d'être is to test dependencies between files: it checks whether
{f2} is more recent than {f1} which is useful when
{f2} depends on {f1}.
The function returns:
Proposes a command and a function that make sure a directory exists. If the directory didn't exist before the call, it is created. If the parent directories of the required directory do not exist, they are created in the way.
Tested on:
mkdir
here), be sure to have your
$PATH correctly set.
The function FixDname({path})
will correct the
{path}
passed in parameter so that
it will be usable will external tools. Under Win32 boxes, it will build the
new path according to the value of 'shellslash'
, under other boxes, the new
path will be exclusively composed of forward slashes. NB: I suppose that
'shellslash'
is defined
accordingly to the current shell used (bash, command.com, cmd32, tcsh,
etc.).
For instance, "c:\Program
Files/longpathname/some\ spaces/foo"
will be corrected
into:
"c:\Program
Files\longpathname\some spaces\foo
under win32 systems
when 'shellslash'
equals 1,
or into:
"c:/Program\
Files/longpathname/some\ spaces/foo
otherwise.
Until now, I have use this function in two ways:
exe ":!cp
" .escape(FixDname('very odd/path/file.ext'), '\'). "
destination"
call system( a_command . '
' . FixDname(somepath))
Unfortunately, the new path constructed:
filereadable()
as this function expects a
path expressed with forward slashes only ;
If you try to expand "<cword>"
in order to get the word
just before the cursor, you won't success: you will instead get the word
after the cursor. It is very problematic when we try to define
completion-oriented macros.
So, this file defines the functions: GetPreviousWord()
,
GetCurrentWord()
, GetNearestWord()
,
GetCurrentKeyword()
, GetNearestKeyword()
, and
GetLikeCTRL_W()
to be used instead of expand("<cword>")
. These functions cover
different needs:
GetPreviousWord()
returns the first characters from
the word located before the cursor ; actually, the word is either
truncated at the cursor's position or completed by as many spaces
as needed to reach this position. I call «word» a sequence of
keyword characters: "\k"
, see :h
isk
.function! Parent() let w = GetPreviousWord() if w =~ '^if\s*$' return "\<esc>bcwif () {\<cr>}\<esc>O" eleif w =~ '^for\s*$' return "\<esc>bcwfor (;;) {\<cr>}\<esc>O" else return "" endif endfunction inoremap ( <c-r>=Parent()<cr>But, it is IMHO more interesting to use it to correct frequent misspellings. May be, it could be interesting to skip all the ending spaces in future versions ; this way, it will be very easy to implement an automatic completion behaving like
<tab>
in many
environments like bash or VIM.
GetCurrentWord()
returns the complete word just
before the cursor, without any bonus space. If a white space
precedes the current cursor's position, an empty string is
returned. This time, a word is defined as sequence of
non-white-space characters: "\S"
;
GetCurrentKeyword()
works of keyword characters.
It comes handy to implement automatic completion like the one
of Zsh. Actually, I use this function in
Mail_mutt_alias_set.vim
to expand regular expressions into e-mail addresses.
GetNearestWord()
returns the complete word (sequence
of "\S"
; GetNearestKeyword()
works on
"\k"
) near the cursor's position: i.e.
just after, just before or around the cursor's position.
GetLikeCTRL_W()
returns the string that would have
been deleted by i_CTRL_W
.
In order to have a better idea of what is returned by these functions, here
is a little table that shows the results from the different functions
regarding the position of the cursor.
Let's use ^
, $
and |
as possible
cursor's positions in INSERT-mode, ×
to represent a
white-space ; while WORD1
and WORD2
are two
already typed words. The table is filled with the evaluations of the
functions on this line.
×^W|o|r|d|1$×^W|o|r|d|2$×|×|×|×...
1st^ |
1st| |
2nd| |
3th| |
4th| |
1st$ |
2nd^ |
5th| |
6th| |
7th| |
8th| |
2nd$ |
nth| |
|
expand("<cword>") |
«Word1» | «Word1» | «Word1» | «Word1» | «Word1» | «Word2» | «Word2» | «Word2» | «Word2» | «Word2» | «Word2» | Ø | Ø |
GetPreviousWord() |
Ø | «W» | «Wo» | «Wor» | «Word» | «Word1» | «Word1×» | «W» | «Wo» | «Wor» | «Word» | «Word2» | «Word2×××» |
GetCurrentWord() |
Ø | «Word1» | «Word1» | «Word1» | «Word1» | «Word1» | Ø | «Word2» | «Word2» | «Word2» | «Word2» | «Word2» | Ø |
GetNearestWord() |
«Word1» | «Word1» | «Word1» | «Word1» | «Word1» | «Word1» | «Word2» | «Word2» | «Word2» | «Word2» | «Word2» | «Word2» | Ø |
These functions are just examples of want could be done on this topic. They
just fulfill some specific needs I had. There are several ways to
define/customize such kind of functions regarding if we want the word
preceding or following the cursor, if we want it in its entirety, if a
word is defined by "\k*"
or "\S*"
, and so on.
Here is a big piece of cake. The purpose of Triggers.vim
is
very simple: to ease the association of a key to the activation and
deactivation of a set of macros. Some of you already knows what
inoremap <F7>:set ai!<cr>:set ai?<cr>does: hitting
<F7>
toggles
the activation state of the autoindent
option and echoes it.
Triggers.vim
provides a set of functions that extends such
behavior to mappings, abbreviations and non boolean VIM-options.
Here are some examples of its applications:
call Trigger_Define('<F7>', 'set
ai')
does exactly the
same thing than the previous example.
call Trigger_Define('<F4>', 'set
tw=120 sw^=2')
records the current values of textwidth
and
shiftwidth
, then defines <F4>
as the trigger key that will
turn after turn set textwidth
and
shiftwidth
to their new values then restore them to
the initial ones.
call Trigger_Define('<F4>', 'set
tw+=80')
works
slightly differently: it does not record the initial value but
apply set tw-=80
as
the inverse operation. Thus, :set tw=100<cr><F4><F4>:echo &tw<cr>
will always echo 100.
call Trigger_Define('<F9>', 'inoremap
{ {}<Left>')
is very useful to me:
when I want to insert a block, I make sure that the open
curly-bracket also insert its counterpart ; and when I only want the
open curly-bracket, I deactivate the mapping thanks to <F9>
and re-activate it
afterward.
call Trigger_Define('<F3>', 'iab
LU Last Update:')
is
also supported and could be useful when doing Linear Algebra... Ok!
Ok! This is not a very good example, but I'm sure you see what I
mean.
source myAbbrevAndMap.vim
call Trigger_Function('<F3>', 'MyAbbrevs', 'myAbbrevAndMap.vim')
is may be the more
useful application of the plugin. Let's say you have a file
named myAbbrevAndMap.vim
which defines the
parameter-less function MyAbbrevs()
.
Trigger_Function(...)
is designed to activate and
deactivate every mapping, abbreviation and option setting
contained in the specified function. Actually, it defines the
inverse function (that will be written in the folder
$VIMRUNTIME/.triggers
; so
make sure it exists !) and hitting the trigger key will call turn
after turn either MyAbbrevs()
or its inverse.
Incidentally, all other VIM code is ignore and copied as it is in
the inverse operation. Take a look at
common_brackets.vim
exe 'noremap foo1
foo2'
. And thus, the mappings (from
misc_map.vim
) on
<
and >
are not necessarily
deactivable when defined with b:cb_ltFn
and
b:cb_gtFn
.
TRIGGER "echo 'foo ON'", "echo 'foo OFF'"
: this new command is
designed to be used within functions to be inversed with
Trigger_Function(...)
. Its opposite is itself, but
with the order of its two parameters inversed. Quite useful
for echoing. Beware, the double quotes must be around the single
ones in the case of echo
.
call
Trigger_DoSwitch('<M-F9>', 'let b:usemarks=1', 'let b:usemarks=0')
: can be useful for
mappings that have nothing to do with options-settings, mappings or
abbreviations.
If you are interested in more precise information like syntax variations, report to the comments within the plugin.
This plugin defines several functions and commands to be used when you want to program mappings and abbreviations:
"inoremap if<space> <C-R>=MapNoContext( 'if ', Inoreabbr if <C-R>=MapNoContext( 'if ', \ '\<c-f\>if () {\<cr\>}\<esc\>?)\<cr\>i')<CR>If you are interested in other applications, take a look at my ftplugins.
Regarding the difference between the two functions, if you are up to
use variables like tarif
, you actually need to use the
second form of the function. Indeed, if the character before the cursor
is a keyword character, the key is returned instead of the
interpreted {sequence} ; cf.
:h 'iskeyword'
for more
information about keyword characters.
Reserve the first form of the function to "keyword-less" keys like
{
for instance.
Regarding the format of the {sequence} to
interpret, every special character must see its greater-than
and lesser-than symbols escaped with backslash. Thus
<esc>
becomes for
instance \<esc\>
.
{begin}
is added before the
selection while {end}
is added
just after. The function accepts two options that indicates whether the
mapping should be line wise and whether the selected text should be
indented.
At this time, it is only used in tex_set.vim
in order to define things like:
vnoremap ]ec :call MapAroundVisualLines('\begin{center}', \ '\end{center}',1,1)<cr>It also fits perfectly to define the C&co. dedicated visual mapping:
vnoremap ,else :call MapAroundVisualLines('else {', '}',1,1)<cr>
Rem.: there still are problems with the indenting and more precisely
when a text is smartindented under VIM 5.xx ; it seems to work fine
with VIM 6.0.
BTW, never use stuff that could be expanded as an abbreviation within
{begin}
or {end}
. Unless you like oddities.
¡.*!
and build a string that can be used as second
parameter by the MapNoContext()
functions. The expanded
mappings are considered to be dedicated to the INSERT mode. bracketing.base.vim
) within context-dependant macros.
For the moment, it is only used from c_set.vim. For instance, I mapped the C structure, for
, to:
"inoremap for<space> <C-R>=Def_Map( Inoreabbr for <C-R>=Def_Map( \ 'for', \ '\<c-f\>for (;;) {\<cr\>}\<esc\>?(\<cr\>a', \ '\<c-f\>for (;¡mark!;¡mark!) {\<cr\>¡mark!\<cr\>}¡mark!\<esc\>?(\<CR\>a')<cr> function! Def_Map(key,expr1,expr2) if exists('b:usemarks') && b:usemarks return "\<c-r>=MapNoContext2('".a:key."',BuildMapSeq(\"".a:expr2."\"))\<cr>" else return "\<c-r>=MapNoContext2('".a:key."', \"".a:expr1."\")\<cr>" endif endfunctionAnd so, within normal context, when
b:usemarks
is set,
for
is expanded to: for (;«»;«») { «» }«»and the cursor placed just after the opening parenthesis.
If you have always dreamed of abbreviations that do not insert the <space>
you typed to make it (the
abbrev.) expand, this function is for you !
Let's suppose you want to map "if<space>
" to "if ()<left>
". Doing this is quite easy thanks to
imap
. But it does not
display the characters as you type them, unless you use
iabbr
. Unfortunately, this
time when you type "if<space>
", a space will be added between
the parenthesis.
The function proposed here, and the two commands Iabbr
and
Inoreabbr
address this problem. Define your abbreviations
thanks to these commands, and spaces won't show up.
N.B.: I am not the original author of this tip. You have to thank Bram Moolenar, Benji Fisher and some other people on the VIM mailing list for this. The version I propose in my file does not support multi-byte characters for the moment.
This file defines the function: FirstModeLine()
that extends
the VIM modeline feature to variables. In VIM, it is possible to set
options in the first and last lines. -- cf. :h
modeline
. The function proposed extends it to variables
affectations.
let {variable} = {value}The VIM-options
'modeline'
and 'modelines'
are taken
into account to determine which lines must be parsed, if any.
g:TeXfile
. Hence
it knows that latex should be called on this main file ;
aux2tags.vim
could also be told to compute the associated .aux file.
g:TeXfile
each time is really boring. It bored me so much that I programmed a first
version of this plugin. In every file of one of my projects I added the
line: % VIM: let g:TeXfile=main.tex[
main.tex
is the name of the main file of the project]
Thus, I can very simply call LaTeX from within VIM without having to
wonder which file is the main one nor having to specify
g:TeXfile
each time.
Actually, in order to affect g:TeXfile,
I have to call another
function. Hence, I define a callback function (in my (La)TeX ftplugin)
that checks whether I want to set g:TeXfile
. In that case, the
callback function calls the right function and return true. Otherwise, it
returns false. The name of the callback function should be specified in
ftplugins with the buffer relative variable:
b:ModeLine_CallBack
. Here is as an example this callback
function:
let b:ModeLine_CallBack = "TeXModeLine_CallBack" function! TeXModeLine_CallBack(var,val) if match(a:var, "g:TeXfile") != -1 " No quotes around the file name ! call TKSetTeXfileName( 2, a:val ) return 1 else return 0 endif endfunction
{line} | ::= | [text]{white}VIM:[white]let{affectations} |
{affectations} | ::= | {sgl_affect.} |
{affectations} | ::= | {sgl_affect.}{white}{affectations} |
{sgl_affect.} | ::= | {variable}[white]=[white]{value} |
{variable} | ::= | cf. vim variables format ; beware simple variables (other than global-, buffer-, window-, or environment- (v1.6) -variables) are not exported. |
{value} | ::= | string or numeral value: no function call allowed. |
'[', ']'
) is optional, and something
in curly-brackets ('{', '}'
) is required. Others are required
text constants.
let g:foo="abc".DEF()
' are
recognized and forbidden. So, do not accept (as the maintainer of your
installation) a callback function that parses its parameters and calls a
function named after them.
I define four mappings:
<C-F>
and
<tab>
in VISUAL mode
re-indent the current selection ;
<tab>
in NORMAL mode
re-indents the current line ;
<C-tab>
in NORMAL
mode re-indents the current paragraph.
:SearchInRuntime
), by this plugin,
extends what the :runtime
command does with :source
:
i.e. searching for files within the directories specified by the
'runtimepath'
option, and
then sourcing them.
:SearchInRuntime
also searches for files within 'runtimepath'
, but enables to call any
command after that. If no file is found, nothing is done. And as with
:runtime
, the bang
(!
) parameter will ask for an extensive search that will not
stop after the first file found.
Typical use of the :SearchInRuntime
pass only one
argument to {command}
: the
path to the file found. To provide other arguments to {command}
, we must add them after the
list of {file_pattern}
and a separation pipe ('|
'). Note: spaces are expected
before and after the pipe.
For instance:
:command -nargs=+ Echo
echo "<args>"
:SearchInRuntime! Echo *.vim ftplugin/*_set.vim
'runtimepath'
.
:SearchInRuntime! Echo *.vim ftplugin/*_set.vim | found!
will echo the same files followed by the string "found!", on the same
line.
:command -nargs=+ ExeThis
exe "!<args> ".bufname('%')
:SearchInRuntime! ExeThis tools/vimlatex
vimlatex
is, and execute
it with bufname('%')
as a parameter.
:SearchInRuntime! source ftplugin/c.vim ftplugin/c_*.vim
ftplugin/c/*.vim
:runtime!
with the same pattern.
:Runtime
, defined in
runtime.vim
, in order to propose
an implementation of :runtime
to VIM 5.x, is a simplified
version of :SearchInRuntime
.
:SearchInRuntime sp plugin/searchInRuntime.vim
searchInRuntime.vim
. [the full path can be very long and
not always the same]
:exe ":SearchInRuntime 0r
template/template.".&ft
template/template.<filetype>
that should be
somewhere in the 'runtimepath'
.
:SearchInVAR
will search within a list of directories
specified by a variable: buffer, global, script or environment variable
like $PATH.
:SearchInPATH
is equivalent to :SearchInVAR
$PATH
and :SearchInRuntime
is equivalent to :SearchInVAR &runtimepath
.
<SID>
and s:
stuff.
'verbose'
option is
supported: :runtime
,
the search accepts absolute paths ; for instance: :runtime! /usr/local/share/vim/foo*.vim
macros/foo*.vim
:SearchInRuntime! source /usr/local/share/vim/foo*.vim
macros/foo*.vim
:SearchInVAR
used to be :SearchInENV
.
The purpose of this plugin is to propose different functions that will ease the definition of menus and mappings.
The usual way for this is to call :*menu
AND :*map
for every mode (INSERT, VISUAL, NORMAL,
COMMAND) you wish the mapping to be defined. Thus, the (ft)plugins you write
becomes very long are more difficult to maintain.
Here comes menu-map.vim
. It is a generic extension over an
idea I've found in Benji Fisher's TeX ftplugin.
It can build a menu plus the mappings for different modes at once and
recall the key-binding of the mapping within the menu.
This plugin doesn't require anything, while it is required by several ftplugins of mine.
Two functions are defined.
First example: the following call will add the menu "LaTeX.Run LaTeX
once <C-L><C-O>", with the
priority (placement) 50.305, for the INSERT, NORMAL and COMMAND modes. The
action associated first saves all the changed buffers and then invokes
LaTeX.
The same action is also binded to <C-L><C-O>
for the same modes, with
the nuance that the maps will be local to the buffer ; I haven't tried yet
to integrate Michael Geddes's Buffer-menus plugin.
call MenuMake("nic", '50.305', '&LaTeX.Run LaTeX &once', "<C-L><C-O>", \ '<buffer>', ":wa<CR>:call TKMakeDVIfile(1)<CR>")
The second example demonstrates an hidden, but useful, behavior:
if the mode is the visual one, then the register v
is filled with the text of the visual area.
This text can then be used in the function called. Here, it will be
proposed as a default name for the section to insert:
function! TKinsertSec() " ... if (strlen(@v) != 0) && (visualmode() == 'v') let SecName = input("name of ".SecType.": ", @v) else let SecName = input("name of ".SecType.": ") endif " ... endfunction call MenuMake("nic", '50.360.100', '&LaTeX.&Insert.&Section', "<C-L><C-S>", \ '<buffer>', ":call TKinsertSec()<CR>")We have to be cautious to one little thing: there is a side effect: the visual mode vanishes when we enter the function. If you don't want this to happen, use the non-existant command:
:VCall
...
Third: if it is known that a function will be called only
under VISUAL-mode, and that we don't want of the previous behavior, we can
explicitly invoke the function with :VCall
-- command that
doesn't have to exist. Check s:MapMenu4Env
for such an
example.
Fourth thing: actually, MenuMake()
is not restricted
to commands. The action can be anything that could come at the right hand
side of any :map
or
:menu
action. But this time,
you have to be cautious with the modes you dedicate your map to. I won't
give any related example ; this is the underlying approach in
IVN_MenuMake()
.
IVN_MenuMake()
accepts three different actions for the three
modes: INSERT, VISUAL and NORMAL. The mappings defined will be relative to
the current buffer -- this function is addressed to ftplugins writers.
The last arguments specify the inner mappings and abbreviations embedded
within the actions should be expanded or not ; i.e. are we
defining «noremaps/menus» ?
You could find very simple examples of what could be done at the end of
menu-map.vim
. Instead, I'll show here an extract of my TeX
ftplugin: it defines complex functions that will help to define very
simply the different mappings I use. You could find another variation on
this theme in html_set.vim.
:MapMenu 50.370.300 &LaTeX.&Fonts.&Emphasize ]em emph call <SID>MapMenu4Env("50.370.200", '&LaTeX.&Environments.&itemize', \ ']ei', 'itemize', '\item ')
The first command binds ]em
to \emph{}
for the
three different modes. In INSERT mode, the cursor is positioned between the
curly brackets, and a marker is added after the closing bracket --
cf. my bracketing system.
In VISUAL mode, the curly brackets are added around the visual area. In
NORMAL mode, the area is considered to be the current word.
The second call binds for the three modes: ]ei
to:
\begin{itemize} \item \end{itemize}
The definition of the different functions and commands involved just follows.
command -nargs=1 -buffer MapMenu :call <SID>MapMenu(<f-args>) function! s:MapMenu(code,text,binding, tex_cmd, ...) let _2visual = (a:0 > 0) ? a:1 : "viw" " If the tex_cmd starts with an alphabetic character, then suppose the " command must begin with a '\'. let texc = ((a:tex_cmd[0] =~ '\a') ? '\' : "") . a:tex_cmd call IVN_MenuMake(a:code, a:text.' -- ' . texc .'{}', a:binding, \ texc.'{', \ '<ESC>`>a}<ESC>`<i' . texc . '{<ESC>%l', \ ( (_2visual=='0') ? "" : _2visual.a:binding), \ 0, 1, 0) endfunction " a function and its map to close a "}", and that works whatever the " activation states of the brackets and marking features are. function! s:Close() if strlen(maparg('{')) == 0 | exe "normal a} \<esc>" elseif exists("b:usemarks") && (b:usemarks==1) | exe "normal ¡jump! " else | exe "normal a " endif endfunction imap <buffer> ¡close! <c-o>:call <SID>Close()<cr> function! s:MapMenu4Env(code,text,binding, tex_env, middle, ...) let _2visual = (a:0 > 0) ? a:1 : "vip" let b = "'" . '\begin{' . a:tex_env . '}' . "'" let e = "'" . '\end{' . a:tex_env . '}' . "'" call IVN_MenuMake(a:code, a:text, a:binding, \ '\begin{'.a:tex_env.'¡close!<CR>'.a:middle.' <CR>\end{'.a:tex_env.'}<C-F><esc>ks', \ ':VCall MapAroundVisualLines('.b. ',' .e.',1,1)', \ _2visual.a:binding, \ 0, 1, 0) endfunction endif
Back to the VIM Page | hermitte at free.fr |