go to references

This commit is contained in:
Dongdong Zhou 2020-12-08 22:05:50 +00:00
parent f97bb5da3f
commit 90c07ed78d
5 changed files with 180 additions and 43 deletions

View File

@ -100,6 +100,7 @@ pub struct EditorState {
pub header_height: f64,
pub locations: Vec<EditorLocation>,
pub current_location: usize,
pub saved_buffer_id: BufferId,
pub saved_selection: Selection,
pub saved_scroll_offset: Vec2,
}
@ -134,6 +135,7 @@ pub fn new(
header_height: 0.0,
locations: Vec::new(),
current_location: 0,
saved_buffer_id: BufferId(0),
saved_selection: Selection::new_simple(),
saved_scroll_offset: Vec2::ZERO,
}
@ -255,6 +257,27 @@ fn get_count(
.flatten())
}
fn window_portion(
&mut self,
ctx: &mut EventCtx,
portion: f64,
buffer: &mut Buffer,
env: &Env,
) {
let line_height = env.get(LapceTheme::EDITOR_LINE_HEIGHT);
let line = buffer.line_of_offset(self.selection.get_cursor_offset());
let y = if line as f64 * line_height > self.view_size.height * portion {
line as f64 * line_height - self.view_size.height * portion
} else {
0.0
};
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ScrollTo((0.0, y)),
Target::Widget(self.view_id),
));
}
fn center_of_window(
&mut self,
ctx: &mut EventCtx,
@ -1004,6 +1027,7 @@ pub fn notify_fill_text_layouts(
pub fn save_selection(&mut self) -> Option<()> {
let editor = self.editors.get_mut(&self.active)?;
editor.saved_buffer_id = editor.buffer_id.clone().unwrap();
editor.saved_selection = editor.selection.clone();
editor.saved_scroll_offset = editor.scroll_offset.clone();
None
@ -1015,17 +1039,21 @@ pub fn restore_selection(
ui_state: &mut LapceUIState,
) -> Option<()> {
let editor = self.editors.get_mut(&self.active)?;
let buffer_id = editor.saved_buffer_id;
editor.buffer_id = Some(buffer_id);
ui_state.get_editor_mut(&self.active).buffer_id = editor.saved_buffer_id;
let buffer = self.buffers.get(editor.buffer_id.as_ref()?)?;
editor.selection = editor.saved_selection.clone();
editor.update_ui_state(ui_state, buffer);
ctx.submit_command(Command::new(
LAPCE_UI_COMMAND,
LapceUICommand::ScrollTo((
LapceUICommand::ForceScrollTo(
editor.saved_scroll_offset.x,
editor.saved_scroll_offset.y,
)),
),
Target::Widget(editor.view_id),
));
self.notify_fill_text_layouts(ctx, &buffer_id);
None
}
@ -1042,12 +1070,13 @@ pub fn jump_to_postion(
let offset = buffer.offset_of_line(position.line as usize)
+ position.character as usize;
editor.selection = Selection::caret(offset);
editor.ensure_cursor_visible(
ctx,
buffer,
env,
Some(EnsureVisiblePosition::CenterOfWindow),
);
// editor.ensure_cursor_visible(
// ctx,
// buffer,
// env,
// Some(EnsureVisiblePosition::CenterOfWindow),
// );
editor.window_portion(ctx, 0.75, buffer, env);
editor.update_ui_state(ui_state, buffer);
self.notify_fill_text_layouts(ctx, &buffer_id);
None
@ -1073,12 +1102,13 @@ pub fn jump_to_line(
None,
None,
);
editor.ensure_cursor_visible(
ctx,
buffer,
env,
Some(EnsureVisiblePosition::CenterOfWindow),
);
editor.window_portion(ctx, 0.75, buffer, env);
// editor.ensure_cursor_visible(
// ctx,
// buffer,
// env,
// Some(EnsureVisiblePosition::CenterOfWindow),
// );
editor.update_ui_state(ui_state, buffer);
self.notify_fill_text_layouts(ctx, &buffer_id);
None
@ -1290,19 +1320,35 @@ pub fn get_references(&self) -> Option<()> {
let buffer = self.buffers.get(buffer_id)?;
let offset = editor.selection.get_cursor_offset();
let state = LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
let widget_id = self.widget_id;
let tab_id = self.tab_id;
state.clone().proxy.lock().as_ref().unwrap().get_references(
buffer.id,
buffer.offset_to_position(offset),
Box::new(move |result| {
// println!("getting references result {:?}", result);
if let Ok(res) = result {
println!(
"get references {}",
serde_json::to_string(&res).unwrap()
);
} else {
println!("get references {:?}", result);
};
let resp: Result<Vec<Location>, serde_json::Error> =
serde_json::from_value(res);
if let Ok(locations) = resp {
if locations.len() == 0 {
return;
}
if locations.len() == 1 {
LAPCE_APP_STATE.submit_ui_command(
LapceUICommand::GotoLocation(
locations[0].to_owned(),
),
widget_id,
);
return;
}
*state.focus.lock() = LapceFocus::Palette;
state.palette.lock().run_references(locations);
LAPCE_APP_STATE
.submit_ui_command(LapceUICommand::RequestPaint, tab_id);
}
}
}),
);
None
@ -1609,6 +1655,26 @@ pub fn jump_to_location(
None
}
pub fn go_to_location(
&mut self,
ctx: &mut EventCtx,
ui_state: &mut LapceUIState,
location: &Location,
env: &Env,
) {
self.save_jump_location();
let path = location.uri.path().to_string();
let buffer = self.get_buffer_from_path(ctx, ui_state, &path);
let offset = buffer.offset_of_line(location.range.start.line as usize)
+ location.range.start.character as usize;
let location = EditorLocation {
path,
offset,
scroll_offset: None,
};
self.jump_to_location(ctx, ui_state, &location, env);
}
pub fn go_to_definition(
&mut self,
request_id: usize,
@ -2694,6 +2760,22 @@ pub fn run_command(
None
}
pub fn window_portion(
&mut self,
ctx: &mut EventCtx,
portion: f64,
env: &Env,
) -> Option<()> {
let editor = self.editors.get_mut(&self.active)?;
let buffer_id = editor.buffer_id.as_ref()?;
let buffer = self.buffers.get_mut(buffer_id)?;
editor.window_portion(ctx, portion, buffer, env);
let editor = self.editors.get(&self.active)?;
let buffer_id = editor.buffer_id.as_ref()?;
self.notify_fill_text_layouts(ctx, buffer_id);
None
}
pub fn buffer_request_layout(&self, buffer_id: &BufferId) {
for (_, editor) in &self.editors {
if let Some(b) = &editor.buffer_id {
@ -3881,7 +3963,8 @@ fn paint(&mut self, ctx: &mut PaintCtx, data: &LapceUIState, env: &Env) {
..buffer.offset_of_line(line + 1),
)
.to_string();
if *focus == LapceFocus::Editor
if (*focus == LapceFocus::Editor
|| *focus == LapceFocus::Palette)
&& editor_split.active == self.view_id
{
let cursor_x =

View File

@ -52,6 +52,7 @@ pub enum PaletteType {
DocumentSymbol,
Workspace,
Command,
Reference,
}
#[derive(Clone, Debug, PartialEq)]
@ -73,6 +74,7 @@ pub struct PaletteItem {
index: usize,
match_mask: BitVec,
position: Option<Position>,
location: Option<Location>,
path: Option<PathBuf>,
workspace: Option<LapceWorkspace>,
command: Option<LapceCommand>,
@ -151,6 +153,41 @@ pub fn run(&mut self, palette_type: Option<PaletteType>) {
}
}
pub fn run_references(&mut self, locations: Vec<Location>) {
self.palette_type = PaletteType::Reference;
self.run_id = Uuid::new_v4().to_string();
self.rev += 1;
let window_id = self.window_id;
let tab_id = self.tab_id;
let items = locations
.iter()
.map(|location| PaletteItem {
window_id,
tab_id,
kind: PaletteType::Reference,
text: location.uri.as_str().to_string(),
hint: None,
position: None,
location: Some(location.clone()),
path: None,
score: 0.0,
index: 0,
match_mask: BitVec::new(),
icon: PaletteIcon::None,
workspace: None,
command: None,
})
.collect::<Vec<PaletteItem>>();
self.items = items;
LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id)
.editor_split
.lock()
.save_selection();
LAPCE_APP_STATE
.submit_ui_command(LapceUICommand::FilterItems, self.widget_id);
}
pub fn cancel(&mut self, ctx: &mut EventCtx, ui_state: &mut LapceUIState) {
match &self.palette_type {
&PaletteType::Line => {
@ -167,6 +204,13 @@ pub fn cancel(&mut self, ctx: &mut EventCtx, ui_state: &mut LapceUIState) {
.lock()
.restore_selection(ctx, ui_state);
}
&PaletteType::Reference => {
LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id)
.editor_split
.lock()
.restore_selection(ctx, ui_state);
}
_ => (),
}
self.reset(ctx);
@ -197,6 +241,9 @@ fn ensure_visible(&self, ctx: &mut EventCtx, env: &Env) {
pub fn key_event(&mut self, key: &KeyEvent) {}
fn get_palette_type(&self) -> PaletteType {
if self.palette_type == PaletteType::Reference {
return PaletteType::Reference;
}
if self.input == "" {
return PaletteType::File;
}
@ -238,6 +285,7 @@ fn update_palette(&mut self) {
}
&PaletteType::Workspace => self.items = self.get_workspaces(),
&PaletteType::Command => self.items = self.get_commands(),
_ => (),
}
LAPCE_APP_STATE
.submit_ui_command(LapceUICommand::RequestPaint, self.widget_id);
@ -287,6 +335,7 @@ pub fn delete_to_beginning_of_line(
let start = match &self.palette_type {
&PaletteType::File => 0,
&PaletteType::Reference => 0,
&PaletteType::Line => 1,
&PaletteType::DocumentSymbol => 1,
&PaletteType::Workspace => 1,
@ -306,6 +355,7 @@ pub fn delete_to_beginning_of_line(
pub fn get_input(&self) -> &str {
match &self.palette_type {
PaletteType::File => &self.input,
PaletteType::Reference => &self.input,
PaletteType::Line => &self.input[1..],
PaletteType::DocumentSymbol => &self.input[1..],
PaletteType::Workspace => &self.input[1..],
@ -330,6 +380,7 @@ fn get_commands(&self) -> Vec<PaletteItem> {
match_mask: BitVec::new(),
workspace: None,
position: None,
location: None,
path: None,
command: Some(c.1.clone()),
})
@ -389,6 +440,7 @@ fn get_workspaces(&self) -> Vec<PaletteItem> {
kind: PaletteType::Workspace,
text,
hint: None,
location: None,
score: 0.0,
index: i,
match_mask: BitVec::new(),
@ -438,6 +490,7 @@ fn get_document_symbols(&self) -> Option<()> {
hint: s.container_name.clone(),
position: Some(s.location.range.start),
path: None,
location: None,
score: 0.0,
index: i,
match_mask: BitVec::new(),
@ -456,6 +509,7 @@ fn get_document_symbols(&self) -> Option<()> {
text: s.name.clone(),
hint: None,
path: None,
location: None,
position: Some(s.range.start),
score: 0.0,
index: i,
@ -541,6 +595,7 @@ fn get_lines(&self) -> Option<Vec<PaletteItem>> {
hint: None,
position: None,
path: None,
location: None,
score: 0.0,
index: i,
match_mask: BitVec::new(),
@ -624,6 +679,7 @@ fn get_files(&self) {
hint: Some(hint),
position: None,
path: Some(path.clone()),
location: None,
score: 0.0,
index,
match_mask: BitVec::new(),
@ -710,6 +766,7 @@ fn get_ssh_files(&self, user: &str, host: &str) -> Vec<PaletteItem> {
kind: PaletteType::File,
text,
position: None,
location: None,
path: Some(path),
score: 0.0,
match_mask: BitVec::new(),
@ -780,6 +837,7 @@ fn get_local_files(&self) -> Vec<PaletteItem> {
hint: Some(hint),
position: None,
path: Some(path),
location: None,
score: 0.0,
index,
match_mask: BitVec::new(),
@ -825,6 +883,9 @@ pub fn preview(
&PaletteType::Line => {
item.select(ctx, ui_state, env);
}
&PaletteType::Reference => {
item.select(ctx, ui_state, env);
}
&PaletteType::DocumentSymbol => {
item.select(ctx, ui_state, env);
}
@ -1479,6 +1540,18 @@ pub fn select(
env,
);
}
&PaletteType::Reference => {
let state =
LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
let mut editor_split = state.editor_split.lock();
editor_split.go_to_location(
ctx,
ui_state,
self.location.as_ref().unwrap(),
env,
);
editor_split.window_portion(ctx, 0.75, env);
}
}
}
}

View File

@ -218,18 +218,7 @@ fn event(
let state = LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id);
let mut editor_split = state.editor_split.lock();
editor_split.save_jump_location();
let path = location.uri.path().to_string();
let buffer =
editor_split.get_buffer_from_path(ctx, data, &path);
let location = EditorLocation {
path,
offset: buffer.offset_of_line(
location.range.start.line as usize,
) + location.range.start.character as usize,
scroll_offset: None,
};
editor_split.jump_to_location(ctx, data, &location, env);
editor_split.go_to_location(ctx, data, location, env);
}
LapceUICommand::Split(vertical) => {
if self.children.len() <= 1 {

View File

@ -252,14 +252,6 @@ pub fn get_tab_state(
.clone()
}
pub fn submit_command(&self, comand: LapceCommand, widget_id: WidgetId) {
self.ui_sink.lock().as_ref().unwrap().submit_command(
LAPCE_COMMAND,
comand,
Target::Widget(widget_id),
);
}
pub fn submit_ui_command(&self, comand: LapceUICommand, widget_id: WidgetId) {
self.ui_sink.lock().as_ref().unwrap().submit_command(
LAPCE_UI_COMMAND,

View File

@ -662,7 +662,7 @@ pub fn request_references<CB>(
work_done_progress_params: WorkDoneProgressParams::default(),
partial_result_params: PartialResultParams::default(),
context: ReferenceContext {
include_declaration: true,
include_declaration: false,
},
};
let params = Params::from(serde_json::to_value(params).unwrap());