Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version 2.00

Modularize and generalize for completing other types of snippets (e.g. from snipMate).
  • Loading branch information...
commit 3d589356fac41644c9b6b5f77f40d82973764305 1 parent 7d39682
Ingo Karkat authored committed
View
36 README
@@ -4,27 +4,27 @@ DESCRIPTION
Insert mode abbreviations and snippets can dramatically speed up editing, but
how does one remember all those shortcuts that are rarely used? You can list
all insert mode abbreviations via :ia to break out of this vicious circle,
-but switching to command mode for that is cumbersome.
+but switching to command mode for that is cumbersome.
This plugin offers a context-sensitive insert mode completion to quickly list
-and complete defined abbreviations directly while typing.
+and complete defined abbreviations directly while typing.
USAGE
-i_CTRL-X_] Find matches for abbreviations that start with the
- text in front of the cursor.
+i_CTRL-X_] Find matches for abbreviations that start with the
+ text in front of the cursor.
- There are three types of abbreviations (full-id,
- end-id and non-id), which can consist of different
- characters. Thus, there can be more than one candidate
- for the existing completion base, e.g. "pre@c" can
- expand into a full-id abbreviation starting with "c"
- or into a non-id one starting with "pre@c". The
- completion indicates such a ambiguity through the
- message "base n of m; next: blah", and you can cycle
- through the different completion bases by repeating
- the i_CTRL-X_] shortcut.
+ There are three types of abbreviations (full-id,
+ end-id and non-id), which can consist of different
+ characters. Thus, there can be more than one candidate
+ for the existing completion base, e.g. "pre@c" can
+ expand into a full-id abbreviation starting with "c"
+ or into a non-id one starting with "pre@c". The
+ completion indicates such a ambiguity through the
+ message "base n of m; next: blah", and you can cycle
+ through the different completion bases by repeating
+ the i_CTRL-X_] shortcut.
- Matches are selected and inserted as with any other
- ins-completion, see popupmenu-keys. If you use
- <Space> or i_CTRL-] to select an abbreviation, it'll
- be expanded automatically.
+ Matches are selected and inserted as with any other
+ ins-completion, see popupmenu-keys. If you use
+ <Space> or i_CTRL-] to select an abbreviation, it'll
+ be expanded automatically.
View
207 autoload/SnippetComplete.vim
@@ -1,53 +1,103 @@
" SnippetComplete.vim: Insert mode completion that completes defined
-" abbreviations.
+" abbreviations and snippets.
"
" DEPENDENCIES:
"
-" Copyright: (C) 2010 Ingo Karkat
-" The VIM LICENSE applies to this script; see ':help copyright'.
+" Copyright: (C) 2010-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
-" REVISION DATE REMARKS
+" REVISION DATE REMARKS
+" 2.00.003 05-May-2012 Rewrite s:RegistryTypeCompare() so that it
+" doesn't need to access
+" g:SnippetComplete_Registry.
+" Allow to pass in types instead of accessing
+" g:SnippetComplete_Registry.
+" 2.00.002 03-May-2012 Generalize for completing other types of
+" snippets (e.g. from snipMate):
+" Introduce g:SnippetComplete_Registry for snippet
+" types.
+" Move resolution of Vim abbreviations to
+" SnippetComplete/Abbreviations.vim autoload
+" script.
" 1.01.001 25-Sep-2010 Moved functions from plugin to separate autoload
-" script.
+" script.
" The autocmd uses a global variable so that it
" can pass the
" g:SnippetComplete_LastInsertStartPosition to the
" autoload script's functions without loading the
-" autoload script on the first InsertEnter.
+" autoload script on the first InsertEnter.
" file creation
+let s:save_cpo = &cpo
+set cpo&vim
-let s:abbreviationExpressions = [['fullid', '\k\+'], ['endid', '\%(\k\@!\S\)\+\k\?'], ['nonid', '\S\+\%(\k\@!\S\)\?']]
-function! s:DetermineBaseCol()
+function! s:TypeCompare( c1, c2 )
+ let l:p1 = a:c1[1].priority
+ let l:p2 = a:c2[1].priority
+ return (l:p1 ==# l:p2 ? 0 : l:p1 ># l:p2 ? 1 : -1)
+endfunction
+function! s:GetSortedTypes( types )
+ return map(sort(items(a:types), 's:TypeCompare'), 'v:val[0]')
+endfunction
+function! s:GetSnippetPatternsPerType( types )
+ return map(
+ \ s:GetSortedTypes(a:types),
+ \ '[v:val, a:types[v:val].pattern]'
+ \)
+endfunction
+function! s:GetSnippets( types, type )
+ if a:type ==# 'none'
+ " There is no base, so the snippet type can not be determined. Ask all
+ " registered types for their snippets.
+ let l:snippets = []
+ for l:type in s:GetSortedTypes(a:types)
+ let l:snippets += call(a:types[l:type].generator, [])
+ endfor
+ return l:snippets
+ else
+ return call(a:types[a:type].generator, [])
+ endif
+endfunction
+
+function! s:DetermineBaseCol( types )
"*******************************************************************************
"* PURPOSE:
" Check the text before the cursor to determine possible base columns where
-" abbreviations of the various types may start.
+" snippets of the various types may start.
"* ASSUMPTIONS / PRECONDITIONS:
-" None.
+" None.
"* EFFECTS / POSTCONDITIONS:
-" None.
+" None.
"* INPUTS:
-" None.
-"* RETURN VALUES:
-" List of possible base columns, more stringently defined and shorter
-" abbreviation types come first. Each element consists of a [abbreviationType,
-" baseCol] tuple.
+" None.
+"* RETURN VALUES:
+" List of possible base columns, more stringently defined and shorter snippet
+" types come first. Each element consists of a [type, baseCol] tuple.
"*******************************************************************************
- " Locate possible start positions of the abbreviation, searching for
- " full-id, end-id and non-id abbreviations.
- " If the insertion started in the current line, only consider characters
- " that were inserted by the last insertion. For this, we match with the
- " stored start position of the current insert mode, if insertion started in
- " the current line. The matched text must definitely be somewhere after it,
- " but need not start with the start-of-insert position.
- let l:insertedTextExpr = (line('.') == g:SnippetComplete_LastInsertStartPosition[1] ? '\%(\%' . g:SnippetComplete_LastInsertStartPosition[2] . 'c.\)\?\%>' . g:SnippetComplete_LastInsertStartPosition[2] . 'c.*\%#\&' : '')
+ " Locate possible start positions of the snippet, searching for full-id,
+ " end-id and non-id abbreviations, and whatever else was registered.
+
+ let l:insertedTextExpr = ''
+ if line('.') == g:SnippetComplete_LastInsertStartPosition[1]
+ " If the insertion started in the current line, only consider characters
+ " that were inserted by the last insertion for Vim abbreviations,
+ " because they only apply then. For this, we match with the stored start
+ " position of the current insert mode, if insertion started in the
+ " current line. The matched text must definitely be somewhere after it,
+ " but need not start with the start-of-insert position.
+ let l:insertedTextExpr = '\%(\%' . g:SnippetComplete_LastInsertStartPosition[2] . 'c.\)\?\%>' . g:SnippetComplete_LastInsertStartPosition[2] . 'c.*\%#\&'
+ endif
+
let l:baseColumns = []
- for l:abbreviationExpression in s:abbreviationExpressions
- let l:startCol = searchpos(l:insertedTextExpr . '\%(' . l:abbreviationExpression[1] . '\)\%#', 'bn', line('.'))[1]
+ for [l:type, l:pattern] in s:GetSnippetPatternsPerType(a:types)
+ let l:needsInsertionAtOnce = get(a:types[l:type], 'needsInsertionAtOnce', 0)
+ let l:startCol = searchpos(
+ \ (l:needsInsertionAtOnce ? l:insertedTextExpr : '') .
+ \ '\%(' . l:pattern . '\)\%#',
+ \ 'bn', line('.'))[1]
if l:startCol != 0
- call add(l:baseColumns, [l:abbreviationExpression[0], l:startCol])
+ call add(l:baseColumns, [l:type, l:startCol])
endif
endfor
if empty(l:baseColumns)
@@ -56,66 +106,25 @@ function! s:DetermineBaseCol()
return l:baseColumns
endfunction
-function! s:GetAbbreviations()
- let l:abbreviations = ''
- let l:save_verbose = &verbose
- try
- set verbose=0 " Do not include any "Last set from" info.
- redir => l:abbreviations
- silent iabbrev
- finally
- redir END
- let &verbose = l:save_verbose
- endtry
-
- let l:globalMatches = []
- let l:localMatches = []
- try
- for l:abb in split(l:abbreviations, "\n")
- let [l:lhs, l:flags, l:rhs] = matchlist(l:abb, '^\S\s\+\(\S\+\)\s\+\([* ][@ ]\)\(.*\)$')[1:3]
- let l:match = { 'word': l:lhs, 'menu': l:rhs }
- call add((l:flags =~# '@' ? l:localMatches : l:globalMatches), l:match)
- endfor
- catch /^Vim\%((\a\+)\)\=:E688/ " catch error E688: More targets than List items
- " When there are no abbreviations, Vim returns "No abbreviation found".
- endtry
-
- " A buffer-local abbreviation overrides an existing global abbreviation with
- " the same {lhs}.
- for l:localWord in map(copy(l:localMatches), 'v:val.word')
- call filter(l:globalMatches, 'v:val.word !=# ' . string(l:localWord))
- endfor
- return l:globalMatches + l:localMatches
-endfunction
-
function! s:GetBase( baseCol, cursorCol )
return strpart(getline('.'), a:baseCol - 1, (a:cursorCol - a:baseCol))
endfunction
-function! s:MatchAbbreviations( abbreviations, abbreviationFilterExpr, baseCol )
+function! s:MatchSnippets( snippets, baseCol )
let l:base = s:GetBase(a:baseCol, col('.'))
"****D echomsg '****' a:baseCol l:base
-
- let l:filter = 'v:val.word =~#' . string(a:abbreviationFilterExpr)
- if ! empty(l:base)
- let l:filter .= ' && v:val.word =~# ''^\V'' . ' . string(escape(l:base, '\'))
- endif
- return filter(copy(a:abbreviations), l:filter)
+ return (empty(l:base) ?
+ \ a:snippets :
+ \ filter(copy(a:snippets), 'strpart(v:val.word, 0, ' . len(l:base) . ') ==# ' . string(l:base))
+ \)
endfunction
-let s:filterExpr = {
-\ 'fullid': '^\k\+$',
-\ 'endid': '^\%(\k\@\!\S\)\+\k$',
-\ 'nonid': '^\S*\%(\k\@!\S\)$',
-\ 'none': '^\S\+$'
-\}
-function! s:GetAbbreviationCompletions()
- let l:baseColumns = s:DetermineBaseCol()
- let l:abbreviations = s:GetAbbreviations()
+function! s:GetSnippetCompletions( types )
+ let l:baseColumns = s:DetermineBaseCol(a:types)
"****D echomsg '####' string(l:baseColumns)
-
let l:completionsByBaseCol = {}
- for [l:abbreviationType, l:baseCol] in l:baseColumns
- let l:matches = s:MatchAbbreviations(l:abbreviations, s:filterExpr[l:abbreviationType], l:baseCol)
-"****D echomsg '****' l:abbreviationType string(l:matches)
+ for [l:type, l:baseCol] in l:baseColumns
+ let l:snippets = s:GetSnippets(a:types, l:type)
+ let l:matches = s:MatchSnippets(l:snippets, l:baseCol)
+"****D echomsg '****' l:type string(l:matches)
if ! empty(l:matches)
let l:completions = get(l:completionsByBaseCol, l:baseCol, [])
let l:completions += l:matches
@@ -134,14 +143,14 @@ function! s:SetupCmdlineForBaseMessage()
" built-in "match m of n" completion mode messages. Unfortunately, an active
" 'showmode' setting may prevent the user from seeing the message in a
" one-line command line. Thus, we temporarily disable the 'showmode'
- " setting.
+ " setting.
if &showmode && &cmdheight == 1
set noshowmode
" Use a single-use autocmd to restore the 'showmode' setting when the
" cursor is moved (this already happens when a next match is selected,
" but then the "match m of n" message takes over) or insert mode is
- " left.
+ " left.
augroup SnippetCompleteTemporaryNoShowMode
autocmd!
autocmd CursorMovedI,InsertLeave * set showmode | autocmd! SnippetCompleteTemporaryNoShowMode
@@ -160,59 +169,59 @@ function! s:ShowMultipleBasesMessage( nextIdx, baseNum, nextBase )
endfunction
function! s:RecordPosition()
" The position record consists of the current cursor position, the buffer,
- " window and tab page number and the buffer's current change state.
+ " window and tab page number and the buffer's current change state.
" As soon as you make an edit, move to another buffer or even the same
" buffer in another tab page or window (or as a minor side effect just close
- " a window above the current), the position changes.
+ " a window above the current), the position changes.
return getpos('.') + [bufnr(''), winnr(), tabpagenr()]
endfunction
let s:lastCompletionsByBaseCol = {}
let s:nextBaseIdx = 0
let s:initialCompletePosition = []
let s:lastCompleteEndPosition = []
-function! SnippetComplete#SnippetComplete()
+function! SnippetComplete#SnippetComplete( types )
"****D echomsg '****' string(s:RecordPosition())
let l:baseNum = len(keys(s:lastCompletionsByBaseCol))
if s:initialCompletePosition == s:RecordPosition() && l:baseNum > 1
" The Snippet complete mapping is being repeatedly executed on the same
" position, and we have multiple completion bases. Use the next/first
- " base from the cached completions.
+ " base from the cached completions.
let l:baseIdx = s:nextBaseIdx
else
- " This is a new completion.
- let s:lastCompletionsByBaseCol = s:GetAbbreviationCompletions()
+ " This is a new completion.
+ let s:lastCompletionsByBaseCol = s:GetSnippetCompletions(a:types)
let l:baseIdx = 0
let l:baseNum = len(keys(s:lastCompletionsByBaseCol))
let s:initialCompletePosition = s:RecordPosition()
- let s:initialCompletionCol = col('.') " Note: The column is also contained in s:initialCompletePosition, but a separate variable is more expressive.
+ let s:initialCompletionCol = col('.') " Note: The column is also contained in s:initialCompletePosition, but a separate variable is more expressive.
endif
" Multiple bases are presented from shortest base (i.e. largest base column)
" to longest base. Full-id abbreviations have the most restrictive pattern
" and thus always generate the shortest bases; end-id and non-id
" abbreviations accept more character classes and can result in longer
- " bases.
+ " bases.
let l:baseColumns = reverse(sort(keys(s:lastCompletionsByBaseCol)))
if l:baseNum > 0
- " Show the completions for the current base.
+ " Show the completions for the current base.
call complete(l:baseColumns[l:baseIdx], sort(s:lastCompletionsByBaseCol[l:baseColumns[l:baseIdx]], 's:CompletionCompare'))
let s:lastCompleteEndPosition = s:RecordPosition()
if l:baseNum > 1
" There are multiple bases; make subsequent invocations cycle
- " through them.
+ " through them.
let s:nextBaseIdx = (l:baseIdx < l:baseNum - 1 ? l:baseIdx + 1 : 0)
" Note: Setting the completions typically inserts the first match
" and thus advances the cursor. We need the initial cursor position
" to resolve the next base(s) only up to what has actually been
- " entered.
+ " entered.
let l:nextBase = s:GetBase(l:baseColumns[s:nextBaseIdx], s:initialCompletionCol)
" Indicate to the user that additional bases exist, and offer a
- " preview of the next one.
+ " preview of the next one.
call s:ShowMultipleBasesMessage(l:baseIdx + 1, l:baseNum, l:nextBase)
endif
endif
@@ -226,17 +235,17 @@ function! SnippetComplete#PreSnippetCompleteExpr()
" completion end position (after the completions are shown) is recorded in
" s:lastCompleteEndPosition. This position can change if the user selects
" another completion match (via CTRL-N) that has a different length, and
- " only then re-triggers the completion for the next abbreviation base.
+ " only then re-triggers the completion for the next abbreviation base.
" We can still handle this situation by checking for an active popup menu;
" that means that (presumably, could be from another completion type)
- " another abbreviation completion had been triggered.
+ " another abbreviation completion had been triggered.
" To return the cursor to the inital completion position, CTRL-E is used to
" end the completion; this may only not work when 'completeopt' contains
- " "longest" (Vim returns to what was typed or longest common string).
+ " "longest" (Vim returns to what was typed or longest common string).
let l:baseNum = len(keys(s:lastCompletionsByBaseCol))
return (pumvisible() || s:lastCompleteEndPosition == s:RecordPosition() && l:baseNum > 1 ? "\<C-e>" : '')
endfunction
-function! SnippetComplete#RecordInsertStartPosition()
-endfunction
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
74 autoload/SnippetComplete/Abbreviations.vim
@@ -0,0 +1,74 @@
+" SnippetComplete/Abbreviations.vim: Retrieval of defined Vim abbreviations.
+"
+" DEPENDENCIES:
+"
+" Copyright: (C) 2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+"
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 2.00.001 03-May-2012 file creation
+
+let s:filterExpr = {
+\ 'none': '^\S\+$'
+\}
+function! SnippetComplete#Abbreviations#RetrieveAbbreviations()
+ let l:abbreviations = ''
+ let l:save_verbose = &verbose
+ try
+ set verbose=0 " Do not include any "Last set from" info.
+ redir => l:abbreviations
+ silent iabbrev
+ finally
+ redir END
+ let &verbose = l:save_verbose
+ endtry
+
+ let l:globalMatches = []
+ let l:localMatches = []
+ try
+ for l:abb in split(l:abbreviations, "\n")
+ let [l:lhs, l:flags, l:rhs] = matchlist(l:abb, '^\S\s\+\(\S\+\)\s\+\([* ][@ ]\)\(.*\)$')[1:3]
+ let l:match = { 'word': l:lhs, 'menu': l:rhs }
+ call add((l:flags =~# '@' ? l:localMatches : l:globalMatches), l:match)
+ endfor
+ catch /^Vim\%((\a\+)\)\=:E688/ " catch error E688: More targets than List items
+ " When there are no abbreviations, Vim returns "No abbreviation found".
+ endtry
+
+ " A buffer-local abbreviation overrides an existing global abbreviation with
+ " the same {lhs}.
+ for l:localWord in map(copy(l:localMatches), 'v:val.word')
+ call filter(l:globalMatches, 'v:val.word !=# ' . string(l:localWord))
+ endfor
+ return l:globalMatches + l:localMatches
+endfunction
+
+" All three different types of abbreviations are backed by the same query of
+" defined abbreviations. As a balance between memory and performance, let's
+" cache the abbreviations for the current buffer, so that all three queries of
+" the different abbreviation types can be handled with a single lookup, and
+" subsequent lookups in the same buffer, too. As there can be buffer-local
+" abbreviations, the cache has to be re-generated when the buffer changes.
+let s:bufnr = 0
+let s:cache = []
+function! s:GetAbbreviations( pattern )
+ if empty(s:cache) || s:bufnr != bufnr('')
+ let s:cache = SnippetComplete#Abbreviations#RetrieveAbbreviations()
+ let s:bufnr = bufnr('')
+ endif
+ return filter(copy(s:cache), 'v:val.word =~# ' . string(a:pattern))
+endfunction
+
+function! SnippetComplete#Abbreviations#fullid()
+ return s:GetAbbreviations('^\k\+$')
+endfunction
+function! SnippetComplete#Abbreviations#endid()
+ return s:GetAbbreviations('^\%(\k\@\!\S\)\+\k$')
+endfunction
+function! SnippetComplete#Abbreviations#nonid()
+ return s:GetAbbreviations('^\S*\%(\k\@!\S\)$')
+endfunction
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
View
84 doc/SnippetComplete.txt
@@ -1,11 +1,11 @@
-*SnippetComplete.txt* Insert mode completion that completes defined abbreviations.
+*SnippetComplete.txt* Insert mode completion that completes defined abbreviations and other snippets.
SNIPPET COMPLETE by Ingo Karkat
*SnippetComplete.vim*
description |SnippetComplete-description|
-usage |SnippetComplete-usage|
-installation |SnippetComplete-installation|
-configuration |SnippetComplete-configuration|
+usage |SnippetComplete-usage|
+installation |SnippetComplete-installation|
+configuration |SnippetComplete-configuration|
integration |SnippetComplete-integration|
limitations |SnippetComplete-limitations|
known problems |SnippetComplete-known-problems|
@@ -18,16 +18,17 @@ DESCRIPTION *SnippetComplete-description*
Insert mode abbreviations and snippets can dramatically speed up editing, but
how does one remember all those shortcuts that are rarely used? You can list
all insert mode abbreviations via |:ia| to break out of this vicious circle,
-but switching to command mode for that is cumbersome.
+but switching to command mode for that is cumbersome.
This plugin offers a context-sensitive insert mode completion to quickly list
-and complete defined abbreviations directly while typing.
+and complete defined abbreviations directly while typing.
==============================================================================
USAGE *SnippetComplete-usage*
*i_CTRL-X_]*
i_CTRL-X_] Find matches for abbreviations that start with the
- text in front of the cursor.
+ text in front of the cursor. If other snippet types
+ are registered, show those, too.
There are three types of |abbreviations| (full-id,
end-id and non-id), which can consist of different
@@ -38,12 +39,12 @@ i_CTRL-X_] Find matches for abbreviations that start with the
completion indicates such a ambiguity through the
message "base n of m; next: blah", and you can cycle
through the different completion bases by repeating
- the i_CTRL-X_] shortcut.
+ the i_CTRL-X_] shortcut.
Matches are selected and inserted as with any other
|ins-completion|, see |popupmenu-keys|. If you use
<Space> or |i_CTRL-]| to select an abbreviation, it'll
- be expanded automatically.
+ be expanded automatically.
==============================================================================
INSTALLATION *SnippetComplete-installation*
@@ -54,54 +55,91 @@ the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
vimball or via the |:UseVimball| command. >
vim SnippetComplete.vba.gz
:so %
-To uninstall, use the |:RmVimball| command.
+To uninstall, use the |:RmVimball| command.
DEPENDENCIES *SnippetComplete-dependencies*
-- Requires Vim 7.0 or higher.
+- Requires Vim 7.0 or higher.
==============================================================================
CONFIGURATION *SnippetComplete-configuration*
If you want to use a different mapping, map your keys to the
-<Plug>SnippetComplete mapping target _before_ sourcing this script (e.g. in
-your |vimrc|).
+<Plug>(SnippetComplete) mapping target _before_ sourcing this script (e.g. in
+your |vimrc|).
For example, to use CTRL-X <Tab>, use this: >
- imap <C-x><Tab> <Plug>SnippetComplete
+ imap <C-x><Tab> <Plug>(SnippetComplete)
<
==============================================================================
INTEGRATION *SnippetComplete-integration*
-It is planned to extend the completion to snippets for the snipMate plugin
-(vimscript #2540) and offer an extension point for other snippet plugins.
+There exist multiple snippet systems that extend the built-in abbreviations
+with support for filetype-specific and more complex expansions, like allowing
+placeholders and expansion of in-line scriptlets. One popular one is the
+snipMate plugin (vimscript #2540).
+Since there is a seamless transition from simple abbreviation to complex
+snippet, it may help to have a completion for both sources. To support this,
+this plugin allows to write completions for other snippet plugins with just a
+little bit of configuration and a function to retrieve the valid snippets.
+This completion can be stand-alone via a different mapping, or it can add the
+snippets to the |i_CTRL-X_]| completion mapping provided here.
+
+The definition of a snippet type consists of an object with the following
+properties: >
+ let typeDefinition = {
+ \ '{typeName}': {
+ \ 'priority': 100,
+ \ 'pattern': '\k\+',
+ \ 'generator': function('MySnippets#Get')
+ \ }
+ \}
+<
+The {pattern} key specifies the valid syntax of the snippets; the {generator}
+should return all snippets in the format of |complete-items|; the filtering
+according to the completion base is done by this plugin itself.
+ *g:SnippetComplete_RegisteredTypes*
+To include the snippets in the |i_CTRL-X_]| completion mapping provided here: >
+ call extend(g:SnippetComplete_RegisteredTypes, typeDefinition)
+<
+To create a separate completion mapping for your type: >
+ inoremap <silent> <C-x>% <C-r>=SnippetComplete#PreSnippetCompleteExpr()<CR><C-r>=SnippetComplete#SnippetComplete(typeDefinition)<CR>
+<
==============================================================================
LIMITATIONS *SnippetComplete-limitations*
KNOWN PROBLEMS *SnippetComplete-known-problems*
+- When <CR> is :map-expr to <C-Y> when pumvisible() to accept the current
+ entry, and there's additional processing after <C-Y> (in my case, <C-\><C-o>
+ to call a function) the completed abbreviation is not expanded any more.
+
TODO *SnippetComplete-todo*
-- Getting and sorting of matches when 'ignorecase' is on.
-- Limiting the length of the snippet expansion shown in the popup menu.
+- Getting and sorting of matches when 'ignorecase' is on.
+- Limiting the length of the snippet expansion shown in the popup menu.
IDEAS *SnippetComplete-ideas*
==============================================================================
HISTORY *SnippetComplete-history*
+2.00 08-May-2012
+- Modularize and generalize for completing other types of snippets (e.g. from
+ snipMate).
+
1.01 25-Sep-2010
-Using separate autoload script to help speed up Vim startup.
+Using separate autoload script to help speed up Vim startup.
1.00 12-Jan-2010
-First published version.
+First published version.
0.01 08-Jan-2010
-Started development.
+Started development.
==============================================================================
-Copyright: (C) 2010 Ingo Karkat
-The VIM LICENSE applies to this script; see|copyright|.
+Copyright: (C) 2010-2012 Ingo Karkat
+The VIM LICENSE applies to this script; see|copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================
View
83 plugin/SnippetComplete.vim
@@ -1,50 +1,101 @@
" SnippetComplete.vim: Insert mode completion that completes defined
-" abbreviations.
+" abbreviations and snippets.
"
" DEPENDENCIES:
-" - Requires Vim 7.0 or higher.
-" - SnippetComplete.vim autoload script.
+" - Requires Vim 7.0 or higher.
+" - SnippetComplete.vim autoload script
+" - SnippetComplete/Abbreviations.vim autoload script
"
-" Copyright: (C) 2010 by Ingo Karkat
-" The VIM LICENSE applies to this script; see ':help copyright'.
+" Copyright: (C) 2010-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
"
" Maintainer: Ingo Karkat <ingo@karkat.de>
"
-" REVISION DATE REMARKS
+" REVISION DATE REMARKS
+" 2.00.006 05-May-2012 Rename g:SnippetComplete_Registry to
+" g:SnippetComplete_RegisteredTypes and pass this
+" to SnippetComplete#SnippetComplete() to allow
+" other uses of the completion excluding the Vim
+" abbreviations.
+" 2.00.005 03-May-2012 Generalize for completing other types of
+" snippets (e.g. from snipMate):
+" Introduce g:SnippetComplete_Registry for snippet
+" types.
+" 1.02.004 03-Oct-2011 Change <Plug>-mapping to <Plug>(SnippetComplete)
+" for consistency with my other completion plugins.
" 1.01.003 25-Sep-2010 Moved functions from plugin to separate autoload
-" script.
+" script.
" 1.00.002 12-Jan-2010 Completed implementation for defined
-" :iabbrev's.
+" :iabbrev's.
" 001 08-Jan-2010 file creation
-" Avoid installing twice or when in unsupported Vim version.
+" Avoid installing twice or when in unsupported Vim version.
if exists('g:loaded_SnippetComplete') || (v:version < 700)
finish
endif
let g:loaded_SnippetComplete = 1
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+"- integration -----------------------------------------------------------------
+
+if ! exists('g:SnippetComplete_AbbreviationTypes')
+ let g:SnippetComplete_AbbreviationTypes = {
+ \ 'fullid': {
+ \ 'priority': 10,
+ \ 'pattern': '\k\+',
+ \ 'generator': function('SnippetComplete#Abbreviations#fullid'),
+ \ 'needsInsertionAtOnce': 1
+ \ },
+ \ 'endid': {
+ \ 'priority': 20,
+ \ 'pattern': '\%(\k\@!\S\)\+\k\?',
+ \ 'generator': function('SnippetComplete#Abbreviations#endid'),
+ \ 'needsInsertionAtOnce': 1
+ \ },
+ \ 'nonid': {
+ \ 'priority': 30,
+ \ 'pattern': '\S\+\%(\k\@!\S\)\?',
+ \ 'generator': function('SnippetComplete#Abbreviations#nonid'),
+ \ 'needsInsertionAtOnce': 1
+ \ },
+ \}
+endif
+if ! exists('g:SnippetComplete_RegisteredTypes')
+ let g:SnippetComplete_RegisteredTypes = copy(g:SnippetComplete_AbbreviationTypes)
+endif
+
+
+"- autocmds --------------------------------------------------------------------
" In order to determine the base column of the completion, we need the start
" position of the current insertion. Mark '[ isn't set until we (at least
" temporarily via i_CTRL-O) move out of insert mode; however doing so then
" prevents the completed abbreviation from being expanded: The insertion was
" interrupted, and Vim doesn't consider the full expanded abbreviation to have
-" been inserted in the current insert mode.
+" been inserted in the current insert mode.
" To work around this, we use an autocmd to capture the cursor position whenever
-" insert mode is entered.
+" insert mode is entered.
augroup SnippetComplete
autocmd!
autocmd InsertEnter * let g:SnippetComplete_LastInsertStartPosition = getpos('.')
augroup END
+
+"- mappings --------------------------------------------------------------------
+
" Triggering a completion typically inserts the first match and thus
" advances the cursor. We need the original cursor position to detect the
" repetition of the completion at the same position, in case the user wants to
" use another completion base. The reset of the cursor position is done in a
" preceding expression mapping, because it is not allowed to change the cursor
-" position from within the actual SnippetComplete#SnippetComplete() expression.
-inoremap <silent> <Plug>SnippetComplete <C-r>=SnippetComplete#PreSnippetCompleteExpr()<CR><C-r>=SnippetComplete#SnippetComplete()<CR>
-if ! hasmapto('<Plug>SnippetComplete', 'i')
- imap <C-x>] <Plug>SnippetComplete
+" position from within the actual SnippetComplete#SnippetComplete() expression.
+inoremap <silent> <Plug>(SnippetComplete) <C-r>=SnippetComplete#PreSnippetCompleteExpr()<CR><C-r>=SnippetComplete#SnippetComplete(g:SnippetComplete_RegisteredTypes)<CR>
+if ! hasmapto('<Plug>(SnippetComplete)', 'i')
+ imap <C-x>] <Plug>(SnippetComplete)
endif
-" vim: set sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
+let &cpo = s:save_cpo
+unlet s:save_cpo
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
Please sign in to comment.
Something went wrong with that request. Please try again.