diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..2c9154d --- /dev/null +++ b/.hgignore @@ -0,0 +1,2 @@ +syntax: glob +*.pyc diff --git a/common/.config/ipython/profile_default/ipython_config.py b/common/.config/ipython/profile_default/ipython_config.py new file mode 100644 index 0000000..e7d47d1 --- /dev/null +++ b/common/.config/ipython/profile_default/ipython_config.py @@ -0,0 +1,5 @@ +c = get_config() + +c.InteractiveShellApp.extensions = [ + 'powerline.bindings.ipython.post_0_11' +] diff --git a/common/.config/powerline/config.json b/common/.config/powerline/config.json index 8882ad9..628d727 100644 --- a/common/.config/powerline/config.json +++ b/common/.config/powerline/config.json @@ -24,10 +24,6 @@ } }, "shell": { - "colorscheme": "default", - "theme": "default" - }, - "tmux": { "colorscheme": "default", "theme": "default", "segments" : { @@ -37,6 +33,10 @@ } } }, + "tmux": { + "colorscheme": "default", + "theme": "default" + }, "vim": { "colorscheme": "default", "theme": "default", diff --git a/common/.local/bin/powerline-zsh.py b/common/.local/bin/powerline-zsh.py new file mode 100755 index 0000000..ada55b8 --- /dev/null +++ b/common/.local/bin/powerline-zsh.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import subprocess +import sys +import re +import argparse + + +def warn(msg): + print '[powerline-zsh] ', msg + + +class Color: + # The following link is a pretty good resources for color values: + # http://www.calmar.ws/vim/color-output.png + + PATH_BG = 237 # dark grey + PATH_FG = 250 # light grey + CWD_FG = 254 # nearly-white grey + SEPARATOR_FG = 244 + + REPO_CLEAN_BG = 148 # a light green color + REPO_CLEAN_FG = 0 # black + REPO_DIRTY_BG = 161 # pink/red + REPO_DIRTY_FG = 15 # white + + CMD_PASSED_BG = 236 + CMD_PASSED_FG = 15 + CMD_FAILED_BG = 161 + CMD_FAILED_FG = 15 + + SVN_CHANGES_BG = 148 + SVN_CHANGES_FG = 22 # dark green + + VIRTUAL_ENV_BG = 35 # a mid-tone green + VIRTUAL_ENV_FG = 22 + + +class Powerline: + symbols = { + 'compatible': { + 'separator': u'\u25B6', + 'separator_thin': u'\u276F' + }, + 'patched': { + 'separator': u'\u2B80', + 'separator_thin': u'\u2B81' + }, + 'default': { + 'separator': '⮀', + 'separator_thin': '⮁' + } + } + LSQESCRSQ = '\\[\\e%s\\]' + reset = ' %f%k' + + def __init__(self, mode='default'): + self.separator = Powerline.symbols[mode]['separator'] + self.separator_thin = Powerline.symbols[mode]['separator_thin'] + self.segments = [] + + def color(self, prefix, code): + if prefix == '38': + return '%%F{%s}' % code + elif prefix == '48': + return '%%K{%s}' % code + + def fgcolor(self, code): + return self.color('38', code) + + def bgcolor(self, code): + return self.color('48', code) + + def append(self, segment): + self.segments.append(segment) + + def draw(self): + return (''.join((s[0].draw(self, s[1]) for s in zip(self.segments, self.segments[1:] + [None]))) + + self.reset) + + +class Segment: + def __init__(self, powerline, content, fg, bg, separator=None, separator_fg=None): + self.powerline = powerline + self.content = content + self.fg = fg + self.bg = bg + self.separator = separator or powerline.separator + self.separator_fg = separator_fg or bg + + def draw(self, powerline, next_segment=None): + if next_segment: + separator_bg = powerline.bgcolor(next_segment.bg) + else: + separator_bg = powerline.reset + + return ''.join(( + powerline.fgcolor(self.fg), + powerline.bgcolor(self.bg), + self.content, + separator_bg, + powerline.fgcolor(self.separator_fg), + self.separator)) + + +def add_cwd_segment(powerline, cwd, maxdepth, cwd_only=False): + #powerline.append(' \\w ', 15, 237) + home = os.getenv('HOME') + cwd = os.getenv('PWD') + + if cwd.find(home) == 0: + cwd = cwd.replace(home, '~', 1) + + if cwd[0] == '/': + cwd = cwd[1:] + + names = cwd.split('/') + if len(names) > maxdepth: + names = names[:2] + ['⋯ '] + names[2 - maxdepth:] + + if not cwd_only: + for n in names[:-1]: + powerline.append(Segment(powerline, ' %s ' % n, Color.PATH_FG, Color.PATH_BG, powerline.separator_thin, Color.SEPARATOR_FG)) + powerline.append(Segment(powerline, ' %s ' % names[-1], Color.CWD_FG, Color.PATH_BG)) + + +def get_hg_status(): + has_modified_files = False + has_untracked_files = False + has_missing_files = False + output = subprocess.Popen(['hg', 'status'], stdout=subprocess.PIPE).communicate()[0] + for line in output.split('\n'): + if line == '': + continue + elif line[0] == '?': + has_untracked_files = True + elif line[0] == '!': + has_missing_files = True + else: + has_modified_files = True + return has_modified_files, has_untracked_files, has_missing_files + + +def add_hg_segment(powerline, cwd): + branch = os.popen('hg branch 2> /dev/null').read().rstrip() + if len(branch) == 0: + return False + bg = Color.REPO_CLEAN_BG + fg = Color.REPO_CLEAN_FG + has_modified_files, has_untracked_files, has_missing_files = get_hg_status() + if has_modified_files or has_untracked_files or has_missing_files: + bg = Color.REPO_DIRTY_BG + fg = Color.REPO_DIRTY_FG + extra = '' + if has_untracked_files: + extra += '+' + if has_missing_files: + extra += '!' + branch += (' ' + extra if extra != '' else '') + powerline.append(Segment(powerline, ' %s ' % branch, fg, bg)) + return True + + +def get_git_status(): + has_pending_commits = True + has_untracked_files = False + detached_head = False + origin_position = "" + current_branch = '' + output = subprocess.Popen(['git', 'status', '-unormal'], stdout=subprocess.PIPE).communicate()[0] + for line in output.split('\n'): + origin_status = re.findall("Your branch is (ahead|behind).*?(\d+) comm", line) + if len(origin_status) > 0: + origin_position = " %d" % int(origin_status[0][1]) + if origin_status[0][0] == 'behind': + origin_position += '⇣' + if origin_status[0][0] == 'ahead': + origin_position += '⇡' + + if line.find('nothing to commit (working directory clean)') >= 0: + has_pending_commits = False + if line.find('Untracked files') >= 0: + has_untracked_files = True + if line.find('Not currently on any branch') >= 0: + detached_head = True + if line.find('On branch') >= 0: + current_branch = re.findall('On branch ([^ ]+)', line)[0] + return has_pending_commits, has_untracked_files, origin_position, detached_head, current_branch + + +def add_git_segment(powerline, cwd): + #cmd = "git branch 2> /dev/null | grep -e '\\*'" + p1 = subprocess.Popen(['git', 'branch'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p2 = subprocess.Popen(['grep', '-e', '\\*'], stdin=p1.stdout, stdout=subprocess.PIPE) + output = p2.communicate()[0].strip() + if len(output) == 0: + return False + + has_pending_commits, has_untracked_files, origin_position, detached_head, current_branch = get_git_status() + + if len(current_branch) > 0: + branch = current_branch + elif detached_head: + branch = subprocess.Popen(['git', 'describe', '--all', '--contains', '--abbrev=4', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + branch = '((' + branch.communicate()[0].strip() + '))' + else: + return 'master' + + branch += origin_position + + if has_untracked_files: + branch += ' +' + + bg = Color.REPO_CLEAN_BG + fg = Color.REPO_CLEAN_FG + + if has_pending_commits: + bg = Color.REPO_DIRTY_BG + fg = Color.REPO_DIRTY_FG + + powerline.append(Segment(powerline, ' %s ' % branch, fg, bg)) + return True + + +def add_svn_segment(powerline, cwd): + if not os.path.exists(os.path.join(cwd, '.svn')): + return + '''svn info: + First column: Says if item was added, deleted, or otherwise changed + ' ' no modifications + 'A' Added + 'C' Conflicted + 'D' Deleted + 'I' Ignored + 'M' Modified + 'R' Replaced + 'X' an unversioned directory created by an externals definition + '?' item is not under version control + '!' item is missing (removed by non-svn command) or incomplete + '~' versioned item obstructed by some item of a different kind + ''' + #TODO: Color segment based on above status codes + try: + #cmd = '"svn status | grep -c "^[ACDIMRX\\!\\~]"' + p1 = subprocess.Popen(['svn', 'status'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p2 = subprocess.Popen(['grep', '-c', '^[ACDIMRX\\!\\~]'], stdin=p1.stdout, stdout=subprocess.PIPE) + output = p2.communicate()[0].strip() + if len(output) > 0 and int(output) > 0: + changes = output.strip() + powerline.append(Segment(powerline, ' %s ' % changes, Color.SVN_CHANGES_FG, Color.SVN_CHANGES_BG)) + except OSError: + return False + except subprocess.CalledProcessError: + return False + return True + + +def add_repo_segment(powerline, cwd): + for add_repo_segment in [add_git_segment, add_svn_segment, add_hg_segment]: + try: + if add_repo_segment(p, cwd): + return + except subprocess.CalledProcessError: + pass + except OSError: + pass + + +def add_virtual_env_segment(powerline, cwd): + env = os.getenv("VIRTUAL_ENV") + if env is None: + return False + env_name = os.path.basename(env) + bg = Color.VIRTUAL_ENV_BG + fg = Color.VIRTUAL_ENV_FG + powerline.append(Segment(powerline, ' %s ' % env_name, fg, bg)) + return True + + +def add_root_indicator(powerline, error): + bg = Color.CMD_PASSED_BG + fg = Color.CMD_PASSED_FG + if int(error) != 0: + fg = Color.CMD_FAILED_FG + bg = Color.CMD_FAILED_BG + powerline.append(Segment(powerline, ' $ ', fg, bg)) + + +def get_valid_cwd(): + try: + cwd = os.getcwd() + except: + cwd = os.getenv('PWD') # This is where the OS thinks we are + parts = cwd.split(os.sep) + up = cwd + while parts and not os.path.exists(up): + parts.pop() + up = os.sep.join(parts) + try: + os.chdir(up) + except: + warn("Your current directory is invalid.") + sys.exit(1) + warn("Your current directory is invalid. Lowest valid directory: " + up) + return cwd + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--cwd-only', action="store_true") + arg_parser.add_argument('prev_error', nargs='?', default=0) + args = arg_parser.parse_args() + + p = Powerline(mode='default') + cwd = get_valid_cwd() + add_virtual_env_segment(p, cwd) + #p.append(Segment(' \\u ', 250, 240)) + #p.append(Segment(' \\h ', 250, 238)) + add_cwd_segment(p, cwd, 5, args.cwd_only) + add_repo_segment(p, cwd) + add_root_indicator(p, args.prev_error) + sys.stdout.write(p.draw()) + +# vim: set expandtab: diff --git a/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/PKG-INFO b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/PKG-INFO new file mode 100644 index 0000000..24a9e45 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/PKG-INFO @@ -0,0 +1,282 @@ +Metadata-Version: 1.1 +Name: jedi +Version: 0.5b5 +Summary: An autocompletion tool for Python that can be used for text editors. +Home-page: https://github.com/davidhalter/jedi +Author: David Halter +Author-email: davidhalter88@gmail.com +License: LGPLv3 +Description: ######################################## + Jedi - an awesome Python auto-completion + ######################################## + + .. image:: https://secure.travis-ci.org/davidhalter/jedi.png?branch=master + :target: http://travis-ci.org/davidhalter/jedi + :alt: Travis-CI build status + + **beta testing** + + *If you have any comments or feature requests, please tell me! I really want to + know, what you think about Jedi.* + + Jedi is an autocompletion tool for Python. It works. With and without syntax + errors. Sometimes it sucks, but that's normal in dynamic languages. But it + sucks less than other tools. It understands almost all of the basic Python + syntax elements including many builtins. + + Jedi suports two different goto functions and has support for renaming. + Probably it will also have some support for refactoring in the future. + + Jedi uses a very simple interface to connect with IDE's. As an reference, there + is a VIM implementation, which uses Jedi's autocompletion. However, I encourage + you to use Jedi in your IDEs. Start writing plugins! If there are problems with + licensing, just contact me. + + At the moment Jedi can be used as a + `VIM-Plugin `_. So, if you want to test + Jedi for now, you'll have to use VIM. But there are new plugins emerging: + + - `Emacs-Plugin `_ + - `Sublime-Plugin `_ **Under construction** + + Here are some pictures: + + .. image:: https://github.com/davidhalter/jedi/raw/master/screenshot_complete.png + + Completion for almost anything (Ctrl+Space). + + .. image:: https://github.com/davidhalter/jedi/raw/master/screenshot_function.png + + Display of function/class bodies, docstrings. + + .. image:: https://github.com/davidhalter/jedi/raw/master/screenshot_pydoc.png + + Pydoc support (with highlighting, Shift+k). + + There is also support for goto and renaming. + + Get the latest from `github `_. + + + Installation + ============ + + You can either include Jedi as a submodule in your text editor plugin (like + jedi-vim_ does it by default), or you + can install Jedi systemwide. + + The preferred way to install the Jedi library into your system is by using + pip_:: + + sudo pip install jedi + + If you want to install the current development version:: + + sudo pip install -e git://github.com/davidhalter/jedi.git#egg=jedi + + Note: This just installs the Jedi library, not the editor plugins. For + information about how to make it work with your editor, refer to the + corresponding documentation. + + + Support + ======= + + Jedi supports Python 2.5 up to 3.x. There is just one code base, for both + Python 2 and 3. + Jedi supports many of the widely used Python features: + + - builtin functions/classes support + - complex module / function / class structures + - ignores syntax and indentation errors + - multiple returns / yields + - tuple assignments / array indexing / dictionary indexing + - exceptions / with-statement + - \*args / \*\*kwargs + - decorators + - descriptors -> property / staticmethod / classmethod + - closures + - generators (yield statement) / iterators + - support for some magic methods: ``__call__``, ``__iter__``, ``__next__``, + ``__get__``, ``__getitem__``, ``__init__`` + - support for list.append, set.add, list.extend, etc. + - (nested) list comprehensions / ternary expressions + - relative imports + - ``getattr()`` / ``__getattr__`` / ``__getattribute__`` + - function annotations (py3k feature, are ignored right now, but being parsed. + I don't know what to do with them.) + - class decorators (py3k feature, are being ignored too, until I find a use + case, that doesn't work with Jedi) + - simple/usual ``sys.path`` modifications + - ``isinstance`` checks for if/while/assert + - virtualenv support + - infer function arguments with sphinx (and other) docstrings + + However, it does not yet support (and probably will in future versions, because + they are on my todo list): + + - manipulations of instances outside the instance variables, without using + functions + + It does not support (and most probably will not in future versions): + + - metaclasses (how could an auto-completion ever support this) + - ``setattr()``, ``__import__()`` + - Writing to some dicts: ``globals()``, ``locals()``, ``object.__dict__`` + - evaluate ``if`` / ``while`` + + + Caveats + ======= + + This framework should work for both Python 2/3. However, some things were just + not as *pythonic* in Python 2 as things should be. To keep things simple, some + things have been held back: + + - Classes: Always Python 3 like, therefore all classes inherit from ``object``. + - Generators: No ``next`` method. The ``__next__`` method is used instead. + - Exceptions are only looked at in the form of ``Exception as e``, no comma! + + Syntax errors and other strange stuff, that is defined differently in the + Python language, may lead to undefined behaviour of the completion. Jedi is + **NOT** a Python compiler, that tries to correct you. It is a tool that wants + to help you. But **YOU** have to know Python, not Jedi. + + Importing ``numpy`` can be quite slow sometimes, as well as loading the builtins + the first time. If you want to speed it up, you could write import hooks in + jedi, which preloads this stuff. However, once loaded, this is not a problem + anymore. The same is true for huge modules like ``PySide``, ``wx``, etc. + + Security is an important issue for Jedi. Therefore no Python code is executed. + As long as you write pure python, everything is evaluated statically. But: If + you use builtin modules (`c_builtin`) there is no other option than to execute + those modules. However: Execute isn't that critical (as e.g. in pythoncomplete, + which used to execute *every* import!), because it means one import and no + more. So basically the only dangerous thing is using the import itself. If your + `c_builtin` uses some strange initializations, it might be dangerous. But if it + does you're screwed anyways, because eventualy you're going to execute your + code, which executes the import. + + + A little history + ================ + + The Star Wars Jedi are awesome. My Jedi software tries to imitate a little bit + of the precognition the Jedi have. There is even an awesome `scene + `_ of Monty Python Jedi's :-). + + But actually the name hasn't so much to do with Star Wars. It's part of my + second name. + + After I explained Guido van Rossum, how some parts of my auto-completion work, + he said (we drank a beer or two): + + *Oh, that worries me* + + When it's finished, I hope he'll like it :-) + + I actually started Jedi, because there were no good solutions available for + VIM. Most auto-completions just didn't work well. The only good solution was + PyCharm. I just like my good old VIM. Rope was never really intended to be an + auto-completion (and also I really hate project folders for my Python scripts). + It's more of a refactoring suite. So I decided to do my own version of a + completion, which would execute non-dangerous code. But I soon realized, that + this wouldn't work. So I built an extremely recursive thing which understands + many of Python's key features. + + By the way, I really tried to program it as understandable as possible. But I + think understanding it might need quite some time, because of its recursive + nature. + + + API-Design for IDEs + =================== + + If you want to set up an IDE with Jedi, you need to ``import jedi``. You should + have the following objects available: + + :: + + Script(source, line, column, source_path) + + ``source`` would be the source of your python file/script, separated by new + lines. ``line`` is the current line you want to perform actions on (starting + with line #1 as the first line). ``column`` represents the current + column/indent of the cursor (starting with zero). ``source_path`` should be the + path of your file in the file system. + + It returns a script object that contains the relevant information for the other + functions to work without params. + + :: + + Script().complete + + Returns ``api.Completion`` objects. Those objects have got + informations about the completions. More than just names. + + :: + + Script().goto + + Similar to complete. The returned ``api.Definition`` objects contain + information about the definitions found. + + :: + + Script().get_definition + + Mostly used for tests. Like goto, but follows statements and imports and + doesn't break there. You probably don't want to use this function. It's + mostly for testing. + + :: + + Script().related_names + + Returns all names that point to the definition of the name under the + cursor. This is also very useful for refactoring (renaming). + + :: + + Script().get_in_function_call + + Get the ``Function`` object of the call you're currently in, e.g.: ``abs(`` + with the cursor at the end would return the builtin ``abs`` function. + + :: + + NotFoundError + + If you use the goto function and no valid identifier (name) is at the + place of the cursor (position). It will raise this exception. + + :: + + set_debug_function + + Sets a callback function for ``debug.py``. This function is called with + multiple text objects, in python 3 you could insert ``print``. + + :: + + settings + + Access to the ``settings.py`` module. The settings are described there. + + + + .. _jedi-vim: http://github.com/davidhalter/jedi-vim + .. _pip: http://www.pip-installer.org/ + +Keywords: python completion refactoring vim +Platform: any +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Plugins +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE) +Classifier: Topic :: Utilities diff --git a/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/SOURCES.txt b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/SOURCES.txt new file mode 100644 index 0000000..c1d625b --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/SOURCES.txt @@ -0,0 +1,31 @@ +AUTHORS.txt +LICENSE.txt +MANIFEST.in +README.rst +setup.cfg +setup.py +jedi/__init__.py +jedi/_compatibility.py +jedi/api.py +jedi/api_classes.py +jedi/builtin.py +jedi/debug.py +jedi/docstrings.py +jedi/dynamic.py +jedi/evaluate.py +jedi/helpers.py +jedi/imports.py +jedi/keywords.py +jedi/modules.py +jedi/parsing.py +jedi/settings.py +jedi.egg-info/PKG-INFO +jedi.egg-info/SOURCES.txt +jedi.egg-info/dependency_links.txt +jedi.egg-info/top_level.txt +jedi/mixin/_functools.pym +jedi/mixin/_sre.pym +jedi/mixin/_weakref.pym +jedi/mixin/builtins.pym +jedi/mixin/datetime.pym +jedi/mixin/posix.pym \ No newline at end of file diff --git a/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/dependency_links.txt b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/installed-files.txt b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/installed-files.txt new file mode 100644 index 0000000..d4fc8a0 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/installed-files.txt @@ -0,0 +1,41 @@ +../jedi/builtin.py +../jedi/evaluate.py +../jedi/debug.py +../jedi/helpers.py +../jedi/settings.py +../jedi/keywords.py +../jedi/api_classes.py +../jedi/api.py +../jedi/modules.py +../jedi/__init__.py +../jedi/parsing.py +../jedi/docstrings.py +../jedi/_compatibility.py +../jedi/imports.py +../jedi/dynamic.py +../jedi/mixin/builtins.pym +../jedi/mixin/posix.pym +../jedi/mixin/_functools.pym +../jedi/mixin/_weakref.pym +../jedi/mixin/_sre.pym +../jedi/mixin/datetime.pym +../jedi/builtin.pyc +../jedi/evaluate.pyc +../jedi/debug.pyc +../jedi/helpers.pyc +../jedi/settings.pyc +../jedi/keywords.pyc +../jedi/api_classes.pyc +../jedi/api.pyc +../jedi/modules.pyc +../jedi/__init__.pyc +../jedi/parsing.pyc +../jedi/docstrings.pyc +../jedi/_compatibility.pyc +../jedi/imports.pyc +../jedi/dynamic.pyc +./ +SOURCES.txt +PKG-INFO +dependency_links.txt +top_level.txt diff --git a/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/top_level.txt b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/top_level.txt new file mode 100644 index 0000000..86c1cb1 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi-0.5b5.egg-info/top_level.txt @@ -0,0 +1 @@ +jedi diff --git a/common/.local/lib/python2.7/site-packages/jedi/__init__.py b/common/.local/lib/python2.7/site-packages/jedi/__init__.py new file mode 100644 index 0000000..9f8c369 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/__init__.py @@ -0,0 +1,16 @@ +import sys + +# python imports are hell sometimes. Especially the combination of relative +# imports and circular imports... Just avoid it: +sys.path.insert(0, __path__[0]) + +from .api import Script, NotFoundError, set_debug_function +from . import settings + +from . import api + +__doc__ = api.__doc__ + +del api + +sys.path.pop(0) diff --git a/common/.local/lib/python2.7/site-packages/jedi/_compatibility.py b/common/.local/lib/python2.7/site-packages/jedi/_compatibility.py new file mode 100644 index 0000000..d701526 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/_compatibility.py @@ -0,0 +1,169 @@ +""" +This is a compatibility module, to make it possible to use jedi also with older +python versions. +""" +import sys + +is_py3k = sys.hexversion >= 0x03000000 + +is_py25 = sys.hexversion < 0x02060000 + +# next was defined in python 2.6, in python 3 obj.next won't be possible +# anymore +try: + next = next +except NameError: + _raiseStopIteration = object() + + def next(iterator, default=_raiseStopIteration): + if not hasattr(iterator, 'next'): + raise TypeError("not an iterator") + try: + return iterator.next() + except StopIteration: + if default is _raiseStopIteration: + raise + else: + return default + +# ast module was defined in python 2.6 +try: + from ast import literal_eval +except ImportError: + literal_eval = eval + + +# properties in 2.5 +try: + property.setter +except AttributeError: + class property(property): + def __init__(self, fget, *args, **kwargs): + self.__doc__ = fget.__doc__ + super(property, self).__init__(fget, *args, **kwargs) + + def setter(self, fset): + cls_ns = sys._getframe(1).f_locals + for k, v in cls_ns.iteritems(): + if v == self: + propname = k + break + cls_ns[propname] = property(self.fget, fset, + self.fdel, self.__doc__) + return cls_ns[propname] +else: + property = property + +# unicode function +try: + unicode = unicode +except NameError: + unicode = str + +if is_py3k: + utf8 = lambda s: s +else: + utf8 = lambda s: s.decode('utf-8') + +utf8.__doc__ = """ +Decode a raw string into unicode object. Do nothing in Python 3. +""" + +# exec function +if is_py3k: + def exec_function(source, global_map): + exec(source, global_map) +else: + eval(compile("""def exec_function(source, global_map): + exec source in global_map """, 'blub', 'exec')) + +# StringIO (Python 2.5 has no io module), so use io only for py3k +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + +# hasattr function used because python +if is_py3k: + hasattr = hasattr +else: + def hasattr(obj, name): + try: + getattr(obj, name) + return True + except AttributeError: + return False + + +class Python3Method(object): + def __init__(self, func): + self.func = func + + def __get__(self, obj, objtype): + if obj is None: + return lambda *args, **kwargs: self.func(*args, **kwargs) + else: + return lambda *args, **kwargs: self.func(obj, *args, **kwargs) + +try: + # the python3 way + from functools import reduce +except ImportError: + reduce = reduce + + +def use_metaclass(meta, *bases): + """ Create a class with a metaclass. """ + if not bases: + bases = (object,) + return meta("HackClass", bases, {}) + +try: + from inspect import cleandoc +except ImportError: + # python 2.5 doesn't have this method + import string + + def cleandoc(doc): + """Clean up indentation from docstrings. + + Any whitespace that can be uniformly removed from the second line + onwards is removed.""" + try: + lines = string.split(string.expandtabs(doc), '\n') + except UnicodeError: + return None + else: + # Find minimum indentation of any non-blank lines after first line. + margin = sys.maxint + for line in lines[1:]: + content = len(string.lstrip(line)) + if content: + indent = len(line) - content + margin = min(margin, indent) + # Remove indentation. + if lines: + lines[0] = lines[0].lstrip() + if margin < sys.maxint: + for i in range(1, len(lines)): + lines[i] = lines[i][margin:] + # Remove any trailing or leading blank lines. + while lines and not lines[-1]: + lines.pop() + while lines and not lines[0]: + lines.pop(0) + return string.join(lines, '\n') + +if is_py25: + # adds the `itertools.chain.from_iterable` constructor + import itertools + + class chain(itertools.chain): + @staticmethod + def from_iterable(iterables): + # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F + for it in iterables: + for element in it: + yield element + itertools.chain = chain + del chain diff --git a/common/.local/lib/python2.7/site-packages/jedi/api.py b/common/.local/lib/python2.7/site-packages/jedi/api.py new file mode 100644 index 0000000..248991b --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/api.py @@ -0,0 +1,457 @@ +""" +Jedi is an autocompletion library for Python. It offers additonal +services such as goto / get_definition / pydoc support / +get_in_function_call / related names. + +To give you a simple exmple how you can use the jedi library, +here is an exmple for the autocompletion feature: + +>>> import jedi +>>> source = '''import json; json.l''' +>>> script = jedi.Script(source, 1, 19, '') +>>> script + +>>> completions = script.complete() +>>> completions +[, ] +>>> completions[0].complete +'oad' +>>> completions[0].word +'load' + +As you see Jedi is pretty simple and allows you to concentrate +writing a good text editor, while still having very good IDE features +for Python. +""" +from __future__ import with_statement +__all__ = ['Script', 'NotFoundError', 'set_debug_function'] + +import re + +import parsing +import dynamic +import imports +import evaluate +import modules +import debug +import settings +import keywords +import helpers +import builtin +import api_classes + +from _compatibility import next, unicode + + +class NotFoundError(Exception): + """ A custom error to avoid catching the wrong exceptions """ + pass + + +class Script(object): + """ + A Script is the base for a completion, goto or whatever call. + + :param source: The source code of the current file + :type source: string + :param line: The line to complete in. + :type line: int + :param col: The column to complete in. + :type col: int + :param source_path: The path in the os, the current module is in. + :type source_path: string or None + :param source_encoding: encoding for decoding `source`, when it + is not a `unicode` object. + :type source_encoding: string + """ + def __init__(self, source, line, column, source_path, + source_encoding='utf-8'): + debug.reset_time() + try: + source = unicode(source, source_encoding, 'replace') + # Use 'replace' over 'ignore' to hold code structure. + except TypeError: # `source` is already a unicode object + pass + self.pos = line, column + self.module = modules.ModuleWithCursor(source_path, source=source, + position=self.pos) + self.source_path = source_path + debug.speed('init') + + @property + def parser(self): + """ The lazy parser """ + return self.module.parser + + def complete(self): + """ + An auto completer for python files. + + :return: list of Completion objects, sorted by name and __ comes last. + :rtype: list + """ + def follow_imports_if_possible(name): + # TODO remove this, or move to another place (not used) + par = name.parent + if isinstance(par, parsing.Import) and not \ + isinstance(self.parser.user_stmt, parsing.Import): + new = imports.ImportPath(par).follow(is_goto=True) + # Only remove the old entry if a new one has been found. + #print par, new, par.parent + if new: + try: + return new + except AttributeError: # .name undefined + pass + return [name] + + + debug.speed('complete start') + path = self.module.get_path_until_cursor() + path, dot, like = self._get_completion_parts(path) + + try: + scopes = list(self._prepare_goto(path, True)) + except NotFoundError: + scopes = [] + scope_generator = evaluate.get_names_for_scope( + self.parser.user_scope, self.pos) + completions = [] + for scope, name_list in scope_generator: + for c in name_list: + completions.append((c, scope)) + else: + completions = [] + debug.dbg('possible scopes', scopes) + for s in scopes: + if s.isinstance(evaluate.Function): + names = s.get_magic_method_names() + else: + if isinstance(s, imports.ImportPath): + if like == 'import': + l = self.module.get_line(self.pos[0])[:self.pos[1]] + if not l.endswith('import import'): + continue + names = s.get_defined_names(on_import_stmt=True) + else: + names = s.get_defined_names() + + for c in names: + completions.append((c, s)) + + if not dot: # named_params have no dots + call_def = self.get_in_function_call() + if call_def: + if not call_def.module.is_builtin(): + for p in call_def.params: + completions.append((p.get_name(), p)) + + # Do the completion if there is no path before and no import stmt. + if (not scopes or not isinstance(scopes[0], imports.ImportPath)) \ + and not path: + # add keywords + bs = builtin.Builtin.scope + completions += ((k, bs) for k in keywords.get_keywords( + all=True)) + + needs_dot = not dot and path + + comps = [] + for c, s in set(completions): + n = c.names[-1] + if settings.case_insensitive_completion \ + and n.lower().startswith(like.lower()) \ + or n.startswith(like): + if not evaluate.filter_private_variable(s, + self.parser.user_stmt, n): + new = api_classes.Completion(c, needs_dot, + len(like), s) + comps.append(new) + + debug.speed('complete end') + + return sorted(comps, key=lambda x: (x.word.startswith('__'), + x.word.startswith('_'), + x.word.lower())) + + def _prepare_goto(self, goto_path, is_like_search=False): + """ Base for complete, goto and get_definition. Basically it returns + the resolved scopes under cursor. """ + debug.dbg('start: %s in %s' % (goto_path, self.parser.scope)) + + user_stmt = self.parser.user_stmt + debug.speed('parsed') + if not user_stmt and len(goto_path.split('\n')) > 1: + # If the user_stmt is not defined and the goto_path is multi line, + # something's strange. Most probably the backwards tokenizer + # matched to much. + return [] + + if isinstance(user_stmt, parsing.Import): + scopes = [self._get_on_import_stmt(is_like_search)[0]] + else: + # just parse one statement, take it and evaluate it + stmt = self._get_under_cursor_stmt(goto_path) + scopes = evaluate.follow_statement(stmt) + return scopes + + def _get_under_cursor_stmt(self, cursor_txt): + r = parsing.PyFuzzyParser(cursor_txt, self.source_path, no_docstr=True) + try: + stmt = r.module.statements[0] + except IndexError: + raise NotFoundError() + stmt.start_pos = self.pos + stmt.parent = self.parser.user_scope + return stmt + + def get_definition(self): + """ + Returns the definitions of a the path under the cursor. This is + not a goto function! This follows complicated paths and returns the + end, not the first definition. + The big difference of goto and get_definition is that goto doesn't + follow imports and statements. + Multiple objects may be returned, because Python itself is a dynamic + language, which means depending on an option you can have two different + versions of a function. + + :return: list of Definition objects, which are basically scopes. + :rtype: list + """ + def resolve_import_paths(scopes): + for s in scopes.copy(): + if isinstance(s, imports.ImportPath): + scopes.remove(s) + scopes.update(resolve_import_paths(set(s.follow()))) + return scopes + + goto_path = self.module.get_path_under_cursor() + + context = self.module.get_context() + if next(context) in ('class', 'def'): + scopes = set([self.module.parser.user_scope]) + elif not goto_path: + op = self.module.get_operator_under_cursor() + scopes = set([keywords.get_operator(op, self.pos)] if op else []) + else: + scopes = set(self._prepare_goto(goto_path)) + + scopes = resolve_import_paths(scopes) + + # add keywords + scopes |= keywords.get_keywords(string=goto_path, pos=self.pos) + + d = set([api_classes.Definition(s) for s in scopes + if not isinstance(s, imports.ImportPath._GlobalNamespace)]) + return sorted(d, key=lambda x: (x.module_path, x.start_pos)) + + def goto(self): + """ + Returns the first definition found by goto. This means: It doesn't + follow imports and statements. + Multiple objects may be returned, because Python itself is a dynamic + language, which means depending on an option you can have two different + versions of a function. + + :return: list of Definition objects, which are basically scopes. + """ + d = [api_classes.Definition(d) for d in set(self._goto()[0])] + return sorted(d, key=lambda x: (x.module_path, x.start_pos)) + + def _goto(self, add_import_name=False): + """ + Used for goto and related_names. + :param add_import_name: TODO add description + """ + def follow_inexistent_imports(defs): + """ Imports can be generated, e.g. following + `multiprocessing.dummy` generates an import dummy in the + multiprocessing module. The Import doesn't exist -> follow. + """ + definitions = set(defs) + for d in defs: + if isinstance(d.parent, parsing.Import) \ + and d.start_pos == (0, 0): + i = imports.ImportPath(d.parent).follow(is_goto=True) + definitions.remove(d) + definitions |= follow_inexistent_imports(i) + return definitions + + goto_path = self.module.get_path_under_cursor() + context = self.module.get_context() + if next(context) in ('class', 'def'): + user_scope = self.parser.user_scope + definitions = set([user_scope.name]) + search_name = str(user_scope.name) + elif isinstance(self.parser.user_stmt, parsing.Import): + s, name_part = self._get_on_import_stmt() + try: + definitions = [s.follow(is_goto=True)[0]] + except IndexError: + definitions = [] + search_name = str(name_part) + + if add_import_name: + import_name = self.parser.user_stmt.get_defined_names() + # imports have only one name + if name_part == import_name[0].names[-1]: + definitions.append(import_name[0]) + else: + stmt = self._get_under_cursor_stmt(goto_path) + defs, search_name = evaluate.goto(stmt) + definitions = follow_inexistent_imports(defs) + return definitions, search_name + + def related_names(self, additional_module_paths=[]): + """ + Returns `dynamic.RelatedName` objects, which contain all names, that + are defined by the same variable, function, class or import. + This function can be used either to show all the usages of a variable + or for renaming purposes. + + TODO implement additional_module_paths + """ + user_stmt = self.parser.user_stmt + definitions, search_name = self._goto(add_import_name=True) + if isinstance(user_stmt, parsing.Statement) \ + and self.pos < user_stmt.get_assignment_calls().start_pos: + # the search_name might be before `=` + definitions = [v for v in user_stmt.set_vars + if str(v) == search_name] + if not isinstance(user_stmt, parsing.Import): + # import case is looked at with add_import_name option + definitions = dynamic.related_name_add_import_modules(definitions, + search_name) + + module = set([d.get_parent_until() for d in definitions]) + module.add(self.parser.module) + names = dynamic.related_names(definitions, search_name, module) + + for d in set(definitions): + if isinstance(d, parsing.Module): + names.append(api_classes.RelatedName(d, d)) + else: + names.append(api_classes.RelatedName(d.names[0], d)) + + return sorted(set(names), key=lambda x: (x.module_path, x.start_pos), + reverse=True) + + def get_in_function_call(self): + """ + Return the function, that the cursor is in, e.g.: + >>> isinstance(| # | <-- cursor is here + + This would return the `isinstance` function. In contrary: + >>> isinstance()| # | <-- cursor is here + + This would return `None`. + """ + def check_user_stmt(user_stmt): + if user_stmt is None \ + or not isinstance(user_stmt, parsing.Statement): + return None, 0 + ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls()) + + call, index, stop = helpers.scan_array_for_pos(ass, self.pos) + return call, index + + def check_cache(): + """ Do the parsing with a part parser, therefore reduce ressource + costs. + TODO this is not working with multi-line docstrings, improve. + """ + if self.source_path is None: + return None, 0 + + try: + timestamp, parser = builtin.CachedModule.cache[ + self.source_path] + except KeyError: + return None, 0 + part_parser = self.module.get_part_parser() + user_stmt = part_parser.user_stmt + call, index = check_user_stmt(user_stmt) + if call: + old_stmt = parser.module.get_statement_for_position(self.pos) + if old_stmt is None: + return None, 0 + old_call, old_index = check_user_stmt(old_stmt) + if old_call: + # compare repr because that should definitely be the same. + # Otherwise the whole thing is out of sync. + if repr(old_call) == repr(call): + # return the index of the part_parser + return old_call, index + return None, 0 + else: + raise NotFoundError() + + debug.speed('func_call start') + try: + call, index = check_cache() + except NotFoundError: + return None + debug.speed('func_call parsed') + + if call is None: + # This is a backup, if the above is not successful. + user_stmt = self.parser.user_stmt + call, index = check_user_stmt(user_stmt) + if call is None: + return None + + debug.speed('func_call user_stmt') + with helpers.scale_speed_settings(settings.scale_get_in_function_call): + origins = evaluate.follow_call(call) + debug.speed('func_call followed') + + if len(origins) == 0: + return None + # just take entry zero, because we need just one. + executable = origins[0] + + return api_classes.CallDef(executable, index, call) + + def _get_on_import_stmt(self, is_like_search=False): + """ Resolve the user statement, if it is an import. Only resolve the + parts until the user position. """ + user_stmt = self.parser.user_stmt + import_names = user_stmt.get_all_import_names() + kill_count = -1 + cur_name_part = None + for i in import_names: + if user_stmt.alias == i: + continue + for name_part in i.names: + if name_part.end_pos >= self.pos: + if not cur_name_part: + cur_name_part = name_part + kill_count += 1 + + i = imports.ImportPath(user_stmt, is_like_search, + kill_count=kill_count, direct_resolve=True) + return i, cur_name_part + + def _get_completion_parts(self, path): + """ + Returns the parts for the completion + :return: tuple - (path, dot, like) + """ + match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S) + return match.groups() + + def __del__(self): + evaluate.clear_caches() + + +def set_debug_function(func_cb=debug.print_to_stdout, warnings=True, + notices=True, speed=True): + """ + You can define a callback debug function to get all the debug messages. + :param func_cb: The callback function for debug messages, with n params. + """ + debug.debug_function = func_cb + debug.enable_warning = warnings + debug.enable_notice = notices + debug.enable_speed = speed diff --git a/common/.local/lib/python2.7/site-packages/jedi/api_classes.py b/common/.local/lib/python2.7/site-packages/jedi/api_classes.py new file mode 100644 index 0000000..367615a --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/api_classes.py @@ -0,0 +1,311 @@ +""" The classes returned by the api """ + +import re +import os + +import settings +import evaluate +import imports +import parsing +import keywords + + +class BaseDefinition(object): + _mapping = {'posixpath': 'os.path', + 'riscospath': 'os.path', + 'ntpath': 'os.path', + 'os2emxpath': 'os.path', + 'macpath': 'os.path', + 'genericpath': 'os.path', + '_io': 'io', + '__builtin__': '', + 'builtins': '', + } + + _tuple_mapping = dict((tuple(k.split('.')), v) for (k, v) in { + 'argparse._ActionsContainer': 'argparse.ArgumentParser', + '_sre.SRE_Match': 're.MatchObject', + '_sre.SRE_Pattern': 're.RegexObject', + }.items()) + + def __init__(self, definition, start_pos): + self.start_pos = start_pos + self.definition = definition + self.is_keyword = isinstance(definition, keywords.Keyword) + + # generate a path to the definition + self.module_path = str(definition.get_parent_until().path) + + @property + def type(self): + # generate the type + stripped = self.definition + if isinstance(self.definition, evaluate.InstanceElement): + stripped = self.definition.var + return type(stripped).__name__ + + @property + def path(self): + path = [] + if not isinstance(self.definition, keywords.Keyword): + par = self.definition + while par is not None: + try: + path.insert(0, par.name) + except AttributeError: + pass + par = par.parent + return path + + @property + def module_name(self): + path = self.module_path + sep = os.path.sep + p = re.sub(r'^.*?([\w\d]+)(%s__init__)?.py$' % sep, r'\1', path) + return p + + def in_builtin_module(self): + return not self.module_path.endswith('.py') + + @property + def line_nr(self): + return self.start_pos[0] + + @property + def column(self): + return self.start_pos[1] + + @property + def doc(self): + """ Return a document string for this completion object. """ + try: + return self.definition.doc + except AttributeError: + return self.raw_doc + + @property + def raw_doc(self): + """ Returns the raw docstring `__doc__` for any object """ + try: + return str(self.definition.docstr) + except AttributeError: + return '' + + @property + def description(self): + return str(self.definition) + + @property + def full_name(self): + """ + Returns the path to a certain class/function, see #61. + """ + path = [str(p) for p in self.path] + # TODO add further checks, the mapping should only occur on stdlib. + try: + path[0] = self._mapping[path[0]] + except KeyError: + pass + for key, repl in self._tuple_mapping.items(): + if tuple(path[:len(key)]) == key: + path = [repl] + path[len(key):] + + return '.'.join(path if path[0] else path[1:]) + + def __repr__(self): + return "<%s %s>" % (type(self).__name__, self.description) + + +class Completion(BaseDefinition): + """ `Completion` objects are returned from `Script.complete`. Providing + some useful functions for IDE's. """ + def __init__(self, name, needs_dot, like_name_length, base): + super(Completion, self).__init__(name.parent, name.start_pos) + + self.name = name + self.needs_dot = needs_dot + self.like_name_length = like_name_length + self.base = base + + self._followed_definitions = None + + @property + def complete(self): + """ Delievers the rest of the word, e.g. completing `isinstance` + >>> isinstan + + would return the string 'ce'. It also adds additional stuff, depending + on your `settings.py` + """ + dot = '.' if self.needs_dot else '' + append = '' + if settings.add_bracket_after_function \ + and self.type == 'Function': + append = '(' + + if settings.add_dot_after_module: + if isinstance(self.base, parsing.Module): + append += '.' + if isinstance(self.base, parsing.Param): + append += '=' + return dot + self.name.names[-1][self.like_name_length:] + append + + @property + def word(self): + """ In contrary to `complete` returns the whole word, e.g. + >>> isinstan + + would return 'isinstance'. + """ + return str(self.name.names[-1]) + + @property + def description(self): + """ Provides a description of the completion object + TODO return value is just __repr__ of some objects, improve! """ + parent = self.name.parent + if parent is None: + return '' + t = self.type + if t == 'Statement' or t == 'Import': + desc = self.definition.get_code(False) + else: + desc = '.'.join(str(p) for p in self.path) + + line_nr = '' if self.in_builtin_module else '@%s' % self.line_nr + return '%s: %s%s' % (t, desc, line_nr) + + def follow_definition(self): + """ Returns you the original definitions. I strongly recommend not + using it for your completions, because it might slow down Jedi. If you + want to read only a few objects (<=20). I think it might be useful, + especially to get the original docstrings. + The basic problem of this function is that it follows all results. This + means with 1000 completions (e.g. numpy), it's just PITA slow. + """ + if self._followed_definitions is None: + if self.definition.isinstance(parsing.Statement): + defs = evaluate.follow_statement(self.definition) + elif self.definition.isinstance(parsing.Import): + defs = imports.strip_imports([self.definition]) + else: + return [self] + + self._followed_definitions = \ + [BaseDefinition(d, d.start_pos) for d in defs] + evaluate.clear_caches() + + return self._followed_definitions + + def __repr__(self): + return '<%s: %s>' % (type(self).__name__, self.name) + + +class Definition(BaseDefinition): + """ These are the objects returned by either `Script.goto` or + `Script.get_definition`. """ + def __init__(self, definition): + super(Definition, self).__init__(definition, definition.start_pos) + + @property + def description(self): + """ A description of the Definition object, which is heavily used in + testing. e.g. for `isinstance` it returns 'def isinstance' """ + d = self.definition + if isinstance(d, evaluate.InstanceElement): + d = d.var + if isinstance(d, evaluate.parsing.Name): + d = d.parent + + if isinstance(d, evaluate.Array): + d = 'class ' + d.type + elif isinstance(d, (parsing.Class, evaluate.Class, evaluate.Instance)): + d = 'class ' + str(d.name) + elif isinstance(d, (evaluate.Function, evaluate.parsing.Function)): + d = 'def ' + str(d.name) + elif isinstance(d, evaluate.parsing.Module): + # only show module name + d = 'module %s' % self.module_name + elif self.is_keyword: + d = 'keyword %s' % d.name + else: + d = d.get_code().replace('\n', '') + return d + + @property + def desc_with_module(self): + """ In addition to the Definition, it also returns the module. Don't + use it yet, its behaviour may change. If you really need it, talk to me + TODO add full path. This function is should return a + module.class.function path. """ + if self.module_path.endswith('.py') \ + and not isinstance(self.definition, parsing.Module): + position = '@%s' % (self.line_nr) + else: + # is a builtin or module + position = '' + return "%s:%s%s" % (self.module_name, self.description, position) + + +class RelatedName(BaseDefinition): + def __init__(self, name_part, scope): + super(RelatedName, self).__init__(scope, name_part.start_pos) + self.name_part = name_part + self.text = str(name_part) + self.end_pos = name_part.end_pos + + @property + def description(self): + return "%s@%s,%s" % (self.text, self.start_pos[0], self.start_pos[1]) + + def __eq__(self, other): + return self.start_pos == other.start_pos \ + and self.module_path == other.module_path + + def __hash__(self): + return hash((self.start_pos, self.module_path)) + + +class CallDef(object): + """ `CallDef` objects is the return value of `Script.get_in_function_call`. + It knows what functions you are currently in. e.g. `isinstance(` would + return the `isinstance` function. without `(` it would return nothing.""" + def __init__(self, executable, index, call): + self.executable = executable + self.index = index + self.call = call + + @property + def params(self): + if self.executable.isinstance(evaluate.Function): + if isinstance(self.executable, evaluate.InstanceElement): + return self.executable.params[1:] + return self.executable.params + else: + try: + sub = self.executable.get_subscope_by_name('__init__') + return sub.params[1:] # ignore self + except KeyError: + return [] + + @property + def bracket_start(self): + """ The indent of the bracket that is responsible for the last function + call. """ + c = self.call + while c.next is not None: + c = c.next + return c.name.end_pos + + @property + def call_name(self): + """ The name (e.g. 'isinstance') as a string. """ + return str(self.executable.name) + + @property + def module(self): + return self.executable.get_parent_until() + + def __repr__(self): + return '<%s: %s index %s>' % (type(self).__name__, self.executable, + self.index) diff --git a/common/.local/lib/python2.7/site-packages/jedi/builtin.py b/common/.local/lib/python2.7/site-packages/jedi/builtin.py new file mode 100644 index 0000000..da4fc56 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/builtin.py @@ -0,0 +1,472 @@ +from __future__ import with_statement +from _compatibility import exec_function, is_py3k + +import re +import sys +import os +if is_py3k: + import io +import types +import inspect + +import debug +import parsing +import imports +import evaluate + + +def get_sys_path(): + def check_virtual_env(sys_path): + """ Add virtualenv's site-packages to the `sys.path`.""" + venv = os.getenv('VIRTUAL_ENV') + if not venv: + return + venv = os.path.abspath(venv) + p = os.path.join( + venv, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages') + sys_path.insert(0, p) + + p = sys.path[1:] + check_virtual_env(p) + return p + + +class CachedModule(object): + """ + The base type for all modules, which is not to be confused with + `parsing.Module`. Caching happens here. + """ + cache = {} + + def __init__(self, path=None, name=None): + self.path = path and os.path.abspath(path) + self.name = name + self._parser = None + + @property + def parser(self): + """ get the parser lazy """ + if not self._parser: + try: + timestamp, parser = self.cache[self.path or self.name] + if not self.path or os.path.getmtime(self.path) <= timestamp: + self._parser = parser + else: + # In case there is already a module cached and this module + # has to be reparsed, we also need to invalidate the import + # caches. + imports.invalidate_star_import_cache(parser.module) + raise KeyError() + except KeyError: + self._load_module() + return self._parser + + def _get_source(self): + raise NotImplementedError() + + def _load_module(self): + source = self._get_source() + self._parser = parsing.PyFuzzyParser(source, self.path or self.name) + p_time = None if not self.path else os.path.getmtime(self.path) + + if self.path or self.name: + self.cache[self.path or self.name] = p_time, self._parser + + +class Parser(CachedModule): + """ + This module is a parser for all builtin modules, which are programmed in + C/C++. It should also work on third party modules. + It can be instantiated with either a path or a name of the module. The path + is important for third party modules. + + :param name: The name of the module. + :param path: The path of the module. + :param sys_path: The sys.path, which is can be customizable. + """ + + map_types = { + 'floating point number': '0.0', + 'string': '""', + 'str': '""', + 'character': '"a"', + 'integer': '0', + 'int': '0', + 'dictionary': '{}', + 'list': '[]', + 'file object': 'file("")', + # TODO things like dbg: ('not working', 'tuple of integers') + } + + if is_py3k: + map_types['file object'] = 'import io; return io.TextIOWrapper()' + + module_cache = {} + + def __init__(self, path=None, name=None, sys_path=None): + if sys_path is None: + sys_path = get_sys_path() + if not name: + name = os.path.basename(path) + name = name.rpartition('.')[0] # cut file type (normally .so) + super(Parser, self).__init__(path=path, name=name) + + self.sys_path = list(sys_path) + self._module = None + + @property + def module(self): + def load_module(name, path): + if path: + self.sys_path.insert(0, path) + + temp, sys.path = sys.path, self.sys_path + content = {} + try: + exec_function('import %s as module' % name, content) + self._module = content['module'] + except AttributeError: + # use sys.modules, because you cannot access some modules + # directly. -> #59 + self._module = sys.modules[name] + sys.path = temp + + if path: + self.sys_path.pop(0) + + # module might already be defined + if not self._module: + path = self.path + name = self.name + if self.path: + + dot_path = [] + p = self.path + # search for the builtin with the correct path + while p and p not in sys.path: + p, sep, mod = p.rpartition(os.path.sep) + dot_path.append(mod.partition('.')[0]) + if p: + name = ".".join(reversed(dot_path)) + path = p + else: + path = os.path.dirname(self.path) + + load_module(name, path) + return self._module + + def _get_source(self): + """ Override this abstract method """ + return _generate_code(self.module, self._load_mixins()) + + def _load_mixins(self): + """ + Load functions that are mixed in to the standard library. + E.g. builtins are written in C (binaries), but my autocompletion only + understands Python code. By mixing in Python code, the autocompletion + should work much better for builtins. + """ + regex = r'^(def|class)\s+([\w\d]+)' + + def process_code(code, depth=0): + funcs = {} + matches = list(re.finditer(regex, code, re.MULTILINE)) + positions = [m.start() for m in matches] + for i, pos in enumerate(positions): + try: + code_block = code[pos:positions[i + 1]] + except IndexError: + code_block = code[pos:len(code)] + structure_name = matches[i].group(1) + name = matches[i].group(2) + if structure_name == 'def': + funcs[name] = code_block + elif structure_name == 'class': + if depth > 0: + raise NotImplementedError() + + # remove class line + c = re.sub(r'^[^\n]+', '', code_block) + # remove whitespace + c = re.compile(r'^[ ]{4}', re.MULTILINE).sub('', c) + + funcs[name] = process_code(c) + else: + raise NotImplementedError() + return funcs + + try: + name = self.name + if name == '__builtin__' and not is_py3k: + name = 'builtins' + path = os.path.dirname(os.path.abspath(__file__)) + with open(os.path.sep.join([path, 'mixin', name]) + '.pym') as f: + s = f.read() + except IOError: + return {} + else: + mixin_dct = process_code(s) + if is_py3k and self.name == Builtin.name: + # in the case of Py3k xrange is now range + mixin_dct['range'] = mixin_dct['xrange'] + return mixin_dct + + +def _generate_code(scope, mixin_funcs={}, depth=0): + """ + Generate a string, which uses python syntax as an input to the + PyFuzzyParser. + """ + def get_doc(obj, indent=False): + doc = inspect.getdoc(obj) + if doc: + doc = ('r"""\n%s\n"""\n' % doc) + if indent: + doc = parsing.indent_block(doc) + return doc + return '' + + def is_in_base_classes(cls, name, comparison): + """ Base classes may contain the exact same object """ + if name in mixin_funcs: + return False + try: + mro = cls.mro() + except TypeError: + # this happens, if cls == type + return False + for base in mro[1:]: + try: + attr = getattr(base, name) + except AttributeError: + continue + if attr == comparison: + return True + return False + + def get_scope_objects(names): + """ + Looks for the names defined with dir() in an objects and divides + them into different object types. + """ + classes = {} + funcs = {} + stmts = {} + members = {} + for n in names: + try: + # this has a builtin_function_or_method + exe = getattr(scope, n) + except AttributeError: + # happens e.g. in properties of + # PyQt4.QtGui.QStyleOptionComboBox.currentText + # -> just set it to None + members[n] = None + else: + if inspect.isclass(scope): + if is_in_base_classes(scope, n, exe): + continue + if inspect.isbuiltin(exe) or inspect.ismethod(exe) \ + or inspect.ismethoddescriptor(exe): + funcs[n] = exe + elif inspect.isclass(exe): + classes[n] = exe + elif inspect.ismemberdescriptor(exe): + members[n] = exe + else: + stmts[n] = exe + return classes, funcs, stmts, members + + code = '' + if inspect.ismodule(scope): # generate comment where the code's from. + try: + path = scope.__file__ + except AttributeError: + path = '?' + code += '# Generated module %s from %s\n' % (scope.__name__, path) + + code += get_doc(scope) + + names = set(dir(scope)) - set(['__file__', '__name__', '__doc__', + '__path__', '__package__']) \ + | set(['mro']) + + classes, funcs, stmts, members = get_scope_objects(names) + + # classes + for name, cl in classes.items(): + bases = (c.__name__ for c in cl.__bases__) + code += 'class %s(%s):\n' % (name, ','.join(bases)) + if depth == 0: + try: + mixin = mixin_funcs[name] + except KeyError: + mixin = {} + cl_code = _generate_code(cl, mixin, depth + 1) + code += parsing.indent_block(cl_code) + code += '\n' + + # functions + for name, func in funcs.items(): + params, ret = parse_function_doc(func) + if depth > 0: + params = 'self, ' + params + doc_str = get_doc(func, indent=True) + try: + mixin = mixin_funcs[name] + except KeyError: + # normal code generation + code += 'def %s(%s):\n' % (name, params) + code += doc_str + code += parsing.indent_block('%s\n\n' % ret) + else: + # generation of code with mixins + # the parser only supports basic functions with a newline after + # the double dots + # find doc_str place + pos = re.search(r'\):\s*\n', mixin).end() + if pos is None: + raise Exception("Builtin function not parsed correctly") + code += mixin[:pos] + doc_str + mixin[pos:] + + # class members (functions) properties? + for name, func in members.items(): + # recursion problem in properties TODO remove + if name in ['fget', 'fset', 'fdel']: + continue + ret = 'pass' + code += '@property\ndef %s(self):\n' % (name) + code += parsing.indent_block(get_doc(func) + '%s\n\n' % ret) + + # variables + for name, value in stmts.items(): + if is_py3k: + file_type = io.TextIOWrapper + else: + file_type = types.FileType + if type(value) == file_type: + value = 'open()' + elif name == 'None': + value = '' + elif type(value).__name__ in ['int', 'bool', 'float', + 'dict', 'list', 'tuple']: + value = repr(value) + else: + # get the type, if the type is not simple. + mod = type(value).__module__ + value = type(value).__name__ + '()' + if mod != '__builtin__': + value = '%s.%s' % (mod, value) + code += '%s = %s\n' % (name, value) + + if depth == 0: + #with open('writeout.py', 'w') as f: + # f.write(code) + #import sys + #sys.stdout.write(code) + #exit() + pass + return code + + +def parse_function_doc(func): + """ + Takes a function and returns the params and return value as a tuple. + This is nothing more than a docstring parser. + """ + # TODO: things like utime(path, (atime, mtime)) and a(b [, b]) -> None + doc = inspect.getdoc(func) + + # get full string, parse round parentheses: def func(a, (b,c)) + try: + count = 0 + debug.dbg(func, func.__name__, doc) + start = doc.index('(') + for i, s in enumerate(doc[start:]): + if s == '(': + count += 1 + elif s == ')': + count -= 1 + if count == 0: + end = start + i + break + param_str = doc[start + 1:end] + + # remove square brackets, that show an optional param ( = None) + def change_options(m): + args = m.group(1).split(',') + for i, a in enumerate(args): + if a and '=' not in a: + args[i] += '=None' + return ','.join(args) + while True: + param_str, changes = re.subn(r' ?\[([^\[\]]+)\]', + change_options, param_str) + if changes == 0: + break + except (ValueError, AttributeError): + debug.dbg('no brackets found - no param') + end = 0 + param_str = '' + + param_str = param_str.replace('-', '_') # see: isinstance.__doc__ + + if doc is not None: + r = re.search('-[>-]* ', doc[end:end + 7]) + if doc is None or r is None: + ret = 'pass' + else: + index = end + r.end() + # get result type, which can contain newlines + pattern = re.compile(r'(,\n|[^\n-])+') + ret_str = pattern.match(doc, index).group(0).strip() + # New object -> object() + ret_str = re.sub(r'[nN]ew (.*)', r'\1()', ret_str) + + ret = Parser.map_types.get(ret_str, ret_str) + if ret == ret_str and ret not in ['None', 'object', 'tuple', 'set']: + debug.dbg('not working', ret_str) + if ret != 'pass': + ret = ('return ' if 'return' not in ret else '') + ret + return param_str, ret + + +class Builtin(object): + """ The builtin scope / module """ + # Python 3 compatibility + if is_py3k: + name = 'builtins' + else: + name = '__builtin__' + + _builtin = None + + @property + def builtin(self): + if self._builtin is None: + self._builtin = Parser(name=self.name) + return self._builtin + + @property + def scope(self): + return self.builtin.parser.module + + @property + def magic_function_scope(self): + try: + return self._magic_function_scope + except AttributeError: + # depth = 1 because this is not a module + class Container(object): + FunctionType = types.FunctionType + source = _generate_code(Container, depth=0) + parser = parsing.PyFuzzyParser(source, None) + module = parser.module + module.parent = self.scope + typ = evaluate.follow_path(iter(['FunctionType']), module, module) + + s = self._magic_function_scope = typ.pop() + return s + + +Builtin = Builtin() diff --git a/common/.local/lib/python2.7/site-packages/jedi/debug.py b/common/.local/lib/python2.7/site-packages/jedi/debug.py new file mode 100644 index 0000000..321ffa8 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/debug.py @@ -0,0 +1,64 @@ +import inspect +import time + +try: + # Use colorama for nicer console output. + from colorama import Fore, init + init() +except ImportError: + class Fore(object): + RED = '' + GREEN = '' + YELLOW = '' + RESET = '' + +NOTICE = object() +WARNING = object() +SPEED = object() + +enable_speed = False +enable_warning = False +enable_notice = False + +# callback, interface: level, str +debug_function = None +ignored_modules = ['parsing', 'builtin', 'jedi.builtin', 'jedi.parsing'] + + +def reset_time(): + global start_time + start_time = time.time() + + +def dbg(*args): + """ Looks at the stack, to see if a debug message should be printed. """ + if debug_function and enable_notice: + frm = inspect.stack()[1] + mod = inspect.getmodule(frm[0]) + if not (mod.__name__ in ignored_modules): + debug_function(NOTICE, 'dbg: ' + ', '.join(str(a) for a in args)) + + +def warning(*args): + if debug_function and enable_warning: + debug_function(WARNING, 'warning: ' + ', '.join(str(a) for a in args)) + + +def speed(name): + if debug_function and enable_speed: + now = time.time() + debug_function(SPEED, 'speed: ' + '%s %s' % (name, now - start_time)) + + +def print_to_stdout(level, str_out): + """ The default debug function """ + if level == NOTICE: + col = Fore.GREEN + elif level == WARNING: + col = Fore.RED + else: + col = Fore.YELLOW + print(col + str_out + Fore.RESET) + + +#debug_function = print_to_stdout diff --git a/common/.local/lib/python2.7/site-packages/jedi/docstrings.py b/common/.local/lib/python2.7/site-packages/jedi/docstrings.py new file mode 100644 index 0000000..29bf0d2 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/docstrings.py @@ -0,0 +1,34 @@ +""" Processing of docstrings, which means parsing for types. """ + +import re + +import evaluate + + +#@evaluate.memoize_default() # TODO add +def follow_param(param): + func = param.parent_function + #print func, param, param.parent_function + param_str = search_param_in_docstr(func.docstr, str(param.get_name())) + + if param_str is not None: + scope = func.get_parent_until() + return evaluate.get_scopes_for_name(scope, param_str, + search_global=True) + return [] + + +def search_param_in_docstr(docstr, param_str): + lines = docstr.split('\n') + + # look at #40 to see definitions of those params + sphinx_comp = ':type %s:' % param_str + googley_comp = re.compile('\s*%s\s+\(([^()]+)\)' % re.escape(param_str)) + for l in lines: + if l.startswith(sphinx_comp): + return l.replace(sphinx_comp, '', 1).strip() + + r = re.match(googley_comp, l) + if r is not None: + return r.group(1) + return None diff --git a/common/.local/lib/python2.7/site-packages/jedi/dynamic.py b/common/.local/lib/python2.7/site-packages/jedi/dynamic.py new file mode 100644 index 0000000..2e77546 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/dynamic.py @@ -0,0 +1,507 @@ +""" +For dynamic completion. + +Sorry to everyone who is reading this code. Especially the array parts are +really cryptic and not understandable. It's just a hack, that turned out to be +working quite good. +""" +from __future__ import with_statement + +import os + +import parsing +import modules +import evaluate +import helpers +import settings +import debug +import builtin +import imports +import api_classes + +# This is something like the sys.path, but only for searching params. It means +# that this is the order in which Jedi searches params. +search_param_modules = ['.'] +search_param_cache = {} + + +def get_directory_modules_for_name(mods, name): + """ + Search a name in the directories of modules. + """ + def check_python_file(path): + try: + return builtin.CachedModule.cache[path][1].module + except KeyError: + try: + return check_fs(path) + except IOError: + return None + + def check_fs(path): + with open(path) as f: + source = f.read() + if name in source: + return modules.Module(path, source).parser.module + + # skip non python modules + mods = set(m for m in mods if m.path.endswith('.py')) + mod_paths = set() + for m in mods: + mod_paths.add(m.path) + yield m + + if settings.dynamic_params_for_other_modules: + paths = set(settings.additional_dynamic_modules) + for p in mod_paths: + d = os.path.dirname(p) + for entry in os.listdir(d): + if entry not in mod_paths: + if entry.endswith('.py'): + paths.add(d + os.path.sep + entry) + + for p in paths: + c = check_python_file(p) + if c is not None and c not in mods: + yield c + + +def search_param_memoize(func): + """ + Is only good for search params memoize, respectively the closure, + because it just caches the input, not the func, like normal memoize does. + """ + def wrapper(*args, **kwargs): + key = (args, frozenset(kwargs.items())) + if key in search_param_cache: + return search_param_cache[key] + else: + rv = func(*args, **kwargs) + search_param_cache[key] = rv + return rv + return wrapper + + +class ParamListener(object): + """ + This listener is used to get the params for a function. + """ + def __init__(self): + self.param_possibilities = [] + + def execute(self, params): + self.param_possibilities.append(params) + + +@evaluate.memoize_default([]) +def search_params(param): + """ + This is a dynamic search for params. If you try to complete a type: + >>> def func(foo): + >>> # here is the completion + >>> foo + >>> func(1) + >>> func("") + + It is not known what the type is, because it cannot be guessed with + recursive madness. Therefore one has to analyse the statements that are + calling the function, as well as analyzing the incoming params. + """ + if not settings.dynamic_params: + return [] + + def get_params_for_module(module): + """ + Returns the values of a param, or an empty array. + """ + @search_param_memoize + def get_posibilities(module, func_name): + try: + possible_stmts = module.used_names[func_name] + except KeyError: + return [] + + for stmt in possible_stmts: + if not isinstance(stmt, parsing.Import): + calls = _scan_array(stmt.get_assignment_calls(), func_name) + for c in calls: + # no execution means that params cannot be set + call_path = c.generate_call_path() + pos = c.start_pos + scope = stmt.parent + evaluate.follow_call_path(call_path, scope, pos) + return listener.param_possibilities + + result = [] + for params in get_posibilities(module, func_name): + for p in params: + if str(p) == param_name: + result += evaluate.follow_statement(p.parent) + return result + + func = param.get_parent_until(parsing.Function) + current_module = param.get_parent_until() + func_name = str(func.name) + if func_name == '__init__' and isinstance(func.parent, parsing.Class): + func_name = str(func.parent.name) + + # get the param name + if param.assignment_details: + arr = param.assignment_details[0][1] + else: + arr = param.get_assignment_calls() + offset = 1 if arr[0][0] in ['*', '**'] else 0 + param_name = str(arr[0][offset].name) + + # add the listener + listener = ParamListener() + func.listeners.add(listener) + + result = [] + # This is like backtracking: Get the first possible result. + for mod in get_directory_modules_for_name([current_module], func_name): + result = get_params_for_module(mod) + if result: + break + + # cleanup: remove the listener; important: should not stick. + func.listeners.remove(listener) + + return result + + +def check_array_additions(array): + """ Just a mapper function for the internal _check_array_additions """ + if array._array.type not in ['list', 'set']: + # TODO also check for dict updates + return [] + + is_list = array._array.type == 'list' + current_module = array._array.parent_stmt.get_parent_until() + res = _check_array_additions(array, current_module, is_list) + return res + + +def _scan_array(arr, search_name): + """ Returns the function Call that match search_name in an Array. """ + result = [] + for sub in arr: + for s in sub: + if isinstance(s, parsing.Array): + result += _scan_array(s, search_name) + elif isinstance(s, parsing.Call): + s_new = s + while s_new is not None: + n = s_new.name + if isinstance(n, parsing.Name) and search_name in n.names: + result.append(s) + + if s_new.execution is not None: + result += _scan_array(s_new.execution, search_name) + s_new = s_new.next + return result + + +counter = 0 +def dec(func): + """ TODO delete this """ + def wrapper(*args, **kwargs): + global counter + element = args[0] + if isinstance(element, evaluate.Array): + stmt = element._array.parent_stmt + else: + # must be instance + stmt = element.var_args.parent_stmt + print(' ' * counter + 'recursion,', stmt) + counter += 1 + res = func(*args, **kwargs) + counter -= 1 + #print ' '*counter + 'end,' + return res + return wrapper + + +#@dec +@evaluate.memoize_default([]) +def _check_array_additions(compare_array, module, is_list): + """ + Checks if a `parsing.Array` has "add" statements: + >>> a = [""] + >>> a.append(1) + """ + if not settings.dynamic_array_additions or module.is_builtin(): + return [] + + def check_calls(calls, add_name): + """ + Calls are processed here. The part before the call is searched and + compared with the original Array. + """ + result = [] + for c in calls: + call_path = list(c.generate_call_path()) + separate_index = call_path.index(add_name) + if add_name == call_path[-1] or separate_index == 0: + # this means that there is no execution -> [].append + # or the keyword is at the start -> append() + continue + backtrack_path = iter(call_path[:separate_index]) + + position = c.start_pos + scope = c.parent_stmt.parent + + found = evaluate.follow_call_path(backtrack_path, scope, position) + if not compare_array in found: + continue + + params = call_path[separate_index + 1] + if not params.values: + continue # no params: just ignore it + if add_name in ['append', 'add']: + result += evaluate.follow_call_list(params) + elif add_name in ['insert']: + try: + second_param = params[1] + except IndexError: + continue + else: + result += evaluate.follow_call_list([second_param]) + elif add_name in ['extend', 'update']: + iterators = evaluate.follow_call_list(params) + result += evaluate.get_iterator_types(iterators) + return result + + def get_execution_parent(element, *stop_classes): + """ Used to get an Instance/Execution parent """ + if isinstance(element, evaluate.Array): + stmt = element._array.parent_stmt + else: + # must be instance + stmt = element.var_args.parent_stmt + if isinstance(stmt, evaluate.InstanceElement): + stop_classes = list(stop_classes) + [evaluate.Function] + return stmt.get_parent_until(stop_classes) + + temp_param_add = settings.dynamic_params_for_other_modules + settings.dynamic_params_for_other_modules = False + + search_names = ['append', 'extend', 'insert'] if is_list else \ + ['add', 'update'] + comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution) + possible_stmts = [] + res = [] + for n in search_names: + try: + possible_stmts += module.used_names[n] + except KeyError: + continue + for stmt in possible_stmts: + # Check if the original scope is an execution. If it is, one + # can search for the same statement, that is in the module + # dict. Executions are somewhat special in jedi, since they + # literally copy the contents of a function. + if isinstance(comp_arr_parent, evaluate.Execution): + stmt = comp_arr_parent. \ + get_statement_for_position(stmt.start_pos) + if stmt is None: + continue + # InstanceElements are special, because they don't get copied, + # but have this wrapper around them. + if isinstance(comp_arr_parent, evaluate.InstanceElement): + stmt = evaluate.InstanceElement(comp_arr_parent.instance, stmt) + + if evaluate.follow_statement.push_stmt(stmt): + # check recursion + continue + res += check_calls(_scan_array(stmt.get_assignment_calls(), n), n) + evaluate.follow_statement.pop_stmt() + # reset settings + settings.dynamic_params_for_other_modules = temp_param_add + return res + + +def check_array_instances(instance): + """ Used for set() and list() instances. """ + if not settings.dynamic_arrays_instances: + return instance.var_args + ai = ArrayInstance(instance) + return helpers.generate_param_array([ai], instance.var_args.parent_stmt) + + +class ArrayInstance(parsing.Base): + """ + Used for the usage of set() and list(). + This is definitely a hack, but a good one :-) + It makes it possible to use set/list conversions. + """ + def __init__(self, instance): + self.instance = instance + self.var_args = instance.var_args + + def iter_content(self): + """ + The index is here just ignored, because of all the appends, etc. + lists/sets are too complicated too handle that. + """ + items = [] + for array in evaluate.follow_call_list(self.var_args): + if isinstance(array, evaluate.Instance) and len(array.var_args): + temp = array.var_args[0][0] + if isinstance(temp, ArrayInstance): + # prevent recursions + # TODO compare Modules + if self.var_args.start_pos != temp.var_args.start_pos: + items += temp.iter_content() + else: + debug.warning('ArrayInstance recursion', self.var_args) + continue + items += evaluate.get_iterator_types([array]) + + if self.var_args.parent_stmt is None: + return [] # generated var_args should not be checked for arrays + + module = self.var_args.parent_stmt.get_parent_until() + is_list = str(self.instance.name) == 'list' + items += _check_array_additions(self.instance, module, is_list) + return items + + +def related_names(definitions, search_name, mods): + def check_call(call): + result = [] + follow = [] # There might be multiple search_name's in one call_path + call_path = list(call.generate_call_path()) + for i, name in enumerate(call_path): + # name is `parsing.NamePart`. + if name == search_name: + follow.append(call_path[:i + 1]) + + for f in follow: + follow_res, search = evaluate.goto(call.parent_stmt, f) + follow_res = related_name_add_import_modules(follow_res, search) + + #print follow_res, [d.parent for d in follow_res] + # compare to see if they match + if any(r in definitions for r in follow_res): + scope = call.parent_stmt + result.append(api_classes.RelatedName(search, scope)) + + return result + + if not definitions: + return set() + + def is_definition(arr): + try: + for a in arr: + assert len(a) == 1 + a = a[0] + if a.isinstance(parsing.Array): + assert is_definition(a) + elif a.isinstance(parsing.Call): + assert a.execution is None + return True + except AssertionError: + return False + + mods |= set([d.get_parent_until() for d in definitions]) + names = [] + for m in get_directory_modules_for_name(mods, search_name): + try: + stmts = m.used_names[search_name] + except KeyError: + continue + for stmt in stmts: + if isinstance(stmt, parsing.Import): + count = 0 + imps = [] + for i in stmt.get_all_import_names(): + for name_part in i.names: + count += 1 + if name_part == search_name: + imps.append((count, name_part)) + + for used_count, name_part in imps: + i = imports.ImportPath(stmt, kill_count=count - used_count, + direct_resolve=True) + f = i.follow(is_goto=True) + if set(f) & set(definitions): + names.append(api_classes.RelatedName(name_part, stmt)) + else: + calls = _scan_array(stmt.get_assignment_calls(), search_name) + for d in stmt.assignment_details: + if not is_definition(d[1]): + calls += _scan_array(d[1], search_name) + for call in calls: + names += check_call(call) + return names + + +def related_name_add_import_modules(definitions, search_name): + """ Adds the modules of the imports """ + new = set() + for d in definitions: + if isinstance(d.parent, parsing.Import): + s = imports.ImportPath(d.parent, direct_resolve=True) + try: + new.add(s.follow(is_goto=True)[0]) + except IndexError: + pass + return set(definitions) | new + + +def check_flow_information(flow, search_name, pos): + """ Try to find out the type of a variable just with the information that + is given by the flows: e.g. It is also responsible for assert checks. + >>> if isinstance(k, str): + >>> k. # <- completion here + + ensures that `k` is a string. + """ + result = [] + if isinstance(flow, parsing.Scope) and not result: + for ass in reversed(flow.asserts): + if pos is None or ass.start_pos > pos: + continue + result = check_statement_information(ass, search_name) + if result: + break + + if isinstance(flow, parsing.Flow) and not result: + if flow.command in ['if', 'while'] and len(flow.inits) == 1: + result = check_statement_information(flow.inits[0], search_name) + return result + + +def check_statement_information(stmt, search_name): + try: + ass = stmt.get_assignment_calls() + try: + call = ass.get_only_subelement() + except AttributeError: + assert False + assert type(call) == parsing.Call and str(call.name) == 'isinstance' + assert bool(call.execution) + + # isinstance check + isinst = call.execution.values + assert len(isinst) == 2 # has two params + assert len(isinst[0]) == 1 + assert len(isinst[1]) == 1 + assert isinstance(isinst[0][0], parsing.Call) + # names fit? + assert str(isinst[0][0].name) == search_name + classes_call = isinst[1][0] # class_or_type_or_tuple + assert isinstance(classes_call, parsing.Call) + result = [] + for c in evaluate.follow_call(classes_call): + if isinstance(c, evaluate.Array): + result += c.get_index_types() + else: + result.append(c) + for i, c in enumerate(result): + result[i] = evaluate.Instance(c) + return result + except AssertionError: + return [] diff --git a/common/.local/lib/python2.7/site-packages/jedi/evaluate.py b/common/.local/lib/python2.7/site-packages/jedi/evaluate.py new file mode 100644 index 0000000..5b3d212 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/evaluate.py @@ -0,0 +1,1614 @@ +""" +This is the core part of jedi. Most of the logic, how to evaluate certain +objects (imports, etc.) is here. + +The functions should be described in their docstrings. However, there are some +classes, which are used to store the values. After those classes, there are the +search functions `get_names_for_scope` and `get_scopes_for_name`. At the end +there are the `follow_` functions, which evaluate a statement, or parts of a +statement. + +TODO super() +TODO nonlocal statement, needed or can be ignored? (py3k) +""" +from _compatibility import next, property, hasattr, is_py3k, use_metaclass, \ + unicode + +import sys +import itertools +import copy + +import parsing +import debug +import builtin +import imports +import helpers +import dynamic +import docstrings + +memoize_caches = [] +faked_scopes = [] + + +class DecoratorNotFound(LookupError): + """ + Decorators are sometimes not found, if that happens, that error is raised. + """ + pass + + +class MultiLevelStopIteration(Exception): + """ + StopIteration's get catched pretty easy by for loops, let errors propagate. + """ + pass + + +class MultiLevelAttributeError(Exception): + """ + Important, because `__getattr__` and `hasattr` catch AttributeErrors + implicitly. This is really evil (mainly because of `__getattr__`). + `hasattr` in Python 2 is even more evil, because it catches ALL exceptions. + Therefore this class has to be a `BaseException` and not an `Exception`. + But because I rewrote hasattr, we can now switch back to `Exception`. + + :param base: return values of sys.exc_info(). + """ + def __init__(self, base): + self.base = base + + def __str__(self): + import traceback + tb = traceback.format_exception(*self.base) + return 'Original:\n\n' + ''.join(tb) + + +def clear_caches(): + """ + Clears all caches of this and related modules. Jedi caches many things, + that should be completed after each completion finishes. The only things + that stays is the module cache (which is not deleted here). + """ + global memoize_caches, faked_scopes + + for m in memoize_caches: + m.clear() + + dynamic.search_param_cache.clear() + helpers.ExecutionRecursionDecorator.reset() + + # memorize_caches must never be deleted, because the dicts will get lost in + # the wrappers. + faked_scopes = [] + + follow_statement.reset() + + imports.imports_processed = 0 + + +def memoize_default(default=None): + """ + This is a typical memoization decorator, BUT there is one difference: + To prevent recursion it sets defaults. + + Preventing recursion is in this case the much bigger use than speed. I + don't think, that there is a big speed difference, but there are many cases + where recursion could happen (think about a = b; b = a). + """ + def func(function): + memo = {} + memoize_caches.append(memo) + + def wrapper(*args, **kwargs): + key = (args, frozenset(kwargs.items())) + if key in memo: + return memo[key] + else: + memo[key] = default + rv = function(*args, **kwargs) + memo[key] = rv + return rv + return wrapper + return func + + +class CachedMetaClass(type): + """ + This is basically almost the same than the decorator above, it just caches + class initializations. I haven't found any other way, so I do it with meta + classes. + """ + @memoize_default() + def __call__(self, *args, **kwargs): + return super(CachedMetaClass, self).__call__(*args, **kwargs) + + +class Executable(parsing.Base): + """ An instance is also an executable - because __init__ is called """ + def __init__(self, base, var_args=None): + self.base = base + # The param input array. + if var_args is None: + var_args = parsing.Array(None, None) + self.var_args = var_args + + def get_parent_until(self, *args, **kwargs): + return self.base.get_parent_until(*args, **kwargs) + + @property + def parent(self): + return self.base.parent + + +class Instance(use_metaclass(CachedMetaClass, Executable)): + """ This class is used to evaluate instances. """ + def __init__(self, base, var_args=None): + super(Instance, self).__init__(base, var_args) + if str(base.name) in ['list', 'set'] \ + and builtin.Builtin.scope == base.get_parent_until(): + # compare the module path with the builtin name. + self.var_args = dynamic.check_array_instances(self) + else: + # need to execute the __init__ function, because the dynamic param + # searching needs it. + try: + self.execute_subscope_by_name('__init__', self.var_args) + except KeyError: + pass + # Generated instances are classes that are just generated by self + # (No var_args) used. + self.is_generated = False + + @memoize_default() + def get_init_execution(self, func): + func = InstanceElement(self, func, True) + return Execution(func, self.var_args) + + def get_func_self_name(self, func): + """ + Returns the name of the first param in a class method (which is + normally self + """ + try: + return func.params[0].used_vars[0].names[0] + except IndexError: + return None + + def get_self_properties(self): + def add_self_dot_name(name): + n = copy.copy(name) + n.names = n.names[1:] + names.append(InstanceElement(self, n)) + + names = [] + # This loop adds the names of the self object, copies them and removes + # the self. + for sub in self.base.subscopes: + if isinstance(sub, parsing.Class): + continue + # Get the self name, if there's one. + self_name = self.get_func_self_name(sub) + if self_name: + # Check the __init__ function. + if sub.name.get_code() == '__init__': + sub = self.get_init_execution(sub) + for n in sub.get_set_vars(): + # Only names with the selfname are being added. + # It is also important, that they have a len() of 2, + # because otherwise, they are just something else + if n.names[0] == self_name and len(n.names) == 2: + add_self_dot_name(n) + + for s in self.base.get_super_classes(): + if s == self.base: + # I don't know how this could happen... But saw it once. + continue + names += Instance(s).get_self_properties() + + return names + + def get_subscope_by_name(self, name): + sub = self.base.get_subscope_by_name(name) + return InstanceElement(self, sub, True) + + def execute_subscope_by_name(self, name, args=None): + if args is None: + args = helpers.generate_param_array([]) + method = self.get_subscope_by_name(name) + if args.parent_stmt is None: + args.parent_stmt = method + return Execution(method, args).get_return_types() + + def get_descriptor_return(self, obj): + """ Throws a KeyError if there's no method. """ + # Arguments in __get__ descriptors are obj, class. + # `method` is the new parent of the array, don't know if that's good. + v = [obj, obj.base] if isinstance(obj, Instance) else [None, obj] + args = helpers.generate_param_array(v) + return self.execute_subscope_by_name('__get__', args) + + @memoize_default([]) + def get_defined_names(self): + """ + Get the instance vars of a class. This includes the vars of all + classes + """ + names = self.get_self_properties() + + class_names = self.base.get_defined_names() + for var in class_names: + names.append(InstanceElement(self, var, True)) + return names + + def scope_generator(self): + """ + An Instance has two scopes: The scope with self names and the class + scope. Instance variables have priority over the class scope. + """ + yield self, self.get_self_properties() + + names = [] + class_names = self.base.get_defined_names() + for var in class_names: + names.append(InstanceElement(self, var, True)) + yield self, names + + def get_index_types(self, index=None): + args = helpers.generate_param_array([] if index is None else [index]) + try: + return self.execute_subscope_by_name('__getitem__', args) + except KeyError: + debug.warning('No __getitem__, cannot access the array.') + return [] + + def __getattr__(self, name): + if name not in ['start_pos', 'end_pos', 'name', 'get_imports', + 'docstr', 'asserts']: + raise AttributeError("Instance %s: Don't touch this (%s)!" + % (self, name)) + return getattr(self.base, name) + + def __repr__(self): + return "" % \ + (type(self).__name__, self.base, len(self.var_args or [])) + + +class InstanceElement(use_metaclass(CachedMetaClass)): + """ + InstanceElement is a wrapper for any object, that is used as an instance + variable (e.g. self.variable or class methods). + """ + def __init__(self, instance, var, is_class_var=False): + if isinstance(var, parsing.Function): + var = Function(var) + elif isinstance(var, parsing.Class): + var = Class(var) + self.instance = instance + self.var = var + self.is_class_var = is_class_var + + @property + @memoize_default() + def parent(self): + par = self.var.parent + if isinstance(par, Class) and par == self.instance.base \ + or isinstance(par, parsing.Class) \ + and par == self.instance.base.base: + par = self.instance + elif not isinstance(par, parsing.Module): + par = InstanceElement(self.instance, par, self.is_class_var) + return par + + def get_parent_until(self, *args, **kwargs): + return parsing.Simple.get_parent_until(self, *args, **kwargs) + + def get_decorated_func(self): + """ Needed because the InstanceElement should not be stripped """ + func = self.var.get_decorated_func() + if func == self.var: + return self + return func + + def get_assignment_calls(self): + # Copy and modify the array. + origin = self.var.get_assignment_calls() + # Delete parent, because it isn't used anymore. + new = helpers.fast_parent_copy(origin) + par = InstanceElement(self.instance, origin.parent_stmt, + self.is_class_var) + new.parent_stmt = par + faked_scopes.append(par) + faked_scopes.append(new) + return new + + def __getattr__(self, name): + return getattr(self.var, name) + + def isinstance(self, *cls): + return isinstance(self.var, cls) + + def __repr__(self): + return "<%s of %s>" % (type(self).__name__, self.var) + + +class Class(use_metaclass(CachedMetaClass, parsing.Base)): + """ + This class is not only important to extend `parsing.Class`, it is also a + important for descriptors (if the descriptor methods are evaluated or not). + """ + def __init__(self, base): + self.base = base + + @memoize_default(default=[]) + def get_super_classes(self): + supers = [] + # TODO care for mro stuff (multiple super classes). + for s in self.base.supers: + # Super classes are statements. + for cls in follow_statement(s): + if not isinstance(cls, Class): + debug.warning('Received non class, as a super class') + continue # Just ignore other stuff (user input error). + supers.append(cls) + if not supers and self.base.parent != builtin.Builtin.scope: + # add `object` to classes + supers += get_scopes_for_name(builtin.Builtin.scope, 'object') + return supers + + @memoize_default(default=[]) + def get_defined_names(self): + def in_iterable(name, iterable): + """ checks if the name is in the variable 'iterable'. """ + for i in iterable: + # Only the last name is important, because these names have a + # maximal length of 2, with the first one being `self`. + if i.names[-1] == name.names[-1]: + return True + return False + + result = self.base.get_defined_names() + super_result = [] + # TODO mro! + for cls in self.get_super_classes(): + # Get the inherited names. + for i in cls.get_defined_names(): + if not in_iterable(i, result): + super_result.append(i) + result += super_result + return result + + def get_subscope_by_name(self, name): + for sub in reversed(self.subscopes): + if sub.name.get_code() == name: + return sub + raise KeyError("Couldn't find subscope.") + + @property + def name(self): + return self.base.name + + def __getattr__(self, name): + if name not in ['start_pos', 'end_pos', 'parent', 'subscopes', + 'get_imports', 'get_parent_until', 'docstr', 'asserts']: + raise AttributeError("Don't touch this (%s)!" % name) + return getattr(self.base, name) + + def __repr__(self): + return "" % (type(self).__name__, self.base) + + +class Function(use_metaclass(CachedMetaClass, parsing.Base)): + """ + Needed because of decorators. Decorators are evaluated here. + """ + + def __init__(self, func, is_decorated=False): + """ This should not be called directly """ + self.base_func = func + self.is_decorated = is_decorated + + @property + @memoize_default() + def _decorated_func(self): + """ + Returns the function, that is to be executed in the end. + This is also the places where the decorators are processed. + """ + f = self.base_func + + # Only enter it, if has not already been processed. + if not self.is_decorated: + for dec in reversed(self.base_func.decorators): + debug.dbg('decorator:', dec, f) + dec_results = follow_statement(dec) + if not len(dec_results): + debug.warning('decorator func not found: %s in stmt %s' % + (self.base_func, dec)) + return None + if len(dec_results) > 1: + debug.warning('multiple decorators found', self.base_func, + dec_results) + decorator = dec_results.pop() + # Create param array. + old_func = Function(f, is_decorated=True) + params = helpers.generate_param_array([old_func], old_func) + faked_scopes.append(old_func) + + wrappers = Execution(decorator, params).get_return_types() + if not len(wrappers): + debug.warning('no wrappers found', self.base_func) + return None + if len(wrappers) > 1: + debug.warning('multiple wrappers found', self.base_func, + wrappers) + # This is here, that the wrapper gets executed. + f = wrappers[0] + + debug.dbg('decorator end', f) + if f != self.base_func and isinstance(f, parsing.Function): + f = Function(f) + return f + + def get_decorated_func(self): + if self._decorated_func is None: + raise DecoratorNotFound() + if self._decorated_func == self.base_func: + return self + return self._decorated_func + + def get_magic_method_names(self): + return builtin.Builtin.magic_function_scope.get_defined_names() + + def get_magic_method_scope(self): + return builtin.Builtin.magic_function_scope + + def __getattr__(self, name): + return getattr(self.base_func, name) + + def __repr__(self): + dec = '' + if self._decorated_func != self.base_func: + dec = " is " + repr(self._decorated_func) + return "" % (type(self).__name__, self.base_func, dec) + + +class Execution(Executable): + """ + This class is used to evaluate functions and their returns. + + This is the most complicated class, because it contains the logic to + transfer parameters. It is even more complicated, because there may be + multiple calls to functions and recursion has to be avoided. But this is + responsibility of the decorators. + """ + @memoize_default(default=[]) + @helpers.ExecutionRecursionDecorator + def get_return_types(self, evaluate_generator=False): + """ Get the return types of a function. """ + stmts = [] + if self.base.parent == builtin.Builtin.scope \ + and not isinstance(self.base, (Generator, Array)): + func_name = str(self.base.name) + + # some implementations of builtins: + if func_name == 'getattr': + # follow the first param + try: + objects = follow_call_list([self.var_args[0]]) + names = follow_call_list([self.var_args[1]]) + except IndexError: + debug.warning('getattr() called with to few args.') + return [] + + for obj in objects: + if not isinstance(obj, (Instance, Class)): + debug.warning('getattr called without instance') + continue + + for name in names: + key = name.var_args.get_only_subelement() + stmts += follow_path(iter([key]), obj, self.base) + return stmts + elif func_name == 'type': + # otherwise it would be a metaclass + if len(self.var_args) == 1: + objects = follow_call_list([self.var_args[0]]) + return [o.base for o in objects if isinstance(o, Instance)] + + if self.base.isinstance(Class): + # There maybe executions of executions. + stmts = [Instance(self.base, self.var_args)] + elif isinstance(self.base, Generator): + return self.base.iter_content() + else: + # Don't do this with exceptions, as usual, because some deeper + # exceptions could be catched - and I wouldn't know what happened. + try: + self.base.returns + except (AttributeError, DecoratorNotFound): + if hasattr(self.base, 'execute_subscope_by_name'): + try: + stmts = self.base.execute_subscope_by_name('__call__', + self.var_args) + except KeyError: + debug.warning("no __call__ func available", self.base) + else: + debug.warning("no execution possible", self.base) + else: + stmts = self._get_function_returns(evaluate_generator) + + debug.dbg('exec result: %s in %s' % (stmts, self)) + + return imports.strip_imports(stmts) + + def _get_function_returns(self, evaluate_generator): + """ A normal Function execution """ + # Feed the listeners, with the params. + for listener in self.base.listeners: + listener.execute(self.get_params()) + func = self.base.get_decorated_func() + if func.is_generator and not evaluate_generator: + return [Generator(func, self.var_args)] + else: + stmts = [] + for r in self.returns: + stmts += follow_statement(r) + return stmts + + @memoize_default(default=[]) + def get_params(self): + """ + This returns the params for an Execution/Instance and is injected as a + 'hack' into the parsing.Function class. + This needs to be here, because Instance can have __init__ functions, + which act the same way as normal functions. + """ + def gen_param_name_copy(param, keys=[], values=[], array_type=None): + """ + Create a param with the original scope (of varargs) as parent. + """ + parent_stmt = self.var_args.parent_stmt + pos = parent_stmt.start_pos if parent_stmt else None + calls = parsing.Array(pos, parsing.Array.NOARRAY, parent_stmt) + calls.values = values + calls.keys = keys + calls.type = array_type + new_param = copy.copy(param) + if parent_stmt is not None: + new_param.parent = parent_stmt + new_param._assignment_calls_calculated = True + new_param._assignment_calls = calls + new_param.is_generated = True + name = copy.copy(param.get_name()) + name.parent = new_param + faked_scopes.append(new_param) + return name + + result = [] + start_offset = 0 + if isinstance(self.base, InstanceElement): + # Care for self -> just exclude it and add the instance + start_offset = 1 + self_name = copy.copy(self.base.params[0].get_name()) + self_name.parent = self.base.instance + result.append(self_name) + + param_dict = {} + for param in self.base.params: + param_dict[str(param.get_name())] = param + # There may be calls, which don't fit all the params, this just ignores + # it. + var_arg_iterator = self.get_var_args_iterator() + + non_matching_keys = [] + keys_used = set() + keys_only = False + for param in self.base.params[start_offset:]: + # The value and key can both be null. There, the defaults apply. + # args / kwargs will just be empty arrays / dicts, respectively. + # Wrong value count is just ignored. If you try to test cases that + # are not allowed in Python, Jedi will maybe not show any + # completions. + key, value = next(var_arg_iterator, (None, None)) + while key: + keys_only = True + try: + key_param = param_dict[str(key)] + except KeyError: + non_matching_keys.append((key, value)) + else: + keys_used.add(str(key)) + result.append(gen_param_name_copy(key_param, + values=[value])) + key, value = next(var_arg_iterator, (None, None)) + + assignments = param.get_assignment_calls().values + assignment = assignments[0] + keys = [] + values = [] + array_type = None + if assignment[0] == '*': + # *args param + array_type = parsing.Array.TUPLE + if value: + values.append(value) + for key, value in var_arg_iterator: + # Iterate until a key argument is found. + if key: + var_arg_iterator.push_back((key, value)) + break + values.append(value) + elif assignment[0] == '**': + # **kwargs param + array_type = parsing.Array.DICT + if non_matching_keys: + keys, values = zip(*non_matching_keys) + else: + # normal param + if value: + values = [value] + else: + if param.assignment_details: + # No value: return the default values. + values = assignments + else: + # If there is no assignment detail, that means there is + # no assignment, just the result. Therefore nothing has + # to be returned. + values = [] + + # Just ignore all the params that are without a key, after one + # keyword argument was set. + if not keys_only or assignment[0] == '**': + keys_used.add(str(key)) + result.append(gen_param_name_copy(param, keys=keys, + values=values, array_type=array_type)) + + if keys_only: + # sometimes param arguments are not completely written (which would + # create an Exception, but we have to handle that). + for k in set(param_dict) - keys_used: + result.append(gen_param_name_copy(param_dict[k])) + return result + + def get_var_args_iterator(self): + """ + Yields a key/value pair, the key is None, if its not a named arg. + """ + def iterate(): + # `var_args` is typically an Array, and not a list. + for var_arg in self.var_args: + # empty var_arg + if len(var_arg) == 0: + yield None, None + # *args + elif var_arg[0] == '*': + arrays = follow_call_list([var_arg[1:]]) + for array in arrays: + if hasattr(array, 'get_contents'): + for field in array.get_contents(): + yield None, field + # **kwargs + elif var_arg[0] == '**': + arrays = follow_call_list([var_arg[1:]]) + for array in arrays: + if hasattr(array, 'get_contents'): + for key, field in array.get_contents(): + # Take the first index. + if isinstance(key, parsing.Name): + name = key + else: + # `parsing`.[Call|Function|Class] lookup. + name = key[0].name + yield name, field + # Normal arguments (including key arguments). + else: + if len(var_arg) > 1 and var_arg[1] == '=': + # This is a named parameter (var_arg[0] is a Call). + yield var_arg[0].name, var_arg[2:] + else: + yield None, var_arg + + return iter(parsing.PushBackIterator(iterate())) + + def get_set_vars(self): + return self.get_defined_names() + + def get_defined_names(self): + """ + Call the default method with the own instance (self implements all + the necessary functions). Add also the params. + """ + return self.get_params() + parsing.Scope.get_set_vars(self) + + def copy_properties(self, prop): + """ + Literally copies a property of a Function. Copying is very expensive, + because it is something like `copy.deepcopy`. However, these copied + objects can be used for the executions, as if they were in the + execution. + """ + # Copy all these lists into this local function. + attr = getattr(self.base, prop) + objects = [] + for element in attr: + copied = helpers.fast_parent_copy(element) + copied.parent = self._scope_copy(copied.parent) + if isinstance(copied, parsing.Function): + copied = Function(copied) + objects.append(copied) + faked_scopes.append(copied) + return objects + + def __getattr__(self, name): + if name not in ['start_pos', 'end_pos', 'imports']: + raise AttributeError('Tried to access %s: %s. Why?' % (name, self)) + return getattr(self.base, name) + + @memoize_default() + def _scope_copy(self, scope): + try: + """ Copies a scope (e.g. if) in an execution """ + # TODO method uses different scopes than the subscopes property. + + # just check the start_pos, sometimes it's difficult with closures + # to compare the scopes directly. + if scope.start_pos == self.start_pos: + return self + else: + copied = helpers.fast_parent_copy(scope) + copied.parent = self._scope_copy(copied.parent) + faked_scopes.append(copied) + return copied + except AttributeError: + raise MultiLevelAttributeError(sys.exc_info()) + + @property + @memoize_default() + def returns(self): + return self.copy_properties('returns') + + @property + @memoize_default() + def asserts(self): + return self.copy_properties('asserts') + + @property + @memoize_default() + def statements(self): + return self.copy_properties('statements') + + @property + @memoize_default() + def subscopes(self): + return self.copy_properties('subscopes') + + def get_statement_for_position(self, pos): + return parsing.Scope.get_statement_for_position(self, pos) + + def __repr__(self): + return "<%s of %s>" % \ + (type(self).__name__, self.base) + + +class Generator(use_metaclass(CachedMetaClass, parsing.Base)): + """ Cares for `yield` statements. """ + def __init__(self, func, var_args): + super(Generator, self).__init__() + self.func = func + self.var_args = var_args + + def get_defined_names(self): + """ + Returns a list of names that define a generator, which can return the + content of a generator. + """ + names = [] + none_pos = (0, 0) + executes_generator = ('__next__', 'send') + for n in ('close', 'throw') + executes_generator: + name = parsing.Name([(n, none_pos)], none_pos, none_pos) + if n in executes_generator: + name.parent = self + names.append(name) + debug.dbg('generator names', names) + return names + + def iter_content(self): + """ returns the content of __iter__ """ + return Execution(self.func, self.var_args).get_return_types(True) + + def get_index_types(self, index=None): + debug.warning('Tried to get array access on a generator', self) + return [] + + @property + def parent(self): + return self.func.parent + + def __repr__(self): + return "<%s of %s>" % (type(self).__name__, self.func) + + +class Array(use_metaclass(CachedMetaClass, parsing.Base)): + """ + Used as a mirror to parsing.Array, if needed. It defines some getter + methods which are important in this module. + """ + def __init__(self, array): + self._array = array + + def get_index_types(self, index_call_list=None): + """ Get the types of a specific index or all, if not given """ + # array slicing + if index_call_list is not None: + if index_call_list and [x for x in index_call_list if ':' in x]: + return [self] + + index_possibilities = list(follow_call_list(index_call_list)) + if len(index_possibilities) == 1: + # This is indexing only one element, with a fixed index number, + # otherwise it just ignores the index (e.g. [1+1]). + try: + # Multiple elements in the array are not wanted. var_args + # and get_only_subelement can raise AttributeErrors. + i = index_possibilities[0].var_args.get_only_subelement() + except AttributeError: + pass + else: + try: + return self.get_exact_index_types(i) + except (IndexError, KeyError): + pass + + result = list(self.follow_values(self._array.values)) + result += dynamic.check_array_additions(self) + return set(result) + + def get_exact_index_types(self, index): + """ Here the index is an int. Raises IndexError/KeyError """ + if self._array.type == parsing.Array.DICT: + old_index = index + index = None + for i, key_elements in enumerate(self._array.keys): + # Because we only want the key to be a string. + if len(key_elements) == 1: + try: + str_key = key_elements.get_code() + except AttributeError: + try: + str_key = key_elements[0].name + except AttributeError: + str_key = None + if old_index == str_key: + index = i + break + if index is None: + raise KeyError('No key found in dictionary') + values = [self._array[index]] + return self.follow_values(values) + + def follow_values(self, values): + """ helper function for the index getters """ + return follow_call_list(values) + + def get_defined_names(self): + """ + This method generates all ArrayElements for one parsing.Array. + It returns e.g. for a list: append, pop, ... + """ + # `array.type` is a string with the type, e.g. 'list'. + scope = get_scopes_for_name(builtin.Builtin.scope, self._array.type)[0] + scope = Instance(scope) + names = scope.get_defined_names() + return [ArrayElement(n) for n in names] + + def get_contents(self): + return self._array + + @property + def parent(self): + """ + Return the builtin scope as parent, because the arrays are builtins + """ + return builtin.Builtin.scope + + def get_parent_until(self, *args, **kwargs): + return builtin.Builtin.scope + + def __getattr__(self, name): + if name not in ['type', 'start_pos']: + raise AttributeError('Strange access: %s.' % name) + return getattr(self._array, name) + + def __repr__(self): + return "" % (type(self).__name__, self._array) + + +class ArrayElement(object): + """ + A name, e.g. `list.append`, it is used to access to original array methods. + """ + def __init__(self, name): + super(ArrayElement, self).__init__() + self.name = name + + def __getattr__(self, name): + # Set access privileges: + if name not in ['parent', 'names', 'start_pos', 'end_pos', 'get_code']: + raise AttributeError('Strange access: %s.' % name) + return getattr(self.name, name) + + def get_parent_until(self): + return builtin.Builtin.scope + + def __repr__(self): + return "<%s of %s>" % (type(self).__name__, self.name) + + +def get_defined_names_for_position(scope, position=None, start_scope=None): + """ + Deletes all names that are ahead of the position, except for some special + objects like instances, where the position doesn't matter. + + :param position: the position as a line/column tuple, default is infinity. + """ + names = scope.get_defined_names() + # Instances have special rules, always return all the possible completions, + # because class variables are always valid and the `self.` variables, too. + if (not position or isinstance(scope, (Array, Instance)) + or start_scope != scope + and isinstance(start_scope, (parsing.Function, Execution))): + return names + names_new = [] + for n in names: + if n.start_pos[0] is not None and n.start_pos < position: + names_new.append(n) + return names_new + + +def get_names_for_scope(scope, position=None, star_search=True, + include_builtin=True): + """ + Get all completions possible for the current scope. + The star search option is only here to provide an optimization. Otherwise + the whole thing would probably start a little recursive madness. + """ + in_func_scope = scope + non_flow = scope.get_parent_until(parsing.Flow, reverse=True, + include_current=True) + while scope: + # `parsing.Class` is used, because the parent is never `Class`. + # Ignore the Flows, because the classes and functions care for that. + # InstanceElement of Class is ignored, if it is not the start scope. + if not (scope != non_flow and scope.isinstance(parsing.Class) + or scope.isinstance(parsing.Flow) + or scope.isinstance(Instance) + and non_flow.isinstance(Function) + ): + try: + if isinstance(scope, Instance): + for g in scope.scope_generator(): + yield g + else: + yield scope, get_defined_names_for_position(scope, + position, in_func_scope) + except StopIteration: + raise MultiLevelStopIteration('StopIteration raised somewhere') + if scope.isinstance(parsing.ForFlow) and scope.is_list_comp: + # is a list comprehension + yield scope, scope.get_set_vars(is_internal_call=True) + + scope = scope.parent + # This is used, because subscopes (Flow scopes) would distort the + # results. + if scope and scope.isinstance(Function, parsing.Function, Execution): + in_func_scope = scope + + # Add star imports. + if star_search: + for s in imports.remove_star_imports(non_flow.get_parent_until()): + for g in get_names_for_scope(s, star_search=False): + yield g + + # Add builtins to the global scope. + if include_builtin: + builtin_scope = builtin.Builtin.scope + yield builtin_scope, builtin_scope.get_defined_names() + + +def get_scopes_for_name(scope, name_str, position=None, search_global=False, + is_goto=False): + """ + This is the search function. The most important part to debug. + `remove_statements` and `filter_statements` really are the core part of + this completion. + + :param position: Position of the last statement -> tuple of line, column + :return: List of Names. Their parents are the scopes, they are defined in. + :rtype: list + """ + def remove_statements(result): + """ + This is the part where statements are being stripped. + + Due to lazy evaluation, statements like a = func; b = a; b() have to be + evaluated. + """ + res_new = [] + for r in result: + add = [] + if r.isinstance(parsing.Statement): + check_instance = None + if isinstance(r, InstanceElement) and r.is_class_var: + check_instance = r.instance + r = r.var + + # Global variables handling. + if r.is_global(): + for token_name in r.token_list[1:]: + if isinstance(token_name, parsing.Name): + add = get_scopes_for_name(r.parent, + str(token_name)) + else: + # generated objects are used within executions, but these + # objects are in functions, and we have to dynamically + # execute first. + if isinstance(r, parsing.Param): + func = r.parent + # Instances are typically faked, if the instance is not + # called from outside. Here we check it for __init__ + # functions and return. + if isinstance(func, InstanceElement) \ + and func.instance.is_generated \ + and hasattr(func, 'name') \ + and str(func.name) == '__init__' \ + and r.position_nr > 0: # 0 would be self + r = func.var.params[r.position_nr] + + # add docstring knowledge + doc_params = docstrings.follow_param(r) + if doc_params: + res_new += doc_params + continue + + if not r.is_generated: + res_new += dynamic.search_params(r) + if not r.assignment_details: + # this means that there are no default params, + # so just ignore it. + continue + + scopes = follow_statement(r, seek_name=name_str) + add += remove_statements(scopes) + + if check_instance is not None: + # class renames + add = [InstanceElement(check_instance, a, True) + if isinstance(a, (Function, parsing.Function)) + else a for a in add] + res_new += add + else: + if isinstance(r, parsing.Class): + r = Class(r) + elif isinstance(r, parsing.Function): + r = Function(r) + if r.isinstance(Function): + try: + r = r.get_decorated_func() + except DecoratorNotFound: + continue + res_new.append(r) + debug.dbg('sfn remove, new: %s, old: %s' % (res_new, result)) + return res_new + + def filter_name(scope_generator): + """ + Filters all variables of a scope (which are defined in the + `scope_generator`), until the name fits. + """ + def handle_for_loops(loop): + # Take the first statement (for has always only + # one, remember `in`). And follow it. + if not len(loop.inits): + return [] + result = get_iterator_types(follow_statement(loop.inits[0])) + if len(loop.set_vars) > 1: + var_arr = loop.set_stmt.get_assignment_calls() + result = assign_tuples(var_arr, result, name_str) + return result + + def process(name): + """ + Returns the parent of a name, which means the element which stands + behind a name. + """ + result = [] + no_break_scope = False + par = name.parent + + if par.isinstance(parsing.Flow): + if par.command == 'for': + result += handle_for_loops(par) + else: + debug.warning('Flow: Why are you here? %s' % par.command) + elif par.isinstance(parsing.Param) \ + and par.parent is not None \ + and par.parent.parent.isinstance(parsing.Class) \ + and par.position_nr == 0: + # This is where self gets added - this happens at another + # place, if the var_args are clear. But sometimes the class is + # not known. Therefore add a new instance for self. Otherwise + # take the existing. + if isinstance(scope, InstanceElement): + inst = scope.instance + else: + inst = Instance(Class(par.parent.parent)) + inst.is_generated = True + result.append(inst) + elif par.isinstance(parsing.Statement): + def is_execution(arr): + for a in arr: + a = a[0] # rest is always empty with assignees + if a.isinstance(parsing.Array): + if is_execution(a): + return True + elif a.isinstance(parsing.Call): + if a.name == name and a.execution: + return True + return False + + is_exe = False + for op, assignee in par.assignment_details: + is_exe |= is_execution(assignee) + if is_exe: + # filter array[3] = ... + # TODO check executions for dict contents + pass + else: + details = par.assignment_details + if details and details[0][0] != '=': + no_break_scope = True + + # TODO this makes self variables non-breakable. wanted? + if isinstance(name, InstanceElement) \ + and not name.is_class_var: + no_break_scope = True + + result.append(par) + else: + result.append(par) + return result, no_break_scope + + flow_scope = scope + result = [] + # compare func uses the tuple of line/indent = line/column + comparison_func = lambda name: (name.start_pos) + + for nscope, name_list in scope_generator: + break_scopes = [] + # here is the position stuff happening (sorting of variables) + for name in sorted(name_list, key=comparison_func, reverse=True): + p = name.parent.parent if name.parent else None + if isinstance(p, InstanceElement) \ + and isinstance(p.var, parsing.Class): + p = p.var + if name_str == name.get_code() and p not in break_scopes: + r, no_break_scope = process(name) + if is_goto: + if r: + # Directly assign the name, but there has to be a + # result. + result.append(name) + else: + result += r + # for comparison we need the raw class + s = nscope.base if isinstance(nscope, Class) else nscope + # this means that a definition was found and is not e.g. + # in if/else. + if result and not no_break_scope: + if not name.parent or p == s: + break + break_scopes.append(p) + + while flow_scope: + # TODO check if result is in scope -> no evaluation necessary + n = dynamic.check_flow_information(flow_scope, name_str, + position) + if n: + result = n + break + + if result: + break + if flow_scope == nscope: + break + flow_scope = flow_scope.parent + flow_scope = nscope + if result: + break + + if not result and isinstance(nscope, Instance): + # getattr() / __getattr__ / __getattribute__ + result += check_getattr(nscope, name_str) + debug.dbg('sfn filter "%s" in %s: %s' % (name_str, nscope, result)) + return result + + def descriptor_check(result): + """ Processes descriptors """ + res_new = [] + for r in result: + if isinstance(scope, (Instance, Class)) \ + and hasattr(r, 'get_descriptor_return'): + # handle descriptors + try: + res_new += r.get_descriptor_return(scope) + continue + except KeyError: + pass + res_new.append(r) + return res_new + + if search_global: + scope_generator = get_names_for_scope(scope, position=position) + else: + if isinstance(scope, Instance): + scope_generator = scope.scope_generator() + else: + if isinstance(scope, (Class, parsing.Module)): + # classes are only available directly via chaining? + # strange stuff... + names = scope.get_defined_names() + else: + names = get_defined_names_for_position(scope, position) + scope_generator = iter([(scope, names)]) + + if is_goto: + return filter_name(scope_generator) + return descriptor_check(remove_statements(filter_name(scope_generator))) + + +def check_getattr(inst, name_str): + result = [] + # str is important to lose the NamePart! + name = parsing.Call(str(name_str), parsing.Call.STRING, (0, 0), inst) + args = helpers.generate_param_array([name]) + try: + result = inst.execute_subscope_by_name('__getattr__', args) + except KeyError: + pass + if not result: + # this is a little bit special. `__getattribute__` is executed + # before anything else. But: I know no use case, where this + # could be practical and the jedi would return wrong types. If + # you ever have something, let me know! + try: + result = inst.execute_subscope_by_name('__getattribute__', args) + except KeyError: + pass + return result + + +def get_iterator_types(inputs): + """ Returns the types of any iterator (arrays, yields, __iter__, etc). """ + iterators = [] + # Take the first statement (for has always only + # one, remember `in`). And follow it. + for it in inputs: + if isinstance(it, (Generator, Array, dynamic.ArrayInstance)): + iterators.append(it) + else: + if not hasattr(it, 'execute_subscope_by_name'): + debug.warning('iterator/for loop input wrong', it) + continue + try: + iterators += it.execute_subscope_by_name('__iter__') + except KeyError: + debug.warning('iterators: No __iter__ method found.') + + result = [] + for gen in iterators: + if isinstance(gen, Array): + # Array is a little bit special, since this is an internal + # array, but there's also the list builtin, which is + # another thing. + result += gen.get_index_types() + elif isinstance(gen, Instance): + # __iter__ returned an instance. + name = '__next__' if is_py3k else 'next' + try: + result += gen.execute_subscope_by_name(name) + except KeyError: + debug.warning('Instance has no __next__ function', gen) + else: + # is a generator + result += gen.iter_content() + return result + + +def assign_tuples(tup, results, seek_name): + """ + This is a normal assignment checker. In python functions and other things + can return tuples: + >>> a, b = 1, "" + >>> a, (b, c) = 1, ("", 1.0) + + Here, if seek_name is "a", the number type will be returned. + The first part (before `=`) is the param tuples, the second one result. + + :type tup: parsing.Array + """ + def eval_results(index): + types = [] + for r in results: + if hasattr(r, "get_exact_index_types"): + try: + types += r.get_exact_index_types(index) + except IndexError: + pass + else: + debug.warning("invalid tuple lookup %s of result %s in %s" + % (tup, results, seek_name)) + + return types + + result = [] + if tup.type == parsing.Array.NOARRAY: + # Here we have unnessecary braces, which we just remove. + arr = tup.get_only_subelement() + if type(arr) == parsing.Call: + if arr.name.names[-1] == seek_name: + result = results + else: + result = assign_tuples(arr, results, seek_name) + else: + for i, t in enumerate(tup): + # Used in assignments. There is just one call and no other things, + # therefore we can just assume, that the first part is important. + if len(t) != 1: + raise AttributeError('Array length should be 1') + t = t[0] + + # Check the left part, if there are still tuples in it or a Call. + if isinstance(t, parsing.Array): + # These are "sub"-tuples. + result += assign_tuples(t, eval_results(i), seek_name) + else: + if t.name.names[-1] == seek_name: + result += eval_results(i) + return result + + +@helpers.RecursionDecorator +@memoize_default(default=[]) +def follow_statement(stmt, seek_name=None): + """ + The starting point of the completion. A statement always owns a call list, + which are the calls, that a statement does. + In case multiple names are defined in the statement, `seek_name` returns + the result for this name. + + :param stmt: A `parsing.Statement`. + :param seek_name: A string. + """ + debug.dbg('follow_stmt %s (%s)' % (stmt, seek_name)) + call_list = stmt.get_assignment_calls() + debug.dbg('calls: %s' % call_list) + + try: + result = follow_call_list(call_list) + except AttributeError: + # This is so evil! But necessary to propagate errors. The attribute + # errors here must not be catched, because they shouldn't exist. + raise MultiLevelAttributeError(sys.exc_info()) + + # Assignment checking is only important if the statement defines multiple + # variables. + if len(stmt.get_set_vars()) > 1 and seek_name and stmt.assignment_details: + new_result = [] + for op, set_vars in stmt.assignment_details: + new_result += assign_tuples(set_vars, result, seek_name) + result = new_result + return set(result) + + +def follow_call_list(call_list): + """ + The call_list has a special structure. + This can be either `parsing.Array` or `list of list`. + It is used to evaluate a two dimensional object, that has calls, arrays and + operators in it. + """ + def evaluate_list_comprehension(lc, parent=None): + input = lc.input + nested_lc = lc.input.token_list[0] + if isinstance(nested_lc, parsing.ListComprehension): + # is nested LC + input = nested_lc.stmt + loop = parsing.ForFlow([input], lc.stmt.start_pos, + lc.middle, True) + if parent is None: + loop.parent = lc.stmt.parent + else: + loop.parent = parent + + if isinstance(nested_lc, parsing.ListComprehension): + loop = evaluate_list_comprehension(nested_lc, loop) + return loop + + if parsing.Array.is_type(call_list, parsing.Array.TUPLE, + parsing.Array.DICT): + # Tuples can stand just alone without any braces. These would be + # recognized as separate calls, but actually are a tuple. + result = follow_call(call_list) + else: + result = [] + for calls in call_list: + calls_iterator = iter(calls) + for call in calls_iterator: + if parsing.Array.is_type(call, parsing.Array.NOARRAY): + result += follow_call_list(call) + elif isinstance(call, parsing.ListComprehension): + loop = evaluate_list_comprehension(call) + stmt = copy.copy(call.stmt) + stmt.parent = loop + # create a for loop which does the same as list + # comprehensions + result += follow_statement(stmt) + else: + # With things like params, these can also be functions... + if isinstance(call, (Function, Class, Instance, + dynamic.ArrayInstance)): + result.append(call) + # The string tokens are just operations (+, -, etc.) + elif not isinstance(call, (str, unicode)): + if str(call.name) == 'if': + # Ternary operators. + while True: + try: + call = next(calls_iterator) + except StopIteration: + break + try: + if str(call.name) == 'else': + break + except AttributeError: + pass + continue + result += follow_call(call) + elif call == '*': + if [r for r in result if isinstance(r, Array) + or isinstance(r, Instance) + and str(r.name) == 'str']: + # if it is an iterable, ignore * operations + next(calls_iterator) + return set(result) + + +def follow_call(call): + """ Follow a call is following a function, variable, string, etc. """ + scope = call.parent_stmt.parent + path = call.generate_call_path() + position = call.parent_stmt.start_pos + return follow_call_path(path, scope, position) + + +def follow_call_path(path, scope, position): + """ Follows a path generated by `parsing.Call.generate_call_path()` """ + current = next(path) + + if isinstance(current, parsing.Array): + result = [Array(current)] + else: + if not isinstance(current, parsing.NamePart): + if current.type in (parsing.Call.STRING, parsing.Call.NUMBER): + t = type(current.name).__name__ + scopes = get_scopes_for_name(builtin.Builtin.scope, t) + else: + debug.warning('unknown type:', current.type, current) + scopes = [] + # Make instances of those number/string objects. + arr = helpers.generate_param_array([current.name]) + scopes = [Instance(s, arr) for s in scopes] + else: + # This is the first global lookup. + scopes = get_scopes_for_name(scope, current, position=position, + search_global=True) + result = imports.strip_imports(scopes) + + return follow_paths(path, result, scope, position=position) + + +def follow_paths(path, results, call_scope, position=None): + """ + In each result, `path` must be followed. Copies the path iterator. + """ + results_new = [] + if results: + if len(results) > 1: + iter_paths = itertools.tee(path, len(results)) + else: + iter_paths = [path] + + for i, r in enumerate(results): + fp = follow_path(iter_paths[i], r, call_scope, position=position) + if fp is not None: + results_new += fp + else: + # This means stop iteration. + return results + return results_new + + +def follow_path(path, scope, call_scope, position=None): + """ + Uses a generator and tries to complete the path, e.g. + >>> foo.bar.baz + + `follow_path` is only responsible for completing `.bar.baz`, the rest is + done in the `follow_call` function. + """ + # Current is either an Array or a Scope. + try: + current = next(path) + except StopIteration: + return None + debug.dbg('follow %s in scope %s' % (current, scope)) + + result = [] + if isinstance(current, parsing.Array): + # This must be an execution, either () or []. + if current.type == parsing.Array.LIST: + if hasattr(scope, 'get_index_types'): + result = scope.get_index_types(current) + elif current.type not in [parsing.Array.DICT]: + # Scope must be a class or func - make an instance or execution. + debug.dbg('exe', scope) + result = Execution(scope, current).get_return_types() + else: + # Curly braces are not allowed, because they make no sense. + debug.warning('strange function call with {}', current, scope) + else: + # The function must not be decorated with something else. + if scope.isinstance(Function): + scope = scope.get_magic_method_scope() + else: + # This is the typical lookup while chaining things. + if filter_private_variable(scope, call_scope, current): + return [] + result = imports.strip_imports(get_scopes_for_name(scope, current, + position=position)) + return follow_paths(path, set(result), call_scope, position=position) + + +def filter_private_variable(scope, call_scope, var_name): + if isinstance(var_name, (str, unicode)) \ + and var_name.startswith('__') and isinstance(scope, Instance): + s = call_scope.get_parent_until((parsing.Class, Instance), + include_current=True) + if s != scope and s != scope.base.base: + return True + return False + + +def goto(stmt, call_path=None): + if call_path is None: + arr = stmt.get_assignment_calls() + call = arr.get_only_subelement() + call_path = list(call.generate_call_path()) + + scope = stmt.parent + pos = stmt.start_pos + call_path, search = call_path[:-1], call_path[-1] + if call_path: + scopes = follow_call_path(iter(call_path), scope, pos) + search_global = False + pos = None + else: + scopes = [scope] + search_global = True + follow_res = [] + for s in scopes: + follow_res += get_scopes_for_name(s, search, pos, + search_global=search_global, is_goto=True) + return follow_res, search diff --git a/common/.local/lib/python2.7/site-packages/jedi/helpers.py b/common/.local/lib/python2.7/site-packages/jedi/helpers.py new file mode 100644 index 0000000..b1f6e4c --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/helpers.py @@ -0,0 +1,266 @@ +import copy +import contextlib + +import parsing +import evaluate +import debug +import builtin +import settings + + +class RecursionDecorator(object): + """ + A decorator to detect recursions in statements. In a recursion a statement + at the same place, in the same module may not be executed two times. + """ + def __init__(self, func): + self.func = func + self.reset() + + def __call__(self, stmt, *args, **kwargs): + #print stmt, len(self.node_statements()) + if self.push_stmt(stmt): + return [] + else: + result = self.func(stmt, *args, **kwargs) + self.pop_stmt() + return result + + def push_stmt(self, stmt): + self.current = RecursionNode(stmt, self.current) + if self._check_recursion(): + debug.warning('catched recursion', stmt) + self.pop_stmt() + return True + return False + + def pop_stmt(self): + if self.current is not None: + # I don't know how current can be None, but sometimes it happens + # with Python3. + self.current = self.current.parent + + def _check_recursion(self): + test = self.current + while True: + test = test.parent + if self.current == test: + return True + if not test: + return False + + def reset(self): + self.top = None + self.current = None + + def node_statements(self): + result = [] + n = self.current + while n: + result.insert(0, n.stmt) + n = n.parent + return result + + +class RecursionNode(object): + """ A node of the RecursionDecorator. """ + def __init__(self, stmt, parent): + self.script = stmt.get_parent_until() + self.position = stmt.start_pos + self.parent = parent + self.stmt = stmt + + # Don't check param instances, they are not causing recursions + # The same's true for the builtins, because the builtins are really + # simple. + self.is_ignored = isinstance(stmt, parsing.Param) \ + or (self.script == builtin.Builtin.scope) + + def __eq__(self, other): + if not other: + return None + return self.script == other.script \ + and self.position == other.position \ + and not self.is_ignored and not other.is_ignored + + +class ExecutionRecursionDecorator(object): + """ + Catches recursions of executions. + It is designed like a Singelton. Only one instance should exist. + """ + def __init__(self, func): + self.func = func + self.reset() + + def __call__(self, execution, evaluate_generator=False): + debug.dbg('Execution recursions: %s' % execution, self.recursion_level, + self.execution_count, len(self.execution_funcs)) + if self.check_recursion(execution, evaluate_generator): + result = [] + else: + result = self.func(execution, evaluate_generator) + self.cleanup() + return result + + @classmethod + def cleanup(cls): + cls.parent_execution_funcs.pop() + cls.recursion_level -= 1 + + @classmethod + def check_recursion(cls, execution, evaluate_generator): + in_par_execution_funcs = execution.base in cls.parent_execution_funcs + in_execution_funcs = execution.base in cls.execution_funcs + cls.recursion_level += 1 + cls.execution_count += 1 + cls.execution_funcs.add(execution.base) + cls.parent_execution_funcs.append(execution.base) + + if cls.execution_count > settings.max_executions: + return True + + if isinstance(execution.base, (evaluate.Generator, evaluate.Array)): + return False + module = execution.get_parent_until() + if evaluate_generator or module == builtin.Builtin.scope: + return False + + if in_par_execution_funcs: + if cls.recursion_level > settings.max_function_recursion_level: + return True + if in_execution_funcs and \ + len(cls.execution_funcs) > settings.max_until_execution_unique: + return True + if cls.execution_count > settings.max_executions_without_builtins: + return True + return False + + @classmethod + def reset(cls): + cls.recursion_level = 0 + cls.parent_execution_funcs = [] + cls.execution_funcs = set() + cls.execution_count = 0 + + +def fast_parent_copy(obj): + """ + Much, much faster than copy.deepcopy, but just for certain elements. + """ + new_elements = {} + + def recursion(obj): + new_obj = copy.copy(obj) + new_elements[obj] = new_obj + + items = new_obj.__dict__.items() + for key, value in items: + # replace parent (first try _parent and then parent) + if key in ['parent', '_parent', '_parent_stmt'] \ + and value is not None: + if key == 'parent' and '_parent' in items: + # parent can be a property + continue + try: + setattr(new_obj, key, new_elements[value]) + except KeyError: + pass + elif key in ['parent_stmt', 'parent_function']: + continue + elif isinstance(value, list): + setattr(new_obj, key, list_rec(value)) + elif isinstance(value, (parsing.Simple, parsing.Call)): + setattr(new_obj, key, recursion(value)) + return new_obj + + def list_rec(list_obj): + copied_list = list_obj[:] # lists, tuples, strings, unicode + for i, el in enumerate(copied_list): + if isinstance(el, (parsing.Simple, parsing.Call)): + copied_list[i] = recursion(el) + elif isinstance(el, list): + copied_list[i] = list_rec(el) + return copied_list + return recursion(obj) + + +def generate_param_array(args_tuple, parent_stmt=None): + """ This generates an array, that can be used as a param. """ + values = [] + for arg in args_tuple: + if arg is None: + values.append([]) + else: + values.append([arg]) + pos = None + arr = parsing.Array(pos, parsing.Array.TUPLE, parent_stmt, values=values) + evaluate.faked_scopes.append(arr) + return arr + + +def scan_array_for_pos(arr, pos): + """ + Returns the function Call that match search_name in an Array. + Makes changes to arr! + """ + def check_arr_index(): + positions = arr.arr_el_pos + for index, comma_pos in enumerate(positions): + if pos < comma_pos: + return index + return len(positions) + + call = None + stop = False + for sub in arr.values: + call = None + for s in sub: + if isinstance(s, parsing.Array): + new = scan_array_for_pos(s, pos) + if new[0] is not None: + call, index, stop = new + if stop: + return call, index, stop + elif isinstance(s, parsing.Call): + start_s = s + # check parts of calls + while s is not None: + if s.start_pos >= pos: + return call, check_arr_index(), stop + elif s.execution is not None: + end = s.execution.end_pos + if s.execution.start_pos < pos and \ + (end is None or pos < end): + c, index, stop = scan_array_for_pos( + s.execution, pos) + if stop: + return c, index, stop + + # call should return without execution and + # next + reset = c or s + if reset.execution.type not in \ + [parsing.Array.TUPLE, + parsing.Array.NOARRAY]: + return start_s, index, False + + reset.execution = None + reset.next = None + return c or start_s, index, True + s = s.next + + # The third return is just necessary for recursion inside, because + # it needs to know when to stop iterating. + return call, check_arr_index(), stop + + +@contextlib.contextmanager +def scale_speed_settings(factor): + a = settings.max_executions + b = settings.max_until_execution_unique + settings.max_executions *= factor + settings.max_until_execution_unique *= factor + yield + settings.max_executions = a + settings.max_until_execution_unique = b diff --git a/common/.local/lib/python2.7/site-packages/jedi/imports.py b/common/.local/lib/python2.7/site-packages/jedi/imports.py new file mode 100644 index 0000000..03a76ca --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/imports.py @@ -0,0 +1,332 @@ +from __future__ import with_statement + +import os +import pkgutil +import imp +import sys +import time + +import builtin +import modules +import debug +import parsing +import evaluate +import itertools +import settings + +# for debugging purposes only +imports_processed = 0 + +star_import_cache = {} + + +class ModuleNotFound(Exception): + pass + + +class ImportPath(parsing.Base): + """ + An ImportPath is the path of a `parsing.Import` object. + """ + class _GlobalNamespace(object): + def get_defined_names(self): + return [] + + def get_imports(self): + return [] + + @property + def start_pos(self): + return (0, 0) + + def get_parent_until(self): + return None + + GlobalNamespace = _GlobalNamespace() + + def __init__(self, import_stmt, is_like_search=False, kill_count=0, + direct_resolve=False): + self.import_stmt = import_stmt + self.is_like_search = is_like_search + self.direct_resolve = direct_resolve + self.is_partial_import = bool(kill_count) + path = import_stmt.get_parent_until().path + self.file_path = os.path.dirname(path) if path is not None else None + + # rest is import_path resolution + self.import_path = [] + if import_stmt.from_ns: + self.import_path += import_stmt.from_ns.names + if import_stmt.namespace: + if self.is_nested_import() and not direct_resolve: + self.import_path.append(import_stmt.namespace.names[0]) + else: + self.import_path += import_stmt.namespace.names + + for i in range(kill_count + int(is_like_search)): + self.import_path.pop() + + def __repr__(self): + return '<%s: %s>' % (type(self).__name__, self.import_stmt) + + def is_nested_import(self): + """ + This checks for the special case of nested imports, without aliases and + from statement: + >>> import foo.bar + """ + return not self.import_stmt.alias and not self.import_stmt.from_ns \ + and len(self.import_stmt.namespace.names) > 1 \ + and not self.direct_resolve + + def get_nested_import(self, parent): + """ + See documentation of `self.is_nested_import`. + Generates an Import statement, that can be used to fake nested imports. + """ + i = self.import_stmt + # This is not an existing Import statement. Therefore, set position to + # 0 (0 is not a valid line number). + zero = (0, 0) + n = parsing.Name(i.namespace.names[1:], zero, zero, self.import_stmt) + new = parsing.Import(zero, zero, n) + new.parent = parent + evaluate.faked_scopes.append(new) + debug.dbg('Generated a nested import: %s' % new) + return new + + def get_defined_names(self, on_import_stmt=False): + names = [] + for scope in self.follow(): + if scope is ImportPath.GlobalNamespace: + if self.import_stmt.relative_count == 0: + names += self.get_module_names() + + if self.file_path is not None: + path = os.path.abspath(self.file_path) + for i in range(self.import_stmt.relative_count - 1): + path = os.path.dirname(path) + names += self.get_module_names([path]) + else: + if on_import_stmt and isinstance(scope, parsing.Module) \ + and scope.path.endswith('__init__.py'): + pkg_path = os.path.dirname(scope.path) + names += self.get_module_names([pkg_path]) + for s, scope_names in evaluate.get_names_for_scope(scope, + include_builtin=False): + for n in scope_names: + if self.import_stmt.from_ns is None \ + or self.is_partial_import: + # from_ns must be defined to access module + # values plus a partial import means that there + # is something after the import, which + # automatically implies that there must not be + # any non-module scope. + continue + names.append(n) + return names + + def get_module_names(self, search_path=None): + """ + Get the names of all modules in the search_path. This means file names + and not names defined in the files. + """ + if not search_path: + search_path = self.sys_path_with_modifications() + names = [] + for module_loader, name, is_pkg in pkgutil.iter_modules(search_path): + inf_pos = (float('inf'), float('inf')) + names.append(parsing.Name([(name, inf_pos)], inf_pos, inf_pos, + self.import_stmt)) + return names + + def sys_path_with_modifications(self): + module = self.import_stmt.get_parent_until() + return modules.sys_path_with_modifications(module) + + def follow(self, is_goto=False): + """ + Returns the imported modules. + """ + if evaluate.follow_statement.push_stmt(self.import_stmt): + # check recursion + return [] + + if self.import_path: + try: + scope, rest = self._follow_file_system() + except ModuleNotFound: + debug.warning('Module not found: ' + str(self.import_stmt)) + evaluate.follow_statement.pop_stmt() + return [] + + scopes = [scope] + scopes += itertools.chain.from_iterable( + remove_star_imports(s) for s in scopes) + + # follow the rest of the import (not FS -> classes, functions) + if len(rest) > 1 or rest and self.is_like_search: + scopes = [] + elif rest: + if is_goto: + scopes = itertools.chain.from_iterable( + evaluate.get_scopes_for_name(s, rest[0], is_goto=True) + for s in scopes) + else: + scopes = itertools.chain.from_iterable( + evaluate.follow_path(iter(rest), s, s) + for s in scopes) + scopes = list(scopes) + + if self.is_nested_import(): + scopes.append(self.get_nested_import(scope)) + else: + scopes = [ImportPath.GlobalNamespace] + debug.dbg('after import', scopes) + + evaluate.follow_statement.pop_stmt() + return scopes + + def _follow_file_system(self): + """ + Find a module with a path (of the module, like usb.backend.libusb10). + """ + def follow_str(ns, string): + debug.dbg('follow_module', ns, string) + path = None + if ns: + path = ns[1] + elif self.import_stmt.relative_count: + module = self.import_stmt.get_parent_until() + path = os.path.abspath(module.path) + for i in range(self.import_stmt.relative_count): + path = os.path.dirname(path) + + global imports_processed + imports_processed += 1 + if path is not None: + return imp.find_module(string, [path]) + else: + debug.dbg('search_module', string, self.file_path) + # Override the sys.path. It works only good that way. + # Injecting the path directly into `find_module` did not work. + sys.path, temp = sys_path_mod, sys.path + try: + i = imp.find_module(string) + except ImportError: + sys.path = temp + raise + sys.path = temp + return i + + if self.file_path: + sys_path_mod = list(self.sys_path_with_modifications()) + sys_path_mod.insert(0, self.file_path) + else: + sys_path_mod = list(builtin.get_sys_path()) + + current_namespace = None + # now execute those paths + rest = [] + for i, s in enumerate(self.import_path): + try: + current_namespace = follow_str(current_namespace, s) + except ImportError: + if current_namespace: + rest = self.import_path[i:] + else: + raise ModuleNotFound( + 'The module you searched has not been found') + + sys_path_mod.pop(0) # TODO why is this here? + path = current_namespace[1] + is_package_directory = current_namespace[2][2] == imp.PKG_DIRECTORY + + f = None + if is_package_directory or current_namespace[0]: + # is a directory module + if is_package_directory: + path += '/__init__.py' + with open(path) as f: + source = f.read() + else: + source = current_namespace[0].read() + current_namespace[0].close() + if path.endswith('.py'): + f = modules.Module(path, source) + else: + f = builtin.Parser(path=path) + else: + f = builtin.Parser(name=path) + + return f.parser.module, rest + + +def strip_imports(scopes): + """ + Here we strip the imports - they don't get resolved necessarily. + Really used anymore? Merge with remove_star_imports? + """ + result = [] + for s in scopes: + if isinstance(s, parsing.Import): + result += ImportPath(s).follow() + else: + result.append(s) + return result + + +def cache_star_import(func): + def wrapper(scope, *args, **kwargs): + try: + mods = star_import_cache[scope] + if mods[0] + settings.star_import_cache_validity > time.time(): + return mods[1] + except KeyError: + pass + # cache is too old and therefore invalid or not available + invalidate_star_import_cache(scope) + mods = func(scope, *args, **kwargs) + star_import_cache[scope] = time.time(), mods + + return mods + return wrapper + + +def invalidate_star_import_cache(module, only_main=False): + """ Important if some new modules are being reparsed """ + try: + t, mods = star_import_cache[module] + + del star_import_cache[module] + + for m in mods: + invalidate_star_import_cache(m, only_main=True) + except KeyError: + pass + + if not only_main: + # We need a list here because otherwise the list is being changed + # during the iteration in py3k: iteritems -> items. + for key, (t, mods) in list(star_import_cache.items()): + if module in mods: + invalidate_star_import_cache(key) + + +@cache_star_import +def remove_star_imports(scope, ignored_modules=[]): + """ + Check a module for star imports: + >>> from module import * + + and follow these modules. + """ + modules = strip_imports(i for i in scope.get_imports() if i.star) + new = [] + for m in modules: + if m not in ignored_modules: + new += remove_star_imports(m, modules) + modules += new + + # Filter duplicate modules. + return set(modules) diff --git a/common/.local/lib/python2.7/site-packages/jedi/keywords.py b/common/.local/lib/python2.7/site-packages/jedi/keywords.py new file mode 100644 index 0000000..950270b --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/keywords.py @@ -0,0 +1,86 @@ +import keyword + +from _compatibility import is_py3k +import builtin + +import pydoc +try: + from pydoc_data import topics as pydoc_topics +except ImportError: + # Python 2.6 + try: + import pydoc_topics + except ImportError: + # Python 2.5 + pydoc_topics = None + +if is_py3k: + keys = keyword.kwlist +else: + keys = keyword.kwlist + ['None', 'False', 'True'] + + +def get_keywords(string='', pos=(0, 0), all=False): + if all: + return set([Keyword(k, pos) for k in keys]) + if string in keys: + return set([Keyword(string, pos)]) + return set() + + +def get_operator(string, pos): + return Keyword(string, pos) + + +class Keyword(object): + def __init__(self, name, pos): + self.name = name + self.start_pos = pos + self.parent = builtin.Builtin.scope + + def get_parent_until(self): + return self.parent + + @property + def names(self): + """ For a `parsing.Name` like comparision """ + return [self.name] + + @property + def docstr(self): + return imitate_pydoc(self.name) + + def __repr__(self): + return '<%s: %s>' % (type(self).__name__, self.name) + + +def imitate_pydoc(string): + """ + It's not possible to get the pydoc's without starting the annoying pager + stuff. + """ + # str needed because of possible unicode stuff in py2k (pydoc doesn't work + # with unicode strings) + string = str(string) + h = pydoc.help + try: + # try to access symbols + string = h.symbols[string] + string, _, related = string.partition(' ') + except KeyError: + pass + + get_target = lambda s: h.topics.get(s, h.keywords.get(s)) + while isinstance(string, str): + string = get_target(string) + + try: + # is a tuple now + label, related = string + except TypeError: + return '' + + try: + return pydoc_topics.topics[label] if pydoc_topics else '' + except KeyError: + return '' diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/_functools.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/_functools.pym new file mode 100644 index 0000000..be8470f --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/_functools.pym @@ -0,0 +1,9 @@ +class partial(): + def __init__(self, func, *args, **keywords): + self.__func = func + self.__args = args + self.__keywords = keywords + + def __call__(self, *args, **kwargs): + # I know this doesn't work in Python, but Jedi can this ;-) + return self.__func(*self.__args, *args, **self.keywords, **kwargs) diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/_sre.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/_sre.pym new file mode 100644 index 0000000..2b6935b --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/_sre.pym @@ -0,0 +1,99 @@ +def compile(): + class SRE_Match(): + endpos = 1 + lastgroup = 0 + lastindex = 1 + pos = 0 + string = 'a' + regs = ((0, 1),) + + def __init__(self, pattern): + self.re = pattern + + def start(self): + return 0 + + def end(self): + return 1 + + def span(self): + return 0, 1 + + def expand(self): + return '' + + def group(self): + return '' + + def groupdict(self): + return {'a', 'a'} + + def groups(self): + return ('a',) + + class SRE_Pattern(): + flags = 0 + groupindex = {} + groups = 0 + pattern = 'a' + + def findall(self): + """ + findall(string[, pos[, endpos]]) --> list. + Return a list of all non-overlapping matches of pattern in string. + """ + return ['a'] + + def finditer(self): + """ + finditer(string[, pos[, endpos]]) --> iterator. + Return an iterator over all non-overlapping matches for the + RE pattern in string. For each match, the iterator returns a + match object. + """ + yield SRE_Match(self) + + def match(self): + """ + match(string[, pos[, endpos]]) --> match object or None. + Matches zero or more characters at the beginning of the string + pattern + """ + return SRE_Match(self) + + def scanner(self): + pass + + def search(self): + """ + search(string[, pos[, endpos]]) --> match object or None. + Scan through string looking for a match, and return a corresponding + MatchObject instance. Return None if no position in the string matches. + """ + return SRE_Match(self) + + def split(self): + """ + split(string[, maxsplit = 0]) --> list. + Split string by the occurrences of pattern. + """ + return ['a'] + + def sub(self): + """ + sub(repl, string[, count = 0]) --> newstring + Return the string obtained by replacing the leftmost non-overlapping + occurrences of pattern in string by the replacement repl. + """ + return '' + + def subn(self): + """ + subn(repl, string[, count = 0]) --> (newstring, number of subs) + Return the tuple (new_string, number_of_subs_made) found by replacing + the leftmost non-overlapping occurrences of pattern with the + replacement repl. + """ + return ('', 1) + + return SRE_Pattern() diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/_weakref.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/_weakref.pym new file mode 100644 index 0000000..05eab2c --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/_weakref.pym @@ -0,0 +1,8 @@ +def proxy(object, callback=None): + return object + +class ref(): + def __init__(self, object, callback=None): + self.__object = object + def __call__(self): + return self.__object diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/builtins.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/builtins.pym new file mode 100644 index 0000000..28ddedf --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/builtins.pym @@ -0,0 +1,218 @@ +""" +Pure Python implementation of some builtins. +This code is not going to be executed anywhere. +These implementations are not always correct, but should work as good as +possible for the auto completion. +""" + + +def next(iterator, default=None): + if hasattr("next"): + return iterator.next() + else: + return iterator.__next__() + return default + + +def iter(collection, sentinel=None): + if sentinel: + yield collection() + else: + for c in collection: + yield c + + +def range(start, stop=None, step=1): + return [0] + + +class xrange(): + # Attention: this function doesn't exist in Py3k (there it is range). + def __iter__(self): + yield 1 + + def count(self): + return 1 + + def index(self): + return 1 + + +#-------------------------------------------------------- +# descriptors +#-------------------------------------------------------- +class property(): + def __init__(self, fget, fset=None, fdel=None, doc=None): + self.fget = fget + self.fset = fset + self.fdel = fdel + self.__doc__ = doc + + def __get__(self, obj, cls): + return self.fget(obj) + + def __set__(self, obj, value): + self.fset(obj, value) + + def __delete__(self, obj): + self.fdel(obj) + + def setter(self, func): + self.fset = func + return self + + def getter(self, func): + self.fget = func + return self + + def deleter(self, func): + self.fdel = func + return self + + +class staticmethod(): + def __init__(self, func): + self.__func = func + + def __get__(self, obj, cls): + return self.__func + + +class classmethod(): + def __init__(self, func): + self.__func = func + + def __get__(self, obj, cls): + def _method(*args, **kwargs): + return self.__func(cls, *args, **kwargs) + return _method + + +#-------------------------------------------------------- +# array stuff +#-------------------------------------------------------- +class list(): + def __init__(self, iterable=[]): + self.__iterable = [] + for i in iterable: + self.__iterable += [i] + + def __iter__(self): + for i in self.__iterable: + yield i + + def __getitem__(self, y): + return self.__iterable[y] + + def pop(self): + return self.__iterable[-1] + + +class tuple(): + def __init__(self, iterable=[]): + self.__iterable = [] + for i in iterable: + self.__iterable += [i] + + def __iter__(self): + for i in self.__iterable: + yield i + + def __getitem__(self, y): + return self.__iterable[y] + + def index(self): + return 1 + + def count(self): + return 1 + + +class set(): + def __init__(self, iterable=[]): + self.__iterable = iterable + + def __iter__(self): + for i in self.__iterable: + yield i + + def pop(self): + return self.__iterable.pop() + + def copy(self): + return self + + def difference(self, other): + return self - other + + def intersection(self, other): + return self & other + + def symmetric_difference(self, other): + return self ^ other + + def union(self, other): + return self | other + + +class frozenset(): + def __init__(self, iterable=[]): + self.__iterable = iterable + + def __iter__(self): + for i in self.__iterable: + yield i + + def copy(self): + return self + + +class dict(): + def __init__(self, **elements): + self.__elements = elements + + def clear(self): + # has a strange docstr + pass + + def get(self, k, d=None): + # TODO implement + try: + #return self.__elements[k] + pass + except KeyError: + return d + + +class reversed(): + def __init__(self, sequence): + self.__sequence = sequence + + def __iter__(self): + for i in self.__sequence: + yield i + + def __next__(self): + return next(self.__iter__()) + + def next(self): + return self.__next__() + + +#-------------------------------------------------------- +# basic types +#-------------------------------------------------------- +class int(): + def __init__(self, x, base=None): + pass + + +class str(): + def __init__(self, obj): + pass + +class object(): + def mro(): + """ mro() -> list + return a type's method resolution order """ + return [object] diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/datetime.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/datetime.pym new file mode 100644 index 0000000..823ac5b --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/datetime.pym @@ -0,0 +1,4 @@ +class datetime(): + @staticmethod + def now(): + return datetime() diff --git a/common/.local/lib/python2.7/site-packages/jedi/mixin/posix.pym b/common/.local/lib/python2.7/site-packages/jedi/mixin/posix.pym new file mode 100644 index 0000000..4417f7c --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/mixin/posix.pym @@ -0,0 +1,5 @@ +def getcwd(): + return '' + +def getcwdu(): + return '' diff --git a/common/.local/lib/python2.7/site-packages/jedi/modules.py b/common/.local/lib/python2.7/site-packages/jedi/modules.py new file mode 100644 index 0000000..2421e91 --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/modules.py @@ -0,0 +1,312 @@ +from __future__ import with_statement + +from _compatibility import exec_function + +import re +import tokenize +import sys +import os +import time + +import parsing +import builtin +import debug +import evaluate +import settings +import imports + + +class Module(builtin.CachedModule): + """ + Manages all files, that are parsed and caches them. + + :param path: The module path of the file. + :param source: The source code of the file. + """ + def __init__(self, path, source): + super(Module, self).__init__(path=path) + self.source = source + self._line_cache = None + + def _get_source(self): + """ Just one time """ + s = self.source + del self.source # memory efficiency + return s + + +class ModuleWithCursor(Module): + """ + Manages all files, that are parsed and caches them. + Important are the params source and path, one of them has to + be there. + + :param source: The source code of the file. + :param path: The module path of the file or None. + :param position: The position, the user is currently in. Only important \ + for the main file. + """ + def __init__(self, path, source, position): + super(ModuleWithCursor, self).__init__(path, source) + self.position = position + + # this two are only used, because there is no nonlocal in Python 2 + self._line_temp = None + self._relevant_temp = None + + self.source = source + self._part_parser = None + + @property + def parser(self): + """ get the parser lazy """ + if not self._parser: + try: + ts, parser = builtin.CachedModule.cache[self.path] + imports.invalidate_star_import_cache(parser.module) + + del builtin.CachedModule.cache[self.path] + except KeyError: + pass + # Call the parser already here, because it will be used anyways. + # Also, the position is here important (which will not be used by + # default), therefore fill the cache here. + self._parser = parsing.PyFuzzyParser(self.source, self.path, + self.position) + if self.path is not None: + builtin.CachedModule.cache[self.path] = time.time(), \ + self._parser + return self._parser + + def get_path_until_cursor(self): + """ Get the path under the cursor. """ + result = self._get_path_until_cursor() + self._start_cursor_pos = self._line_temp + 1, self._column_temp + return result + + def _get_path_until_cursor(self, start_pos=None): + def fetch_line(): + line = self.get_line(self._line_temp) + if self._is_first: + self._is_first = False + self._line_length = self._column_temp + line = line[:self._column_temp] + else: + self._line_length = len(line) + line = line + '\n' + # add lines with a backslash at the end + while 1: + self._line_temp -= 1 + last_line = self.get_line(self._line_temp) + if last_line and last_line[-1] == '\\': + line = last_line[:-1] + ' ' + line + else: + break + return line[::-1] + + self._is_first = True + if start_pos is None: + self._line_temp = self.position[0] + self._column_temp = self.position[1] + else: + self._line_temp, self._column_temp = start_pos + + open_brackets = ['(', '[', '{'] + close_brackets = [')', ']', '}'] + + gen = tokenize.generate_tokens(fetch_line) + string = '' + level = 0 + force_point = False + try: + for token_type, tok, start, end, line in gen: + #print 'tok', token_type, tok, force_point + if level > 0: + if tok in close_brackets: + level += 1 + if tok in open_brackets: + level -= 1 + elif tok == '.': + force_point = False + elif force_point: + # it is reversed, therefore a number is getting recognized + # as a floating point number + if token_type == tokenize.NUMBER and tok[0] == '.': + force_point = False + else: + break + elif tok in close_brackets: + level += 1 + elif token_type in [tokenize.NAME, tokenize.STRING]: + force_point = True + elif token_type == tokenize.NUMBER: + pass + else: + break + + self._column_temp = self._line_length - end[1] + string += tok + except tokenize.TokenError: + debug.warning("Tokenize couldn't finish", sys.exc_info) + + return string[::-1] + + def get_path_under_cursor(self): + """ + Return the path under the cursor. If there is a rest of the path left, + it will be added to the stuff before it. + """ + line = self.get_line(self.position[0]) + after = re.search("[\w\d]*", line[self.position[1]:]).group(0) + return self.get_path_until_cursor() + after + + def get_operator_under_cursor(self): + line = self.get_line(self.position[0]) + after = re.match("[^\w\s]+", line[self.position[1]:]) + before = re.match("[^\w\s]+", line[:self.position[1]][::-1]) + return (before.group(0) if before is not None else '') \ + + (after.group(0) if after is not None else '') + + def get_context(self): + pos = self._start_cursor_pos + while pos > (1, 0): + # remove non important white space + line = self.get_line(pos[0]) + while pos[1] > 0 and line[pos[1] - 1].isspace(): + pos = pos[0], pos[1] - 1 + + try: + yield self._get_path_until_cursor(start_pos=pos) + except StopIteration: + yield '' + pos = self._line_temp, self._column_temp + + while True: + yield '' + + def get_line(self, line_nr): + if not self._line_cache: + self._line_cache = self.source.split('\n') + + if line_nr == 0: + # This is a fix for the zeroth line. We need a newline there, for + # the backwards parser. + return '' + if line_nr < 0: + raise StopIteration() + try: + return self._line_cache[line_nr - 1] + except IndexError: + raise StopIteration() + + def get_part_parser(self): + """ Returns a parser that contains only part of the source code. This + exists only because of performance reasons. + """ + if self._part_parser: + return self._part_parser + + # TODO check for docstrings + length = settings.part_line_length + offset = max(self.position[0] - length, 0) + s = '\n'.join(self.source.split('\n')[offset:offset + length]) + self._part_parser = parsing.PyFuzzyParser(s, self.path, self.position, + line_offset=offset) + return self._part_parser + + +@evaluate.memoize_default([]) +def sys_path_with_modifications(module): + def execute_code(code): + c = "import os; from os.path import *; result=%s" + variables = {'__file__': module.path} + try: + exec_function(c % code, variables) + except Exception: + debug.warning('sys path detected, but failed to evaluate') + return None + try: + res = variables['result'] + if isinstance(res, str): + return os.path.abspath(res) + else: + return None + except KeyError: + return None + + def check_module(module): + try: + possible_stmts = module.used_names['path'] + except KeyError: + return builtin.get_sys_path() + + sys_path = list(builtin.get_sys_path()) # copy + for p in possible_stmts: + try: + call = p.get_assignment_calls().get_only_subelement() + except AttributeError: + continue + n = call.name + if not isinstance(n, parsing.Name) or len(n.names) != 3: + continue + if n.names[:2] != ('sys', 'path'): + continue + array_cmd = n.names[2] + if call.execution is None: + continue + exe = call.execution + if not (array_cmd == 'insert' and len(exe) == 2 + or array_cmd == 'append' and len(exe) == 1): + continue + + if array_cmd == 'insert': + exe_type, exe.type = exe.type, parsing.Array.NOARRAY + exe_pop = exe.values.pop(0) + res = execute_code(exe.get_code()) + if res is not None: + sys_path.insert(0, res) + debug.dbg('sys path inserted: %s' % res) + exe.type = exe_type + exe.values.insert(0, exe_pop) + elif array_cmd == 'append': + res = execute_code(exe.get_code()) + if res is not None: + sys_path.append(res) + debug.dbg('sys path added: %s' % res) + return sys_path + + if module.path is None: + return [] # support for modules without a path is intentionally bad. + + curdir = os.path.abspath(os.curdir) + try: + os.chdir(os.path.dirname(module.path)) + except OSError: + pass + + result = check_module(module) + result += detect_django_path(module.path) + + # cleanup, back to old directory + os.chdir(curdir) + return result + + +def detect_django_path(module_path): + """ Detects the path of the very well known Django library (if used) """ + result = [] + while True: + new = os.path.dirname(module_path) + # If the module_path doesn't change anymore, we're finished -> / + if new == module_path: + break + else: + module_path = new + + try: + with open(module_path + os.path.sep + 'manage.py'): + debug.dbg('Found django path: %s' % module_path) + result.append(module_path) + except IOError: + pass + return result diff --git a/common/.local/lib/python2.7/site-packages/jedi/parsing.py b/common/.local/lib/python2.7/site-packages/jedi/parsing.py new file mode 100644 index 0000000..d56f7ae --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/parsing.py @@ -0,0 +1,1855 @@ +""" +Maintainer: David Halter +Version: 0.1 + +py_fuzzyparser parses python code, with the goal of a good representation of +the code within a tree structure. Variables, Classes and Functions are defined +within this tree structure, containing their exact locations in the code. +It is also a primary goal to work with code which contains syntax errors. + +This behaviour may be used to refactor, modify, search and complete code. + +To understand this code it is extremely important to understand the behaviour +of the python module 'tokenize'. + +This original codebase of this parser, which has been refactored and heavily +changed, was programmed by Aaron Griffin . + +**The structure of the following script:** +A Scope has + - imports (Import) + - subscopes (Scope, Class, Function, Flow) + - statements (Statement) + +All these objects have `Name`s. `Call` and `Array` are used as detail objects +of a statement. + +All those classes are being generated by PyFuzzyParser, which takes python text +as input and ignores just all the non-python stuff. Basically you could feed it +a perl script, and it should still work (which means throw no error. +""" +from _compatibility import (next, literal_eval, StringIO, + property, cleandoc, Python3Method) + +import tokenize +import re +import keyword +import os + +import debug + + +class ParserError(Exception): + pass + + +def indent_block(text, indention=' '): + """ This function indents a text block with a default of four spaces """ + temp = '' + while text and text[-1] == '\n': + temp += text[-1] + text = text[:-1] + lines = text.split('\n') + return '\n'.join(map(lambda s: indention + s, lines)) + temp + + +class PushBackIterator(object): + def __init__(self, iterator): + self.pushes = [] + self.iterator = iterator + + def push_back(self, value): + self.pushes.append(value) + + def __iter__(self): + return self + + def next(self): + """ Python 2 Compatibility """ + return self.__next__() + + def __next__(self): + if self.pushes: + return self.pushes.pop() + else: + return next(self.iterator) + + +class Base(object): + """ + This is just here to have an isinstance check, which is also used on + evaluate classes. But since they have sometimes a special type of + delegation, it is important for those classes to override this method. + + I know that there is a chance to do such things with __instancecheck__, but + since Python 2.5 doesn't support it, I decided to do it this way. + """ + def isinstance(self, *cls): + return isinstance(self, cls) + + +class Simple(Base): + """ + The super class for Scope, Import, Name and Statement. Every object in + the parser tree inherits from this class. + """ + def __init__(self, start_pos, end_pos=(None, None)): + self.start_pos = start_pos + self.end_pos = end_pos + self.parent = None + + @Python3Method + def get_parent_until(self, classes=(), reverse=False, + include_current=False): + """ Takes always the parent, until one class (not a Class) """ + if type(classes) not in (tuple, list): + classes = (classes,) + scope = self + while scope.parent is not None: + if classes and reverse != scope.isinstance(*classes): + if include_current: + return scope + break + scope = scope.parent + return scope + + def __repr__(self): + code = self.get_code().replace('\n', ' ') + return "<%s: %s@%s>" % \ + (type(self).__name__, code, self.start_pos[0]) + + +class Scope(Simple): + """ + Super class for the parser tree, which represents the state of a python + text file. + A Scope manages and owns its subscopes, which are classes and functions, as + well as variables and imports. It is used to access the structure of python + files. + + :param start_pos: The position (line and column) of the scope. + :type start_pos: tuple(int, int) + :param docstr: The docstring for the current Scope. + :type docstr: str + """ + def __init__(self, start_pos, docstr=''): + super(Scope, self).__init__(start_pos) + self.subscopes = [] + self.imports = [] + self.statements = [] + self.docstr = docstr + self.asserts = [] + + def add_scope(self, sub, decorators): + sub.parent = self + sub.decorators = decorators + for d in decorators: + # the parent is the same, because the decorator has not the scope + # of the function + d.parent = sub.parent + self.subscopes.append(sub) + return sub + + def add_statement(self, stmt): + """ + Used to add a Statement or a Scope. + A statement would be a normal command (Statement) or a Scope (Flow). + """ + stmt.parent = self + self.statements.append(stmt) + return stmt + + def add_docstr(self, string): + """ Clean up a docstring """ + self.docstr = cleandoc(literal_eval(string)) + + def add_import(self, imp): + self.imports.append(imp) + imp.parent = self + + def get_imports(self): + """ Gets also the imports within flow statements """ + i = [] + self.imports + for s in self.statements: + if isinstance(s, Scope): + i += s.get_imports() + return i + + def get_code(self, first_indent=False, indention=' '): + """ + :return: Returns the code of the current scope. + :rtype: str + """ + string = "" + if len(self.docstr) > 0: + string += '"""' + self.docstr + '"""\n' + for i in self.imports: + string += i.get_code() + for sub in self.subscopes: + string += sub.get_code(first_indent=True, indention=indention) + for stmt in self.statements: + string += stmt.get_code() + + if first_indent: + string = indent_block(string, indention=indention) + return string + + @Python3Method + def get_set_vars(self): + """ + Get all the names, that are active and accessible in the current + scope. + + :return: list of Name + :rtype: list + """ + n = [] + for stmt in self.statements: + try: + n += stmt.get_set_vars(True) + except TypeError: + n += stmt.get_set_vars() + + # function and class names + n += [s.name for s in self.subscopes] + + for i in self.imports: + if not i.star: + n += i.get_defined_names() + return n + + def get_defined_names(self): + return [n for n in self.get_set_vars() + if isinstance(n, Import) or len(n) == 1] + + def is_empty(self): + """ + :return: True if there are no subscopes, imports and statements. + :rtype: bool + """ + return not (self.imports or self.subscopes or self.statements) + + @Python3Method + def get_statement_for_position(self, pos): + checks = self.statements + self.asserts + if self.isinstance(Function): + checks += self.params + self.decorators + self.returns + for s in checks: + if isinstance(s, Flow): + p = s.get_statement_for_position(pos) + while s.next and not p: + s = s.next + p = s.get_statement_for_position(pos) + if p: + return p + elif s.start_pos <= pos < s.end_pos: + return s + + for s in self.subscopes: + if s.start_pos <= pos <= s.end_pos: + p = s.get_statement_for_position(pos) + if p: + return p + + def __repr__(self): + try: + name = self.path + except AttributeError: + try: + name = self.name + except AttributeError: + name = self.command + + return "<%s: %s@%s-%s>" % (type(self).__name__, name, + self.start_pos[0], self.end_pos[0]) + + +class Module(Scope): + """ + The top scope, which is always a module. + """ + def __init__(self, path, docstr=''): + super(Module, self).__init__((1, 0), docstr) + self.path = path + self.global_vars = [] + self._name = None + self.used_names = {} + self.temp_used_names = [] + + def add_global(self, name): + """ + Global means in these context a function (subscope) which has a global + statement. + This is only relevant for the top scope. + + :param name: The name of the global. + :type name: Name + """ + self.global_vars.append(name) + # set no parent here, because globals are not defined in this scope. + + def get_set_vars(self): + n = super(Module, self).get_set_vars() + n += self.global_vars + return n + + @property + def name(self): + """ This is used for the goto function. """ + if self._name is not None: + return self._name + if self.path is None: + string = '' # no path -> empty name + else: + sep = (re.escape(os.path.sep),) * 2 + r = re.search(r'([^%s]*?)(%s__init__)?(\.py|\.so)?$' % sep, + self.path) + string = r.group(1) + names = [(string, (0, 0))] + self._name = Name(names, self.start_pos, self.end_pos, self) + return self._name + + def is_builtin(self): + return not (self.path is None or self.path.endswith('.py')) + + +class Class(Scope): + """ + Used to store the parsed contents of a python class. + + :param name: The Class name. + :type name: string + :param supers: The super classes of a Class. + :type supers: list + :param start_pos: The start position (line, column) of the class. + :type start_pos: tuple(int, int) + :param docstr: The docstring for the current Scope. + :type docstr: str + """ + def __init__(self, name, supers, start_pos, docstr=''): + super(Class, self).__init__(start_pos, docstr) + self.name = name + name.parent = self + self.supers = supers + for s in self.supers: + s.parent = self + self.decorators = [] + + def get_code(self, first_indent=False, indention=' '): + string = "\n".join('@' + stmt.get_code() for stmt in self.decorators) + string += 'class %s' % (self.name) + if len(self.supers) > 0: + sup = ','.join(stmt.code for stmt in self.supers) + string += '(%s)' % sup + string += ':\n' + string += super(Class, self).get_code(True, indention) + if self.is_empty(): + string += "pass\n" + return string + + +class Function(Scope): + """ + Used to store the parsed contents of a python function. + + :param name: The Function name. + :type name: string + :param params: The parameters (Statement) of a Function. + :type params: list + :param start_pos: The start position (line, column) the Function. + :type start_pos: tuple(int, int) + :param docstr: The docstring for the current Scope. + :type docstr: str + """ + def __init__(self, name, params, start_pos, annotation): + Scope.__init__(self, start_pos) + self.name = name + name.parent = self + self.params = params + for p in params: + p.parent = self + p.parent_function = self + self.decorators = [] + self.returns = [] + self.is_generator = False + self.listeners = set() # not used here, but in evaluation. + + if annotation is not None: + annotation.parent = self + self.annotation = annotation + + def get_code(self, first_indent=False, indention=' '): + string = "\n".join('@' + stmt.get_code() for stmt in self.decorators) + params = ','.join([stmt.code for stmt in self.params]) + string += "def %s(%s):\n" % (self.name, params) + string += super(Function, self).get_code(True, indention) + if self.is_empty(): + string += "pass\n" + return string + + def get_set_vars(self): + n = super(Function, self).get_set_vars() + for p in self.params: + try: + n.append(p.get_name()) + except IndexError: + debug.warning("multiple names in param %s" % n) + return n + + def get_call_signature(self, width=72): + """ + Generate call signature of this function. + + :param width: Fold lines if a line is longer than this value. + :type width: int + + :rtype: str + """ + l = self.name.names[-1] + '(' + lines = [] + for (i, p) in enumerate(self.params): + code = p.get_code(False) + if i != len(self.params) - 1: + code += ', ' + if len(l + code) > width: + lines.append(l[:-1] if l[-1] == ' ' else l) + l = code + else: + l += code + if l: + lines.append(l) + lines[-1] += ')' + return '\n'.join(lines) + + @property + def doc(self): + """ Return a document string including call signature. """ + return '%s\n\n%s' % (self.get_call_signature(), self.docstr) + + +class Flow(Scope): + """ + Used to describe programming structure - flow statements, + which indent code, but are not classes or functions: + + - for + - while + - if + - try + - with + + Therefore statements like else, except and finally are also here, + they are now saved in the root flow elements, but in the next variable. + + :param command: The flow command, if, while, else, etc. + :type command: str + :param inits: The initializations of a flow -> while 'statement'. + :type inits: list(Statement) + :param start_pos: Position (line, column) of the Flow statement. + :type start_pos: tuple(int, int) + :param set_vars: Local variables used in the for loop (only there). + :type set_vars: list + """ + def __init__(self, command, inits, start_pos, set_vars=None): + self.next = None + self.command = command + super(Flow, self).__init__(start_pos, '') + self._parent = None + # These have to be statements, because of with, which takes multiple. + self.inits = inits + for s in inits: + s.parent = self + if set_vars is None: + self.set_vars = [] + else: + self.set_vars = set_vars + for s in self.set_vars: + s.parent.parent = self + s.parent = self + + @property + def parent(self): + return self._parent + + @parent.setter + def parent(self, value): + self._parent = value + if self.next: + self.next.parent = value + + def get_code(self, first_indent=False, indention=' '): + stmts = [] + for s in self.inits: + stmts.append(s.get_code(new_line=False)) + stmt = ', '.join(stmts) + string = "%s %s:\n" % (self.command, vars, stmt) + string += super(Flow, self).get_code(True, indention) + if self.next: + string += self.next.get_code() + return string + + def get_set_vars(self, is_internal_call=False): + """ + Get the names for the flow. This includes also a call to the super + class. + :param is_internal_call: defines an option for internal files to crawl\ + through this class. Normally it will just call its superiors, to\ + generate the output. + """ + if is_internal_call: + n = list(self.set_vars) + for s in self.inits: + n += s.set_vars + if self.next: + n += self.next.get_set_vars(is_internal_call) + n += super(Flow, self).get_set_vars() + return n + else: + return self.get_parent_until((Class, Function)).get_set_vars() + + def get_imports(self): + i = super(Flow, self).get_imports() + if self.next: + i += self.next.get_imports() + return i + + def set_next(self, next): + """ Set the next element in the flow, those are else, except, etc. """ + if self.next: + return self.next.set_next(next) + else: + self.next = next + self.next.parent = self.parent + return next + + +class ForFlow(Flow): + """ + Used for the for loop, because there are two statement parts. + """ + def __init__(self, inits, start_pos, set_stmt, is_list_comp=False): + super(ForFlow, self).__init__('for', inits, start_pos, + set_stmt.used_vars) + self.set_stmt = set_stmt + self.is_list_comp = is_list_comp + + def get_code(self, first_indent=False, indention=" " * 4): + vars = ",".join(x.get_code() for x in self.set_vars) + stmts = [] + for s in self.inits: + stmts.append(s.get_code(new_line=False)) + stmt = ', '.join(stmts) + s = "for %s in %s:\n" % (vars, stmt) + return s + super(Flow, self).get_code(True, indention) + + +class Import(Simple): + """ + Stores the imports of any Scopes. + + >>> 1+1 + 2 + + :param start_pos: Position (line, column) of the Import. + :type start_pos: tuple(int, int) + :param namespace: The import, can be empty if a star is given + :type namespace: Name + :param alias: The alias of a namespace(valid in the current namespace). + :type alias: Name + :param from_ns: Like the namespace, can be equally used. + :type from_ns: Name + :param star: If a star is used -> from time import *. + :type star: bool + :param defunct: An Import is valid or not. + :type defunct: bool + """ + def __init__(self, start_pos, end_pos, namespace, alias=None, + from_ns=None, star=False, relative_count=0, defunct=False): + super(Import, self).__init__(start_pos, end_pos) + + self.namespace = namespace + self.alias = alias + self.from_ns = from_ns + for n in [namespace, alias, from_ns]: + if n: + n.parent = self + + self.star = star + self.relative_count = relative_count + self.defunct = defunct + + def get_code(self, new_line=True): + # in case one of the names is None + alias = self.alias or '' + namespace = self.namespace or '' + from_ns = self.from_ns or '' + + if self.alias: + ns_str = "%s as %s" % (namespace, alias) + else: + ns_str = str(namespace) + + nl = '\n' if new_line else '' + if self.from_ns or self.relative_count: + if self.star: + ns_str = '*' + dots = '.' * self.relative_count + return "from %s%s import %s%s" % (dots, from_ns, ns_str, nl) + else: + return "import %s%s" % (ns_str, nl) + + def get_defined_names(self): + if self.defunct: + return [] + if self.star: + return [self] + if self.alias: + return [self.alias] + if len(self.namespace) > 1: + o = self.namespace + n = Name([(o.names[0], o.start_pos)], o.start_pos, o.end_pos, + parent=o.parent) + return [n] + else: + return [self.namespace] + + def get_set_vars(self): + return self.get_defined_names() + + def get_all_import_names(self): + n = [] + if self.from_ns: + n.append(self.from_ns) + if self.namespace: + n.append(self.namespace) + if self.alias: + n.append(self.alias) + return n + + +class Statement(Simple): + """ + This is the class for all the possible statements. Which means, this class + stores pretty much all the Python code, except functions, classes, imports, + and flow functions like if, for, etc. + + :param code: The full code of a statement. This is import, if one wants \ + to execute the code at some level. + :param code: str + :param set_vars: The variables which are defined by the statement. + :param set_vars: str + :param used_funcs: The functions which are used by the statement. + :param used_funcs: str + :param used_vars: The variables which are used by the statement. + :param used_vars: str + :param token_list: Token list which is also peppered with Name. + :param token_list: list + :param start_pos: Position (line, column) of the Statement. + :type start_pos: tuple(int, int) + """ + def __init__(self, code, set_vars, used_funcs, used_vars, token_list, + start_pos, end_pos): + super(Statement, self).__init__(start_pos, end_pos) + self.code = code + self.used_funcs = used_funcs + self.used_vars = used_vars + self.token_list = token_list + for s in set_vars + used_funcs + used_vars: + s.parent = self + self.set_vars = self._remove_executions_from_set_vars(set_vars) + + # cache + self._assignment_calls = None + self._assignment_details = None + # this is important for other scripts + self._assignment_calls_calculated = False + + def _remove_executions_from_set_vars(self, set_vars): + """ + Important mainly for assosiative arrays: + + >>> a = 3 + >>> b = {} + >>> b[a] = 3 + + `a` is in this case not a set_var, it is used to index the dict. + """ + + if not set_vars: + return set_vars + result = set(set_vars) + last = None + in_execution = 0 + for tok in self.token_list: + if isinstance(tok, Name): + if tok not in result: + break + if in_execution: + result.remove(tok) + elif isinstance(tok, tuple): + tok = tok[1] + if tok in ['(', '['] and isinstance(last, Name): + in_execution += 1 + elif tok in [')', ']'] and in_execution > 0: + in_execution -= 1 + last = tok + return list(result) + + def get_code(self, new_line=True): + if new_line: + return self.code + '\n' + else: + return self.code + + def get_set_vars(self): + """ Get the names for the statement. """ + return list(self.set_vars) + + @property + def assignment_details(self): + if self._assignment_details is None: + # normally, this calls sets this variable + self.get_assignment_calls() + # it may not have been set by get_assignment_calls -> just use an empty + # array + return self._assignment_details or [] + + def is_global(self): + # first keyword of the first token is global -> must be a global + return str(self.token_list[0]) == "global" + + def get_assignment_calls(self): + """ + This is not done in the main parser, because it might be slow and + most of the statements won't need this data anyway. This is something + 'like' a lazy execution. + + This is not really nice written, sorry for that. If you plan to replace + it and make it nicer, that would be cool :-) + """ + if self._assignment_calls_calculated: + return self._assignment_calls + self._assignment_details = [] + top = result = Array(self.start_pos, Array.NOARRAY, self) + level = 0 + is_chain = False + close_brackets = False + + tok_iter = enumerate(self.token_list) + for i, tok_temp in tok_iter: + #print 'tok', tok_temp, result + if isinstance(tok_temp, ListComprehension): + result.add_to_current_field(tok_temp) + continue + try: + token_type, tok, start_pos = tok_temp + except TypeError: + # the token is a Name, which has already been parsed + tok = tok_temp + token_type = None + start_pos = tok.start_pos + except ValueError: + debug.warning("unkown value, shouldn't happen", + tok_temp, type(tok_temp)) + raise + else: + if tok in ['return', 'yield'] or level == 0 and \ + tok.endswith('=') and not tok in ['>=', '<=', '==', '!=']: + # This means, there is an assignment here. + + # Add assignments, which can be more than one + self._assignment_details.append((tok, top)) + # All these calls wouldn't be important if nonlocal would + # exist. -> Initialize the first item again. + result = Array(start_pos, Array.NOARRAY, self) + top = result + level = 0 + close_brackets = False + is_chain = False + continue + elif tok == 'as': + next(tok_iter, None) + continue + + brackets = {'(': Array.TUPLE, '[': Array.LIST, '{': Array.SET} + is_call = lambda: type(result) == Call + is_call_or_close = lambda: is_call() or close_brackets + + is_literal = token_type in [tokenize.STRING, tokenize.NUMBER] + if isinstance(tok, Name) or is_literal: + c_type = Call.NAME + if is_literal: + tok = literal_eval(tok) + if token_type == tokenize.STRING: + c_type = Call.STRING + elif token_type == tokenize.NUMBER: + c_type = Call.NUMBER + + if is_chain: + call = Call(tok, c_type, start_pos, parent=result) + result = result.set_next_chain_call(call) + is_chain = False + close_brackets = False + else: + if close_brackets: + result = result.parent + close_brackets = False + if type(result) == Call: + result = result.parent + call = Call(tok, c_type, start_pos, parent=result) + result.add_to_current_field(call) + result = call + elif tok in brackets.keys(): # brackets + level += 1 + if is_call_or_close(): + result = Array(start_pos, brackets[tok], parent=result) + result = result.parent.add_execution(result) + close_brackets = False + else: + result = Array(start_pos, brackets[tok], parent=result) + result.parent.add_to_current_field(result) + elif tok == ':': + while is_call_or_close(): + result = result.parent + close_brackets = False + if result.type == Array.LIST: # [:] lookups + result.add_to_current_field(tok) + else: + result.add_dictionary_key() + elif tok == '.': + if close_brackets and result.parent != top: + # only get out of the array, if it is a array execution + result = result.parent + close_brackets = False + is_chain = True + elif tok == ',': + while is_call_or_close(): + result = result.parent + close_brackets = False + result.add_field((start_pos[0], start_pos[1] + 1)) + # important - it cannot be empty anymore + if result.type == Array.NOARRAY: + result.type = Array.TUPLE + elif tok in [')', '}', ']']: + while is_call_or_close(): + result = result.parent + close_brackets = False + if tok == '}' and not len(result): + # this is a really special case - empty brackets {} are + # always dictionaries and not sets. + result.type = Array.DICT + level -= 1 + result.end_pos = start_pos[0], start_pos[1] + 1 + close_brackets = True + else: + while is_call_or_close(): + result = result.parent + close_brackets = False + if tok != '\n': + result.add_to_current_field(tok) + + if level != 0: + debug.warning("Brackets don't match: %s." + "This is not normal behaviour." % level) + + self._assignment_calls_calculated = True + self._assignment_calls = top + return top + + +class Param(Statement): + """ + The class which shows definitions of params of classes and functions. + But this is not to define function calls. + """ + def __init__(self, code, set_vars, used_funcs, used_vars, + token_list, start_pos, end_pos): + super(Param, self).__init__(code, set_vars, used_funcs, used_vars, + token_list, start_pos, end_pos) + + # this is defined by the parser later on, not at the initialization + # it is the position in the call (first argument, second...) + self.position_nr = None + self.is_generated = False + self.annotation_stmt = None + self.parent_function = None + + def add_annotation(self, annotation_stmt): + annotation_stmt.parent = self + self.annotation_stmt = annotation_stmt + + def get_name(self): + """ get the name of the param """ + n = self.set_vars or self.used_vars + if len(n) > 1: + debug.warning("Multiple param names (%s)." % n) + return n[0] + + +class Call(Base): + """ + `Call` contains a call, e.g. `foo.bar` and owns the executions of those + calls, which are `Array`s. + """ + NAME = 1 + NUMBER = 2 + STRING = 3 + + def __init__(self, name, type, start_pos, parent_stmt=None, parent=None): + self.name = name + # parent is not the oposite of next. The parent of c: a = [b.c] would + # be an array. + self.parent = parent + self.type = type + self.start_pos = start_pos + + self.next = None + self.execution = None + self._parent_stmt = parent_stmt + + @property + def parent_stmt(self): + if self._parent_stmt is not None: + return self._parent_stmt + elif self.parent: + return self.parent.parent_stmt + else: + return None + + @parent_stmt.setter + def parent_stmt(self, value): + self._parent_stmt = value + + def set_next_chain_call(self, call): + """ Adds another part of the statement""" + self.next = call + call.parent = self.parent + return call + + def add_execution(self, call): + """ + An execution is nothing else than brackets, with params in them, which + shows access on the internals of this name. + """ + self.execution = call + # there might be multiple executions, like a()[0], in that case, they + # have the same parent. Otherwise it's not possible to parse proper. + if self.parent.execution == self: + call.parent = self.parent + else: + call.parent = self + return call + + def generate_call_path(self): + """ Helps to get the order in which statements are executed. """ + # TODO include previous nodes? As an option? + try: + for name_part in self.name.names: + yield name_part + except AttributeError: + yield self + if self.execution is not None: + for y in self.execution.generate_call_path(): + yield y + if self.next is not None: + for y in self.next.generate_call_path(): + yield y + + def get_code(self): + if self.type == Call.NAME: + s = self.name.get_code() + else: + s = repr(self.name) + if self.execution is not None: + s += '(%s)' % self.execution.get_code() + if self.next is not None: + s += self.next.get_code() + return s + + def __repr__(self): + return "<%s: %s>" % \ + (type(self).__name__, self.name) + + +class Array(Call): + """ + Describes the different python types for an array, but also empty + statements. In the Python syntax definitions this type is named 'atom'. + http://docs.python.org/py3k/reference/grammar.html + Array saves sub-arrays as well as normal operators and calls to methods. + + :param array_type: The type of an array, which can be one of the constants\ + below. + :type array_type: int + """ + NOARRAY = None + TUPLE = 'tuple' + LIST = 'list' + DICT = 'dict' + SET = 'set' + + def __init__(self, start_pos, arr_type=NOARRAY, parent_stmt=None, + parent=None, values=None): + super(Array, self).__init__(None, arr_type, start_pos, parent_stmt, + parent) + + self.values = values if values else [] + self.arr_el_pos = [] + self.keys = [] + self.end_pos = None + + def add_field(self, start_pos): + """ + Just add a new field to the values. + + Each value has a sub-array, because there may be different tokens in + one array. + """ + self.arr_el_pos.append(start_pos) + self.values.append([]) + + def add_to_current_field(self, tok): + """ Adds a token to the latest field (in content). """ + if not self.values: + # An empty round brace is just a tuple, filled it is unnecessary. + if self.type == Array.TUPLE: + self.type = Array.NOARRAY + # Add the first field, this is done here, because if nothing + # gets added, the list is empty, which is also needed sometimes. + self.values.append([]) + self.values[-1].append(tok) + + def add_dictionary_key(self): + """ + Only used for dictionaries, automatically adds the tokens added by now + from the values to keys, because the parser works this way. + """ + if self.type in (Array.LIST, Array.TUPLE): + return # these are basically code errors, just ignore + self.keys.append(self.values.pop()) + if self.type == Array.SET: + self.type = Array.DICT + self.values.append([]) + + def get_only_subelement(self): + """ + Returns the only element that an array contains. If it contains + more than one element, raise an exception. + """ + if len(self.values) != 1 or len(self.values[0]) != 1: + raise AttributeError("More than one value found") + return self.values[0][0] + + @staticmethod + def is_type(instance, *types): + """ + This is not only used for calls on the actual object, but for + ducktyping, to invoke this function with anything as `self`. + """ + if isinstance(instance, Array): + if instance.type in types: + return True + return False + + def __len__(self): + return len(self.values) + + def __getitem__(self, key): + return self.values[key] + + def __iter__(self): + if self.type == self.DICT: + return iter(zip(self.keys, self.values)) + else: + return iter(self.values) + + def get_code(self): + def to_str(el): + try: + return el.get_code() + except AttributeError: + return str(el) + + map = {Array.NOARRAY: '%s', + Array.TUPLE: '(%s)', + Array.LIST: '[%s]', + Array.DICT: '{%s}', + Array.SET: '{%s}' + } + inner = [] + for i, value in enumerate(self.values): + s = '' + try: + key = self.keys[i] + except IndexError: + pass + else: + for el in key[i]: + s += to_str(el) + for el in value: + s += to_str(el) + inner.append(s) + return map[self.type] % ', '.join(inner) + + def __repr__(self): + if self.type == self.NOARRAY: + typ = 'noarray' + else: + typ = self.type + return "<%s: %s%s>" % (type(self).__name__, typ, self.values) + + +class NamePart(str): + """ + A string. Sometimes it is important to know if the string belongs to a name + or not. + """ + def __new__(cls, s, start_pos): + self = super(NamePart, cls).__new__(cls, s) + self.start_pos = start_pos + return self + + @property + def end_pos(self): + return self.start_pos[0], self.start_pos[1] + len(self) + + +class Name(Simple): + """ + Used to define names in python. + Which means the whole namespace/class/function stuff. + So a name like "module.class.function" + would result in an array of [module, class, function] + """ + def __init__(self, names, start_pos, end_pos, parent=None): + super(Name, self).__init__(start_pos, end_pos) + self.names = tuple(n if isinstance(n, NamePart) else NamePart(*n) + for n in names) + if parent is not None: + self.parent = parent + + def get_code(self): + """ Returns the names in a full string format """ + return ".".join(self.names) + + def __str__(self): + return self.get_code() + + def __len__(self): + return len(self.names) + + +class ListComprehension(object): + """ Helper class for list comprehensions """ + def __init__(self, stmt, middle, input): + self.stmt = stmt + self.middle = middle + self.input = input + + def __repr__(self): + return "<%s: %s>" % \ + (type(self).__name__, self.get_code()) + + def get_code(self): + statements = self.stmt, self.middle, self.input + code = [s.get_code().replace('\n', '') for s in statements] + return "%s for %s in %s" % tuple(code) + + +class PyFuzzyParser(object): + """ + This class is used to parse a Python file, it then divides them into a + class structure of different scopes. + + :param code: The codebase for the parser. + :type code: str + :param user_position: The line/column, the user is currently on. + :type user_position: tuple(int, int) + """ + def __init__(self, code, module_path=None, user_position=None, + no_docstr=False, line_offset=0): + self.user_position = user_position + self.user_scope = None + self.user_stmt = None + self.code = code + '\n' # end with \n, because the parser needs it + self.no_docstr = no_docstr + + # initialize global Scope + self.module = Module(module_path) + self.scope = self.module + self.current = (None, None) + + # Stuff to fix tokenize errors. The parser is pretty good in tolerating + # any errors of tokenize and just parse ahead. + self._line_of_tokenize_restart = line_offset + + self.parse() + + # delete code again, only the parser needs it + del self.code + + def __repr__(self): + return "<%s: %s>" % (type(self).__name__, self.module) + + @property + def start_pos(self): + return (self._line_of_tokenize_restart + self._tokenize_start_pos[0], + self._tokenize_start_pos[1]) + + @property + def end_pos(self): + return (self._line_of_tokenize_restart + self._tokenize_end_pos[0], + self._tokenize_end_pos[1]) + + def _check_user_stmt(self, simple): + if not isinstance(simple, Param): + for tok_name in self.module.temp_used_names: + try: + self.module.used_names[tok_name].add(simple) + except KeyError: + self.module.used_names[tok_name] = set([simple]) + self.module.temp_used_names = [] + + if not self.user_position: + return + # the position is right + if simple.start_pos <= self.user_position <= simple.end_pos: + if self.user_stmt is not None: + # if there is already a user position (another import, because + # imports are splitted) the names are checked. + for n in simple.get_set_vars(): + if n.start_pos < self.user_position <= n.end_pos: + self.user_stmt = simple + else: + self.user_stmt = simple + + def _parsedotname(self, pre_used_token=None): + """ + The dot name parser parses a name, variable or function and returns + their names. + + :return: Tuple of Name, token_type, nexttoken. + :rtype: tuple(Name, int, str) + """ + def append(el): + names.append(el) + self.module.temp_used_names.append(el[0]) + + names = [] + if pre_used_token is None: + token_type, tok = self.next() + if token_type != tokenize.NAME and tok != '*': + return [], token_type, tok + else: + token_type, tok = pre_used_token + + if token_type != tokenize.NAME and tok != '*': + # token maybe a name or star + return None, token_type, tok + + append((tok, self.start_pos)) + first_pos = self.start_pos + while True: + token_type, tok = self.next() + if tok != '.': + break + token_type, tok = self.next() + if token_type != tokenize.NAME: + break + append((tok, self.start_pos)) + + n = Name(names, first_pos, self.end_pos) if names else None + return n, token_type, tok + + def _parseimportlist(self): + """ + The parser for the imports. Unlike the class and function parse + function, this returns no Import class, but rather an import list, + which is then added later on. + The reason, why this is not done in the same class lies in the nature + of imports. There are two ways to write them: + + - from ... import ... + - import ... + + To distinguish, this has to be processed after the parser. + + :return: List of imports. + :rtype: list + """ + imports = [] + brackets = False + continue_kw = [",", ";", "\n", ')'] \ + + list(set(keyword.kwlist) - set(['as'])) + while True: + defunct = False + token_type, tok = self.next() + if token_type == tokenize.ENDMARKER: + break + if brackets and tok == '\n': + self.next() + if tok == '(': # python allows only one `(` in the statement. + brackets = True + self.next() + i, token_type, tok = self._parsedotname(self.current) + if not i: + defunct = True + name2 = None + if tok == 'as': + name2, token_type, tok = self._parsedotname() + imports.append((i, name2, defunct)) + while tok not in continue_kw: + token_type, tok = self.next() + if not (tok == "," or brackets and tok == '\n'): + break + return imports + + def _parseparen(self): + """ + Functions and Classes have params (which means for classes + super-classes). They are parsed here and returned as Statements. + + :return: List of Statements + :rtype: list + """ + names = [] + tok = None + pos = 0 + breaks = [',', ':'] + while tok not in [')', ':']: + param, tok = self._parse_statement(added_breaks=breaks, + stmt_class=Param) + if param and tok == ':': + # parse annotations + annotation, tok = self._parse_statement(added_breaks=breaks) + if annotation: + param.add_annotation(annotation) + + # params without vars are usually syntax errors. + if param and (param.set_vars or param.used_vars): + param.position_nr = pos + names.append(param) + pos += 1 + + return names + + def _parsefunction(self): + """ + The parser for a text functions. Process the tokens, which follow a + function definition. + + :return: Return a Scope representation of the tokens. + :rtype: Function + """ + first_pos = self.start_pos + token_type, fname = self.next() + if token_type != tokenize.NAME: + return None + + fname = Name([(fname, self.start_pos)], self.start_pos, self.end_pos) + + token_type, open = self.next() + if open != '(': + return None + params = self._parseparen() + + token_type, colon = self.next() + annotation = None + if colon in ['-', '->']: + # parse annotations + if colon == '-': + # The Python 2 tokenizer doesn't understand this + token_type, colon = self.next() + if colon != '>': + return None + annotation, colon = self._parse_statement(added_breaks=[':']) + + if colon != ':': + return None + + # because of 2 line func param definitions + scope = Function(fname, params, first_pos, annotation) + if self.user_scope and scope != self.user_scope \ + and self.user_position > first_pos: + self.user_scope = scope + return scope + + def _parseclass(self): + """ + The parser for a text class. Process the tokens, which follow a + class definition. + + :return: Return a Scope representation of the tokens. + :rtype: Class + """ + first_pos = self.start_pos + token_type, cname = self.next() + if token_type != tokenize.NAME: + debug.warning("class: syntax err, token is not a name@%s (%s: %s)" + % (self.start_pos[0], tokenize.tok_name[token_type], cname)) + return None + + cname = Name([(cname, self.start_pos)], self.start_pos, self.end_pos) + + super = [] + token_type, next = self.next() + if next == '(': + super = self._parseparen() + token_type, next = self.next() + + if next != ':': + debug.warning("class syntax: %s@%s" % (cname, self.start_pos[0])) + return None + + # because of 2 line class initializations + scope = Class(cname, super, first_pos) + if self.user_scope and scope != self.user_scope \ + and self.user_position > first_pos: + self.user_scope = scope + return scope + + def _parse_statement(self, pre_used_token=None, added_breaks=None, + stmt_class=Statement, list_comp=False): + """ + Parses statements like: + + >>> a = test(b) + >>> a += 3 - 2 or b + + and so on. One line at a time. + + :param pre_used_token: The pre parsed token. + :type pre_used_token: set + :return: Statement + last parsed token. + :rtype: (Statement, str) + """ + + string = '' + set_vars = [] + used_funcs = [] + used_vars = [] + level = 0 # The level of parentheses + is_return = None + + if pre_used_token: + token_type, tok = pre_used_token + else: + token_type, tok = self.next() + + while token_type == tokenize.COMMENT: + # remove newline and comment + self.next() + token_type, tok = self.next() + + first_pos = self.start_pos + opening_brackets = ['{', '(', '['] + closing_brackets = ['}', ')', ']'] + + # the difference between "break" and "always break" is that the latter + # will even break in parentheses. This is true for typical flow + # commands like def and class and the imports, which will never be used + # in a statement. + breaks = ['\n', ':', ')'] + always_break = [';', 'import', 'from', 'class', 'def', 'try', 'except', + 'finally', 'while'] + if added_breaks: + breaks += added_breaks + + tok_list = [] + while not (tok in always_break or tok in breaks and level <= 0): + try: + set_string = None + #print 'parse_stmt', tok, tokenize.tok_name[token_type] + tok_list.append(self.current + (self.start_pos,)) + if tok == 'as': + string += " %s " % tok + token_type, tok = self.next() + if token_type == tokenize.NAME: + n, token_type, tok = self._parsedotname(self.current) + if n: + set_vars.append(n) + tok_list.append(n) + string += ".".join(n.names) + continue + elif token_type == tokenize.NAME: + if tok in ['return', 'yield', 'del', 'raise']: + if len(tok_list) > 1: + # this happens, when a statement has opening + # brackets, which are not closed again, here I just + # start a new statement. This is a hack, but I + # could not come up with a better solution. + # This is basically a reset of the statement. + debug.warning('keyword in statement %s@%s', + tok_list, self.start_pos[0]) + tok_list = [self.current + (self.start_pos,)] + set_vars = [] + used_funcs = [] + used_vars = [] + level = 0 + set_string = tok + ' ' + if tok in ['return', 'yield']: + is_return = tok + elif tok == 'for': + # list comprehensions! + middle, tok = self._parse_statement( + added_breaks=['in']) + if tok != 'in' or middle is None: + if middle is None: + level -= 1 + else: + middle.parent = self.scope + debug.warning('list comprehension formatting @%s' % + self.start_pos[0]) + continue + + b = [')', ']'] + in_clause, tok = self._parse_statement(added_breaks=b, + list_comp=True) + if tok not in b or in_clause is None: + middle.parent = self.scope + if in_clause is None: + self.gen.push_back(self._current_full) + else: + in_clause.parent = self.scope + in_clause.parent = self.scope + debug.warning('list comprehension in_clause %s@%s' + % (tok, self.start_pos[0])) + continue + other_level = 0 + + for i, tok in enumerate(reversed(tok_list)): + if not isinstance(tok, (Name, ListComprehension)): + tok = tok[1] + if tok in closing_brackets: + other_level -= 1 + elif tok in opening_brackets: + other_level += 1 + if other_level > 0: + break + else: + # could not detect brackets -> nested list comp + i = 0 + + tok_list, toks = tok_list[:-i], tok_list[-i:-1] + src = '' + for t in toks: + src += t[1] if isinstance(t, tuple) \ + else t.get_code() + st = Statement(src, [], [], [], + toks, first_pos, self.end_pos) + + for s in [st, middle, in_clause]: + s.parent = self.scope + tok = ListComprehension(st, middle, in_clause) + tok_list.append(tok) + if list_comp: + string = '' + string += tok.get_code() + continue + else: + n, token_type, tok = self._parsedotname(self.current) + # removed last entry, because we add Name + tok_list.pop() + if n: + tok_list.append(n) + if tok == '(': + # it must be a function + used_funcs.append(n) + else: + used_vars.append(n) + if string and re.match(r'[\w\d\'"]', string[-1]): + string += ' ' + string += ".".join(n.names) + continue + elif tok.endswith('=') and tok not in ['>=', '<=', '==', '!=']: + # there has been an assignement -> change vars + if level == 0: + set_vars += used_vars + used_vars = [] + elif tok in opening_brackets: + level += 1 + elif tok in closing_brackets: + level -= 1 + + string = set_string if set_string is not None else string + tok + token_type, tok = self.next() + except StopIteration: + # comes from tokenizer + break + + if not string: + return None, tok + #print 'new_stat', string, set_vars, used_funcs, used_vars + if self.freshscope and not self.no_docstr and len(tok_list) == 1 \ + and self.last_token[0] == tokenize.STRING: + self.scope.add_docstr(self.last_token[1]) + return None, tok + else: + stmt = stmt_class(string, set_vars, used_funcs, used_vars, + tok_list, first_pos, self.end_pos) + self._check_user_stmt(stmt) + if is_return: + # add returns to the scope + func = self.scope.get_parent_until(Function) + if is_return == 'yield': + func.is_generator = True + try: + func.returns.append(stmt) + except AttributeError: + debug.warning('return in non-function') + + if tok in always_break: + self.gen.push_back(self._current_full) + return stmt, tok + + def next(self): + return self.__next__() + + def __iter__(self): + return self + + def __next__(self): + """ Generate the next tokenize pattern. """ + try: + self._current_full = next(self.gen) + except tokenize.TokenError: + # We just ignore this error, I try to handle it earlier - as + # good as possible + debug.warning('parentheses not closed error') + except IndentationError: + # This is an error, that tokenize may produce, because the code + # is not indented as it should. Here it just ignores this line + # and restarts the parser. + # (This is a rather unlikely error message, for normal code, + # tokenize seems to be pretty tolerant) + debug.warning('indentation error on line %s, ignoring it' % + (self.start_pos[0])) + self._line_of_tokenize_restart = self.start_pos[0] + 1 + self.gen = PushBackIterator(tokenize.generate_tokens( + self.buf.readline)) + return self.next() + except StopIteration: + # set end_pos correctly, if we finish + s = self.scope + while s is not None: + s.end_pos = self.end_pos + s = s.parent + raise + + type, tok, self._tokenize_start_pos, self._tokenize_end_pos, \ + self.parserline = self._current_full + if self.user_position and (self.start_pos[0] == self.user_position[0] + or self.user_scope is None + and self.start_pos[0] >= self.user_position[0]): + debug.dbg('user scope found [%s] = %s' % \ + (self.parserline.replace('\n', ''), repr(self.scope))) + self.user_scope = self.scope + self.last_token = self.current + self.current = (type, tok) + return self.current + + def parse(self): + """ + The main part of the program. It analyzes the given code-text and + returns a tree-like scope. For a more detailed description, see the + class description. + + :param text: The code which should be parsed. + :param type: str + + :raises: IndentationError + """ + self.buf = StringIO(self.code) + self.gen = PushBackIterator(tokenize.generate_tokens( + self.buf.readline)) + + extended_flow = ['else', 'elif', 'except', 'finally'] + statement_toks = ['{', '[', '(', '`'] + + decorators = [] + self.freshscope = True + self.iterator = iter(self) + # This iterator stuff is not intentional. It grew historically. + for token_type, tok in self.iterator: + self.module.temp_used_names = [] + #debug.dbg('main: tok=[%s] type=[%s] indent=[%s]'\ + # % (tok, tokenize.tok_name[token_type], start_position[0])) + + while token_type == tokenize.DEDENT and self.scope != self.module: + token_type, tok = self.next() + if self.start_pos[1] <= self.scope.start_pos[1]: + self.scope.end_pos = self.start_pos + self.scope = self.scope.parent + + # check again for unindented stuff. this is true for syntax + # errors. only check for names, because thats relevant here. If + # some docstrings are not indented, I don't care. + while self.start_pos[1] <= self.scope.start_pos[1] \ + and (token_type == tokenize.NAME or tok in ['(', '['])\ + and self.scope != self.module: + self.scope.end_pos = self.start_pos + self.scope = self.scope.parent + + first_pos = self.start_pos + if tok == 'def': + func = self._parsefunction() + if func is None: + debug.warning("function: syntax error@%s" % + self.start_pos[0]) + continue + self.freshscope = True + self.scope = self.scope.add_scope(func, decorators) + decorators = [] + elif tok == 'class': + cls = self._parseclass() + if cls is None: + debug.warning("class: syntax error@%s" % self.start_pos[0]) + continue + self.freshscope = True + self.scope = self.scope.add_scope(cls, decorators) + decorators = [] + # import stuff + elif tok == 'import': + imports = self._parseimportlist() + for m, alias, defunct in imports: + i = Import(first_pos, self.end_pos, m, alias, + defunct=defunct) + self._check_user_stmt(i) + self.scope.add_import(i) + if not imports: + i = Import(first_pos, self.end_pos, None, defunct=True) + self._check_user_stmt(i) + self.freshscope = False + elif tok == 'from': + defunct = False + # take care for relative imports + relative_count = 0 + while 1: + token_type, tok = self.next() + if tok != '.': + break + relative_count += 1 + # the from import + mod, token_type, tok = self._parsedotname(self.current) + if str(mod) == 'import' and relative_count: + self.gen.push_back(self._current_full) + tok = 'import' + mod = None + if not mod and not relative_count or tok != "import": + debug.warning("from: syntax error@%s" % self.start_pos[0]) + defunct = True + if tok != 'import': + self.gen.push_back(self._current_full) + names = self._parseimportlist() + for name, alias, defunct2 in names: + star = name is not None and name.names[0] == '*' + if star: + name = None + i = Import(first_pos, self.end_pos, name, alias, mod, + star, relative_count, defunct=defunct or defunct2) + self._check_user_stmt(i) + self.scope.add_import(i) + self.freshscope = False + #loops + elif tok == 'for': + set_stmt, tok = self._parse_statement(added_breaks=['in']) + if tok == 'in': + statement, tok = self._parse_statement() + if tok == ':': + s = [] if statement is None else [statement] + f = ForFlow(s, first_pos, set_stmt) + self.scope = self.scope.add_statement(f) + else: + debug.warning('syntax err, for flow started @%s', + self.start_pos[0]) + if statement is not None: + statement.parent = self.scope + if set_stmt is not None: + set_stmt.parent = self.scope + else: + debug.warning('syntax err, for flow incomplete @%s', + self.start_pos[0]) + if set_stmt is not None: + set_stmt.parent = self.scope + + elif tok in ['if', 'while', 'try', 'with'] + extended_flow: + added_breaks = [] + command = tok + if command in ['except', 'with']: + added_breaks.append(',') + # multiple statements because of with + inits = [] + first = True + while first or command == 'with' \ + and tok not in [':', '\n']: + statement, tok = \ + self._parse_statement(added_breaks=added_breaks) + if command == 'except' and tok in added_breaks: + # the except statement defines a var + # this is only true for python 2 + n, token_type, tok = self._parsedotname() + if n: + statement.set_vars.append(n) + statement.code += ',' + n.get_code() + if statement: + inits.append(statement) + first = False + + if tok == ':': + f = Flow(command, inits, first_pos) + if command in extended_flow: + # the last statement has to be another part of + # the flow statement, because a dedent releases the + # main scope, so just take the last statement. + try: + s = self.scope.statements[-1].set_next(f) + except (AttributeError, IndexError): + # If set_next doesn't exist, just add it. + s = self.scope.add_statement(f) + else: + s = self.scope.add_statement(f) + self.scope = s + else: + for i in inits: + i.parent = self.scope + debug.warning('syntax err, flow started @%s', + self.start_pos[0]) + # globals + elif tok == 'global': + stmt, tok = self._parse_statement(self.current) + if stmt: + self.scope.add_statement(stmt) + for name in stmt.used_vars: + # add the global to the top, because there it is + # important. + self.module.add_global(name) + # decorator + elif tok == '@': + stmt, tok = self._parse_statement() + decorators.append(stmt) + elif tok == 'pass': + continue + elif tok == 'assert': + stmt, tok = self._parse_statement() + stmt.parent = self.scope + self.scope.asserts.append(stmt) + # default + elif token_type in [tokenize.NAME, tokenize.STRING, + tokenize.NUMBER] \ + or tok in statement_toks: + # this is the main part - a name can be a function or a + # normal var, which can follow anything. but this is done + # by the statement parser. + stmt, tok = self._parse_statement(self.current) + if stmt: + self.scope.add_statement(stmt) + self.freshscope = False + else: + if token_type not in [tokenize.COMMENT, tokenize.INDENT, + tokenize.NEWLINE, tokenize.NL, + tokenize.ENDMARKER]: + debug.warning('token not classified', tok, token_type, + self.start_pos[0]) + + del self.buf + return self.module diff --git a/common/.local/lib/python2.7/site-packages/jedi/settings.py b/common/.local/lib/python2.7/site-packages/jedi/settings.py new file mode 100644 index 0000000..23f366d --- /dev/null +++ b/common/.local/lib/python2.7/site-packages/jedi/settings.py @@ -0,0 +1,87 @@ +# ---------------- +# completion output settings +# ---------------- + +# The completion is by default case insensitive. +case_insensitive_completion = True + +# Adds a dot after a module, because a module that is not accessed this way is +# definitely not the normal case. However, in VIM this doesn't work, that's why +# it isn't used at the moment. +add_dot_after_module = False + +# Adds an opening bracket after a function, because that's normal behaviour. +# Removed it again, because in VIM that is not very practical. +add_bracket_after_function = False + + +# ---------------- +# dynamic stuff +# ---------------- + +# check for `append`, etc. on array instances like list() +dynamic_arrays_instances = True +# check for `append`, etc. on arrays: [], {}, () +dynamic_array_additions = True + +# A dynamic param completion, finds the callees of the function, which define +# the params of a function. +dynamic_params = True +# Do the same for other modules. +dynamic_params_for_other_modules = True + +# Additional modules in which Jedi checks if statements are to be found. This +# is practical for IDE's, that want to administrate their modules themselves. +additional_dynamic_modules = [] + +# ---------------- +# recursions +# ---------------- + +# Recursion settings are important if you don't want extremly recursive python +# code to go absolutely crazy. First of there is a global limit +# `max_executions`. This limit is important, to set a maximum amount of time, +# the completion may use. +# +# The `max_until_execution_unique` limit is probably the most important one, +# because if that limit is passed, functions can only be one time executed. So +# new functions will be executed, complex recursions with the same functions +# again and again, are ignored. +# +# `max_function_recursion_level` is more about whether the recursions are +# stopped in deepth or in width. The ratio beetween this and +# `max_until_execution_unique` is important here. It stops a recursion (after +# the number of function calls in the recursion), if it was already used +# earlier. +# +# The values are based on my experimental tries, used on the jedi library. But +# I don't think there's any other Python library, that uses recursion in a +# similar (extreme) way. This makes the completion definitely worse in some +# cases. But a completion should also be fast. + +max_function_recursion_level = 5 +max_until_execution_unique = 50 +max_executions_without_builtins = 200 +max_executions = 250 + +# Because get_in_function_call is normally used on every single key hit, it has +# to be faster than a normal completion. This is the factor that is used to +# scale `max_executions` and `max_until_execution_unique`: +scale_get_in_function_call = 0.1 + +# ---------------- +# various +# ---------------- + +# Size of the current code part, which is used to speed up parsing. +part_line_length = 20 + +# ---------------- +# star import caching +# ---------------- + +# In huge packages like numpy, checking all star imports on every completion +# might be slow, therefore we do a star import caching, that lasts a certain +# time span (in seconds). + +star_import_cache_validity = 60.0 diff --git a/common/.local/lib/python2.7/site-packages/powerline/segments/vim.py b/common/.local/lib/python2.7/site-packages/powerline/segments/vim.py index 9e7a8b6..21dff03 100644 --- a/common/.local/lib/python2.7/site-packages/powerline/segments/vim.py +++ b/common/.local/lib/python2.7/site-packages/powerline/segments/vim.py @@ -184,7 +184,7 @@ def file_name(pl, segment_info, display_no_file=False, no_file_text='[No file]') }] else: return None - file_name = vim_funcs['fnamemodify'](name, ':~:.:t') + file_name = vim_funcs['fnamemodify'](name, ':~:.:t').decode('utf-8') return file_name diff --git a/common/.vim/bundle/nerdtree/.git/HEAD b/common/.vim/bundle/nerdtree/.git/HEAD deleted file mode 100644 index cb089cd..0000000 --- a/common/.vim/bundle/nerdtree/.git/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/common/.vim/bundle/nerdtree/.git/config b/common/.vim/bundle/nerdtree/.git/config deleted file mode 100644 index bf20b6d..0000000 --- a/common/.vim/bundle/nerdtree/.git/config +++ /dev/null @@ -1,11 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true -[remote "origin"] - fetch = +refs/heads/*:refs/remotes/origin/* - url = https://github.com/scrooloose/nerdtree.git -[branch "master"] - remote = origin - merge = refs/heads/master diff --git a/common/.vim/bundle/nerdtree/.git/description b/common/.vim/bundle/nerdtree/.git/description deleted file mode 100644 index 498b267..0000000 --- a/common/.vim/bundle/nerdtree/.git/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/common/.vim/bundle/nerdtree/.git/hooks/applypatch-msg.sample b/common/.vim/bundle/nerdtree/.git/hooks/applypatch-msg.sample deleted file mode 100755 index 8b2a2fe..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/common/.vim/bundle/nerdtree/.git/hooks/commit-msg.sample b/common/.vim/bundle/nerdtree/.git/hooks/commit-msg.sample deleted file mode 100755 index b58d118..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/common/.vim/bundle/nerdtree/.git/hooks/post-update.sample b/common/.vim/bundle/nerdtree/.git/hooks/post-update.sample deleted file mode 100755 index ec17ec1..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/common/.vim/bundle/nerdtree/.git/hooks/pre-applypatch.sample b/common/.vim/bundle/nerdtree/.git/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/common/.vim/bundle/nerdtree/.git/hooks/pre-commit.sample b/common/.vim/bundle/nerdtree/.git/hooks/pre-commit.sample deleted file mode 100755 index 18c4829..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/pre-commit.sample +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ascii filenames set this variable to true. -allownonascii=$(git config hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ascii filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - echo "Error: Attempt to add a non-ascii file name." - echo - echo "This can cause problems if you want to work" - echo "with people on other platforms." - echo - echo "To be portable it is advisable to rename the file ..." - echo - echo "If you know what you are doing you can disable this" - echo "check using:" - echo - echo " git config hooks.allownonascii true" - echo - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/common/.vim/bundle/nerdtree/.git/hooks/pre-rebase.sample b/common/.vim/bundle/nerdtree/.git/hooks/pre-rebase.sample deleted file mode 100755 index 33730ca..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/common/.vim/bundle/nerdtree/.git/hooks/prepare-commit-msg.sample b/common/.vim/bundle/nerdtree/.git/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/common/.vim/bundle/nerdtree/.git/hooks/update.sample b/common/.vim/bundle/nerdtree/.git/hooks/update.sample deleted file mode 100755 index 71ab04e..0000000 --- a/common/.vim/bundle/nerdtree/.git/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/common/.vim/bundle/nerdtree/.git/index b/common/.vim/bundle/nerdtree/.git/index deleted file mode 100644 index 9f2de7c..0000000 Binary files a/common/.vim/bundle/nerdtree/.git/index and /dev/null differ diff --git a/common/.vim/bundle/nerdtree/.git/info/exclude b/common/.vim/bundle/nerdtree/.git/info/exclude deleted file mode 100644 index a5196d1..0000000 --- a/common/.vim/bundle/nerdtree/.git/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/common/.vim/bundle/nerdtree/.git/logs/HEAD b/common/.vim/bundle/nerdtree/.git/logs/HEAD deleted file mode 100644 index 2348d75..0000000 --- a/common/.vim/bundle/nerdtree/.git/logs/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 c3b63d2fd9c929359231363bcabc880ba29eb96e Christophe Buffenoir 1357751567 +0100 clone: from https://github.com/scrooloose/nerdtree.git diff --git a/common/.vim/bundle/nerdtree/.git/logs/refs/heads/master b/common/.vim/bundle/nerdtree/.git/logs/refs/heads/master deleted file mode 100644 index 2348d75..0000000 --- a/common/.vim/bundle/nerdtree/.git/logs/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 c3b63d2fd9c929359231363bcabc880ba29eb96e Christophe Buffenoir 1357751567 +0100 clone: from https://github.com/scrooloose/nerdtree.git diff --git a/common/.vim/bundle/nerdtree/.git/logs/refs/remotes/origin/HEAD b/common/.vim/bundle/nerdtree/.git/logs/refs/remotes/origin/HEAD deleted file mode 100644 index 2348d75..0000000 --- a/common/.vim/bundle/nerdtree/.git/logs/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 c3b63d2fd9c929359231363bcabc880ba29eb96e Christophe Buffenoir 1357751567 +0100 clone: from https://github.com/scrooloose/nerdtree.git diff --git a/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.idx b/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.idx deleted file mode 100644 index b846f8c..0000000 Binary files a/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.idx and /dev/null differ diff --git a/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.pack b/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.pack deleted file mode 100644 index d2e331d..0000000 Binary files a/common/.vim/bundle/nerdtree/.git/objects/pack/pack-fabae269ee6a303f1bab5c4620044bd810e1771f.pack and /dev/null differ diff --git a/common/.vim/bundle/nerdtree/.git/packed-refs b/common/.vim/bundle/nerdtree/.git/packed-refs deleted file mode 100644 index 1a031bf..0000000 --- a/common/.vim/bundle/nerdtree/.git/packed-refs +++ /dev/null @@ -1,23 +0,0 @@ -# pack-refs with: peeled -c3b63d2fd9c929359231363bcabc880ba29eb96e refs/remotes/origin/master -57ccede2509ed5c421cc7baacc9fade973069cd6 refs/remotes/origin/refactor-open -a856622f0cc38223b5147531394829a8456ec566 refs/tags/2.10.0 -95ee07c9d377c4e844d95e5272ea0152323b96e1 refs/tags/2.10.0rc1 -e6d2f12bf68a55f68ec9d99d467042fc799f677d refs/tags/2.11.0 -3cb3227d56959cca112f20973b41327213e3ba5a refs/tags/2.12.0 -0620b91efa4041288dc69325c53b3d98e8478536 refs/tags/2.13.0 -2ca4573b016a150bdb25e6a81062489e10f59463 refs/tags/2.14.0 -5fcdd03f1233305be3277dc72af3d0d1e3a41c9f refs/tags/2.14.1 -090791407e0b451838ad4f2eff086945f81a9d54 refs/tags/2.14.2 -9aba1c17f6a2803a8cc36ffea3d5ca2f63f544b7 refs/tags/2.14.3 -6a77424c253b1e2ec0d8f7d1f00a21b2fb27cb07 refs/tags/2.7.0 -a5bc034851fabe38e53527b569860fdc8a4a8cce refs/tags/2.7.1 -c008fb3983775f553b06db8f806757677b759113 refs/tags/2.8.0 -80e0bca4dc7f5ca80712f501d662efddc83755a7 refs/tags/2.9.0 -6f2401346381ccae42a818cb16ac1c52ee6728e2 refs/tags/3.0.0 -efe03d6988f6835c857ff27c99ebbe6d158a0c78 refs/tags/3.0.1 -bdfac3e25cd37ce757703c569f5abbcd70a2da83 refs/tags/3.1.0 -e7ebee3084cfe97b2084782f004a723f83be243f refs/tags/3.1.1 -241f2e9dfe866010889c9c190278b95080d944ed refs/tags/4.0.0 -153041ac939502746e5a24468910eb7214a3f593 refs/tags/4.1.0 -205367ab3f46dcc88b6ebb819a276e793a21e995 refs/tags/4.2.0 diff --git a/common/.vim/bundle/nerdtree/.git/refs/heads/master b/common/.vim/bundle/nerdtree/.git/refs/heads/master deleted file mode 100644 index 9e24bfd..0000000 --- a/common/.vim/bundle/nerdtree/.git/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -c3b63d2fd9c929359231363bcabc880ba29eb96e diff --git a/common/.vim/bundle/nerdtree/.git/refs/remotes/origin/HEAD b/common/.vim/bundle/nerdtree/.git/refs/remotes/origin/HEAD deleted file mode 100644 index 6efe28f..0000000 --- a/common/.vim/bundle/nerdtree/.git/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/remotes/origin/master diff --git a/common/.vim/bundle/nerdtree/.gitignore b/common/.vim/bundle/nerdtree/.gitignore deleted file mode 100644 index 3698c0e..0000000 --- a/common/.vim/bundle/nerdtree/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*~ -*.swp -tags diff --git a/common/.vim/bundle/nerdtree/README.markdown b/common/.vim/bundle/nerdtree/README.markdown deleted file mode 100644 index 60869de..0000000 --- a/common/.vim/bundle/nerdtree/README.markdown +++ /dev/null @@ -1,108 +0,0 @@ -The NERD Tree -============= - -Intro ------ - -The NERD tree allows you to explore your filesystem and to open files and -directories. It presents the filesystem to you in the form of a tree which you -manipulate with the keyboard and/or mouse. It also allows you to perform -simple filesystem operations. - -The following features and functionality are provided by the NERD tree: - - * Files and directories are displayed in a hierarchical tree structure - * Different highlighting is provided for the following types of nodes: - * files - * directories - * sym-links - * windows .lnk files - * read-only files - * executable files - * Many (customisable) mappings are provided to manipulate the tree: - * Mappings to open/close/explore directory nodes - * Mappings to open files in new/existing windows/tabs - * Mappings to change the current root of the tree - * Mappings to navigate around the tree - * ... - * Directories and files can be bookmarked. - * Most NERD tree navigation can also be done with the mouse - * Filtering of tree content (can be toggled at runtime) - * custom file filters to prevent e.g. vim backup files being displayed - * optional displaying of hidden files (. files) - * files can be "turned off" so that only directories are displayed - * The position and size of the NERD tree window can be customised - * The order in which the nodes in the tree are listed can be customised. - * A model of your filesystem is created/maintained as you explore it. This - has several advantages: - * All filesystem information is cached and is only re-read on demand - * If you revisit a part of the tree that you left earlier in your - session, the directory nodes will be opened/closed as you left them - * The script remembers the cursor position and window position in the NERD - tree so you can toggle it off (or just close the tree window) and then - reopen it (with NERDTreeToggle) the NERD tree window will appear exactly - as you left it - * You can have a separate NERD tree for each tab, share trees across tabs, - or a mix of both. - * By default the script overrides the default file browser (netw), so if - you :edit a directory a (slighly modified) NERD tree will appear in the - current window - * A programmable menu system is provided (simulates right clicking on a node) - * one default menu plugin is provided to perform basic filesytem - operations (create/delete/move/copy files/directories) - * There's an API for adding your own keymappings - -Installation ------------- - -[pathogen.vim](https://github.com/tpope/vim-pathogen) is the recommended way to install nerdtree. - - cd ~/.vim/bundle - git clone https://github.com/scrooloose/nerdtree.git - -Then reload vim, run `:helptags`, and check out `:help NERD_tree.txt`. - - -Faq ---- - -__Q. Can I have the nerdtree on every tab automatically?__ - -A. Nope. If this is something you want then chances are you aren't using tabs - and buffers as they were intended to be used. Read this - http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers - - If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) - -__Q. How can I open a NERDTree automatically when vim starts up?__ - -A. Stick this in your vimrc: `autocmd vimenter * NERDTree` - -__Q. How can I open a NERDTree automatically when vim starts up if no files were specified?__ - -A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif` - -__Q. How can I map a specific key or shortcut to open NERDTree?__ - -A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): `map :NERDTreeToggle` - -__Q. How can I close vim if the only window left open is a NERDTree?__ - -A. Stick this in your vimrc: - - `autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif` - - -Changelog ---------- - -4.2.0 (2011-12-28) - - * Add NERDTreeDirArrows option to make the UI use pretty arrow chars instead of the old +~| chars to define the tree structure (sickill) - * shift the syntax highlighting out into its own syntax file (gnap) * add some mac specific options to the filesystem menu - for macvim only (andersonfreitas) - * Add NERDTreeMinimalUI option to remove some non functional parts of the nerdtree ui (camthompson) - * tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the new behaviour (benjamingeiger) - * if no name is given to :Bookmark, make it default to the name of the target file/dir (minyoung) - * use 'file' completion when doing copying, create, and move operations (EvanDotPro) - * lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!) - diff --git a/common/.vim/bundle/nerdtree/autoload/nerdtree.vim b/common/.vim/bundle/nerdtree/autoload/nerdtree.vim deleted file mode 100644 index e6054e0..0000000 --- a/common/.vim/bundle/nerdtree/autoload/nerdtree.vim +++ /dev/null @@ -1,1391 +0,0 @@ -if exists("g:loaded_nerdtree_autoload") - finish -endif -let g:loaded_nerdtree_autoload = 1 - -function! nerdtree#version() - return '4.2.0' -endfunction - -" SECTION: General Functions {{{1 -"============================================================ -"FUNCTION: nerdtree#bufInWindows(bnum){{{2 -"[[STOLEN FROM VTREEEXPLORER.VIM]] -"Determine the number of windows open to this buffer number. -"Care of Yegappan Lakshman. Thanks! -" -"Args: -"bnum: the subject buffers buffer number -function! nerdtree#bufInWindows(bnum) - let cnt = 0 - let winnum = 1 - while 1 - let bufnum = winbufnr(winnum) - if bufnum < 0 - break - endif - if bufnum ==# a:bnum - let cnt = cnt + 1 - endif - let winnum = winnum + 1 - endwhile - - return cnt -endfunction - -" FUNCTION: nerdtree#bufNamePrefix() {{{2 -function! nerdtree#bufNamePrefix() - return 'NERD_tree_' -endfunction - -"FUNCTION: nerdtree#checkForBrowse(dir) {{{2 -"inits a secondary nerd tree in the current buffer if appropriate -function! nerdtree#checkForBrowse(dir) - if a:dir != '' && isdirectory(a:dir) - call g:NERDTreeCreator.CreateSecondary(a:dir) - endif -endfunction - -" FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2 -" completion function for the bookmark commands -function! nerdtree#completeBookmarks(A,L,P) - return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"') -endfunction - -"FUNCTION: nerdtree#compareBookmarks(dir) {{{2 -function! nerdtree#compareBookmarks(first, second) - return a:first.compareTo(a:second) -endfunction - -"FUNCTION: nerdtree#compareNodes(dir) {{{2 -function! nerdtree#compareNodes(n1, n2) - return a:n1.path.compareTo(a:n2.path) -endfunction - -" FUNCTION: nerdtree#createDefaultBindings() {{{2 -function! nerdtree#createDefaultBindings() - let s = '' . s:SID() . '_' - - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleMiddleMouse" }) - call NERDTreeAddKeyMap({ 'key': '', 'scope': "all", 'callback': s."handleLeftClick" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" }) - call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" }) - - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': s."chRootCwd" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" }) - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" }) - - call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" }) -endfunction - -" FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 -" Issue a deprecation warning for a:func. If a second arg is given, use this -" as the deprecation message -function! nerdtree#deprecated(func, ...) - let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated' - - if !exists('s:deprecationWarnings') - let s:deprecationWarnings = {} - endif - if !has_key(s:deprecationWarnings, a:func) - let s:deprecationWarnings[a:func] = 1 - echomsg msg - endif -endfunction - -"FUNCTION: nerdtree#escChars(dir) {{{2 -function! nerdtree#escChars() - if nerdtree#runningWindows() - return " `\|\"#%&,?()\*^<>" - endif - - return " \\`\|\"#%&,?()\*^<>[]" -endfunction - -" FUNCTION: nerdtree#exec(cmd) {{{2 -" same as :exec cmd but eventignore=all is set for the duration -function! nerdtree#exec(cmd) - let old_ei = &ei - set ei=all - exec a:cmd - let &ei = old_ei -endfunction - -" FUNCTION: nerdtree#findAndRevealPath() {{{2 -function! nerdtree#findAndRevealPath() - try - let p = g:NERDTreePath.New(expand("%:p")) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("no file for the current buffer") - return - endtry - - if p.isUnixHiddenPath() - let showhidden=g:NERDTreeShowHidden - let g:NERDTreeShowHidden = 1 - endif - - if !nerdtree#treeExistsForTab() - try - let cwd = g:NERDTreePath.New(getcwd()) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("current directory does not exist.") - let cwd = p.getParent() - endtry - - if p.isUnder(cwd) - call g:NERDTreeCreator.CreatePrimary(cwd.str()) - else - call g:NERDTreeCreator.CreatePrimary(p.getParent().str()) - endif - else - if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path) - if !nerdtree#isTreeOpen() - call g:NERDTreeCreator.TogglePrimary('') - else - call nerdtree#putCursorInTreeWin() - endif - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - call nerdtree#chRoot(g:NERDTreeDirNode.New(p.getParent())) - else - if !nerdtree#isTreeOpen() - call g:NERDTreeCreator.TogglePrimary("") - endif - endif - endif - call nerdtree#putCursorInTreeWin() - call b:NERDTreeRoot.reveal(p) - - if p.isUnixHiddenFile() - let g:NERDTreeShowHidden = showhidden - endif -endfunction - -" FUNCTION: nerdtree#has_opt(options, name) {{{2 -function! nerdtree#has_opt(options, name) - return has_key(a:options, a:name) && a:options[a:name] == 1 -endfunction - -" FUNCTION: nerdtree#invokeKeyMap(key) {{{2 -"this is needed since I cant figure out how to invoke dict functions from a -"key map -function! nerdtree#invokeKeyMap(key) - call g:NERDTreeKeyMap.Invoke(a:key) -endfunction - -" FUNCTION: nerdtree#nextBufferName() {{{2 -" returns the buffer name for the next nerd tree -function! nerdtree#nextBufferName() - let name = nerdtree#bufNamePrefix() . nerdtree#nextBufferNumber() - return name -endfunction - -" FUNCTION: nerdtree#nextBufferNumber() {{{2 -" the number to add to the nerd tree buffer name to make the buf name unique -function! nerdtree#nextBufferNumber() - if !exists("s:nextBufNum") - let s:nextBufNum = 1 - else - let s:nextBufNum += 1 - endif - - return s:nextBufNum -endfunction - -" FUNCTION: nerdtree#postSourceActions() {{{2 -function! nerdtree#postSourceActions() - call g:NERDTreeBookmark.CacheBookmarks(0) - call nerdtree#createDefaultBindings() - - "load all nerdtree plugins - runtime! nerdtree_plugin/**/*.vim -endfunction - -"FUNCTION: nerdtree#runningWindows(dir) {{{2 -function! nerdtree#runningWindows() - return has("win16") || has("win32") || has("win64") -endfunction - -" Function: s:SID() {{{2 -function s:SID() - if !exists("s:sid") - let s:sid = matchstr(expand(''), '\zs\d\+\ze_SID$') - endif - return s:sid -endfun - -" FUNCTION: nerdtree#tabpagevar(tabnr, var) {{{2 -function! nerdtree#tabpagevar(tabnr, var) - let currentTab = tabpagenr() - let old_ei = &ei - set ei=all - - exec "tabnext " . a:tabnr - let v = -1 - if exists('t:' . a:var) - exec 'let v = t:' . a:var - endif - exec "tabnext " . currentTab - - let &ei = old_ei - - return v -endfunction - -" Function: nerdtree#treeExistsForBuffer() {{{2 -" Returns 1 if a nerd tree root exists in the current buffer -function! nerdtree#treeExistsForBuf() - return exists("b:NERDTreeRoot") -endfunction - -" Function: nerdtree#treeExistsForTab() {{{2 -" Returns 1 if a nerd tree root exists in the current tab -function! nerdtree#treeExistsForTab() - return exists("t:NERDTreeBufName") -endfunction - -"FUNCTION: nerdtree#treeMarkupReg(dir) {{{2 -function! nerdtree#treeMarkupReg() - if g:NERDTreeDirArrows - return '^\([▾▸] \| \+[▾▸] \| \+\)' - endif - - return '^[ `|]*[\-+~]' -endfunction - -"FUNCTION: nerdtree#treeUpDirLine(dir) {{{2 -function! nerdtree#treeUpDirLine() - return '.. (up a dir)' -endfunction - -"FUNCTION: nerdtree#treeWid(dir) {{{2 -function! nerdtree#treeWid() - return 2 -endfunction - -"FUNCTION: nerdtree#upDir(keepState) {{{2 -"moves the tree up a level -" -"Args: -"keepState: 1 if the current root should be left open when the tree is -"re-rendered -function! nerdtree#upDir(keepState) - let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) - if cwd ==# "/" || cwd =~# '^[^/]..$' - call nerdtree#echo("already at top dir") - else - if !a:keepState - call b:NERDTreeRoot.close() - endif - - let oldRoot = b:NERDTreeRoot - - if empty(b:NERDTreeRoot.parent) - let path = b:NERDTreeRoot.path.getParent() - let newRoot = g:NERDTreeDirNode.New(path) - call newRoot.open() - call newRoot.transplantChild(b:NERDTreeRoot) - let b:NERDTreeRoot = newRoot - else - let b:NERDTreeRoot = b:NERDTreeRoot.parent - endif - - if g:NERDTreeChDirMode ==# 2 - call b:NERDTreeRoot.path.changeToDir() - endif - - call nerdtree#renderView() - call oldRoot.putCursorHere(0, 0) - endif -endfunction - -" Function: nerdtree#unique(list) {{{2 -" returns a:list without duplicates -function! nerdtree#unique(list) - let uniqlist = [] - for elem in a:list - if index(uniqlist, elem) ==# -1 - let uniqlist += [elem] - endif - endfor - return uniqlist -endfunction - -" SECTION: View Functions {{{1 -"============================================================ -" -"FUNCTION: nerdtree#centerView() {{{2 -"centers the nerd tree window around the cursor (provided the nerd tree -"options permit) -function! nerdtree#centerView() - if g:NERDTreeAutoCenter - let current_line = winline() - let lines_to_top = current_line - let lines_to_bottom = winheight(nerdtree#getTreeWinNum()) - current_line - if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold - normal! zz - endif - endif -endfunction - -" FUNCTION: nerdtree#chRoot(node) {{{2 -" changes the current root to the selected one -function! nerdtree#chRoot(node) - call s:chRoot(a:node) -endfunction -"FUNCTION: nerdtree#closeTree() {{{2 -"Closes the primary NERD tree window for this tab -function! nerdtree#closeTree() - if !nerdtree#isTreeOpen() - throw "NERDTree.NoTreeFoundError: no NERDTree is open" - endif - - if winnr("$") != 1 - if winnr() == nerdtree#getTreeWinNum() - call nerdtree#exec("wincmd p") - let bufnr = bufnr("") - call nerdtree#exec("wincmd p") - else - let bufnr = bufnr("") - endif - - call nerdtree#exec(nerdtree#getTreeWinNum() . " wincmd w") - close - call nerdtree#exec(bufwinnr(bufnr) . " wincmd w") - else - close - endif -endfunction - -"FUNCTION: nerdtree#closeTreeIfOpen() {{{2 -"Closes the NERD tree window if it is open -function! nerdtree#closeTreeIfOpen() - if nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif -endfunction - -"FUNCTION: nerdtree#closeTreeIfQuitOnOpen() {{{2 -"Closes the NERD tree window if the close on open option is set -function! nerdtree#closeTreeIfQuitOnOpen() - if g:NERDTreeQuitOnOpen && nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif -endfunction - -"FUNCTION: nerdtree#dumpHelp {{{2 -"prints out the quick help -function! nerdtree#dumpHelp() - let old_h = @h - if b:treeShowHelp ==# 1 - let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n" - let @h=@h."\" ============================\n" - let @h=@h."\" File node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" - let @h=@h."\" ,\n" - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" - else - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" - endif - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" - endif - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" - let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" - let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n" - let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Directory node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" - let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" - let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" - let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" - let @h=@h."\" current node recursively\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Bookmark table mappings~\n" - let @h=@h."\" double-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree navigation mappings~\n" - let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" - let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" - let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" - let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" - let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" - let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Filesystem mappings~\n" - let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" - let @h=@h."\" selected dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" - let @h=@h."\" but leave old root open\n" - let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" - let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" - let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n" - let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" - let @h=@h."\" selected dir\n" - let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree filtering mappings~\n" - let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" - - "add quickhelp entries for each custom key map - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Custom mappings~\n" - for i in g:NERDTreeKeyMap.All() - if !empty(i.quickhelpText) - let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" - endif - endfor - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Other mappings~\n" - let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n" - let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n" - let @h=@h."\" the NERDTree window\n" - let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n" - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Bookmark commands~\n" - let @h=@h."\" :Bookmark \n" - let @h=@h."\" :BookmarkToRoot \n" - let @h=@h."\" :RevealBookmark \n" - let @h=@h."\" :OpenBookmark \n" - let @h=@h."\" :ClearBookmarks []\n" - let @h=@h."\" :ClearAllBookmarks\n" - silent! put h - elseif g:NERDTreeMinimalUI == 0 - let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" - silent! put h - endif - - let @h = old_h -endfunction - -"FUNCTION: nerdtree#echo {{{2 -"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages -" -"Args: -"msg: the message to echo -function! nerdtree#echo(msg) - redraw - echomsg "NERDTree: " . a:msg -endfunction - -"FUNCTION: nerdtree#echoError {{{2 -"Wrapper for nerdtree#echo, sets the message type to errormsg for this message -"Args: -"msg: the message to echo -function! nerdtree#echoError(msg) - echohl errormsg - call nerdtree#echo(a:msg) - echohl normal -endfunction - -"FUNCTION: nerdtree#echoWarning {{{2 -"Wrapper for nerdtree#echo, sets the message type to warningmsg for this message -"Args: -"msg: the message to echo -function! nerdtree#echoWarning(msg) - echohl warningmsg - call nerdtree#echo(a:msg) - echohl normal -endfunction - -"FUNCTION: nerdtree#firstUsableWindow(){{{2 -"find the window number of the first normal window -function! nerdtree#firstUsableWindow() - let i = 1 - while i <= winnr("$") - let bnum = winbufnr(i) - if bnum != -1 && getbufvar(bnum, '&buftype') ==# '' - \ && !getwinvar(i, '&previewwindow') - \ && (!getbufvar(bnum, '&modified') || &hidden) - return i - endif - - let i += 1 - endwhile - return -1 -endfunction - -"FUNCTION: nerdtree#getPath(ln) {{{2 -"Gets the full path to the node that is rendered on the given line number -" -"Args: -"ln: the line number to get the path for -" -"Return: -"A path if a node was selected, {} if nothing is selected. -"If the 'up a dir' line was selected then the path to the parent of the -"current root is returned -function! nerdtree#getPath(ln) - let line = getline(a:ln) - - let rootLine = g:NERDTreeFileNode.GetRootLineNum() - - "check to see if we have the root node - if a:ln == rootLine - return b:NERDTreeRoot.path - endif - - if !g:NERDTreeDirArrows - " in case called from outside the tree - if line !~# '^ *[|`▸▾ ]' || line =~# '^$' - return {} - endif - endif - - if line ==# nerdtree#treeUpDirLine() - return b:NERDTreeRoot.path.getParent() - endif - - let indent = nerdtree#indentLevelFor(line) - - "remove the tree parts and the leading space - let curFile = nerdtree#stripMarkupFromLine(line, 0) - - let wasdir = 0 - if curFile =~# '/$' - let wasdir = 1 - let curFile = substitute(curFile, '/\?$', '/', "") - endif - - let dir = "" - let lnum = a:ln - while lnum > 0 - let lnum = lnum - 1 - let curLine = getline(lnum) - let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1) - - "have we reached the top of the tree? - if lnum == rootLine - let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir - break - endif - if curLineStripped =~# '/$' - let lpindent = nerdtree#indentLevelFor(curLine) - if lpindent < indent - let indent = indent - 1 - - let dir = substitute (curLineStripped,'^\\', "", "") . dir - continue - endif - endif - endwhile - let curFile = b:NERDTreeRoot.path.drive . dir . curFile - let toReturn = g:NERDTreePath.New(curFile) - return toReturn -endfunction - -"FUNCTION: nerdtree#getTreeWinNum() {{{2 -"gets the nerd tree window number for this tab -function! nerdtree#getTreeWinNum() - if exists("t:NERDTreeBufName") - return bufwinnr(t:NERDTreeBufName) - else - return -1 - endif -endfunction - -"FUNCTION: nerdtree#indentLevelFor(line) {{{2 -function! nerdtree#indentLevelFor(line) - let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid() - " check if line includes arrows - if match(a:line, '[▸▾]') > -1 - " decrement level as arrow uses 3 ascii chars - let level = level - 1 - endif - return level -endfunction - -"FUNCTION: nerdtree#isTreeOpen() {{{2 -function! nerdtree#isTreeOpen() - return nerdtree#getTreeWinNum() != -1 -endfunction - -"FUNCTION: nerdtree#isWindowUsable(winnumber) {{{2 -"Returns 0 if opening a file from the tree in the given window requires it to -"be split, 1 otherwise -" -"Args: -"winnumber: the number of the window in question -function! nerdtree#isWindowUsable(winnumber) - "gotta split if theres only one window (i.e. the NERD tree) - if winnr("$") ==# 1 - return 0 - endif - - let oldwinnr = winnr() - call nerdtree#exec(a:winnumber . "wincmd p") - let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') - let modified = &modified - call nerdtree#exec(oldwinnr . "wincmd p") - - "if its a special window e.g. quickfix or another explorer plugin then we - "have to split - if specialWindow - return 0 - endif - - if &hidden - return 1 - endif - - return !modified || nerdtree#bufInWindows(winbufnr(a:winnumber)) >= 2 -endfunction - -" FUNCTION: nerdtree#jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! nerdtree#jumpToChild(currentNode, direction) - if a:currentNode.isRoot() - return nerdtree#echo("cannot jump to " . (a:direction ? "last" : "first") . " child") - end - let dirNode = a:currentNode.parent - let childNodes = dirNode.getVisibleChildren() - - let targetNode = childNodes[0] - if a:direction - let targetNode = childNodes[len(childNodes) - 1] - endif - - if targetNode.equals(a:currentNode) - let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction) - if siblingDir != {} - let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0 - let targetNode = siblingDir.getChildByIndex(indx, 1) - endif - endif - - call targetNode.putCursorHere(1, 0) - - call nerdtree#centerView() -endfunction - -" FUNCTION: nerdtree#jumpToSibling(currentNode, forward) {{{2 -" moves the cursor to the sibling of the current node in the given direction -" -" Args: -" forward: 1 if the cursor should move to the next sibling, 0 if it should -" move back to the previous sibling -function! nerdtree#jumpToSibling(currentNode, forward) - let sibling = a:currentNode.findSibling(a:forward) - - if !empty(sibling) - call sibling.putCursorHere(1, 0) - call nerdtree#centerView() - endif -endfunction - -"FUNCTION: nerdtree#promptToDelBuffer(bufnum, msg){{{2 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is deleted -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! nerdtree#promptToDelBuffer(bufnum, msg) - echo a:msg - if nr2char(getchar()) ==# 'y' - exec "silent bdelete! " . a:bufnum - endif -endfunction - -"FUNCTION: nerdtree#putCursorOnBookmarkTable(){{{2 -"Places the cursor at the top of the bookmarks table -function! nerdtree#putCursorOnBookmarkTable() - if !b:NERDTreeShowBookmarks - throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" - endif - - if g:NERDTreeMinimalUI - return cursor(1, 2) - endif - - let rootNodeLine = g:NERDTreeFileNode.GetRootLineNum() - - let line = 1 - while getline(line) !~# '^>-\+Bookmarks-\+$' - let line = line + 1 - if line >= rootNodeLine - throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" - endif - endwhile - call cursor(line, 2) -endfunction - -"FUNCTION: nerdtree#putCursorInTreeWin(){{{2 -"Places the cursor in the nerd tree window -function! nerdtree#putCursorInTreeWin() - if !nerdtree#isTreeOpen() - throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists" - endif - - call nerdtree#exec(nerdtree#getTreeWinNum() . "wincmd w") -endfunction - -"FUNCTION: nerdtree#renderBookmarks {{{2 -function! nerdtree#renderBookmarks() - - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) - endif - - for i in g:NERDTreeBookmark.Bookmarks() - call setline(line(".")+1, i.str()) - call cursor(line(".")+1, col(".")) - endfor - - call setline(line(".")+1, '') - call cursor(line(".")+1, col(".")) -endfunction - -"FUNCTION: nerdtree#renderView {{{2 -"The entry function for rendering the tree -function! nerdtree#renderView() - setlocal modifiable - - "remember the top line of the buffer and the current line so we can - "restore the view exactly how it was - let curLine = line(".") - let curCol = col(".") - let topLine = line("w0") - - "delete all lines in the buffer (being careful not to clobber a register) - silent 1,$delete _ - - call nerdtree#dumpHelp() - - "delete the blank line before the help and add one after it - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) - endif - - if b:NERDTreeShowBookmarks - call nerdtree#renderBookmarks() - endif - - "add the 'up a dir' line - if !g:NERDTreeMinimalUI - call setline(line(".")+1, nerdtree#treeUpDirLine()) - call cursor(line(".")+1, col(".")) - endif - - "draw the header line - let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) - call setline(line(".")+1, header) - call cursor(line(".")+1, col(".")) - - "draw the tree - let old_o = @o - let @o = b:NERDTreeRoot.renderToString() - silent put o - let @o = old_o - - "delete the blank line at the top of the buffer - silent 1,1delete _ - - "restore the view - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(topLine, 1) - normal! zt - call cursor(curLine, curCol) - let &scrolloff = old_scrolloff - - setlocal nomodifiable -endfunction - -"FUNCTION: nerdtree#renderViewSavingPosition {{{2 -"Renders the tree and ensures the cursor stays on the current node or the -"current nodes parent if it is no longer available upon re-rendering -function! nerdtree#renderViewSavingPosition() - let currentNode = g:NERDTreeFileNode.GetSelected() - - "go up the tree till we find a node that will be visible or till we run - "out of nodes - while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot() - let currentNode = currentNode.parent - endwhile - - call nerdtree#renderView() - - if currentNode != {} - call currentNode.putCursorHere(0, 0) - endif -endfunction -" -"FUNCTION: nerdtree#restoreScreenState() {{{2 -" -"Sets the screen state back to what it was when nerdtree#saveScreenState was last -"called. -" -"Assumes the cursor is in the NERDTree window -function! nerdtree#restoreScreenState() - if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize") - return - endif - exec("silent vertical resize ".b:NERDTreeOldWindowSize) - - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(b:NERDTreeOldTopLine, 0) - normal! zt - call setpos(".", b:NERDTreeOldPos) - let &scrolloff=old_scrolloff -endfunction - -"FUNCTION: nerdtree#saveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function! nerdtree#saveScreenState() - let win = winnr() - try - call nerdtree#putCursorInTreeWin() - let b:NERDTreeOldPos = getpos(".") - let b:NERDTreeOldTopLine = line("w0") - let b:NERDTreeOldWindowSize = winwidth("") - call nerdtree#exec(win . "wincmd w") - catch /^NERDTree.InvalidOperationError/ - endtry -endfunction - -"FUNCTION: nerdtree#stripMarkupFromLine(line, removeLeadingSpaces){{{2 -"returns the given line with all the tree parts stripped off -" -"Args: -"line: the subject line -"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = -"any spaces before the actual text of the node) -function! nerdtree#stripMarkupFromLine(line, removeLeadingSpaces) - let line = a:line - "remove the tree parts and the leading space - let line = substitute (line, nerdtree#treeMarkupReg(),"","") - - "strip off any read only flag - let line = substitute (line, ' \[RO\]', "","") - - "strip off any bookmark flags - let line = substitute (line, ' {[^}]*}', "","") - - "strip off any executable flags - let line = substitute (line, '*\ze\($\| \)', "","") - - let wasdir = 0 - if line =~# '/$' - let wasdir = 1 - endif - let line = substitute (line,' -> .*',"","") " remove link to - if wasdir ==# 1 - let line = substitute (line, '/\?$', '/', "") - endif - - if a:removeLeadingSpaces - let line = substitute (line, '^ *', '', '') - endif - - return line -endfunction - -"SECTION: Interface bindings {{{1 -"============================================================ - -"FUNCTION: s:activateAll() {{{2 -"handle the user activating the updir line -function! s:activateAll() - if getline(".") ==# nerdtree#treeUpDirLine() - return nerdtree#upDir(0) - endif -endfunction -"FUNCTION: s:activateDirNode() {{{2 -"handle the user activating a tree node -function! s:activateDirNode(node) - call a:node.activate({'reuse': 1}) -endfunction - -"FUNCTION: s:activateFileNode() {{{2 -"handle the user activating a tree node -function! s:activateFileNode(node) - call a:node.activate({'reuse': 1, 'where': 'p'}) -endfunction - -"FUNCTION: s:activateBookmark() {{{2 -"handle the user activating a bookmark -function! s:activateBookmark(bm) - call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {}) -endfunction - -" FUNCTION: nerdtree#bookmarkNode(name) {{{2 -" Associate the current node with the given name -function! nerdtree#bookmarkNode(...) - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - let name = a:1 - if empty(name) - let name = currentNode.path.getLastPathComponent(0) - endif - try - call currentNode.bookmark(name) - call nerdtree#renderView() - catch /^NERDTree.IllegalBookmarkNameError/ - call nerdtree#echo("bookmark names must not contain spaces") - endtry - else - call nerdtree#echo("select a node first") - endif -endfunction - -" FUNCTION: s:chCwd(node) {{{2 -function! s:chCwd(node) - try - call a:node.path.changeToDir() - catch /^NERDTree.PathChangeError/ - call nerdtree#echoWarning("could not change cwd") - endtry -endfunction - -" FUNCTION: s:chRoot(node) {{{2 -" changes the current root to the selected one -function! s:chRoot(node) - call a:node.makeRoot() - call nerdtree#renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:chRootCwd() {{{2 -" changes the current root to CWD -function! s:chRootCwd() - try - let cwd = g:NERDTreePath.New(getcwd()) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("current directory does not exist.") - return - endtry - if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str() - return - endif - call nerdtree#chRoot(g:NERDTreeDirNode.New(cwd)) -endfunction - -" FUNCTION: nerdtree#clearBookmarks(bookmarks) {{{2 -function! nerdtree#clearBookmarks(bookmarks) - if a:bookmarks ==# '' - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - call currentNode.clearBookmarks() - endif - else - for name in split(a:bookmarks, ' ') - let bookmark = g:NERDTreeBookmark.BookmarkFor(name) - call bookmark.delete() - endfor - endif - call nerdtree#renderView() -endfunction - -" FUNCTION: s:closeChildren(node) {{{2 -" closes all childnodes of the current node -function! s:closeChildren(node) - call a:node.closeChildren() - call nerdtree#renderView() - call a:node.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:closeCurrentDir(node) {{{2 -" closes the parent dir of the current node -function! s:closeCurrentDir(node) - let parent = a:node.parent - if parent ==# {} || parent.isRoot() - call nerdtree#echo("cannot close tree root") - else - call a:node.parent.close() - call nerdtree#renderView() - call a:node.parent.putCursorHere(0, 0) - endif -endfunction - -" FUNCTION: s:closeTreeWindow() {{{2 -" close the tree window -function! s:closeTreeWindow() - if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1 - exec "buffer " . b:NERDTreePreviousBuf - else - if winnr("$") > 1 - call nerdtree#closeTree() - else - call nerdtree#echo("Cannot close last window") - endif - endif -endfunction - -" FUNCTION: s:deleteBookmark(bm) {{{2 -" if the cursor is on a bookmark, prompt to delete -function! s:deleteBookmark(bm) - echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):" - - if nr2char(getchar()) ==# 'y' - try - call a:bm.delete() - call nerdtree#renderView() - redraw - catch /^NERDTree/ - call nerdtree#echoWarning("Could not remove bookmark") - endtry - else - call nerdtree#echo("delete aborted" ) - endif - -endfunction - -" FUNCTION: s:displayHelp() {{{2 -" toggles the help display -function! s:displayHelp() - let b:treeShowHelp = b:treeShowHelp ? 0 : 1 - call nerdtree#renderView() - call nerdtree#centerView() -endfunction - -"FUNCTION: s:handleLeftClick() {{{2 -"Checks if the click should open the current node -function! s:handleLeftClick() - let currentNode = g:NERDTreeFileNode.GetSelected() - if currentNode != {} - - "the dir arrows are multibyte chars, and vim's string functions only - "deal with single bytes - so split the line up with the hack below and - "take the line substring manually - let line = split(getline(line(".")), '\zs') - let startToCur = "" - for i in range(0,len(line)-1) - let startToCur .= line[i] - endfor - - if currentNode.path.isDirectory - if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$' - call currentNode.activate() - return - endif - endif - - if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 - let char = strpart(startToCur, strlen(startToCur)-1, 1) - if char !~# nerdtree#treeMarkupReg() - if currentNode.path.isDirectory - call currentNode.activate() - else - call currentNode.activate({'reuse': 1, 'where': 'p'}) - endif - return - endif - endif - endif -endfunction - -" FUNCTION: s:handleMiddleMouse() {{{2 -function! s:handleMiddleMouse() - let curNode = g:NERDTreeFileNode.GetSelected() - if curNode ==# {} - call nerdtree#echo("Put the cursor on a node first" ) - return - endif - - if curNode.path.isDirectory - call nerdtree#openExplorer(curNode) - else - call curNode.open({'where': 'h'}) - endif -endfunction - -" FUNCTION: s:jumpToFirstChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToFirstChild(node) - call nerdtree#jumpToChild(a:node, 0) -endfunction - -" FUNCTION: s:jumpToLastChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToLastChild(node) - call nerdtree#jumpToChild(a:node, 1) -endfunction - -" FUNCTION: s:jumpToParent(node) {{{2 -" moves the cursor to the parent of the current node -function! s:jumpToParent(node) - if !empty(a:node.parent) - call a:node.parent.putCursorHere(1, 0) - call nerdtree#centerView() - else - call nerdtree#echo("cannot jump to parent") - endif -endfunction - -" FUNCTION: s:jumpToRoot() {{{2 -" moves the cursor to the root node -function! s:jumpToRoot() - call b:NERDTreeRoot.putCursorHere(1, 0) - call nerdtree#centerView() -endfunction - -" FUNCTION: s:jumpToNextSibling(node) {{{2 -function! s:jumpToNextSibling(node) - call nerdtree#jumpToSibling(a:node, 1) -endfunction - -" FUNCTION: s:jumpToPrevSibling(node) {{{2 -function! s:jumpToPrevSibling(node) - call nerdtree#jumpToSibling(a:node, 0) -endfunction - -" FUNCTION: nerdtree#openBookmark(name) {{{2 -" put the cursor on the given bookmark and, if its a file, open it -function! nerdtree#openBookmark(name) - try - let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - redraw! - catch /^NERDTree.BookmarkedNodeNotFoundError/ - call nerdtree#echo("note - target node is not cached") - let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name) - let targetNode = g:NERDTreeFileNode.New(bookmark.path) - endtry - if targetNode.path.isDirectory - call targetNode.openExplorer() - else - call targetNode.open({'where': 'p'}) - endif -endfunction - -" FUNCTION: s:openHSplit(target) {{{2 -function! s:openHSplit(target) - call a:target.activate({'where': 'h'}) -endfunction - -" FUNCTION: s:openVSplit(target) {{{2 -function! s:openVSplit(target) - call a:target.activate({'where': 'v'}) -endfunction - -" FUNCTION: s:openExplorer(node) {{{2 -function! s:openExplorer(node) - call a:node.openExplorer() -endfunction - -" FUNCTION: s:openInNewTab(target) {{{2 -function! s:openInNewTab(target) - call a:target.activate({'where': 't'}) -endfunction - -" FUNCTION: s:openInNewTabSilent(target) {{{2 -function! s:openInNewTabSilent(target) - call a:target.activate({'where': 't', 'stay': 1}) -endfunction - -" FUNCTION: s:openNodeRecursively(node) {{{2 -function! s:openNodeRecursively(node) - call nerdtree#echo("Recursively opening node. Please wait...") - call a:node.openRecursively() - call nerdtree#renderView() - redraw - call nerdtree#echo("Recursively opening node. Please wait... DONE") -endfunction - -"FUNCTION: s:previewNodeCurrent(node) {{{2 -function! s:previewNodeCurrent(node) - call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeHSplit(node) {{{2 -function! s:previewNodeHSplit(node) - call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1}) -endfunction - -"FUNCTION: s:previewNodeVSplit(node) {{{2 -function! s:previewNodeVSplit(node) - call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1}) -endfunction - -" FUNCTION: nerdtree#revealBookmark(name) {{{2 -" put the cursor on the node associate with the given name -function! nerdtree#revealBookmark(name) - try - let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - catch /^NERDTree.BookmarkNotFoundError/ - call nerdtree#echo("Bookmark isnt cached under the current root") - endtry -endfunction - -" FUNCTION: s:refreshRoot() {{{2 -" Reloads the current root. All nodes below this will be lost and the root dir -" will be reloaded. -function! s:refreshRoot() - call nerdtree#echo("Refreshing the root node. This could take a while...") - call b:NERDTreeRoot.refresh() - call nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing the root node. This could take a while... DONE") -endfunction - -" FUNCTION: s:refreshCurrent(node) {{{2 -" refreshes the root for the current node -function! s:refreshCurrent(node) - let node = a:node - if !node.path.isDirectory - let node = node.parent - endif - - call nerdtree#echo("Refreshing node. This could take a while...") - call node.refresh() - call nerdtree#renderView() - redraw - call nerdtree#echo("Refreshing node. This could take a while... DONE") -endfunction - -" FUNCTION: s:showMenu(node) {{{2 -function! s:showMenu(node) - let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled()) - call mc.showMenu() -endfunction - -" FUNCTION: s:toggleIgnoreFilter() {{{2 -" toggles the use of the NERDTreeIgnore option -function! s:toggleIgnoreFilter() - let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowBookmarks() {{{2 -" toggles the display of bookmarks -function! s:toggleShowBookmarks() - let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks - if b:NERDTreeShowBookmarks - call nerdtree#renderView() - call nerdtree#putCursorOnBookmarkTable() - else - call nerdtree#renderViewSavingPosition() - endif - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowFiles() {{{2 -" toggles the display of hidden files -function! s:toggleShowFiles() - let b:NERDTreeShowFiles = !b:NERDTreeShowFiles - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleShowHidden() {{{2 -" toggles the display of hidden files -function! s:toggleShowHidden() - let b:NERDTreeShowHidden = !b:NERDTreeShowHidden - call nerdtree#renderViewSavingPosition() - call nerdtree#centerView() -endfunction - -" FUNCTION: s:toggleZoom() {{{2 -" zoom (maximize/minimize) the NERDTree window -function! s:toggleZoom() - if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - exec "silent vertical resize ". size - let b:NERDTreeZoomed = 0 - else - exec "vertical resize" - let b:NERDTreeZoomed = 1 - endif -endfunction - -" FUNCTION: s:upDirCurrentRootOpen() {{{2 -function! s:upDirCurrentRootOpen() - call nerdtree#upDir(1) -endfunction - -" FUNCTION: s:upDirCurrentRootClosed() {{{2 -function! s:upDirCurrentRootClosed() - call nerdtree#upDir(0) -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/doc/NERD_tree.txt b/common/.vim/bundle/nerdtree/doc/NERD_tree.txt deleted file mode 100644 index 47f3472..0000000 --- a/common/.vim/bundle/nerdtree/doc/NERD_tree.txt +++ /dev/null @@ -1,1362 +0,0 @@ -*NERD_tree.txt* A tree explorer plugin that owns your momma! - - - - omg its ... ~ - - ________ ________ _ ____________ ____ __________ ____________~ - /_ __/ / / / ____/ / | / / ____/ __ \/ __ \ /_ __/ __ \/ ____/ ____/~ - / / / /_/ / __/ / |/ / __/ / /_/ / / / / / / / /_/ / __/ / __/ ~ - / / / __ / /___ / /| / /___/ _, _/ /_/ / / / / _, _/ /___/ /___ ~ - /_/ /_/ /_/_____/ /_/ |_/_____/_/ |_/_____/ /_/ /_/ |_/_____/_____/ ~ - - - Reference Manual~ - - - - -============================================================================== -CONTENTS *NERDTree-contents* - - 1.Intro...................................|NERDTree| - 2.Functionality provided..................|NERDTreeFunctionality| - 2.1.Global commands...................|NERDTreeGlobalCommands| - 2.2.Bookmarks.........................|NERDTreeBookmarks| - 2.2.1.The bookmark table..........|NERDTreeBookmarkTable| - 2.2.2.Bookmark commands...........|NERDTreeBookmarkCommands| - 2.2.3.Invalid bookmarks...........|NERDTreeInvalidBookmarks| - 2.3.NERD tree mappings................|NERDTreeMappings| - 2.4.The NERD tree menu................|NERDTreeMenu| - 3.Options.................................|NERDTreeOptions| - 3.1.Option summary....................|NERDTreeOptionSummary| - 3.2.Option details....................|NERDTreeOptionDetails| - 4.The NERD tree API.......................|NERDTreeAPI| - 4.1.Key map API.......................|NERDTreeKeymapAPI| - 4.2.Menu API..........................|NERDTreeMenuAPI| - 5.About...................................|NERDTreeAbout| - 6.Changelog...............................|NERDTreeChangelog| - 7.Credits.................................|NERDTreeCredits| - 8.License.................................|NERDTreeLicense| - -============================================================================== -1. Intro *NERDTree* - -What is this "NERD tree"?? - -The NERD tree allows you to explore your filesystem and to open files and -directories. It presents the filesystem to you in the form of a tree which you -manipulate with the keyboard and/or mouse. It also allows you to perform -simple filesystem operations. - -The following features and functionality are provided by the NERD tree: - * Files and directories are displayed in a hierarchical tree structure - * Different highlighting is provided for the following types of nodes: - * files - * directories - * sym-links - * windows .lnk files - * read-only files - * executable files - * Many (customisable) mappings are provided to manipulate the tree: - * Mappings to open/close/explore directory nodes - * Mappings to open files in new/existing windows/tabs - * Mappings to change the current root of the tree - * Mappings to navigate around the tree - * ... - * Directories and files can be bookmarked. - * Most NERD tree navigation can also be done with the mouse - * Filtering of tree content (can be toggled at runtime) - * custom file filters to prevent e.g. vim backup files being displayed - * optional displaying of hidden files (. files) - * files can be "turned off" so that only directories are displayed - * The position and size of the NERD tree window can be customised - * The order in which the nodes in the tree are listed can be customised. - * A model of your filesystem is created/maintained as you explore it. This - has several advantages: - * All filesystem information is cached and is only re-read on demand - * If you revisit a part of the tree that you left earlier in your - session, the directory nodes will be opened/closed as you left them - * The script remembers the cursor position and window position in the NERD - tree so you can toggle it off (or just close the tree window) and then - reopen it (with NERDTreeToggle) the NERD tree window will appear exactly - as you left it - * You can have a separate NERD tree for each tab, share trees across tabs, - or a mix of both. - * By default the script overrides the default file browser (netw), so if - you :edit a directory a (slighly modified) NERD tree will appear in the - current window - * A programmable menu system is provided (simulates right clicking on a - node) - * one default menu plugin is provided to perform basic filesytem - operations (create/delete/move/copy files/directories) - * There's an API for adding your own keymappings - - -============================================================================== -2. Functionality provided *NERDTreeFunctionality* - ------------------------------------------------------------------------------- -2.1. Global Commands *NERDTreeGlobalCommands* - -:NERDTree [ | ] *:NERDTree* - Opens a fresh NERD tree. The root of the tree depends on the argument - given. There are 3 cases: If no argument is given, the current directory - will be used. If a directory is given, that will be used. If a bookmark - name is given, the corresponding directory will be used. For example: > - :NERDTree /home/marty/vim7/src - :NERDTree foo (foo is the name of a bookmark) -< -:NERDTreeFromBookmark *:NERDTreeFromBookmark* - Opens a fresh NERD tree with the root initialized to the dir for - . This only reason to use this command over :NERDTree is for - the completion (which is for bookmarks rather than directories). - -:NERDTreeToggle [ | ] *:NERDTreeToggle* - If a NERD tree already exists for this tab, it is reopened and rendered - again. If no NERD tree exists for this tab then this command acts the - same as the |:NERDTree| command. - -:NERDTreeMirror *:NERDTreeMirror* - Shares an existing NERD tree, from another tab, in the current tab. - Changes made to one tree are reflected in both as they are actually the - same buffer. - - If only one other NERD tree exists, that tree is automatically mirrored. If - more than one exists, the script will ask which tree to mirror. - -:NERDTreeClose *:NERDTreeClose* - Close the NERD tree in this tab. - -:NERDTreeFind *:NERDTreeFind* - Find the current file in the tree. - - If not tree exists and the current file is under vim's CWD, then init a - tree at the CWD and reveal the file. Otherwise init a tree in the current - file's directory. - - In any case, the current file is revealed and the cursor is placed on it. - -:NERDTreeCWD *:NERDTreeCWD* - Change tree root to current directory. If no NERD tree exists for this - tab, a new tree will be opened. - ------------------------------------------------------------------------------- -2.2. Bookmarks *NERDTreeBookmarks* - -Bookmarks in the NERD tree are a way to tag files or directories of interest. -For example, you could use bookmarks to tag all of your project directories. - ------------------------------------------------------------------------------- -2.2.1. The Bookmark Table *NERDTreeBookmarkTable* - -If the bookmark table is active (see |NERDTree-B| and -|'NERDTreeShowBookmarks'|), it will be rendered above the tree. You can double -click bookmarks or use the |NERDTree-o| mapping to activate them. See also, -|NERDTree-t| and |NERDTree-T| - ------------------------------------------------------------------------------- -2.2.2. Bookmark commands *NERDTreeBookmarkCommands* - -Note that the following commands are only available in the NERD tree buffer. - -:Bookmark - Bookmark the current node as . If there is already a - bookmark, it is overwritten. must not contain spaces. - If is not provided, it defaults to the file or directory name. - For directories, a trailing slash is present. - -:BookmarkToRoot - Make the directory corresponding to the new root. If a treenode - corresponding to is already cached somewhere in the tree then - the current tree will be used, otherwise a fresh tree will be opened. - Note that if points to a file then its parent will be used - instead. - -:RevealBookmark - If the node is cached under the current root then it will be revealed - (i.e. directory nodes above it will be opened) and the cursor will be - placed on it. - -:OpenBookmark - must point to a file. The file is opened as though |NERDTree-o| - was applied. If the node is cached under the current root then it will be - revealed and the cursor will be placed on it. - -:ClearBookmarks [] - Remove all the given bookmarks. If no bookmarks are given then remove all - bookmarks on the current node. - -:ClearAllBookmarks - Remove all bookmarks. - -:ReadBookmarks - Re-read the bookmarks in the |'NERDTreeBookmarksFile'|. - -See also |:NERDTree| and |:NERDTreeFromBookmark|. - ------------------------------------------------------------------------------- -2.2.3. Invalid Bookmarks *NERDTreeInvalidBookmarks* - -If invalid bookmarks are detected, the script will issue an error message and -the invalid bookmarks will become unavailable for use. - -These bookmarks will still be stored in the bookmarks file (see -|'NERDTreeBookmarksFile'|), down the bottom. There will always be a blank line -after the valid bookmarks but before the invalid ones. - -Each line in the bookmarks file represents one bookmark. The proper format is: - - -After you have corrected any invalid bookmarks, either restart vim, or go -:ReadBookmarks from the NERD tree window. - ------------------------------------------------------------------------------- -2.3. NERD tree Mappings *NERDTreeMappings* - -Default Description~ help-tag~ -Key~ - -o.......Open files, directories and bookmarks....................|NERDTree-o| -go......Open selected file, but leave cursor in the NERDTree.....|NERDTree-go| -t.......Open selected node/bookmark in a new tab.................|NERDTree-t| -T.......Same as 't' but keep the focus on the current tab........|NERDTree-T| -i.......Open selected file in a split window.....................|NERDTree-i| -gi......Same as i, but leave the cursor on the NERDTree..........|NERDTree-gi| -s.......Open selected file in a new vsplit.......................|NERDTree-s| -gs......Same as s, but leave the cursor on the NERDTree..........|NERDTree-gs| -O.......Recursively open the selected directory..................|NERDTree-O| -x.......Close the current nodes parent...........................|NERDTree-x| -X.......Recursively close all children of the current node.......|NERDTree-X| -e.......Edit the current dif.....................................|NERDTree-e| - -...............same as |NERDTree-o|. -double-click.......same as the |NERDTree-o| map. -middle-click.......same as |NERDTree-i| for files, same as - |NERDTree-e| for dirs. - -D.......Delete the current bookmark .............................|NERDTree-D| - -P.......Jump to the root node....................................|NERDTree-P| -p.......Jump to current nodes parent.............................|NERDTree-p| -K.......Jump up inside directories at the current tree depth.....|NERDTree-K| -J.......Jump down inside directories at the current tree depth...|NERDTree-J| -...Jump down to the next sibling of the current directory...|NERDTree-C-J| -...Jump up to the previous sibling of the current directory.|NERDTree-C-K| - -C.......Change the tree root to the selected dir.................|NERDTree-C| -u.......Move the tree root up one directory......................|NERDTree-u| -U.......Same as 'u' except the old root node is left open........|NERDTree-U| -r.......Recursively refresh the current directory................|NERDTree-r| -R.......Recursively refresh the current root.....................|NERDTree-R| -m.......Display the NERD tree menu...............................|NERDTree-m| -cd......Change the CWD to the dir of the selected node...........|NERDTree-cd| -CD......Change tree root to the CWD..............................|NERDTree-CD| - -I.......Toggle whether hidden files displayed....................|NERDTree-I| -f.......Toggle whether the file filters are used.................|NERDTree-f| -F.......Toggle whether files are displayed.......................|NERDTree-F| -B.......Toggle whether the bookmark table is displayed...........|NERDTree-B| - -q.......Close the NERDTree window................................|NERDTree-q| -A.......Zoom (maximize/minimize) the NERDTree window.............|NERDTree-A| -?.......Toggle the display of the quick help.....................|NERDTree-?| - ------------------------------------------------------------------------------- - *NERDTree-o* -Default key: o -Map option: NERDTreeMapActivateNode -Applies to: files and directories. - -If a file node is selected, it is opened in the previous window. - -If a directory is selected it is opened or closed depending on its current -state. - -If a bookmark that links to a directory is selected then that directory -becomes the new root. - -If a bookmark that links to a file is selected then that file is opened in the -previous window. - ------------------------------------------------------------------------------- - *NERDTree-go* -Default key: go -Map option: None -Applies to: files. - -If a file node is selected, it is opened in the previous window, but the -cursor does not move. - -The key combo for this mapping is always "g" + NERDTreeMapActivateNode (see -|NERDTree-o|). - ------------------------------------------------------------------------------- - *NERDTree-t* -Default key: t -Map option: NERDTreeMapOpenInTab -Applies to: files and directories. - -Opens the selected file in a new tab. If a directory is selected, a fresh -NERD Tree for that directory is opened in a new tab. - -If a bookmark which points to a directory is selected, open a NERD tree for -that directory in a new tab. If the bookmark points to a file, open that file -in a new tab. - ------------------------------------------------------------------------------- - *NERDTree-T* -Default key: T -Map option: NERDTreeMapOpenInTabSilent -Applies to: files and directories. - -The same as |NERDTree-t| except that the focus is kept in the current tab. - ------------------------------------------------------------------------------- - *NERDTree-i* -Default key: i -Map option: NERDTreeMapOpenSplit -Applies to: files. - -Opens the selected file in a new split window and puts the cursor in the new -window. - ------------------------------------------------------------------------------- - *NERDTree-gi* -Default key: gi -Map option: None -Applies to: files. - -The same as |NERDTree-i| except that the cursor is not moved. - -The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see -|NERDTree-i|). - ------------------------------------------------------------------------------- - *NERDTree-s* -Default key: s -Map option: NERDTreeMapOpenVSplit -Applies to: files. - -Opens the selected file in a new vertically split window and puts the cursor in -the new window. - ------------------------------------------------------------------------------- - *NERDTree-gs* -Default key: gs -Map option: None -Applies to: files. - -The same as |NERDTree-s| except that the cursor is not moved. - -The key combo for this mapping is always "g" + NERDTreeMapOpenVSplit (see -|NERDTree-s|). - ------------------------------------------------------------------------------- - *NERDTree-O* -Default key: O -Map option: NERDTreeMapOpenRecursively -Applies to: directories. - -Recursively opens the selelected directory. - -All files and directories are cached, but if a directory would not be -displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the -hidden file filter (see |'NERDTreeShowHidden'|) then its contents are not -cached. This is handy, especially if you have .svn directories. - ------------------------------------------------------------------------------- - *NERDTree-x* -Default key: x -Map option: NERDTreeMapCloseDir -Applies to: files and directories. - -Closes the parent of the selected node. - ------------------------------------------------------------------------------- - *NERDTree-X* -Default key: X -Map option: NERDTreeMapCloseChildren -Applies to: directories. - -Recursively closes all children of the selected directory. - -Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping. - ------------------------------------------------------------------------------- - *NERDTree-e* -Default key: e -Map option: NERDTreeMapOpenExpl -Applies to: files and directories. - -|:edit|s the selected directory, or the selected file's directory. This could -result in a NERD tree or a netrw being opened, depending on -|'NERDTreeHijackNetrw'|. - ------------------------------------------------------------------------------- - *NERDTree-D* -Default key: D -Map option: NERDTreeMapDeleteBookmark -Applies to: lines in the bookmarks table - -Deletes the currently selected bookmark. - ------------------------------------------------------------------------------- - *NERDTree-P* -Default key: P -Map option: NERDTreeMapJumpRoot -Applies to: no restrictions. - -Jump to the tree root. - ------------------------------------------------------------------------------- - *NERDTree-p* -Default key: p -Map option: NERDTreeMapJumpParent -Applies to: files and directories. - -Jump to the parent node of the selected node. - ------------------------------------------------------------------------------- - *NERDTree-K* -Default key: K -Map option: NERDTreeMapJumpFirstChild -Applies to: files and directories. - -Jump to the first child of the current nodes parent. - -If the cursor is already on the first node then do the following: - * loop back thru the siblings of the current nodes parent until we find an - open dir with children - * go to the first child of that node - ------------------------------------------------------------------------------- - *NERDTree-J* -Default key: J -Map option: NERDTreeMapJumpLastChild -Applies to: files and directories. - -Jump to the last child of the current nodes parent. - -If the cursor is already on the last node then do the following: - * loop forward thru the siblings of the current nodes parent until we find - an open dir with children - * go to the last child of that node - ------------------------------------------------------------------------------- - *NERDTree-C-J* -Default key: -Map option: NERDTreeMapJumpNextSibling -Applies to: files and directories. - -Jump to the next sibling of the selected node. - ------------------------------------------------------------------------------- - *NERDTree-C-K* -Default key: -Map option: NERDTreeMapJumpPrevSibling -Applies to: files and directories. - -Jump to the previous sibling of the selected node. - ------------------------------------------------------------------------------- - *NERDTree-C* -Default key: C -Map option: NERDTreeMapChdir -Applies to: directories. - -Make the selected directory node the new tree root. If a file is selected, its -parent is used. - ------------------------------------------------------------------------------- - *NERDTree-u* -Default key: u -Map option: NERDTreeMapUpdir -Applies to: no restrictions. - -Move the tree root up a dir (like doing a "cd .."). - ------------------------------------------------------------------------------- - *NERDTree-U* -Default key: U -Map option: NERDTreeMapUpdirKeepOpen -Applies to: no restrictions. - -Like |NERDTree-u| except that the old tree root is kept open. - ------------------------------------------------------------------------------- - *NERDTree-r* -Default key: r -Map option: NERDTreeMapRefresh -Applies to: files and directories. - -If a dir is selected, recursively refresh that dir, i.e. scan the filesystem -for changes and represent them in the tree. - -If a file node is selected then the above is done on it's parent. - ------------------------------------------------------------------------------- - *NERDTree-R* -Default key: R -Map option: NERDTreeMapRefreshRoot -Applies to: no restrictions. - -Recursively refresh the tree root. - ------------------------------------------------------------------------------- - *NERDTree-m* -Default key: m -Map option: NERDTreeMapMenu -Applies to: files and directories. - -Display the NERD tree menu. See |NERDTreeMenu| for details. - ------------------------------------------------------------------------------- - *NERDTree-cd* -Default key: cd -Map option: NERDTreeMapChdir -Applies to: files and directories. - -Change vims current working directory to that of the selected node. - ------------------------------------------------------------------------------- - *NERDTree-CD* -Default key: CD -Map option: NERDTreeMapCWD -Applies to: no restrictions. - -Change tree root to vims current working directory. - ------------------------------------------------------------------------------- - *NERDTree-I* -Default key: I -Map option: NERDTreeMapToggleHidden -Applies to: no restrictions. - -Toggles whether hidden files (i.e. "dot files") are displayed. - ------------------------------------------------------------------------------- - *NERDTree-f* -Default key: f -Map option: NERDTreeMapToggleFilters -Applies to: no restrictions. - -Toggles whether file filters are used. See |'NERDTreeIgnore'| for details. - ------------------------------------------------------------------------------- - *NERDTree-F* -Default key: F -Map option: NERDTreeMapToggleFiles -Applies to: no restrictions. - -Toggles whether file nodes are displayed. - ------------------------------------------------------------------------------- - *NERDTree-B* -Default key: B -Map option: NERDTreeMapToggleBookmarks -Applies to: no restrictions. - -Toggles whether the bookmarks table is displayed. - ------------------------------------------------------------------------------- - *NERDTree-q* -Default key: q -Map option: NERDTreeMapQuit -Applies to: no restrictions. - -Closes the NERDtree window. - ------------------------------------------------------------------------------- - *NERDTree-A* -Default key: A -Map option: NERDTreeMapToggleZoom -Applies to: no restrictions. - -Maximize (zoom) and minimize the NERDtree window. - ------------------------------------------------------------------------------- - *NERDTree-?* -Default key: ? -Map option: NERDTreeMapHelp -Applies to: no restrictions. - -Toggles whether the quickhelp is displayed. - ------------------------------------------------------------------------------- -2.3. The NERD tree menu *NERDTreeMenu* - -The NERD tree has a menu that can be programmed via the an API (see -|NERDTreeMenuAPI|). The idea is to simulate the "right click" menus that most -file explorers have. - -The script comes with two default menu plugins: exec_menuitem.vim and -fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for -creating/deleting/moving/copying files and dirs. exec_menuitem.vim provides a -menu item to execute executable files. - -Related tags: |NERDTree-m| |NERDTreeApi| - -============================================================================== -3. Customisation *NERDTreeOptions* - - ------------------------------------------------------------------------------- -3.1. Customisation summary *NERDTreeOptionSummary* - -The script provides the following options that can customise the behaviour the -NERD tree. These options should be set in your vimrc. - -|'loaded_nerd_tree'| Turns off the script. - -|'NERDChristmasTree'| Tells the NERD tree to make itself colourful - and pretty. - -|'NERDTreeAutoCenter'| Controls whether the NERD tree window centers - when the cursor moves within a specified - distance to the top/bottom of the window. -|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering. - -|'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case - sensitive or not when sorting nodes. - -|'NERDTreeChDirMode'| Tells the NERD tree if/when it should change - vim's current working directory. - -|'NERDTreeHighlightCursorline'| Tell the NERD tree whether to highlight the - current cursor line. - -|'NERDTreeHijackNetrw'| Tell the NERD tree whether to replace the netrw - autocommands for exploring local directories. - -|'NERDTreeIgnore'| Tells the NERD tree which files to ignore. - -|'NERDTreeBookmarksFile'| Where the bookmarks are stored. - -|'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse - clicks. - -|'NERDTreeQuitOnOpen'| Closes the tree window after opening a file. - -|'NERDTreeShowBookmarks'| Tells the NERD tree whether to display the - bookmarks table on startup. - -|'NERDTreeShowFiles'| Tells the NERD tree whether to display files - in the tree on startup. - -|'NERDTreeShowHidden'| Tells the NERD tree whether to display hidden - files on startup. - -|'NERDTreeShowLineNumbers'| Tells the NERD tree whether to display line - numbers in the tree window. - -|'NERDTreeSortOrder'| Tell the NERD tree how to sort the nodes in - the tree. - -|'NERDTreeStatusline'| Set a statusline for NERD tree windows. - -|'NERDTreeWinPos'| Tells the script where to put the NERD tree - window. - -|'NERDTreeWinSize'| Sets the window size when the NERD tree is - opened. - -|'NERDTreeMinimalUI'| Disables display of the 'Bookmarks' label and - 'Press ? for help' text. - -|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of - + ~ chars when displaying directories. - -|'NERDTreeCasadeOpenSingleChildDir'| - Casade open while selected directory has only - one child that also is a directory. - -|'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove - a buffer when a file is being deleted or renamed - via a context menu command. - ------------------------------------------------------------------------------- -3.2. Customisation details *NERDTreeOptionDetails* - -To enable any of the below options you should put the given line in your -~/.vimrc - - *'loaded_nerd_tree'* -If this plugin is making you feel homicidal, it may be a good idea to turn it -off with this line in your vimrc: > - let loaded_nerd_tree=1 -< ------------------------------------------------------------------------------- - *'NERDChristmasTree'* -Values: 0 or 1. -Default: 1. - -If this option is set to 1 then some extra syntax highlighting elements are -added to the nerd tree to make it more colourful. - -Set it to 0 for a more vanilla looking tree. - ------------------------------------------------------------------------------- - *'NERDTreeAutoCenter'* -Values: 0 or 1. -Default: 1 - -If set to 1, the NERD tree window will center around the cursor if it moves to -within |'NERDTreeAutoCenterThreshold'| lines of the top/bottom of the window. - -This is ONLY done in response to tree navigation mappings, -i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-C-K| |NERDTree-p| -|NERDTree-P| - -The centering is done with a |zz| operation. - ------------------------------------------------------------------------------- - *'NERDTreeAutoCenterThreshold'* -Values: Any natural number. -Default: 3 - -This option controls the "sensitivity" of the NERD tree auto centering. See -|'NERDTreeAutoCenter'| for details. - ------------------------------------------------------------------------------- - *'NERDTreeCaseSensitiveSort'* -Values: 0 or 1. -Default: 0. - -By default the NERD tree does not sort nodes case sensitively, i.e. nodes -could appear like this: > - bar.c - Baz.c - blarg.c - boner.c - Foo.c -< -But, if you set this option to 1 then the case of the nodes will be taken into -account. The above nodes would then be sorted like this: > - Baz.c - Foo.c - bar.c - blarg.c - boner.c -< ------------------------------------------------------------------------------- - *'NERDTreeChDirMode'* - -Values: 0, 1 or 2. -Default: 0. - -Use this option to tell the script when (if at all) to change the current -working directory (CWD) for vim. - -If it is set to 0 then the CWD is never changed by the NERD tree. - -If set to 1 then the CWD is changed when the NERD tree is first loaded to the -directory it is initialized in. For example, if you start the NERD tree with > - :NERDTree /home/marty/foobar -< -then the CWD will be changed to /home/marty/foobar and will not be changed -again unless you init another NERD tree with a similar command. - -If the option is set to 2 then it behaves the same as if set to 1 except that -the CWD is changed whenever the tree root is changed. For example, if the CWD -is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new -root then the CWD will become /home/marty/foobar/baz. - ------------------------------------------------------------------------------- - *'NERDTreeHighlightCursorline'* -Values: 0 or 1. -Default: 1. - -If set to 1, the current cursor line in the NERD tree buffer will be -highlighted. This is done using the |'cursorline'| option. - ------------------------------------------------------------------------------- - *'NERDTreeHijackNetrw'* -Values: 0 or 1. -Default: 1. - -If set to 1, doing a > - :edit -< -will open up a "secondary" NERD tree instead of a netrw in the target window. - -Secondary NERD trees behaves slighly different from a regular trees in the -following respects: - 1. 'o' will open the selected file in the same window as the tree, - replacing it. - 2. you can have as many secondary tree as you want in the same tab. - ------------------------------------------------------------------------------- - *'NERDTreeIgnore'* -Values: a list of regular expressions. -Default: ['\~$']. - -This option is used to specify which files the NERD tree should ignore. It -must be a list of regular expressions. When the NERD tree is rendered, any -files/dirs that match any of the regex's in 'NERDTreeIgnore' wont be -displayed. - -For example if you put the following line in your vimrc: > - let NERDTreeIgnore=['\.vim$', '\~$'] -< -then all files ending in .vim or ~ will be ignored. - -There are 2 magic flags that can be appended to the end of each regular -expression to specify that the regex should match only files or only dirs. -These flags are "[[dir]]" and "[[file]]". Example: > - let NERDTreeIgnore=['.d$[[dir]]', '.o$[[file]]'] -< -This will cause all dirs ending in ".d" to be ignored and all files ending in -".o" to be ignored. - -Note: to tell the NERD tree not to ignore any files you must use the following -line: > - let NERDTreeIgnore=[] -< - -The file filters can be turned on and off dynamically with the |NERDTree-f| -mapping. - ------------------------------------------------------------------------------- - *'NERDTreeBookmarksFile'* -Values: a path -Default: $HOME/.NERDTreeBookmarks - -This is where bookmarks are saved. See |NERDTreeBookmarkCommands|. - ------------------------------------------------------------------------------- - *'NERDTreeMouseMode'* -Values: 1, 2 or 3. -Default: 1. - -If set to 1 then a double click on a node is required to open it. -If set to 2 then a single click will open directory nodes, while a double -click will still be required for file nodes. -If set to 3 then a single click will open any node. - -Note: a double click anywhere on a line that a tree node is on will -activate it, but all single-click activations must be done on name of the node -itself. For example, if you have the following node: > - | | |-application.rb -< -then (to single click activate it) you must click somewhere in -'application.rb'. - ------------------------------------------------------------------------------- - *'NERDTreeQuitOnOpen'* - -Values: 0 or 1. -Default: 0 - -If set to 1, the NERD tree window will close after opening a file with the -|NERDTree-o|, |NERDTree-i|, |NERDTree-t| and |NERDTree-T| mappings. - ------------------------------------------------------------------------------- - *'NERDTreeShowBookmarks'* -Values: 0 or 1. -Default: 0. - -If this option is set to 1 then the bookmarks table will be displayed. - -This option can be toggled dynamically, per tree, with the |NERDTree-B| -mapping. - ------------------------------------------------------------------------------- - *'NERDTreeShowFiles'* -Values: 0 or 1. -Default: 1. - -If this option is set to 1 then files are displayed in the NERD tree. If it is -set to 0 then only directories are displayed. - -This option can be toggled dynamically, per tree, with the |NERDTree-F| -mapping and is useful for drastically shrinking the tree when you are -navigating to a different part of the tree. - ------------------------------------------------------------------------------- - *'NERDTreeShowHidden'* -Values: 0 or 1. -Default: 0. - -This option tells vim whether to display hidden files by default. This option -can be dynamically toggled, per tree, with the |NERDTree-I| mapping. Use one -of the follow lines to set this option: > - let NERDTreeShowHidden=0 - let NERDTreeShowHidden=1 -< - ------------------------------------------------------------------------------- - *'NERDTreeShowLineNumbers'* -Values: 0 or 1. -Default: 0. - -This option tells vim whether to display line numbers for the NERD tree -window. Use one of the follow lines to set this option: > - let NERDTreeShowLineNumbers=0 - let NERDTreeShowLineNumbers=1 -< - ------------------------------------------------------------------------------- - *'NERDTreeSortOrder'* -Values: a list of regular expressions. -Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$'] - -This option is set to a list of regular expressions which are used to -specify the order of nodes under their parent. - -For example, if the option is set to: > - ['\.vim$', '\.c$', '\.h$', '*', 'foobar'] -< -then all .vim files will be placed at the top, followed by all .c files then -all .h files. All files containing the string 'foobar' will be placed at the -end. The star is a special flag: it tells the script that every node that -doesnt match any of the other regexps should be placed here. - -If no star is present in 'NERDTreeSortOrder' then one is automatically -appended to the array. - -The regex '\/$' should be used to match directory nodes. - -After this sorting is done, the files in each group are sorted alphabetically. - -Other examples: > - (1) ['*', '\/$'] - (2) [] - (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$'] -< -1. Directories will appear last, everything else will appear above. -2. Everything will simply appear in alphabetical order. -3. Dirs will appear first, then ruby and php. Swap files, bak files and vim - backup files will appear last with everything else preceding them. - ------------------------------------------------------------------------------- - *'NERDTreeStatusline'* -Values: Any valid statusline setting. -Default: %{b:NERDTreeRoot.path.strForOS(0)} - -Tells the script what to use as the |'statusline'| setting for NERD tree -windows. - -Note that the statusline is set using |:let-&| not |:set| so escaping spaces -isn't necessary. - -Setting this option to -1 will will deactivate it so that your global -statusline setting is used instead. - ------------------------------------------------------------------------------- - *'NERDTreeWinPos'* -Values: "left" or "right" -Default: "left". - -This option is used to determine where NERD tree window is placed on the -screen. - -This option makes it possible to use two different explorer plugins -simultaneously. For example, you could have the taglist plugin on the left of -the window and the NERD tree on the right. - ------------------------------------------------------------------------------- - *'NERDTreeWinSize'* -Values: a positive integer. -Default: 31. - -This option is used to change the size of the NERD tree when it is loaded. - ------------------------------------------------------------------------------- - *'NERDTreeMinimalUI'* -Values: 0 or 1 -Default: 0 - -This options disables the 'Bookmarks' label 'Press ? for help' text. Use one -of the following lines to set this option: > - let NERDTreeMinimalUI=0 - let NERDTreeMinimalUI=1 -< - ------------------------------------------------------------------------------- - *'NERDTreeDirArrows'* -Values: 0 or 1 -Default: 0. - -This option is used to change the default look of directory nodes displayed in -the tree. When set to 0 it shows old-school bars (|), + and ~ chars. If set to -1 it shows right and down arrows. Use one of the follow lines to set this -option: > - let NERDTreeDirArrows=0 - let NERDTreeDirArrows=1 -< - ------------------------------------------------------------------------------- - *'NERDTreeCasadeOpenSingleChildDir'* -Values: 0 or 1 -Default: 1. - -When opening dir nodes, this option tells NERDTree to recursively open dirs -that have only one child which is also a dir. NERDTree will stop when it finds -a dir that contains anything but another single dir. This option may be useful -for Java projects. Use one of the follow lines to set this option: > - let NERDTreeCasadeOpenSingleChildDir=0 - let NERDTreeCasadeOpenSingleChildDir=1 -< - ------------------------------------------------------------------------------- - *'NERDTreeAutoDeleteBuffer'* -Values: 0 or 1 -Default: 0. - -When using a context menu to delete or rename a file you may also want to delete -the buffer which is no more valid. If the option is not set you will see a -confirmation if you really want to delete an old buffer. If you always press 'y' -then it worths to set this option to 1. Use one of the follow lines to set this -option: > - let NERDTreeAutoDeleteBuffer=0 - let NERDTreeAutoDeleteBuffer=1 -< - -============================================================================== -4. The NERD tree API *NERDTreeAPI* - -The NERD tree script allows you to add custom key mappings and menu items via -a set of API calls. Any scripts that use this API should be placed in -~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows). - -The script exposes some prototype objects that can be used to manipulate the -tree and/or get information from it: > - g:NERDTreePath - g:NERDTreeDirNode - g:NERDTreeFileNode - g:NERDTreeBookmark -< -See the code/comments in NERD_tree.vim to find how to use these objects. The -following code conventions are used: - * class members start with a capital letter - * instance members start with a lower case letter - * private members start with an underscore - -See this blog post for more details: - http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html - ------------------------------------------------------------------------------- -4.1. Key map API *NERDTreeKeymapAPI* - -NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()* - Adds a new keymapping for all NERD tree buffers. - {options} must be a dictionary, and must contain the following keys: - "key" - the trigger key for the new mapping - "callback" - the function the new mapping will be bound to - "quickhelpText" - the text that will appear in the quickhelp (see - |NERDTree-?|) - - Additionally, a "scope" argument may be supplied. This constrains the - mapping so that it is only activated if the cursor is on a certain object. - That object is then passed into the handling method. Possible values are: - "FileNode" - a file node - "DirNode" - a directory node - "Node" - a file or directory node - "Bookmark" - A bookmark - "all" - the keymap is not constrained to any scope (default). When - thei is used, the handling function is not passed any arguments. - - - Example: > - call NERDTreeAddKeyMap({ - \ 'key': 'foo', - \ 'callback': 'NERDTreeCDHandler', - \ 'quickhelpText': 'echo full path of current node' }) - \ 'scope': 'DirNode' - - function! NERDTreeCDHandler(dirnode) - call a:dirnode.changeToDir() - endfunction -< - This code should sit in a file like ~/.vim/nerdtree_plugin/mymapping.vim. - It adds a (redundant) mapping on 'foo' which changes vim's CWD to that of - the current dir node. Note this mapping will only fire when the cursor is - on a directory node. - ------------------------------------------------------------------------------- -4.2. Menu API *NERDTreeMenuAPI* - -NERDTreeAddSubmenu({options}) *NERDTreeAddSubmenu()* - Creates and returns a new submenu. - - {options} must be a dictionary and must contain the following keys: - "text" - the text of the submenu that the user will see - "shortcut" - a shortcut key for the submenu (need not be unique) - - The following keys are optional: - "isActiveCallback" - a function that will be called to determine whether - this submenu item will be displayed or not. The callback function must return - 0 or 1. - "parent" - the parent submenu of the new submenu (returned from a previous - invocation of NERDTreeAddSubmenu()). If this key is left out then the new - submenu will sit under the top level menu. - - See below for an example. - -NERDTreeAddMenuItem({options}) *NERDTreeAddMenuItem()* - Adds a new menu item to the NERD tree menu (see |NERDTreeMenu|). - - {options} must be a dictionary and must contain the - following keys: - "text" - the text of the menu item which the user will see - "shortcut" - a shortcut key for the menu item (need not be unique) - "callback" - the function that will be called when the user activates the - menu item. - - The following keys are optional: - "isActiveCallback" - a function that will be called to determine whether - this menu item will be displayed or not. The callback function must return - 0 or 1. - "parent" - if the menu item belongs under a submenu then this key must be - specified. This value for this key will be the object that - was returned when the submenu was created with |NERDTreeAddSubmenu()|. - - See below for an example. - -NERDTreeAddMenuSeparator([{options}]) *NERDTreeAddMenuSeparator()* - Adds a menu separator (a row of dashes). - - {options} is an optional dictionary that may contain the following keys: - "isActiveCallback" - see description in |NERDTreeAddMenuItem()|. - -Below is an example of the menu API in action. > - call NERDTreeAddMenuSeparator() - - call NERDTreeAddMenuItem({ - \ 'text': 'a (t)op level menu item', - \ 'shortcut': 't', - \ 'callback': 'SomeFunction' }) - - let submenu = NERDTreeAddSubmenu({ - \ 'text': 'a (s)ub menu', - \ 'shortcut': 's' }) - - call NERDTreeAddMenuItem({ - \ 'text': '(n)ested item 1', - \ 'shortcut': 'n', - \ 'callback': 'SomeFunction', - \ 'parent': submenu }) - - call NERDTreeAddMenuItem({ - \ 'text': '(n)ested item 2', - \ 'shortcut': 'n', - \ 'callback': 'SomeFunction', - \ 'parent': submenu }) -< -This will create the following menu: > - -------------------- - a (t)op level menu item - a (s)ub menu -< -Where selecting "a (s)ub menu" will lead to a second menu: > - (n)ested item 1 - (n)ested item 2 -< -When any of the 3 concrete menu items are selected the function "SomeFunction" -will be called. - ------------------------------------------------------------------------------- -NERDTreeRender() *NERDTreeRender()* - Re-renders the NERD tree buffer. Useful if you change the state of the - tree and you want to it to be reflected in the UI. - -============================================================================== -5. About *NERDTreeAbout* - -The author of the NERD tree is a terrible terrible monster called Martyzilla -who gobbles up small children with milk and sugar for breakfast. - -He can be reached at martin.grenfell at gmail dot com. He would love to hear -from you, so feel free to send him suggestions and/or comments about this -plugin. Don't be shy --- the worst he can do is slaughter you and stuff you in -the fridge for later ;) - -The latest stable versions can be found at - http://www.vim.org/scripts/script.php?script_id=1658 - -The latest dev versions are on github - http://github.com/scrooloose/nerdtree - - -============================================================================== -6. Changelog *NERDTreeChangelog* - -Next - - add 'scope' argument to the key map API - - add NERDTreeCustomIgnoreFilter hook - needs doc - - add magic [[dir]] and [[file]] flags to NERDTreeIgnore - -4.2.0 - - Add NERDTreeDirArrows option to make the UI use pretty arrow chars - instead of the old +~| chars to define the tree structure (sickill) - - shift the syntax highlighting out into its own syntax file (gnap) - - add some mac specific options to the filesystem menu - for macvim - only (andersonfreitas) - - Add NERDTreeMinimalUI option to remove some non functional parts of the - nerdtree ui (camthompson) - - tweak the behaviour of :NERDTreeFind - see :help :NERDTreeFind for the - new behaviour (benjamingeiger) - - if no name is given to :Bookmark, make it default to the name of the - target file/dir (minyoung) - - use 'file' completion when doing copying, create, and move - operations (EvanDotPro) - - lots of misc bug fixes (paddyoloughlin, sdewald, camthompson, Vitaly - Bogdanov, AndrewRadev, mathias, scottstvnsn, kml, wycats, me RAWR!) - -4.1.0 - features: - - NERDTreeFind to reveal the node for the current buffer in the tree, - see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by - Doug McInnes) into the script. - - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan - Ritter and Rémi Prévost. - - truncate the root node if wider than the tree window. Thanks to Victor - Gonzalez. - - bugfixes: - - really fix window state restoring - - fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky, - jfilip1024, and Chris Chambers - -4.0.0 - - add a new programmable menu system (see :help NERDTreeMenu). - - add new APIs to add menus/menu-items to the menu system as well as - custom key mappings to the NERD tree buffer (see :help NERDTreeAPI). - - removed the old API functions - - added a mapping to maximize/restore the size of nerd tree window, thanks - to Guillaume Duranceau for the patch. See :help NERDTree-A for details. - - - fix a bug where secondary nerd trees (netrw hijacked trees) and - NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey. - - fix a bug where the script ignored directories whose name ended in a dot, - thanks to Aggelos Orfanakos for the patch. - - fix a bug when using the x mapping on the tree root, thanks to Bryan - Venteicher for the patch. - - fix a bug where the cursor position/window size of the nerd tree buffer - wasnt being stored on closing the window, thanks to Richard Hart. - - fix a bug where NERDTreeMirror would mirror the wrong tree - -3.1.1 - - fix a bug where a non-listed no-name buffer was getting created every - time the tree windows was created, thanks to Derek Wyatt and owen1 - - make behave the same as the 'o' mapping - - some helptag fixes in the doc, thanks strull - - fix a bug when using :set nohidden and opening a file where the previous - buf was modified. Thanks iElectric - - other minor fixes - -3.1.0 - New features: - - add mappings to open files in a vsplit, see :help NERDTree-s and :help - NERDTree-gs - - make the statusline for the nerd tree window default to something - hopefully more useful. See :help 'NERDTreeStatusline' - Bugfixes: - - make the hijack netrw functionality work when vim is started with "vim - " (thanks to Alf Mikula for the patch). - - fix a bug where the CWD wasnt being changed for some operations even when - NERDTreeChDirMode==2 (thanks to Lucas S. Buchala) - - add -bar to all the nerd tree :commands so they can chain with other - :commands (thanks to tpope) - - fix bugs when ignorecase was set (thanks to nach) - - fix a bug with the relative path code (thanks to nach) - - fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach) - - -3.0.1 - Bugfixes: - - fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden - was not set - - fix a bug where :NERDTree would fail if was relative and - didnt start with a ./ or ../ Thanks to James Kanze. - - make the q mapping work with secondary (:e style) trees, - thanks to jamessan - - fix a bunch of small bugs with secondary trees - - More insane refactoring. - -3.0.0 - - hijack netrw so that doing an :edit will put a NERD tree in - the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw' - - allow sharing of trees across tabs, see :help :NERDTreeMirror - - remove "top" and "bottom" as valid settings for NERDTreeWinPos - - change the '' mapping to 'i' - - change the 'H' mapping to 'I' - - lots of refactoring - -============================================================================== -7. Credits *NERDTreeCredits* - -Thanks to the following people for testing, bug reports, ideas etc. Without -you I probably would have got bored of the hacking the NERD tree and -just downloaded pr0n instead. - - Tim Carey-Smith (halorgium) - Vigil - Nick Brettell - Thomas Scott Urban - Terrance Cohen - Yegappan Lakshmanan - Jason Mills - Michael Geddes (frogonwheels) - Yu Jun - Michael Madsen - AOYAMA Shotaro - Zhang Weiwu - Niels Aan de Brugh - Olivier Yiptong - Zhang Shuhan - Cory Echols - Piotr Czachur - Yuan Jiang - Matan Nassau - Maxim Kim - Charlton Wang - Matt Wozniski (godlygeek) - knekk - Sean Chou - Ryan Penn - Simon Peter Nicholls - Michael Foobar - Tomasz Chomiuk - Denis Pokataev - Tim Pope (tpope) - James Kanze - James Vega (jamessan) - Frederic Chanal (nach) - Alf Mikula - Lucas S. Buchala - Curtis Harvey - Guillaume Duranceau - Richard Hart (hates) - Doug McInnes - Stefan Ritter - Rémi Prévost - Victor Gonzalez - Stephan Baumeister - Ricky - jfilip1024 - Chris Chambers - Vitaly Bogdanov - Patrick O'Loughlin (paddyoloughlin) - Cam Thompson (camthompson) - Marcin Kulik (sickill) - Steve DeWald (sdewald) - Ivan Necas (iNecas) - George Ang (gnap) - Evan Coury (EvanDotPro) - Andrew Radev (AndrewRadev) - Matt Gauger (mathias) - Scott Stevenson (scottstvnsn) - Anderson Freitas (andersonfreitas) - Kamil K. Lemański (kml) - Yehuda Katz (wycats) - Min-Young Wu (minyoung) - Benjamin Geiger (benjamingeiger) - -============================================================================== -8. License *NERDTreeLicense* - -The NERD tree is released under the wtfpl. -See http://sam.zoy.org/wtfpl/COPYING. diff --git a/common/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim b/common/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim deleted file mode 100644 index e7a7c53..0000000 --- a/common/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim +++ /dev/null @@ -1,41 +0,0 @@ -" ============================================================================ -" File: exec_menuitem.vim -" Description: plugin for NERD Tree that provides an execute file menu item -" Maintainer: Martin Grenfell -" Last Change: 22 July, 2009 -" License: This program is free software. It comes without any warranty, -" to the extent permitted by applicable law. You can redistribute -" it and/or modify it under the terms of the Do What The Fuck You -" Want To Public License, Version 2, as published by Sam Hocevar. -" See http://sam.zoy.org/wtfpl/COPYING for more details. -" -" ============================================================================ -if exists("g:loaded_nerdtree_exec_menuitem") - finish -endif -let g:loaded_nerdtree_exec_menuitem = 1 - -call NERDTreeAddMenuItem({ - \ 'text': '(!)Execute file', - \ 'shortcut': '!', - \ 'callback': 'NERDTreeExecFile', - \ 'isActiveCallback': 'NERDTreeExecFileActive' }) - -function! NERDTreeExecFileActive() - let node = g:NERDTreeFileNode.GetSelected() - return !node.path.isDirectory && node.path.isExecutable -endfunction - -function! NERDTreeExecFile() - let treenode = g:NERDTreeFileNode.GetSelected() - echo "==========================================================\n" - echo "Complete the command to execute (add arguments etc):\n" - let cmd = treenode.path.str({'escape': 1}) - let cmd = input(':!', cmd . ' ') - - if cmd != '' - exec ':!' . cmd - else - echo "Aborted" - endif -endfunction diff --git a/common/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim b/common/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim deleted file mode 100644 index 9b81ed3..0000000 --- a/common/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim +++ /dev/null @@ -1,262 +0,0 @@ -" ============================================================================ -" File: fs_menu.vim -" Description: plugin for the NERD Tree that provides a file system menu -" Maintainer: Martin Grenfell -" Last Change: 17 July, 2009 -" License: This program is free software. It comes without any warranty, -" to the extent permitted by applicable law. You can redistribute -" it and/or modify it under the terms of the Do What The Fuck You -" Want To Public License, Version 2, as published by Sam Hocevar. -" See http://sam.zoy.org/wtfpl/COPYING for more details. -" -" ============================================================================ -if exists("g:loaded_nerdtree_fs_menu") - finish -endif -let g:loaded_nerdtree_fs_menu = 1 - -"Automatically delete the buffer after deleting or renaming a file -if !exists("g:NERDTreeAutoDeleteBuffer") - let g:NERDTreeAutoDeleteBuffer = 0 -endif - -call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'}) -call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) -call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) - -if has("gui_mac") || has("gui_macvim") - call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'}) - call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'}) - call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'}) -endif - -if g:NERDTreePath.CopyingSupported() - call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) -endif - -"FUNCTION: s:echo(msg){{{1 -function! s:echo(msg) - redraw - echomsg "NERDTree: " . a:msg -endfunction - -"FUNCTION: s:echoWarning(msg){{{1 -function! s:echoWarning(msg) - echohl warningmsg - call s:echo(a:msg) - echohl normal -endfunction - -"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is deleted -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! s:promptToDelBuffer(bufnum, msg) - echo a:msg - if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' - " 1. ensure that all windows which display the just deleted filename - " now display an empty buffer (so a layout is preserved). - " Is not it better to close single tabs with this file only ? - let s:originalTabNumber = tabpagenr() - let s:originalWindowNumber = winnr() - exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif" - exec "tabnext " . s:originalTabNumber - exec s:originalWindowNumber . "wincmd w" - " 3. We don't need a previous buffer anymore - exec "bwipeout! " . a:bufnum - endif -endfunction - -"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is replaced with a new one -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! s:promptToRenameBuffer(bufnum, msg, newFileName) - echo a:msg - if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' - " 1. ensure that a new buffer is loaded - exec "badd " . a:newFileName - " 2. ensure that all windows which display the just deleted filename - " display a buffer for a new filename. - let s:originalTabNumber = tabpagenr() - let s:originalWindowNumber = winnr() - exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif" - exec "tabnext " . s:originalTabNumber - exec s:originalWindowNumber . "wincmd w" - " 3. We don't need a previous buffer anymore - exec "bwipeout! " . a:bufnum - endif -endfunction -"FUNCTION: NERDTreeAddNode(){{{1 -function! NERDTreeAddNode() - let curDirNode = g:NERDTreeDirNode.GetSelected() - - let newNodeName = input("Add a childnode\n". - \ "==========================================================\n". - \ "Enter the dir/file name to be created. Dirs end with a '/'\n" . - \ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file") - - if newNodeName ==# '' - call s:echo("Node Creation Aborted.") - return - endif - - try - let newPath = g:NERDTreePath.Create(newNodeName) - let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) - - let newTreeNode = g:NERDTreeFileNode.New(newPath) - if parentNode.isOpen || !empty(parentNode.children) - call parentNode.addChild(newTreeNode, 1) - call NERDTreeRender() - call newTreeNode.putCursorHere(1, 0) - endif - catch /^NERDTree/ - call s:echoWarning("Node Not Created.") - endtry -endfunction - -"FUNCTION: NERDTreeMoveNode(){{{1 -function! NERDTreeMoveNode() - let curNode = g:NERDTreeFileNode.GetSelected() - let newNodePath = input("Rename the current node\n" . - \ "==========================================================\n" . - \ "Enter the new path for the node: \n" . - \ "", curNode.path.str(), "file") - - if newNodePath ==# '' - call s:echo("Node Renaming Aborted.") - return - endif - - try - let bufnum = bufnr(curNode.path.str()) - - call curNode.rename(newNodePath) - call NERDTreeRender() - - "if the node is open in a buffer, ask the user if they want to - "close that buffer - if bufnum != -1 - let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with a new file? (yN)" - call s:promptToRenameBuffer(bufnum, prompt, newNodePath) - endif - - call curNode.putCursorHere(1, 0) - - redraw - catch /^NERDTree/ - call s:echoWarning("Node Not Renamed.") - endtry -endfunction - -" FUNCTION: NERDTreeDeleteNode() {{{1 -function! NERDTreeDeleteNode() - let currentNode = g:NERDTreeFileNode.GetSelected() - let confirmed = 0 - - if currentNode.path.isDirectory - let choice =input("Delete the current node\n" . - \ "==========================================================\n" . - \ "STOP! To delete this entire directory, type 'yes'\n" . - \ "" . currentNode.path.str() . ": ") - let confirmed = choice ==# 'yes' - else - echo "Delete the current node\n" . - \ "==========================================================\n". - \ "Are you sure you wish to delete the node:\n" . - \ "" . currentNode.path.str() . " (yN):" - let choice = nr2char(getchar()) - let confirmed = choice ==# 'y' - endif - - - if confirmed - try - call currentNode.delete() - call NERDTreeRender() - - "if the node is open in a buffer, ask the user if they want to - "close that buffer - let bufnum = bufnr(currentNode.path.str()) - if buflisted(bufnum) - let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" - call s:promptToDelBuffer(bufnum, prompt) - endif - - redraw - catch /^NERDTree/ - call s:echoWarning("Could not remove node") - endtry - else - call s:echo("delete aborted") - endif - -endfunction - -" FUNCTION: NERDTreeCopyNode() {{{1 -function! NERDTreeCopyNode() - let currentNode = g:NERDTreeFileNode.GetSelected() - let newNodePath = input("Copy the current node\n" . - \ "==========================================================\n" . - \ "Enter the new path to copy the node to: \n" . - \ "", currentNode.path.str(), "file") - - if newNodePath != "" - "strip trailing slash - let newNodePath = substitute(newNodePath, '\/$', '', '') - - let confirmed = 1 - if currentNode.path.copyingWillOverwrite(newNodePath) - call s:echo("Warning: copying may overwrite files! Continue? (yN)") - let choice = nr2char(getchar()) - let confirmed = choice ==# 'y' - endif - - if confirmed - try - let newNode = currentNode.copy(newNodePath) - if !empty(newNode) - call NERDTreeRender() - call newNode.putCursorHere(0, 0) - endif - catch /^NERDTree/ - call s:echoWarning("Could not copy node") - endtry - endif - else - call s:echo("Copy aborted.") - endif - redraw -endfunction - -function! NERDTreeQuickLook() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - call system("qlmanage -p 2>/dev/null '" . treenode.path.str() . "'") - endif -endfunction - -function! NERDTreeRevealInFinder() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - let x = system("open -R '" . treenode.path.str() . "'") - endif -endfunction - -function! NERDTreeExecuteFile() - let treenode = g:NERDTreeFileNode.GetSelected() - if treenode != {} - let x = system("open '" . treenode.path.str() . "'") - endif -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/NERD_tree.vim b/common/.vim/bundle/nerdtree/plugin/NERD_tree.vim deleted file mode 100644 index 8b853d4..0000000 --- a/common/.vim/bundle/nerdtree/plugin/NERD_tree.vim +++ /dev/null @@ -1,218 +0,0 @@ -" ============================================================================ -" File: NERD_tree.vim -" Description: vim global plugin that provides a nice tree explorer -" Maintainer: Martin Grenfell -" Last Change: 28 December, 2011 -" License: This program is free software. It comes without any warranty, -" to the extent permitted by applicable law. You can redistribute -" it and/or modify it under the terms of the Do What The Fuck You -" Want To Public License, Version 2, as published by Sam Hocevar. -" See http://sam.zoy.org/wtfpl/COPYING for more details. -" -" ============================================================================ -" -" SECTION: Script init stuff {{{1 -"============================================================ -if exists("loaded_nerd_tree") - finish -endif -if v:version < 700 - echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" - finish -endif -let loaded_nerd_tree = 1 - -"for line continuation - i.e dont want C in &cpo -let s:old_cpo = &cpo -set cpo&vim - -"Function: s:initVariable() function {{{2 -"This function is used to initialise a given variable to a given value. The -"variable is only initialised if it does not exist prior -" -"Args: -"var: the name of the var to be initialised -"value: the value to initialise var to -" -"Returns: -"1 if the var is set, 0 otherwise -function! s:initVariable(var, value) - if !exists(a:var) - exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'" - return 1 - endif - return 0 -endfunction - -"SECTION: Init variable calls and other random constants {{{2 -call s:initVariable("g:NERDChristmasTree", 1) -call s:initVariable("g:NERDTreeAutoCenter", 1) -call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) -call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) -call s:initVariable("g:NERDTreeChDirMode", 0) -call s:initVariable("g:NERDTreeMinimalUI", 0) -if !exists("g:NERDTreeIgnore") - let g:NERDTreeIgnore = ['\~$'] -endif -call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') -call s:initVariable("g:NERDTreeHighlightCursorline", 1) -call s:initVariable("g:NERDTreeHijackNetrw", 1) -call s:initVariable("g:NERDTreeMouseMode", 1) -call s:initVariable("g:NERDTreeNotificationThreshold", 100) -call s:initVariable("g:NERDTreeQuitOnOpen", 0) -call s:initVariable("g:NERDTreeShowBookmarks", 0) -call s:initVariable("g:NERDTreeShowFiles", 1) -call s:initVariable("g:NERDTreeShowHidden", 0) -call s:initVariable("g:NERDTreeShowLineNumbers", 0) -call s:initVariable("g:NERDTreeSortDirs", 1) -call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows()) -call s:initVariable("g:NERDTreeCasadeOpenSingleChildDir", 1) - -if !exists("g:NERDTreeSortOrder") - let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] -else - "if there isnt a * in the sort sequence then add one - if count(g:NERDTreeSortOrder, '*') < 1 - call add(g:NERDTreeSortOrder, '*') - endif -endif - -if !exists('g:NERDTreeStatusline') - - "the exists() crap here is a hack to stop vim spazzing out when - "loading a session that was created with an open nerd tree. It spazzes - "because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash) - let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}" - -endif -call s:initVariable("g:NERDTreeWinPos", "left") -call s:initVariable("g:NERDTreeWinSize", 31) - -"init the shell commands that will be used to copy nodes, and remove dir trees -" -"Note: the space after the command is important -if nerdtree#runningWindows() - call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ') -else - call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ') - call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ') -endif - - -"SECTION: Init variable calls for key mappings {{{2 -call s:initVariable("g:NERDTreeMapActivateNode", "o") -call s:initVariable("g:NERDTreeMapChangeRoot", "C") -call s:initVariable("g:NERDTreeMapChdir", "cd") -call s:initVariable("g:NERDTreeMapCloseChildren", "X") -call s:initVariable("g:NERDTreeMapCloseDir", "x") -call s:initVariable("g:NERDTreeMapDeleteBookmark", "D") -call s:initVariable("g:NERDTreeMapMenu", "m") -call s:initVariable("g:NERDTreeMapHelp", "?") -call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") -call s:initVariable("g:NERDTreeMapJumpLastChild", "J") -call s:initVariable("g:NERDTreeMapJumpNextSibling", "") -call s:initVariable("g:NERDTreeMapJumpParent", "p") -call s:initVariable("g:NERDTreeMapJumpPrevSibling", "") -call s:initVariable("g:NERDTreeMapJumpRoot", "P") -call s:initVariable("g:NERDTreeMapOpenExpl", "e") -call s:initVariable("g:NERDTreeMapOpenInTab", "t") -call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T") -call s:initVariable("g:NERDTreeMapOpenRecursively", "O") -call s:initVariable("g:NERDTreeMapOpenSplit", "i") -call s:initVariable("g:NERDTreeMapOpenVSplit", "s") -call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode) -call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit) -call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit) -call s:initVariable("g:NERDTreeMapQuit", "q") -call s:initVariable("g:NERDTreeMapRefresh", "r") -call s:initVariable("g:NERDTreeMapRefreshRoot", "R") -call s:initVariable("g:NERDTreeMapToggleBookmarks", "B") -call s:initVariable("g:NERDTreeMapToggleFiles", "F") -call s:initVariable("g:NERDTreeMapToggleFilters", "f") -call s:initVariable("g:NERDTreeMapToggleHidden", "I") -call s:initVariable("g:NERDTreeMapToggleZoom", "A") -call s:initVariable("g:NERDTreeMapUpdir", "u") -call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") -call s:initVariable("g:NERDTreeMapCWD", "CD") - -"SECTION: Load class files{{{2 -runtime plugin/nerdtree/path.vim -runtime plugin/nerdtree/menu_controller.vim -runtime plugin/nerdtree/menu_item.vim -runtime plugin/nerdtree/key_map.vim -runtime plugin/nerdtree/bookmark.vim -runtime plugin/nerdtree/tree_file_node.vim -runtime plugin/nerdtree/tree_dir_node.vim -runtime plugin/nerdtree/opener.vim -runtime plugin/nerdtree/creator.vim - -" SECTION: Commands {{{1 -"============================================================ -"init the command that users start the nerd tree with -command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('') -command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('') -command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen() -command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('') -command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() -command! -n=0 -bar NERDTreeFind call nerdtree#findAndRevealPath() -command! -n=0 -bar NERDTreeFocus call NERDTreeFocus() -command! -n=0 -bar NERDTreeCWD call NERDTreeCWD() -" SECTION: Auto commands {{{1 -"============================================================ -augroup NERDTree - "Save the cursor position whenever we close the nerd tree - exec "autocmd BufWinLeave ". nerdtree#bufNamePrefix() ."* call nerdtree#saveScreenState()" - - "disallow insert mode in the NERDTree - exec "autocmd BufEnter ". nerdtree#bufNamePrefix() ."* stopinsert" -augroup END - -if g:NERDTreeHijackNetrw - augroup NERDTreeHijackNetrw - autocmd VimEnter * silent! autocmd! FileExplorer - au BufEnter,VimEnter * call nerdtree#checkForBrowse(expand("")) - augroup END -endif - -" SECTION: Public API {{{1 -"============================================================ -function! NERDTreeAddMenuItem(options) - call g:NERDTreeMenuItem.Create(a:options) -endfunction - -function! NERDTreeAddMenuSeparator(...) - let opts = a:0 ? a:1 : {} - call g:NERDTreeMenuItem.CreateSeparator(opts) -endfunction - -function! NERDTreeAddSubmenu(options) - return g:NERDTreeMenuItem.Create(a:options) -endfunction - -function! NERDTreeAddKeyMap(options) - call g:NERDTreeKeyMap.Create(a:options) -endfunction - -function! NERDTreeRender() - call nerdtree#renderView() -endfunction - -function! NERDTreeFocus() - if nerdtree#isTreeOpen() - call nerdtree#putCursorInTreeWin() - else - call g:NERDTreeCreator.TogglePrimary("") - endif -endfunction - -function! NERDTreeCWD() - call NERDTreeFocus() - call nerdtree#chRootCwd() -endfunction -" SECTION: Post Source Actions {{{1 -call nerdtree#postSourceActions() - -"reset &cpo back to users setting -let &cpo = s:old_cpo - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/bookmark.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/bookmark.vim deleted file mode 100644 index 0d37b47..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/bookmark.vim +++ /dev/null @@ -1,315 +0,0 @@ -"CLASS: Bookmark -"============================================================ -let s:Bookmark = {} -let g:NERDTreeBookmark = s:Bookmark - -" FUNCTION: Bookmark.activate() {{{1 -function! s:Bookmark.activate(...) - call self.open(a:0 ? a:1 : {}) -endfunction - -" FUNCTION: Bookmark.AddBookmark(name, path) {{{1 -" Class method to add a new bookmark to the list, if a previous bookmark exists -" with the same name, just update the path for that bookmark -function! s:Bookmark.AddBookmark(name, path) - for i in s:Bookmark.Bookmarks() - if i.name ==# a:name - let i.path = a:path - return - endif - endfor - call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) - call s:Bookmark.Sort() -endfunction - -" FUNCTION: Bookmark.Bookmarks() {{{1 -" Class method to get all bookmarks. Lazily initializes the bookmarks global -" variable -function! s:Bookmark.Bookmarks() - if !exists("g:NERDTreeBookmarks") - let g:NERDTreeBookmarks = [] - endif - return g:NERDTreeBookmarks -endfunction - -" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1 -" class method that returns 1 if a bookmark with the given name is found, 0 -" otherwise -function! s:Bookmark.BookmarkExistsFor(name) - try - call s:Bookmark.BookmarkFor(a:name) - return 1 - catch /^NERDTree.BookmarkNotFoundError/ - return 0 - endtry -endfunction - -" FUNCTION: Bookmark.BookmarkFor(name) {{{1 -" Class method to get the bookmark that has the given name. {} is return if no -" bookmark is found -function! s:Bookmark.BookmarkFor(name) - for i in s:Bookmark.Bookmarks() - if i.name ==# a:name - return i - endif - endfor - throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name .'"' -endfunction - -" FUNCTION: Bookmark.BookmarkNames() {{{1 -" Class method to return an array of all bookmark names -function! s:Bookmark.BookmarkNames() - let names = [] - for i in s:Bookmark.Bookmarks() - call add(names, i.name) - endfor - return names -endfunction - -" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1 -" Class method to read all bookmarks from the bookmarks file intialize -" bookmark objects for each one. -" -" Args: -" silent - dont echo an error msg if invalid bookmarks are found -function! s:Bookmark.CacheBookmarks(silent) - if filereadable(g:NERDTreeBookmarksFile) - let g:NERDTreeBookmarks = [] - let g:NERDTreeInvalidBookmarks = [] - let bookmarkStrings = readfile(g:NERDTreeBookmarksFile) - let invalidBookmarksFound = 0 - for i in bookmarkStrings - - "ignore blank lines - if i != '' - - let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') - let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') - - try - let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path)) - call add(g:NERDTreeBookmarks, bookmark) - catch /^NERDTree.InvalidArgumentsError/ - call add(g:NERDTreeInvalidBookmarks, i) - let invalidBookmarksFound += 1 - endtry - endif - endfor - if invalidBookmarksFound - call s:Bookmark.Write() - if !a:silent - call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") - endif - endif - call s:Bookmark.Sort() - endif -endfunction - -" FUNCTION: Bookmark.compareTo(otherbookmark) {{{1 -" Compare these two bookmarks for sorting purposes -function! s:Bookmark.compareTo(otherbookmark) - return a:otherbookmark.name < self.name -endfunction -" FUNCTION: Bookmark.ClearAll() {{{1 -" Class method to delete all bookmarks. -function! s:Bookmark.ClearAll() - for i in s:Bookmark.Bookmarks() - call i.delete() - endfor - call s:Bookmark.Write() -endfunction - -" FUNCTION: Bookmark.delete() {{{1 -" Delete this bookmark. If the node for this bookmark is under the current -" root, then recache bookmarks for its Path object -function! s:Bookmark.delete() - let node = {} - try - let node = self.getNode(1) - catch /^NERDTree.BookmarkedNodeNotFoundError/ - endtry - call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self)) - if !empty(node) - call node.path.cacheDisplayString() - endif - call s:Bookmark.Write() -endfunction - -" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{1 -" Gets the treenode for this bookmark -" -" Args: -" searchFromAbsoluteRoot: specifies whether we should search from the current -" tree root, or the highest cached node -function! s:Bookmark.getNode(searchFromAbsoluteRoot) - let searchRoot = a:searchFromAbsoluteRoot ? g:NERDTreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot - let targetNode = searchRoot.findNode(self.path) - if empty(targetNode) - throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name - endif - return targetNode -endfunction - -" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{1 -" Class method that finds the bookmark with the given name and returns the -" treenode for it. -function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) - let bookmark = s:Bookmark.BookmarkFor(a:name) - return bookmark.getNode(a:searchFromAbsoluteRoot) -endfunction - -" FUNCTION: Bookmark.GetSelected() {{{1 -" returns the Bookmark the cursor is over, or {} -function! s:Bookmark.GetSelected() - let line = getline(".") - let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '') - if name != line - try - return s:Bookmark.BookmarkFor(name) - catch /^NERDTree.BookmarkNotFoundError/ - return {} - endtry - endif - return {} -endfunction - -" FUNCTION: Bookmark.InvalidBookmarks() {{{1 -" Class method to get all invalid bookmark strings read from the bookmarks -" file -function! s:Bookmark.InvalidBookmarks() - if !exists("g:NERDTreeInvalidBookmarks") - let g:NERDTreeInvalidBookmarks = [] - endif - return g:NERDTreeInvalidBookmarks -endfunction - -" FUNCTION: Bookmark.mustExist() {{{1 -function! s:Bookmark.mustExist() - if !self.path.exists() - call s:Bookmark.CacheBookmarks(1) - throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"". - \ self.name ."\" points to a non existing location: \"". self.path.str() - endif -endfunction - -" FUNCTION: Bookmark.New(name, path) {{{1 -" Create a new bookmark object with the given name and path object -function! s:Bookmark.New(name, path) - if a:name =~# ' ' - throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name - endif - - let newBookmark = copy(self) - let newBookmark.name = a:name - let newBookmark.path = a:path - return newBookmark -endfunction - -" FUNCTION: Bookmark.open([options]) {{{1 -"Args: -"A dictionary containing the following keys (all optional): -" 'where': Specifies whether the node should be opened in new split/tab or in -" the previous window. Can be either 'v' (vertical split), 'h' -" (horizontal split), 't' (new tab) or 'p' (previous window). -" 'reuse': if a window is displaying the file then jump the cursor there -" 'keepopen': dont close the tree window -" 'stay': open the file, but keep the cursor in the tree win -" -function! s:Bookmark.open(...) - let opts = a:0 ? a:1 : {} - - if self.path.isDirectory && !has_key(opts, 'where') - call self.toRoot() - else - let opener = g:NERDTreeOpener.New(self.path, opts) - call opener.open(self) - endif -endfunction - -" FUNCTION: Bookmark.openInNewTab(options) {{{1 -" Create a new bookmark object with the given name and path object -function! s:Bookmark.openInNewTab(options) - call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead') - call self.open(a:options) -endfunction - -" FUNCTION: Bookmark.setPath(path) {{{1 -" makes this bookmark point to the given path -function! s:Bookmark.setPath(path) - let self.path = a:path -endfunction - -" FUNCTION: Bookmark.Sort() {{{1 -" Class method that sorts all bookmarks -function! s:Bookmark.Sort() - let CompareFunc = function("nerdtree#compareBookmarks") - call sort(s:Bookmark.Bookmarks(), CompareFunc) -endfunction - -" FUNCTION: Bookmark.str() {{{1 -" Get the string that should be rendered in the view for this bookmark -function! s:Bookmark.str() - let pathStrMaxLen = winwidth(nerdtree#getTreeWinNum()) - 4 - len(self.name) - if &nu - let pathStrMaxLen = pathStrMaxLen - &numberwidth - endif - - let pathStr = self.path.str({'format': 'UI'}) - if len(pathStr) > pathStrMaxLen - let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) - endif - return '>' . self.name . ' ' . pathStr -endfunction - -" FUNCTION: Bookmark.toRoot() {{{1 -" Make the node for this bookmark the new tree root -function! s:Bookmark.toRoot() - if self.validate() - try - let targetNode = self.getNode(1) - catch /^NERDTree.BookmarkedNodeNotFoundError/ - let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) - endtry - call targetNode.makeRoot() - call nerdtree#renderView() - call targetNode.putCursorHere(0, 0) - endif -endfunction - -" FUNCTION: Bookmark.ToRoot(name) {{{1 -" Make the node for this bookmark the new tree root -function! s:Bookmark.ToRoot(name) - let bookmark = s:Bookmark.BookmarkFor(a:name) - call bookmark.toRoot() -endfunction - -" FUNCTION: Bookmark.validate() {{{1 -function! s:Bookmark.validate() - if self.path.exists() - return 1 - else - call s:Bookmark.CacheBookmarks(1) - call nerdtree#renderView() - call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") - return 0 - endif -endfunction - -" FUNCTION: Bookmark.Write() {{{1 -" Class method to write all bookmarks to the bookmarks file -function! s:Bookmark.Write() - let bookmarkStrings = [] - for i in s:Bookmark.Bookmarks() - call add(bookmarkStrings, i.name . ' ' . i.path.str()) - endfor - - "add a blank line before the invalid ones - call add(bookmarkStrings, "") - - for j in s:Bookmark.InvalidBookmarks() - call add(bookmarkStrings, j) - endfor - call writefile(bookmarkStrings, g:NERDTreeBookmarksFile) -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/creator.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/creator.vim deleted file mode 100644 index 5adc960..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/creator.vim +++ /dev/null @@ -1,298 +0,0 @@ -"CLASS: Creator -"Creates primary/secondary/mirror nerdtree windows. Sets up all the window and -"buffer options and key mappings etc. -"============================================================ -let s:Creator = {} -let g:NERDTreeCreator = s:Creator - -"FUNCTION: s:Creator._bindMappings() {{{1 -function! s:Creator._bindMappings() - call g:NERDTreeKeyMap.BindAll() - - "make do the same as the default 'o' mapping - exec "nnoremap :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')" - - command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('') - command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('') - command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() call nerdtree#renderView() - command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) call nerdtree#renderView() - command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() -endfunction - -"FUNCTION: s:Creator._broadcastInitEvent() {{{1 -function! s:Creator._broadcastInitEvent() - silent doautocmd User NERDTreeInit -endfunction - -"FUNCTION: s:Creator.CreatePrimary(a:name) {{{1 -function! s:Creator.CreatePrimary(name) - let creator = s:Creator.New() - call creator.createPrimary(a:name) -endfunction - -"FUNCTION: s:Creator.createPrimary(a:name) {{{1 -"name: the name of a bookmark or a directory -function! s:Creator.createPrimary(name) - let path = self._pathForString(a:name) - - "if instructed to, then change the vim CWD to the dir the NERDTree is - "inited in - if g:NERDTreeChDirMode != 0 - call path.changeToDir() - endif - - if nerdtree#treeExistsForTab() - if nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif - unlet t:NERDTreeBufName - endif - - let newRoot = g:NERDTreeDirNode.New(path) - call newRoot.open() - - call self._createTreeWin() - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - let b:NERDTreeRoot = newRoot - let b:NERDTreeType = "primary" - - call nerdtree#renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) - - call self._broadcastInitEvent() -endfunction - -"FUNCTION: s:Creator.CreateSecondary(dir) {{{1 -function! s:Creator.CreateSecondary(dir) - let creator = s:Creator.New() - call creator.createSecondary(a:dir) -endfunction - -"FUNCTION: s:Creator.createSecondary(dir) {{{1 -function! s:Creator.createSecondary(dir) - try - let path = g:NERDTreePath.New(a:dir) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("Invalid directory name:" . a:name) - return - endtry - - "we want the directory buffer to disappear when we do the :edit below - setlocal bufhidden=wipe - - let previousBuf = expand("#") - - "we need a unique name for each secondary tree buffer to ensure they are - "all independent - exec "silent edit " . nerdtree#nextBufferName() - - let b:NERDTreePreviousBuf = bufnr(previousBuf) - - let b:NERDTreeRoot = g:NERDTreeDirNode.New(path) - call b:NERDTreeRoot.open() - - call self._setCommonBufOptions() - let b:NERDTreeType = "secondary" - - call nerdtree#renderView() - - call self._broadcastInitEvent() -endfunction - -" FUNCTION: s:Creator.CreateMirror() {{{1 -function! s:Creator.CreateMirror() - let creator = s:Creator.New() - call creator.createMirror() -endfunction - -" FUNCTION: s:Creator.createMirror() {{{1 -function! s:Creator.createMirror() - "get the names off all the nerd tree buffers - let treeBufNames = [] - for i in range(1, tabpagenr("$")) - let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName') - if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) - call add(treeBufNames, nextName) - endif - endfor - let treeBufNames = nerdtree#unique(treeBufNames) - - "map the option names (that the user will be prompted with) to the nerd - "tree buffer names - let options = {} - let i = 0 - while i < len(treeBufNames) - let bufName = treeBufNames[i] - let treeRoot = getbufvar(bufName, "NERDTreeRoot") - let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName - let i = i + 1 - endwhile - - "work out which tree to mirror, if there is more than 1 then ask the user - let bufferName = '' - if len(keys(options)) > 1 - let choices = ["Choose a tree to mirror"] - let choices = extend(choices, sort(keys(options))) - let choice = inputlist(choices) - if choice < 1 || choice > len(options) || choice ==# '' - return - endif - - let bufferName = options[sort(keys(options))[choice-1]] - elseif len(keys(options)) ==# 1 - let bufferName = values(options)[0] - else - call nerdtree#echo("No trees to mirror") - return - endif - - if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen() - call nerdtree#closeTree() - endif - - let t:NERDTreeBufName = bufferName - call self._createTreeWin() - exec 'buffer ' . bufferName - if !&hidden - call nerdtree#renderView() - endif -endfunction - -"FUNCTION: s:Creator._createTreeWin() {{{1 -"Inits the NERD tree window. ie. opens it, sizes it, sets all the local -"options etc -function! s:Creator._createTreeWin() - "create the nerd tree window - let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright " - let splitSize = g:NERDTreeWinSize - - if !exists('t:NERDTreeBufName') - let t:NERDTreeBufName = nerdtree#nextBufferName() - silent! exec splitLocation . 'vertical ' . splitSize . ' new' - silent! exec "edit " . t:NERDTreeBufName - else - silent! exec splitLocation . 'vertical ' . splitSize . ' split' - silent! exec "buffer " . t:NERDTreeBufName - endif - - setlocal winfixwidth - call self._setCommonBufOptions() -endfunction - -"FUNCTION: s:Creator.New() {{{1 -function! s:Creator.New() - let newCreator = copy(self) - return newCreator -endfunction - -"FUNCTION: s:Creator._pathForString(str) {{{1 -"find a bookmark or adirectory for the given string -function! s:Creator._pathForString(str) - let path = {} - if g:NERDTreeBookmark.BookmarkExistsFor(a:str) - let path = g:NERDTreeBookmark.BookmarkFor(a:str).path - else - let dir = a:str ==# '' ? getcwd() : a:str - - "hack to get an absolute path if a relative path is given - if dir =~# '^\.' - let dir = getcwd() . g:NERDTreePath.Slash() . dir - endif - let dir = g:NERDTreePath.Resolve(dir) - - try - let path = g:NERDTreePath.New(dir) - catch /^NERDTree.InvalidArgumentsError/ - call nerdtree#echo("No bookmark or directory found for: " . a:str) - return - endtry - endif - if !path.isDirectory - let path = path.getParent() - endif - - return path -endfunction - -"FUNCTION: s:Creator._setCommonBufOptions() {{{1 -function! s:Creator._setCommonBufOptions() - "throwaway buffer options - setlocal noswapfile - setlocal buftype=nofile - setlocal bufhidden=hide - setlocal nowrap - setlocal foldcolumn=0 - setlocal foldmethod=manual - setlocal nofoldenable - setlocal nobuflisted - setlocal nospell - if g:NERDTreeShowLineNumbers - setlocal nu - else - setlocal nonu - if v:version >= 703 - setlocal nornu - endif - endif - - iabc - - if g:NERDTreeHighlightCursorline - setlocal cursorline - endif - - call self._setupStatusline() - - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - setfiletype nerdtree - call self._bindMappings() -endfunction - -"FUNCTION: s:Creator._setupStatusline() {{{1 -function! s:Creator._setupStatusline() - if g:NERDTreeStatusline != -1 - let &l:statusline = g:NERDTreeStatusline - endif -endfunction - -"FUNCTION: s:Creator.TogglePrimary(dir) {{{1 -function! s:Creator.TogglePrimary(dir) - let creator = s:Creator.New() - call creator.togglePrimary(a:dir) -endfunction - -"FUNCTION: s:Creator.togglePrimary(dir) {{{1 -"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is -"closed it is restored or initialized (if it doesnt exist) -" -"Args: -"dir: the full path for the root node (is only used if the NERD tree is being -"initialized. -function! s:Creator.togglePrimary(dir) - if nerdtree#treeExistsForTab() - if !nerdtree#isTreeOpen() - call self._createTreeWin() - if !&hidden - call nerdtree#renderView() - endif - call nerdtree#restoreScreenState() - else - call nerdtree#closeTree() - endif - else - call self.createPrimary(a:dir) - endif -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/key_map.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/key_map.vim deleted file mode 100644 index 8645765..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/key_map.vim +++ /dev/null @@ -1,143 +0,0 @@ -"CLASS: KeyMap -"============================================================ -let s:KeyMap = {} -let g:NERDTreeKeyMap = s:KeyMap - -"FUNCTION: KeyMap.All() {{{1 -function! s:KeyMap.All() - if !exists("s:keyMaps") - let s:keyMaps = [] - endif - return s:keyMaps -endfunction - -"FUNCTION: KeyMap.FindFor(key, scope) {{{1 -function! s:KeyMap.FindFor(key, scope) - for i in s:KeyMap.All() - if i.key ==# a:key && i.scope ==# a:scope - return i - endif - endfor - return {} -endfunction - -"FUNCTION: KeyMap.BindAll() {{{1 -function! s:KeyMap.BindAll() - for i in s:KeyMap.All() - call i.bind() - endfor -endfunction - -"FUNCTION: KeyMap.bind() {{{1 -function! s:KeyMap.bind() - " If the key sequence we're trying to map contains any '<>' notation, we - " must replace each of the '<' characters with '' to ensure the string - " is not translated into its corresponding keycode during the later part - " of the map command below - " :he <> - let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)' - if self.key =~# specialNotationRegex - let keymapInvokeString = substitute(self.key, specialNotationRegex, '\1', 'g') - else - let keymapInvokeString = self.key - endif - - let premap = self.key == "" ? " " : " " - - exec 'nnoremap '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")' -endfunction - -"FUNCTION: KeyMap.Remove(key, scope) {{{1 -function! s:KeyMap.Remove(key, scope) - let maps = s:KeyMap.All() - for i in range(len(maps)) - if maps[i].key ==# a:key && maps[i].scope ==# a:scope - return remove(maps, i) - endif - endfor -endfunction - -"FUNCTION: KeyMap.invoke() {{{1 -"Call the KeyMaps callback function -function! s:KeyMap.invoke(...) - let Callback = function(self.callback) - if a:0 - call Callback(a:1) - else - call Callback() - endif -endfunction - -"FUNCTION: KeyMap.Invoke() {{{1 -"Find a keymapping for a:key and the current scope invoke it. -" -"Scope is determined as follows: -" * if the cursor is on a dir node then "DirNode" -" * if the cursor is on a file node then "FileNode" -" * if the cursor is on a bookmark then "Bookmark" -" -"If a keymap has the scope of "all" then it will be called if no other keymap -"is found for a:key and the scope. -function! s:KeyMap.Invoke(key) - let node = g:NERDTreeFileNode.GetSelected() - if !empty(node) - - "try file node - if !node.path.isDirectory - let km = s:KeyMap.FindFor(a:key, "FileNode") - if !empty(km) - return km.invoke(node) - endif - endif - - "try dir node - if node.path.isDirectory - let km = s:KeyMap.FindFor(a:key, "DirNode") - if !empty(km) - return km.invoke(node) - endif - endif - - "try generic node - let km = s:KeyMap.FindFor(a:key, "Node") - if !empty(km) - return km.invoke(node) - endif - - endif - - "try bookmark - let bm = g:NERDTreeBookmark.GetSelected() - if !empty(bm) - let km = s:KeyMap.FindFor(a:key, "Bookmark") - if !empty(km) - return km.invoke(bm) - endif - endif - - "try all - let km = s:KeyMap.FindFor(a:key, "all") - if !empty(km) - return km.invoke() - endif -endfunction - -"FUNCTION: KeyMap.Create(options) {{{1 -function! s:KeyMap.Create(options) - let newKeyMap = copy(self) - let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options)) - let newKeyMap.key = opts['key'] - let newKeyMap.quickhelpText = opts['quickhelpText'] - let newKeyMap.callback = opts['callback'] - let newKeyMap.scope = opts['scope'] - - call s:KeyMap.Add(newKeyMap) -endfunction - -"FUNCTION: KeyMap.Add(keymap) {{{1 -function! s:KeyMap.Add(keymap) - call s:KeyMap.Remove(a:keymap.key, a:keymap.scope) - call add(s:KeyMap.All(), a:keymap) -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_controller.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_controller.vim deleted file mode 100644 index ae0ee84..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_controller.vim +++ /dev/null @@ -1,180 +0,0 @@ -"CLASS: MenuController -"============================================================ -let s:MenuController = {} -let g:NERDTreeMenuController = s:MenuController - -"FUNCTION: MenuController.New(menuItems) {{{1 -"create a new menu controller that operates on the given menu items -function! s:MenuController.New(menuItems) - let newMenuController = copy(self) - if a:menuItems[0].isSeparator() - let newMenuController.menuItems = a:menuItems[1:-1] - else - let newMenuController.menuItems = a:menuItems - endif - return newMenuController -endfunction - -"FUNCTION: MenuController.showMenu() {{{1 -"start the main loop of the menu and get the user to choose/execute a menu -"item -function! s:MenuController.showMenu() - call self._saveOptions() - - try - let self.selection = 0 - - let done = 0 - while !done - redraw! - call self._echoPrompt() - let key = nr2char(getchar()) - let done = self._handleKeypress(key) - endwhile - finally - call self._restoreOptions() - endtry - - if self.selection != -1 - let m = self._current() - call m.execute() - endif -endfunction - -"FUNCTION: MenuController._echoPrompt() {{{1 -function! s:MenuController._echoPrompt() - echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated" - echo "==========================================================" - - for i in range(0, len(self.menuItems)-1) - if self.selection == i - echo "> " . self.menuItems[i].text - else - echo " " . self.menuItems[i].text - endif - endfor -endfunction - -"FUNCTION: MenuController._current(key) {{{1 -"get the MenuItem that is currently selected -function! s:MenuController._current() - return self.menuItems[self.selection] -endfunction - -"FUNCTION: MenuController._handleKeypress(key) {{{1 -"change the selection (if appropriate) and return 1 if the user has made -"their choice, 0 otherwise -function! s:MenuController._handleKeypress(key) - if a:key == 'j' - call self._cursorDown() - elseif a:key == 'k' - call self._cursorUp() - elseif a:key == nr2char(27) "escape - let self.selection = -1 - return 1 - elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j - return 1 - else - let index = self._nextIndexFor(a:key) - if index != -1 - let self.selection = index - if len(self._allIndexesFor(a:key)) == 1 - return 1 - endif - endif - endif - - return 0 -endfunction - -"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1 -"get indexes to all menu items with the given shortcut -function! s:MenuController._allIndexesFor(shortcut) - let toReturn = [] - - for i in range(0, len(self.menuItems)-1) - if self.menuItems[i].shortcut == a:shortcut - call add(toReturn, i) - endif - endfor - - return toReturn -endfunction - -"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1 -"get the index to the next menu item with the given shortcut, starts from the -"current cursor location and wraps around to the top again if need be -function! s:MenuController._nextIndexFor(shortcut) - for i in range(self.selection+1, len(self.menuItems)-1) - if self.menuItems[i].shortcut == a:shortcut - return i - endif - endfor - - for i in range(0, self.selection) - if self.menuItems[i].shortcut == a:shortcut - return i - endif - endfor - - return -1 -endfunction - -"FUNCTION: MenuController._setCmdheight() {{{1 -"sets &cmdheight to whatever is needed to display the menu -function! s:MenuController._setCmdheight() - let &cmdheight = len(self.menuItems) + 3 -endfunction - -"FUNCTION: MenuController._saveOptions() {{{1 -"set any vim options that are required to make the menu work (saving their old -"values) -function! s:MenuController._saveOptions() - let self._oldLazyredraw = &lazyredraw - let self._oldCmdheight = &cmdheight - set nolazyredraw - call self._setCmdheight() -endfunction - -"FUNCTION: MenuController._restoreOptions() {{{1 -"restore the options we saved in _saveOptions() -function! s:MenuController._restoreOptions() - let &cmdheight = self._oldCmdheight - let &lazyredraw = self._oldLazyredraw -endfunction - -"FUNCTION: MenuController._cursorDown() {{{1 -"move the cursor to the next menu item, skipping separators -function! s:MenuController._cursorDown() - let done = 0 - while !done - if self.selection < len(self.menuItems)-1 - let self.selection += 1 - else - let self.selection = 0 - endif - - if !self._current().isSeparator() - let done = 1 - endif - endwhile -endfunction - -"FUNCTION: MenuController._cursorUp() {{{1 -"move the cursor to the previous menu item, skipping separators -function! s:MenuController._cursorUp() - let done = 0 - while !done - if self.selection > 0 - let self.selection -= 1 - else - let self.selection = len(self.menuItems)-1 - endif - - if !self._current().isSeparator() - let done = 1 - endif - endwhile -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_item.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_item.vim deleted file mode 100644 index 6fb9d9e..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/menu_item.vim +++ /dev/null @@ -1,114 +0,0 @@ -"CLASS: MenuItem -"============================================================ -let s:MenuItem = {} -let g:NERDTreeMenuItem = s:MenuItem - -"FUNCTION: MenuItem.All() {{{1 -"get all top level menu items -function! s:MenuItem.All() - if !exists("s:menuItems") - let s:menuItems = [] - endif - return s:menuItems -endfunction - -"FUNCTION: MenuItem.AllEnabled() {{{1 -"get all top level menu items that are currently enabled -function! s:MenuItem.AllEnabled() - let toReturn = [] - for i in s:MenuItem.All() - if i.enabled() - call add(toReturn, i) - endif - endfor - return toReturn -endfunction - -"FUNCTION: MenuItem.Create(options) {{{1 -"make a new menu item and add it to the global list -function! s:MenuItem.Create(options) - let newMenuItem = copy(self) - - let newMenuItem.text = a:options['text'] - let newMenuItem.shortcut = a:options['shortcut'] - let newMenuItem.children = [] - - let newMenuItem.isActiveCallback = -1 - if has_key(a:options, 'isActiveCallback') - let newMenuItem.isActiveCallback = a:options['isActiveCallback'] - endif - - let newMenuItem.callback = -1 - if has_key(a:options, 'callback') - let newMenuItem.callback = a:options['callback'] - endif - - if has_key(a:options, 'parent') - call add(a:options['parent'].children, newMenuItem) - else - call add(s:MenuItem.All(), newMenuItem) - endif - - return newMenuItem -endfunction - -"FUNCTION: MenuItem.CreateSeparator(options) {{{1 -"make a new separator menu item and add it to the global list -function! s:MenuItem.CreateSeparator(options) - let standard_options = { 'text': '--------------------', - \ 'shortcut': -1, - \ 'callback': -1 } - let options = extend(a:options, standard_options, "force") - - return s:MenuItem.Create(options) -endfunction - -"FUNCTION: MenuItem.CreateSubmenu(options) {{{1 -"make a new submenu and add it to global list -function! s:MenuItem.CreateSubmenu(options) - let standard_options = { 'callback': -1 } - let options = extend(a:options, standard_options, "force") - - return s:MenuItem.Create(options) -endfunction - -"FUNCTION: MenuItem.enabled() {{{1 -"return 1 if this menu item should be displayed -" -"delegates off to the isActiveCallback, and defaults to 1 if no callback was -"specified -function! s:MenuItem.enabled() - if self.isActiveCallback != -1 - return {self.isActiveCallback}() - endif - return 1 -endfunction - -"FUNCTION: MenuItem.execute() {{{1 -"perform the action behind this menu item, if this menuitem has children then -"display a new menu for them, otherwise deletegate off to the menuitem's -"callback -function! s:MenuItem.execute() - if len(self.children) - let mc = s:MenuController.New(self.children) - call mc.showMenu() - else - if self.callback != -1 - call {self.callback}() - endif - endif -endfunction - -"FUNCTION: MenuItem.isSeparator() {{{1 -"return 1 if this menuitem is a separator -function! s:MenuItem.isSeparator() - return self.callback == -1 && self.children == [] -endfunction - -"FUNCTION: MenuItem.isSubmenu() {{{1 -"return 1 if this menuitem is a submenu -function! s:MenuItem.isSubmenu() - return self.callback == -1 && !empty(self.children) -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/opener.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/opener.vim deleted file mode 100644 index bcc0d4f..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/opener.vim +++ /dev/null @@ -1,264 +0,0 @@ -"CLASS: Opener -"============================================================ -let s:Opener = {} -let g:NERDTreeOpener = s:Opener - -"FUNCTION: Opener._checkToCloseTree(newtab) {{{1 -"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see -"if the tree should be closed now. -" -"Args: -"a:newtab - boolean. If set, only close the tree now if we are opening the -"target in a new tab. This is needed because we have to close tree before we -"leave the tab -function! s:Opener._checkToCloseTree(newtab) - if self._keepopen - return - endif - - if (a:newtab && self._where == 't') || !a:newtab - call nerdtree#closeTreeIfQuitOnOpen() - endif -endfunction - -"FUNCTION: Opener._gotoTargetWin() {{{1 -function! s:Opener._gotoTargetWin() - if b:NERDTreeType ==# "secondary" - if self._where == 'v' - vsplit - elseif self._where == 'h' - split - elseif self._where == 't' - tabnew - endif - else - call self._checkToCloseTree(1) - - if self._where == 'v' - call self._newVSplit() - elseif self._where == 'h' - call self._newSplit() - elseif self._where == 't' - tabnew - elseif self._where == 'p' - call self._previousWindow() - endif - - call self._checkToCloseTree(0) - endif -endfunction - -"FUNCTION: Opener.New(path, opts) {{{1 -"Args: -" -"a:path: The path object that is to be opened. -" -"a:opts: -" -"A dictionary containing the following keys (all optional): -" 'where': Specifies whether the node should be opened in new split/tab or in -" the previous window. Can be either 'v' or 'h' or 't' (for open in -" new tab) -" 'reuse': if a window is displaying the file then jump the cursor there -" 'keepopen': dont close the tree window -" 'stay': open the file, but keep the cursor in the tree win -function! s:Opener.New(path, opts) - let newObj = copy(self) - - let newObj._path = a:path - let newObj._stay = nerdtree#has_opt(a:opts, 'stay') - let newObj._reuse = nerdtree#has_opt(a:opts, 'reuse') - let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen') - let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : '' - let newObj._treetype = b:NERDTreeType - call newObj._saveCursorPos() - - return newObj -endfunction - -"FUNCTION: Opener._newSplit() {{{1 -function! s:Opener._newSplit() - " Save the user's settings for splitbelow and splitright - let savesplitbelow=&splitbelow - let savesplitright=&splitright - - " 'there' will be set to a command to move from the split window - " back to the explorer window - " - " 'back' will be set to a command to move from the explorer window - " back to the newly split window - " - " 'right' and 'below' will be set to the settings needed for - " splitbelow and splitright IF the explorer is the only window. - " - let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l" - let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h" - let right= g:NERDTreeWinPos ==# "left" - let below=0 - - " Attempt to go to adjacent window - call nerdtree#exec(back) - - let onlyOneWin = (winnr("$") ==# 1) - - " If no adjacent window, set splitright and splitbelow appropriately - if onlyOneWin - let &splitright=right - let &splitbelow=below - else - " found adjacent window - invert split direction - let &splitright=!right - let &splitbelow=!below - endif - - let splitMode = onlyOneWin ? "vertical" : "" - - " Open the new window - try - exec(splitMode." sp ") - catch /^Vim\%((\a\+)\)\=:E37/ - call nerdtree#putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - "do nothing - endtry - - "resize the tree window if no other window was open before - if onlyOneWin - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - call nerdtree#exec(there) - exec("silent ". splitMode ." resize ". size) - call nerdtree#exec('wincmd p') - endif - - " Restore splitmode settings - let &splitbelow=savesplitbelow - let &splitright=savesplitright -endfunction - -"FUNCTION: Opener._newVSplit() {{{1 -function! s:Opener._newVSplit() - let winwidth = winwidth(".") - if winnr("$")==#1 - let winwidth = g:NERDTreeWinSize - endif - - call nerdtree#exec("wincmd p") - vnew - - "resize the nerd tree back to the original size - call nerdtree#putCursorInTreeWin() - exec("silent vertical resize ". winwidth) - call nerdtree#exec('wincmd p') -endfunction - -"FUNCTION: Opener.open(target) {{{1 -function! s:Opener.open(target) - if self._path.isDirectory - call self._openDirectory(a:target) - else - call self._openFile() - endif -endfunction - -"FUNCTION: Opener._openFile() {{{1 -function! s:Opener._openFile() - if self._reuse && self._reuseWindow() - return - endif - - call self._gotoTargetWin() - - if self._treetype ==# "secondary" - call self._path.edit() - else - call self._path.edit() - - - if self._stay - call self._restoreCursorPos() - endif - endif -endfunction - -"FUNCTION: Opener._openDirectory(node) {{{1 -function! s:Opener._openDirectory(node) - if self._treetype ==# "secondary" - call self._gotoTargetWin() - call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) - else - call self._gotoTargetWin() - if empty(self._where) - call a:node.makeRoot() - call nerdtree#renderView() - call a:node.putCursorHere(0, 0) - elseif self._where == 't' - call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) - else - call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) - endif - endif - - if self._stay - call self._restoreCursorPos() - endif -endfunction - -"FUNCTION: Opener._previousWindow() {{{1 -function! s:Opener._previousWindow() - if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1 - call self._newSplit() - else - try - if !nerdtree#isWindowUsable(winnr("#")) - call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w") - else - call nerdtree#exec('wincmd p') - endif - catch /^Vim\%((\a\+)\)\=:E37/ - call nerdtree#putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - echo v:exception - endtry - endif -endfunction - -"FUNCTION: Opener._restoreCursorPos(){{{1 -function! s:Opener._restoreCursorPos() - call nerdtree#exec('normal ' . self._tabnr . 'gt') - call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w') -endfunction - -"FUNCTION: Opener._reuseWindow(){{{1 -"put the cursor in the first window we find for this file -" -"return 1 if we were successful -function! s:Opener._reuseWindow() - "check the current tab for the window - let winnr = bufwinnr('^' . self._path.str() . '$') - if winnr != -1 - call nerdtree#exec(winnr . "wincmd w") - call self._checkToCloseTree(0) - return 1 - else - "check other tabs - let tabnr = self._path.tabnr() - if tabnr - call self._checkToCloseTree(1) - call nerdtree#exec('normal! ' . tabnr . 'gt') - let winnr = bufwinnr('^' . self._path.str() . '$') - call nerdtree#exec(winnr . "wincmd w") - return 1 - endif - endif - return 0 -endfunction - -"FUNCTION: Opener._saveCursorPos(){{{1 -function! s:Opener._saveCursorPos() - let self._bufnr = bufnr("") - let self._tabnr = tabpagenr() -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/path.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/path.vim deleted file mode 100644 index 58bb013..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/path.vim +++ /dev/null @@ -1,724 +0,0 @@ -"we need to use this number many times for sorting... so we calculate it only -"once here -let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') - -"CLASS: Path -"============================================================ -let s:Path = {} -let g:NERDTreePath = s:Path - -"FUNCTION: Path.AbsolutePathFor(str) {{{1 -function! s:Path.AbsolutePathFor(str) - let prependCWD = 0 - if nerdtree#runningWindows() - let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)' - else - let prependCWD = a:str !~# '^/' - endif - - let toReturn = a:str - if prependCWD - let toReturn = getcwd() . s:Path.Slash() . a:str - endif - - return toReturn -endfunction - -"FUNCTION: Path.bookmarkNames() {{{1 -function! s:Path.bookmarkNames() - if !exists("self._bookmarkNames") - call self.cacheDisplayString() - endif - return self._bookmarkNames -endfunction - -"FUNCTION: Path.cacheDisplayString() {{{1 -function! s:Path.cacheDisplayString() - let self.cachedDisplayString = self.getLastPathComponent(1) - - if self.isExecutable - let self.cachedDisplayString = self.cachedDisplayString . '*' - endif - - let self._bookmarkNames = [] - for i in g:NERDTreeBookmark.Bookmarks() - if i.path.equals(self) - call add(self._bookmarkNames, i.name) - endif - endfor - if !empty(self._bookmarkNames) - let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}' - endif - - if self.isSymLink - let self.cachedDisplayString .= ' -> ' . self.symLinkDest - endif - - if self.isReadOnly - let self.cachedDisplayString .= ' [RO]' - endif -endfunction - -"FUNCTION: Path.changeToDir() {{{1 -function! s:Path.changeToDir() - let dir = self.str({'format': 'Cd'}) - if self.isDirectory ==# 0 - let dir = self.getParent().str({'format': 'Cd'}) - endif - - try - execute "cd " . dir - call nerdtree#echo("CWD is now: " . getcwd()) - catch - throw "NERDTree.PathChangeError: cannot change CWD to " . dir - endtry -endfunction - -"FUNCTION: Path.compareTo() {{{1 -" -"Compares this Path to the given path and returns 0 if they are equal, -1 if -"this Path is "less than" the given path, or 1 if it is "greater". -" -"Args: -"path: the path object to compare this to -" -"Return: -"1, -1 or 0 -function! s:Path.compareTo(path) - let thisPath = self.getLastPathComponent(1) - let thatPath = a:path.getLastPathComponent(1) - - "if the paths are the same then clearly we return 0 - if thisPath ==# thatPath - return 0 - endif - - let thisSS = self.getSortOrderIndex() - let thatSS = a:path.getSortOrderIndex() - - "compare the sort sequences, if they are different then the return - "value is easy - if thisSS < thatSS - return -1 - elseif thisSS > thatSS - return 1 - else - "if the sort sequences are the same then compare the paths - "alphabetically - let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath limit - let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1) - endif - endif - - return toReturn -endfunction - -"FUNCTION: Path._strForUI() {{{1 -function! s:Path._strForUI() - let toReturn = '/' . join(self.pathSegments, '/') - if self.isDirectory && toReturn != '/' - let toReturn = toReturn . '/' - endif - return toReturn -endfunction - -"FUNCTION: Path._strForCd() {{{1 -" -" returns a string that can be used with :cd -function! s:Path._strForCd() - return escape(self.str(), nerdtree#escChars()) -endfunction - -"FUNCTION: Path._strForEdit() {{{1 -" -"Return: the string for this path that is suitable to be used with the :edit -"command -function! s:Path._strForEdit() - let p = escape(self.str({'format': 'UI'}), nerdtree#escChars()) - let cwd = getcwd() . s:Path.Slash() - - "return a relative path if we can - let isRelative = 0 - if nerdtree#runningWindows() - let isRelative = stridx(tolower(p), tolower(cwd)) == 0 - else - let isRelative = stridx(p, cwd) == 0 - endif - - if isRelative - let p = strpart(p, strlen(cwd)) - - "handle the edge case where the file begins with a + (vim interprets - "the +foo in `:e +foo` as an option to :edit) - if p[0] == "+" - let p = '\' . p - endif - endif - - if p ==# '' - let p = '.' - endif - - return p -endfunction - -"FUNCTION: Path._strForGlob() {{{1 -function! s:Path._strForGlob() - let lead = s:Path.Slash() - - "if we are running windows then slap a drive letter on the front - if nerdtree#runningWindows() - let lead = self.drive . '\' - endif - - let toReturn = lead . join(self.pathSegments, s:Path.Slash()) - - if !nerdtree#runningWindows() - let toReturn = escape(toReturn, nerdtree#escChars()) - endif - return toReturn -endfunction - -"FUNCTION: Path._str() {{{1 -" -"Gets the string path for this path object that is appropriate for the OS. -"EG, in windows c:\foo\bar -" in *nix /foo/bar -function! s:Path._str() - let lead = s:Path.Slash() - - "if we are running windows then slap a drive letter on the front - if nerdtree#runningWindows() - let lead = self.drive . '\' - endif - - return lead . join(self.pathSegments, s:Path.Slash()) -endfunction - -"FUNCTION: Path.strTrunk() {{{1 -"Gets the path without the last segment on the end. -function! s:Path.strTrunk() - return self.drive . '/' . join(self.pathSegments[0:-2], '/') -endfunction - -" FUNCTION: Path.tabnr() {{{1 -" return the number of the first tab that is displaying this file -" -" return 0 if no tab was found -function! s:Path.tabnr() - let str = self.str() - for t in range(tabpagenr('$')) - for b in tabpagebuflist(t+1) - if str == expand('#' . b . ':p') - return t+1 - endif - endfor - endfor - return 0 -endfunction - -"FUNCTION: Path.WinToUnixPath(pathstr){{{1 -"Takes in a windows path and returns the unix equiv -" -"A class level method -" -"Args: -"pathstr: the windows path to convert -function! s:Path.WinToUnixPath(pathstr) - if !nerdtree#runningWindows() - return a:pathstr - endif - - let toReturn = a:pathstr - - "remove the x:\ of the front - let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "") - - "remove the \\ network share from the front - let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "") - - "convert all \ chars to / - let toReturn = substitute(toReturn, '\', '/', "g") - - return toReturn -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_dir_node.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_dir_node.vim deleted file mode 100644 index 1b1a231..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_dir_node.vim +++ /dev/null @@ -1,528 +0,0 @@ -"CLASS: TreeDirNode -"A subclass of NERDTreeFileNode. -" -"The 'composite' part of the file/dir composite. -"============================================================ -let s:TreeDirNode = copy(g:NERDTreeFileNode) -let g:NERDTreeDirNode = s:TreeDirNode - -"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1 -"class method that returns the highest cached ancestor of the current root -function! s:TreeDirNode.AbsoluteTreeRoot() - let currentNode = b:NERDTreeRoot - while currentNode.parent != {} - let currentNode = currentNode.parent - endwhile - return currentNode -endfunction - -"FUNCTION: TreeDirNode.activate([options]) {{{1 -unlet s:TreeDirNode.activate -function! s:TreeDirNode.activate(...) - let opts = a:0 ? a:1 : {} - call self.toggleOpen(opts) - call nerdtree#renderView() - call self.putCursorHere(0, 0) -endfunction - -"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{1 -"Adds the given treenode to the list of children for this node -" -"Args: -"-treenode: the node to add -"-inOrder: 1 if the new node should be inserted in sorted order -function! s:TreeDirNode.addChild(treenode, inOrder) - call add(self.children, a:treenode) - let a:treenode.parent = self - - if a:inOrder - call self.sortChildren() - endif -endfunction - -"FUNCTION: TreeDirNode.close() {{{1 -"Closes this directory -function! s:TreeDirNode.close() - let self.isOpen = 0 -endfunction - -"FUNCTION: TreeDirNode.closeChildren() {{{1 -"Closes all the child dir nodes of this node -function! s:TreeDirNode.closeChildren() - for i in self.children - if i.path.isDirectory - call i.close() - call i.closeChildren() - endif - endfor -endfunction - -"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{1 -"Instantiates a new child node for this node with the given path. The new -"nodes parent is set to this node. -" -"Args: -"path: a Path object that this node will represent/contain -"inOrder: 1 if the new node should be inserted in sorted order -" -"Returns: -"the newly created node -function! s:TreeDirNode.createChild(path, inOrder) - let newTreeNode = g:NERDTreeFileNode.New(a:path) - call self.addChild(newTreeNode, a:inOrder) - return newTreeNode -endfunction - -"FUNCTION: TreeDirNode.findNode(path) {{{1 -"Will find one of the children (recursively) that has the given path -" -"Args: -"path: a path object -unlet s:TreeDirNode.findNode -function! s:TreeDirNode.findNode(path) - if a:path.equals(self.path) - return self - endif - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return {} - endif - - if self.path.isDirectory - for i in self.children - let retVal = i.findNode(a:path) - if retVal != {} - return retVal - endif - endfor - endif - return {} -endfunction - -"FUNCTION: TreeDirNode.getChildCount() {{{1 -"Returns the number of children this node has -function! s:TreeDirNode.getChildCount() - return len(self.children) -endfunction - -"FUNCTION: TreeDirNode.getChild(path) {{{1 -"Returns child node of this node that has the given path or {} if no such node -"exists. -" -"This function doesnt not recurse into child dir nodes -" -"Args: -"path: a path object -function! s:TreeDirNode.getChild(path) - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return {} - endif - - let index = self.getChildIndex(a:path) - if index ==# -1 - return {} - else - return self.children[index] - endif - -endfunction - -"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{1 -"returns the child at the given index -"Args: -"indx: the index to get the child from -"visible: 1 if only the visible children array should be used, 0 if all the -"children should be searched. -function! s:TreeDirNode.getChildByIndex(indx, visible) - let array_to_search = a:visible? self.getVisibleChildren() : self.children - if a:indx > len(array_to_search) - throw "NERDTree.InvalidArgumentsError: Index is out of bounds." - endif - return array_to_search[a:indx] -endfunction - -"FUNCTION: TreeDirNode.getChildIndex(path) {{{1 -"Returns the index of the child node of this node that has the given path or -"-1 if no such node exists. -" -"This function doesnt not recurse into child dir nodes -" -"Args: -"path: a path object -function! s:TreeDirNode.getChildIndex(path) - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return -1 - endif - - "do a binary search for the child - let a = 0 - let z = self.getChildCount() - while a < z - let mid = (a+z)/2 - let diff = a:path.compareTo(self.children[mid].path) - - if diff ==# -1 - let z = mid - elseif diff ==# 1 - let a = mid+1 - else - return mid - endif - endwhile - return -1 -endfunction - -"FUNCTION: TreeDirNode.GetSelected() {{{1 -"Returns the current node if it is a dir node, or else returns the current -"nodes parent -unlet s:TreeDirNode.GetSelected -function! s:TreeDirNode.GetSelected() - let currentDir = g:NERDTreeFileNode.GetSelected() - if currentDir != {} && !currentDir.isRoot() - if currentDir.path.isDirectory ==# 0 - let currentDir = currentDir.parent - endif - endif - return currentDir -endfunction - -"FUNCTION: TreeDirNode.getVisibleChildCount() {{{1 -"Returns the number of visible children this node has -function! s:TreeDirNode.getVisibleChildCount() - return len(self.getVisibleChildren()) -endfunction - -"FUNCTION: TreeDirNode.getVisibleChildren() {{{1 -"Returns a list of children to display for this node, in the correct order -" -"Return: -"an array of treenodes -function! s:TreeDirNode.getVisibleChildren() - let toReturn = [] - for i in self.children - if i.path.ignore() ==# 0 - call add(toReturn, i) - endif - endfor - return toReturn -endfunction - -"FUNCTION: TreeDirNode.hasVisibleChildren() {{{1 -"returns 1 if this node has any childre, 0 otherwise.. -function! s:TreeDirNode.hasVisibleChildren() - return self.getVisibleChildCount() != 0 -endfunction - -"FUNCTION: TreeDirNode._initChildren() {{{1 -"Removes all childen from this node and re-reads them -" -"Args: -"silent: 1 if the function should not echo any "please wait" messages for -"large directories -" -"Return: the number of child nodes read -function! s:TreeDirNode._initChildren(silent) - "remove all the current child nodes - let self.children = [] - - "get an array of all the files in the nodes dir - let dir = self.path - let globDir = dir.str({'format': 'Glob'}) - - if version >= 703 - let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1) - else - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - endif - - let files = split(filesStr, "\n") - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call nerdtree#echo("Please wait, caching a large dir ...") - endif - - let invalidFilesFound = 0 - for i in files - - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' - - "put the next file in a new node and attach it - try - let path = g:NERDTreePath.New(i) - call self.createChild(path, 0) - catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ - let invalidFilesFound += 1 - endtry - endif - endfor - - call self.sortChildren() - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call nerdtree#echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).") - endif - - if invalidFilesFound - call nerdtree#echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") - endif - return self.getChildCount() -endfunction - -"FUNCTION: TreeDirNode.New(path) {{{1 -"Returns a new TreeNode object with the given path and parent -" -"Args: -"path: a path object representing the full filesystem path to the file/dir that the node represents -unlet s:TreeDirNode.New -function! s:TreeDirNode.New(path) - if a:path.isDirectory != 1 - throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object." - endif - - let newTreeNode = copy(self) - let newTreeNode.path = a:path - - let newTreeNode.isOpen = 0 - let newTreeNode.children = [] - - let newTreeNode.parent = {} - - return newTreeNode -endfunction - -"FUNCTION: TreeDirNode.open([opts]) {{{1 -"Open the dir in the current tree or in a new tree elsewhere. -" -"If opening in the current tree, return the number of cached nodes. -unlet s:TreeDirNode.open -function! s:TreeDirNode.open(...) - let opts = a:0 ? a:1 : {} - - if has_key(opts, 'where') && !empty(opts['where']) - let opener = g:NERDTreeOpener.New(self.path, opts) - call opener.open(self) - else - let self.isOpen = 1 - if self.children ==# [] - return self._initChildren(0) - else - return 0 - endif - endif -endfunction - -"FUNCTION: TreeDirNode.openAlong([opts]) {{{1 -"recursive open the dir if it has only one directory child. -" -"return the level of opened directories. -function! s:TreeDirNode.openAlong(...) - let opts = a:0 ? a:1 : {} - let level = 0 - - let node = self - while node.path.isDirectory - call node.open(opts) - let level += 1 - if node.getVisibleChildCount() == 1 - let node = node.getChildByIndex(0, 1) - else - break - endif - endwhile - return level -endfunction - -" FUNCTION: TreeDirNode.openExplorer() {{{1 -" opens an explorer window for this node in the previous window (could be a -" nerd tree or a netrw) -function! s:TreeDirNode.openExplorer() - call self.open({'where': 'p'}) -endfunction - -"FUNCTION: TreeDirNode.openInNewTab(options) {{{1 -unlet s:TreeDirNode.openInNewTab -function! s:TreeDirNode.openInNewTab(options) - call nerdtree#deprecated('TreeDirNode.openInNewTab', 'is deprecated, use open() instead') - call self.open({'where': 't'}) -endfunction - -"FUNCTION: TreeDirNode._openInNewTab() {{{1 -function! s:TreeDirNode._openInNewTab() - tabnew - call g:NERDTreeCreator.CreatePrimary(self.path.str()) -endfunction - -"FUNCTION: TreeDirNode.openRecursively() {{{1 -"Opens this treenode and all of its children whose paths arent 'ignored' -"because of the file filters. -" -"This method is actually a wrapper for the OpenRecursively2 method which does -"the work. -function! s:TreeDirNode.openRecursively() - call self._openRecursively2(1) -endfunction - -"FUNCTION: TreeDirNode._openRecursively2() {{{1 -"Opens this all children of this treenode recursively if either: -" *they arent filtered by file filters -" *a:forceOpen is 1 -" -"Args: -"forceOpen: 1 if this node should be opened regardless of file filters -function! s:TreeDirNode._openRecursively2(forceOpen) - if self.path.ignore() ==# 0 || a:forceOpen - let self.isOpen = 1 - if self.children ==# [] - call self._initChildren(1) - endif - - for i in self.children - if i.path.isDirectory ==# 1 - call i._openRecursively2(0) - endif - endfor - endif -endfunction - -"FUNCTION: TreeDirNode.refresh() {{{1 -unlet s:TreeDirNode.refresh -function! s:TreeDirNode.refresh() - call self.path.refresh() - - "if this node was ever opened, refresh its children - if self.isOpen || !empty(self.children) - "go thru all the files/dirs under this node - let newChildNodes = [] - let invalidFilesFound = 0 - let dir = self.path - let globDir = dir.str({'format': 'Glob'}) - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - let files = split(filesStr, "\n") - for i in files - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' - - try - "create a new path and see if it exists in this nodes children - let path = g:NERDTreePath.New(i) - let newNode = self.getChild(path) - if newNode != {} - call newNode.refresh() - call add(newChildNodes, newNode) - - "the node doesnt exist so create it - else - let newNode = g:NERDTreeFileNode.New(path) - let newNode.parent = self - call add(newChildNodes, newNode) - endif - - - catch /^NERDTree.InvalidArgumentsError/ - let invalidFilesFound = 1 - endtry - endif - endfor - - "swap this nodes children out for the children we just read/refreshed - let self.children = newChildNodes - call self.sortChildren() - - if invalidFilesFound - call nerdtree#echoWarning("some files could not be loaded into the NERD tree") - endif - endif -endfunction - -"FUNCTION: TreeDirNode.reveal(path) {{{1 -"reveal the given path, i.e. cache and open all treenodes needed to display it -"in the UI -function! s:TreeDirNode.reveal(path) - if !a:path.isUnder(self.path) - throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str() - endif - - call self.open() - - if self.path.equals(a:path.getParent()) - let n = self.findNode(a:path) - call nerdtree#renderView() - call n.putCursorHere(1,0) - return - endif - - let p = a:path - while !p.getParent().equals(self.path) - let p = p.getParent() - endwhile - - let n = self.findNode(p) - call n.reveal(a:path) -endfunction - -"FUNCTION: TreeDirNode.removeChild(treenode) {{{1 -" -"Removes the given treenode from this nodes set of children -" -"Args: -"treenode: the node to remove -" -"Throws a NERDTree.ChildNotFoundError if the given treenode is not found -function! s:TreeDirNode.removeChild(treenode) - for i in range(0, self.getChildCount()-1) - if self.children[i].equals(a:treenode) - call remove(self.children, i) - return - endif - endfor - - throw "NERDTree.ChildNotFoundError: child node was not found" -endfunction - -"FUNCTION: TreeDirNode.sortChildren() {{{1 -" -"Sorts the children of this node according to alphabetical order and the -"directory priority. -" -function! s:TreeDirNode.sortChildren() - let CompareFunc = function("nerdtree#compareNodes") - call sort(self.children, CompareFunc) -endfunction - -"FUNCTION: TreeDirNode.toggleOpen([options]) {{{1 -"Opens this directory if it is closed and vice versa -function! s:TreeDirNode.toggleOpen(...) - let opts = a:0 ? a:1 : {} - if self.isOpen ==# 1 - call self.close() - else - if g:NERDTreeCasadeOpenSingleChildDir == 0 - call self.open(opts) - else - call self.openAlong(opts) - endif - endif -endfunction - -"FUNCTION: TreeDirNode.transplantChild(newNode) {{{1 -"Replaces the child of this with the given node (where the child node's full -"path matches a:newNode's fullpath). The search for the matching node is -"non-recursive -" -"Arg: -"newNode: the node to graft into the tree -function! s:TreeDirNode.transplantChild(newNode) - for i in range(0, self.getChildCount()-1) - if self.children[i].equals(a:newNode) - let self.children[i] = a:newNode - let a:newNode.parent = self - break - endif - endfor -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_file_node.vim b/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_file_node.vim deleted file mode 100644 index ab8d371..0000000 --- a/common/.vim/bundle/nerdtree/plugin/nerdtree/tree_file_node.vim +++ /dev/null @@ -1,485 +0,0 @@ -"CLASS: TreeFileNode -"This class is the parent of the TreeDirNode class and is the -"'Component' part of the composite design pattern between the treenode -"classes. -"============================================================ -let s:TreeFileNode = {} -let g:NERDTreeFileNode = s:TreeFileNode - -"FUNCTION: TreeFileNode.activate(...) {{{1 -function! s:TreeFileNode.activate(...) - call self.open(a:0 ? a:1 : {}) -endfunction - -"FUNCTION: TreeFileNode.bookmark(name) {{{1 -"bookmark this node with a:name -function! s:TreeFileNode.bookmark(name) - - "if a bookmark exists with the same name and the node is cached then save - "it so we can update its display string - let oldMarkedNode = {} - try - let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1) - catch /^NERDTree.BookmarkNotFoundError/ - catch /^NERDTree.BookmarkedNodeNotFoundError/ - endtry - - call g:NERDTreeBookmark.AddBookmark(a:name, self.path) - call self.path.cacheDisplayString() - call g:NERDTreeBookmark.Write() - - if !empty(oldMarkedNode) - call oldMarkedNode.path.cacheDisplayString() - endif -endfunction - -"FUNCTION: TreeFileNode.cacheParent() {{{1 -"initializes self.parent if it isnt already -function! s:TreeFileNode.cacheParent() - if empty(self.parent) - let parentPath = self.path.getParent() - if parentPath.equals(self.path) - throw "NERDTree.CannotCacheParentError: already at root" - endif - let self.parent = s:TreeFileNode.New(parentPath) - endif -endfunction - -"FUNCTION: TreeFileNode.clearBookmarks() {{{1 -function! s:TreeFileNode.clearBookmarks() - for i in g:NERDTreeBookmark.Bookmarks() - if i.path.equals(self.path) - call i.delete() - end - endfor - call self.path.cacheDisplayString() -endfunction - -"FUNCTION: TreeFileNode.copy(dest) {{{1 -function! s:TreeFileNode.copy(dest) - call self.path.copy(a:dest) - let newPath = g:NERDTreePath.New(a:dest) - let parent = b:NERDTreeRoot.findNode(newPath.getParent()) - if !empty(parent) - call parent.refresh() - return parent.findNode(newPath) - else - return {} - endif -endfunction - -"FUNCTION: TreeFileNode.delete {{{1 -"Removes this node from the tree and calls the Delete method for its path obj -function! s:TreeFileNode.delete() - call self.path.delete() - call self.parent.removeChild(self) -endfunction - -"FUNCTION: TreeFileNode.displayString() {{{1 -" -"Returns a string that specifies how the node should be represented as a -"string -" -"Return: -"a string that can be used in the view to represent this node -function! s:TreeFileNode.displayString() - return self.path.displayString() -endfunction - -"FUNCTION: TreeFileNode.equals(treenode) {{{1 -" -"Compares this treenode to the input treenode and returns 1 if they are the -"same node. -" -"Use this method instead of == because sometimes when the treenodes contain -"many children, vim seg faults when doing == -" -"Args: -"treenode: the other treenode to compare to -function! s:TreeFileNode.equals(treenode) - return self.path.str() ==# a:treenode.path.str() -endfunction - -"FUNCTION: TreeFileNode.findNode(path) {{{1 -"Returns self if this node.path.Equals the given path. -"Returns {} if not equal. -" -"Args: -"path: the path object to compare against -function! s:TreeFileNode.findNode(path) - if a:path.equals(self.path) - return self - endif - return {} -endfunction - -"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{1 -" -"Finds the next sibling for this node in the indicated direction. This sibling -"must be a directory and may/may not have children as specified. -" -"Args: -"direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -"Return: -"a treenode object or {} if no appropriate sibling could be found -function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) - "if we have no parent then we can have no siblings - if self.parent != {} - let nextSibling = self.findSibling(a:direction) - - while nextSibling != {} - if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen - return nextSibling - endif - let nextSibling = nextSibling.findSibling(a:direction) - endwhile - endif - - return {} -endfunction - -"FUNCTION: TreeFileNode.findSibling(direction) {{{1 -" -"Finds the next sibling for this node in the indicated direction -" -"Args: -"direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -"Return: -"a treenode object or {} if no sibling could be found -function! s:TreeFileNode.findSibling(direction) - "if we have no parent then we can have no siblings - if self.parent != {} - - "get the index of this node in its parents children - let siblingIndx = self.parent.getChildIndex(self.path) - - if siblingIndx != -1 - "move a long to the next potential sibling node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - - "keep moving along to the next sibling till we find one that is valid - let numSiblings = self.parent.getChildCount() - while siblingIndx >= 0 && siblingIndx < numSiblings - - "if the next node is not an ignored node (i.e. wont show up in the - "view) then return it - if self.parent.children[siblingIndx].path.ignore() ==# 0 - return self.parent.children[siblingIndx] - endif - - "go to next node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - endwhile - endif - endif - - return {} -endfunction - -"FUNCTION: TreeFileNode.getLineNum(){{{1 -"returns the line number this node is rendered on, or -1 if it isnt rendered -function! s:TreeFileNode.getLineNum() - "if the node is the root then return the root line no. - if self.isRoot() - return s:TreeFileNode.GetRootLineNum() - endif - - let totalLines = line("$") - - "the path components we have matched so far - let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')] - "the index of the component we are searching for - let curPathComponent = 1 - - let fullpath = self.path.str({'format': 'UI'}) - - - let lnum = s:TreeFileNode.GetRootLineNum() - while lnum > 0 - let lnum = lnum + 1 - "have we reached the bottom of the tree? - if lnum ==# totalLines+1 - return -1 - endif - - let curLine = getline(lnum) - - let indent = nerdtree#indentLevelFor(curLine) - if indent ==# curPathComponent - let curLine = nerdtree#stripMarkupFromLine(curLine, 1) - - let curPath = join(pathcomponents, '/') . '/' . curLine - if stridx(fullpath, curPath, 0) ==# 0 - if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/' - let curLine = substitute(curLine, '/ *$', '', '') - call add(pathcomponents, curLine) - let curPathComponent = curPathComponent + 1 - - if fullpath ==# curPath - return lnum - endif - endif - endif - endif - endwhile - return -1 -endfunction - -"FUNCTION: TreeFileNode.GetRootForTab(){{{1 -"get the root node for this tab -function! s:TreeFileNode.GetRootForTab() - if nerdtree#treeExistsForTab() - return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') - end - return {} -endfunction - -"FUNCTION: TreeFileNode.GetRootLineNum(){{{1 -"gets the line number of the root node -function! s:TreeFileNode.GetRootLineNum() - let rootLine = 1 - while getline(rootLine) !~# '^\(/\|<\)' - let rootLine = rootLine + 1 - endwhile - return rootLine -endfunction - -"FUNCTION: TreeFileNode.GetSelected() {{{1 -"gets the treenode that the cursor is currently over -function! s:TreeFileNode.GetSelected() - try - let path = nerdtree#getPath(line(".")) - if path ==# {} - return {} - endif - return b:NERDTreeRoot.findNode(path) - catch /^NERDTree/ - return {} - endtry -endfunction - -"FUNCTION: TreeFileNode.isVisible() {{{1 -"returns 1 if this node should be visible according to the tree filters and -"hidden file filters (and their on/off status) -function! s:TreeFileNode.isVisible() - return !self.path.ignore() -endfunction - -"FUNCTION: TreeFileNode.isRoot() {{{1 -"returns 1 if this node is b:NERDTreeRoot -function! s:TreeFileNode.isRoot() - if !nerdtree#treeExistsForBuf() - throw "NERDTree.NoTreeError: No tree exists for the current buffer" - endif - - return self.equals(b:NERDTreeRoot) -endfunction - -"FUNCTION: TreeFileNode.makeRoot() {{{1 -"Make this node the root of the tree -function! s:TreeFileNode.makeRoot() - if self.path.isDirectory - let b:NERDTreeRoot = self - else - call self.cacheParent() - let b:NERDTreeRoot = self.parent - endif - - call b:NERDTreeRoot.open() - - "change dir to the dir of the new root if instructed to - if g:NERDTreeChDirMode ==# 2 - exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'}) - endif - - silent doautocmd User NERDTreeNewRoot -endfunction - -"FUNCTION: TreeFileNode.New(path) {{{1 -"Returns a new TreeNode object with the given path and parent -" -"Args: -"path: a path object representing the full filesystem path to the file/dir that the node represents -function! s:TreeFileNode.New(path) - if a:path.isDirectory - return g:NERDTreeDirNode.New(a:path) - else - let newTreeNode = copy(self) - let newTreeNode.path = a:path - let newTreeNode.parent = {} - return newTreeNode - endif -endfunction - -"FUNCTION: TreeFileNode.open() {{{1 -function! s:TreeFileNode.open(...) - let opts = a:0 ? a:1 : {} - let opener = g:NERDTreeOpener.New(self.path, opts) - call opener.open(self) -endfunction - -"FUNCTION: TreeFileNode.openSplit() {{{1 -"Open this node in a new window -function! s:TreeFileNode.openSplit() - call nerdtree#deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.') - call self.open({'where': 'h'}) -endfunction - -"FUNCTION: TreeFileNode.openVSplit() {{{1 -"Open this node in a new vertical window -function! s:TreeFileNode.openVSplit() - call nerdtree#deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.') - call self.open({'where': 'v'}) -endfunction - -"FUNCTION: TreeFileNode.openInNewTab(options) {{{1 -function! s:TreeFileNode.openInNewTab(options) - echomsg 'TreeFileNode.openInNewTab is deprecated' - call self.open(extend({'where': 't'}, a:options)) -endfunction - -"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{1 -"Places the cursor on the line number this node is rendered on -" -"Args: -"isJump: 1 if this cursor movement should be counted as a jump by vim -"recurseUpward: try to put the cursor on the parent if the this node isnt -"visible -function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) - let ln = self.getLineNum() - if ln != -1 - if a:isJump - mark ' - endif - call cursor(ln, col(".")) - else - if a:recurseUpward - let node = self - while node != {} && node.getLineNum() ==# -1 - let node = node.parent - call node.open() - endwhile - call nerdtree#renderView() - call node.putCursorHere(a:isJump, 0) - endif - endif -endfunction - -"FUNCTION: TreeFileNode.refresh() {{{1 -function! s:TreeFileNode.refresh() - call self.path.refresh() -endfunction - -"FUNCTION: TreeFileNode.rename() {{{1 -"Calls the rename method for this nodes path obj -function! s:TreeFileNode.rename(newName) - let newName = substitute(a:newName, '\(\\\|\/\)$', '', '') - call self.path.rename(newName) - call self.parent.removeChild(self) - - let parentPath = self.path.getParent() - let newParent = b:NERDTreeRoot.findNode(parentPath) - - if newParent != {} - call newParent.createChild(self.path, 1) - call newParent.refresh() - endif -endfunction - -"FUNCTION: TreeFileNode.renderToString {{{1 -"returns a string representation for this tree to be rendered in the view -function! s:TreeFileNode.renderToString() - return self._renderToString(0, 0, [], self.getChildCount() ==# 1) -endfunction - -"Args: -"depth: the current depth in the tree for this call -"drawText: 1 if we should actually draw the line for this node (if 0 then the -"child nodes are rendered only) -"vertMap: a binary array that indicates whether a vertical bar should be draw -"for each depth in the tree -"isLastChild:true if this curNode is the last child of its parent -function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild) - let output = "" - if a:drawText ==# 1 - - let treeParts = '' - - "get all the leading spaces and vertical tree parts for this line - if a:depth > 1 - for j in a:vertMap[0:-2] - if g:NERDTreeDirArrows - let treeParts = treeParts . ' ' - else - if j ==# 1 - let treeParts = treeParts . '| ' - else - let treeParts = treeParts . ' ' - endif - endif - endfor - endif - - "get the last vertical tree part for this line which will be different - "if this node is the last child of its parent - if !g:NERDTreeDirArrows - if a:isLastChild - let treeParts = treeParts . '`' - else - let treeParts = treeParts . '|' - endif - endif - - "smack the appropriate dir/file symbol on the line before the file/dir - "name itself - if self.path.isDirectory - if self.isOpen - if g:NERDTreeDirArrows - let treeParts = treeParts . '▾ ' - else - let treeParts = treeParts . '~' - endif - else - if g:NERDTreeDirArrows - let treeParts = treeParts . '▸ ' - else - let treeParts = treeParts . '+' - endif - endif - else - if g:NERDTreeDirArrows - let treeParts = treeParts . ' ' - else - let treeParts = treeParts . '-' - endif - endif - let line = treeParts . self.displayString() - - let output = output . line . "\n" - endif - - "if the node is an open dir, draw its children - if self.path.isDirectory ==# 1 && self.isOpen ==# 1 - - let childNodesToDraw = self.getVisibleChildren() - if len(childNodesToDraw) > 0 - - "draw all the nodes children except the last - let lastIndx = len(childNodesToDraw)-1 - if lastIndx > 0 - for i in childNodesToDraw[0:lastIndx-1] - let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0) - endfor - endif - - "draw the last child, indicating that it IS the last - let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1) - endif - endif - - return output -endfunction - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/common/.vim/bundle/nerdtree/syntax/nerdtree.vim b/common/.vim/bundle/nerdtree/syntax/nerdtree.vim deleted file mode 100644 index 636d2af..0000000 --- a/common/.vim/bundle/nerdtree/syntax/nerdtree.vim +++ /dev/null @@ -1,88 +0,0 @@ -let s:tree_up_dir_line = '.. (up a dir)' -"NERDTreeFlags are syntax items that should be invisible, but give clues as to -"how things should be highlighted -syn match NERDTreeFlag #\~# -syn match NERDTreeFlag #\[RO\]# - -"highlighting for the .. (up dir) line at the top of the tree -execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" - -"highlighting for the ~/+ symbols for the directory nodes -syn match NERDTreeClosable #\~\<# -syn match NERDTreeClosable #\~\.# -syn match NERDTreeOpenable #+\<# -syn match NERDTreeOpenable #+\.#he=e-1 - -"highlighting for the tree structural parts -syn match NERDTreePart #|# -syn match NERDTreePart #`# -syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart - -"quickhelp syntax elements -syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 -syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 -syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag -syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey -syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey -syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 -syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand - -"highlighting for readonly files -syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile - -"highlighting for sym links -syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash - -"highlighing for directory nodes and file nodes -syn match NERDTreeDirSlash #/# -syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable -syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark -syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile -syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile -syn match NERDTreeCWD #^[# -syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader -syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader -syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader - -if exists("g:NERDChristmasTree") && g:NERDChristmasTree - hi def link NERDTreePart Special - hi def link NERDTreePartFile Type - hi def link NERDTreeFile Normal - hi def link NERDTreeExecFile Title - hi def link NERDTreeDirSlash Identifier - hi def link NERDTreeClosable Type -else - hi def link NERDTreePart Normal - hi def link NERDTreePartFile Normal - hi def link NERDTreeFile Normal - hi def link NERDTreeClosable Title -endif - -hi def link NERDTreeBookmarksHeader statement -hi def link NERDTreeBookmarksLeader ignore -hi def link NERDTreeBookmarkName Identifier -hi def link NERDTreeBookmark normal - -hi def link NERDTreeHelp String -hi def link NERDTreeHelpKey Identifier -hi def link NERDTreeHelpCommand Identifier -hi def link NERDTreeHelpTitle Macro -hi def link NERDTreeToggleOn Question -hi def link NERDTreeToggleOff WarningMsg - -hi def link NERDTreeDir Directory -hi def link NERDTreeUp Directory -hi def link NERDTreeCWD Statement -hi def link NERDTreeLink Macro -hi def link NERDTreeOpenable Title -hi def link NERDTreeFlag ignore -hi def link NERDTreeRO WarningMsg -hi def link NERDTreeBookmark Statement - -hi def link NERDTreeCurrentNode Search diff --git a/common/.vim/closetag.vim b/common/.vim/closetag.vim deleted file mode 100644 index 6ce41fb..0000000 --- a/common/.vim/closetag.vim +++ /dev/null @@ -1,327 +0,0 @@ -" File: closetag.vim -" Summary: Functions and mappings to close open HTML/XML tags -" Uses: -- close matching open tag -" Author: Steven Mueller -" Last Modified: Tue May 24 13:29:48 PDT 2005 -" Version: 0.9.1 -" XXX - breaks if close attempted while XIM is in preedit mode -" TODO - allow usability as a global plugin - -" Add g:unaryTagsStack - always contains html tags settings -" and g:closetag_default_xml - user should define this to default to xml -" When a close is attempted but b:unaryTagsStack undefined, -" use b:closetag_html_style to determine if the file is to be treated -" as html or xml. Failing that, check the filetype for xml or html. -" Finally, default to g:closetag_html_style. -" If the file is html, let b:unaryTagsStack=g:unaryTagsStack -" otherwise, let b:unaryTagsStack="" -" TODO - make matching work for all comments -" -- kinda works now, but needs syn sync minlines to be very long -" -- Only check whether in syntax in the beginning, then store comment tags -" in the tagstacks to determine whether to move into or out of comment mode -" TODO - The new normal mode mapping clears recent messages with its , and -" it doesn't fix the null-undo issue for vim 5.7 anyway. -" TODO - make use of the following neat features: -" -- the ternary ?: operator -" -- :echomsg and :echoerr -" -- curly brace expansion for variables and function name definitions? -" -- check up on map \FuncName -" -" Description: -" This script eases redundant typing when writing html or xml files (even if -" you're very good with ctrl-p and ctrl-n :). Hitting ctrl-_ will initiate a -" search for the most recent open tag above that is not closed in the -" intervening space and then insert the matching close tag at the cursor. In -" normal mode, the close tag is inserted one character after cursor rather than -" at it, as if a had been used. This allows putting close tags at the -" ends of lines while in normal mode, but disallows inserting them in the -" first column. -" -" For HTML, a configurable list of tags are ignored in the matching process. -" By default, the following tags will not be matched and thus not closed -" automatically: area, base, br, dd, dt, hr, img, input, link, meta, and -" param. -" -" For XML, all tags must have a closing match or be terminated by />, as in -" . These empty element tags are ignored for matching. -" -" Comment checking is now handled by vim's internal syntax checking. If tag -" closing is initiated outside a comment, only tags outside of comments will -" be matched. When closing tags in comments, only tags within comments will -" be matched, skipping any non-commented out code (wee!). However, the -" process of determining the syntax ID of an arbitrary position can still be -" erroneous if a comment is not detected because the syntax highlighting is -" out of sync, or really slow if syn sync minlines is large. -" Set the b:closetag_disable_synID variable to disable this feature if you -" have really big chunks of comment in your code and closing tags is too slow. -" -" If syntax highlighting is not enabled, comments will not be handled very -" well. Commenting out HTML in certain ways may cause a "tag mismatch" -" message and no completion. For example, '' -" between the cursor and the most recent unclosed open tag above causes -" trouble. Properly matched well formed tags in comments don't cause a -" problem. -" -" Install: -" To use, place this file in your standard vim scripts directory, and source -" it while editing the file you wish to close tags in. If the filetype is not -" set or the file is some sort of template with embedded HTML, you may force -" HTML style tag matching by first defining the b:closetag_html_style buffer -" variable. Otherwise, the default is XML style tag matching. -" -" Example: -" :let b:closetag_html_style=1 -" :source ~/.vim/scripts/closetag.vim -" -" For greater convenience, load this script in an autocommand: -" :au Filetype html,xml,xsl source ~/.vim/scripts/closetag.vim -" -" Also, set noignorecase for html files or edit b:unaryTagsStack to match your -" capitalization style. You may set this variable before or after loading the -" script, or simply change the file itself. -" -" Configuration Variables: -" -" b:unaryTagsStack Buffer local string containing a whitespace -" seperated list of element names that should be -" ignored while finding matching closetags. Checking -" is done according to the current setting of the -" ignorecase option. -" -" b:closetag_html_style Define this (as with let b:closetag_html_style=1) -" and source the script again to set the -" unaryTagsStack to its default value for html. -" -" b:closetag_disable_synID Define this to disable comment checking if tag -" closing is too slow. This can be set or unset -" without having to source again. -" -" Changelog: -" May 24, 2005 Tuesday -" * Changed function names to be script-local to avoid conflicts with other -" scripts' stack implementations. -" -" June 07, 2001 Thursday -" * Added comment handling. Currently relies on synID, so if syn sync -" minlines is small, the chance for failure is high, but if minlines is -" large, tagclosing becomes rather slow... -" -" * Changed normal mode closetag mapping to use in insert mode -" rather than p in normal mode. This has 2 implications: -" - Tag closing no longer clobbers the unnamed register -" - When tag closing fails or finds no match, no longer adds to the undo -" buffer for recent vim 6.0 development versions. -" - However, clears the last message when closing tags in normal mode -" -" * Changed the closetag_html_style variable to be buffer-local rather than -" global. -" -" * Expanded documentation - -"------------------------------------------------------------------------------ -" User configurable settings -"------------------------------------------------------------------------------ - -" if html, don't close certain tags. Works best if ignorecase is set. -" otherwise, capitalize these elements according to your html editing style -if !exists("b:unaryTagsStack") || exists("b:closetag_html_style") - if &filetype == "html" || exists("b:closetag_html_style") - let b:unaryTagsStack="area base br dd dt hr img input link meta param" - else " for xsl and xsl - let b:unaryTagsStack="" - endif -endif - -" Has this already been loaded? -if exists("loaded_closetag") - finish -endif -let loaded_closetag=1 - -" set up mappings for tag closing -inoremap =GetCloseTag() -map a - -"------------------------------------------------------------------------------ -" Tag closer - uses the stringstack implementation below -"------------------------------------------------------------------------------ - -" Returns the most recent unclosed tag-name -" (ignores tags in the variable referenced by a:unaryTagsStack) -function! GetLastOpenTag(unaryTagsStack) - " Search backwards through the file line by line using getline() - " Overall strategy (moving backwards through the file from the cursor): - " Push closing tags onto a stack. - " On an opening tag, if the tag matches the stack top, discard both. - " -- if the tag doesn't match, signal an error. - " -- if the stack is empty, use this tag - let linenum=line(".") - let lineend=col(".") - 1 " start: cursor position - let first=1 " flag for first line searched - let b:TagStack="" " main stack of tags - let startInComment=s:InComment() - - let tagpat='' - " Search for: closing tags - while (linenum>0) - " Every time we see an end-tag, we push it on the stack. When we see an - " open tag, if the stack isn't empty, we pop it and see if they match. - " If no, signal an error. - " If yes, continue searching backwards. - " If stack is empty, return this open tag as the one that needs closing. - let line=getline(linenum) - if first - let line=strpart(line,0,lineend) - else - let lineend=strlen(line) - endif - let b:lineTagStack="" - let mpos=0 - let b:TagCol=0 - " Search the current line in the forward direction, pushing any tags - " onto a special stack for the current line - while (mpos > -1) - let mpos=matchend(line,tagpat) - if mpos > -1 - let b:TagCol=b:TagCol+mpos - let tag=matchstr(line,tagpat) - - if exists("b:closetag_disable_synID") || startInComment==s:InCommentAt(linenum, b:TagCol) - let b:TagLine=linenum - call s:Push(matchstr(tag,'[^<>]\+'),"b:lineTagStack") - endif - "echo "Tag: ".tag." ending at position ".mpos." in '".line."'." - let lineend=lineend-mpos - let line=strpart(line,mpos,lineend) - endif - endwhile - " Process the current line stack - while (!s:EmptystackP("b:lineTagStack")) - let tag=s:Pop("b:lineTagStack") - if match(tag, "^/") == 0 "found end tag - call s:Push(tag,"b:TagStack") - "echo linenum." ".b:TagStack - elseif s:EmptystackP("b:TagStack") && !s:Instack(tag, a:unaryTagsStack) "found unclosed tag - return tag - else - let endtag=s:Peekstack("b:TagStack") - if endtag == "/".tag || endtag == "/" - call s:Pop("b:TagStack") "found a open/close tag pair - "echo linenum." ".b:TagStack - elseif !s:Instack(tag, a:unaryTagsStack) "we have a mismatch error - echohl Error - echon "\rError:" - echohl None - echo " tag mismatch: <".tag."> doesn't match <".endtag.">. (Line ".linenum." Tagstack: ".b:TagStack.")" - return "" - endif - endif - endwhile - let linenum=linenum-1 | let first=0 - endwhile - " At this point, we have exhausted the file and not found any opening tag - echo "No opening tags." - return "" -endfunction - -" Returns closing tag for most recent unclosed tag, respecting the -" current setting of b:unaryTagsStack for tags that should not be closed -function! GetCloseTag() - let tag=GetLastOpenTag("b:unaryTagsStack") - if tag == "" - return "" - else - return "" - endif -endfunction - -" return 1 if the cursor is in a syntactically identified comment field -" (fails for empty lines: always returns not-in-comment) -function! s:InComment() - return synIDattr(synID(line("."), col("."), 0), "name") =~ 'Comment' -endfunction - -" return 1 if the position specified is in a syntactically identified comment field -function! s:InCommentAt(line, col) - return synIDattr(synID(a:line, a:col, 0), "name") =~ 'Comment' -endfunction - -"------------------------------------------------------------------------------ -" String Stacks -"------------------------------------------------------------------------------ -" These are strings of whitespace-separated elements, matched using the \< and -" \> patterns after setting the iskeyword option. -" -" The sname argument should contain a symbolic reference to the stack variable -" on which method should operate on (i.e., sname should be a string containing -" a fully qualified (ie: g:, b:, etc) variable name.) - -" Helper functions -function! s:SetKeywords() - let g:IsKeywordBak=&iskeyword - let &iskeyword="33-255" -endfunction - -function! s:RestoreKeywords() - let &iskeyword=g:IsKeywordBak -endfunction - -" Push el onto the stack referenced by sname -function! s:Push(el, sname) - if !s:EmptystackP(a:sname) - exe "let ".a:sname."=a:el.' '.".a:sname - else - exe "let ".a:sname."=a:el" - endif -endfunction - -" Check whether the stack is empty -function! s:EmptystackP(sname) - exe "let stack=".a:sname - if match(stack,"^ *$") == 0 - return 1 - else - return 0 - endif -endfunction - -" Return 1 if el is in stack sname, else 0. -function! s:Instack(el, sname) - exe "let stack=".a:sname - call s:SetKeywords() - let m=match(stack, "\\<".a:el."\\>") - call s:RestoreKeywords() - if m < 0 - return 0 - else - return 1 - endif -endfunction - -" Return the first element in the stack -function! s:Peekstack(sname) - call s:SetKeywords() - exe "let stack=".a:sname - let top=matchstr(stack, "\\<.\\{-1,}\\>") - call s:RestoreKeywords() - return top -endfunction - -" Remove and return the first element in the stack -function! s:Pop(sname) - if s:EmptystackP(a:sname) - echo "Error! Stack ".a:sname." is empty and can't be popped." - return "" - endif - exe "let stack=".a:sname - " Find the first space, loc is 0-based. Marks the end of 1st elt in stack. - call s:SetKeywords() - let loc=matchend(stack,"\\<.\\{-1,}\\>") - exe "let ".a:sname."=strpart(stack, loc+1, strlen(stack))" - let top=strpart(stack, match(stack, "\\<"), loc) - call s:RestoreKeywords() - return top -endfunction - -function! s:Clearstack(sname) - exe "let ".a:sname."=''" -endfunction diff --git a/common/.vimrc b/common/.vimrc index 7e42ba9..b2562d4 100644 --- a/common/.vimrc +++ b/common/.vimrc @@ -27,6 +27,8 @@ set encoding=utf-8 set nocompatible " désactivation de la compatibilité avec vi +set shortmess+=filmnrxoOtT " retire le hit + colorscheme distinguished " couleur set background=dark " fond noir par défaut "hi CursorLine guibg=#606060 " couleur de la ligne de curseur @@ -78,6 +80,12 @@ set foldcolumn=6 " colonne de replis(fold colding) set viminfo='10,\"100,:20,%,n~/.viminfo au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif +"""""""""""""""""""""""""""""""""""""""""""""""""" +"Appel des bundles avec pathogen +"""""""""""""""""""""""""""""""""""""""""""""""""" +runtime! autoload/pathogen.vim +silent! call pathogen#helptags() +silent! call pathogen#runtime_append_all_bundles() """""""""""""""""""""""""""""""""""""""""""""""""" @@ -106,18 +114,18 @@ imap :set noexpandtab "Sauvegarde automatique des vues, utiles pour les "replis manuels """""""""""""""""""""""""""""""""""""""""""""""""" -au BufWinLeave *.html mkview -au BufWinEnter *.html silent loadview -au BufWinLeave *.css mkview -au BufWinEnter *.css silent loadview -au BufWinLeave *.php mkview -au BufWinEnter *.php silent loadview -au BufWinLeave *.js mkview -au BufWinEnter *.js silent loadview -au BufWinLeave *.py mkview -au BufWinEnter *.py silent loadview -au BufWinLeave *.java mkview -au BufWinEnter *.java silent loadview +"au BufWinLeave *.html mkview +"au BufWinEnter *.html silent loadview +"au BufWinLeave *.css mkview +"au BufWinEnter *.css silent loadview +"au BufWinLeave *.php mkview +"au BufWinEnter *.php silent loadview +"au BufWinLeave *.js mkview +"au BufWinEnter *.js silent loadview +"au BufWinLeave *.py mkview +"au BufWinEnter *.py silent loadview +"au BufWinLeave *.java mkview +"au BufWinEnter *.java silent loadview """""""""""""""""""""""""""""""""""""""""""""""" "Options du fichier de syntaxe python @@ -209,3 +217,5 @@ if ! has('gui_running') au InsertLeave * set timeoutlen=1000 augroup END endif + +let g:jedi#autocompletion_command = "" diff --git a/common/.zshrc b/common/.zshrc index 1e6d472..38eb87d 100644 --- a/common/.zshrc +++ b/common/.zshrc @@ -100,4 +100,3 @@ hisoka() { ssc hisoka.kujiu.org ${argv[-1]:-`whoami`} 22 $argv[1,-2]; hl() { highlight --out-format=xterm256 -l ${argv} | less -R; } bindkey "^[[A" history-search-backward bindkey "^[[B" history-search-forward - diff --git a/update-home.sh b/update-home.sh index 5a788de..27e0368 100755 --- a/update-home.sh +++ b/update-home.sh @@ -1,13 +1,75 @@ #!/usr/bin/env bash +# Remove zsh completion dump +rm ~/.zcompdump + +# Remove vim config directory +rm -rf ~/.vim-backup +mv ~/.vim ~/.vim-backup +mkdir -p ~/.vim/{autoload,bundle,colors,doc,ftplugin,plugin,spell,syntax} + +# Install oh-my-zsh rm -rf ~/.oh-my-zsh git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh +# Copy the graphical part if needed if [ "$1" == '--graphic' ] then rsync -av graphic/ ~/ fc-cache -vf ~/.fonts fi +# Copy the common part rsync -av common/ ~/ + +# Adjust the tmux conf sed -i "s/REPLACEMEWITHFIRSTLETTEROFHOSTNAME/`expr substr \`hostname\` 1 1`/g" ~/.tmux.conf + +######### VIM Config ########### + +# Install pathogen + +curl -Sso ~/.vim/autoload/pathogen.vim https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim + +# Install jedi plugin for vim +rm -rf ~/.vim/bundle/jedi +git clone https://github.com/davidhalter/jedi-vim.git ~/.vim/bundle/jedi + +# Install nerdtree for vim +rm -rf ~/.vim/bundle/nerdtree +git clone https://github.com/scrooloose/nerdtree.git ~/.vim/bundle/nerdtree + +# Install xmledit for vim +rm -rf ~/.vim/bundle/xmledit +git clone https://github.com/sukima/xmledit.git ~/.vim/bundle/xmledit +pushd ~/.vim/bundle/xmledit +make install +popd + +# Install pyflakes plugin +rm -rf ~/.vim/bundle/pyflakes +git clone --recursive git://github.com/kevinw/pyflakes-vim.git ~/.vim/bundle/pyflakes + +# Install autoclose plugin +rm -rf ~/.vim/bundle/autoclose +git clone https://github.com/Townk/vim-autoclose.git ~/.vim/bundle/autoclose + +# Install tagbar plugin +rm -rf ~/.vim/bundle/tagbar +git clone https://github.com/majutsushi/tagbar ~/.vim/bundle/tagbar + +# Install vcscommand plugin +rm -rf ~/.vim/bundle/vcscommand +git clone https://github.com/vim-scripts/vcscommand.vim.git ~/.vim/bundle/vcscommand + +# Install easytag plugin +rm -rf ~/.vim/bundle/easytag +git clone https://github.com/vim-scripts/easytags.vim.git ~/.vim/bundle/easytag + +# Install closetag plugin +rm -rf ~/.vim/bundle/closetag +git clone https://github.com/vim-scripts/closetag.vim.git ~/.vim/bundle/closetag + +# Install css3 syntax +rm -rf ~/.vim/bundle/css3-mod +git clone https://github.com/vim-scripts/css3-mod.git ~/.vim/bundle/css3-mod