62 Commits

Author SHA1 Message Date
Dave Halter
3a1c900a26 Remove Python 2 stuff 2020-12-27 00:44:17 +01:00
Dave Halter
57757bd334 Merge pull request #1025 from davidhalter/jedi-api
Use the new Jedi API
2020-12-26 23:47:32 +01:00
Dave Halter
ea52ca5305 Try to use GitHub Actions 2020-12-26 23:38:46 +01:00
Dave Halter
04ba9a2430 A small fix 2020-12-25 17:44:22 +01:00
Dave Halter
dc0fdc55cb Updated jedi and parso 2020-12-25 12:45:23 +01:00
Dave Halter
a76965238a Fix the project choice 2020-10-23 17:45:40 +02:00
Dave Halter
6193c9fd95 Remove the Python 2 support
It should mostly still work (except for :Pyimport), but it won't pass all the tests anymore.
Since I'm dropping Python 2 in Jedi anyways, it makes sense to also remove it here.
2020-08-04 15:22:38 +02:00
Dave Halter
acbb712906 Try and update the CI from Ubuntu 16.04 to 18.04 2020-08-04 15:11:30 +02:00
Dave Halter
48b3e5c0e7 In older versions of VIM bufname needs an argument 2020-08-04 15:07:39 +02:00
Dave Halter
74fd73d017 Added an undocumented JediLoadProject for now 2020-08-01 13:32:48 +02:00
Dave Halter
6efd966481 Remove multi definition tests that are not really working anymore because of changes in Jedi 2020-08-01 12:01:54 +02:00
Dave Halter
862fbbc8a9 Add a choose-venv test 2020-08-01 11:16:57 +02:00
Dave Halter
87abaf0781 Fix goto issues 2020-08-01 00:30:54 +02:00
Dave Halter
01e6e6bcf7 Fix debug info 2020-08-01 00:15:46 +02:00
Dave Halter
2c157e323e Fix documentation tests 2020-08-01 00:12:24 +02:00
Dave Halter
6edda9063a Make choose environment buffer disappear if it's not visible anymore 2020-07-31 20:25:12 +02:00
Dave Halter
e23687462b Implement :JediChooseEnvironment 2020-07-31 15:06:09 +02:00
Dave Halter
104d817f0c environment_path needs to be defined properly 2020-07-30 18:37:27 +02:00
Dave Halter
2949389be4 Describe the environment_path option properly 2020-07-30 18:16:35 +02:00
Dave Halter
c4fc2cde8c Use projects instead of environments 2020-07-30 15:45:12 +02:00
Dave Halter
5858a999de Unify Pyimport and goto 2020-07-30 14:36:40 +02:00
Dave Halter
1e9bdc863a definition -> name, because Jedi calls it name now 2020-07-30 14:18:33 +02:00
Dave Halter
3a27747773 Use the project.search function 2020-07-30 14:00:16 +02:00
Dave Halter
4ca918e830 Use the new API instead of the deprecated one 2020-07-30 13:47:53 +02:00
Daniel Hahler
a17b033303 Update Jedi to v0.17.2 (#1023)
* pythonx/jedi 3ad3dc08...3b7106ae (203):
      > Fix a typo
      > Prepare for 0.17.2
      > Fix a Python 3.9 issue on travis
      > Properly negate with Interpreter, fixes #1636
      > Fix issues with generators, fixes #1624
      > Introduce py__next__ to have more clear way to use __next__
      > Merge pull request #1633 from mrclary/mrclary-fix-wingkinl-patch-python-environ
      > Fix dict completions for inherited dicts, fixes #1631
      > Refactor Interpeter completions a bit
      > Make sure the interpreter completions work better in Jupyter Notebook, fixes #1628
      > Fix an issue with interpreter completion, see also #1628
      > Making sure to note that Python 2 will not be supported after 0.17.2
      > Mention in Changelog that 3.9 is now supported
      > Add download badge
      > Some test skips
      > Revert some of the Decoratee changes
      > Some more signature adjustments
      > Change Decoratee slightly
      > Fix an issue with decoratee names
      > Add Project.path, fixes #1622
      > Fix the of a signature with a decorator
      > Fix docstrings for method decorators, fixes #1621
      > Make partial use the __doc__ of its function, fixes #1621
      > Merge pull request #1614 from PeterJCLaw/fix-decorator-factory-passthrough
      > Merge pull request #1623 from mallamanis/master
      > Remove a print
      > Typeshed third party libraries should not be loaded if they don't actually exist in the environment, fixes #1620
      > Add the env_vars change to CHANGELOG
      > Merge pull request #1619 from mrclary/subprocess-env-vars
      > Make sure that Callables are properly represented
      > Add Python 3.8 to the tox env list (#1618)
      > Use Python 3 in the deployment script
      > Prepare release 0.17.1
      > Make sure the current version doesn't install a parso version that is new
      > Small changelog improvement
      > Mention Django Manager support for managers/querysets in changelog
      > Add SyntaxError.get_message
      > Mention 3.9 support better
      > Fix decorator param completion
      > Merge branch 'django'
      > Merge branch 'master' of github.com:davidhalter/jedi
      > Fix some issues with sub class matching, fixes #1560
      > Better debugging output for is_sub_class_of
      > Ignore runtime_checkable, because we don't really need it
      > Fix a small extract_variable issue, fixes #1611
      > Try to get get the tests for Python 3.9 passing, fixes #1608
      > Make it possible to use inheritance on generics without always specifying type vars, see also discussion in #1593
      > Update MANIFEST.in
      > Make sure that scopes can only be exact values, see #1590
      > Merge pull request #1590 from muffinmad/references-scope
      > Fix a small issue with doctest completions, fixes #1585
      > Exclude more Linux constants in test_import
      > Merge pull request #1601 from yuan-xy/patch_3
      > Refactoring about checking \r\n (#1603)
      > fix typo (#1602)
      > fix typo
      > Merge pull request #1599 from isidentical/py38-plus-setuppy
      > Merge pull request #1595 from PeterJCLaw/operator-not-in
      > Import FileNotFoundError from jedi._compatibility
      > Merge pull request #1586 from PeterJCLaw/django-more-fields
      > Fix potential AttributeError in get_defintion_start_position/get_defintion_end_position, see #1584
      > Fix an error of get_definition_end_pos, see #1584
      > Refactor test_definition_start_end_position to use parametrize
      > definition_end_position -> get_definition_end_position, same for start, see #1584
      > Merge pull request #1584 from pappasam/get_definition_position
      > Fix tests in Python 2
      > Fix a small issue
      > Magic methods fixes for reverse methods
      > lists and tuples should not be added
      > Use __truediv__ instead of __div__
      > Fix an issue with Tuple generics
      > A few class renames
      > Better debugging
      > Skip another non-important Python 2 test that fails on Windows
      > Fix a namespace issue when getting references
      > Fix an about dict completions
      > Fix a None issue
      > Implement magic method return values, fixes #1577
      > Remove an unused cache method
      > Undefined api types should not return a random value
      > Add support for generic optional parameters (#1559)
      > Fix inline case where a name was removed without the code being used, fixes #1582
      > Make the diff nicer if there is no ending newline, fixes #1581
      > Merge pull request #1579 from muffinmad/pseudotreenameclass
      > Merge pull request #1572 from davidhalter/classvar
      > Reduce noise in signatures of compiled params (#1564)
      > Fix #1573 again; a tree_node can be None
      > Fix argument clinic unpacking, remove dynamic bullshit
      > This fixes two issues with the caching on Windows:
      > Fix getattr completions on very weird cases, fixes #1573
      > Fix tests
      > Remove the common folder and move it to a common file
      > Remove common.value
      > Move infer_type_vars to base_value
      > Merge pull request #1554 from PeterJCLaw/fix-nested-tuple-argument
      > Add .venv to _IGNORE_FOLDERS
      > Correct a test
      > Speed up signature fetching for MixedName, see discussion in #1422
      > Test that the actual signature of a function is used in Interpreter
      > Very small refactoring
      > Tell sith that goto_assignments is now goto
      > Merge pull request #1561 from PeterJCLaw/newtype-pyclass
      > Merge pull request #1553 from PeterJCLaw/generic-tuple-return
      > Allow files for get_default_project, fixes #1552
      > Don't display unnecessary help, fixes #1557
      > Pin Django in a different way so tests can work everywhere
      > Make sure that Django's values/values_list is tested (though not implemented
      > Properly implement inheritance for Django models
      > Make sure Django User inference works
      > Pin the Django test dependency
      > Mention django stubs support in README
      > Include Django stubs license in Jedi package
      > Some more django query tests
      > Infer many to many fields
      > Include Django stubs as a third party repo
      > Make sure that infering the Django User model works
      > Fix a recursion error issue
      > Remove unused imports
      > Fix typos in api.classes docstrings
      > Remove a redundant check from Name.desc_with_module
      > Actually fix #1556, forgot to add this in 94d374c9ceeb16ea1c6fe49b8e039d415c7dbe5a
      > Start changelog for 0.17.1
      > Fix a small issue with the help method, fixes #1556
      > Django is not supported for Python 2
      > Work with a NameWrapper, so Django goto works better
      > Fix another django modelfield issue
      > Some nitpicks
      > Fix another issue with foreign keys
      > Fix ForeignKey issues with invalid values
      > Some other small refactorings
      > Refactor a few things for django
      > Remove old third party django tests
      > Use debug instead of print for Django and fix indentation, see #1467
      > Make Django test optional
      > Merge branch 'master' of https://github.com/ANtlord/jedi
      > Better developer tools
      > Make the linter completely private
      > Make sure that calling Jedi with a random argument in CLI results in errors
      > Fix a small _get_annotated_class_object, fixes #1550
      > Also don't complete keywords if kwargs only are allowed, see #1541
      > Completion: Don't suggest variables when only kwargs are legal, fixes #1541
      > fix #1548
      > * Use an explicit environment for subprocess to ensure that existing environment variables are not inherited. This ensures more reliable results, see issue #1540. * Attempt to send SYSTEMROOT variable to Windows subprocess
      > Sort test_project::test_search results to fix failures
      > Inc difference limit in TestSetupReadline::test_import for py3.8
      > Project._python_path -> Project.environment_path
      > Set the release date in Changelog
      > Some README improvements
      > Extract now properly validates line/column and those two params are required
      > Some minor CHANGELOG changes
      > Upgrade parso version
      > Fix a small issue
      > Some more code quality fixes
      > Some code cleanups
      > Don't reuse a variable
      > Remove unreachable code
      > _convert_names kwargs are not needed
      > Add pyproject.toml to the list of files to search for projects
      > Use the interpreter environment if the executable is not available, fixes #1531
      > Fix a potential AttributeError
      > Add a comment to clarify the Type case
      > Avoid AttributeErrors for generics when a module is passed
      > Merge branch 'improve-type-annotation-inference-refactors' of https://github.com/PeterJCLaw/jedi
      > Merge branch 'improve-type-annotation-inference' of https://github.com/PeterJCLaw/jedi
      > If branch inference should not trigger for things we don't know, fixes #1530
      > Fix string completion issue, fixes #1528
      > Fix wrong types for iterate, fixes #1524
      > Fix stub conversion for Decoratee, so docstrings work, see #117
      > Remove unused environment param
      > Fix a Python 2 test
      > Merge branch 'refactor'
      > Merge branch 'project'
      > Included statement as a possible return type for BaseDefinition.type
      > Fix partialmethod issues
      > Make sure partialmethod tests are only executed for Python 3
      > Merge branch 'add-partialmethod' of https://github.com/ffe4/jedi
      > Merge branch 'expandtab' of https://github.com/Carreau/jedi
      > Changed semantics of ClassVar attributes in classes, fixes #1502
      > Avoid duplicate definitions for goto, fixes #1514
      > Merge _remove_statements and infer_expr_stmt, fixes #1504
      > Fix namedtuple docstring/signature issues, fixes #1506
      > Fix a getattr_static issue, fixes #1517
      > Disable some more tests for Python 2
      > Make InterpreterEnvironment public
      > is_typeddict should be part of ClassMixin
      > Don't continue searching for values if an annotation is found
      > TypedDict checking should be at a later point
      > Simplify tests a bit
      > Merge branch 'typeddict' of https://github.com/pappasam/jedi
      > Update sith's module docstring to match the available operations
      > Remove the word 'class' from annotation_string
      > Add a couple of docstrings
      > Tell sith that 'completions' became 'complete'
      > Add venv to .gitignore
      > Remove additional prefix which seems incorrect
      > Update use of _source which no longer exists to _code
      > Make sure to move up VSCode, because it's used a lot
      > Revert "Make sure to mention that VSCode is using Jedi"
      > Make sure to mention that VSCode is using Jedi
      > Fix a test issue
      > Actually use follow_builtin_imports and improve the goto docstring, fixes #1492
      > Catch an error with illegal class instances, fixes #1491
      > Make Ellipsis without list in Callable work, fixes #1475
2020-07-17 23:14:17 +02:00
Dave Halter
a0207fadf9 Instead of zip completions (for tests) use something else, see discussions in #1020 2020-06-30 09:24:28 +02:00
Maxim Belkin
e83112f9aa doc/jedi-vim.txt: fix apostrophe (#1002) 2020-03-07 21:38:13 +01:00
Daniel Hahler
b2e8c65e35 Improve/harden jedi#setup_python_imports
In particular it should not try to import `jedi_vim_debug` during error
handling "unprotected", which might hide the real error on Python 2 at
least.

Ref: https://github.com/davidhalter/jedi-vim/issues/998#issuecomment-592305240
2020-03-05 21:06:06 +01:00
Daniel Hahler
686f39ac00 Fix jedi#add_goto_window: use :copen to go to the qf window always
Without this it would not go there with an already open qf window, and
would go to an unexpected buffer line instead of selecting the entry.

This is a follow-up to b689409, where it was decided that it should
always require the user to select an entry.

An exception is when the same usages are used again: then it will select
the nearest/current entry only (via ":cc").
2020-02-27 20:41:45 +01:00
Daniel Hahler
055199f2aa show_goto_multi_results: handle full_name=None
Seen with `<Definition name='key', description='param key'>` (using
usages on an function argument) [1].

1: https://github.com/pytest-dev/py/blob/2b6bd2925/py/_vendored_packages/iniconfig.py#L32-L33
2020-02-27 20:40:11 +01:00
Daniel Hahler
8d24b83754 Merge pull request #993 from blueyed/cover-jedi_debug_info
tests: cover jedi_debug_info
2020-02-03 01:43:09 +01:00
Daniel Hahler
a3696bee36 ci: upload coverage always 2020-02-03 01:37:10 +01:00
Daniel Hahler
5d4658f989 tests: cover jedi_debug_info 2020-02-03 01:37:10 +01:00
Daniel Hahler
18b1a519b0 Update parso/jedi (v0.6.0, v0.16.0+) (#991) 2020-02-03 01:36:04 +01:00
Daniel Hahler
acb98fc706 show_call_signatures: doc, default to 2 without 'conceal' (#994)
It basically allows to give a warning when '1' is used / set explicitly, and
the 'conceal' feature is not available.

Also defaulting to '2' (cmdline mode) then seems better than not using
it.

This is just some minor clean up before
https://github.com/davidhalter/jedi-vim/pull/652.
2020-02-03 01:31:10 +01:00
Daniel Hahler
e99cfd32de Update submodule pythonx/jedi afbd8cad...3ad3dc08
* pythonx/jedi afbd8cad...3ad3dc08 (197):
      > Run get_type_hint tests only for 3.6+
      > Stubs should not become stubs again in the conversion function, fixes #1475
      > Make sure to print errors in __main__ completions
      > Make sure param hints are working for functions
      > Generate type hints, fixes #987
      > Bump version to 0.16.1
      > Make sure to be able to deal with all kinds of loaders, fixes #1487
      > Make generators return more correct values with while loops, fixes #683
      > Avoid aborting search for yields when they are still reachable, see #683
      > Jedi understand now when you use del, fixes #313
      > Remove dead code
      > Remove Python 3.3 from environment tests
      > Make sure to skip some tests for Python 3.5
      > Small Changelog updates
      > Fix a small signature issue
      > Create a private helper to test completions
      > Fix an issue with names
      > compiled_object -> compiled_value
      > Remove dead code
      > CompiledObject -> CompiledValue
      > CompiledValue -> ExactValue
      > Revisit caching of mixed
      > Make MixedName a Namewrapper instead of inheritance
      > Remove underscore_memoization caching method
      > Refactor MixedName quite a bit
      > Fix issue with mixed objects, fixes #1480
      > Remove some dead code
      > Prepare a test for #1479
      > Avoid a print in tests
      > Fix value/context mixup in mixed, fixes #1479
      > Clarify that for Python 2 we will not fix bugs anymore
      > Skip a test in Python 2
      > Use is_compiled instead of isinstance checks
      > Create CompiledModule to have a better differentiation between compiled modules and compiles values
      > Make sure that the builtin docstring works again for infer calls
      > Fix a bug with version_info, fixes #1477
      > Make sure that del_stmt as a name can be handled, see #313
      > Remove use_filesystem_cache and additional_dynamic_modules, it hasn't been implemented for a long time
      > Removed settings.no_completion_duplicates
      > Make sure to stop gathering buildout paths at a certain point, fixes #1325
      > Rewrite some whitespace
      > Reformat the changelog a bit
      > Add follow_imports to Definition.goto, fixes #1474
      > Raise a proper exception instead of assert in case only_stubs and prefer_stubs are given
      > Make sure a certain test passes as well with tox
      > Fix a Python 2 issue
      > Rename Script.names to Script.get_names, fixes #1476
      > find_signatures -> get_signatures, see #1476
      > find_references -> get_references, see #1476
      > Fix remaining tests
      > Reduce limits of files to parse by quite a bit
      > Make sure that CompiledObject doesn't have a file_io
      > Use different limits for references and dynamic calls
      > Explain why the references limits were chosen
      > Start limiting opened files and parsed files for references
      > Remove a few imports
      > Make sure to not scan the same directory multiple times
      > Don't search for usages when we are working with params
      > Ignore .gitignore in get_references and therefore make get_references usable again
      > Revisit reference finding, scan a lot of folders
      > Added FolderIO.walk and FolderIO.get_base_name
      > Move get_module_contexts_containing_name to the references module
      > Apparently this one variable is needed
      > Small changelog fix
      > Forgot to use sudo for installing dependencies in travis
      > Another few travis fixes
      > Don't run some usage tests on Python 2
      > Interpreter test fix for travis config
      > Add a few more stub usage tests
      > Disable flow analysis for finding usages
      > Add another stub usage test
      > Fix stub conversion
      > Make sure to find both stubs and non-stubs with usages
      > Use the proper fixture
      > Implement interpreter test on travis
      > Get interpreter environment tests working
      > Make sure tests are proper packages, so that pytest doesn't do shenannigans with sys path
      > Remove NestedImportModule, because it hasn't been used in years
      > Refactor execute_operation a bit
      > Finally get rid of call_of_leaf
      > Refactor the isinstance checks a bit
      > Makes sure examples are excluded from pytest
      > speed test to examples
      > Move not_in_sys_path tests to examples
      > Move namespace tests to examples
      > Moved zipped imports test files
      > Move sample_venvs to examples
      > Move the extension test to examples
      > Move another test to examples
      > Remove unused test code
      > Move implicit namespace package code to example dir
      > Move flask tests to examples folder
      > Move the absolute import test files
      > Avoid a bug that a compiler might have found, fixes #1469
      > Make sure the latest changes work with Python 3.6/3.7
      > Properly convert compiled values to generic classes
      > Make Union/Optional works with compiled objects
      > Make sure that CompiledValue can deal with string annotations
      > Avoid a few warnings
      > Skip a test that doesn't work in Python 2
      > Remove a statement that didn't make sense
      > Remove a method that was not necessary
      > Fix a bug where parent_context was a value
      > Fix some issues with converting names, see #1466
      > Use one single way to convert stubs to Python, see #1466
      > Make sure to use _stub_to_python_value_set for all conversions, see #1466
      > Make sure fixture resolving works in conftest.py, see #791
      > Fix signatures when used for Generic classes, fixes #1468
      > Make sure inheritance works for fixtures, fixes #791
      > Add a test to check if numpy tensorflow stuff is now cached, see #1116
      > Make sure to check the module cache before loading a module (again)
      > Add a completion cache for numpy/tensorflow, fixes #1116
      > Ignore processing param names, fixes #520
      > Avoid using params in tests and use get_signatures().params
      > Make sure params have no name
      > Make sure that kwargs are not repeated when they are inferred
      > Undo finding signatures for everything and only do it for stubs and non-statements for when used in docstrings
      > Fix an issue with the is_big_annoying_library function, see #520
      > Make sure decorators are also not inferred for big annoying libraries, see #520
      > Make sure the repr of compiled access isn't huge
      > Disable some features for big annoying libraries like pandas, tensorflow, see #520
      > Fix a debug message
      > Fix a small issue
      > Little refactoring
      > Remove the old definition tests
      > Remove get_signatures again from names
      > Infer doctests and signatures uniformly, fixes #1466
      > Fix a small pytest fixture bug
      > Raise a deprecation warning on Definition.params
      > Remove a weird assert
      > Make sure coverage works again
      > Use Python 3.7 for calculating test coverage
      > Remoeve dead code
      > Remove unnecessary code
      > Separate getting docstrings and getting signatures for names, see discussion #1466
      > LazyInstanceClassName -> Use NameWrapper
      > Make sure that equals will only be added to keyword arguments and not just randomly
      > Make some test code prettier
      > Remove some skips around attribute docstrings
      > Add some more dict completion tests with whitespace
      > Change ModuleValue param order and add defaults
      > Make sure to pass tests again on Python 3.4
      > Make sure that include_signature always works, fixes #1466
      > Add a test for #1465
      > Skip dict key completion tests for Python 3.5, because it's just annoying with all the f-string stuff
      > Revert "Use the root implementation for get_root_context"
      > Added debug.warning to coveragerc, it's not relevant
      > Remove unused code
      > Use the root implementation for get_root_context
      > Add github sponsor FUNDING.yml file
      > Merge branch 'qa' of https://github.com/blueyed/jedi
      > Get rid of most flake8 errors
      > Get rid of a lot of flake8 errors
      > Make sure to get completions for backticks in docstrings work, see #860
      > Some more clarifications around docstrings, see #860
      > Get doctest completions working, fixes #860
      > Fix tests, skip more Python 2
      > Make sure test prefixed functions are checked for pytest fixtures, see #791
      > Make sure pytester is also used for fixtures, see #791
      > Clarify a sentence around virtualenv security, see #1250
      > Add the CHANGELOG entries for dict completions.
      > Merge branch 'dict', fixes #951
      > Make sure to mention that Jedi understands Pytest fixtures
      > Fix namedtuple issues that were uncovered by the 'self' changes
      > Self manipulations are now more correct, fixes #1392
      > Skip pytest tests when environments is not the same one
      > Make sure pytest stdlib fixtures are completable
      > Make sure the monkeypatch fixture completion works
      > Merge branch 'pytest', fixes parts of #791
      > Make sure py__name__ and name are defined on all values
      > Fix tests
      > Keyword completion after ... should not work, fixes davidhalter/jedi-vim#506
      > Fix python 2 environment finalizing, fixes #1412
      > Remove a function that did nothing anymore
      > Make sure modules for dynamic searches are not checked twice
      > Make sure classmethod param completion works better for the first param
      > Make sure staticmethod params are (mostly) inferred correctly, fixes #735
      > Python 2 test fixes
      > Add the fix for #997 to the changelog
      > Goto on a function/attribute in a class now goes to the definition in its super class, fixes #1175
      > Fix a few tests
      > Add support for completion even when __getattr__ is present, fixes #997
      > Fix an error recovery goto issue, fixes davidhalter/jedi-vim#962
      > Add a test to make sure some renamings work always
      > Refactor references: Matching more names that might be related
      > Catch an additional case for get_context where the cursor is e.g. on the function name
      > Add Script().get_context, fixes #253
      > Fix some issues with Definition.parent()
      > Test parents a bit better
      > Refactor tests a bit
      > Attribute docstrings work now, fixes #138
      > Avoid some duplication of code
      > Remove the _Help class completely
      > Move the docstring checking code to the names
      > Add the Script.help function, fixes #392
      > Add big API changes to Changelog
      > Merge branch 'api', fixes #1166
2020-02-03 01:27:40 +01:00
Daniel Hahler
41ecaa5c15 Update submodule pythonx/parso fb010f2...c864ca6
* pythonx/parso fb010f2...c864ca6 (14):
      > Bump version to 0.6.0
      > Make sure iter_funcdefs includes async functions with decorators, fixes #98
      > Add a bit to the changelog
      > del_stmt is now considered a name definition
      > Forgot to increase the pickle version
      > Revision on fstring issues (#100)
      > Revision on assignment errors (#97)
      > Add a Changelog note about dropping 2.6/3.3
      > Fix a Python 2.7 issue
      > Get rid of Python 3.3 artifacts
      > Remove Python 2.6 grammar
      > Merge branch 'rm-2.6' of https://github.com/hugovk/parso
      > Make sure to limit the amount of cached files parso stores, fixes davidhalter/jedi#1340
      > Fix simple typo: utitilies -> utilities
2020-02-03 01:27:31 +01:00
Dave Halter
5dd5631027 Merge pull request #990 from blueyed/fix-goto
Fix "goto" with multiple results
2020-02-02 18:53:08 +01:00
Daniel Hahler
b689409a2a Do not use :cc, but only select the line in the qf window
Ref: https://github.com/davidhalter/jedi-vim/pull/990#issuecomment-580163737
2020-02-02 07:20:43 +01:00
Daniel Hahler
ea4de13344 Minor CI/test improvements (#992)
* ci: Travis: pip-list, nvim-version

* tests: remove unused fixture argument
2020-02-02 07:10:11 +01:00
Daniel Hahler
1f7bc2a0fb Fix "goto" with multiple results
E.g. with `os.path`.
2020-01-29 19:20:12 +01:00
Aleksandrs Stier
c9bdefca54 doc: goto_stubs mapping <leader>s (#989)
Co-Authored-By: Daniel Hahler <github@thequod.de>
2020-01-24 20:11:02 +01:00
Daniel Hahler
e8790b1d8f minor: rewrite/expand show_documentation (#980)
* minor: rewrite/expand show_documentation

* tests: improve 'documentation docstrings'
2020-01-17 13:48:22 +01:00
Daniel Hahler
e2abec21c5 VimError: include throwpoint
This is helpful information to have in case of errors.
2020-01-14 21:09:35 +01:00
Daniel Hahler
c0ded0baf2 ci: add codecov.yml to disable comments (#981) 2020-01-10 19:59:28 +01:00
Daniel Hahler
7dfc56992a ci: Travis: test with py38 also 2020-01-10 17:51:51 +01:00
Dave Halter
2572136fcb Add a funding button to github (#976) 2020-01-01 14:14:45 +01:00
Daniel Hahler
55120b28e4 Merge pull request #974 from blueyed/update
Update parso and Jedi
2019-12-20 17:27:20 +01:00
Dave Halter
d57edde2e8 Update tests 2019-12-20 17:20:02 +01:00
Daniel Hahler
fab26f4551 Update submodule pythonx/jedi 005f6939...afbd8cad
* pythonx/jedi 005f6939...afbd8cad (208):
      > Don't test Python 3.4 in tox anymore by default
      > Add the release date to Changelog
      > Jedi needs at least parso 0.5.2 now
      > Fix a rb byte literal test
      > Goto definition doesn't work on strings anymore, fixes microsoft/vscode#81520
      > Make sure that sequence literals have the right generic classes, fixes #1416
      > Improved Generic subclass matching
      > Make sure overload checks work for TypeAlias, see #1416
      > Avoid recursion in a specific example, see also #1458
      > Fix simple typo: wheter -> whether (#1460)
      > Completions.complete returns None for fuzzy completions #1409
      > Cleanup fuzzy tests a bit, see #1409
      > Add fuzzy completions to Changelog
      > Merge branch 'feature_827_fuzzy_search' of https://github.com/jmfrank63/jedi
      > Python 2 compatibility
      > Make sure that the definition order in stubs are ignored
      > Make sure that a goto on stubs even without the implementation is possible
      > Fix a goto case with nested pyi files
      > Catch some cases were _sqlite3.Connection was misidentified as sqlite3.Connection
      > Rename goto_changes to options
      > Fix: Stubs in typeshed weren't loaded properly sometimes, fixes #1434
      > Files bigger than one MB (about 20kLOC) get cropped to avoid getting stuck completely
      > Upgrade typeshed, fixes #1084
      > Add a typeshed README
      > Make sure param annotation completions work
      > Make sure that you can select virtualenvs more precisely, fixes #1407
      > Python 2 compatibility
      > Make sure goto definitions works on with, fixes #1280
      > Make sure that __getattr__ is always working with Interpreter
      > qualified names can be None, so we need to handle it
      > Cleanup some callbacks
      > Make sure that Python 2 passes a test on more systems
      > Make sure warnings are not shown if a property is executed, fixes #1383
      > Fix RecursionError: global statements in modules should just be ignored, fixes #1457
      > Make it possible to infer Callable TypeVars, fixes #1449
      > Account for sys path potentially not being all unicode in typeshed, fixes #1456
      > Make sure docstrings can always be inferred for builtins modules, fixes #1432
      > Forgot to add some test files
      > Get the context of a class name right, fixes #1396
      > Make sure classmethod signatures don't include cls, fixes #1455
      > Add a test to show that type var inference also works for tuples
      > Don't use globals anymore
      > Remove a duplicate method
      > More docstrings
      > A bit better documentation
      > Refactor so typing uses BaseTypingValueWithGenerics
      > Make some more classes private for inference.gradual.base
      > Use _create_instance_with_generics
      > The generics manager is now part of DefineGenericBase
      > Remove get_index_and_execute and use something else
      > _InstanceWrapper to _GenericInstanceWrapper
      > Another rename for readability
      > Merge GenericClass and  _AbstractAnnotatedClass
      > Use the generics manager for all the typing classes
      > Start using generic managers, for #1413
      > Start working on generic managers, see #1413
      > Move iter_over_arguments to a separate file
      > value_of_index -> context_of_index
      > Try to prepare DefineGenericBase for a more general usage
      > Make AbstractAnnotatedClass private
      > Move parts of AbstractAnnotatedClass to the new class DefineGenericBase
      > Formatting
      > Rename two classes to make some things clearer
      > Make some lines shorter
      > Remove an unused InstanceArguments
      > Move more stuff from gradual/typing.py to gradual/base.py
      > Remove TypingName, it looks like it's not used
      > Start splitting up gradual/typing.py
      > Make sure Callable TypeVars are better identified, solves a part of #1413
      > Remove a TODO that was implemented
      > Pin colorama to a version that works for Python 3.4
      > Find active conda environment and set it as default (if there is one) (#1440)
      > Remove Python 3.4 test from appveyor
      > Make sure overload signatures work, see #1417
      > Shorten a line to < 100 chars
      > Fix a tuple test
      > Make sure that Tuple autocompletes properly, fixes #1389
      > Avoid more Python 2
      > Fix issues with interpreter completions on unittest.mock.
      > Start writing the changelog
      > Improve call signature detection by a lot
      > Make sure we use the right context in case of goto with decorators, fixes #1427
      > Python 2 still sucks.
      > Make sure an assert no longer causes unnecessary trouble
      > Make sure that decorator signature completion is working, see #1433
      > Avoid wrong random call signature completion, fixes #1433
      > Make sure py__iter__ has the right signature
      > Remove probably dead code
      > Python 2
      > Make sure execute_function_slots and get_function_slots is defined for all instances
      > Upgrade typeshed to the latest commits
      > Make sure that the differences are calculated a bit more reliable, fixes #1429
      > Unfortunately commited something that should not have been committed
      > Fix Python 2 issues
      > A CompiledInstance is not really compiled, it's an instance of a compiled class value
      > Remove is_package on contexts
      > Fix some more package issues
      > Get rid of py__package__ from contexts
      > Make is_package a function and call it consistently
      > Make sure code_lines works on stubs, even if they are builtins
      > Fix the MixedContext and also use MixedModuleContext
      > Separate CompiledModuleContext from CompiledContext, fixes #1428
      > Fix contextualizing of subscriptlist
      > Fix a globals context issue, fixes #1435
      > Remove Python 2 implicit relative imports feature
      > A small rename of a value that is actually a context
      > Merge pull request #1451 from pappasam/FIX_SHOW_SYSTEM_FOLDERS
      > Add __ne__ to BaseValueSet. Might have caused issues in Python 2, see #1442
      > Avoid finding submodules for compiled objects, because it's at least not implemented
      > Make sure that goto on a subscript colon doesn't crash
      > Fix getitem in compiled
      > Make sure py__get__ is defined on all values
      > Fix file name completions when file name is too long
      > Fix an issue around completions in comments before strings
      > Fix missing inference for typing.Type[typing.TypeVar] (#1448)
      > Remove Python 3.9 dev build from travis, it's not needed
      > Start to use Python 3.8 in the normal CI pipeline
      > Fix the pow test for Python 3.8
      > Fix inference from type comment for function parameter with dot
      > Fix annotation string generated from wrong object
      > Fix a small issue created in #1398
      > fix static analysis test skips with latest pytest
      > Fixed rST in changelog
      > test: test_completion: Dynamically resolve current directory name.
      > Skip Python 2 tests for some array issues
      > Skip some param resolving tests in Python 2/3.4
      > Add a few tests for a previous assertion failure
      > Make sure a compiled instance is is_compiled
      > Reenable a test
      > Disable a test in Python2
      > Remove a few unused imports
      > Move eval_node to one place
      > Avoid creating the same object twice
      > Move inference_state.goto to the name and _follow_error_node_imports_if_possible away from inference_state
      > Make some dynamic array variables private
      > ContextualizedName -> TreeNameDefinition
      > Use create_name instead of duplicated logic
      > Replace obj with value
      > Remove get_object, it's not needed anymore
      > Implement properties properly
      > Make arguments private for instance
      > Refactor dynamic params a bit
      > Revert "Refactor some dynamic function arguments things"
      > Refactor some dynamic function arguments things
      > Move some annotation inferring code to proper functions
      > Remove an unneeded list cast
      > SimpleParamName -> AnonymousParamName
      > Make create_instance_context a lot more understandable (and shorter)
      > Make sure a self variable is only defined in a function not outside
      > get_first_non_keyword_argument_values is not really used anymore
      > A simplification
      > Fix recursion issues about dynamic param lookups and defaults work again
      > Refactor search_param_names interface
      > Use get_executed_param_names if get_executed_param_names_and_issues is not necessary
      > Don't use get_executed_param_names_and_issues as an attribute on arguments
      > Remvoe AnonymousArguments
      > Refactor AnonymousInstance/TreeInstance, so that the anonymous instance doesn't have to use arguments
      > Separate tree/compiled instances better
      > Get rid of create_init_executions
      > Implement super() properly
      > Start using AnonymousMethodExecutionContext instead of the normal function execution context with arguments
      > Prepare instance for AnonymousMethodExecutionContext
      > Use the function execution filters with proper inheritance
      > Deal with inheritance properly when dealing with function executions
      > Separate FunctionExecution and AnonymousFunctionExecution
      > Fix static analysis for params
      > Add get_param_names to the function execution, which is needed to do some filtering
      > Move the normal anonymous arguments case over to names
      > Prefer annotations in SimpleParamName
      > Add some dynamic inference checks for annotations
      > Avoid using arguments.get_executed_param_names_and_issues
      > Remove get_executed_param_names_and_issues from FunctionExecution
      > Use function/arguments intead of execution
      > Make FunctionExecutionContext.arguments private
      > _ArrayInstance -> _DynamicArrayAdditions
      > var_args -> arguments
      > Fix the final issues about parameter arguments
      > Fix infering of dynamic params
      > Remove an unnecessary piece of code from goto
      > Use Context.create_name instead of weird playing with params everywhere
      > Use SimpleParamName everywhere it's needed
      > Refactor params and what execution contexts need
      > Fix a TODO
      > Make the order of overloaded functions correct
      > Get py__simple_getitem__ working on dicts that have a dict as a param, see #1385
      > Move some code from SequenceLiteralValue to DictLiteralValue
      > Fix usages in context of the new parso parameter include_setitem=True
      > execution_allowed should be called with nodes
      > Move a repr function
      > Fix cases where dicts are passed to dicts and generics were not properly applied
      > Small rename
      > Change a test so it works with generics
      > Get py__simple_getitem__ modifications working for list/dict instances
      > Random objects should not be affected by list/dict modifications
      > Add a way how dict setitem can be understood
      > Move the dynamic module to dynamic_params
      > Move the dynamic arrays code
      > Add a comment about how _ArrayInstance is used
      > check_array_additions -> _check_array_additions
      > Remove methods that are not used
      > Create separate classes for FakeSequence
      > Remove _FakeArray, because it's no longer needed
      > Enable a sys path test that is working now
      > Reenable some tests
      > Add a method implementation, that doesn't seem to be used, but it might one day be.
      > Merge branch 'refactoring'
      > Merge branch 'master' of github.com:davidhalter/jedi
      > Bump version
2019-12-20 12:37:26 +01:00
Daniel Hahler
4dcc6437e3 Update submodule pythonx/parso c0ace63...fb010f2
* pythonx/parso c0ace63...fb010f2 (22):
      > Add a release date to the Changelog
      > Prepare the next release v0.5.2
      > Merge pull request #93 from yangyangxcf/fstring_tokenize
      > Add information about named expressions (#90) to the Changelog
      > Use a lower pytest version so python3.4 is able to pass
      > Use Python 3.8 on travis for testing
      > Whitespace changes
      > Fix: Add more cases for named expression errors, see #89, #90
      > Add Python 3.8 to tested environments for tox
      > Fix: Catch some additional cases named expr errors, see #89, #90
      > Make sure that function executions are errors as well, see #90
      > Some minor refactorings for #90
      > Merge https://github.com/JarryShaw/parso into master
      > Fix trailing comma error
      > Remove debug print statement
      > Fix typo (#84)
      > Fix is_definition test
      > Add include_setitem for get_defined_names, is_definition and get_definition
      > Make is_definition work on setitem modifications, see #66
      > ENH: update grammar for py39 (#78)
      > Refactor the ambiguity tests a bit, see #70
      > Make pgen2's grammar ambiguity detection handle more cases
2019-12-20 12:37:23 +01:00
Daniel Hahler
c80a08d983 Fix invalidating cache with jedi#show_call_signatures (#968) 2019-12-08 17:26:24 +01:00
Daniel Hahler
ac6b2f1e3e ci: Travis: slighty improve codecov-bash invocation (#967) 2019-12-05 23:09:19 +01:00
Dave Halter
12e97c7a04 Make sure call signatures are cleared before they are calculated again 2019-12-05 01:02:58 +01:00
Daniel Hahler
08f13af066 completions: skip docstr without preview, handle exceptions (#958)
Closes https://github.com/davidhalter/jedi-vim/issues/948.
2019-10-20 23:56:22 +02:00
Daniel Hahler
5880f2de93 Revisit usage highlighting (#851) 2019-10-16 22:54:29 +02:00
Daniel Hahler
b4b2f3ef54 debug info: catch any errors with PythonJedi commands
Ref: https://github.com/davidhalter/jedi-vim/issues/953
2019-09-28 12:34:54 +02:00
Daniel Hahler
50abb5e95a jedi#debug_info: escape script path for "git" (#950)
Ref: https://github.com/davidhalter/jedi-vim/issues/949
2019-09-24 08:43:48 +02:00
Daniel Hahler
89c995e7d9 display_debug_info: add global sys.executable (#947)
This helps with bug reports in general.
2019-09-19 00:46:16 +02:00
Daniel Hahler
4f2499e4f2 ci/tests: update dependencies 2019-08-19 01:06:32 +02:00
Daniel Hahler
7665d73eae Update submodule pythonx/jedi to v0.15.1: 35e5cf2c...005f6939 (#940)
* pythonx/jedi 35e5cf2c...005f6939 (5):
      > Write the CHANGELOG for 0.15.1
      > Remove forgotten debug/print in filename completion. (#1380)
      > staticmethod and a few other cases might not have properly returned its signatures
      > Remove reference to a file that doesn't exist anymore
      > Bump version to make it clear that it's a different one than the current one
2019-08-18 21:35:09 +02:00
Daniel Hahler
b3d715c5fc Update submodule pythonx/jedi 60415033...35e5cf2c
* pythonx/jedi 60415033...35e5cf2c (106):
      > A small Changelog improvement
      > Cleanup Changelog for the next release
      > Make it possible to access functions that were inherited, see #1347
      > Messed up a Windows test
      > Again a small windows issue fixed.
      > Need to escape the path backslash for windows slashes
      > Make it possible to access properties again
      > A small compatibility fix
      > Fix an issue with type vars that might have been a problem for other things as well
      > Don't add quotes after paths if they are already there
      > A small speed optimization that helps a lot with sys.version_info >= (3, 0) patterns in typeshed
      > Remove an unnecessary isinstance usage
      > Make CompiledValue lazy
      > A python 2 fix
      > Fix an error that occured because of some refactorings
      > Fix one more os.path.join issue
      > Fix more issues with os.path path completion
      > Make join detection much easier
      > Fix some remaining issues with file path completions
      > A few more tests for path completions (join)
      > Fix quote completions for os.path.join path completions
      > Fix first param argument of os.path.join file completions
      > Fix arglist/trailer issues
      > in os.path.join completions, directories should not end in a slash
      > Make some file path completions in os.path.join work
      > Fix os.path.join static value gathering
      > os.path.sep should always have a clear value
      > Fix string name completion for stuff like dirname and abspath
      > Fix bytes issue with file path adding
      > Python 2 compatibility
      > Make __file__ return the correct value
      > Fix string additions when used in certain ways
      > Make string additions work for file path completion
      > Fix interpeter project path
      > Fix the REPL completer for file path completions
      > Fix a few more file name completion cases
      > A first iteration for file path completions
      > Fix a test failure
      > Add Definition.execute, fixes #1076
      > Add tests to show that #516 is not working, yet
      > List possible Definition.type in its docstring, fixes #1069.
      > Start writing the Changelog for 0.15.0
      > 3.8-dev should not be allowed to fail
      > Skip more Python 2 tests
      > Skipping of tests was done the wrong way again
      > Skip the right tests
      > Parameter.kind is not avaialble in Python 3.5
      > Fix Python 2 test issues
      > Add a few docstrings to make some things clearer
      > Add ParamDefinition.kind, fixes #1361
      > Make it possible to format a param to a string, fixes #1074
      > Add another test for signature annotations
      > Add Signature.to_string() with proper tests, fixes #779, fixes #780
      > Test infer_default
      > Use a helper to create definitions
      > Add a execute_annotation option to infer_annotation
      > Test infer_annotation
      > Make it possible for users to infer annotations/defaults
      > A first iteration of adding signatures to the API, fixes #1139
      > Fix a caching issue
      > Forgot the right resolve_stars parameters in one place
      > Cache getting resolved param names
      > Turn around resolve_stars, it shouldn't by default be resolved
      > Remove a class that is not needed anymore
      > Revert "Use __str__ instead of to_string"
      > Fix the last remaining issues with function signature
      > overloaded_functions should be private
      > Use __str__ instead of to_string
      > Better repr for CallSignature
      > Fix some minor signature issues
      > Remove the unused function signature_matches
      > Fix signatures for __init__ calls when used with supers, fixes #1163
      > Fix some issues for args resolving in method calls
      > Remove a bit of code that i sprobably unused
      > Move get_signatures from Function to FunctionMixin
      > Merge the signature changes
      > Remove an import
      > Small refactoring
      > Skipped Python 2 Interpreter tests the wrong way
      > Remove a paragraph in docs that was arguing that stubs and generics (and other things) were not properly supported, fixes #1012
      > Fix partial signatures for MixedObject
      > Fix partial signatures, fixes #1371
      > Make sure with a test that the staticmethod signature is also correct
      > Fix classmethod signature, fixes #498
      > Deal with annotation on *args and **kwargs correctly, fixes #980
      > Use LazyContextWrapper more
      > Very small refactoring
      > Fix for failing assertion on native modules Issue #1354 (#1370)
      > Skip numpydoc tests for Python 2
      > Remove code that didn't mean anything
      > Fix docstrings for wrapped functions, fixes #906
      > Fix an isue about dict ordering in Python before 3.6.
      > Make it clearer when get_param is used.
      > A small dataclass refactoring
      > Evaluate annotations for dataclasses when infer is called on param
      > Get inheritance of dataclass right
      > A first working iteration of dataclass signatures, fixes #1213
      > Remove an unused function
      > Dataclass progress
      > Add enum changes to changelog
      > Fix a recursion error about getting metaclasses
      > One test about recursion issues only applied to Python 2
      > Use class filters in instances differently so metaclass plugins work, fixes #1090
      > First step in working with metaclasses in plugins, see #1090.
      > Refactor the plugin registry
      > Remove classes from plugins and use decorators instead
2019-08-12 00:16:06 +02:00
21 changed files with 889 additions and 339 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: [davidhalter]

63
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: ci
on: push
jobs:
tests:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive
- name: Setup
run: |
sudo pip install pytest
vim --version
#- name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
- name: Run tests
run: 'make test'
code-quality:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive
- name: Run tests
run: |
vim --version
make check
coverage:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive
- name: Install dependencies
run: |
sudo add-apt-repository ppa:neovim-ppa/stable -y
sudo apt-get update -q
sudo apt-get install neovim -y
sudo pip install pynvim pytest-cov
sudo pip list
nvim --version
- name: Run tests
run: |
make --keep-going test_coverage BUILD_VIRTUAL_ENV=$VIRTUAL_ENV
- name: Upload coverage data
run: |
coverage xml
bash <(curl -s https://codecov.io/bash) -X fix -f coverage.xml -F py${TRAVIS_PYTHON_VERSION//./}

View File

@@ -1,15 +1,10 @@
dist: xenial dist: bionic
language: python language: python
python: 3.7 python: 3.8
env: env:
matrix: - ENV=test
- ENV=test - ENV=check
- ENV=check - ENV=test_coverage
- ENV=test_coverage
matrix:
include:
- env: ENV=test_coverage
python: 2.7
install: install:
- | - |
if [ "$ENV" = "test" ]; then if [ "$ENV" = "test" ]; then
@@ -20,15 +15,17 @@ install:
sudo apt-get install neovim -y sudo apt-get install neovim -y
pip install pynvim pytest-cov pip install pynvim pytest-cov
pip list
nvim --version
else else
vim --version vim --version
fi fi
script: script:
- make --keep-going "$ENV" BUILD_VIRTUAL_ENV=$VIRTUAL_ENV - make --keep-going "$ENV" BUILD_VIRTUAL_ENV=$VIRTUAL_ENV
after_success: after_script:
- | - |
if [ "$ENV" = "test_coverage" ]; then if [ "$ENV" = "test_coverage" ]; then
coverage xml coverage xml
bash <(curl -s https://codecov.io/bash) -X gcov -X coveragepy -X fix -X search -X xcode -f coverage.xml -F py${TRAVIS_PYTHON_VERSION//./} travis_retry bash <(curl -s https://codecov.io/bash) -X fix -f coverage.xml -F py${TRAVIS_PYTHON_VERSION//./}
fi fi

View File

@@ -16,10 +16,10 @@ $(BUILD_VIRTUAL_ENV): | $(dir $(BUILD_VIRTUAL_ENV))
python -m venv $@ python -m venv $@
$(BUILD_VIRTUAL_ENV)/bin/vint: | $(BUILD_VIRTUAL_ENV) $(BUILD_VIRTUAL_ENV)/bin/vint: | $(BUILD_VIRTUAL_ENV)
$|/bin/python -m pip install vim-vint==0.3.19 $|/bin/python -m pip install vim-vint==0.3.21
$(BUILD_VIRTUAL_ENV)/bin/flake8: | $(BUILD_VIRTUAL_ENV) $(BUILD_VIRTUAL_ENV)/bin/flake8: | $(BUILD_VIRTUAL_ENV)
$|/bin/python -m pip install -q flake8==3.5.0 $|/bin/python -m pip install -q flake8==3.7.8
vint: $(BUILD_VIRTUAL_ENV)/bin/vint vint: $(BUILD_VIRTUAL_ENV)/bin/vint
$(BUILD_VIRTUAL_ENV)/bin/vint after autoload ftplugin plugin $(BUILD_VIRTUAL_ENV)/bin/vint after autoload ftplugin plugin

View File

@@ -58,9 +58,10 @@ generators, there is broad support.
Apart from that, jedi-vim supports the following commands Apart from that, jedi-vim supports the following commands
- Completion ``<C-Space>`` - Completion ``<C-Space>``
- Goto assignments ``<leader>g`` (typical goto function) - Goto assignment ``<leader>g`` (typical goto function)
- Goto definitions ``<leader>d`` (follow identifier as far as possible, - Goto definition ``<leader>d`` (follow identifier as far as possible,
includes imports and statements) includes imports and statements)
- Goto (typing) stub ``<leader>s``
- Show Documentation/Pydoc ``K`` (shows a popup with assignments) - Show Documentation/Pydoc ``K`` (shows a popup with assignments)
- Renaming ``<leader>r`` - Renaming ``<leader>r``
- Usages ``<leader>n`` (shows all the usages of a name) - Usages ``<leader>n`` (shows all the usages of a name)
@@ -181,8 +182,10 @@ and usually saves one keypress.
Jedi displays function call signatures in insert mode in real-time, highlighting Jedi displays function call signatures in insert mode in real-time, highlighting
the current argument. The call signatures can be displayed as a pop-up in the the current argument. The call signatures can be displayed as a pop-up in the
buffer (set to 1, the default), which has the advantage of being easier to refer buffer (set to 1 by default (with the conceal feature), 2 otherwise),
to, or in Vim's command line aligned with the function call (set to 2), which which has the advantage of being easier to refer to (but is a hack with
many drawbacks since it changes the buffer's contents),
or in Vim's command line aligned with the function call (set to 2), which
can improve the integrity of Vim's undo history. can improve the integrity of Vim's undo history.
.. code-block:: vim .. code-block:: vim
@@ -198,12 +201,18 @@ get more information. If you set them to ``""``, they are not assigned.
let g:jedi#goto_command = "<leader>d" let g:jedi#goto_command = "<leader>d"
let g:jedi#goto_assignments_command = "<leader>g" let g:jedi#goto_assignments_command = "<leader>g"
let g:jedi#goto_stubs_command = "<leader>s"
let g:jedi#goto_definitions_command = "" let g:jedi#goto_definitions_command = ""
let g:jedi#documentation_command = "K" let g:jedi#documentation_command = "K"
let g:jedi#usages_command = "<leader>n" let g:jedi#usages_command = "<leader>n"
let g:jedi#completions_command = "<C-Space>" let g:jedi#completions_command = "<C-Space>"
let g:jedi#rename_command = "<leader>r" let g:jedi#rename_command = "<leader>r"
A few examples of setting up your project:
.. code-block:: vim
let g:jedi#environment_path = "<leader>d"
Finally, if you don't want completion, but all the other features, use: Finally, if you don't want completion, but all the other features, use:

View File

@@ -27,7 +27,7 @@ let s:default_settings = {
\ 'completions_enabled': 1, \ 'completions_enabled': 1,
\ 'popup_on_dot': 'g:jedi#completions_enabled', \ 'popup_on_dot': 'g:jedi#completions_enabled',
\ 'documentation_command': "'K'", \ 'documentation_command': "'K'",
\ 'show_call_signatures': 1, \ 'show_call_signatures': has('conceal') ? 1 : 2,
\ 'show_call_signatures_delay': 500, \ 'show_call_signatures_delay': 500,
\ 'call_signature_escape': "'?!?'", \ 'call_signature_escape': "'?!?'",
\ 'auto_close_doc': 1, \ 'auto_close_doc': 1,
@@ -35,6 +35,8 @@ let s:default_settings = {
\ 'popup_select_first': 1, \ 'popup_select_first': 1,
\ 'quickfix_window_height': 10, \ 'quickfix_window_height': 10,
\ 'force_py_version': "'auto'", \ 'force_py_version': "'auto'",
\ 'environment_path': "'auto'",
\ 'project_path': "'auto'",
\ 'smart_auto_mappings': 0, \ 'smart_auto_mappings': 0,
\ 'use_tag_stack': 1 \ 'use_tag_stack': 1
\ } \ }
@@ -52,41 +54,21 @@ for [s:key, s:val] in items(s:default_settings)
endif endif
endfor endfor
let s:supports_buffer_usages = has('nvim') || exists('*prop_add')
" ------------------------------------------------------------------------ " ------------------------------------------------------------------------
" Python initialization " Python initialization
" ------------------------------------------------------------------------ " ------------------------------------------------------------------------
let s:script_path = fnameescape(expand('<sfile>:p:h:h')) let s:script_path = expand('<sfile>:p:h:h')
" Initialize Python (PythonJedi command).
function! s:init_python() abort function! s:init_python() abort
" Use g:jedi#force_py_version for loading Jedi, or fall back to using " Use g:jedi#force_py_version for loading Jedi, or fall back to using
" `has()` - preferring Python 3. " `has()` - preferring Python 3.
let loader_version = get(g:, 'jedi#loader_py_version', g:jedi#force_py_version) if !has('python3')
if loader_version ==# 'auto' throw 'jedi-vim requires Vim with support for Python 3.'
if has('python3')
let loader_version = 3
elseif has('python')
let loader_version = 2
else
throw 'jedi-vim requires Vim with support for Python 2 or 3.'
endif
else
if loader_version =~# '^3'
let loader_version = 3
elseif loader_version =~# '^2'
let loader_version = 2
else
if !exists('g:jedi#squelch_py_warning')
echohl WarningMsg
echom printf("jedi-vim: could not determine Python loader version from 'g:jedi#loader_py_version/g:jedi#force_py_version' (%s), using 3.",
\ loader_version)
echohl None
endif
let loader_version = 3
endif
endif endif
call jedi#setup_python_imports(loader_version) call jedi#setup_python_imports()
return 1 return 1
endfunction endfunction
@@ -141,33 +123,25 @@ function! jedi#init_python() abort
endfunction endfunction
let s:python_version = 'null' function! jedi#setup_python_imports() abort
function! jedi#setup_python_imports(py_version) abort
if a:py_version == 2
let cmd_exec = 'python'
let s:python_version = 2
elseif a:py_version == 3
let cmd_exec = 'python3'
let s:python_version = 3
else
throw 'jedi#setup_python_imports: invalid py_version: '.a:py_version
endif
execute 'command! -nargs=1 PythonJedi '.cmd_exec.' <args>'
let g:_jedi_init_error = 0 let g:_jedi_init_error = 0
let init_lines = [ let init_lines = [
\ 'import vim', \ 'import vim',
\ 'def _jedi_handle_exc(exc_info):',
\ ' try:',
\ ' from jedi_vim_debug import format_exc_info',
\ ' vim.vars["_jedi_init_error"] = format_exc_info(exc_info)',
\ ' except Exception:',
\ ' import traceback',
\ ' vim.vars["_jedi_init_error"] = "\\n".join(traceback.format_exception(*exc_info))',
\ 'try:', \ 'try:',
\ ' import jedi_vim', \ ' import jedi_vim',
\ ' if hasattr(jedi_vim, "jedi_import_error"):', \ ' if hasattr(jedi_vim, "jedi_import_error"):',
\ ' from jedi_vim_debug import format_exc_info', \ ' _jedi_handle_exc(jedi_vim.jedi_import_error)',
\ ' vim.vars["_jedi_init_error"] = format_exc_info(jedi_vim.jedi_import_error)',
\ 'except Exception as exc:', \ 'except Exception as exc:',
\ ' from jedi_vim_debug import format_exc_info', \ ' _jedi_handle_exc(sys.exc_info())',
\ ' vim.vars["_jedi_init_error"] = format_exc_info()',
\ ] \ ]
exe 'PythonJedi exec('''.escape(join(init_lines, '\n'), "'").''')' exe 'python3 exec('''.escape(join(init_lines, '\n'), "'").''')'
if g:_jedi_init_error isnot 0 if g:_jedi_init_error isnot 0
throw printf('jedi#setup_python_imports: %s', g:_jedi_init_error) throw printf('jedi#setup_python_imports: %s', g:_jedi_init_error)
endif endif
@@ -181,33 +155,43 @@ function! jedi#debug_info() abort
echohl WarningMsg | echo 'You should run this in a buffer with filetype "python".' | echohl None echohl WarningMsg | echo 'You should run this in a buffer with filetype "python".' | echohl None
endif endif
endif endif
let spath = shellescape(s:script_path)
echo '#### Jedi-vim debug information' echo '#### Jedi-vim debug information'
echo "\n" echo "\n"
echo '##### jedi-vim version' echo '##### jedi-vim version'
echo "\n" echo "\n"
echo ' - jedi-vim git version: ' echo ' - jedi-vim git version: '
echon substitute(system('git -C '.s:script_path.' describe --tags --always --dirty'), '\v\n$', '', '') echon substitute(system('git -C '.spath.' describe --tags --always --dirty'), '\v\n$', '', '')
echo ' - jedi git submodule status: ' echo ' - jedi git submodule status: '
echon substitute(system('git -C '.s:script_path.' submodule status pythonx/jedi'), '\v\n$', '', '') echon substitute(system('git -C '.spath.' submodule status pythonx/jedi'), '\v\n$', '', '')
echo ' - parso git submodule status: ' echo ' - parso git submodule status: '
echon substitute(system('git -C '.s:script_path.' submodule status pythonx/parso'), '\v\n$', '', '') echon substitute(system('git -C '.spath.' submodule status pythonx/parso'), '\v\n$', '', '')
echo "\n" echo "\n"
echo '##### Global Python' echo '##### Global Python'
echo "\n" echo "\n"
echo 'Using Python version '.s:python_version.' to access Jedi.' echo 'Using Python version 3 to access Jedi.'
let pyeval = s:python_version == 3 ? 'py3eval' : 'pyeval'
let s:pythonjedi_called = 0 let s:pythonjedi_called = 0
PythonJedi import vim; vim.command('let s:pythonjedi_called = 1') try
python3 import vim; vim.command('let s:pythonjedi_called = 1')
catch
echo 'Error when trying to import vim: '.v:exception
endtry
if !s:pythonjedi_called if !s:pythonjedi_called
echohl WarningMsg echohl WarningMsg
echom 'PythonJedi failed to run, likely a Python config issue.' echom 'python3 failed to run, likely a Python config issue.'
if exists(':checkhealth') == 2 if exists(':checkhealth') == 2
echom 'Try :checkhealth for more information.' echom 'Try :checkhealth for more information.'
endif endif
echohl None echohl None
else else
PythonJedi from jedi_vim_debug import display_debug_info try
PythonJedi display_debug_info() python3 from jedi_vim_debug import display_debug_info
python3 display_debug_info()
catch
echohl WarningMsg
echo 'Error when running display_debug_info: '.v:exception
echohl None
endtry
endif endif
echo "\n" echo "\n"
echo '##### Settings' echo '##### Settings'
@@ -277,71 +261,150 @@ call jedi#init_python() " Might throw an error.
" functions that call python code " functions that call python code
" ------------------------------------------------------------------------ " ------------------------------------------------------------------------
function! jedi#goto() abort function! jedi#goto() abort
PythonJedi jedi_vim.goto(mode="goto") python3 jedi_vim.goto(mode="goto")
endfunction endfunction
function! jedi#goto_assignments() abort function! jedi#goto_assignments() abort
PythonJedi jedi_vim.goto(mode="assignment") python3 jedi_vim.goto(mode="assignment")
endfunction endfunction
function! jedi#goto_definitions() abort function! jedi#goto_definitions() abort
PythonJedi jedi_vim.goto(mode="definition") python3 jedi_vim.goto(mode="definition")
endfunction endfunction
function! jedi#goto_stubs() abort function! jedi#goto_stubs() abort
PythonJedi jedi_vim.goto(mode="stubs") python3 jedi_vim.goto(mode="stubs")
endfunction endfunction
function! jedi#usages() abort function! jedi#usages() abort
call jedi#remove_usages() if exists('#jedi_usages#BufWinEnter')
PythonJedi jedi_vim.usages() call jedi#clear_usages()
endif
python3 jedi_vim.usages()
endfunction endfunction
function! jedi#remove_usages() abort if !s:supports_buffer_usages
for match in getmatches() " Hide usages in the current window.
if stridx(match['group'], 'jediUsage') == 0 " Only handles the current window due to matchdelete() restrictions.
call matchdelete(match['id']) function! jedi#_hide_usages_in_win() abort
endif let winnr = winnr()
let matchids = getwinvar(winnr, '_jedi_usages_vim_matchids', [])
for matchid in matchids[1:]
call matchdelete(matchid)
endfor endfor
call setwinvar(winnr, '_jedi_usages_vim_matchids', [])
" Remove the autocommands that might have triggered this function.
augroup jedi_usages
exe 'autocmd! * <buffer='.winbufnr(winnr).'>'
augroup END
unlet! b:_jedi_usages_needs_clear
endfunction
" Show usages for current window (Vim without textprops only).
function! jedi#_show_usages_in_win() abort
python3 jedi_vim.highlight_usages_for_vim_win()
if !exists('#jedi_usages#TextChanged#<buffer>')
augroup jedi_usages
" Unset highlights on any changes to this buffer.
" NOTE: Neovim's API handles movement of highlights, but would only
" need to clear highlights that are changed inline.
autocmd TextChanged <buffer> call jedi#_clear_buffer_usages()
" Hide usages when the buffer is removed from the window, or when
" entering insert mode (but keep them for later).
autocmd BufWinLeave,InsertEnter <buffer> call jedi#_hide_usages_in_win()
augroup END
endif
endfunction
" Remove usages for the current buffer (and all its windows).
function! jedi#_clear_buffer_usages() abort
let bufnr = bufnr('%')
let nvim_src_ids = getbufvar(bufnr, '_jedi_usages_src_ids', [])
if !empty(nvim_src_ids)
for src_id in nvim_src_ids
" TODO: could only clear highlights below/after changed line?!
call nvim_buf_clear_highlight(bufnr, src_id, 0, -1)
endfor
else
call jedi#_hide_usages_in_win()
endif
endfunction
endif
" Remove/unset global usages.
function! jedi#clear_usages() abort
augroup jedi_usages
autocmd! BufWinEnter
autocmd! WinEnter
augroup END
if !s:supports_buffer_usages
" Vim without textprops: clear current window,
" autocommands will clean others on demand.
call jedi#_hide_usages_in_win()
" Setup autocommands to clear remaining highlights on WinEnter.
augroup jedi_usages
for b in range(1, bufnr('$'))
if getbufvar(b, '_jedi_usages_needs_clear')
exe 'autocmd WinEnter <buffer='.b.'> call jedi#_hide_usages_in_win()'
endif
endfor
augroup END
endif
python3 jedi_vim.clear_usages()
endfunction endfunction
function! jedi#rename(...) abort function! jedi#rename(...) abort
PythonJedi jedi_vim.rename() python3 jedi_vim.rename()
endfunction endfunction
function! jedi#rename_visual(...) abort function! jedi#rename_visual(...) abort
PythonJedi jedi_vim.rename_visual() python3 jedi_vim.rename_visual()
endfunction endfunction
function! jedi#completions(findstart, base) abort function! jedi#completions(findstart, base) abort
PythonJedi jedi_vim.completions() python3 jedi_vim.completions()
endfunction endfunction
function! jedi#enable_speed_debugging() abort function! jedi#enable_speed_debugging() abort
PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False) python3 jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
endfunction endfunction
function! jedi#enable_debugging() abort function! jedi#enable_debugging() abort
PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout) python3 jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
endfunction endfunction
function! jedi#disable_debugging() abort function! jedi#disable_debugging() abort
PythonJedi jedi_vim.jedi.set_debug_function(None) python3 jedi_vim.jedi.set_debug_function(None)
endfunction endfunction
function! jedi#py_import(args) abort function! jedi#py_import(args) abort
PythonJedi jedi_vim.py_import() python3 jedi_vim.py_import()
endfun
function! jedi#choose_environment(args) abort
python3 jedi_vim.choose_environment()
endfun
function! jedi#load_project(args) abort
python3 jedi_vim.load_project()
endfun endfun
function! jedi#py_import_completions(argl, cmdl, pos) abort function! jedi#py_import_completions(argl, cmdl, pos) abort
PythonJedi jedi_vim.py_import_completions() python3 jedi_vim.py_import_completions()
endfun endfun
function! jedi#clear_cache(bang) abort function! jedi#clear_cache(bang) abort
if a:bang if a:bang
PythonJedi jedi_vim.jedi.cache.clear_time_caches(True) python3 jedi_vim.jedi.cache.clear_time_caches(True)
else else
PythonJedi jedi_vim.jedi.cache.clear_time_caches(False) python3 jedi_vim.jedi.cache.clear_time_caches(False)
endif endif
endfunction endfunction
@@ -350,7 +413,7 @@ endfunction
" show_documentation " show_documentation
" ------------------------------------------------------------------------ " ------------------------------------------------------------------------
function! jedi#show_documentation() abort function! jedi#show_documentation() abort
PythonJedi if jedi_vim.show_documentation() is None: vim.command('return') python3 if jedi_vim.show_documentation() is None: vim.command('return')
let bn = bufnr('__doc__') let bn = bufnr('__doc__')
if bn > 0 if bn > 0
@@ -392,20 +455,48 @@ endfunction
" helper functions " helper functions
" ------------------------------------------------------------------------ " ------------------------------------------------------------------------
function! jedi#add_goto_window(len) abort function! jedi#add_goto_window(for_usages, len) abort
set lazyredraw
cclose
let height = min([a:len, g:jedi#quickfix_window_height]) let height = min([a:len, g:jedi#quickfix_window_height])
" Use :copen to go to the window always - the user should select an entry.
execute 'belowright copen '.height execute 'belowright copen '.height
set nolazyredraw
if &filetype !=# 'qf'
echoerr printf('jedi-vim: unexpected ft with current window (%s), please report!', &filetype)
endif
if g:jedi#use_tabs_not_buffers == 1 if g:jedi#use_tabs_not_buffers == 1
noremap <buffer> <CR> :call jedi#goto_window_on_enter()<CR> noremap <buffer> <CR> :call jedi#goto_window_on_enter()<CR>
endif endif
augroup jedi_goto_window augroup jedi_goto_window
au! if a:for_usages
au WinLeave <buffer> q " automatically leave, if an option is chosen autocmd BufWinLeave <buffer> call jedi#clear_usages()
else
autocmd WinLeave <buffer> q " automatically leave, if an option is chosen
endif
augroup END augroup END
redraw!
if a:for_usages && !has('nvim')
if s:supports_buffer_usages
" Setup autocommand for pending highlights with Vim's textprops.
" (cannot be added to unlisted buffers)
augroup jedi_usages
autocmd! BufWinEnter * call s:usages_for_pending_buffers()
augroup END
else
" Setup global autocommand to display any usages for a window.
" Gets removed when closing the quickfix window that displays them, or
" when clearing them (e.g. on TextChanged).
augroup jedi_usages
autocmd! BufWinEnter,WinEnter * call jedi#_show_usages_in_win()
augroup END
endif
endif
endfunction
" Highlight usages for a buffer if not done so yet (Neovim only).
function! s:usages_for_pending_buffers() abort
python3 jedi_vim._handle_pending_usages_for_buf()
endfunction endfunction
@@ -415,7 +506,7 @@ function! jedi#goto_window_on_enter() abort
if l:data.bufnr if l:data.bufnr
" close goto_window buffer " close goto_window buffer
normal! ZQ normal! ZQ
PythonJedi jedi_vim.new_buffer(vim.eval('bufname(l:data.bufnr)')) python3 jedi_vim.new_buffer(vim.eval('bufname(l:data.bufnr)'))
call cursor(l:data.lnum, l:data.col) call cursor(l:data.lnum, l:data.col)
else else
echohl WarningMsg | echo 'Builtin module cannot be opened.' | echohl None echohl WarningMsg | echo 'Builtin module cannot be opened.' | echohl None
@@ -461,22 +552,23 @@ function! jedi#show_call_signatures() abort
" Caching. On the same line only. " Caching. On the same line only.
if line == s:show_call_signatures_last[0] if line == s:show_call_signatures_last[0]
" Check if the number of commas and parenthesis before or after the " Check if the number of special signs before or after the
" cursor has not changed since the last call, which means that the " cursor has not changed since the last call, which means that the
" argument position was not changed and we can skip repainting. " argument position was not changed and we can skip repainting.
let prevcol = s:show_call_signatures_last[1] let prevcol = s:show_call_signatures_last[1]
let prevline = s:show_call_signatures_last[2] let prevline = s:show_call_signatures_last[2]
if substitute(curline[:col-2], '[^,()]', '', 'g') let no_special = '[^,()=]'
\ == substitute(prevline[:prevcol-2], '[^,()]', '', 'g') if substitute(curline[:col-2], no_special, '', 'g')
\ && substitute(curline[(col-2):], '[^,()]', '', 'g') \ == substitute(prevline[:prevcol-2], no_special, '', 'g')
\ == substitute(prevline[(prevcol-2):], '[^,()]', '', 'g') \ && substitute(curline[(col-2):], no_special, '', 'g')
\ == substitute(prevline[(prevcol-2):], no_special, '', 'g')
let reload_signatures = 0 let reload_signatures = 0
endif endif
endif endif
let s:show_call_signatures_last = [line, col, curline] let s:show_call_signatures_last = [line, col, curline]
if reload_signatures if reload_signatures
PythonJedi jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
endif endif
endfunction endfunction
@@ -487,7 +579,7 @@ function! jedi#clear_call_signatures() abort
endif endif
let s:show_call_signatures_last = [0, 0, ''] let s:show_call_signatures_last = [0, 0, '']
PythonJedi jedi_vim.clear_call_signatures() python3 jedi_vim.clear_call_signatures()
endfunction endfunction
@@ -632,7 +724,7 @@ function! jedi#setup_completion() abort
endif endif
endfunction endfunction
"PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False) "python3 jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout, speed=True, warnings=False, notices=False)
"PythonJedi jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout) "python3 jedi_vim.jedi.set_debug_function(jedi_vim.print_to_stdout)
" vim: set et ts=4: " vim: set et ts=4:

7
codecov.yml Normal file
View File

@@ -0,0 +1,7 @@
coverage:
status:
project: true
patch: true
changes: true
comment: off

View File

@@ -24,7 +24,7 @@ Contents *jedi-vim-contents*
5.1. Start completion |g:jedi#completions_command| 5.1. Start completion |g:jedi#completions_command|
5.2. Go to definition |g:jedi#goto_command| 5.2. Go to definition |g:jedi#goto_command|
5.3. Go to assignment |g:jedi#goto_assignments_command| 5.3. Go to assignment |g:jedi#goto_assignments_command|
5.4 Go to definition (deprecated) |g:jedi#goto_definitions_command| 5.4 Go to stub |g:jedi#goto_stubs_command|
5.5. Show documentation |g:jedi#documentation_command| 5.5. Show documentation |g:jedi#documentation_command|
5.6. Rename variables |g:jedi#rename_command| 5.6. Rename variables |g:jedi#rename_command|
5.7. Show name usages |g:jedi#usages_command| 5.7. Show name usages |g:jedi#usages_command|
@@ -44,6 +44,7 @@ Contents *jedi-vim-contents*
6.12. force_py_version |g:jedi#force_py_version| 6.12. force_py_version |g:jedi#force_py_version|
6.13. smart_auto_mappings |g:jedi#smart_auto_mappings| 6.13. smart_auto_mappings |g:jedi#smart_auto_mappings|
6.14. use_tag_stack |g:jedi#use_tag_stack| 6.14. use_tag_stack |g:jedi#use_tag_stack|
6.15. environment_path |g:jedi#environment_path|
7. Testing |jedi-vim-testing| 7. Testing |jedi-vim-testing|
8. Contributing |jedi-vim-contributing| 8. Contributing |jedi-vim-contributing|
9. License |jedi-vim-license| 9. License |jedi-vim-license|
@@ -170,7 +171,7 @@ Python features, among them:
- Class decorators (py3k feature, are being ignored at the moment, but are - Class decorators (py3k feature, are being ignored at the moment, but are
parsed) parsed)
- Simple/usual `sys.path` modifications - Simple/usual `sys.path` modifications
- `isinstance` checks for `if`/`while`/`assert` case, that doesnt work with - `isinstance` checks for `if`/`while`/`assert` case, that doesn't work with
Jedi Jedi
- Stubs - Stubs
- And more... - And more...
@@ -274,12 +275,11 @@ This function finds the first definition of the function/class under the
cursor. It produces an error if the definition is not in a Python file. cursor. It produces an error if the definition is not in a Python file.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
5.4. `g:jedi#goto_definitions_command` *g:jedi#goto_definitions_command* 5.4. `g:jedi#goto_stubs_command` *g:jedi#goto_stubs_command*
Function: `jedi#goto_definitions()` Function: `jedi#goto_stubs()`
Default: - Go to original definition Default: <leader>s Go to stub
NOTE: Deprecated. Use |g:jedi#goto_command| / |jedi#goto()| instead, which Finds the stub of the function/class under the cursor.
currently uses this internally.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
5.5. `g:jedi#documentation_command` *g:jedi#documentation_command* 5.5. `g:jedi#documentation_command` *g:jedi#documentation_command*
@@ -507,6 +507,17 @@ definition with arbitrary changes to the |jumplist|.
Options: 0 or 1 Options: 0 or 1
Default: 1 (enabled by default) Default: 1 (enabled by default)
------------------------------------------------------------------------------
6.15. `g:jedi#environment_path` *g:jedi#environment_path*
To use a specific virtualenv or a specific Python version it is possible to
set an interpreter.
Both setting the directory and setting a project is working.
Examples: "/usr/bin/python3.9", "venv", "../venv", "../venv/bin/python"
Default: "auto"
============================================================================== ==============================================================================
7. Testing *jedi-vim-testing* 7. Testing *jedi-vim-testing*

View File

@@ -32,7 +32,7 @@ if g:jedi#auto_initialization
execute 'nnoremap <silent> <buffer>'.g:jedi#documentation_command.' :call jedi#show_documentation()<CR>' execute 'nnoremap <silent> <buffer>'.g:jedi#documentation_command.' :call jedi#show_documentation()<CR>'
endif endif
if g:jedi#show_call_signatures > 0 && has('conceal') if g:jedi#show_call_signatures > 0
call jedi#configure_call_signatures() call jedi#configure_call_signatures()
endif endif
@@ -50,8 +50,4 @@ if g:jedi#auto_initialization
autocmd! InsertLeave <buffer> if pumvisible() == 0|pclose|endif autocmd! InsertLeave <buffer> if pumvisible() == 0|pclose|endif
augroup END augroup END
endif endif
augroup jedi_usages
autocmd! TextChanged <buffer> call jedi#remove_usages()
autocmd! InsertEnter <buffer> call jedi#remove_usages()
augroup END
endif endif

View File

@@ -53,6 +53,10 @@ endif
" Pyimport command " Pyimport command
command! -nargs=1 -complete=custom,jedi#py_import_completions Pyimport :call jedi#py_import(<q-args>) command! -nargs=1 -complete=custom,jedi#py_import_completions Pyimport :call jedi#py_import(<q-args>)
command! -nargs=? -complete=file JediChooseEnvironment :call jedi#choose_environment(<q-args>)
command! -nargs=? -complete=file JediLoadProject :call jedi#load_project(<q-args>)
function! s:jedi_debug_info() function! s:jedi_debug_info()
" Ensure the autoload file has been loaded (and ignore any errors, which " Ensure the autoload file has been loaded (and ignore any errors, which
" will be displayed with the debug info). " will be displayed with the debug info).

View File

@@ -67,7 +67,9 @@ class VimError(Exception):
self.executing = executing self.executing = executing
def __str__(self): def __str__(self):
return self.message + '; created by: ' + repr(self.executing) return "{}; created by {!r} (in {})".format(
self.message, self.executing, self.throwpoint
)
def _catch_exception(string, is_eval): def _catch_exception(string, is_eval):
@@ -134,6 +136,58 @@ finally:
sys.path.remove(parso_path) sys.path.remove(parso_path)
class VimCompat:
_eval_cache = {}
_func_cache = {}
@classmethod
def has(cls, what):
try:
return cls._eval_cache[what]
except KeyError:
ret = cls._eval_cache[what] = cls.call('has', what)
return ret
@classmethod
def call(cls, func, *args):
try:
f = cls._func_cache[func]
except KeyError:
if IS_NVIM:
f = cls._func_cache[func] = getattr(vim.funcs, func)
else:
f = cls._func_cache[func] = vim.Function(func)
return f(*args)
@classmethod
def setqflist(cls, items, title, context):
if cls.has('patch-7.4.2200'): # can set qf title.
what = {'title': title}
if cls.has('patch-8.0.0590'): # can set qf context
what['context'] = {'jedi_usages': context}
if cls.has('patch-8.0.0657'): # can set items via "what".
what['items'] = items
cls.call('setqflist', [], ' ', what)
else:
# Can set title (and maybe context), but needs two calls.
cls.call('setqflist', items)
cls.call('setqflist', items, 'a', what)
else:
cls.call('setqflist', items)
@classmethod
def setqflist_title(cls, title):
if cls.has('patch-7.4.2200'):
cls.call('setqflist', [], 'a', {'title': title})
@classmethod
def can_update_current_qflist_for_context(cls, context):
if cls.has('patch-8.0.0590'): # can set qf context
return cls.call('getqflist', {'context': 1})['context'] == {
'jedi_usages': context,
}
def catch_and_print_exceptions(func): def catch_and_print_exceptions(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
try: try:
@@ -157,51 +211,84 @@ def _check_jedi_availability(show_error=False):
return func_receiver return func_receiver
current_environment = (None, None) # Tuple of cache key / project
_current_project_cache = None, None
def get_environment(use_cache=True): def get_project():
global current_environment vim_environment_path = vim_eval("g:jedi#environment_path")
vim_project_path = vim_eval("g:jedi#project_path")
vim_force_python_version = vim_eval("g:jedi#force_py_version") global _current_project_cache
if use_cache and vim_force_python_version == current_environment[0]: cache_key = dict(project_path=vim_project_path, environment_path=vim_environment_path)
return current_environment[1] if cache_key == _current_project_cache[0]:
return _current_project_cache[1]
environment = None if vim_environment_path in ("auto", "", None):
if vim_force_python_version == "auto": environment_path = None
environment = jedi.api.environment.get_cached_default_environment()
else: else:
force_python_version = vim_force_python_version environment_path = vim_environment_path
if '0000' in force_python_version or '9999' in force_python_version:
# It's probably a float that wasn't shortened.
try:
force_python_version = "{:.1f}".format(float(force_python_version))
except ValueError:
pass
elif isinstance(force_python_version, float):
force_python_version = "{:.1f}".format(force_python_version)
try: if vim_project_path in ("auto", "", None):
environment = jedi.get_system_environment(force_python_version) project_path = jedi.get_default_project().path
except jedi.InvalidPythonEnvironment as exc: else:
environment = jedi.api.environment.get_cached_default_environment() project_path = vim_project_path
echo_highlight(
"force_python_version=%s is not supported: %s - using %s." % (
vim_force_python_version, str(exc), str(environment)))
current_environment = (vim_force_python_version, environment) project = jedi.Project(project_path, environment_path=environment_path)
return environment
_current_project_cache = cache_key, project
def get_known_environments(): return project
"""Get known Jedi environments."""
envs = list(jedi.api.environment.find_virtualenvs())
envs.extend(jedi.api.environment.find_system_environments())
return envs
@catch_and_print_exceptions @catch_and_print_exceptions
def get_script(source=None, column=None): def choose_environment():
args = shsplit(vim.eval('a:args'))
envs = list(jedi.find_system_environments())
envs.extend(jedi.find_virtualenvs(paths=args or None))
env_paths = [env.executable for env in envs]
vim_command('belowright new')
vim.current.buffer[:] = env_paths
vim.current.buffer.name = "Hit Enter to Choose an Environment"
vim_command(
'setlocal buftype=nofile bufhidden=wipe noswapfile nobuflisted readonly nomodifiable')
vim_command('noremap <buffer> <ESC> :bw<CR>')
vim_command('noremap <buffer> <CR> :python3 jedi_vim.choose_environment_hit_enter()<CR>')
@catch_and_print_exceptions
def choose_environment_hit_enter():
vim.vars['jedi#environment_path'] = vim.current.line
vim_command('bd')
@catch_and_print_exceptions
def load_project():
path = vim.eval('a:args')
vim.vars['jedi#project_path'] = path
env_path = vim_eval("g:jedi#environment_path")
if env_path == 'auto':
env_path = None
if path:
try:
project = jedi.Project.load(path)
except FileNotFoundError:
project = jedi.Project(path, environment_path=env_path)
project.save()
else:
project = jedi.get_default_project()
path = project.path
project.save()
global _current_project_cache
cache_key = dict(project_path=path, environment_path=env_path)
_current_project_cache = cache_key, project
@catch_and_print_exceptions
def get_script(source=None):
jedi.settings.additional_dynamic_modules = [ jedi.settings.additional_dynamic_modules = [
b.name for b in vim.buffers if ( b.name for b in vim.buffers if (
b.name is not None and b.name is not None and
@@ -209,16 +296,19 @@ def get_script(source=None, column=None):
b.options['buflisted'])] b.options['buflisted'])]
if source is None: if source is None:
source = '\n'.join(vim.current.buffer) source = '\n'.join(vim.current.buffer)
buf_path = vim.current.buffer.name
if not buf_path:
# If a buffer has no name its name is an empty string.
buf_path = None
return jedi.Script(source, path=buf_path, project=get_project())
def get_pos(column=None):
row = vim.current.window.cursor[0] row = vim.current.window.cursor[0]
if column is None: if column is None:
column = vim.current.window.cursor[1] column = vim.current.window.cursor[1]
buf_path = vim.current.buffer.name return row, column
return jedi.Script(
source, row, column, buf_path,
encoding=vim_eval('&encoding') or 'latin1',
environment=get_environment(),
)
@_check_jedi_availability(show_error=False) @_check_jedi_availability(show_error=False)
@@ -249,20 +339,26 @@ def completions():
# here again hacks, because jedi has a different interface than vim # here again hacks, because jedi has a different interface than vim
column += len(base) column += len(base)
try: try:
script = get_script(source=source, column=column) script = get_script(source=source)
completions = script.completions() completions = script.complete(*get_pos(column))
signatures = script.call_signatures() signatures = script.get_signatures(*get_pos(column))
add_info = "preview" in vim.eval("&completeopt").split(",")
out = [] out = []
for c in completions: for c in completions:
d = dict(word=PythonToVimStr(c.name[:len(base)] + c.complete), d = dict(word=PythonToVimStr(c.name[:len(base)] + c.complete),
abbr=PythonToVimStr(c.name_with_symbols), abbr=PythonToVimStr(c.name_with_symbols),
# stuff directly behind the completion # stuff directly behind the completion
menu=PythonToVimStr(c.description), menu=PythonToVimStr(c.description),
info=PythonToVimStr(c.docstring()), # docstr
icase=1, # case insensitive icase=1, # case insensitive
dup=1 # allow duplicates (maybe later remove this) dup=1 # allow duplicates (maybe later remove this)
) )
if add_info:
try:
d["info"] = PythonToVimStr(c.docstring())
except Exception:
print("jedi-vim: error with docstring for %r: %s" % (
c, traceback.format_exc()))
out.append(d) out.append(d)
strout = str(out) strout = str(out)
@@ -294,59 +390,64 @@ def tempfile(content):
def goto(mode="goto"): def goto(mode="goto"):
""" """
:param str mode: "definition", "assignment", "goto" :param str mode: "definition", "assignment", "goto"
:return: list of definitions/assignments :rtype: list of jedi.api.classes.Name
:rtype: list
""" """
script = get_script() script = get_script()
pos = get_pos()
if mode == "goto": if mode == "goto":
definitions = script.goto_assignments(follow_imports=True) names = script.goto(*pos, follow_imports=True)
elif mode == "definition": elif mode == "definition":
definitions = script.goto_definitions() names = script.infer(*pos)
elif mode == "assignment": elif mode == "assignment":
definitions = script.goto_assignments() names = script.goto(*pos)
elif mode == "stubs": elif mode == "stubs":
definitions = script.goto_assignments(follow_imports=True, only_stubs=True) names = script.goto(*pos, follow_imports=True, only_stubs=True)
if not definitions: if not names:
echo_highlight("Couldn't find any definitions for this.") echo_highlight("Couldn't find any definitions for this.")
elif len(definitions) == 1 and mode != "related_name": elif len(names) == 1 and mode != "related_name":
d = list(definitions)[0] n = list(names)[0]
if d.column is None: _goto_specific_name(n)
if d.is_keyword:
echo_highlight("Cannot get the definition of Python keywords.")
else:
echo_highlight("Builtin modules cannot be displayed (%s)."
% d.desc_with_module)
else:
using_tagstack = int(vim_eval('g:jedi#use_tag_stack')) == 1
if (d.module_path or '') != vim.current.buffer.name:
result = new_buffer(d.module_path,
using_tagstack=using_tagstack)
if not result:
return []
if (using_tagstack and d.module_path and
os.path.exists(d.module_path)):
tagname = d.name
with tempfile('{0}\t{1}\t{2}'.format(
tagname, d.module_path, 'call cursor({0}, {1})'.format(
d.line, d.column + 1))) as f:
old_tags = vim.eval('&tags')
old_wildignore = vim.eval('&wildignore')
try:
# Clear wildignore to ensure tag file isn't ignored
vim.command('set wildignore=')
vim.command('let &tags = %s' %
repr(PythonToVimStr(f.name)))
vim.command('tjump %s' % tagname)
finally:
vim.command('let &tags = %s' %
repr(PythonToVimStr(old_tags)))
vim.command('let &wildignore = %s' %
repr(PythonToVimStr(old_wildignore)))
vim.current.window.cursor = d.line, d.column
else: else:
show_goto_multi_results(definitions) show_goto_multi_results(names, mode)
return definitions return names
def _goto_specific_name(n, options=''):
if n.column is None:
if n.is_keyword:
echo_highlight("Cannot get the definition of Python keywords.")
else:
echo_highlight("Builtin modules cannot be displayed (%s)."
% (n.full_name or n.name))
else:
using_tagstack = int(vim_eval('g:jedi#use_tag_stack')) == 1
module_path = str(n.module_path or '')
if module_path != vim.current.buffer.name:
result = new_buffer(module_path, options=options,
using_tagstack=using_tagstack)
if not result:
return []
if (using_tagstack and module_path and
os.path.exists(module_path)):
tagname = n.name
with tempfile('{0}\t{1}\t{2}'.format(
tagname, module_path, 'call cursor({0}, {1})'.format(
n.line, n.column + 1))) as f:
old_tags = vim.eval('&tags')
old_wildignore = vim.eval('&wildignore')
try:
# Clear wildignore to ensure tag file isn't ignored
vim.command('set wildignore=')
vim.command('let &tags = %s' %
repr(PythonToVimStr(f.name)))
vim.command('tjump %s' % tagname)
finally:
vim.command('let &tags = %s' %
repr(PythonToVimStr(old_tags)))
vim.command('let &wildignore = %s' %
repr(PythonToVimStr(old_wildignore)))
vim.current.window.cursor = n.line, n.column
def relpath(path): def relpath(path):
@@ -357,61 +458,298 @@ def relpath(path):
return path return path
def annotate_description(d): def annotate_description(n):
code = d.get_line_code().strip() code = n.get_line_code().strip()
if d.type == 'statement': if n.type == 'statement':
return code return code
if d.type == 'function': if n.type == 'function':
if code.startswith('def'): if code.startswith('def'):
return code return code
typ = 'def' typ = 'def'
else: else:
typ = d.type typ = n.type
return '[%s] %s' % (typ, code) return '[%s] %s' % (typ, code)
def show_goto_multi_results(definitions): def show_goto_multi_results(names, mode):
"""Create a quickfix list for multiple definitions.""" """Create (or reuse) a quickfix list for multiple names."""
global _current_names
lst = [] lst = []
for d in definitions: (row, col) = vim.current.window.cursor
if d.column is None: current_idx = None
current_def = None
for n in names:
if n.column is None:
# Typically a namespace, in the future maybe other things as # Typically a namespace, in the future maybe other things as
# well. # well.
lst.append(dict(text=PythonToVimStr(d.description))) lst.append(dict(text=PythonToVimStr(n.description)))
else: else:
text = annotate_description(d) text = annotate_description(n)
lst.append(dict(filename=PythonToVimStr(relpath(d.module_path)), lst.append(dict(filename=PythonToVimStr(relpath(str(n.module_path))),
lnum=d.line, col=d.column + 1, lnum=n.line, col=n.column + 1,
text=PythonToVimStr(text))) text=PythonToVimStr(text)))
vim_eval('setqflist(%s)' % repr(lst))
vim_eval('jedi#add_goto_window(' + str(len(lst)) + ')') # Select current/nearest entry via :cc later.
if n.line == row and n.column <= col:
if (current_idx is None
or (abs(lst[current_idx]["col"] - col)
> abs(n.column - col))):
current_idx = len(lst)
current_def = n
# Build qflist title.
qf_title = mode
if current_def is not None:
if current_def.full_name:
qf_title += ": " + current_def.full_name
else:
qf_title += ": " + str(current_def)
select_entry = current_idx
else:
select_entry = 0
qf_context = id(names)
if (_current_names
and VimCompat.can_update_current_qflist_for_context(qf_context)):
# Same list, only adjust title/selected entry.
VimCompat.setqflist_title(qf_title)
vim_command('%dcc' % select_entry)
else:
VimCompat.setqflist(lst, title=qf_title, context=qf_context)
for_usages = mode == "usages"
vim_eval('jedi#add_goto_window(%d, %d)' % (for_usages, len(lst)))
vim_command('%d' % select_entry)
def _same_names(a, b):
"""Compare without _inference_state.
Ref: https://github.com/davidhalter/jedi-vim/issues/952)
"""
return all(
x._name.start_pos == y._name.start_pos
and x.module_path == y.module_path
and x.name == y.name
for x, y in zip(a, b)
)
@catch_and_print_exceptions @catch_and_print_exceptions
def usages(visuals=True): def usages(visuals=True):
script = get_script() script = get_script()
definitions = script.usages() names = script.get_references(*get_pos())
if not definitions: if not names:
echo_highlight("No usages found here.") echo_highlight("No usages found here.")
return definitions return names
if visuals: if visuals:
highlight_usages(definitions) global _current_names
show_goto_multi_results(definitions)
return definitions if _current_names:
if _same_names(_current_names, names):
names = _current_names
else:
clear_usages()
assert not _current_names
show_goto_multi_results(names, "usages")
if not _current_names:
_current_names = names
highlight_usages()
else:
assert names is _current_names # updated above
return names
def highlight_usages(definitions, length=None): _current_names = None
for definition in definitions: """Current definitions to use for highlighting."""
# Only color the current module/buffer. _pending_names = {}
if (definition.module_path or '') == vim.current.buffer.name: """Pending definitions for unloaded buffers."""
# mathaddpos needs a list of positions where a position is a list _placed_names_in_buffers = set()
# of (line, column, length). """Set of buffers for faster cleanup."""
# The column starts with 1 and not 0.
positions = [
[definition.line, definition.column + 1, length or len(definition.name)] IS_NVIM = hasattr(vim, 'from_nvim')
] if IS_NVIM:
vim_eval("matchaddpos('jediUsage', %s)" % repr(positions)) vim_prop_add = None
else:
vim_prop_type_added = False
try:
vim_prop_add = vim.Function("prop_add")
except ValueError:
vim_prop_add = None
else:
vim_prop_remove = vim.Function("prop_remove")
def clear_usages():
"""Clear existing highlights."""
global _current_names
if _current_names is None:
return
_current_names = None
if IS_NVIM:
for buf in _placed_names_in_buffers:
src_ids = buf.vars.get('_jedi_usages_src_ids')
if src_ids is not None:
for src_id in src_ids:
buf.clear_highlight(src_id)
elif vim_prop_add:
for buf in _placed_names_in_buffers:
vim_prop_remove({
'type': 'jediUsage',
'all': 1,
'bufnr': buf.number,
})
else:
# Unset current window only.
assert _current_names is None
highlight_usages_for_vim_win()
_placed_names_in_buffers.clear()
def highlight_usages():
"""Set usage names to be highlighted.
With Neovim it will use the nvim_buf_add_highlight API to highlight all
buffers already.
With Vim without support for text-properties only the current window is
highlighted via matchaddpos, and autocommands are setup to highlight other
windows on demand. Otherwise Vim's text-properties are used.
"""
global _current_names, _pending_names
names = _current_names
_pending_names = {}
if IS_NVIM or vim_prop_add:
bufs = {x.name: x for x in vim.buffers}
defs_per_buf = {}
for name in names:
try:
buf = bufs[str(name.module_path)]
except KeyError:
continue
defs_per_buf.setdefault(buf, []).append(name)
if IS_NVIM:
# We need to remember highlight ids with Neovim's API.
buf_src_ids = {}
for buf, names in defs_per_buf.items():
buf_src_ids[buf] = []
for name in names:
src_id = _add_highlighted_name(buf, name)
buf_src_ids[buf].append(src_id)
for buf, src_ids in buf_src_ids.items():
buf.vars['_jedi_usages_src_ids'] = src_ids
else:
for buf, names in defs_per_buf.items():
try:
for name in names:
_add_highlighted_name(buf, name)
except vim.error as exc:
if exc.args[0].startswith('Vim:E275:'):
# "Cannot add text property to unloaded buffer"
_pending_names.setdefault(buf.name, []).extend(
names)
else:
highlight_usages_for_vim_win()
def _handle_pending_usages_for_buf():
"""Add (pending) highlights for the current buffer (Vim with textprops)."""
buf = vim.current.buffer
bufname = buf.name
try:
buf_names = _pending_names[bufname]
except KeyError:
return
for name in buf_names:
_add_highlighted_name(buf, name)
del _pending_names[bufname]
def _add_highlighted_name(buf, name):
lnum = name.line
start_col = name.column
# Skip highlighting of module definitions that point to the start
# of the file.
if name.type == 'module' and lnum == 1 and start_col == 0:
return
_placed_names_in_buffers.add(buf)
# TODO: validate that name.name is at this position?
# Would skip the module definitions from above already.
length = len(name.name)
if vim_prop_add:
# XXX: needs jediUsage highlight (via after/syntax/python.vim).
global vim_prop_type_added
if not vim_prop_type_added:
vim.eval("prop_type_add('jediUsage', {'highlight': 'jediUsage'})")
vim_prop_type_added = True
vim_prop_add(lnum, start_col+1, {
'type': 'jediUsage',
'bufnr': buf.number,
'length': length,
})
return
assert IS_NVIM
end_col = name.column + length
src_id = buf.add_highlight('jediUsage', lnum-1, start_col, end_col,
src_id=0)
return src_id
def highlight_usages_for_vim_win():
"""Highlight usages in the current window.
It stores the matchids in a window-local variable.
(matchaddpos() only works for the current window.)
"""
win = vim.current.window
cur_matchids = win.vars.get('_jedi_usages_vim_matchids')
if cur_matchids:
if cur_matchids[0] == vim.current.buffer.number:
return
# Need to clear non-matching highlights.
for matchid in cur_matchids[1:]:
expr = 'matchdelete(%d)' % int(matchid)
vim.eval(expr)
matchids = []
if _current_names:
buffer_path = vim.current.buffer.name
for name in _current_names:
if (str(name.module_path) or '') == buffer_path:
positions = [
[name.line,
name.column + 1,
len(name.name)]
]
expr = "matchaddpos('jediUsage', %s)" % repr(positions)
matchids.append(int(vim_eval(expr)))
if matchids:
vim.current.window.vars['_jedi_usages_vim_matchids'] = [
vim.current.buffer.number] + matchids
elif cur_matchids is not None:
# Always set it (uses an empty list for "unset", which is not possible
# using del).
vim.current.window.vars['_jedi_usages_vim_matchids'] = []
# Remember if clearing is needed for later buffer autocommands.
vim.current.buffer.vars['_jedi_usages_needs_clear'] = bool(matchids)
@_check_jedi_availability(show_error=True) @_check_jedi_availability(show_error=True)
@@ -419,19 +757,27 @@ def highlight_usages(definitions, length=None):
def show_documentation(): def show_documentation():
script = get_script() script = get_script()
try: try:
definitions = script.goto_definitions() names = script.help(*get_pos())
except Exception: except Exception:
# print to stdout, will be in :messages # print to stdout, will be in :messages
definitions = [] names = []
print("Exception, this shouldn't happen.") print("Exception, this shouldn't happen.")
print(traceback.format_exc()) print(traceback.format_exc())
if not definitions: if not names:
echo_highlight('No documentation found for that.') echo_highlight('No documentation found for that.')
vim.command('return') vim.command('return')
else: return
docs = ['Docstring for %s\n%s\n%s' % (d.desc_with_module, '=' * 40, d.docstring())
if d.docstring() else '|No Docstring for %s|' % d for d in definitions] docs = []
for n in names:
doc = n.docstring()
if doc:
title = 'Docstring for %s %s' % (n.type, n.full_name or n.name)
underline = '=' * len(title)
docs.append('%s\n%s\n%s' % (title, underline, doc))
else:
docs.append('|No Docstring for %s|' % n)
text = ('\n' + '-' * 79 + '\n').join(docs) text = ('\n' + '-' * 79 + '\n').join(docs)
vim.command('let l:doc = %s' % repr(PythonToVimStr(text))) vim.command('let l:doc = %s' % repr(PythonToVimStr(text)))
vim.command('let l:doc_lines = %s' % len(text.split('\n'))) vim.command('let l:doc_lines = %s' % len(text.split('\n')))
@@ -470,9 +816,12 @@ def show_call_signatures(signatures=()):
if int(vim_eval("has('conceal') && g:jedi#show_call_signatures")) == 0: if int(vim_eval("has('conceal') && g:jedi#show_call_signatures")) == 0:
return return
if signatures == (): # We need to clear the signatures before we calculate them again. The
signatures = get_script().call_signatures() # reason for this is that call signatures are unfortunately written to the
# buffer.
clear_call_signatures() clear_call_signatures()
if signatures == ():
signatures = get_script().get_signatures(*get_pos())
if not signatures: if not signatures:
return return
@@ -695,18 +1044,19 @@ def do_rename(replace, orig=None):
# Sort the whole thing reverse (positions at the end of the line # Sort the whole thing reverse (positions at the end of the line
# must be first, because they move the stuff before the position). # must be first, because they move the stuff before the position).
temp_rename = sorted(temp_rename, reverse=True, temp_rename = sorted(temp_rename, reverse=True,
key=lambda x: (x.module_path, x.line, x.column)) key=lambda x: (str(x.module_path), x.line, x.column))
buffers = set() buffers = set()
for r in temp_rename: for r in temp_rename:
if r.in_builtin_module(): if r.in_builtin_module():
continue continue
if os.path.abspath(vim.current.buffer.name) != r.module_path: module_path = r.module_path
assert r.module_path is not None if os.path.abspath(vim.current.buffer.name) != str(module_path):
result = new_buffer(r.module_path) assert module_path is not None
result = new_buffer(module_path)
if not result: if not result:
echo_highlight('Failed to create buffer window for %s!' % ( echo_highlight('Failed to create buffer window for %s!' % (
r.module_path)) module_path))
continue continue
buffers.add(vim.current.buffer.name) buffers.add(vim.current.buffer.name)
@@ -730,35 +1080,25 @@ def do_rename(replace, orig=None):
@_check_jedi_availability(show_error=True) @_check_jedi_availability(show_error=True)
@catch_and_print_exceptions @catch_and_print_exceptions
def py_import(): def py_import():
# args are the same as for the :edit command
args = shsplit(vim.eval('a:args')) args = shsplit(vim.eval('a:args'))
import_path = args.pop() import_path = args.pop()
text = 'import %s' % import_path name = next(get_project().search(import_path), None)
scr = jedi.Script(text, 1, len(text), '', environment=get_environment()) if name is None:
try: echo_highlight('Cannot find %s in your project or on sys.path!' % import_path)
completion = scr.goto_assignments()[0]
except IndexError:
echo_highlight('Cannot find %s in sys.path!' % import_path)
else: else:
if completion.column is None: # Python modules always have a line number. cmd_args = ' '.join([a.replace(' ', '\\ ') for a in args])
echo_highlight('%s is a builtin module.' % import_path) _goto_specific_name(name, options=cmd_args)
else:
cmd_args = ' '.join([a.replace(' ', '\\ ') for a in args])
new_buffer(completion.module_path, cmd_args)
@catch_and_print_exceptions @catch_and_print_exceptions
def py_import_completions(): def py_import_completions():
argl = vim.eval('a:argl') argl = vim.eval('a:argl')
try: if jedi is None:
import jedi
except ImportError:
print('Pyimport completion requires jedi module: https://github.com/davidhalter/jedi') print('Pyimport completion requires jedi module: https://github.com/davidhalter/jedi')
comps = [] comps = []
else: else:
text = 'import %s' % argl names = get_project().complete_search(argl)
script = jedi.Script(text, 1, len(text), '', environment=get_environment()) comps = [argl + n for n in sorted(set(c.complete for c in names))]
comps = ['%s%s' % (argl, c.complete) for c in script.completions()]
vim.command("return '%s'" % '\n'.join(comps)) vim.command("return '%s'" % '\n'.join(comps))

View File

@@ -2,7 +2,7 @@
import sys import sys
import vim import vim
from jedi_vim import PythonToVimStr from jedi_vim import PythonToVimStr, jedi
def echo(msg): def echo(msg):
@@ -32,7 +32,15 @@ def format_exc_info(exc_info=None, tb_indent=2):
return '{0}'.format(('\n' + indent).join(lines)) return '{0}'.format(('\n' + indent).join(lines))
def get_known_environments():
"""Get known Jedi environments."""
envs = list(jedi.find_virtualenvs())
envs.extend(jedi.find_system_environments())
return envs
def display_debug_info(): def display_debug_info():
echo(' - global sys.executable: `{0}`'.format(sys.executable))
echo(' - global sys.version: `{0}`'.format( echo(' - global sys.version: `{0}`'.format(
', '.join([x.strip() ', '.join([x.strip()
for x in sys.version.split('\n')]))) for x in sys.version.split('\n')])))
@@ -57,7 +65,8 @@ def display_debug_info():
echo(' - version: {0}'.format(jedi_vim.jedi.__version__)) echo(' - version: {0}'.format(jedi_vim.jedi.__version__))
try: try:
environment = jedi_vim.get_environment(use_cache=False) project = jedi_vim.get_project()
environment = project.get_environment()
except AttributeError: except AttributeError:
script_evaluator = jedi_vim.jedi.Script('')._evaluator script_evaluator = jedi_vim.jedi.Script('')._evaluator
try: try:
@@ -80,7 +89,7 @@ def display_debug_info():
if environment: if environment:
echo('\n##### Known environments\n\n') echo('\n##### Known environments\n\n')
for environment in jedi_vim.get_known_environments(): for environment in get_known_environments():
echo(' - {0} ({1})\n'.format( echo(' - {0} ({1})\n'.format(
environment, environment,
environment.executable, environment.executable,

View File

@@ -9,7 +9,7 @@ import zipfile
import pytest import pytest
vspec_version = '1.8.1' vspec_version = '1.9.0'
VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/%s.zip' % vspec_version VSPEC_URL = 'https://github.com/kana/vim-vspec/archive/%s.zip' % vspec_version
root = os.path.dirname(os.path.dirname(__file__)) root = os.path.dirname(os.path.dirname(__file__))
@@ -20,7 +20,7 @@ TEST_DIR = os.path.join(root, 'test', 'vspec')
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def install_vspec(request): def install_vspec():
if not os.path.isdir(CACHE_FOLDER): if not os.path.isdir(CACHE_FOLDER):
os.mkdir(CACHE_FOLDER) os.mkdir(CACHE_FOLDER)

View File

@@ -0,0 +1,29 @@
source plugin/jedi.vim
source test/_utils.vim
describe 'simple:'
before
new
normal! ifoo
end
after
bd!
end
it 'choose'
Expect g:jedi#environment_path == 'auto'
Expect bufname('%') == ''
JediChooseEnvironment
" A Python executable needs to be a few letters
Expect len(getline('.')) > 5
Expect bufname('%') == 'Hit Enter to Choose an Environment'
execute "normal \<CR>"
Expect g:jedi#environment_path != 'auto'
bd " TODO why is this necessary? There seems to be a random buffer.
Expect bufname('%') == ''
Expect getline('.') == 'foo'
end
end

View File

@@ -15,7 +15,10 @@ describe 'documentation docstrings'
normal GK normal GK
Expect bufname('%') == "__doc__" Expect bufname('%') == "__doc__"
Expect &filetype == 'rst' Expect &filetype == 'rst'
let content = join(getline(1,'$'), "\n") let header = getline(1, 2)
Expect header[0] == "Docstring for class builtins.ImportError"
Expect header[1] == "========================================"
let content = join(getline(3, '$'), "\n")
Expect stridx(content, "Import can't find module") > 0 Expect stridx(content, "Import can't find module") > 0
normal K normal K
Expect bufname('%') == '' Expect bufname('%') == ''

View File

@@ -73,27 +73,6 @@ describe 'goto with tabs:'
Expect tabpagenr('$') == 1 Expect tabpagenr('$') == 1
Expect bufname('%') == '' Expect bufname('%') == ''
end end
" it 'multi definitions'
" " This used to behave differently. Now we don't have any real multi
" " definitions.
"
" " put = ['import tokenize']
" " normal G$\d
" " Expect CurrentBufferIsModule('tokenize') == 1
" " Expect CurrentBufferIsModule('token') == 0
" " execute "normal \<CR>"
" " Expect tabpagenr('$') == 2
" " Expect winnr('$') == 1
" " Expect CurrentBufferIsModule('token') == 1
"
" " bd
" " normal G$\d
" " execute "normal j\<CR>"
" " Expect tabpagenr('$') == 2
" " Expect winnr('$') == 1
" " Expect CurrentBufferIsModule('tokenize') == 1
" end
end end
@@ -112,7 +91,7 @@ describe 'goto with buffers'
put = ['import os'] put = ['import os']
normal G$ normal G$
call jedi#goto_assignments() call jedi#goto_assignments()
PythonJedi jedi_vim.goto() python3 jedi_vim.goto()
Expect CurrentBufferIsModule('os') == 0 Expect CurrentBufferIsModule('os') == 0
" Without hidden, it's not possible to open a new buffer, when the old " Without hidden, it's not possible to open a new buffer, when the old
" one is not saved. " one is not saved.
@@ -124,25 +103,6 @@ describe 'goto with buffers'
Expect line('.') == 1 Expect line('.') == 1
Expect col('.') == 1 Expect col('.') == 1
end end
" it 'multi definitions'
" " set hidden
" " put = ['import tokenize']
" " normal G$\d
" " Expect CurrentBufferIsModule('tokenize') == 0
" " Expect CurrentBufferIsModule('token') == 0
" " execute "normal \<CR>"
" " Expect tabpagenr('$') == 1
" " Expect winnr('$') == 1
" " Expect CurrentBufferIsModule('token') == 1
"
" " bd
" " normal G$\d
" " execute "normal j\<CR>"
" " Expect tabpagenr('$') == 1
" " Expect winnr('$') == 1
" " Expect CurrentBufferIsModule('tokenize') == 1
" end
end end

View File

@@ -0,0 +1,13 @@
source plugin/jedi.vim
describe 'JediDebugInfo'
it 'works'
redir @a | JediDebugInfo | redir END
let output = split(@a, '\n')
Expect output[0] == 'You should run this in a buffer with filetype "python".'
Expect output[1] == '#### Jedi-vim debug information'
Expect output[-1] == '</details>'
end
end
" vim: et:ts=4:sw=4

View File

@@ -4,10 +4,12 @@ source test/_utils.vim
describe 'pyimport' describe 'pyimport'
before before
let g:jedi#use_tabs_not_buffers = 1 let g:jedi#use_tabs_not_buffers = 1
let g:jedi#project_path = 'autoload'
end end
after after
try | %bwipeout! | catch | endtry try | %bwipeout! | catch | endtry
unlet g:jedi#project_path
end end
it 'open_tab' it 'open_tab'
@@ -26,10 +28,7 @@ describe 'pyimport'
Expect jedi#py_import_completions('subproc', 0, 0) == 'subprocess' Expect jedi#py_import_completions('subproc', 0, 0) == 'subprocess'
Expect jedi#py_import_completions('subprocess', 0, 0) == 'subprocess' Expect jedi#py_import_completions('subprocess', 0, 0) == 'subprocess'
let g:comp = jedi#py_import_completions('zip', 0, 0) let g:comp = jedi#py_import_completions('sre_', 0, 0)
" Sometimes zipapp is in there sometimes not, depends on Python Expect g:comp == "sre_compile\nsre_constants\nsre_parse"
" version.
let g:comp = substitute(g:comp, '^zipapp\n', '', '')
Expect g:comp == "zipfile\nzipimport"
end end
end end

View File

@@ -41,12 +41,29 @@ describe 'signatures'
doautocmd CursorHoldI doautocmd CursorHoldI
noautocmd normal istaticmethod() noautocmd normal istaticmethod()
doautocmd CursorHoldI doautocmd CursorHoldI
Expect getline(1) == '?!?jedi=0, ?!? (*_*f: Callable*_*) ?!?jedi?!?' Expect getline(1) == '?!?jedi=0, ?!? (*_*f: Callable[..., Any]*_*) ?!?jedi?!?'
end
it 'highlights correct argument'
noautocmd normal o
doautocmd CursorHoldI
noautocmd normal iprint(42, sep="X", )
" Move to "=" - hightlights "sep=...".
noautocmd normal 5h
doautocmd CursorHoldI
Expect getline(1) =~# '\V\^?!?jedi=0, ?!? (*values: object, *_*sep: Optional[Text]=...*_*'
" Move left to "=" - hightlights first argument ("values").
" NOTE: it is arguable that maybe "sep=..." should be highlighted
" still, but this tests for the cache to be "busted", and that
" fresh results are retrieved from Jedi.
noautocmd normal h
doautocmd CursorHoldI
Expect getline(1) =~# '\V\^?!?jedi=0, ?!? (*_**values: object*_*, sep: Optional[Text]=...,'
end end
it 'no signature' it 'no signature'
exe 'normal ostr ' exe 'normal ostr '
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
Expect getline(1, '$') == ['', 'str '] Expect getline(1, '$') == ['', 'str ']
end end
@@ -54,7 +71,7 @@ describe 'signatures'
let g:jedi#show_call_signatures = 0 let g:jedi#show_call_signatures = 0
exe 'normal ostr( ' exe 'normal ostr( '
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
Expect getline(1, '$') == ['', 'str( '] Expect getline(1, '$') == ['', 'str( ']
let g:jedi#show_call_signatures = 1 let g:jedi#show_call_signatures = 1
@@ -66,9 +83,9 @@ describe 'signatures'
exe 'normal ostaticmethod( ' exe 'normal ostaticmethod( '
redir => msg redir => msg
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
redir END redir END
Expect msg == "\nstaticmethod(f: Callable)" Expect msg == "\nstaticmethod(f: Callable[..., Any])"
redir => msg redir => msg
doautocmd InsertLeave doautocmd InsertLeave
@@ -78,7 +95,7 @@ describe 'signatures'
normal Sdef foo(a, b): pass normal Sdef foo(a, b): pass
exe 'normal ofoo(a, b, c, ' exe 'normal ofoo(a, b, c, '
redir => msg redir => msg
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
redir END redir END
Expect msg == "\nfoo(a, b)" Expect msg == "\nfoo(a, b)"
end end
@@ -89,7 +106,7 @@ describe 'signatures'
function! Signature() function! Signature()
redir => msg redir => msg
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
redir END redir END
return msg return msg
endfunction endfunction
@@ -122,7 +139,7 @@ describe 'signatures'
exe 'normal ostr ' exe 'normal ostr '
redir => msg redir => msg
Python jedi_vim.show_call_signatures() python3 jedi_vim.show_call_signatures()
redir END redir END
Expect msg == "\n" Expect msg == "\n"
end end