@@ -13,6 +13,8 @@ use once_cell::sync::Lazy;
13use crate::compositor::Compositor;
13use crate::compositor::Compositor;
14use crate::ui::{self, Popup, Prompt, PromptEvent};
14use crate::ui::{self, Popup, Prompt, PromptEvent};
16+use std::path::PathBuf;
16use helix_view::{
18use helix_view::{
17 document::Mode,
19 document::Mode,
18 view::{View, PADDING},
20 view::{View, PADDING},
@@ -21,6 +23,8 @@ use helix_view::{
22use crossterm::event::{KeyCode, KeyEvent};
24use crossterm::event::{KeyCode, KeyEvent};
24pub struct Context<'a> {
28pub struct Context<'a> {
25 pub count: usize,
29 pub count: usize,
26 pub editor: &'a mut Editor,
30 pub editor: &'a mut Editor,
@@ -846,6 +850,108 @@ pub fn exit_select_mode(cx: &mut Context) {
846 cx.doc().mode = Mode::Normal;
850 cx.doc().mode = Mode::Normal;
853+fn goto(cx: &mut Context, locations: Vec<lsp::Location>) {
854+ let executor = cx.executor;
857+ doc.mode = Mode::Normal;
859+ match locations.as_slice() {
862+ .open(PathBuf::from(location.uri.path()), cx.executor);
864+ let definition_pos = location.range.start;
865+ let new_pos = helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
866+ doc.set_selection(Selection::point(new_pos));
868+ [] => (), // maybe show user message that no definition was found?
870+ let mut picker = ui::Picker::new(
873+ let file = item.uri.as_str();
874+ let line = item.range.start.line;
875+ format!("{}:{}", file, line).into()
877+ move |editor: &mut Editor, item| {
878+ editor.open(PathBuf::from(item.uri.path()), &executor);
879+ let mut doc = &mut editor.view_mut().doc;
880+ let definition_pos = item.range.start;
882+ helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
883+ doc.set_selection(Selection::point(new_pos));
886+ cx.push_layer(Box::new(picker));
891+pub fn goto_definition(cx: &mut Context) {
893+ let language_server = match doc.language_server.as_ref() {
894+ Some(language_server) => language_server,
898+ // TODO: blocking here is not ideal
899+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
901+ // TODO: handle fails
903+ smol::block_on(language_server.goto_definition(doc.identifier(), pos)).unwrap_or_default();
907+pub fn goto_type_definition(cx: &mut Context) {
909+ let language_server = match doc.language_server.as_ref() {
910+ Some(language_server) => language_server,
914+ // TODO: blocking here is not ideal
915+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
917+ // TODO: handle fails
918+ let res = smol::block_on(language_server.goto_type_definition(doc.identifier(), pos))
919+ .unwrap_or_default();
923+pub fn goto_implementation(cx: &mut Context) {
925+ let language_server = match doc.language_server.as_ref() {
926+ Some(language_server) => language_server,
930+ // TODO: blocking here is not ideal
931+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
933+ // TODO: handle fails
934+ let res = smol::block_on(language_server.goto_implementation(doc.identifier(), pos))
935+ .unwrap_or_default();
939+pub fn goto_reference(cx: &mut Context) {
941+ let language_server = match doc.language_server.as_ref() {
942+ Some(language_server) => language_server,
946+ // TODO: blocking here is not ideal
947+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
949+ // TODO: handle fails
951+ smol::block_on(language_server.goto_reference(doc.identifier(), pos)).unwrap_or_default();
849// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
955// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
850pub mod insert {
956pub mod insert {
851 use super::*;
957 use super::*;