aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-03-16 14:09:04 +0000
committerGitHub2021-03-16 14:09:04 +0000
commit8dc0b18e35cdfdd76f435dcd43c1cfd5a3f0c7f7 (patch)
treea26c6025d45658b4d85d6917ea82489d6ba8fb2e /helix-term/src
parentd8599f3a140eca7cd14f47e9b64f1ae9d829a0eb (diff)
parente3ec5e31ec005e33da4c848b4272e81a6d21a5f0 (diff)
Merge pull request #8 from helix-editor/gd
Goto
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/commands.rs106
-rw-r--r--helix-term/src/keymap.rs8
2 files changed, 112 insertions, 2 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 353d79cc..3e90fb63 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -13,6 +13,8 @@ use once_cell::sync::Lazy;
use crate::compositor::Compositor;
use crate::ui::{self, Popup, Prompt, PromptEvent};
+use std::path::PathBuf;
+
use helix_view::{
document::Mode,
view::{View, PADDING},
@@ -21,6 +23,8 @@ use helix_view::{
use crossterm::event::{KeyCode, KeyEvent};
+use helix_lsp::lsp;
+
pub struct Context<'a> {
pub count: usize,
pub editor: &'a mut Editor,
@@ -846,6 +850,108 @@ pub fn exit_select_mode(cx: &mut Context) {
cx.doc().mode = Mode::Normal;
}
+fn goto(cx: &mut Context, locations: Vec<lsp::Location>) {
+ let executor = cx.executor;
+ let doc = cx.doc();
+
+ doc.mode = Mode::Normal;
+
+ match locations.as_slice() {
+ [location] => {
+ cx.editor
+ .open(PathBuf::from(location.uri.path()), cx.executor);
+ let doc = cx.doc();
+ let definition_pos = location.range.start;
+ let new_pos = helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
+ doc.set_selection(Selection::point(new_pos));
+ }
+ [] => (), // maybe show user message that no definition was found?
+ _locations => {
+ let mut picker = ui::Picker::new(
+ locations,
+ |item| {
+ let file = item.uri.as_str();
+ let line = item.range.start.line;
+ format!("{}:{}", file, line).into()
+ },
+ move |editor: &mut Editor, item| {
+ editor.open(PathBuf::from(item.uri.path()), &executor);
+ let mut doc = &mut editor.view_mut().doc;
+ let definition_pos = item.range.start;
+ let new_pos =
+ helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
+ doc.set_selection(Selection::point(new_pos));
+ },
+ );
+ cx.push_layer(Box::new(picker));
+ }
+ }
+}
+
+pub fn goto_definition(cx: &mut Context) {
+ let doc = cx.doc();
+ let language_server = match doc.language_server.as_ref() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: blocking here is not ideal
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
+
+ // TODO: handle fails
+ let res =
+ smol::block_on(language_server.goto_definition(doc.identifier(), pos)).unwrap_or_default();
+ goto(cx, res);
+}
+
+pub fn goto_type_definition(cx: &mut Context) {
+ let doc = cx.doc();
+ let language_server = match doc.language_server.as_ref() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: blocking here is not ideal
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
+
+ // TODO: handle fails
+ let res = smol::block_on(language_server.goto_type_definition(doc.identifier(), pos))
+ .unwrap_or_default();
+ goto(cx, res);
+}
+
+pub fn goto_implementation(cx: &mut Context) {
+ let doc = cx.doc();
+ let language_server = match doc.language_server.as_ref() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: blocking here is not ideal
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
+
+ // TODO: handle fails
+ let res = smol::block_on(language_server.goto_implementation(doc.identifier(), pos))
+ .unwrap_or_default();
+ goto(cx, res);
+}
+
+pub fn goto_reference(cx: &mut Context) {
+ let doc = cx.doc();
+ let language_server = match doc.language_server.as_ref() {
+ Some(language_server) => language_server,
+ None => return,
+ };
+
+ // TODO: blocking here is not ideal
+ let pos = helix_lsp::util::pos_to_lsp_pos(doc.text().slice(..), doc.selection().cursor());
+
+ // TODO: handle fails
+ let res =
+ smol::block_on(language_server.goto_reference(doc.identifier(), pos)).unwrap_or_default();
+ goto(cx, res);
+}
+
// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
pub mod insert {
use super::*;
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 67490003..d9fe348f 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -311,8 +311,12 @@ pub fn default() -> Keymaps {
code: KeyCode::Esc,
modifiers: Modifiers::NONE
} => commands::normal_mode as Command,
- key!('g') => commands::move_file_start as Command,
- key!('e') => commands::move_file_end as Command,
+ key!('g') => commands::move_file_start,
+ key!('e') => commands::move_file_end,
+ key!('d') => commands::goto_definition,
+ key!('t') => commands::goto_type_definition,
+ key!('r') => commands::goto_reference,
+ key!('i') => commands::goto_implementation,
),
)
}