GithubHelp home page GithubHelp logo

ruff-lsp's People

Contributors

aspizu avatar ayoubelmhamdi avatar bluetech avatar charliermarsh avatar dependabot[bot] avatar dhruvmanila avatar diegorodriguezv avatar fannheyward avatar figsoda avatar francescelies avatar harupy avatar igorlfs avatar konstin avatar ldap avatar luccahuguet avatar markis avatar michareiser avatar mrgreentea avatar mrkazzila avatar patillacode avatar pedramnavid avatar polyzen avatar pushupek avatar rchl avatar rockerboo avatar sauravmaheshkar avatar venhance avatar whynothugo avatar yaegassy avatar zanieb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruff-lsp's Issues

codeAction does not work in Helix editor

codeAction does not work in Helix editor.

image

I can select actions but do nothing. I'm searching now but do you have any idea?

I check the output (actions) of here,, the actions returned correctlly.

INFO:exampleLogger:[CodeAction(title='Ruff: Organize Imports', kind=<CodeActionKind.SourceOrganizeImports: 'source.organizeImports'>, diagnostics=[], is_preferred=None, disabled=None, edit=None, command=None, data='file:///home/akira/akira/oss/ruff-lsp/ruff_lsp/complete.py'), CodeAction(title='Ruff: Fix All', kind='source.fixAll.ruff', diagnostics=[], is_preferred=None, disabled=None, edit=None, command=None, data='file:///home/akira/akira/oss/ruff-lsp/ruff_lsp/complete.py')]

No code actions available when hovered over certain warnings

