diff --git a/.vim/bundle/gundo/.gitignore b/.vim/bundle/gundo/.gitignore new file mode 100644 index 0000000..a9f5875 --- /dev/null +++ b/.vim/bundle/gundo/.gitignore @@ -0,0 +1,4 @@ +*.un~ +*.pyc +tags +.DS_Store diff --git a/.vim/bundle/gundo/.hgignore b/.vim/bundle/gundo/.hgignore new file mode 100644 index 0000000..ba4b7d0 --- /dev/null +++ b/.vim/bundle/gundo/.hgignore @@ -0,0 +1,6 @@ +syntax:glob + +*.un~ +*.pyc +tags +.DS_Store diff --git a/.vim/bundle/gundo/.hgtags b/.vim/bundle/gundo/.hgtags new file mode 100644 index 0000000..8877c43 --- /dev/null +++ b/.vim/bundle/gundo/.hgtags @@ -0,0 +1,13 @@ +4101cbccf1d5fd0cfb81a3c6757c8f71657c1243 v0.8.0 +4101cbccf1d5fd0cfb81a3c6757c8f71657c1243 semver +aa431c484c032ebc7b11e1e49c3b339d6d775384 v0.9.0 +ede41dc6613eac08af5c98e69e123788b5a8e65a v1.0.0 +e1365403fefc8b192252fa1dfda997f6c166ab60 v2.0.0 +7fb1c286cca3c0c07974cc1b59002cfe2b7132f5 v2.1.0 +dc582486455b428fc2ae50913b7844966ce64afc v2.1.1 +d2406d0bce25549bb35c59767574386d3d241ace v2.2.0 +c1cda256969c75523f9a8ef9629f08fca9ded216 v2.2.1 +d6f98011d079bb1fd1bf6debb3f7cae55263b093 v2.2.2 +bf31800e9784bd83c220f18fafde215abc72c4ef v2.3.0 +25b74fe299c35aba1bc54c4af3febad1682b682b v2.4.0 +39f23f08456425288c4a7e0ab94bec34c0b629ab v2.5.0 diff --git a/.vim/bundle/gundo/README.markdown b/.vim/bundle/gundo/README.markdown new file mode 100644 index 0000000..4adeade --- /dev/null +++ b/.vim/bundle/gundo/README.markdown @@ -0,0 +1,34 @@ + +Flattr this + +Gundo.vim is Vim plugin to visualize your Vim undo tree. + +Preview +------- + +Screencast: + +### [http://screenr.com/M9l](http://screenr.com/M9l) + +Screenshot: + +gundo + +Requirements +------------ + +* Vim 7.3+ +* Python support for Vim +* Python 2.4+ + +Installation and Usage +---------------------- + +Check out the [project site][] for installation instructions. + +[project site]: http://sjl.bitbucket.org/gundo.vim/ + +License +------- + +GPLv2+, just like Mercurial. diff --git a/.vim/bundle/gundo/autoload/gundo.py b/.vim/bundle/gundo/autoload/gundo.py new file mode 100644 index 0000000..e80dcda --- /dev/null +++ b/.vim/bundle/gundo/autoload/gundo.py @@ -0,0 +1,580 @@ +# ============================================================================ +# File: gundo.py +# Description: vim global plugin to visualize your undo tree +# Maintainer: Steve Losh +# License: GPLv2+ -- look it up. +# Notes: Much of this code was thiefed from Mercurial, and the rest was +# heavily inspired by scratch.vim and histwin.vim. +# +# ============================================================================ + +import difflib +import itertools +import sys +import time +import vim + + +# Mercurial's graphlog code -------------------------------------------------------- +def asciiedges(seen, rev, parents): + """adds edge info to changelog DAG walk suitable for ascii()""" + if rev not in seen: + seen.append(rev) + nodeidx = seen.index(rev) + + knownparents = [] + newparents = [] + for parent in parents: + if parent in seen: + knownparents.append(parent) + else: + newparents.append(parent) + + ncols = len(seen) + seen[nodeidx:nodeidx + 1] = newparents + edges = [(nodeidx, seen.index(p)) for p in knownparents] + + if len(newparents) > 0: + edges.append((nodeidx, nodeidx)) + if len(newparents) > 1: + edges.append((nodeidx, nodeidx + 1)) + + nmorecols = len(seen) - ncols + return nodeidx, edges, ncols, nmorecols + +def get_nodeline_edges_tail( + node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail): + if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0: + # Still going in the same non-vertical direction. + if n_columns_diff == -1: + start = max(node_index + 1, p_node_index) + tail = ["|", " "] * (start - node_index - 1) + tail.extend(["/", " "] * (n_columns - start)) + return tail + else: + return ["\\", " "] * (n_columns - node_index - 1) + else: + return ["|", " "] * (n_columns - node_index - 1) + +def draw_edges(edges, nodeline, interline): + for (start, end) in edges: + if start == end + 1: + interline[2 * end + 1] = "/" + elif start == end - 1: + interline[2 * start + 1] = "\\" + elif start == end: + interline[2 * start] = "|" + else: + nodeline[2 * end] = "+" + if start > end: + (start, end) = (end, start) + for i in range(2 * start + 1, 2 * end): + if nodeline[i] != "+": + nodeline[i] = "-" + +def fix_long_right_edges(edges): + for (i, (start, end)) in enumerate(edges): + if end > start: + edges[i] = (start, end + 1) + +def ascii(buf, state, type, char, text, coldata): + """prints an ASCII graph of the DAG + + takes the following arguments (one call per node in the graph): + + - Somewhere to keep the needed state in (init to asciistate()) + - Column of the current node in the set of ongoing edges. + - Type indicator of node data == ASCIIDATA. + - Payload: (char, lines): + - Character to use as node's symbol. + - List of lines to display as the node's text. + - Edges; a list of (col, next_col) indicating the edges between + the current node and its parents. + - Number of columns (ongoing edges) in the current revision. + - The difference between the number of columns (ongoing edges) + in the next revision and the number of columns (ongoing edges) + in the current revision. That is: -1 means one column removed; + 0 means no columns added or removed; 1 means one column added. + """ + + idx, edges, ncols, coldiff = coldata + assert -2 < coldiff < 2 + if coldiff == -1: + # Transform + # + # | | | | | | + # o | | into o---+ + # |X / |/ / + # | | | | + fix_long_right_edges(edges) + + # add_padding_line says whether to rewrite + # + # | | | | | | | | + # | o---+ into | o---+ + # | / / | | | # <--- padding line + # o | | | / / + # o | | + add_padding_line = (len(text) > 2 and coldiff == -1 and + [x for (x, y) in edges if x + 1 < y]) + + # fix_nodeline_tail says whether to rewrite + # + # | | o | | | | o | | + # | | |/ / | | |/ / + # | o | | into | o / / # <--- fixed nodeline tail + # | |/ / | |/ / + # o | | o | | + fix_nodeline_tail = len(text) <= 2 and not add_padding_line + + # nodeline is the line containing the node character (typically o) + nodeline = ["|", " "] * idx + nodeline.extend([char, " "]) + + nodeline.extend( + get_nodeline_edges_tail(idx, state[1], ncols, coldiff, + state[0], fix_nodeline_tail)) + + # shift_interline is the line containing the non-vertical + # edges between this entry and the next + shift_interline = ["|", " "] * idx + if coldiff == -1: + n_spaces = 1 + edge_ch = "/" + elif coldiff == 0: + n_spaces = 2 + edge_ch = "|" + else: + n_spaces = 3 + edge_ch = "\\" + shift_interline.extend(n_spaces * [" "]) + shift_interline.extend([edge_ch, " "] * (ncols - idx - 1)) + + # draw edges from the current node to its parents + draw_edges(edges, nodeline, shift_interline) + + # lines is the list of all graph lines to print + lines = [nodeline] + if add_padding_line: + lines.append(get_padding_line(idx, ncols, edges)) + lines.append(shift_interline) + + # make sure that there are as many graph lines as there are + # log strings + while len(text) < len(lines): + text.append("") + if len(lines) < len(text): + extra_interline = ["|", " "] * (ncols + coldiff) + while len(lines) < len(text): + lines.append(extra_interline) + + # print lines + indentation_level = max(ncols, ncols + coldiff) + for (line, logstr) in zip(lines, text): + ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) + buf.write(ln.rstrip() + '\n') + + # ... and start over + state[0] = coldiff + state[1] = idx + +def generate(dag, edgefn, current): + seen, state = [], [0, 0] + buf = Buffer() + for node, parents in list(dag): + if node.time: + age_label = age(int(node.time)) + else: + age_label = 'Original' + line = '[%s] %s' % (node.n, age_label) + if node.n == current: + char = '@' + else: + char = 'o' + ascii(buf, state, 'C', char, [line], edgefn(seen, node, parents)) + return buf.b + + +# Mercurial age function ----------------------------------------------------------- +agescales = [("year", 3600 * 24 * 365), + ("month", 3600 * 24 * 30), + ("week", 3600 * 24 * 7), + ("day", 3600 * 24), + ("hour", 3600), + ("minute", 60), + ("second", 1)] + +def age(ts): + '''turn a timestamp into an age string.''' + + def plural(t, c): + if c == 1: + return t + return t + "s" + def fmt(t, c): + return "%d %s" % (c, plural(t, c)) + + now = time.time() + then = ts + if then > now: + return 'in the future' + + delta = max(1, int(now - then)) + if delta > agescales[0][1] * 2: + return time.strftime('%Y-%m-%d', time.gmtime(float(ts))) + + for t, s in agescales: + n = delta // s + if n >= 2 or s == 1: + return '%s ago' % fmt(t, n) + + +# Python Vim utility functions ----------------------------------------------------- +normal = lambda s: vim.command('normal %s' % s) + +MISSING_BUFFER = "Cannot find Gundo's target buffer (%s)" +MISSING_WINDOW = "Cannot find window (%s) for Gundo's target buffer (%s)" + +def _check_sanity(): + '''Check to make sure we're not crazy. + + Does the following things: + + * Make sure the target buffer still exists. + ''' + b = int(vim.eval('g:gundo_target_n')) + + if not vim.eval('bufloaded(%d)' % b): + vim.command('echo "%s"' % (MISSING_BUFFER % b)) + return False + + w = int(vim.eval('bufwinnr(%d)' % b)) + if w == -1: + vim.command('echo "%s"' % (MISSING_WINDOW % (w, b))) + return False + + return True + +def _goto_window_for_buffer(b): + w = int(vim.eval('bufwinnr(%d)' % int(b))) + vim.command('%dwincmd w' % w) + +def _goto_window_for_buffer_name(bn): + b = vim.eval('bufnr("%s")' % bn) + return _goto_window_for_buffer(b) + +def _undo_to(n): + n = int(n) + if n == 0: + vim.command('silent earlier %s' % (int(vim.eval('&undolevels')) + 1)) + else: + vim.command('silent undo %d' % n) + + +INLINE_HELP = '''\ +" Gundo for %s (%d) +" %s/%s - move between undo states +" p - preview diff of selected and current states +" - revert to selected state + +''' + + +# Python undo tree data structures and functions ----------------------------------- +class Buffer(object): + def __init__(self): + self.b = '' + + def write(self, s): + self.b += s + +class Node(object): + def __init__(self, n, parent, time, curhead): + self.n = int(n) + self.parent = parent + self.children = [] + self.curhead = curhead + self.time = time + +def _make_nodes(alts, nodes, parent=None): + p = parent + + for alt in alts: + curhead = 'curhead' in alt + node = Node(n=alt['seq'], parent=p, time=alt['time'], curhead=curhead) + nodes.append(node) + if alt.get('alt'): + _make_nodes(alt['alt'], nodes, p) + p = node + +def make_nodes(): + ut = vim.eval('undotree()') + entries = ut['entries'] + + root = Node(0, None, False, 0) + nodes = [] + _make_nodes(entries, nodes, root) + nodes.append(root) + nmap = dict((node.n, node) for node in nodes) + return nodes, nmap + +def changenr(nodes): + _curhead_l = list(itertools.dropwhile(lambda n: not n.curhead, nodes)) + if _curhead_l: + current = _curhead_l[0].parent.n + else: + current = int(vim.eval('changenr()')) + return current + + +# Gundo rendering ------------------------------------------------------------------ + +# Rendering utility functions +def _fmt_time(t): + return time.strftime('%Y-%m-%d %I:%M:%S %p', time.localtime(float(t))) + +def _output_preview_text(lines): + _goto_window_for_buffer_name('__Gundo_Preview__') + vim.command('setlocal modifiable') + vim.current.buffer[:] = lines + vim.command('setlocal nomodifiable') + +def _generate_preview_diff(current, node_before, node_after): + _goto_window_for_buffer(vim.eval('g:gundo_target_n')) + + if not node_after.n: # we're at the original file + before_lines = [] + + _undo_to(0) + after_lines = vim.current.buffer[:] + + before_name = 'n/a' + before_time = '' + after_name = 'Original' + after_time = '' + elif not node_before.n: # we're at a pseudo-root state + _undo_to(0) + before_lines = vim.current.buffer[:] + + _undo_to(node_after.n) + after_lines = vim.current.buffer[:] + + before_name = 'Original' + before_time = '' + after_name = node_after.n + after_time = _fmt_time(node_after.time) + else: + _undo_to(node_before.n) + before_lines = vim.current.buffer[:] + + _undo_to(node_after.n) + after_lines = vim.current.buffer[:] + + before_name = node_before.n + before_time = _fmt_time(node_before.time) + after_name = node_after.n + after_time = _fmt_time(node_after.time) + + _undo_to(current) + + return list(difflib.unified_diff(before_lines, after_lines, + before_name, after_name, + before_time, after_time)) + +def _generate_change_preview_diff(current, node_before, node_after): + _goto_window_for_buffer(vim.eval('g:gundo_target_n')) + + _undo_to(node_before.n) + before_lines = vim.current.buffer[:] + + _undo_to(node_after.n) + after_lines = vim.current.buffer[:] + + before_name = node_before.n or 'Original' + before_time = node_before.time and _fmt_time(node_before.time) or '' + after_name = node_after.n or 'Original' + after_time = node_after.time and _fmt_time(node_after.time) or '' + + _undo_to(current) + + return list(difflib.unified_diff(before_lines, after_lines, + before_name, after_name, + before_time, after_time)) + +def GundoRenderGraph(): + if not _check_sanity(): + return + + nodes, nmap = make_nodes() + + for node in nodes: + node.children = [n for n in nodes if n.parent == node] + + def walk_nodes(nodes): + for node in nodes: + if node.parent: + yield (node, [node.parent]) + else: + yield (node, []) + + dag = sorted(nodes, key=lambda n: int(n.n), reverse=True) + current = changenr(nodes) + + result = generate(walk_nodes(dag), asciiedges, current).rstrip().splitlines() + result = [' ' + l for l in result] + + target = (vim.eval('g:gundo_target_f'), int(vim.eval('g:gundo_target_n'))) + mappings = (vim.eval('g:gundo_map_move_older'), + vim.eval('g:gundo_map_move_newer')) + + if int(vim.eval('g:gundo_help')): + header = (INLINE_HELP % (target + mappings)).splitlines() + else: + header = [] + + vim.command('call s:GundoOpenGraph()') + vim.command('setlocal modifiable') + vim.current.buffer[:] = (header + result) + vim.command('setlocal nomodifiable') + + i = 1 + for line in result: + try: + line.split('[')[0].index('@') + i += 1 + break + except ValueError: + pass + i += 1 + vim.command('%d' % (i+len(header)-1)) + +def GundoRenderPreview(): + if not _check_sanity(): + return + + target_state = vim.eval('s:GundoGetTargetState()') + + # Check that there's an undo state. There may not be if we're talking about + # a buffer with no changes yet. + if target_state == None: + _goto_window_for_buffer_name('__Gundo__') + return + else: + target_state = int(target_state) + + _goto_window_for_buffer(vim.eval('g:gundo_target_n')) + + nodes, nmap = make_nodes() + current = changenr(nodes) + + node_after = nmap[target_state] + node_before = node_after.parent + + vim.command('call s:GundoOpenPreview()') + _output_preview_text(_generate_preview_diff(current, node_before, node_after)) + + _goto_window_for_buffer_name('__Gundo__') + +def GundoRenderChangePreview(): + if not _check_sanity(): + return + + target_state = vim.eval('s:GundoGetTargetState()') + + # Check that there's an undo state. There may not be if we're talking about + # a buffer with no changes yet. + if target_state == None: + _goto_window_for_buffer_name('__Gundo__') + return + else: + target_state = int(target_state) + + _goto_window_for_buffer(vim.eval('g:gundo_target_n')) + + nodes, nmap = make_nodes() + current = changenr(nodes) + + node_after = nmap[target_state] + node_before = nmap[current] + + vim.command('call s:GundoOpenPreview()') + _output_preview_text(_generate_change_preview_diff(current, node_before, node_after)) + + _goto_window_for_buffer_name('__Gundo__') + + +# Gundo undo/redo +def GundoRevert(): + if not _check_sanity(): + return + + target_n = int(vim.eval('s:GundoGetTargetState()')) + back = vim.eval('g:gundo_target_n') + + _goto_window_for_buffer(back) + _undo_to(target_n) + + vim.command('GundoRenderGraph') + _goto_window_for_buffer(back) + + if int(vim.eval('g:gundo_close_on_revert')): + vim.command('GundoToggle') + +def GundoPlayTo(): + if not _check_sanity(): + return + + target_n = int(vim.eval('s:GundoGetTargetState()')) + back = int(vim.eval('g:gundo_target_n')) + delay = int(vim.eval('g:gundo_playback_delay')) + + vim.command('echo "%s"' % back) + + _goto_window_for_buffer(back) + normal('zR') + + nodes, nmap = make_nodes() + + start = nmap[changenr(nodes)] + end = nmap[target_n] + + def _walk_branch(origin, dest): + rev = origin.n < dest.n + + nodes = [] + if origin.n > dest.n: + current, final = origin, dest + else: + current, final = dest, origin + + while current.n >= final.n: + if current.n == final.n: + break + nodes.append(current) + current = current.parent + else: + return None + nodes.append(current) + + if rev: + return reversed(nodes) + else: + return nodes + + branch = _walk_branch(start, end) + + if not branch: + vim.command('unsilent echo "No path to that node from here!"') + return + + for node in branch: + _undo_to(node.n) + vim.command('GundoRenderGraph') + normal('zz') + _goto_window_for_buffer(back) + vim.command('redraw') + vim.command('sleep %dm' % delay) + +def initPythonModule(): + if sys.version_info[:2] < (2, 4): + vim.command('let s:has_supported_python = 0') diff --git a/.vim/bundle/gundo/autoload/gundo.vim b/.vim/bundle/gundo/autoload/gundo.vim new file mode 100644 index 0000000..970413d --- /dev/null +++ b/.vim/bundle/gundo/autoload/gundo.vim @@ -0,0 +1,472 @@ +" ============================================================================ +" File: gundo.vim +" Description: vim global plugin to visualize your undo tree +" Maintainer: Steve Losh +" License: GPLv2+ -- look it up. +" Notes: Much of this code was thiefed from Mercurial, and the rest was +" heavily inspired by scratch.vim and histwin.vim. +" +" ============================================================================ + + +"{{{ Init + +if v:version < '703'"{{{ + function! s:GundoDidNotLoad() + echohl WarningMsg|echomsg "Gundo unavailable: requires Vim 7.3+"|echohl None + endfunction + command! -nargs=0 GundoToggle call s:GundoDidNotLoad() + finish +endif"}}} + +if !exists('g:gundo_width')"{{{ + let g:gundo_width = 45 +endif"}}} +if !exists('g:gundo_preview_height')"{{{ + let g:gundo_preview_height = 15 +endif"}}} +if !exists('g:gundo_preview_bottom')"{{{ + let g:gundo_preview_bottom = 0 +endif"}}} +if !exists('g:gundo_right')"{{{ + let g:gundo_right = 0 +endif"}}} +if !exists('g:gundo_help')"{{{ + let g:gundo_help = 1 +endif"}}} +if !exists("g:gundo_map_move_older")"{{{ + let g:gundo_map_move_older = 'j' +endif"}}} +if !exists("g:gundo_map_move_newer")"{{{ + let g:gundo_map_move_newer = 'k' +endif"}}} +if !exists("g:gundo_close_on_revert")"{{{ + let g:gundo_close_on_revert = 0 +endif"}}} +if !exists("g:gundo_prefer_python3")"{{{ + let g:gundo_prefer_python3 = 0 +endif"}}} +if !exists("g:gundo_auto_preview")"{{{ + let g:gundo_auto_preview = 1 +endif"}}} +if !exists("g:gundo_playback_delay")"{{{ + let g:gundo_playback_delay = 60 +endif"}}} + +let s:has_supported_python = 0 +if g:gundo_prefer_python3 && has('python3')"{{{ + let s:has_supported_python = 2 +elseif has('python')" + let s:has_supported_python = 1 +endif + +if !s:has_supported_python + function! s:GundoDidNotLoad() + echohl WarningMsg|echomsg "Gundo requires Vim to be compiled with Python 2.4+"|echohl None + endfunction + command! -nargs=0 GundoToggle call s:GundoDidNotLoad() + finish +endif"}}} + +let s:plugin_path = escape(expand(':p:h'), '\') +"}}} + +"{{{ Gundo utility functions + +function! s:GundoGetTargetState()"{{{ + let target_line = matchstr(getline("."), '\v\[[0-9]+\]') + return matchstr(target_line, '\v[0-9]+') +endfunction"}}} + +function! s:GundoGoToWindowForBufferName(name)"{{{ + if bufwinnr(bufnr(a:name)) != -1 + exe bufwinnr(bufnr(a:name)) . "wincmd w" + return 1 + else + return 0 + endif +endfunction"}}} + +function! s:GundoIsVisible()"{{{ + if bufwinnr(bufnr("__Gundo__")) != -1 || bufwinnr(bufnr("__Gundo_Preview__")) != -1 + return 1 + else + return 0 + endif +endfunction"}}} + +function! s:GundoInlineHelpLength()"{{{ + if g:gundo_help + return 6 + else + return 0 + endif +endfunction"}}} + +"}}} + +"{{{ Gundo buffer settings + +function! s:GundoMapGraph()"{{{ + exec 'nnoremap + + + + + + + + +
+
+

Gundo

+

Graph your Vim undo tree in style.

+
+
+ gundo + + +

+ You know that Vim lets you undo changes like any text editor. What you might + not know is that it doesn't just keep a list of your changes — it keeps + a tree of them. +

+ +

+ Say you make a change (call it X), undo that change, and then make another + change (call it Y). With most editors, change X is now gone forever. With Vim + you can get it back. +

+ +

+ The problem is that trying to do this in the real world is painful. Vim gives + you an :undolist command that shows you the leaves of the tree. Good luck + finding the change you want in that list. +

+ +

+ Gundo is a plugin to make browsing this ridiculously powerful undo tree less + painful. +

+ +

+ Check out this + quick screencast + if you want to see it in action. +

+
+ +
+ +

Requirements

+ +

+ Gundo requires Vim 7.3+ compiled with Python support, and Python 2.4+. +

+
+
+ +

Installation

+ +

Use Pathogen. Don't use pathogen? Start.

+
hg clone http://bitbucket.org/sjl/gundo.vim ~/.vim/bundle/gundo
+ +

There's a git mirror if you prefer:

+
git clone http://github.com/sjl/gundo.vim.git ~/.vim/bundle/gundo
+ +

Add a mapping to your ~/.vimrc (change the key to suit your taste):

+
nnoremap <F5> :GundoToggle<CR>
+
+
+ +

Usage

+ +

+ We'll get to the technical details later, but if you're a human the first + thing you need to do is add a mapping to your vimrc file to toggle the undo + graph: +

+ +
nnoremap <F5> :GundoToggle<CR>
+ +

+ Change the mapped key to suit your taste. We'll stick with <F5> because that's + what the author uses. +

+ +

+ Now you can press <F5> to toggle the undo graph and preview pane, which will + look something like this: +

+ +
+  Undo graph                          File
++-----------------------------------+---------------------------+
+| " Gundo for something.txt [1]     |one                        |
+| " j/k  - move between undo states |two                        |
+| " <cr> - revert to that state     |three                      |
+|                                   |five                       |
+| @  [5] 3 hours ago                |                           |
+| |                                 |                           |
+| | o  [4] 4 hours ago              |                           |
+| | |                               |                           |
+| o |  [3] 4 hours ago              |                           |
+| | |                               |                           |
+| o |  [2] 4 hours ago              |                           |
+| |/                                |                           |
+| o  [1] 4 hours ago                |                           |
+| |                                 |                           |
+| o  [0] Original                   |                           |
++-----------------------------------+                           |
+| --- 3 2010-10-12 06:27:35 PM      |                           |
+| +++ 5 2010-10-12 07:38:37 PM      |                           |
+| @@ -1,3 +1,4                      |                           |
+|  one                              |                           |
+|  two                              |                           |
+|  three                            |                           |
+| +five                             |                           |
++-----------------------------------+---------------------------+
+  Preview pane
+
+ +

+ Your current position in the undo tree is marked with an @ character. Other + nodes are marked with an o character. +

+ +

+ When you toggle open the graph Gundo will put your cursor on your current + position in the tree. You can move up and down the graph with the j and + k keys. +

+ +

+ You can move to the top of the graph (the newest state) with gg and to the + bottom of the graph (the oldest state) with G. +

+ +

+ As you move between undo states the preview pane will show you a unified diff + of the change that state made. +

+ +

+ Pressing return on a state (or double clicking on it) will + revert the contents of the file to match that state. +

+ +

+ You can use p on a state to make the preview window show the + diff between your current state and the selected state, instead of a preview + of what the selected state changed. +

+ +

+ Pressing P while on a state will initiate "play to" mode targeted at that + state. This will replay all the changes between your current state and the + target, with a slight pause after each change. It's mostly useless, but can be + fun to watch and see where your editing lags — that might be a good place to + define a new mapping to speed up your editing. +

+ +

+ Pressing q while in the undo graph will close it. You can also just press your + toggle mapping key. +

+
+
+ +

Configuration

+ +

+ You can tweak the behavior of Gundo by setting a few variables + in your :vimrc file. For example: +

+ +
+let g:gundo_width = 60
+let g:gundo_preview_height = 40
+let g:gundo_right = 1
+
+ + +

g:gundo_width

+ +

Set the horizontal width of the Gundo graph (and preview).

+ +

Default: 45

+ + +

g:gundo_preview_height

+ +

Set the vertical height of the Gundo preview.

+ +

Default: 15

+ + +

g:gundo_preview_bottom

+ +

+ Force the preview window below current windows instead of below + the graph. This gives the preview window more space to show the + unified diff. +

+ +

Example:

+ +
++--------+            +--------+
+!g!      !            !      !g!
+!g!      !     or     !      !g!
+!g!______!            !______!g!
+!g!pppppp!            !pppppp!g!
++--------+            +--------+
+
+ +

Default: 0

+ + +

g:gundo_right

+ +

+ Set this to 1 to make the Gundo graph (and preview) open on the + right side instead of the left. +

+ +

Default: 0 (off, open on the left side)

+ + +

g:gundo_help

+ +

Set this to 0 to disable the help text in the Gundo graph window.

+ +

Default: 1 (show the help)

+ + +

g:gundo_disable

+ +

Set this to 1 to disable Gundo entirely.

+ +

+ Useful if you use the same ~/.vim folder on + multiple machines, and some of them may not have Python support. +

+ +

Default: 0 (Gundo is enabled as usual)

+ + +

g:gundo_map_move_[older/newer]

+ +

+ These options let you change the keys that navigate the + undo graph. This is useful if you use a Dvorak keyboard and + have changed your movement keys. +

+ +

+ Default:
+ gundo_map_move_older: "j"
+ gundo_map_move_newer: "k" +

+ + +

g:gundo_close_on_revert

+ +

Set this to 1 to automatically close the Gundo windows when reverting.

+ +

Default: 0 (windows do not automatically close)

+ + +

g:gundo_[preview/tree]_statusline

+ +

+ Set this to 0 to disable automatically rendering preview diffs as you move + through the undo tree (you can still render a specific diff with r). This can + be useful on large files and undo trees to speed up Gundo. +

+ +

Default: unset (windows use the default statusline)

+ + + +

g:gundo_auto_preview

+ +

Set this to 1 to rendering diff automatically with cursor move.

+ +

Default: 1 (auto preview diff)

+ + +

g:gundo_playback_delay

+ +

+ This is the delay in milliseconds between each change when running 'play to' + mode. Set this to a higher number for a slower playback or to a lower number + for a faster playback. +

+ +

Default: 60

+
+
+ +

License

+ +

GPLv2+.

+
+
+ +

Bugs

+ +

+ If you find a bug please post it on the + issue tracker. +

+
+
+ +

Contributing

+ +

+ Fork the repository on + BitBucket + or + GitHub + and send a pull request. +

+ +

Make sure you document your changes in the following places:

+ +
    +
  • The README.markdown file.
  • +
  • The site/index.html file.
  • +
  • The doc/gundo.txt file.
  • +
+
+
+ +

Changelog

+ +
    +
  1. v2.5.0 +
      +
    • + Fix the help window to take custom mappings into account. +
    • +
    • + Add g:gundo_playback_delay option. +
    • +
    +
  2. +
  3. v2.4.0 +
      +
    • + Add auto preview option. +
    • +
    • + Add 'r' mapping to preview current state. +
    • +
    • + Add public gundo#GundoShow() and gundo#GundoHide() functions. +
    • +
    +
  4. +
  5. v2.3.0 +
      +
    • + Add statusline configuration. +
    • +
    +
  6. +
  7. v2.2.2 +
      +
    • + More performance improvements. +
    • +
    +
  8. +
  9. v2.2.1 +
      +
    • + Refactoring and performance improvements. +
    • +
    +
  10. +
  11. v2.2.0 +
      +
    • + Add the g:gundo_close_on_revert setting. +
    • +
    • + Fix a bug with the splitbelow setting. +
    • +
    +
  12. +
  13. v2.1.1 +
      +
    • + Fix a bug with the movement key mappings. +
    • +
    +
  14. +
  15. v2.1.0 +
      +
    • + Warnings about having an incompatible Vim and/or + Python installation are now deferred until the + first time you try to use Gundo, instead of being + displayed on launch. +
    • +
    • + The j and k mappings are + now configurable with + g:gundo_map_move_older and + g:gundo_map_move_newer. +
    • +
    • + The o, Up and + Down keys are now mapped in the + Gundo pane. +
    • +
    • + Improve and add several unit tests for Gundo. +
    • +
    +
  16. +
  17. v2.0.0 +
      +
    • + Make GundoToggle close the Gundo windows if they're + visible but not the current window, instead of moving to them. +
    • +
    • Add the g:gundo_disable setting.
    • +
    • Add the g:gundo_help setting.
    • +
    • + Add the p mapping to preview the result of + reverting to the selected state. +
    • +
    • Fix movement commands with counts in the graph.
    • +
    +
  18. +
  19. v1.0.0 +
      +
    • Initial stable release.
    • +
    +
  20. +
+
+
+ +

Credits

+ +

+ The graphing code was all taken from Mercurial, hence the + GPLv2+ license. +

+ +

+ The plugin was heavily inspired by histwin.vim, and the code + for scratch.vim helped the author get started. +

