lh-brackets (ex- map-tool) provides various commands and functions to help design smart and advanced mappings dedicated to text insertion.
It is made of three sub-systems:
- the core bracketing-system,
- a placeholder subsystem,
- various Vim functions to support ftplugin definitions.
This subsystem provides a command that helps define INSERT-, NORMAL-, and VISUAL-mode mappings to insert any pairs of brackets-like characters.
- The INSERT-mode mappings will
- insert the pair of brackets-like characters when the opening one is triggered, add a placeholder after the closing character, and move the cursor between the two bracket characters;
- insert the closing character when pressed, or move after it if it is the next character after the cursor ;
- delete the current pair of empty brackets when
<BS>
is hit from within the brackets (following placeholders will also be deleted) (this can be disabled by setting[gb]:cb_delete_empty_brackets
to 0) - insert an extra newline when
<CR>
is hit within an empty pair of curly-brackets {} (this can be disabled by setting[gb]:cb_newline_within_empty_brackets
to 0)
- The VISUAL-mode mapping will surround the current selection with the pair of bracket-like characters ;
- The NORMAL-mode mapping will select the current word (or the current line depending on the use of the newline (
-nl
) option), and then surround this selection with the pair of bracket-like characters.
It is possible to:
- tune what is exactly inserted in INSERT-mode (thanks to the
-open
and-close
options), - not insert the placeholder (depending on
b:usemark
value), - specify which keys sequence actually triggers the mappings defined (thanks to the
-trigger
option), - define the mappings only in some modes (thanks to the options
-insert
,-visual
, and also-normal
) - make the mappings line-wise (thanks to the
-nl
option), - tune how the NORMAL-mode mapping select a current anything (thanks to the
-normal
option), - toggle the definitions of all the brackets mappings by pressing
<F9>
(:h <Plug>ToggleBrackets
) ; - make the mappings global with
:Brackets!
, or local to a buffer with:Brackets
. ; - neutralize the INSERT-mode mappings:
- for specific filetypes with
-but
option - when the cursor is not under a space, coma, (semi-)colon, a equal sign, a closing pair character or at the end of line by default -- it will be possible to tune this feature in a later version
- for specific filetypes with
- specify exactly which is the canonical pair for deletion when it's not immediate from the context (thanks to the
-pair
option)
Here is an excerpt from the C&C++ brackets definitions, see the documentation for more help.
let b:usemarks = 1
let b:cb_jump_on_close = 1
:Brackets { } -visual=0 -nl
:Brackets { } -visual=0 -trigger=#{
:Brackets { } -visual=1 -insert=0 -nl -trigger=<localleader>{
:Brackets { } -visual=1 -insert=0
:Brackets ( )
:Brackets [ ] -visual=0
:Brackets [ ] -insert=0 -trigger=<localleader>[
:Brackets " " -visual=0 -insert=1 -escapable
:Brackets " " -visual=1 -insert=0 -trigger=""
:Brackets ' ' -visual=0 -insert=1
:Brackets ' ' -visual=1 -insert=0 -trigger=''
:Brackets < > -open=function('lh#cpp#brackets#lt') -visual=0
Note: This feature has been completely rewritten for the version 1.0.0 of map-tools. The old way of tuning the brackets insertion is no longer available.
By default, the mappings are active for most filetypes.
lh-brackets provides mappings (originally from auctex.vim) to replace a pair of bracket-characters by another pair of bracket-characters. See :h brackets_manipulations
for more information.
This subsystem provides functions and mappings to:
- mark places in the code where we could jump to later,
See the help about!mark!
,lh#marker#txt()
, and<Plug>MarkersMark
- jump forward and backward to those places.
See the help about!jump!
, and<Plug>MarkersJumpF
- close all placeholders on the same line that are after closing bracket-like
characters and jump to the last one -- see
<Plug>MarkersCloseAllAndJumpToLast
which is binded by default to<M-End>
(or<C-L>$
in terminal instancef of Vim).
The marker/placeholder characters:
- default to the French quote characters («»),
- can be specified on a filetype basis,
- are converted to match the current encoding,
- can be shared with the ones from imaps.vim (
:h g:use_place_holders
).
Jumping to the next/previous placeholder:
- is binded to
<M-Del>
(GUI) or<C-J>
(terminal) by default (see:h <Plug>MarkersJumpF
), or<M-S-Del>
/<C-L><S-Del>
to jump backward. Can be disabled by settingg:marker_define_jump_mappings
to 0. - can be tuned to delete or select the placeholder the cursor is jumping to (
:h g:marker_prefers_select
,:h g:marker_select_empty_marks
), - can select or ignore the placeholder where the cursor is currently within (if any) (
:h g:marker_select_current
,:h g:marker_select_current_fwd
), - may move the line of the placeholder (we jump to) to the middle of the window (
:h g:marker_center
), - respects
'wrapscan'
, - opens the folder where the placeholder, we jump to, is,
- doesn't break redo (is the case of empty placeholders, when placeholders are deleted instead of selected) ; this feature requires Vim 7.4-849.
As lh-vim-lib, map-tools provides a few functions of its own. All these functions are specialized into the definition of smart abbreviations and INSERT-mode mappings.
Function | Purpose |
---|---|
lh#map#no_context() , lh#map#no_context2() |
Core functions to define mappings that only expand outside of string, comment, and character contexts |
lh#map#4_these_contexts() |
Like lh#map#no_context() , except this time we can specify which text must be returned depending on the current context |
lh#map#insert_around_visual() |
This is the core surrounding function ; the surrounding text is not interpreted |
lh#map#surround() |
Interprets the !.*! mappings that are passed to lh#map#insert_around_visual() (!cursorhere! tells were to put the cursor). This function also recognises when the selected area is actually a marker/placeholder in order to not surround, but expand instead. |
lh#map#build_map_seq() |
Core function that interprets !.*! mappings |
lh#map#eat_char() , :I(nore)abbr |
Permits to define abbreviations that do not insert a whitespace when the <space> key is used to trigger the abbreviation |
lh#map#insert_seq() |
High level function that interprets !.*! mappings, and take the context into account |
-
Requirements: Vim 7.+ (7.4-849 in order to support redo), lh-vim-lib v5.3.0+, lh-style v1.0.0+ for unit testing.
-
With vim-addon-manager, install lh-brackets (this is the preferred method because of the dependencies)
ActivateAddons lh-brackets
-
or with vim-flavor (which also support dependencies)
flavor 'LucHermitte/lh-brackets'
-
or you can clone the git repositories
git clone git@github.com:LucHermitte/lh-vim-lib.git git clone git@github.com:LucHermitte/lh-brackets.git
-
or with Vundle/NeoBundle:
Bundle 'LucHermitte/lh-vim-lib' Bundle 'LucHermitte/lh-brackets'
- This bracketing system is actually a variation on Stephen Riehm's original bracketing system ;
- The brackets manipulation comes from Saul Lubkin code, also present in auctex.vim ;
- Using SELECT-mode when reaching a placeholder was a suggestion from Gergely Kontra.
- imaps.vim, from LaTeX-suite, with which map-tools is compatible (there is no conflictual mappings if both are installed) ;
- All the brackets related tips on vim.wikia ;
- Most of my ftplugins for examples of use, or more simply the Python ftplugin shipped with lh-brackets.
- muTemplate, a template-files expander built on top of map-tools.
- surround plugin on SF