document symbols

This commit is contained in:
Dongdong Zhou 2020-11-27 16:33:48 +00:00
parent 4668312df5
commit 36ec2fb285
5 changed files with 217 additions and 10 deletions

View File

@ -1691,8 +1691,30 @@ pub fn get_code_actions(&self) -> Option<()> {
let offset = editor.selection.get_cursor_offset();
let prev_offset = buffer.prev_code_boundary(offset);
if buffer.code_actions.get(&prev_offset).is_none() {
let position = buffer.offset_to_position(prev_offset);
let rev = buffer.rev;
let state = LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
// state.lsp.lock().get_code_actions(prev_offset, buffer);
state
.clone()
.proxy
.lock()
.as_ref()
.unwrap()
.get_code_actions(
buffer.id,
position,
Box::new(move |result| {
if let Ok(res) = result {
let mut editor_split = state.editor_split.lock();
editor_split.set_code_actions(
buffer_id,
prev_offset,
rev,
res,
);
}
}),
);
}
None
}
@ -2202,7 +2224,6 @@ pub fn run_command(
buffer.id,
buffer.offset_to_position(offset),
Box::new(move |result| {
println!("got definition result {:?}", result);
let state =
LAPCE_APP_STATE.get_tab_state(&window_id, &tab_id);
let editor_split = state.editor_split.lock();
@ -2233,7 +2254,6 @@ pub fn run_command(
None
}
} {
println!("send go to location");
LAPCE_APP_STATE.submit_ui_command(
LapceUICommand::GotoLocation(location),
editor_split.widget_id,

View File

@ -29,6 +29,7 @@
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::thread;
use uuid::Uuid;
use crate::{
command::LapceCommand, command::LapceUICommand, command::LAPCE_COMMAND,
@ -82,6 +83,7 @@ pub struct PaletteState {
items: Vec<PaletteItem>,
index: usize,
palette_type: PaletteType,
run_id: String,
}
impl PaletteState {
@ -96,6 +98,7 @@ pub fn new(window_id: WindowId, tab_id: WidgetId) -> PaletteState {
cursor: 0,
index: 0,
palette_type: PaletteType::File,
run_id: Uuid::new_v4().to_string(),
}
}
}
@ -103,6 +106,7 @@ pub fn new(window_id: WindowId, tab_id: WidgetId) -> PaletteState {
impl PaletteState {
pub fn run(&mut self, palette_type: Option<PaletteType>) {
self.palette_type = palette_type.unwrap_or(PaletteType::File);
self.run_id = Uuid::new_v4().to_string();
match &self.palette_type {
&PaletteType::Line => {
self.input = "/".to_string();
@ -117,7 +121,7 @@ pub fn run(&mut self, palette_type: Option<PaletteType>) {
&PaletteType::DocumentSymbol => {
self.input = "@".to_string();
self.cursor = 1;
self.items = self.get_document_symbols().unwrap_or(Vec::new());
self.get_document_symbols();
LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id)
.editor_split
@ -208,20 +212,22 @@ fn update_palette(
let palette_type = self.get_palette_type();
if self.palette_type != palette_type {
self.palette_type = palette_type;
self.run_id = Uuid::new_v4().to_string();
match &self.palette_type {
&PaletteType::File => self.items = self.get_files(),
&PaletteType::Line => {
self.items = self.get_lines().unwrap_or(Vec::new())
}
&PaletteType::DocumentSymbol => {
self.items = self.get_document_symbols().unwrap_or(Vec::new())
self.get_document_symbols();
}
&PaletteType::Workspace => self.items = self.get_workspaces(),
&PaletteType::Command => self.items = self.get_commands(),
}
self.request_layout(ctx);
} else {
self.filter_items(ctx);
self.filter_items();
self.request_layout(ctx);
self.preview(ctx, ui_state, env);
}
self.ensure_visible(ctx, env);
@ -291,7 +297,7 @@ pub fn get_input(&self) -> &str {
}
}
pub fn filter_items(&mut self, ctx: &mut EventCtx) {
pub fn filter_items(&mut self) {
let input = self.get_input().to_string();
for item in self.items.iter_mut() {
if input == "" {
@ -310,7 +316,6 @@ pub fn filter_items(&mut self, ctx: &mut EventCtx) {
}
self.items
.sort_by(|a, b| b.score.partial_cmp(&a.score).unwrap_or(Ordering::Less));
self.request_layout(ctx);
}
fn get_commands(&self) -> Vec<PaletteItem> {
@ -401,13 +406,84 @@ fn get_workspaces(&self) -> Vec<PaletteItem> {
.collect()
}
fn get_document_symbols(&self) -> Option<Vec<PaletteItem>> {
return None;
fn get_document_symbols(&self) -> Option<()> {
let state = LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
let editor_split = state.editor_split.lock();
let editor = editor_split.editors.get(&editor_split.active)?;
let buffer_id = editor.buffer_id?;
let buffer = editor_split.buffers.get(&buffer_id)?;
let window_id = self.window_id;
let tab_id = self.tab_id;
let run_id = self.run_id.clone();
let widget_id = self.widget_id;
state.proxy.lock().as_ref().unwrap().get_document_symbols(
buffer_id,
Box::new(move |result| {
if let Ok(res) = result {
let state = LAPCE_APP_STATE.get_tab_state(&window_id, &tab_id);
if *state.focus.lock() != LapceFocus::Palette {
return;
}
let mut palette = state.palette.lock();
if palette.run_id != run_id {
return;
}
let resp: Result<DocumentSymbolResponse, serde_json::Error> =
serde_json::from_value(res);
if let Ok(resp) = resp {
let items: Vec<PaletteItem> = match resp {
DocumentSymbolResponse::Flat(symbols) => symbols
.iter()
.enumerate()
.map(|(i, s)| PaletteItem {
window_id,
tab_id,
kind: PaletteType::DocumentSymbol,
text: s.name.clone(),
hint: s.container_name.clone(),
position: Some(s.location.range.start),
path: None,
score: 0.0,
index: i,
match_mask: BitVec::new(),
icon: PaletteIcon::Symbol(s.kind),
workspace: None,
command: None,
})
.collect(),
DocumentSymbolResponse::Nested(symbols) => symbols
.iter()
.enumerate()
.map(|(i, s)| PaletteItem {
window_id,
tab_id,
kind: PaletteType::DocumentSymbol,
text: s.name.clone(),
hint: None,
path: None,
position: Some(s.range.start),
score: 0.0,
index: i,
match_mask: BitVec::new(),
icon: PaletteIcon::Symbol(s.kind),
workspace: None,
command: None,
})
.collect(),
};
palette.items = items;
if palette.get_input() != "" {
palette.filter_items();
}
LAPCE_APP_STATE.submit_ui_command(
LapceUICommand::RequestLayout,
widget_id,
);
}
}
}),
);
None
// let resp = state.lsp.lock().get_document_symbols(buffer)?;
// Some(match resp {
// DocumentSymbolResponse::Flat(symbols) => symbols

View File

@ -113,6 +113,32 @@ pub fn get_definition(
);
}
pub fn get_document_symbols(&self, buffer_id: BufferId, f: Box<dyn Callback>) {
self.peer.send_rpc_request_async(
"get_document_symbols",
&json!({
"buffer_id": buffer_id,
}),
f,
);
}
pub fn get_code_actions(
&self,
buffer_id: BufferId,
position: Position,
f: Box<dyn Callback>,
) {
self.peer.send_rpc_request_async(
"get_code_actions",
&json!({
"buffer_id": buffer_id,
"position": position,
}),
f,
);
}
pub fn get_document_formatting(
&self,
buffer_id: BufferId,

View File

@ -63,6 +63,13 @@ pub enum Request {
buffer_id: BufferId,
position: Position,
},
GetCodeActions {
buffer_id: BufferId,
position: Position,
},
GetDocumentSymbols {
buffer_id: BufferId,
},
GetDocumentFormatting {
buffer_id: BufferId,
},
@ -250,6 +257,19 @@ fn handle_request(&self, id: RequestId, rpc: Request) {
.lock()
.get_definition(id, request_id, buffer, position);
}
Request::GetCodeActions {
buffer_id,
position,
} => {
let buffers = self.buffers.lock();
let buffer = buffers.get(&buffer_id).unwrap();
self.lsp.lock().get_code_actions(id, buffer, position);
}
Request::GetDocumentSymbols { buffer_id } => {
let buffers = self.buffers.lock();
let buffer = buffers.get(&buffer_id).unwrap();
self.lsp.lock().get_document_symbols(id, buffer);
}
Request::GetDocumentFormatting { buffer_id } => {
let buffers = self.buffers.lock();
let buffer = buffers.get(&buffer_id).unwrap();

View File

@ -133,6 +133,15 @@ pub fn get_semantic_tokens(&self, buffer: &Buffer) {
}
}
pub fn get_document_symbols(&self, id: RequestId, buffer: &Buffer) {
if let Some(client) = self.clients.get(&buffer.language_id) {
let uri = client.get_uri(buffer);
client.request_document_symbols(uri, move |lsp_client, result| {
lsp_client.dispatcher.respond(id, result);
});
}
}
pub fn get_document_formatting(&self, id: RequestId, buffer: &Buffer) {
if let Some(client) = self.clients.get(&buffer.language_id) {
let uri = client.get_uri(buffer);
@ -167,6 +176,34 @@ pub fn get_completion(
}
}
pub fn get_code_actions(
&self,
id: RequestId,
buffer: &Buffer,
position: Position,
) {
if let Some(client) = self.clients.get(&buffer.language_id) {
let uri = client.get_uri(buffer);
let range = Range {
start: position,
end: position,
};
client.request_code_actions(uri, range, move |lsp_client, result| {
let mut resp = json!({ "id": id });
match result {
Ok(v) => resp["result"] = v,
Err(e) => {
resp["error"] = json!({
"code": 0,
"message": format!("{}",e),
})
}
}
lsp_client.dispatcher.sender.send(resp);
});
}
}
pub fn get_definition(
&self,
id: RequestId,
@ -511,6 +548,19 @@ pub fn send_initialize<CB>(&self, root_uri: Option<Url>, on_init: CB)
self.send_request("initialize", params, Box::new(on_init));
}
pub fn request_document_symbols<CB>(&self, document_uri: Url, cb: CB)
where
CB: 'static + Send + FnOnce(&LspClient, Result<Value>),
{
let params = DocumentSymbolParams {
text_document: TextDocumentIdentifier { uri: document_uri },
work_done_progress_params: WorkDoneProgressParams::default(),
partial_result_params: PartialResultParams::default(),
};
let params = Params::from(serde_json::to_value(params).unwrap());
self.send_request("textDocument/documentSymbol", params, Box::new(cb));
}
pub fn request_document_formatting<CB>(&self, document_uri: Url, cb: CB)
where
CB: 'static + Send + FnOnce(&LspClient, Result<Value>),
@ -541,6 +591,21 @@ pub fn request_semantic_tokens<CB>(&self, document_uri: Url, cb: CB)
self.send_request("textDocument/semanticTokens/full", params, Box::new(cb));
}
pub fn request_code_actions<CB>(&self, document_uri: Url, range: Range, cb: CB)
where
CB: 'static + Send + FnOnce(&LspClient, Result<Value>),
{
let params = CodeActionParams {
text_document: TextDocumentIdentifier { uri: document_uri },
range,
context: CodeActionContext::default(),
work_done_progress_params: WorkDoneProgressParams::default(),
partial_result_params: PartialResultParams::default(),
};
let params = Params::from(serde_json::to_value(params).unwrap());
self.send_request("textDocument/codeAction", params, Box::new(cb));
}
pub fn request_definition<CB>(
&self,
document_uri: Url,