Skip to main content

A language server for Jedi!

Project description

Jedi Language Server

image-version image-license image-python-versions image-pypi-downloads github-action-testing poetry

A Python Language Server powered by the latest version of Jedi.

Installation

Some frameworks, like coc-jedi and vscode-python, will install and manage jedi-language-server for you. If you're setting up manually, you can run the following from your command line (bash / zsh):

pip install -U jedi-language-server

Alternatively (and preferably), use pipx to keep jedi-language-server and its dependencies isolated from your other Python dependencies. Don't worry, jedi is smart enough to figure out which Virtual environment you're currently using!

Editor Setup

The following instructions show how to use jedi-language-server with your development tooling. The instructions assume you have already installed jedi-language-server.

Vim / Neovim

Users may choose 1 of the following options:

Note: this list is non-exhaustive. If you know of a great choice not included in this list, please submit a PR!

Emacs

Users may choose one of the following options:

Note: this list is non-exhaustive. If you know of a great choice not included in this list, please submit a PR!

Visual Studio Code (vscode)

Starting from the October 2021 release, set the python.languageServer setting to Jedi to use jedi-language-server.

See: https://github.com/pappasam/jedi-language-server/issues/50#issuecomment-781101169

Configuration

jedi-language-server supports the following initializationOptions:

{
  "initializationOptions": {
    "codeAction": {
      "nameExtractVariable": "jls_extract_var",
      "nameExtractFunction": "jls_extract_def"
    },
    "completion": {
      "disableSnippets": false,
      "resolveEagerly": false,
      "ignorePatterns": []
    },
    "diagnostics": {
      "enable": false,
      "didOpen": true,
      "didChange": true,
      "didSave": true
    },
    "hover": {
      "enable": true,
      "disable": {
        "class": { "all": false, "names": [], "fullNames": [] },
        "function": { "all": false, "names": [], "fullNames": [] },
        "instance": { "all": false, "names": [], "fullNames": [] },
        "keyword": { "all": false, "names": [], "fullNames": [] },
        "module": { "all": false, "names": [], "fullNames": [] },
        "param": { "all": false, "names": [], "fullNames": [] },
        "path": { "all": false, "names": [], "fullNames": [] },
        "property": { "all": false, "names": [], "fullNames": [] },
        "statement": { "all": false, "names": [], "fullNames": [] }
      }
    },
    "jediSettings": {
      "autoImportModules": [],
      "caseInsensitiveCompletion": true,
      "debug": false
    },
    "markupKindPreferred": "markdown",
    "workspace": {
      "extraPaths": [],
      "environmentPath": "/path/to/venv/bin/python",
      "symbols": {
        "ignoreFolders": [".nox", ".tox", ".venv", "__pycache__", "venv"],
        "maxSymbols": 20
      }
    }
  }
}

The different sections of the InitializationOptions are explained below, in detail. Section headers use a . to separate nested JSON-object keys.

markupKindPreferred

The preferred MarkupKind for all jedi-language-server messages that take MarkupContent.

  • type: string
  • accepted values: "markdown", "plaintext"

If omitted, jedi-language-server defaults to the client-preferred configuration. If there is no client-preferred configuration, jedi language server users "plaintext".

jediSettings.autoImportModules

Modules that jedi will directly import without analyzing. Improves autocompletion but loses goto definition.

  • type: string[]
  • default: []

If you're noticing that modules like numpy and pandas are taking a super long time to load, and you value completions / signatures over goto definition, I recommend using this option like this:

{
  "jediSettings": {
    "autoImportModules": ["numpy", "pandas"]
  }
}

jediSettings.caseInsensitiveCompletion

Completions are by default case-insensitive. Set to false to make completions case-sensitive.

  • type: boolean
  • default: true
{
  "jediSettings": {
    "caseInsensitiveCompletion": false
  }
}

jediSettings.debug

Print jedi debugging messages to stderr.

  • type: boolean
  • default: false
{
  "jediSettings": {
    "debug": false
  }
}

codeAction.nameExtractFunction

Function name generated by the 'extract_function' codeAction.

  • type: string
  • default: "jls_extract_def"

codeAction.nameExtractVariable

Variable name generated by the 'extract_variable' codeAction.

  • type: string
  • default: "jls_extract_var"

completion.disableSnippets

