dotfiles

Unnamed repository; edit this file 'description' to name the repository.
git clone git://edryd.org/dotfiles
Log | Files | Refs

commit fb0b4c0725e3ca220a210081b16d3d335bc94285
parent 512a4f0ee2e8e8818c23abcf5fb7d2e89648f860
Author: edvb54 <edvb54@gmail.com>
Date:   Mon, 26 May 2014 10:29:20 -0700

Remove JavaRun and add Eclim

Diffstat:
bash_profile | 1-
vim/bundle/JavaRun | 1-
vim/bundle/vundle | 1-
vim/eclim/autoload/eclim.vim | 339+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/android.vim | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/android/project.vim | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/c/complete.vim | 49+++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/c/project.vim | 331+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/c/search.vim | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/client/nailgun.vim | 193+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/client/python/nailgun.py | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/client/python/nailgun.vim | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/buffers.vim | 400+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/history.vim | 332+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/largefile.vim | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/license.vim | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/locate.vim | 655+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/template.vim | 237+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/common/util.vim | 195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/css/complete.vim | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/css/validate.vim | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/cygwin.vim | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/display/menu.vim | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/display/signs.vim | 388+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/display/window.vim | 352+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/help.vim | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/html/complete.vim | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/html/util.vim | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/html/validate.vim | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/ant/complete.vim | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/ant/doc.vim | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/ant/ivy.vim | 31+++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/ant/util.vim | 36++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/classpath.vim | 241+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/complete.vim | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/correct.vim | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/doc.vim | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/hierarchy.vim | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/impl.vim | 341+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/import.vim | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/junit.vim | 247+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/logging.vim | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/maven.vim | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/refactor.vim | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/search.vim | 409+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/src.vim | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/tools.vim | 310+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/java/util.vim | 355+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/javascript/complete.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/javascript/util.vim | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/lang.vim | 649+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/lang/hierarchy.vim | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/project/problems.vim | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/project/tree.vim | 522+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/project/util.vim | 1461+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/complete.vim | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/django/find.vim | 253+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/django/manage.vim | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/django/template.vim | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/django/util.vim | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/import.vim | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/jinja.vim | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope.vim | 376+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/__init__.py | 17+++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/__init__.py | 8++++++++
vim/eclim/autoload/eclim/python/rope/base/arguments.py | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/ast.py | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/astutils.py | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/builtins.py | 728+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/change.py | 448+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/codeanalyze.py | 358+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/default_config.py | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/evaluate.py | 317+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/exceptions.py | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/fscommands.py | 267+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/history.py | 235+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/libutils.py | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/__init__.py | 38++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/doa.py | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/memorydb.py | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/objectdb.py | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/objectinfo.py | 232+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/runmod.py | 210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/soa.py | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/soi.py | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/oi/transform.py | 285+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/prefs.py | 41+++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/project.py | 428+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pycore.py | 407+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pynames.py | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pynamesdef.py | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pyobjects.py | 311+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pyobjectsdef.py | 535+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/pyscopes.py | 313+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/resourceobserver.py | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/resources.py | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/simplify.py | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/stdmods.py | 40++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/taskhandle.py | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/utils.py | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/base/worder.py | 509+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/__init__.py | 7+++++++
vim/eclim/autoload/eclim/python/rope/contrib/autoimport.py | 217+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/changestack.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/codeassist.py | 646+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/finderrors.py | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/findit.py | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/fixmodnames.py | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/fixsyntax.py | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/contrib/generate.py | 355+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/__init__.py | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/change_signature.py | 342+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/encapsulate_field.py | 202+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/extract.py | 789+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/functionutils.py | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/importutils/__init__.py | 299+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/importutils/actions.py | 359+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/importutils/importinfo.py | 201+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/importutils/module_imports.py | 454+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/inline.py | 553+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/introduce_factory.py | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/introduce_parameter.py | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/localtofield.py | 50++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/method_object.py | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/move.py | 625+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/multiproject.py | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/occurrences.py | 334+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/patchedast.py | 732+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/rename.py | 216+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/restructure.py | 307+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/similarfinder.py | 362+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/sourceutils.py | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/suites.py | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/topackage.py | 32++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/usefunction.py | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/rope/refactor/wildcards.py | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/search.vim | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/python/validate.vim | 242+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/commonsvalidator.vim | 33+++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/cproject.vim | 40++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/eclimhelp.vim | 32++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/forrest.vim | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/gant.vim | 33+++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/hibernate.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/junit.vim | 33+++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/spring.vim | 33+++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/webxml.vim | 43+++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/taglisttoo/lang/wsdl.vim | 48++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/tree.vim | 1210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/util.vim | 1574+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/vimplugin.vim | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/web.vim | 232+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/xml/complete.vim | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/xml/definition.vim | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/xml/format.vim | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/xml/util.vim | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/autoload/eclim/xml/validate.vim | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/bin/bash_complete | 21+++++++++++++++++++++
vim/eclim/compiler/eclim_ant.vim | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/compiler/eclim_javadoc.vim | 44++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/compiler/eclim_make.vim | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/compiler/eclim_maven.vim | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/compiler/eclim_mvn.vim | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/compiler/eclim_xmllint.vim | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/dict/java | 32++++++++++++++++++++++++++++++++
vim/eclim/doc/404.txt | 12++++++++++++
vim/eclim/doc/archive/changes.txt | 1228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/archive/news.txt | 465+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/changes.txt | 497+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/cheatsheet.txt | 334+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/contribute.txt | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/development/architecture.txt | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/development/commands.txt | 243+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/development/gettingstarted.txt | 269+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/development/index.txt | 22++++++++++++++++++++++
vim/eclim/doc/development/plugins.txt | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/eclimd.txt | 435+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/faq.txt | 357+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/features.txt | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/gettinghelp.txt | 50++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/gettingstarted.txt | 325+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/index.txt | 319+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/install.txt | 608+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/relatedprojects.txt | 23+++++++++++++++++++++++
vim/eclim/doc/vim/c/complete.txt | 25+++++++++++++++++++++++++
vim/eclim/doc/vim/c/index.txt | 31+++++++++++++++++++++++++++++++
vim/eclim/doc/vim/c/inspection.txt | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/c/project.txt | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/c/search.txt | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/c/validate.txt | 36++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/code_completion.txt | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/core/eclim.txt | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/core/history.txt | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/core/index.txt | 13+++++++++++++
vim/eclim/doc/vim/core/locate.txt | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/core/project.txt | 453+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/core/util.txt | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/dltk/buildpath.txt | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/html/index.txt | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/index.txt | 32++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/android.txt | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/ant.txt | 219+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/classpath.txt | 362+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/complete.txt | 36++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/format.txt | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/import.txt | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/index.txt | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/inspection.txt | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/java.txt | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/javadoc.txt | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/logging.txt | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/maven.txt | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/methods.txt | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/refactor.txt | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/search.txt | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/unittests.txt | 234+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/validate.txt | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/java/webxml.txt | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/javascript/index.txt | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/php/buildpath.txt | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/php/complete.txt | 28++++++++++++++++++++++++++++
vim/eclim/doc/vim/php/index.txt | 30++++++++++++++++++++++++++++++
vim/eclim/doc/vim/php/search.txt | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/php/validate.txt | 45+++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/python/complete.txt | 22++++++++++++++++++++++
vim/eclim/doc/vim/python/django.txt | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/python/index.txt | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/python/search.txt | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/python/validate.txt | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/refactoring.txt | 43+++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/ruby/buildpath.txt | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/ruby/complete.txt | 26++++++++++++++++++++++++++
vim/eclim/doc/vim/ruby/index.txt | 12++++++++++++
vim/eclim/doc/vim/ruby/search.txt | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/ruby/validate.txt | 36++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/scala/complete.txt | 23+++++++++++++++++++++++
vim/eclim/doc/vim/scala/import.txt | 36++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/scala/index.txt | 12++++++++++++
vim/eclim/doc/vim/scala/search.txt | 40++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/scala/validate.txt | 36++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/settings.txt | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/doc/vim/xml/index.txt | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/ant.vim | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/c.vim | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/commonsvalidator.vim | 35+++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/cpp.vim | 24++++++++++++++++++++++++
vim/eclim/ftplugin/css.vim | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/dtd.vim | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/eclimhelp.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/eclipse_classpath.vim | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/eclipse_cproject.vim | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/forrestdocument.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/forreststatus.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/gant.vim | 35+++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/hibernate.vim | 44++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/html.vim | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/htmldjango.vim | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/htmljinja.vim | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/ivy.vim | 48++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/java-xml.vim | 40++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/java.vim | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/javascript.vim | 49+++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/junitresult.vim | 35+++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/log4j.vim | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/make.vim | 32++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/mvn_pom.vim | 48++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/python.vim | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/spring.vim | 36++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/strutsconfig.vim | 28++++++++++++++++++++++++++++
vim/eclim/ftplugin/tld.vim | 36++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/webxml.vim | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/wsdl.vim | 37+++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/xml.vim | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/ftplugin/xml_complete.vim | 30++++++++++++++++++++++++++++++
vim/eclim/ftplugin/xsd.vim | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/css.vim | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/dtd.vim | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/html.vim | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/htmldjango.vim | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/htmljinja.vim | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/indentanything.vim | 683+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/javascript.vim | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/indent/xml.vim | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/android.vim | 28++++++++++++++++++++++++++++
vim/eclim/plugin/cproject.vim | 31+++++++++++++++++++++++++++++++
vim/eclim/plugin/django.vim | 32++++++++++++++++++++++++++++++++
vim/eclim/plugin/eclim.vim | 330+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/ftdetect.vim | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/ftdetect_adt.vim | 27+++++++++++++++++++++++++++
vim/eclim/plugin/ftdetect_cdt.vim | 28++++++++++++++++++++++++++++
vim/eclim/plugin/ftdetect_jdt.vim | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/java_tools.vim | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/project.vim | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/plugin/vimplugin.vim | 38++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/ant.vim | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/commonsvalidator.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/css.vim | 47+++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/eclimhelp.vim | 29+++++++++++++++++++++++++++++
vim/eclim/syntax/eclipse_classpath.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/eclipse_cproject.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/forrestdocument.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/forreststatus.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/gant.vim | 33+++++++++++++++++++++++++++++++++
vim/eclim/syntax/groovy_simple_template.vim | 31+++++++++++++++++++++++++++++++
vim/eclim/syntax/hg.vim | 48++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/hibernate.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/html.vim | 39+++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/htmldjango.vim | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/ivy.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/java.vim | 36++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/junitresult.vim | 25+++++++++++++++++++++++++
vim/eclim/syntax/log4j.vim | 49+++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/mvn_pom.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/mysql.vim | 45+++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/perl.vim | 38++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/spring.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/sql.vim | 50++++++++++++++++++++++++++++++++++++++++++++++++++
vim/eclim/syntax/strutsconfig.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/tld.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/webxml.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/wsdl.vim | 27+++++++++++++++++++++++++++
vim/eclim/syntax/xml.vim | 43+++++++++++++++++++++++++++++++++++++++++++
vim/plugin/eclim.vim | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vimrc | 5++++-
vimrc.bundles | 4+---
325 files changed, 51636 insertions(+), 7 deletions(-)