When hovering over certain warnings, like F401, no code actions are available. This seems to be unintended as the first example gif in the readme (https://github.com/charliermarsh/ruff-lsp#quick-fix-actions-for-auto-fixable-violations-like-unused-imports) shows available code actions when hovering F401.

Environment: neovim 0.9.0, ruff-lsp 0.0.24

Steps to reproduce:

  1. Open a python file
  2. Scroll over or write in an unused import to create a F401 warning.
  3. Try to call code actions :lua =vim.lsp.buf.code_action()

screenshot

Another diagnostic code that causes this issue is F821(undefined name). Per #91 (comment) this may affect quite a few more types of warnings.

Crashes at startup

ruff-lsp has been crashing at startup for a few days for me. I though it might be an issue with my neovim setup, but apparently it's something else:

> ruff-lsp --version
Traceback (most recent call last):
  File "/usr/bin/ruff-lsp", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/lib/python3.11/site-packages/ruff_lsp/__main__.py", line 5, in main
    from ruff_lsp import __version__, server
  File "/usr/lib/python3.11/site-packages/ruff_lsp/server.py", line 325, in <module>
    @LSP_SERVER.feature(
     ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pygls/feature_manager.py", line 174, in decorator
    raise TypeError(
TypeError: Options of method "textDocument/codeAction" should be instance of type <class 'lsprotocol.types.CodeActionOptions'>

Versions:

> apk list --installed | grep ruff
ruff-0.0.261-r0 x86_64 {ruff} (MIT) [installed]
ruff-lsp-0.0.24-r0 x86_64 {ruff-lsp} (MIT) [installed]
ruff-zsh-completion-0.0.261-r0 x86_64 {ruff} (MIT) [installed]

> apk list --installed | grep py3-gls
py3-gls-1.0.1-r0 x86_64 {py3-gls} (Apache-2.0) [installed]


> python --version
Python 3.11.3

Investigate range formatting

Figure out and document which capabilities to use for range formatting and what kind of offsets we get from VS Code and other LSP clients. Make a plan how to pass those to ruff

feat: Use sphinx-like documentation for hover

Given this simple type

class Human:
    #: This is the person's name.
    name: str

And this code:

h = human
h.name

When fetching the "hover" information (e.g.: textDocument/hover, vim.lsp.buf.hover() on neovim) with the cursor on name this shows the documentation for the type (e.g.: str) in this case.

I think that it would be very useful to show the documentation right above the field, instead of the documentation for type type. This particular format is used by sphinx, so a lot of code-bases (e.g.: Django) use this to document fields. In many contexts, the docs for the field are far more relevant/useful that the docs for the type (especially so when the type is something like int or str).

Is there a way to combine ruff and pyright?

I'm using helix, and I'd be interested in having both ruff and pyright in the editor as they seem complementary. For example, pyright catches missing dependencies, which ruff does not seem to do.

Has someone figured out how to use both in helix?

LSP always indicates possible actions, even if they are no-op

Problem description

My editor setup shows an indicator when there are code actions available for the current line.

This works well on most languages, but ruff always shows available actions: Organize Imports and Fix All. Even if they are both no-op.

This kind of negates the value of code actions entirely, because instead of being able to tell at a glace if any are possible, the answer is always yes (though generally, they're no-op actions).

Possible solution

Only show code-actions available if any are really available. E.g.: if any imports can be sorted or if there's actually anything to fix.

[Feature request] "Fix all $RULE" code action

This would probably require an additional option for ruff itself, but it'd be very cool to be able to apply fixes of a particular rule all at once, while being able to weed through the others. A typical example could be UP007 -- there could be dozens in a single file and it's rather tedious to apply fixes for each separate case e.g. when upgrading from Python 3.8 to 3.11. Would be nice to have "Fix all", "Fix UP007" and "Fix all UP007 in file" to choose from.

Selectively disable language server features

I tried using ruff-lsp in neovim as a flake8 replacement-- basically I just wanted the faster diagnostics. I use the jedi language server for features like format and hover. However, since I can't selectively disable "hover" for ruff, when I initiate a "hover" on a symbol, jedi pops up the correct info, but ruff prints a "No information available" at the bottom of the screen.

The jedi language server lets you selectively disable various LSP features, which makes it easier to mix and match with other language servers for the same language.

I also tried using ruff with null-ls for diagnostics, but that didn't seem to actually do anything.

GoTo Definition (etc.) support

Hey,
I love the project and would like to eventually switch to ruff-lsp for my daily use. To do that, I'd like to contribute more functionality to the LSP, such as GoToDefinition, hover functionality etc.
It would be cool to have some kind of roadmap for the planned features for the LSP.

Passing --config parameter to Ruff-lsp in Coc-ruff

This may be not an issue but rather my lack of experience using Ruff. However, I have been unable to trace what is the current way to fix it.

I have a Ruff config file at ~/.config/ruff.toml, which I want to use when ruff-lsp verifies the code inside NeoVim (using CoC).
The only (most complete) snippet I found in issue #11 is the following:

"languageserver": {
  {
    "ruff-lsp": {
      "command": "ruff-lsp",
      "filetypes": ["python"],
      "initializationOptions": {
        "settings": {
          "path": ["~/proj/check-ruff-lsp/venv/bin/ruff"]
        }
      }
    },
  }
}

I have tried, without success, to add a parameter under settings like "config": "~/.config/ruff.toml", or inside a possible "args: []" parameter.

Is there a way to actually pass the config command to Ruff?

`LSP_SERVER.workspace` is `None` when `initializationOptions` are set

This is a weird one, it's more a cry for help than a definitive issue in ruff-lsp. Might be connected to #42, but that's a conjecture at best.

So I'm trying to get my LSP configuration to do what it's supposed to do (Emacs 28.2 + lsp-mode). There seems to be a problem with initializationOptions, so I try both with and without them:

Trial 1: without initializationOptions. Initialization message seems to be alright:

{
  "processId": null,
  "rootPath": "/home/user/project",
  "clientInfo": {
      ...
  },
  "rootUri": "file:///home/user/project",
  "capabilities": {
      ...
  },
  "initializationOptions": null,
  "workDoneToken": "1"
}

The language server starts normally and successfully tries to call ruff on file change (but fails in my case, since it's trying to call /usr/bin/ruff, which is not installed).

Trial 2: with initializationOptions to set both Python binary and ruff binary. Initialization message only differs in those parameters (I sincerely hope the format of interpreter and path is correct):

{
  "processId": null,
  "rootPath": "/home/user/project",
  "clientInfo": {
      ...
  },
  "rootUri": "file:///home/user/project",
  "capabilities": {
      ...
  },
  "initializationOptions": {
    "interpreter": [
      "~/project/.venv/bin/python3"
    ],
    "path": [
      "~/project/.venv/bin/ruff"
    ],
    "logLevel": "debug"
  },
  "workDoneToken": "1"
}

In this case, the language server starts, but fails to call ruff with the following error message:

Failed to handle notification "textDocument/didSave": DidSaveTextDocumentParams(text_document=TextDocumentIdentifier(uri='file:///home/user/project/module/file.py'), text='[snip]')
Traceback (most recent call last):
  File "/home/user/.local/lib/python3.8/site-packages/pygls/protocol.py", line 316, in _handle_notification
    self._execute_notification(handler, params)
  File "/home/user/.local/lib/python3.8/site-packages/pygls/protocol.py", line 228, in _execute_notification
    handler(*params)
  File "/home/user/.local/lib/python3.8/site-packages/ruff_lsp/server.py", line 90, in did_save
    document = LSP_SERVER.workspace.get_document(params.text_document.uri)
AttributeError: 'NoneType' object has no attribute 'get_document'

I'm massively confused at to why this happens. The source code for pygls tells me that setting up a workspace can only fail if root_path/rootPath is not set, but it's set in both cases and should have failed in trial 1 if it fails in trial 2. There is also a peculiar case of pygls somehow transparently converting snake-case to camel-case and vice-versa, but I have to assume it's working somehow.

I honestly don't see a fault in ruff-lsp's handling, but something is happening between ruff-lsp and pygls, which is possibly triggered by my configuration. I just can't see where the problem is happening and what it is.

Respect `workspace/didChangeConfiguration` events

Right now, we only support initializationOptions. But see these notes from nvim-lspconfig:

Additionally, the following options are often added:

* `init_options`: a table sent during initialization, corresponding to initializationOptions sent in [initializeParams](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#initializeParams) as part of the first request sent from client to server during startup.
* `settings`: a table sent during [`workspace/didChangeConfiguration`](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#didChangeConfigurationParams) shortly after server initialization. This is an undocumented convention for most language servers. There is often some duplication with initOptions.

Support specifying default options through server settings

(Note that I haven't yet played with overriding settings so things I write below might be inaccurate. I did look through documentation though.)

I think it would make sense to be able to tell the server to use certain defaults (like line width 120) but still allow the project-specific overrides win. I believe that if one now specifies default line width through initializationOptions.settings.args then that will win over any other settings.

I saw in the documentation that it's possible to specify default settings in a file within home directory and that's fine but I would still prefer to specify defaults through LSP settings instead to keep everything contained within the server configuration.

I wonder what do you think about this.

ruff-lsp errors out in nvim

I'm trying to setup ruff-lsp with neovim. When opening a python file in nvim I get the following message:
Client 2 quit with exit code 1 and signal 0

LspLogs:

[START][2023-01-30 17:08:29] LSP logging initiated
[ERROR][2023-01-30 17:08:29] .../vim/lsp/rpc.lua:734	"rpc"	"ruff-lsp"	"stderr"
'Traceback (most recent call last):
  File "/Users/balsa/.pyenv/versions/3.10.8/bin/ruff-lsp", line 8, in <module'
[ERROR][2023-01-30 17:08:29] .../vim/lsp/rpc.lua:734	"rpc"	"ruff-lsp"	"stderr"	
"    sys.exit(main())
File "/Users/balsa/.pyenv/versions/3.10.8/lib/python3.10/site-packages/ruff_lsp/__main__.py", line 5, in main
        from ruff_lsp import __version__, server
File "/Users/balsa/.pyenv/versions/3.10.8/lib/python3.10/site-packages/ruff_lsp/server.py", line 51, in <module>
        from pygls import protocol, server, uris, workspace
File "/Users/balsa/.pyenv/versions/3.10.8/lib/python3.10/site-packages/pygls/protocol.py", line 33, in <module>
        from cattrs.errors import ClassValidationError\nImportError: cannot import name 'ClassValidationError' from 'cattrs.errors'
(/Users/balsa/.pyenv/versions/3.10.8/lib/python3.10/site-packages/cattrs/errors.py)"

Versions of all related packages:

ruff                       0.0.237
ruff-lsp                   0.0.16
cattrs                     1.10.0
pygls                      1.0.0

Another possible cause is my neovim config. I used lsp-zero to configure the LSP. Here is the ruff-lsp setup code:

require'lspconfig'.ruff_lsp.setup{
  init_options = {
    settings = {
      args = { },
    }
  }
}

I've reached out to @tombh to check if this is something pygls, and he suggested to open an issue here to kick off the discussion.

[Feature] Add endpoints specifically for Organize Imports and Fix All

Right now, Organize Imports and Fix All code actions fill the code actions list anywhere in any python code. There are settings to disable these code actions (it seems, I'm new to this LSP). I would like to disable the code actions and make each of these separate commands that could be run.

For example, in typescript-language-server has workspace/executeCommand which allows you to run these specific actions. This allows the functionality of these good code actions, but done separately of the code actions list.

Thanks for this LSP and the great ruff linter.

"interpreter" or "path" in LSP.sublime-settings?

My main OS is Manjaro, which is running right now Python 3.10.9 as its system Python version. And I'm using Sublime Text 4 (4143).
I try to leave the system python untouched and run pyenv and/or venv for my different projects. I installed for example ruff-lsp on a Python version 3.8.16, which was installed via pyenv.

When I start Sublime I get an error saying The ruff-lsp server has crashed 5 times in the last 180 seconds
The console shows:

LSP: enabled configs: ruff-lsp
LSP: disabled configs: clangd, erlang-ls, gopls, ocaml, polymer-ide, ruby, rust-analyzer, sorbet
LSP: starting ['ruff-lsp'] in /opt/sublime_text
LSP: ruff-lsp crashed (1 / 5 times in the last 180.0 seconds), exit code 127, exception: None
LSP: starting ['ruff-lsp'] in /opt/sublime_text
LSP: ruff-lsp crashed (2 / 5 times in the last 180.0 seconds), exit code 127, exception: None
LSP: starting ['ruff-lsp'] in /opt/sublime_text
LSP: ruff-lsp crashed (3 / 5 times in the last 180.0 seconds), exit code 127, exception: None
LSP: starting ['ruff-lsp'] in /opt/sublime_text
LSP: ruff-lsp crashed (4 / 5 times in the last 180.0 seconds), exit code 127, exception: None
LSP: starting ['ruff-lsp'] in /opt/sublime_text
LSP: ruff-lsp crashed (5 / 5 times in the last 180.0 seconds), exit code 127, exception: None

So, LSP is not finding ruff-lsp, right? Under the LSP settings I specify now the path of the Python version that has ruff-lsp and the path of the ruff binary:

{
  "log_debug": true,
  "clients": {
    "ruff-lsp": {
      "command": ["ruff-lsp"],
      "enabled": true,
      "selector": "source.python",
      "initializationOptions": {
        "settings": {
          "path": ["/home/myuser/.pyenv/versions/3.8.16/bin/ruff"],
          "interpreter": ["/home/myuser/.pyenv/versions/3.8.16/bin/python"],
          "organizeImports": true,
          "fixAll": true,
        }
      }
    }
  }
}

I still get the same error. Are the "interpreter" and "path" settings not working as intended? My solution has been running Sublime with a PYENV_VERSION=3.8.16 environment variable. This way Sublime runs in an environment where the default version of python is the one where I installed ruff-lsp.

I consider this a workaround, I would prefer to point to the correct Python version via the "interpreter" and "path" settings in the LSP.sublime-settings.

Any hints why "interpreter" and "path" are not working for me?
Thanks in advance!

edit: instead of dealing with "interpreter" and "path", I just used ruff-lsp's full path under "command" and it worked:

{
  "log_debug": true,
  "clients": {
    "ruff-lsp": {
      "command": ["/home/myuser/.pyenv/versions/3.8.16/bin/ruff-lsp"],
      "enabled": true,
      "selector": "source.python",
      "initializationOptions": {
        "settings": {
          // "path": ["/home/myuser/.pyenv/versions/3.8.16/bin/ruff"],
          // "interpreter": ["/home/myuser/.pyenv/versions/3.8.16/bin/python"],
          "organizeImports": true,
          "fixAll": true,
        }
      }
    }
  }
}

Fails to install on Termux

โฏ pip install --user ruff-lsp
Collecting ruff-lsp
Using cached ruff_lsp-0.0.27-py3-none-any.whl (11 kB)
Collecting lsprotocol>=2023.0.0a1 (from ruff-lsp)
Using cached lsprotocol-2023.0.0a1-py3-none-any.whl (69 kB)
Collecting pygls>=1.0.1 (from ruff-lsp)
Using cached pygls-1.0.1-py3-none-any.whl (40 kB)
Collecting ruff>=0.0.267 (from ruff-lsp)
Using cached ruff-0.0.267.tar.gz (1.1 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... error
error: subprocess-exited-with-error

ร— Preparing metadata (pyproject.toml) did not run successfully.
โ”‚ exit code: 1
โ•ฐโ”€> [22 lines of output]
error: failed to get ruff as a dependency of package ruff_cli v0.0.267 (/data/data/com.termux/files/usr/tmp/pip-install-3b_k6s5l/ruff_47f73d9b13cc46e2b1aa33cd8a95cf41/crates/ruff_cli)

  Caused by:
    failed to load source for dependency `ruff`

  Caused by:
    Unable to update /data/data/com.termux/files/usr/tmp/pip-install-3b_k6s5l/ruff_47f73d9b13cc46e2b1aa33cd8a95cf41/local_dependencies/ruff

  Caused by:
    failed to parse manifest at `/data/data/com.termux/files/usr/tmp/pip-install-3b_k6s5l/ruff_47f73d9b13cc46e2b1aa33cd8a95cf41/local_dependencies/ruff/Cargo.toml`

  Caused by:
    error inheriting `colored` from workspace root manifest's `workspace.dependencies.colored`

  Caused by:
    failed to find a workspace root
  ๐Ÿ’ฅ maturin failed
    Caused by: Cargo metadata failed. Does your crate compile with `cargo build`?
    Caused by: `cargo metadata` exited with an error:
  Error running maturin: Command '['maturin', 'pep517', 'write-dist-info', '--metadata-directory', '/data/data/com.termux/files/usr/tmp/pip-modern-metadata-m8_1bl32', '--interpreter', '/data/data/com.termux/files/usr/bin/python3']' returned non-zero exit status 1.
  Checking for Rust toolchain....
  Running `maturin pep517 write-dist-info --metadata-directory /data/data/com.termux/files/usr/tmp/pip-modern-metadata-m8_1bl32 --interpreter /data/data/com.termux/files/usr/bin/python3`
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

ร— Encountered error while generating package metadata.
โ•ฐโ”€> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Customise or better default for severity level?

Hi, I found that currently most diagnostics, except for two, are assigned the severity level of "Warning".

It would be nice if this can be customised via user's settings.

Otherwise would you be open to a PR just extending the current behaviour to consider some diagnostic with "Information" or "Hint" level by default like ARG, SIM, PTH?

Tests fail with ruff >0.0.265

FF
======================================================================
FAIL: test_linting_example (tests.test_server.TestServer.test_linting_example)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/ruff-lsp/src/ruff_lsp-0.0.26/tests/test_server.py", line 98, in test_linting_example
    self.assertEqual(actual, expected)
AssertionError: {'uri[132 chars]}}, 'message': '`sys` imported but unused', 's[477 chars]3}}]} != {'uri[132 chars]}}, 'data': {'fix': {'message': 'Remove unused[445 chars]f'}]}
  {'diagnostics': [{'code': 'F401',
+                   'data': {'fix': {'edits': [{'content': '',
-                   'data': {'fix': {'applicability': 'Unspecified',
-                                    'edits': [{'content': '',
                                                'end_location': {'column': 0,
                                                                 'row': 2},
                                                'location': {'column': 0,
                                                             'row': 1}}],
                                     'message': 'Remove unused import: `sys`'},
                             'noqa_row': 1},
                    'message': '`sys` imported but unused',
                    'range': {'end': {'character': 10, 'line': 0},
                              'start': {'character': 7, 'line': 0}},
                    'severity': 2,
                    'source': 'Ruff',
                    'tags': [1]},
                   {'code': 'F821',
                    'data': {'fix': None, 'noqa_row': 3},
                    'message': 'Undefined name `x`',
                    'range': {'end': {'character': 7, 'line': 2},
                              'start': {'character': 6, 'line': 2}},
                    'severity': 1,
                    'source': 'Ruff'}],
   'uri': 'file:///tmp/tmpjz3mhkpm.py'}

======================================================================
FAIL: test_no_initialization_options (tests.test_server.TestServer.test_no_initialization_options)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/ruff-lsp/src/ruff_lsp-0.0.26/tests/test_server.py", line 181, in test_no_initialization_options
    self.assertEqual(actual, expected)
AssertionError: {'uri[132 chars]}}, 'message': '`sys` imported but unused', 's[477 chars]3}}]} != {'uri[132 chars]}}, 'data': {'fix': {'message': 'Remove unused[445 chars]f'}]}
  {'diagnostics': [{'code': 'F401',
+                   'data': {'fix': {'edits': [{'content': '',
-                   'data': {'fix': {'applicability': 'Unspecified',
-                                    'edits': [{'content': '',
                                                'end_location': {'column': 0,
                                                                 'row': 2},
                                                'location': {'column': 0,
                                                             'row': 1}}],
                                     'message': 'Remove unused import: `sys`'},
                             'noqa_row': 1},
                    'message': '`sys` imported but unused',
                    'range': {'end': {'character': 10, 'line': 0},
                              'start': {'character': 7, 'line': 0}},
                    'severity': 2,
                    'source': 'Ruff',
                    'tags': [1]},
                   {'code': 'F821',
                    'data': {'fix': None, 'noqa_row': 3},
                    'message': 'Undefined name `x`',
                    'range': {'end': {'character': 7, 'line': 2},
                              'start': {'character': 6, 'line': 2}},
                    'severity': 1,
                    'source': 'Ruff'}],
   'uri': 'file:///tmp/tmpvu2p4_pc.py'}

----------------------------------------------------------------------
Ran 2 tests in 0.854s

FAILED (failures=2)

aerial.nvim doesn't show all of symbols when using ruff-lsp

I always open the symbol outline when I code. However, it seems that the symbol outline generated by aerial.nvim only displays class names and functions without their attributes or local variables:

image

However, the symbol outline works normally when I use Pyright instead:
image

I use Arch Linux, AstroNvim v2.0 and ruff-lsp v0.0.23

not inside window folders

I recently came across ruff and would love to have it in ST4. I normally use SublimeLinter, but would move to LSP for ruff! Unfortunately, true to form, LSP is a nuisance to configure and get working. I following the instructions (install LSP plugin and setup settings file with "log_debug": true,:

// Settings in here override those in "LSP/LSP.sublime-settings"
{
  "log_debug": true,
  "clients": {
    "ruff-lsp": {
      "command": ["/Users/reagle/.pyenv/shims/ruff-lsp"],
      "enabled": true,
      "selector": "source.python",
      "initializationOptions": {
        "settings": {
          "args": []
        }
      }
    }
  }
}

Unfortunately, it's not identifying any errors and I see this is the log.

SP: starting ['/Users/reagle/.pyenv/shims/ruff-lsp'] in /Users/reagle/e/clear/data
LSP: ruff-lsp: Supported execute commands: ['ruff.applyAutofix', 'ruff.applyOrganizeImports']
LSP: ruff-lsp: supported code action kinds: ['quickfix', 'source.fixAll', 'source.organizeImports', 'CodeActionKind.SourceFixAll.ruff', 'CodeActionKind.SourceOrganizeImports.ruff']
LSP: ignoring unsuitable diagnostics for file:///Users/reagle/bin/td/extract-dictation.py reason: not inside window folders

I'm not sure why its starting ruff-lsp in /Users/reagle/e/clear/data and I don'T know what window folders it's talking about.

Discussion: implementation

This plugin is great and help me a lot on python development, but I have a question, why this implement in python instead of rust, is it because there are some advantages?

Since the core ruff functions implement in rust. Maybe use rust is more consistent?

Loosing internal functionality of SublimeText 4

I really like ruff-lsp, but when I install it the recommended way, I loose SublimeText internal functionality like showing definition and references on hover over a function/class name and jumping there by clicking. Is there a way to use ruff-lsp and keep those things?

Supporting Virtualenv in NeoVim

Hello folks, is there anyway to select a virtualenv depending on the folder for neovim?
I'm really looking forward to testing ruff-lsp but I couldn't configure it properly...

I'm used to pyright with the following setup:

    require("lspconfig").pyright.setup {
      on_init = function(client)
        client.config.settings.python.pythonPath = get_python_path(client.config.root_dir)
        client.config.settings.venvPath = path.join(vim.env.PYENV_ROOT, 'versions')
        client.config.settings.venv = get_venv(client.config.root_dir)
      end
    }
  end,

Then the get_python_path and get_venv are lua functions defined to get the right value for each different folder where I'm in (using pyenv virtualenv and pyenv local version to setup the virtualenvs)

For ruff I tried something similar but didn't work.

Thanks a lot (=

Not all extra arguments to `ruff` throughs the `args` field in the `settings` are valid

I was trying to debug ruff-lsp by specifying the verbose flag -v to the underlying ruff executable.
I did this by following the comment of the readme and the guide here.
However, the global TOOL_ARGS here automatically specifies the --quiet flag (to only print lint violations) and therefore the -v flag in args leads to an error, which is not straight forward to locate in the LspLog inside Neovim.
Perhaps the source code should raise an ValueError if the -v flag is specified in args, or maybe the readme should be more upfront that not all args to ruff are allowed (for obvious reasons; although not so obvious that I understood it the first time ๐Ÿ˜ƒ) ?

Make `ruff` dependency optional

I know the issue title sounds weird for a "ruff language server", but please hear me out, it might make sense in the end. Please keep in mind that I don't quite know how to solve this properly, but I do see the need for it.

If we consider a developer who is part of a team effort on a particular project, we can subdivide all the tools they are using in roughly two categories: developer-provided and project-provided.

In any given project, its development team converges on some common ground regarding linting, code formatting etc., including tool versions, so using ruff version X on a project is a project-based decision, reflected in this project's dependencies. Other projects might be using a version Y, so having a global ruff binary installed might be wrong in these circumstances.

However, using an IDE/editor with LSP support and its particular ruff integration is a decision by the developer for their own comfort. So whether or not they are using VSCode or Emacs or Notepad is not something that should affect other team members. In this case, adding ruff-lsp to the project's dependencies is in best case useless for the people using e.g. VSCode and could be considered rude in some teams ("we don't commit .vscode/ after all either").

So we have a situation where ruff-lsp should probably be kept out of projects' dependencies and installed (user)-globally, but ruff itself needs to be part of a project. In many cases, there would be no need for a (user)-global ruff at all, however it's getting installed by ruff-lsp as a dependency nevertheless. It would be nice if there was a way to install it separately and explicitely.

`nvim-lspconfig` setting not correctly passing arguments to `ruff-lsp`

When configuring the ruff-lsp server in neovim using nvim-lspconfig I am using the standard configuration shown in the documentation with the addition of a change to ruff's --line-length argument:

require'lspconfig'.ruff_lsp.setup{
  settings = {
    ruff_lsp = {
      -- Any extra CLI arguments for `ruff` go here.
      args = { '--line-length 120' },
    }
  }
}

However, when ruff-lsp is attached to a neovim buffer, this argument is not respected and the max line length is still 88. I'm guessing there is either a syntax issue here, or the args not being passed to ruff correctly. Any help would be appreciated!

`textDocument/codeAction` crashes when there are no actions

Trying to enumerate actions for a line crashes if there are no available actions for the current position.

On neovim, I get the errors:

LSP[ruff_lsp] Unexpected error in LSP server, see server's logs for details                                                   
[Fzf-lua] Error executing 'textDocument/codeAction': timeout                                                                  

The LSP logs neovim generates are, regrettably, not the easiest to read:

[ERROR][2023-01-17 16:08:01] .../vim/lsp/rpc.lua:733	"rpc"	"ruff-lsp"	"stderr"	"Unable to deserialize message\n  + Exception Group Traceback (most recent call last):\n  |   File \"/usr/lib/python3.11/site-packages/pygls/protocol.py\", line 401, in _deserialize_message\n  |     return self._converter.structure(data, request_type)\n  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |   File \"/usr/lib/python3.11/site-packages/cattrs/converters.py\", line 309, in structure\n  |     return self._structure_func.dispatch(cl)(obj, cl)\n  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |   File \"<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>\", line 26, in structure_TextDocumentCodeActionRequest\n  |     if errors: raise __c_cve('While structuring ' + 'TextDocumentCodeActionRequest', errors, __cl)\n  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  | cattrs.errors.ClassValidationError: While structuring TextDocumentCodeActionRequest (1 sub-exception)\n  +-+---------------- 1 ----------------\n    | Exception Group Traceback (most recent call last):\n    |   File \"<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>\", line 10, in structure_TextDocumentCodeActionRequest\n    |     res['params'] = __c_structure_params(o['params'], __c_type_params)\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    |   File \"<cattrs generated structure lsprotocol.types.CodeActionParams>\", line 31, in structure_CodeActionParams\n    |     if errors: raise __c_cve('While structuring ' + 'CodeActionParams', errors, __cl)\n    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    | cattrs.errors.ClassValidationError: While structuring CodeActionParams (1 sub-exception)\n    | Structuring class TextDocumentCodeActionRequest @ attribute params\n    +-+---------------- 1 ----------------\n      | Exception Group Traceback (most recent call last):\n      |   File \"<cattrs generated structure lsprotocol.types.CodeActionParams>\", line 15, in structure_CodeActionParams\n      |     res['context'] = __c_structure_context(o['context'], __c_type_context)\n      |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n      |   File \"<cattrs generated structure lsprotocol.types.CodeActionContext>\", line 21, in structure_CodeActionContext\n      |     if errors: raise __c_cve('While structuring ' + 'CodeActionContext', errors, __cl)\n      |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n      | cattrs.errors.ClassValidationError: While structuring CodeActionContext (1 sub-exception)\n      | Structuring class CodeActionParams @ attribute context\n      +-+---------------- 1 ----------------\n        | Traceback (most recent call last):\n        |   File \"<cattrs generated structure lsprotocol.types.CodeActionContext>\", line 5, in structure_CodeActionContext\n        |     res['diagnostics'] = __c_structure_diagnostics(o['diagnostics'], __c_type_diagnostics)\n        |                                                     ~^^^^^^^^^^^^^^^\n        | TypeError: list indices must be integers or slices, not str\n        | Structuring class CodeActionContext @ attribute diagnostics\n        +------------------------------------\n\n"
[ERROR][2023-01-17 16:08:01] .../vim/lsp/rpc.lua:733	"rpc"	"ruff-lsp"	"stderr"	"Error receiving data\n  + Exception Group Traceback (most recent call last):\n  |   File \"/usr/lib/python3.11/site-packages/pygls/protocol.py\", line 401, in _deserialize_message\n  |     return self._converter.structure(data, request_type)\n  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |   File \"/usr/lib/python3.11/site-packages/cattrs/converters.py\", line 309, in structure\n  |     return self._structure_func.dispatch(cl)(obj, cl)\n  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |   File \"<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>\", line 26, in structure_TextDocumentCodeActionRequest\n  |     if errors: raise __c_cve('While structuring ' + 'TextDocumentCodeActionRequest', errors, __cl)\n  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  | cattrs.errors.ClassValidationError: While structuring TextDocumentCodeActionRequest (1 sub-exception)\n  +-+---------------- 1 ----------------\n    | Exception Group Traceback (most recent call last):\n    |   File \"<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>\", line 10, in structure_TextDocumentCodeActionRequest\n    |     res['params'] = __c_structure_params(o['params'], __c_type_params)\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    |   File \"<cattrs generated structure lsprotocol.types.CodeActionParams>\", line 31, in structure_CodeActionParams\n    |     if errors: raise __c_cve('While structuring ' + 'CodeActionParams', errors, __cl)\n    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    | cattrs.errors.ClassValidationError: While structuring CodeActionParams (1 sub-exception)\n    | Structuring class TextDocumentCodeActionRequest @ attribute params\n    +-+---------------- 1 ----------------\n      | Exception Group Traceback (most recent call last):\n      |   File \"<cattrs generated structure lsprotocol.types.CodeActionParams>\", line 15, in structure_CodeActionParams\n      |     res['context'] = __c_structure_context(o['context'], __c_type_context)\n      |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n      |   File \"<cattrs generated structure lsprotocol.types.CodeActionContext>\", line 21, in structure_CodeActionContext\n      |     if errors: raise __c_cve('While structuring ' + 'CodeActionContext', errors, __cl)\n      |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n      | cattrs.errors.ClassValidationError: While structuring CodeActionContext (1 sub-exception)\n      | Structuring class CodeActionParams @ attribute context\n      +-+---------------- 1 ----------------\n        | Traceback (most recent call last):\n        |   File \"<cattrs generated structure lsprotocol.types.CodeActionContext>\", line 5, in structure_CodeActionContext\n        |     res['diagnostics'] = __c_structure_diagnostics(o['diagnostics'], __c_type_diagnostics)\n        |                                                     ~^^^^^^^^^^^^^^^\n        | TypeError: list indices must be integers or slices, not str\n        | Structuring class CodeActionContext @ attribute diagnostics\n        +------------------------------------\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n  File \"/usr/lib/python3.11/site-packages/pygls/protocol.py\", line 507, in data_received\n    self._data_received(data)\n  File \"/usr/lib/python3.11/site-packages/pygls/protocol.py\", line 539, in _data_received\n    json.loads(body.decode(self.CHARSET),\n  File \"/usr/lib/python3.11/json/__init__.py\", line 359, in loads\n    return cls(**kw).decode(s)\n           ^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.11/json/decoder.py\", line 337, in decode\n    obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.11/json/decoder.py\", line 353, in raw_decode\n    obj, end = self.scan_once(s, idx)\n               ^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.11/site-packages/pygls/protocol.py\", line 415, in _deserialize_message\n    raise JsonRpcInvalidParams() from exc\npygls.exceptions.JsonRpcInvalidParams: Invalid Params\n"
[ERROR][2023-01-17 16:08:06] .../vim/lsp/rpc.lua:733	"rpc"	"pylsp"	"stderr"	"2023-01-17 16:08:06,200 CET - WARNING - pylsp_jsonrpc.endpoint - Received cancel notification for unknown message id 2\n"
[ERROR][2023-01-17 16:08:06] .../vim/lsp/rpc.lua:733	"rpc"	"ruff-lsp"	"stderr"	'Cancel notification for unknown message id "2"\n'

I managed to unmangle it a bit tho. The big string in the first error is:

 "Unable to deserialize message
  + Exception Group Traceback (most recent call last):
  |   File "/usr/lib/python3.11/site-packages/pygls/protocol.py", line 401, in _deserialize_message
  |     return self._converter.structure(data, request_type)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.11/site-packages/cattrs/converters.py", line 309, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>", line 26, in structure_TextDocumentCodeActionRequest
  |     if errors: raise __c_cve('While structuring ' + 'TextDocumentCodeActionRequest', errors, __cl)
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  | cattrs.errors.ClassValidationError: While structuring TextDocumentCodeActionRequest (1 sub-exception)
  +-+---------------- 1 ----------------
    | Exception Group Traceback (most recent call last):
    |   File "<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>", line 10, in structure_TextDocumentCodeActionRequest
    |     res['params'] = __c_structure_params(o['params'], __c_type_params)
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "<cattrs generated structure lsprotocol.types.CodeActionParams>", line 31, in structure_CodeActionParams
    |     if errors: raise __c_cve('While structuring ' + 'CodeActionParams', errors, __cl)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | cattrs.errors.ClassValidationError: While structuring CodeActionParams (1 sub-exception)
    | Structuring class TextDocumentCodeActionRequest @ attribute params
    +-+---------------- 1 ----------------
      | Exception Group Traceback (most recent call last):
      |   File "<cattrs generated structure lsprotocol.types.CodeActionParams>", line 15, in structure_CodeActionParams
      |     res['context'] = __c_structure_context(o['context'], __c_type_context)
      |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |   File "<cattrs generated structure lsprotocol.types.CodeActionContext>", line 21, in structure_CodeActionContext
      |     if errors: raise __c_cve('While structuring ' + 'CodeActionContext', errors, __cl)
      |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      | cattrs.errors.ClassValidationError: While structuring CodeActionContext (1 sub-exception)
      | Structuring class CodeActionParams @ attribute context
      +-+---------------- 1 ----------------
        | Traceback (most recent call last):
        |   File "<cattrs generated structure lsprotocol.types.CodeActionContext>", line 5, in structure_CodeActionContext
        |     res['diagnostics'] = __c_structure_diagnostics(o['diagnostics'], __c_type_diagnostics)
        |                                                     ~^^^^^^^^^^^^^^^
        | TypeError: list indices must be integers or slices, not str
        | Structuring class CodeActionContext @ attribute diagnostics
        +------------------------------------

And the other one is:

 "Error receiving data
  + Exception Group Traceback (most recent call last):
  |   File "/usr/lib/python3.11/site-packages/pygls/protocol.py", line 401, in _deserialize_message
  |     return self._converter.structure(data, request_type)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.11/site-packages/cattrs/converters.py", line 309, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>", line 26, in structure_TextDocumentCodeActionRequest
  |     if errors: raise __c_cve('While structuring ' + 'TextDocumentCodeActionRequest', errors, __cl)
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  | cattrs.errors.ClassValidationError: While structuring TextDocumentCodeActionRequest (1 sub-exception)
  +-+---------------- 1 ----------------
    | Exception Group Traceback (most recent call last):
    |   File "<cattrs generated structure lsprotocol.types.TextDocumentCodeActionRequest>", line 10, in structure_TextDocumentCodeActionRequest
    |     res['params'] = __c_structure_params(o['params'], __c_type_params)
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "<cattrs generated structure lsprotocol.types.CodeActionParams>", line 31, in structure_CodeActionParams
    |     if errors: raise __c_cve('While structuring ' + 'CodeActionParams', errors, __cl)
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | cattrs.errors.ClassValidationError: While structuring CodeActionParams (1 sub-exception)
    | Structuring class TextDocumentCodeActionRequest @ attribute params
    +-+---------------- 1 ----------------
      | Exception Group Traceback (most recent call last):
      |   File "<cattrs generated structure lsprotocol.types.CodeActionParams>", line 15, in structure_CodeActionParams
      |     res['context'] = __c_structure_context(o['context'], __c_type_context)
      |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |   File "<cattrs generated structure lsprotocol.types.CodeActionContext>", line 21, in structure_CodeActionContext
      |     if errors: raise __c_cve('While structuring ' + 'CodeActionContext', errors, __cl)
      |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      | cattrs.errors.ClassValidationError: While structuring CodeActionContext (1 sub-exception)
      | Structuring class CodeActionParams @ attribute context
      +-+---------------- 1 ----------------
        | Traceback (most recent call last):
        |   File "<cattrs generated structure lsprotocol.types.CodeActionContext>", line 5, in structure_CodeActionContext
        |     res['diagnostics'] = __c_structure_diagnostics(o['diagnostics'], __c_type_diagnostics)
        |                                                     ~^^^^^^^^^^^^^^^
        | TypeError: list indices must be integers or slices, not str
        | Structuring class CodeActionContext @ attribute diagnostics
        +------------------------------------

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pygls/protocol.py", line 507, in data_received
    self._data_received(data)
  File "/usr/lib/python3.11/site-packages/pygls/protocol.py", line 539, in _data_received
    json.loads(body.decode(self.CHARSET),
  File "/usr/lib/python3.11/json/__init__.py", line 359, in loads
    return cls(**kw).decode(s)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pygls/protocol.py", line 415, in _deserialize_message
    raise JsonRpcInvalidParams() from exc
pygls.exceptions.JsonRpcInvalidParams: Invalid Params

The file/code being edited seems to be irrelevant. I can repro with the following minimal file:

print(1)

Emacs setup instructions

Trying to figure out what to do after pip install ruff-lsp to get this working in emacs. I came across emacs-lsp/lsp-mode#3876 which seems to indicate that there's more to do to get it up and running. Happy to help test steps.

[Question] Unable to Ignore Repetitive Suggestions

I am unable to ignore repetitive suggestions in my editor neovim while using the Lighthub ๐Ÿ’ก icon. I have noticed that two suggestions from Ruff keep appearing even though I have already considered them in the past. I believe this is due to my consistent usage of the ๐Ÿ’ก which remains visible at all times, leading to the repetition of the same suggestions. Could you please provide a solution to this issue so that I can use my editor without any hindrances?

require('lspconfig').ruff_lsp.setup {
  on_attach = on_attach,
  init_options = {
    settings = {
      args = {
      ignore: {
         "Ruff: Organize Import",
         "Ruff: Fix ALL"
         --or
         1234,
         5678
        },
      },
    }
  }
}

image

Feature Request: AutoImport missing library

One of the problems in Python is that you often have to go to the beginning of a file and write code such as import os or import numpy as np when you use a library first time in a file. This is a hassle. Right now, I configure my editor so that it runs tidy-import from pyflyby to automatically add missing imports when I saved the file. I just need to keep a common set of import at ~/.pyflyby. Unfortunately, tidy-import is slow to run (it takes ~0.5s on 10 lines of code).

I think it would be best if ruff can support this feature given its speed. I am not sure if that is within the capacity of ruff. I put this feature request under ruff-lsp as I felt it might be hard to configure the auto-import behavior for ruff tool itself since pyproject.toml are intended for linting.

Support `textDocument/formatting`

It looks like the only way to have ruff-lsp format a document right now is via a textDocument/codeAction. From my experience, most LSP servers allow document formatting via textDocument/formatting.

It took me a bit to realize, because the example Neovim config registers a keymap for vim.lsp.buf.format(), so I was a bit baffled trying to use that to format a file, as ruff-lsp does nothing when that request is issued right now.

Cannot overwrite default settings for `fixAll` and `organizeImports`?

Hi, I am trying to overwrite some default settings of ruff-lsp, but it doesn't seem to work. Can you provide me some guidance on what is the correct way to do it?

What I have done:

I tried both coc.nvim and nvim.lspconfig, and neither of them worked.

In coc.nvim's settings, I added the following:

    "ruff-lsp": {
      "command": "ruff-lsp",
      "filetypes": ["python"],
      "settings": {
        "fixAll": false,
        "organizeImports": false
      }
    },

When using nvim.lspconfig, I used the following:

require("lspconfig").ruff_lsp.setup({
    settings = {fixAll=false, organizeImports=false}
})

After I added these settings, I still see ruff's fixAll and organizeImports in code actions. I probably have missed something here? Thanks very much for your help!

Neovim: sort imports on save

I've been trying to use ruff-lsp's built-in import sorting to get rid of isort, but I'm having trouble figuring out how to do so automatically upon saving a file. I would appreciate any help. I'm on neovim 0.9.0 and ruff-lsp 0.0.24.

background

I've already got an autocmd that calls vim.lsp.buf.format() on BufWritePre events. But it seems ruff-lsp doesn't provide formatting capability.

:lua =vim.lsp.get_active_clients()[1].server_capabilities
{
  codeActionProvider = {
    codeActionKinds = { "quickfix", "source.fixAll", "source.organizeImports", "source.fixAll.ruff", "source.organizeImports.ruff" },
    resolveProvider = true
  },
  executeCommandProvider = {
    commands = { "ruff.applyAutofix", "ruff.applyOrganizeImports" }
  },
  hoverProvider = true,
  textDocumentSync = {
    change = 2,
    openClose = true,
    save = true,
    willSave = false,
    willSaveWaitUntil = false
  },
  workspace = {
    fileOperations = vim.empty_dict(),
    workspaceFolders = {
      changeNotifications = true,
      supported = true
    }
  }
}

This seems to have been discussed recently in the following threads:
#61 - feat request to add formatting support
#64 - pull request for formatting support
#73 - reverting formatting support

my attempt

So, it looks like ruff-lsp is limiting import sorting to a code action instead. I tried setting up an autocmd to run the organize imports code action on save, similar to how I did for formatting on save with lspconfig:

      ruff_lsp = {
        on_attach = function(client, bufnr)
          -- Disable hover in favor of Pyright
          client.server_capabilities.hoverProvider = false
          -- Organize imports via code action on save
          vim.api.nvim_create_autocmd("BufWritePre", {
            callback = function()
              vim.lsp.buf.code_action { context = { only = { "source.organizeImports" } }, apply = true }
            end,
            buffer = bufnr,
          })
        end,
      },

This was modeled after the example in the gopls docs (https://github.com/golang/tools/blob/master/gopls/doc/vim.md#imports).

When I try to write the buffer with :w, the code action is executed but the file is not saved. When I run :w a second time, the file is saved, but I get a no-op notification "No code actions available".

Any ideas how to set up something like this?

textDocument/definition is not supported

I installed ruff-lsp through mason in Neovim but get this message when trying to go to a definition. Any ideas? I configured per the example in the docs.

LspInfo shows ruff-lsp is attached to the buffer and warnings like line too long do show up in the editor.

Passing "settings" causes an error on the language server side

Description

The ruff command that ruff-lsp executes by default uses the command bundled with ruff-lsp.

For example, when using a ruff installed in a project (venv), it seems to be adjustable in the settings, so I tried it.

After checking the code, it seems that the settings key in the initializationOptions sent by the language client can be adjusted, so I set it up.

I checked the output of the language server from the language client and it seems that there is an error and the settings are not reflected.

Error

// ...snip
Traceback (most recent call last):
  File "/Users/yaegassy/.local/src/ruff-lsp/venv/lib/python3.11/site-packages/pygls/protocol.py", line 84, in decorator
    self._execute_notification(user_func, *args, **kwargs)
  File "/Users/yaegassy/.local/src/ruff-lsp/venv/lib/python3.11/site-packages/pygls/protocol.py", line 228, in _execute_notification
    handler(*params)
  File "/Users/yaegassy/.local/src/ruff-lsp/venv/lib/python3.11/site-packages/ruff_lsp/server.py", line 504, in initialize
    _update_workspace_settings(settings)
  File "/Users/yaegassy/.local/src/ruff-lsp/venv/lib/python3.11/site-packages/ruff_lsp/server.py", line 540, in _update_workspace_settings
    key = uris.to_fs_path(setting["workspace"])
                          ~~~~~~~^^^^^^^^^^^^^

There is an error here.

Misc

I use Neovim and use coc.nvim, a plugin with VSCode-like LSP client feature. The following is the registration of ruff-lsp and setting of path in "coc.nvim" (coc-settings.json).

"languageserver": {
  {
    "ruff-lsp": {
      "command": "ruff-lsp",
      "filetypes": ["python"],
      "initializationOptions": {
        "settings": {
          "path": ["~/proj/check-ruff-lsp/venv/bin/ruff"]
        }
      }
    },
  }
}

Support for Kate

Hi!
I just wanted to drop here a simple question โ€“ did anybody managed to wire ruff-lsp with Kate editor? It does have support for LSP, but I have no idea how to wire ruff-lsp up.
Editor in question: Kate

Thanks,
Damian

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.