on master help sign in
Retrieve completion options on ctrl-x.
commit56f2193811fca2fa20284442c2042fa271464445 authorBlaž Hrastnik <blaz@mxxn.io> dateWed 23 Dec 2020, 16:20 (6 years ago) parent955cb81
7 files changed+86−3
helix-lsp/src/client.rs+43 helix-term/src/application.rs+7−1 helix-term/src/commands.rs+29 helix-term/src/compositor.rs+1 helix-term/src/keymap.rs+2 helix-term/src/ui/editor.rs+1 helix-term/src/ui/picker.rs+3−2
helix-lsp/src/client.rs+43
@@ -196,6 +196,12 @@ impl Client {
196196 root_uri: None, // set to project root in the future
197197 initialization_options: None,
198198 capabilities: lsp::ClientCapabilities {
199+ // text_document:
200+ // { completion: {
201+ // dynamic_registration: bool
202+ // completion_item: { snippet, documentation_format, ... }
203+ // completion_item_kind: { }
204+ // } }
199205 ..Default::default()
200206 },
201207 trace: None,
@@ -358,4 +364,41 @@ impl Client {
358364 pub async fn text_document_did_save(&self) -> anyhow::Result<()> {
359365 unimplemented!()
360366 }
367+
368+ pub async fn completion(&self, doc: &Document) -> anyhow::Result<Vec<lsp::CompletionItem>> {
369+ // TODO: figure out what should happen when you complete with multiple cursors
370+
371+ let params = lsp::CompletionParams {
372+ text_document_position: lsp::TextDocumentPositionParams {
373+ text_document: text_document_identifier(doc),
374+ position: crate::util::pos_to_lsp_pos(
375+ &doc.text().slice(..),
376+ doc.selection().cursor(),
377+ ),
378+ },
379+ // TODO: support these tokens by async receiving and updating the choice list
380+ work_done_progress_params: lsp::WorkDoneProgressParams {
381+ work_done_token: None,
382+ },
383+ partial_result_params: lsp::PartialResultParams {
384+ partial_result_token: None,
385+ },
386+ context: None,
387+ // lsp::CompletionContext { trigger_kind: , trigger_character: Some(), }
388+ };
389+
390+ let response = self.request::<lsp::request::Completion>(params).await?;
391+
392+ let items = match response {
393+ Some(lsp::CompletionResponse::Array(items)) => items,
394+ // TODO: do something with is_incomplete
395+ Some(lsp::CompletionResponse::List(lsp::CompletionList {
396+ is_incomplete: _is_incomplete,
397+ items,
398+ })) => items,
399+ None => Vec::new(),
400+ };
401+
402+ Ok(items)
403+ }
361404}
helix-term/src/application.rs+7−1
@@ -69,10 +69,15 @@ impl Application {
6969
7070 fn render(&mut self) {
7171 let executor = &self.executor;
72+ let language_servers = &self.language_servers;
7273 let editor = &mut self.editor;
7374 let compositor = &self.compositor;
7475
75− let mut cx = crate::compositor::Context { editor, executor };
76+ let mut cx = crate::compositor::Context {
77+ editor,
78+ executor,
79+ language_servers,
80+ };
7681 let area = self.terminal.size().unwrap();
7782
7883 compositor.render(area, self.terminal.current_buffer_mut(), &mut cx);
@@ -113,6 +118,7 @@ impl Application {
113118 let mut cx = crate::compositor::Context {
114119 editor: &mut self.editor,
115120 executor: &self.executor,
121+ language_servers: &self.language_servers,
116122 };
117123 // Handle key events
118124 let should_redraw = match event {
helix-term/src/commands.rs+29
@@ -22,6 +22,7 @@ pub struct Context<'a, 'b> {
2222 pub count: usize,
2323 pub view: &'a mut View,
2424 pub executor: &'a smol::Executor<'b>,
25+ pub language_servers: &'a helix_lsp::Registry,
2526
2627 pub callback: Option<crate::compositor::Callback>,
2728}
@@ -831,3 +832,31 @@ pub fn save(cx: &mut Context) {
831832 // TODO: handle save errors somehow?
832833 cx.executor.spawn(cx.view.doc.save()).detach();
833834}
835+
836+pub fn completion(cx: &mut Context) {
837+ let language_server = cx.language_servers.get("rust", &cx.executor).unwrap();
838+ use log::info;
839+
840+ // TODO: blocking here is not ideal
841+ let res = smol::block_on(language_server.completion(&cx.view.doc)).expect("completion failed!");
842+
843+ let picker = ui::Picker::new(
844+ res,
845+ |item| {
846+ // format_fn
847+ item.label.as_str().into()
848+ },
849+ |editor: &mut Editor, item| {
850+ //
851+ },
852+ );
853+
854+ cx.callback = Some(Box::new(
855+ move |compositor: &mut Compositor, editor: &mut Editor| {
856+ compositor.push(Box::new(picker));
857+ },
858+ ));
859+
860+ // TODO: when iterating over items, show the docs in popup
861+ // language server client needs to be accessible via a registry of some sort
862+}
helix-term/src/compositor.rs+1
@@ -39,6 +39,7 @@ use helix_view::{Editor, View};
3939// shared with commands.rs
4040pub struct Context<'a> {
4141 pub editor: &'a mut Editor,
42+ pub language_servers: &'a helix_lsp::Registry,
4243 pub executor: &'static smol::Executor<'static>,
4344}
4445
helix-term/src/keymap.rs+2
@@ -208,6 +208,8 @@ pub fn default() -> Keymaps {
208208 code: KeyCode::Tab,
209209 modifiers: Modifiers::NONE
210210 }] => commands::insert::insert_tab,
211+
212+ vec![ctrl!('x')] => commands::completion,
211213 ),
212214 Mode::Goto => hashmap!(
213215 vec![Key {
helix-term/src/ui/editor.rs+1
@@ -263,6 +263,7 @@ impl Component for EditorView {
263263 let mut cx = commands::Context {
264264 view,
265265 executor: cx.executor,
266+ language_servers: cx.language_servers,
266267 count: 1,
267268 callback: None,
268269 };
helix-term/src/ui/picker.rs+3−2
@@ -196,12 +196,13 @@ impl<T> Component for Picker<T> {
196196
197197 // -- Render the frame:
198198
199− // clear area
199+ // clear area
200200 let background = cx.editor.theme.get("ui.background");
201201 for y in area.top()..area.bottom() {
202202 for x in area.left()..area.right() {
203203 let cell = surface.get_mut(x, y);
204− cell.symbol.clear();
204+ cell.reset();
205+ // cell.symbol.clear();
205206 cell.set_style(background);
206207 }
207208 }