@@ -1122,14 +1122,106 @@ pub fn goto_reference(cx: &mut Context) {
1122 goto(cx, res);
1122 goto(cx, res);
1125+pub fn signature_help(cx: &mut Context) {
1126+ let doc = cx.doc();
1128+ let language_server = match doc.language_server() {
1129+ Some(language_server) => language_server,
1133+ // TODO: blocking here is not ideal
1134+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text(), doc.selection().cursor());
1136+ // TODO: handle fails
1138+ let res = smol::block_on(language_server.text_document_signature_help(doc.identifier(), pos))
1139+ .unwrap_or_default();
1141+ if let Some(signature_help) = res {
1142+ log::info!("{:?}", signature_help);
1144+ // active_signature
1145+ // active_parameter
1152+ // with active param highlighted
1125// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
1156// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
1126pub mod insert {
1157pub mod insert {
1127 use super::*;
1158 use super::*;
1128 pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;
1159 pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;
1160+ pub type PostHook = fn(&mut Context, char);
1130 use helix_core::auto_pairs;
1162 use helix_core::auto_pairs;
1131 const HOOKS: &[Hook] = &[auto_pairs::hook];
1163 const HOOKS: &[Hook] = &[auto_pairs::hook];
1165+ fn completion(cx: &mut Context, ch: char) {
1166+ // if ch matches completion char, trigger completion
1167+ let doc = cx.doc();
1168+ let language_server = match doc.language_server() {
1169+ Some(language_server) => language_server,
1173+ let capabilities = language_server.capabilities();
1175+ if let lsp::ServerCapabilities {
1176+ completion_provider:
1177+ Some(lsp::CompletionOptions {
1178+ trigger_characters: Some(triggers),
1184+ // TODO: what if trigger is multiple chars long
1185+ let is_trigger = triggers.iter().any(|trigger| trigger.contains(ch));
1188+ super::completion(cx);
1193+ // TODO: the pre-hook handles ( so post hook never gets called
1194+ fn signature_help(cx: &mut Context, ch: char) {
1195+ // if ch matches signature_help char, trigger
1196+ let doc = cx.doc();
1197+ let language_server = match doc.language_server() {
1198+ Some(language_server) => language_server,
1202+ let capabilities = language_server.capabilities();
1204+ if let lsp::ServerCapabilities {
1205+ signature_help_provider:
1206+ Some(lsp::SignatureHelpOptions {
1207+ trigger_characters: Some(triggers),
1208+ // TODO: retrigger_characters
1214+ // TODO: what if trigger is multiple chars long
1215+ let is_trigger = triggers.iter().any(|trigger| trigger.contains(ch));
1218+ super::signature_help(cx);
1223+ const POST_HOOKS: &[PostHook] = &[completion, signature_help];
1133 // TODO: insert means add text just before cursor, on exit we should be on the last letter.
1225 // TODO: insert means add text just before cursor, on exit we should be on the last letter.
1134 pub fn insert_char(cx: &mut Context, c: char) {
1226 pub fn insert_char(cx: &mut Context, c: char) {
1135 let doc = cx.doc();
1227 let doc = cx.doc();
@@ -1142,10 +1234,17 @@ pub mod insert {
1145− let c = Tendril::from_char(c);
1237+ let t = Tendril::from_char(c);
1146− let transaction = Transaction::insert(doc.text(), doc.selection(), c);
1238+ let transaction = Transaction::insert(doc.text(), doc.selection(), t);
1148 doc.apply(&transaction);
1240 doc.apply(&transaction);
1242+ // TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc)
1243+ // this could also generically look at Transaction, but it's a bit annoying to look at
1244+ // Operation instead of Change.
1245+ for hook in POST_HOOKS {
1151 pub fn insert_tab(cx: &mut Context) {
1250 pub fn insert_tab(cx: &mut Context) {
@@ -1162,6 +1261,7 @@ pub mod insert {
1162 let doc = cx.doc();
1261 let doc = cx.doc();
1163 let text = doc.text().slice(..);
1262 let text = doc.text().slice(..);
1164 let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
1263 let transaction = Transaction::change_by_selection(doc.text(), doc.selection(), |range| {
1264+ // TODO: offset range.head by 1? when calculating?
1165 let indent_level =
1265 let indent_level =
1166 helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, range.head, true);
1266 helix_core::indent::suggested_indent_for_pos(doc.syntax(), text, range.head, true);
1167 let indent = doc.indent_unit().repeat(indent_level);
1267 let indent = doc.indent_unit().repeat(indent_level);
@@ -1514,6 +1614,7 @@ pub fn completion(cx: &mut Context) {
1515 // or we could simply use doc.undo + apply when changing between options
1615 // or we could simply use doc.undo + apply when changing between options
1617+ // always present here
1517 let item = item.unwrap();
1618 let item = item.unwrap();
1519 use helix_lsp::{lsp, util};
1620 use helix_lsp::{lsp, util};