@@ -237,6 +237,7 @@ impl Command {
237 code_action, "Perform code action",
237 code_action, "Perform code action",
238 buffer_picker, "Open buffer picker",
238 buffer_picker, "Open buffer picker",
239 symbol_picker, "Open symbol picker",
239 symbol_picker, "Open symbol picker",
240+ workspace_symbol_picker, "Open workspace symbol picker",
240 last_picker, "Open last picker",
241 last_picker, "Open last picker",
241 prepend_to_line, "Insert at start of line",
242 prepend_to_line, "Insert at start of line",
242 append_to_line, "Insert at end of line",
243 append_to_line, "Insert at end of line",
@@ -2723,7 +2724,7 @@ fn symbol_picker(cx: &mut Context) {
2726− let picker = FilePicker::new(
2727+ let mut picker = FilePicker::new(
2727 symbols,
2728 symbols,
2728 |symbol| (&symbol.name).into(),
2729 |symbol| (&symbol.name).into(),
2729 move |editor: &mut Editor, symbol, _action| {
2730 move |editor: &mut Editor, symbol, _action| {
@@ -2748,6 +2749,69 @@ fn symbol_picker(cx: &mut Context) {
2748 Some((path, line))
2749 Some((path, line))
2752+ picker.truncate_start = false;
2753+ compositor.push(Box::new(picker))
2759+fn workspace_symbol_picker(cx: &mut Context) {
2760+ let (_, doc) = current!(cx.editor);
2762+ let language_server = match doc.language_server() {
2763+ Some(language_server) => language_server,
2766+ let offset_encoding = language_server.offset_encoding();
2768+ let future = language_server.workspace_symbols("".to_string());
2770+ let current_path = doc_mut!(cx.editor).path().cloned();
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(
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()
2784+ let relative_path = helix_core::path::get_relative_path(path.as_path())
2788+ format!("{} ({})", &symbol.name, relative_path).into()
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);
2796+ if let Some(range) =
2797+ lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
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);
2805+ move |_editor, symbol| {
2806+ let path = symbol.location.uri.to_file_path().unwrap();
2808+ symbol.location.range.start.line as usize,
2809+ symbol.location.range.end.line as usize,
2814+ picker.truncate_start = false;
2751 compositor.push(Box::new(picker))
2815 compositor.push(Box::new(picker))