If your language client supports CompletionItem snippets but you don't like them, disable them by setting this option to true.

  • type: boolean
  • default: false

completion.resolveEagerly

Return all completion results in initial completion request. Set to true if your language client does not support completionItem/resolve.

  • type: boolean
  • default: false

completion.ignorePatterns

A list of regular expressions. If any regular expression in ignorePatterns matches a completion's name, that completion item is not returned to the client.

  • type: string[]
  • default: []

In general, you should prefer the default value for this option. Jedi is very good at filtering values for end users. That said, there are situations where IDE developers, or some programmers in some code bases, may want to filter some completions by name. This flexible interface is provided to accommodate these advanced use cases. If you have one of these advanced use cases, see below for some example patterns (and their corresponding regular expression).

All Private Names

Matches Non-Matches
_hello, __world __dunder__

Regular Expression:

^_{1,3}$|^_[^_].*$|^__.*(?<!__)$

Only private mangled names

Matches Non-Matches
__world _hello, __dunder__

Regular Expression:

^_{2,3}$|^__.*(?<!__)$

Only dunder names

Matches Non-Matches
__dunder__ _hello, __world

Regular Expression:

^__.*?__$

All names beginning with underscore

Matches Non-Matches
_hello, __world, __dunder__ regular

Regular Expression:

^_.*$

diagnostics.enable

Enables (or disables) diagnostics provided by Jedi.

  • type: boolean
  • default: true

diagnostics.didOpen

When diagnostics are enabled, run on document open

  • type: boolean
  • default: true

diagnostics.didChange

