mirror of
https://github.com/kastdeur/dotfiles.git
synced 2025-05-14 20:09:26 +02:00
Added vim plugin + autoindent\n use vi if vim is typed and not available
This commit is contained in:
parent
ef8bf8ac54
commit
061f80b9b9
144 changed files with 30057 additions and 0 deletions
323
vim/vim-latex/plugin/SyntaxFolds.vim
Executable file
323
vim/vim-latex/plugin/SyntaxFolds.vim
Executable file
|
@ -0,0 +1,323 @@
|
|||
" ==============================================================================
|
||||
" File: syntaxFolds.vim
|
||||
" Author: Srinath Avadhanula
|
||||
" ( srinath@fastmail.fm )
|
||||
" Last Change: Sun Oct 27 01:00 AM 2002 PST
|
||||
" Description: Emulation of the syntax folding capability of vim using manual
|
||||
" folding
|
||||
"
|
||||
" This script provides an emulation of the syntax folding of vim using manual
|
||||
" folding. Just as in syntax folding, the folds are defined by regions. Each
|
||||
" region is specified by a call to FoldRegions() which accepts 4 parameters:
|
||||
"
|
||||
" call FoldRegions(startpat, endpat, startoff, endoff)
|
||||
"
|
||||
" startpat: a line matching this pattern defines the beginning of a fold.
|
||||
" endpat : a line matching this pattern defines the end of a fold.
|
||||
" startoff: this is the offset from the starting line at which folding will
|
||||
" actually start
|
||||
" endoff : like startoff, but gives the offset of the actual fold end from
|
||||
" the line satisfying endpat.
|
||||
" startoff and endoff are necessary when the folding region does
|
||||
" not have a specific end pattern corresponding to a start
|
||||
" pattern. for example in latex,
|
||||
" \begin{section}
|
||||
" defines the beginning of a section, but its not necessary to
|
||||
" have a corresponding
|
||||
" \end{section}
|
||||
" the section is assumed to end 1 line _before_ another section
|
||||
" starts.
|
||||
" startskip: a pattern which defines the beginning of a "skipped" region.
|
||||
"
|
||||
" For example, suppose we define a \itemize fold as follows:
|
||||
" startpat = '^\s*\\item',
|
||||
" endpat = '^\s*\\item\|^\s*\\end{\(enumerate\|itemize\|description\)}',
|
||||
" startoff = 0,
|
||||
" endoff = -1
|
||||
"
|
||||
" This defines a fold which starts with a line beginning with an
|
||||
" \item and ending one line before a line beginning with an
|
||||
" \item or \end{enumerate} etc.
|
||||
"
|
||||
" Then, as long as \item's are not nested things are fine.
|
||||
" However, once items begin to nest, the fold started by one
|
||||
" \item can end because of an \item in an \itemize
|
||||
" environment within this \item. i.e, the following can happen:
|
||||
"
|
||||
" \begin{itemize}
|
||||
" \item Some text <------- fold will start here
|
||||
" This item will contain a nested item
|
||||
" \begin{itemize} <----- fold will end here because next line contains \item...
|
||||
" \item Hello
|
||||
" \end{itemize} <----- ... instead of here.
|
||||
" \item Next item of the parent itemize
|
||||
" \end{itemize}
|
||||
"
|
||||
" Therefore, in order to completely define a folding item which
|
||||
" allows nesting, we need to also define a "skip" pattern.
|
||||
" startskip and end skip do that.
|
||||
" Leave '' when there is no nesting.
|
||||
" endskip: the pattern which defines the end of the "skip" pattern for
|
||||
" nested folds.
|
||||
"
|
||||
" Example:
|
||||
" 1. A syntax fold region for a latex section is
|
||||
" startpat = "\\section{"
|
||||
" endpat = "\\section{"
|
||||
" startoff = 0
|
||||
" endoff = -1
|
||||
" startskip = ''
|
||||
" endskip = ''
|
||||
" Note that the start and end patterns are thus the same and endoff has a
|
||||
" negative value to capture the effect of a section ending one line before
|
||||
" the next starts.
|
||||
" 2. A syntax fold region for the \itemize environment is:
|
||||
" startpat = '^\s*\\item',
|
||||
" endpat = '^\s*\\item\|^\s*\\end{\(enumerate\|itemize\|description\)}',
|
||||
" startoff = 0,
|
||||
" endoff = -1,
|
||||
" startskip = '^\s*\\begin{\(enumerate\|itemize\|description\)}',
|
||||
" endskip = '^\s*\\end{\(enumerate\|itemize\|description\)}'
|
||||
" Note the use of startskip and endskip to allow nesting.
|
||||
"
|
||||
"
|
||||
" Each time a call is made to FoldRegions(), all the regions (which might be
|
||||
" disjoint, but not nested) are folded up.
|
||||
" Nested folds can be created by successive calls to FoldRegions(). The first
|
||||
" call defines the region which is deepest in the folding. See MakeTexFolds()
|
||||
" for an idea of how this works for latex files.
|
||||
|
||||
" Function: AddSyntaxFoldItem (start, end, startoff, endoff [, skipStart, skipEnd]) {{{
|
||||
function! AddSyntaxFoldItem(start, end, startoff, endoff, ...)
|
||||
if a:0 > 0
|
||||
let skipStart = a:1
|
||||
let skipEnd = a:2
|
||||
else
|
||||
let skipStart = ''
|
||||
let skipEnd = ''
|
||||
end
|
||||
if !exists('b:numFoldItems')
|
||||
let b:numFoldItems = 0
|
||||
end
|
||||
let b:numFoldItems = b:numFoldItems + 1
|
||||
|
||||
exe 'let b:startPat_'.b:numFoldItems.' = a:start'
|
||||
exe 'let b:endPat_'.b:numFoldItems.' = a:end'
|
||||
exe 'let b:startOff_'.b:numFoldItems.' = a:startoff'
|
||||
exe 'let b:endOff_'.b:numFoldItems.' = a:endoff'
|
||||
exe 'let b:skipStartPat_'.b:numFoldItems.' = skipStart'
|
||||
exe 'let b:skipEndPat_'.b:numFoldItems.' = skipEnd'
|
||||
endfunction
|
||||
|
||||
|
||||
" }}}
|
||||
" Function: MakeSyntaxFolds (force) {{{
|
||||
" Description: This function calls FoldRegions() several times with the
|
||||
" parameters specifying various regions resulting in a nested fold
|
||||
" structure for the file.
|
||||
function! MakeSyntaxFolds(force, ...)
|
||||
if exists('b:doneFolding') && a:force == 0
|
||||
return
|
||||
end
|
||||
|
||||
let skipEndPattern = ''
|
||||
if a:0 > 0
|
||||
let line1 = a:1
|
||||
let skipEndPattern = '\|'.a:2
|
||||
else
|
||||
let line1 = 1
|
||||
let r = line('.')
|
||||
let c = virtcol('.')
|
||||
|
||||
setlocal fdm=manual
|
||||
normal! zE
|
||||
end
|
||||
if !exists('b:numFoldItems')
|
||||
b:numFoldItems = 1000000
|
||||
end
|
||||
|
||||
let i = 1
|
||||
|
||||
let maxline = line('.')
|
||||
|
||||
while exists('b:startPat_'.i) && i <= b:numFoldItems
|
||||
exe 'let startPat = b:startPat_'.i
|
||||
exe 'let endPat = b:endPat_'.i
|
||||
exe 'let startOff = b:startOff_'.i
|
||||
exe 'let endOff = b:endOff_'.i
|
||||
|
||||
let skipStart = ''
|
||||
let skipEnd = ''
|
||||
if exists('b:skipStartPat_'.i)
|
||||
exe 'let skipStart = b:skipStartPat_'.i
|
||||
exe 'let skipEnd = b:skipEndPat_'.i
|
||||
end
|
||||
exe line1
|
||||
let lastLoc = line1
|
||||
|
||||
if skipStart != ''
|
||||
call InitStack('BeginSkipArray')
|
||||
call FoldRegionsWithSkip(startPat, endPat, startOff, endOff, skipStart, skipEnd, 1, line('$'))
|
||||
" call PrintError('done folding ['.startPat.']')
|
||||
else
|
||||
call FoldRegionsWithNoSkip(startPat, endPat, startOff, endOff, 1, line('$'), '')
|
||||
end
|
||||
|
||||
let i = i + 1
|
||||
endwhile
|
||||
|
||||
exe maxline
|
||||
|
||||
if a:0 == 0
|
||||
exe r
|
||||
exe "normal! ".c."|"
|
||||
if foldlevel(r) > 1
|
||||
exe "normal! ".(foldlevel(r) - 1)."zo"
|
||||
end
|
||||
let b:doneFolding = 0
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
" }}}
|
||||
" FoldRegionsWithSkip: folding things such as \item's which can be nested. {{{
|
||||
function! FoldRegionsWithSkip(startpat, endpat, startoff, endoff, startskip, endskip, line1, line2)
|
||||
exe a:line1
|
||||
" count the regions which have been skipped as we go along. do not want to
|
||||
" create a fold which with a beginning or end line in one of the skipped
|
||||
" regions.
|
||||
let skippedRegions = ''
|
||||
|
||||
" start searching for either the starting pattern or the end pattern.
|
||||
while search(a:startskip.'\|'.a:endskip, 'W')
|
||||
|
||||
if getline('.') =~ a:endskip
|
||||
|
||||
let lastBegin = Pop('BeginSkipArray')
|
||||
" call PrintError('popping '.lastBegin.' from stack and folding till '.line('.'))
|
||||
call FoldRegionsWithNoSkip(a:startpat, a:endpat, a:startoff, a:endoff, lastBegin, line('.'), skippedRegions)
|
||||
let skippedRegions = skippedRegions.lastBegin.','.line('.').'|'
|
||||
|
||||
|
||||
" if this is the beginning of a skip region, then, push this line as
|
||||
" the beginning of a skipped region.
|
||||
elseif getline('.') =~ a:startskip
|
||||
|
||||
" call PrintError('pushing '.line('.').' ['.getline('.').'] into stack')
|
||||
call Push('BeginSkipArray', line('.'))
|
||||
|
||||
end
|
||||
endwhile
|
||||
|
||||
" call PrintError('with skip starting at '.a:line1.' returning at line# '.line('.'))
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" FoldRegionsWithNoSkip: folding things such as \sections which do not nest. {{{
|
||||
function! FoldRegionsWithNoSkip(startpat, endpat, startoff, endoff, line1, line2, skippedRegions)
|
||||
exe a:line1
|
||||
|
||||
" call PrintError('line1 = '.a:line1.', searching from '.line('.').'... for ['.a:startpat.'')
|
||||
let lineBegin = s:MySearch(a:startpat, 'in')
|
||||
" call PrintError('... and finding it at '.lineBegin)
|
||||
|
||||
while lineBegin <= a:line2
|
||||
if IsInSkippedRegion(lineBegin, a:skippedRegions)
|
||||
let lineBegin = s:MySearch(a:startpat, 'out')
|
||||
" call PrintError(lineBegin.' is being skipped')
|
||||
continue
|
||||
end
|
||||
let lineEnd = s:MySearch(a:endpat, 'out')
|
||||
while IsInSkippedRegion(lineEnd, a:skippedRegions) && lineEnd <= a:line2
|
||||
let lineEnd = s:MySearch(a:endpat, 'out')
|
||||
endwhile
|
||||
if lineEnd > a:line2
|
||||
exe (lineBegin + a:startoff).','.a:line2.' fold'
|
||||
break
|
||||
else
|
||||
" call PrintError ('for ['.a:startpat.'] '.(lineBegin + a:startoff).','.(lineEnd + a:endoff).' fold')
|
||||
exe (lineBegin + a:startoff).','.(lineEnd + a:endoff).' fold'
|
||||
end
|
||||
|
||||
" call PrintError('line1 = '.a:line1.', searching from '.line('.').'... for ['.a:startpat.'')
|
||||
let lineBegin = s:MySearch(a:startpat, 'in')
|
||||
" call PrintError('... and finding it at '.lineBegin)
|
||||
endwhile
|
||||
|
||||
exe a:line2
|
||||
return
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" InitStack: initialize a stack {{{
|
||||
function! InitStack(name)
|
||||
exe 'let s:'.a:name.'_numElems = 0'
|
||||
endfunction
|
||||
" }}}
|
||||
" Push: push element into stack {{{
|
||||
function! Push(name, elem)
|
||||
exe 'let numElems = s:'.a:name.'_numElems'
|
||||
let numElems = numElems + 1
|
||||
exe 'let s:'.a:name.'_Element_'.numElems.' = a:elem'
|
||||
exe 'let s:'.a:name.'_numElems = numElems'
|
||||
endfunction
|
||||
" }}}
|
||||
" Pop: pops element off stack {{{
|
||||
function! Pop(name)
|
||||
exe 'let numElems = s:'.a:name.'_numElems'
|
||||
if numElems == 0
|
||||
return ''
|
||||
else
|
||||
exe 'let ret = s:'.a:name.'_Element_'.numElems
|
||||
let numElems = numElems - 1
|
||||
exe 'let s:'.a:name.'_numElems = numElems'
|
||||
return ret
|
||||
end
|
||||
endfunction
|
||||
" }}}
|
||||
" MySearch: just like search(), but returns large number on failure {{{
|
||||
function! <SID>MySearch(pat, opt)
|
||||
if a:opt == 'in'
|
||||
if getline('.') =~ a:pat
|
||||
let ret = line('.')
|
||||
else
|
||||
let ret = search(a:pat, 'W')
|
||||
end
|
||||
else
|
||||
normal! $
|
||||
let ret = search(a:pat, 'W')
|
||||
end
|
||||
|
||||
if ret == 0
|
||||
let ret = line('$') + 1
|
||||
end
|
||||
return ret
|
||||
endfunction
|
||||
" }}}
|
||||
" Function: IsInSkippedRegion (lnum, regions) {{{
|
||||
" Description: finds whether a given line number is within one of the regions
|
||||
" skipped.
|
||||
function! IsInSkippedRegion(lnum, regions)
|
||||
let i = 1
|
||||
let subset = s:Strntok(a:regions, '|', i)
|
||||
while subset != ''
|
||||
let n1 = s:Strntok(subset, ',', 1)
|
||||
let n2 = s:Strntok(subset, ',', 2)
|
||||
if a:lnum >= n1 && a:lnum <= n2
|
||||
return 1
|
||||
end
|
||||
|
||||
let subset = s:Strntok(a:regions, '|', i)
|
||||
let i = i + 1
|
||||
endwhile
|
||||
|
||||
return 0
|
||||
endfunction " }}}
|
||||
" Function: Strntok (string, tok, n) {{{
|
||||
" extract the n^th token from s seperated by tok.
|
||||
" example: Strntok('1,23,3', ',', 2) = 23
|
||||
fun! <SID>Strntok(s, tok, n)
|
||||
return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}')
|
||||
endfun " }}}
|
||||
|
||||
" vim600:fdm=marker
|
250
vim/vim-latex/plugin/filebrowser.vim
Executable file
250
vim/vim-latex/plugin/filebrowser.vim
Executable file
|
@ -0,0 +1,250 @@
|
|||
" filebrowser.vim: utility file for vim 6.2+
|
||||
"
|
||||
" Copyright: Srinath Avadhanula <srinath AT fastmail DOT fm>
|
||||
" Parts of this file are taken from explorer.vim which is a plugin file
|
||||
" distributed with vim under the Vim charityware license.
|
||||
" License: distributed under the Vim charityware license.
|
||||
"
|
||||
" Settings:
|
||||
" FB_CallBackFunction: the function name which gets called when the user
|
||||
" presses <cr> on a file-name in the file browser.
|
||||
" FB_AllowRegexp: A filename has to match this regexp to be displayed.
|
||||
" FB_RejectRegexp: If a filename matches this regexp, then its not displayed.
|
||||
" (Both these regexps are '' by default which means no filtering is
|
||||
" done).
|
||||
|
||||
" line continuation used here.
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
"======================================================================
|
||||
" Globally visible functions (API)
|
||||
"======================================================================
|
||||
" FB_OpenFileBrowser: opens a new buffer and displays the file list {{{
|
||||
" Description:
|
||||
function! FB_OpenFileBrowser(dir)
|
||||
if !isdirectory(a:dir)
|
||||
return
|
||||
endif
|
||||
if exists('s:FB_BufferNumber')
|
||||
if bufwinnr(s:FB_BufferNumber) != -1
|
||||
execute bufwinnr(s:FB_BufferNumber).' wincmd w'
|
||||
return
|
||||
endif
|
||||
execute 'aboveleft split #'.s:FB_BufferNumber
|
||||
else
|
||||
aboveleft split __Choose_File__
|
||||
let s:FB_BufferNumber = bufnr('%')
|
||||
endif
|
||||
call FB_DisplayFiles(a:dir)
|
||||
endfunction " }}}
|
||||
" FB_DisplayFiles: displays the files in a given directory {{{
|
||||
" Description:
|
||||
" Call this function only when the cursor is in a temporary buffer
|
||||
function! FB_DisplayFiles(dir)
|
||||
if !isdirectory(a:dir)
|
||||
return
|
||||
endif
|
||||
call s:FB_SetSilentSettings()
|
||||
" make this a "scratch" buffer
|
||||
call s:FB_SetScratchSettings()
|
||||
|
||||
let allowRegexp = s:FB_GetVar('FB_AllowRegexp', '')
|
||||
let rejectRegexp = s:FB_GetVar('FB_RejectRegexp', '')
|
||||
|
||||
" change to the directory to make processing simpler.
|
||||
execute "lcd ".a:dir
|
||||
" delete everything in the buffer.
|
||||
" IMPORTANT: we need to be in a scratch buffer
|
||||
0,$ d_
|
||||
|
||||
let allFilenames = glob('*')
|
||||
let dispFiles = ""
|
||||
let subDirs = "../\n"
|
||||
|
||||
let allFilenames = allFilenames."\n"
|
||||
let start = 0
|
||||
while 1
|
||||
let next = stridx(allFilenames, "\n", start)
|
||||
let filename = strpart(allFilenames, start, next-start)
|
||||
if filename == ""
|
||||
break
|
||||
endif
|
||||
|
||||
if isdirectory(filename)
|
||||
let subDirs = subDirs.filename."/\n"
|
||||
else
|
||||
if allowRegexp != '' && filename !~ allowRegexp
|
||||
elseif rejectRegexp != '' && filename =~ rejectRegexp
|
||||
else
|
||||
let dispFiles = dispFiles.filename."\n"
|
||||
endif
|
||||
endif
|
||||
|
||||
let start = next + 1
|
||||
endwhile
|
||||
|
||||
0put!=dispFiles
|
||||
0put!=subDirs
|
||||
" delte the last empty line resulting from the put
|
||||
$ d_
|
||||
|
||||
call s:FB_SetHighlighting()
|
||||
call s:FB_DisplayHelp()
|
||||
call s:FB_SetMaps()
|
||||
|
||||
" goto the first file/directory
|
||||
0
|
||||
call search('^"=', 'w')
|
||||
normal! j:<bs>
|
||||
|
||||
set nomodified nomodifiable
|
||||
|
||||
call s:FB_ResetSilentSettings()
|
||||
endfunction " }}}
|
||||
" FB_SetVar: sets script local variables from outside this script {{{
|
||||
" Description:
|
||||
function! FB_SetVar(varname, value)
|
||||
let s:{a:varname} = a:value
|
||||
endfunction " }}}
|
||||
|
||||
" ==============================================================================
|
||||
" Script local functions below this
|
||||
" ==============================================================================
|
||||
" FB_SetHighlighting: sets syntax highlighting for the buffer {{{
|
||||
" Description:
|
||||
" Origin: from explorer.vim in vim
|
||||
function! <SID>FB_SetHighlighting()
|
||||
" Set up syntax highlighting
|
||||
" Something wrong with the evaluation of the conditional though...
|
||||
if has("syntax") && exists("g:syntax_on") && !has("syntax_items")
|
||||
syn match browseSynopsis "^\"[ -].*"
|
||||
syn match browseDirectory "[^\"].*/ "
|
||||
syn match browseDirectory "[^\"].*/$"
|
||||
syn match browseCurDir "^\"= .*$"
|
||||
syn match browseSortBy "^\" Sorted by .*$" contains=browseSuffixInfo
|
||||
syn match browseSuffixInfo "(.*)$" contained
|
||||
syn match browseFilter "^\" Not Showing:.*$"
|
||||
syn match browseFiletime "«\d\+$"
|
||||
|
||||
"hi def link browseSynopsis PreProc
|
||||
hi def link browseSynopsis Special
|
||||
hi def link browseDirectory Directory
|
||||
hi def link browseCurDir Statement
|
||||
hi def link browseSortBy String
|
||||
hi def link browseSuffixInfo Type
|
||||
hi def link browseFilter String
|
||||
hi def link browseFiletime Ignore
|
||||
hi def link browseSuffixes Type
|
||||
endif
|
||||
endfunction " }}}
|
||||
" FB_SetMaps: sets buffer local maps {{{
|
||||
" Description:
|
||||
function! <SID>FB_SetMaps()
|
||||
nnoremap <buffer> <silent> q :bdelete<cr>
|
||||
nnoremap <buffer> <silent> C :call FB_DisplayFiles(getcwd())<CR>
|
||||
nnoremap <buffer> <silent> <esc> :bdelete<cr>
|
||||
nnoremap <buffer> <silent> <CR> :call <SID>FB_EditEntry()<CR>
|
||||
nnoremap <buffer> <silent> ? :call <SID>FB_ToggleHelp()<CR>
|
||||
|
||||
" lock the user in this window
|
||||
nnoremap <buffer> <C-w> <nop>
|
||||
endfunction " }}}
|
||||
" FB_SetSilentSettings: some settings which make things silent {{{
|
||||
" Description:
|
||||
" Origin: from explorer.vim distributed with vim.
|
||||
function! <SID>FB_SetSilentSettings()
|
||||
let s:save_report=&report
|
||||
let s:save_showcmd = &sc
|
||||
set report=10000 noshowcmd
|
||||
endfunction
|
||||
" FB_ResetSilentSettings: reset settings set by FB_SetSilentSettings
|
||||
" Description:
|
||||
function! <SID>FB_ResetSilentSettings()
|
||||
let &report=s:save_report
|
||||
let &showcmd = s:save_showcmd
|
||||
endfunction " }}}
|
||||
" FB_SetScratchSettings: makes the present buffer a scratch buffer {{{
|
||||
" Description:
|
||||
function! <SID>FB_SetScratchSettings()
|
||||
" Turn off the swapfile, set the buffer type so that it won't get
|
||||
" written, and so that it will get deleted when it gets hidden.
|
||||
setlocal noreadonly modifiable
|
||||
setlocal noswapfile
|
||||
setlocal buftype=nowrite
|
||||
setlocal bufhidden=delete
|
||||
" Don't wrap around long lines
|
||||
setlocal nowrap
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" FB_ToggleHelp: toggles verbosity of help {{{
|
||||
" Description:
|
||||
function! <SID>FB_ToggleHelp()
|
||||
let s:FB_VerboseHelp = 1 - s:FB_GetVar('FB_VerboseHelp', 0)
|
||||
|
||||
call FB_DisplayFiles('.')
|
||||
endfunction " }}}
|
||||
" FB_DisplayHelp: displays a helpful header {{{
|
||||
" Description:
|
||||
function! <SID>FB_DisplayHelp()
|
||||
let verboseHelp = s:FB_GetVar('FB_VerboseHelp', 0)
|
||||
if verboseHelp
|
||||
let txt =
|
||||
\ "\" <cr>: on file, choose the file and quit\n"
|
||||
\ ."\" on dir, enter directory\n"
|
||||
\ ."\" q/<esc>: quit without choosing\n"
|
||||
\ ."\" C: change directory to getcwd()\n"
|
||||
\ ."\" ?: toggle help verbosity\n"
|
||||
\ ."\"= ".getcwd()
|
||||
else
|
||||
let txt = "\" ?: toggle help verbosity\n"
|
||||
\ ."\"= ".getcwd()
|
||||
endif
|
||||
0put!=txt
|
||||
endfunction " }}}
|
||||
" FB_EditEntry: handles the user pressing <enter> on a line {{{
|
||||
" Description:
|
||||
function! <SID>FB_EditEntry()
|
||||
let line = getline('.')
|
||||
|
||||
if isdirectory(line)
|
||||
call FB_DisplayFiles(line)
|
||||
endif
|
||||
|
||||
" If the user has a call back function defined on choosing a file, handle
|
||||
" it.
|
||||
let cbf = s:FB_GetVar('FB_CallBackFunction', '')
|
||||
if cbf != '' && line !~ '^" ' && filereadable(line)
|
||||
let fname = fnamemodify(line, ':p')
|
||||
bdelete
|
||||
|
||||
let arguments = s:FB_GetVar('FB_CallBackFunctionArgs', '')
|
||||
if arguments != ''
|
||||
let arguments = ','.arguments
|
||||
endif
|
||||
call Tex_Debug('arguments = '.arguments, 'fb')
|
||||
call Tex_Debug("call ".cbf."('".fname."'".arguments.')', 'fb')
|
||||
exec "call ".cbf."('".fname."'".arguments.')'
|
||||
endif
|
||||
endfunction " }}}
|
||||
" FB_GetVar: gets the most local value of a variable {{{
|
||||
function! <SID>FB_GetVar(name, default)
|
||||
if exists('s:'.a:name)
|
||||
return s:{a:name}
|
||||
elseif exists('w:'.a:name)
|
||||
return w:{a:name}
|
||||
elseif exists('b:'.a:name)
|
||||
return b:{a:name}
|
||||
elseif exists('g:'.a:name)
|
||||
return g:{a:name}
|
||||
else
|
||||
return a:default
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
|
||||
" vim:fdm=marker:ff=unix:noet:ts=4:sw=4:nowrap
|
832
vim/vim-latex/plugin/imaps.vim
Executable file
832
vim/vim-latex/plugin/imaps.vim
Executable file
|
@ -0,0 +1,832 @@
|
|||
" File: imaps.vim
|
||||
" Authors: Srinath Avadhanula <srinath AT fastmail.fm>
|
||||
" Benji Fisher <benji AT member.AMS.org>
|
||||
"
|
||||
" WWW: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/vim-latex/vimfiles/plugin/imaps.vim?only_with_tag=MAIN
|
||||
"
|
||||
" Description: insert mode template expander with cursor placement
|
||||
" while preserving filetype indentation.
|
||||
"
|
||||
" $Id: imaps.vim 997 2006-03-20 09:45:45Z srinathava $
|
||||
"
|
||||
" Documentation: {{{
|
||||
"
|
||||
" Motivation:
|
||||
" this script provides a way to generate insert mode mappings which do not
|
||||
" suffer from some of the problem of mappings and abbreviations while allowing
|
||||
" cursor placement after the expansion. It can alternatively be thought of as
|
||||
" a template expander.
|
||||
"
|
||||
" Consider an example. If you do
|
||||
"
|
||||
" imap lhs something
|
||||
"
|
||||
" then a mapping is set up. However, there will be the following problems:
|
||||
" 1. the 'ttimeout' option will generally limit how easily you can type the
|
||||
" lhs. if you type the left hand side too slowly, then the mapping will not
|
||||
" be activated.
|
||||
" 2. if you mistype one of the letters of the lhs, then the mapping is
|
||||
" deactivated as soon as you backspace to correct the mistake.
|
||||
"
|
||||
" If, in order to take care of the above problems, you do instead
|
||||
"
|
||||
" iab lhs something
|
||||
"
|
||||
" then the timeout problem is solved and so is the problem of mistyping.
|
||||
" however, abbreviations are only expanded after typing a non-word character.
|
||||
" which causes problems of cursor placement after the expansion and invariably
|
||||
" spurious spaces are inserted.
|
||||
"
|
||||
" Usage Example:
|
||||
" this script attempts to solve all these problems by providing an emulation
|
||||
" of imaps wchich does not suffer from its attendant problems. Because maps
|
||||
" are activated without having to press additional characters, therefore
|
||||
" cursor placement is possible. furthermore, file-type specific indentation is
|
||||
" preserved, because the rhs is expanded as if the rhs is typed in literally
|
||||
" by the user.
|
||||
"
|
||||
" The script already provides some default mappings. each "mapping" is of the
|
||||
" form:
|
||||
"
|
||||
" call IMAP (lhs, rhs, ft)
|
||||
"
|
||||
" Some characters in the RHS have special meaning which help in cursor
|
||||
" placement.
|
||||
"
|
||||
" Example One:
|
||||
"
|
||||
" call IMAP ("bit`", "\\begin{itemize}\<cr>\\item <++>\<cr>\\end{itemize}<++>", "tex")
|
||||
"
|
||||
" This effectively sets up the map for "bit`" whenever you edit a latex file.
|
||||
" When you type in this sequence of letters, the following text is inserted:
|
||||
"
|
||||
" \begin{itemize}
|
||||
" \item *
|
||||
" \end{itemize}<++>
|
||||
"
|
||||
" where * shows the cursor position. The cursor position after inserting the
|
||||
" text is decided by the position of the first "place-holder". Place holders
|
||||
" are special characters which decide cursor placement and movement. In the
|
||||
" example above, the place holder characters are <+ and +>. After you have typed
|
||||
" in the item, press <C-j> and you will be taken to the next set of <++>'s.
|
||||
" Therefore by placing the <++> characters appropriately, you can minimize the
|
||||
" use of movement keys.
|
||||
"
|
||||
" NOTE: Set g:Imap_UsePlaceHolders to 0 to disable placeholders altogether.
|
||||
" Set
|
||||
" g:Imap_PlaceHolderStart and g:Imap_PlaceHolderEnd
|
||||
" to something else if you want different place holder characters.
|
||||
" Also, b:Imap_PlaceHolderStart and b:Imap_PlaceHolderEnd override the values
|
||||
" of g:Imap_PlaceHolderStart and g:Imap_PlaceHolderEnd respectively. This is
|
||||
" useful for setting buffer specific place hoders.
|
||||
"
|
||||
" Example Two:
|
||||
" You can use the <C-r> command to insert dynamic elements such as dates.
|
||||
" call IMAP ('date`', "\<c-r>=strftime('%b %d %Y')\<cr>", '')
|
||||
"
|
||||
" sets up the map for date` to insert the current date.
|
||||
"
|
||||
"--------------------------------------%<--------------------------------------
|
||||
" Bonus: This script also provides a command Snip which puts tearoff strings,
|
||||
" '----%<----' above and below the visually selected range of lines. The
|
||||
" length of the string is chosen to be equal to the longest line in the range.
|
||||
" Recommended Usage:
|
||||
" '<,'>Snip
|
||||
"--------------------------------------%<--------------------------------------
|
||||
" }}}
|
||||
|
||||
" line continuation used here.
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" ==============================================================================
|
||||
" Script Options / Variables
|
||||
" ==============================================================================
|
||||
" Options {{{
|
||||
if !exists('g:Imap_StickyPlaceHolders')
|
||||
let g:Imap_StickyPlaceHolders = 1
|
||||
endif
|
||||
if !exists('g:Imap_DeleteEmptyPlaceHolders')
|
||||
let g:Imap_DeleteEmptyPlaceHolders = 1
|
||||
endif
|
||||
" }}}
|
||||
" Variables {{{
|
||||
" s:LHS_{ft}_{char} will be generated automatically. It will look like
|
||||
" s:LHS_tex_o = 'fo\|foo\|boo' and contain all mapped sequences ending in "o".
|
||||
" s:Map_{ft}_{lhs} will be generated automatically. It will look like
|
||||
" s:Map_c_foo = 'for(<++>; <++>; <++>)', the mapping for "foo".
|
||||
"
|
||||
" }}}
|
||||
|
||||
" ==============================================================================
|
||||
" functions for easy insert mode mappings.
|
||||
" ==============================================================================
|
||||
" IMAP: Adds a "fake" insert mode mapping. {{{
|
||||
" For example, doing
|
||||
" IMAP('abc', 'def' ft)
|
||||
" will mean that if the letters abc are pressed in insert mode, then
|
||||
" they will be replaced by def. If ft != '', then the "mapping" will be
|
||||
" specific to the files of type ft.
|
||||
"
|
||||
" Using IMAP has a few advantages over simply doing:
|
||||
" imap abc def
|
||||
" 1. with imap, if you begin typing abc, the cursor will not advance and
|
||||
" long as there is a possible completion, the letters a, b, c will be
|
||||
" displayed on on top of the other. using this function avoids that.
|
||||
" 2. with imap, if a backspace or arrow key is pressed before completing
|
||||
" the word, then the mapping is lost. this function allows movement.
|
||||
" (this ofcourse means that this function is only limited to
|
||||
" left-hand-sides which do not have movement keys or unprintable
|
||||
" characters)
|
||||
" It works by only mapping the last character of the left-hand side.
|
||||
" when this character is typed in, then a reverse lookup is done and if
|
||||
" the previous characters consititute the left hand side of the mapping,
|
||||
" the previously typed characters and erased and the right hand side is
|
||||
" inserted
|
||||
|
||||
" IMAP: set up a filetype specific mapping.
|
||||
" Description:
|
||||
" "maps" the lhs to rhs in files of type 'ft'. If supplied with 2
|
||||
" additional arguments, then those are assumed to be the placeholder
|
||||
" characters in rhs. If unspecified, then the placeholder characters
|
||||
" are assumed to be '<+' and '+>' These placeholder characters in
|
||||
" a:rhs are replaced with the users setting of
|
||||
" [bg]:Imap_PlaceHolderStart and [bg]:Imap_PlaceHolderEnd settings.
|
||||
"
|
||||
function! IMAP(lhs, rhs, ft, ...)
|
||||
|
||||
" Find the place holders to save for IMAP_PutTextWithMovement() .
|
||||
if a:0 < 2
|
||||
let phs = '<+'
|
||||
let phe = '+>'
|
||||
else
|
||||
let phs = a:1
|
||||
let phe = a:2
|
||||
endif
|
||||
|
||||
let hash = s:Hash(a:lhs)
|
||||
let s:Map_{a:ft}_{hash} = a:rhs
|
||||
let s:phs_{a:ft}_{hash} = phs
|
||||
let s:phe_{a:ft}_{hash} = phe
|
||||
|
||||
" Add a:lhs to the list of left-hand sides that end with lastLHSChar:
|
||||
let lastLHSChar = a:lhs[strlen(a:lhs)-1]
|
||||
let hash = s:Hash(lastLHSChar)
|
||||
if !exists("s:LHS_" . a:ft . "_" . hash)
|
||||
let s:LHS_{a:ft}_{hash} = escape(a:lhs, '\')
|
||||
else
|
||||
let s:LHS_{a:ft}_{hash} = escape(a:lhs, '\') .'\|'. s:LHS_{a:ft}_{hash}
|
||||
endif
|
||||
|
||||
" map only the last character of the left-hand side.
|
||||
if lastLHSChar == ' '
|
||||
let lastLHSChar = '<space>'
|
||||
end
|
||||
exe 'inoremap <silent>'
|
||||
\ escape(lastLHSChar, '|')
|
||||
\ '<C-r>=<SID>LookupCharacter("' .
|
||||
\ escape(lastLHSChar, '\|"') .
|
||||
\ '")<CR>'
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" IMAP_list: list the rhs and place holders corresponding to a:lhs {{{
|
||||
"
|
||||
" Added mainly for debugging purposes, but maybe worth keeping.
|
||||
function! IMAP_list(lhs)
|
||||
let char = a:lhs[strlen(a:lhs)-1]
|
||||
let charHash = s:Hash(char)
|
||||
if exists("s:LHS_" . &ft ."_". charHash) && a:lhs =~ s:LHS_{&ft}_{charHash}
|
||||
let ft = &ft
|
||||
elseif exists("s:LHS__" . charHash) && a:lhs =~ s:LHS__{charHash}
|
||||
let ft = ""
|
||||
else
|
||||
return ""
|
||||
endif
|
||||
let hash = s:Hash(a:lhs)
|
||||
return "rhs = " . s:Map_{ft}_{hash} . " place holders = " .
|
||||
\ s:phs_{ft}_{hash} . " and " . s:phe_{ft}_{hash}
|
||||
endfunction
|
||||
" }}}
|
||||
" LookupCharacter: inserts mapping corresponding to this character {{{
|
||||
"
|
||||
" This function extracts from s:LHS_{&ft}_{a:char} or s:LHS__{a:char}
|
||||
" the longest lhs matching the current text. Then it replaces lhs with the
|
||||
" corresponding rhs saved in s:Map_{ft}_{lhs} .
|
||||
" The place-holder variables are passed to IMAP_PutTextWithMovement() .
|
||||
function! s:LookupCharacter(char)
|
||||
if IMAP_GetVal('Imap_FreezeImap', 0) == 1
|
||||
return a:char
|
||||
endif
|
||||
let charHash = s:Hash(a:char)
|
||||
|
||||
" The line so far, including the character that triggered this function:
|
||||
let text = strpart(getline("."), 0, col(".")-1) . a:char
|
||||
" Prefer a local map to a global one, even if the local map is shorter.
|
||||
" Is this what we want? Do we care?
|
||||
" Use '\V' (very no-magic) so that only '\' is special, and it was already
|
||||
" escaped when building up s:LHS_{&ft}_{charHash} .
|
||||
if exists("s:LHS_" . &ft . "_" . charHash)
|
||||
\ && text =~ "\\C\\V\\(" . s:LHS_{&ft}_{charHash} . "\\)\\$"
|
||||
let ft = &ft
|
||||
elseif exists("s:LHS__" . charHash)
|
||||
\ && text =~ "\\C\\V\\(" . s:LHS__{charHash} . "\\)\\$"
|
||||
let ft = ""
|
||||
else
|
||||
" If this is a character which could have been used to trigger an
|
||||
" abbreviation, check if an abbreviation exists.
|
||||
if a:char !~ '\k'
|
||||
let lastword = matchstr(getline('.'), '\k\+$', '')
|
||||
call IMAP_Debug('getting lastword = ['.lastword.']', 'imap')
|
||||
if lastword != ''
|
||||
" An extremeley wierd way to get around the fact that vim
|
||||
" doesn't have the equivalent of the :mapcheck() function for
|
||||
" abbreviations.
|
||||
let _a = @a
|
||||
exec "redir @a | silent! iab ".lastword." | redir END"
|
||||
let abbreviationRHS = matchstr(@a."\n", "\n".'i\s\+'.lastword.'\s\+@\?\zs.*\ze'."\n")
|
||||
|
||||
call IMAP_Debug('getting abbreviationRHS = ['.abbreviationRHS.']', 'imap')
|
||||
|
||||
if @a =~ "No abbreviation found" || abbreviationRHS == ""
|
||||
let @a = _a
|
||||
return a:char
|
||||
endif
|
||||
|
||||
let @a = _a
|
||||
let abbreviationRHS = escape(abbreviationRHS, '\<"')
|
||||
exec 'let abbreviationRHS = "'.abbreviationRHS.'"'
|
||||
|
||||
let lhs = lastword.a:char
|
||||
let rhs = abbreviationRHS.a:char
|
||||
let phs = IMAP_GetPlaceHolderStart()
|
||||
let phe = IMAP_GetPlaceHolderEnd()
|
||||
else
|
||||
return a:char
|
||||
endif
|
||||
else
|
||||
return a:char
|
||||
endif
|
||||
endif
|
||||
" Find the longest left-hand side that matches the line so far.
|
||||
" matchstr() returns the match that starts first. This automatically
|
||||
" ensures that the longest LHS is used for the mapping.
|
||||
if !exists('lhs') || !exists('rhs')
|
||||
let lhs = matchstr(text, "\\C\\V\\(" . s:LHS_{ft}_{charHash} . "\\)\\$")
|
||||
let hash = s:Hash(lhs)
|
||||
let rhs = s:Map_{ft}_{hash}
|
||||
let phs = s:phs_{ft}_{hash}
|
||||
let phe = s:phe_{ft}_{hash}
|
||||
endif
|
||||
|
||||
if strlen(lhs) == 0
|
||||
return a:char
|
||||
endif
|
||||
" enough back-spaces to erase the left-hand side; -1 for the last
|
||||
" character typed:
|
||||
let bs = substitute(strpart(lhs, 1), ".", "\<bs>", "g")
|
||||
" \<c-g>u inserts an undo point
|
||||
return a:char . "\<c-g>u\<bs>" . bs . IMAP_PutTextWithMovement(rhs, phs, phe)
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" IMAP_PutTextWithMovement: returns the string with movement appended {{{
|
||||
" Description:
|
||||
" If a:str contains "placeholders", then appends movement commands to
|
||||
" str in a way that the user moves to the first placeholder and enters
|
||||
" insert or select mode. If supplied with 2 additional arguments, then
|
||||
" they are assumed to be the placeholder specs. Otherwise, they are
|
||||
" assumed to be '<+' and '+>'. These placeholder chars are replaced
|
||||
" with the users settings of [bg]:Imap_PlaceHolderStart and
|
||||
" [bg]:Imap_PlaceHolderEnd.
|
||||
function! IMAP_PutTextWithMovement(str, ...)
|
||||
|
||||
" The placeholders used in the particular input string. These can be
|
||||
" different from what the user wants to use.
|
||||
if a:0 < 2
|
||||
let phs = '<+'
|
||||
let phe = '+>'
|
||||
else
|
||||
let phs = escape(a:1, '\')
|
||||
let phe = escape(a:2, '\')
|
||||
endif
|
||||
|
||||
let text = a:str
|
||||
|
||||
" The user's placeholder settings.
|
||||
let phsUser = IMAP_GetPlaceHolderStart()
|
||||
let pheUser = IMAP_GetPlaceHolderEnd()
|
||||
|
||||
" Problem: depending on the setting of the 'encoding' option, a character
|
||||
" such as "\xab" may not match itself. We try to get around this by
|
||||
" changing the encoding of all our strings. At the end, we have to
|
||||
" convert text back.
|
||||
let phsEnc = s:Iconv(phs, "encode")
|
||||
let pheEnc = s:Iconv(phe, "encode")
|
||||
let phsUserEnc = s:Iconv(phsUser, "encode")
|
||||
let pheUserEnc = s:Iconv(pheUser, "encode")
|
||||
let textEnc = s:Iconv(text, "encode")
|
||||
if textEnc != text
|
||||
let textEncoded = 1
|
||||
else
|
||||
let textEncoded = 0
|
||||
endif
|
||||
|
||||
let pattern = '\V\(\.\{-}\)' .phs. '\(\.\{-}\)' .phe. '\(\.\*\)'
|
||||
" If there are no placeholders, just return the text.
|
||||
if textEnc !~ pattern
|
||||
call IMAP_Debug('Not getting '.phs.' and '.phe.' in '.textEnc, 'imap')
|
||||
return text
|
||||
endif
|
||||
" Break text up into "initial <+template+> final"; any piece may be empty.
|
||||
let initialEnc = substitute(textEnc, pattern, '\1', '')
|
||||
let templateEnc = substitute(textEnc, pattern, '\2', '')
|
||||
let finalEnc = substitute(textEnc, pattern, '\3', '')
|
||||
|
||||
" If the user does not want to use placeholders, then remove all but the
|
||||
" first placeholder.
|
||||
" Otherwise, replace all occurences of the placeholders here with the
|
||||
" user's choice of placeholder settings.
|
||||
if exists('g:Imap_UsePlaceHolders') && !g:Imap_UsePlaceHolders
|
||||
let finalEnc = substitute(finalEnc, '\V'.phs.'\.\{-}'.phe, '', 'g')
|
||||
else
|
||||
let finalEnc = substitute(finalEnc, '\V'.phs.'\(\.\{-}\)'.phe,
|
||||
\ phsUserEnc.'\1'.pheUserEnc, 'g')
|
||||
endif
|
||||
|
||||
" The substitutions are done, so convert back, if necessary.
|
||||
if textEncoded
|
||||
let initial = s:Iconv(initialEnc, "decode")
|
||||
let template = s:Iconv(templateEnc, "decode")
|
||||
let final = s:Iconv(finalEnc, "decode")
|
||||
else
|
||||
let initial = initialEnc
|
||||
let template = templateEnc
|
||||
let final = finalEnc
|
||||
endif
|
||||
|
||||
" Build up the text to insert:
|
||||
" 1. the initial text plus an extra character;
|
||||
" 2. go to Normal mode with <C-\><C-N>, so it works even if 'insertmode'
|
||||
" is set, and mark the position;
|
||||
" 3. replace the extra character with tamplate and final;
|
||||
" 4. back to Normal mode and restore the cursor position;
|
||||
" 5. call IMAP_Jumpfunc().
|
||||
let template = phsUser . template . pheUser
|
||||
" Old trick: insert and delete a character to get the same behavior at
|
||||
" start, middle, or end of line and on empty lines.
|
||||
let text = initial . "X\<C-\>\<C-N>:call IMAP_Mark('set')\<CR>\"_s"
|
||||
let text = text . template . final
|
||||
let text = text . "\<C-\>\<C-N>:call IMAP_Mark('go')\<CR>"
|
||||
let text = text . "i\<C-r>=IMAP_Jumpfunc('', 1)\<CR>"
|
||||
|
||||
call IMAP_Debug('IMAP_PutTextWithMovement: text = ['.text.']', 'imap')
|
||||
return text
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" IMAP_Jumpfunc: takes user to next <+place-holder+> {{{
|
||||
" Author: Luc Hermitte
|
||||
" Arguments:
|
||||
" direction: flag for the search() function. If set to '', search forwards,
|
||||
" if 'b', then search backwards. See the {flags} argument of the
|
||||
" |search()| function for valid values.
|
||||
" inclusive: In vim, the search() function is 'exclusive', i.e we always goto
|
||||
" next cursor match even if there is a match starting from the
|
||||
" current cursor position. Setting this argument to 1 makes
|
||||
" IMAP_Jumpfunc() also respect a match at the current cursor
|
||||
" position. 'inclusive'ness is necessary for IMAP() because a
|
||||
" placeholder string can occur at the very beginning of a map which
|
||||
" we want to select.
|
||||
" We use a non-zero value only in special conditions. Most mappings
|
||||
" should use a zero value.
|
||||
function! IMAP_Jumpfunc(direction, inclusive)
|
||||
|
||||
" The user's placeholder settings.
|
||||
let phsUser = IMAP_GetPlaceHolderStart()
|
||||
let pheUser = IMAP_GetPlaceHolderEnd()
|
||||
|
||||
let searchString = ''
|
||||
" If this is not an inclusive search or if it is inclusive, but the
|
||||
" current cursor position does not contain a placeholder character, then
|
||||
" search for the placeholder characters.
|
||||
if !a:inclusive || strpart(getline('.'), col('.')-1) !~ '\V\^'.phsUser
|
||||
let searchString = '\V'.phsUser.'\_.\{-}'.pheUser
|
||||
endif
|
||||
|
||||
" If we didn't find any placeholders return quietly.
|
||||
if searchString != '' && !search(searchString, a:direction)
|
||||
return ''
|
||||
endif
|
||||
|
||||
" Open any closed folds and make this part of the text visible.
|
||||
silent! foldopen!
|
||||
|
||||
" Calculate if we have an empty placeholder or if it contains some
|
||||
" description.
|
||||
let template =
|
||||
\ matchstr(strpart(getline('.'), col('.')-1),
|
||||
\ '\V\^'.phsUser.'\zs\.\{-}\ze\('.pheUser.'\|\$\)')
|
||||
let placeHolderEmpty = !strlen(template)
|
||||
|
||||
" If we are selecting in exclusive mode, then we need to move one step to
|
||||
" the right
|
||||
let extramove = ''
|
||||
if &selection == 'exclusive'
|
||||
let extramove = 'l'
|
||||
endif
|
||||
|
||||
" Select till the end placeholder character.
|
||||
let movement = "\<C-o>v/\\V".pheUser."/e\<CR>".extramove
|
||||
|
||||
" First remember what the search pattern was. s:RemoveLastHistoryItem will
|
||||
" reset @/ to this pattern so we do not create new highlighting.
|
||||
let g:Tex_LastSearchPattern = @/
|
||||
|
||||
" Now either goto insert mode or select mode.
|
||||
if placeHolderEmpty && g:Imap_DeleteEmptyPlaceHolders
|
||||
" delete the empty placeholder into the blackhole.
|
||||
return movement."\"_c\<C-o>:".s:RemoveLastHistoryItem."\<CR>"
|
||||
else
|
||||
return movement."\<C-\>\<C-N>:".s:RemoveLastHistoryItem."\<CR>gv\<C-g>"
|
||||
endif
|
||||
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" Maps for IMAP_Jumpfunc {{{
|
||||
"
|
||||
" These mappings use <Plug> and thus provide for easy user customization. When
|
||||
" the user wants to map some other key to jump forward, he can do for
|
||||
" instance:
|
||||
" nmap ,f <plug>IMAP_JumpForward
|
||||
" etc.
|
||||
|
||||
" jumping forward and back in insert mode.
|
||||
imap <silent> <Plug>IMAP_JumpForward <c-r>=IMAP_Jumpfunc('', 0)<CR>
|
||||
imap <silent> <Plug>IMAP_JumpBack <c-r>=IMAP_Jumpfunc('b', 0)<CR>
|
||||
|
||||
" jumping in normal mode
|
||||
nmap <silent> <Plug>IMAP_JumpForward i<c-r>=IMAP_Jumpfunc('', 0)<CR>
|
||||
nmap <silent> <Plug>IMAP_JumpBack i<c-r>=IMAP_Jumpfunc('b', 0)<CR>
|
||||
|
||||
" deleting the present selection and then jumping forward.
|
||||
vmap <silent> <Plug>IMAP_DeleteAndJumpForward "_<Del>i<c-r>=IMAP_Jumpfunc('', 0)<CR>
|
||||
vmap <silent> <Plug>IMAP_DeleteAndJumpBack "_<Del>i<c-r>=IMAP_Jumpfunc('b', 0)<CR>
|
||||
|
||||
" jumping forward without deleting present selection.
|
||||
vmap <silent> <Plug>IMAP_JumpForward <C-\><C-N>i<c-r>=IMAP_Jumpfunc('', 0)<CR>
|
||||
vmap <silent> <Plug>IMAP_JumpBack <C-\><C-N>`<i<c-r>=IMAP_Jumpfunc('b', 0)<CR>
|
||||
|
||||
" }}}
|
||||
" Default maps for IMAP_Jumpfunc {{{
|
||||
" map only if there is no mapping already. allows for user customization.
|
||||
" NOTE: Default mappings for jumping to the previous placeholder are not
|
||||
" provided. It is assumed that if the user will create such mappings
|
||||
" hself if e so desires.
|
||||
if !hasmapto('<Plug>IMAP_JumpForward', 'i')
|
||||
imap <C-J> <Plug>IMAP_JumpForward
|
||||
endif
|
||||
if !hasmapto('<Plug>IMAP_JumpForward', 'n')
|
||||
nmap <C-J> <Plug>IMAP_JumpForward
|
||||
endif
|
||||
if exists('g:Imap_StickyPlaceHolders') && g:Imap_StickyPlaceHolders
|
||||
if !hasmapto('<Plug>IMAP_JumpForward', 'v')
|
||||
vmap <C-J> <Plug>IMAP_JumpForward
|
||||
endif
|
||||
else
|
||||
if !hasmapto('<Plug>IMAP_DeleteAndJumpForward', 'v')
|
||||
vmap <C-J> <Plug>IMAP_DeleteAndJumpForward
|
||||
endif
|
||||
endif
|
||||
" }}}
|
||||
|
||||
nmap <silent> <script> <plug><+SelectRegion+> `<v`>
|
||||
|
||||
" ==============================================================================
|
||||
" enclosing selected region.
|
||||
" ==============================================================================
|
||||
" VEnclose: encloses the visually selected region with given arguments {{{
|
||||
" Description: allows for differing action based on visual line wise
|
||||
" selection or visual characterwise selection. preserves the
|
||||
" marks and search history.
|
||||
function! VEnclose(vstart, vend, VStart, VEnd)
|
||||
|
||||
" its characterwise if
|
||||
" 1. characterwise selection and valid values for vstart and vend.
|
||||
" OR
|
||||
" 2. linewise selection and invalid values for VStart and VEnd
|
||||
if (visualmode() ==# 'v' && (a:vstart != '' || a:vend != '')) || (a:VStart == '' && a:VEnd == '')
|
||||
|
||||
let newline = ""
|
||||
let _r = @r
|
||||
|
||||
let normcmd = "normal! \<C-\>\<C-n>`<v`>\"_s"
|
||||
|
||||
exe "normal! \<C-\>\<C-n>`<v`>\"ry"
|
||||
if @r =~ "\n$"
|
||||
let newline = "\n"
|
||||
let @r = substitute(@r, "\n$", '', '')
|
||||
endif
|
||||
|
||||
" In exclusive selection, we need to select an extra character.
|
||||
if &selection == 'exclusive'
|
||||
let movement = 8
|
||||
else
|
||||
let movement = 7
|
||||
endif
|
||||
let normcmd = normcmd.
|
||||
\ a:vstart."!!mark!!".a:vend.newline.
|
||||
\ "\<C-\>\<C-N>?!!mark!!\<CR>v".movement."l\"_s\<C-r>r\<C-\>\<C-n>"
|
||||
|
||||
" this little if statement is because till very recently, vim used to
|
||||
" report col("'>") > length of selected line when `> is $. on some
|
||||
" systems it reports a -ve number.
|
||||
if col("'>") < 0 || col("'>") > strlen(getline("'>"))
|
||||
let lastcol = strlen(getline("'>"))
|
||||
else
|
||||
let lastcol = col("'>")
|
||||
endif
|
||||
if lastcol - col("'<") != 0
|
||||
let len = lastcol - col("'<")
|
||||
else
|
||||
let len = ''
|
||||
endif
|
||||
|
||||
" the next normal! is for restoring the marks.
|
||||
let normcmd = normcmd."`<v".len."l\<C-\>\<C-N>"
|
||||
|
||||
" First remember what the search pattern was. s:RemoveLastHistoryItem
|
||||
" will reset @/ to this pattern so we do not create new highlighting.
|
||||
let g:Tex_LastSearchPattern = @/
|
||||
|
||||
silent! exe normcmd
|
||||
" this is to restore the r register.
|
||||
let @r = _r
|
||||
" and finally, this is to restore the search history.
|
||||
execute s:RemoveLastHistoryItem
|
||||
|
||||
else
|
||||
|
||||
exec 'normal! `<O'.a:VStart."\<C-\>\<C-n>"
|
||||
exec 'normal! `>o'.a:VEnd."\<C-\>\<C-n>"
|
||||
if &indentexpr != ''
|
||||
silent! normal! `<kV`>j=
|
||||
endif
|
||||
silent! normal! `>
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
" ExecMap: adds the ability to correct an normal/visual mode mapping. {{{
|
||||
" Author: Hari Krishna Dara <hari_vim@yahoo.com>
|
||||
" Reads a normal mode mapping at the command line and executes it with the
|
||||
" given prefix. Press <BS> to correct and <Esc> to cancel.
|
||||
function! ExecMap(prefix, mode)
|
||||
" Temporarily remove the mapping, otherwise it will interfere with the
|
||||
" mapcheck call below:
|
||||
let myMap = maparg(a:prefix, a:mode)
|
||||
exec a:mode."unmap ".a:prefix
|
||||
|
||||
" Generate a line with spaces to clear the previous message.
|
||||
let i = 1
|
||||
let clearLine = "\r"
|
||||
while i < &columns
|
||||
let clearLine = clearLine . ' '
|
||||
let i = i + 1
|
||||
endwhile
|
||||
|
||||
let mapCmd = a:prefix
|
||||
let foundMap = 0
|
||||
let breakLoop = 0
|
||||
echon "\rEnter Map: " . mapCmd
|
||||
while !breakLoop
|
||||
let char = getchar()
|
||||
if char !~ '^\d\+$'
|
||||
if char == "\<BS>"
|
||||
let mapCmd = strpart(mapCmd, 0, strlen(mapCmd) - 1)
|
||||
endif
|
||||
else " It is the ascii code.
|
||||
let char = nr2char(char)
|
||||
if char == "\<Esc>"
|
||||
let breakLoop = 1
|
||||
else
|
||||
let mapCmd = mapCmd . char
|
||||
if maparg(mapCmd, a:mode) != ""
|
||||
let foundMap = 1
|
||||
let breakLoop = 1
|
||||
elseif mapcheck(mapCmd, a:mode) == ""
|
||||
let mapCmd = strpart(mapCmd, 0, strlen(mapCmd) - 1)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
echon clearLine
|
||||
echon "\rEnter Map: " . mapCmd
|
||||
endwhile
|
||||
if foundMap
|
||||
if a:mode == 'v'
|
||||
" use a plug to select the region instead of using something like
|
||||
" `<v`> to avoid problems caused by some of the characters in
|
||||
" '`<v`>' being mapped.
|
||||
let gotoc = "\<plug><+SelectRegion+>"
|
||||
else
|
||||
let gotoc = ''
|
||||
endif
|
||||
exec "normal ".gotoc.mapCmd
|
||||
endif
|
||||
exec a:mode.'noremap '.a:prefix.' '.myMap
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
" ==============================================================================
|
||||
" helper functions
|
||||
" ==============================================================================
|
||||
" Strntok: extract the n^th token from a list {{{
|
||||
" example: Strntok('1,23,3', ',', 2) = 23
|
||||
fun! <SID>Strntok(s, tok, n)
|
||||
return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}')
|
||||
endfun
|
||||
|
||||
" }}}
|
||||
" s:RemoveLastHistoryItem: removes last search item from search history {{{
|
||||
" Description: Execute this string to clean up the search history.
|
||||
let s:RemoveLastHistoryItem = ':call histdel("/", -1)|let @/=g:Tex_LastSearchPattern'
|
||||
|
||||
" }}}
|
||||
" s:Hash: Return a version of a string that can be used as part of a variable" {{{
|
||||
" name.
|
||||
" Converts every non alphanumeric character into _{ascii}_ where {ascii} is
|
||||
" the ASCII code for that character...
|
||||
fun! s:Hash(text)
|
||||
return substitute(a:text, '\([^[:alnum:]]\)',
|
||||
\ '\="_".char2nr(submatch(1))."_"', 'g')
|
||||
endfun
|
||||
"" }}}
|
||||
" IMAP_GetPlaceHolderStart and IMAP_GetPlaceHolderEnd: "{{{
|
||||
" return the buffer local placeholder variables, or the global one, or the default.
|
||||
function! IMAP_GetPlaceHolderStart()
|
||||
if exists("b:Imap_PlaceHolderStart") && strlen(b:Imap_PlaceHolderEnd)
|
||||
return b:Imap_PlaceHolderStart
|
||||
elseif exists("g:Imap_PlaceHolderStart") && strlen(g:Imap_PlaceHolderEnd)
|
||||
return g:Imap_PlaceHolderStart
|
||||
else
|
||||
return "<+"
|
||||
endfun
|
||||
function! IMAP_GetPlaceHolderEnd()
|
||||
if exists("b:Imap_PlaceHolderEnd") && strlen(b:Imap_PlaceHolderEnd)
|
||||
return b:Imap_PlaceHolderEnd
|
||||
elseif exists("g:Imap_PlaceHolderEnd") && strlen(g:Imap_PlaceHolderEnd)
|
||||
return g:Imap_PlaceHolderEnd
|
||||
else
|
||||
return "+>"
|
||||
endfun
|
||||
" }}}
|
||||
" s:Iconv: a wrapper for iconv()" {{{
|
||||
" Problem: after
|
||||
" let text = "\xab"
|
||||
" (or using the raw 8-bit ASCII character in a file with 'fenc' set to
|
||||
" "latin1") if 'encoding' is set to utf-8, then text does not match itself:
|
||||
" echo text =~ text
|
||||
" returns 0.
|
||||
" Solution: When this happens, a re-encoded version of text does match text:
|
||||
" echo iconv(text, "latin1", "utf8") =~ text
|
||||
" returns 1. In this case, convert text to utf-8 with iconv().
|
||||
" TODO: Is it better to use &encoding instead of "utf8"? Internally, vim
|
||||
" uses utf-8, and can convert between latin1 and utf-8 even when compiled with
|
||||
" -iconv, so let's try using utf-8.
|
||||
" Arguments:
|
||||
" a:text = text to be encoded or decoded
|
||||
" a:mode = "encode" (latin1 to utf8) or "decode" (utf8 to latin1)
|
||||
" Caution: do not encode and then decode without checking whether the text
|
||||
" has changed, becuase of the :if clause in encoding!
|
||||
function! s:Iconv(text, mode)
|
||||
if a:mode == "decode"
|
||||
return iconv(a:text, "utf8", "latin1")
|
||||
endif
|
||||
if a:text =~ '\V\^' . escape(a:text, '\') . '\$'
|
||||
return a:text
|
||||
endif
|
||||
let textEnc = iconv(a:text, "latin1", "utf8")
|
||||
if textEnc !~ '\V\^' . escape(a:text, '\') . '\$'
|
||||
call IMAP_Debug('Encoding problems with text '.a:text.' ', 'imap')
|
||||
endif
|
||||
return textEnc
|
||||
endfun
|
||||
"" }}}
|
||||
" IMAP_Debug: interface to Tex_Debug if available, otherwise emulate it {{{
|
||||
" Description:
|
||||
" Do not want a memory leak! Set this to zero so that imaps always
|
||||
" starts out in a non-debugging mode.
|
||||
if !exists('g:Imap_Debug')
|
||||
let g:Imap_Debug = 0
|
||||
endif
|
||||
function! IMAP_Debug(string, pattern)
|
||||
if !g:Imap_Debug
|
||||
return
|
||||
endif
|
||||
if exists('*Tex_Debug')
|
||||
call Tex_Debug(a:string, a:pattern)
|
||||
else
|
||||
if !exists('s:debug_'.a:pattern)
|
||||
let s:debug_{a:pattern} = a:string
|
||||
else
|
||||
let s:debug_{a:pattern} = s:debug_{a:pattern}.a:string
|
||||
endif
|
||||
endif
|
||||
endfunction " }}}
|
||||
" IMAP_DebugClear: interface to Tex_DebugClear if avaialable, otherwise emulate it {{{
|
||||
" Description:
|
||||
function! IMAP_DebugClear(pattern)
|
||||
if exists('*Tex_DebugClear')
|
||||
call Tex_DebugClear(a:pattern)
|
||||
else
|
||||
let s:debug_{a:pattern} = ''
|
||||
endif
|
||||
endfunction " }}}
|
||||
" IMAP_PrintDebug: interface to Tex_DebugPrint if avaialable, otherwise emulate it {{{
|
||||
" Description:
|
||||
function! IMAP_PrintDebug(pattern)
|
||||
if exists('*Tex_PrintDebug')
|
||||
call Tex_PrintDebug(a:pattern)
|
||||
else
|
||||
if exists('s:debug_'.a:pattern)
|
||||
echo s:debug_{a:pattern}
|
||||
endif
|
||||
endif
|
||||
endfunction " }}}
|
||||
" IMAP_Mark: Save the cursor position (if a:action == 'set') in a" {{{
|
||||
" script-local variable; restore this position if a:action == 'go'.
|
||||
let s:Mark = "(0,0)"
|
||||
let s:initBlanks = ''
|
||||
function! IMAP_Mark(action)
|
||||
if a:action == 'set'
|
||||
let s:Mark = "(" . line(".") . "," . col(".") . ")"
|
||||
let s:initBlanks = matchstr(getline('.'), '^\s*')
|
||||
elseif a:action == 'go'
|
||||
execute "call cursor" s:Mark
|
||||
let blanksNow = matchstr(getline('.'), '^\s*')
|
||||
if strlen(blanksNow) > strlen(s:initBlanks)
|
||||
execute 'silent! normal! '.(strlen(blanksNow) - strlen(s:initBlanks)).'l'
|
||||
elseif strlen(blanksNow) < strlen(s:initBlanks)
|
||||
execute 'silent! normal! '.(strlen(s:initBlanks) - strlen(blanksNow)).'h'
|
||||
endif
|
||||
endif
|
||||
endfunction "" }}}
|
||||
" IMAP_GetVal: gets the value of a variable {{{
|
||||
" Description: first checks window local, then buffer local etc.
|
||||
function! IMAP_GetVal(name, ...)
|
||||
if a:0 > 0
|
||||
let default = a:1
|
||||
else
|
||||
let default = ''
|
||||
endif
|
||||
if exists('w:'.a:name)
|
||||
return w:{a:name}
|
||||
elseif exists('b:'.a:name)
|
||||
return b:{a:name}
|
||||
elseif exists('g:'.a:name)
|
||||
return g:{a:name}
|
||||
else
|
||||
return default
|
||||
endif
|
||||
endfunction " }}}
|
||||
|
||||
" ==============================================================================
|
||||
" A bonus function: Snip()
|
||||
" ==============================================================================
|
||||
" Snip: puts a scissor string above and below block of text {{{
|
||||
" Desciption:
|
||||
"-------------------------------------%<-------------------------------------
|
||||
" this puts a the string "--------%<---------" above and below the visually
|
||||
" selected block of lines. the length of the 'tearoff' string depends on the
|
||||
" maximum string length in the selected range. this is an aesthetically more
|
||||
" pleasing alternative instead of hardcoding a length.
|
||||
"-------------------------------------%<-------------------------------------
|
||||
function! <SID>Snip() range
|
||||
let i = a:firstline
|
||||
let maxlen = -2
|
||||
" find out the maximum virtual length of each line.
|
||||
while i <= a:lastline
|
||||
exe i
|
||||
let length = virtcol('$')
|
||||
let maxlen = (length > maxlen ? length : maxlen)
|
||||
let i = i + 1
|
||||
endwhile
|
||||
let maxlen = (maxlen > &tw && &tw != 0 ? &tw : maxlen)
|
||||
let half = maxlen/2
|
||||
exe a:lastline
|
||||
" put a string below
|
||||
exe "norm! o\<esc>".(half - 1)."a-\<esc>A%<\<esc>".(half - 1)."a-"
|
||||
" and above. its necessary to put the string below the block of lines
|
||||
" first because that way the first line number doesnt change...
|
||||
exe a:firstline
|
||||
exe "norm! O\<esc>".(half - 1)."a-\<esc>A%<\<esc>".(half - 1)."a-"
|
||||
endfunction
|
||||
|
||||
com! -nargs=0 -range Snip :<line1>,<line2>call <SID>Snip()
|
||||
" }}}
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
|
||||
" vim:ft=vim:ts=4:sw=4:noet:fdm=marker:commentstring=\"\ %s:nowrap
|
249
vim/vim-latex/plugin/libList.vim
Executable file
249
vim/vim-latex/plugin/libList.vim
Executable file
|
@ -0,0 +1,249 @@
|
|||
" File: libList.vim
|
||||
" Last Change: 2001 Dec 10
|
||||
" Maintainer: Gontran BAERTS <gbcreation@free.fr>
|
||||
" Version: 0.1
|
||||
"
|
||||
" Please don't hesitate to correct my english :)
|
||||
" Send corrections to <gbcreation@free.fr>
|
||||
"
|
||||
"-----------------------------------------------------------------------------
|
||||
" Description: libList.vim is a set of functions to work with lists or one
|
||||
" level arrays.
|
||||
"
|
||||
"-----------------------------------------------------------------------------
|
||||
" To Enable: Normally, this file will reside in your plugins directory and be
|
||||
" automatically sourced.
|
||||
"
|
||||
"-----------------------------------------------------------------------------
|
||||
" Usage: Lists are strings variable with values separated by g:listSep
|
||||
" character (comma" by default). You may redefine g:listSep variable as you
|
||||
" wish.
|
||||
"
|
||||
" Here are available functions :
|
||||
"
|
||||
" - AddListItem( array, newItem, index ) :
|
||||
" Add item "newItem" to array "array" at "index" position
|
||||
" - GetListItem( array, index ) :
|
||||
" Return item at "index" position in array "array"
|
||||
" - GetListMatchItem( array, pattern ) :
|
||||
" Return item matching "pattern" in array "array"
|
||||
" - GetListCount( array ) :
|
||||
" Return the number of items in array "array"
|
||||
" - RemoveListItem( array, index ) :
|
||||
" Remove item at "index" position from array "array"
|
||||
" - ReplaceListItem( array, index, item ) :
|
||||
" Remove item at "index" position by "item" in array "array"
|
||||
" - ExchangeListItems( array, item1Index, item2Index ) :
|
||||
" Exchange item "item1Index" with item "item2Index" in array "array"
|
||||
" - QuickSortList( array, beg, end ) :
|
||||
" Return array "array" with items between "beg" and "end" sorted
|
||||
"
|
||||
" Example:
|
||||
" let mylist=""
|
||||
" echo GetListCount( mylist ) " --> 0
|
||||
" let mylist = AddListItem( mylist, "One", 0 ) " mylist == "One"
|
||||
" let mylist = AddListItem( mylist, "Three", 1 ) " mylist == "One,Three"
|
||||
" let mylist = AddListItem( mylist, "Two", 1 ) " mylist == "One,Two,Three"
|
||||
" echo GetListCount( mylist ) " --> 3
|
||||
" echo GetListItem( mylist, 2 ) " --> Three
|
||||
" echo GetListMatchItem( mylist, "w" ) " --> two
|
||||
" echo GetListMatchItem( mylist, "e" ) " --> One
|
||||
" let mylist = RemoveListItem( mylist, 2 ) " mylist == "One,Two"
|
||||
" echo GetListCount( mylist ) " --> 2
|
||||
" let mylist = ReplaceListItem( mylist, 0, "Three" ) " mylist == "Three,Two"
|
||||
" let mylist = ExchangeListItems( mylist, 0, 1 ) " mylist == "Two,Three"
|
||||
" let mylist = AddListItem( mylist, "One", 0 ) " mylist == "One,Two,Three"
|
||||
" let mylist = QuickSortList( mylist, 0, GetListCount(mylist)-1 )
|
||||
" " mylist == "One,Three,Two"
|
||||
"
|
||||
"-----------------------------------------------------------------------------
|
||||
" Updates:
|
||||
" in version 0.1
|
||||
" - First version
|
||||
|
||||
" Has this already been loaded ?
|
||||
if exists("loaded_libList")
|
||||
finish
|
||||
endif
|
||||
let loaded_libList=1
|
||||
|
||||
"**
|
||||
" Separator:
|
||||
" You may change the separator character et any time.
|
||||
"**
|
||||
let g:listSep = ","
|
||||
|
||||
"**
|
||||
"AddListItem:
|
||||
" Add new item at given position.
|
||||
" First item index is 0 (zero).
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values) which receives the new item.
|
||||
" - newItem : String containing the item value to add.
|
||||
" - index : Integer indicating the position at which the new item is added.
|
||||
" It must be greater than or equals to 0 (zero).
|
||||
"Return:
|
||||
"String containing array values, including newItem.
|
||||
"**
|
||||
function AddListItem( array, newItem, index )
|
||||
if a:index == 0
|
||||
if a:array == ""
|
||||
return a:newItem
|
||||
endif
|
||||
return a:newItem . g:listSep . a:array
|
||||
endif
|
||||
return substitute( a:array, '\(\%(^\|' . g:listSep . '\)[^' . g:listSep . ']\+\)\{' . a:index . '\}', '\0' . g:listSep . a:newItem , "" )
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"GetListItem:
|
||||
" Get item at given position.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
" - index : Integer indicating the position of item to return.
|
||||
" It must be greater than or equals to 0 (zero).
|
||||
"Return:
|
||||
"String representing the item.
|
||||
"**
|
||||
function GetListItem( array, index )
|
||||
if a:index == 0
|
||||
return matchstr( a:array, '^[^' . g:listSep . ']\+' )
|
||||
else
|
||||
return matchstr( a:array, "[^" . g:listSep . "]\\+", matchend( a:array, '\(\%(^\|' . g:listSep . '\)[^' . g:listSep . ']\+\)\{' . a:index . '\}' . g:listSep ) )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"GetListMatchItem:
|
||||
" Get the first item matching given pattern.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
" - pattern : Regular expression to match with items.
|
||||
" Avoid to use ^, $ and listSep characters in pattern, unless you
|
||||
" know what you do.
|
||||
"Return:
|
||||
"String representing the first item that matches the pattern.
|
||||
"**
|
||||
function GetListMatchItem( array, pattern )
|
||||
return matchstr( a:array, '[^' . g:listSep . ']*' . a:pattern . '[^' . g:listSep . ']*' )
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"ReplaceListItem:
|
||||
" Replace item at given position by a new one.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
" - index : Integer indicating the position of item to replace.
|
||||
" It must be greater than or equals to 0 (zero).
|
||||
" - item : String containing the new value of the replaced item.
|
||||
"Return:
|
||||
"String containing array values.
|
||||
"**
|
||||
function ReplaceListItem( array, index, item )
|
||||
if a:index == 0
|
||||
return substitute( a:array, '^[^' .g:listSep. ']\+', a:item, "" )
|
||||
else
|
||||
return substitute( a:array, '\(\%(\%(^\|' . g:listSep . '\)[^' . g:listSep . ']\+\)\{' . a:index . '\}\)' . g:listSep . '[^' . g:listSep . ']\+', '\1' . g:listSep . a:item , "" )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"RemoveListItem:
|
||||
" Remove item at given position.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values) from which remove an item.
|
||||
" - index : Integer indicating the position of item to remove.
|
||||
" It must be greater than or equals to 0 (zero).
|
||||
"Return:
|
||||
"String containing array values, except the removed one.
|
||||
"**
|
||||
function RemoveListItem( array, index )
|
||||
if a:index == 0
|
||||
return substitute( a:array, '^[^' .g:listSep. ']\+\(' . g:listSep . '\|$\)', "", "" )
|
||||
else
|
||||
return substitute( a:array, '\(\%(\%(^\|' . g:listSep . '\)[^' . g:listSep . ']\+\)\{' . a:index . '\}\)' . g:listSep . '[^' . g:listSep . ']\+', '\1', "" )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"ExchangeListItems:
|
||||
" Exchange item at position item1Index with item at position item2Index.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
" - item1index : Integer indicating the position of the first item to exchange.
|
||||
" It must be greater than or equals to 0 (zero).
|
||||
" - item2index : Integer indicating the position of the second item to
|
||||
" exchange. It must be greater than or equals to 0 (zero).
|
||||
"Return:
|
||||
"String containing array values.
|
||||
"**
|
||||
function ExchangeListItems( array, item1Index, item2Index )
|
||||
let item1 = GetListItem( a:array, a:item1Index )
|
||||
let array = ReplaceListItem( a:array, a:item1Index, GetListItem( a:array, a:item2Index ) )
|
||||
return ReplaceListItem( array, a:item2Index, item1 )
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"GetListCount:
|
||||
" Number of items in array.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
"Return:
|
||||
"Integer representing the number of items in array.
|
||||
"Index of last item is GetListCount(array)-1.
|
||||
"**
|
||||
function GetListCount( array )
|
||||
if a:array == "" | return 0 | endif
|
||||
let pos = 0
|
||||
let cnt = 0
|
||||
while pos != -1
|
||||
let pos = matchend( a:array, g:listSep, pos )
|
||||
let cnt = cnt + 1
|
||||
endwhile
|
||||
return cnt
|
||||
endfunction
|
||||
|
||||
"**
|
||||
"QuickSortList:
|
||||
" Sort array.
|
||||
"Parameters:
|
||||
" - array : Array/List (string of values).
|
||||
" - beg : Min index of the range of items to sort.
|
||||
" - end : Max index of the range of items to sort.
|
||||
"Return:
|
||||
"String containing array values with indicated range of items sorted.
|
||||
"**
|
||||
function QuickSortList( array, beg, end )
|
||||
let array = a:array
|
||||
let pivot = GetListItem( array, a:beg )
|
||||
let l = a:beg
|
||||
let r = a:end
|
||||
while l < r
|
||||
while GetListItem( array, r ) > pivot
|
||||
let r = r - 1
|
||||
endwhile
|
||||
if l != r
|
||||
let array = ReplaceListItem( array, l, GetListItem( array, r ) )
|
||||
let array = ReplaceListItem( array, r, pivot )
|
||||
let l = l + 1
|
||||
endif
|
||||
|
||||
while GetListItem( array, l ) < pivot
|
||||
let l = l + 1
|
||||
endwhile
|
||||
if l != r
|
||||
let array = ReplaceListItem( array, r, GetListItem( array, l ) )
|
||||
let array = ReplaceListItem( array, l, pivot )
|
||||
let r = r - 1
|
||||
endif
|
||||
endwhile
|
||||
if a:beg < l-1
|
||||
let array = QuickSortList( array, a:beg, l-1 )
|
||||
endif
|
||||
if a:end > l+1
|
||||
let array = QuickSortList( array, l+1, a:end )
|
||||
endif
|
||||
return array
|
||||
endfunction
|
||||
|
||||
|
163
vim/vim-latex/plugin/remoteOpen.vim
Executable file
163
vim/vim-latex/plugin/remoteOpen.vim
Executable file
|
@ -0,0 +1,163 @@
|
|||
" File: remoteOpen.vim
|
||||
" Author: Srinath Avadhanula <srinath AT fastmail DOT fm>
|
||||
" $Id: remoteOpen.vim 1080 2010-01-26 22:02:34Z tmaas $
|
||||
"
|
||||
" Description:
|
||||
" Often times, an external program needs to open a file in gvim from the
|
||||
" command line. However, it will not know if the file is already opened in a
|
||||
" previous vim session. It is not sufficient to simply specify
|
||||
"
|
||||
" gvim --remote-silent <filename>
|
||||
"
|
||||
" because this simply opens up <filename> in the first remote gvim session it
|
||||
" sees. This script provides a command RemoteOpen which is meant to be used
|
||||
" from the command line as follows:
|
||||
"
|
||||
" gvim -c ":RemoteOpen +<lnum> <filename>"
|
||||
"
|
||||
" where <lnum> is the line-number you wish <filename> to open to. What will
|
||||
" happen is that a new gvim will start up and enquire from all previous
|
||||
" sessions if <filename> is already open in any of them. If it is, then it
|
||||
" will edit the file in that session and bring it to the foreground and itself
|
||||
" quit. Otherwise, it will not quit and instead open up the file for editing
|
||||
" at <lnum>.
|
||||
"
|
||||
" This was mainly created to be used with Yap (the dvi previewer in miktex),
|
||||
" so you can specify the program for "inverse search" as specified above.
|
||||
" This ensures that the inverse search uses the correct gvim each time.
|
||||
"
|
||||
" Ofcourse, this requires vim with +clientserver. If not, then RemoteOpen just
|
||||
" opens in the present session.
|
||||
|
||||
" Enclose <args> in single quotes so it can be passed as a function argument.
|
||||
com! -nargs=1 RemoteOpen :call RemoteOpen('<args>')
|
||||
com! -nargs=? RemoteInsert :call RemoteInsert('<args>')
|
||||
|
||||
" RemoteOpen: open a file remotely (if possible) {{{
|
||||
" Description: checks all open vim windows to see if this file has been opened
|
||||
" anywhere and if so, opens it there instead of in this session.
|
||||
function! RemoteOpen(arglist)
|
||||
|
||||
" First construct line number and filename from argument. a:arglist is of
|
||||
" the form:
|
||||
" +10 c:\path\to\file
|
||||
" or just
|
||||
" c:\path\to\file
|
||||
if a:arglist =~ '^\s*+\d\+'
|
||||
let linenum = matchstr(a:arglist, '^\s*+\zs\d\+\ze')
|
||||
let filename = matchstr(a:arglist, '^\s*+\d\+\s*\zs.*\ze')
|
||||
else
|
||||
let linenum = 1
|
||||
let filename = matchstr(a:arglist, '^\s*\zs.*\ze')
|
||||
endif
|
||||
let filename = escape(filename, ' ')
|
||||
call Tex_Debug("linenum = ".linenum.', filename = '.filename, "ropen")
|
||||
|
||||
" If there is no clientserver functionality, then just open in the present
|
||||
" session and return
|
||||
if !has('clientserver')
|
||||
call Tex_Debug("-clientserver, opening locally and returning", "ropen")
|
||||
exec "e ".filename
|
||||
exec linenum
|
||||
normal! zv
|
||||
return
|
||||
endif
|
||||
|
||||
" Otherwise, loop through all available servers
|
||||
let servers = serverlist()
|
||||
" If there are no servers, open file locally.
|
||||
if servers == ''
|
||||
call Tex_Debug("no open servers, opening locally", "ropen")
|
||||
exec "e ".filename
|
||||
exec linenum
|
||||
let g:Remote_Server = 1
|
||||
normal! zv
|
||||
return
|
||||
endif
|
||||
|
||||
let i = 1
|
||||
let server = s:Strntok(servers, "\n", i)
|
||||
let targetServer = v:servername
|
||||
|
||||
while server != ''
|
||||
" Find out if there was any server which was used by remoteOpen before
|
||||
" this. If a new gvim session was ever started via remoteOpen, then
|
||||
" g:Remote_Server will be set.
|
||||
if remote_expr(server, 'exists("g:Remote_Server")')
|
||||
let targetServer = server
|
||||
endif
|
||||
|
||||
" Ask each server if that file is being edited by them.
|
||||
let bufnum = remote_expr(server, "bufnr('".filename."')")
|
||||
" If it is...
|
||||
if bufnum != -1
|
||||
" ask the server to edit that file and come to the foreground.
|
||||
" set a variable g:Remote_Server to indicate that this server
|
||||
" session has at least one file opened via RemoteOpen
|
||||
let targetServer = server
|
||||
break
|
||||
end
|
||||
|
||||
let i = i + 1
|
||||
let server = s:Strntok(servers, "\n", i)
|
||||
endwhile
|
||||
|
||||
" If none of the servers have the file open, then open this file in the
|
||||
" first server. This has the advantage if yap tries to make vim open
|
||||
" multiple vims, then at least they will all be opened by the same gvim
|
||||
" server.
|
||||
call remote_send(targetServer,
|
||||
\ "\<C-\>\<C-n>".
|
||||
\ ":let g:Remote_Server = 1\<CR>".
|
||||
\ ":drop ".filename."\<CR>".
|
||||
\ ":".linenum."\<CR>zv"
|
||||
\ )
|
||||
call remote_foreground(targetServer)
|
||||
" quit this vim session
|
||||
if v:servername != targetServer
|
||||
q
|
||||
endif
|
||||
endfunction " }}}
|
||||
" RemoteInsert: inserts a \cite'ation remotely (if possible) {{{
|
||||
" Description:
|
||||
function! RemoteInsert(...)
|
||||
|
||||
let citation = matchstr(argv(0), "\\[InsText('.cite{\\zs.\\{-}\\ze}');\\]")
|
||||
if citation == ""
|
||||
q
|
||||
endif
|
||||
|
||||
" Otherwise, loop through all available servers
|
||||
let servers = serverlist()
|
||||
|
||||
let i = 1
|
||||
let server = s:Strntok(servers, "\n", i)
|
||||
let targetServer = v:servername
|
||||
|
||||
while server != ''
|
||||
if remote_expr(server, 'exists("g:Remote_WaitingForCite")')
|
||||
call remote_send(server, citation . "\<CR>")
|
||||
call remote_foreground(server)
|
||||
if v:servername != server
|
||||
q
|
||||
else
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let i = i + 1
|
||||
let server = s:Strntok(servers, "\n", i)
|
||||
endwhile
|
||||
|
||||
q
|
||||
|
||||
endfunction " }}}
|
||||
" Strntok: extract the n^th token from a list {{{
|
||||
" example: Strntok('1,23,3', ',', 2) = 23
|
||||
fun! <SID>Strntok(s, tok, n)
|
||||
return matchstr( a:s.a:tok[0], '\v(\zs([^'.a:tok.']*)\ze['.a:tok.']){'.a:n.'}')
|
||||
endfun
|
||||
|
||||
" }}}
|
||||
|
||||
" vim:ft=vim:ts=4:sw=4:noet:fdm=marker:commentstring=\"\ %s:nowrap
|
Loading…
Add table
Add a link
Reference in a new issue