Skip to content

update the tag stack for jump to definition #1218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from
Open
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ maplit = "1"
serde = "1"
serde_derive = "1"
serde_json = "1"
serde_tuple = "0.5.0"
json-patch = "0.2"
crossbeam = "0.7.3"
jsonrpc-core = "15"
Expand Down
17 changes: 17 additions & 0 deletions src/language_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,8 @@ impl LanguageClient {
let position = self.vim()?.get_position(params)?;
let current_word = self.vim()?.get_current_word(params)?;
let goto_cmd = self.vim()?.get_goto_cmd(params)?;
let bufnr = self.vim()?.get_bufnr(&filename, params)?;
let winnr = self.vim()?.get_winnr(params)?;

let params = serde_json::to_value(TextDocumentPositionParams {
text_document: TextDocumentIdentifier {
Expand Down Expand Up @@ -1080,6 +1082,21 @@ impl LanguageClient {
loc.range.start.line + 1,
loc.range.start.character + 1
))?;

self.vim()?.update_tagstack(
winnr,
TagStackItem {
bufnr,
from: Pos {
bufnr,
lnum: position.line + 1,
col: position.character + 1,
off: 0,
},
matchnr: None,
tagname: current_word,
},
)?;
}
_ => {
let title = format!("[LC]: search for {}", current_word);
Expand Down
30 changes: 30 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use maplit::hashmap;
use pathdiff::diff_paths;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_tuple::{Deserialize_tuple, Serialize_tuple};
use std::{
collections::HashMap,
io::{BufRead, BufReader, BufWriter, Write},
Expand Down Expand Up @@ -110,6 +111,8 @@ pub type Id = u64;
pub type LanguageId = Option<String>;
/// Buffer id/handle.
pub type Bufnr = i64;
/// Window id/handle.
pub type Winnr = u32;

#[derive(Debug, Serialize, Deserialize)]
pub enum Message {
Expand Down Expand Up @@ -1199,3 +1202,30 @@ pub struct WorkspaceEditWithCursor {
pub workspace_edit: WorkspaceEdit,
pub cursor_position: Option<TextDocumentPositionParams>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TagStack {
pub curidx: u32,
pub items: Vec<TagStackItem>,
pub length: u32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TagStackItem {
pub bufnr: Bufnr,
pub from: Pos,
pub matchnr: Option<u32>,
pub tagname: String,
}

/// This represents a position in a buffer.
///
/// Vim returns this as a List from the `getpos()` function. It is also used as the `from` value in
/// tag stack items.
#[derive(Debug, Serialize_tuple, Deserialize_tuple)]
pub struct Pos {
pub bufnr: Bufnr,
pub lnum: u32,
pub col: u32,
pub off: u32,
}
15 changes: 14 additions & 1 deletion src/vim.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
rpcclient::RpcClient,
sign::Sign,
types::{Bufnr, QuickfixEntry, VimExp, VirtualText},
types::{Bufnr, QuickfixEntry, TagStack, TagStackItem, VimExp, VirtualText, Winnr},
utils::Canonicalize,
viewport::Viewport,
};
Expand Down Expand Up @@ -131,6 +131,12 @@ impl Vim {
try_get(key, params)?.map_or_else(|| self.eval(format!("bufnr('{}')", filename)), Ok)
}

pub fn get_winnr(&self, params: &Value) -> Result<Winnr> {
let key = "winnr";

try_get(key, params)?.map_or_else(|| self.eval("winnr()"), Ok)
}

pub fn get_viewport(&self, params: &Value) -> Result<Viewport> {
let key = "viewport";
let expr = "LSP#viewport()";
Expand Down Expand Up @@ -275,4 +281,11 @@ impl Vim {
pub fn set_signs(&self, filename: &str, signs: &[Sign]) -> Result<i8> {
self.rpcclient.call("s:set_signs", json!([filename, signs]))
}

pub fn update_tagstack(&self, winnr: Winnr, item: TagStackItem) -> Result<()> {
let mut stack: TagStack = self.rpcclient.call("gettagstack", winnr)?;
stack.items.clear();
stack.items.push(item);
self.rpcclient.notify("settagstack", (winnr, stack, "t"))
}
}