Skip to content
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

Added workspace_symbol_picker #1041

Merged
merged 3 commits into from
Nov 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/keymap.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ This layer is a kludge of mappings, mostly pickers.
| `b` | Open buffer picker | `buffer_picker` |
| `k` | Show documentation for item under cursor (**LSP**) | `hover` |
| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
| `r` | Rename symbol (**LSP**) | `rename_symbol` |
| `a` | Apply code action (**LSP**) | `code_action` |
| `'` | Open last fuzzy picker | `last_picker` |
Expand Down
66 changes: 65 additions & 1 deletion helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impl Command {
code_action, "Perform code action",
buffer_picker, "Open buffer picker",
symbol_picker, "Open symbol picker",
workspace_symbol_picker, "Open workspace symbol picker",
last_picker, "Open last picker",
prepend_to_line, "Insert at start of line",
append_to_line, "Insert at end of line",
Expand Down Expand Up @@ -2724,7 +2725,7 @@ fn symbol_picker(cx: &mut Context) {
}
};

let picker = FilePicker::new(
let mut picker = FilePicker::new(
symbols,
|symbol| (&symbol.name).into(),
move |editor: &mut Editor, symbol, _action| {
Expand All @@ -2749,6 +2750,69 @@ fn symbol_picker(cx: &mut Context) {
Some((path, line))
},
);
picker.truncate_start = false;
compositor.push(Box::new(picker))
}
},
)
}

fn workspace_symbol_picker(cx: &mut Context) {
let (_, doc) = current!(cx.editor);

let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};
let offset_encoding = language_server.offset_encoding();

let future = language_server.workspace_symbols("".to_string());

let current_path = doc_mut!(cx.editor).path().cloned();
cx.callback(
future,
move |_editor: &mut Editor,
compositor: &mut Compositor,
response: Option<Vec<lsp::SymbolInformation>>| {
if let Some(symbols) = response {
let mut picker = FilePicker::new(
symbols,
move |symbol| {
let path = symbol.location.uri.to_file_path().unwrap();
if current_path.as_ref().map(|p| p == &path).unwrap_or(false) {
(&symbol.name).into()
} else {
let relative_path = helix_core::path::get_relative_path(path.as_path())
.to_str()
.unwrap()
.to_owned();
format!("{} ({})", &symbol.name, relative_path).into()
}
},
move |editor: &mut Editor, symbol, action| {
let path = symbol.location.uri.to_file_path().unwrap();
editor.open(path, action).expect("editor.open failed");
let (view, doc) = current!(editor);

if let Some(range) =
lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
{
// we flip the range so that the cursor sits on the start of the symbol
// (for example start of the function).
doc.set_selection(view.id, Selection::single(range.head, range.anchor));
align_view(doc, view, Align::Center);
}
},
move |_editor, symbol| {
let path = symbol.location.uri.to_file_path().unwrap();
let line = Some((
symbol.location.range.start.line as usize,
symbol.location.range.end.line as usize,
));
Some((path, line))
},
);
picker.truncate_start = false;
compositor.push(Box::new(picker))
}
},
Expand Down
1 change: 1 addition & 0 deletions helix-term/src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ impl Default for Keymaps {
"f" => file_picker,
"b" => buffer_picker,
"s" => symbol_picker,
"S" => workspace_symbol_picker,
"a" => code_action,
"'" => last_picker,
"w" => { "Window"
Expand Down
8 changes: 7 additions & 1 deletion helix-term/src/ui/picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type FileLocation = (PathBuf, Option<(usize, usize)>);

pub struct FilePicker<T> {
picker: Picker<T>,
pub truncate_start: bool,
/// Caches paths to documents
preview_cache: HashMap<PathBuf, CachedPreview>,
read_buffer: Vec<u8>,
Expand Down Expand Up @@ -90,6 +91,7 @@ impl<T> FilePicker<T> {
) -> Self {
Self {
picker: Picker::new(false, options, format_fn, callback_fn),
truncate_start: true,
preview_cache: HashMap::new(),
read_buffer: Vec::with_capacity(1024),
file_fn: Box::new(preview_fn),
Expand Down Expand Up @@ -172,6 +174,7 @@ impl<T: 'static> Component for FilePicker<T> {
};

let picker_area = area.with_width(picker_width);
self.picker.truncate_start = self.truncate_start;
self.picker.render(picker_area, surface, cx);

if !render_preview {
Expand Down Expand Up @@ -277,6 +280,8 @@ pub struct Picker<T> {
prompt: Prompt,
/// Whether to render in the middle of the area
render_centered: bool,
/// Wheather to truncate the start (default true)
pub truncate_start: bool,

format_fn: Box<dyn Fn(&T) -> Cow<str>>,
callback_fn: Box<dyn Fn(&mut Editor, &T, Action)>,
Expand Down Expand Up @@ -306,6 +311,7 @@ impl<T> Picker<T> {
cursor: 0,
prompt,
render_centered,
truncate_start: true,
format_fn: Box::new(format_fn),
callback_fn: Box::new(callback_fn),
};
Expand Down Expand Up @@ -521,7 +527,7 @@ impl<T: 'static> Component for Picker<T> {
text_style
},
true,
true,
self.truncate_start,
);
}
}
Expand Down