Skip to content

Commit eb99696

Browse files
committed
feat(lsp): code lens
Initial implementation of LSP code lense.
1 parent 96ff64a commit eb99696

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

helix-lsp/src/client.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ impl Client {
367367
publish_diagnostics: Some(lsp::PublishDiagnosticsClientCapabilities {
368368
..Default::default()
369369
}),
370+
code_lens: Some(lsp::CodeLensClientCapabilities {
371+
..Default::default()
372+
}),
370373
..Default::default()
371374
}),
372375
window: Some(lsp::WindowClientCapabilities {
@@ -1077,4 +1080,22 @@ impl Client {
10771080

10781081
Some(self.call::<lsp::request::ExecuteCommand>(params))
10791082
}
1083+
1084+
pub fn code_lens(
1085+
&self,
1086+
text_document: lsp::TextDocumentIdentifier,
1087+
) -> Option<impl Future<Output = Result<Value>>> {
1088+
let capabilities = self.capabilities.get().unwrap();
1089+
1090+
// Return early if the server does not support code lens.
1091+
capabilities.code_lens_provider.as_ref()?;
1092+
1093+
let params = lsp::CodeLensParams {
1094+
text_document,
1095+
work_done_progress_params: lsp::WorkDoneProgressParams::default(),
1096+
partial_result_params: lsp::PartialResultParams::default(),
1097+
};
1098+
1099+
Some(self.call::<lsp::request::CodeLensRequest>(params))
1100+
}
10801101
}

helix-term/src/commands.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ impl MappableCommand {
348348
paste_after, "Paste after selection",
349349
paste_before, "Paste before selection",
350350
paste_clipboard_after, "Paste clipboard after selections",
351+
code_lenses_picker, "Show code lense picker",
351352
paste_clipboard_before, "Paste clipboard before selections",
352353
paste_primary_clipboard_after, "Paste primary clipboard after selections",
353354
paste_primary_clipboard_before, "Paste primary clipboard before selections",

helix-term/src/commands/lsp.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub use helix_lsp::lsp::Command;
12
use helix_lsp::{
23
block_on,
34
lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString},
@@ -1256,3 +1257,78 @@ pub fn select_references_to_symbol_under_cursor(cx: &mut Context) {
12561257
},
12571258
);
12581259
}
1260+
1261+
impl ui::menu::Item for lsp::CodeLens {
1262+
type Data = ();
1263+
1264+
fn label(&self, _: &Self::Data) -> Spans {
1265+
match self.command.clone() {
1266+
Some(cmd) => cmd.title.into(),
1267+
None => "unresolved".into(),
1268+
}
1269+
}
1270+
}
1271+
1272+
pub fn code_lenses_picker(cx: &mut Context) {
1273+
let doc = doc!(cx.editor);
1274+
1275+
let language_server = match doc.language_server() {
1276+
Some(language_server) => language_server,
1277+
None => return,
1278+
};
1279+
1280+
let request = match language_server.code_lens(doc.identifier()) {
1281+
Some(future) => future,
1282+
None => {
1283+
cx.editor
1284+
.set_error("Language server does not support code lense");
1285+
return;
1286+
}
1287+
};
1288+
1289+
let doc_id = doc.id();
1290+
cx.callback(
1291+
request,
1292+
move |editor, compositor, lenses: Option<Vec<lsp::CodeLens>>| {
1293+
if let Some(lenses) = lenses {
1294+
log::error!("lenses got: {:?}", lenses);
1295+
let picker = FilePicker::new(
1296+
lenses,
1297+
(),
1298+
|cx, meta, _action| {
1299+
let doc = doc!(cx.editor);
1300+
let language_server = language_server!(cx.editor, doc);
1301+
1302+
if let Some(cmd) = meta.command.clone() {
1303+
let future = match language_server.command(cmd) {
1304+
Some(future) => future,
1305+
None => {
1306+
cx.editor.set_error(
1307+
"Language server does not support executing commands",
1308+
);
1309+
return;
1310+
}
1311+
};
1312+
tokio::spawn(async move {
1313+
let res = future.await;
1314+
1315+
if let Err(e) = res {
1316+
log::error!("execute LSP command: {}", e);
1317+
}
1318+
});
1319+
}
1320+
},
1321+
move |_editor, meta| {
1322+
Some((
1323+
doc_id.into(),
1324+
Some((meta.range.start.line as usize, meta.range.end.line as usize)),
1325+
))
1326+
},
1327+
);
1328+
compositor.push(Box::new(overlayed(picker)));
1329+
} else {
1330+
editor.set_status("no lense found");
1331+
}
1332+
},
1333+
)
1334+
}

helix-term/src/keymap/default.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ pub fn default() -> HashMap<Mode, Keymap> {
217217
"D" => workspace_diagnostics_picker,
218218
"a" => code_action,
219219
"'" => last_picker,
220+
// "l" => execute_lense_under_cursor,
221+
"L" => code_lenses_picker,
220222
"g" => { "Debug (experimental)" sticky=true
221223
"l" => dap_launch,
222224
"b" => dap_toggle_breakpoint,

0 commit comments

Comments
 (0)