diff --git a/README.md b/README.md index cb6f4a7..3613f80 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,8 @@ Vamp.configure do |config| initialization_options: {}, settings: { "my-language-server" => { "exampleOption" => true } } } - config.bind "leader d", "lsp_definition" + config.bind "leader d", config.core.lsp_definition + config.bind "leader D", config.core.lsp_diagnostics end ``` @@ -272,6 +273,8 @@ The native module initializes each server, sends `initialization_options` as `in `:lsp_definition` or the configured Space d binding requests a definition at the primary caret, once regardless of selection count. Both Location and LocationLink results are supported; multiple results use the first. Local-file navigation reuses loaded buffers without overwriting unsaved text. LSP UTF-16 positions and percent-encoded file URIs are translated to validated grapheme coordinates. Navigation is ignored if its source buffer, revision, caret, or latest request has changed. +For programmatic bindings, use `config.core.lsp_definition` and `config.core.lsp_diagnostics`, immutable Action objects eligible in Normal mode. Both route to the same native implementation as their Ex commands; no LSP keys are bound by default. These actions are also available in the command palette. + Diagnostics appear as severity-colored gutter numbers and text underlines; the primary caret's diagnostic appears in the message row. `:lsp_diagnostics` reports the current document's server state. Older versioned diagnostics are discarded; unversioned diagnostics can only be associated with the arrival-time document revision. Editing clears previous annotations immediately. Server startup/transport failures are reported and clear that server's diagnostics; other servers and native editing remain available. There are no automatic restarts. Native LSP currently provides synchronization, diagnostics, and go-to-definition—not completion, hover, rename, formatting, code actions, workspace edits, or semantic highlighting. Tree-sitter remains the syntax highlighter. The former Ruby LSP plugin has been removed; migrate its `servers` entries to `config.lsp[language_id]` objects without the `language_id` field. @@ -323,6 +326,7 @@ Key notation follows [Herdr's readable style](https://herdr.dev/docs/configurati | Normal | `insert`, `append`, `open_below`, `open_above` | | Normal, Visual | `insert_first_nonblank`, `append_line_end`, `clone_above`, `clone_below` | | Normal | `join_lines`, `undo`, `redo`, `command` | +| Normal | `lsp_definition`, `lsp_diagnostics` | | Normal | `search`, `paste_before`, `paste_after` | | Normal | `paste_system_before`, `paste_system_after` | | Normal, Visual | `select`, `search_next`, `search_previous` | diff --git a/examples/config.rb b/examples/config.rb index 5658544..dde8624 100644 --- a/examples/config.rb +++ b/examples/config.rb @@ -19,7 +19,8 @@ Vamp.configure do |config| # command: ["my-language-server", "--stdio"], extensions: ["myl"], # initialization_options: {}, settings: {} # } - # config.bind "leader d", "lsp_definition" + # config.bind "leader d", config.core.lsp_definition + # config.bind "leader D", config.core.lsp_diagnostics config.bind "g", "greet" config.bind "leader g", "greet" config.bind "ctrl+r", config.core.redo diff --git a/src/editor.rs b/src/editor.rs index 448469d..dac7dd7 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -254,6 +254,8 @@ enum Action { Palette, FilePicker, FileExplorer, + LspDefinition, + LspDiagnostics, } // Names and mode eligibility are shared by configured bindings and the palette. @@ -431,6 +433,16 @@ const CORE_ACTIONS: &[(&str, Action, &[Mode])] = &[ Action::FileExplorer, &[Mode::Normal, Mode::Visual], ), + ( + "core.lsp_definition", + Action::LspDefinition, + &[Mode::Normal], + ), + ( + "core.lsp_diagnostics", + Action::LspDiagnostics, + &[Mode::Normal], + ), ]; impl Action { @@ -1977,6 +1989,8 @@ impl Editor { } Action::FilePicker => self.open_file_picker(FilePresentation::Floating), Action::FileExplorer => self.open_file_picker(FilePresentation::Docked), + Action::LspDefinition => return self.execute("lsp_definition"), + Action::LspDiagnostics => return self.execute("lsp_diagnostics"), Action::Insert | Action::InsertFirstNonblank | Action::AppendLineEnd diff --git a/src/ruby_host.rb b/src/ruby_host.rb index 9cc5f5e..a3a3cf3 100644 --- a/src/ruby_host.rb +++ b/src/ruby_host.rb @@ -64,6 +64,7 @@ module Vamp copy_system paste_system_before paste_system_after select_lines clone_above clone_below select_next skip_occurrence select_all file_picker file_explorer + lsp_definition lsp_diagnostics ].each do |name| action = Action.new("core.#{name}".freeze).freeze define_singleton_method(name) { action } diff --git a/tests/lsp.rs b/tests/lsp.rs index 316469f..2006834 100644 --- a/tests/lsp.rs +++ b/tests/lsp.rs @@ -220,7 +220,7 @@ impl Fixture { "settings": {"rust-analyzer": {"cargo": {"allFeatures": true}}}, }); let config = format!( - "Vamp.configure do |config|\n config.clipboard_mode = 'separate'\n config.lsp['fixture-language'] = JSON.parse({})\nend\n", + "Vamp.configure do |config|\n config.clipboard_mode = 'separate'\n config.lsp['fixture-language'] = JSON.parse({})\n config.bind 'leader d', config.core.lsp_definition\n config.bind 'leader D', config.core.lsp_diagnostics\nend\n", serde_json::to_string(&options.to_string()).unwrap(), ); let config_path = self.root.join("config.rb"); @@ -389,7 +389,8 @@ fn lsp_framing_lifecycle_diagnostics_and_unicode_dirty_definition() { for _ in 0..3 { session.handle(Input::Right); } - session.execute("lsp_definition"); + session.handle(Input::Char(' ')); + session.handle(Input::Char('d')); until(&mut session, &fixture, |session| { session.editor().buffer_id() == target_id }); @@ -696,7 +697,8 @@ fn lsp_optional_configuration_numeric_sync_and_unversioned_diagnostics() { session.handle(Input::Char('!')); session.handle(Input::Escape); session.execute("w"); - session.execute("lsp_diagnostics"); + session.handle(Input::Char(' ')); + session.handle(Input::Char('D')); until(&mut session, &fixture, |session| { session .editor()