aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs105
-rw-r--r--helix-term/src/keymap.rs2
2 files changed, 105 insertions, 2 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 24fb1709..dd7de06e 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1122,14 +1122,106 @@ pub fn goto_reference(cx: &mut Context) {
goto(cx, res);
}
+pub fn signature_help(cx: &mut Context) {
+ let doc = cx.doc();
+
+ let language_server = match doc.language_server() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: blocking here is not ideal
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text(), doc.selection().cursor());
+
+ // TODO: handle fails
+
+ let res = smol::block_on(language_server.text_document_signature_help(doc.identifier(), pos))
+ .unwrap_or_default();
+
+ if let Some(signature_help) = res {
+ log::info!("{:?}", signature_help);
+ // signatures
+ // active_signature
+ // active_parameter
+ // render as:
+
+ // signature
+ // ----------
+ // doc
+
+ // with active param highlighted
+ }
+}
+
// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
pub mod insert {
use super::*;
pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;
+ pub type PostHook = fn(&mut Context, char);
use helix_core::auto_pairs;
const HOOKS: &[Hook] = &[auto_pairs::hook];
+ fn completion(cx: &mut Context, ch: char) {
+ // if ch matches completion char, trigger completion
+ let doc = cx.doc();
+ let language_server = match doc.language_server() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ let capabilities = language_server.capabilities();
+
+ if let lsp::ServerCapabilities {
+ completion_provider:
+ Some(lsp::CompletionOptions {
+ trigger_characters: Some(triggers),
+ ..
+ }),
+ ..
+ } = capabilities
+ {
+ // TODO: what if trigger is multiple chars long
+ let is_trigger = triggers.iter().any(|trigger| trigger.contains(ch));
+
+ if is_trigger {
+ super::completion(cx);
+ }
+ }
+ }
+
+ // TODO: the pre-hook handles ( so post hook never gets called
+ fn signature_help(cx: &mut Context, ch: char) {
+ // if ch matches signature_help char, trigger
+ let doc = cx.doc();
+ let language_server = match doc.language_server() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ let capabilities = language_server.capabilities();
+
+ if let lsp::ServerCapabilities {
+ signature_help_provider:
+ Some(lsp::SignatureHelpOptions {
+ trigger_characters: Some(triggers),
+ // TODO: retrigger_characters
+ ..
+ }),
+ ..
+ } = capabilities
+ {
+ // TODO: what if trigger is multiple chars long
+ let is_trigger = triggers.iter().any(|trigger| trigger.contains(ch));
+
+ if is_trigger {
+ super::signature_help(cx);
+ }
+ }
+ }
+
+ const POST_HOOKS: &[PostHook] = &[completion, signature_help];
+
// TODO: insert means add text just before cursor, on exit we should be on the last letter.
pub fn insert_char(cx: &mut Context, c: char) {
let doc = cx.doc();
@@ -1142,10 +1234,17 @@ pub mod insert {
}
}
- let c = Tendril::from_char(c);
- let transaction = Transaction::insert(doc.text(), doc.selection(), c);
+ let t = Tendril::from_char(c);
+ let transaction = Transaction::insert(doc.text(), doc.selection(), t);
doc.apply(&transaction);
+
+ // TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc)
+ // this could also generically look at Transaction, but it's a bit annoying to look at
+ // Operation instead of Change.
+ for hook in POST_HOOKS {
+ hook(cx, c);
+ }
}
pub fn insert_tab(cx: &mut Context) {
@@ -1162,6 +1261,7 @@ pub mod insert {
let doc = cx.doc();
let text = doc.text().slice(..);
let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
+ // TODO: offset range.head by 1? when calculating?
let indent_level =
helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, range.head, true);
let indent = doc.indent_unit().repeat(indent_level);
@@ -1514,6 +1614,7 @@ pub fn completion(cx: &mut Context) {
//
// or we could simply use doc.undo + apply when changing between options
+ // always present here
let item = item.unwrap();
use helix_lsp::{lsp, util};
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 824d469d..aa1f8cce 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -196,7 +196,9 @@ pub fn default() -> Keymaps {
key!('[') => commands::expand_selection,
key!('/') => commands::search,
+ // ? for search_reverse
key!('n') => commands::search_next,
+ // N for search_prev
key!('*') => commands::search_selection,
key!('u') => commands::undo,