on master help sign in
Added workspace_symbol_picker (#1041)

* Added workspace_symbol_picker * Moved truncation of the symbol pickers to the end. * Fixed typo

commitedc976b6bb36c6017bf59691abbde5c086267bfd authorEbbe Steenhoudt <ebbesteenhoudt@gmail.com> dateSun 14 Nov 2021, 16:12 (5 years ago) parent1817b7f
4 files changed+74−2
book/src/keymap.md+1 helix-term/src/commands.rs+65−1 helix-term/src/keymap.rs+1 helix-term/src/ui/picker.rs+7−1
book/src/keymap.md+1
@@ -211,6 +211,7 @@ This layer is a kludge of mappings, mostly pickers.
211211| `b` | Open buffer picker | `buffer_picker` |
212212| `k` | Show documentation for item under cursor (**LSP**) | `hover` |
213213| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
214+| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
214215| `r` | Rename symbol (**LSP**) | `rename_symbol` |
215216| `a` | Apply code action (**LSP**) | `code_action` |
216217| `'` | Open last fuzzy picker | `last_picker` |
helix-term/src/commands.rs+65−1
@@ -237,6 +237,7 @@ impl Command {
237237 code_action, "Perform code action",
238238 buffer_picker, "Open buffer picker",
239239 symbol_picker, "Open symbol picker",
240+ workspace_symbol_picker, "Open workspace symbol picker",
240241 last_picker, "Open last picker",
241242 prepend_to_line, "Insert at start of line",
242243 append_to_line, "Insert at end of line",
@@ -2723,7 +2724,7 @@ fn symbol_picker(cx: &mut Context) {
27232724 }
27242725 };
27252726
2726− let picker = FilePicker::new(
2727+ let mut picker = FilePicker::new(
27272728 symbols,
27282729 |symbol| (&symbol.name).into(),
27292730 move |editor: &mut Editor, symbol, _action| {
@@ -2748,6 +2749,69 @@ fn symbol_picker(cx: &mut Context) {
27482749 Some((path, line))
27492750 },
27502751 );
2752+ picker.truncate_start = false;
2753+ compositor.push(Box::new(picker))
2754+ }
2755+ },
2756+ )
2757+}
2758+
2759+fn workspace_symbol_picker(cx: &mut Context) {
2760+ let (_, doc) = current!(cx.editor);
2761+
2762+ let language_server = match doc.language_server() {
2763+ Some(language_server) => language_server,
2764+ None => return,
2765+ };
2766+ let offset_encoding = language_server.offset_encoding();
2767+
2768+ let future = language_server.workspace_symbols("".to_string());
2769+
2770+ let current_path = doc_mut!(cx.editor).path().cloned();
2771+ cx.callback(
2772+ future,
2773+ move |_editor: &mut Editor,
2774+ compositor: &mut Compositor,
2775+ response: Option<Vec<lsp::SymbolInformation>>| {
2776+ if let Some(symbols) = response {
2777+ let mut picker = FilePicker::new(
2778+ symbols,
2779+ move |symbol| {
2780+ let path = symbol.location.uri.to_file_path().unwrap();
2781+ if current_path.as_ref().map(|p| p == &path).unwrap_or(false) {
2782+ (&symbol.name).into()
2783+ } else {
2784+ let relative_path = helix_core::path::get_relative_path(path.as_path())
2785+ .to_str()
2786+ .unwrap()
2787+ .to_owned();
2788+ format!("{} ({})", &symbol.name, relative_path).into()
2789+ }
2790+ },
2791+ move |editor: &mut Editor, symbol, action| {
2792+ let path = symbol.location.uri.to_file_path().unwrap();
2793+ editor.open(path, action).expect("editor.open failed");
2794+ let (view, doc) = current!(editor);
2795+
2796+ if let Some(range) =
2797+ lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
2798+ {
2799+ // we flip the range so that the cursor sits on the start of the symbol
2800+ // (for example start of the function).
2801+ doc.set_selection(view.id, Selection::single(range.head, range.anchor));
2802+ align_view(doc, view, Align::Center);
2803+ }
2804+ },
2805+ move |_editor, symbol| {
2806+ let path = symbol.location.uri.to_file_path().unwrap();
2807+ let line = Some((
2808+ symbol.location.range.start.line as usize,
2809+ symbol.location.range.end.line as usize,
2810+ ));
2811+ Some((path, line))
2812+ },
2813+ );
2814+ picker.truncate_start = false;
27512815 compositor.push(Box::new(picker))
27522816 }
27532817 },
helix-term/src/keymap.rs+1
@@ -641,6 +641,7 @@ impl Default for Keymaps {
641641 "f" => file_picker,
642642 "b" => buffer_picker,
643643 "s" => symbol_picker,
644+ "S" => workspace_symbol_picker,
644645 "a" => code_action,
645646 "'" => last_picker,
646647 "w" => { "Window"
helix-term/src/ui/picker.rs+7−1
@@ -37,6 +37,7 @@ type FileLocation = (PathBuf, Option<(usize, usize)>);
3737
3838pub struct FilePicker<T> {
3939 picker: Picker<T>,
40+ pub truncate_start: bool,
4041 /// Caches paths to documents
4142 preview_cache: HashMap<PathBuf, CachedPreview>,
4243 read_buffer: Vec<u8>,
@@ -90,6 +91,7 @@ impl<T> FilePicker<T> {
9091 ) -> Self {
9192 Self {
9293 picker: Picker::new(false, options, format_fn, callback_fn),
94+ truncate_start: true,
9395 preview_cache: HashMap::new(),
9496 read_buffer: Vec::with_capacity(1024),
9597 file_fn: Box::new(preview_fn),
@@ -172,6 +174,7 @@ impl<T: 'static> Component for FilePicker<T> {
172174 };
173175
174176 let picker_area = area.with_width(picker_width);
177+ self.picker.truncate_start = self.truncate_start;
175178 self.picker.render(picker_area, surface, cx);
176179
177180 if !render_preview {
@@ -277,6 +280,8 @@ pub struct Picker<T> {
277280 prompt: Prompt,
278281 /// Whether to render in the middle of the area
279282 render_centered: bool,
283+ /// Wheather to truncate the start (default true)
284+ pub truncate_start: bool,
280285
281286 format_fn: Box<dyn Fn(&T) -> Cow<str>>,
282287 callback_fn: Box<dyn Fn(&mut Editor, &T, Action)>,
@@ -306,6 +311,7 @@ impl<T> Picker<T> {
306311 cursor: 0,
307312 prompt,
308313 render_centered,
314+ truncate_start: true,
309315 format_fn: Box::new(format_fn),
310316 callback_fn: Box::new(callback_fn),
311317 };
@@ -521,7 +527,7 @@ impl<T: 'static> Component for Picker<T> {
521527 text_style
522528 },
523529 true,
524− true,
530+ self.truncate_start,
525531 );
526532 }
527533 }