+
+
+ Gundo was written by + Steve Losh + with a lot of help from others. +
+
+ + + diff --git a/.vim/bundle/gundo/site/less.js b/.vim/bundle/gundo/site/less.js new file mode 100644 index 0000000..309bf55 --- /dev/null +++ b/.vim/bundle/gundo/site/less.js @@ -0,0 +1,9 @@ +// +// LESS - Leaner CSS v1.3.0 +// http://lesscss.org +// +// Copyright (c) 2009-2011, Alexis Sellier +// Licensed under the Apache 2.0 License. +// +(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b0?d.firstChild.nodeValue!==a.nodeValue&&d.replaceChild(a,d.firstChild):d.appendChild(a)})(document.createTextNode(a));c&&g&&(t("saving "+e+" to cache."),g.setItem(e,a),g.setItem(e+":timestamp",c))}function q(a,b,c,e){function i(b,c,d){b.status>=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):typeof d=="function"&&d(b.status,a)}var g=r(),h=f?!1:d.async;typeof g.overrideMimeType=="function"&&g.overrideMimeType("text/css"),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),f?g.status===0||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){g.readyState==4&&i(g,c,e)}:i(g,c,e)}function r(){if(a.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(b){return t("browser doesn't support AJAX."),null}}function s(a){return a&&a.parentNode.removeChild(a)}function t(a){d.env=="development"&&typeof console!="undefined"&&console.log("less: "+a)}function u(a,b){var c="less-error-message:"+o(b),e='
  • {content}
  • ',f=document.createElement("div"),g,h,i=[],j=a.filename||b;f.id=c,f.className="less-error-message",h="

    "+(a.message||"There is an error in your .less file")+"

    "+'

    in '+j+" ";var k=function(a,b,c){a.extract[b]&&i.push(e.replace(/\{line\}/,parseInt(a.line)+(b-1)).replace(/\{class\}/,c).replace(/\{content\}/,a.extract[b]))};a.stack?h+="
    "+a.stack.split("\n").slice(1).join("
    "):a.extract&&(k(a,0,""),k(a,1,"line"),k(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":

    "+"
      "+i.join("")+"
    "),f.innerHTML=h,p([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),f.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),d.env=="development"&&(g=setInterval(function(){document.body&&(document.getElementById(c)?document.body.replaceChild(f,document.getElementById(c)):document.body.insertBefore(f,document.body.firstChild),clearInterval(g))},10))}typeof define=="function"&&define.amd&&define("less",[],function(){return d}),Array.isArray||(Array.isArray=function(a){return Object.prototype.toString.call(a)==="[object Array]"||a instanceof Array}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c=this.length>>>0;for(var d=0;d>>0,c=new Array(b),d=arguments[1];for(var e=0;e>>0,c=0;if(b===0&&arguments.length===1)throw new TypeError;if(arguments.length>=2)var d=arguments[1];else do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0);for(;c=b)return-1;c<0&&(c+=b);for(;cl&&(k[g]=k[g].slice(f-l),l=f)}function t(a){var c,d,e,h,i,j,n,o;if(a instanceof Function)return a.call(m.parsers);if(typeof a=="string")c=b.charAt(f)===a?a:null,e=1,s();else{s();if(c=a.exec(k[g]))e=c[0].length;else return null}if(c){o=f+=e,j=f+k[g].length-e;while(f=0&&b.charAt(c)!=="\n";c--)d++;return{line:typeof a=="number"?(b.slice(0,a).match(/\n/g)||"").length:null,column:d}}function A(a,b){var c=y(a,b),d=z(a.index,c),e=d.line,f=d.column,g=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.filename,this.index=a.index,this.line=typeof e=="number"?e+1:null,this.callLine=a.call&&z(a.call,c).line+1,this.callExtract=g[z(a.call,c).line],this.stack=a.stack,this.column=f,this.extract=[g[e-1],g[e],g[e+1]]}var b,f,g,h,i,j,k,l,m,n=this,o=function(){},p=this.imports={paths:a&&a.paths||[],queue:[],files:{},contents:{},mime:a&&a.mime,error:null,push:function(b,c){var e=this;this.queue.push(b),d.Parser.importer(b,this.paths,function(a,d,f){e.queue.splice(e.queue.indexOf(b),1),e.files[b]=d,e.contents[b]=f,a&&!e.error&&(e.error=a),c(a,d),e.queue.length===0&&o()},a)}};return this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,this.env.filename=this.env.filename||null,m={imports:p,parse:function(h,i){var n,p,q,r,s,u,v=[],w,x=null;f=g=l=j=0,b=h.replace(/\r\n/g,"\n"),k=function(c){var d=0,e=/[^"'`\{\}\/\(\)\\]+/g,f=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,g=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,h=0,i,j=c[0],k;for(var l=0,m,n;l0&&(x=new A({index:l,type:"Parse",message:"missing closing `}`",filename:a.filename},a)),c.map(function(a){return a.join("")})}([[]]);if(x)return i(x);try{n=new e.Ruleset([],t(this.parsers.primary)),n.root=!0}catch(y){return i(new A(y,a))}n.toCSS=function(b){var f,g,h;return function(f,g){var h=[],i;f=f||{},typeof g=="object"&&!Array.isArray(g)&&(g=Object.keys(g).map(function(a){var b=g[a];return b instanceof e.Value||(b instanceof e.Expression||(b=new e.Expression([b])),b=new e.Value([b])),new e.Rule("@"+a,b,!1,0)}),h=[new e.Ruleset(null,g)]);try{var j=b.call(this,{frames:h}).toCSS([],{compress:f.compress||!1})}catch(k){throw new A(k,a)}if(i=m.imports.error)throw i instanceof A?i:new A(i,a);return f.yuicompress&&d.mode==="node"?c("./cssmin").compressor.cssmin(j):f.compress?j.replace(/(\s)+/g,"$1"):j}}(n.eval);if(f=0&&b.charAt(z)!=="\n";z--)B++;x={type:"Parse",message:"Syntax Error on line "+s,index:f,filename:a.filename,line:s,column:B,extract:[u[s-2],u[s-1],u[s]]}}this.imports.queue.length>0?o=function(){i(x,n)}:i(x,n)},parsers:{primary:function(){var a,b=[];while((a=t(this.mixin.definition)||t(this.rule)||t(this.ruleset)||t(this.mixin.call)||t(this.comment)||t(this.directive))||t(/^[\s\n]+/))a&&b.push(a);return b},comment:function(){var a;if(b.charAt(f)!=="/")return;if(b.charAt(f+1)==="/")return new e.Comment(t(/^\/\/.*/),!0);if(a=t(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new e.Comment(a)},entities:{quoted:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=='"'&&b.charAt(c)!=="'")return;d&&t("~");if(a=t(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new e.Quoted(a[0],a[1]||a[2],d)},keyword:function(){var a;if(a=t(/^[_A-Za-z-][_A-Za-z0-9-]*/))return e.colors.hasOwnProperty(a)?new e.Color(e.colors[a].slice(1)):new e.Keyword(a)},call:function(){var b,c,d=f;if(!(b=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(k[g])))return;b=b[1].toLowerCase();if(b==="url")return null;f+=b.length;if(b==="alpha")return t(this.alpha);t("("),c=t(this.entities.arguments);if(!t(")"))return;if(b)return new e.Call(b,c,d,a.filename)},arguments:function(){var a=[],b;while(b=t(this.entities.assignment)||t(this.expression)){a.push(b);if(!t(","))break}return a},literal:function(){return t(this.entities.dimension)||t(this.entities.color)||t(this.entities.quoted)},assignment:function(){var a,b;if((a=t(/^\w+(?=\s?=)/i))&&t("=")&&(b=t(this.entity)))return new e.Assignment(a,b)},url:function(){var a;if(b.charAt(f)!=="u"||!t(/^url\(/))return;return a=t(this.entities.quoted)||t(this.entities.variable)||t(this.entities.dataURI)||t(/^[-\w%@$\/.&=:;#+?~]+/)||"",u(")"),new e.URL(a.value||a.data||a instanceof e.Variable?a:new e.Anonymous(a),p.paths)},dataURI:function(){var a;if(t(/^data:/)){a={},a.mime=t(/^[^\/]+\/[^,;)]+/)||"",a.charset=t(/^;\s*charset=[^,;)]+/)||"",a.base64=t(/^;\s*base64/)||"",a.data=t(/^,\s*[^)]+/);if(a.data)return a}},variable:function(){var c,d=f;if(b.charAt(f)==="@"&&(c=t(/^@@?[\w-]+/)))return new e.Variable(c,d,a.filename)},color:function(){var a;if(b.charAt(f)==="#"&&(a=t(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/)))return new e.Color(a[1])},dimension:function(){var a,c=b.charCodeAt(f);if(c>57||c<45||c===47)return;if(a=t(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/))return new e.Dimension(a[1],a[2])},javascript:function(){var a,c=f,d;b.charAt(c)==="~"&&(c++,d=!0);if(b.charAt(c)!=="`")return;d&&t("~");if(a=t(/^`([^`]*)`/))return new e.JavaScript(a[1],f,d)}},variable:function(){var a;if(b.charAt(f)==="@"&&(a=t(/^(@[\w-]+)\s*:/)))return a[1]},shorthand:function(){var a,b;if(!w(/^[@\w.%-]+\/[@\w.-]+/))return;if((a=t(this.entity))&&t("/")&&(b=t(this.entity)))return new e.Shorthand(a,b)},mixin:{call:function(){var c=[],d,g,h,i=f,j=b.charAt(f),k=!1;if(j!=="."&&j!=="#")return;while(d=t(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/))c.push(new e.Element(g,d,f)),g=t(">");t("(")&&(h=t(this.entities.arguments))&&t(")"),t(this.important)&&(k=!0);if(c.length>0&&(t(";")||w("}")))return new e.mixin.Call(c,h||[],i,a.filename,k)},definition:function(){var a,c=[],d,g,h,i,j,k=!1;if(b.charAt(f)!=="."&&b.charAt(f)!=="#"||w(/^[^{]*(;|})/))return;q();if(d=t(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)){a=d[1];do{if(b.charAt(f)==="."&&t(/^\.{3}/)){k=!0;break}if(!(h=t(this.entities.variable)||t(this.entities.literal)||t(this.entities.keyword)))break;if(h instanceof e.Variable)if(t(":"))i=u(this.expression,"expected expression"),c.push({name:h.name,value:i});else{if(t(/^\.{3}/)){c.push({name:h.name,variadic:!0}),k=!0;break}c.push({name:h.name})}else c.push({value:h})}while(t(","));u(")"),t(/^when/)&&(j=u(this.conditions,"expected condition")),g=t(this.block);if(g)return new e.mixin.Definition(a,c,g,j,k);r()}}},entity:function(){return t(this.entities.literal)||t(this.entities.variable)||t(this.entities.url)||t(this.entities.call)||t(this.entities.keyword)||t(this.entities.javascript)||t(this.comment)},end:function(){return t(";")||w("}")},alpha:function(){var a;if(!t(/^\(opacity=/i))return;if(a=t(/^\d+/)||t(this.entities.variable))return u(")"),new e.Alpha(a)},element:function(){var a,b,c,d;c=t(this.combinator),a=t(/^(?:\d+\.\d+|\d+)%/)||t(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)||t("*")||t(this.attribute)||t(/^\([^)@]+\)/),a||t("(")&&(d=t(this.entities.variable))&&t(")")&&(a=new e.Paren(d));if(a)return new e.Element(c,a,f);if(c.value&&c.value.charAt(0)==="&")return new e.Element(c,null,f)},combinator:function(){var a,c=b.charAt(f);if(c===">"||c==="+"||c==="~"){f++;while(b.charAt(f)===" ")f++;return new e.Combinator(c)}if(c==="&"){a="&",f++,b.charAt(f)===" "&&(a="& ");while(b.charAt(f)===" ")f++;return new e.Combinator(a)}return b.charAt(f-1)===" "?new e.Combinator(" "):new e.Combinator(null)},selector:function(){var a,c,d=[],g,h;if(t("("))return a=t(this.entity),u(")"),new e.Selector([new e.Element("",a,f)]);while(c=t(this.element)){g=b.charAt(f),d.push(c);if(g==="{"||g==="}"||g===";"||g===",")break}if(d.length>0)return new e.Selector(d)},tag:function(){return t(/^[a-zA-Z][a-zA-Z-]*[0-9]?/)||t("*")},attribute:function(){var a="",b,c,d;if(!t("["))return;if(b=t(/^[a-zA-Z-]+/)||t(this.entities.quoted))(d=t(/^[|~*$^]?=/))&&(c=t(this.entities.quoted)||t(/^[\w-]+/))?a=[b,d,c.toCSS?c.toCSS():c].join(""):a=b;if(!t("]"))return;if(a)return"["+a+"]"},block:function(){var a;if(t("{")&&(a=t(this.primary))&&t("}"))return a},ruleset:function(){var b=[],c,d,g;q();while(c=t(this.selector)){b.push(c),t(this.comment);if(!t(","))break;t(this.comment)}if(b.length>0&&(d=t(this.block)))return new e.Ruleset(b,d,a.strictImports);j=f,r()},rule:function(){var a,c,d=b.charAt(f),h,l;q();if(d==="."||d==="#"||d==="&")return;if(a=t(this.variable)||t(this.property)){a.charAt(0)!="@"&&(l=/^([^@+\/'"*`(;{}-]*);/.exec(k[g]))?(f+=l[0].length-1,c=new e.Anonymous(l[1])):a==="font"?c=t(this.font):c=t(this.value),h=t(this.important);if(c&&t(this.end))return new e.Rule(a,c,h,i);j=f,r()}},"import":function(){var a,b,c=f;if(t(/^@import\s+/)&&(a=t(this.entities.quoted)||t(this.entities.url))){b=t(this.mediaFeatures);if(t(";"))return new e.Import(a,p,b,c)}},mediaFeature:function(){var a,b,c=[];do if(a=t(this.entities.keyword))c.push(a);else if(t("(")){b=t(this.property),a=t(this.entity);if(!t(")"))return null;if(b&&a)c.push(new e.Paren(new e.Rule(b,a,null,f,!0)));else if(a)c.push(new e.Paren(a));else return null}while(a);if(c.length>0)return new e.Expression(c)},mediaFeatures:function(){var a,b=[];do if(a=t(this.mediaFeature)){b.push(a);if(!t(","))break}else if(a=t(this.entities.variable)){b.push(a);if(!t(","))break}while(a);return b.length>0?b:null},media:function(){var a,b;if(t(/^@media/)){a=t(this.mediaFeatures);if(b=t(this.block))return new e.Media(b,a)}},directive:function(){var a,c,d,g,h,i;if(b.charAt(f)!=="@")return;if(c=t(this["import"])||t(this.media))return c;if(a=t(/^@page|@keyframes/)||t(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)){g=(t(/^[^{]+/)||"").trim();if(d=t(this.block))return new e.Directive(a+" "+g,d)}else if(a=t(/^@[-a-z]+/))if(a==="@font-face"){if(d=t(this.block))return new e.Directive(a,d)}else if((c=t(this.entity))&&t(";"))return new e.Directive(a,c)},font:function(){var a=[],b=[],c,d,f,g;while(g=t(this.shorthand)||t(this.entity))b.push(g);a.push(new e.Expression(b));if(t(","))while(g=t(this.expression)){a.push(g);if(!t(","))break}return new e.Value(a)},value:function(){var a,b=[],c;while(a=t(this.expression)){b.push(a);if(!t(","))break}if(b.length>0)return new e.Value(b)},important:function(){if(b.charAt(f)==="!")return t(/^! *important/)},sub:function(){var a;if(t("(")&&(a=t(this.expression))&&t(")"))return a},multiplication:function(){var a,b,c,d;if(a=t(this.operand)){while(!w(/^\/\*/)&&(c=t("/")||t("*"))&&(b=t(this.operand)))d=new e.Operation(c,[d||a,b]);return d||a}},addition:function(){var a,c,d,g;if(a=t(this.multiplication)){while((d=t(/^[-+]\s+/)||b.charAt(f-1)!=" "&&(t("+")||t("-")))&&(c=t(this.multiplication)))g=new e.Operation(d,[g||a,c]);return g||a}},conditions:function(){var a,b,c=f,d;if(a=t(this.condition)){while(t(",")&&(b=t(this.condition)))d=new e.Condition("or",d||a,b,c);return d||a}},condition:function(){var a,b,c,d,g=f,h=!1;t(/^not/)&&(h=!0),u("(");if(a=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))return(d=t(/^(?:>=|=<|[<=>])/))?(b=t(this.addition)||t(this.entities.keyword)||t(this.entities.quoted))?c=new e.Condition(d,a,b,g,h):v("expected expression"):c=new e.Condition("=",a,new e.Keyword("true"),g,h),u(")"),t(/^and/)?new e.Condition("and",c,t(this.condition)):c},operand:function(){var a,c=b.charAt(f+1);b.charAt(f)==="-"&&(c==="@"||c==="(")&&(a=t("-"));var d=t(this.sub)||t(this.entities.dimension)||t(this.entities.color)||t(this.entities.variable)||t(this.entities.call);return a?new e.Operation("*",[new e.Dimension(-1),d]):d},expression:function(){var a,b,c=[],d;while(a=t(this.addition)||t(this.entity))c.push(a);if(c.length>0)return new e.Expression(c)},property:function(){var a;if(a=t(/^(\*?-?[-a-z_0-9]+)\s*:/))return a[1]}}}};if(d.mode==="browser"||d.mode==="rhino")d.Parser.importer=function(a,b,c,d){!/^([a-z]+:)?\//.test(a)&&b.length>0&&(a=b[0]+a),n({href:a,title:a,type:d.mime},function(e){e&&typeof d.errback=="function"?d.errback.call(null,a,b,c,d):c.apply(null,arguments)},!0)};(function(a){function b(b){return a.functions.hsla(b.h,b.s,b.l,b.a)}function c(b){if(b instanceof a.Dimension)return parseFloat(b.unit=="%"?b.value/100:b.value);if(typeof b=="number")return b;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function d(a){return Math.min(1,Math.max(0,a))}a.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(b,d,e,f){var g=[b,d,e].map(function(a){return c(a)}),f=c(f);return new a.Color(g,f)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,d,e){function h(a){return a=a<0?a+1:a>1?a-1:a,a*6<1?g+(f-g)*a*6:a*2<1?f:a*3<2?g+(f-g)*(2/3-a)*6:g}a=c(a)%360/360,b=c(b),d=c(d),e=c(e);var f=d<=.5?d*(b+1):d+b-d*b,g=d*2-f;return this.rgba(h(a+1/3)*255,h(a)*255,h(a-1/3)*255,e)},hue:function(b){return new a.Dimension(Math.round(b.toHSL().h))},saturation:function(b){return new a.Dimension(Math.round(b.toHSL().s*100),"%")},lightness:function(b){return new a.Dimension(Math.round(b.toHSL().l*100),"%")},alpha:function(b){return new a.Dimension(b.toHSL().a)},saturate:function(a,c){var e=a.toHSL();return e.s+=c.value/100,e.s=d(e.s),b(e)},desaturate:function(a,c){var e=a.toHSL();return e.s-=c.value/100,e.s=d(e.s),b(e)},lighten:function(a,c){var e=a.toHSL();return e.l+=c.value/100,e.l=d(e.l),b(e)},darken:function(a,c){var e=a.toHSL();return e.l-=c.value/100,e.l=d(e.l),b(e)},fadein:function(a,c){var e=a.toHSL();return e.a+=c.value/100,e.a=d(e.a),b(e)},fadeout:function(a,c){var e=a.toHSL();return e.a-=c.value/100,e.a=d(e.a),b(e)},fade:function(a,c){var e=a.toHSL();return e.a=c.value/100,e.a=d(e.a),b(e)},spin:function(a,c){var d=a.toHSL(),e=(d.h+c.value)%360;return d.h=e<0?360+e:e,b(d)},mix:function(b,c,d){var e=d.value/100,f=e*2-1,g=b.toHSL().a-c.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[b.rgb[0]*h+c.rgb[0]*i,b.rgb[1]*h+c.rgb[1]*i,b.rgb[2]*h+c.rgb[2]*i],k=b.alpha*e+c.alpha*(1-e);return new a.Color(j,k)},greyscale:function(b){return this.desaturate(b,new a.Dimension(100))},e:function(b){return new a.Anonymous(b instanceof a.JavaScript?b.evaluated:b)},escape:function(b){return new a.Anonymous(encodeURI(b.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(b){var c=Array.prototype.slice.call(arguments,1),d=b.value;for(var e=0;e255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")},operate:function(b,c){var d=[];c instanceof a.Color||(c=c.toColor());for(var e=0;e<3;e++)d[e]=a.operate(b,this.rgb[e],c.rgb[e]);return new a.Color(d,this.alpha+c.alpha)},toHSL:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255,d=this.alpha,e=Math.max(a,b,c),f=Math.min(a,b,c),g,h,i=(e+f)/2,j=e-f;if(e===f)g=h=0;else{h=i>.5?j/(2-e-f):j/(e+f);switch(e){case a:g=(b-c)/j+(b255?255:a<0?0:a).toString(16),a.length===1?"0"+a:a}).join("")}}}(c("../tree")),function(a){a.Comment=function(a,b){this.value=a,this.silent=!!b},a.Comment.prototype={toCSS:function(a){return a.compress?"":this.value},eval:function(){return this}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype.eval=function(a){var b=this.lvalue.eval(a),c=this.rvalue.eval(a),d=this.index,e,e=function(a){switch(a){case"and":return b&&c;case"or":return b||c;default:if(b.compare)e=b.compare(c);else if(c.compare)e=c.compare(b);else throw{type:"Type",message:"Unable to perform comparison",index:d};switch(e){case-1:return a==="<"||a==="=<";case 0:return a==="="||a===">="||a==="=<";case 1:return a===">"||a===">="}}}(this.op);return this.negate?!e:e}}(c("../tree")),function(a){a.Dimension=function(a,b){this.value=parseFloat(a),this.unit=b||null},a.Dimension.prototype={eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},toCSS:function(){var a=this.value+this.unit;return a},operate:function(b,c){return new a.Dimension(a.operate(b,this.value,c.value),this.unit||c.unit)},compare:function(b){return b instanceof a.Dimension?b.value>this.value?-1:b.value":a.compress?">":" > "}[this.value]}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={eval:function(b){return this.value.length>1?new a.Expression(this.value.map(function(a){return a.eval(b)})):this.value.length===1?this.value[0].eval(b):this},toCSS:function(a){return this.value.map(function(b){return b.toCSS?b.toCSS(a):""}).join(" ")}}}(c("../tree")),function(a){a.Import=function(b,c,d,e){var f=this;this.index=e,this._path=b,this.features=d&&new a.Value(d),b instanceof a.Quoted?this.path=/\.(le?|c)ss(\?.*)?$/.test(b.value)?b.value:b.value+".less":this.path=b.value.value||b.value,this.css=/css(\?.*)?$/.test(this.path),this.css||c.push(this.path,function(b,c){b&&(b.index=e),f.root=c||new a.Ruleset([],[])})},a.Import.prototype={toCSS:function(a){var b=this.features?" "+this.features.toCSS(a):"";return this.css?"@import "+this._path.toCSS()+b+";\n":""},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.css)return this;c=new a.Ruleset([],this.root.rules.slice(0));for(var e=0;e1){var d=new a.Element("&",null,0),e=[new a.Selector([d])];c=new a.Ruleset(e,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(a.length===0)return[];if(a.length===1)return a[0];var b=[],c=this.permute(a.slice(1));for(var d=0;d0){c=this.arguments&&this.arguments.map(function(b){return b.eval(a)});for(var g=0;gthis.params.length)return!1;if(this.required>0&&c>this.params.length)return!1}if(this.condition&&!this.condition.eval({frames:[this.evalParams(b,a)].concat(b.frames)}))return!1;d=Math.min(c,this.arity);for(var f=0;fe.selectors[g].elements.length?Array.prototype.push.apply(d,e.find(new a.Selector(b.elements.slice(1)),c)):d.push(e);break}}),this._lookups[g]=d)},toCSS:function(b,c){var d=[],e=[],f=[],g=[],h,i;this.root||(b.length===0?g=this.selectors.map(function(a){return[a]}):this.joinSelectors(g,b,this.selectors));for(var j=0;j0&&(h=g.map(function(a){return a.map(function(a){return a.toCSS(c)}).join("").trim()}).join(c.compress?",":",\n"),d.push(h,(c.compress?"{":" {\n ")+e.join(c.compress?"":"\n ")+(c.compress?"}":"\n}\n"))),d.push(f),d.join("")+(c.compress?"\n":"")},joinSelectors:function(a,b,c){for(var d=0;d0&&e.push(new a.Selector(g)),h.length>0&&f.push(new a.Selector(h));for(var l=0;l0&&(b.value=c[0]+(b.value.charAt(0)==="/"?b.value.slice(1):b.value)),this.value=b,this.paths=c)},b.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data:"+this.attrs.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("../tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}}}(c("../tree")),function(a){a.Variable=function(a,b,c){this.name=a,this.index=b,this.file=c},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{type:"Name",message:"variable "+e+" is undefined",filename:this.file,index:this.index}}}}(c("../tree")),function(a){a.find=function(a,b){for(var c=0,d;c1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)}}(c("./tree"));var f=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||f?"development":"production"),d.async=!1,d.poll=d.poll||(f?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&m(function(a,b,c,d,e){b&&p(b.toCSS(),d,e.lastModified)})},d.poll)):d.optimization=3;var g;try{g=typeof a.localStorage=="undefined"?null:a.localStorage}catch(h){g=null}var i=document.getElementsByTagName("link"),j=/^text\/(x-)?less$/;d.sheets=[];for(var k=0;k +" +" Version: 2.2.1 +" Created: 17th Apr 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (17th Apr 2007) +"------------------------------------------------------------------------ +" Description: +" Defines functions that asks vim what it is relinquish to tell us +" - menu +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.0.0: +" TODO: «missing features» +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#askvim#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#askvim#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" # Public {{{2 +" Function: lh#askvim#exe(command) {{{3 +function! lh#askvim#Exe(command) + echomsg 'lh#askvim#Exe() is deprecated, use lh#askvim#exe()' + return lh#askvim#exe(a:command) +endfunction + +function! lh#askvim#exe(command) + let save_a = @a + try + silent! redir @a + silent! exe a:command + redir END + finally + " Always restore everything + let res = @a + let @a = save_a + return res + endtry +endfunction + + +" Function: lh#askvim#menu(menuid) {{{3 +function! s:AskOneMenu(menuact, res) + let sKnown_menus = lh#askvim#exe(a:menuact) + let lKnown_menus = split(sKnown_menus, '\n') + " echo string(lKnown_menus) + + " 1- search for the menuid + " todo: fix the next line to correctly interpret "stuff\.stuff" and + " "stuff\\.stuff". + let menuid_parts = split(a:menuact, '\.') + + let simplifiedKnown_menus = deepcopy(lKnown_menus) + call map(simplifiedKnown_menus, 'substitute(v:val, "&", "", "g")') + " let idx = lh#list#match(simplifiedKnown_menus, '^\d\+\s\+'.menuid_parts[-1]) + let idx = match(simplifiedKnown_menus, '^\d\+\s\+'.menuid_parts[-1]) + if idx == -1 + " echo "not found" + return + endif + " echo "l[".idx."]=".lKnown_menus[idx] + + if empty(a:res) + let a:res.priority = matchstr(lKnown_menus[idx], '\d\+\ze\s\+.*') + let a:res.name = matchstr(lKnown_menus[idx], '\d\+\s\+\zs.*') + let a:res.actions = {} + " else + " what if the priority isn't the same? + endif + + " 2- search for the menu definition + let idx += 1 + while idx != len(lKnown_menus) + echo "l[".idx."]=".lKnown_menus[idx] + " should not happen + if lKnown_menus[idx] =~ '^\d\+' | break | endif + + " :h showing-menus + " -> The format of the result of the call to Exe() seems to be: + " ^ssssMns-sACTION$ + " s == 1 whitespace + " M == mode (inrvcs) + " n == noremap(*)/script(&) + " - == disable(-)/of not + let act = {} + let menu_def = matchlist(lKnown_menus[idx], + \ '^\s*\([invocs]\)\([&* ]\) \([- ]\) \(.*\)$') + if len(menu_def) > 4 + let act.mode = menu_def[1] + let act.nore_script = menu_def[2] + let act.disabled = menu_def[3] + let act.action = menu_def[4] + else + echomsg string(menu_def) + echoerr "lh#askvim#menu(): Cannot decode ``".lKnown_menus[idx]."''" + endif + + let a:res.actions["mode_" . act.mode] = act + + let idx += 1 + endwhile + + " n- Return the result + return a:res +endfunction + +function! lh#askvim#menu(menuid, modes) + let res = {} + let i = 0 + while i != strlen(a:modes) + call s:AskOneMenu(a:modes[i].'menu '.a:menuid, res) + let i += 1 + endwhile + return res +endfunction +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer.vim new file mode 100644 index 0000000..6af2ef7 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer.vim @@ -0,0 +1,97 @@ +"============================================================================= +" $Id: buffer.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/buffer.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 23rd Jan 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Defines functions that help finding windows and handling buffers. +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v 1.0.0 First Version +" (*) Functions moved from searchInRuntimeTime +" v 2.2.0 +" (*) new function: lh#buffer#list() +" TODO: +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + +" ## Functions {{{1 +"------------------------------------------------------------------------ +" # Debug {{{2 +function! lh#buffer#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#buffer#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" # Public {{{2 + +" Function: lh#buffer#find({filename}) {{{3 +" If {filename} is opened in a window, jump to this window, otherwise return -1 +" Moved from searchInRuntimeTime.vim +function! lh#buffer#find(filename) + let b = bufwinnr(a:filename) + if b == -1 | return b | endif + exe b.'wincmd w' + return b +endfunction +function! lh#buffer#Find(filename) + return lh#buffer#find(a:filename) +endfunction + +" Function: lh#buffer#jump({filename},{cmd}) {{{3 +function! lh#buffer#jump(filename, cmd) + if lh#buffer#find(a:filename) != -1 | return | endif + exe a:cmd . ' ' . a:filename +endfunction +function! lh#buffer#Jump(filename, cmd) + return lh#buffer#jump(a:filename, a:cmd) +endfunction + +" Function: lh#buffer#scratch({bname},{where}) {{{3 +function! lh#buffer#scratch(bname, where) + try + silent exe a:where.' sp '.a:bname + catch /.*/ + throw "Can't open a buffer named '".a:bname."'!" + endtry + setlocal bt=nofile bh=wipe nobl noswf ro +endfunction +function! lh#buffer#Scratch(bname, where) + return lh#buffer#scratch(a:bname, a:where) +endfunction + +" Function: lh#buffer#list() {{{3 +function! lh#buffer#list() + let all = range(0, bufnr('$')) + " let res = lh#list#transform_if(all, [], 'v:1_', 'buflisted') + let res = lh#list#copy_if(all, [], 'buflisted') + return res +endfunction +" Ex: echo lh#list#transform(lh#buffer#list(), [], "bufname") +"============================================================================= +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer/dialog.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer/dialog.vim new file mode 100644 index 0000000..7628734 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/buffer/dialog.vim @@ -0,0 +1,268 @@ +"============================================================================= +" $Id: dialog.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/buffer/dialog.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 21st Sep 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: «description» +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v 1.0.0 First Version +" (*) Functions imported from Mail_mutt_alias.vim +" TODO: +" (*) --abort-- line +" (*) custom messages +" (*) do not mess with search history +" (*) support any &magic +" (*) syntax +" (*) add number/letters +" (*) tag with '[x] ' instead of '* ' +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + + + +"============================================================================= +" ## Globals {{{1 +let s:LHdialog = {} + +"============================================================================= +" ## Functions {{{1 +" # Debug {{{2 +function! lh#buffer#dialog#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#buffer#dialog#debug(expr) + return eval(a:expr) +endfunction + + +"============================================================================= +" # Dialog functions {{{2 +"------------------------------------------------------------------------ +function! s:Mappings(abuffer) + " map to edit a file, also dbl-click + exe "nnoremap :silent call ".a:abuffer.action."(-1, ".a:abuffer.id.")" + exe "nnoremap q :call lh#buffer#dialog#select(-1, ".a:abuffer.id.")" + exe "nnoremap :call lh#buffer#dialog#select(line('.'), ".a:abuffer.id.")" + " nnoremap <2-LeftMouse> :silent call GrepEditFileLine(line(".")) + " nnoremap Q :call Reformat() + " nnoremap :set tabstop-=1 + " nnoremap :set tabstop+=1 + if a:abuffer.support_tagging + nnoremap t :silent call ToggleTag(line(".")) + nnoremap :silent call ToggleTag(line(".")) + endif + nnoremap :silent call NextChoice('') + nnoremap :silent call NextChoice('b') + exe "nnoremap h :silent call ToggleHelp(".a:abuffer.id.")" +endfunction + +"---------------------------------------- +" Tag / untag the current choice {{{ +function! s:ToggleTag(lineNum) + if a:lineNum > s:Help_NbL() + " If tagged + if (getline(a:lineNum)[0] == '*') + let b:NbTags = b:NbTags - 1 + silent exe a:lineNum.'s/^\* / /e' + else + let b:NbTags = b:NbTags + 1 + silent exe a:lineNum.'s/^ /* /e' + endif + " Move after the tag ; there is something with the two previous :s. They + " don't leave the cursor at the same position. + silent! normal! 3| + call s:NextChoice('') " move to the next choice + endif +endfunction +" }}} + +function! s:Help_NbL() + " return 1 + nb lines of BuildHelp + return 2 + len(b:dialog['help_'.b:dialog.help_type]) +endfunction +"---------------------------------------- +" Go to the Next (/previous) possible choice. {{{ +function! s:NextChoice(direction) + " echomsg "next!" + call search('^[ *]\s*\zs\S\+', a:direction) +endfunction +" }}} + +"------------------------------------------------------------------------ + +function! s:RedisplayHelp(dialog) + silent! 2,$g/^@/d_ + normal! gg + for help in a:dialog['help_'.a:dialog.help_type] + silent put=help + endfor +endfunction + +function! lh#buffer#dialog#update(dialog) + set noro + exe (s:Help_NbL()+1).',$d_' + for choice in a:dialog.choices + silent $put=' '.choice + endfor + set ro +endfunction + +function! s:Display(dialog, atitle) + set noro + 0 put = a:atitle + call s:RedisplayHelp(a:dialog) + for choice in a:dialog.choices + silent $put=' '.choice + endfor + set ro + exe s:Help_NbL()+1 +endfunction + +function! s:ToggleHelp(bufferId) + call lh#buffer#find(a:bufferId) + call b:dialog.toggle_help() +endfunction + +function! lh#buffer#dialog#toggle_help() dict + let self.help_type + \ = (self.help_type == 'short') + \ ? 'long' + \ : 'short' + call s:RedisplayHelp(self) +endfunction + +function! lh#buffer#dialog#new(bname, title, where, support_tagging, action, choices) + " The ID will be the buffer id + let res = {} + let where_it_started = getpos('.') + let where_it_started[0] = bufnr('%') + let res.where_it_started = where_it_started + + try + call lh#buffer#scratch(a:bname, a:where) + catch /.*/ + echoerr v:exception + return res + endtry + let res.id = bufnr('%') + let b:NbTags = 0 + let b:dialog = res + let s:LHdialog[res.id] = res + let res.help_long = [] + let res.help_short = [] + let res.help_type = 'short' + let res.support_tagging = a:support_tagging + let res.action = a:action + let res.choices = a:choices + + " Long help + call lh#buffer#dialog#add_help(res, '@| , : select this', 'long') + call lh#buffer#dialog#add_help(res, '@| , q : Abort', 'long') + if a:support_tagging + call lh#buffer#dialog#add_help(res, '@| , : Tag/Untag the current item', 'long') + endif + call lh#buffer#dialog#add_help(res, '@| /, , +/- : Move between entries', 'long') + call lh#buffer#dialog#add_help(res, '@|', 'long') + " call lh#buffer#dialog#add_help(res, '@| h : Toggle help', 'long') + call lh#buffer#dialog#add_help(res, '@+'.repeat('-', winwidth(bufwinnr(res.id))-3), 'long') + " Short Help + " call lh#buffer#dialog#add_help(res, '@| h : Toggle help', 'short') + call lh#buffer#dialog#add_help(res, '@+'.repeat('-', winwidth(bufwinnr(res.id))-3), 'short') + + let res.toggle_help = function("lh#buffer#dialog#toggle_help") + let title = '@ ' . a:title + let helpstr = '| Toggle (h)elp' + let title = title + \ . repeat(' ', winwidth(bufwinnr(res.id))-strlen(title)-strlen(helpstr)-1) + \ . helpstr + call s:Display(res, title) + + call s:Mappings(res) + return res +endfunction + +function! lh#buffer#dialog#add_help(abuffer, text, help_type) + call add(a:abuffer['help_'.a:help_type],a:text) +endfunction + +"============================================================================= +function! lh#buffer#dialog#quit() + let bufferId = b:dialog.where_it_started[0] + echohl WarningMsg + echo "Abort" + echohl None + quit + call lh#buffer#find(bufferId) +endfunction + +" Function: lh#buffer#dialog#select(line, bufferId [,overriden-action]) +function! lh#buffer#dialog#select(line, bufferId, ...) + if a:line == -1 + call lh#buffer#dialog#quit() + return + " elseif a:line <= s:Help_NbL() + 1 + elseif a:line <= s:Help_NbL() + echoerr "Unselectable item" + return + else + let dialog = s:LHdialog[a:bufferId] + let results = { 'dialog' : dialog, 'selection' : [] } + + if b:NbTags == 0 + " -1 because first index is 0 + " let results = [ dialog.choices[a:line - s:Help_NbL() - 1] ] + let results.selection = [ a:line - s:Help_NbL() - 1 ] + else + silent g/^* /call add(results.selection, line('.')-s:Help_NbL()-1) + endif + endif + + if a:0 > 0 " action overriden + exe 'call '.dialog.action.'(results, a:000)' + else + exe 'call '.dialog.action.'(results)' + endif +endfunction +function! lh#buffer#dialog#Select(line, bufferId, ...) + echomsg "lh#buffer#dialog#Select() is deprecated, use lh#buffer#dialog#select() instead" + if a:0 > 0 " action overriden + exe 'call lh#buffer#dialog#select(a:line, a:bufferId, a:1)' + else + exe 'call lh#buffer#dialog#select(a:line, a:bufferId)' + endif +endfunction + +function! Action(results) + let dialog = a:results.dialog + let choices = dialog.choices + for r in a:results.selection + echomsg '-> '.choices[r] + endfor +endfunction + + +"============================================================================= +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/command.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/command.vim new file mode 100644 index 0000000..e1df77c --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/command.vim @@ -0,0 +1,224 @@ +"============================================================================= +" $Id: command.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/command.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 08th Jan 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (08th Jan 2007) +"------------------------------------------------------------------------ +" Description: +" Helpers to define commands that: +" - support subcommands +" - support autocompletion +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.0.0: +" Code move from other plugins +" TODO: «missing features» +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + +" ## Debug {{{1 +function! lh#command#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#command#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" ## Functions {{{1 + +" Tool functions {{{2 +" Function: lh#command#Fargs2String(aList) {{{3 +" @param[in,out] aList list of params from +" @see tests/lh/test-Fargs2String.vim +function! lh#command#Fargs2String(aList) + if empty(a:aList) | return '' | endif + + let quote_char = a:aList[0][0] + let res = a:aList[0] + call remove(a:aList, 0) + if quote_char !~ '["'."']" + return res + endif + " else + let end_string = '[^\\]\%(\\\\\)*'.quote_char.'$' + while !empty(a:aList) && res !~ end_string + let res .= ' ' . a:aList[0] + call remove(a:aList, 0) + endwhile + return res +endfunction + +"------------------------------------------------------------------------ +" ## Experimental Functions {{{1 + +" Internal functions {{{2 +" Function: s:SaveData({Data}) {{{3 +" @param Data Command definition +" Saves {Data} as s:Data{s:data_id++}. The definition will be used by +" automatically generated commands. +" @return s:data_id +let s:data_id = 0 +function! s:SaveData(Data) + if has_key(a:Data, "command_id") + " Avoid data duplication + return a:Data.command_id + else + let s:Data{s:data_id} = a:Data + let id = s:data_id + let s:data_id += 1 + let a:Data.command_id = id + return id + endif +endfunction + +" BTWComplete(ArgLead, CmdLine, CursorPos): Auto-complete {{{3 +function! lh#command#complete(ArgLead, CmdLine, CursorPos) + let tmp = substitute(a:CmdLine, '\s*\S*', 'Z', 'g') + let pos = strlen(tmp) + if 0 + call confirm( "AL = ". a:ArgLead."\nCL = ". a:CmdLine."\nCP = ".a:CursorPos + \ . "\ntmp = ".tmp."\npos = ".pos + \, '&Ok', 1) + endif + + if 2 == pos + " First argument: a command + return s:commands + elseif 3 == pos + " Second argument: first arg of the command + if -1 != match(a:CmdLine, '^BTW\s\+echo') + return s:functions . "\n" . s:variables + elseif -1 != match(a:CmdLine, '^BTW\s\+\%(help\|?\)') + elseif -1 != match(a:CmdLine, '^BTW\s\+\%(set\|add\)\%(local\)\=') + " Adds a filter + " let files = globpath(&rtp, 'compiler/BT-*') + " let files = files . globpath(&rtp, 'compiler/BT_*') + " let files = files . globpath(&rtp, 'compiler/BT/*') + let files = s:FindFilter('*') + let files = substitute(files, + \ '\(^\|\n\).\{-}compiler[\\/]BTW[-_\\/]\(.\{-}\)\.vim\>\ze\%(\n\|$\)', + \ '\1\2', 'g') + return files + elseif -1 != match(a:CmdLine, '^BTW\s\+remove\%(local\)\=') + " Removes a filter + return substitute(s:FiltersList(), ',', '\n', 'g') + endif + endif + " finally: unknown + echoerr 'BTW: unespected parameter ``'. a:ArgLead ."''" + return '' +endfunction + +function! s:BTW(command, ...) + " todo: check a:0 > 1 + if 'set' == a:command | let g:BTW_build_tool = a:1 + if exists('b:BTW_build_tool') + let b:BTW_build_tool = a:1 + endif + elseif 'setlocal' == a:command | let b:BTW_build_tool = a:1 + elseif 'add' == a:command | call s:AddFilter('g', a:1) + elseif 'addlocal' == a:command | call s:AddFilter('b', a:1) + " if exists('b:BTW_filters_list') " ????? + " call s:AddFilter('b', a:1) + " endif + elseif 'remove' == a:command | call s:RemoveFilter('g', a:1) + elseif 'removelocal' == a:command | call s:RemoveFilter('b', a:1) + elseif 'rebuild' == a:command " wait for s:ReconstructToolsChain() + elseif 'echo' == a:command | exe "echo s:".a:1 + " echo s:{a:f1} ## don't support «echo s:f('foo')» + elseif 'reloadPlugin' == a:command + let g:force_reload_BuildToolsWrapper = 1 + let g:BTW_BTW_in_use = 1 + exe 'so '.s:sfile + unlet g:force_reload_BuildToolsWrapper + unlet g:BTW_BTW_in_use + return + elseif a:command =~ '\%(help\|?\)' + call s:Usage() + return + endif + call s:ReconstructToolsChain() +endfunction + +" ############################################################## +" Public functions {{{2 + +function! s:FindSubcommand(definition, subcommand) + for arg in a:definition.arguments + if arg.name == a:subcommand + return arg + endif + endfor + throw "NF" +endfunction + +function! s:execute_function(definition, params) + if len(a:params) < 1 + throw "(lh#command) Not enough arguments" + endif + let l:Fn = a:definition.action + echo "calling ".string(l:Fn) + echo "with ".string(a:params) + " call remove(a:params, 0) + call l:Fn(a:params) +endfunction + +function! s:execute_sub_commands(definition, params) + try + if len(a:params) < 1 + throw "(lh#command) Not enough arguments" + endif + let subcommand = s:FindSubcommand(a:definition, a:params[0]) + call remove(a:params, 0) + call s:int_execute(subcommand, a:params) + catch /NF.*/ + throw "(lh#command) Unexpected subcommand `".a:params[0]."'." + endtry +endfunction + +function! s:int_execute(definition, params) + echo "params=".string(a:params) + call s:execute_{a:definition.arg_type}(a:definition, a:params) +endfunction + +function! s:execute(definition, ...) + try + let params = copy(a:000) + call s:int_execute(a:definition, params) + catch /(lh#command).*/ + echoerr v:exception . " in `".a:definition.name.' '.join(a:000, ' ')."'" + endtry +endfunction + +function! lh#command#new(definition) + let cmd_name = a:definition.name + " Save the definition as an internal script variable + let id = s:SaveData(a:definition) + exe "command! -nargs=* ".cmd_name." :call s:execute(s:Data".id.", )" +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/common.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/common.vim new file mode 100644 index 0000000..ddbad82 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/common.vim @@ -0,0 +1,93 @@ +"============================================================================= +" $Id: common.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/common.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 07th Oct 2006 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (08th Feb 2008) +"------------------------------------------------------------------------ +" Description: +" Some common functions for: +" - displaying error messages +" - checking dependencies +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.1.1 +" - New function: lh#common#echomsg_multilines() +" - lh#common#warning_msg() supports multilines messages +" +" v2.0.0: +" - Code moved from other plugins +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" Functions {{{1 + +" Function: lh#common#echomsg_multilines {{{2 +function! lh#common#echomsg_multilines(text) + let lines = split(a:text, "[\n\r]") + for line in lines + echomsg line + endfor +endfunction +function! lh#common#echomsgMultilines(text) + return lh#common#echomsg_multilines(a:text) +endfunction + +" Function: lh#common#error_msg {{{2 +function! lh#common#error_msg(text) + if has('gui_running') + call confirm(a:text, '&Ok', '1', 'Error') + else + " echohl ErrorMsg + echoerr a:text + " echohl None + endif +endfunction +function! lh#common#ErrorMsg(text) + return lh#common#error_msg(a:text) +endfunction + +" Function: lh#common#warning_msg {{{2 +function! lh#common#warning_msg(text) + echohl WarningMsg + " echomsg a:text + call lh#common#echomsg_multilines(a:text) + echohl None +endfunction +function! lh#common#WarningMsg(text) + return lh#common#warning_msg(a:text) +endfunction + +" Dependencies {{{2 +function! lh#common#check_deps(Symbol, File, path, plugin) " {{{3 + if !exists(a:Symbol) + exe "runtime ".a:path.a:File + if !exists(a:Symbol) + call lh#common#error_msg( a:plugin.': Requires <'.a:File.'>') + return 0 + endif + endif + return 1 +endfunction + +function! lh#common#CheckDeps(Symbol, File, path, plugin) " {{{3 + echomsg "lh#common#CheckDeps() is deprecated, use lh#common#check_deps() instead." + return lh#common#check_deps(a:Symbol, a:File, a:path, a:plugin) +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/encoding.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/encoding.vim new file mode 100644 index 0000000..6a220d3 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/encoding.vim @@ -0,0 +1,49 @@ +"============================================================================= +" $Id: encoding.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/encoding.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 21st Feb 2008 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Defines functions that help managing various encodings +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.0.7: +" (*) lh#encoding#Iconv() copied from map-tools +" TODO: «missing features» +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ + +" Function: lh#encoding#iconv(expr, from, to) " {{{3 +" Unlike |iconv()|, this wrapper returns {expr} when we know no convertion can +" be acheived. +function! lh#encoding#iconv(expr, from, to) + " call Dfunc("s:ICONV(".a:expr.','.a:from.','.a:to.')') + if has('multi_byte') && + \ ( has('iconv') || has('iconv/dyn') || + \ ((a:from=~'latin1\|utf-8') && (a:to=~'latin1\|utf-8'))) + " call confirm('encoding: '.&enc."\nto:".a:to, "&Ok", 1) + " call Dret("s:ICONV convert=".iconv(a:expr, a:from, a:to)) + return iconv(a:expr,a:from,a:to) + else + " Cannot convert + " call Dret("s:ICONV no convert=".a:expr) + return a:expr + endif +endfunction + +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/env.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/env.vim new file mode 100644 index 0000000..fb8412c --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/env.vim @@ -0,0 +1,75 @@ +"============================================================================= +" $Id: env.vim 244 2010-09-19 22:38:24Z luc.hermitte $ +" File: autoload/lh/env.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 19th Jul 2010 +" Last Update: $Date: 2010-09-19 18:38:24 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Functions related to environment (variables) +" +"------------------------------------------------------------------------ +" Installation: +" Drop this file into {rtp}/autoload/lh +" Requires Vim7+ +" History: +" v2.2.1 First Version +" TODO: «missing features» +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" ## Misc Functions {{{1 +" # Version {{{2 +let s:k_version = 221 +function! lh#env#version() + return s:k_version +endfunction + +" # Debug {{{2 +let s:verbose = 0 +function! lh#env#verbose(...) + if a:0 > 0 | let s:verbose = a:1 | endif + return s:verbose +endfunction + +function! s:Verbose(expr) + if s:verbose + echomsg a:expr + endif +endfunction + +function! lh#env#debug(expr) + return eval(a:expr) +endfunction + + +"------------------------------------------------------------------------ +" ## Exported functions {{{1 +function! lh#env#expand_all(string) + let res = '' + let tail = a:string + while !empty(tail) + let [ all, head, var, tail; dummy ] = matchlist(tail, '\(.\{-}\)\%(${\(.\{-}\)}\)\=\(.*\)') + if empty(var) + let res .= tail + break + else + let res .= head + let val = eval('$'.var) + let res .= val + endif + endwhile + return res +endfunction +"------------------------------------------------------------------------ +" ## Internal functions {{{1 + +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/event.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/event.vim new file mode 100644 index 0000000..ce53c66 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/event.vim @@ -0,0 +1,68 @@ +"============================================================================= +" $Id: event.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/event.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 15th Feb 2008 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Function to help manage vim |autocommand-events| +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.0.6: +" Creation +" TODO: +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim + +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#event#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#event#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" # Event Registration {{{2 +function! s:RegisteredOnce(cmd, group) + " We can't delete the current augroup autocommand => increment a counter + if !exists('s:'.a:group) || s:{a:group} == 0 + let s:{a:group} = 1 + exe a:cmd + endif +endfunction + +function! lh#event#register_for_one_execution_at(event, cmd, group) + let group = a:group.'_once' + let s:{group} = 0 + exe 'augroup '.group + au! + exe 'au '.a:event.' '.expand('%:p').' call s:RegisteredOnce('.string(a:cmd).','.string(group).')' + augroup END +endfunction +function! lh#event#RegisterForOneExecutionAt(event, cmd, group) + return lh#event#register_for_one_execution_at(a:event, a:cmd, a:group) +endfunction +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/function.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/function.vim new file mode 100644 index 0000000..4f9b331 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/function.vim @@ -0,0 +1,214 @@ +"============================================================================= +" $Id: function.vim 161 2010-05-07 01:04:44Z luc.hermitte $ +" File: autoload/lh/function.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.0 +" Created: 03rd Nov 2008 +" Last Update: $Date: 2010-05-06 21:04:44 -0400 (Thu, 06 May 2010) $ +"------------------------------------------------------------------------ +" Description: +" Implements: +" - lh#function#bind() +" - lh#function#execute() +" - lh#function#prepare() +" - a binded function type +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.2.0: first implementation +" TODO: «missing features» +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ + +" ## Functions {{{1 +" # Debug {{{2 +function! lh#function#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#function#debug(expr) + return eval(a:expr) +endfunction + +" # Function: s:Join(arguments...) {{{2 +function! s:Join(args) + let res = '' + if len(a:args) > 0 + let res = string(a:args[0]) + let i = 1 + while i != len(a:args) + let res.=','.string(a:args[i]) + let i += 1 + endwhile + endif + return res +endfunction + +" # Function: s:DoBindList(arguments...) {{{2 +function! s:DoBindList(formal, real) + let args = [] + for arg in a:formal + if type(arg)==type('string') && arg =~ '^v:\d\+_$' + let new = a:real[matchstr(arg, 'v:\zs\d\+\ze_')-1] + elseif type(arg)==type('string') + let new = eval(s:DoBindEvaluatedString(arg, a:real)) + else + let new = arg + endif + call add(args, new) + unlet new + unlet arg + endfor + return args +endfunction + +" # Function: s:DoBindString(arguments...) {{{2 +function! s:DoBindString(expr, real) + let expr = substitute(a:expr, '\', a:real.'[\1-1]', 'g') + return expr +endfunction + +function! s:ToString(expr) + return type(a:expr) != type('') + \ ? string(a:expr) + \ : (a:expr) +endfunction + +function! s:DoBindEvaluatedString(expr, real) + let expr = a:expr + let p = 0 + while 1 + let p = match(expr, '\', p) + if -1 == p | break | endif + let e = matchend(expr, '\', p) + let n = eval(expr[p+2 : e-2]) + " let new = (type(a:real[n-1])==type('') && a:real[n-1]=~ '\') + " \ ? a:real[n-1] + " \ : string(a:real[n-1]) + let new = s:ToString(a:real[n-1]) + " let new = string(a:real[n-1]) " -> bind_counpound vars + let expr = ((p>0) ? (expr[0:p-1]) : '') . new . expr[e : -1] + " echo expr + let p += len(new) + " silent! unlet new + endwhile + + return expr +endfunction + +" # Function: s:Execute(arguments...) {{{2 +function! s:Execute(args) dict + if type(self.function) == type(function('exists')) + let args = s:DoBindList(self.args, a:args) + " echomsg '##'.string(self.function).'('.join(args, ',').')' + let res = eval(string(self.function).'('.s:Join(args).')') + elseif type(self.function) == type('string') + let expr = s:DoBindString(self.function, 'a:args') + let res = eval(expr) + elseif type(self.function) == type({}) + return self.function.execute(a:args) + else + throw "lh#functor#execute: unpected function type: ".type(self.function) + endif + return res +endfunction + +" # Function: lh#function#prepare(function, arguments_list) {{{2 +function! lh#function#prepare(Fn, arguments_list) + if type(a:Fn) == type(function('exists')) + let expr = string(a:Fn).'('.s:Join(a:arguments_list).')' + return expr + elseif type(a:Fn) == type('string') + if a:Fn =~ '^[a-zA-Z0-9_#]\+$' + let expr = string(function(a:Fn)).'('.s:Join(a:arguments_list).')' + return expr + else + let expr = s:DoBindString(a:Fn, 'a:000') + return expr + endif + else + throw "lh#function#prepare(): {Fn} argument of type ".type(a:Fn). " is unsupported" + endif +endfunction + +" # Function: lh#function#execute(function, arguments...) {{{2 +function! lh#function#execute(Fn, ...) + if type(a:Fn) == type({}) && has_key(a:Fn, 'execute') + return a:Fn.execute(a:000) + else + let expr = lh#function#prepare(a:Fn, a:000) + return eval(expr) + endif +endfunction + +" # Function: lh#function#bind(function, arguments...) {{{2 +function! lh#function#bind(Fn, ...) + let args = copy(a:000) + if type(a:Fn) == type('string') && a:Fn =~ '^[a-zA-Z0-9_#]\+$' + \ && exists('*'.a:Fn) + let Fn = function(a:Fn) + elseif type(a:Fn) == type({}) + " echo string(a:Fn).'('.string(a:000).')' + " Rebinding another binded function + " TASSERT has_key(a:Fn, 'function') + " TASSERT has_key(a:Fn, 'execute') + " TASSERT has_key(a:Fn, 'args') + let Fn = a:Fn.function + let N = len(a:Fn.args) + if N != 0 " args to rebind + let i = 0 + let t_args = [] " necessary to avoid type changes + while i != N + silent! unlet arg + let arg = a:Fn.args[i] + if arg =~ 'v:\d\+_$' + let arg2 = eval(s:DoBindString(arg, string(args))) + " echo arg."-(".string(args).")->".string(arg2) + unlet arg + let arg = arg2 + unlet arg2 + endif + call add(t_args, arg) + let i += 1 + endwhile + unlet a:Fn.args + let a:Fn.args = t_args + else " expression to fix + " echo Fn + " echo s:DoBindString(Fn, string(args)) + " echo eval(string(s:DoBindString(Fn, string(args)))) + let Fn = (s:DoBindEvaluatedString(Fn, args)) + endif + let args = a:Fn.args + else + let Fn = a:Fn + endif + + let binded_fn = { + \ 'function': Fn, + \ 'args': args, + \ 'execute': function('s:Execute') + \} + return binded_fn +endfunction + +" }}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: +" Vim: let g:UTfiles='tests/lh/function.vim' diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/graph/tsort.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/graph/tsort.vim new file mode 100644 index 0000000..99dfa72 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/graph/tsort.vim @@ -0,0 +1,177 @@ +"============================================================================= +" $Id: tsort.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/tsort.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 21st Apr 2008 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: Library functions for Topological Sort +" +"------------------------------------------------------------------------ +" Drop the file into {rtp}/autoload/lh/graph +" History: «history» +" TODO: «missing features» +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim + +"------------------------------------------------------------------------ +" ## Debug {{{1 +function! lh#graph#tsort#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#graph#tsort#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +"## Helper functions {{{1 +"# s:Successors_fully_defined(node) {{{2 +function! s:Successors_fully_defined(node) dict + if has_key(self.table, a:node) + return self.table[a:node] + else + return [] + endif +endfunction + +"# s:Successors_lazy(node) {{{2 +function! s:Successors_lazy(node) dict + if !has_key(self.table, a:node) + let nodes = self.fetch(a:node) + let self.table[a:node] = nodes + " if len(nodes) > 0 + " let self.nb += 1 + " endif + return nodes + else + return self.table[a:node] + endif +endfunction + +"# s:PrepareDAG(dag) {{{2 +function! s:PrepareDAG(dag) + if type(a:dag) == type(function('has_key')) + let dag = { + \ 'successors': function('s:Successors_lazy'), + \ 'fetch' : a:dag, + \ 'table' : {} + \} + else + let dag = { + \ 'successors': function('s:Successors_fully_defined'), + \ 'table' : deepcopy(a:dag) + \} + endif + return dag +endfunction + +"## Depth-first search (recursive) {{{1 +" Do not detect cyclic graphs + +"# lh#graph#tsort#depth(dag, start_nodes) {{{2 +function! lh#graph#tsort#depth(dag, start_nodes) + let dag = s:PrepareDAG(a:dag) + let results = [] + let visited_nodes = { 'Visited':function('s:Visited')} + call s:RecursiveDTSort(dag, a:start_nodes, results, visited_nodes) + call reverse(results) + return results +endfunction + +"# The real, recursive, T-Sort {{{2 +"see boost.graph for a non recursive implementation +function! s:RecursiveDTSort(dag, start_nodes, results, visited_nodes) + for node in a:start_nodes + let visited = a:visited_nodes.Visited(node) + if visited == 1 | continue " done + elseif visited == 2 | throw "Tsort: cyclic graph detected: ".node + endif + let a:visited_nodes[node] = 2 " visiting + let succs = a:dag.successors(node) + try + call s:RecursiveDTSort(a:dag, succs, a:results, a:visited_nodes) + catch /Tsort:/ + throw v:exception.'>'.node + endtry + let a:visited_nodes[node] = 1 " visited + call add(a:results, node) + endfor +endfunction + +function! s:Visited(node) dict + return has_key(self, a:node) ? self[a:node] : 0 +endfunction + +"## Breadth-first search (non recursive) {{{1 +"# lh#graph#tsort#breadth(dag, start_nodes) {{{2 +" warning: This implementation does not work with lazy dag, but only with fully +" defined ones +function! lh#graph#tsort#breadth(dag, start_nodes) + let result = [] + let dag = s:PrepareDAG(a:dag) + let queue = deepcopy(a:start_nodes) + + while len(queue) > 0 + let node = remove(queue, 0) + " echomsg "result <- ".node + call add(result, node) + let successors = dag.successors(node) + while len(successors) > 0 + let m = s:RemoveEdgeFrom(dag, node) + " echomsg "graph loose ".node."->".m + if !s:HasIncomingEgde(dag, m) + " echomsg "queue <- ".m + call add(queue, m) + endif + endwhile + endwhile + if !s:Empty(dag) + throw "Tsort: cyclic graph detected: " + endif + return result +endfunction + +function! s:HasIncomingEgde(dag, node) + for node in keys(a:dag.table) + if type(a:dag.table[node]) != type([]) + continue + endif + if index(a:dag.table[node], a:node) != -1 + return 1 + endif + endfor + return 0 +endfunction +function! s:RemoveEdgeFrom(dag, node) + let successors = a:dag.successors(a:node) + if len(successors) > 0 + let successor = remove(successors, 0) + if len(successors) == 0 + " echomsg "finished with ->".a:node + call remove(a:dag.table, a:node) + endif + return successor + endif + throw "No more edges from ".a:node +endfunction +function! s:Empty(dag) + " echomsg "len="len(a:dag.table) + return len(a:dag.table) == 0 +endfunction +" }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/list.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/list.vim new file mode 100644 index 0000000..953c95b --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/list.vim @@ -0,0 +1,338 @@ +"============================================================================= +" $Id: list.vim 236 2010-06-01 00:43:34Z luc.hermitte $ +" File: autoload/lh/list.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 17th Apr 2007 +" Last Update: $Date: 2010-05-31 20:43:34 -0400 (Mon, 31 May 2010) $ (17th Apr 2007) +"------------------------------------------------------------------------ +" Description: +" Defines functions related to |Lists| +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.2.1: +" (*) use :unlet in :for loop to support heterogeneous lists +" (*) binary search algorithms (upper_bound, lower_bound, equal_range) +" v2.2.0: +" (*) new functions: lh#list#accumulate, lh#list#transform, +" lh#list#transform_if, lh#list#find_if, lh#list#copy_if, +" lh#list#subset, lh#list#intersect +" (*) the functions are compatible with lh#function functors +" v2.1.1: +" (*) unique_sort +" v2.0.7: +" (*) Bug fix: lh#list#Match() +" v2.0.6: +" (*) lh#list#Find_if() supports search predicate, and start index +" (*) lh#list#Match() supports start index +" v2.0.0: +" TODO: «missing features» +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#list#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#list#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" # Public {{{2 +" Function: lh#list#Transform(input, output, action) {{{3 +" deprecated version +function! lh#list#Transform(input, output, action) + let new = map(copy(a:input), a:action) + let res = extend(a:output,new) + return res + + for element in a:input + let action = substitute(a:action, 'v:val','element', 'g') + let res = eval(action) + call add(a:output, res) + unlet element " for heterogeneous lists + endfor + return a:output +endfunction + +function! lh#list#transform(input, output, action) + for element in a:input + let res = lh#function#execute(a:action, element) + call add(a:output, res) + unlet element " for heterogeneous lists + endfor + return a:output +endfunction + +function! lh#list#transform_if(input, output, action, predicate) + for element in a:input + if lh#function#execute(a:predicate, element) + let res = lh#function#execute(a:action, element) + call add(a:output, res) + endif + unlet element " for heterogeneous lists + endfor + return a:output +endfunction + +function! lh#list#copy_if(input, output, predicate) + for element in a:input + if lh#function#execute(a:predicate, element) + call add(a:output, element) + endif + unlet element " for heterogeneous lists + endfor + return a:output +endfunction + +function! lh#list#accumulate(input, transformation, accumulator) + let transformed = lh#list#transform(a:input, [], a:transformation) + let res = lh#function#execute(a:accumulator, transformed) + return res +endfunction + +" Function: lh#list#match(list, to_be_matched [, idx]) {{{3 +function! lh#list#match(list, to_be_matched, ...) + let idx = (a:0>0) ? a:1 : 0 + while idx < len(a:list) + if match(a:list[idx], a:to_be_matched) != -1 + return idx + endif + let idx += 1 + endwhile + return -1 +endfunction +function! lh#list#Match(list, to_be_matched, ...) + let idx = (a:0>0) ? a:1 : 0 + return lh#list#match(a:list, a:to_be_matched, idx) +endfunction + +" Function: lh#list#Find_if(list, predicate [, predicate-arguments] [, start-pos]) {{{3 +function! lh#list#Find_if(list, predicate, ...) + " Parameters + let idx = 0 + let args = [] + if a:0 == 2 + let idx = a:2 + let args = a:1 + elseif a:0 == 1 + if type(a:1) == type([]) + let args = a:1 + elseif type(a:1) == type(42) + let idx = a:1 + else + throw "lh#list#Find_if: unexpected argument type" + endif + elseif a:0 != 0 + throw "lh#list#Find_if: unexpected number of arguments: lh#list#Find_if(list, predicate [, predicate-arguments] [, start-pos])" + endif + + " The search loop + while idx != len(a:list) + let predicate = substitute(a:predicate, 'v:val', 'a:list['.idx.']', 'g') + let predicate = substitute(predicate, 'v:\(\d\+\)_', 'args[\1-1]', 'g') + let res = eval(predicate) + if res | return idx | endif + let idx += 1 + endwhile + return -1 +endfunction + +" Function: lh#list#find_if(list, predicate [, predicate-arguments] [, start-pos]) {{{3 +function! lh#list#find_if(list, predicate, ...) + " Parameters + let idx = 0 + let args = [] + if a:0 == 1 + let idx = a:1 + elseif a:0 != 0 + throw "lh#list#find_if: unexpected number of arguments: lh#list#find_if(list, predicate [, start-pos])" + endif + + " The search loop + while idx != len(a:list) + " let predicate = substitute(a:predicate, 'v:val', 'a:list['.idx.']', 'g') + let res = lh#function#execute(a:predicate, a:list[idx]) + if res | return idx | endif + let idx += 1 + endwhile + return -1 +endfunction + +" Function: lh#list#lower_bound(sorted_list, value [, first[, last]]) {{{3 +function! lh#list#lower_bound(list, val, ...) + let first = 0 + let last = len(a:list) + if a:0 >= 1 | let first = a:1 + elseif a:0 >= 2 | let last = a:2 + elseif a:0 > 2 + throw "lh#list#equal_range: unexpected number of arguments: lh#list#equal_range(sorted_list, value [, first[, last]])" + endif + + let len = last - first + + while len > 0 + let half = len / 2 + let middle = first + half + if a:list[middle] < a:val + let first = middle + 1 + let len -= half + 1 + else + let len = half + endif + endwhile + return first +endfunction + +" Function: lh#list#upper_bound(sorted_list, value [, first[, last]]) {{{3 +function! lh#list#upper_bound(list, val, ...) + let first = 0 + let last = len(a:list) + if a:0 >= 1 | let first = a:1 + elseif a:0 >= 2 | let last = a:2 + elseif a:0 > 2 + throw "lh#list#equal_range: unexpected number of arguments: lh#list#equal_range(sorted_list, value [, first[, last]])" + endif + + let len = last - first + + while len > 0 + let half = len / 2 + let middle = first + half + if a:val < a:list[middle] + let len = half + else + let first = middle + 1 + let len -= half + 1 + endif + endwhile + return first +endfunction + +" Function: lh#list#equal_range(sorted_list, value [, first[, last]]) {{{3 +" @return [f, l], where +" f : First position where {value} could be inserted +" l : Last position where {value} could be inserted +function! lh#list#equal_range(list, val, ...) + let first = 0 + let last = len(a:list) + + " Parameters + if a:0 >= 1 | let first = a:1 + elseif a:0 >= 2 | let last = a:2 + elseif a:0 > 2 + throw "lh#list#equal_range: unexpected number of arguments: lh#list#equal_range(sorted_list, value [, first[, last]])" + endif + + " The search loop ( == STLPort's equal_range) + + let len = last - first + while len > 0 + let half = len / 2 + let middle = first + half + if a:list[middle] < a:val + let first = middle + 1 + let len -= half + 1 + elseif a:val < a:list[middle] + let len = half + else + let left = lh#list#lower_bound(a:list, a:val, first, middle) + let right = lh#list#upper_bound(a:list, a:val, middle+1, first+len) + return [left, right] + endif + + " let predicate = substitute(a:predicate, 'v:val', 'a:list['.idx.']', 'g') + " let res = lh#function#execute(a:predicate, a:list[idx]) + endwhile + return [first, first] +endfunction + +" Function: lh#list#unique_sort(list [, func]) {{{3 +" See also http://vim.wikia.com/wiki/Unique_sorting +" +" Works like sort(), optionally taking in a comparator (just like the +" original), except that duplicate entries will be removed. +" todo: support another argument that act as an equality predicate +function! lh#list#unique_sort(list, ...) + let dictionary = {} + for i in a:list + let dictionary[string(i)] = i + endfor + let result = [] + " echo join(values(dictionary),"\n") + if ( exists( 'a:1' ) ) + let result = sort( values( dictionary ), a:1 ) + else + let result = sort( values( dictionary ) ) + endif + return result +endfunction + +function! lh#list#unique_sort2(list, ...) + let list = copy(a:list) + if ( exists( 'a:1' ) ) + call sort(list, a:1 ) + else + call sort(list) + endif + if len(list) <= 1 | return list | endif + let result = [ list[0] ] + let last = list[0] + let i = 1 + while i < len(list) + if last != list[i] + let last = list[i] + call add(result, last) + endif + let i += 1 + endwhile + return result +endfunction + +" Function: lh#list#subset(list, indices) {{{3 +function! lh#list#subset(list, indices) + let result=[] + for e in a:indices + call add(result, a:list[e]) + endfor + return result +endfunction + +" Function: lh#list#intersect(list1, list2) {{{3 +function! lh#list#intersect(list1, list2) + let result = copy(a:list1) + call filter(result, 'index(a:list2, v:val) >= 0') + return result + + for e in a:list1 + if index(a:list2, e) > 0 + call result(result, e) + endif + endfor +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/menu.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/menu.vim new file mode 100644 index 0000000..567e0c2 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/menu.vim @@ -0,0 +1,384 @@ +"============================================================================= +" $Id: menu.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/menu.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 13th Oct 2006 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (28th Aug 2007) +"------------------------------------------------------------------------ +" Description: +" Defines the global function lh#menu#def_menu +" Aimed at (ft)plugin writers. +" +"------------------------------------------------------------------------ +" Installation: +" Drop this file into {rtp}/autoload/lh/ +" Requires Vim 7+ +" History: +" v2.0.0: Moving to vim7 +" v2.0.1: :ToggleXxx echoes the new value +" v2.2.0: Support environment variables +" Only one :Toggle command is defined. +" TODO: +" Should the argument to :Toggle be simplified to use the variable +" name instead ? +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" ## Internal Variables {{{1 +let s:k_Toggle_cmd = 'Toggle' +if !exists('s:toggle_commands') + let s:toggle_commands = {} +endif + +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#menu#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#menu#debug(expr) + return eval(a:expr) +endfunction + +"------------------------------------------------------------------------ +" # Common stuff {{{2 +" Function: lh#menu#text({text}) {{{3 +" @return a text to be used in menus where "\" and spaces have been escaped. +function! lh#menu#text(text) + return escape(a:text, '\ ') +endfunction + +" # Toggling menu item {{{2 +" Function: s:Fetch({Data},{key}) {{{3 +" @param[in] Data Menu-item definition +" @param[in] key Table table from which the result will be fetched +" @return the current value, or text, whose index is Data.idx_crt_value. +function! s:Fetch(Data, key) + let len = len(a:Data[a:key]) + if a:Data.idx_crt_value >= len | let a:Data.idx_crt_value = 0 | endif + let value = a:Data[a:key][a:Data.idx_crt_value] + return value +endfunction + +" Function: s:Search({Data},{value}) {{{3 +" Searches for the index of {value} in {Data.values} list. Return 0 if not +" found. +function! s:Search(Data, value) + let idx = 0 + while idx != len(a:Data.values) + if a:value == a:Data.values[idx] + " echo a:Data.variable . "[".idx."] == " . a:value + return idx + endif + let idx = idx + 1 + endwhile + " echo a:Data.variable . "[".-1."] == " . a:value + return 0 " default is first element +endfunction + +" Function: s:Set({Data}) {{{3 +" @param[in,out] Data Menu item definition +" +" Sets the global variable associated to the menu item according to the item's +" current value. +function! s:Set(Data) + let value = a:Data.values[a:Data.idx_crt_value] + let variable = a:Data.variable + if variable[0] == '$' " environment variabmes + exe "let ".variable." = ".string(value) + else + let g:{variable} = value + endif + if has_key(a:Data, "actions") + let l:Action = a:Data.actions[a:Data.idx_crt_value] + if type(l:Action) == type(function('tr')) + call l:Action() + else + exe l:Action + endif + endif + return value +endfunction + +" Function: s:MenuKey({Data}) {{{3 +" @return the table name from which the current value name (to dsplay in the +" menu) must be fetched. +" Priority is given to the optional "texts" table over the madatory "values" table. +function! s:MenuKey(Data) + if has_key(a:Data, "texts") + let menu_id = "texts" + else + let menu_id = "values" + endif + return menu_id +endfunction + +" Function: s:NextValue({Data}) {{{3 +" Change the value of the variable to the next in the list of value. +" The menu, and the variable are updated in consequence. +function! s:NextValue(Data) + " Where the texts for values must be fetched + let labels_key = s:MenuKey(a:Data) + " Fetch the old current value + let old = s:Fetch(a:Data, labels_key) + + " Remove the entry from the menu + call s:ClearMenu(a:Data.menu, old) + + " Cycle/increment the current value + let a:Data.idx_crt_value += 1 + " Fetch it + let new = s:Fetch(a:Data,labels_key) + " Add the updated entry in the menu + call s:UpdateMenu(a:Data.menu, new, a:Data.command) + " Update the binded global variable + let value = s:Set(a:Data) + echo a:Data.variable.'='.value +endfunction + +" Function: s:ClearMenu({Menu}, {text}) {{{3 +" Removes a menu item +" +" @param[in] Menu.priority Priority of the new menu-item +" @param[in] Menu.name Name of the new menu-item +" @param[in] text Text of the previous value of the variable binded +function! s:ClearMenu(Menu, text) + if has('gui_running') + let name = substitute(a:Menu.name, '&', '', 'g') + let cmd = 'unmenu '.lh#menu#text(name.'('.a:text.')') + silent! exe cmd + endif +endfunction + +" Function: s:UpdateMenu({Menu}, {text}, {command}) {{{3 +" Adds a new menu item, with the text associated to the current value in +" braces. +" +" @param[in] Menu.priority Priority of the new menu-item +" @param[in] Menu.name Name of the new menu-item +" @param[in] text Text of the current value of the variable binded to +" the menu-item +" @param[in] command Toggle command to execute when the menu-item is selected +function! s:UpdateMenu(Menu, text, command) + if has('gui_running') + let cmd = 'nnoremenu '.a:Menu.priority.' '. + \ lh#menu#text(a:Menu.name.'('.a:text.')'). + \ ' :silent '.s:k_Toggle_cmd.' '.a:command."\" + silent! exe cmd + endif +endfunction + +" Function: s:SaveData({Data}) {{{3 +" @param Data Menu-item definition +" Saves {Data} as s:Data{s:data_id++}. The definition will be used by +" automatically generated commands. +" @return s:data_id +let s:data_id = 0 +function! s:SaveData(Data) + let s:Data{s:data_id} = a:Data + let id = s:data_id + let s:data_id += 1 + return id +endfunction + +" Function: lh#menu#def_toggle_item({Data}) {{{3 +" @param Data.idx_crt_value +" @param Data.definitions == [ {value:, menutext: } ] +" @param Data.menu == { name:, position: } +" +" Sets a toggle-able menu-item defined by {Data}. +" +function! lh#menu#def_toggle_item(Data) + " Save the menu data as an internal script variable + let id = s:SaveData(a:Data) + + " If the index of the current value hasn't been set, fetch it from the + " associated variable + if !has_key(a:Data, "idx_crt_value") + " Fetch the value of the associated variable + let value = lh#option#get(a:Data.variable, 0, 'g') + " echo a:Data.variable . " <- " . value + " Update the index of the current value + let a:Data.idx_crt_value = s:Search(a:Data, value) + endif + + " Name of the auto-matically generated toggle command + let cmdName = substitute(a:Data.menu.name, '[^a-zA-Z_]', '', 'g') + " Lazy definition of the command + if 2 != exists(':'.s:k_Toggle_cmd) + exe 'command! -nargs=1 -complete=custom,lh#menu#_toggle_complete ' + \ . s:k_Toggle_cmd . ' :call s:Toggle()' + endif + " silent exe 'command! -nargs=0 '.cmdName.' :call s:NextValue(s:Data'.id.')' + let s:toggle_commands[cmdName] = eval('s:Data'.id) + let a:Data["command"] = cmdName + + " Add the menu entry according to the current value + call s:UpdateMenu(a:Data.menu, s:Fetch(a:Data, s:MenuKey(a:Data)), cmdName) + " Update the associated global variable + call s:Set(a:Data) +endfunction + + +"------------------------------------------------------------------------ +function! s:Toggle(cmdName) + if !has_key(s:toggle_commands, a:cmdName) + throw "toggle-menu: unknown toggable variable ".a:cmdName + endif + let data = s:toggle_commands[a:cmdName] + call s:NextValue(data) +endfunction + +function! lh#menu#_toggle_complete(ArgLead, CmdLine, CursorPos) + return join(keys(s:toggle_commands),"\n") +endfunction + +"------------------------------------------------------------------------ +" # IVN Menus {{{2 +" Function: s:CTRL_O({cmd}) {{{3 +" Build the command (sequence of ':ex commands') to be executed from +" INSERT-mode. +function! s:CTRL_O(cmd) + return substitute(a:cmd, '\(^\|\):', '\1\:', 'g') +endfunction + +" Function: lh#menu#is_in_visual_mode() {{{3 +function! lh#menu#is_in_visual_mode() + return exists('s:is_in_visual_mode') && s:is_in_visual_mode +endfunction + +" Function: lh#menu#_CMD_and_clear_v({cmd}) {{{3 +" Internal function that executes the command and then clears the @v buffer +" todo: save and restore @v, +function! lh#menu#_CMD_and_clear_v(cmd) + try + let s:is_in_visual_mode = 1 + exe a:cmd + finally + let @v='' + silent! unlet s:is_in_visual_mode + endtry +endfunction + +" Function: s:Build_CMD({prefix},{cmd}) {{{3 +" build the exact command to execute regarding the mode it is dedicated +function! s:Build_CMD(prefix, cmd) + if a:cmd[0] != ':' | return ' ' . a:cmd + endif + if a:prefix[0] == "i" | return ' ' . CTRL_O(a:cmd) + elseif a:prefix[0] == "n" | return ' ' . a:cmd + elseif a:prefix[0] == "v" + if match(a:cmd, ":VCall") == 0 + return substitute(a:cmd, ':VCall', ' :call', ''). "\gV" + " gV exit select-mode if we where in it! + else + return + \ " \"vy\:call lh#menu#_CMD_and_clear_v('" . + \ substitute(a:cmd, "$", '', '') ."')\" + endif + elseif a:prefix[0] == "c" | return " \" . a:cmd + else | return ' ' . a:cmd + endif +endfunction + +" Function: lh#menu#map_all({map_type}, [{map args}...) {{{3 +" map the command to all the modes required +function! lh#menu#map_all(map_type,...) + let nore = (match(a:map_type, '[aincv]*noremap') != -1) ? "nore" : "" + let prefix = matchstr(substitute(a:map_type, nore, '', ''), '[aincv]*') + if a:1 == "" | let i = 3 | let binding = a:1 . ' ' . a:2 + else | let i = 2 | let binding = a:1 + endif + let binding = ' ' . binding + let cmd = a:{i} + let i += 1 + while i <= a:0 + let cmd .= ' ' . a:{i} + let i += 1 + endwhile + let build_cmd = nore . 'map ' . binding + while strlen(prefix) + if prefix[0] == "a" | let prefix = "incv" + else + execute prefix[0] . build_cmd . Build_CMD(prefix[0],cmd) + let prefix = strpart(prefix, 1) + endif + endwhile +endfunction + +" Function: lh#menu#make({prefix},{code},{text},{binding},...) {{{3 +" Build the menu and map its associated binding to all the modes required +function! lh#menu#make(prefix, code, text, binding, ...) + let nore = (match(a:prefix, '[aincv]*nore') != -1) ? "nore" : "" + let prefix = matchstr(substitute(a:prefix, nore, '', ''), '[aincv]*') + let b = (a:1 == "") ? 1 : 0 + let i = b + 1 + let cmd = a:{i} + let i += 1 + while i <= a:0 + let cmd .= ' ' . a:{i} + let i += 1 + endwhile + let build_cmd = nore . "menu " . a:code . ' ' . lh#menu#text(a:text) + if strlen(a:binding) != 0 + let build_cmd .= '' . + \ substitute(lh#menu#text(a:binding), '&', '\0\0', 'g') + if b != 0 + call lh#menu#map_all(prefix.nore."map", ' '.a:binding, cmd) + else + call lh#menu#map_all(prefix.nore."map", a:binding, cmd) + endif + endif + if has("gui_running") + while strlen(prefix) + execute BMenu(b).prefix[0].build_cmd.Build_CMD(prefix[0],cmd) + let prefix = strpart(prefix, 1) + endwhile + endif +endfunction + +" Function: s:BMenu({b}) {{{3 +" If is installed and the menu should be local, then the +" apropriate string is returned. +function! s:BMenu(b) + let res = (a:b && exists(':Bmenu') + \ && (1 == lh#option#get("want_buffermenu_or_global_disable", 1, "bg")) + \) ? 'B' : '' + " call confirm("BMenu(".a:b.")=".res, '&Ok', 1) + return res +endfunction + +" Function: lh#menu#IVN_make(...) {{{3 +function! lh#menu#IVN_make(code, text, binding, i_cmd, v_cmd, n_cmd, ...) + " nore options + let nore_i = (a:0 > 0) ? ((a:1 != 0) ? 'nore' : '') : '' + let nore_v = (a:0 > 1) ? ((a:2 != 0) ? 'nore' : '') : '' + let nore_n = (a:0 > 2) ? ((a:3 != 0) ? 'nore' : '') : '' + " + call lh#menu#make('i'.nore_i,a:code,a:text, a:binding, '', a:i_cmd) + call lh#menu#make('v'.nore_v,a:code,a:text, a:binding, '', a:v_cmd) + if strlen(a:n_cmd) != 0 + call lh#menu#make('n'.nore_n,a:code,a:text, a:binding, '', a:n_cmd) + endif +endfunction + +" +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/option.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/option.vim new file mode 100644 index 0000000..db09090 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/option.vim @@ -0,0 +1,107 @@ +"============================================================================= +" $Id: option.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/option.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 24th Jul 2004 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (07th Oct 2006) +"------------------------------------------------------------------------ +" Description: +" Defines the global function lh#option#get(). +" Aimed at (ft)plugin writers. +" +"------------------------------------------------------------------------ +" Installation: +" Drop this file into {rtp}/autoload/lh/ +" Requires Vim 7+ +" History: +" v2.0.5 +" (*) lh#option#get_non_empty() manages Lists and Dictionaries +" (*) lh#option#get() doesn't test emptyness anymore +" v2.0.0 +" Code moved from {rtp}/macros/ +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim + +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#option#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#option#debug(expr) + return eval(a:expr) +endfunction + +" # Public {{{2 +" Function: lh#option#get(name, default [, scope]) {{{3 +" @return b:{name} if it exists, or g:{name} if it exists, or {default} +" otherwise +" The order of the variables checked can be specified through the optional +" argument {scope} +function! lh#option#get(name,default,...) + let scope = (a:0 == 1) ? a:1 : 'bg' + let name = a:name + let i = 0 + while i != strlen(scope) + if exists(scope[i].':'.name) + " \ && (0 != strlen({scope[i]}:{name})) + return {scope[i]}:{name} + endif + let i += 1 + endwhile + return a:default +endfunction +function! lh#option#Get(name,default,...) + let scope = (a:0 == 1) ? a:1 : 'bg' + return lh#option#get(a:name, a:default, scope) +endfunction + +function! s:IsEmpty(variable) + if type(a:variable) == type('string') | return 0 == strlen(a:variable) + elseif type(a:variable) == type(42) | return 0 == a:variable + elseif type(a:variable) == type([]) | return 0 == len(a:variable) + elseif type(a:variable) == type({}) | return 0 == len(a:variable) + else | return false + endif +endfunction + +" Function: lh#option#get_non_empty(name, default [, scope]) {{{3 +" @return of b:{name}, g:{name}, or {default} the first which exists and is not empty +" The order of the variables checked can be specified through the optional +" argument {scope} +function! lh#option#get_non_empty(name,default,...) + let scope = (a:0 == 1) ? a:1 : 'bg' + let name = a:name + let i = 0 + while i != strlen(scope) + if exists(scope[i].':'.name) && !s:IsEmpty({scope[i]}:{name}) + return {scope[i]}:{name} + endif + let i += 1 + endwhile + return a:default +endfunction +function! lh#option#GetNonEmpty(name,default,...) + let scope = (a:0 == 1) ? a:1 : 'bg' + return lh#option#get_non_empty(a:name, a:default, scope) +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/path.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/path.vim new file mode 100644 index 0000000..bac452c --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/path.vim @@ -0,0 +1,308 @@ +"============================================================================= +" $Id: path.vim 237 2010-06-01 00:44:35Z luc.hermitte $ +" File: autoload/lh/path.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 23rd Jan 2007 +" Last Update: 11th Feb 2008 +"------------------------------------------------------------------------ +" Description: +" Functions related to the handling of pathnames +" +"------------------------------------------------------------------------ +" Installation: +" Drop this file into {rtp}/autoload/lh +" Requires Vim7+ +" History: +" v 1.0.0 First Version +" (*) Functions moved from searchInRuntimeTime +" v 2.0.1 +" (*) lh#path#Simplify() becomes like |simplify()| except for trailing +" v 2.0.2 +" (*) lh#path#SelectOne() +" (*) lh#path#ToRelative() +" v 2.0.3 +" (*) lh#path#GlobAsList() +" v 2.0.4 +" (*) lh#path#StripStart() +" v 2.0.5 +" (*) lh#path#StripStart() interprets '.' as getcwd() +" v 2.2.0 +" (*) new functions: lh#path#common(), lh#path#to_dirname(), +" lh#path#depth(), lh#path#relative_to(), lh#path#to_regex(), +" lh#path#find() +" (*) lh#path#simplify() fixed +" (*) lh#path#to_relative() use simplify() +" TODO: +" (*) Decide what #depth('../../bar') shall return +" (*) Fix #simplify('../../bar') +" }}}1 +"============================================================================= + + +"============================================================================= +" Avoid global reinclusion {{{1 +let s:cpo_save=&cpo +set cpo&vim + +"============================================================================= +" ## Functions {{{1 +" # Debug {{{2 +let s:verbose = 0 +function! lh#path#verbose(...) + if a:0 > 0 | let s:verbose = a:1 | endif + return s:verbose +endfunction + +function! s:Verbose(expr) + if s:verbose + echomsg a:expr + endif +endfunction + +function! lh#path#debug(expr) + return eval(a:expr) +endfunction + +"============================================================================= +" # Public {{{2 +" Function: lh#path#simplify({pathname}) {{{3 +" Like |simplify()|, but also strip the leading './' +" It seems unable to simplify '..\' when compiled without +shellslash +function! lh#path#simplify(pathname) + let pathname = simplify(a:pathname) + let pathname = substitute(pathname, '^\%(\.[/\\]\)\+', '', '') + let pathname = substitute(pathname, '\([/\\]\)\%(\.[/\\]\)\+', '\1', 'g') + let pwd = getcwd().'/' + let pathname = substitute(pathname, '^'.lh#path#to_regex(pwd), '', 'g') + return pathname +endfunction +function! lh#path#Simplify(pathname) + return lh#path#simplify(a:pathname) +endfunction + +" Function: lh#path#common({pathnames}) {{{3 +" Find the common leading path between all pathnames +function! lh#path#common(pathnames) + " assert(len(pathnames)) > 1 + let common = a:pathnames[0] + let i = 1 + while i < len(a:pathnames) + let fcrt = a:pathnames[i] + " pathnames should not contain @ + let common = matchstr(common.'@@'.fcrt, '^\zs\(.*[/\\]\)\ze.\{-}@@\1.*$') + if strlen(common) == 0 + " No need to further checks + break + endif + let i += 1 + endwhile + return common +endfunction + +" Function: lh#path#strip_common({pathnames}) {{{3 +" Find the common leading path between all pathnames, and strip it +function! lh#path#strip_common(pathnames) + " assert(len(pathnames)) > 1 + let common = lh#path#common(a:pathnames) + let l = strlen(common) + if l == 0 + return a:pathnames + else + let pathnames = a:pathnames + call map(pathnames, 'strpart(v:val, '.l.')' ) + return pathnames + endif +endfunction +function! lh#path#StripCommon(pathnames) + return lh#path#strip_common(a:pathnames) +endfunction + +" Function: lh#path#is_absolute_path({path}) {{{3 +function! lh#path#is_absolute_path(path) + return a:path =~ '^/' + \ . '\|^[a-zA-Z]:[/\\]' + \ . '\|^[/\\]\{2}' + " Unix absolute path + " or Windows absolute path + " or UNC path +endfunction +function! lh#path#IsAbsolutePath(path) + return lh#path#is_absolute_path(a:path) +endfunction + +" Function: lh#path#is_url({path}) {{{3 +function! lh#path#is_url(path) + " todo: support UNC paths and other urls + return a:path =~ '^\%(https\=\|s\=ftp\|dav\|fetch\|file\|rcp\|rsynch\|scp\)://' +endfunction +function! lh#path#IsURL(path) + return lh#path#is_url(a:path) +endfunction + +" Function: lh#path#select_one({pathnames},{prompt}) {{{3 +function! lh#path#select_one(pathnames, prompt) + if len(a:pathnames) > 1 + let simpl_pathnames = deepcopy(a:pathnames) + let simpl_pathnames = lh#path#strip_common(simpl_pathnames) + let simpl_pathnames = [ '&Cancel' ] + simpl_pathnames + " Consider guioptions+=c is case of difficulties with the gui + let selection = confirm(a:prompt, join(simpl_pathnames,"\n"), 1, 'Question') + let file = (selection == 1) ? '' : a:pathnames[selection-2] + return file + elseif len(a:pathnames) == 0 + return '' + else + return a:pathnames[0] + endif +endfunction +function! lh#path#SelectOne(pathnames, prompt) + return lh#path#select_one(a:pathnames, a:prompt) +endfunction + +" Function: lh#path#to_relative({pathname}) {{{3 +function! lh#path#to_relative(pathname) + let newpath = fnamemodify(a:pathname, ':p:.') + let newpath = simplify(newpath) + return newpath +endfunction +function! lh#path#ToRelative(pathname) + return lh#path#to_relative(a:pathname) +endfunction + +" Function: lh#path#to_dirname({dirname}) {{{3 +" todo: use &shellslash +function! lh#path#to_dirname(dirname) + let dirname = a:dirname . (a:dirname[-1:] =~ '[/\\]' ? '' : '/') + return dirname +endfunction + +" Function: lh#path#depth({dirname}) {{{3 +" todo: make a choice about "negative" paths like "../../foo" +function! lh#path#depth(dirname) + if empty(a:dirname) | return 0 | endif + let dirname = lh#path#to_dirname(a:dirname) + let dirname = lh#path#simplify(dirname) + if lh#path#is_absolute_path(dirname) + let dirname = matchstr(dirname, '.\{-}[/\\]\zs.*') + endif + let depth = len(substitute(dirname, '[^/\\]\+[/\\]', '§', 'g')) + return depth +endfunction + +" Function: lh#path#relative_to({from}, {to}) {{{3 +" @param two directories +" @return a directories delta that ends with a '/' (may depends on +" &shellslash) +function! lh#path#relative_to(from, to) + " let from = fnamemodify(a:from, ':p') + " let to = fnamemodify(a:to , ':p') + let from = lh#path#to_dirname(a:from) + let to = lh#path#to_dirname(a:to ) + let [from, to] = lh#path#strip_common([from, to]) + let nb_up = lh#path#depth(from) + return repeat('../', nb_up).to + + " cannot rely on :cd (as it alters things, and doesn't work with + " non-existant paths) + let pwd = getcwd() + exe 'cd '.a:to + let res = lh#path#to_relative(a:from) + exe 'cd '.pwd + return res +endfunction + +" Function: lh#path#glob_as_list({pathslist}, {expr}) {{{3 +function! s:GlobAsList(pathslist, expr) + let sResult = globpath(a:pathslist, a:expr) + let lResult = split(sResult, '\n') + " workaround a non feature of wildignore: it does not ignore directories + for ignored_pattern in split(&wildignore,',') + if stridx(ignored_pattern,'/') != -1 + call filter(lResult, 'v:val !~ '.string(ignored_pattern)) + endif + endfor + return lResult +endfunction + +function! lh#path#glob_as_list(pathslist, expr) + if type(a:expr) == type('string') + return s:GlobAsList(a:pathslist, a:expr) + elseif type(a:expr) == type([]) + let res = [] + for expr in a:expr + call extend(res, s:GlobAsList(a:pathslist, expr)) + endfor + return res + else + throw "Unexpected type for a:expression" + endif +endfunction +function! lh#path#GlobAsList(pathslist, expr) + return lh#path#glob_as_list(a:pathslist, a:expr) +endfunction + +" Function: lh#path#strip_start({pathname}, {pathslist}) {{{3 +" Strip occurrence of paths from {pathslist} in {pathname} +" @param[in] {pathname} name to simplify +" @param[in] {pathslist} list of pathname (can be a |string| of pathnames +" separated by ",", of a |List|). +function! lh#path#strip_start(pathname, pathslist) + if type(a:pathslist) == type('string') + " let strip_re = escape(a:pathslist, '\\.') + " let strip_re = '^' . substitute(strip_re, ',', '\\|^', 'g') + let pathslist = split(a:pathslist, ',') + elseif type(a:pathslist) == type([]) + let pathslist = deepcopy(a:pathslist) + else + throw "Unexpected type for a:pathname" + endif + + " apply a realpath like operation + let nb_paths = len(pathslist) " set before the loop + let i = 0 + while i != nb_paths + if pathslist[i] =~ '^\.\%(/\|$\)' + let path2 = getcwd().pathslist[i][1:] + call add(pathslist, path2) + endif + let i += 1 + endwhile + " replace path separators by a regex that can match them + call map(pathslist, 'substitute(v:val, "[\\\\/]", "[\\\\/]", "g")') + " echomsg string(pathslist) + " escape . + call map(pathslist, '"^".escape(v:val, ".")') + " build the strip regex + let strip_re = join(pathslist, '\|') + " echomsg strip_re + let res = substitute(a:pathname, '\%('.strip_re.'\)[/\\]\=', '', '') + return res +endfunction +function! lh#path#StripStart(pathname, pathslist) + return lh#path#strip_start(a:pathname, a:pathslist) +endfunction + +" Function: lh#path#to_regex({pathname}) {{{3 +function! lh#path#to_regex(path) + let regex = substitute(a:path, '[/\\]', '[/\\\\]', 'g') + return regex +endfunction + +" Function: lh#path#find({pathname}, {regex}) {{{3 +function! lh#path#find(paths, regex) + let paths = (type(a:paths) == type([])) + \ ? (a:paths) + \ : split(a:paths,',') + for path in paths + if match(path ,a:regex) != -1 + return path + endif + endfor + return '' +endfunction +"============================================================================= +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/position.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/position.vim new file mode 100644 index 0000000..805dcaf --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/position.vim @@ -0,0 +1,93 @@ +"============================================================================= +" $Id: position.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/position.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 05th Sep 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (05th Sep 2007) +"------------------------------------------------------------------------ +" Description: «description» +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: «history» +" v1.0.0: +" Creation +" TODO: +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#position#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#position#debug(expr) + return eval(a:expr) +endfunction + + +"------------------------------------------------------------------------ +" # Public {{{2 +" Function: lh#position#is_before {{{3 +" @param[in] positions as those returned from |getpos()| +" @return whether lhs_pos is before rhs_pos +function! lh#position#is_before(lhs_pos, rhs_pos) + if a:lhs_pos[0] != a:rhs_pos[0] + throw "Positions from incompatible buffers can't be ordered" + endif + "1 test lines + "2 test cols + let before + \ = (a:lhs_pos[1] == a:rhs_pos[1]) + \ ? (a:lhs_pos[2] < a:rhs_pos[2]) + \ : (a:lhs_pos[1] < a:rhs_pos[1]) + return before +endfunction +function! lh#position#IsBefore(lhs_pos, rhs_pos) + return lh#position#is_before(a:lhs_pos, a:rhs_pos) +endfunction + + +" Function: lh#position#char_at_mark {{{3 +" @return the character at a given mark (|mark|) +function! lh#position#char_at_mark(mark) + let c = getline(a:mark)[col(a:mark)-1] + return c +endfunction +function! lh#position#CharAtMark(mark) +return lh#position#char_at_mark(a:mark) +endfunction + +" Function: lh#position#char_at_pos {{{3 +" @return the character at a given position (|getpos()|) +function! lh#position#char_at_pos(pos) + let c = getline(a:pos[1])[col(a:pos[2])-1] + return c +endfunction +function! lh#position#CharAtPos(pos) + return lh#position#char_at_pos(a:pos) +endfunction + + + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/syntax.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/syntax.vim new file mode 100644 index 0000000..7b35731 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/syntax.vim @@ -0,0 +1,138 @@ +"============================================================================= +" $Id: syntax.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: autoload/lh/syntax.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 05th Sep 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (05th Sep 2007) +"------------------------------------------------------------------------ +" Description: «description» +" +"------------------------------------------------------------------------ +" Installation: +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: «history» +" v1.0.0: +" Creation ; +" Functions moved from lhVimSpell +" TODO: +" function, to inject "contained", see lhVimSpell approach +" }}}1 +"============================================================================= + + +"============================================================================= +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" ## Functions {{{1 +" # Debug {{{2 +function! lh#syntax#verbose(level) + let s:verbose = a:level +endfunction + +function! s:Verbose(expr) + if exists('s:verbose') && s:verbose + echomsg a:expr + endif +endfunction + +function! lh#syntax#debug(expr) + return eval(a:expr) +endfunction + +" # Public {{{2 +" Functions: Show name of the syntax kind of a character {{{3 +function! lh#syntax#name_at(l,c, ...) + let what = a:0 > 0 ? a:1 : 0 + return synIDattr(synID(a:l, a:c, what),'name') +endfunction +function! lh#syntax#NameAt(l,c, ...) + let what = a:0 > 0 ? a:1 : 0 + return lh#syntax#name_at(a:l, a:c, what) +endfunction + +function! lh#syntax#name_at_mark(mark, ...) + let what = a:0 > 0 ? a:1 : 0 + return lh#syntax#name_at(line(a:mark), col(a:mark), what) +endfunction +function! lh#syntax#NameAtMark(mark, ...) + let what = a:0 > 0 ? a:1 : 0 + return lh#syntax#name_at_mark(a:mark, what) +endfunction + +" Functions: skip string, comment, character, doxygen {{{3 +func! lh#syntax#skip_at(l,c) + return lh#syntax#name_at(a:l,a:c) =~? 'string\|comment\|character\|doxygen' +endfun +func! lh#syntax#SkipAt(l,c) + return lh#syntax#skip_at(a:l,a:c) +endfun + +func! lh#syntax#skip() + return lh#syntax#skip_at(line('.'), col('.')) +endfun +func! lh#syntax#Skip() + return lh#syntax#skip() +endfun + +func! lh#syntax#skip_at_mark(mark) + return lh#syntax#skip_at(line(a:mark), col(a:mark)) +endfun +func! lh#syntax#SkipAtMark(mark) + return lh#syntax#skip_at_mark(a:mark) +endfun + +" Function: Show current syntax kind {{{3 +command! SynShow echo 'hi<'.lh#syntax#name_at_mark('.',1).'> trans<' + \ lh#syntax#name_at_mark('.',0).'> lo<'. + \ synIDattr(synIDtrans(synID(line('.'), col('.'), 1)), 'name').'>' + + +" Function: lh#syntax#list_raw(name) : string {{{3 +function! lh#syntax#list_raw(name) + let a_save = @a + try + redir @a + exe 'silent! syn list '.a:name + redir END + let res = @a + finally + let @a = a_save + endtry + return res +endfunction + +" Function: lh#syntax#list(name) : List {{{3 +function! lh#syntax#list(name) + let raw = lh#syntax#list_raw(a:name) + let res = [] + let lines = split(raw, '\n') + let started = 0 + for l in lines + if started + let li = (l =~ 'links to') ? '' : l + elseif l =~ 'xxx' + let li = matchstr(l, 'xxx\s*\zs.*') + let started = 1 + else + let li = '' + endif + if strlen(li) != 0 + let li = substitute(li, 'contained\S*\|transparent\|nextgroup\|skipwhite\|skipnl\|skipempty', '', 'g') + let kinds = split(li, '\s\+') + call extend(res, kinds) + endif + endfor + return res +endfunction + + + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/visual.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/visual.vim new file mode 100644 index 0000000..8d6bc98 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/autoload/lh/visual.vim @@ -0,0 +1,42 @@ +"============================================================================= +" $Id$ +" File: autoload/lh/visual.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 08th Sep 2008 +" Last Update: $Date$ +"------------------------------------------------------------------------ +" Helpers functions releated to the visual mode +" +"------------------------------------------------------------------------ +" Drop it into {rtp}/autoload/lh/ +" Vim 7+ required. +" History: +" v2.0.6: First appearance +" TODO: «missing features» +" }}}1 +"============================================================================= + +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" Functions {{{1 + +" Function: lh#visual#selection() {{{3 +" @return the text currently selected +function! lh#visual#selection() + try + let a_save = @a + normal! gv"ay + return @a + finally + let @a = a_save + endtry +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/doc/lh-vim-lib.txt b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/doc/lh-vim-lib.txt new file mode 100644 index 0000000..0090e97 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/doc/lh-vim-lib.txt @@ -0,0 +1,1252 @@ +*lh-vim-lib.txt* Vim common libraries (v2.2.1) + For Vim version 7+ Last change: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ + + By Luc Hermitte + hermitte {at} free {dot} fr + + +============================================================================== +CONTENTS *lhvl-contents* {{{1 +|lhvl-presentation| Presentation +|lhvl-functions| Functions + +|add-local-help| Instructions on installing this help file + + +------------------------------------------------------------------------------ +PRESENTATION *lhvl-presentation* {{{1 + +|lh-vim-lib| is a library that defines some common VimL functions I use in my +various plugins and ftplugins. +This library has been conceived as a suite of |autoload| plugins, and a few +|macros| plugins. As such, it requires Vim 7+. + + +============================================================================== +FUNCTIONS *lhvl-functions* {{{1 +{{{2Functions list~ +Miscellanous functions: |lhvl#misc| +- |lh#askvim#exe()| +- |lh#common#check_deps()| +- |lh#common#error_msg()| +- |lh#common#warning_msg()| +- |lh#common#echomsg_multilines()| +- |lh#encoding#iconv()| +- |lh#event#register_for_one_execution_at()| +- |lh#option#get()| +- |lh#option#get_non_empty()| +- |lh#position#char_at_mark()| +- |lh#position#char_at_pos()| +- |lh#position#is_before()| +- |lh#visual#selection()| +Functors related functions: |lhvl#function| +- |lh#function#bind()| +- |lh#function#execute()| +- |lh#function#prepare()| +Lists related functions: |lhvl#list| +- |lh#list#accumulate()| +- |lh#list#copy_if()| +- |lh#list#Find_if()| and |lh#list#find_if()| +- |lh#list#intersect()| +- |lh#list#match()| +- |lh#list#subset()| +- |lh#list#Transform()| and |lh#list#transform()| +- |lh#list#transform_if()| +- |lh#list#unique_sort()| and |lh#list#unique_sort2()| +o |lh#list#equal_range()|, + |lh#list#lower_bound()| and |lh#list#upper_bound()| +Graphs related functions: |lhvl#graph| +- |lh#graph#tsort#depth()| +- |lh#graph#tsort#breadth()| +Paths related functions: |lhvl#path| +- |lh#path#common()| +- |lh#path#depth()| +- |lh#path#glob_as_list()| +- |lh#path#is_absolute_path()| +- |lh#path#is_url()| +- |lh#path#select_one()| +- |lh#path#simplify()| +- |lh#path#strip_common()| +- |lh#path#strip_start()| +- |lh#path#to_dirname()| +- |lh#path#to_relative()| +- |lh#path#relative_to()| +- |lh#path#to_regex()| +Commands related functions: |lhvl#command| +- |lh#command#new()| (alpha version) +- |lh#command#Fargs2String()| (alpha version) +- |lh#command#complete()| (alpha version) +Menus related functions: |lhvl#menu| +- |lh#menu#def_toggle_item()| +- |lh#menu#text()| +- |lh#menu#make()| +- |lh#menu#IVN_make()| +- |lh#menu#is_in_visual_mode()| +- |lh#menu#map_all()| +- |lh#askvim#menu()| (beta version) +Buffers related functions: |lhvl#buffer| +- |lh#buffer#list()| +- |lh#buffer#find()| +- |lh#buffer#jump()| +- |lh#buffer#scratch()| +- |lh#buffer#dialog#| functions for building interactive dialogs + - |lh#buffer#dialog#new()| + - |lh#buffer#dialog#add_help()| + - |lh#buffer#dialog#select()| + - |lh#buffer#dialog#quit()| + - |lh#buffer#dialog#update()| +Syntax related functions: |lhvl#syntax| +- |lh#syntax#name_at()| +- |lh#syntax#name_at_mark()| +- |lh#syntax#skip()| +- |lh#syntax#skip_at()| +- |lh#syntax#skip_at_mark()| +- |lh#syntax#list_raw()| +- |lh#syntax#list()| + +}}}2 +------------------------------------------------------------------------------ +MISCELLANOUS FUNCTIONS *lhvl#misc* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#common#echomsgMultilines()* {{{3 +lh#common#echomsgMultilines()({text}) (*deprecated*)~ + *lh#common#echomsg_multilines()* +lh#common#echomsg_multilines()({text})~ +@param {text} Message to display on several lines +@return Nothing + +This function executes |:echomsg| as many times as required as there are lines +in the original {text}. +This is a workaround |:echomsg| that is unable to handle correctly multi-lines +messages. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#common#ErrorMsg()* {{{3 +lh#common#ErrorMsg({text}) (*deprecated*)~ + *lh#common#error_msg()* +lh#common#error_msg({text})~ +@param {text} Error message to display +@return Nothing + +This function displays an error message in a |confirm()| box if gvim is being +used, or as a standard vim error message through |:echoerr| otherwise. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#common#WarningMsg()* {{{3 +lh#common#WarningMsg({text}) (*deprecated*)~ + *lh#common#warning_msg()* +lh#common#warning_msg({text})~ +@param {text} Error message to display +@return Nothing + +This function displays a warning message highlighted with |WarningMsg| syntax. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#common#CheckDeps()* {{{3 +lh#common#CheckDeps({symbol},{file},{path},{requester}) (*deprecated*)~ + *lh#common#check_deps()* +lh#common#check_deps({symbol},{file},{path},{requester})~ +@param {symbol} Symbol required, see |exists()| for symbol format. +@param {file} File in which the symbol is expected to be defined +@param {path} Path where the file can be found +@param {requester} Name of the script in need of this symbol +@return 0/1 whether the {symbol} exists + +Checks if {symbol} exists in vim. If not, this function first tries +to |:source| the {file} in which the {symbol} is expected to be defined. If the +{symbol} is still not defined, an error message is issued (with +|lh#common#error_msg()|, and 0 is returned. + +Example: > + if + \ !lh#common#check_deps('*Cpp_CurrentScope', + \ 'cpp_FindContextClass.vim', 'ftplugin/cpp/', + \ 'cpp#GotoFunctionImpl.vim') + \ || !lh#common#check_deps(':CheckOptions', + \ 'cpp_options-commands.vim', 'ftplugin/cpp/', + \ 'cpp#GotoFunctionImpl.vim') + let &cpo=s:cpo_save + finish + endif + +Note: Since the introduction of |autoload| plugins in Vim 7, this function has +lost most of its interrest. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#option#Get()* {{{3 +lh#option#Get({name},{default}[,{scopes}]) (*deprecated*)~ + *lh#option#get()* +lh#option#get({name},{default}[,{scopes}])~ +@param {name} Name of the option to fetch +@param {default} Default value in case the option is not defined +@param {scopes} Vim scopes in which the options must be searched, + default="bg". +@return b:{name} if it exists, or g:{name} if it exists, or + {default} otherwise. +@see For development oriented options, |lh-dev| provides a + dedicated function: |lh#dev#option#get()|. + +This function fetches the value of an user defined option (not Vim |options|). +The option can be either a |global-variable|, a |buffer-variable|, or even +a|window-variable|. + +The order of the variables checked can be specified through the optional +argument {scopes}. By default, buffer-local options have the priority over +global options. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#option#GetNonEmpty()* {{{3 +lh#option#GetNonEmpty({name},{default}[,{scopes}]) (*deprecated*)~ + *lh#option#get_non_empty()* +lh#option#get_non_empty({name},{default}[,{scopes}])~ +@param {name} Name of the option to fetch +@param {default} Default value in case the option is not defined, nor empty +@param {scopes} Vim scopes in which the options must be searched, + default="bg". +@return b:{name} If it exists, of g:{name} if it exists, or {default} + otherwise. + +This function works exactly like |lh#option#get()| except that a defined +variable with an empty value will be ignored as well. +An |expr-string| will be considered empty if its |strlen()| is 0, an +|expr-number| when it values 0, |Lists| and |Dictionaries| when their |len()| +is 0. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#askvim#Exe()* {{{3 +lh#askvim#Exe({command}) (*deprecated*)~ + *lh#askvim#exe()* +lh#askvim#exe({command})~ +@param {command} Command to execute from vim. +@return What the command echoes while executed. +@note This function encapsultates |redir| without altering any + register. + +Some information aren't directly accessible (yet) through vim API +(|functions|). However, they can be obtained by executing some commands, and +redirecting the result of these commands. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#askvim#menu()* {{{3 +lh#askvim#menu({menuid},{modes})~ +@param {menuid} Menu identifier. +@param {modes} List of modes +@return Information related to the {menuid} +@todo Still bugged + +This function provides a way to obtain information related to a menu entry in +Vim. + +The format of the result being «to be stabilized» + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#position#IsBefore()* {{{3 +lh#position#IsBefore({lhs_pos},{rhs_pos}) (*deprecated*)~ + *lh#position#is_before()* +lh#position#is_before({lhs_pos},{rhs_pos})~ +@param[in] Positions as those returned from |getpos()| +@return Whether {lhs_pos} is before {rhs_pos} + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#position#CharAtMark()* {{{3 +lh#position#CharAtMark({mark}) (*deprecated*)~ + *lh#position#char_at_mark()* +lh#position#char_at_mark({mark})~ +@return The character at a given |mark|. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#position#CharAtPos()* {{{3 +lh#position#CharAtPos({pos}) (*deprecated*)~ + *lh#position#char_at_pos()* {{{3 +lh#position#char_at_pos({pos})~ +@return The character at a position (see |getpos()|). + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#visual#selection()* {{{3 +lh#visual#selection()~ +@return The current visual selection +@post |registers| are not altered by this function + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#event#RegisterForOneExecutionAt()* {{{3 +lh#event#RegisterForOneExecutionAt({event}, {cmd}, {group}) (*deprecated*)~ + *lh#event#register_for_one_execution_at()* +lh#event#register_for_one_execution_at({event}, {cmd}, {group})~ +Registers a command to be executed once (and only once) when {event} is +triggered on the current file. + +@param {event} Event that will trigger the execution of {cmd}|autocmd-events| +@param {cmd} |expression-command| to execute +@param {group} |autocmd-groups| under which the internal autocommand will be + registered. +@todo possibility to specify the file pattern + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#encoding#iconv()* {{{3 +lh#encoding#iconv({expr}, {from}, {to})~ +This function just calls |iconv()| with the same arguments. The only +difference is that it return {expr} when we know that |iconv()| will return an +empty string. + + +------------------------------------------------------------------------------ +FUNCTORS RELATED FUNCTIONS *lhvl#function* {{{2 + +This sub-library helps defining functors-like variables, and execute them. + +NB: C++ developpers may be already familiar with boost.bind +(/std(::tr1)::bind) function that inspired by feature. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lhvl#functor* {{{3 +A functor is implemented as a |Dictionary| that has the following fields: +- {execute} is the |Funcref| that will be actually executed by + |lh#function#execute()|. Its only argument is a |List| of + arguments for {function}. +- {function} that identifies the function to execute, + internals: it could be either a |Funcref|or a |expr-string|, or + whatever is compatible with the {execute} |FuncRef| field. +- {args} will contain the binded arguments as defined by + |lh#function#bind()|. If you attach a {execute} function of your + own to a functor, you don't need to fill "args". + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#function#bind()* {{{3 +lh#function#bind({fn} [, {arguments} ...])~ +This function creates a new |lhvl#functor| based on a given function {fn}, and +where some arguments are binded to the ones from {arguments}. +The result is a new function-like data having for parameter v:1_, v:2_, ... +that were specified in |lh#function#bind()| {arguments} list. + +Examples:~ + See tests/lh/function.vim + +Let's suppose Print(...) a VimL variadic function that echoes the arguments it +receives, i.e. > + call Print(1,2,"text", ['foo', 'bar']) +will echo: > + 1 ## 2 ## 'text' ## ['foo', 'bar'] + +* Binding a |FuncRef|:~ + and reverse the arguments given to it when it will be executed > + >:let func = lh#function#bind(function('Print'), 'v:3_', 'v:2_', 'v:1_') + >:echo lh#function#execute(func, 1, 'two', [3]) + [3] ## 'two' ## 1 + +* Binding a named function:~ + the new function has 3 parameters and calls the named function with its 3rd + parameter, 42, its second and its first parameters as arguments. > + >:let func = lh#function#bind('Print', 'v:3_', 42, 'v:2_', 'v:1_') + >:echo lh#function#execute(func, 1, 'two', [3]) + [3] ## 42 ## 'two' ## 1 +< NB: if exists('*'.func_name) is false, then the string is considered to be + an expression that will be evaluated as specified in the next use case. + +* Binding an expression:~ + This time more complex on-the-fly computations on the |lhvl#functor| + parameters can be accomplished > + >:let func = lh#function#bind('Print(len(v:3_), 42, v:2_, v:1_)') + >:echo lh#function#execute(func, 1, 'two', [1,2,3]) + 3 ## 42 ## 'two' ## 1 +< NB: func["args"] is defined, but empty, and unused. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#function#execute()* {{{3 +lh#function#execute({functor} [, {arguments} ...])~ +While |lh#function#bind()| defines a |lhvl#functor| that can be stored and +used later, |lh#function#execute()| directly executes the {functor} received. + +Different kind of {functors} are accepted: +- |FuncRef|, and function names, where arguments are |lh#function#execute()| + ones ; +- |expr-string|, where "v:{pos}_" strings are binded on-the-fly to {arguments} ; +- |lhvl#functor|, that will be given {arguments} as arguments. + +Examples:~ + See tests/lh/function.vim + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#function#prepare()* {{{3 +lh#function#prepare({function}, {arguments} ...)~ +This function expands all the elements from the {arguments} |List|, and +prepares a |expr-string| that once evaluated will call the n-ary {function} +with the n-{arguments}. +The evaluation is meant to be done with |eval()|. +> + >:let call = lh#function#prepare('Print', [1,2,"foo"]) + >:echo eval(call) + 1 ## 2 ## 'foo' + + +------------------------------------------------------------------------------ +LISTS RELATED FUNCTIONS *lhvl#list* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#Match()* {{{3 +lh#list#Match({list},{pattern}[, {start-pos}]) (*deprecated*)~ + *lh#list#match()* +lh#list#match({list},{pattern}[, {start-pos}])~ +@param {list} |List| +@param {pattern} |expr-string| +@param {start-pos} First index to check +@return The lowest index, >= {start-pos}, in |List| {list} where + the item matches {pattern}. +@return -1 if no item matches {pattern}. +@see |index()|, |match()| + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#find_if()* *lh#list#Find_if()* {{{3 +lh#list#Find_if({list},{string-predicate} [, {pred-parameters}][, {start-pos}])~ +lh#list#find_if({list},{functor-predicate} [, {pred-parameters}][, {start-pos}])~ +@param {list} |List| +@param {*-predicate} Predicate to evaluate +@param {pred-parameters}] |List| of Parameters to bind to special arguments in + the {predicate}. +@param {start-pos} First index to check +@return The lowest index, >= {start-pos}, in |List| {list} + where the {predicate} evals to true. +@return -1 if no item matches {pattern}. +@see |index()|, |eval()| + +The {string-predicate} recognizes some special arguments: +- |v:val| is substituted with the current element being evaluated in the list +- *v:1_* *v:2_* , ..., are substituted with the i-th elements from + {pred-parameters}. + NB: the "v:\d\+_" are 1-indexed while {pred-parameters} is indeed seen as + 0-indexed by Vim. + This particular feature permits to pass any type of variable to the + predicate: a |expr-string|, a |List|, a |Dictionary|, ... + +e.g.: > + :let b = { 'min': 12, 'max': 42 } + :let l = [ 1, 5, 48, 25, 5, 28, 6] + :let i = lh#list#Find_if(l, 'v:val>v:1_.min && v:val + :let l = [ 1, 5, 48, 25, 5, 28, 6] + :let i = lh#list#find_if(l, 'v:1_>12 && v:1_<42 && v:1_%2==0') + :echo l[i] + 28 +NB: Expect the Find_if() version to be replaced with the find_if() one. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#unique_sort()* *lh#list#unique_sort2()* {{{3 +lh#list#unique_sort({list} [, {cmp}])~ +lh#list#unique_sort2({list} [, {cmp}])~ +@param[in] {list} |List| to sort +@param {cmp} |Funcref| or function name that acts as a compare predicate. + It seems to be required in order to not compare number with + a lexicographic order (with vim 7.1-156) +@return A new |List| sorted with no element repeated +@todo support an optional {equal} predicate to use in the /unique/ making +process. + +The difference between the two functions is the following: +- unique_sort() stores all the elements in a |Dictionary|, then sort the values + stored in the dictionary ; +- unique_sort2() sorts all the elements from the initial |List|, and then + keeps only the elements that appear once. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#Transform()* {{{3 +lh#list#Transform({input},{output},{action})~ +@param[in] {input} Input |List| to transform +@param[out] {output} Output |List| where the transformed elements will be + appended. +@param {action} Stringified action to apply on each element from {input}. + The string "v:val" will always be replaced with the + element currently transformed. +@return {output} + +This function is actually returning > + extend(a:output, map(copy(a:input), a:action)) + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#transform()* {{{3 +lh#list#transform({input},{output},{action})~ +@param[in] {input} Input |List| to transform +@param[out] {output} Output |List| where the transformed elements will be + appended. +@param {action}|lhvl#functor| action to apply on each element from + {input}. +@return {output} + +This function is equivalent to (|lh#list#Transform()|) > + extend(a:output, map(copy(a:input), a:action)) +except the action is not a string but a |lhvl#functor|. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#transform_if()* {{{3 +lh#list#transform_if({input},{output},{action},{predicate})~ +@param[in] {input} Input |List| to transform +@param[out] {output} Output |List| where the transformed elements will be + appended. +@param {action}|lhvl#functor| action to apply on each element from + {input} that verifies the {predicate}. +@param {predicate} Boolean |lhvl#functor| tested on each element before + transforming it. +@return {output} + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#copy_if()* {{{3 +lh#list#copy_if({input},{output},{predicate})~ +Appends in {output} the elements from {input} that verifies the {predicate}. + +@param[in] {input} Input |List| to transform +@param[out] {output} Output |List| where the elements that verify the + {predicate} will be appended. +@param {predicate} Boolean |lhvl#functor| tested on each element. +@return {output} + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#accumulate()* {{{3 +lh#list#accumulate({input},{transformation},{accumulator})~ +Accumulates the transformed elements from {input}. + +@param[in] {input} Input |List| to transform +@param {transformation}|lhvl#functor| applied on each element from {input}. +@param {accumulator}|lhvl#functor| taking the list of tranformaed elements + as input +@return the result of {accumulator} + +Examples: > + :let strings = [ 'foo', 'bar', 'toto' ] + :echo eval(lh#list#accumulate(strings, 'strlen', 'join(v:1_, "+")')) + 10 + + :let l = [ 1, 2, 'foo', ['bar']] + :echo lh#list#accumulate(l, 'string', 'join(v:1_, "##")') + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#subset()* {{{3 +lh#list#subset({input},{indices})~ +Returns a subset slice of the {input} list. + +@param[in] {input} Input |List| from which element will be extracted +@param[in] {indices}|List| of indices to extract +@return a |List| of the elements from {input} indexed by the {indices} + +Example: > + :let l = [ 1, 25, 5, 48, 25, 5, 28, 6] + :let indices = [ 0, 5, 7, 3 ] + :echo lh#list#subset(l, indices) + [ 1, 5, 6, 48 ] + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#list#intersect()* {{{3 +lh#list#intersect({list1},{list2})~ +Returns the elements present in both input lists. + +@param[in] {list1}|List| +@param[in] {list2}|List| +@return a |List| of the elements in both {list1} and {list2}, the elements are +kepts in the same order as in {list1} +@note the algorithm is in O(len({list1})*len({list2})) + +Example: > + :let l1 = [ 1, 25, 7, 48, 26, 5, 28, 6] + :let l2 = [ 3, 8, 7, 25, 6 ] + :echo lh#list#intersect(l1, l2) + [ 25, 7, 6 ] + +------------------------------------------------------------------------------ +GRAPHS RELATED FUNCTIONS *lhvl#graph* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#graph#tsort#depth()* {{{3 + *lh#graph#tsort#breadth()* {{{3 +lh#graph#tsort#depth({dag}, {start-nodes})~ +lh#graph#tsort#breadth({dag}, {start-nodes})~ +These two functions implement a topological sort on the Direct Acyclic Graph. +- depth() is a recursive implementation of a depth-first search. +- breadth() is a non recursive implementation of a breadth-first search. + +@param {dag} is a direct acyclic graph defined either: + - as a |Dictionnary| that associates to each node, the |List| of + all its successors + - or as a /fetch/ |function()| that returns the |List| of the + successors of a given node -- works only with depth() which + takes care of not calling this function more than once for each + given node. +@param {start-nodes} is a |List| of start nodes with no incoming edge +@throw "Tsort: cyclic graph detected:" if {dag} is not a DAG. +@see http://en.wikipedia.org/wiki/Topological_sort +@since Version 2.1.0 +@test tests/lh/topological-sort.vim + + +------------------------------------------------------------------------------ +PATHS RELATED FUNCTIONS *lhvl#path* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#depth()* {{{3 +lh#path#depth({dirname})~ +Returns the depth of a directory name. + +@param {dirname} Pathname to simplify +@return the depth of the simplified directory name, i.e. + lh#path#depth("bar/b2/../../foo/") returns 1 + +@todo However, it is not able to return depth of negative paths like + "../../foo/". I still need to decide whether the function should return + -1 or 3. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#dirname()* {{{3 +lh#path#dirname({dirname})~ +Ensures the returned directory name ends with a '/' or a '\'. + +@todo On windows, it should take 'shellslash' into account to decide the + character to append. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#Simplify()* {{{3 +lh#path#Simplify({pathname}) (*deprecated*)~ + *lh#path#simplify()* +lh#path#simplify({pathname})~ +Simplifies a path by getting rid of useless '../' and './'. + +@param {pathname} Pathname to simplify +@return the simplified pathname + +This function works like |simplify()|, except that it also strips the leading +"./". + +Note: when vim is compiled for unix, it seems unable to |simplify()| paths +containing "..\". (It likelly works this way when vim is compiled without +'shellslash' support) + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#common()* {{{3 +lh#path#common({pathnames})~ +@param[in] {pathnames} |List| of pathnames to analyse +@return the common leading path between all {pathnames} + +e.g.: > + :echo lh#path#common(['foo/bar/file','foo/file', 'foo/foo/file']) +echoes > + foo/ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#StripCommon()* {{{3 +lh#path#StripCommon({pathnames}) (*deprecated*)~ + *lh#path#strip_common()* +lh#path#strip_common({pathnames})~ +@param[in,out] {pathnames} |List| of pathnames to simplify +@return the simplified pathnames + +This function strips all pathnames from their common leading part. The +compuation of the common leading part is ensured by |lh#path#common()| +thank. +e.g.: > + :echo lh#path#strip_common(['foo/bar/file','foo/file', 'foo/foo/file']) +echoes > + ['bar/file','file', 'foo/file'] + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#StripStart()* {{{3 +lh#path#StripStart({pathname}, {pathslist}) (*deprecated*)~ + *lh#path#strip_start()* +lh#path#strip_start({pathname}, {pathslist})~ +@param[in] {pathname} name to simplify +@param[in] {pathslist} list of pathname (can be a |string| of pathnames + separated by ",", of a |List|). + +Strips {pathname} from any path from {pathslist}. + +e.g.: > + :echo lh#path#strip_start($HOME.'/.vim/template/bar.template', + \ ['/home/foo/.vim', '/usr/local/share/vim/']) + :echo lh#path#strip_start($HOME.'/.vim/template/bar.template',&rtp) +echoes > + template/bar.template + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#IsAbsolutePath()* {{{3 +lh#path#IsAbsolutePath({path}) (*deprecated*)~ + *lh#path#is_absolute_path()* +lh#path#is_absolute_path({path})~ +@return {path} Path to test +@return whether the path is an absolute path +@note Supports Unix absolute paths, Windows absolute paths, and UNC paths + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#IsURL()* {{{3 +lh#path#IsURL({path}) (*deprecated*)~ + *lh#path#is_url()* +lh#path#is_url({path})~ +@return {path} Path to test +@return whether the path is an URL +@note Supports http(s)://, (s)ftp://, dav://, fetch://, file://, rcp://, +rsynch://, scp:// + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#SelectOne()* {{{3 +lh#path#SelectOne({pathnames},{prompt}) (*deprecated*)~ + *lh#path#select_one()* +lh#path#select_one({pathnames},{prompt})~ +@param[in] {pathnames} |List| of pathname +@param {prompt} Prompt for the dialog box + +@return "" if len({pathnames}) == 0 +@return {pathnames}[0] if len({pathnames}) == 1 +@return the selected pathname otherwise + +Asks the end-user to choose a pathname among a list of pathnames. +The pathnames displayed will be simplified thanks to |lh#path#strip_common()| +-- the pathname returned is the "full" original pathname matching the +simplified pathname selected. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#ToRelative()* {{{3 +lh#path#ToRelative({pathname}) (*deprecated*)~ + *lh#path#to_relative()* +lh#path#to_relative({pathname})~ +@param {pathname} Pathname to convert +@return the simplified {pathname} in its relative form as it would be seen + from the current directory. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#relative_to()* {{{3 +lh#path#relative_to({from}, {to})~ +Returns the relative directory that indentifies {to} from {from} location. +@param {from} origin directory +@param {to} destination directory +@return the simplified pathname {to} in its relative form as it would be seen + from the {from} directory. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#GlobAsList()* {{{3 +lh#path#GlobAsList({pathslist}, {expr}) (*deprecated*)~ + *lh#path#glob_as_list()* +lh#path#glob_as_list({pathslist}, {expr})~ +@return |globpath()|'s result, but formatted as a list of matching pathnames. +In case {expr} is a |List|, |globpath()| is applied on each expression in +{expr}. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#find()* {{{3 +lh#path#find({pathslist}, {regex})~ +@param[in] {pathslist} List of paths which can be received as a |List| or as a + string made of coma separated paths. +@return the path that matches the given {regex} + +e.g.: > + let expected_win = $HOME . '/vimfiles' + let expected_nix = $HOME . '/.vim' + let what = lh#path#to_regex($HOME.'/').'\(vimfiles\|.vim\)' + let z = lh#path#find(&rtp,what) + if has('win16')||has('win32')||has('win64') + Assert z == expected_win + else + Assert z == expected_nix + endif + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#path#to_regex()* {{{3 +lh#path#to_regex({pathname})~ +Transforms the {pathname} to separate each node-name by the string '[/\\]' + +The rationale behind this function is to build system independant regex +pattern to use on pathnames as sometimes pathnames are built by appending +'/stuff/like/this' without taking 'shellslash' into account. + +e.g.: > + echo lh#path#to_regex('/home/luc/').'\(vimfiles\|.vim\)' +echoes > + [/\\]home[/\\]luc[/\\]\(vimfiles\|.vim\) + + +------------------------------------------------------------------------------ +MENUS RELATED FUNCTIONS *lhvl#menu* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#def_toggle_item()* {{{3 +lh#menu#def_toggle_item({Data})~ +@param[in,out] {Data} Definition of a |menu| item. + +This function defines a |menu| entry that will be associated to a +|global-variable| whose values can be cycled and explored from the menu. This +global variable can be seen as an enumerate whose value can be cyclically +updated through a menu. + +{Data} is a |Dictionary| whose keys are: +- "variable": name of the |global-variable| to bind to the menu entry + Mandatory. +- "values": associated values of string or integers (|List|) + Mandatory. +- "menu": describes where the menu entry must be placed (|Dictionary|) + - "priority": complete priority of the entry (see |sub-menu-priority|) + - "name": complete name of the entry -- ampersand (&) can be used to define + shortcut keys + Mandatory. +- "idx_crt_value": index of the current value for the option (|expr-number|) + This is also an internal variable that will be automatically updated to + keep the index of the current value of the "variable" in "values". + Optional ; default value is 1, or the associated index of the initial value + of the variable (in "values") before the function call. +- "texts": texts to display according to the variable value (|List|) + Optional, "values" will be used by default. This option is to be used to + distinguish the short encoded value, from the long self explanatory name. + +Warning: + If the variable is changed by hand without using the menu, then the menu + and the variable will be out of synch. Unless the command |lhvl-:Toggle| + is used to change the value of the options (and keep the menu + synchronized). + +Examples: + See tests/lh/test-toggle-menu.vim + + *lhvl-:Toggle* +:Toggle {variable-name}~ +@param {variable-name} must be a |global-variable| name used as "variable" in +the definition of a toggable menu item thanks to |lh#menu#def_toggle_item()|. + +This command supports autocompletion on the {variable-name}. + +Todo: + Propose a *lhvl-:Set{vaName}* command. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#text()* {{{3 +lh#menu#text({text})~ +@param[in] {text} Text to send to |:menu| commands +@return a text to be used in menus where "\" and spaces have been escaped. + +This helper function transforms a regular text into a text that can be +directly used with |:menu| commands. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#make()* {{{3 +option: *[gb]:want_buffermenu_or_global_disable* +If Michael Geddes's |buffer-menu| plugin is installed, this option tells +whether we want to take advantage of it to define menus or to ignore it. + +lh#menu#make({modes}, {menu-priority}, {menu-text}, {key-binding}, [,] {action})~ +Creates a menu entry and its associated mappings for several modes at once. + +@param[in] {modes} Vim modes the menus and maps will be provided for +@param[in] {menu-priority} |sub-menu-priority| for the new menu entry +@param[in] {menu-text} Name of the new menu entry +@param[in] {key-binding} Sequence of keys to execute the associated action +@param[in] "" If the string "" is provided, then the + associated mapping will be a |map-|, and + the menu will be available to the current buffer + only. See |[gb]:want_buffermenu_or_global_disable| + When "" is set, the call to lh#menu#make() + must be done in the buffer-zone from a |ftplugin|, + or from a |local_vimrc|. +@param[in] {action} Action to execute when {key-binding} is typed, or + when the menu entry is selected. +@todo support select ('s') and visual-not-select ('x') modes + +First example:~ +The following call will add the menu "LaTeX.Run LaTeX once ", with +the priority (placement) 50.305, for the NORMAL, INSERT and COMMAND modes. The +action associated first saves all the changed buffers and then invokes LaTeX. +The same action is also binded to for the same modes, with the +nuance that the maps will be local to the buffer. +> + call lh#menu#make("nic", '50.305', '&LaTeX.Run LaTeX &once', "", + \ '', ":wa:call TKMakeDVIfile(1)") + +Second example:~ +This example demonstrates an hidden, but useful, behavior: if the mode is the +visual one, then the register v is filled with the text of the visual area. +This text can then be used in the function called. Here, it will be proposed +as a default name for the section to insert: +> + function! TKinsertSec() + " ... + if (strlen(@v) != 0) && (visualmode() == 'v') + let SecName = input("name of ".SecType.": ", @v) + else + let SecName = input("name of ".SecType.": ") + endif + " ... + endfunction + + call lh#menu#make("vnic", '50.360.100', '&LaTeX.&Insert.&Section', + \ "", '', ":call TKinsertSec()") + +We have to be cautious to one little thing, there is a side effect: the visual +mode vanishes when we enter the function. If you don't want this to happen, +use the non-existant command: |:VCall|. + +Third example:~ +If it is known that a function will be called only under |VISUAL-mode|, and +that we don't want of the previous behavior, we can explicitly invoke the +function with |:VCall| -- command that doesn't actually exist. Check +lh-tex/ftplugin/tex/tex-set.vim |s:MapMenu4Env| for such an example. + +Fourth thing: actually, lh#menu#make() is not restricted to commands. The +action can be anything that could come at the right hand side of any |:map| or +|:menu| action. But this time, you have to be cautious with the modes you +dedicate your map to. I won't give any related example ; this is the +underlying approach in |lh#menu#IVN_make()|. + + + *lh#menu#make()_modes* +Implementation details:~ +The actual creation of the mappings is delegated to |lh#menu#map_all()|. +If the {action} to execute doesn't start with ':', it is left untransformed, +otherwise it is adapted depending on each {mode}: +- INSERT-mode: each recognized |:command| call is prepended with |i_CTRL-O| +- NORMAL-mode: the {action} is used as it is +- VISUAL-mode: ":Vcall" is replaced by "\gV", otherwise the selection is + recorded into @v register, the {action} command is executed after a + |v_CTRL-C|, and eventually @v is cleared. + The use is @v is deprecated, rely instead on |lh#menu#is_in_visual_mode()| + and on |lh#selection#visual()|. +- COMMAND-mode: the {action} is prepended with |c_CTRL-C|. + +Examples: + See tests/lh/test-menu-map.vim + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#IVN_make()* {{{3 +Mappings & menus inserting text~ +lh#menu#IVN_make(, {text}, {key}, {IM-action}, {VM-action}, {NM-action} [, {nore-IM}, {nore-VM}, {nore-NM}])~ + +lh#menu#IVN_MenuMake() accepts three different actions for the three modes: +INSERT, VISUAL and NORMAL. The mappings defined will be relative to the +current buffer -- this function is addressed to ftplugins writers. The last +arguments specify whether the inner mappings and abbreviations embedded within +the actions should be expanded or not ; i.e. are we defining +«noremaps/noremenus» ? + +You will find very simple examples of what could be done at the end of +menu-map.vim. Instead, I'll show here an extract of my TeX ftplugin: it +defines complex functions that will help to define very simply the different +mappings I use. You could find another variation on this theme in +ftplugin/html/html_set.vim. + +> + :MapMenu 50.370.300 &LaTeX.&Fonts.&Emphasize ]em emph + call MapMenu4Env("50.370.200", '&LaTeX.&Environments.&itemize', + \ ']ei', 'itemize', '\item ') + + +The first command binds ]em to \emph{} for the three different modes. In +INSERT mode, the cursor is positioned between the curly brackets, and a marker +is added after the closing bracket -- cf. my bracketing system. In VISUAL +mode, the curly brackets are added around the visual area. In NORMAL mode, the +area is considered to be the current word. + +The second call binds for the three modes: ]ei to: +> + \begin{itemize} + \item + \end{itemize} + +The definition of the different functions and commands involved just follows. +> + command -nargs=1 -buffer MapMenu :call MapMenu() + + function! s:MapMenu(code,text,binding, tex_cmd, ...) + let _2visual = (a:0 > 0) ? a:1 : "viw" + " If the tex_cmd starts with an alphabetic character, then suppose the + " command must begin with a '\'. + let texc = ((a:tex_cmd[0] =~ '\a') ? '\' : "") . a:tex_cmd + call lh#menu#IVN_make(a:code, a:text.' -- ' . texc .'{}', a:binding, + \ texc.'{', + \ '`>a}`%l', + \ ( (_2visual=='0') ? "" : _2visual.a:binding), + \ 0, 1, 0) + endfunction + + " a function and its map to close a "}", and that works whatever the + " activation states of the brackets and marking features are. + function! s:Close() + if strlen(maparg('{')) == 0 | exe "normal a} \" + elseif exists("b:usemarks") && (b:usemarks==1) | exe "normal ¡jump! " + else | exe "normal a " + endif + endfunction + + imap ¡close! :call Close() + + function! s:MapMenu4Env(code,text,binding, tex_env, middle, ...) + let _2visual = (a:0 > 0) ? a:1 : "vip" + let b = "'" . '\begin{' . a:tex_env . '}' . "'" + let e = "'" . '\end{' . a:tex_env . '}' . "'" + call IVN_MenuMake(a:code, a:text, a:binding, + \ '\begin{'.a:tex_env.'¡close!'.a:middle.' \end{'.a:tex_env.'}ks', + \ ':VCall MapAroundVisualLines('.b. ',' .e.',1,1)', + \ _2visual.a:binding, + \ 0, 1, 0) + endfunction + +Examples: + See tests/lh/test-menu-map.vim + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#is_in_visual_mode()* {{{3 +lh#menu#is_in_visual_mode()~ +@return a boolean that tells whether the {action} used in +|lh#menu#is_in_visual_mode()| has been invoked from the VISUAL-mode. + +NB: this function deprecates the test on @v. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#menu#map_all()* {{{3 +lh#menu#map_all({map-type}[, {map-args...}])~ +This function is a helper function that defines several mappings at once as +|:amenu| would do. + +@param {map-type} String of the form "[aincv]*(nore)?map" that tells the + mode on which mappings should be defined, and whether + the mappings shall be |:noremap|. +@param {map-args...} Rest of the parameters that defines the mapping + + +The action to execute will be corrected depending on the current mode. See +|lh#menu#make()_modes| for more details. + + +------------------------------------------------------------------------------ +COMMANDS RELATED FUNCTIONS *lhvl#command* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#command#new()* {{{3 +Highly Experimental. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#command#Fargs2String()* {{{3 +lh#command#Fargs2String({aList})~ +@param[in,out] aList list of params from +@see tests/lh/test-Fargs2String.vim + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#command#complete()* {{{3 +lh#command#complete({argLead}, {cmdLine}, {cursorPos})~ +Under developpement + + +------------------------------------------------------------------------------ +BUFFERS RELATED FUNCTIONS *lhvl#buffer* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#buffer#list()* {{{3 +lh#buffer#list()~ +@return The |List| of |buflisted| buffers. + +e.g.: > + echo lh#list#transform(lh#buffer#list(), [], "bufname") + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#buffer#Find()* {{{3 +lh#buffer#Find({filename}) (*deprecated*)~ + *lh#buffer#find()* +lh#buffer#find({filename})~ +Searchs for a window where the buffer is opened. + +@param {filename} +@return The number of the first window found, in which {filename} is opened. + +If {filename} is opened in a window, jump to this window. Otherwise, return +-1. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#buffer#Jump()* {{{3 +lh#buffer#Jump({filename}, {cmd}) (*deprecated*)~ + *lh#buffer#jump()* +lh#buffer#jump({filename}, {cmd})~ +Jumps to the window where the buffer is opened, or open the buffer in a new +windows if none match. + +@param {filename} +@param {cmd} +@return Nothing. + +If {filename} is opened in a window, jump to this window. +Otherwise, execute {cmd} with {filename} as a parameter. Typical values for +the command will be "sp" or "vsp". (see |:split|, |:vsplit|). + +N.B.: While it is not the rationale behind this function, other commands that +does not open the buffer may be used in the {cmd} parameter. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#buffer#Scratch()* {{{3 +lh#buffer#Scratch({bname},{where}) (*deprecated*)~ + *scratch* *lh#buffer#scratch()* +lh#buffer#scratch({bname},{where})~ +Split-opens a new scratch buffer. + +@param {bname} Name for the new scratch buffer +@param {where} Where the new scratch buffer will be opened ('', or 'v') +@post The buffer has the following properties set: + 'bt'=nofile, 'bh'=wipe, 'nobl', 'noswf', 'ro' + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lhvl-dialog* *lh#buffer#dialog#* {{{3 +Functions for building interactive dialogs~ +Unlike other |lh-vim-lib| functions which can be used independently from each +others, all the lh#buffer#dialog#*() functions constitute a coherent framework +to define interactive dialogs. + +For the moment it only supports the selection of one or several items in a +list. + +From a end-user point of view, a list of items is displayed in a (|scratch|) +buffer. If enabled, the user can select (/tag) one or several items, and then +validate its choice. He can always abort and quit the dialog. A few other +features are also supported: a help message can be shown, the list may be +colored, etc. + + +The items displayed can be of any kind (function signatures, email addresses, +suggested spellings, ...), as well as the validating action. The +help-header can be customized, as well as colours, other mappings, ... + +However the list displaying + selection aspect is almost hardcoded. + + +How it works~ +------------ +Scripts have to call the function *lh#buffer#dialog#new()* + lh#buffer#dialog#new(bname, title, where, support-tagging, action, choices)~ +with: +- {bname} being the name the |scratch| buffer will receive. +- {title} the title that appears at the first line of the scratch buffer. + I usually use it to display the name of the "client" script, its version, + and its purpose/what to do. +- {where} are |:split| options (like "bot below") used to open the scratch + buffer. +- {support-tagging} is a boolean (0/1) option to enable the multi-selection. +- {action} is the name of the callback function (more + advanced calling mechanisms latter may be supported later with + |lhvl-functions|). +- {choices} is the |List| of exact strings to display. + +The #new function builds and returns a |Dictionary|, it also opens and fills +the scratch buffer, and put us within its context -- i.e. any |:map-| +or other buffer-related definitions will done in the new scratch buffer. + +Thus, if we want to add other mappings, and set a syntax highlighting for the +new buffer, it is done at this point (see the *s:PostInit()* function in my +"client" scripts like |lh-tags|). +At this point, I also add all the high level information to the +dictionary (for instance, the list of function signatures is nice, but +it does not provides enough information (the corresponding file, the +command to jump to the definition/declaration, the scope, ...) + +The dictionary returned is filled with the following information: +- buffer ids, +- where was the cursor at the time of the creation of the new scratch buffer, +- name of the callback function. + + +Regarding the callback function: *lhvl-dialog-select-callback* +- It ca not be a |script-local| function, only global and autoload functions + are supported. +- When called, we are still within the scratch buffer context. +- It must accept a |List| of numbers as its first parameter: the index (+1) of + the items selected. +- The number 0, when in the list, means "aborted". In that case, the + callback function is expected to call |lh#buffer#dialog#quit()| that will + terminate the scratch buffer (with |:quit|), and jump back to where we were + when #new was called, and display a little "Abort" message. +- We can terminate the dialog with just :quit if we don't need to jump + back anywhere. For instance, lh-tags callback function first + terminates the dialog, then jumps to the file where the selected tag + comes from. + +- It's completely asynchronous: the callback function does not return anything + to anyone, but instead applies transformations in other places. + This aspect is very important. I don't see how this kind of feature can work + if not asynchronously in vim. + +How to customize it: +- *lh#buffer#dialog#quit()* can be explicitly called, from a registered select + callback (|lhvl-dialog-select-callback|), in order to terminate the dialog. +- *lh#buffer#dialog#add_help()* can be used to complete the help/usage message + in both its short and long form. +- *lh#buffer#dialog#update()* can be called after the list of items has been + altered in order to refresh what is displayed. The rationale behind this + feature is to support sorting, filtering, items expansion, etc. See + |lh-tags| implementation for an example. +- *lh#buffer#dialog#select()* can be used in new mappings in order to handle + differently the selected items. + |lh-tags| uses this function to map 'o' to the split-opening of the selected + items. + NB: the way this feature is supported may change in future releases. + +Limitations: +This script is a little bit experimental (even if it the result of almost 10 +years of evolution), and it is a little bit cumbersome. +- it is defined to support only one callback -- see the hacks in |lh-tags| to + workaround this limitation. +- it is defined to display list of items, and to select one or several items + in the end. +- and of course, it requires many other functions from |lh-vim-lib|, but + nothing else. + +------------------------------------------------------------------------------ +SYNTAX RELATED FUNCTIONS *lhvl#syntax* {{{2 + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#syntax#NameAt()* {{{3 +lh#syntax#NameAt({lnum},{col}[,{trans}]) (*deprecated*)~ + *lh#syntax#name_at()* +lh#syntax#name_at({lnum},{col}[,{trans}])~ +@param {lnum} line of the character +@param {col} column of the character +@param {trans} see |synID()|, default=0 +@return the syntax kind of the given character at {lnum}, {col} + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#syntax#NameAtMark()* {{{3 +lh#syntax#NameAtMark({mark}[,{trans}]) (*deprecated*)~ + *lh#syntax#name_at_mark()* {{{3 +lh#syntax#name_at_mark({mark}[,{trans}])~ +@param {mark} position of the character +@param {trans} see |synID()|, default=0 +@return the syntax kind of the character at the given |mark|. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#syntax#Skip()* *lh#syntax#SkipAt()* *lh#syntax#SkipAtMark()* {{{3 +lh#syntax#Skip() (*deprecated*)~ +lh#syntax#SkipAt({lnum},{col}) (*deprecated*)~ +lh#syntax#SkipAtMark({mark}) (*deprecated*)~ + *lh#syntax#skip()* *lh#syntax#skip_at()* *lh#syntax#skip_at_mark()* +lh#syntax#skip()~ +lh#syntax#skip_at({lnum},{col})~ +lh#syntax#skip_at_mark({mark})~ + +Functions to be used with |searchpair()| functions in order to search for a +pair of elements, without taking comments, strings, characters and doxygen +(syntax) contexts into account while searching. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#syntax#list_raw()* {{{3 +lh#syntax#list_raw({name})~ +@param {group-name} +@return the result of "syn list {group-name}" as a string + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + *lh#syntax#list()* {{{3 +lh#syntax#list()~ +@param {group-name} +@return the result of "syn list {group-name}" as a list. + +This function tries to interpret the result of the raw list of syntax +elements. + + +------------------------------------------------------------------------------ + }}}1 +============================================================================== + © Luc Hermitte, 2001-2010, {{{1 + $Id: lh-vim-lib.txt 246 2010-09-19 22:40:58Z luc.hermitte $ + VIM: let b:VS_language = 'american' + vim:ts=8:sw=4:tw=80:fo=tcq2:ft=help: + vim600:fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/lh-vim-lib.README b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/lh-vim-lib.README new file mode 100644 index 0000000..8f2e162 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/lh-vim-lib.README @@ -0,0 +1,17 @@ + ------------------ + lh-vim-lib 2.2.1 + ------------------ + +lh-vim-lib is a library plugin for vim v7+. It is just a collection of +functions that are meant to be used by script writers. + +Audience : Vim script writers +Requirements : Vim 7.1 +Required by : Just a few other plugins for the moment +Author : Luc Hermitte +License : GPL2 +More Help At : http://code.google.com/p/lh-vim/wiki/lhVimLib +Vim script#214: http://www.vim.org/scripts/script.php?script_id=214 +Repository : + svn checkout http://lh-vim.googlecode.com/svn/vim-lib/trunk lh-vim-lib + diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/macros/menu-map.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/macros/menu-map.vim new file mode 100644 index 0000000..6bae67b --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/macros/menu-map.vim @@ -0,0 +1,83 @@ +"=========================================================================== +" $Id: menu-map.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: macros/menu-map.vim +" Author: Luc Hermitte +" +" +" Purpose: Define functions to build mappings and menus at the same time +" +" Version: 2.2.1 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ (02nd Dec 2006) +" +" Last Changes: {{{ +" Version 2.0.0: +" Moved to vim7, +" Functions moved to {rtp}/autoload/ +" Version 1.6.2: +" (*) Silent mappings and menus +" Version 1.6. : +" (*) Uses has('gui_running') instead of has('gui') to check if +" we can generate the menu. +" Version 1.5. : +" (*) visual mappings launched from select-mode don't end with +" text still selected -- applied to :VCalls +" Version 1.4. : +" (*) address obfuscated for spammers +" (*) support the local option +" b:want_buffermenu_or_global_disable if we don't want +" buffermenu to be used systematically. +" 0 -> buffer menu not used +" 1 -> buffer menu used +" 2 -> the VimL developper will use a global disable. +" cf.: tex-maps.vim:: s:SimpleMenu() +" and texmenus.vim +" Version 1.3. : +" (*) add continuation lines support ; cf 'cpoptions' +" Version 1.2. : +" (*) Code folded. +" (*) Take advantage of buffermenu.vim if present for local +" menus. +" (*) If non gui is available, the menus won't be defined +" Version 1.1. : +" (*) Bug corrected : +" vnore(map\|menu) does not imply v+n(map\|menu) any more +" }}} +" +" Inspired By: A function from Benji Fisher +" +" TODO: (*) no menu if no gui. +" +"=========================================================================== + +if exists("g:loaded_menu_map") | finish | endif +let g:loaded_menu_map = 1 + +"" line continuation used here ?? +let s:cpo_save = &cpo +set cpo&vim + +"========================================================================= +" Commands {{{ +command! -nargs=+ -bang MAP map +command! -nargs=+ IMAP imap +command! -nargs=+ NMAP nmap +command! -nargs=+ CMAP cmap +command! -nargs=+ VMAP vmap +command! -nargs=+ AMAP + \ call lh#menu#map_all('amap', ) + +command! -nargs=+ -bang NOREMAP noremap +command! -nargs=+ INOREMAP inoremap +command! -nargs=+ NNOREMAP nnoremap +command! -nargs=+ CNOREMAP cnoremap +command! -nargs=+ VNOREMAP vnoremap +command! -nargs=+ ANOREMAP + \ call lh#menu#map_all('anoremap', ) +" }}} + +" End ! +let &cpo = s:cpo_save +finish + +"========================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/mkVba/mk-lh-vim-lib.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/mkVba/mk-lh-vim-lib.vim new file mode 100644 index 0000000..8e693a2 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/mkVba/mk-lh-vim-lib.vim @@ -0,0 +1,53 @@ +"============================================================================= +" $Id: mk-lh-vim-lib.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: mk-lh-lib.vim +" Author: Luc Hermitte +" +" Version: 2.2.1 +let s:version = '2.2.1' +" Created: 06th Nov 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +cd :p:h +try + let save_rtp = &rtp + let &rtp = expand(':p:h:h').','.&rtp + exe '22,$MkVimball! lh-vim-lib-'.s:version + set modifiable + set buftype= +finally + let &rtp = save_rtp +endtry +finish +autoload/lh/askvim.vim +autoload/lh/buffer.vim +autoload/lh/buffer/dialog.vim +autoload/lh/command.vim +autoload/lh/common.vim +autoload/lh/encoding.vim +autoload/lh/env.vim +autoload/lh/event.vim +autoload/lh/graph/tsort.vim +autoload/lh/list.vim +autoload/lh/menu.vim +autoload/lh/option.vim +autoload/lh/path.vim +autoload/lh/position.vim +autoload/lh/syntax.vim +autoload/lh/visual.vim +doc/lh-vim-lib.txt +macros/menu-map.vim +mkVba/mk-lh-vim-lib.vim +plugin/let.vim +plugin/lhvl.vim +plugin/ui-functions.vim +plugin/words_tools.vim +tests/lh/function.vim +tests/lh/list.vim +tests/lh/path.vim +tests/lh/test-Fargs2String.vim +tests/lh/test-askmenu.vim +tests/lh/test-command.vim +tests/lh/test-menu-map.vim +tests/lh/test-toggle-menu.vim +tests/lh/topological-sort.vim diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/let.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/let.vim new file mode 100644 index 0000000..ad98f43 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/let.vim @@ -0,0 +1,54 @@ +"============================================================================= +" $Id: let.vim 239 2010-06-01 00:48:43Z luc.hermitte $ +" File: plugin/let.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 31st May 2010 +" Last Update: $Date: 2010-05-31 20:48:43 -0400 (Mon, 31 May 2010) $ +"------------------------------------------------------------------------ +" Description: +" Defines a command :LetIfUndef that sets a variable if undefined +" +"------------------------------------------------------------------------ +" Installation: +" Drop this file into {rtp}/plugin +" Requires Vim7+ +" History: +" v2.2.1: first version of this command into lh-vim-lib +" TODO: +" }}}1 +"============================================================================= + +" Avoid global reinclusion {{{1 +let s:k_version = 221 +if &cp || (exists("g:loaded_let") + \ && (g:loaded_let >= s:k_version) + \ && !exists('g:force_reload_let')) + finish +endif +let g:loaded_let = s:k_version +let s:cpo_save=&cpo +set cpo&vim +" Avoid global reinclusion }}}1 +"------------------------------------------------------------------------ +" Commands and Mappings {{{1 +command! -nargs=+ LetIfUndef call s:LetIfUndef() +" Commands and Mappings }}}1 +"------------------------------------------------------------------------ +" Functions {{{1 +" Note: most functions are best placed into +" autoload/«your-initials»/«let».vim +" Keep here only the functions are are required when the plugin is loaded, +" like functions that help building a vim-menu for this plugin. +function! s:LetIfUndef(var, value) + if !exists(a:var) + let {a:var} = eval(a:value) + endif +endfunction + +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/lhvl.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/lhvl.vim new file mode 100644 index 0000000..367e25d --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/lhvl.vim @@ -0,0 +1,45 @@ +"============================================================================= +" $Id: lhvl.vim 245 2010-09-19 22:40:10Z luc.hermitte $ +" File: plugin/lhvl.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 27th Apr 2010 +" Last Update: $Date: 2010-09-19 18:40:10 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Non-function resources from lh-vim-lib +" +"------------------------------------------------------------------------ +" Installation: +" Drop the file into {rtp}/plugin +" History: +" v2.2.1 first version +" TODO: «missing features» +" }}}1 +"============================================================================= + +" Avoid global reinclusion {{{1 +let s:k_version = 221 +if &cp || (exists("g:loaded_lhvl") + \ && (g:loaded_lhvl >= s:k_version) + \ && !exists('g:force_reload_lhvl')) + finish +endif +let g:loaded_lhvl = s:k_version +let s:cpo_save=&cpo +set cpo&vim +" Avoid global reinclusion }}}1 +"------------------------------------------------------------------------ +" Commands and Mappings {{{1 +" Moved from lh-cpp +command! PopSearch :call histdel('search', -1)| let @/=histget('search',-1) + +" Commands and Mappings }}}1 +"------------------------------------------------------------------------ +" Functions {{{1 +" Functions }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/ui-functions.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/ui-functions.vim new file mode 100644 index 0000000..8f7c3d9 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/ui-functions.vim @@ -0,0 +1,480 @@ +"============================================================================= +" File: plugin/ui-functions.vim {{{1 +" Author: Luc Hermitte +" +" URL: http://hermitte.free.fr/vim/ressources/vimfiles/plugin/ui-functions.vim +" +" Version: 2.2.1 +" Created: 18th nov 2002 +" Last Update: 28th Nov 2007 +"------------------------------------------------------------------------ +" Description: Functions for the interaction with a User Interface. +" The UI can be graphical or textual. +" At first, this was designed to ease the syntax of +" mu-template's templates. +" +" Option: {{{2 +" {[bg]:ui_type} +" = "g\%[ui]", +" = "t\%[ext]" ; the call must not be |:silent| +" = "f\%[te]" +" }}}2 +"------------------------------------------------------------------------ +" Installation: Drop this into one of your {rtp}/plugin/ directories. +" History: {{{2 +" v0.01 Initial Version +" v0.02 +" (*) Code "factorisations" +" (*) Help on enhanced. +" (*) Small changes regarding the parameter accepted +" (*) Function SWITCH +" v0.03 +" (*) Small bug fix with INPUT() +" v0.04 +" (*) New function: WHICH() +" v0.05 +" (*) In vim7e, inputdialog() returns a trailing '\n'. INPUT() strips the +" NL character. +" v0.06 +" (*) :s/echoerr/throw/ => vim7 only +" v2.2.0 +" (*) menu to switch the ui_type +" +" TODO: {{{2 +" (*) Save the hl-User1..9 before using them +" (*) Possibility other than &statusline: +" echohl User1 |echon "bla"|echohl User2|echon "bli"|echohl None +" (*) Wraps too long choices-line (length > term-width) +" (*) Add to the documentation: "don't use CTRL-C to abort !!" +" (*) Look if I need to support 'wildmode' +" (*) 3rd mode: return string for FTE +" (*) 4th mode: interaction in a scratch buffer +" +" }}}1 +"============================================================================= +" Avoid reinclusion {{{1 +" +if exists("g:loaded_ui_functions") && !exists('g:force_reload_ui_functions') + finish +endif +let g:loaded_ui_functions = 1 +let s:cpo_save=&cpo +set cpo&vim +" }}}1 +"------------------------------------------------------------------------ +" External functions {{{1 +" Function: IF(var, then, else) {{{2 +function! IF(var,then, else) + let o = s:Opt_type() " {{{3 + if o =~ 'g\%[ui]\|t\%[ext]' " {{{4 + return a:var ? a:then : a:else + elseif o =~ 'f\%[te]' " {{{4 + return s:if_fte(a:var, a:then, a:else) + else " {{{4 + throw "UI-Fns::IF(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" Function: SWITCH(var, case, action [, case, action] [default_action]) {{{2 +function! SWITCH(var, ...) + let o = s:Opt_type() " {{{3 + if o =~ 'g\%[ui]\|t\%[ext]' " {{{4 + let explicit_def = ((a:0 % 2) == 1) + let default = explicit_def ? a:{a:0} : '' + let i = a:0 - 1 - explicit_def + while i > 0 + if a:var == a:{i} + return a:{i+1} + endif + let i = i - 2 + endwhile + return default + elseif o =~ 'f\%[te]' " {{{4 + return s:if_fte(a:var, a:then, a:else) + else " {{{4 + throw "UI-Fns::SWITCH(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" Function: CONFIRM(text [, choices [, default [, type]]]) {{{2 +function! CONFIRM(text, ...) + " 1- Check parameters {{{3 + if a:0 > 4 " {{{4 + throw "UI-Fns::CONFIRM(): too many parameters" + return 0 + endif + " build the parameters string {{{4 + let i = 1 + while i <= a:0 + if i == 1 | let params = 'a:{1}' + else | let params = params. ',a:{'.i.'}' + endif + let i = i + 1 + endwhile + " 2- Choose the correct way to execute according to the option {{{3 + let o = s:Opt_type() + if o =~ 'g\%[ui]' " {{{4 + exe 'return confirm(a:text,'.params.')' + elseif o =~ 't\%[ext]' " {{{4 + if !has('gui_running') && has('dialog_con') + exe 'return confirm(a:text,'.params.')' + else + exe 'return s:confirm_text("none", a:text,'.params.')' + endif + elseif o =~ 'f\%[te]' " {{{4 + exe 'return s:confirm_fte(a:text,'.params.')' + else " {{{4 + throw "UI-Fns::CONFIRM(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" Function: INPUT(prompt [, default ]) {{{2 +function! INPUT(prompt, ...) + " 1- Check parameters {{{3 + if a:0 > 4 " {{{4 + throw "UI-Fns::INPUT(): too many parameters" + return 0 + endif + " build the parameters string {{{4 + let i = 1 | let params = '' + while i <= a:0 + if i == 1 | let params = 'a:{1}' + else | let params = params. ',a:{'.i.'}' + endif + let i = i + 1 + endwhile + " 2- Choose the correct way to execute according to the option {{{3 + let o = s:Opt_type() + if o =~ 'g\%[ui]' " {{{4 + exe 'return matchstr(inputdialog(a:prompt,'.params.'), ".\\{-}\\ze\\n\\=$")' + elseif o =~ 't\%[ext]' " {{{4 + exe 'return input(a:prompt,'.params.')' + elseif o =~ 'f\%[te]' " {{{4 + exe 'return s:input_fte(a:prompt,'.params.')' + else " {{{4 + throw "UI-Fns::INPUT(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" Function: COMBO(prompt, choice [, ... ]) {{{2 +function! COMBO(prompt, ...) + " 1- Check parameters {{{3 + if a:0 > 4 " {{{4 + throw "UI-Fns::COMBO(): too many parameters" + return 0 + endif + " build the parameters string {{{4 + let i = 1 + while i <= a:0 + if i == 1 | let params = 'a:{1}' + else | let params = params. ',a:{'.i.'}' + endif + let i = i + 1 + endwhile + " 2- Choose the correct way to execute according to the option {{{3 + let o = s:Opt_type() + if o =~ 'g\%[ui]' " {{{4 + exe 'return confirm(a:prompt,'.params.')' + elseif o =~ 't\%[ext]' " {{{4 + exe 'return s:confirm_text("combo", a:prompt,'.params.')' + elseif o =~ 'f\%[te]' " {{{4 + exe 'return s:combo_fte(a:prompt,'.params.')' + else " {{{4 + throw "UI-Fns::COMBO(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" Function: WHICH(function, prompt, choice [, ... ]) {{{2 +function! WHICH(fn, prompt, ...) + " 1- Check parameters {{{3 + " build the parameters string {{{4 + let i = 1 + while i <= a:0 + if i == 1 | let params = 'a:{1}' + else | let params = params. ',a:{'.i.'}' + endif + let i = i + 1 + endwhile + " 2- Execute the function {{{3 + exe 'let which = '.a:fn.'(a:prompt,'.params.')' + if 0 >= which | return '' + elseif 1 == which + return substitute(matchstr(a:{1}, '^.\{-}\ze\%(\n\|$\)'), '&', '', 'g') + else + return substitute( + \ matchstr(a:{1}, '^\%(.\{-}\n\)\{'.(which-1).'}\zs.\{-}\ze\%(\n\|$\)') + \ , '&', '', 'g') + endif + " }}}3 +endfunction + +" Function: CHECK(prompt, choice [, ... ]) {{{2 +function! CHECK(prompt, ...) + " 1- Check parameters {{{3 + if a:0 > 4 " {{{4 + throw "UI-Fns::CHECK(): too many parameters" + return 0 + endif + " build the parameters string {{{4 + let i = 1 + while i <= a:0 + if i == 1 | let params = 'a:{1}' + else | let params = params. ',a:{'.i.'}' + endif + let i = i + 1 + endwhile + " 2- Choose the correct way to execute according to the option {{{3 + let o = s:Opt_type() + if o =~ 'g\%[ui]' " {{{4 + exe 'return s:confirm_text("check", a:prompt,'.params.')' + elseif o =~ 't\%[ext]' " {{{4 + exe 'return s:confirm_text("check", a:prompt,'.params.')' + elseif o =~ 'f\%[te]' " {{{4 + exe 'return s:check_fte(a:prompt,'.params.')' + else " {{{4 + throw "UI-Fns::CHECK(): Unkonwn user-interface style (".o.")" + endif + " }}}3 +endfunction + +" }}}1 +"------------------------------------------------------------------------ +" Options setting {{{1 +let s:OptionData = { + \ "variable": "ui_type", + \ "idx_crt_value": 1, + \ "values": ['gui', 'text', 'fte'], + \ "menu": { "priority": '500.2700', "name": '&Plugin.&LH.&UI type'} + \} + +call lh#menu#def_toggle_item(s:OptionData) + +" }}}1 +"------------------------------------------------------------------------ +" Internal functions {{{1 +function! s:Option(name, default) " {{{2 + if exists('b:ui_'.a:name) | return b:ui_{a:name} + elseif exists('g:ui_'.a:name) | return g:ui_{a:name} + else | return a:default + endif +endfunction + + +function! s:Opt_type() " {{{2 + return s:Option('type', 'gui') +endfunction + +" +" Function: s:status_line(current, hl [, choices] ) {{{2 +" a:current: current item +" a:hl : Generic, Warning, Error +function! s:status_line(current, hl, ...) + " Highlightning {{{3 + if a:hl == "Generic" | let hl = '%1*' + elseif a:hl == "Warning" | let hl = '%2*' + elseif a:hl == "Error" | let hl = '%3*' + elseif a:hl == "Info" | let hl = '%4*' + elseif a:hl == "Question" | let hl = '%5*' + else | let hl = '%1*' + endif + + " Build the string {{{3 + let sl_choices = '' | let i = 1 + while i <= a:0 + if i == a:current + let sl_choices = sl_choices . ' '. hl . + \ substitute(a:{i}, '&\(.\)', '%6*\1'.hl, '') . '%* ' + else + let sl_choices = sl_choices . ' ' . + \ substitute(a:{i}, '&\(.\)', '%6*\1%*', '') . ' ' + endif + let i = i + 1 + endwhile + " }}}3 + return sl_choices +endfunction + + +" Function: s:confirm_text(box, text [, choices [, default [, type]]]) {{{2 +function! s:confirm_text(box, text, ...) + let help = "///////" + " 1- Retrieve the parameters {{{3 + let choices = ((a:0>=1) ? a:1 : '&Ok') + let default = ((a:0>=2) ? a:2 : (('check' == a:box) ? 0 : 1)) + let type = ((a:0>=3) ? a:3 : 'Generic') + if 'none' == a:box | let prefix = '' + elseif 'combo' == a:box | let prefix = '( )_' + elseif 'check' == a:box | let prefix = '[ ]_' + let help = '/ '.help + else | let prefix = '' + endif + + + " 2- Retrieve the proposed choices {{{3 + " Prepare the hot keys + let i = 0 + while i != 26 + let hotkey_{nr2char(i+65)} = 0 + let i += 1 + endwhile + let hotkeys = '' | let help_k = '/' + " Parse the choices + let i = 0 + while choices != "" + let i = i + 1 + let item = matchstr(choices, "^.\\{-}\\ze\\(\n\\|$\\)") + let choices = matchstr(choices, "\n\\zs.*$") + " exe 'anoremenu ]'.a:text.'.'.item.' :let s:choice ='.i.'' + if ('check' == a:box) && (strlen(default)>=i) && (1 == default[i-1]) + " let choice_{i} = '[X]' . substitute(item, '&', '', '') + let choice_{i} = '[X]_' . item + else + " let choice_{i} = prefix . substitute(item, '&', '', '') + let choice_{i} = prefix . item + endif + if i == 1 + let list_choices = 'choice_{1}' + else + let list_choices = list_choices . ',choice_{'.i.'}' + endif + " Update the hotkey. + let key = toupper(matchstr(choice_{i}, '&\zs.\ze')) + let hotkey_{key} = i + let hotkeys = hotkeys . tolower(key) . toupper(key) + let help_k = help_k . tolower(key) + endwhile + let nb_choices = i + if default > nb_choices | let default = nb_choices | endif + + " 3- Run an interactive text menu {{{3 + " Note: emenu can not be used through ":exe" {{{4 + " let wcm = &wcm + " set wcm= + " exe ':emenu ]'.a:text.'.'."" + " let &wcm = wcm + " 3.1- Preparations for the statusline {{{4 + " save the statusline + let sl = &l:statusline + " Color schemes for selected item {{{5 + :hi User1 term=inverse,bold cterm=inverse,bold ctermfg=Yellow + \ guifg=Black guibg=Yellow + :hi User2 term=inverse,bold cterm=inverse,bold ctermfg=LightRed + \ guifg=Black guibg=LightRed + :hi User3 term=inverse,bold cterm=inverse,bold ctermfg=Red + \ guifg=Black guibg=Red + :hi User4 term=inverse,bold cterm=inverse,bold ctermfg=Cyan + \ guifg=Black guibg=Cyan + :hi User5 term=inverse,bold cterm=inverse,bold ctermfg=LightYellow + \ guifg=Black guibg=LightYellow + :hi User6 term=inverse,bold cterm=inverse,bold ctermfg=LightGray + \ guifg=DarkRed guibg=LightGray + " }}}5 + + " 3.2- Interactive loop {{{4 + let help = "\r-- Keys available (".help_k.help.")" + " item selected at the start + let i = ('check' != a:box) ? default : 1 + let direction = 0 | let toggle = 0 + while 1 + if 'combo' == a:box + let choice_{i} = substitute(choice_{i}, '^( )', '(*)', '') + endif + " Colored statusline + " Note: unfortunately the 'statusline' is a global option, {{{ + " not a local one. I the hope that may change, as it does not provokes any + " error, I use '&l:statusline'. }}} + exe 'let &l:statusline=s:status_line(i, type,'. list_choices .')' + if has(':redrawstatus') + redrawstatus! + else + redraw! + endif + " Echo the current selection + echo "\r". a:text.' '.substitute(choice_{i}, '&', '', '') + " Wait the user to hit a key + let key=getchar() + let complType=nr2char(key) + " If the key hit matched awaited keys ... + if -1 != stridx(" \\\".hotkeys,complType) || + \ (key =~ "\\\|\\\|\\\|\") + if key == "\" " Help {{{5 + redraw! + echohl StatusLineNC + echo help + echohl None + let key=getchar() + let complType=nr2char(key) + endif + " TODO: support CTRL-D + if complType == "\" " Validate {{{5 + break + elseif complType == " " " check box {{{5 + let toggle = 1 + elseif complType == "\" " Abort {{{5 + let i = -1 | break + elseif complType == "\" || key == "\" " Next {{{5 + let direction = 1 + elseif key =~ "\\\|\" " Previous {{{5 + let direction = -1 + elseif -1 != stridx(hotkeys, complType ) " Hotkeys {{{5 + if '' == complType | continue | endif + let direction = hotkey_{toupper(complType)} - i + let toggle = 1 + " else + endif + " }}}5 + endif + if direction != 0 " {{{5 + if 'combo' == a:box + let choice_{i} = substitute(choice_{i}, '^(\*)', '( )', '') + endif + let i = i + direction + if i > nb_choices | let i = 1 + elseif i == 0 | let i = nb_choices + endif + let direction = 0 + endif + if toggle == 1 " {{{5 + if 'check' == a:box + let choice_{i} = ((choice_{i}[1] == ' ')? '[X]' : '[ ]') + \ . strpart(choice_{i}, 3) + endif + let toggle = 0 + endif + endwhile " }}}4 + " 4- Terminate {{{3 + " Clear screen + redraw! + + " Restore statusline + let &l:statusline=sl + " Return + if (i == -1) || ('check' != a:box) + return i + else + let r = '' | let i = 1 + while i <= nb_choices + let r = r . ((choice_{i}[1] == 'X') ? '1' : '0') + let i = i + 1 + endwhile + return r + endif +endfunction +" }}}1 +"------------------------------------------------------------------------ +" Functions that insert fte statements {{{1 +" Function: s:if_fte(var, then, else) {{{2 +" Function: s:confirm_fte(text, [, choices [, default [, type]]]) {{{2 +" Function: s:input_fte(prompt [, default]) {{{2 +" Function: s:combo_fte(prompt, choice [, ...]) {{{2 +" Function: s:check_fte(prompt, choice [, ...]) {{{2 +" }}}1 +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/words_tools.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/words_tools.vim new file mode 100644 index 0000000..4857365 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/plugin/words_tools.vim @@ -0,0 +1,104 @@ +" File: plugin/words_tools.vim +" Author: Luc Hermitte +" +" URL: http://hermitte.free.fr/vim/ressources/vim_dollar/plugin/words_tools.vim +" +" Last Update: 14th nov 2002 +" Purpose: Define functions better than expand("") +" +" Note: They are expected to be used in insert mode (thanks to +" or ) +" +"=========================================================================== + +" Return the current keyword, uses spaces to delimitate {{{1 +function! GetNearestKeyword() + let c = col ('.')-1 + let ll = getline('.') + let ll1 = strpart(ll,0,c) + let ll1 = matchstr(ll1,'\k*$') + let ll2 = strpart(ll,c,strlen(ll)-c+1) + let ll2 = matchstr(ll2,'^\k*') + " let ll2 = strpart(ll2,0,match(ll2,'$\|\s')) + return ll1.ll2 +endfunction + +" Return the current word, uses spaces to delimitate {{{1 +function! GetNearestWord() + let c = col ('.')-1 + let l = line('.') + let ll = getline(l) + let ll1 = strpart(ll,0,c) + let ll1 = matchstr(ll1,'\S*$') + let ll2 = strpart(ll,c,strlen(ll)-c+1) + let ll2 = strpart(ll2,0,match(ll2,'$\|\s')) + ""echo ll1.ll2 + return ll1.ll2 +endfunction + +" Return the word before the cursor, uses spaces to delimitate {{{1 +" Rem : is the word under or after the cursor +function! GetCurrentWord() + let c = col ('.')-1 + let l = line('.') + let ll = getline(l) + let ll1 = strpart(ll,0,c) + let ll1 = matchstr(ll1,'\S*$') + if strlen(ll1) == 0 + return ll1 + else + let ll2 = strpart(ll,c,strlen(ll)-c+1) + let ll2 = strpart(ll2,0,match(ll2,'$\|\s')) + return ll1.ll2 + endif +endfunction + +" Return the keyword before the cursor, uses \k to delimitate {{{1 +" Rem : is the word under or after the cursor +function! GetCurrentKeyword() + let c = col ('.')-1 + let l = line('.') + let ll = getline(l) + let ll1 = strpart(ll,0,c) + let ll1 = matchstr(ll1,'\k*$') + if strlen(ll1) == 0 + return ll1 + else + let ll2 = strpart(ll,c,strlen(ll)-c+1) + let ll2 = matchstr(ll2,'^\k*') + " let ll2 = strpart(ll2,0,match(ll2,'$\|\s')) + return ll1.ll2 + endif +endfunction + +" Extract the word before the cursor, {{{1 +" use keyword definitions, skip latter spaces (see "bla word_accepted ") +function! GetPreviousWord() + let lig = getline(line('.')) + let lig = strpart(lig,0,col('.')-1) + return matchstr(lig, '\<\k*\>\s*$') +endfunction + +" GetLikeCTRL_W() retrieves the characters that i_CTRL-W deletes. {{{1 +" Initial need by Hari Krishna Dara +" Last ver: +" Pb: "if strlen(w) == " --> ") == " instead of just "== ". +" There still exists a bug regarding the last char of a line. VIM bug ? +function! GetLikeCTRL_W() + let lig = getline(line('.')) + let lig = strpart(lig,0,col('.')-1) + " treat ending spaces apart. + let s = matchstr(lig, '\s*$') + let lig = strpart(lig, 0, strlen(lig)-strlen(s)) + " First case : last characters belong to a "word" + let w = matchstr(lig, '\<\k\+\>$') + if strlen(w) == 0 + " otherwise, they belong to a "non word" (without any space) + let w = substitute(lig, '.*\(\k\|\s\)', '', 'g') + endif + return w . s +endfunction + +" }}}1 +"======================================================================== +" vim60: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/function.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/function.vim new file mode 100644 index 0000000..44775d6 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/function.vim @@ -0,0 +1,284 @@ +"============================================================================= +" $Id: function.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: tests/lh/function.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 03rd Nov 2008 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Tests for autoload/lh/function.vim +" +"------------------------------------------------------------------------ +" Installation: «install details» +" History: «history» +" TODO: «missing features» +" }}}1 +"============================================================================= + +UTSuite [lh-vim-lib] Testing lh#function plugin + +runtime autoload/lh/function.vim + +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +function! Test(...) + let nb = len(a:000) + " echo "test(".nb.':' .join(a:000, ' -- ')')' + let i =0 + while i!= len(a:000) + echo "Test: type(".i.")=".type(a:000[i]).' --> '. string(a:000[i]) + let i += 1 + endwhile +endfunction + +function! Print(...) + let res = lh#list#accumulate([1,2,'foo'], 'string', 'join(v:1_, " ## ")') + return res +endfunction + +function! Id(...) + return copy(a:000) +endfunction + +function! s:TestId() + let r = Id(1, 'string', [0], [[1]], {'ffo':42}, function('exists'), 1.2) + Assert! len(r) == 7 + Assert! should#be#number (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#list (r[2]) + Assert! should#be#list (r[3]) + Assert! should#be#dict (r[4]) + Assert! should#be#funcref(r[5]) + Assert! should#be#float (r[6]) + Assert r[0] == 1 + Assert r[1] == 'string' + Assert r[2] == [0] + Assert r[3] == [[1]] + Assert r[4].ffo == 42 + Assert r[5] == function('exists') + Assert r[6] == 1.2 +endfunction + +function! s:Test_bind() + " lh#function#bind + lh#function#execute + let rev4 = lh#function#bind(function('Id'), 'v:4_', 42, 'v:3_', 'v:2_', 'v:1_') + let r = lh#function#execute(rev4, 1,'two','three', [4,5]) + Assert! len(r) == 5 + Assert! should#be#list (r[0]) + Assert! should#be#number (r[1]) + Assert! should#be#string (r[2]) + Assert! should#be#string (r[3]) + Assert! should#be#number (r[4]) + + Assert r[0] == [4,5] + Assert r[1] == 42 + Assert r[2] == 'three' + Assert r[3] == 'two' + Assert r[4] == 1 +endfunction + +function! s:Test_bind_compound_vars() + " lh#function#bind + lh#function#execute + let rev4 = lh#function#bind(function('Id'), 'v:4_', 'v:1_ . v:2_', 'v:3_', 'v:2_', 'v:1_') + let r = lh#function#execute(rev4, 1,'two','three', [4,5]) + Assert! len(r) == 5 + Assert! should#be#list (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#string (r[2]) + Assert! should#be#string (r[3]) + Assert! should#be#number (r[4]) + + Assert r[0] == [4,5] + Assert r[1] == '1two' + Assert r[2] == 'three' + Assert r[3] == 'two' + Assert r[4] == 1 +endfunction + + +function! s:Test_execute_func_string_name() + " function name as string + let r = lh#function#execute('Id', 1,'two',3) + Assert! len(r) == 3 + Assert! should#be#number (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#number (r[2]) + Assert r[0] == 1 + Assert r[1] == 'two' + Assert r[2] == 3 +endfunction + +function! s:Test_execute_string_expr() + " exp as binded-string + let r = lh#function#execute('Id(12,len(v:2_).v:2_, 42, v:3_, v:1_)', 1,'two',3) + Assert! len(r) == 5 + Assert! should#be#number (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#number (r[2]) + Assert! should#be#number (r[3]) + Assert! should#be#number (r[4]) + Assert r[0] == 12 + Assert r[1] == len('two').'two' + Assert r[2] == 42 + Assert r[3] == 3 + Assert r[4] == 1 +endfunction + +function! s:Test_execute_func() + " calling a function() + bind + let r = lh#function#execute(function('Id'), 1,'two','v:1_',['a',42]) + Assert! len(r) == 4 + Assert! should#be#number (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#string (r[2]) + Assert! should#be#list (r[3]) + Assert r[0] == 1 + Assert r[1] == 'two' + Assert r[2] == 'v:1_' + Assert r[3] == ['a', 42] +endfunction +"------------------------------------------------------------------------ +function! s:Test_bind_func_string_name_AND_execute() + " function name as string + let rev3 = lh#function#bind('Id', 'v:3_', 12, 'v:2_', 'v:1_') + let r = lh#function#execute(rev3, 1,'two',3) + + Assert! len(r) == 4 + Assert! should#be#number (r[0]) + Assert! should#be#number (r[1]) + Assert! should#be#string (r[2]) + Assert! should#be#number (r[3]) + Assert r[0] == 3 + Assert r[1] == 12 + Assert r[2] == 'two' + Assert r[3] == 1 +endfunction + +function! s:Test_bind_string_expr_AND_execute() +" expressions as string + let rev3 = lh#function#bind('Id(12,len(v:2_).v:2_, 42, v:3_, v:1_)') + let r = lh#function#execute(rev3, 1,'two',3) + Assert! len(r) == 5 + Assert! should#be#number (r[0]) + Assert! should#be#string (r[1]) + Assert! should#be#number (r[2]) + Assert! should#be#number (r[3]) + Assert! should#be#number (r[4]) + Assert r[0] == 12 + Assert r[1] == len('two').'two' + Assert r[2] == 42 + Assert r[3] == 3 + Assert r[4] == 1 +endfunction + +function! s:Test_double_bind_func_name() + let f1 = lh#function#bind('Id', 1, 2, 'v:1_', 4, 'v:2_') + " Comment "f1=".string(f1) + let r = lh#function#execute(f1, 3, 5) + Assert! len(r) == 5 + let i = 0 + while i != len(r) + Assert! should#be#number (r[i]) + Assert r[i] == i+1 + let i += 1 + endwhile + + " f2 + let f2 = lh#function#bind(f1, 'v:1_', 5) + " Comment "f2=f1(v:1_, 5)=".string(f2) + let r = lh#function#execute(f2, 3) + Assert! len(r) == 5 + let i = 0 + while i != len(r) + Assert! should#be#number (r[i]) + " echo "?? ".(r[i])."==".(i+1) + Assert r[i] == i+1 + let i += 1 + endwhile +endfunction + +function! s:Test_double_bind_func() + let f1 = lh#function#bind(function('Id'), 1, 2, 'v:1_', 4, 'v:2_') + " Comment "f1=".string(f1) + let r = lh#function#execute(f1, 3, 5) + Assert! len(r) == 5 + let i = 0 + while i != len(r) + Assert! should#be#number (r[i]) + Assert r[i] == i+1 + let i += 1 + endwhile + + " f2 + let f2 = lh#function#bind(f1, 'v:1_', 5) + " Comment "f2=f1(v:1_, 5)=".string(f2) + let r = lh#function#execute(f2, 3) + Assert! len(r) == 5 + let i = 0 + while i != len(r) + Assert! should#be#number (r[i]) + Assert r[i] == i+1 + let i += 1 + endwhile +endfunction + +function! s:Test_double_bind_func_cplx() + let s:bar = "bar" + let f1 = lh#function#bind(function('Id'), 1, 2, 'v:1_', 4, 'v:2_', 'v:3_', 'v:4_', 'v:5_', 'v:6_', 'v:7_') + " Comment "f1=".string(f1) + let f2 = lh#function#bind(f1, 'v:1_', 5, 'foo', s:bar, 'len(s:bar.v:1_)+v:1_', [1,2], '[v:1_, v:2_]') + " Comment "f2=f1(v:1_, 5)=".string(f2) + + let r = lh#function#execute(f2, 42, "foo") + Assert! 0 && "not ready" + Comment "2bcpl# ".string(r) +endfunction + +function! s:Test_double_bind_expr() + let f1 = lh#function#bind('Id(1, 2, v:1_, v:3_, v:2_)') + Comment "2be# f1=".string(f1) + let r = lh#function#execute(f1, 3, 5, 4) + Comment "2be# ".string(r) + Assert! len(r) == 5 + let i = 0 + while i != len(r) + Assert! should#be#number (r[i]) + Assert r[i] == i+1 + let i += 1 + endwhile + + " f2 + let f2 = lh#function#bind(f1, 'v:1_', '"foo"', []) + Comment "2be# f2=f1(v:1_, 5)=".string(f2) + let r = lh#function#execute(f2, 3) + Comment "2be# ".string(r) + Assert! len(r) == 5 + let i = 0 + while i != len(r)-2 + Assert! should#be#number (r[i]) + Assert r[i] == i+1 + let i += 1 + endwhile + + Assert! should#be#list (r[-2]) + Assert r[-2] == [] + Assert! should#be#string (r[-1]) + Assert r[-1] == 'foo' +endfunction + +"todo: write double-binded tests for all kind of binded parameters: +" 'len(g:bar)' +" 42 +" [] +" v:1_ + len(v:2_.v:3_) +" '"foo"' +" v:1_ + +"------------------------------------------------------------------------ + +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/list.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/list.vim new file mode 100644 index 0000000..d426980 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/list.vim @@ -0,0 +1,165 @@ +"============================================================================= +" $Id: list.vim 238 2010-06-01 00:47:16Z luc.hermitte $ +" File: tests/lh/list.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 19th Nov 2008 +" Last Update: $Date: 2010-05-31 20:47:16 -0400 (Mon, 31 May 2010) $ +"------------------------------------------------------------------------ +" Description: +" Tests for autoload/lh/list.vim +" +"------------------------------------------------------------------------ +" Installation: «install details» +" History: «history» +" TODO: «missing features» +" }}}1 +"============================================================================= + +UTSuite [lh-vim-lib] Testing lh#list functions + +runtime autoload/lh/function.vim +runtime autoload/lh/list.vim +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +" Find_if +function! s:Test_Find_If_string_predicate() + :let b = { 'min': 12, 'max': 42 } + :let l = [ 1, 5, 48, 25, 5, 28, 6] + :let i = lh#list#Find_if(l, 'v:val>v:1_.min && v:val12 && v:1_<42 && v:1_%2==0') + " echo i . '/' . len(l) + Assert i == 5 + Assert l[i] == 28 + " :echo l[i] +endfunction + +function! s:Test_find_if_double_bind() + :let b = { 'min': 12, 'max': 42 } + :let l = [ 1, 5, 48, 25, 5, 28, 6] + :let f = lh#function#bind( 'v:3_>v:1_.min && v:3_ 5") + " Comment string(s) + Assert s == expected +endfunction + +"------------------------------------------------------------------------ +" subset +function! s:Test_subset() + :let l = [ 1, 25, 5, 48, 25, 5, 28, 6] + :let indices = [ 0, 5, 7, 3 ] + :let expected = [ 1, 5, 6, 48 ] + :let s = lh#list#subset(l, indices) + " Comment string(s) + Assert s == expected +endfunction + +"------------------------------------------------------------------------ +" intersect +function! s:Test_intersect() + :let l1 = [ 1, 25, 7, 48, 26, 5, 28, 6] + :let l2 = [ 3, 8, 7, 25, 6 ] + :let expected = [ 25, 7, 6 ] + :let s = lh#list#intersect(l1, l2) + " Comment string(s) + Assert s == expected +endfunction + +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/path.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/path.vim new file mode 100644 index 0000000..71f2abd --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/path.vim @@ -0,0 +1,173 @@ +"============================================================================= +" $Id: path.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: tests/lh/path.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 28th May 2009 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Tests for autoload/lh/path.vim +" +"------------------------------------------------------------------------ +" Installation: «install details» +" History: «history» +" TODO: «missing features» +" }}}1 +"============================================================================= + +UTSuite [lh-vim-lib] Testing lh#path functions + +runtime autoload/lh/path.vim +let s:cpo_save=&cpo +set cpo&vim +"------------------------------------------------------------------------ +function! s:Test_simplify() + Assert lh#path#simplify('a/b/c') == 'a/b/c' + Assert lh#path#simplify('a/b/./c') == 'a/b/c' + Assert lh#path#simplify('./a/b/./c') == 'a/b/c' + Assert lh#path#simplify('./a/../b/./c') == 'b/c' + Assert lh#path#simplify('../a/../b/./c') == '../b/c' + Assert lh#path#simplify('a\b\c') == 'a\b\c' + Assert lh#path#simplify('a\b\.\c') == 'a\b\c' + Assert lh#path#simplify('.\a\b\.\c') == 'a\b\c' + if exists('+shellslash') + Assert lh#path#simplify('.\a\..\b\.\c') == 'b\c' + Assert lh#path#simplify('..\a\..\b\.\c') == '..\b\c' + endif +endfunction + +function! s:Test_strip_common() + let paths = ['foo/bar/file', 'foo/file', 'foo/foo/file'] + let expected = [ 'bar/file', 'file', 'foo/file'] + Assert lh#path#strip_common(paths) == expected +endfunction + +function! s:Test_common() + Assert 'foo/' == lh#path#common(['foo/bar/dir', 'foo']) + Assert 'foo/bar/' == lh#path#common(['foo/bar/dir', 'foo/bar']) + Assert 'foo/' == lh#path#common(['foo/bar/dir', 'foo/bar2']) +endfunction + +function! s:Test_strip_start() + let expected = 'template/bar.template' + Assert lh#path#strip_start($HOME.'/.vim/template/bar.template', + \ [ $HOME.'/.vim', $HOME.'/vimfiles', '/usr/local/share/vim' ]) + \ == expected + + Assert lh#path#strip_start($HOME.'/vimfiles/template/bar.template', + \ [ $HOME.'/.vim', $HOME.'/vimfiles', '/usr/local/share/vim' ]) + \ == expected + + Assert lh#path#strip_start('/usr/local/share/vim/template/bar.template', + \ [ $HOME.'/.vim', $HOME.'/vimfiles', '/usr/local/share/vim' ]) + \ == expected +endfunction + +function! s:Test_IsAbsolutePath() + " nix paths + Assert lh#path#is_absolute_path('/usr/local') + Assert lh#path#is_absolute_path($HOME) + Assert ! lh#path#is_absolute_path('./usr/local') + Assert ! lh#path#is_absolute_path('.usr/local') + + " windows paths + Assert lh#path#is_absolute_path('e:\usr\local') + Assert ! lh#path#is_absolute_path('.\usr\local') + Assert ! lh#path#is_absolute_path('.usr\local') + + " UNC paths + Assert lh#path#is_absolute_path('\\usr\local') + Assert lh#path#is_absolute_path('//usr/local') +endfunction + +function! s:Test_IsURL() + " nix paths + Assert ! lh#path#is_url('/usr/local') + Assert ! lh#path#is_url($HOME) + Assert ! lh#path#is_url('./usr/local') + Assert ! lh#path#is_url('.usr/local') + + " windows paths + Assert ! lh#path#is_url('e:\usr\local') + Assert ! lh#path#is_url('.\usr\local') + Assert ! lh#path#is_url('.usr\local') + + " UNC paths + Assert ! lh#path#is_url('\\usr\local') + Assert ! lh#path#is_url('//usr/local') + + " URLs + Assert lh#path#is_url('http://www.usr/local') + Assert lh#path#is_url('https://www.usr/local') + Assert lh#path#is_url('ftp://www.usr/local') + Assert lh#path#is_url('sftp://www.usr/local') + Assert lh#path#is_url('dav://www.usr/local') + Assert lh#path#is_url('fetch://www.usr/local') + Assert lh#path#is_url('file://www.usr/local') + Assert lh#path#is_url('rcp://www.usr/local') + Assert lh#path#is_url('rsynch://www.usr/local') + Assert lh#path#is_url('scp://www.usr/local') +endfunction + +function! s:Test_ToRelative() + let pwd = getcwd() + Assert lh#path#to_relative(pwd.'/foo/bar') == 'foo/bar' + Assert lh#path#to_relative(pwd.'/./foo') == 'foo' + Assert lh#path#to_relative(pwd.'/foo/../bar') == 'bar' + + " Does not work yet as it returns an absolute path it that case + Assert lh#path#to_relative(pwd.'/../bar') == '../bar' +endfunction + +function! s:Test_relative_path() + Assert lh#path#relative_to('foo/bar/dir', 'foo') == '../../' + Assert lh#path#relative_to('foo', 'foo/bar/dir') == 'bar/dir/' + Assert lh#path#relative_to('foo/bar', 'foo/bar2/dir') == '../bar2/dir/' + + let pwd = getcwd() + Assert lh#path#relative_to(pwd ,pwd.'/../bar') == '../bar/' +endfunction + +function! s:Test_search_vimfiles() + let expected_win = $HOME . '/vimfiles' + let expected_nix = $HOME . '/.vim' + let what = lh#path#to_regex($HOME.'/').'\(vimfiles\|.vim\)' + " Comment what + let z = lh#path#find(&rtp,what) + if has('win16')||has('win32')||has('win64') + Assert z == expected_win + else + Assert z == expected_nix + endif +endfunction + +function! s:Test_path_depth() + Assert 0 == lh#path#depth('.') + Assert 0 == lh#path#depth('./') + Assert 0 == lh#path#depth('.\') + Assert 1 == lh#path#depth('toto') + Assert 1 == lh#path#depth('toto/') + Assert 1 == lh#path#depth('toto\') + Assert 1 == lh#path#depth('toto/.') + Assert 1 == lh#path#depth('toto\.') + Assert 1 == lh#path#depth('toto/./.') + Assert 1 == lh#path#depth('toto\.\.') + Assert 0 == lh#path#depth('toto/..') + if exists('+shellslash') + Assert 0 == lh#path#depth('toto\..') + endif + Assert 2 == lh#path#depth('toto/titi/') + Assert 2 == lh#path#depth('toto\titi\') + Assert 2 == lh#path#depth('/toto/titi/') + Assert 2 == lh#path#depth('c:/toto/titi/') + Assert 2 == lh#path#depth('c:\toto/titi/') +" todo: make a choice about "negative" paths like "../../foo" + Assert -1 == lh#path#depth('../../foo') +endfunction + +"------------------------------------------------------------------------ +let &cpo=s:cpo_save +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-Fargs2String.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-Fargs2String.vim new file mode 100644 index 0000000..dac67e7 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-Fargs2String.vim @@ -0,0 +1,83 @@ +"============================================================================= +" $Id: test-Fargs2String.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: tests/lh/test-Fargs2String.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 16th Apr 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: Tests for lh-vim-lib . lh#command#Fargs2String +" +"------------------------------------------------------------------------ +" Installation: +" Relies on the version «patched by myself|1?» of vim_units +" History: «history» +" TODO: «missing features» +" }}}1 +"============================================================================= + +function! s:TestEmpty() + let empty = [] + let res = lh#command#Fargs2String(empty) + call VUAssertEquals(len(empty), 0, 'Expected empty', 22) + call VUAssertEquals(res, '', 'Expected empty result', 23) +endfunction + +function! s:TestSimpleText1() + let expected = 'text' + let one = [ expected ] + let res = lh#command#Fargs2String(one) + call VUAssertEquals(len(one), 0, 'Expected empty', 27) + call VUAssertEquals(res, expected, 'Expected a simple result', 28) +endfunction + +function! s:TestSimpleTextN() + let expected = 'text' + let list = [ expected , 'stuff1', 'stuff2'] + let res = lh#command#Fargs2String(list) + call VUAssertEquals(len(list), 2, 'Expected not empty', 38) + call VUAssertEquals(res, expected, 'Expected a simple result', 39) +endfunction + +function! s:TestComposedN() + let expected = '"a several tokens string"' + let list = [ '"a', 'several', 'tokens', 'string"', 'stuff1', 'stuff2'] + let res = lh#command#Fargs2String(list) + call VUAssertEquals(len(list), 2, 'Expected not empty', 46) + call VUAssertEquals(res, expected, 'Expected a composed string', 47) + call VUAssertEquals(list, ['stuff1', 'stuff2'], 'Expected a list', 48) + call VUAssertNotSame(list, ['stuff1', 'stuff2'], 'Expected different lists', 49) +endfunction + +function! s:TestComposed1() + let expected = '"string"' + let list = [ '"string"', 'stuff1', 'stuff2'] + let res = lh#command#Fargs2String(list) + call VUAssertEquals(len(list), 2, 'Expected not empty', 56) + call VUAssertEquals(res, expected, 'Expected a string', 57) + call VUAssertEquals(list, ['stuff1', 'stuff2'], 'Expected a list', 58) + call VUAssertNotSame(list, ['stuff1', 'stuff2'], 'Expected different lists', 59) +endfunction + +function! s:TestInvalidString() + let expected = '"a string' + let list = [ '"a', 'string'] + let res = lh#command#Fargs2String(list) + call VUAssertEquals(len(list), 0, 'Expected empty', 66) + call VUAssertEquals(res, expected, 'Expected an invalid string', 67) +endfunction + +function! AllTests() + call s:TestEmpty() + call s:TestSimpleText1() + call s:TestSimpleTextN() + call s:TestComposed1() + call s:TestComposedN() +endfunction + +" call VURunnerRunTest('AllTests') +VURun % AllTests + +"============================================================================= +" vim600: set fdm=marker: diff --git a/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-askmenu.vim b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-askmenu.vim new file mode 100644 index 0000000..c970936 --- /dev/null +++ b/.vim/bundle/gundo/tests/bundled/lh-vim-lib/tests/lh/test-askmenu.vim @@ -0,0 +1,65 @@ +"============================================================================= +" $Id: test-askmenu.vim 246 2010-09-19 22:40:58Z luc.hermitte $ +" File: test-buffer-menu.vim {{{1 +" Author: Luc Hermitte +" +" Version: 2.2.1 +" Created: 18th Apr 2007 +" Last Update: $Date: 2010-09-19 18:40:58 -0400 (Sun, 19 Sep 2010) $ +"------------------------------------------------------------------------ +" Description: +" Test units for buffermenu.vim +" +"------------------------------------------------------------------------ +" Installation: Requires: +" (*) Vim 7.0+ +" (*) vim_units.vim v0.2/1.0? +" Vimscript # «???» +" (*) lh-vim-lib (lh#ask#menu) +" +" User Manual: +" Source this file. +" +" History: +" (*) 17th Apr 2007: First version +" TODO: «missing features» +" }}}1 +"============================================================================= + + + +"============================================================================= +let s:cpo_save=&cpo +"------------------------------------------------------------------------ +" Functions {{{1 + +function! TestAskMenu() + imenu 42.40.10 &LH-Tests.&Menu.&ask.i iask + inoremenu 42.40.10 &LH-Tests.&Menu.&ask.inore inoreask + nmenu 42.40.10 &LH-Tests.&Menu.&ask.n nask + nnoremenu 42.40.10 &LH-Tests.&Menu.&ask.nnore nnoreask + nmenu +< + At the line 1 and 3, neocomplete#get_context_filetype() is + "html" and at the line 2 it's "javascript", while at any + lines 'filetype' is "html". + + *neocomplete#disable_default_dictionary()* +neocomplete#disable_default_dictionary({variable-name}) + Disable default {variable-name} dictionary initialization. + Note: It must be called in .vimrc. +> + call neocomplete#disable_default_dictionary( + \ 'g:neocomplete#same_filetypes') +< +------------------------------------------------------------------------------ +KEY MAPPINGS *neocomplete-key-mappings* + + *neocomplete#start_manual_complete()* +neocomplete#start_manual_complete([{sources}]) + Use this function on inoremap . The keymapping call the + completion of neocomplete. When you rearrange the completion + of the Vim standard, you use it. + If you give {sources} argument, neocomplete call {sources}. + {sources} is name of source or list of sources name. +> + inoremap neocomplete#start_manual_complete() +< + *neocomplete#close_popup()* +neocomplete#close_popup() + Insert candidate and close popup menu for neocomplete. +> + inoremap neocomplete#close_popup() +< + *neocomplete#cancel_popup()* +neocomplete#cancel_popup() + Cancel completion menu for neocomplete. +> + inoremap neocomplete#cancel_popup() +< + *neocomplete#smart_close_popup()* +neocomplete#smart_close_popup() + Insert candidate and re-generate popup menu for neocomplete. + Unlike |neocomplete#close_popup()|, this function changes + behavior by |g:neocomplete#enable_auto_select| smart. + Note: This mapping is conflicted with |SuperTab| or |endwise| + plugins. + Note: This key mapping is for or keymappings. + You should not use it for . + + *neocomplete#undo_completion()* +neocomplete#undo_completion() + Use this function on inoremap to undo inputted + candidate. Because there is not mechanism to cancel + candidate in Vim, it will be convenient when it inflects. +> + inoremap neocomplete#undo_completion() +< + *neocomplete#complete_common_string()* +neocomplete#complete_common_string() + Use this function on inoremap to complete common + string in candidates. It will be convenient when candidates + have long common string. +> + inoremap neocomplete#complete_common_string() + inoremap + \ neocomplete#complete_common_string() != '' ? + \ neocomplete#complete_common_string() : + \ pumvisible() ? "\" : "\" +< + *(neocomplete_start_unite_complete)* +(neocomplete_start_unite_complete) + Start completion with |unite|. + Note: unite.vim Latest ver.3.0 or above is required. + Note: In unite interface, uses partial match instead of head + match. + + *(neocomplete_start_quick_match)* +(neocomplete_start_unite_quick_match) + Start completion with |unite| and start quick match mode. + Note: unite.vim Latest ver.3.0 or above is required. + +============================================================================== +EXAMPLES *neocomplete-examples* +> + " Note: This option must set it in .vimrc(_vimrc). + " NOT IN .gvimrc(_gvimrc)! + " Disable AutoComplPop. + let g:acp_enableAtStartup = 0 + " Use neocomplete. + let g:neocomplete#enable_at_startup = 1 + " Use smartcase. + let g:neocomplete#enable_smart_case = 1 + " Set minimum syntax keyword length. + let g:neocomplete#sources#syntax#min_keyword_length = 3 + let g:neocomplete#lock_buffer_name_pattern = '\*ku\*' + + " Define dictionary. + let g:neocomplete#sources#dictionary#dictionaries = { + \ 'default' : '', + \ 'vimshell' : $HOME.'/.vimshell_hist', + \ 'scheme' : $HOME.'/.gosh_completions' + \ } + + " Define keyword. + if !exists('g:neocomplete#keyword_patterns') + let g:neocomplete#keyword_patterns = {} + endif + let g:neocomplete#keyword_patterns['default'] = '\h\w*' + + " Plugin key-mappings. + inoremap neocomplete#undo_completion() + inoremap neocomplete#complete_common_string() + + " Recommended key-mappings. + " : close popup and save indent. + inoremap =my_cr_function() + function! s:my_cr_function() + return neocomplete#close_popup() . "\" + " For no inserting key. + "return pumvisible() ? neocomplete#close_popup() : "\" + endfunction + " : completion. + inoremap pumvisible() ? "\" : "\" + " , : close popup and delete backword char. + inoremap neocomplete#smart_close_popup()."\" + inoremap neocomplete#smart_close_popup()."\" + inoremap neocomplete#close_popup() + inoremap neocomplete#cancel_popup() + " Close popup by . + "inoremap pumvisible() ? neocomplete#close_popup() : "\" + + " AutoComplPop like behavior. + "let g:neocomplete#enable_auto_select = 1 + + " Shell like behavior(not recommended). + "set completeopt+=longest + "let g:neocomplete#enable_auto_select = 1 + "let g:neocomplete#disable_auto_complete = 1 + "inoremap pumvisible() ? "\" : + " \ neocomplete#start_manual_complete() + + " Enable omni completion. + autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS + autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags + autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS + autocmd FileType python setlocal omnifunc=pythoncomplete#Complete + autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags + + " Enable heavy omni completion. + if !exists('g:neocomplete#sources#omni#input_patterns') + let g:neocomplete#sources#omni#input_patterns = {} + endif + if !exists('g:neocomplete#force_omni_input_patterns') + let g:neocomplete#force_omni_input_patterns = {} + endif + "let g:neocomplete#sources#omni#input_patterns.php = + "\ '[^. \t]->\%(\h\w*\)\?\|\h\w*::\%(\h\w*\)\?' + "let g:neocomplete#sources#omni#input_patterns.c = + "\ '[^.[:digit:] *\t]\%(\.\|->\)\%(\h\w*\)\?' + "let g:neocomplete#sources#omni#input_patterns.cpp = + "\ '[^.[:digit:] *\t]\%(\.\|->\)\%(\h\w*\)\?\|\h\w*::\%(\h\w*\)\?' + + " For perlomni.vim setting. + " https://github.com/c9s/perlomni.vim + let g:neocomplete#sources#omni#input_patterns.perl = + \ '[^. \t]->\%(\h\w*\)\?\|\h\w*::\%(\h\w*\)\?' + + " For smart TAB completion. + "inoremap pumvisible() ? "\" : + " \ check_back_space() ? "\" : + " \ neocomplete#start_manual_complete() + " function! s:check_back_space() "{{{ + " let col = col('.') - 1 + " return !col || getline('.')[col - 1] =~ '\s' + " endfunction"}}} +< +============================================================================== +SOURCES *neocomplete-sources* + +neocomplete reads automatically sources saved in an +autoload/neocomplete/sources directory. + +buffer *neocomplete-source-buffer* + This source collects keywords from buffer. + +member *neocomplete-source-member* + This source collects use of member variables from buffer. + +tag *neocomplete-source-tag* + This source analyzes a tag file from tagfiles() for completion. + When a huge tag file (above + |g:neocomplete#sources#tags#cache_limit_size|) is set, + neocomplete does not make cache if you do not execute + |:NeoCompleteTagMakeCache| command. Because tag is + too slow if tag read a big tags file. You should use + more convenient include source completion now. + +syntax *neocomplete-source-syntax* + This source analyzes a syntax file like + autoload/syntaxcomplete.vim offered by default, and to + add to candidate completion. The plugin can recognize + candidates a lot more than autoload/syntaxcomplete.vim. + +dictionary *neocomplete-source-dictionary* + This source adds candidates from 'dictionary' or + |g:neocomplete#sources#dictionary#dictionaries|. + +file *neocomplete-source-file* + This source collects filename candidates. + Note: It is relative path to current buffer directory. + +omni *neocomplete-source-omni* + This source calls 'omnifunc' automatically when cursor + text is matched with |g:neocomplete#sources#omni#input_patterns|. If + |g:neocomplete_omni_function_list|is defined, + neocomplete will give priority it. + + +suffix of complete candidates in popup menu declaration. +(This will be good for user to know where candidate from and what it is.) + + file -> [F] {filename} + file/include -> [FI] {filename} + dictionary -> [D] {words} + member -> [M] member + buffer -> [B] {buffer} + syntax -> [S] {syntax-keyword} + include -> [I] + neosnippet -> [neosnip] + UltiSnips -> [US] + vim -> [vim] type + omni -> [O] + tag -> [T] + other sources -> [plugin-name-prefix] + +------------------------------------------------------------------------------ +USER SOURCES *neocomplete-user-sources* + +This section, introduce non default neocomplete sources. + +neosnippet *neocomplete-sources-neosnippet* + This source is for snippets completion. + https://github.com/Shougo/neosnippet + +UltiSnips *neocomplete-sources-ultisnips* + This source is for UltiSnips snippets completion. + https://github.com/SirVer/ultisnips + +neco-ghc *neocomplete-sources-neco-ghc* + https://github.com/eagletmt/neco-ghc + eagletmt originally implemented and ujihisa added some new + features. It completes a source file written in Haskell. + It requires ghc-mod . + +neco-vim *neocomplete-sources-neco-vim* + https://github.com/Shougo/neco-vim + It analyzes context and start Omni completion of Vim script. + It does not work other than editing time of Vim script. I + created it because neocomplete cannot call |i_CTRL-X_CTRL-V|. + Local variable and a script variable, a function and the + analysis of the command are implemented now. + +============================================================================== +FILTERS *neocomplete-filters* + +To custom candidates, neocomplete uses the filters. There are three kinds of +filters are available. "matcher" is to filter candidates by user input. +"sorter" is to sort candidates. "converter" is to candidates conversion. + +Default sources are below. But you can create original filters(cf: +|neocomplete-create-filter|) and set them by +|neocomplete#custom#source()|. +> + call neocomplete#custom#source( + \ 'buffer', 'converters', []) + + " Change default matcher. + call neocomplete#custom#source('_', 'matchers', + \ ['matcher_head', 'matcher_length']) + + " Change default sorter. + call neocomplete#custom#source('_', 'sorters', + \ ['sorter_length']) + + " Disable sort. + call neocomplete#custom#source('_', 'sorters', []) + + " Change default converter. + call neocomplete#custom#source('_', 'converters', + \ ['converter_remove_overlap', 'converter_remove_last_paren', + \ 'converter_delimiter', 'converter_abbr']) +< + *neocomplete-filter-matcher_default* +Default matchers: + If |g:neocomplete#enable_fuzzy_completion|: + ['matcher_head', 'matcher_length'] + Otherwise: + ['matcher_fuzzy', 'matcher_length'] + + *neocomplete-filter-sorter_default* +Default sorters: ['sorter_rank']. + + *neocomplete-filter-converter_default* +Default converters: ['converter_remove_overlap', + \ 'converter_delimiter', 'converter_abbr']. + + *neocomplete-filter-matcher_head* +matcher_head Head matching matcher. + + *neocomplete-filter-matcher_fuzzy* +matcher_fuzzy Fuzzy matching matcher. + + *neocomplete-filter-matcher_length* +matcher_length Input keyword length matcher. It removes candidates which is + less than input keyword length. + + *neocomplete-filter-sorter_rank* +sorter_rank Matched rank order sorter. The higher the matched word is + already selected or in current buffer + + *neocomplete-filter-sorter_length* +sorter_length Candidates length order sorter. + + *neocomplete-filter-sorter_word* +sorter_word Candidates word order sorter. + + *neocomplete-filter-converter_abbr* +converter_abbr + The converter which abbreviates a candidate's abbr. + + *neocomplete-filter-converter_disable_abbr* +converter_disable_abbr + The converter which disables a candidate's abbr. + + *neocomplete-filter-converter_delimiter* +converter_delimiter + The converter which abbreviates a candidate's delimiter. + (cf: |g:neocomplete#delimiter_patterns|) + + *neocomplete-filter-converter_remove_overlap* +converter_remove_overlap + The converter which removes overlapped text in a candidate's + word. + Note: It removes candidates which is not overlapped + (it is in auto completion only). + + *neocomplete-filter-converter_remove_last_paren* +converter_remove_last_paren + The converter which removes last parentheses in a + candidate's word. It is useful if you use auto closing + parentheses plugins. + +============================================================================== +CREATE SOURCE *neocomplete-create-source* + +In this clause, I comment on a method to make source of neocomplete. The +ability of neocomplete will spread by creating source by yourself. + +The files in autoload/neocomplete/sources are automatically loaded and it +calls neocomplete#sources#{source_name}#define() whose return value is the +source. Each return value can be a list so you can return an empty list to +avoid adding undesirable sources. To add your own sources dynamically, you +can use |neocomplete#define_source()|. + +------------------------------------------------------------------------------ +SOURCE ATTRIBUTES *neocomplete-source-attributes* + + *neocomplete-source-attribute-name* +name String (Required) + The name of a source. Allowed characters are: + - a-z + - 0-9 + - _ + - / + - - (Not head) + + *neocomplete-source-attribute-kind* +kind String (Optional) + The kind of the source. It decides the behaviour of + the complete position. The following values are + available: + + "manual": The source decides the complete position + manually with the "get_complete_position" + attribute. See also: + |neocomplete-source-attribute-get_complete_position| + + "keyword": The source decides the complete position + with |g:neocomplete#keyword_patterns|. This + pattern is also used to filter the candidates. + + Note that "plugin", "complfunc" and "ftplugin" are old + values that are no longer accepted. + + + *neocomplete-source-attribute-filetypes* +filetypes Dictionary (Optional) + Available filetype dictionary. + + For example: +> + let source = { + \ 'name' : 'test', + \ 'kind' : 'manual', + \ 'filetypes' : { 'vim' : 1, 'html' : 1 }, + \} +< + The source is available in vim and html filetypes. + + If you omit it, this source available in all + filetypes. + + *neocomplete-source-attribute-disabled_filetypes* +disabled_filetypes Dictionary (Optional) + Not available filetype dictionary. + If the key is "_", the source is disabled in all + sources. + + *neocomplete-source-attribute-rank* +rank Number (Optional) + Source priority. Higher values imply higher priority. + If you omit it, it is set below value. + Note: It is high priority than match position. + + If kind attribute is "keyword": 5 + If filetype attribute is empty: 10 + Otherwise: 100 + + Example: +> + " Change vim source default rank value of 300. + call neocomplete#custom#source('ultisnips', 'rank', 1000) +< + *neocomplete-source-attribute-min_pattern_length* +min_pattern_length + Number (Optional) + Required pattern length for completion. + + If you omit it, it is set below value. + If kind attribute is "keyword": + |g:neocomplete#auto_completion_start_length| + Otherwise: 0 + + *neocomplete-source-attribute-max_candidates* +max_candidates + Number (Optional) + The maximum number of candidates. + + This attribute is optional; if it is not given, + 0 is used as the default value. This means + maximum number is infinity. + + *neocomplete-source-attribute-keyword_patterns* +keyword_patterns + Dictionary (Optional) + This dictionary changes keyword patterns to + completion for specific types. +> + let keyword_patterns = {} + let keyword_patterns.tex = '\\\?\h\w*' + call neocomplete#custom#source('dictionary', + \ 'keyword_patterns', keyword_patterns) +< + This attribute is optional; if it is not given, + |g:neocomplete#keyword_patterns| is used as the + default value. + + *neocomplete-source-attribute-is_volatile* +is_volatile Number (Optional) + Whether the source recalculates the candidates + everytime the input is changed. + This attribute is optional. + If it's not given, 0 is set as the default value. In + this case, candidates are cached. + + *neocomplete-source-attribute-disabled* +disabled Number (Optional) + This attribute is optional. + If it's not given, 0 is set as the default value. + Otherwise, the source is disabled. + + *neocomplete-source-attribute-hooks* +hooks Dictionary (Optional) + You may put hook functions in this dictionary in which + the key is the position to hook and the value is the + reference to the function to be called. The following + hook functions are defined: + + *neocomplete-source-attribute-hooks-on_init* + on_init + Called when initializing the source. + This function takes {context} as its parameters. + + *neocomplete-source-attribute-hooks-on_final* + on_final + Called after executing |:NeoCompleteDisable|. + This function takes {context} as its parameters. + + *neocomplete-source-attribute-hooks-on_post_filter* + on_post_filter + Called after the filters to narrow down the + candidates. This is used to set attributes. This + filters is to avoid adversely affecting the + performance. + This function takes {context} as its parameters. + + *neocomplete-source-attribute-get_complete_position* +get_complete_position Function (Optional) + This function takes {context} as its + parameter and returns complete position in current + line. + Here, {context} is the context information when the + source is called(|neocomplete-notation-{context}|). + If you omit it, neocomplete will use the position + using |g:neocomplete#keyword_patterns|. + Note: If the source returns candidates which are not + matched |g:neocomplete#keyword_patterns|, you must + define + |neocomplete-source-attribute-get_complete_position|. + + *neocomplete-source-attribute-gather_candidates* +gather_candidates Function (Required) + This function is called in gathering candidates. If + you enabled fuzzy completion by + |g:neocomplete#enable_fuzzy_completion| , this + function is called whenever the input string is + changed. This function takes {context} as its + parameter and returns a list of {candidate}. + Here, {context} is the context information when the + source is called(|neocomplete-notation-{context}|). + +{context} *neocomplete-notation-{context}* + A dictionary to give context information. + The followings are the primary information. + The global context information can be acquired + by |neocomplete#get_context()|. + + input (String) + The input string of current line. + + complete_pos (Number) + The complete position of current source. + + complete_str (String) + The complete string of current source. + + source__{name} (Unknown) (Optional) + Additional source information. + Note: Recommend sources save + variables instead of s: variables. + +------------------------------------------------------------------------------ +CANDIDATE ATTRIBUTES *neocomplete-candidate-attributes* + + *neocomplete-candidate-attribute-name* +word String (Required) + The completion word of a candidate. It is used for + matching inputs. + + *neocomplete-candidate-attribute-abbr* +abbr String (Optional) + The abbreviation of a candidate. It is displayed in + popup window. It is omitted by + |g:neocomplete#max_keyword_width|. + + *neocomplete-candidate-attribute-kind* +kind String (Optional) + The kind of a candidate. It is displayed in popup + window. + + *neocomplete-candidate-attribute-menu* +menu String (Optional) + The menu information of a candidate. It is displayed + in popup window. + + *neocomplete-candidate-attribute-info* +info String (Optional) + The preview information of a candidate. If + 'completeopt' contains "preview", it will be displayed + in |preview-window|. + + *neocomplete-candidate-attribute-rank* +rank Number (Optional) + The completion priority. + +CONTEXT *neocomplete-context* + +============================================================================== +CREATE FILTER *neocomplete-create-filter* + +The files in autoload/neocomplete/filters are automatically loaded and it +calls neocomplete#filters#{filter_name}#define() whose return value is the +filter. Each return value can be a list so you can return an empty list to +avoid adding undesirable filters. To add your own filters dynamically, you +can use |neocomplete#define_filter()|. + +------------------------------------------------------------------------------ +FILTER ATTRIBUTES *neocomplete-filter-attributes* + + + *neocomplete-filter-attribute-name* +name String (Required) + The filter name. + + *neocomplete-filter-attribute-filter* +filter Function (Required) + The filter function. This function takes {context} as + its parameter and returns a list of {candidate}. + The specification of the parameters and the returned + value is same as + |neocomplete-source-attribute-gather_candidates|. + + *neocomplete-filter-attribute-description* +description String (Optional) + The filter description string. + +============================================================================== +UNITE SOURCES *neocomplete-unite-sources* + + *neocomplete-unite-source-neocomplete* +neocomplete + Nominates neocomplete completion candidates. The kind is + "completion". This source is used in + |(neocomplete_start_unite_complete)|. +> + imap (neocomplete_start_unite_complete) + imap (neocomplete_start_unite_quick_match) +< +============================================================================== +EXTERNAL SOURCES *neocomplete-external-sources* + +neosnippet source: + +https://github.com/Shougo/neosnippet.vim + +include, file/include sources: + +https://github.com/Shougo/neoinclude.vim + +UltiSnips source: + +https://github.com/SirVer/ultisnips + +vimshell source: + +https://github.com/Shougo/vimshell.vim + +look source: + +https://github.com/ujihisa/neco-look + +ghc source: + +https://github.com/eagletmt/neco-ghc + +calc source: + +https://github.com/hrsh7th/vim-neco-calc + +============================================================================== +FAQ *neocomplete-faq* + +Q: My customization for neocomplete is invalid. Why? + +A: User customization for neocomplete must be set before initialization of +neocomplete. For example: |neocomplete#custom#source()| + +Q: I want to use head match instead of default fuzzy match. + +A: +> + let g:neocomplete#enable_fuzzy_completion = 0 +< +or +> + call neocomplete#custom#source('_', 'matchers', + \ ['matcher_head', 'matcher_length']) +< +Q: I want to sort candidates by different way. + +A: +> +> + call neocomplete#custom#source('_', 'sorters', + \ ['sorter_length']) +< +Q: Is there a way to control the colors used for popup menu using highlight +groups?: + +A: Like this: +> + highlight Pmenu ctermbg=8 guibg=#606060 + highlight PmenuSel ctermbg=1 guifg=#dddd00 guibg=#1f82cd + highlight PmenuSbar ctermbg=0 guibg=#d6d6d6 +< + +Q: Python (or Ruby) interface crashes Vim when I use neocomplete or not +responding when input ".": + +A: This is not neocomplete's issue. Please report to the maintainers of the +omnicomplete (rubycomplete or pythoncomplete) and its Vim interface. You +should disable omni source in python or ruby. +> + if !exists('g:neocomplete#sources#omni#input_patterns') + let g:neocomplete#sources#omni#input_patterns = {} + endif + let g:neocomplete#sources#omni#input_patterns.python = '' + let g:neocomplete#sources#omni#input_patterns.ruby = '' +< + +Q: Where are the snippets for neocomplete? + +A: https://github.com/Shougo/neosnippet or +https://github.com/SirVer/ultisnips + + +Q: How can I disable python omni complete of neocomplete?: + +A: +> + if !exists('g:neocomplete#sources#omni#input_patterns') + let g:neocomplete#sources#omni#input_patterns = {} + endif + let g:neocomplete#sources#omni#input_patterns.python = '' +< + +Q: Can I enable quick match?: + +A: Quick match feature had been removed in latest neocomplete +because quick match turned into hard to implement. +But you can use |unite.vim| instead to use quick match. +> + imap - pumvisible() ? + \ "\(neocomplete_start_unite_quick_match)" : '-' +< + +Q: neocomplete cannot create cache files in "sudo vim": + +A: Because neocomplete (and other plugins) creates temporary files in super +user permission by sudo command. You must use sudo.vim or set "Defaults +always_set_home" in "/etc/sudoers", or must use "sudoedit" command. + +Ubuntu has a command "sudoedit" which can work well with neocomplete. +I'm not sure if other distros has this command... + +http://www.vim.org/scripts/script.php?script_id=729 + + +Q: Error occurred in ruby omni complete using +|g:neocomplete#sources#omni#input_patterns|. +https://github.com/vim-ruby/vim-ruby/issues/95 + +A: Please set |g:neocomplete#force_omni_input_patterns| instead of +|g:neocomplete#sources#omni#input_patterns|. + +Q: Does not work with clang_complete. + +A: Please try below settings. +> + if !exists('g:neocomplete#force_omni_input_patterns') + let g:neocomplete#force_omni_input_patterns = {} + endif + let g:neocomplete#force_omni_input_patterns.c = + \ '[^.[:digit:] *\t]\%(\.\|->\)\w*' + let g:neocomplete#force_omni_input_patterns.cpp = + \ '[^.[:digit:] *\t]\%(\.\|->\)\w*\|\h\w*::\w*' + let g:neocomplete#force_omni_input_patterns.objc = + \ '\[\h\w*\s\h\?\|\h\w*\%(\.\|->\)' + let g:neocomplete#force_omni_input_patterns.objcpp = + \ '\[\h\w*\s\h\?\|\h\w*\%(\.\|->\)\|\h\w*::\w*' + let g:clang_complete_auto = 0 + let g:clang_auto_select = 0 + let g:clang_default_keymappings = 0 + "let g:clang_use_library = 1 +< + +Q: I want to support omni patterns for external plugins. + +A: You can add find some already found omni patterns and functions at here. + +Note: Some patterns are omitted here, (someone should check out those plugin's +source code's complete function, and find out the omni pattern). +> + " Go (plugin: gocode) + let g:neocomplete#sources#omni#functions.go = + \ 'gocomplete#Complete' + " Clojure (plugin: vim-clojure) + let g:neocomplete#sources#omni#functions.clojure = + \ 'vimclojure#OmniCompletion' + " SQL + let g:neocomplete#sources#omni#functions.sql = + \ 'sqlcomplete#Complete' + " R (plugin: vim-R-plugin) + let g:neocomplete#sources#omni#input_patterns.r = + \ '[[:alnum:].\\]\+' + let g:neocomplete#sources#omni#functions.r = + \ 'rcomplete#CompleteR' + " XQuery (plugin: XQuery-indentomnicomplete) + let g:neocomplete#sources#omni#input_patterns.xquery = + \ '\k\|:\|\-\|&' + let g:neocomplete#sources#omni#functions.xquery = + \ 'xquerycomplete#CompleteXQuery' +< + +Q: Does not indent when I input "else" in ruby filetype. + +A: + +You must install "vim-ruby" from github to indent in neocomplete first. +https://github.com/vim-ruby/vim-ruby + +neocomplete pops up a completion window automatically, but if the popup +window is already visible, Vim cannot indent text. So you must choose "close +popup window manually by or mappings" or "close popup window by + user mappings". + +Q: mapping conflicts with |SuperTab| or |endwise| plugins. + +A: Please try below settings. +> + " : close popup and save indent. + inoremap =my_cr_function() + function! s:my_cr_function() + return neocomplete#close_popup() . "\" + " For no inserting key. + "return pumvisible() ? neocomplete#close_popup() : "\" + endfunction +> +Q: No completion offered from "vim" buffers in "non-vim" buffers. + +A: It is feature. neocomplete completes from same filetype buffers in +default. But you can completes from other filetype buffers using +|g:neocomplete#same_filetypes|. + +Q: I want to complete from all buffers. + +A: |g:neocomplete#same_filetypes| +> + let g:neocomplete#same_filetypes = {} + let g:neocomplete#same_filetypes._ = '_' +< + +Q: Suggestions are case insensitive in "gitcommit" buffers, but not +"javascript". + +A: This is g:neocomplete#text_mode_filetypes feature. +You can disable it by following code. +> + if !exists('g:neocomplete#text_mode_filetypes') + let g:neocomplete#tags_filter_patterns = {} + endif + let g:neocomplete#text_mode_filetypes.gitcommit = 0 +< +Q: I want to use Ruby omni completion. + +A: Please set |g:neocomplete#force_omni_input_patterns|. But this completion +is heavy, so disabled by default. +Note: But you should use |neocomplete-rsense| instead of rubycomplete. +https://github.com/Shougo/neocomplete-rsense +> + autocmd FileType ruby setlocal omnifunc=rubycomplete#Complete + if !exists('g:neocomplete#force_omni_input_patterns') + let g:neocomplete#force_omni_input_patterns = {} + endif + let g:neocomplete#force_omni_input_patterns.ruby = + \ '[^. *\t]\.\w*\|\h\w*::' +< +Q: I want to use jedi omni completion. +https://github.com/davidhalter/jedi-vim + +A: Please set |g:neocomplete#force_omni_input_patterns| as below. +> + autocmd FileType python setlocal omnifunc=jedi#completions + let g:jedi#completions_enabled = 0 + let g:jedi#auto_vim_configuration = 0 + let g:neocomplete#force_omni_input_patterns.python = + \ '\%([^. \t]\.\|^\s*@\|^\s*from\s.\+import \|^\s*from \|^\s*import \)\w*' + " alternative pattern: '\h\w*\|[^. \t]\.\w*' +< +Q: Candidates are not found in heavy completion(neco-look, etc). + +A: It may be caused by skip completion. + + +Q: I want to disable skip completion. + +A: +> + let g:neocomplete#skip_auto_completion_time = '' +< +Q: I want to initialize neocomplete in .vimrc. + +A: Please call neocomplete#initialize() in .vimrc. But this function slows +your Vim initialization. +> + call neocomplete#initialize() +< +Q: neocomplete conflicts when multibyte input in GVim. + +A: Because Vim multibyte IME integration is incomplete. +You should use "fcitx" instead of "ibus". +If you set |g:neocomplete#lock_iminsert| is non-zero, it may be fixed. + +Q: Freeze for a while and close opened folding when I begin to insert. +https://github.com/Shougo/neocomplcache.vim/issues/368 + +A: I think you use 'foldmethod' is "expr" or "syntax". It is too heavy to use +neocomplete(or other auto completion). You should change 'foldmethod' +option. +Note: In current version, neocomplete does not restore 'foldmethod'. Because +it is too heavy. + +Q: I want to use Pydiction with neocomplete. + +A: You should set |g:neocomplete#sources#dictionary#dictionaries|. +neocomplete can load Pydiction dictionary file. + +Q: Why does neocomplcache use if_lua besides if_python? Many people may not be +able to use it because they do not have the root privilege to recompile vim. + +A: +Because of the following reasons. + 1. Python interface is not available on every Vim environment. For example, + Android, iOS, non configured Vim, or etc. + 2. Incompatibility between Python2 and Python3. I must rewrite for it. + 3. Loading Python interface is slow (10~20ms), but loading Lua interface is + absolutely fast (270ns). + 4. Python2 and Python3 are not loaded at the same time on Unix environment. + 5. Python itself is too large. + 6. Python interface is slower than Lua interface (almost twice.) + 7. Lua interface is stable (no crashes on latest Vim.) + 8. Using C module (like vimproc, YouCompleteMe) is hard to compile on Windows + environment. + 9. Using both Python and C, like YouCompleteMe, is too unstable. Your Vim may + crashes or causes mysterious errors. + 10. To build if_lua is easy. + 11. I think if_lua is the second level language in Vim (The first is Vim + script.) + +Q: I want to disable preview window. + +A: +> + set completeopt-=preview +< + +Q: I want to use "vim-lua-ftplugin". +https://github.com/xolox/vim-lua-ftplugin + +A: Please set |g:neocomplete#sources#omni#input_patterns| as below. +Note: You can not use "vim-lua-ftplugin" on 7.3.885 or below, +because if_lua has double-free problem. +> + let g:lua_check_syntax = 0 + let g:lua_complete_omni = 1 + let g:lua_complete_dynamic = 0 + + let g:neocomplete#sources#omni#functions.lua = + \ 'xolox#lua#omnifunc' + let g:neocomplete#sources#omni#input_patterns.lua = + \ '\w\+[.:]\|require\s*(\?["'']\w*' + " let g:neocomplete#force_omni_input_patterns.lua = + " \ '\w\+[.:]\|require\s*(\?["'']\w*' +< + +Q: I want to disable sources in certain filetype. + +A: +> + " Disable dictionary source in python filetype. + call neocomplete#custom#source('dictionary', + \ 'disabled_filetypes', {'python' : 1}) +< + +Q: neocomplete closes DiffGitCached window from vim-fugitive +https://github.com/Shougo/neocomplcache.vim/issues/424 +A: +> + let g:neocomplete#enable_auto_close_preview = 0 +< + +Q: I want to use PHP omni completion. + +A: +Note: You should use this omni completion for PHP. +https://github.com/shawncplus/phpcomplete.vim +> + let g:neocomplete#sources#omni#input_patterns.php = + \ '\h\w*\|[^. \t]->\%(\h\w*\)\?\|\h\w*::\%(\h\w*\)\?' +< + +Q: Eclim does not work well with neocomplete. +https://github.com/Shougo/neocomplete.vim/issues/39 + +A: neocomplete does not support eclim. You should use +|g:neocomplete#force_omni_input_patterns| instead of +|g:neocomplete#sources#omni#input_patterns|. +> + if !exists('g:neocomplete#force_omni_input_patterns') + let g:neocomplete#force_omni_input_patterns = {} + endif + g:neocomplete#force_omni_input_patterns.java = + \ \'\%(\h\w*\|)\)\.\w* + +Q: I want to get quiet messages in auto completion. +https://github.com/Shougo/neocomplcache.vim/issues/448 + +A: Before 7.4 patch 314 it was not possible because of vim's default +behavior. If you are using a recent version of vim you can disable the +messages through the 'shortmess' option. +> + if has("patch-7.4.314") + set shortmess+=c + endif +< +For earlier vim versions you can try to hide them by using the settings below +> + autocmd VimEnter * + \ highlight ModeMsg guifg=bg guibg=bg | highlight WarningMsg guifg=bg +< + +Q: I don't want to complete too long words. +https://github.com/Shougo/neocomplete.vim/issues/69 + +A: You can use |g:neocomplete#sources#buffer#max_keyword_width|. + +Q: neocomplete will change external completeopt value(longest). +https://github.com/Shougo/neocomplcache.vim/issues/453 + +A: It is feature. Because "longest" completeopt conflicts with auto +completion. To use "longest" option, you must disable auto completion. +"longest" is good feature. But it is for manual completion only. + +Q: autoclose conflicts with neocomplete. +https://github.com/Shougo/neocomplcache.vim/issues/350 + +A: It is autoclose mappings problem. I cannot fix it. You should use +auto-pairs plugin instead of it. +https://github.com/jiangmiao/auto-pairs + +Q: I want to complete by Erlang omnifunc. +https://github.com/vim-erlang/vim-erlang-omnicomplete + +A: > + if !exists('g:neocomplete#force_omni_input_patterns') + let g:neocomplete#force_omni_input_patterns = {} + endif + g:neocomplete#force_omni_input_patterns.erlang = + \ '\<[[:digit:][:alnum:]_-]\+:[[:digit:][:alnum:]_-]*' + +Q: I want to look selected function's arguments in neocomplete. But I don't +like preview window feature. +https://github.com/Shougo/neocomplete.vim/issues/120 + +A: You can do it by |echodoc|. +http://github.com/Shougo/echodoc.vim +Note: This feature is available from neocomplete candidates only. +You cannot get it from |g:neocomplete#force_omni_input_patterns|. + +Q: In ||g:neocomplete#force_omni_input_patterns|, +|g:neocomplete#enable_auto_select| feature is not work. +https://github.com/Shougo/neocomplete.vim/issues/139 + +A: It is feature. See |g:neocomplete#force_omni_input_patterns| documentation. + +Q: I want to disable all sources by default. + +A: > + call neocomplete#custom#source('_', 'disabled', 1) + +Q: I want to disable candidates abbr in tag source. +https://github.com/Shougo/neocomplete.vim/issues/158 + +A: > + call neocomplete#custom#source('tags', 'converters', + \ ['converter_remove_overlap', 'converter_remove_last_paren', + \ 'converter_delimiter', 'converter_disable_abbr', 'converter_abbr']) + +Q: does not work. +https://github.com/Shougo/neocomplete.vim/issues/305 + +A: It is feature. +You must use |neocomplete#start_manual_complete()| instead of . + +Q: My mapping never works. + +A: https://github.com/Shougo/neocomplete.vim/issues/334 +Note: It is fixed in Vim 7.4.653. + +============================================================================== +vim:tw=78:ts=8:ft=help:norl:noet:fen:noet: diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete.vim new file mode 100644 index 0000000..1c17170 --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete.vim @@ -0,0 +1,63 @@ +"============================================================================= +" FILE: neocomplete.vim +" AUTHOR: Shougo Matsushita +" License: MIT license {{{ +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be included +" in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +" }}} +"============================================================================= + +if exists('g:loaded_neocomplete') + finish +endif +let g:loaded_neocomplete = 1 + +let s:save_cpo = &cpo +set cpo&vim + +command! -nargs=0 -bar NeoCompleteEnable + \ call neocomplete#init#enable() +command! -nargs=0 -bar NeoCompleteDisable + \ call neocomplete#init#disable() +command! -nargs=0 -bar NeoCompleteLock + \ call neocomplete#commands#_lock() +command! -nargs=0 -bar NeoCompleteUnlock + \ call neocomplete#commands#_unlock() +command! -nargs=0 -bar NeoCompleteToggle + \ call neocomplete#commands#_toggle_lock() +command! -nargs=1 -bar -complete=filetype NeoCompleteSetFileType + \ call neocomplete#commands#_set_file_type() +command! -nargs=0 -bar NeoCompleteClean + \ call neocomplete#commands#_clean() + +" Global options definition. "{{{ +let g:neocomplete#enable_debug = + \ get(g:, 'neocomplete#enable_debug', 0) +if get(g:, 'neocomplete#enable_at_startup', 0) + augroup neocomplete + " Enable startup. + autocmd CursorHold,InsertEnter + \ * call neocomplete#init#enable() + augroup END +endif"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete/buffer.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete/buffer.vim new file mode 100644 index 0000000..db3da89 --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete/buffer.vim @@ -0,0 +1,24 @@ +"============================================================================= +" FILE: buffer.vim +" AUTHOR: Shougo Matsushita +"============================================================================= + +if exists('g:loaded_neocomplete_buffer') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +" Add commands. "{{{ +command! -nargs=? -complete=file -bar + \ NeoCompleteBufferMakeCache + \ call neocomplete#sources#buffer#make_cache() +"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +let g:loaded_neocomplete_buffer = 1 + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete/dictionary.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete/dictionary.vim new file mode 100644 index 0000000..39d6294 --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete/dictionary.vim @@ -0,0 +1,24 @@ +"============================================================================= +" FILE: dictionary.vim +" AUTHOR: Shougo Matsushita +"============================================================================= + +if exists('g:loaded_neocomplete_dictionary') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +" Add commands. "{{{ +command! -nargs=? -complete=customlist,neocomplete#filetype_complete + \ NeoCompleteDictionaryMakeCache + \ call neocomplete#sources#dictionary#remake_cache() +"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +let g:loaded_neocomplete_dictionary = 1 + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete/include.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete/include.vim new file mode 100644 index 0000000..860d96d --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete/include.vim @@ -0,0 +1,23 @@ +"============================================================================= +" FILE: include.vim +" AUTHOR: Shougo Matsushita +"============================================================================= + +if exists('g:loaded_neocomplete_include') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +" Add commands. "{{{ +command! -nargs=? -complete=buffer NeoCompleteIncludeMakeCache + \ call neocomplete#sources#include#make_cache() +"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +let g:loaded_neocomplete_include = 1 + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete/syntax.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete/syntax.vim new file mode 100644 index 0000000..aadc755 --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete/syntax.vim @@ -0,0 +1,24 @@ +"============================================================================= +" FILE: syntax.vim +" AUTHOR: Shougo Matsushita +"============================================================================= + +if exists('g:loaded_neocomplete_syntax') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +" Add commands. "{{{ +command! -nargs=? -complete=customlist,neocomplete#filetype_complete + \ NeoCompleteSyntaxMakeCache + \ call neocomplete#sources#syntax#remake_cache() +"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +let g:loaded_neocomplete_syntax = 1 + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/plugin/neocomplete/tag.vim b/.vim/bundle/neocomplete.vim/plugin/neocomplete/tag.vim new file mode 100644 index 0000000..ff58ff3 --- /dev/null +++ b/.vim/bundle/neocomplete.vim/plugin/neocomplete/tag.vim @@ -0,0 +1,24 @@ +"============================================================================= +" FILE: tag.vim +" AUTHOR: Shougo Matsushita +"============================================================================= + +if exists('g:loaded_neocomplete_tag') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +" Add commands. "{{{ +command! -nargs=0 -bar + \ NeoCompleteTagMakeCache + \ call neocomplete#sources#tag#make_cache(1) +"}}} + +let &cpo = s:save_cpo +unlet s:save_cpo + +let g:loaded_neocomplete_tag = 1 + +" vim: foldmethod=marker diff --git a/.vim/bundle/neocomplete.vim/test/neocomplete.vim b/.vim/bundle/neocomplete.vim/test/neocomplete.vim new file mode 100644 index 0000000..dc3255d --- /dev/null +++ b/.vim/bundle/neocomplete.vim/test/neocomplete.vim @@ -0,0 +1,76 @@ + +let s:suite = themis#suite('parser') +let s:assert = themis#helper('assert') + +function! s:suite.escape() + call s:assert.equals( + \ neocomplete#filters#fuzzy_escape('abc'), 'a.*b.*c.*') + call s:assert.equals( + \ neocomplete#filters#fuzzy_escape('%a%b%c'), '%%a.*%%b.*%%c.*') + call s:assert.equals( + \ neocomplete#filters#fuzzy_escape('%[ab]c'), '%%%[a.*b.*%]c.*') + call s:assert.equals( + \ neocomplete#filters#fuzzy_escape('.abc'), '%.a.*b.*c.*') +endfunction + +function! s:suite.sort() + let candidates = [] + for i in range(1, 1000) + call add(candidates, { 'word' : i, 'rank' : i }) + endfor + function! CompareRank(i1, i2) + let diff = (get(a:i2, 'rank', 0) - get(a:i1, 'rank', 0)) + return (diff != 0) ? diff : (len(a:i1.word) < len(a:i2.word)) ? 1 : -1 + endfunction" + + " Benchmark. + let start = reltime() + call sort(copy(candidates), 'CompareRank') + echomsg reltimestr(reltime(start)) + let start = reltime() + call neocomplete#filters#sorter_rank#define().filter( + \ {'candidates' : copy(candidates), 'input' : '' }) + echomsg reltimestr(reltime(start)) + + call s:assert.equals(sort(copy(candidates), 'CompareRank'), + \ neocomplete#filters#sorter_rank#define().filter( + \ {'candidates' : copy(candidates), 'input' : '' })) +endfunction + +function! s:suite.fuzzy() + call s:assert.equals(neocomplete#filters#matcher_fuzzy#define().filter( + \ {'complete_str' : 'ae', 'candidates' : ['~/~']}), []) +endfunction + +function! s:suite.overlap() + call s:assert.equals(neocomplete#filters#converter_remove_overlap# + \length('foo bar', 'bar baz'), 3) + call s:assert.equals(neocomplete#filters#converter_remove_overlap# + \length('foobar', 'barbaz'), 3) + call s:assert.equals(neocomplete#filters#converter_remove_overlap# + \length('foob', 'baz'), 1) + call s:assert.equals(neocomplete#filters#converter_remove_overlap# + \length('foobar', 'foobar'), 6) + call s:assert.equals(neocomplete#filters#converter_remove_overlap# + \length('теÑÑ‚', 'ÑÑ‚'), len('ÑÑ‚')) +endfunction + +function! s:suite.syntax() + call s:assert.equals(sort(neocomplete#sources#syntax#_split_pattern( + \ '\(d\|e\|f\)', '')), + \ ['d', 'e', 'f']) + call s:assert.equals(sort(neocomplete#sources#syntax#_split_pattern( + \ '\(a\|b\)-c', '')), + \ ['a-c', 'b-c']) + call s:assert.equals(sort(neocomplete#sources#syntax#_split_pattern( + \ 'c\(d\|e\|f\)', '')), + \ ['cd', 'ce', 'cf']) + call s:assert.equals(sort(neocomplete#sources#syntax#_split_pattern( + \ '\(a\|b\)c\(d\|e\|f\)', '')), + \ ['acd', 'ace', 'acf', 'bcd', 'bce', 'bcf']) + call s:assert.equals(sort(neocomplete#sources#syntax#_split_pattern( + \ '\\\%(dump\|end\|jobname\)', '')), + \ ['\dump', '\end', '\jobname']) +endfunction + +" vim:foldmethod=marker:fen: diff --git a/.vim/bundle/tagbar/.gitattributes b/.vim/bundle/tagbar/.gitattributes new file mode 100644 index 0000000..3b1db11 --- /dev/null +++ b/.vim/bundle/tagbar/.gitattributes @@ -0,0 +1,4 @@ +.gitignore export-ignore +.gitattributes export-ignore +README export-ignore +.info export-ignore diff --git a/.vim/bundle/tagbar/.gitignore b/.vim/bundle/tagbar/.gitignore new file mode 100644 index 0000000..0a56e3f --- /dev/null +++ b/.vim/bundle/tagbar/.gitignore @@ -0,0 +1 @@ +/doc/tags diff --git a/.vim/bundle/tagbar/.info b/.vim/bundle/tagbar/.info new file mode 100644 index 0000000..f4d9137 --- /dev/null +++ b/.vim/bundle/tagbar/.info @@ -0,0 +1,2 @@ +tagbar +3465 diff --git a/.vim/bundle/tagbar/LICENSE b/.vim/bundle/tagbar/LICENSE new file mode 100644 index 0000000..5ae1a75 --- /dev/null +++ b/.vim/bundle/tagbar/LICENSE @@ -0,0 +1,82 @@ +TAGBAR LICENSE + +This is the normal Vim license (see ':h license' in Vim) with the necessary +replacements for the project and maintainer information. + +I) There are no restrictions on distributing unmodified copies of Tagbar + except that they must include this license text. You can also distribute + unmodified parts of Tagbar, likewise unrestricted except that they must + include this license text. You are also allowed to include executables + that you made from the unmodified Tagbar sources, plus your own usage + examples and scripts. + +II) It is allowed to distribute a modified (or extended) version of Tagbar, + including executables and/or source code, when the following four + conditions are met: + 1) This license text must be included unmodified. + 2) The modified Tagbar must be distributed in one of the following five ways: + a) If you make changes to Tagbar yourself, you must clearly describe in + the distribution how to contact you. When the maintainer asks you + (in any way) for a copy of the modified Tagbar you distributed, you + must make your changes, including source code, available to the + maintainer without fee. The maintainer reserves the right to + include your changes in the official version of Tagbar. What the + maintainer will do with your changes and under what license they + will be distributed is negotiable. If there has been no negotiation + then this license, or a later version, also applies to your changes. + The current maintainer is Jan Larres . If this + changes it will be announced in appropriate places (most likely + majutsushi.github.io/tagbar and/or github.com/majutsushi/tagbar). + When it is completely impossible to contact the maintainer, the + obligation to send him your changes ceases. Once the maintainer has + confirmed that he has received your changes they will not have to be + sent again. + b) If you have received a modified Tagbar that was distributed as + mentioned under a) you are allowed to further distribute it + unmodified, as mentioned at I). If you make additional changes the + text under a) applies to those changes. + c) Provide all the changes, including source code, with every copy of + the modified Tagbar you distribute. This may be done in the form of + a context diff. You can choose what license to use for new code you + add. The changes and their license must not restrict others from + making their own changes to the official version of Tagbar. + d) When you have a modified Tagbar which includes changes as mentioned + under c), you can distribute it without the source code for the + changes if the following three conditions are met: + - The license that applies to the changes permits you to distribute + the changes to the Tagbar maintainer without fee or restriction, and + permits the Tagbar maintainer to include the changes in the official + version of Tagbar without fee or restriction. + - You keep the changes for at least three years after last + distributing the corresponding modified Tagbar. When the + maintainer or someone who you distributed the modified Tagbar to + asks you (in any way) for the changes within this period, you must + make them available to him. + - You clearly describe in the distribution how to contact you. This + contact information must remain valid for at least three years + after last distributing the corresponding modified Tagbar, or as + long as possible. + e) When the GNU General Public License (GPL) applies to the changes, + you can distribute the modified Tagbar under the GNU GPL version 2 + or any later version. + 3) A message must be added, at least in the documentation, such that the + user of the modified Tagbar is able to see that it was modified. When + distributing as mentioned under 2)e) adding the message is only + required for as far as this does not conflict with the license used for + the changes. + 4) The contact information as required under 2)a) and 2)d) must not be + removed or changed, except that the person himself can make + corrections. + +III) If you distribute a modified version of Tagbar, you are encouraged to use + the Tagbar license for your changes and make them available to the + maintainer, including the source code. The preferred way to do this is + by e-mail or by uploading the files to a server and e-mailing the URL. If + the number of changes is small (e.g., a modified Makefile) e-mailing a + context diff will do. The e-mail address to be used is + + +IV) It is not allowed to remove this license from the distribution of the + Tagbar sources, parts of it or from a modified version. You may use this + license for previous Tagbar releases instead of the license that they + came with, at your option. diff --git a/.vim/bundle/tagbar/README.md b/.vim/bundle/tagbar/README.md new file mode 100644 index 0000000..eceddbe --- /dev/null +++ b/.vim/bundle/tagbar/README.md @@ -0,0 +1,89 @@ +# Tagbar: a class outline viewer for Vim + +## What Tagbar is + +Tagbar is a Vim plugin that provides an easy way to browse the tags of the +current file and get an overview of its structure. It does this by creating a +sidebar that displays the ctags-generated tags of the current file, ordered by +their scope. This means that for example methods in C++ are displayed under +the class they are defined in. + +## What Tagbar is not + +Tagbar is not a general-purpose tool for managing `tags` files. It only +creates the tags it needs on-the-fly in-memory without creating any files. +`tags` file management is provided by other plugins, like for example +[easytags](https://github.com/xolox/vim-easytags). + +## Dependencies + +[Vim 7.0](http://www.vim.org/) (But see note below) +[Exuberant ctags 5.5](http://ctags.sourceforge.net/) + +## Installation + +Extract the archive or clone the repository into a directory in your +`'runtimepath'`, or use a plugin manager of your choice like +[pathogen](https://github.com/tpope/vim-pathogen). Don't forget to run +`:helptags` if your plugin manager doesn't do it for you so you can access the +documentation with `:help tagbar`. + +Note: Vim versions < 7.0.167 have a bug that prevents Tagbar from working. If +you are affected by this use this alternate Tagbar download instead: +[zip](https://github.com/majutsushi/tagbar/zipball/70fix). It is on par with +version 2.2 but probably won't be updated after that due to the amount of +changes required. + +If the ctags executable is not installed in one of the directories in your +`$PATH` environment variable you have to set the `g:tagbar_ctags_bin` +variable, see the documentation for more info. + +## Quickstart + +Put something like the following into your ~/.vimrc: + +```vim +nmap :TagbarToggle +``` + +If you do this the F8 key will toggle the Tagbar window. You can of course use +any shortcut you want. For more flexible ways to open and close the window +(and the rest of the functionality) see the documentation. + +## Support for additional filetypes + +For filetypes that are not supported by Exuberant Ctags check out [the +wiki](https://github.com/majutsushi/tagbar/wiki) to see whether other projects +offer support for them and how to use them. Please add any other +projects/configurations that you find or create yourself so that others can +benefit from them, too. + +## Note: If the file structure display is wrong + +If you notice that there are some errors in the way your file's structure is +displayed in Tagbar, please make sure that the bug is actually in Tagbar +before you report an issue. Since Tagbar uses +[exuberant-ctags](http://ctags.sourceforge.net/) and compatible programs to do +the actual file parsing, it is likely that the bug is actually in the program +responsible for that filetype instead. + +There is an example in `:h tagbar-issues` about how to run ctags manually so +you can determine where the bug actually is. If the bug is actually in ctags, +please report it on their website instead, as there is nothing I can do about +it in Tagbar. Thank you! + +You can also have a look at [ctags bugs that have previously been filed +against Tagbar](https://github.com/majutsushi/tagbar/issues?labels=ctags-bug&page=1&state=closed). + +## Screenshots + +![screenshot1](https://i.imgur.com/Sf9Ls2r.png) +![screenshot2](https://i.imgur.com/n4bpPv3.png) + +## License + +Vim license, see LICENSE + +## Maintainer + +Jan Larres <[jan@majutsushi.net](mailto:jan@majutsushi.net)> diff --git a/.vim/bundle/tagbar/autoload/tagbar.vim b/.vim/bundle/tagbar/autoload/tagbar.vim new file mode 100644 index 0000000..34e3f48 --- /dev/null +++ b/.vim/bundle/tagbar/autoload/tagbar.vim @@ -0,0 +1,4268 @@ +" ============================================================================ +" File: tagbar.vim +" Description: List the current file's tags in a sidebar, ordered by class etc +" Author: Jan Larres +" Licence: Vim licence +" Website: http://majutsushi.github.com/tagbar/ +" Version: 2.6.1 +" Note: This plugin was heavily inspired by the 'Taglist' plugin by +" Yegappan Lakshmanan and uses a small amount of code from it. +" +" Original taglist copyright notice: +" Permission is hereby granted to use and distribute this code, +" with or without modifications, provided that this copyright +" notice is copied with it. Like anything else that's free, +" taglist.vim is provided *as is* and comes with no warranty of +" any kind, either expressed or implied. In no event will the +" copyright holder be liable for any damamges resulting from the +" use of this software. +" ============================================================================ + +scriptencoding utf-8 + +" Initialization {{{1 + +" If another plugin calls an autoloaded Tagbar function on startup before the +" plugin/tagbar.vim file got loaded, load it explicitly +if exists(':Tagbar') == 0 + runtime plugin/tagbar.vim +endif + +if exists(':Tagbar') == 0 + echomsg 'Tagbar: Could not load plugin code, check your runtimepath!' + finish +endif + +" Basic init {{{2 + +redir => s:ftype_out +silent filetype +redir END +if s:ftype_out !~# 'detection:ON' + echomsg 'Tagbar: Filetype detection is turned off, skipping plugin' + unlet s:ftype_out + finish +endif +unlet s:ftype_out + +let s:icon_closed = g:tagbar_iconchars[0] +let s:icon_open = g:tagbar_iconchars[1] + +let s:type_init_done = 0 +let s:autocommands_done = 0 +let s:statusline_in_use = 0 + +" 0: not checked yet; 1: checked and found; 2: checked and not found +let s:checked_ctags = 0 +let s:checked_ctags_types = 0 +let s:ctags_types = {} + +let s:new_window = 1 +let s:is_maximized = 0 +let s:winrestcmd = '' +let s:short_help = 1 +let s:nearby_disabled = 0 +let s:paused = 0 +let s:pwin_by_tagbar = 0 + +let s:window_expanded = 0 +let s:expand_bufnr = -1 +let s:window_pos = { + \ 'pre' : { 'x' : 0, 'y' : 0 }, + \ 'post' : { 'x' : 0, 'y' : 0 } +\} + +" Script-local variable needed since compare functions can't +" take extra arguments +let s:compare_typeinfo = {} + +let s:visibility_symbols = { + \ 'public' : '+', + \ 'protected' : '#', + \ 'private' : '-' +\ } + +let g:loaded_tagbar = 1 + +let s:last_highlight_tline = 0 +let s:debug = 0 +let s:debug_file = '' + +let s:warnings = { + \ 'type': [], + \ 'encoding': 0 +\ } + +" s:Init() {{{2 +function! s:Init(silent) abort + if s:checked_ctags == 2 && a:silent + return 0 + elseif s:checked_ctags != 1 + if !s:CheckForExCtags(a:silent) + return 0 + endif + endif + + if !s:checked_ctags_types + call s:GetSupportedFiletypes() + endif + + if !s:type_init_done + call s:InitTypes() + endif + + if !s:autocommands_done + call s:CreateAutocommands() + call s:AutoUpdate(fnamemodify(expand('%'), ':p'), 0) + endif + + return 1 +endfunction + +" s:InitTypes() {{{2 +function! s:InitTypes() abort + call s:debug('Initializing types') + + let s:known_types = {} + + " Ant {{{3 + let type_ant = s:TypeInfo.New() + let type_ant.ctagstype = 'ant' + let type_ant.kinds = [ + \ {'short' : 'p', 'long' : 'projects', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'targets', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.ant = type_ant + " Asm {{{3 + let type_asm = s:TypeInfo.New() + let type_asm.ctagstype = 'asm' + let type_asm.kinds = [ + \ {'short' : 'm', 'long' : 'macros', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'd', 'long' : 'defines', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.asm = type_asm + " ASP {{{3 + let type_aspvbs = s:TypeInfo.New() + let type_aspvbs.ctagstype = 'asp' + let type_aspvbs.kinds = [ + \ {'short' : 'd', 'long' : 'constants', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.aspvbs = type_aspvbs + " Awk {{{3 + let type_awk = s:TypeInfo.New() + let type_awk.ctagstype = 'awk' + let type_awk.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.awk = type_awk + " Basic {{{3 + let type_basic = s:TypeInfo.New() + let type_basic.ctagstype = 'basic' + let type_basic.kinds = [ + \ {'short' : 'c', 'long' : 'constants', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'g', 'long' : 'enumerations', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.basic = type_basic + " BETA {{{3 + let type_beta = s:TypeInfo.New() + let type_beta.ctagstype = 'beta' + let type_beta.kinds = [ + \ {'short' : 'f', 'long' : 'fragments', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'slots', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'patterns', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.beta = type_beta + " C {{{3 + let type_c = s:TypeInfo.New() + let type_c.ctagstype = 'c' + let type_c.kinds = [ + \ {'short' : 'd', 'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'p', 'long' : 'prototypes', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'g', 'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ {'short' : 's', 'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'u', 'long' : 'unions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'members', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let type_c.sro = '::' + let type_c.kind2scope = { + \ 'g' : 'enum', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + let type_c.scope2kind = { + \ 'enum' : 'g', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + let s:known_types.c = type_c + " C++ {{{3 + let type_cpp = s:TypeInfo.New() + let type_cpp.ctagstype = 'c++' + let type_cpp.kinds = [ + \ {'short' : 'd', 'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'p', 'long' : 'prototypes', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'g', 'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'u', 'long' : 'unions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'members', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ ] + let type_cpp.sro = '::' + let type_cpp.kind2scope = { + \ 'g' : 'enum', + \ 'n' : 'namespace', + \ 'c' : 'class', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + let type_cpp.scope2kind = { + \ 'enum' : 'g', + \ 'namespace' : 'n', + \ 'class' : 'c', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + let s:known_types.cpp = type_cpp + let s:known_types.cuda = type_cpp + " C# {{{3 + let type_cs = s:TypeInfo.New() + let type_cs.ctagstype = 'c#' + let type_cs.kinds = [ + \ {'short' : 'd', 'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'fields', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'g', 'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'E', 'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'properties', 'fold' : 0, 'stl' : 1} + \ ] + let type_cs.sro = '.' + let type_cs.kind2scope = { + \ 'n' : 'namespace', + \ 'i' : 'interface', + \ 'c' : 'class', + \ 's' : 'struct', + \ 'g' : 'enum' + \ } + let type_cs.scope2kind = { + \ 'namespace' : 'n', + \ 'interface' : 'i', + \ 'class' : 'c', + \ 'struct' : 's', + \ 'enum' : 'g' + \ } + let s:known_types.cs = type_cs + " COBOL {{{3 + let type_cobol = s:TypeInfo.New() + let type_cobol.ctagstype = 'cobol' + let type_cobol.kinds = [ + \ {'short' : 'd', 'long' : 'data items', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'file descriptions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'g', 'long' : 'group items', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'paragraphs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'P', 'long' : 'program ids', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'sections', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.cobol = type_cobol + " DOS Batch {{{3 + let type_dosbatch = s:TypeInfo.New() + let type_dosbatch.ctagstype = 'dosbatch' + let type_dosbatch.kinds = [ + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.dosbatch = type_dosbatch + " Eiffel {{{3 + let type_eiffel = s:TypeInfo.New() + let type_eiffel.ctagstype = 'eiffel' + let type_eiffel.kinds = [ + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'features', 'fold' : 0, 'stl' : 1} + \ ] + let type_eiffel.sro = '.' " Not sure, is nesting even possible? + let type_eiffel.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'feature' + \ } + let type_eiffel.scope2kind = { + \ 'class' : 'c', + \ 'feature' : 'f' + \ } + let s:known_types.eiffel = type_eiffel + " Erlang {{{3 + let type_erlang = s:TypeInfo.New() + let type_erlang.ctagstype = 'erlang' + let type_erlang.kinds = [ + \ {'short' : 'm', 'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'd', 'long' : 'macro definitions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'r', 'long' : 'record definitions', 'fold' : 0, 'stl' : 1} + \ ] + let type_erlang.sro = '.' " Not sure, is nesting even possible? + let type_erlang.kind2scope = { + \ 'm' : 'module' + \ } + let type_erlang.scope2kind = { + \ 'module' : 'm' + \ } + let s:known_types.erlang = type_erlang + " Flex {{{3 + " Vim doesn't support Flex out of the box, this is based on rough + " guesses and probably requires + " http://www.vim.org/scripts/script.php?script_id=2909 + " Improvements welcome! + let type_as = s:TypeInfo.New() + let type_as.ctagstype = 'flex' + let type_as.kinds = [ + \ {'short' : 'v', 'long' : 'global variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'properties', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'x', 'long' : 'mxtags', 'fold' : 0, 'stl' : 0} + \ ] + let type_as.sro = '.' + let type_as.kind2scope = { + \ 'c' : 'class' + \ } + let type_as.scope2kind = { + \ 'class' : 'c' + \ } + let s:known_types.mxml = type_as + let s:known_types.actionscript = type_as + " Fortran {{{3 + let type_fortran = s:TypeInfo.New() + let type_fortran.ctagstype = 'fortran' + let type_fortran.kinds = [ + \ {'short' : 'm', 'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'programs', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'k', 'long' : 'components', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'derived types and structures', 'fold' : 0, + \ 'stl' : 1}, + \ {'short' : 'c', 'long' : 'common blocks', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'b', 'long' : 'block data', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'e', 'long' : 'entry points', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'n', 'long' : 'namelists', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ ] + let type_fortran.sro = '.' " Not sure, is nesting even possible? + let type_fortran.kind2scope = { + \ 'm' : 'module', + \ 'p' : 'program', + \ 'f' : 'function', + \ 's' : 'subroutine' + \ } + let type_fortran.scope2kind = { + \ 'module' : 'm', + \ 'program' : 'p', + \ 'function' : 'f', + \ 'subroutine' : 's' + \ } + let s:known_types.fortran = type_fortran + " HTML {{{3 + let type_html = s:TypeInfo.New() + let type_html.ctagstype = 'html' + let type_html.kinds = [ + \ {'short' : 'f', 'long' : 'JavaScript funtions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'a', 'long' : 'named anchors', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.html = type_html + " Java {{{3 + let type_java = s:TypeInfo.New() + let type_java.ctagstype = 'java' + let type_java.kinds = [ + \ {'short' : 'p', 'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'fields', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'g', 'long' : 'enum types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'enum constants', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'methods', 'fold' : 0, 'stl' : 1} + \ ] + let type_java.sro = '.' + let type_java.kind2scope = { + \ 'g' : 'enum', + \ 'i' : 'interface', + \ 'c' : 'class' + \ } + let type_java.scope2kind = { + \ 'enum' : 'g', + \ 'interface' : 'i', + \ 'class' : 'c' + \ } + let s:known_types.java = type_java + " JavaScript {{{3 + " jsctags/doctorjs will be used if available. + let type_javascript = s:TypeInfo.New() + let type_javascript.ctagstype = 'javascript' + let jsctags = s:CheckFTCtags('jsctags', 'javascript') + if jsctags != '' + let type_javascript.kinds = [ + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let type_javascript.sro = '.' + let type_javascript.kind2scope = { + \ 'v' : 'namespace', + \ 'f' : 'namespace' + \ } + let type_javascript.scope2kind = { + \ 'namespace' : 'v' + \ } + let type_javascript.ctagsbin = jsctags + let type_javascript.ctagsargs = '-f -' + else + let type_javascript.kinds = [ + \ {'short': 'v', 'long': 'global variables', 'fold': 0, 'stl': 0}, + \ {'short': 'c', 'long': 'classes', 'fold': 0, 'stl': 1}, + \ {'short': 'p', 'long': 'properties', 'fold': 0, 'stl': 0}, + \ {'short': 'm', 'long': 'methods', 'fold': 0, 'stl': 1}, + \ {'short': 'f', 'long': 'functions', 'fold': 0, 'stl': 1}, + \ ] + let type_javascript.sro = '.' + let type_javascript.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'function', + \ 'm' : 'method', + \ 'p' : 'property', + \ } + let type_javascript.scope2kind = { + \ 'class' : 'c', + \ 'function' : 'f', + \ } + endif + let s:known_types.javascript = type_javascript + " Lisp {{{3 + let type_lisp = s:TypeInfo.New() + let type_lisp.ctagstype = 'lisp' + let type_lisp.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.lisp = type_lisp + let s:known_types.clojure = type_lisp + " Lua {{{3 + let type_lua = s:TypeInfo.New() + let type_lua.ctagstype = 'lua' + let type_lua.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.lua = type_lua + " Make {{{3 + let type_make = s:TypeInfo.New() + let type_make.ctagstype = 'make' + let type_make.kinds = [ + \ {'short' : 'm', 'long' : 'macros', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.make = type_make + " Matlab {{{3 + let type_matlab = s:TypeInfo.New() + let type_matlab.ctagstype = 'matlab' + let type_matlab.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.matlab = type_matlab + " Ocaml {{{3 + let type_ocaml = s:TypeInfo.New() + let type_ocaml.ctagstype = 'ocaml' + let type_ocaml.kinds = [ + \ {'short' : 'M', 'long' : 'modules or functors', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'global variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'C', 'long' : 'constructors', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'exceptions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'type names', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'r', 'long' : 'structure fields', 'fold' : 0, 'stl' : 0} + \ ] + let type_ocaml.sro = '.' " Not sure, is nesting even possible? + let type_ocaml.kind2scope = { + \ 'M' : 'Module', + \ 'c' : 'class', + \ 't' : 'type' + \ } + let type_ocaml.scope2kind = { + \ 'Module' : 'M', + \ 'class' : 'c', + \ 'type' : 't' + \ } + let s:known_types.ocaml = type_ocaml + " Pascal {{{3 + let type_pascal = s:TypeInfo.New() + let type_pascal.ctagstype = 'pascal' + let type_pascal.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.pascal = type_pascal + " Perl {{{3 + let type_perl = s:TypeInfo.New() + let type_perl.ctagstype = 'perl' + let type_perl.kinds = [ + \ {'short' : 'p', 'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'formats', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.perl = type_perl + " PHP {{{3 + let type_php = s:TypeInfo.New() + let type_php.ctagstype = 'php' + let type_php.kinds = [ + \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'd', 'long' : 'constant definitions', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'j', 'long' : 'javascript functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.php = type_php + " Python {{{3 + let type_python = s:TypeInfo.New() + let type_python.ctagstype = 'python' + let type_python.kinds = [ + \ {'short' : 'i', 'long' : 'imports', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'members', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ ] + let type_python.sro = '.' + let type_python.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'function', + \ 'm' : 'function' + \ } + let type_python.scope2kind = { + \ 'class' : 'c', + \ 'function' : 'f' + \ } + let s:known_types.python = type_python + let s:known_types.pyrex = type_python + let s:known_types.cython = type_python + " REXX {{{3 + let type_rexx = s:TypeInfo.New() + let type_rexx.ctagstype = 'rexx' + let type_rexx.kinds = [ + \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.rexx = type_rexx + " Ruby {{{3 + let type_ruby = s:TypeInfo.New() + let type_ruby.ctagstype = 'ruby' + let type_ruby.kinds = [ + \ {'short' : 'm', 'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'F', 'long' : 'singleton methods', 'fold' : 0, 'stl' : 1} + \ ] + let type_ruby.sro = '.' + let type_ruby.kind2scope = { + \ 'c' : 'class', + \ 'm' : 'class' + \ } + let type_ruby.scope2kind = { + \ 'class' : 'c' + \ } + let s:known_types.ruby = type_ruby + " Scheme {{{3 + let type_scheme = s:TypeInfo.New() + let type_scheme.ctagstype = 'scheme' + let type_scheme.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'sets', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.scheme = type_scheme + let s:known_types.racket = type_scheme + " Shell script {{{3 + let type_sh = s:TypeInfo.New() + let type_sh.ctagstype = 'sh' + let type_sh.kinds = [ + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.sh = type_sh + let s:known_types.csh = type_sh + let s:known_types.zsh = type_sh + " SLang {{{3 + let type_slang = s:TypeInfo.New() + let type_slang.ctagstype = 'slang' + let type_slang.kinds = [ + \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.slang = type_slang + " SML {{{3 + let type_sml = s:TypeInfo.New() + let type_sml.ctagstype = 'sml' + let type_sml.kinds = [ + \ {'short' : 'e', 'long' : 'exception declarations', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'function definitions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'functor definitions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'signature declarations', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'r', 'long' : 'structure declarations', 'fold' : 0, 'stl' : 0}, + \ {'short' : 't', 'long' : 'type definitions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'value bindings', 'fold' : 0, 'stl' : 0} + \ ] + let s:known_types.sml = type_sml + " SQL {{{3 + " The SQL ctags parser seems to be buggy for me, so this just uses the + " normal kinds even though scopes should be available. Improvements + " welcome! + let type_sql = s:TypeInfo.New() + let type_sql.ctagstype = 'sql' + let type_sql.kinds = [ + \ {'short' : 'P', 'long' : 'packages', 'fold' : 1, 'stl' : 1}, + \ {'short' : 'd', 'long' : 'prototypes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'cursors', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'F', 'long' : 'record fields', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'L', 'long' : 'block label', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'subtypes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'tables', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'T', 'long' : 'triggers', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'i', 'long' : 'indexes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'U', 'long' : 'publications', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'R', 'long' : 'services', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'D', 'long' : 'domains', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'V', 'long' : 'views', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'n', 'long' : 'synonyms', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'x', 'long' : 'MobiLink Table Scripts', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'y', 'long' : 'MobiLink Conn Scripts', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'z', 'long' : 'MobiLink Properties', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.sql = type_sql + " Tcl {{{3 + let type_tcl = s:TypeInfo.New() + let type_tcl.ctagstype = 'tcl' + let type_tcl.kinds = [ + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.tcl = type_tcl + " LaTeX {{{3 + let type_tex = s:TypeInfo.New() + let type_tex.ctagstype = 'tex' + let type_tex.kinds = [ + \ {'short' : 'i', 'long' : 'includes', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'p', 'long' : 'parts', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'chapters', 'fold' : 0, 'stl' : 1}, + \ {'short' : 's', 'long' : 'sections', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'u', 'long' : 'subsections', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'b', 'long' : 'subsubsections', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'P', 'long' : 'paragraphs', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'G', 'long' : 'subparagraphs', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 0} + \ ] + let type_tex.sro = '""' + let type_tex.kind2scope = { + \ 'p' : 'part', + \ 'c' : 'chapter', + \ 's' : 'section', + \ 'u' : 'subsection', + \ 'b' : 'subsubsection' + \ } + let type_tex.scope2kind = { + \ 'part' : 'p', + \ 'chapter' : 'c', + \ 'section' : 's', + \ 'subsection' : 'u', + \ 'subsubsection' : 'b' + \ } + let type_tex.sort = 0 + let s:known_types.tex = type_tex + " Vala {{{3 + " Vala is supported by the ctags fork provided by Anjuta, so only add the + " type if the fork is used to prevent error messages otherwise + if has_key(s:ctags_types, 'vala') || executable('anjuta-tags') + let type_vala = s:TypeInfo.New() + let type_vala.ctagstype = 'vala' + let type_vala.kinds = [ + \ {'short' : 'e', 'long' : 'Enumerations', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'Enumeration values', 'fold' : 0, 'stl' : 0}, + \ {'short' : 's', 'long' : 'Structures', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'i', 'long' : 'Interfaces', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'd', 'long' : 'Delegates', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'Classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'Properties', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'Fields', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'm', 'long' : 'Methods', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'E', 'long' : 'Error domains', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'r', 'long' : 'Error codes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'S', 'long' : 'Signals', 'fold' : 0, 'stl' : 1} + \ ] + let type_vala.sro = '.' + " 'enum' doesn't seem to be used as a scope, but it can't hurt to have + " it here + let type_vala.kind2scope = { + \ 's' : 'struct', + \ 'i' : 'interface', + \ 'c' : 'class', + \ 'e' : 'enum' + \ } + let type_vala.scope2kind = { + \ 'struct' : 's', + \ 'interface' : 'i', + \ 'class' : 'c', + \ 'enum' : 'e' + \ } + let s:known_types.vala = type_vala + endif + if !has_key(s:ctags_types, 'vala') && executable('anjuta-tags') + let s:known_types.vala.ctagsbin = 'anjuta-tags' + endif + " Vera {{{3 + " Why are variables 'virtual'? + let type_vera = s:TypeInfo.New() + let type_vera.ctagstype = 'vera' + let type_vera.kinds = [ + \ {'short' : 'd', 'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'g', 'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'T', 'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'm', 'long' : 'members', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'tasks', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'p', 'long' : 'programs', 'fold' : 0, 'stl' : 1} + \ ] + let type_vera.sro = '.' " Nesting doesn't seem to be possible + let type_vera.kind2scope = { + \ 'g' : 'enum', + \ 'c' : 'class', + \ 'v' : 'virtual' + \ } + let type_vera.scope2kind = { + \ 'enum' : 'g', + \ 'class' : 'c', + \ 'virtual' : 'v' + \ } + let s:known_types.vera = type_vera + " Verilog {{{3 + let type_verilog = s:TypeInfo.New() + let type_verilog.ctagstype = 'verilog' + let type_verilog.kinds = [ + \ {'short' : 'c', 'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'e', 'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'm', 'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'n', 'long' : 'net data types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'ports', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'r', 'long' : 'register data types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 't', 'long' : 'tasks', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.verilog = type_verilog + " VHDL {{{3 + " The VHDL ctags parser unfortunately doesn't generate proper scopes + let type_vhdl = s:TypeInfo.New() + let type_vhdl.ctagstype = 'vhdl' + let type_vhdl.kinds = [ + \ {'short' : 'P', 'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'c', 'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ {'short' : 't', 'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'T', 'long' : 'subtypes', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'r', 'long' : 'records', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'e', 'long' : 'entities', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.vhdl = type_vhdl + " Vim {{{3 + let type_vim = s:TypeInfo.New() + let type_vim.ctagstype = 'vim' + let type_vim.kinds = [ + \ {'short' : 'n', 'long' : 'vimball filenames', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'v', 'long' : 'variables', 'fold' : 1, 'stl' : 0}, + \ {'short' : 'f', 'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ {'short' : 'a', 'long' : 'autocommand groups', 'fold' : 1, 'stl' : 1}, + \ {'short' : 'c', 'long' : 'commands', 'fold' : 0, 'stl' : 0}, + \ {'short' : 'm', 'long' : 'maps', 'fold' : 1, 'stl' : 0} + \ ] + let s:known_types.vim = type_vim + " YACC {{{3 + let type_yacc = s:TypeInfo.New() + let type_yacc.ctagstype = 'yacc' + let type_yacc.kinds = [ + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1} + \ ] + let s:known_types.yacc = type_yacc + " }}}3 + + for [type, typeinfo] in items(s:known_types) + let typeinfo.ftype = type + endfor + + call s:LoadUserTypeDefs() + + for typeinfo in values(s:known_types) + call typeinfo.createKinddict() + endfor + + let s:type_init_done = 1 +endfunction + +" s:LoadUserTypeDefs() {{{2 +function! s:LoadUserTypeDefs(...) abort + if a:0 > 0 + let type = a:1 + + call s:debug("Initializing user type '" . type . "'") + + let defdict = {} + let defdict[type] = g:tagbar_type_{type} + else + call s:debug('Initializing user types') + + let defdict = tagbar#getusertypes() + endif + + let transformed = {} + for [type, def] in items(defdict) + let transformed[type] = s:TransformUserTypeDef(def) + let transformed[type].ftype = type + endfor + + for [key, value] in items(transformed) + if !has_key(s:known_types, key) || get(value, 'replace', 0) + let s:known_types[key] = s:TypeInfo.New(value) + else + call extend(s:known_types[key], value) + endif + endfor + + if a:0 > 0 + call s:known_types[type].createKinddict() + endif +endfunction + +" s:TransformUserTypeDef() {{{2 +" Transform the user definitions into the internal format +function! s:TransformUserTypeDef(def) abort + let newdef = copy(a:def) + + if has_key(a:def, 'kinds') + let newdef.kinds = [] + let kinds = a:def.kinds + for kind in kinds + let kindlist = split(kind, ':') + let kinddict = {'short' : kindlist[0], 'long' : kindlist[1]} + let kinddict.fold = get(kindlist, 2, 0) + let kinddict.stl = get(kindlist, 3, 1) + call add(newdef.kinds, kinddict) + endfor + endif + + " If the user only specified one of kind2scope and scope2kind then use it + " to generate the respective other + if has_key(a:def, 'kind2scope') && !has_key(a:def, 'scope2kind') + let newdef.scope2kind = {} + for [key, value] in items(a:def.kind2scope) + let newdef.scope2kind[value] = key + endfor + elseif has_key(a:def, 'scope2kind') && !has_key(a:def, 'kind2scope') + let newdef.kind2scope = {} + for [key, value] in items(a:def.scope2kind) + let newdef.kind2scope[value] = key + endfor + endif + + return newdef +endfunction + +" s:RestoreSession() {{{2 +" Properly restore Tagbar after a session got loaded +function! s:RestoreSession() abort + call s:debug('Restoring session') + + let curfile = fnamemodify(bufname('%'), ':p') + + let tagbarwinnr = bufwinnr('__Tagbar__') + if tagbarwinnr == -1 + " Tagbar wasn't open in the saved session, nothing to do + return + else + let in_tagbar = 1 + if winnr() != tagbarwinnr + call s:goto_win(tagbarwinnr) + let in_tagbar = 0 + endif + endif + + let s:last_autofocus = 0 + + call s:Init(0) + + call s:InitWindow(g:tagbar_autoclose) + + call s:AutoUpdate(curfile, 0) + + if !in_tagbar + call s:goto_win('p') + endif +endfunction + +" s:MapKeys() {{{2 +function! s:MapKeys() abort + call s:debug('Mapping keys') + + nnoremap