When diagnostics are enabled, run on in-memory document change (eg, while you're editing, without needing to save to disk)

  • type: boolean
  • default: true

diagnostics.didSave

When diagnostics are enabled, run on document save (to disk)

  • type: boolean
  • default: true

hover.enable

Enable (or disable) all hover text. If set to false, will cause the hover method not to be registered to the language server.

  • type: boolean
  • default: true

hover.disable.*

The following options are available under this prefix:

  • hover.disable.class.all
  • hover.disable.class.names
  • hover.disable.class.fullNames
  • hover.disable.function.all
  • hover.disable.function.names
  • hover.disable.function.fullNames
  • hover.disable.instance.all
  • hover.disable.instance.names
  • hover.disable.instance.fullNames
  • hover.disable.keyword.all
  • hover.disable.keyword.names
  • hover.disable.keyword.fullNames
  • hover.disable.module.all
  • hover.disable.module.names
  • hover.disable.module.fullNames
  • hover.disable.param.all
  • hover.disable.param.names
  • hover.disable.param.fullNames
  • hover.disable.path.all
  • hover.disable.path.names
  • hover.disable.path.fullNames
  • hover.disable.property.all
  • hover.disable.property.names
  • hover.disable.property.fullNames
  • hover.disable.statement.all
  • hover.disable.statement.names
  • hover.disable.statement.fullNames

hover.disable.[jedi-type].all

Disable all hover text of jedi-type specified.

  • type: bool
  • default: false

hover.disable.[jedi-type].names

Disable hover text identified by name in list of jedi-type specified.

  • type: string[]
  • default: []

hover.disable.[jedi-type].fullNames

Disable hover text identified by the fully qualified name in list of jedi-type specified. If no fully qualified name can be found, jedi-language-server will default to the name to prevent any unexpected behavior for users (relevant for jedi types like keywords that don't have full names).

  • type: string[]
  • default: []

workspace.extraPaths

Add additional paths for Jedi's analysis. Useful with vendor directories, packages in a non-standard location, etc. You probably won't need to use this, but you'll be happy it's here when you need it!

  • type: string[]
  • default: []

Non-absolute paths are relative to your project root. For example, let's say your Python project is structured like this:

├── funky
│   └── haha.py
├── poetry.lock
├── pyproject.toml
├── test.py

Assume that funky/haha.py contains 1 line, x = 12, and your build system does some wizardry that makes haha importable just like os or pathlib. In this example, if you want to have this same non-standard behavior with jedi-language-server, put the following in your coc-settings.json:

{
  "workspace": {
    "extraPaths": ["funky"]
  }
}

When editing test.py, you'll get completions, goto definition, and all other lsp features for the line from haha import ....

Again, you probably don't need this.

workspace.environmentPath

The Python executable path, typically the path of a virtual environment.

  • type: string

If omitted, defaults to the active Python environment.

workspace.symbols.maxSymbols

Maximum number of symbols returned by a call to workspace/symbols.

  • type: number
  • default: 20
{
  "workspace": {
    "symbols": {
      "maxSymbols": 20
    }
  }
}

A value less than or equal to zero removes the maximum and allows jedi-language-server to return all workplace symbols found by jedi.

workspace.symbols.ignoreFolders

Performance optimization that sets names of folders that are ignored for workspace/symbols.

  • type: string[]
  • default: [".nox", ".tox", ".venv", "__pycache__", "venv"]
{
  "workspace": {
    "symbols": {
      "ignoreFolders": ["hello", "world"]
    }
  }
}

If you manually set this option, it overrides the default. Setting it to an empty array will result in no ignored folders.

Diagnostics

Diagnostics are provided by Python's built-in compile function.

If you would like additional diagnostics, we recommend using other tools (like diagnostic-language-server) to complement jedi-language-server.

Code Formatting

Again, we recommend that you use diagnostic-language-server. It also supports code formatting.

Command line usage

jedi-language-server can be run directly from the command line.

$ jedi-language-server --help
usage: jedi-language-server [-h] [--version] [--tcp] [--ws] [--host HOST] [--port PORT] [--log-file LOG_FILE] [-v]

If testing sending requests over stdio manually from the command line, you must include Windows-style line endings: \r\n. For an example, from within this project, run the following:

$ jedi-language-server < ./example-initialization-request.txt
INFO:pygls.server:Starting IO server
...

If testing interactively, be sure to manually insert carriage returns. Although this may differ between shell environments, within most bash terminals, you can explicitly insert the required line endings by typing <C-v><C-m>, which will insert a ^M. See:

$ jedi-language-server 2>logs
Content-Length: 1062^M
^M
...

Technical capabilities

jedi-language-server aims to support Jedi's capabilities and expose them through the Language Server Protocol. It supports the following Language Server capabilities:

Language Features

Text Synchronization (for diagnostics)

Local Development

To build and run this project from source:

Dependencies

Install the following tools manually:

Recommended

Get source code

Fork this repository and clone the fork to your development machine:

git clone https://github.com/<YOUR-USERNAME>/jedi-language-server
cd jedi-language-server

Set up development environment

make setup

Automatically format files

make fix

Run tests

make lint
make typecheck
make tests

Inspiration

Palantir's python-language-server inspired this project. In fact, for consistency's sake, many of python-language-server's CLI options are used as-is in jedi-language-server.

Unlike python-language-server, jedi-language-server:

  • Uses pygls instead of creating its own low-level Language Server Protocol bindings
  • Supports one powerful 3rd party static analysis / completion / refactoring library: Jedi. By only supporting Jedi, we can focus on supporting all Jedi features without exposing ourselves to too many broken 3rd party dependencies (I'm looking at you, rope).
  • Is supremely simple because of its scope constraints. Leave complexity to the Jedi master. If the force is strong with you, please submit a PR!

Articles

Written by

Samuel Roeca

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jedi_language_server-0.41.3.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jedi_language_server-0.41.3-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file jedi_language_server-0.41.3.tar.gz.

File metadata

  • Download URL: jedi_language_server-0.41.3.tar.gz
  • Upload date:
  • Size: 29.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.0 CPython/3.11.8 Linux/5.15.0-1056-azure

File hashes

Hashes for jedi_language_server-0.41.3.tar.gz
Algorithm Hash digest
SHA256 113ec22b95fadaceefbb704b5f365384bed296b82ede59026be375ecc97a9f8a
MD5 f186d39e2ffb5a31159c3041476dc3f4
BLAKE2b-256 f3344a35094c680040c8dd598b1ee9153a701289351c1dcbad1a0f2d196c524b

See more details on using hashes here.

File details

Details for the file jedi_language_server-0.41.3-py3-none-any.whl.

File metadata

File hashes

Hashes for jedi_language_server-0.41.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7411f7479cdc9e9ea495f91e20b182a5d00170c0a8a4a87d3a147462282c06af
MD5 7fa0f262ac87b5e9c3cfc9fa9d8bbeb2
BLAKE2b-256 b6672cf4419a8c418b0e5cba0b43dc1ea33a0bb42907694d6a786a3644889f32

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page