diff --git a/bash_profile b/bash_profile @@ -28,7 +28,6 @@ ${Cyan}❯${Color_Off}❯ " PS2=' ${ICyan}❯${Color_Off} ' # basic{{{1 -set -o vi bind -m vi-insert '"jj": vi-movement-mode' export EDITOR='vim' diff --git a/vim/bundle/JavaRun b/vim/bundle/JavaRun @@ -1 +0,0 @@ -Subproject commit 1d2bd59638fff78c28c79d4bcf64dc3724a6c329 diff --git a/vim/bundle/vundle b/vim/bundle/vundle @@ -1 +0,0 @@ -Subproject commit 8db3bcb5921103f0eb6de361c8b25cc03cb350b5 diff --git a/vim/eclim/autoload/eclim.vim b/vim/eclim/autoload/eclim.vim @@ -0,0 +1,339 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Plugin that integrates vim with the eclipse plugin eclim (ECLipse +" IMproved). +" +" This plugin contains shared functions that can be used regardless of the +" current file type being edited. +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + if !exists("g:EclimShowErrors") + let g:EclimShowErrors = 1 + endif +" }}} + +" Script Variables {{{ + let s:command_ping = '-command ping' + let s:command_settings = '-command settings' + let s:command_settings_update = '-command settings_update -s "<settings>"' + let s:command_shutdown = "-command shutdown" + let s:connect= '^connect: .*$' +" }}} + +function! eclim#Execute(command, ...) " {{{ + " Optional args: + " options { + " One of the following to determine the eclimd instance to use, honored in + " the order shown here: + " instance: dictionary representing an eclimd instance. + " project: project name + " workspace: workspace path + " dir: directory path to use as the current dir + " exec: 1 to execute the command using execute instead of system. + " raw: 1 to get the result without evaluating as json + " } + + if exists('g:EclimDisabled') + return + endif + + if !eclim#EclimAvailable() + return + endif + + let command = '-editor vim ' . a:command + + " encode special characters + " http://www.w3schools.com/TAGS/ref_urlencode.asp + let command = substitute(command, '\*', '%2A', 'g') + let command = substitute(command, '\$', '%24', 'g') + let command = substitute(command, '<', '%3C', 'g') + let command = substitute(command, '>', '%3E', 'g') + + " determine the eclimd instance to use + let options = a:0 ? a:1 : {} + let instance = get(options, 'instance', {}) + if len(instance) == 0 + let workspace = '' + + let project = get(options, 'project', '') + if project != '' + let workspace = eclim#project#util#GetProjectWorkspace(project) + endif + if workspace == '' + let workspace = get(options, 'workspace', '') + endif + + let dir = workspace != '' ? workspace : get(options, 'dir', '') + let chosen = eclim#client#nailgun#ChooseEclimdInstance(dir) + if type(chosen) != g:DICT_TYPE + return + endif + let instance = chosen + endif + + let exec = get(options, 'exec', 0) + let [retcode, result] = eclim#client#nailgun#Execute(instance, command, exec) + let result = substitute(result, '\n$', '', '') + + " not sure this is the best place to handle this, but when using the python + " client, the result has a trailing ctrl-m on windows. also account for + " running under cygwin vim. + if has('win32') || has('win64') || has('win32unix') + let result = substitute(result, "\<c-m>$", '', '') + endif + + " an echo during startup causes an annoying issue with vim. + "call eclim#util#Echo(' ') + + " check for errors + let error = '' + if result =~ '^[^\n]*Exception:\?[^\n]*\n\s\+\<at\> ' || + \ result =~ '^[^\n]*ResourceException(.\{-})\[[0-9]\+\]:[^\n]*\n\s\+\<at\> ' + if g:EclimLogLevel < 10 + let error = substitute(result, '\(.\{-}\)\n.*', '\1', '') + else + let error = result + endif + elseif retcode + let error = result + endif + + if retcode || error != '' + if g:EclimShowErrors + if error =~ s:connect + " if we are not in an autocmd or the autocmd is for an acwrite buffer, + " alert the user that eclimd is not running. + if expand('<abuf>') == '' || &buftype == 'acwrite' + call eclim#util#EchoWarning( + \ "unable to connect to eclimd (port: " . instance.port . ") - " . error) + endif + else + let error = error . "\n" . + \ 'while executing command (port: ' . instance.port . '): ' . command + " if we are not in an autocmd or in a autocmd for an acwrite buffer, + " echo the error, otherwise just log it. + if expand('<abuf>') == '' || &buftype == 'acwrite' + call eclim#util#EchoError(error) + else + call eclim#util#EchoDebug(error) + endif + endif + endif + return + endif + + let raw = get(options, 'raw', 0) + return result != '' && !raw ? eval(result) : result +endfunction " }}} + +function! eclim#Disable() " {{{ + if !exists('g:EclimDisabled') + let g:EclimDisabled = 1 + endif +endfunction " }}} + +function! eclim#Enable() " {{{ + if exists('g:EclimDisabled') + unlet g:EclimDisabled + endif +endfunction " }}} + +function! eclim#EclimAvailable(...) " {{{ + " Optional args: + " echo: Whether or not to echo an error if eclim is not available + " (default: 1) + let instances = eclim#UserHome() . '/.eclim/.eclimd_instances' + let available = filereadable(instances) + let echo = a:0 ? a:1 : 1 + if echo && !available && expand('<abuf>') == '' + call eclim#util#EchoError(printf( + \ 'No eclimd instances found running (eclimd created file not found %s)', + \ eclim#UserHome() . '/.eclim/.eclimd_instances')) + endif + return available +endfunction " }}} + +function! eclim#PingEclim(echo, ...) " {{{ + " If echo is non 0, then the result is echoed to the user. + " Optional args: + " workspace + + let workspace = a:0 ? a:1 : '' + if a:echo + let result = eclim#Execute(s:command_ping, {'workspace': workspace}) + if type(result) == g:DICT_TYPE + call eclim#util#Echo( + \ 'eclim ' . result.eclim . "\n" . + \ 'eclipse ' . result.eclipse) + endif + else + let savedErr = g:EclimShowErrors + let savedLog = g:EclimLogLevel + let g:EclimShowErrors = 0 + let g:EclimLogLevel = 0 + + let result = eclim#Execute(s:command_ping, {'workspace': workspace}) + + let g:EclimShowErrors = savedErr + let g:EclimLogLevel = savedLog + + return type(result) == g:DICT_TYPE + endif +endfunction " }}} + +function! eclim#ParseSettingErrors(errors) " {{{ + let errors = [] + for error in a:errors + let message = error.message + let setting = substitute(message, '^\(.\{-}\): .*', '\1', '') + let message = substitute(message, '^.\{-}: \(.*\)', '\1', '') + if error.line == 1 && setting != error.message + let line = search('^\s*' . setting . '\s*=', 'cnw') + let error.line = line > 0 ? line : 1 + endif + call add(errors, { + \ 'bufnr': bufnr('%'), + \ 'lnum': error.line, + \ 'text': message, + \ 'type': error.warning == 1 ? 'w' : 'e', + \ }) + endfor + return errors +endfunction " }}} + +function! eclim#SaveSettings(command, project) " {{{ + " don't check modified since undo seems to not set the modified flag + "if &modified + let tempfile = substitute(tempname(), '\', '/', 'g') + + " get all lines, filtering out comments and blank lines + let lines = filter(getline(1, line('$')), 'v:val !~ "^\\s*\\(#\\|$\\)"') + + " convert lines into a settings dict + let index = 0 + let settings = {} + let pattern = '^\s*\([[:alnum:]_.-]\+\)\s*=\s*\(.*\)' + while index < len(lines) + if lines[index] =~ pattern + let name = substitute(lines[index], pattern, '\1', '') + let value = substitute(lines[index], pattern, '\2', '') + while value =~ '\\$' + let index += 1 + let value = substitute(value, '\\$', '', '') + let value .= substitute(lines[index], '^\s*', '', '') + endwhile + let settings[name] = value + endif + let index += 1 + endwhile + call writefile([string(settings)], tempfile) + + if has('win32unix') + let tempfile = eclim#cygwin#WindowsPath(tempfile) + endif + + let command = a:command + let command = substitute(command, '<project>', a:project, '') + let command = substitute(command, '<settings>', tempfile, '') + + if exists('b:eclimd_instance') + let result = eclim#Execute(command, {'instance': b:eclimd_instance}) + else + let result = eclim#Execute(command) + endif + + if type(result) == g:LIST_TYPE + call eclim#util#EchoError + \ ("Operation contained errors. See location list for details.") + let errors = eclim#ParseSettingErrors(result) + call eclim#util#SetLocationList(errors) + else + call eclim#util#ClearLocationList() + call eclim#util#Echo(result) + endif + + setlocal nomodified + "endif +endfunction " }}} + +function! eclim#Settings(workspace) " {{{ + let instance = eclim#client#nailgun#ChooseEclimdInstance(a:workspace) + if type(instance) != g:DICT_TYPE + return + endif + + let settings = eclim#Execute(s:command_settings, {'instance': instance}) + if type(settings) != g:LIST_TYPE + return + endif + + let content = ['# Global settings for workspace: ' . instance.workspace, ''] + let path = '' + for setting in settings + if setting.path != path + if path != '' + let content += ['# }', ''] + endif + let path = setting.path + call add(content, '# ' . path . ' {') + endif + let description = split(setting.description, '\n') + let content += map(description, "'\t# ' . v:val") + call add(content, "\t" . setting.name . '=' . setting.value) + endfor + if path != '' + call add(content, '# }') + endif + + call eclim#util#TempWindow("Eclim_Global_Settings", content) + setlocal buftype=acwrite + setlocal filetype=jproperties + setlocal noreadonly + setlocal modifiable + setlocal foldmethod=marker + setlocal foldmarker={,} + let b:eclimd_instance = instance + + augroup eclim_settings + autocmd! BufWriteCmd <buffer> + exec 'autocmd BufWriteCmd <buffer> ' . + \ 'call eclim#SaveSettings(s:command_settings_update, "")' + augroup END +endfunction " }}} + +function! eclim#ShutdownEclim() " {{{ + call eclim#Execute(s:command_shutdown) +endfunction " }}} + +function! eclim#UserHome() " {{{ + let home = expand('$HOME') + if has('win32unix') + let home = eclim#cygwin#WindowsHome() + elseif has('win32') || has('win64') + let home = expand('$USERPROFILE') + endif + return substitute(home, '\', '/', 'g') +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/android.vim b/vim/eclim/autoload/eclim/android.vim @@ -0,0 +1,39 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" +" Copyright (C) 2012 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:command_reload = '-command android_reload' +" }}} + +function! eclim#android#Reload() " {{{ + let result = eclim#Execute(s:command_reload) + if type(result) != g:DICT_TYPE + return + endif + + if has_key(result, 'error') + call eclim#util#EchoError(result.error) + else + call eclim#util#Echo(result.message) + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/android/project.vim b/vim/eclim/autoload/eclim/android/project.vim @@ -0,0 +1,170 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2012 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:command_list_targets = '-command android_list_targets' +" }}} + +function! eclim#android#project#ProjectCreatePre(folder) " {{{ + return s:InitAndroid(a:folder) +endfunction " }}} + +function! eclim#android#project#ProjectNatureAddPre(project) " {{{ + return s:InitAndroid(eclim#project#util#GetProjectRoot(a:project)) +endfunction " }}} + +function! eclim#android#project#GetTargets(folder) " {{{ + let results = eclim#Execute(s:command_list_targets, {'dir': a:folder}) + if type(results) != g:LIST_TYPE + if type(results) == g:STRING_TYPE + call eclim#util#EchoError(results) + endif + return + endif + return results +endfunction " }}} + +function! s:InitAndroid(folder) " {{{ + let args = '' + + let targets = eclim#android#project#GetTargets(a:folder) + if type(targets) != g:LIST_TYPE + return + endif + + if len(targets) == 0 + let message = "No android platform targets found." + let sdk = eclim#util#GetSetting('com.android.ide.eclipse.adt.sdk') + if type(sdk) == g:STRING_TYPE && sdk != '' + let sdk = substitute(sdk, '\\', '/', 'g') + if sdk !~ '[/\\]$' + let sdk .= '/' + endif + let managers = [ + \ sdk . 'SDK Manager.exe', + \ sdk . 'tools/android', + \ ] + let manager = '' + for path in managers + if filereadable(path) + let manager = path + break + endif + endfor + + if manager != '' + let message .= + \ "\nYou can use the SDK Manager to install target packages:" . + \ "\n " . manager . + \ "\nThen you can reload the android sdk by running the vim command:" . + \ "\n :AndroidReload" + endif + endif + call eclim#util#EchoError(message) + return 0 + endif + + if len(targets) == 1 + let target = targets[0].hash + else + let answer = eclim#util#PromptList( + \ "Please choose the target android platform for this project", + \ map(copy(targets), 'v:val.name')) + if answer == -1 + return 0 + endif + + let target = targets[answer].hash + redraw + endif + let args = '--target ' . target + + let manifest = a:folder . '/AndroidManifest.xml' + if !filereadable(manifest) + " choose a package name + let package = eclim#util#Prompt( + \ "Please specify a package name", + \ function('eclim#android#project#ValidatePackage')) + if package == '' + call eclim#util#EchoWarning('Project create canceled.') + return 0 + endif + let args .= ' --package ' . package + + " choose an app name + let name = eclim#util#Prompt("Please specify a name for this application") + if name == '' + call eclim#util#EchoWarning('Project create canceled.') + return 0 + endif + let args .= ' --application "' . escape(name, '"') . '"' + + " is this a library? + let library = eclim#util#PromptConfirm('Is this a library project?') + if library == -1 + call eclim#util#EchoWarning('Project create canceled.') + return 0 + endif + if library + let args .= ' --library' + else + " create an activity? + let create = eclim#util#PromptConfirm('Create an activity?') + if create == -1 + call eclim#util#EchoWarning('Project create canceled.') + return 0 + endif + if create + " choose an app name + redraw + let default = substitute(name, '\W', '', 'g') . 'Activity' + let activity = eclim#util#Prompt( + \ ["Please specify an activity name", default], + \ function('eclim#android#project#ValidateActivity')) + if activity == '' + call eclim#util#EchoWarning('Project create canceled.') + return 0 + endif + let args .= ' --activity ' . activity + endif + endif + endif + + return args +endfunction " }}} + +function! eclim#android#project#ValidateActivity(activity) " {{{ + if a:activity !~? '^[a-z]\w*$' + return "Activity name must be a valid java identifier." + endif + return 1 +endfunction " }}} + +function! eclim#android#project#ValidatePackage(package) " {{{ + if a:package !~? '^[a-z][a-z0-9_]*\(.[a-z][a-z0-9_]*\)*$' + return "Must be a valid package name with no trailing dots." + endif + return 1 +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/c/complete.vim b/vim/eclim/autoload/eclim/c/complete.vim @@ -0,0 +1,49 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/c/complete.html +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ + if !exists("g:EclimCCompleteLayout") + if &completeopt !~ 'preview' && &completeopt =~ 'menu' + let g:EclimCCompleteLayout = 'standard' + else + let g:EclimCCompleteLayout = 'compact' + endif + endif +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command c_complete -p "<project>" -f "<file>" ' . + \ '-o <offset> -e <encoding> -l <layout>' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles code completion. +function! eclim#c#complete#CodeComplete(findstart, base) + return eclim#lang#CodeComplete( + \ s:complete_command, a:findstart, a:base, + \ {'temp': 0, 'layout': g:EclimCCompleteLayout}) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/c/project.vim b/vim/eclim/autoload/eclim/c/project.vim @@ -0,0 +1,331 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/c/project.html +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:configs_command = '-command c_project_configs -p "<project>"' + let s:src_command = + \ '-command c_project_src -p "<project>" -a <action> -d "<dir>"' + let s:include_command = + \ '-command c_project_include -p "<project>" -a <action> -l <lang> -d "<dir>"' + let s:symbol_command = + \ '-command c_project_symbol -p "<project>" -a <action> -l <lang> -n "<name>"' +" }}} + +" Configs([project]) {{{ +" Open a buffer with current project configs info. +function! eclim#c#project#Configs(...) + if len(a:000) > 0 && a:000[0] != '' + let project = a:000[0] + else + let project = eclim#project#util#GetCurrentProjectName() + endif + + if project == '' + " force printing of project error message + call eclim#project#util#IsCurrentFileInProject() + return + endif + + let command = s:configs_command + let command = substitute(command, '<project>', project, '') + + let configs = eclim#Execute(command, {'project': project}) + if type(configs) != g:LIST_TYPE + return + endif + + let content = [] + for config in configs + call add(content, 'Config: ' . config.name) + call add(content, '') + + call add(content, "\tSources: |add|") + if has_key(config, 'sources') + for src in config.sources + call add(content, "\t\tdir: " . src.dir) + if has_key(src, 'excludes') + call add(content, "\t\t\texcludes: " . join(src.excludes, ',')) + endif + endfor + endif + call add(content, '') + + if has_key(config, 'tools') + for tool in config.tools + call add(content, "\tTool: " . tool.name) + call add(content, "\t\tIncludes: |add|") + if has_key(tool, 'includes') + for include in tool.includes + call add(content, "\t\t\tpath: " . include) + endfor + endif + call add(content, "\t\tSymbols: |add|") + if has_key(tool, 'symbols') + for symbol in tool.symbols + call add(content, "\t\t\tname/value: " . symbol) + endfor + endif + call add(content, '') + endfor + endif + endfor + + call eclim#util#TempWindow('[' . project . ' configs]', content) + let b:project = project + call s:Syntax() + + nnoremap <silent> <buffer> <cr> :call <SID>FollowLink()<cr> + nnoremap <silent> <buffer> D :call <SID>Delete()<cr> +endfunction " }}} + +" s:Syntax() {{{ +function! s:Syntax() + syntax match CProjectConfigLabel /^\s*[A-Z]\w\+:/ + syntax match CProjectConfigSubLabel /^\s*[a-z][a-z\/]\+:/ + syntax match CProjectConfigLink /|\S.\{-}\S|/ + hi link CProjectConfigLabel Statement + hi link CProjectConfigSubLabel Identifier + hi link CProjectConfigLink Label +endfunction " }}} + +" s:FollowLink() {{{ +function! s:FollowLink() + let line = getline('.') + let link = substitute( + \ getline('.'), '.*|\(.\{-}\%' . col('.') . 'c.\{-}\)|.*', '\1', '') + if link == line + return + endif + + if line =~ '^\s*Sources:' + call s:AddSource() + elseif line =~ '^\s*Includes:' + call s:AddInclude() + elseif line =~ '^\s*Symbols:' + call s:AddSymbol() + endif +endfunction " }}} + +" s:AddSource() {{{ +function! s:AddSource() + let project_root = eclim#project#util#GetProjectRoot(b:project) + let complete = 'customlist,eclim#project#util#CommandCompleteProjectRelative' + let dir = input('dir: ', '', complete) + while dir != '' && !isdirectory(project_root . '/' . dir) + call eclim#util#Echo('Directory "' . dir . '" not found in the project.') + let dir = input('dir: ', dir, complete) + endwhile + + if dir == '' + return + endif + + let excludes = input('excludes (comma separated patterns): ') + + let command = s:src_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'add', '') + let command = substitute(command, '<dir>', dir, '') + if excludes != '' + let command .= ' -e "' . excludes . '"' + endif + + let result = eclim#Execute(command) + if result != '0' + call eclim#c#project#Configs(b:project) + call eclim#util#Echo(result) + endif +endfunction " }}} + +" s:AddInclude() {{{ +function! s:AddInclude() + let project_root = eclim#project#util#GetProjectRoot(b:project) + let complete = 'customlist,eclim#project#util#CommandCompleteAbsoluteOrProjectRelativeDir' + let dir = input('dir: ', '', complete) + + if dir == '' + return + endif + + if has('win32unix') && dir =~ '^/' + let dir = eclim#cygwin#WindowsPath(dir) + endif + + let command = s:include_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'add', '') + let command = substitute(command, '<lang>', s:GetLang(), '') + let command = substitute(command, '<dir>', dir, '') + + let result = eclim#Execute(command) + if result != '0' + call eclim#c#project#Configs(b:project) + call eclim#util#Echo(result) + endif +endfunction " }}} + +" s:AddSymbol() {{{ +function! s:AddSymbol() + let project_root = eclim#project#util#GetProjectRoot(b:project) + let name = input('name: ', '') + if name == '' + return + endif + + let value = input('value: ') + if value == '' + return + endif + + let command = s:symbol_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'add', '') + let command = substitute(command, '<lang>', s:GetLang(), '') + let command = substitute(command, '<name>', name, '') + let command .= ' -v "' . value . '"' + + let result = eclim#Execute(command) + if result != '0' + call eclim#c#project#Configs(b:project) + call eclim#util#Echo(result) + endif +endfunction " }}} + +" s:Delete() {{{ +function! s:Delete() + let reload = 0 + let message = '' + let pos = getpos('.') + let lnum = line('.') + let line = getline(lnum) + + " source entry excludes + if line =~ '^\s*excludes:\s\+' + let lnum -= 1 + let line = getline(lnum) + endif + + " source entry dir + if line =~ '^\s*dir:\s\+' + let reload = 1 + let message = s:DeleteSource(lnum) + + " include path entry + elseif line =~ '^\s*path:\s\+' + let reload = 1 + let message = s:DeleteInclude(lnum) + + " symbol entry + elseif line =~ '^\s*name/value:\s\+' + let reload = 1 + let message = s:DeleteSymbol(lnum) + endif + + if reload + call eclim#c#project#Configs(b:project) + call setpos('.', pos) + if message != '' + call eclim#util#Echo(message) + endif + endif +endfunction " }}} + +" s:DeleteSource(lnum) {{{ +function! s:DeleteSource(lnum) + let dir = substitute(getline(a:lnum), '^\s*dir:\s\+\(.*\)', '\1', '') + let command = s:src_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'delete', '') + let command = substitute(command, '<dir>', dir, '') + + let result = eclim#Execute(command) + if result != '0' + return result + endif + return '' +endfunction " }}} + +" s:DeleteInclude(lnum) {{{ +function! s:DeleteInclude(lnum) + let dir = substitute(getline(a:lnum), '^\s*path:\s\+\(.*\)', '\1', '') + let dir = substitute(dir, '\(^"\|"$\)', '', 'g') + let dir = substitute(dir, '^\$', '', '') + let dir = substitute(dir, '\(^{\|}$\)', '', 'g') + let dir = substitute(dir, '^workspace_loc:', '', '') + + let command = s:include_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'delete', '') + let command = substitute(command, '<lang>', s:GetLang(), '') + let command = substitute(command, '<dir>', dir, '') + + let result = eclim#Execute(command) + if result != '0' + return result + endif + return '' +endfunction " }}} + +" s:DeleteSymbol(lnum) {{{ +function! s:DeleteSymbol(lnum) + let name = substitute( + \ getline(a:lnum), '^\s*name/value:\s\+\(.\{-}\)=.*', '\1', '') + + let command = s:symbol_command + let command = substitute(command, '<project>', b:project, '') + let command = substitute(command, '<action>', 'delete', '') + let command = substitute(command, '<lang>', s:GetLang(), '') + let command = substitute(command, '<name>', name, '') + + let result = eclim#Execute(command) + if result != '0' + return result + endif + return '' +endfunction " }}} + +" s:GetLang() {{{ +function! s:GetLang() + let lang_line = getline(search('^\s\+Tool:', 'bnW')) + if lang_line =~? 'assembl' + return 'assembly' + elseif lang_line =~? 'c++\|cpp' + return "c++" + endif + return 'c' +endfunction " }}} + +" CommandCompleteProject(argLead, cmdLine, cursorPos) {{{ +" Custom command completion for project names. +function! eclim#c#project#CommandCompleteProject(argLead, cmdLine, cursorPos) + let c_projects = eclim#project#util#CommandCompleteProjectByNature( + \ a:argLead, a:cmdLine, a:cursorPos, 'c') + let cpp_projects = eclim#project#util#CommandCompleteProjectByNature( + \ a:argLead, a:cmdLine, a:cursorPos, 'cpp') + let projects = c_projects + cpp_projects + call sort(projects) + return projects +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/c/search.vim b/vim/eclim/autoload/eclim/c/search.vim @@ -0,0 +1,162 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/c/search.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ + if !exists("g:EclimCSearchSingleResult") + " possible values ('split', 'edit', 'lopen') + let g:EclimCSearchSingleResult = g:EclimDefaultFileOpenAction + endif +" }}} + +" Script Varables {{{ + let s:search = '-command c_search' + let s:includepaths = '-command c_includepaths -p "<project>"' + let s:sourcepaths = '-command c_sourcepaths -p "<project>"' + let s:options = ['-p', '-t', '-s', '-x', '-i'] + let s:scopes = ['all', 'project'] + let s:types = [ + \ 'class_struct', + \ 'function', + \ 'variable', + \ 'union', + \ 'method', + \ 'field', + \ 'enum', + \ 'enumerator', + \ 'namespace', + \ 'typedef', + \ 'macro' + \ ] + let s:contexts = [ + \ 'all', + \ 'declarations', + \ 'definitions', + \ 'references' + \ ] +" }}} + +" Search(argline) {{{ +" Executes a search. +function! eclim#c#search#Search(argline) + return eclim#lang#Search( + \ s:search, g:EclimCSearchSingleResult, a:argline) +endfunction " }}} + +" FindInclude() {{{ +" Finds the include file under the cursor +function eclim#c#search#FindInclude() + if !eclim#project#util#IsCurrentFileInProject(1) + return + endif + + let file = substitute(getline('.'), '.*#include\s*[<"]\(.*\)[>"].*', '\1', '') + + let project = eclim#project#util#GetCurrentProjectName() + let command = substitute(s:includepaths, '<project>', project, '') + let result = eclim#Execute(command) + let paths = type(result) == g:LIST_TYPE ? result : [] + + let command = substitute(s:sourcepaths, '<project>', project, '') + let result = eclim#Execute(command) + let paths += type(result) == g:LIST_TYPE ? result : [] + + let dir = expand('%:p:h') + if index(paths, dir) == -1 + call add(paths, dir) + endif + let results = split(globpath(join(paths, ','), file), '\n') + + if !empty(results) + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries(results)) + + " single result in another file. + if len(results) == 1 && g:EclimCSearchSingleResult != "lopen" + let entry = getloclist(0)[0] + call eclim#util#GoToBufferWindowOrOpen + \ (bufname(entry.bufnr), g:EclimCSearchSingleResult) + call eclim#display#signs#Update() + else + exec 'lopen ' . g:EclimLocationListHeight + endif + else + call eclim#util#EchoInfo("File not found.") + endif +endfunction " }}} + +" SearchContext() {{{ +" Executes a contextual search. +function! eclim#c#search#SearchContext() + if getline('.')[col('.') - 1] == '$' + call cursor(line('.'), col('.') + 1) + let cnum = eclim#util#GetCurrentElementColumn() + call cursor(line('.'), col('.') - 1) + else + let cnum = eclim#util#GetCurrentElementColumn() + endif + + if getline('.') =~ '#include\s*[<"][A-Za-z0-9.]*\%' . cnum . 'c' + call eclim#c#search#FindInclude() + return + "elseif getline('.') =~ '\<\(class\|????\)\s\+\%' . cnum . 'c' + " call eclim#c#search#Search('-x references') + return + endif + + call eclim#c#search#Search('-x context') +endfunction " }}} + +" CommandCompleteCSearch(argLead, cmdLine, cursorPos) {{{ +" Custom command completion for CSearch +function! eclim#c#search#CommandCompleteCSearch(argLead, cmdLine, cursorPos) + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + if cmdLine =~ '-s\s\+[a-z]*$' + let scopes = deepcopy(s:scopes) + call filter(scopes, 'v:val =~ "^' . argLead . '"') + return scopes + elseif cmdLine =~ '-t\s\+[a-z]*$' + let types = deepcopy(s:types) + call filter(types, 'v:val =~ "^' . argLead . '"') + return types + elseif cmdLine =~ '-x\s\+[a-z]*$' + let contexts = deepcopy(s:contexts) + call filter(contexts, 'v:val =~ "^' . argLead . '"') + return contexts + elseif cmdLine =~ '\s\+[-]\?$' + let options = deepcopy(s:options) + let index = 0 + for option in options + if a:cmdLine =~ option + call remove(options, index) + else + let index += 1 + endif + endfor + return options + endif + return [] +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/client/nailgun.vim b/vim/eclim/autoload/eclim/client/nailgun.vim @@ -0,0 +1,193 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + if !exists("g:EclimNailgunKeepAlive") + " keepAlive flag - can be re-defined in the user ~/.vimrc . + " Read once, on client initialization. Subsequent changes of + " this flag in run-time has no effect. + let g:EclimNailgunKeepAlive = 0 + endif +" }}} + +function! eclim#client#nailgun#ChooseEclimdInstance(...) " {{{ + " Function which prompts the user to pick the target workspace and returns + " their choice or if only one workspace is active simply return it without + " prompting the user. If the optional 'dir' argument is supplied and that dir + " is a subdirectory of one of the workspaces, then that workspace will be + " returned. + " Optional args: + " dir + + if !eclim#EclimAvailable() + return + endif + + let instances = eclim#client#nailgun#GetEclimdInstances() + if len(instances) == 1 + return instances[keys(instances)[0]] + endif + + if len(instances) > 1 + let path = a:0 && a:1 != '' ? a:1 : expand('%:p') + if path == '' + let path = getcwd() . '/' + endif + let path = substitute(path, '\', '/', 'g') + + " when we are in a temp window, use the initiating filename + if &buftype != '' && exists('b:filename') + let path = b:filename + endif + + " project inside of a workspace dir + for workspace in keys(instances) + if path =~ '^' . workspace + return instances[workspace] + endif + endfor + + " project outside of a workspace dir + let project = eclim#project#util#GetProject(path) + if len(project) > 0 + return get(instances, project.workspace, 0) + endif + + let workspaces = keys(instances) + let response = eclim#util#PromptList( + \ 'Muliple workspaces found, please choose the target workspace', + \ workspaces, g:EclimInfoHighlight) + + " user cancelled, error, etc. + if response < 0 + return + endif + + return instances[workspaces[response]] + endif + + call eclim#util#Echo('No eclimd instances found running.') +endfunction " }}} + +function! eclim#client#nailgun#GetEclimdInstances() " {{{ + " Returns a dict with eclimd instances. + let instances = {} + if eclim#EclimAvailable() + let dotinstances = eclim#UserHome() . '/.eclim/.eclimd_instances' + let lines = readfile(dotinstances) + for line in lines + if line !~ '^{' + continue + endif + let values = eval(line) + let instances[values.workspace] = values + endfor + endif + return instances +endfunction " }}} + +function! eclim#client#nailgun#Execute(instance, command, ...) " {{{ + let exec = a:0 ? a:1 : 0 + + if !exec + if !exists('g:EclimNailgunClient') + call s:DetermineClient() + endif + + if g:EclimNailgunClient == 'python' && has('python') + return eclim#client#python#nailgun#Execute(a:instance.port, a:command) + endif + endif + + let eclim = eclim#client#nailgun#GetEclimCommand(a:instance.home) + if string(eclim) == '0' + return [1, g:EclimErrorReason] + endif + + let command = a:command + if exec + let command = escape(command, '%#') + endif + + " on windows/cygwin where cmd.exe is used, we need to escape any '^' + " characters in the command args. + if has('win32') || has('win64') || has('win32unix') + let command = substitute(command, '\^', '^^', 'g') + endif + + let eclim .= ' --nailgun-port ' . a:instance.port . ' ' . command + if exec + let eclim = '!' . eclim + endif + + let result = eclim#util#System(eclim, exec, exec) + return [v:shell_error, result] +endfunction " }}} + +function! eclim#client#nailgun#GetEclimCommand(home) " {{{ + " Gets the command to exexute eclim. + let command = a:home . 'bin/eclim' + + if has('win32') || has('win64') || has('win32unix') + let command = command . (has('win95') ? '.bat' : '.cmd') + endif + + if !filereadable(command) + let g:EclimErrorReason = 'Could not locate file: ' . command + return + endif + + if has('win32unix') + " in cygwin, we must use 'cmd /c' to prevent issues with eclim script + + " some arg containing spaces causing a failure to invoke the script. + return 'cmd /c "' . eclim#cygwin#WindowsPath(command) . '"' + endif + return '"' . command . '"' +endfunction " }}} + +function! s:DetermineClient() " {{{ + " at least one ubuntu user had serious performance issues using the python + " client, so we are only going to default to python on windows machines + " where there is an actual potential benefit to using it. + if has('python') && (has('win32') || has('win64')) + let g:EclimNailgunClient = 'python' + else + let g:EclimNailgunClient = 'external' + endif +endfunction " }}} + +function! eclim#client#nailgun#CommandCompleteWorkspaces(argLead, cmdLine, cursorPos) " {{{ + " Custom command completion for available workspaces. + + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let args = eclim#util#ParseCmdLine(cmdLine) + let argLead = cmdLine =~ '\s$' ? '' : args[len(args) - 1] + + let instances = eclim#client#nailgun#GetEclimdInstances() + let workspaces = sort(keys(instances)) + if cmdLine !~ '[^\\]\s$' + call filter(workspaces, 'v:val =~ "^' . argLead . '"') + endif + + return workspaces +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/client/python/nailgun.py b/vim/eclim/autoload/eclim/client/python/nailgun.py @@ -0,0 +1,214 @@ +""" +Copyright (C) 2005 - 2011 Eric Van Dewoestine + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +@author: Anton Sharonov +@author: Eric Van Dewoestine +""" +import socket + +try: + from cStringIO import StringIO +except: + from StringIO import StringIO + +class Nailgun(object): + """ + Client used to communicate with a nailgun server. + """ + + def __init__(self, **kwargs): + self.socket = None + self.port = kwargs.get('port') + self.keepAlive = int(kwargs.get('keepAlive', 0)) + self.reconnectCounter = 0 + + def send(self, cmdline): + """ + Sends a complete command to the nailgun server. Handles connecting to the + server if not currently connected. + @param cmdline command, which is sent to server, for instance + "-command ping". + @return tuple consisting of: + - retcode from server (0 for success, non-0 for failure) + - string response from server + """ + if not self.isConnected(): + # with keepAlive do only first reconnect + if not self.keepAlive or self.reconnectCounter == 0: + (retcode, result) = self.reconnect() + if retcode: + return (retcode, result) + + if not self.isConnected(): # Only for keepAlive + return (-1, "connect: ERROR - socket is not connected (nailgun.py)") + + try: # outer try for pre python 2.5 support. + try: + for arg in self.parseArgs(cmdline): + self.sendChunk("A", arg) + + if self.keepAlive: + self.sendChunk("K") + + self.sendChunk("C", "org.eclim.command.Main") + + (retcode, result) = self.processResponse() + if self.keepAlive and retcode: + # force reconnect on error (may not be necessary) + self.reconnect() + + return (retcode, result) + except socket.error, ex: + args = ex.args + if len(args) > 1: + retcode, msg = args[0], args[1] + elif len(args): + retcode, msg = 1, args[0] + else: + retcode, msg = 1, 'No message' + return (retcode, 'send: %s' % msg) + finally: + if not self.keepAlive: + try: + self.close() + except: + # don't let an error on close mask any previous error. + pass + + def connect(self, port=None): + """ + Establishes the connection to specified port or if not supplied, + uses the default. + """ + port = port or self.port + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect(('localhost', port)) + except socket.error, ex: + args = ex.args + if len(args) > 1: + retcode, msg = args[0], args[1] + elif len(args): + retcode, msg = 1, args[0] + else: + retcode, msg = 1, 'No message' + return (retcode, 'connect: %s' % msg) + + self.socket = sock + return (0, '') + + def reconnect(self): + if self.socket != None: + self.close() + self.reconnectCounter += 1 + return self.connect() + + def close(self): + self.socket.close() + self.socket = None + + def isConnected(self): + return self.socket != None + + def parseArgs(self, cmdline): + # FIXME: doesn't handle escaping of spaces/quotes yet (may never need to) + args = [] + arg = '' + quote = '' + for char in cmdline: + if char == ' ' and not quote: + if arg: + args.append(arg) + arg = '' + elif char == '"' or char == "'": + if quote and char == quote: + quote = '' + elif not quote: + quote = char + else: + arg += char + else: + arg += char + + if arg: + args.append(arg) + + return args + + def sendChunk(self, chunkType, text=''): + """ + Sends a nailgun 'chunk' to the server. + """ + #print("sendChunk " + chunkType + " " + text) + length = len(text) + str = "%c%c%c%c%c" % ( + (length / (65536*256)) % 256, + (length / 65536) % 256, + (length / 256) % 256, + length % 256, + chunkType) + nbytes = self.socket.sendall(str) + nbytes = self.socket.sendall(text) + + def processResponse(self): + result = StringIO() + exit = 0 + exitFlag = 1 # expecting 1 times exit chunk + while exitFlag > 0: + answer = self.recvBlocked(5) + if len(answer) < 5: + print("error: socket closed unexpectedly\n") + return None + lenPayload = ord(answer[0]) * 65536 * 256 \ + + ord(answer[1]) * 65536 \ + + ord(answer[2]) * 256 \ + + ord(answer[3]) + #print("lenPayload detected : %d" % lenPayload) + chunkType = answer[4] + if chunkType == "1": + # STDOUT + result.write(self.recvToFD(1, answer, lenPayload)) + elif chunkType == "2": + # STDERR + result.write(self.recvToFD(2, answer, lenPayload)) + elif chunkType == "X": + exitFlag = exitFlag - 1 + exit = int(self.recvToFD(2, answer, lenPayload)) + else: + print("error: unknown chunk type = %d\n" % chunkType) + exitFlag = 0 + + return [exit, result.getvalue()] + + def recvBlocked(self, lenPayload): + """ + Receives until all data is read - necessary because usual recv sometimes + returns with number of bytes read less then asked. + """ + received = "" + while (len(received) < lenPayload): + received = received + self.socket.recv(lenPayload - len(received)) + return received + + def recvToFD(self, destFD, buf, lenPayload): + """ + This function just mimics the function with the same name from the C + client. We don't really care which file descriptor the server tells us to + write to - STDOUT and STDERR are the same on VIM side (see eclim.bat, + "2>&1" at the end of command). + """ + received = self.recvBlocked(lenPayload) + return received diff --git a/vim/eclim/autoload/eclim/client/python/nailgun.vim b/vim/eclim/autoload/eclim/client/python/nailgun.vim @@ -0,0 +1,115 @@ +" Author: Anton Sharonov +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2010 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:python_dir = expand("<sfile>:h") +" }}} + +" Execute(port, command) {{{ +" Sends to the eclimd server command, supplied as argument string. +" Returns server's respond. +function! eclim#client#python#nailgun#Execute(port, command) + call s:InitClient(a:port) + let result_viml = "" + let retcode = 0 + + let begin = localtime() + try +python << PYTHONEOF +command = vim.eval('a:command') +(retcode, result) = client.send(command) +vim.command('let retcode = %i' % retcode) +vim.command("let result = '%s'" % result.replace("'", "''")) +PYTHONEOF + finally + call eclim#util#EchoTrace( + \ 'nailgun.py (port: ' . a:port . '): ' . a:command, localtime() - begin) + endtry + + return [retcode, result] +endfunction " }}} + +" Reconnect(port) {{{ +" Does unconditional reconnect of the python_if +" (useful to manual recover from errors in the python_if) +function! eclim#client#python#nailgun#Reconnect(port) + call s:InitClient(a:port) +python << PYTHONEOF +client.reconnect() +PYTHONEOF +endfunction " }}} + +" SetKeepAlive(port, value) {{{ +" Updates the in runtime value of the keepAlive flag. +function! eclim#client#python#nailgun#SetKeepAlive(port, value) + call s:InitClient(a:port) +python << PYTHONEOF +client.keepAlive = int(vim.eval('a:value')) +PYTHONEOF +endfunction " }}} + +" GetKeepAlive(port) {{{ +" Retrieves the value of the keepAlive flag. +function! eclim#client#python#nailgun#GetKeepAlive(port) + call s:InitClient(a:port) + let result = 0 +python << PYTHONEOF +vim.command("let result = %s" % client.keepAlive) +PYTHONEOF + return result +endfunction " }}} + +" GetReconnectCounter(port) {{{ +" Retrieves the value of the reconnect counter. +function! eclim#client#python#nailgun#GetReconnectCounter(port) + call s:InitClient(a:port) + let result = 0 +python << PYTHONEOF +vim.command("let result = %d" % client.reconnectCounter) +PYTHONEOF + return result +endfunction " }}} + +" s:InitClient(port) {{{ +" Initializes the python interface to the nailgun server. +function! s:InitClient(port) +python << PYTHONEOF +if not vars().has_key('clients'): + import sys, vim + sys.path.append(vim.eval('s:python_dir')) + import nailgun + + clients = {} + +port = int(vim.eval('a:port')) +if not clients.has_key(port): + clients[port] = nailgun.Nailgun( + port=port, + keepAlive=vim.eval('g:EclimNailgunKeepAlive'), + ) +client = clients[port] +PYTHONEOF +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/buffers.vim b/vim/eclim/autoload/eclim/common/buffers.vim @@ -0,0 +1,400 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists('g:EclimBuffersSort') + let g:EclimBuffersSort = 'file' +endif +if !exists('g:EclimBuffersSortDirection') + let g:EclimBuffersSortDirection = 'asc' +endif +if !exists('g:EclimBuffersDefaultAction') + let g:EclimBuffersDefaultAction = g:EclimDefaultFileOpenAction +endif +if !exists('g:EclimBuffersDeleteOnTabClose') + let g:EclimBuffersDeleteOnTabClose = 0 +endif +if !exists('g:EclimOnlyExclude') + let g:EclimOnlyExclude = '^NONE$' +endif +if !exists('g:EclimOnlyExcludeFixed') + let g:EclimOnlyExcludeFixed = 1 +endif +" }}} + +" ScriptVariables {{{ + let s:eclim_tab_id = 0 +" }}} + +function! eclim#common#buffers#Buffers(bang) " {{{ + " Like, :buffers, but opens a temporary buffer. + + let options = {'maxfilelength': 0} + let buffers = eclim#common#buffers#GetBuffers(options) + + if g:EclimBuffersSort != '' + call sort(buffers, 'eclim#common#buffers#BufferCompare') + endif + + let lines = [] + let buflist = [] + let filelength = options['maxfilelength'] + let tabid = exists('*gettabvar') ? s:GetTabId() : 0 + let tabbuffers = tabpagebuflist() + for buffer in buffers + let eclim_tab_id = getbufvar(buffer.bufnr, 'eclim_tab_id') + if a:bang != '' || eclim_tab_id == '' || eclim_tab_id == tabid + " for buffers w/ out a tab id, don't show them in the list if they + " are active, but aren't open on the current tab. + if a:bang == '' && buffer.status =~ 'a' && index(tabbuffers, buffer.bufnr) == -1 + continue + endif + + call add(lines, s:BufferEntryToLine(buffer, filelength)) + call add(buflist, buffer) + endif + endfor + + call eclim#util#TempWindow('[buffers]', lines) + + setlocal modifiable noreadonly + call append(line('$'), ['', '" use ? to view help']) + setlocal nomodifiable readonly + + let b:eclim_buffers = buflist + + " syntax + set ft=eclim_buffers + hi link BufferActive Special + hi link BufferHidden Comment + syntax match BufferActive /+\?active\s\+\(\[RO\]\)\?/ + syntax match BufferHidden /+\?hidden\s\+\(\[RO\]\)\?/ + syntax match Comment /^".*/ + + " mappings + nnoremap <silent> <buffer> <cr> :call <SID>BufferOpen(g:EclimBuffersDefaultAction)<cr> + nnoremap <silent> <buffer> E :call <SID>BufferOpen('edit')<cr> + nnoremap <silent> <buffer> S :call <SID>BufferOpen('split')<cr> + nnoremap <silent> <buffer> V :call <SID>BufferOpen('vsplit')<cr> + nnoremap <silent> <buffer> T :call <SID>BufferOpen('tablast \| tabnew')<cr> + nnoremap <silent> <buffer> D :call <SID>BufferDelete()<cr> + nnoremap <silent> <buffer> R :Buffers<cr> + + " assign to buffer var to get around weird vim issue passing list containing + " a string w/ a '<' in it on execution of mapping. + let b:buffers_help = [ + \ '<cr> - open buffer with default action', + \ 'E - open with :edit', + \ 'S - open in a new split window', + \ 'V - open in a new vertically split window', + \ 'T - open in a new tab', + \ 'D - delete the buffer', + \ 'R - refresh the buffer list', + \ ] + nnoremap <buffer> <silent> ? + \ :call eclim#help#BufferHelp(b:buffers_help, 'vertical', 40)<cr> + + "augroup eclim_buffers + " autocmd! + " autocmd BufAdd,BufWinEnter,BufDelete,BufWinLeave * + " \ call eclim#common#buffers#BuffersUpdate() + " autocmd BufUnload <buffer> autocmd! eclim_buffers + "augroup END +endfunction " }}} + +function! eclim#common#buffers#BuffersToggle(bang) " {{{ + let name = eclim#util#EscapeBufferName('[buffers]') + if bufwinnr(name) == -1 + call eclim#common#buffers#Buffers(a:bang) + else + exec "bdelete " . bufnr(name) + endif +endfunction " }}} + +function! eclim#common#buffers#BufferCompare(buffer1, buffer2) " {{{ + exec 'let attr1 = a:buffer1.' . g:EclimBuffersSort + exec 'let attr2 = a:buffer2.' . g:EclimBuffersSort + let compare = attr1 == attr2 ? 0 : attr1 > attr2 ? 1 : -1 + if g:EclimBuffersSortDirection == 'desc' + let compare = 0 - compare + endif + return compare +endfunction " }}} + +function! eclim#common#buffers#Only() " {{{ + let curwin = winnr() + let winnum = 1 + while winnum <= winnr('$') + let fixed = g:EclimOnlyExcludeFixed && ( + \ getwinvar(winnum, '&winfixheight') == 1 || + \ getwinvar(winnum, '&winfixwidth') == 1) + let excluded = bufname(winbufnr(winnum)) =~ g:EclimOnlyExclude + if winnum != curwin && !fixed && !excluded + if winnum < curwin + let curwin -= 1 + endif + exec winnum . 'winc w' + close + exec curwin . 'winc w' + continue + endif + let winnum += 1 + endwhile +endfunction " }}} + +function! eclim#common#buffers#GetBuffers(...) " {{{ + let options = a:0 ? a:1 : {} + + redir => list + silent buffers + redir END + + let buffers = [] + let maxfilelength = 0 + for entry in split(list, '\n') + let buffer = {} + let buffer.status = substitute(entry, '\s*[0-9]\+\s\+\(.\{-}\)\s\+".*', '\1', '') + let buffer.path = substitute(entry, '.\{-}"\(.\{-}\)".*', '\1', '') + let buffer.path = fnamemodify(buffer.path, ':p') + let buffer.file = fnamemodify(buffer.path, ':p:t') + let buffer.dir = fnamemodify(buffer.path, ':p:h') + let buffer.bufnr = str2nr(substitute(entry, '\s*\([0-9]\+\).*', '\1', '')) + let buffer.lnum = str2nr(substitute(entry, '.*"\s\+\w\+\s\+\(\d\+\)', '\1', '')) + call add(buffers, buffer) + + if len(buffer.file) > maxfilelength + let maxfilelength = len(buffer.file) + endif + endfor + + if has_key(options, 'maxfilelength') + let options['maxfilelength'] = maxfilelength + endif + + return buffers +endfunction " }}} + +function! eclim#common#buffers#TabInit() " {{{ + let tabnr = 1 + while tabnr <= tabpagenr('$') + let tab_id = gettabvar(tabnr, 'eclim_tab_id') + if tab_id == '' + let s:eclim_tab_id += 1 + call settabvar(tabnr, 'eclim_tab_id', s:eclim_tab_id) + for bufnr in tabpagebuflist(tabnr) + let btab_id = getbufvar(bufnr, 'eclim_tab_id') + if btab_id == '' + call setbufvar(bufnr, 'eclim_tab_id', s:eclim_tab_id) + endif + endfor + endif + let tabnr += 1 + endwhile +endfunction " }}} + +function! eclim#common#buffers#TabEnter() " {{{ + if !s:GetTabId() + call s:SetTabId() + endif + + if g:EclimBuffersDeleteOnTabClose + if exists('s:tab_count') && s:tab_count > tabpagenr('$') + " delete any buffers associated with the closed tab + let buffers = eclim#common#buffers#GetBuffers() + for buffer in buffers + let eclim_tab_id = getbufvar(buffer.bufnr, 'eclim_tab_id') + " don't delete active buffers, just in case the tab has the wrong + " eclim_tab_id + if eclim_tab_id == s:tab_prev && buffer.status !~ 'a' + try + exec 'bdelete ' . buffer.bufnr + catch /E89/ + " ignore since it happens when using bd! on the last buffer for + " another tab. + endtry + endif + endfor + endif + endif +endfunction " }}} + +function! eclim#common#buffers#TabLeave() " {{{ + let s:tab_prev = s:GetTabId() + let s:tab_count = tabpagenr('$') +endfunction " }}} + +function! eclim#common#buffers#TabLastOpenIn() " {{{ + if !buflisted('%') + silent! unlet b:eclim_tab_id + endif + + if !s:GetTabId() + call s:SetTabId() + endif + + let tabnr = 1 + let other_tab = 0 + let bufnr = bufnr('%') + while tabnr <= tabpagenr('$') + if tabnr != tabpagenr() && + \ eclim#util#ListContains(tabpagebuflist(tabnr), bufnr) + let other_tab = tabnr + break + endif + let tabnr += 1 + endwhile + + if !exists('b:eclim_tab_id') || !other_tab + let b:eclim_tab_id = s:GetTabId() + endif +endfunction " }}} + +function! eclim#common#buffers#OpenNextHiddenTabBuffer(current) " {{{ + let allbuffers = eclim#common#buffers#GetBuffers() + + " build list of buffers open in other tabs to exclude + let tabbuffers = [] + let lasttab = tabpagenr('$') + let index = 1 + while index <= lasttab + if index != tabpagenr() + for bnum in tabpagebuflist(index) + call add(tabbuffers, bnum) + endfor + endif + let index += 1 + endwhile + + " build list of buffers not open in any window, and last seen on the + " current tab. + let hiddenbuffers = [] + for buffer in allbuffers + let bnum = buffer.bufnr + if bnum != a:current && index(tabbuffers, bnum) == -1 && bufwinnr(bnum) == -1 + let eclim_tab_id = getbufvar(bnum, 'eclim_tab_id') + if eclim_tab_id != '' && eclim_tab_id != t:eclim_tab_id + continue + endif + + if bnum < a:current + call insert(hiddenbuffers, bnum) + else + call add(hiddenbuffers, bnum) + endif + endif + endfor + + " we found a hidden buffer, so open it + if len(hiddenbuffers) > 0 + exec 'buffer ' . hiddenbuffers[0] + doautocmd BufEnter + doautocmd BufWinEnter + doautocmd BufReadPost + return hiddenbuffers[0] + endif + return 0 +endfunction " }}} + +function! s:BufferDelete() " {{{ + let line = line('.') + if line > len(b:eclim_buffers) + return + endif + + let index = line - 1 + setlocal modifiable + setlocal noreadonly + exec line . ',' . line . 'delete _' + setlocal nomodifiable + setlocal readonly + let buffer = b:eclim_buffers[index] + call remove(b:eclim_buffers, index) + + let winnr = winnr() + " make sure the autocmds are executed in the following order + noautocmd exec 'bd ' . buffer.bufnr + doautocmd BufDelete + doautocmd BufEnter + exec winnr . 'winc w' +endfunction " }}} + +function! s:BufferEntryToLine(buffer, filelength) " {{{ + let line = '' + let line .= a:buffer.status =~ '+' ? '+' : ' ' + let line .= a:buffer.status =~ 'a' ? 'active' : 'hidden' + let line .= a:buffer.status =~ '[-=]' ? ' [RO] ' : ' ' + let line .= a:buffer.file + + let pad = a:filelength - len(a:buffer.file) + 2 + while pad > 0 + let line .= ' ' + let pad -= 1 + endwhile + + let line .= a:buffer.dir + return line +endfunction " }}} + +function! s:BufferOpen(cmd) " {{{ + let line = line('.') + if line > len(b:eclim_buffers) + return + endif + + let file = bufname(b:eclim_buffers[line - 1].bufnr) + let winnr = b:winnr + close + + " prevent opening the buffer in a split of a vertical tool window (project + " tree, taglist, etc.) + if exists('g:VerticalToolBuffers') && has_key(g:VerticalToolBuffers, winbufnr(winnr)) + let winnr = 1 + while has_key(g:VerticalToolBuffers, winbufnr(winnr)) + let winnr += 1 + if winnr > winnr('$') + let winnr -= 1 + break + endif + endwhile + endif + + exec winnr . 'winc w' + call eclim#util#GoToBufferWindowOrOpen(file, a:cmd) +endfunction " }}} + +function! s:GetTabId(...) " {{{ + let tabnr = a:0 ? a:1 : tabpagenr() + " using gettabvar over t:eclim_tab_id because while autocmds are executing, + " the tabpagenr() may return the correct tab number, but accessing + " t:eclim_tab_id may return the value from the previously focused tab. + return gettabvar(tabnr, 'eclim_tab_id') +endfunction " }}} + +function! s:SetTabId(...) " {{{ + let tabnr = a:0 ? a:1 : tabpagenr() + let s:eclim_tab_id += 1 + " using settabvar for reason explained in s:GetTabId() + call settabvar(tabnr, 'eclim_tab_id', s:eclim_tab_id) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/history.vim b/vim/eclim/autoload/eclim/common/history.vim @@ -0,0 +1,332 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + if !exists('g:EclimHistoryDiffOrientation') + let g:EclimHistoryDiffOrientation = 'vertical' + endif +" }}} + +" Script Variables {{{ +let s:command_add = '-command history_add -p "<project>" -f "<file>"' +let s:command_list = '-command history_list -p "<project>" -f "<file>"' +let s:command_revision = + \ '-command history_revision -p "<project>" -f "<file>" -r <revision>' +let s:command_clear = '-command history_clear -p "<project>" -f "<file>"' +" }}} + +" AddHistory() {{{ +" Adds the current state of the file to the eclipse local history (should be +" invoked prior to saving to disk). +function! eclim#common#history#AddHistory() + if !filereadable(expand('%')) || !eclim#project#util#IsCurrentFileInProject(0) + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_add + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + call eclim#Execute(command) +endfunction " }}} + +" History() {{{ +" Opens a temporary buffer with a list of local history revisions. +function! eclim#common#history#History() + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_list + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let history = eclim#Execute(command) + if type(history) != g:LIST_TYPE + return + endif + + let lines = [file] + let revisions = [0] + let indent = eclim#util#GetIndent(1) + for rev in history + call add(lines, indent . rev.datetime . ' (' . rev.delta . ')') + call add(revisions, rev.timestamp) + endfor + call add(lines, '') + call eclim#util#TempWindow('[History]', lines) + + setlocal modifiable noreadonly + if !g:EclimProjectKeepLocalHistory + call append(line('$'), + \ '" Note: local history is current disabled: ' . + \ 'g:EclimProjectKeepLocalHistory = ' . g:EclimProjectKeepLocalHistory) + endif + call append(line('$'), '" use ? to view help') + setlocal nomodifiable readonly + syntax match Comment /^".*/ + + let b:history_revisions = revisions + call s:Syntax() + + command! -count=1 HistoryDiffNext call s:DiffNextPrev(1, <count>) + command! -count=1 HistoryDiffPrev call s:DiffNextPrev(-1, <count>) + augroup eclim_history_window + autocmd! BufWinLeave <buffer> + autocmd BufWinLeave <buffer> + \ delcommand HistoryDiffNext | + \ delcommand HistoryDiffPrev + augroup END + noremap <buffer> <silent> <cr> :call <SID>View()<cr> + noremap <buffer> <silent> d :call <SID>Diff()<cr> + noremap <buffer> <silent> r :call <SID>Revert()<cr> + noremap <buffer> <silent> c :call <SID>Clear(1)<cr> + + " assign to buffer var to get around weird vim issue passing list containing + " a string w/ a '<' in it on execution of mapping. + let b:history_help = [ + \ '<cr> - view the entry', + \ 'd - diff the file with the version under the cursor', + \ 'r - revert the file to the version under the cursor', + \ 'c - clear the history', + \ ':HistoryDiffNext - diff the file with the next version in the history', + \ ':HistoryDiffPrev - diff the file with the previous version in the history', + \ ] + nnoremap <buffer> <silent> ? + \ :call eclim#help#BufferHelp(b:history_help, 'vertical', 50)<cr> +endfunction " }}} + +" HistoryClear(bang) {{{ +" Clear the history for the current file. +function! eclim#common#history#HistoryClear(bang) + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call s:Clear(a:bang == '', expand('%:p')) +endfunction " }}} + +" s:View([cmd]) {{{ +" View the contents of the revision under the cursor. +function s:View(...) + if line('.') == 1 || line('.') > len(b:history_revisions) + return + endif + + let current = b:filename + let entry = line('.') - 1 + let revision = b:history_revisions[entry] + if eclim#util#GoToBufferWindow(current) + let filetype = &ft + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_revision + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<revision>', revision, '') + let result = eclim#Execute(command) + if result == "0" + return + endif + + let cmd = len(a:000) > 0 ? a:000[0] : 'split' + call eclim#util#GoToBufferWindowOrOpen(current . '_' . revision, cmd) + + setlocal modifiable + setlocal noreadonly + + let temp = tempname() + call writefile(split(result, '\n'), temp) + try + silent 1,$delete _ + silent read ++edit `=temp` + silent 1,1delete _ + finally + call delete(temp) + endtry + + exec 'setlocal filetype=' . filetype + setlocal nomodified + setlocal readonly + setlocal nomodifiable + setlocal noswapfile + setlocal nobuflisted + setlocal buftype=nofile + setlocal bufhidden=delete + doautocmd BufReadPost + + call s:HighlightEntry(entry) + + return 1 + else + call eclim#util#EchoWarning('Target file is no longer open.') + endif +endfunction " }}} + +" s:Diff() {{{ +" Diff the contents of the revision under the cursor against the current +" contents. +function s:Diff() + let hist_buf = bufnr('%') + let winend = winnr('$') + let winnum = 1 + while winnum <= winend + let bufnr = winbufnr(winnum) + if getbufvar(bufnr, 'history_diff') != '' + exec bufnr . 'bd' + continue + endif + let winnum += 1 + endwhile + call eclim#util#GoToBufferWindow(hist_buf) + + let current = b:filename + let orien = g:EclimHistoryDiffOrientation == 'horizontal' ? '' : 'vertical' + if s:View(orien . ' below split') + let b:history_diff = 1 + diffthis + augroup history_diff + autocmd! BufWinLeave <buffer> + call eclim#util#GoToBufferWindowRegister(current) + autocmd BufWinLeave <buffer> diffoff + augroup END + + call eclim#util#GoToBufferWindow(current) + diffthis + endif +endfunction " }}} + +" s:DiffNextPrev(dir, count) {{{ +function s:DiffNextPrev(dir, count) + let winnr = winnr() + if eclim#util#GoToBufferWindow('[History]') + let num = v:count > 0 ? v:count : a:count + let cur = exists('b:history_current_entry') ? b:history_current_entry : 0 + let index = cur + (a:dir * num) + if index < 0 || index > len(b:history_revisions) + call eclim#util#EchoError('Operation exceeds history stack range.') + exec winnr . 'winc w' + return + endif + call cursor(index + 1, 0) + call s:Diff() + endif +endfunction " }}} + +" s:Revert() {{{ +" Revert the file to the revision under the cursor. +function s:Revert() + if line('.') == 1 || line('.') > len(b:history_revisions) + return + endif + + let current = b:filename + let revision = b:history_revisions[line('.') - 1] + if eclim#util#GoToBufferWindow(current) + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_revision + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<revision>', revision, '') + let result = eclim#Execute(command) + if result == "0" + return + endif + + let ff = &ff + let temp = tempname() + call writefile(split(result, '\n'), temp) + try + silent 1,$delete _ + silent read ++edit `=temp` + silent 1,1delete _ + finally + call delete(temp) + endtry + + if ff != &ff + call eclim#util#EchoWarning( + \ "Warning: the file format is being reverted from '" . ff . "' to '" . + \ &ff . "'. Using vim's undo will not restore the previous format so " . + \ "if you choose to undo the reverting of this file, you will need to " . + \ "manually set the file format back to " . ff . " (set ff=" . ff . ").") + endif + endif +endfunction " }}} + +" s:Clear(prompt, [filename]) {{{ +" Clear the history. +function s:Clear(prompt, ...) + let response = 1 + if a:prompt + let response = eclim#util#PromptConfirm( + \ 'Clear local history?', g:EclimInfoHighlight) + endif + + if response == 1 + let filename = len(a:000) > 0 ? a:000[0] : b:filename + let current = eclim#project#util#GetProjectRelativeFilePath(filename) + let project = eclim#project#util#GetCurrentProjectName() + let command = s:command_clear + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', current, '') + let result = eclim#Execute(command) + if result == "0" + return + endif + + if filename != expand('%:p') + quit + endif + call eclim#util#Echo(result) + endif +endfunction " }}} + +" s:Syntax() {{{ +function! s:Syntax() + set ft=eclim_history + hi link HistoryFile Identifier + hi link HistoryCurrentEntry Constant + syntax match HistoryFile /.*\%1l.*/ + syntax match Comment /^".*/ +endfunction " }}} + +" s:HighlightEntry(index) {{{ +function s:HighlightEntry(index) + let winnr = winnr() + if eclim#util#GoToBufferWindow('[History]') + let b:history_current_entry = a:index + try + " forces reset of syntax + call s:Syntax() + exec 'syntax match HistoryCurrentEntry /.*\%' . (a:index + 1) . 'l.*/' + finally + exec winnr . 'winc w' + endtry + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/largefile.vim b/vim/eclim/autoload/eclim/common/largefile.vim @@ -0,0 +1,58 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Initially based on vimscript 1506 +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Settings {{{ +let s:file_size = g:EclimLargeFileSize * 1024 * 1024 +let s:events = ['BufRead', 'CursorHold', 'FileType'] +" }}} + +function! eclim#common#largefile#InitSettings() " {{{ + let file = expand("<afile>") + let size = getfsize(file) + if size >= s:file_size || size == -2 + if !exists('b:save_events') + let b:save_events = &eventignore + call s:ApplySettings() + setlocal noswapfile nowrap bufhidden=unload + autocmd eclim_largefile BufEnter,BufWinEnter <buffer> call <SID>ApplySettings() + autocmd eclim_largefile BufLeave,BufWinLeave <buffer> call <SID>RevertSettings() + endif + endif +endfunction " }}} + +function! s:ApplySettings() " {{{ + let &eventignore=join(s:events, ',') + if !exists('b:largefile_notified') + let b:largefile_notified = 1 + call eclim#util#Echo('Note: Large file settings applied.') + endif +endfunction " }}} + +function! s:RevertSettings() " {{{ + if exists('b:save_events') + let &eventignore=b:save_events + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/license.vim b/vim/eclim/autoload/eclim/common/license.vim @@ -0,0 +1,87 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:year = exists('*strftime') ? strftime('%Y') : '2009' +" }}} + +" GetLicense() {{{ +" Retrieves the file containing the license text. +function! eclim#common#license#GetLicense() + let file = eclim#project#util#GetProjectSetting('org.eclim.project.copyright') + if type(file) == g:NUMBER_TYPE + return + elseif file == '' + call eclim#util#EchoWarning( + \ "Project setting 'org.eclim.project.copyright' has not been supplied.") + return + endif + + let file = eclim#project#util#GetCurrentProjectRoot() . '/' . file + if !filereadable(file) + return + endif + return file +endfunction " }}} + +" License(pre, post, mid) {{{ +" Retrieves the license configured license and applies the specified prefix +" and postfix as the lines before and after the license and uses 'mid' as the +" prefix for every line. +" Returns the license as a list of strings. +function! eclim#common#license#License(pre, post, mid) + let file = eclim#common#license#GetLicense() + if type(file) == g:NUMBER_TYPE && file == 0 + return '' + endif + + let contents = readfile(file) + if a:mid != '' + call map(contents, 'a:mid . v:val') + endif + + if a:pre != '' + call insert(contents, a:pre) + endif + + if a:post != '' + call add(contents, a:post) + endif + + call map(contents, "substitute(v:val, '${year}', s:year, 'g')") + + let author = eclim#project#util#GetProjectSetting('org.eclim.user.name') + if type(author) == g:STRING_TYPE && author != '' + call map(contents, "substitute(v:val, '${author}', author, 'g')") + endif + + let email = eclim#project#util#GetProjectSetting('org.eclim.user.email') + if type(email) == g:STRING_TYPE && email != '' + call map(contents, "substitute(v:val, '${email}', email, 'g')") + endif + call map(contents, "substitute(v:val, '\\s\\+$', '', '')") + + return contents +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/locate.vim b/vim/eclim/autoload/eclim/common/locate.vim @@ -0,0 +1,655 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Implements the :LocateFile functionality. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists('g:EclimLocateFileDefaultAction') + let g:EclimLocateFileDefaultAction = g:EclimDefaultFileOpenAction +endif + +if !exists('g:EclimLocateFileScope') + let g:EclimLocateFileScope = 'project' +endif + +if !exists('g:EclimLocateFileNonProjectScope') + let g:EclimLocateFileNonProjectScope = 'workspace' +endif + +if !exists('g:EclimLocateFileFuzzy') + let g:EclimLocateFileFuzzy = 1 +endif + +if !exists('g:EclimLocateFileCaseInsensitive') + " one of: 'lower', 'never', 'always' + let g:EclimLocateFileCaseInsensitive = 'lower' +endif + +if !exists('g:EclimLocateUserScopes') + let g:EclimLocateUserScopes = [] +endif + +let g:eclim_locate_default_updatetime = &updatetime + +" disable autocomplpop in the locate prompt +if exists('g:acp_behavior') + let g:acp_behavior['locate_prompt'] = [] +endif + +" }}} + +" Script Variables {{{ +let s:command_locate = '-command locate_file -s "<scope>"' +let s:scopes = [ + \ 'project', + \ 'workspace', + \ 'buffers', + \ 'quickfix', + \ ] + +let s:help = [ + \ '<esc> - close the locate prompt + results', + \ '<tab>, <down> - select the next file', + \ '<s-tab>, <up> - select the previous file', + \ '<cr> - open selected file w/ default action', + \ '<c-e> - open with :edit', + \ '<c-s> - open in a split window', + \ '<c-t> - open in a new tab', + \ '<c-l> - choose search scope', + \ '<c-h> - toggle help buffer', + \ ] +" }}} + +" LocateFile(action, file, [scope]) {{{ +" Locates a file using the specified action for opening the file when found. +" action - '' (use user default), 'split', 'edit', etc. +" file - 'somefile.txt', +" '', (kick off completion mode), +" '<cursor>' (locate the file under the cursor) +" scope - optional scope to search in (project, workspace, buffers, etc.) +function! eclim#common#locate#LocateFile(action, file, ...) + let project = eclim#project#util#GetCurrentProjectName() + let scope = a:0 > 0 ? a:1 : g:EclimLocateFileScope + + if !eclim#util#ListContains(s:scopes, scope) && + \ !eclim#util#ListContains(g:EclimLocateUserScopes, scope) + call eclim#util#EchoWarning('Unrecognized scope: ' . scope) + return + endif + + if scope == 'project' && (project == '' || !eclim#EclimAvailable(0)) + let scope = g:EclimLocateFileNonProjectScope + endif + + let workspace = '' + if scope == 'project' || scope == 'workspace' + let instance = eclim#client#nailgun#ChooseEclimdInstance() + if type(instance) != g:DICT_TYPE + return + endif + + let workspace = instance.workspace + if !eclim#PingEclim(0, workspace) + call eclim#util#EchoError('Unable to connect to eclimd.') + return + endif + endif + + let results = [] + let action = a:action + if action == '' + let action = g:EclimLocateFileDefaultAction + endif + + let file = a:file + if file == '' + call s:LocateFileCompletionInit(action, scope, project, workspace) + return + elseif file == '<cursor>' + let file = eclim#util#GrabUri() + + " if grabbing a relative url, remove any anchor info or query parameters + let file = substitute(file, '[#?].*', '', '') + endif + + let name = fnamemodify(file, ':t') + if name == '' + call eclim#util#Echo('Please supply more than just a directory name.') + return + endif + + let pattern = file + let pattern = s:LocateFileConvertPattern(pattern, 0) + let pattern = '[^/]*' . pattern + try + let b:workspace = workspace + let b:project = project + let results = s:LocateFileFunction(scope)(pattern) + finally + unlet! b:workspce + unlet! b:project + endtry + + call map(results, "v:val.path") + + let result = '' + " One result. + if len(results) == 1 + let result = results[0] + + " More than one result. + elseif len(results) > 1 + let message = "Multiple results, choose the file to open" + let response = eclim#util#PromptList(message, results, g:EclimInfoHighlight) + if response == -1 + return + endif + + let result = results[response] + + " No results + else + call eclim#util#Echo('Unable to locate file pattern "' . file . '".') + return + endif + + if has('win32unix') + let result = eclim#cygwin#CygwinPath(result) + endif + + call eclim#util#GoToBufferWindowOrOpen(eclim#util#Simplify(result), action) + call eclim#util#Echo(' ') +endfunction " }}} + +function! eclim#common#locate#LocateFileCompletion() " {{{ + let line = getline('.') + if line !~ '^> ' + call setline(1, substitute(line, '^>\?\s*', '> \1', '')) + call cursor(1, 3) + let line = getline('.') + endif + + let completions = [] + let display = [] + let name = substitute(line, '^>\s*', '', '') + if name !~ '^\s*$' + let pattern = name + let pattern = s:LocateFileConvertPattern(pattern, g:EclimLocateFileFuzzy) + + let results = s:LocateFileFunction(b:scope)(pattern) + if !empty(results) + for result in results + let rel = eclim#util#Simplify(get(result, 'projectPath', result.path)) + let dict = {'word': result.name, 'menu': rel, 'info': result.path} + call add(completions, dict) + call add(display, result.name . ' ' . rel) + endfor + endif + endif + let b:completions = completions + let winnr = winnr() + noautocmd exec bufwinnr(b:results_bufnum) . 'winc w' + setlocal modifiable + 1,$delete _ + call append(1, display) + 1,1delete _ + setlocal nomodifiable + exec winnr . 'winc w' + + " part of bad hack for gvim on windows + let b:start_selection = 1 + + call s:LocateFileSelection(1) +endfunction " }}} + +function! eclim#common#locate#LocateFileClose() " {{{ + if bufname(bufnr('%')) !~ '^\[Locate.*\]$' + let bufnr = bufnr('\[Locate in *\]') + let winnr = bufwinnr(bufnr) + if winnr != -1 + let curbuf = bufnr('%') + exec winnr . 'winc w' + try + exec 'bw ' . b:results_bufnum + bw + autocmd! locate_file_init + stopinsert + finally + exec bufwinnr(curbuf) . 'winc w' + endtry + endif + endif +endfunction " }}} + +function! s:LocateFileCompletionInit(action, scope, project, workspace) " {{{ + let file = expand('%') + let bufnum = bufnr('%') + let winrestcmd = winrestcmd() + + topleft 12split [Locate\ Results] + set filetype=locate_results + setlocal nonumber nowrap + setlocal noswapfile nobuflisted + setlocal buftype=nofile bufhidden=delete + + let results_bufnum = bufnr('%') + + let locate_in = (a:scope == 'project' ? a:project : a:scope) + exec 'topleft 1split ' . escape('[Locate in ' . locate_in . ']', ' -') + setlocal modifiable + call setline(1, '> ') + call cursor(1, col('$')) + set filetype=locate_prompt + syntax match Keyword /^>/ + setlocal winfixheight + setlocal nonumber + setlocal nolist + setlocal noswapfile nobuflisted + setlocal buftype=nofile bufhidden=delete + + let b:bufnum = bufnum + let b:project = a:project + let b:workspace = a:workspace + let b:scope = a:scope + let b:results_bufnum = results_bufnum + let b:help_bufnum = 0 + let b:selection = 1 + let b:winrestcmd = winrestcmd + + set updatetime=300 + + augroup locate_file_init + autocmd! + autocmd BufEnter <buffer> nested startinsert! | let &updatetime = 300 + autocmd BufLeave \[Locate*\] + \ call eclim#util#DelayedCommand('call eclim#common#locate#LocateFileClose()') + exec 'autocmd InsertLeave <buffer> ' . + \ 'let &updatetime = g:eclim_locate_default_updatetime | ' . + \ 'doautocmd BufWinLeave | bw | ' . + \ 'doautocmd BufWinLeave | bw ' . b:results_bufnum . ' | ' . + \ 'call eclim#util#GoToBufferWindow(' . b:bufnum . ') | ' . + \ 'doautocmd BufEnter | ' . + \ 'doautocmd WinEnter | ' . + \ winrestcmd + exec 'autocmd WinEnter <buffer=' . b:results_bufnum .'> ' + \ 'exec bufwinnr(' . bufnr('%') . ') "winc w"' + augroup END + + " enable completion after user starts typing + call s:LocateFileCompletionAutocmdDeferred() + + imap <buffer> <silent> <tab> <c-r>=<SID>LocateFileSelection("n")<cr> + imap <buffer> <silent> <down> <c-r>=<SID>LocateFileSelection("n")<cr> + imap <buffer> <silent> <s-tab> <c-r>=<SID>LocateFileSelection("p")<cr> + imap <buffer> <silent> <up> <c-r>=<SID>LocateFileSelection("p")<cr> + exec 'imap <buffer> <silent> <cr> ' . + \ '<c-r>=<SID>LocateFileSelect("' . a:action . '")<cr>' + imap <buffer> <silent> <c-e> <c-r>=<SID>LocateFileSelect('edit')<cr> + imap <buffer> <silent> <c-s> <c-r>=<SID>LocateFileSelect('split')<cr> + imap <buffer> <silent> <c-t> <c-r>=<SID>LocateFileSelect("tablast \| tabnew")<cr> + imap <buffer> <silent> <c-l> <c-r>=<SID>LocateFileChangeScope()<cr> + imap <buffer> <silent> <c-h> <c-r>=<SID>LocateFileHelp()<cr> + + startinsert! +endfunction " }}} + +function! s:LocateFileCompletionAutocmd() " {{{ + augroup locate_file + autocmd! + autocmd CursorHoldI <buffer> call eclim#common#locate#LocateFileCompletion() + augroup END +endfunction " }}} + +function! s:LocateFileCompletionAutocmdDeferred() " {{{ + augroup locate_file + autocmd! + autocmd CursorMovedI <buffer> call <SID>LocateFileCompletionAutocmd() + augroup END +endfunction " }}} + +function! s:LocateFileSelection(sel) " {{{ + " pause completion while tabbing though results + augroup locate_file + autocmd! + augroup END + + let sel = a:sel + let prev_sel = b:selection + + " bad hack for gvim on windows + let start_sel = b:start_selection + let double_defer = 0 + if sel =~ '^[np]$' && (has('win32') || has('win64')) + let double_defer = b:start_selection == 1 + let b:start_selection = 0 + endif + + let winnr = winnr() + noautocmd exec bufwinnr(b:results_bufnum) . 'winc w' + + if sel == 'n' + let sel = prev_sel < line('$') ? prev_sel + 1 : 1 + elseif sel == 'p' + let sel = prev_sel > 1 ? prev_sel - 1 : line('$') + endif + + syntax clear + exec 'syntax match PmenuSel /\%' . sel . 'l.*/' + exec 'call cursor(' . sel . ', 1)' + let save_scrolloff = &scrolloff + let &scrolloff = 5 + normal! zt + let &scrolloff = save_scrolloff + + exec winnr . 'winc w' + + exec 'let b:selection = ' . sel + + if double_defer + augroup locate_file + autocmd! + autocmd CursorMovedI <buffer> call <SID>LocateFileCompletionAutocmdDeferred() + augroup END + else + call s:LocateFileCompletionAutocmdDeferred() + endif + + return '' +endfunction " }}} + +function! s:LocateFileSelect(action) " {{{ + if exists('b:completions') && !empty(b:completions) + let &updatetime = g:eclim_locate_default_updatetime + + let file = eclim#util#Simplify(b:completions[b:selection - 1].info) + if has('win32unix') + let file = eclim#cygwin#CygwinPath(file) + endif + + let bufnum = b:bufnum + let winrestcmd = b:winrestcmd + + " close locate windows + exec 'bdelete ' . b:results_bufnum + exec 'bdelete ' . bufnr('%') + + " reset windows to pre-locate sizes + exec winrestcmd + + " open the selected result + call eclim#util#GoToBufferWindow(bufnum) + call eclim#util#GoToBufferWindowOrOpen(file, a:action) + call feedkeys("\<esc>", 'n') + doautocmd WinEnter + endif + return '' +endfunction " }}} + +function! s:LocateFileChangeScope() " {{{ + if b:help_bufnum && bufexists(b:help_bufnum) + exec 'bdelete ' . b:help_bufnum + endif + + let bufnr = bufnr('%') + let winnr = winnr() + + " trigger [Locate] buffer's BufLeave autocmd before we leave the buffer + doautocmd BufLeave + + noautocmd exec bufwinnr(b:results_bufnum) . 'winc w' + silent noautocmd exec '50vnew [Locate\ Scope]' + + let b:locate_bufnr = bufnr + let b:locate_winnr = winnr + stopinsert + setlocal modifiable + call append(1, s:scopes + g:EclimLocateUserScopes) + 1,1delete _ + call append(line('$'), + \ ['', '" <cr> - select a scope', '" <c-c>, <c-l>, or q - cancel']) + syntax match Comment /^".*/ + setlocal nomodifiable + setlocal winfixheight + setlocal nonumber + setlocal nolist + setlocal noswapfile nobuflisted + setlocal buftype=nofile bufhidden=delete + + nnoremap <buffer> <silent> <cr> :call <SID>ChooseScope()<cr> + nnoremap <buffer> <silent> q :call <SID>CloseScopeChooser()<cr> + nnoremap <buffer> <silent> <c-c> :call <SID>CloseScopeChooser()<cr> + nnoremap <buffer> <silent> <c-l> :call <SID>CloseScopeChooser()<cr> + + autocmd BufLeave <buffer> call <SID>CloseScopeChooser() + + return '' +endfunction " }}} + +function! s:ChooseScope() " {{{ + let scope = getline('.') + if scope =~ '^"\|^\s*$' + return + endif + + let workspace = '' + let project = '' + let locate_in = scope + + if scope == 'project' + let project = '' + let names = eclim#project#util#GetProjectNames() + let prompt = 'Choose a project (ctrl-c to cancel): ' + while project == '' + let project = input( + \ prompt, '', 'customlist,eclim#project#util#CommandCompleteProject') + if project == '' + echo '' + return + endif + + if !eclim#util#ListContains(names, project) + let prompt = "Project '" . project . "' not found (ctrl-c to cancel): " + let project = '' + endif + endwhile + let locate_in = project + let workspace = eclim#project#util#GetProjectWorkspace(project) + + elseif scope == 'workspace' + let project = '' + let instance = eclim#client#nailgun#ChooseEclimdInstance() + if type(instance) != g:DICT_TYPE + return + endif + let workspace = instance.workspace + endif + + call s:CloseScopeChooser() + + let b:scope = scope + let b:project = project + let b:workspace = workspace != '' ? workspace : b:workspace + + exec 'file ' . escape('[Locate in ' . locate_in . ']', ' ') + + call eclim#common#locate#LocateFileCompletion() +endfunction " }}} + +function! s:CloseScopeChooser() " {{{ + let winnum = b:locate_winnr + bwipeout + exec winnum . 'winc w' + + " hack to make :q work like the other close mappings + doautocmd BufEnter + " if we end up in a non-Locate window, make sure everything is as it should + " be (a hack for the above hack). + augroup locate_file_chooser_hack + autocmd! + autocmd BufEnter * + \ if bufname('%') !~ '^\[Locate in .*\]$' | + \ call eclim#common#locate#LocateFileClose() | + \ endif | + \ autocmd! locate_file_chooser_hack + augroup END +endfunction " }}} + +function! s:LocateFileHelp() " {{{ + let winnr = winnr() + noautocmd exec bufwinnr(b:results_bufnum) . 'winc w' + let help_bufnum = eclim#help#BufferHelp(s:help, 'vertical', 50) + exec winnr . 'winc w' + let b:help_bufnum = help_bufnum + + return '' +endfunction " }}} + +function! s:LocateFileConvertPattern(pattern, fuzzy) " {{{ + let pattern = a:pattern + + if a:fuzzy + let pattern = '.*' . substitute(pattern, '\(.\)', '\1.*?', 'g') + let pattern = substitute(pattern, '\.\([^*]\)', '\\.\1', 'g') + else + " if the user supplied a path, prepend a '.*/' to it so that they don't need + " to type full paths to match. + if pattern =~ '.\+/' + let pattern = '.*/' . pattern + endif + let pattern = substitute(pattern, '\*\*', '.*', 'g') + let pattern = substitute(pattern, '\(^\|\([^.]\)\)\*', '\1[^/]*?', 'g') + let pattern = substitute(pattern, '\.\([^*]\)', '\\.\1', 'g') + "let pattern = substitute(pattern, '\([^*]\)?', '\1.', 'g') + let pattern .= '.*' + endif + + return pattern +endfunction " }}} + +function! s:LocateFileFunction(scope) " {{{ + if eclim#util#ListContains(s:scopes, a:scope) + return function('s:LocateFile_' . a:scope) + endif + return function('LocateFile_' . a:scope) +endfunction " }}} + +function! s:LocateFileCommand(pattern) " {{{ + let command = s:command_locate + if g:EclimLocateFileCaseInsensitive == 'always' || + \ (a:pattern !~# '[A-Z]' && g:EclimLocateFileCaseInsensitive != 'never') + let command .= ' -i' + endif + let command .= ' -p "' . a:pattern . '"' + return command +endfunction " }}} + +function! s:LocateFile_workspace(pattern) " {{{ + let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'workspace', '') + let results = eclim#Execute(command, {'workspace': b:workspace}) + if type(results) != g:LIST_TYPE + return [] + endif + return results +endfunction " }}} + +function! s:LocateFile_project(pattern) " {{{ + let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'project', '') + let command .= ' -n "' . b:project . '"' + let results = eclim#Execute(command, {'workspace': b:workspace}) + if type(results) != g:LIST_TYPE + return [] + endif + return results +endfunction " }}} + +function! s:LocateFile_buffers(pattern) " {{{ + redir => list + silent exec 'buffers' + redir END + + let buffers = map(split(list, '\n'), + \ "substitute(v:val, '.\\{-}\"\\(.\\{-}\\)\".*', '\\1', '')") + if a:pattern =~ '/' + let buffers = map(buffers, "fnamemodify(v:val, ':p')") + endif + + if len(buffers) > 0 + let tempfile = substitute(tempname(), '\', '/', 'g') + call writefile(buffers, tempfile) + try + return eclim#common#locate#LocateFileFromFileList(a:pattern, tempfile) + finally + call delete(tempfile) + endtry + endif + return [] +endfunction " }}} + +function! s:LocateFile_quickfix(pattern) " {{{ + let buffers = [] + let prev = '' + for entry in getqflist() + let name = bufname(entry.bufnr) + if a:pattern =~ '/' + let name = fnamemodify(name, ':p') + endif + if name != prev + call add(buffers, name) + let prev = name + endif + endfor + + if len(buffers) > 0 + let tempfile = substitute(tempname(), '\', '/', 'g') + call writefile(buffers, tempfile) + try + return eclim#common#locate#LocateFileFromFileList(a:pattern, tempfile) + finally + call delete(tempfile) + endtry + endif + return [] +endfunction " }}} + +function! eclim#common#locate#LocateFileFromFileList(pattern, file) " {{{ + let file = a:file + if has('win32unix') + let file = eclim#cygwin#WindowsPath(file) + endif + if eclim#EclimAvailable(0) + let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'list', '') + let command .= ' -f "' . file . '"' + let results = eclim#Execute(command, {'workspace': b:workspace}) + if type(results) != g:LIST_TYPE + return [] + endif + else + let results = [] + for result in readfile(file) + call add(results, {'name': fnamemodify(result, ':t'), 'path': result}) + endfor + endif + + return results +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/template.vim b/vim/eclim/autoload/eclim/common/template.vim @@ -0,0 +1,237 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists("g:EclimTemplateDir") + let g:EclimTemplateDir = g:EclimBaseDir . '/template' +endif +if !exists("g:EclimTemplateExtension") + let g:EclimTemplateExtension = '.vim' +endif +if !exists("g:EclimTemplateIgnore") + let g:EclimTemplateIgnore = [] +endif +" }}} + +" Script Variables {{{ +let s:quote = "['\"]" +let s:tag_regex = + \ '<vim:[a-zA-Z]\+\(\s\+[a-zA-Z]\+\s*=\s*' . s:quote . '.*' . s:quote . '\)\?\s*/>' +let s:tagname_regex = '.\{-}<vim:\([a-zA-Z]\+\).*' +" }}} + +" Template() {{{ +" Main method for finding and executing the template. +function! eclim#common#template#Template() + " allow some plugins to disable templates temporarily + if exists('g:EclimTemplateTempIgnore') && g:EclimTemplateTempIgnore + return + endif + + " ignore certain file patterns + for ignore in g:EclimTemplateIgnore + if expand('%') =~ ignore + return + endif + endfor + + let template = s:FindTemplate() + if template != '' + let lines = readfile(template) + call s:ExecuteTemplate(lines) + 1,1delete _ + endif +endfunction " }}} + +" s:FindTemplate() {{{ +" Finds the template file and returns the location. +function! s:FindTemplate() + let templatesDir = expand(g:EclimTemplateDir) + if !isdirectory(templatesDir) + call eclim#util#EchoDebug( + \ 'Template dir not found (g:EclimTemplateDir): ' . templatesDir) + return '' + endif + + let filename = expand('%:t') + let ext = "" + + " template equal to the filename + if filereadable(templatesDir . '/' . filename . g:EclimTemplateExtension) + return templatesDir . '/' . filename . g:EclimTemplateExtension + endif + + " template pattern + let templates = globpath(templatesDir, '*' . g:EclimTemplateExtension) + for template in split(templates, '\n') + " remove path info + let temp_template = substitute(template, '.*[/\\]', '', '') + if g:EclimTemplateExtension != '' + let temp_template = + \ strpart(temp_template, 0, stridx(temp_template, g:EclimTemplateExtension)) + endif + + while stridx(temp_template, '.') != -1 + let ext = strpart(temp_template, stridx(temp_template, '.')) + let temp_template = strpart(temp_template, 0, stridx(temp_template, '.')) + if filename =~ '.*' . temp_template . '.*' . ext + return template + endif + endwhile + endfor + + " template equal to file extension + if stridx(filename, '.') > 0 + let ext = strpart(filename, stridx(filename, '.')) + while stridx(ext, '.') != -1 + let ext = strpart(ext, stridx(ext, '.') + 1) + if filereadable(templatesDir . '/' . ext . g:EclimTemplateExtension) + return templatesDir . '/' . ext . g:EclimTemplateExtension + endif + endwhile + endif + + " template equal to file type + if filereadable(templatesDir . '/' . &ft . g:EclimTemplateExtension) + return templatesDir . '/' . &ft . g:EclimTemplateExtension + endif + + return '' +endfunction " }}} + +" s:ExecuteTemplate(lines) {{{ +" Executes any logic in the supplied lines and appends those lines to the +" current file. +function! s:ExecuteTemplate(lines) + for line in a:lines + if line =~ s:tag_regex + let tag = substitute(line, s:tagname_regex, '\1', '') + call s:ExecuteTemplate(s:Process_{tag}(line)) + else + call append(line('$'), line) + endif + endfor +endfunction " }}} + +" s:EvaluateExpression(expression) {{{ +" Evaluates the supplied expression. +function! s:EvaluateExpression(expression) + exec "return " . a:expression +endfunction " }}} + +" s:GetAttribute(line, tag, attribute, fail) {{{ +" Gets the an attribute value. +function! s:GetAttribute(line, tag, attribute, fail) + let attribute = substitute(a:line, + \ '.\{-}<vim:' . a:tag . '.\{-}\s\+' . a:attribute . + \ '\s*=\s*\(' . s:quote . '\)\(.\{-}\)\1.*/>.*', + \ '\2', '') + + if attribute == a:line + if a:fail + call s:TemplateError( + \ a:line, "syntax error - missing '" . a:attribute . "' attribute") + endif + return "" + endif + return attribute +endfunction " }}} + +" s:TemplateError(line, message) {{{ +" Echos an error message to the user. +function! s:TemplateError(line, message) + call eclim#util#EchoError("Template error, line " . a:line . ": " . a:message) +endfunction " }}} + +" s:Process_var(line) {{{ +" Process <vim:var/> tags. +function! s:Process_var(line) + let name = expand(s:GetAttribute(a:line, 'var', 'name', 1)) + let value = expand(s:GetAttribute(a:line, 'var', 'value', 1)) + + exec "let " . name . " = \"" . s:EvaluateExpression(value) . "\"" + + return [] +endfunction " }}} + +" s:Process_import(line) {{{ +" Process <vim:import/> tags. +function! s:Process_import(line) + let resource = expand(s:GetAttribute(a:line, 'import', 'resource', 1)) + if resource !~ '^/\' + let resource = expand(g:EclimTemplateDir . '/' . resource) + endif + + if !filereadable(resource) + call s:TemplateError(a:line, "resource not found '" . resource . "'") + endif + + exec "source " . resource + + return [] +endfunction " }}} + +" s:Process_out(line) {{{ +" Process <vim:out/> tags. +function! s:Process_out(line) + let value = s:GetAttribute(a:line, 'out', 'value', 1) + let result = s:EvaluateExpression(value) + return s:Out(a:line, '<vim:out\s\+.\{-}\s*\/>', result) +endfunction " }}} + +" s:Process_include(line) {{{ +" Process <vim:include/> tags. +function! s:Process_include(line) + let template = expand( + \ g:EclimTemplateDir . '/' . s:GetAttribute(a:line, 'include', 'template', 1)) + + if !filereadable(template) + call s:TemplateError(a:line, "template not found '" . template . "'") + return [] + endif + + return readfile(template) +endfunction " }}} + +" s:Process_username(line) {{{ +" Process <vim:username/> tags. +function! s:Process_username(line) + silent! let username = eclim#project#util#GetProjectSetting('org.eclim.user.name') + if type(username) == g:NUMBER_TYPE + let username = '' + endif + return s:Out(a:line, '<vim:username\s*\/>', username) +endfunction " }}} + +" s:Out(line, pattern, value) {{{ +function! s:Out(line, pattern, value) + let results = type(a:value) == g:LIST_TYPE ? a:value : [a:value] + if results[0] == '' && a:line =~ '^\s*' . a:pattern . '\s*$' + return [] + endif + + let line = substitute(a:line, a:pattern, results[0], '') + return [line] + (len(results) > 1 ? results[1:] : []) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/common/util.vim b/vim/eclim/autoload/eclim/common/util.vim @@ -0,0 +1,195 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Various functions that are useful in and out of eclim. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +let s:command_read = '-command archive_read -f "<file>"' +" }}} + +" DiffLastSaved() {{{ +" Diff a modified file with the last saved version. +function! eclim#common#util#DiffLastSaved() + if &modified + let winnum = winnr() + let filetype=&ft + vertical botright new | r # + 1,1delete _ + + diffthis + setlocal buftype=nofile + setlocal bufhidden=wipe + setlocal nobuflisted + setlocal noswapfile + setlocal readonly + exec "setlocal ft=" . filetype + let diffnum = winnr() + + augroup diff_saved + autocmd! BufUnload <buffer> + autocmd BufUnload <buffer> :diffoff! + augroup END + + exec winnum . "winc w" + diffthis + + " for some reason, these settings only take hold if set here. + call setwinvar(diffnum, "&foldmethod", "diff") + call setwinvar(diffnum, "&foldlevel", "0") + else + echo "No changes" + endif +endfunction " }}} + +" SwapTypedArguments() {{{ +" Swaps typed method declaration arguments. +function! eclim#common#util#SwapTypedArguments() + " FIXME: add validation to see if user is executing on a valid position. + normal! w + SwapWords + normal! b + SwapWords + normal! www + SwapWords + normal! bb + SwapWords + normal! b +endfunction " }}} + +" SwapWords() {{{ +" Initially based on http://www.vim.org/tips/tip.php?tip_id=329 +function! eclim#common#util#SwapWords() + " save the last search pattern + let save_search = @/ + + normal! "_yiw + s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/ + exec "normal! \<C-O>" + + " restore the last search pattern + let @/ = save_search + + silent! call repeat#set(":call eclim#common#util#SwapWords()\<cr>", v:count) +endfunction " }}} + +" Tcd(dir) {{{ +" Like vim's :lcd, but tab local instead of window local. +function! eclim#common#util#Tcd(dir) + let t:cwd = fnamemodify(a:dir, ':p') + + " initialize the tab cwd for all other tabs if not already set + let curtab = tabpagenr() + try + let index = 1 + while index <= tabpagenr('$') + if index != curtab + exec 'tabn ' . index + if !exists('t:cwd') + let t:cwd = getcwd() + " try to find a window without a localdir if necessary + if haslocaldir() + let curwin = winnr() + let windex = 1 + while windex <= winnr('$') + if windex != curwin + exec windex . 'winc w' + if !haslocaldir() + let t:cwd = getcwd() + break + endif + endif + let windex += 1 + endwhile + exec curwin . 'winc w' + endif + endif + endif + let index += 1 + endwhile + finally + exec 'tabn ' . curtab + endtry + + call s:ApplyTcd(0) + + augroup tcd + autocmd! + autocmd TabEnter * call <SID>ApplyTcd(1) + augroup END +endfunction " }}} + +" s:ApplyTcd(honor_lcd) {{{ +function! s:ApplyTcd(honor_lcd) + if !exists('t:cwd') + return + endif + + if a:honor_lcd && haslocaldir() + let lcwd = getcwd() + exec 'cd ' . escape(t:cwd, ' ') + exec 'lcd ' . escape(lcwd, ' ') + else + exec 'cd ' . escape(t:cwd, ' ') + endif +endfunction " }}} + +" ReadFile() {{{ +" Reads the contents of an archived file. +function! eclim#common#util#ReadFile() + let archive = substitute(expand('%'), '\', '/', 'g') + let command = substitute(s:command_read, '<file>', archive, '') + + let file = eclim#Execute(command) + + if string(file) != '0' + let project = exists('b:eclim_project') ? b:eclim_project : '' + let bufnum = bufnr('%') + if has('win32unix') + let file = eclim#cygwin#CygwinPath(file) + endif + silent exec "keepalt keepjumps edit! " . escape(file, ' ') + if project != '' + let b:eclim_project = project + let b:eclim_file = archive + endif + + exec 'bdelete ' . bufnum + + " alternate solution, that keeps the archive url as the buffer's filename, + " but prevents taglist from being able to parse tags. + "setlocal noreadonly + "setlocal modifiable + "silent! exec "read " . file + "1,1delete _ + + silent exec "doautocmd BufReadPre " . file + silent exec "doautocmd BufReadPost " . file + + setlocal readonly + setlocal nomodifiable + setlocal noswapfile + " causes taglist.vim errors (fold then delete fails) + "setlocal bufhidden=delete + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/css/complete.vim b/vim/eclim/autoload/eclim/css/complete.vim @@ -0,0 +1,95 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/css/complete.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command css_complete -p "<project>" -f "<file>" -o <offset> -e <encoding>' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles css code completion. +function! eclim#css#complete#CodeComplete(findstart, base) + if !eclim#project#util#IsCurrentFileInProject(0) + return a:findstart ? -1 : [] + endif + + if a:findstart + call eclim#lang#SilentUpdate(1) + + " locate the start of the word + let line = getline('.') + + let start = col('.') - 1 + + while start > 0 && line[start - 1] =~ '[[:alnum:]_-]' + let start -= 1 + endwhile + + return start + else + let offset = eclim#util#GetOffset() + len(a:base) + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate(1, 0) + if file == '' + return [] + endif + + let command = s:complete_command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + let completions = [] + let results = eclim#Execute(command) + if type(results) != g:LIST_TYPE + return + endif + + let filter = 0 + for result in results + let word = result.completion + if word =~ '^:' + let word = strpart(word, 1) + let filter = 1 + endif + + let menu = result.menu + let info = result.info + + let dict = {'word': tolower(word), 'menu': menu, 'info': info} + + call add(completions, dict) + endfor + + " eclipse doesn't filter out :results properly. + if filter + call filter(completions, 'v:val.word =~ "^" . a:base') + endif + + return completions + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/css/validate.vim b/vim/eclim/autoload/eclim/css/validate.vim @@ -0,0 +1,51 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/css/validate.html +" +" License: +" +" Copyright (C) 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +function! eclim#css#validate#Filter(errors) " {{{ + let results = [] + let ignore_next_parse_error = 0 + for error in a:errors + " ignore errors related to browser targeted properties + if error.text =~ '\(^\|\s\)-\(moz\|webkit\|khtml\|o\)-\w\+\>' + continue + endif + + " ignore errors on IE filter property line + if getline(error.lnum) =~ '^\s*filter:\s*progid' + " next parse error will be because of this filter + let ignore_next_parse_error = 1 + continue + endif + if error.text == 'Parse Error' && ignore_next_parse_error + let ignore_next_parse_error = 0 + continue + endif + + call add(results, error) + endfor + + return results +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/cygwin.vim b/vim/eclim/autoload/eclim/cygwin.vim @@ -0,0 +1,60 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Utility functions for cygwin usage. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +function! eclim#cygwin#CygwinPath(path) " {{{ + return s:Cygpath(a:path, 'cygwin') +endfunction " }}} + +function! eclim#cygwin#WindowsPath(path) " {{{ + if type(a:path) == g:STRING_TYPE && a:path =~? '^[a-z]:' + return substitute(a:path, '\', '/', 'g') + endif + return s:Cygpath(a:path, 'windows') +endfunction " }}} + +function! eclim#cygwin#WindowsHome() " {{{ + if !exists('s:cygpath_winhome') + let dir = s:Cygpath('-D', 'cygwin') + let s:cygpath_winhome = dir != '-D' ? fnamemodify(dir, ':h') : '' + endif + return s:cygpath_winhome +endfunction " }}} + +function! s:Cygpath(paths, type) " {{{ + if executable('cygpath') + let paths = type(a:paths) == g:LIST_TYPE ? a:paths : [a:paths] + let paths = map(paths, "'\"' . substitute(v:val, '\\', '/', 'g') . '\"'") + + let args = a:type == 'windows' ? '-m ' : '' + let results = split(eclim#util#System('cygpath ' . args . join(paths)), "\n") + + if type(a:paths) == g:LIST_TYPE + return results + endif + return results[0] + endif + return a:paths +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/display/menu.vim b/vim/eclim/autoload/eclim/display/menu.vim @@ -0,0 +1,103 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Plugin to generate gvim eclim menus. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + +let s:eclim_menus_root = [] +let s:eclim_menus = {} + +" }}} + +" Generate() {{{ +" Generate gvim menu items for available eclim commands. +function! eclim#display#menu#Generate() + " check that the menu bar is enabled or that we are running in a mac gui where + " the menu bar always exists regardless of guioptions + if &guioptions !~ 'm' && !has('gui_macvim') + if exists('b:eclim_menus') + unlet b:eclim_menus + endif + return + endif + + redir => commands + silent exec 'command' + redir END + + if !exists('b:eclim_menus') + let b:eclim_menus = {} + + let pattern = '\<eclim#' + if len(s:eclim_menus_root) != 0 + let pattern = '^..b.*\<eclim#' + endif + + for cmd in split(commands, '\n') + if cmd =~ pattern + let name = substitute(cmd, '....\(\w\+\)\s.*', '\1', '') + if cmd =~ '\<eclim#[A-Z]' + if index(s:eclim_menus_root, name) == -1 + call add(s:eclim_menus_root, name) + endif + else + let group = substitute(cmd, '.\{-}\<eclim#\(\w\+\)#.*', '\1', '') + let var = cmd =~ '^..b' ? 'b:eclim_menus' : 's:eclim_menus' + if !has_key({var}, group) + let {var}[group] = [] + endif + if index({var}[group], name) == -1 + call add({var}[group], name) + endif + endif + endif + endfor + + call sort(s:eclim_menus_root) + endif + + silent! unmenu &Plugin.eclim + + " merge non-buffer items with buffer items + let menus = deepcopy(s:eclim_menus, 1) + for group in keys(b:eclim_menus) + if !has_key(menus, group) + let menus[group] = [] + endif + for name in b:eclim_menus[group] + call add(menus[group], name) + endfor + endfor + + for name in s:eclim_menus_root + exec 'menu &Plugin.eclim.' . name . ' :' . name . ' ' + endfor + + for group in sort(keys(menus)) + for name in sort(menus[group]) + exec 'menu &Plugin.eclim.' . group . '.' . name . ' :' . name . ' ' + endfor + endfor +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/display/signs.vim b/vim/eclim/autoload/eclim/display/signs.vim @@ -0,0 +1,388 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Functions for working with vim signs. +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists("g:EclimShowQuickfixSigns") + let g:EclimShowQuickfixSigns = 1 +endif + +if !exists("g:EclimShowLoclistSigns") + let g:EclimShowLoclistSigns = 1 +endif + +if !exists("g:EclimQuickfixSignText") + let g:EclimQuickfixSignText = '> ' +endif + +if !exists("g:EclimLoclistSignText") + let g:EclimLoclistSignText = '>>' +endif + +if !exists("g:EclimUserSignText") + let g:EclimUserSignText = '#' +endif + +if !exists("g:EclimUserSignHighlight") + let g:EclimUserSignHighlight = g:EclimInfoHighlight +endif +" }}} + +function! eclim#display#signs#Define(name, text, highlight) " {{{ + " Defines a new sign name or updates an existing one. + exec "sign define " . a:name . " text=" . a:text . " texthl=" . a:highlight +endfunction " }}} + +function! eclim#display#signs#Place(name, line) " {{{ + " Places a sign in the current buffer. + if a:line > 0 + let lastline = line('$') + let line = a:line <= lastline ? a:line : lastline + let id = a:name == 'placeholder' ? 999999 : line + exec "sign place " . id . " line=" . line . " name=" . a:name . + \ " buffer=" . bufnr('%') + endif +endfunction " }}} + +function! eclim#display#signs#PlaceAll(name, list) " {{{ + " Places a sign in the current buffer for each line in the list. + + let lastline = line('$') + for line in a:list + if line > 0 + let line = line <= lastline ? line : lastline + exec "sign place " . line . " line=" . line . " name=" . a:name . + \ " buffer=" . bufnr('%') + endif + endfor +endfunction " }}} + +function! eclim#display#signs#Undefine(name) " {{{ + " Undefines a sign name. + exec "sign undefine " . a:name +endfunction " }}} + +function! eclim#display#signs#Unplace(id) " {{{ + " Un-places a sign in the current buffer. + exec 'sign unplace ' . a:id . ' buffer=' . bufnr('%') +endfunction " }}} + +function! eclim#display#signs#UnplaceAll(list) " {{{ + " Un-places all signs in the supplied list from the current buffer. + " The list may be a list of ids or a list of dictionaries as returned by + " GetExisting() + + for sign in a:list + if type(sign) == g:DICT_TYPE + call eclim#display#signs#Unplace(sign['id']) + else + call eclim#display#signs#Unplace(sign) + endif + endfor +endfunction " }}} + +function! eclim#display#signs#Toggle(name, line) " {{{ + if !g:EclimSignLevel + call eclim#util#Echo('Eclim signs have been disabled.') + return + endif + + " Toggle a sign on the current line. + if a:line > 0 + let existing = eclim#display#signs#GetExisting(a:name) + let exists = len(filter(existing, "v:val['line'] == a:line")) + if exists + call eclim#display#signs#Unplace(a:line) + else + call eclim#display#signs#Place(a:name, a:line) + endif + endif +endfunction " }}} + +function! s:CompareSigns(s1, s2) " {{{ + " Used by ViewSigns to sort list of sign dictionaries. + + if a:s1.line == a:s2.line + return 0 + endif + if a:s1.line > a:s2.line + return 1 + endif + return -1 +endfunction " }}} + +function! eclim#display#signs#ViewSigns(name) " {{{ + " Open a window to view all placed signs with the given name in the current + " buffer. + + if !g:EclimSignLevel + call eclim#util#Echo('Eclim signs have been disabled.') + return + endif + + let filename = expand('%:p') + let signs = eclim#display#signs#GetExisting(a:name) + call sort(signs, 's:CompareSigns') + let content = map(signs, "v:val.line . '|' . getline(v:val.line)") + + call eclim#util#TempWindow('[Sign List]', content) + + set ft=qf + nnoremap <silent> <buffer> <cr> :call <SID>JumpToSign()<cr> + + " Store filename so that plugins can use it if necessary. + let b:filename = filename + augroup temp_window + autocmd! BufWinLeave <buffer> + call eclim#util#GoToBufferWindowRegister(filename) + augroup END +endfunction " }}} + +function! s:JumpToSign() " {{{ + let winnr = bufwinnr(bufnr('^' . b:filename)) + if winnr != -1 + let line = substitute(getline('.'), '^\(\d\+\)|.*', '\1', '') + exec winnr . "winc w" + call cursor(line, 1) + endif +endfunction " }}} + +function! eclim#display#signs#GetDefined() " {{{ + " Gets a list of defined sign names. + + redir => list + silent exec 'sign list' + redir END + + let names = [] + for name in split(list, '\n') + let name = substitute(name, 'sign\s\(.\{-}\)\s.*', '\1', '') + call add(names, name) + endfor + return names +endfunction " }}} + +function! eclim#display#signs#GetExisting(...) " {{{ + " Gets a list of existing signs for the current buffer. + " The list consists of dictionaries with the following keys: + " id: The sign id. + " line: The line number. + " name: The sign name (erorr, warning, etc.) + " + " Optionally a sign name may be supplied to only retrieve signs of that name. + + if !has('signs') || !g:EclimSignLevel + return [] + endif + + let bufnr = bufnr('%') + + redir => signs + silent exec 'sign place buffer=' . bufnr + redir END + + let existing = [] + for line in split(signs, '\n') + if line =~ '.\{-}=.\{-}=' " only two equals to account for swedish output + call add(existing, s:ParseSign(line)) + endif + endfor + + if len(a:000) > 0 + call filter(existing, "v:val['name'] == a:000[0]") + endif + + return existing +endfunction " }}} + +function! eclim#display#signs#HasExisting(...) " {{{ + " Determines if there are any existing signs. + " Optionally a sign name may be supplied to only test for signs of that name. + + if !has('signs') || !g:EclimSignLevel + return 0 + endif + + let bufnr = bufnr('%') + + redir => results + silent exec 'sign place buffer=' . bufnr + redir END + + for line in split(results, '\n') + if line =~ '.\{-}=.\{-}=' " only two equals to account for swedish output + if len(a:000) == 0 + return 1 + endif + let sign = s:ParseSign(line) + if sign.name == a:000[0] + return 1 + endif + endif + endfor + + return 0 +endfunction " }}} + +function! s:ParseSign(raw) " {{{ + let attrs = split(a:raw) + + exec 'let line = ' . split(attrs[0], '=')[1] + + let id = split(attrs[1], '=')[1] + " hack for the italian localization + if id =~ ',$' + let id = id[:-2] + endif + + " hack for the swedish localization + if attrs[2] =~ '^namn' + let name = substitute(attrs[2], 'namn=\?', '', '') + else + let name = split(attrs[2], '=')[1] + endif + + return {'id': id, 'line': line, 'name': name} +endfunction " }}} + +function! eclim#display#signs#Update() " {{{ + " Updates the signs for the current buffer. This function will read both the + " location list and the quickfix list and place a sign for any entries for the + " current file. + " This function supports a severity level by examining the 'type' key of the + " dictionaries in the location or quickfix list. It supports 'i' (info), 'w' + " (warning), and 'e' (error). + + if !has('signs') || !g:EclimSignLevel || &ft == 'qf' + return + endif + + let save_lazy = &lazyredraw + set lazyredraw + + let placeholder = eclim#display#signs#SetPlaceholder() + + " remove all existing signs + let existing = eclim#display#signs#GetExisting() + for exists in existing + if exists.name =~ '^\(qf_\)\?\(error\|info\|warning\)$' + call eclim#display#signs#Unplace(exists.id) + endif + endfor + + let qflist = filter(g:EclimShowQuickfixSigns ? getqflist() : [], + \ 'bufnr("%") == v:val.bufnr') + let show_loclist = g:EclimShowLoclistSigns && exists('b:eclim_loclist') + let loclist = filter(show_loclist ? getloclist(0) : [], + \ 'bufnr("%") == v:val.bufnr') + + for [list, marker, prefix] in [ + \ [qflist, g:EclimQuickfixSignText, 'qf_'], + \ [loclist, g:EclimLoclistSignText, '']] + if g:EclimSignLevel >= 4 + let info = filter(copy(list), 'v:val.type == "" || tolower(v:val.type) == "i"') + call eclim#display#signs#Define(prefix . 'info', marker, g:EclimInfoHighlight) + call eclim#display#signs#PlaceAll(prefix . 'info', map(info, 'v:val.lnum')) + endif + + if g:EclimSignLevel >= 3 + let warnings = filter(copy(list), 'tolower(v:val.type) == "w"') + call eclim#display#signs#Define(prefix . 'warning', marker, g:EclimWarningHighlight) + call eclim#display#signs#PlaceAll(prefix . 'warning', map(warnings, 'v:val.lnum')) + endif + + if g:EclimSignLevel >= 2 + let errors = filter(copy(list), 'tolower(v:val.type) == "e"') + call eclim#display#signs#Define(prefix . 'error', marker, g:EclimErrorHighlight) + call eclim#display#signs#PlaceAll(prefix . 'error', map(errors, 'v:val.lnum')) + endif + endfor + + if placeholder + call eclim#display#signs#RemovePlaceholder() + endif + + let &lazyredraw = save_lazy +endfunction " }}} + +function! eclim#display#signs#QuickFixCmdPost() " {{{ + " Force 'make' results to be of type error if no type set. + if expand('<amatch>') == 'make' + let newentries = [] + for entry in getqflist() + if entry['type'] == '' + let entry['type'] = 'e' + endif + call add(newentries, entry) + endfor + call setqflist(newentries, 'r') + endif + call eclim#display#signs#Update() + redraw! +endfunction " }}} + +function! eclim#display#signs#SetPlaceholder(...) " {{{ + " Set sign at line 1 to prevent sign column from collapsing, and subsiquent + " screen redraw. + " Optional args: + " only_if_necessary: if 1, only set a placeholder if there are no existing + " signs + + if !has('signs') || !g:EclimSignLevel + return + endif + + if len(a:000) > 0 && a:000[0] + let existing = eclim#display#signs#GetExisting() + if !len(existing) + return + endif + endif + + call eclim#display#signs#Define('placeholder', '_ ', g:EclimInfoHighlight) + let existing = eclim#display#signs#GetExisting('placeholder') + if len(existing) == 0 && eclim#display#signs#HasExisting() + call eclim#display#signs#Place('placeholder', 1) + return 1 + endif + return +endfunction " }}} + +function! eclim#display#signs#RemovePlaceholder() " {{{ + if !has('signs') || !g:EclimSignLevel + return + endif + + let existing = eclim#display#signs#GetExisting('placeholder') + for exists in existing + call eclim#display#signs#Unplace(exists.id) + endfor +endfunction " }}} + +" define signs for manually added user marks. +if has('signs') + call eclim#display#signs#Define( + \ 'user', g:EclimUserSignText, g:EclimUserSignHighlight) +endif + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/display/window.vim b/vim/eclim/autoload/eclim/display/window.vim @@ -0,0 +1,352 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Utility functions for working with vim windows. +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" GlobalVariables {{{ +let g:VerticalToolBuffers = {} + +if !exists('g:VerticalToolWindowSide') + let g:VerticalToolWindowSide = 'left' +endif + +if g:VerticalToolWindowSide == 'right' + let g:VerticalToolWindowPosition = 'botright vertical' +else + let g:VerticalToolWindowPosition = 'topleft vertical' +endif + +if !exists('g:VerticalToolWindowWidth') + let g:VerticalToolWindowWidth = 30 +endif +" }}} + +function! eclim#display#window#VerticalToolWindowOpen(name, weight, ...) " {{{ + " Handles opening windows in the vertical tool window on the left (taglist, + " project tree, etc.) + + let taglist_window = -1 + if exists('g:TagList_title') + let taglist_window = bufwinnr(eclim#util#EscapeBufferName(g:TagList_title)) + let taglist_position = 'left' + if exists('g:Tlist_Use_Horiz_Window') && g:Tlist_Use_Horiz_Window + let taglist_position = 'horizontal' + elseif exists('g:TaglistTooPosition') + let taglist_position = g:TaglistTooPosition + elseif exists('g:Tlist_Use_Right_Window') && g:Tlist_Use_Right_Window + let taglist_position = 'right' + endif + endif + if taglist_window == -1 && exists(':TagbarOpen') + let taglist_window = bufwinnr('__Tagbar__') + let taglist_position = 'right' + if exists('g:tagbar_left') && g:tagbar_left + let taglist_position = 'left' + endif + endif + if taglist_window != -1 + " don't consider horizontal taglist, or taglist configured to display + " opposite the tool windows as a tool window member. + if taglist_position != g:VerticalToolWindowSide + let taglist_window = -1 + endif + endif + + + let relative_window = 0 + let relative_window_loc = 'below' + if taglist_window != -1 || len(g:VerticalToolBuffers) > 0 + if taglist_window != -1 + let relative_window = taglist_window + endif + for toolbuf in keys(g:VerticalToolBuffers) + exec 'let toolbuf = ' . toolbuf + if bufwinnr(toolbuf) != -1 + if relative_window == 0 + let relative_window = bufwinnr(toolbuf) + if getbufvar(toolbuf, 'weight') > a:weight + let relative_window_loc = 'below' + else + let relative_window_loc = 'above' + endif + elseif getbufvar(toolbuf, 'weight') > a:weight + let relative_window = bufwinnr(toolbuf) + let relative_window_loc = 'below' + endif + endif + endfor + endif + + if relative_window != 0 + let wincmd = relative_window . 'winc w | ' . relative_window_loc . ' ' + else + let wincmd = g:VerticalToolWindowPosition . ' ' . g:VerticalToolWindowWidth + endif + + let escaped = substitute( + \ a:name, '\(.\{-}\)\[\(.\{-}\)\]\(.\{-}\)', '\1[[]\2[]]\3', 'g') + if a:0 && a:1 + let bufnum = -1 + for bnr in tabpagebuflist() + if bufname(bnr) == a:name + let bufnum = bnr + break + endif + endfor + else + let bufnum = bufnr(escaped) + endif + let name = bufnum == -1 ? a:name : '+buffer' . bufnum + silent call eclim#util#ExecWithoutAutocmds(wincmd . ' split ' . name) + + doautocmd BufWinEnter + setlocal winfixwidth + setlocal nonumber + setlocal nospell norelativenumber + + let b:weight = a:weight + let bufnum = bufnr('%') + let g:VerticalToolBuffers[bufnum] = a:name + augroup eclim_vertical_tool_windows + autocmd! + autocmd BufDelete * call s:PreventCloseOnBufferDelete() + autocmd BufEnter * nested call s:CloseIfLastWindow() + augroup END + + if exists('g:TagList_title') && + \ (!exists('g:Tlist_Use_Horiz_Window') || !g:Tlist_Use_Horiz_Window) + augroup eclim_vertical_tool_windows_move_taglist + autocmd! + exec 'autocmd BufWinEnter ' . eclim#util#EscapeBufferName(g:TagList_title) . + \ ' call s:MoveRelativeTo()' + augroup END + endif + if exists(':TagbarOpen') + augroup eclim_vertical_tool_windows_move_tagbar + autocmd! + autocmd BufWinEnter __Tagbar__ call s:MoveRelativeTo() + augroup END + endif + augroup eclim_vertical_tool_windows_buffer + exec 'autocmd BufWinLeave <buffer> ' . + \ 'silent! call remove(g:VerticalToolBuffers, ' . bufnum . ') | ' . + \ 'autocmd! eclim_vertical_tool_windows_buffer * <buffer=' . bufnum . '>' + augroup END +endfunction " }}} + +function! eclim#display#window#VerticalToolWindowRestore() " {{{ + " Used to restore the tool windows to their proper width if some action + " altered them. + + for toolbuf in keys(g:VerticalToolBuffers) + exec 'let toolbuf = ' . toolbuf + if bufwinnr(toolbuf) != -1 + exec 'vertical ' . bufwinnr(toolbuf) . 'resize ' . g:VerticalToolWindowWidth + endif + endfor +endfunction " }}} + +function! eclim#display#window#GetWindowOptions(winnum) " {{{ + " Gets a dictionary containing all the localy set options for the specified + " window. + + let curwin = winnr() + try + exec a:winnum . 'winc w' + redir => list + silent exec 'setlocal' + redir END + finally + exec curwin . 'winc w' + endtry + + let list = substitute(list, '---.\{-}---', '', '') + let winopts = {} + for wopt in split(list, '\(\n\|\s\s\+\)')[1:] + if wopt =~ '^[a-z]' + if wopt =~ '=' + let key = substitute(wopt, '\(.\{-}\)=.*', '\1', '') + let value = substitute(wopt, '.\{-}=\(.*\)', '\1', '') + let winopts[key] = value + else + let winopts[wopt] = '' + endif + endif + endfor + return winopts +endfunction " }}} + +function! eclim#display#window#SetWindowOptions(winnum, options) " {{{ + " Given a dictionary of options, sets each as local options for the specified + " window. + + let curwin = winnr() + try + exec a:winnum . 'winc w' + for key in keys(a:options) + if key =~ '^no' + silent! exec 'setlocal ' . key + else + silent! exec 'setlocal ' . key . '=' . escape(a:options[key], ' ') + endif + endfor + finally + exec curwin . 'winc w' + endtry +endfunction " }}} + +function! s:CloseIfLastWindow() " {{{ + if histget(':', -1) !~ '^bd' + let close = 1 + for bufnr in tabpagebuflist() + if has_key(g:VerticalToolBuffers, bufnr) + continue + endif + if exists('g:TagList_title') && bufname(bufnr) == g:TagList_title + continue + endif + if exists('g:BufExplorer_title') && bufname(bufnr) == '[BufExplorer]' + let close = 0 + break + endif + + let buftype = getbufvar(bufnr, '&buftype') + if buftype != '' && buftype != 'help' + continue + endif + + let close = 0 + break + endfor + + if close + if tabpagenr('$') > 1 + tabclose + else + quitall + endif + endif + endif +endfunction " }}} + +function! s:MoveRelativeTo() " {{{ + " get the buffer that the taglist was opened from + let curwin = winnr() + let list_buffer = bufnr('%') + winc p + let orig_buffer = bufnr('%') + exec curwin . 'winc p' + + for toolbuf in keys(g:VerticalToolBuffers) + exec 'let toolbuf = ' . toolbuf + if bufwinnr(toolbuf) != -1 + call setwinvar(bufwinnr(toolbuf), 'marked_for_removal', 1) + let winoptions = eclim#display#window#GetWindowOptions(bufwinnr(toolbuf)) + call remove(winoptions, 'filetype') + call remove(winoptions, 'syntax') + call eclim#display#window#VerticalToolWindowOpen( + \ g:VerticalToolBuffers[toolbuf], getbufvar(toolbuf, 'weight')) + call eclim#display#window#SetWindowOptions(winnr(), winoptions) + endif + endfor + + let winnum = 1 + while winnum <= winnr('$') + if getwinvar(winnum, 'marked_for_removal') == 1 + exec winnum . 'winc w' + close + else + let winnum += 1 + endif + endwhile + call eclim#display#window#VerticalToolWindowRestore() + + " some window juggling so that winc p from taglist goes back to the original + " buffer + exec bufwinnr(orig_buffer) . 'winc w' + exec bufwinnr(list_buffer) . 'winc w' +endfunction " }}} + +function! s:PreventCloseOnBufferDelete() " {{{ + let index = 1 + let numtoolwindows = 0 + let numtempwindows = 0 + let tempbuffersbot = [] + while index <= winnr('$') + let buf = winbufnr(index) + let bufname = bufname(buf) + if index(keys(g:VerticalToolBuffers), string(buf)) != -1 + let numtoolwindows += 1 + elseif getwinvar(index, '&winfixheight') || getwinvar(index, '&winfixwidth') + let numtempwindows += 1 + if getwinvar(index, '&winfixheight') + call add(tempbuffersbot, buf) + endif + endif + let index += 1 + endwhile + + if winnr('$') == (numtoolwindows + numtempwindows) + let toolbuf = bufnr('%') + if g:VerticalToolWindowSide == 'right' + vertical topleft new + else + vertical botright new + endif + setlocal noreadonly modifiable + let curbuf = bufnr('%') + let removed = str2nr(expand('<abuf>')) + let next = eclim#common#buffers#OpenNextHiddenTabBuffer(removed) + if next != 0 + let curbuf = next + endif + + " resize windows + exec bufwinnr(toolbuf) . 'winc w' + exec 'vertical resize ' . g:VerticalToolWindowWidth + + " fix the position of the temp windows + for buf in tempbuffersbot + " open the buffer in the temp window position + botright 10new + exec 'buffer ' . buf + setlocal winfixheight + + " close the old window + let winnr = winnr() + let index = 1 + while index <= winnr('$') + if winbufnr(index) == buf && index != winnr + exec index . 'winc w' + close + winc p + break + endif + let index += 1 + endwhile + endfor + + exec bufwinnr(curbuf) . 'winc w' + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/help.vim b/vim/eclim/autoload/eclim/help.vim @@ -0,0 +1,169 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Commands view / search eclim help files. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + let g:EclimHelpDir = g:EclimBaseDir . '/eclim/doc' +" }}} + +" Help(tag) {{{ +function! eclim#help#Help(tag, link) + if !filereadable(substitute(g:EclimHelpDir, '\\\s', ' ', 'g') . '/tags') + call eclim#util#Echo('indexing eclim help files...') + exec 'helptags ' . g:EclimHelpDir + let paths = split(glob(g:EclimHelpDir . '/**/*'), '\n') + call filter(paths, 'isdirectory(v:val)') + for path in paths + exec 'helptags ' . path + endfor + call eclim#util#Echo('eclim help files indexed') + endif + + let savetags = &tags + exec 'set tags=' . escape(escape(g:EclimHelpDir, ' '), ' ') . '/**/tags' + try + let tag = a:tag + if tag == '' && !a:link + let tag = 'index' + elseif tag =='' + let line = getline('.') + let tag = substitute( + \ line, '.*|\(\S\{-}\%' . col('.') . 'c\S\{-}\)|.*', '\1', '') + if tag == line + return + endif + endif + + call s:HelpWindow() + exec 'tag ' . tag + let w:eclim_help = 1 + + " needed to ensure taglist is updated if open + doautocmd BufEnter + catch /^Vim\%((\a\+)\)\=:E426/ + if !exists('w:eclim_help') + close + endif + call eclim#util#EchoError('Sorry no eclim help for ' . tag) + finally + let &tags = savetags + endtry +endfunction " }}} + +" HelpGrep() {{{ +function! eclim#help#HelpGrep(args) + exec 'vimgrep ' a:args . ' ' . g:EclimHelpDir . '/**/*.txt' +endfunction " }}} + +" s:HelpWindow() {{{ +function s:HelpWindow() + let max = winnr('$') + let index = 1 + while index <= max + if getwinvar(index, 'eclim_help') + exec index . 'winc w' + return + endif + let index += 1 + endwhile + + new +endfunction " }}} + +" BufferHelp(lines, orientation, size) {{{ +" Function to display a help window for the current buffer. +function! eclim#help#BufferHelp(lines, orientation, size) + let orig_bufnr = bufnr('%') + let name = expand('%') + if name =~ '^\W.*\W$' + let name = name[:-2] . ' Help' . name[len(name) - 1] + else + let name .= ' Help' + endif + + let bname = eclim#util#EscapeBufferName(name) + + let orient = a:orientation == 'vertical' ? 'v' : '' + if bufwinnr(bname) != -1 + exec 'bd ' . bufnr(bname) + return + endif + + silent! noautocmd exec a:size . orient . "new " . escape(name, ' ') + if a:orientation == 'vertical' + setlocal winfixwidth + else + setlocal winfixheight + endif + setlocal nowrap + setlocal noswapfile nobuflisted nonumber + setlocal nospell norelativenumber + setlocal buftype=nofile bufhidden=delete + nnoremap <buffer> <silent> ? :bd<cr> + nnoremap <buffer> <silent> q :bd<cr> + + setlocal modifiable noreadonly + silent 1,$delete _ + call append(1, a:lines) + retab + silent 1,1delete _ + + if len(a:000) == 0 || a:000[0] + setlocal nomodified nomodifiable readonly + endif + + let help_bufnr = bufnr('%') + augroup eclim_help_buffer + autocmd! BufWinLeave <buffer> + autocmd BufWinLeave <buffer> nested autocmd! eclim_help_buffer * <buffer> + exec 'autocmd BufWinLeave <buffer> nested ' . + \ 'autocmd! eclim_help_buffer * <buffer=' . orig_bufnr . '>' + exec 'autocmd! BufWinLeave <buffer=' . orig_bufnr . '>' + exec 'autocmd BufWinLeave <buffer=' . orig_bufnr . '> nested bd ' . help_bufnr + augroup END + + return help_bufnr +endfunction " }}} + +" CommandComplete(argLead, cmdLine, cursorPos) {{{ +function! eclim#help#CommandCompleteTag(argLead, cmdLine, cursorPos) + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + + let savetags = &tags + exec 'set tags=' . escape(escape(g:EclimHelpDir, ' '), ' ') . '/**/tags' + try + let tags = sort(map(taglist(argLead . '.*'), "v:val['name']")) + let results = [] + for tag in tags + if index(results, tag) == -1 + call add(results, tag) + endif + endfor + return results + finally + let &tags = savetags + endtry +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/html/complete.vim b/vim/eclim/autoload/eclim/html/complete.vim @@ -0,0 +1,59 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/html/complete.html +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command html_complete -p "<project>" -f "<file>" -o <offset> -e <encoding>' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles html code completion. +function! eclim#html#complete#CodeComplete(findstart, base) + "if eclim#html#util#InJavascriptBlock() + " return eclim#javascript#complete#CodeComplete(a:findstart, a:base) + "endif + + if eclim#html#util#InCssBlock() + return eclim#css#complete#CodeComplete(a:findstart, a:base) + endif + + if a:findstart + call eclim#lang#SilentUpdate(1) + + " locate the start of the word + let line = getline('.') + + let start = col('.') - 1 + + while start > 0 && line[start - 1] =~ '[[:alnum:]_-]' + let start -= 1 + endwhile + + return start + else + return eclim#lang#CodeComplete(s:complete_command, a:findstart, a:base) + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/html/util.vim b/vim/eclim/autoload/eclim/html/util.vim @@ -0,0 +1,135 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Various html relatd functions. +" +" License: +" +" Copyright (C) 2005 - 2009 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" HtmlToText() {{{ +" Converts the supplied basic html to text. +function! eclim#html#util#HtmlToText(html) + let text = a:html + let text = substitute(text, '<br/\?>\c', '\n', 'g') + let text = substitute(text, '</\?b>\c', '', 'g') + let text = substitute(text, '</\?ul>\c', '', 'g') + let text = substitute(text, '<li>\c', '- ', 'g') + let text = substitute(text, '</li>\c', '', 'g') + let text = substitute(text, '</\?p/\?>\c', '', 'g') + let text = substitute(text, '</\?code>\c', '', 'g') + let text = substitute(text, '</\?pre>\c', '', 'g') + let text = substitute(text, '<a .\{-}>\c', '', 'g') + let text = substitute(text, '</a>', '', 'g') + let text = substitute(text, '&quot;\c', '"', 'g') + let text = substitute(text, '&amp;\c', '&', 'g') + let text = substitute(text, '&lt;\c', '<', 'g') + let text = substitute(text, '&gt;\c', '>', 'g') + + return text +endfunction " }}} + +" InCssBlock() {{{ +" Determines if the cusor is inside of <style> tags. +function! eclim#html#util#InCssBlock() + let line = line('.') + + let stylestart = search('<style\>', 'bcWn') + if stylestart > 0 + let styleend = search('</style\s*>', 'bWn') + endif + if stylestart > 0 && stylestart < line && + \ (styleend == 0 || (styleend > stylestart && line < styleend)) + return stylestart + endif + + return 0 +endfunction " }}} + +" InJavascriptBlock() {{{ +" Determines if the cursor is inside of <script> tags. +function! eclim#html#util#InJavascriptBlock() + let line = line('.') + + let scriptstart = search('<script\>', 'bcWn') + if scriptstart > 0 + let scriptend = search('</script\s*>', 'bWn') + endif + if scriptstart > 0 && scriptstart < line && + \ (scriptend == 0 || (scriptend > scriptstart && line < scriptend)) + return scriptstart + endif + + return 0 +endfunction " }}} + +" OpenInBrowser(file) {{{ +function! eclim#html#util#OpenInBrowser(file) + let file = a:file + if file == '' + let file = expand('%:p') + else + let file = getcwd() . '/' . file + endif + let url = 'file://' . file + call eclim#web#OpenUrl(url) +endfunction " }}} + +" UrlEncode(string) {{{ +function! eclim#html#util#UrlEncode(string) + let result = a:string + + " must be first + let result = substitute(result, '%', '%25', 'g') + + let result = substitute(result, '\s', '%20', 'g') + let result = substitute(result, '!', '%21', 'g') + let result = substitute(result, '"', '%22', 'g') + let result = substitute(result, '#', '%23', 'g') + let result = substitute(result, '\$', '%24', 'g') + let result = substitute(result, '&', '%26', 'g') + let result = substitute(result, "'", '%27', 'g') + let result = substitute(result, '(', '%28', 'g') + let result = substitute(result, ')', '%29', 'g') + let result = substitute(result, '*', '%2A', 'g') + let result = substitute(result, '+', '%2B', 'g') + let result = substitute(result, ',', '%2C', 'g') + let result = substitute(result, '-', '%2D', 'g') + let result = substitute(result, '\.', '%2E', 'g') + let result = substitute(result, '\/', '%2F', 'g') + let result = substitute(result, ':', '%3A', 'g') + let result = substitute(result, ';', '%3B', 'g') + let result = substitute(result, '<', '%3C', 'g') + let result = substitute(result, '=', '%3D', 'g') + let result = substitute(result, '>', '%3E', 'g') + let result = substitute(result, '?', '%3F', 'g') + let result = substitute(result, '@', '%40', 'g') + let result = substitute(result, '[', '%5B', 'g') + let result = substitute(result, '\\', '%5C', 'g') + let result = substitute(result, ']', '%5D', 'g') + let result = substitute(result, '\^', '%5E', 'g') + let result = substitute(result, '`', '%60', 'g') + let result = substitute(result, '{', '%7B', 'g') + let result = substitute(result, '|', '%7C', 'g') + let result = substitute(result, '}', '%7D', 'g') + let result = substitute(result, '\~', '%7E', 'g') + + return result +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/html/validate.vim b/vim/eclim/autoload/eclim/html/validate.vim @@ -0,0 +1,64 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/html/validate.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +function! eclim#html#validate#Validate(on_save) " {{{ + let validate = !a:on_save || ( + \ g:EclimHtmlValidate && + \ (!exists('g:EclimFileTypeValidate') || g:EclimFileTypeValidate)) + + if !validate || eclim#util#WillWrittenBufferClose() + return + endif + + if !eclim#project#util#IsCurrentFileInProject(!a:on_save) + return + endif + + " prevent closing of sign column between validation methods + call eclim#display#signs#SetPlaceholder() + + call eclim#lang#Validate('html', a:on_save) + + " prevent closing of sign column between validation methods + "call eclim#display#signs#SetPlaceholder() + + " disabled for now since the parser will attempt to follow all style tags + " and interprets //domain.com/styles.css as an ftp path leading to + " long validation delays due to connection timeouts. + "let html_errors = getloclist(0) + "let css_errors = [] + "if search('<style', 'cnw') + " call eclim#lang#Validate('css', a:on_save) + " let css_errors = getloclist(0) + "endif + + "call eclim#util#SetLocationList(html_errors + css_errors) + + if search('<script', 'cnw') + call eclim#javascript#util#UpdateSrcFile(a:on_save) + endif + call eclim#display#signs#RemovePlaceholder() +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/ant/complete.vim b/vim/eclim/autoload/eclim/java/ant/complete.vim @@ -0,0 +1,144 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/ant/complete.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command ant_complete -p "<project>" -f "<file>" -o <offset> -e <encoding>' + let s:command_targets = '-command ant_targets -p "<project>" -f "<file>"' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles ant code completion. +function! eclim#java#ant#complete#CodeComplete(findstart, base) + if !eclim#project#util#IsCurrentFileInProject(0) + return a:findstart ? -1 : [] + endif + + if a:findstart + call eclim#lang#SilentUpdate(1) + + " locate the start of the word + let line = getline('.') + + let start = col('.') - 1 + + "exceptions that break the rule + if line[start - 1] == '.' + let start -= 1 + endif + + " always start in front of the the '<' + if line[start] == '<' + let start += 1 + endif + + while start > 0 && line[start - 1] =~ '\w' + let start -= 1 + endwhile + + " if prev char is '/' then back off the start pos, since the completion + " result will contain the '/'. + if line[start - 1] == '/' + let start -= 1 + endif + + return start + else + let offset = eclim#util#GetOffset() + len(a:base) - 1 + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate(1, 0) + if file == '' + return [] + endif + + let command = s:complete_command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + let completions = [] + let results = eclim#Execute(command) + if type(results) != g:LIST_TYPE + return + endif + + " if the word has a '.' in it (like package completion) then we need to + " strip some off according to what is currently in the buffer. + let prefix = substitute(getline('.'), + \ '.\{-}\([[:alnum:].]\+\%' . col('.') . 'c\).*', '\1', '') + + for result in results + let word = result.completion + " removed '<' and '>' from end tag results + let word = substitute(word, '^<\(.*\)>$', '\1', '') + + " strip off prefix if necessary. + if word =~ '\.' + let word = substitute(word, escape(prefix, '*'), '', '') + endif + + let menu = eclim#html#util#HtmlToText(result.menu) + let info = eclim#html#util#HtmlToText(result.info) + + let dict = {'word': word, 'menu': menu, 'info': info} + + call add(completions, dict) + endfor + + return completions + endif +endfunction " }}} + +" CommandCompleteTarget(argLead, cmdLine, cursorPos) {{{ +" Custom command completion for ant targets. +function! eclim#java#ant#complete#CommandCompleteTarget(argLead, cmdLine, cursorPos) + let project = eclim#project#util#GetCurrentProjectName() + if project == '' + return [] + endif + + let file = eclim#java#ant#util#FindBuildFile() + if project != "" && file != "" + let file = eclim#project#util#GetProjectRelativeFilePath(file) + let command = s:command_targets + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + + let targets = eclim#Execute(command) + if type(targets) != g:LIST_TYPE + return [] + endif + + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + call filter(targets, 'v:val =~ "^' . argLead . '"') + + return targets + endif + + return [] +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/ant/doc.vim b/vim/eclim/autoload/eclim/java/ant/doc.vim @@ -0,0 +1,171 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/ant/doc.html +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ +if !exists("g:AntDocDefaultUrl") + let g:AntDocDefaultUrl = + \ 'http://www.google.com/search?btnI=1&q=allintitle%3A<element>+task+%7C+type+site%3Aant.apache.org' +endif + +if !exists("g:AntUserDocs") + let g:AntUserDocs = {} +endif +" }}} + +" Script Varables {{{ +let s:targets = 'http://ant.apache.org/manual/targets.html' +let s:using = 'http://ant.apache.org/manual/using.html#<element>s' +let s:conditions = 'http://ant.apache.org/manual/Tasks/conditions.html#<element>' +let s:mappers = 'http://ant.apache.org/manual/Types/mapper.html' +let s:paths = 'http://ant.apache.org/manual/using.html#path' +let s:types = + \ 'http://ant.apache.org/manual/Types/<element>.html' +let s:selectors = + \ 'http://ant.apache.org/manual/Types/selectors.html#<element>select' +let s:contrib_1 = + \ 'http://ant-contrib.sourceforge.net/tasks/tasks/<element>.html' +let s:contrib_2 = + \ 'http://ant-contrib.sourceforge.net/tasks/tasks/<element>_task.html' +let s:element_docs = { + \ 'project' : s:using, + \ 'target' : s:targets, + \ 'and' : s:conditions, + \ 'checksum' : s:conditions, + \ 'checs' : s:conditions, + \ 'contains' : s:conditions, + \ 'equals' : s:conditions, + \ 'filesmatch' : s:conditions, + \ 'http' : s:conditions, + \ 'isfalse' : s:conditions, + \ 'isfileselected' : s:conditions, + \ 'isreference' : s:conditions, + \ 'isset' : s:conditions, + \ 'istrue' : s:conditions, + \ 'length' : s:conditions, + \ 'not' : s:conditions, + \ 'or' : s:conditions, + \ 'os' : s:conditions, + \ 'socket' : s:conditions, + \ 'compositemapper' : s:mappers, + \ 'filtermapper' : s:mappers, + \ 'flattenmapper' : s:mappers, + \ 'globmapper' : s:mappers, + \ 'identitymapper' : s:mappers, + \ 'mergemapper' : s:mappers, + \ 'packagemapper' : s:mappers, + \ 'regexmapper' : s:mappers, + \ 'antlib' : s:types, + \ 'description' : s:types, + \ 'dirset' : s:types, + \ 'filelist' : s:types, + \ 'fileset' : s:types, + \ 'filterchain' : s:types, + \ 'filterset' : s:types, + \ 'mapper' : s:types, + \ 'patternset' : s:types, + \ 'permissions' : s:types, + \ 'propertyset' : s:types, + \ 'redirector' : s:types, + \ 'regexp' : s:types, + \ 'xmlcatalog' : s:types, + \ 'zipfileset' : s:types, + \ 'classpath' : s:paths, + \ 'path' : s:paths, + \ 'containsregexp' : s:selectors, + \ 'date' : s:selectors, + \ 'depend' : s:selectors, + \ 'depth' : s:selectors, + \ 'different' : s:selectors, + \ 'filename' : s:selectors, + \ 'majority' : s:selectors, + \ 'modified' : s:selectors, + \ 'none' : s:selectors, + \ 'present' : s:selectors, + \ 'selector' : s:selectors, + \ 'size' : s:selectors, + \ 'type' : s:selectors, + \ 'for' : s:contrib_1, + \ 'foreach' : s:contrib_1, + \ 'if' : s:contrib_1, + \ 'outofdate' : s:contrib_1, + \ 'runtarget' : s:contrib_1, + \ 'switch' : s:contrib_1, + \ 'throw' : s:contrib_1, + \ 'timestampselector' : s:contrib_1, + \ 'trycatch' : s:contrib_1, + \ 'osfamily' : s:contrib_1, + \ 'shellscript' : s:contrib_1, + \ 'propertycopy' : s:contrib_1, + \ 'propertyselector' : s:contrib_1, + \ 'pathoffileset' : s:contrib_1, + \ 'propertyregex' : s:contrib_1, + \ 'sortlist' : s:contrib_1, + \ 'urlencode' : s:contrib_1, + \ 'forget' : s:contrib_1, + \ 'compilewithwalls' : s:contrib_1, + \ 'inifile' : s:contrib_1, + \ 'verifydesign' : s:contrib_1, + \ 'antcallback' : s:contrib_2, + \ 'antfetch' : s:contrib_2, + \ 'assert' : s:contrib_2, + \ 'post' : s:contrib_2, + \ 'stopwatch' : s:contrib_2, + \ 'match' : s:contrib_2, + \ 'variable' : s:contrib_2, + \ 'limit' : s:contrib_2, + \ 'antclipse' : s:contrib_2 + \ } +" }}} + +" FindDoc(element) {{{ +" Open the url to the documentation for the supplied element name or if not +" provided, the element name under the cursor. +function! eclim#java#ant#doc#FindDoc(element) + let element = a:element + if element == '' + let col = eclim#util#GetCurrentElementColumn() + if getline('.')[col - 2] !~ '<\|\/' + " not on an element + return + endif + let element = expand('<cword>') + endif + let element = tolower(element) + + if has_key(s:element_docs, element) + let url = s:element_docs[element] + elseif has_key(g:AntUserDocs, element) + let url = g:AntUserDocs[element] + else + let url = g:AntDocDefaultUrl + endif + + "let url = escape(url, '&%#') + "let url = escape(url, '%#') + let url = substitute(url, '<element>', element, 'g') + + call eclim#web#OpenUrl(url) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/ant/ivy.vim b/vim/eclim/autoload/eclim/java/ant/ivy.vim @@ -0,0 +1,31 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/classpath.html +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" SetRepo(path) {{{ +" Sets the location of the ivy repository. +function! eclim#java#ant#ivy#SetRepo(path) + call eclim#java#classpath#VariableCreate('IVY_REPO', a:path) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/ant/util.vim b/vim/eclim/autoload/eclim/java/ant/util.vim @@ -0,0 +1,36 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Utility functions for working with ant. +" +" License: +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" FindBuildFile() {{{ +" Finds the build file relative to the current file (like ant -find). +function! eclim#java#ant#util#FindBuildFile() + let buildFile = eclim#util#Findfile('build.xml', fnamemodify(expand('%:p'), ':h') . ';') + if filereadable(buildFile) + return substitute(fnamemodify(buildFile, ':p'), '\', '/', 'g') + endif + + return '' +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/classpath.vim b/vim/eclim/autoload/eclim/java/classpath.vim @@ -0,0 +1,241 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/classpath.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:command_variables = '-command java_classpath_variables' + let s:command_variable_create = + \ '-command java_classpath_variable_create -n "<name>" -p "<path>"' + let s:command_variable_delete = + \ '-command java_classpath_variable_delete -n "<name>"' + + let s:entry_project = + \ "\t<classpathentry exported=\"true\" kind=\"src\" path=\"/<path>\"/>" + let s:entry ="\t<classpathentry kind=\"<kind>\" path=\"<path>\"/>" + let s:entry_sourcepath = + \ "\t<classpathentry kind=\"<kind>\" path=\"<path>\"\n\t\t\tsourcepath=\"<src>\"/>" + let s:entry_javadoc = + \ "\t<classpathentry kind=\"<kind>\" path=\"<path>\"\n" . + \ "\t\t\tsourcepath=\"<src>\">\n" . + \ "\t\t<attributes>\n" . + \ "\t\t\t<attribute name=\"javadoc_location\" value=\"<javadoc>\"/>\n" . + \ "\t\t</attributes>\n" . + \ "\t</classpathentry>" +" }}} + +function! eclim#java#classpath#NewClasspathEntry(kind, arg, ...) " {{{ + " Adds a new entry to the current .classpath file. + let template_name = 's:entry' + let args = {'kind': a:kind, 'path': substitute(a:arg, '\', '/', 'g')} + if a:0 + if a:0 == 1 + let template_name = 's:entry_sourcepath' + let args['src'] = substitute(a:1, '\', '/', 'g') + elseif a:0 == 2 + let template_name = 's:entry_javadoc' + let args['src'] = substitute(a:1, '\', '/', 'g') + let javadoc = substitute(a:2, '\', '/', 'g') + let absolute = javadoc =~? '^\([a-z]:\)\?/' + + " handle absolute vs project relative javadoc location + if absolute + " windows paths need a leading slash + if javadoc =~? '^[a-z]:/' + let javadoc = '/' . javadoc + endif + let javadoc = 'file:' . javadoc + else + if !eclim#project#util#IsCurrentFileInProject(1) + return + endif + if javadoc =~? '\.jar$' + let project = eclim#project#util#GetCurrentProjectName() + let javadoc = 'platform:/resource/' . project . '/' . javadoc + else + " relative dirs must be made absolute + let project = eclim#project#util#GetCurrentProjectRoot() + let javadoc = project . '/' . javadoc + endif + endif + + if javadoc =~? '\.jar$' + let javadoc = 'jar:' . javadoc . '!/' + elseif javadoc !~ '^file:' + let javadoc = 'file:' . javadoc + endif + let args['javadoc'] = javadoc + else + call eclim#util#EchoError('Too many arguments.') + return + endif + endif + + if exists(template_name . '_' . a:kind) + let template = {template_name}_{a:kind} + else + let template = {template_name} + endif + + for [key, value] in items(args) + let template = substitute(template, '<' . key . '>', value, 'g') + endfor + + let cline = line('.') + let ccol = col('.') + call s:MoveToInsertPosition() + let line = line('.') + call append(line, split(template, '\n')) + call cursor(cline + 1, ccol) +endfunction " }}} + +function! s:MoveToInsertPosition() " {{{ + " If necessary moves the cursor to a valid insert position. + let start = search('<classpath\s*>', 'wn') + let end = search('</classpath\s*>', 'wn') + if line('.') < start || line('.') >= end + call cursor(end - 1, 1) + endif +endfunction " }}} + +function! eclim#java#classpath#GetVariableNames() " {{{ + let variables = eclim#Execute(s:command_variables) + if type(variables) != g:LIST_TYPE + return [] + endif + return map(variables, "v:val.name") +endfunction " }}} + +function! eclim#java#classpath#VariableList() " {{{ + let variables = eclim#Execute(s:command_variables) + if type(variables) != g:LIST_TYPE + return + endif + if len(variables) == 0 + call eclim#util#Echo("No variables.") + endif + + let pad = 0 + for variable in variables + let pad = len(variable.name) > pad ? len(variable.name) : pad + endfor + + let output = [] + for variable in variables + call add(output, eclim#util#Pad(variable.name, pad) . ' - ' . variable.path) + endfor + + call eclim#util#Echo(join(output, "\n")) +endfunction " }}} + +function! eclim#java#classpath#VariableCreate(name, path) " {{{ + let path = substitute(fnamemodify(a:path, ':p'), '\', '/', 'g') + if has('win32unix') + let path = eclim#cygwin#WindowsPath(path) + endif + let command = s:command_variable_create + let command = substitute(command, '<name>', a:name, '') + let command = substitute(command, '<path>', path, '') + + let result = eclim#Execute(command) + if result != '0' + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#java#classpath#VariableDelete(name) " {{{ + let command = s:command_variable_delete + let command = substitute(command, '<name>', a:name, '') + + let result = eclim#Execute(command) + if result != '0' + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#java#classpath#CommandCompleteVar(argLead, cmdLine, cursorPos) " {{{ + " Custom command completion for classpath var relative files. + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + + let vars = eclim#java#classpath#GetVariableNames() + call filter(vars, 'v:val =~ "\\M^' . argLead . '"') + + return vars +endfunction " }}} + +function! eclim#java#classpath#CommandCompleteVarPath(argLead, cmdLine, cursorPos) " {{{ + " Custom command completion for classpath var relative files. + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let args = eclim#util#ParseCmdLine(cmdLine) + let argLead = cmdLine =~ '\s$' ? '' : args[len(args) - 1] + + let vars = eclim#Execute(s:command_variables) + + " just the variable name + if argLead !~ '/' + let var_names = deepcopy(vars) + call filter(var_names, 'v:val.name =~ "^' . argLead . '"') + if len(var_names) > 0 + call map(var_names, + \ "isdirectory(v:val.path) ? v:val.name . '/' : v:val.name") + endif + return var_names + endif + + " variable name + path + let var = substitute(argLead, '\(.\{-}\)/.*', '\1', '') + let var_dir = "" + for cv in vars + if cv.name =~ '^' . var + let var_dir = cv.path + break + endif + endfor + if var_dir == '' + return [] + endif + + let var_dir = escape(substitute(var_dir, '\', '/', 'g'), ' ') + let argLead = substitute(argLead, var, var_dir, '') + let files = eclim#util#CommandCompleteFile(argLead, a:cmdLine, a:cursorPos) + let replace = escape(var_dir, '\') + call map(files, "substitute(v:val, '" . replace . "', '" . var . "', '')") + + return files +endfunction " }}} + +function! eclim#java#classpath#CommandCompleteVarAndDir(argLead, cmdLine, cursorPos) " {{{ + " Custom command completion for classpath var relative files. + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let args = eclim#util#ParseCmdLine(cmdLine) + let argLead = cmdLine =~ '\s$' ? '' : args[len(args) - 1] + + " complete vars for first arg + if cmdLine =~ '^' . args[0] . '\s*' . escape(argLead, '~.\') . '$' + return eclim#java#classpath#CommandCompleteVar(argLead, a:cmdLine, a:cursorPos) + endif + + return eclim#util#CommandCompleteDir(a:argLead, a:cmdLine, a:cursorPos) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/complete.vim b/vim/eclim/autoload/eclim/java/complete.vim @@ -0,0 +1,188 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/complete.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ + if !exists("g:EclimJavaCompleteLayout") + if &completeopt !~ 'preview' && &completeopt =~ 'menu' + let g:EclimJavaCompleteLayout = 'standard' + else + let g:EclimJavaCompleteLayout = 'compact' + endif + endif + if !exists("g:EclimJavaCompleteCaseSensitive") + let g:EclimJavaCompleteCaseSensitive = !&ignorecase + endif +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command java_complete -p "<project>" -f "<file>" ' . + \ '-o <offset> -e <encoding> -l <layout>' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles java code completion. +function! eclim#java#complete#CodeComplete(findstart, base) + if !eclim#project#util#IsCurrentFileInProject(0) + return a:findstart ? -1 : [] + endif + + if a:findstart + call eclim#lang#SilentUpdate(1) + + " locate the start of the word + let line = getline('.') + + let start = col('.') - 1 + + "exceptions that break the rule + if line[start] == '.' && line[start - 1] != '.' + let start -= 1 + endif + + while start > 0 && line[start - 1] =~ '\w' + let start -= 1 + endwhile + + return start + else + let offset = eclim#util#GetOffset() + len(a:base) + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate(1, 0) + if file == '' + return [] + endif + + let command = s:complete_command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let command = substitute(command, '<layout>', g:EclimJavaCompleteLayout, '') + + let completions = [] + let response = eclim#Execute(command) + if type(response) != g:DICT_TYPE + return + endif + + if has_key(response, 'imports') && len(response.imports) + let imports = response.imports + if exists('g:TestEclimWorkspace') " allow this to be tested somewhat + call eclim#java#complete#ImportThenComplete(imports) + else + let func = "eclim#java#complete#ImportThenComplete(" . string(imports) . ")" + call feedkeys("\<c-e>\<c-r>=" . func . "\<cr>", 'n') + endif + " prevents supertab's completion chain from attempting the next + " completion in the chain. + return -1 + endif + + if has_key(response, 'error') && len(response.completions) == 0 + call eclim#util#EchoError(response.error.message) + return -1 + endif + + " if the word has a '.' in it (like package completion) then we need to + " strip some off according to what is currently in the buffer. + let prefix = substitute(getline('.'), + \ '.\{-}\([[:alnum:].]\+\%' . col('.') . 'c\).*', '\1', '') + + " as of eclipse 3.2 it will include the parens on a completion result even + " if the file already has them. + let open_paren = getline('.') =~ '\%' . col('.') . 'c\s*(' + let close_paren = getline('.') =~ '\%' . col('.') . 'c\s*(\s*)' + + " when completing imports, the completions include ending ';' + let semicolon = getline('.') =~ '\%' . col('.') . 'c\s*;' + + for result in response.completions + let word = result.completion + + " strip off prefix if necessary. + if word =~ '\.' + let word = substitute(word, prefix, '', '') + endif + + " strip off close paren if necessary. + if word =~ ')$' && close_paren + let word = strpart(word, 0, strlen(word) - 1) + endif + + " strip off open paren if necessary. + if word =~ '($' && open_paren + let word = strpart(word, 0, strlen(word) - 1) + endif + + " strip off semicolon if necessary. + if word =~ ';$' && semicolon + let word = strpart(word, 0, strlen(word) - 1) + endif + + " if user wants case sensitivity, then filter out completions that don't + " match + if g:EclimJavaCompleteCaseSensitive && a:base != '' + if word !~ '^' . a:base . '\C' + continue + endif + endif + + let menu = result.menu + let info = eclim#html#util#HtmlToText(result.info) + + let dict = { + \ 'word': word, + \ 'menu': menu, + \ 'info': info, + \ 'kind': result.type, + \ 'dup': 1, + \ 'icase': !g:EclimJavaCompleteCaseSensitive, + \ } + + call add(completions, dict) + endfor + + return completions + endif +endfunction " }}} + +" ImportThenComplete {{{ +" Called by CodeComplete when the completion depends on a missing import. +function! eclim#java#complete#ImportThenComplete(choices) + let choice = '' + if len(a:choices) > 1 + let choice = eclim#java#import#ImportPrompt(a:choices) + elseif len(a:choices) + let choice = a:choices[0] + endif + + if choice != '' + call eclim#java#import#Import(choice) + call feedkeys("\<c-x>\<c-u>", 'tn') + endif + return '' +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/correct.vim b/vim/eclim/autoload/eclim/java/correct.vim @@ -0,0 +1,139 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/correct.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" define Correction group based on Normal. +hi link Correction Normal +hi Correction gui=underline,bold term=underline,bold cterm=underline,bold + +" Script Varables {{{ + let s:command_correct = + \ '-command java_correct -p "<project>" -f "<file>" ' . + \ '-l <line> -o <offset> -e <encoding>' + let s:command_correct_apply = s:command_correct . ' -a <apply>' +" }}} + +" Correct() {{{ +function! eclim#java#correct#Correct() + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + + let command = s:command_correct + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<line>', line('.'), '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + let window_name = file . "_correct" + let filename = expand('%:p') + call eclim#util#TempWindowClear(window_name) + + let result = eclim#Execute(command) + + " error executing the command. + if type(result) != g:DICT_TYPE && type(result) != g:STRING_TYPE + return + + " no error on the current line + elseif type(result) == g:STRING_TYPE + call eclim#util#Echo(result) + return + + " no correction proposals found. + elseif len(result.corrections) == 0 + call eclim#util#EchoInfo('No Suggestions') + return + endif + + let content = [] + call add(content, result.message) + for correction in result.corrections + call add(content, + \ correction.index . '.' . result.offset . ': ' . correction.description) + for line in split(correction.preview, '\n') + call add(content, line != '' ? ("\t" . line) : line) + endfor + endfor + + call eclim#util#TempWindow(window_name, content) + + let b:filename = filename + augroup temp_window + autocmd! BufWinLeave <buffer> + call eclim#util#GoToBufferWindowRegister(filename) + augroup END + + setlocal ft=java + + "exec "syntax match Normal /" . escape(getline(1), '^$/\') . "/" + syntax match Correction /^[0-9]\+\.[0-9]\+:.*/ + + nnoremap <silent> <buffer> <cr> + \ :call eclim#java#correct#CorrectApply()<cr> + + redraw | echo "" +endfunction " }}} + +" CorrectApply() {{{ +function! eclim#java#correct#CorrectApply() + let line = getline('.') + if line =~ '^[0-9]\+\.[0-9]\+:' + let winnr = bufwinnr('%') + let name = substitute(expand('%:p'), '_correct$', '', '') + let file_winnr = bufwinnr(bufnr('^' . b:filename)) + if file_winnr != -1 + let filename = b:filename + exec file_winnr . "winc w" + call eclim#lang#SilentUpdate() + + let index = substitute(line, '^\([0-9]\+\)\..*', '\1', '') + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_correct_apply + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<line>', line('.'), '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let command = substitute(command, '<apply>', index, '') + + call eclim#lang#Refactor(command) + call eclim#lang#UpdateSrcFile('java', 1) + + exec winnr . "winc w" + close + else + call eclim#util#EchoError(name . ' no longer found in an open window.') + endif + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/doc.vim b/vim/eclim/autoload/eclim/java/doc.vim @@ -0,0 +1,272 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/doc.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:command_comment = + \ '-command javadoc_comment -p "<project>" -f "<file>" -o <offset> -e <encoding>' +let s:command_element_doc = + \ '-command java_element_doc -p "<project>" -f "<file>" -o <offset> -l <length> -e <encoding>' +let s:command_doc_link = '-command java_element_doc -u "<url>"' +let s:command_source_dirs = '-command java_src_dirs -p "<project>"' +" }}} + +function! eclim#java#doc#Comment() " {{{ + " Add / update the comments for the element under the cursor. + + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let offset = eclim#util#GetCurrentElementOffset() + + let command = s:command_comment + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + let result = eclim#Execute(command) + + if result != "0" + call eclim#util#Reload({'retab': 1}) + write + endif +endfunction " }}} + +function! eclim#java#doc#Preview() " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + if !eclim#java#util#IsValidIdentifier(expand('<cword>')) + call eclim#util#EchoError + \ ("Element under the cursor is not a valid java identifier.") + return 0 + endif + + exec 'pedit +:call\ eclim#java#doc#PreviewOpen(' . bufnr('%') . ') [javadoc]' +endfunction " }}} + +function! eclim#java#doc#PreviewOpen(bufnr_or_url) " {{{ + if a:bufnr_or_url =~ '^\d\+$' + let curwin = winnr() + exec bufwinnr(a:bufnr_or_url) . 'winc w' + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate(1, 1) + let position = eclim#util#GetCurrentElementPosition() + let offset = substitute(position, '\(.*\);\(.*\)', '\1', '') + let length = substitute(position, '\(.*\);\(.*\)', '\2', '') + + exec curwin . 'winc w' + + let command = s:command_element_doc + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<length>', length, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + else + let command = s:command_doc_link + let command = substitute(command, '<url>', a:bufnr_or_url, '') + endif + + let result = eclim#Execute(command) + if type(result) == g:DICT_TYPE + if !exists('b:eclim_javadoc_stack') + let b:eclim_javadoc_stack = [] + let b:eclim_javadoc_index = -1 + elseif b:eclim_javadoc_index >= 0 + let b:eclim_javadoc_stack = b:eclim_javadoc_stack[:b:eclim_javadoc_index] + endif + call add(b:eclim_javadoc_stack, result) + let b:eclim_javadoc_index += 1 + let b:eclim_javadoc = result + + setlocal modifiable + call append(0, split(result.text, '\n')) + retab + if getline('$') =~ '^\s*$' + $,$delete _ + endif + call cursor(1, 1) + + elseif type(result) == g:STRING_TYPE + if result == '' + call eclim#util#EchoWarning('No javadoc found.') + else + call eclim#util#EchoError(result) + endif + + return + endif + + setlocal wrap + setlocal nomodifiable + setlocal nolist + setlocal noswapfile + setlocal nobuflisted + setlocal buftype=nofile + setlocal bufhidden=delete + setlocal conceallevel=2 concealcursor=ncv + + set ft=javadoc_preview + hi link javadocPreviewLink Label + syntax match javadocPreviewLinkStart contained /|/ conceal + syntax match javadocPreviewLinkEnd contained /\[\d\+\]|/ conceal + syntax region javadocPreviewLink start="|" end="" concealends + syntax match javadocPreviewLink /|.\{-}\[\d\+\]|/ + \ contains=JavadocPreviewLinkStart,JavadocPreviewLinkEnd + + nnoremap <silent> <buffer> <cr> :call eclim#java#doc#PreviewLink()<cr> + nnoremap <silent> <buffer> <c-]> :call eclim#java#doc#PreviewLink()<cr> + nnoremap <silent> <buffer> <c-o> :call eclim#java#doc#PreviewHistory(-1)<cr> + nnoremap <silent> <buffer> <c-i> :call eclim#java#doc#PreviewHistory(1)<cr> +endfunction " }}} + +function! eclim#java#doc#PreviewLink() " {{{ + let line = getline('.') + let cnum = col('.') + if line[cnum - 1] == '|' + let cnum += cnum > 1 && line[cnum - 2] == ']' ? -1 : 1 + endif + let text = substitute(line, '.*|\(.\{-}\%' . cnum . 'c.\{-}\)|.*', '\1', '') + if text == line || text !~ '\[\d\+]$' + return + endif + + exec 'let index = ' . substitute(text, '.*\[\(\d\+\)\]$', '\1', '') + if !exists('b:eclim_javadoc') || len(b:eclim_javadoc.links) <= index + return + endif + + let url = b:eclim_javadoc.links[index].href + if url =~ '^eclipse-javadoc:' + exec 'pedit +:call\ eclim#java#doc#PreviewOpen("' . url . '") [javadoc]' + else + call eclim#web#OpenUrl(url) + endif +endfunction " }}} + +function! eclim#java#doc#PreviewHistory(offset) " {{{ + if !exists('b:eclim_javadoc_stack') + return + endif + + let index = b:eclim_javadoc_index + a:offset + if index < 0 || index > len(b:eclim_javadoc_stack) -1 + return + endif + + let result = b:eclim_javadoc_stack[index] + let b:eclim_javadoc = result + let b:eclim_javadoc_index = index + + setlocal modifiable + 1,$delete _ + call append(0, split(result.text, '\n')) + retab + if getline('$') =~ '^\s*$' + $,$delete _ + endif + setlocal nomodifiable + call cursor(1, 1) +endfunction " }}} + +function! eclim#java#doc#Javadoc(bang, ...) " {{{ + " Run javadoc for all, or the supplied, source files. + " Optional args: + " file, file, file, ...: one ore more source files. + + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project_path = eclim#project#util#GetCurrentProjectRoot() + let project = eclim#project#util#GetCurrentProjectName() + let args = '-p "' . project . '"' + + if len(a:000) > 0 && (len(a:000) > 1 || a:000[0] != '') + let args .= ' -f "' . join(a:000, ' ') . '"' + endif + + let cwd = getcwd() + try + exec 'lcd ' . escape(project_path, ' ') + call eclim#util#MakeWithCompiler('eclim_javadoc', a:bang, args) + finally + exec 'lcd ' . escape(cwd, ' ') + endtry +endfunction " }}} + +function! eclim#java#doc#CommandCompleteJavadoc(argLead, cmdLine, cursorPos) " {{{ + let dir = eclim#project#util#GetCurrentProjectRoot() + + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let args = eclim#util#ParseCmdLine(cmdLine) + let argLead = cmdLine =~ '\s$' ? '' : args[len(args) - 1] + + let project = eclim#project#util#GetCurrentProjectName() + let command = substitute(s:command_source_dirs, '<project>', project, '') + let result = eclim#Execute(command) + let paths = [] + if result != '' && result != '0' + let paths = map(split(result, "\n"), + \ "eclim#project#util#GetProjectRelativeFilePath(v:val)") + endif + + let results = [] + + if argLead !~ '^\s*$' + let follow = 0 + for path in paths + if argLead =~ '^' . path + let follow = 1 + break + elseif path =~ '^' . argLead + call add(results, path) + endif + endfor + + if follow + let results = split(eclim#util#Glob(dir . '/' . argLead . '*', 1), '\n') + call filter(results, "isdirectory(v:val) || v:val =~ '\\.java$'") + call map(results, "substitute(v:val, '\\', '/', 'g')") + call map(results, 'isdirectory(v:val) ? v:val . "/" : v:val') + call map(results, 'substitute(v:val, dir, "", "")') + call map(results, 'substitute(v:val, "^\\(/\\|\\\\\\)", "", "g")') + call map(results, "substitute(v:val, ' ', '\\\\ ', 'g')") + endif + else + let results = paths + endif + + return eclim#util#ParseCommandCompletionResults(argLead, results) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/hierarchy.vim b/vim/eclim/autoload/eclim/java/hierarchy.vim @@ -0,0 +1,147 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/hierarchy.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists('g:EclimJavaHierarchyDefaultAction') + let g:EclimJavaHierarchyDefaultAction = g:EclimDefaultFileOpenAction +endif +" }}} + +" Script Variables {{{ +let s:command_hierarchy = + \ '-command java_hierarchy -p "<project>" -f "<file>" -o <offset> -e <encoding>' + +" }}} + +" Hierarchy() {{{ +function! eclim#java#hierarchy#Hierarchy() + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_hierarchy + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let result = eclim#Execute(command) + if type(result) != g:DICT_TYPE + return + endif + + let lines = [] + let info = [] + call s:FormatHierarchy(result, lines, info, '') + call eclim#util#TempWindow('[Hierarchy]', lines) + set ft=java + + setlocal modifiable noreadonly + call append(line('$'), ['', '" use ? to view help']) + setlocal nomodifiable readonly + syntax match Comment /^".*/ + + let b:hierarchy_info = info + call eclim#util#Echo(b:hierarchy_info[line('.') - 1]) + + augroup eclim_java_hierarchy + autocmd! + autocmd CursorMoved <buffer> + \ if line('.') <= len(b:hierarchy_info) | + \ call eclim#util#Echo(b:hierarchy_info[line('.') - 1]) | + \ else | + \ echo '' | + \ endif + augroup END + + nnoremap <buffer> <silent> <cr> + \ :call <SID>Open(g:EclimJavaHierarchyDefaultAction)<cr> + nnoremap <buffer> <silent> E :call <SID>Open('edit')<cr> + nnoremap <buffer> <silent> S :call <SID>Open('split')<cr> + nnoremap <buffer> <silent> T :call <SID>Open("tablast \| tabnew")<cr> + + " assign to buffer var to get around weird vim issue passing list containing + " a string w/ a '<' in it on execution of mapping. + let b:hierarchy_help = [ + \ '<cr> - open file with default action', + \ 'E - open with :edit', + \ 'S - open in a new split window', + \ 'T - open in a new tab', + \ ] + nnoremap <buffer> <silent> ? + \ :call eclim#help#BufferHelp(b:hierarchy_help, 'vertical', 40)<cr> +endfunction " }}} + +" s:FormatHierarchy(hierarchy, lines, indent) {{{ +function! s:FormatHierarchy(hierarchy, lines, info, indent) + call add(a:lines, a:indent . a:hierarchy.name) + call add(a:info, a:hierarchy.qualified) + let indent = eclim#util#GetIndent(1) + for child in a:hierarchy.children + call s:FormatHierarchy(child, a:lines, a:info, a:indent . indent) + endfor +endfunction " }}} + +" s:Open(action) {{{ +function! s:Open(action) + let line = line('.') + if line > len(b:hierarchy_info) + return + endif + + let type = b:hierarchy_info[line - 1] + " go to the buffer that initiated the hierarchy + exec b:winnr . 'winc w' + + " source the search plugin if necessary + if !exists("g:EclimJavaSearchSingleResult") + runtime autoload/eclim/java/search.vim + endif + + let action = a:action + let filename = expand('%:p') + if exists('b:filename') + let filename = b:filename + if !eclim#util#GoToBufferWindow(b:filename) + " if the file is no longer open, open it + silent! exec action . ' ' . b:filename + let action = 'edit' + endif + endif + + if line != 1 + let saved = g:EclimJavaSearchSingleResult + try + let g:EclimJavaSearchSingleResult = action + if eclim#java#search#SearchAndDisplay('java_search', '-x declarations -p ' . type) + let b:filename = filename + endif + finally + let g:EclimJavaSearchSingleResult = saved + endtry + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/impl.vim b/vim/eclim/autoload/eclim/java/impl.vim @@ -0,0 +1,341 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/impl.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:command_constructor = + \ '-command java_constructor -p "<project>" -f "<file>" -o <offset> -e <encoding>' + let s:command_properties = + \ '-command java_bean_properties -p "<project>" -f "<file>" ' . + \ '-o <offset> -e <encoding> -t <type> -r <properties> <indexed>' + let s:command_impl = + \ '-command java_impl -p "<project>" -f "<file>" -o <offset> -e <encoding>' + let s:command_impl_insert = + \ '-command java_impl -p "<project>" -f "<file>" -t "<type>" ' . + \ '-s "<superType>" <methods>' + let s:command_delegate = + \ '-command java_delegate -p "<project>" -f "<file>" -o <offset> -e <encoding>' + let s:command_delegate_insert = + \ '-command java_delegate -p "<project>" -f "<file>" -v "<type>" ' . + \ '-s "<superType>" <methods>' + + + let s:no_properties = + \ 'Unable to find property at current cursor position: ' . + \ 'Not on a field declaration or possible java syntax error.' + let s:cross_type_selection = "Visual selection is currently limited to methods of one super type at a time." +" }}} + +function! eclim#java#impl#Constructor(first, last, bang) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let properties = a:last == 1 ? [] : + \ eclim#java#util#GetSelectedFields(a:first, a:last) + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + + let command = s:command_constructor + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + if a:bang == '' + let command .= ' -s' + endif + if len(properties) > 0 + let command .= ' -r ''' . substitute(string(properties), "'", '"', 'g') . '''' + endif + + let result = eclim#Execute(command) + if type(result) == g:STRING_TYPE && result != '' + call eclim#util#EchoError(result) + return + endif + + if result != "0" + call eclim#util#Reload({'retab': 1}) + write + endif +endfunction " }}} + +function! eclim#java#impl#GetterSetter(first, last, bang, type) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let properties = eclim#java#util#GetSelectedFields(a:first, a:last) + + if len(properties) == 0 + call eclim#util#EchoError(s:no_properties) + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let indexed = a:bang != '' ? '-i' : '' + + let command = s:command_properties + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let command = substitute(command, '<type>', a:type, '') + let command = substitute(command, '<properties>', join(properties, ','), '') + let command = substitute(command, '<indexed>', indexed, '') + + let result = eclim#Execute(command) + if result != "0" + call eclim#util#Reload({'retab': 1}) + write + endif +endfunction " }}} + +function! eclim#java#impl#Impl() " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let offset = eclim#util#GetCurrentElementOffset() + + let command = s:command_impl + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + call eclim#java#impl#ImplWindow(command) +endfunction " }}} + +function! eclim#java#impl#ImplWindow(command) " {{{ + if (eclim#java#impl#Window(a:command, "impl")) + nnoremap <silent> <buffer> <cr> :call <SID>AddImpl(0)<cr> + vnoremap <silent> <buffer> <cr> :<C-U>call <SID>AddImpl(1)<cr> + endif +endfunction " }}} + +function! eclim#java#impl#ImplWindowFolding() " {{{ + setlocal foldmethod=syntax + setlocal foldlevel=99 +endfunction " }}} + +function! eclim#java#impl#Delegate() " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let offset = eclim#util#GetCurrentElementOffset() + let encoding = eclim#util#GetEncoding() + + let command = s:command_delegate + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', encoding, '') + + call eclim#java#impl#DelegateWindow(command) +endfunction " }}} + +function! eclim#java#impl#DelegateWindow(command) " {{{ + if (eclim#java#impl#Window(a:command, "delegate")) + nnoremap <silent> <buffer> <cr> :call <SID>AddDelegate(0)<cr> + vnoremap <silent> <buffer> <cr> :<C-U>call <SID>AddDelegate(1)<cr> + endif +endfunction " }}} + +function! eclim#java#impl#Add(command, function, visual) " {{{ + let winnr = bufwinnr(bufnr('^' . b:filename)) + " src window is not longer open. + if winnr == -1 + call eclim#util#EchoError(b:filename . ' no longer found in an open window.') + return + endif + + if a:visual + let start = line("'<") + let end = line("'>") + endif + + let superType = "" + let methods = [] + " non-visual mode or only one line selected + if !a:visual || start == end + " not a valid selection + if line('.') == 1 || getline('.') =~ '^\(\s*//\|package\|$\|}\)' + return + endif + + let line = getline('.') + if line =~ '^\s*throws' + let line = getline(line('.') - 1) + endif + " on a method line + if line =~ '^\s\+' + call add(methods, s:MethodSig(line)) + let ln = search('^\w', 'bWn') + if ln > 0 + let superType = substitute(getline(ln), '.*\s\(.*\) {', '\1', '') + endif + " on a type line + else + let superType = substitute(line, '.*\s\(.*\) {', '\1', '') + endif + + " visual mode + else + let pos = getpos('.') + let index = start + while index <= end + let line = getline(index) + if line =~ '^\s*\($\|throws\|package\)' + " do nothing + " on a method line + elseif line =~ '^\s\+' + call add(methods, s:MethodSig(line)) + call cursor(index, 1) + let ln = search('^\w', 'bWn') + if ln > 0 + let super = substitute(getline(ln), '.*\s\(.*\) {', '\1', '') + if superType != "" && super != superType + call eclim#util#EchoError(s:cross_type_selection) + call setpos('.', pos) + return + endif + let superType = super + endif + " on a type line + else + let super = substitute(line, '.*\s\(.*\) {', '\1', '') + if superType != "" && super != superType + call eclim#util#EchoError(s:cross_type_selection) + call setpos('.', pos) + return + endif + let superType = super + endif + call setpos('.', pos) + + let index += 1 + endwhile + + if superType == "" + return + endif + endif + + " search up for the nearest package + let ln = search('^package', 'bWn') + if ln > 0 + let package = substitute(getline(ln), '.*\s\(.*\);', '\1', '') + let superType = package . '.' . substitute(superType, '<.\{-}>', '', 'g') + endif + + let type = getline(1) + let impl_winnr = winnr() + exec winnr . "winc w" + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + + let command = a:command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<type>', type, '') + let command = substitute(command, '<superType>', superType, '') + if len(methods) + let json = substitute(string(methods), "'", '"', 'g') + let command = substitute(command, '<methods>', '-m ''' . json . '''', '') + else + let command = substitute(command, '<methods>', '', '') + endif + + call a:function(command) + + noautocmd exec winnr . "winc w" + call eclim#util#Reload({'retab': 1}) + write + noautocmd exec impl_winnr . "winc w" +endfunction " }}} + +function! eclim#java#impl#Window(command, name) " {{{ + let name = eclim#project#util#GetProjectRelativeFilePath() . '_' . a:name + let project = eclim#project#util#GetCurrentProjectName() + let result = eclim#Execute(a:command, {'project': project}) + if type(result) == g:STRING_TYPE + call eclim#util#EchoError(result) + return + endif + if type(result) != g:DICT_TYPE + return + endif + + let content = [result.type] + for super in result.superTypes + call add(content, '') + call add(content, 'package ' . super.packageName . ';') + call add(content, super.signature . ' {') + for method in super.methods + let signature = split(method, '\n') + let content += map(signature, '"\t" . v:val') + endfor + call add(content, '}') + endfor + + call eclim#util#TempWindow(name, content, {'preserveCursor': 1}) + setlocal ft=java + call eclim#java#impl#ImplWindowFolding() + return 1 +endfunction " }}} + +function! s:AddImpl(visual) " {{{ + call eclim#java#impl#Add + \ (s:command_impl_insert, function("eclim#java#impl#ImplWindow"), a:visual) +endfunction " }}} + +function! s:AddDelegate(visual) " {{{ + call eclim#java#impl#Add + \ (s:command_delegate_insert, function("eclim#java#impl#DelegateWindow"), a:visual) +endfunction " }}} + +function! s:MethodSig(line) " {{{ + let sig = substitute(a:line, '.*\s\(\w\+(.*\)', '\1', '') + let sig = substitute(sig, ',\s', ',', 'g') + let sig = substitute(sig, '<.\{-}>', '', 'g') + return sig +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/import.vim b/vim/eclim/autoload/eclim/java/import.vim @@ -0,0 +1,140 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/import.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:command_import = + \ '-command java_import -p "<project>" -f "<file>" -o <offset> -e <encoding>' +let s:command_organize = + \ '-command java_import_organize -p "<project>" -f "<file>" -o <offset> -e <encoding>' +" }}} + +function! eclim#java#import#Import(...) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + if !a:0 + let name = expand('<cword>') + if !eclim#java#util#IsValidIdentifier(name) || + \ eclim#java#util#IsKeyword(name) + call eclim#util#EchoError("'" . name . "' not a classname.") + return + endif + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate() + let offset = eclim#util#GetOffset() + let command = s:command_import + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + if a:0 + let command .= ' -t ' . a:1 + endif + let result = eclim#Execute(command) + + if type(result) == g:STRING_TYPE + call eclim#util#EchoError(result) + return + endif + + if type(result) == g:DICT_TYPE + call eclim#util#Reload({'pos': [result.line, result.column]}) + call eclim#lang#UpdateSrcFile('java', 1) + if result.offset != offset + call eclim#util#Echo('Imported ' . (a:0 ? a:1 : '')) + endif + return + endif + + if type(result) != g:LIST_TYPE + return + endif + + let choice = eclim#java#import#ImportPrompt(result) + if choice != '' + call eclim#java#import#Import(choice) + endif +endfunction " }}} + +function! eclim#java#import#OrganizeImports(...) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate() + let offset = eclim#util#GetOffset() + let command = s:command_organize + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + if a:0 + let command .= ' -t ' . join(a:1, ',') + endif + let result = eclim#Execute(command) + + if type(result) == g:STRING_TYPE + call eclim#util#EchoError(result) + return + endif + + if type(result) == g:DICT_TYPE + call eclim#util#Reload({'pos': [result.line, result.column]}) + call eclim#lang#UpdateSrcFile('java', 1) + return + endif + + if type(result) != g:LIST_TYPE + return + endif + + let chosen = [] + for choices in result + let choice = eclim#java#import#ImportPrompt(choices) + if choice == '' + return + endif + call add(chosen, choice) + endfor + + if len(chosen) + call eclim#java#import#OrganizeImports(chosen) + endif +endfunction " }}} + +function! eclim#java#import#ImportPrompt(choices) " {{{ + " prompt the user to choose the class to import. + let response = eclim#util#PromptList("Choose the class to import", a:choices) + if response == -1 + return '' + endif + + return get(a:choices, response) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/junit.vim b/vim/eclim/autoload/eclim/java/junit.vim @@ -0,0 +1,247 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/junit.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:command_junit = '-command java_junit -p "<project>"' +let s:command_tests = '-command java_junit_tests -p "<project>"' +let s:command_find_test = + \ '-command java_junit_find_test -p "<project>" -f "<file>" ' . + \ '-o <offset> -e <encoding>' +let s:command_impl = '-command java_junit_impl -p "<project>" -f "<file>"' +let s:command_insert = + \ '-command java_junit_impl -p "<project>" -f "<file>" ' . + \ '-t "<type>" -s "<superType>" <methods>' +" }}} + +function! eclim#java#junit#JUnit(test, bang) " {{{ + let project = eclim#project#util#GetCurrentProjectName() + if project == '' && exists('b:project') + let project = b:project + endif + + if project == '' + call eclim#project#util#IsCurrentFileInProject() + return + endif + + let command = s:command_junit + let command = substitute(command, '<project>', project, '') + if a:test != '' + if a:test == '%' + let command .= ' -f "' . eclim#project#util#GetProjectRelativeFilePath() . '"' + elseif a:test != '*' + let command .= ' -t "' . a:test . '"' + endif + else + let command .= ' -f "' . eclim#project#util#GetProjectRelativeFilePath() . '"' + let command .= ' -o ' . eclim#util#GetOffset() + let command .= ' -e ' . eclim#util#GetEncoding() + endif + + let curbuf = bufnr('%') + let result = eclim#Execute(command, {'project': project, 'exec': 1, 'raw': 1}) + let results = split(substitute(result, "^\n*", '', 'g'), "\n") + call eclim#util#TempWindow('[JUnit Output]', results) + let b:project = project + + if exists(":JUnit") != 2 + command -buffer -nargs=? -complete=customlist,eclim#java#junit#CommandCompleteTest + \ JUnit :call eclim#java#junit#JUnit('<args>', '<bang>') + endif + + exec bufwinnr(curbuf) . 'winc w' +endfunction " }}} + +function! eclim#java#junit#JUnitFindTest() " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + runtime eclim/autoload/eclim/java/search.vim + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate() + let command = s:command_find_test + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', eclim#util#GetOffset(), '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let result = eclim#Execute(command) + if type(result) == g:STRING_TYPE + call eclim#util#EchoError(result) + return + endif + + if type(result) != g:DICT_TYPE + return + endif + + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries([result])) + let entry = getloclist(0)[0] + let name = substitute(bufname(entry.bufnr), '\', '/', 'g') + if g:EclimJavaSearchSingleResult != 'lopen' + call eclim#util#GoToBufferWindowOrOpen(name, g:EclimJavaSearchSingleResult) + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries([result])) + call eclim#display#signs#Update() + call cursor(entry.lnum, entry.col) + else + exec 'lopen ' . g:EclimLocationListHeight + endif +endfunction " }}} + +function! eclim#java#junit#JUnitResult(test) " {{{ + " Argument test can be one of the following: + " Empty string: Use the current file to determine the test result file. + " Class name of a test: Locate the results for class (ex. 'TestMe'). + " The results dir relative results file name: TEST-org.foo.TestMe.xml + + let path = s:GetResultsDir() + if path == '' + call eclim#util#EchoWarning( + \ "Output directory setting for 'junit' not set. " . + \ "Use :EclimSettings or :ProjectSettings to set it.") + return + endif + + if a:test != '' + let file = a:test + if file !~ '^TEST-' + let file = '*' . file + endif + else + let file = substitute(eclim#java#util#GetFullyQualifiedClassname(), '\.', '/', 'g') + endif + + if file !~ '^TEST-' + let file = substitute(file, '\/', '.', 'g') + let file = 'TEST-' . file . '.xml' + endif + + let found = eclim#util#Globpath(path, file) + + " try text version if xml not found. + if found == "" + let file = fnamemodify(file, ':r') . '.txt' + let found = eclim#util#Globpath(path, file) + endif + + if found != "" + let filename = expand('%:p') + exec "below split " . escape(found, ' ') + + augroup temp_window + autocmd! BufWinLeave <buffer> + call eclim#util#GoToBufferWindowRegister(filename) + augroup END + + return + endif + call eclim#util#Echo("Test result file not found for: " . fnamemodify(file, ':r')) +endfunction " }}} + +function! eclim#java#junit#JUnitImpl() " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_impl + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + call eclim#java#junit#JUnitImplWindow(command) +endfunction " }}} + +function! eclim#java#junit#JUnitImplWindow(command) " {{{ + if (eclim#java#impl#Window(a:command, "impl")) + nnoremap <silent> <buffer> <cr> :call <SID>AddTestImpl(0)<cr> + vnoremap <silent> <buffer> <cr> :<C-U>call <SID>AddTestImpl(1)<cr> + endif +endfunction " }}} + +function! s:AddTestImpl(visual) " {{{ + call eclim#java#impl#Add + \ (s:command_insert, function("eclim#java#junit#JUnitImplWindow"), a:visual) +endfunction " }}} + +function! s:GetResultsDir() " {{{ + let path = eclim#project#util#GetProjectSetting("org.eclim.java.junit.output_dir") + if type(path) == g:NUMBER_TYPE + return + endif + + let root = eclim#project#util#GetCurrentProjectRoot() + let path = substitute(path, '<project>', root, '') + let path = path != '' && path !~ '/$' ? path . '/' : path + if path != '' && has('win32unix') + let path = eclim#cygwin#CygwinPath(path) + endif + return path +endfunction " }}} + +function! eclim#java#junit#CommandCompleteTest(argLead, cmdLine, cursorPos) " {{{ + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + + let project = eclim#project#util#GetCurrentProjectName() + if project == '' && exists('b:project') + let project = b:project + endif + if project == '' + return [] + endif + + let command = s:command_tests + let command = substitute(command, '<project>', project, '') + let results = eclim#Execute(command) + if type(results) != g:LIST_TYPE + return [] + endif + + call filter(results, 'v:val =~ "' . argLead . '"') + return results +endfunction " }}} + +function! eclim#java#junit#CommandCompleteResult(argLead, cmdLine, cursorPos) " {{{ + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + + let path = s:GetResultsDir() + if path == '' + call eclim#util#EchoWarning( + \ "Output directory setting for 'junit' not set. " . + \ "Use :EclimSettings or :ProjectSettings to set it.") + return [] + endif + + let results = split(eclim#util#Globpath(path, '*'), '\n') + call map(results, 'fnamemodify(v:val, ":r:e")') + call filter(results, 'v:val =~ "^' . argLead . '"') + + return results +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/logging.vim b/vim/eclim/autoload/eclim/java/logging.vim @@ -0,0 +1,127 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/logging.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +function! eclim#java#logging#LoggingInit(var) " {{{ + let char = nr2char(getchar()) + " only execute if the user types a '.' for a method call and if the logger + " is not already present. + if char == '.' && s:InitLoggingSettings() && + \ !search('\(final\|static\)\>.\{-}\<Log\(ger\)\?\s', 'n') + let line = line('.') + let col = col('.') + let position = eclim#java#util#GetClassDeclarationPosition(1) + if position + let logger = s:logger + let logger = substitute(logger, '\${class}', eclim#java#util#GetClassname(), '') + let logger = substitute(logger, '\${var}', a:var, '') + if strlen(logger) > &textwidth && logger !~ '\n' + let logger = substitute(logger, + \ '\(.*\)\s\(.*\)', '\1\n' . eclim#util#GetIndent(2) . '\2', '') + endif + + let position = search('{') + let lines = split(logger, '\n') + let offset = len(lines) + 1 + call append(position, '') + call append(position, lines) + call cursor(line + offset, col) + for import in s:logger_imports + call eclim#java#import#Import(import) + endfor + endif + endif + return char +endfunction " }}} + +function! s:InitLoggingSettings() " {{{ + let s:EclimLoggingImpl = + \ eclim#project#util#GetProjectSetting("org.eclim.java.logging.impl") + if type(s:EclimLoggingImpl) == g:NUMBER_TYPE || s:EclimLoggingImpl == '0' + unlet s:EclimLoggingImpl + return + endif + + let indent = eclim#util#GetIndent(1) + if s:EclimLoggingImpl == "commons-logging" + let s:logger = indent . + \ "private static final Log ${var} = LogFactory.getLog(${class}.class);" + let s:logger_imports = [ + \ "org.apache.commons.logging.Log", + \ "org.apache.commons.logging.LogFactory"] + elseif s:EclimLoggingImpl == "slf4j" + let s:logger = indent . + \ "private static final Logger ${var} = LoggerFactory.getLogger(${class}.class);" + let s:logger_imports = ["org.slf4j.Logger", "org.slf4j.LoggerFactory"] + elseif s:EclimLoggingImpl == "log4j" + let s:logger = indent . + \ "private static final Logger ${var} = Logger.getLogger(${class}.class);" + let s:logger_imports = ["org.apache.log4j.Logger"] + elseif s:EclimLoggingImpl == "jdk" + let s:logger = indent . + \ "private static final Logger ${var} = Logger.getLogger(${class}.class.getName());" + let s:logger_imports = ["java.util.logging.Logger"] + elseif s:EclimLoggingImpl == "custom" + let instance = eclim#client#nailgun#ChooseEclimdInstance() + if type(instance) != g:DICT_TYPE + return + endif + + let name = eclim#project#util#GetProjectSetting("org.eclim.java.logging.template") + if type(name) == g:NUMBER_TYPE || name == '' + return + endif + + let local = eclim#UserHome() . '/.eclim/resources/jdt/templates/' . name + let remote = substitute(instance.home, 'org.eclim_', 'org.eclim.jdt_', '') . + \ '/resources/templates/' . name + if filereadable(local) + let template = local + elseif filereadable(remote) + let template = remote + else + call eclim#util#EchoError( + \ "Custom logger template not found local or remote location:\n" . + \ " local: " . local . "\n" . + \ " remote: " . remote) + return + endif + let lines = readfile(template) + let s:logger_imports = lines[:] + call filter(s:logger_imports, "v:val =~ '^\\s*import\\>'") + call map(s:logger_imports, + \ "substitute(v:val, '^\\s*import\\>\\s*\\(.*\\);\\s*', '\\1', '')") + call filter(lines, "v:val !~ '\\(^\\s*$\\|^\\s*import\\>\\)'") + let s:logger = indent . join(lines, "\n" . indent) + elseif s:EclimLoggingImpl == '' + " no setting returned, probably not in a project, or user is attempting to + " disable this functionality for the current project. + return + else + echoe "Invalid logging implementation '" . s:EclimLoggingImpl . "' configured." + return + endif + return 1 +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/maven.vim b/vim/eclim/autoload/eclim/java/maven.vim @@ -0,0 +1,118 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ +let s:update_command = '-command project_update -p "<project>" -b "<build>"' +" }}} + +function! eclim#java#maven#SetClasspathVariable(cmd, variable, args) " {{{ + let instance = eclim#client#nailgun#ChooseEclimdInstance() + if type(instance) != g:DICT_TYPE + return + endif + + let workspace = instance.workspace + + " maven 1.x + if a:cmd == 'Maven' + let prefs = workspace . + \ '/.metadata/.plugins/org.eclipse.jdt.core/pref_store.ini' + let command = a:cmd . + \ ' "-Dmaven.eclipse.workspace=' . workspace . '"' . + \ ' eclipse:add-maven-repo' + + " maven 2.x + else + let prefs = workspace . + \ '/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs' + let command = a:cmd . ' ' . a:args . + \ ' "-Declipse.workspace=' . workspace . '"' . + \ ' eclipse:configure-workspace' + endif + + call eclim#util#Exec(command) + + if !v:shell_error + " the maven command edits the eclipse preference file directly, so in + " order to get the value in memory without restarting eclim, we read the + " value out and let the server set it again. + let winrestore = winrestcmd() + + if filereadable(prefs) + silent exec 'sview ' . prefs + let line = search('org.eclipse.jdt.core.classpathVariable.' . a:variable, 'cnw') + let value = line ? substitute(getline(line), '.\{-}=\(.*\)', '\1', '') : '' + if line + call eclim#java#classpath#VariableCreate(a:variable, value) + endif + + if substitute(bufname('%'), '\', '/', 'g') =~ prefs + close + exec winrestore + endif + + if line + call eclim#util#Echo(a:variable . " classpath variable set to:\n" . value) + else + call eclim#util#EchoWarning( + \ "Unable to locate " . a:variable . " classpath variable.\n" . + \ "If it was successful set by maven, you may need to\n" . + \ "restart eclipse for the change to take affect.") + endif + else + call eclim#util#EchoWarning( + \ "Unable to read:\n" . prefs . "\n" . + \ "If the " . a:variable . " classpath variable was successfully set by maven\n" . + \ "you may need to restart eclipse for the change to take affect.") + endif + endif +endfunction " }}} + +function! eclim#java#maven#UpdateClasspath() " {{{ + " Updates the classpath on the server w/ the changes made to the current pom file. + + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + " validate the xml first + if eclim#xml#validate#Validate(expand('%:p'), 0) + return + endif + + let name = eclim#project#util#GetCurrentProjectName() + let command = s:update_command + let command = substitute(command, '<project>', name, '') + let command = substitute(command, '<build>', escape(expand('%:p'), '\'), '') + let result = eclim#Execute(command) + + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + call eclim#util#SetLocationList(errors, 'r') + call eclim#util#EchoError( + \ "Operation contained errors. See location list for details (:lopen).") + else + call eclim#util#ClearLocationList() + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/refactor.vim b/vim/eclim/autoload/eclim/java/refactor.vim @@ -0,0 +1,120 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" +" Copyright (C) 2005 - 2012 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:command_rename = '-command java_refactor_rename ' . + \ '-p "<project>" -f "<file>" -o <offset> -e <encoding> -l <length> -n <name>' + let s:command_move = '-command java_refactor_move ' . + \ '-p "<project>" -f "<file>" -n <package>' +" }}} + +function! eclim#java#refactor#Rename(name) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let element = expand('<cword>') + if !eclim#java#util#IsValidIdentifier(element) + call eclim#util#EchoError + \ ("Element under the cursor is not a valid java identifier.") + return + endif + + let line = getline('.') + let package_pattern = '^\s*package\s\+\(.*\%' . col('.') . 'c\w*\).*;' + if line =~ package_pattern + let element = substitute(line, package_pattern, '\1', '') + endif + + let prompt = printf('Rename "%s" to "%s"', element, a:name) + let result = exists('g:EclimRefactorPromptDefault') ? + \ g:EclimRefactorPromptDefault : eclim#lang#RefactorPrompt(prompt) + if result <= 0 + return + endif + + " update the file before vim makes any changes. + call eclim#lang#SilentUpdate() + wall + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let position = eclim#util#GetCurrentElementPosition() + let offset = substitute(position, '\(.*\);\(.*\)', '\1', '') + let length = substitute(position, '\(.*\);\(.*\)', '\2', '') + + let command = s:command_rename + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<length>', length, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + let command = substitute(command, '<name>', a:name, '') + " user chose preview at the prompt + if result == 2 + let command .= ' -v' + call eclim#lang#RefactorPreview(command) + return + endif + + call eclim#lang#Refactor(command) +endfunction " }}} + +function! eclim#java#refactor#Move(package) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let line = getline('.') + let package_pattern = '^\s*package\s\+\(.*\%' . col('.') . 'c\w*\).*;' + if line =~ package_pattern + let element = substitute(line, package_pattern, '\1', '') + endif + + let name = eclim#java#util#GetClassname() + let package = eclim#java#util#GetPackage() + let prompt = printf('Move %s from "%s" to "%s"', name, package, a:package) + let result = exists('g:EclimRefactorPromptDefault') ? + \ g:EclimRefactorPromptDefault : eclim#lang#RefactorPrompt(prompt) + if result <= 0 + return + endif + + " update the file before vim makes any changes. + call eclim#lang#SilentUpdate() + wall + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:command_move + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<package>', a:package, '') + " user chose preview at the prompt + if result == 2 + let command .= ' -v' + call eclim#lang#RefactorPreview(command) + return + endif + call eclim#lang#Refactor(command) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/search.vim b/vim/eclim/autoload/eclim/java/search.vim @@ -0,0 +1,409 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/search.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ + if !exists("g:EclimJavaDocSearchSingleResult") + " possible values ('open', 'lopen') + let g:EclimJavaDocSearchSingleResult = "open" + endif + + if !exists("g:EclimJavaSearchSingleResult") + " possible values ('split', 'edit', 'lopen') + let g:EclimJavaSearchSingleResult = g:EclimDefaultFileOpenAction + endif +" }}} + +" Script Varables {{{ + let s:search_src = "java_search" + let s:search_doc = "java_docsearch" + let s:search_element = + \ '-command <search> -n "<project>" -f "<file>" ' . + \ '-o <offset> -e <encoding> -l <length> <args>' + let s:search_pattern = '-command <search>' + let s:options = ['-p', '-t', '-x', '-s', '-i'] + let s:contexts = ['all', 'declarations', 'implementors', 'references'] + let s:scopes = ['all', 'project'] + let s:types = [ + \ 'annotation', + \ 'class', + \ 'classOrEnum', + \ 'classOrInterface', + \ 'constructor', + \ 'enum', + \ 'field', + \ 'interface', + \ 'method', + \ 'package', + \ 'type'] + + let s:search_alt_all = '\<<element>\>' + let s:search_alt_references = s:search_alt_all + let s:search_alt_implementors = + \ '\(implements\|extends\)\_[0-9A-Za-z,[:space:]]*\<<element>\>\_[0-9A-Za-z,[:space:]]*{' +" }}} + +function! s:Search(command, ...) " {{{ + " Executes a search. + " Usage closely resebles eclim command line client usage. + " When doing a non-pattern search the element under the cursor is searched for. + " Search for declarations of element under the cursor + " call s:Search("-x", "declarations") + " Search for references of HashMap + " call s:Search("-p", "HashM*", "-t", "class", "-x", "references") + " Or all the arguments can be passed in at once: + " call s:Search("-p 'HashM*' -t class -x references") + + let argline = "" + let index = 1 + while index <= a:0 + if index != 1 + let argline = argline . " " + endif + let argline = argline . a:{index} + let index = index + 1 + endwhile + + " check if pattern supplied without -p. + if argline !~ '^\s*-[a-z]' && argline !~ '^\s*$' + let argline = '-p ' . argline + endif + + let in_project = eclim#project#util#IsCurrentFileInProject(0) + + " element search + if argline !~ '-p\>' + if &ft != 'java' + call eclim#util#EchoWarning + \ ("Element searches only supported in java source files.") + return 0 + endif + + if !eclim#java#util#IsValidIdentifier(expand('<cword>')) + call eclim#util#EchoError + \ ("Element under the cursor is not a valid java identifier.") + return 0 + endif + + if !in_project + " build a pattern search and execute it + let results = s:SearchAlternate('-p ' . s:BuildPattern() . ' ' . argline, 1) + " kind of gross. if there was no alternate result and eclimd is not + " running, then make sure a message is echoed to the user so they know + " that eclimd not running *may* be the cause of no results. + if len(results) == 0 && !eclim#EclimAvailable() + return 0 + endif + return results + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let position = eclim#util#GetCurrentElementPosition() + let offset = substitute(position, '\(.*\);\(.*\)', '\1', '') + let length = substitute(position, '\(.*\);\(.*\)', '\2', '') + + let search_cmd = s:search_element + let search_cmd = substitute(search_cmd, '<project>', project, '') + let search_cmd = substitute(search_cmd, '<search>', a:command, '') + let search_cmd = substitute(search_cmd, '<file>', file, '') + let search_cmd = substitute(search_cmd, '<offset>', offset, '') + let search_cmd = substitute(search_cmd, '<encoding>', eclim#util#GetEncoding(), '') + let search_cmd = substitute(search_cmd, '<length>', length, '') + let search_cmd = substitute(search_cmd, '<args>', argline, '') + + let result = eclim#Execute(search_cmd) + + " pattern search + else + let project = eclim#project#util#GetCurrentProjectName() + + " pattern search + let search_cmd = s:search_pattern + let search_cmd = substitute(search_cmd, '<search>', a:command, '') + if project != '' + let search_cmd .= ' -n "' . project . '"' + endif + let file = eclim#project#util#GetProjectRelativeFilePath() + if file != '' + let search_cmd .= ' -f "' . file . '"' + endif + let search_cmd .= ' ' . argline + " quote the search pattern + let search_cmd = + \ substitute(search_cmd, '\(.*-p\s\+\)\(.\{-}\)\(\s\|$\)\(.*\)', '\1"\2"\3\4', '') + + let result = eclim#Execute(search_cmd) + + if !in_project && filereadable(expand('%')) + return result + s:SearchAlternate(argline, 0) + endif + endif + + return result +endfunction " }}} + +function! s:SearchAlternate(argline, element) " {{{ + " Alternate search for non-project src files using vimgrep and &path. + + call eclim#util#EchoInfo("Executing alternate search...") + if a:argline =~ '-t' + call eclim#util#EchoError + \ ("Alternate search doesn't support the type (-t) option yet.") + return [] + endif + let search_pattern = "" + if a:argline =~ '-x all' + let search_pattern = s:search_alt_all + elseif a:argline =~ '-x implementors' + let search_pattern = s:search_alt_implementors + elseif a:argline =~ '-x references' + let search_pattern = s:search_alt_references + endif + + let pattern = substitute(a:argline, '.*-p\s\+\(.\{-}\)\(\s.*\|$\)', '\1', '') + let file_pattern = substitute(pattern, '\.', '/', 'g') . ".java" + + " search relative to the current dir first. + let package_path = substitute(eclim#java#util#GetPackage(), '\.', '/', 'g') + let path = substitute(expand('%:p:h'), '\', '/', 'g') + let path = substitute(path, package_path, '', '') + let files = split(eclim#util#Globpath(path, "**/" . file_pattern), '\n') + + " if none found, then search the path. + if len(files) == 0 + let files = eclim#util#FindFileInPath(file_pattern, 1) + let path = "" + endif + + let results = [] + + if len(files) > 0 && search_pattern != '' + " narrow down to, hopefully, a distribution path for a narrower search. + let response = eclim#util#PromptList( + \ "Multiple type matches. Please choose the relevant file.", + \ files, g:EclimInfoHighlight) + if response == -1 + return + endif + + let file = substitute(get(files, response), '\', '/', 'g') + if path == "" + let path = eclim#util#GetPathEntry(file) + endif + let path = escape(path, '/\') + let path = substitute(file, '\(' . path . '[/\\]\?.\{-}[/\\]\).*', '\1', '') + let pattern = substitute(pattern, '\*', '.\\\\{-}', 'g') + let search_pattern = substitute(search_pattern, '<element>', pattern, '') + let command = "vimgrep /" . search_pattern . "/gj " . path . "**/*.java" + silent! exec command + + let loclist = getloclist(0) + for entry in loclist + let bufname = bufname(entry.bufnr) + let result = { + \ 'filename': bufname, + \ 'message': entry.text, + \ 'line': entry.lnum, + \ 'column': entry.col, + \ } + " when searching for implementors, prevent dupes from the somewhat + " greedy pattern search (may need some more updating post conversion to + " dict results). + if a:argline !~ '-x implementors' || !eclim#util#ListContains(results, result) + call add(results, result) + endif + endfor + elseif len(files) > 0 + for file in files + let fully_qualified = eclim#java#util#GetPackage(file) . '.' . + \ eclim#java#util#GetClassname(file) + " if an element search, filter out results that are not imported. + if !a:element || eclim#java#util#IsImported(fully_qualified) + call add(results, { + \ 'filename': file, + \ 'message': fully_qualified, + \ 'line': 1, + \ 'column': 1, + \ }) + endif + endfor + endif + call eclim#util#Echo(' ') + return results +endfunction " }}} + +function! s:BuildPattern() " {{{ + " Builds a pattern based on the cursors current position in the file. + + let class = expand('<cword>') + " see if the classname element selected is fully qualified. + let line = getline('.') + let package = + \ substitute(line, '.*\s\([0-9A-Za-z._]*\)\.' . class . '\>.*', '\1', '') + + " not fully qualified, so attempt to determine package from import. + if package == line + let package = eclim#java#util#GetPackageFromImport(class) + + " maybe the element is the current class? + if package == "" + if eclim#java#util#GetClassname() == class + let package = eclim#java#util#GetPackage() + endif + endif + endif + + if package != "" + return package . "." . class + endif + return class +endfunction " }}} + +function! eclim#java#search#SearchAndDisplay(type, args) " {{{ + " Execute a search and displays the results via quickfix. + + " if running from a non java source file, no SilentUpdate needed. + if &ft == 'java' + call eclim#lang#SilentUpdate() + endif + + let argline = a:args + + " check if just a pattern was supplied. + if argline =~ '^\s*\w' + let argline = '-p ' . argline + endif + + let results = s:Search(a:type, argline) + if type(results) != g:LIST_TYPE + return + endif + if !empty(results) + if a:type == 'java_search' + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries(results)) + let locs = getloclist(0) + " if only one result and it's for the current file, just jump to it. + " note: on windows the expand result must be escaped + if len(results) == 1 && locs[0].bufnr == bufnr('%') + if results[0].line != 1 && results[0].column != 1 + lfirst + endif + + " single result in another file. + elseif len(results) == 1 && g:EclimJavaSearchSingleResult != "lopen" + let entry = getloclist(0)[0] + let name = substitute(bufname(entry.bufnr), '\', '/', 'g') + call eclim#util#GoToBufferWindowOrOpen(name, g:EclimJavaSearchSingleResult) + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries(results)) + call eclim#display#signs#Update() + call cursor(entry.lnum, entry.col) + else + exec 'lopen ' . g:EclimLocationListHeight + endif + elseif a:type == 'java_docsearch' + let window_name = "javadoc_search_results" + let filename = expand('%:p') + call eclim#util#TempWindowClear(window_name) + + if len(results) == 1 && g:EclimJavaDocSearchSingleResult == "open" + let entry = results[0] + call s:ViewDoc(entry) + else + call eclim#util#TempWindow( + \ window_name, results, {'height': g:EclimLocationListHeight}) + + nnoremap <silent> <buffer> <cr> :call <SID>ViewDoc()<cr> + augroup temp_window + autocmd! BufWinLeave <buffer> + call eclim#util#GoToBufferWindowRegister(filename) + augroup END + endif + endif + return 1 + else + if argline =~ '-p ' + let searchedFor = substitute(argline, '.*-p \(.\{-}\)\( .*\|$\)', '\1', '') + call eclim#util#EchoInfo("Pattern '" . searchedFor . "' not found.") + elseif &ft == 'java' + if !eclim#java#util#IsValidIdentifier(expand('<cword>')) + return + endif + + let searchedFor = expand('<cword>') + call eclim#util#EchoInfo("No results for '" . searchedFor . "'.") + endif + endif +endfunction " }}} + +function! s:ViewDoc(...) " {{{ + " View the supplied file in a browser, or if none proved, the file under the + " cursor. + let url = a:0 > 0 ? a:1 : substitute(getline('.'), '\(.\{-}\)|.*', '\1', '') + call eclim#web#OpenUrl(url) +endfunction " }}} + +function! eclim#java#search#CommandCompleteJavaSearch(argLead, cmdLine, cursorPos) " {{{ + let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + if cmdLine =~ '-s\s\+[a-z]*$' + let scopes = deepcopy(s:scopes) + call filter(scopes, 'v:val =~ "^' . argLead . '"') + return scopes + elseif cmdLine =~ '-t\s\+[a-z]*$' + let types = deepcopy(s:types) + call filter(types, 'v:val =~ "^' . argLead . '"') + return types + elseif cmdLine =~ '-x\s\+[a-z]*$' + let contexts = deepcopy(s:contexts) + call filter(contexts, 'v:val =~ "^' . argLead . '"') + return contexts + elseif cmdLine =~ '\s\+[-]\?$' + let options = deepcopy(s:options) + let index = 0 + for option in options + if a:cmdLine =~ option + call remove(options, index) + else + let index += 1 + endif + endfor + return options + endif + return [] +endfunction " }}} + +function! eclim#java#search#FindClassDeclaration() " {{{ + " Used by non java source files to find the declaration of a classname under + " the cursor. + let line = getline('.') + let class = substitute(line, + \ '.\{-}\([0-9a-zA-Z_.]*\%' . col('.') . 'c[0-9a-zA-Z_.]*\).*', '\1', '') + if class != line && class != '' && class =~ '^[a-zA-Z]' + call eclim#java#search#SearchAndDisplay( + \ 'java_search', '-t classOrInterface -p ' . class) + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/src.vim b/vim/eclim/autoload/eclim/java/src.vim @@ -0,0 +1,88 @@ +" Author: Eric Van Dewoestine +" +" License: " {{{ +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:format_command = + \ '-command java_format -p "<project>" -f "<file>" ' . + \ '-h <hoffset> -t <toffset> -e <encoding>' + let s:checkstyle_command = '-command java_checkstyle -p "<project>" -f "<file>"' +" }}} + +function! eclim#java#src#Format(first, last) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + + let command = s:format_command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let begin = eclim#util#GetOffset(a:first, 1) + let end = eclim#util#GetOffset(a:last, 1) + len(getline(a:last)) - 1 + let command = substitute(command, '<hoffset>', begin, '') + let command = substitute(command, '<toffset>', end, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + + let result = eclim#Execute(command) + if result != "0" + call eclim#util#Reload({'retab': 1}) + write + endif +endfunction " }}} + +function! eclim#java#src#Checkstyle() " {{{ + let project = eclim#project#util#GetCurrentProjectName() + if project != "" + let config = + \ eclim#project#util#GetProjectSetting('org.eclim.java.checkstyle.config') + if type(config) == g:NUMBER_TYPE + return + endif + + if config == '' + call eclim#util#EchoWarning( + \ "Before invoking checkstyle, you must first configure the " . + \ "location of your\ncheckstyle config via the setting: " . + \ "'org.eclim.java.checkstyle.config'.") + return + endif + + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:checkstyle_command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + + let result = eclim#Execute(command) + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + call eclim#util#SetLocationList(errors) + else + call eclim#util#ClearLocationList('checkstyle') + endif + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/tools.vim b/vim/eclim/autoload/eclim/java/tools.vim @@ -0,0 +1,310 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/java/tools.html +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:command_src_find = '-command java_src_find -p "<project>" -c "<classname>"' + + let s:entry_match{'junit'} = 'Tests run:' + let s:entry_text_replace{'junit'} = '.*[junit] ' + let s:entry_text_with{'junit'} = '' + + let s:entry_match{'testng'} = 'eclim testng:' + let s:entry_text_replace{'testng'} = '.*eclim testng: .\{-}:' + let s:entry_text_with{'testng'} = '' + + let s:open_console = 'Open jconsole' + let s:view_info = 'View Info' + let s:view_stacks = 'View Stacks' + let s:view_map = 'View Memory Map' + let s:args_main = 'Arguments To Main Method' + let s:args_vm = 'Arguments To JVM' + + let s:supported_command = '\(' . + \ s:open_console . '\|' . + \ s:view_info . '\|' . + \ s:view_stacks . '\|' . + \ s:view_map . + \ '\)' + + hi link JpsArguments Normal + hi link JpsViewAdditional Normal + hi JpsViewAdditional gui=underline,bold term=underline,bold cterm=underline,bold +" }}} + +function! eclim#java#tools#MakeWithJavaBuildTool(compiler, bang, args) " {{{ + augroup eclim_make_java_test + autocmd! + autocmd QuickFixCmdPost make + \ call eclim#java#tools#ResolveQuickfixResults(['junit', 'testng']) + augroup END + + try + call eclim#util#MakeWithCompiler(a:compiler, a:bang, a:args) + finally + silent! autocmd! eclim_make_java_test + endtry +endfunction " }}} + +function! eclim#java#tools#ResolveQuickfixResults(frameworks) " {{{ + " Invoked after a :make to resolve any junit results in the quickfix entries. + let frameworks = type(a:frameworks) == g:LIST_TYPE ? a:frameworks : [a:frameworks] + let entries = getqflist() + let newentries = [] + for entry in entries + let filename = bufname(entry.bufnr) + let text = entry.text + + for framework in frameworks + if entry.text =~ s:entry_match{framework} + let filename = fnamemodify(filename, ':t') + let text = substitute(text, + \ s:entry_text_replace{framework}, s:entry_text_with{framework}, '') + + let project = eclim#project#util#GetCurrentProjectName() + let command = s:command_src_find + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<classname>', filename, '') + let filename = eclim#Execute(command) + if filename == '' + " file not found. + continue + endif + endif + endfor + + if !filereadable(filename) + continue + endif + + let newentry = { + \ 'filename': filename, + \ 'lnum': entry.lnum, + \ 'col': entry.col, + \ 'type': entry.type, + \ 'text': text + \ } + call add(newentries, newentry) + endfor + + call setqflist(newentries, 'r') + + " vim is finicky about changing the quickfix list during a QuickFixCmdPost + " autocmd, so force a delayed reload of the quickfix results + call eclim#util#DelayedCommand('call setqflist(getqflist(), "r")') +endfunction " }}} + +function! eclim#java#tools#Jps() " {{{ + call eclim#util#Echo('Executing...') + + let content = [] + let processes = eclim#java#tools#GetJavaProcesses() + if len(processes) == 1 && string(processes[0]) == '0' + return + endif + + for process in processes + if len(content) > 0 + call add(content, "") + endif + + call add(content, process.id . ' - ' . process.name) + + if executable('jconsole') + call add(content, "\t" . s:open_console) + endif + + if executable('jinfo') + call add(content, "\t" . s:view_info) + endif + + if executable('jstack') + call add(content, "\t" . s:view_stacks) + endif + + if executable('jmap') + call add(content, "\t" . s:view_map) + endif + + call add(content, "") + + call add(content, "\t" . s:args_main . " {") + let args_main = has_key(process, 'args_main') ? + \ map(split(process.args_main), '"\t\t" . v:val') : [] + let content = content + args_main + call add(content, "\t}") + + if has_key(process, 'args_vm') + call add(content, "") + call add(content, "\t" . s:args_vm . " {") + let args_vm = map(split(process.args_vm), '"\t\t" . v:val') + let content = content + args_vm + call add(content, "\t}") + endif + endfor + + if len(content) == 0 + call add(content, 'No Running Java Processes Found') + endif + + call eclim#util#TempWindow('Java_Processes', content) + + setlocal ft=jps_list + setlocal foldmethod=syntax + setlocal foldlevel=0 + setlocal foldtext=getline(v:foldstart) + + exec 'syntax match JpsViewAdditional /' . s:supported_command . '$/' + exec 'syntax region JpsArguments start=/' . s:args_main . ' {$/ end=/^\s*}$/ fold' + exec 'syntax region JpsArguments start=/' . s:args_vm . ' {$/ end=/^\s*}$/ fold' + + nnoremap <silent> <buffer> <cr> :call <SID>ViewAdditionalInfo()<cr> + + call eclim#util#Echo(' ') +endfunction " }}} + +function! eclim#java#tools#GetJavaProcesses() " {{{ + let java_processes = [] + let result = eclim#util#System('jps -vV') + if v:shell_error + call eclim#util#EchoError('Unable to execute jps - ' . result) + return [0] + endif + let vm_args = split(result, '\n') + for process in split(eclim#util#System('jps -lm'), '\n') + if process =~ 'sun.tools.jps.Jps' "|| process =~ '^[0-9]\+\s*$' + continue + endif + + let java_process_info = {} + let java_process_info['id'] = substitute(process, '\(.\{-}\) .*', '\1', '') + let java_process_info['name'] = + \ substitute(process, '.\{-} \(.\{-}\) .*', '\1', '') + if process =~ '.\{-} .\{-} \(.*\)' + let java_process_info['args_main'] = + \ substitute(process, '.\{-} .\{-} \(.*\)', '\1', '') + endif + + let index = 0 + for args in vm_args + if args =~ '^' . java_process_info.id . '\>' + if args =~ '.\{-} .\{-} \(.*\)' + let java_process_info['args_vm'] = + \ substitute(args, '.\{-} .\{-} \(.*\)', '\1', '') + endif + call remove(vm_args, index) + endif + let index += 1 + endfor + + call add(java_processes, java_process_info) + endfor + return java_processes +endfunction " }}} + +function! s:ViewAdditionalInfo() " {{{ + let line = getline('.') + if line =~ '^\s*' . s:supported_command . '$' + " get the process id. + let lnum = search('^[0-9]\+ - ', 'bn') + let id = substitute(getline(lnum), '^\([0-9]\+\) - .*', '\1', '') + + if line =~ '^\s*' . s:open_console . '$' + call s:OpenConsole(id) + elseif line =~ '^\s*' . s:view_info . '$' + call s:ViewInfo(id) + elseif line =~ '^\s*' . s:view_stacks . '$' + call s:ViewStacks(id) + elseif line =~ '^\s*' . s:view_map . '$' + call s:ViewMap(id) + endif + endif +endfunction " }}} + +function! s:OpenConsole(id) " {{{ + call eclim#util#Echo('Executing...') + + if has('win32') || has('win64') + call eclim#util#Exec('silent! !start jconsole ' . a:id) + else + call eclim#util#Exec('silent! !jconsole ' . a:id . ' &') + endif + exec "normal! \<c-l>" + + call eclim#util#Echo(' ') +endfunction " }}} + +function! s:ViewInfo(id) " {{{ + if executable('jinfo') + call eclim#util#Echo('Executing...') + + let content = split(eclim#util#System('jinfo ' . a:id), '\n') + if v:shell_error + call eclim#util#EchoError('Unable to execute jinfo.') + return + endif + + call eclim#util#TempWindow('Java_Process_Info_' . a:id, content) + setlocal ft=jproperties + + call eclim#util#Echo(' ') + endif +endfunction " }}} + +function! s:ViewStacks(id) " {{{ + if executable('jstack') + call eclim#util#Echo('Executing...') + let content = split(eclim#util#System('jstack ' . a:id), '\n') + + if v:shell_error + call eclim#util#EchoError('Unable to execute jstack.') + return + endif + + call map(content, 'substitute(v:val, "^ \\(\\S\\)", " \\1", "")') + call map(content, 'substitute(v:val, "^\t", " ", "")') + + call eclim#util#TempWindow('Java_Process_Stacks_' . a:id, content) + setlocal ft=java + + call eclim#util#Echo(' ') + endif +endfunction " }}} + +function! s:ViewMap(id) " {{{ + if executable('jmap') + call eclim#util#Echo('Executing...') + let content = split(eclim#util#System('jmap ' . a:id), '\n') + + if v:shell_error + call eclim#util#EchoError('Unable to execute jmap.') + return + endif + + call eclim#util#TempWindow('Java_Process_Map_' . a:id, content) + + call eclim#util#Echo(' ') + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/java/util.vim b/vim/eclim/autoload/eclim/java/util.vim @@ -0,0 +1,355 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Utility functions for java eclim ftplugins. +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:keywords = '\(abstract\|assert\|boolean\|case\|catch\|char\|class\|do\|double\|enum\|extends\|final\|finally\|float\|for\|if\|implements\|import\|int\|interface\|long\|new\|null\|package\|private\|protected\|public\|return\|short\|static\|switch\|throw\|throws\|try\|void\|while\)' + + let s:class_declaration = '^\s*\(public\|private\|protected\)\?\(\s\+abstract\)\?\s\+\(class\|interface\|enum\)\s\+[A-Z]' + + let s:command_src_exists = '-command java_src_exists -f "<file>"' + let s:command_list_installs = '-command java_list_installs' + let s:command_classpath = '-command java_classpath -p "<project>"' + let s:command_read_class = '-command java_class_prototype -c <class>' + let s:command_complete_package = '-command java_complete_package -p "<project>"' + + let s:import_pattern = '^\s*import\_s\+<import>\_s*;' +" }}} + +function! eclim#java#util#FileExists(name) " {{{ + let command = substitute(s:command_src_exists, '<file>', a:name, '') + let result = eclim#Execute(command) + return result =~ '^true$' +endfunction " }}} + +function! eclim#java#util#GetClassname(...) " {{{ + if a:0 > 0 + return fnamemodify(a:1, ":t:r") + endif + return expand("%:t:r") +endfunction " }}} + +function! eclim#java#util#GetClassDeclarationPosition(movecursor) " {{{ + let pos = getpos('.') + call cursor(1,1) + + let position = search(s:class_declaration) + + if !a:movecursor || !position + call setpos('.', pos) + endif + + return position +endfunction " }}} + +function! eclim#java#util#GetFullyQualifiedClassname(...) " {{{ + let package = a:0 > 0 ? + \ eclim#java#util#GetPackage(a:1) : + \ eclim#java#util#GetPackage() + let classname = a:0 > 0 ? + \ eclim#java#util#GetClassname(a:1) : + \ eclim#java#util#GetClassname() + return len(package) ? (package . '.' . classname) : classname +endfunction " }}} + +function! eclim#java#util#GetPackage(...) " {{{ + if a:0 > 0 + let winreset = winrestcmd() + silent exec "sview " . a:1 + endif + + let pos = getpos('.') + + call cursor(1,1) + + let package = "" + let packageLine = search('^\s*\<package\>', 'w') + if packageLine > 0 + let package = + \ substitute(getline('.'), '.*\<package\>\s\+\(.\{-\}\)[ ;].*', '\1', '') + endif + + if a:0 > 0 + close + silent exec winreset + + " not necessary and may screw up display (see autoload/project.vim) + "redraw + else + call setpos('.', pos) + endif + + return package +endfunction " }}} + +function! eclim#java#util#GetPackageFromImport(class) " {{{ + let pattern = '^\s*import\s\+\([0-9A-Za-z._]*\)\.' . a:class . '\s*;' + let found = search(pattern, 'wn') + if found + return substitute(getline(found), pattern, '\1', '') + endif + return "" +endfunction " }}} + +function! eclim#java#util#GetSelectedFields(first, last) range " {{{ + " normalize each field statement into a single line. + let selection = '' + let index = a:first + let blockcomment = 0 + while index <= a:last + let line = getline(index) + + " ignore comment lines + if line =~ '^\s*/\*' + let blockcomment = 1 + endif + if blockcomment && line =~ '\*/\s*$' + let blockcomment = 0 + endif + if line !~ '^\s*//' && !blockcomment + " remove quoted values. + let line = substitute(line, '".\{-}"', '', 'g') + " strip off trailing comments + let line = substitute(line, '//.*', '', '') + let line = substitute(line, '/\*.*\*/', '', '') + + let selection = selection . line + endif + + let index += 1 + endwhile + + " compact comma separated multi field declarations + let selection = substitute(selection, ',\s*', ',', 'g') + " break fields back up into their own line. + let selection = substitute(selection, ';', ';\n', 'g') + " remove the assignment portion of the field. + let selection = substitute(selection, '\(.\{-}\)\s*=.\{-};', '\1;', 'g') + + " extract field names + let properties = [] + let lines = split(selection, '\n') + for line in lines + if line !~ '^\s*\/\/' + let fields = substitute(line, '.*\s\(.*\);', '\1', '') + if fields =~ '^[a-zA-Z0-9_,]' + for field in split(fields, ',') + call add(properties, field) + endfor + endif + endif + endfor + + return properties +endfunction " }}} + +function! eclim#java#util#IsKeyword(word) " {{{ + return (a:word =~ '^' . s:keywords . '$\C') +endfunction " }}} + +function! eclim#java#util#IsImported(classname) " {{{ + " search for fully qualified import + let import_search = s:import_pattern + let import_search = substitute(import_search, '<import>', a:classname, '') + let found = search(import_search, 'wn') + if found + return 1 + endif + + " search for package.* import + let package = substitute(a:classname, '\(.*\)\..*', '\1', '') + let import_search = s:import_pattern + let import_search = substitute(import_search, '<import>', package . '\\.\\*', '') + let found = search(import_search, 'wn') + if found + return 1 + endif + + " check if current file and supplied classname are in the same package + if eclim#java#util#GetPackage() == package + return 1 + endif + + " not imported + return 0 +endfunction " }}} + +function! eclim#java#util#IsValidIdentifier(word) " {{{ + if a:word == '' || a:word =~ '\W' || a:word =~ '^\d\+$' || + \ eclim#java#util#IsKeyword(a:word) + return 0 + endif + return 1 +endfunction " }}} + +function! eclim#java#util#Java(classname, args) " {{{ + let project = eclim#project#util#GetCurrentProjectName() + if project == '' && exists('b:project') + let project = b:project + endif + + if project == '' + call eclim#project#util#IsCurrentFileInProject() + return + endif + + let args = eclim#util#ParseArgs(a:args) + let classname = a:classname + if classname == '' && len(args) + let arg1 = args[0] + if arg1 == '%' + let args = args[1:] + let classname = exists('b:filename') ? + \ eclim#java#util#GetFullyQualifiedClassname(b:filename) : + \ eclim#java#util#GetFullyQualifiedClassname() + endif + endif + + let command = '-command java -p "' . project . '"' + if classname != '' + let command .= ' -c ' . classname + endif + + if len(args) + let command .= ' -a' + for arg in args + let arg = substitute(arg, '^-', '\\-', '') + let command .= ' "' . escape(arg, '"') . '"' + endfor + endif + + let result = eclim#Execute(command, {'project': project, 'exec': 1, 'raw': 1}) + let results = split(result, "\n") + call eclim#util#TempWindow('[Java Output]', results) + let b:project = project + + if exists(":Java") != 2 + command -buffer -nargs=* Java :call eclim#java#util#Java('', <q-args>) + endif +endfunction " }}} + +function! eclim#java#util#Classpath(...) " {{{ + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let command = s:command_classpath + let command = substitute(command, '<project>', project, '') + for arg in a:000 + if arg == '\n' + let arg = "\n" + endif + let command .= " \"" . arg . "\"" + endfor + let result = eclim#Execute(command) + if result == '0' + return + endif + call eclim#util#Echo(result) +endfunction " }}} + +function! eclim#java#util#ListInstalls() " {{{ + let installs = eclim#Execute(s:command_list_installs) + if type(installs) != g:LIST_TYPE + return + endif + if len(installs) == 0 + call eclim#util#Echo("No jdk/jre installs found.") + endif + + let pad = 0 + for install in installs + let name = install.name . ' ' . install.version + if install.default + let name .= ' (default)' + endif + let pad = len(name) > pad ? len(name) : pad + endfor + + let output = [] + let type = '' + for install in installs + if install.type != type + let type = install.type + call add(output, 'Type: ' . install.type) + endif + let name = install.name . ' ' . install.version + if install.default + let name .= ' (default)' + endif + call add(output, ' ' . eclim#util#Pad(name, pad) . ' - ' . install.dir) + endfor + call eclim#util#Echo(join(output, "\n")) +endfunction " }}} + +function! eclim#java#util#ReadClassPrototype() " {{{ + let file = substitute(expand('%:p'), '\', '/', 'g') + let command = s:command_read_class + let command = substitute(command, '<class>', expand('%:t:r'), '') + let command .= ' -f "' . file . '"' + + let file = eclim#Execute(command) + if string(file) != '0' + let bufnum = bufnr('%') + if has('win32unix') + let file = eclim#cygwin#CygwinPath(file) + endif + silent exec "keepjumps edit! " . escape(file, ' ') + + exec 'bdelete ' . bufnum + + silent exec "doautocmd BufReadPre " . file + silent exec "doautocmd BufReadPost " . file + + call eclim#util#DelayedCommand('set ft=java') + setlocal readonly + setlocal nomodifiable + setlocal noswapfile + endif +endfunction " }}} + +function! eclim#java#util#CommandCompleteProject(argLead, cmdLine, cursorPos) " {{{ + return eclim#project#util#CommandCompleteProjectByNature( + \ a:argLead, a:cmdLine, a:cursorPos, 'java') +endfunction " }}} + +function! eclim#java#util#CommandCompletePackage(argLead, cmdLine, cursorPos) " {{{ + let cmdTail = strpart(a:cmdLine, a:cursorPos) + let argLead = substitute(a:argLead, cmdTail . '$', '', '') + + let project = eclim#project#util#GetCurrentProjectName() + if project == '' + return [] + endif + + let command = s:command_complete_package + let command = substitute(command, '<project>', project, '') + if argLead != '' + let command .= ' -n ' . argLead + endif + let results = eclim#Execute(command) + return type(results) == g:LIST_TYPE ? results : [] +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/javascript/complete.vim b/vim/eclim/autoload/eclim/javascript/complete.vim @@ -0,0 +1,37 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" see http://eclim.org/vim/javascript/complete.html +" +" License: +" +" Copyright (C) 2005 - 2009 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Varables {{{ + let s:complete_command = + \ '-command javascript_complete ' . + \ '-p "<project>" -f "<file>" -o <offset> -e <encoding>' +" }}} + +" CodeComplete(findstart, base) {{{ +" Handles code completion. +function! eclim#javascript#complete#CodeComplete(findstart, base) + return eclim#lang#CodeComplete(s:complete_command, a:findstart, a:base) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/javascript/util.vim b/vim/eclim/autoload/eclim/javascript/util.vim @@ -0,0 +1,143 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + + if !exists("g:EclimJavascriptValidate") + let g:EclimJavascriptValidate = 1 + endif + + if !exists("g:EclimJavascriptLintEnabled") + " enabling by default until jsdt validation is mature enough to use. + "let g:EclimJavascriptLintEnabled = 0 + let g:EclimJavascriptLintEnabled = 1 + endif + + if !exists('g:EclimJavascriptLintConf') + let g:EclimJavascriptLintConf = eclim#UserHome() . '/.jslrc' + endif +" }}} + +" Script Variables {{{ + let s:warnings = '\(' . join([ + \ 'imported but unused', + \ ], '\|') . '\)' +" }}} + +function! eclim#javascript#util#UpdateSrcFile(on_save) " {{{ + " Optional arg: + " validate: when 1 force the validation to execute, when 0 prevent it. + + " Disabled until the jsdt matures. + "if !a:on_save + " call eclim#lang#UpdateSrcFile('javascript', 1) + "else + " call eclim#lang#UpdateSrcFile('javascript') + "endif + + let validate = !a:on_save || ( + \ g:EclimJavascriptValidate && + \ (!exists('g:EclimFileTypeValidate') || g:EclimFileTypeValidate)) + + if validate && g:EclimJavascriptLintEnabled + call eclim#javascript#util#Jsl() + endif +endfunction " }}} + +function! eclim#javascript#util#Jsl() " {{{ + " Runs jsl (javascript lint) on the current file. + + if eclim#util#WillWrittenBufferClose() + return + endif + + let result = '' + + if !executable('jsl') + if !exists('g:eclim_javascript_jsl_warn') + call eclim#util#EchoWarning("Unable to find 'jsl' command.") + let g:eclim_javascript_jsl_warn = 1 + endif + else + if !exists('g:EclimJavascriptLintVersion') + call eclim#util#System('jsl --help') + let g:EclimJavascriptLintVersion = v:shell_error == 2 ? 'c' : 'python' + endif + + let conf = expand(g:EclimJavascriptLintConf) + + " the c version + if g:EclimJavascriptLintVersion == 'c' + let command = 'jsl -process "' . expand('%:p') . '"' + if filereadable(conf) + let command .= ' -conf "' . conf . '"' + endif + + " the new python version + else + let command = 'jsl "' . expand('%:p') . '"' + if filereadable(conf) + let command .= ' --conf "' . conf . '"' + endif + endif + + let result = eclim#util#System(command) + if v:shell_error == 2 "|| v:shell_error == 4 + call eclim#util#EchoError('Error running command: ' . command) + return + endif + endif + + if result =~ ':' + let results = split(result, '\n') + let errors = [] + for error in results + if error =~ '.\{-}(\d\+): .\{-}: .\{-}' + let file = substitute(error, '\(.\{-}\)([0-9]\+):.*', '\1', '') + let line = substitute(error, '.\{-}(\([0-9]\+\)):.*', '\1', '') + let message = substitute(error, '.\{-}([0-9]\+):.\{-}: \(.*\)', '\1', '') + let dict = { + \ 'filename': eclim#util#Simplify(file), + \ 'lnum': line, + \ 'text': "[jsl] " . message, + \ 'type': error =~ ': \(lint \)\?warning:' ? 'w' : 'e', + \ } + + call add(errors, dict) + endif + endfor + + call eclim#display#signs#SetPlaceholder() + call eclim#util#ClearLocationList('jsl') + if &ft == 'javascript' + call eclim#util#SetLocationList(errors) + else + call eclim#util#SetLocationList(errors, 'a') + endif + call eclim#display#signs#RemovePlaceholder() + else + call eclim#util#ClearLocationList('jsl') + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/lang.vim b/vim/eclim/autoload/eclim/lang.vim @@ -0,0 +1,649 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" Common language functionality (validation, completion, etc.) abstracted +" into re-usable functions. +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Varables {{{ + if !exists('g:EclimTempFilesEnable') + let g:EclimTempFilesEnable = 1 + endif + + if !exists('g:EclimFileTypeValidate') + let g:EclimFileTypeValidate = 1 + endif + + if !exists('g:EclimRefactorDiffOrientation') + let g:EclimRefactorDiffOrientation = 'vertical' + endif +" }}} + +" Script Variables {{{ + let s:update_command = '-command <lang>_src_update -p "<project>" -f "<file>"' + let s:validate_command = '-command <type>_validate -p "<project>" -f "<file>"' + let s:undoredo_command = '-command refactor_<operation>' +" }}} + +function! eclim#lang#CodeComplete(command, findstart, base, ...) " {{{ + " Optional args: + " options: dict containing one or more of the following: + " temp: 1 to use a temp file, 0 otherwise + " regex: regular expression of characters to walk back over to find the + " starting position of the completion. + " layout: passed through to the eclimd completion for languages that + " support this (typically decides how overloaded method names are + " presented in the completion list). + + if !eclim#project#util#IsCurrentFileInProject(0) + return a:findstart ? -1 : [] + endif + + let options = a:0 ? a:1 : {} + + if a:findstart + call eclim#lang#SilentUpdate(get(options, 'temp', 1)) + + " locate the start of the word + let line = getline('.') + + let start = col('.') - 1 + + "exceptions that break the rule + if line[start] =~ '\.' + let start -= 1 + endif + + let pattern = get(options, 'regex', '\w') + while start > 0 && line[start - 1] =~ pattern + let start -= 1 + endwhile + + return start + else + let offset = eclim#util#GetOffset() + len(a:base) + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#lang#SilentUpdate(get(options, 'temp', 1), 0) + if file == '' + return [] + endif + + let command = a:command + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + if has_key(options, 'layout') + let command = substitute(command, '<layout>', options.layout, '') + endif + + let completions = [] + let results = eclim#Execute(command) + if type(results) != g:LIST_TYPE + return + endif + + let open_paren = getline('.') =~ '\%' . col('.') . 'c\s*(' + let close_paren = getline('.') =~ '\%' . col('.') . 'c\s*(\s*)' + + for result in results + let word = result.completion + + " strip off close paren if necessary. + if word =~ ')$' && close_paren + let word = strpart(word, 0, strlen(word) - 1) + endif + + " strip off open paren if necessary. + if word =~ '($' && open_paren + let word = strpart(word, 0, strlen(word) - 1) + endif + + let menu = eclim#html#util#HtmlToText(result.menu) + let info = has_key(result, 'info') ? + \ eclim#html#util#HtmlToText(result.info) : '' + + let dict = { + \ 'word': word, + \ 'menu': menu, + \ 'info': info, + \ 'dup': 1 + \ } + + call add(completions, dict) + endfor + + return completions + endif +endfunction " }}} + +" Search(command, singleResultAction, argline) {{{ +" Executes a search. +function! eclim#lang#Search(command, singleResultAction, argline) + let argline = a:argline + "if argline == '' + " call eclim#util#EchoError('You must supply a search pattern.') + " return + "endif + + " check if pattern supplied without -p. + if argline !~ '^\s*-[a-z]' && argline !~ '^\s*$' + let argline = '-p ' . argline + endif + + if !eclim#project#util#IsCurrentFileInProject(0) + let args = eclim#util#ParseArgs(argline) + let index = index(args, '-s') + 1 + if index && len(args) > index && args[index] != 'all' + return + endif + let argline .= ' -s all' + endif + + let search_cmd = a:command + let project = eclim#project#util#GetCurrentProjectName() + if project != '' + let search_cmd .= ' -n "' . project . '"' + endif + + " no pattern supplied, use element search. + if argline !~ '-p\>' + if !eclim#project#util#IsCurrentFileInProject(1) + return + endif + " update the file. + call eclim#util#ExecWithoutAutocmds('silent update') + + let file = eclim#project#util#GetProjectRelativeFilePath() + let position = eclim#util#GetCurrentElementPosition() + let offset = substitute(position, '\(.*\);\(.*\)', '\1', '') + let length = substitute(position, '\(.*\);\(.*\)', '\2', '') + let encoding = eclim#util#GetEncoding() + let search_cmd .= ' -f "' . file . '"' . + \ ' -o ' . offset . ' -l ' . length . ' -e ' . encoding + else + " quote the search pattern + let search_cmd = substitute( + \ search_cmd, '\(.*-p\s\+\)\(.\{-}\)\(\s\|$\)\(.*\)', '\1"\2"\3\4', '') + endif + + let search_cmd .= ' ' . argline + let results = eclim#Execute(search_cmd) + if type(results) != g:LIST_TYPE + return + endif + + if !empty(results) + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries(results)) + let locs = getloclist(0) + " if only one result and it's for the current file, just jump to it. + " note: on windows the expand result must be escaped + if len(results) == 1 && locs[0].bufnr == bufnr('%') + if results[0].line != 1 && results[0].column != 1 + lfirst + endif + + " single result in another file. + elseif len(results) == 1 && a:singleResultAction != "lopen" + let entry = getloclist(0)[0] + call eclim#util#GoToBufferWindowOrOpen + \ (bufname(entry.bufnr), a:singleResultAction) + call eclim#util#SetLocationList(eclim#util#ParseLocationEntries(results)) + call eclim#display#signs#Update() + + call cursor(entry.lnum, entry.col) + else + exec 'lopen ' . g:EclimLocationListHeight + endif + return 1 + else + if argline !~ '-p\>' + call eclim#util#EchoInfo("Element not found.") + else + let searchedFor = substitute(argline, '.*-p \(.\{-}\)\( .*\|$\)', '\1', '') + call eclim#util#EchoInfo("Pattern '" . searchedFor . "' not found.") + endif + endif + +endfunction " }}} + +function! eclim#lang#IsFiletypeValidationEnabled(lang) " {{{ + " global setting + if !g:EclimFileTypeValidate + return 0 + endif + " per lang setting + exec 'let validate = g:Eclim' . toupper(a:lang[0]) . a:lang[1:] . 'Validate' + return validate +endfunction " }}} + +function! eclim#lang#DisableSyntasticIfValidationIsEnabled(lang, ...) " {{{ + "Optional arg: + " syntastic lang: The syntastic lang string if it doesn't match eclim's lang. + + if exists('g:loaded_syntastic_plugin') && + \ eclim#lang#IsFiletypeValidationEnabled(a:lang) + let lang = a:0 ? a:1 : a:lang + exec 'let syntastic_enabled = ' . + \ 'g:Eclim' . toupper(lang[0]) . lang[1:] . 'SyntasticEnabled' + + if !syntastic_enabled + if !exists('g:syntastic_mode_map') + let g:syntastic_mode_map = {'passive_filetypes': []} + elseif !has_key(g:syntastic_mode_map, 'passive_filetypes') + let g:syntastic_mode_map.passive_filetypes = [] + endif + if index(g:syntastic_mode_map.passive_filetypes, lang) == -1 + call add(g:syntastic_mode_map.passive_filetypes, lang) + endif + endif + endif +endfunction " }}} + +function! eclim#lang#UpdateSrcFile(lang, ...) " {{{ + " Updates the src file on the server w/ the changes made to the current file. + " Optional arg: + " validate: when 1 force the validation to execute, when 0 prevent it. + + if !a:0 + let validate = eclim#lang#IsFiletypeValidationEnabled(a:lang) + else + " arg override + let validate = a:1 + endif + + let project = eclim#project#util#GetCurrentProjectName() + if project != "" + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:update_command + let command = substitute(command, '<lang>', a:lang, '') + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + if validate && !eclim#util#WillWrittenBufferClose() + let command = command . ' -v' + if eclim#project#problems#IsProblemsList() && + \ g:EclimProjectProblemsUpdateOnSave + let command = command . ' -b' + endif + endif + + let result = eclim#Execute(command) + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + call eclim#util#SetLocationList(errors) + else + call eclim#util#ClearLocationList('global') + endif + + call eclim#project#problems#ProblemsUpdate('save') + elseif validate && expand('<amatch>') == '' + call eclim#project#util#IsCurrentFileInProject() + endif +endfunction " }}} + +" Validate(type, on_save, [filter]) {{{ +" Validates the current file. Used by languages which are not validated via +" UpdateSrcFile (pretty much all the xml dialects and wst langs). +function! eclim#lang#Validate(type, on_save, ...) + if eclim#util#WillWrittenBufferClose() + return + endif + + if !eclim#project#util#IsCurrentFileInProject(!a:on_save) + return + endif + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let command = s:validate_command + let command = substitute(command, '<type>', a:type, '') + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + + let result = eclim#Execute(command) + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + if a:0 + let errors = function(a:1)(errors) + endif + call eclim#util#SetLocationList(errors) + else + call eclim#util#ClearLocationList() + endif +endfunction " }}} + +function! eclim#lang#SilentUpdate(...) " {{{ + " Silently updates the current source file w/out validation. + " Optional args: + " temp: construct a temp file path for the current file and return that path + " (default is to not create a temp file) + " temp_write: when constructing a temp file path, whether or not to write + " the current file's contents to that path (default is to do so) + + " i couldn't reproduce the issue, but at least one person experienced the + " cursor moving on update and breaking code completion: + " http://sourceforge.net/tracker/index.php?func=detail&aid=1995319&group_id=145869&atid=763323 + let pos = getpos('.') + silent let file = eclim#project#util#GetProjectRelativeFilePath() + if file != '' + try + if a:0 && a:1 && g:EclimTempFilesEnable + " don't create temp files if no server is available to clean them up. + let project = eclim#project#util#GetCurrentProjectName() + let workspace = eclim#project#util#GetProjectWorkspace(project) + if workspace != '' && eclim#PingEclim(0, workspace) + let prefix = '__eclim_temp_' + let file = fnamemodify(file, ':h') . '/' . prefix . fnamemodify(file, ':t') + let tempfile = expand('%:p:h') . '/' . prefix . expand('%:t') + if a:0 < 2 || a:2 + let savepatchmode = &patchmode + set patchmode= + exec 'silent noautocmd keepalt write! ' . escape(tempfile, ' ') + let &patchmode = savepatchmode + endif + endif + else + if a:0 < 2 || a:2 + silent noautocmd update + endif + endif + finally + call setpos('.', pos) + endtry + endif + return file +endfunction " }}} + +" Refactor(command) {{{ +" Executes the supplied refactoring command handle error response and +" reloading files that have changed. +function! eclim#lang#Refactor(command) + let cwd = substitute(getcwd(), '\', '/', 'g') + let cwd_return = 1 + + try + " turn off swap files temporarily to avoid issues with folder/file + " renaming. + let bufend = bufnr('$') + let bufnum = 1 + while bufnum <= bufend + if bufexists(bufnum) + call setbufvar(bufnum, 'save_swapfile', getbufvar(bufnum, '&swapfile')) + call setbufvar(bufnum, '&swapfile', 0) + endif + let bufnum = bufnum + 1 + endwhile + + " cd to the project root to avoid folder renaming issues on windows. + exec 'cd ' . escape(eclim#project#util#GetCurrentProjectRoot(), ' ') + + let result = eclim#Execute(a:command) + if type(result) != g:LIST_TYPE && type(result) != g:DICT_TYPE + return + endif + + " error occurred + if type(result) == g:DICT_TYPE && has_key(result, 'errors') + call eclim#util#EchoError(result.errors) + return + endif + + " reload affected files. + let curwin = winnr() + try + for info in result + let newfile = '' + " handle file renames + if has_key(info, 'to') + let file = info.from + let newfile = info.to + if has('win32unix') + let newfile = eclim#cygwin#CygwinPath(newfile) + endif + else + let file = info.file + endif + + if has('win32unix') + let file = eclim#cygwin#CygwinPath(file) + endif + + " ignore unchanged directories + if isdirectory(file) + continue + endif + + " handle current working directory moved. + if newfile != '' && isdirectory(newfile) + if file =~ '^' . cwd . '\(/\|$\)' + while cwd !~ '^' . file . '\(/\|$\)' + let file = fnamemodify(file, ':h') + let newfile = fnamemodify(newfile, ':h') + endwhile + endif + + if cwd =~ '^' . file . '\(/\|$\)' + let dir = substitute(cwd, file, newfile, '') + exec 'cd ' . escape(dir, ' ') + let cwd_return = 0 + endif + continue + endif + + let winnr = bufwinnr(file) + if winnr > -1 + exec winnr . 'winc w' + if newfile != '' + let bufnr = bufnr('%') + enew + exec 'bdelete ' . bufnr + exec 'edit ' . escape(eclim#util#Simplify(newfile), ' ') + else + call eclim#util#Reload({'retab': 1}) + endif + endif + endfor + finally + exec curwin . 'winc w' + if cwd_return + exec 'cd ' . escape(cwd, ' ') + endif + endtry + finally + " re-enable swap files + let bufnum = 1 + while bufnum <= bufend + if bufexists(bufnum) + let save_swapfile = getbufvar(bufnum, 'save_swapfile') + if save_swapfile != '' + call setbufvar(bufnum, '&swapfile', save_swapfile) + endif + endif + let bufnum = bufnum + 1 + endwhile + endtry +endfunction " }}} + +" RefactorPreview(command) {{{ +" Executes the supplied refactor preview command and opens a corresponding +" window to view that preview. +function! eclim#lang#RefactorPreview(command) + let result = eclim#Execute(a:command) + if type(result) != g:DICT_TYPE + return + endif + + " error occurred + if has_key(result, 'errors') + call eclim#util#EchoError(result.errors) + return + endif + + let lines = [] + for change in result.changes + if change.type == 'diff' + call add(lines, '|diff|: ' . change.file) + else + call add(lines, change.type . ': ' . change.message) + endif + endfor + + call add(lines, '') + call add(lines, '|Execute Refactoring|') + call eclim#util#TempWindow('[Refactor Preview]', lines) + let b:refactor_command = result.apply + + set ft=refactor_preview + hi link RefactorLabel Identifier + hi link RefactorLink Label + syntax match RefactorLabel /^\s*\w\+:/ + syntax match RefactorLink /|\S.\{-}\S|/ + + nnoremap <silent> <buffer> <cr> :call eclim#lang#RefactorPreviewLink()<cr> +endfunction " }}} + +" RefactorPreviewLink() {{{ +" Called when a user hits <cr> on a link in the refactor preview window, +" issuing a diff for that file. +function! eclim#lang#RefactorPreviewLink() + let line = getline('.') + if line =~ '^|' + let command = b:refactor_command + + let winend = winnr('$') + let winnum = 1 + while winnum <= winend + let bufnr = winbufnr(winnum) + if getbufvar(bufnr, 'refactor_preview_diff') != '' + exec bufnr . 'bd' + continue + endif + let winnum += 1 + endwhile + + if line == '|Execute Refactoring|' + call eclim#lang#Refactor(command) + let winnr = b:winnr + close + " the filename might change, so we have to use the winnr to get back to + " where we were. + exec winnr . 'winc w' + + elseif line =~ '^|diff|' + let file = substitute(line, '^|diff|:\s*', '', '') + let command .= ' -v -d "' . file . '"' + + let diff = eclim#Execute(command) + if type(diff) != g:STRING_TYPE + return + endif + + " split relative to the original window + exec b:winnr . 'winc w' + + if has('win32unix') + let file = eclim#cygwin#CygwinPath(file) + endif + let name = fnamemodify(file, ':t:r') + let ext = fnamemodify(file, ':e') + exec printf('silent below new %s.current.%s', name, ext) + silent 1,$delete _ " counter-act any templating plugin + exec 'read ' . escape(file, ' ') + silent 1,1delete _ + let winnr = winnr() + let b:refactor_preview_diff = 1 + setlocal readonly nomodifiable + setlocal noswapfile nobuflisted + setlocal buftype=nofile bufhidden=delete + diffthis + + let orien = g:EclimRefactorDiffOrientation == 'horizontal' ? '' : 'vertical' + exec printf('silent below %s split %s.new.%s', orien, name, ext) + silent 1,$delete _ " counter-act any templating plugin + call append(1, split(diff, "\n")) + let b:refactor_preview_diff = 1 + silent 1,1delete _ + setlocal readonly nomodifiable + setlocal noswapfile nobuflisted + setlocal buftype=nofile bufhidden=delete + diffthis + exec winnr . 'winc w' + endif + endif +endfunction " }}} + +" RefactorPrompt(prompt) {{{ +" Issues the standard prompt for language refactorings. +function! eclim#lang#RefactorPrompt(prompt) + exec "echohl " . g:EclimInfoHighlight + try + " clear any previous messages + redraw + echo a:prompt . "\n" + let response = input("([e]xecute / [p]review / [c]ancel): ") + while response != '' && + \ response !~ '^\c\s*\(e\(xecute\)\?\|p\(review\)\?\|c\(ancel\)\?\)\s*$' + let response = input("You must choose either e, p, or c. (Ctrl-C to cancel): ") + endwhile + finally + echohl None + endtry + + if response == '' + return -1 + endif + + if response =~ '\c\s*\(c\(ancel\)\?\)\s*' + return 0 + endif + + return response =~ '\c\s*\(e\(execute\)\?\)\s*' ? 1 : 2 " preview +endfunction " }}} + +" UndoRedo(operation, peek) {{{ +" Performs an undo or redo (operation = 'undo' or 'redo') for the last +" executed refactoring. +function! eclim#lang#UndoRedo(operation, peek) + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + " update the file before vim makes any changes. + call eclim#lang#SilentUpdate() + wall + + let command = s:undoredo_command + let command = substitute(command, '<operation>', a:operation, '') + if a:peek + let command .= ' -p' + let result = eclim#Execute(command) + if type(result) == g:STRING_TYPE + call eclim#util#Echo(result) + endif + return + endif + + call eclim#lang#Refactor(command) +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/lang/hierarchy.vim b/vim/eclim/autoload/eclim/lang/hierarchy.vim @@ -0,0 +1,139 @@ +" Author: Eric Van Dewoestine +" +" License: {{{ +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Script Variables {{{ + let s:call_hierarchy = + \ '-command <lang>_callhierarchy -p "<project>" -f "<file>" ' . + \ '-o <offset> -l <length> -e <encoding>' +" }}} + +function! eclim#lang#hierarchy#CallHierarchy(lang, default_action, bang) " {{{ + if !eclim#project#util#IsCurrentFileInProject(1) + return + endif + + call eclim#lang#SilentUpdate() + + let project = eclim#project#util#GetCurrentProjectName() + let file = eclim#project#util#GetProjectRelativeFilePath() + let position = eclim#util#GetCurrentElementPosition() + let offset = substitute(position, '\(.*\);\(.*\)', '\1', '') + let length = substitute(position, '\(.*\);\(.*\)', '\2', '') + let command = s:call_hierarchy + let command = substitute(command, '<lang>', a:lang, '') + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<file>', file, '') + let command = substitute(command, '<offset>', offset, '') + let command = substitute(command, '<length>', length, '') + let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '') + " return callees + if a:bang != '' + let command .= ' -c' + endif + + let result = eclim#Execute(command) + if type(result) != g:DICT_TYPE + return + endif + + if len(result) == 0 + call eclim#util#Echo('No results found.') + return + endif + + let lines = [] + let info = [] + let key = a:bang != '' ? 'callees' : 'callers' + call s:CallHierarchyFormat(result, key, lines, info, '') + + call eclim#util#TempWindow('[Call Hierarchy]', lines) + exec 'set ft=' . a:lang + " fold function calls into their parent + setlocal foldmethod=expr + setlocal foldexpr='>'.len(substitute(getline(v:lnum),'^\\(\\s*\\).*','\\1',''))/2 + setlocal foldtext=substitute(getline(v:foldstart),'^\\(\\s*\\)\\s\\s','\\1+\ ','').':\ '.(v:foldend-v:foldstart+1).'\ lines' + + setlocal modifiable noreadonly + call append(line('$'), ['', '" use ? to view help']) + setlocal nomodifiable readonly + syntax match Comment /^".*/ + + let b:hierarchy_info = info + + exec 'nnoremap <buffer> <silent> <cr> ' . + \ ':call <SID>Open("' . a:default_action . '")<cr>' + nnoremap <buffer> <silent> E :call <SID>Open('edit')<cr> + nnoremap <buffer> <silent> S :call <SID>Open('split')<cr> + nnoremap <buffer> <silent> T :call <SID>Open("tablast \| tabnew")<cr> + + " assign to buffer var to get around weird vim issue passing list containing + " a string w/ a '<' in it on execution of mapping. + let b:hierarchy_help = [ + \ '<cr> - open file with default action', + \ 'E - open with :edit', + \ 'S - open in a new split window', + \ 'T - open in a new tab', + \ ] + nnoremap <buffer> <silent> ? + \ :call eclim#help#BufferHelp(b:hierarchy_help, 'vertical', 40)<cr> +endfunction " }}} + +function! s:CallHierarchyFormat(result, key, lines, info, indent) " {{{ + if has_key(a:result, 'position') + call add(a:info, { + \ 'file': a:result.position.filename, + \ 'line': a:result.position.line, + \ 'col': a:result.position.column + \ }) + call add(a:lines, a:indent . a:result.name) + else + call add(a:info, {'file': '', 'line': -1, 'col': -1}) + call add(a:lines, a:indent . a:result.name) + endif + + for call in get(a:result, a:key, []) + call s:CallHierarchyFormat(call, a:key, a:lines, a:info, a:indent . "\t") + endfor +endfunction " }}} + +function! s:Open(action) " {{{ + let line = line('.') + if line > len(b:hierarchy_info) + return + endif + + let info = b:hierarchy_info[line - 1] + if info.file != '' + " go to the buffer that initiated the hierarchy + exec b:winnr . 'winc w' + + let action = a:action + call eclim#util#GoToBufferWindowOrOpen(info.file, action) + call cursor(info.line, info.col) + + " force any previous messge from else below to be cleared + echo '' + else + call eclim#util#Echo('No associated file was found.') + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/project/problems.vim b/vim/eclim/autoload/eclim/project/problems.vim @@ -0,0 +1,133 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global variables {{{ + if !exists('g:EclimProblemsQuickFixOpen') + let g:EclimProblemsQuickFixOpen = 'botright copen' + endif +" }}} + +" Script variables {{{ + let s:problems_command = '-command problems -p "<project>"' +" }}} + +function! eclim#project#problems#Problems(project, open, bang) " {{{ + let project = a:project + if project == '' + let project = eclim#project#util#GetCurrentProjectName() + endif + if project == '' + call eclim#project#util#UnableToDetermineProject() + return + endif + + let command = s:problems_command + let command = substitute(command, '<project>', project, '') + if a:bang != "" + let command .= ' -e' + endif + let result = eclim#Execute(command) + let errors = [] + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + endif + + let action = eclim#project#problems#IsProblemsList() ? 'r' : ' ' + call eclim#util#SetQuickfixList(errors, action) + + " generate a 'signature' to distinguish the problems list from other qf + " lists. + let s:eclim_problems_sig = s:QuickfixSignature() + let s:eclim_problems_bang = a:bang + + if a:open + exec g:EclimProblemsQuickFixOpen + endif +endfunction " }}} + +function! eclim#project#problems#ProblemsUpdate(action) " {{{ + if a:action == 'save' && !g:EclimProjectProblemsUpdateOnSave + return + endif + + if a:action == 'build' && !g:EclimProjectProblemsUpdateOnBuild + return + endif + + if !eclim#project#problems#IsProblemsList() + return + endif + + " preserve the cursor position in the quickfix window + let qf_winnr = 0 + let index = 1 + while index <= winnr('$') + if getbufvar(winbufnr(index), '&ft') == 'qf' + let cur = winnr() + let qf_winnr = index + exec qf_winnr . 'winc w' + let pos = getpos('.') + exec cur . 'winc w' + break + endif + let index += 1 + endwhile + + let bang = exists('s:eclim_problems_bang') ? s:eclim_problems_bang : '' + call eclim#project#problems#Problems('', 0, bang) + + " restore the cursor position + if qf_winnr + let cur = winnr() + exec qf_winnr . 'winc w' + call setpos('.', pos) + redraw + exec cur . 'winc w' + endif +endfunction " }}} + +function! eclim#project#problems#IsProblemsList() " {{{ + " if available, compare the problems signature against the signature of + " the current list to see if we are now on the problems list, probably via + " :colder or :cnewer. + if exists('s:eclim_problems_sig') + return s:QuickfixSignature() == s:eclim_problems_sig + endif + if exists('s:eclim_problems_bang') + unlet s:eclim_problems_bang + endif + return 0 +endfunction " }}} + +function! s:QuickfixSignature() " {{{ + let qflist = getqflist() + let len = len(qflist) + return { + \ 'len': len, + \ 'first': len > 0 ? (qflist[0]['bufnr'] . ':' . qflist[0]['text']) : '', + \ 'last': len > 0 ? (qflist[-1]['bufnr'] . ':' . qflist[-1]['text']) : '' + \ } +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/project/tree.vim b/vim/eclim/autoload/eclim/project/tree.vim @@ -0,0 +1,522 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2014 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ + if !exists('g:EclimProjectTreeActions') + let g:EclimProjectTreeActions = [ + \ {'pattern': '.*', 'name': 'Split', 'action': 'split'}, + \ {'pattern': '.*', 'name': 'VSplit', 'action': 'vsplit'}, + \ {'pattern': '.*', 'name': 'Tab', 'action': 'tablast | tabnew'}, + \ {'pattern': '.*', 'name': 'Edit', 'action': 'edit'}, + \ ] + endif + if !exists('g:EclimProjectTreePathEcho') + let g:EclimProjectTreePathEcho = 1 + endif +" }}} + +" Script Variables {{{ + let s:project_tree_ids = 0 + let s:shared_instances_by_buffer = {} + let s:shared_instances_by_names = {} +" }}} + +function! eclim#project#tree#ProjectTree(...) " {{{ + " Open a tree view of the current or specified projects. + + " no project dirs supplied, use current project + if len(a:000) == 0 + let name = eclim#project#util#GetCurrentProjectName() + let names = [name] + if name == '' + if exists('t:cwd') + let names = [t:cwd] + else + call eclim#project#util#UnableToDetermineProject() + return + endif + endif + + " list of project names supplied + elseif type(a:000[0]) == g:LIST_TYPE + let names = a:000[0] + if len(names) == 1 && (names[0] == '0' || names[0] == '') + return + endif + + " list or project names + else + let names = a:000 + endif + + let dirs = [] + let index = 0 + let names_copy = copy(names) + for name in names + if name == 'CURRENT' + let name = eclim#project#util#GetCurrentProjectName() + let names_copy[index] = name + endif + + let dir = eclim#project#util#GetProjectRoot(name) + if dir == '' + let dir = expand(name, ':p') + if !isdirectory(dir) + if eclim#EclimAvailable(0) + call eclim#util#EchoWarning('Project not found: ' . name) + endif + call remove(names_copy, index) + continue + endif + let names_copy[index] = fnamemodify(substitute(dir, '/$', '', ''), ':t') + endif + call add(dirs, dir) + let index += 1 + endfor + let names = names_copy + + if len(dirs) == 0 + return + endif + + " for session reload + let g:Eclim_project_tree_names = join(names, '|') + + let display = len(names) == 1 ? + \ 'Project: ' . names[0] : + \ 'Projects: ' . join(names, ', ') + + call eclim#project#tree#ProjectTreeClose() + call eclim#project#tree#ProjectTreeOpen(display, names, dirs) +endfunction " }}} + +function! eclim#project#tree#ProjectTreeToggle() " {{{ + let title = s:GetTreeTitle() + let bufnum = bufnr(title) + let winnum = bufwinnr(title) + if bufnum == -1 || winnum == -1 + call eclim#project#tree#ProjectTree() + else + exec winnum . 'winc w' + close + winc p + endif +endfunction " }}} + +function! eclim#project#tree#ProjectTreeOpen(display, names, dirs) " {{{ + let expand = len(a:dirs) == 1 + let expandDir = '' + if expand && g:EclimProjectTreeExpandPathOnOpen + let expandDir = substitute(expand('%:p:h'), '\', '/', 'g') + endif + + " see if we should just use a shared tree + let shared = s:GetSharedTreeBuffer(a:names) + if shared != -1 && bufloaded(shared) + call eclim#display#window#VerticalToolWindowOpen(bufname(shared), 9) + "exec 'buffer ' . shared + if line('$') > 1 || getline(1) !~ '^\s*$' + setlocal nowrap nonumber + setlocal foldmethod=manual foldtext=getline(v:foldstart) + exec 'setlocal statusline=' . escape(a:display, ' ') + if !exists('t:project_tree_name') + exec 'let t:project_tree_id = ' . + \ substitute(bufname(shared), g:EclimProjectTreeTitle . '\(\d\+\)', '\1', '') + endif + + if expand && expandDir != '' + call eclim#tree#ExpandPath(s:GetTreeTitle(), expandDir) + endif + + return + endif + endif + + " clear the project tree id if we are replacing a shared tree instance + if g:EclimProjectTreeSharedInstance && exists('t:project_tree_id') + unlet t:project_tree_id + endif + + call eclim#display#window#VerticalToolWindowOpen(s:GetTreeTitle(), 9) + + " command used to navigate to a content window before executing a command. + if !exists('g:EclimProjectTreeContentWincmd') + if g:VerticalToolWindowSide == 'right' + let g:EclimProjectTreeContentWincmd = 'winc h' + else + let g:EclimProjectTreeContentWincmd = 'winc l' + endif + endif + + if exists('g:TreeSettingsFunction') + let s:TreeSettingsFunction = g:TreeSettingsFunction + endif + let g:TreeSettingsFunction = 'eclim#project#tree#ProjectTreeSettings' + + try + call eclim#tree#Tree(s:GetTreeTitle(), a:dirs, a:names, expand, []) + finally + if exists('s:TreeSettingsFunction') + let g:TreeSettingsFunction = s:TreeSettingsFunction + else + unlet g:TreeSettingsFunction + endif + endtry + + setlocal bufhidden=hide + exec 'setlocal statusline=' . escape(a:display, ' ') + + if expand && expandDir != '' + call eclim#util#DelayedCommand( + \ 'call eclim#tree#ExpandPath("' . s:GetTreeTitle() . '", "' . expandDir . '")') + endif + + normal! zs + + let instance_names = join(a:names, '_') + let instance_names = substitute(instance_names, '\W', '_', 'g') + + " remove the old associated tree value if one exists + silent! unlet s:shared_instances_by_names[s:shared_instances_by_buffer[bufnr('%')]] + + let s:shared_instances_by_buffer[bufnr('%')] = instance_names + let s:shared_instances_by_names[instance_names] = bufnr('%') + + call s:Mappings() + setlocal modifiable + call append(line('$'), ['', '" use ? to view help']) + call s:InfoLine() + setlocal nomodifiable +endfunction " }}} + +function! eclim#project#tree#ProjectTreeClose() " {{{ + if exists('t:project_tree_name') || exists('t:project_tree_id') + let winnr = bufwinnr(s:GetTreeTitle()) + if winnr != -1 + exec winnr . 'winc w' + close + endif + endif +endfunction " }}} + +function! eclim#project#tree#Restore() " {{{ + if exists('t:project_tree_restoring') + return + endif + let t:project_tree_restoring = 1 + + " prevent auto open from firing after session is loaded. + augroup project_tree_autoopen + autocmd! + augroup END + + let title = s:GetTreeTitle() + let winnum = bufwinnr(title) + if winnum != -1 + if exists('g:Eclim_project_tree_names') + let projects = split(g:Eclim_project_tree_names, '|') + call map(projects, 'escape(v:val, " ")') + let names = join(projects, ' ') + call eclim#util#DelayedCommand( + \ 'let bufnum = bufnr("%") | ' . + \ 'exec "ProjectTree ' . names . '" | ' . + \ 'exec bufwinnr(bufnum) . "winc w" | ' . + \ 'unlet t:project_tree_restoring') + else + exec 'bd ' . bufnr(title) + endif + endif +endfunction " }}} + +function! s:GetTreeTitle() " {{{ + " support a custom name from an external plugin + if exists('t:project_tree_name') + return t:project_tree_name + endif + + if !exists('t:project_tree_id') + let t:project_tree_id = s:project_tree_ids + 1 + let s:project_tree_ids += 1 + endif + return g:EclimProjectTreeTitle . t:project_tree_id +endfunction " }}} + +function! s:GetSharedTreeBuffer(names) " {{{ + let instance_names = join(a:names, '_') + let instance_names = substitute(instance_names, '\W', '_', 'g') + if g:EclimProjectTreeSharedInstance && + \ has_key(s:shared_instances_by_names, instance_names) + return s:shared_instances_by_names[instance_names] + endif + return -1 +endfunction " }}} + +function! s:Mappings() " {{{ + nnoremap <buffer> <silent> E :call <SID>OpenFile('edit')<cr> + nnoremap <buffer> <silent> S :call <SID>OpenFile('split')<cr> + nnoremap <buffer> <silent> \| :call <SID>OpenFile('vsplit')<cr> + nnoremap <buffer> <silent> T :call <SID>OpenFile('tablast \| tabnew')<cr> + nnoremap <buffer> <silent> F :call <SID>OpenFileName()<cr> + nnoremap <buffer> <silent> Y :call <SID>YankFileName()<cr> + + " assign to buffer var to get around weird vim issue passing list containing + " a string w/ a '<' in it on execution of mapping. + let b:project_tree_help = [ + \ '<cr> - open/close dir, open file', + \ 'o - toggle dir fold, choose file open action', + \ 'E - open with :edit', + \ 'S - open in a new split window', + \ '| (pipe) - open in a new vertical split window', + \ 'T - open in a new tab', + \ 'R - refresh directory', + \ 'i - view file info', + \ 's - open shell at directory', + \ 'p - move cursor to parent dir', + \ 'P - move cursor to last child of dir', + \ 'C - set root to dir under the cursor', + \ 'B - set root up one dir', + \ '~ - set root to home dir', + \ 'K - set root to top most dir', + \ 'F - open/create a file by name', + \ 'D - create a new directory', + \ 'Y - yank current file/dir path to the clipboard', + \ 'A - toggle hide/view hidden files', + \ ':CD <dir> - set the root to <dir>', + \ ] + nnoremap <buffer> <silent> ? + \ :call eclim#help#BufferHelp(b:project_tree_help, 'horizontal', 10)<cr> +endfunction " }}} + +function! s:InfoLine() " {{{ + setlocal modifiable + let pos = getpos('.') + if len(b:roots) == 1 + let lnum = line('$') - 1 + if getline(lnum) =~ '^"' + exec lnum . ',' . lnum . 'delete _' + endif + + let info = '' + try + let info = function('vcs#util#GetInfo')(b:roots[0]) + catch /E\(117\|700\)/ + " fall back to fugitive + try + " fugitive calls a User autocmd, so stop if that one is triggering + " this one to prevent a recursive loop + if exists('b:eclim_fugative_autocmd') + return + endif + + " make sure fugitive has the git dir for the current project + if !exists('b:git_dir') || (b:git_dir !~ '^\M' . b:roots[0]) + let cwd = '' + if getcwd() . '/' != b:roots[0] + let cwd = getcwd() + exec 'lcd ' . escape(b:roots[0], ' ') + endif + + if exists('b:git_dir') + unlet b:git_dir + endif + + " slight hack to prevent recursive autocmd loop with fugitive + let b:eclim_fugative_autocmd = 1 + + silent! doautocmd fugitive BufReadPost % + + if cwd != '' + exec 'lcd ' . escape(cwd, ' ') + endif + endif + + let info = function('fugitive#statusline')() + if info != '' + let branch = substitute(info, '^\[\Git(\(.*\))\]$', '\1', 'g') + if branch != info + let info = 'git:' . branch + endif + endif + catch /E\(117\|700\)/ + " noop if the neither function was found + finally + silent! unlet b:eclim_fugative_autocmd + endtry + endtry + + " &modifiable check for silly side effect of fugitive autocmd + if info != '' && &modifiable + call append(line('$') - 1, '" ' . info) + endif + endif + call setpos('.', pos) + setlocal nomodifiable +endfunction " }}} + +function! s:PathEcho() " {{{ + if mode() != 'n' + return + endif + + let path = eclim#tree#GetPath() + let path = substitute(path, eclim#tree#GetRoot(), '', '') + if path !~ '^"' + call eclim#util#WideMessage('echo', path) + else + call eclim#util#WideMessage('echo', '') + endif +endfunction " }}} + +function! s:OpenFile(action) " {{{ + let path = eclim#tree#GetPath() + if path !~ '/$' + if !filereadable(path) + echo "File is not readable or has been deleted." + return + endif + + call eclim#tree#ExecuteAction(path, + \ "call eclim#project#tree#OpenProjectFile('" . a:action . "', '<file>')") + endif +endfunction " }}} + +function! s:OpenFileName() " {{{ + let path = eclim#tree#GetPath() + if !isdirectory(path) + let path = fnamemodify(path, ':h') . '/' + endif + + let response = input('file: ', path, 'file') + if response != '' + let actions = eclim#tree#GetFileActions(response) + call eclim#tree#ExecuteAction(response, actions[0].action) + endif +endfunction " }}} + +function! s:YankFileName() " {{{ + let path = eclim#tree#GetPath() + let [@*, @+, @"] = [path, path, path] + call eclim#util#Echo('Copied path to clipboard: ' . path) +endfunction " }}} + +function! eclim#project#tree#ProjectTreeSettings() " {{{ + for action in g:EclimProjectTreeActions + call eclim#tree#RegisterFileAction(action.pattern, action.name, + \ "call eclim#project#tree#OpenProjectFile('" . action.action . "', '<file>')") + endfor + + call eclim#tree#RegisterDirAction(function('eclim#project#tree#InjectLinkedResources')) + + if exists('s:TreeSettingsFunction') + let l:Settings = function(s:TreeSettingsFunction) + call l:Settings() + endif + + augroup eclim_tree + autocmd User <buffer> call <SID>InfoLine() + if g:EclimProjectTreePathEcho + autocmd CursorMoved <buffer> call <SID>PathEcho() + endif + augroup END +endfunction " }}} + +function! eclim#project#tree#OpenProjectFile(cmd, file) " {{{ + " Execute the supplied command in one of the main content windows. + if eclim#util#GoToBufferWindow(a:file) + return + endif + + let file = a:file + let cmd = a:cmd + let cwd = getcwd() + + exec g:EclimProjectTreeContentWincmd + + " if the buffer is a no name and action is split, use edit instead. + if cmd =~ 'split' && expand('%') == '' && + \ !&modified && line('$') == 1 && getline(1) == '' + let cmd = 'edit' + endif + + " current file doesn't share same cwd as the project tree + let lcwd = getcwd() + if lcwd != cwd && !filereadable(file) + let file = escape(substitute(cwd, '\', '/', 'g'), ' &') . '/' . file + endif + + try + exec cmd . ' ' file + catch /E325/ + " ignore attention error since the user should be prompted to handle it. + finally + if lcwd != cwd + exec 'lcd ' . escape(cwd, ' ') + endif + endtry +endfunction " }}} + +function! eclim#project#tree#InjectLinkedResources(dir, contents) " {{{ + let project = eclim#project#util#GetProject(a:dir) + if len(project) == 0 + return + endif + + " listing the project root, so inject our project links + if len(get(project, 'links', {})) && + \ substitute(a:dir, '/$', '', '') == project.path + if !exists('b:links') + let b:links = {} + endif + call extend(b:links, project.links) + + let links = keys(project.links) + call sort(links) + + let index = 0 + for entry in copy(a:contents) + if !len(links) + break + endif + + while len(links) && links[0] < fnamemodify(entry, ':h:t') + call insert(a:contents, a:dir . remove(links, 0) . '/', index) + endwhile + let index += 1 + endfor + + for link in links + call add(a:contents, a:dir . link . '/') + endfor + endif +endfunction " }}} + +function! eclim#project#tree#HorizontalContentWindow() " {{{ + " Command for g:EclimProjectTreeContentWincmd used when relative to a + " horizontal taglist window. + winc k + if exists('g:TagList_title') && bufname(bufnr('%')) == g:TagList_title + winc k + endif +endfunction " }}} + +" vim:ft=vim:fdm=marker diff --git a/vim/eclim/autoload/eclim/project/util.vim b/vim/eclim/autoload/eclim/project/util.vim @@ -0,0 +1,1461 @@ +" Author: Eric Van Dewoestine +" +" Description: {{{ +" +" License: +" +" Copyright (C) 2005 - 2013 Eric Van Dewoestine +" +" This program is free software: you can redistribute it and/or modify +" it under the terms of the GNU General Public License as published by +" the Free Software Foundation, either version 3 of the License, or +" (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public License +" along with this program. If not, see <http://www.gnu.org/licenses/>. +" +" }}} + +" Global Variables {{{ +if !exists('g:EclimTodoSearchPattern') + let g:EclimTodoSearchPattern = '\(\<fixme\>\|\<todo\>\)\c' +endif + +if !exists('g:EclimTodoSearchExtensions') + let g:EclimTodoSearchExtensions = [ + \ 'css', + \ 'html', + \ 'java', + \ 'js', + \ 'jsp', + \ 'php', + \ 'py', + \ 'rb', + \ 'sql', + \ 'xml', + \ ] +endif + +if !exists('g:EclimProjectStatusLine') + let g:EclimProjectStatusLine = '${name}' +endif +" }}} + +" Script Variables {{{ +let s:command_create = '-command project_create -f "<folder>"' +let s:command_create_name = ' -p "<name>"' +let s:command_create_natures = ' -n <natures>' +let s:command_create_depends = ' -d <depends>' +let s:command_import = '-command project_import -f "<folder>"' +let s:command_delete = '-command project_delete -p "<project>"' +let s:command_rename = '-command project_rename -p "<project>" -n "<name>"' +let s:command_move = '-command project_move -p "<project>" -d "<dir>"' +let s:command_refresh = '-command project_refresh -p "<project>"' +let s:command_refresh_file = + \ '-command project_refresh_file -p "<project>" -f "<file>"' +let s:command_build = '-command project_build -p "<project>"' +let s:command_projects = '-command projects' +let s:command_project_list = '-command project_list' +let s:command_project_by_resource = '-command project_by_resource -f "<file>"' +let s:command_project_info = '-command project_info -p "<project>"' +let s:command_project_settings = '-command project_settings -p "<project>"' +let s:command_project_setting = '-command project_setting -p "<project>" -s <setting>' +let s:command_project_update = '-command project_update -p "<project>"' +let s:command_update = '-command project_update -p "<project>" -s "<settings>"' +let s:command_open = '-command project_open -p "<project>"' +let s:command_close = '-command project_close -p "<project>"' +let s:command_nature_aliases = '-command project_nature_aliases' +let s:command_natures = '-command project_natures' +let s:command_nature_add = + \ '-command project_nature_add -p "<project>" -n "<natures>"' +let s:command_nature_remove = + \ '-command project_nature_remove -p "<project>" -n "<natures>"' + +let s:workspace_projects = {} +" }}} + +function! eclim#project#util#ClearProjectsCache() " {{{ + " Flush the cached list of projects. + let s:workspace_projects = {} +endfunction " }}} + +function! eclim#project#util#ProjectCD(scope) " {{{ + " Change the current working directory to the current project root. + let dir = eclim#project#util#GetCurrentProjectRoot() + if a:scope == 0 + exec 'cd ' . escape(dir, ' ') + elseif a:scope == 1 + exec 'lcd ' . escape(dir, ' ') + endif +endfunction " }}} + +function! eclim#project#util#ProjectCreate(args) " {{{ + let args = eclim#util#ParseCmdLine(a:args) + + let folder = fnamemodify(expand(args[0]), ':p') + let folder = substitute(folder, '\', '/', 'g') + if has('win32unix') + let folder = eclim#cygwin#WindowsPath(folder) + endif + let command = substitute(s:command_create, '<folder>', folder, '') + + let name = substitute(a:args, '.* -p\s\+\(.\{-}\)\(\s\+-\(d\|n\)\>.*\|$\)', '\1', '') + if name != a:args + let command .= substitute(s:command_create_name, '<name>', name, '') + endif + + let natureIds = [] + let natures = substitute(a:args, '.* -n\s\+\(.\{-}\)\(\s\+-\(d\|p\)\>.*\|$\)', '\1', '') + if natures != a:args + let natures = substitute(natures, '\s\+', ',', 'g') + let natureIds = split(natures, ',') + let command .= substitute(s:command_create_natures, '<natures>', natures, '') + endif + + let depends = substitute(a:args, '.* -d\s\+\(.\{-}\)\(\s\+-\(n\|p\)\>.*\|$\)', '\1', '') + if depends != a:args + let depends = substitute(depends, '\s\+', ',', 'g') + let command .= substitute(s:command_create_depends, '<depends>', depends, '') + endif + + " execute any pre-project creation hooks + let hook_result = s:ProjectNatureHooks(natureIds, 'ProjectCreatePre', [folder]) + if type(hook_result) == g:NUMBER_TYPE && !hook_result + return + elseif type(hook_result) == g:STRING_TYPE && len(hook_result) + let command .= ' -a ' . hook_result + endif + + let result = eclim#Execute(command, {'dir': folder}) + if result != '0' + call eclim#util#Echo(result) + call eclim#project#util#ClearProjectsCache() + endif + + " execute any post-project creation hooks + call s:ProjectNatureHooks(natureIds, 'ProjectCreatePost', [folder]) +endfunction " }}} + +function! s:ProjectNatureHooks(natureIds, hookName, args) " {{{ + let results = '' + for nature in a:natureIds + if nature == 'none' + continue + endif + + exec 'runtime autoload/eclim/' . nature . '/project.vim' + try + let l:Hook = function('eclim#' . nature . '#project#' . a:hookName) + let result = call(l:Hook, a:args) + if type(result) == g:NUMBER_TYPE && !result + return result + endif + if type(result) == g:STRING_TYPE + if len(results) + let results .= ' ' + endif + let results .= result + endif + catch /E\(117\|700\):.*/ + " ignore + endtry + endfor + + if len(results) + return results + endif + + return 1 +endfunction " }}} + +function! eclim#project#util#ProjectImport(arg) " {{{ + let folder = fnamemodify(expand(a:arg), ':p') + let folder = substitute(folder, '\', '/', 'g') + if has('win32unix') + let folder = eclim#cygwin#WindowsPath(folder) + endif + let command = substitute(s:command_import, '<folder>', folder, '') + + let naturesDict = {} + for [key, value] in items(eclim#project#util#GetNatureAliasesDict()) + let naturesDict[value[-1]] = key + endfor + + let natureIds = [] + let dotproject = folder . '/' . '.project' + if filereadable(dotproject) + for line in readfile(dotproject) + if line =~ '^\s*<nature>' + let id = substitute(line, '.*\<nature>\(.*\)</nature>.*', '\1', '') + if has_key(naturesDict, id) + call add(natureIds, naturesDict[id]) + endif + endif + endfor + if !s:ProjectNatureHooks(natureIds, 'ProjectImportPre', [folder]) + return + endif + endif + + let result = eclim#Execute(command, {'dir': folder}) + if result != '0' + let project = eclim#project#util#GetProject(folder) + if !len(natureIds) + let natureIds = eclim#project#util#GetProjectNatureAliases(project) + endif + call s:ProjectNatureHooks(natureIds, 'ProjectImportPost', [project]) + call eclim#util#Echo(result) + call eclim#project#util#ClearProjectsCache() + endif +endfunction " }}} + +function! eclim#project#util#ProjectDelete(name) " {{{ + let command = substitute(s:command_delete, '<project>', a:name, '') + let result = eclim#Execute(command, {'project': a:name}) + if result != '0' + call eclim#util#Echo(result) + call eclim#project#util#ClearProjectsCache() + endif +endfunction " }}} + +function! eclim#project#util#ProjectRename(args) " {{{ + let args = eclim#util#ParseCmdLine(a:args) + if len(args) == 1 + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let project = eclim#project#util#GetCurrentProjectName() + let name = args[0] + else + let project = args[0] + let name = args[1] + endif + + if exists('g:EclimProjectRenamePrompt') && !g:EclimProjectRenamePrompt + let response = 1 + else + let response = eclim#util#PromptConfirm( + \ printf("Rename project '%s' to '%s'", project, name), + \ g:EclimInfoHighlight) + endif + + if response == 1 + let command = s:command_rename + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<name>', name, '') + call s:ProjectMove(project, name, command) + endif +endfunction " }}} + +function! eclim#project#util#ProjectMove(args) " {{{ + let args = eclim#util#ParseCmdLine(a:args) + if len(args) == 1 + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let project = eclim#project#util#GetCurrentProjectName() + let dir = args[0] + else + let project = args[0] + let dir = args[1] + endif + let dir = expand(dir) + let dir = substitute(fnamemodify(dir, ':p'), '\', '/', 'g') + if has('win32unix') + let dir = eclim#cygwin#WindowsPath(dir) + endif + + if exists('g:EclimProjectMovePrompt') && !g:EclimProjectMovePrompt + let response = 1 + else + let response = eclim#util#PromptConfirm( + \ printf("Move project '%s' to '%s'", project, dir), + \ g:EclimInfoHighlight) + endif + + if response == 1 + let command = s:command_move + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<dir>', dir, '') + call s:ProjectMove(project, project, command) + endif +endfunction " }}} + +function! s:ProjectMove(oldname, newname, command) " {{{ + let cwd = substitute(getcwd(), '\', '/', 'g') + let cwd_return = 1 + let oldpath = eclim#project#util#GetProjectRoot(a:oldname) + + let curwin = winnr() + try + " cd to home to avoid folder renaming issues on windows. + cd ~ + + " turn off swap files temporarily to avoid issues with folder renaming. + let bufend = bufnr('$') + let bufnum = 1 + while bufnum <= bufend + if bufexists(bufnum) + call setbufvar(bufnum, 'save_swapfile', getbufvar(bufnum, '&swapfile')) + call setbufvar(bufnum, '&swapfile', 0) + endif + let bufnum = bufnum + 1 + endwhile + + " write all changes before moving + wall + + let result = eclim#Execute(a:command, {'project': a:oldname}) + if result == "0" + return + endif + call eclim#project#util#ClearProjectsCache() + let newpath = eclim#project#util#GetProjectRoot(a:newname) + if cwd =~ '^' . oldpath + exec 'cd ' . substitute(cwd, oldpath, newpath, '') + let cwd_return = 0 + endif + + " reload files affected by the project renaming + let bufnum = 1 + while bufnum <= bufend + if buflisted(bufnum) + let path = substitute(fnamemodify(bufname(bufnum), ':p'), '\', '/', 'g') + if path =~ '^' . oldpath + let path = substitute(path, oldpath, newpath, '') + if filereadable(path) + let winnr = bufwinnr(bufnum) + if winnr != -1 + exec winnr . 'winc w' + exec 'edit ' . eclim#util#Simplify(path) + endif + exec 'bdelete ' . bufnum + endif + endif + endif + let bufnum = bufnum + 1 + endwhile + + finally + exec curwin 'winc w' + if cwd_return + exec 'cd ' . escape(cwd, ' ') + endif + + " re-enable swap files + let bufnum = 1 + while bufnum <= bufend + if bufexists(bufnum) + let save_swapfile = getbufvar(bufnum, 'save_swapfile') + if save_swapfile != '' + call setbufvar(bufnum, '&swapfile', save_swapfile) + endif + endif + let bufnum = bufnum + 1 + endwhile + endtry + + call eclim#util#Echo(result) +endfunction " }}} + +function! eclim#project#util#ProjectRefreshAll() " {{{ + call eclim#project#util#ClearProjectsCache() + let projects = eclim#project#util#GetProjectNames() + for project in projects + call eclim#project#util#ProjectRefresh(project, 0) + endfor + call eclim#util#Echo('Done.') +endfunction " }}} + +function! eclim#project#util#ProjectRefresh(args, ...) " {{{ + " Optional args: + " clear_cache: Clear the in memory project cache first + + if a:0 == 0 || a:000[0] == 1 + call eclim#project#util#ClearProjectsCache() + endif + + if a:args != '' + let projects = eclim#util#ParseCmdLine(a:args) + else + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let project = eclim#project#util#GetCurrentProjectName() + let projects = [project] + endif + + for project in projects + call eclim#util#Echo("Updating project '" . project . "'...") + let command = substitute(s:command_refresh, '<project>', project, '') + call eclim#util#Echo(eclim#Execute(command, {'project': project})) + endfor + + if len(projects) > 1 + call eclim#util#Echo('Done.') + endif +endfunction " }}} + +function! eclim#project#util#ProjectBuild(...) " {{{ + " Option args: + " project: The name of the project to build (use the current project + " otherwise) + let project = a:0 > 0 ? a:1 : '' + + if project == '' + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let project = eclim#project#util#GetCurrentProjectName() + endif + + call eclim#util#Echo("Building project '" . project . "'...") + let command = substitute(s:command_build, '<project>', project, '') + let result = eclim#Execute(command, {'project': project}) + call eclim#project#problems#ProblemsUpdate('build') + call eclim#util#Echo(result) +endfunction " }}} + +function! eclim#project#util#ProjectInfo(project) " {{{ + let project = a:project + if project == '' + let project = eclim#project#util#GetCurrentProjectName() + endif + if project == '' + call eclim#project#util#UnableToDetermineProject() + return + endif + + let command = substitute(s:command_project_info, '<project>', project, '') + let result = eclim#Execute(command, {'project': project}) + if type(result) == g:DICT_TYPE + let output = + \ 'Name: ' . result.name . "\n" . + \ 'Path: ' . result.path . "\n" . + \ 'Workspace: ' . result.workspace . "\n" . + \ 'Open: ' . (result.open ? 'true' : 'false') + if has_key(result, 'natures') + let output .= "\n" . 'Natures: ' . join(result.natures, ', ') + endif + if has_key(result, 'depends') + let output .= "\n" . 'Depends On: ' . join(result.depends, ', ') + endif + if has_key(result, 'referenced') + let output .= "\n" . 'Referenced By: ' . join(result.referenced, ', ') + endif + call eclim#util#Echo(output) + elseif type(result) == g:STRING_TYPE + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#project#util#ProjectStatusLine() " {{{ + " Includes status information for the current file to VIM status + + let project = eclim#project#util#GetProject(expand('%:p')) + if !empty(project) + let status = g:EclimProjectStatusLine + while status =~ '\${\w\+}' + let m = matchstr(status, '\${\w\+}') + let key = substitute(m, '^\${\(\w\+\)}', '\1', '') + let val = '' + if has_key(project, key) + let type = type(project[key]) + if type == 1 + let val = project[key] + elseif type == 3 + let val = join(project[key], ',') + else + let val = string(project[key]) + endif + endif + let status = substitute(status, m, val, 'g') + endwhile + return status + endif +endfunction " }}} + +function! eclim#project#util#ProjectOpen(name) " {{{ + let name = a:name + if name == '' + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let name = eclim#project#util#GetCurrentProjectName() + endif + + let command = substitute(s:command_open, '<project>', name, '') + let result = eclim#Execute(command, {'project': name}) + if result != '0' + call eclim#util#Echo(result) + call eclim#project#util#ClearProjectsCache() + endif +endfunction " }}} + +function! eclim#project#util#ProjectClose(name) " {{{ + let name = a:name + if name == '' + if !eclim#project#util#IsCurrentFileInProject() + return + endif + let name = eclim#project#util#GetCurrentProjectName() + endif + + let command = substitute(s:command_close, '<project>', name, '') + let result = eclim#Execute(command, {'project': name}) + if result != '0' + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#project#util#ProjectList(workspace) " {{{ + let projects = eclim#Execute(s:command_project_list, {'workspace': a:workspace}) + if len(projects) == 0 + call eclim#util#Echo("No projects.") + endif + if type(projects) != g:LIST_TYPE + return + endif + + let pad = 0 + for project in projects + let pad = len(project.name) > pad ? len(project.name) : pad + endfor + + let output = [] + for project in projects + call add(output, + \ eclim#util#Pad(project.name, pad) . ' - ' . + \ (project.open ? ' open ' : 'closed') . ' - ' . + \ project.path) + endfor + + call eclim#util#Echo(join(output, "\n")) +endfunction " }}} + +function! eclim#project#util#ProjectNatures(project) " {{{ + " Prints nature info of one or all projects. + + if !eclim#EclimAvailable() + return + endif + + let command = s:command_natures + if a:project != '' + let command .= ' -p "' . a:project . '"' + let projects = eclim#Execute(command, {'project': a:project}) + if type(projects) != g:LIST_TYPE + return + endif + else + let projects = [] + let instances = eclim#client#nailgun#GetEclimdInstances() + for workspace in keys(instances) + let results = eclim#Execute(command, {'instance': instances[workspace]}) + if type(results) != g:LIST_TYPE + continue + endif + let projects += results + endfor + endif + + if len(projects) == 0 + call eclim#util#Echo("No projects.") + endif + + let pad = 0 + for project in projects + let pad = len(project.name) > pad ? len(project.name) : pad + endfor + + let output = [] + for project in projects + call add(output, + \ eclim#util#Pad(project.name, pad) . ' - ' . join(project.natures, ', ')) + endfor + call eclim#util#Echo(join(output, "\n")) +endfunction " }}} + +function! eclim#project#util#ProjectNatureModify(command, args) " {{{ + " Modifies one or more natures for the specified project. + + let args = eclim#util#ParseCmdLine(a:args) + + let project = args[0] + let natures = args[1:] + let command = a:command == 'add' ? s:command_nature_add : s:command_nature_remove + let command = substitute(command, '<project>', project, '') + let command = substitute(command, '<natures>', join(natures, ','), '') + + if a:command == 'add' + let hook_result = s:ProjectNatureHooks(natures, 'ProjectNatureAddPre', [project]) + if type(hook_result) == g:NUMBER_TYPE && !hook_result + return + elseif type(hook_result) == g:STRING_TYPE && len(hook_result) + let command .= ' -a ' . hook_result + endif + endif + + let result = eclim#Execute(command, {'project': project}) + if result != '0' + if a:command == 'add' + call s:ProjectNatureHooks(natures, 'ProjectNatureAddPost', [project]) + endif + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#project#util#ProjectSettings(project) " {{{ + " Opens a window that can be used to edit a project's settings. + + let project = a:project + if project == '' + let project = eclim#project#util#GetCurrentProjectName() + endif + if project == '' + call eclim#project#util#UnableToDetermineProject() + return + endif + + let command = substitute(s:command_project_settings, '<project>', project, '') + let settings = eclim#Execute(command, {'project': project}) + if type(settings) != g:LIST_TYPE + return + endif + + let content = ['# Settings for project: eclim', ''] + let path = '' + for setting in settings + if setting.path != path + if path != '' + let content += ['# }', ''] + endif + let path = setting.path + call add(content, '# ' . path . ' {') + endif + let description = split(setting.description, '\n') + let content += map(description, "'\t# ' . v:val") + call add(content, "\t" . setting.name . '=' . setting.value) + endfor + if path != '' + call add(content, '# }') + endif + + call eclim#util#TempWindow(project . "_settings", content) + exec "lcd " . escape(eclim#project#util#GetProjectRoot(project), ' ') + setlocal buftype=acwrite + setlocal filetype=jproperties + setlocal noreadonly + setlocal modifiable + setlocal foldmethod=marker + setlocal foldmarker={,} + setlocal foldlevel=0 + + let b:project = project + augroup project_settings + autocmd! BufWriteCmd <buffer> + autocmd BufWriteCmd <buffer> call <SID>SaveSettings() + augroup END +endfunction " }}} + +function! eclim#project#util#ProjectUpdate() " {{{ + " Executes a project update which may also validate nature specific resource + " file. + + let name = eclim#project#util#GetCurrentProjectName() + if name == '' + call eclim#util#EchoError('Unable to determine the project.') + return + endif + + let command = substitute(s:command_project_update, '<project>', name, '') + + let result = eclim#Execute(command) + if type(result) == g:LIST_TYPE && len(result) > 0 + let errors = eclim#util#ParseLocationEntries( + \ result, g:EclimValidateSortResults) + call eclim#util#SetLocationList(errors) + else + call eclim#util#ClearLocationList() + call eclim#util#Echo(result) + endif +endfunction " }}} + +function! eclim#project#util#ProjectGrep(command, args) " {{{ + " Executes the supplied vim grep command with the specified pattern against + " one or more file patterns. + + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let project = eclim#project#util#GetProject(expand('%:p')) + let tail = substitute(a:args, '\(.\).\{-}\1\s\(.*\)', '\2', '') + let pattern = substitute(a:args, '\(.*\)\s\+\M' . tail . '\m$', '\1', '') + let cmd = a:command + let acd = &autochdir + set noautochdir + try + if pattern != a:args && tail != a:args && tail != '' + let files = eclim#util#ParseArgs(tail) + let paths = '' + for file in files + if paths != '' + let paths .= ' ' + endif + let paths .= escape(project.path, ' ') . '/' . file + endfor + let links = get(project, 'links', {}) + if len(links) + for link in values(links) + for file in files + let paths .= ' ' . escape(link, ' ') . '/' . file + endfor + endfor + endif + silent exec a:command . ' ' . pattern . ' ' . paths + else + " let vim generate the proper error + silent exec a:command . ' ' . a:args + endif + catch /E480/ + " no results found + catch /.*/ + call eclim#util#EchoError(v:exception) + return + finally + let &autochdir = acd + " force quickfix / location list signs to update. + call eclim#display#signs#Update() + endtry + + let numresults = len(a:command =~ '^l' ? getloclist(0) : getqflist()) + if numresults == 0 + call eclim#util#EchoInfo('No results found.') + endif +endfunction " }}} + +function! eclim#project#util#ProjectTab(project) " {{{ + " Opens a new tab with the project tree and tab relative working directory for + " the specified project. + + let project = a:project + let names = eclim#project#util#GetProjectNames() + if index(names, project) == -1 + let is_project = 0 + let dir = expand(project, ':p') + if !isdirectory(dir) + if eclim#EclimAvailable(0) + call eclim#util#EchoError("No project '" . project . "' found.") + endif + return + endif + let project = fnamemodify(substitute(dir, '/$', '', ''), ':t') + else + let is_project = 1 + let dir = eclim#project#util#GetProjectRoot(project) + endif + + if exists('t:eclim_project') || + \ winnr('$') > 1 || expand('%') != '' || + \ &modified || line('$') != 1 || getline(1) != '' + tablast | tabnew + endif + + let t:eclim_project = project + call eclim#common#util#Tcd(dir) + if g:EclimProjectTabTreeAutoOpen + if is_project + call eclim#project#tree#ProjectTree(project) + else + call eclim#project#tree#ProjectTree(dir) + endif + else + call eclim#util#Echo('ProjectTab ' . project . ' cwd: ' . dir) + endif +endfunction " }}} + +function! eclim#project#util#Todo() " {{{ + " Show the todo tags of the curent file in the location list. + + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + let path = expand('%:p') + silent! exec 'lvimgrep /' . g:EclimTodoSearchPattern . '/gj ' . path + if !empty(getloclist(0)) + exec 'lopen ' . g:EclimLocationListHeight + else + call eclim#util#Echo('No Results found') + endif +endfunction " }}} + +function! eclim#project#util#ProjectTodo() " {{{ + " Show the todo tags of the whole project in the location list. + if !eclim#project#util#IsCurrentFileInProject() + return + endif + + if len(g:EclimTodoSearchExtensions) == 0 + endif + + let project = eclim#project#util#GetProject(expand('%:p')) + let paths = '' + for ext in g:EclimTodoSearchExtensions + if paths != '' + let paths .= ' ' + endif + let paths .= escape(project.path, ' ') . '/**/*' . ext + endfor + let links = get(project, 'links', {}) + if len(links) + for link in values(links) + for ext in g:EclimTodoSearchExtensions + let paths .= ' ' . escape(link, ' ') . '/**/*' . ext + endfor + endfor + endif + + silent! exec 'lvimgrep /' . g:EclimTodoSearchPattern . '/gj ' . paths + + if !empty(getloclist(0)) + exec 'lopen ' . g:EclimLocationListHeight + else + call eclim#util#Echo('No Results found') + endif +endfunction " }}} + +function! s:SaveSettings() " {{{ + call eclim#SaveSettings(s:command_update, b:project) +endfunction " }}} + +function! eclim#project#util#GetCurrentProjectName() " {{{ + " Gets the project name that the current file is in. + let project = eclim#project#util#GetProject(expand('%:p')) + return len(project) > 0 ? project.name : '' +endfunction " }}} + +function! eclim#project#util#GetCurrentProjectRoot() " {{{ + " Gets the project root dir for the project that the current file is in. + let project = eclim#project#util#GetProject(expand('%:p')) + return len(project) > 0 ? project.path : '' +endfunction " }}} + +function! eclim#project#util#GetProjectWorkspace(name) " {{{ + " Gets the workspace that a project belongs to. + let project = {} + for p in eclim#project#util#GetProjects() + if p.name == a:name + let project = p + break + endif + endfor + return get(project, 'workspace', '') +endfunction " }}} + +function! eclim#project#util#GetProjectRelativeFilePath(...) " {{{ + " Gets the project relative path for the current or supplied file. + " Optional args: + " file: get the relative path for this file instead of the current one. + + if exists('b:eclim_file') + return b:eclim_file + endif + + let file = a:0 == 0 ? expand('%:p') : a:1 + let project = eclim#project#util#GetProject(file) + if !len(project) + return '' + endif + + let file = substitute(fnamemodify(file, ':p'), '\', '/', 'g') + let pattern = '\(/\|$\)' + if has('win32') || has('win64') + let pattern .= '\c' + endif + let result = substitute(file, get(project, 'path', '') . pattern, '', '') + + " handle file in linked folder + if result == file + for name in keys(get(project, 'links', {})) + if file =~ '^' . project.links[name] . pattern + let result = substitute(file, project.links[name], name, '&#