|
| 1 | +use collections::HashSet; |
| 2 | +use editor::Editor; |
| 3 | +use gpui::{Entity, WeakEntity}; |
| 4 | +use project::LspStore; |
1 | 5 | use ui::{IconButtonShape, Tooltip, prelude::*}; |
2 | | -use workspace::StatusItemView; |
| 6 | +use workspace::{StatusItemView, Workspace}; |
3 | 7 |
|
4 | | -pub struct LspTool {} |
| 8 | +pub struct LspTool { |
| 9 | + active_editor: Option<WeakEntity<Editor>>, |
| 10 | + lsp_store: Entity<LspStore>, |
| 11 | +} |
5 | 12 |
|
6 | 13 | impl LspTool { |
7 | | - pub fn new() -> Self { |
8 | | - Self {} |
| 14 | + pub fn new(workspace: &Workspace, cx: &App) -> Self { |
| 15 | + let lsp_store = workspace.project().read(cx).lsp_store(); |
| 16 | + Self { |
| 17 | + active_editor: None, |
| 18 | + lsp_store, |
| 19 | + } |
9 | 20 | } |
10 | 21 | } |
11 | 22 |
|
12 | 23 | impl StatusItemView for LspTool { |
13 | 24 | fn set_active_pane_item( |
14 | 25 | &mut self, |
15 | | - _active_pane_item: Option<&dyn workspace::ItemHandle>, |
| 26 | + active_pane_item: Option<&dyn workspace::ItemHandle>, |
16 | 27 | _window: &mut ui::Window, |
17 | | - _cx: &mut ui::Context<Self>, |
| 28 | + cx: &mut ui::Context<Self>, |
18 | 29 | ) { |
19 | | - // TODO kb see inline_completion_button.rs |
| 30 | + self.active_editor = active_pane_item |
| 31 | + .and_then(|item| item.downcast::<Editor>().map(|editor| editor.downgrade())); |
| 32 | + cx.notify(); |
20 | 33 | } |
21 | 34 | } |
22 | 35 |
|
23 | 36 | impl Render for LspTool { |
24 | | - // TODO kb won't work for remote clients, disable for now |
| 37 | + // TODO kb won't work for remote clients for now |
25 | 38 | // TODO kb add a setting to remove this button out of the status bar |
26 | 39 | fn render( |
27 | 40 | &mut self, |
28 | 41 | _window: &mut ui::Window, |
29 | 42 | cx: &mut ui::Context<Self>, |
30 | 43 | ) -> impl ui::IntoElement { |
| 44 | + let Some(editor) = self |
| 45 | + .active_editor |
| 46 | + .as_ref() |
| 47 | + .and_then(|editor| editor.upgrade()) |
| 48 | + else { |
| 49 | + return div(); |
| 50 | + }; |
| 51 | + |
| 52 | + let buffers = editor.read(cx).buffer().read(cx).all_buffers(); |
| 53 | + let mut server_ids = HashSet::default(); |
| 54 | + let applicable_language_servers = self.lsp_store.update(cx, |lsp_store, cx| { |
| 55 | + buffers |
| 56 | + .iter() |
| 57 | + .flat_map(|buffer| { |
| 58 | + buffer.update(cx, |buffer, cx| { |
| 59 | + lsp_store |
| 60 | + .language_servers_for_local_buffer(buffer, cx) |
| 61 | + .filter(|(_, server)| server_ids.insert(server.server_id())) |
| 62 | + .map(|(adapter, server)| (adapter.clone(), server.clone())) |
| 63 | + .collect::<Vec<_>>() |
| 64 | + }) |
| 65 | + }) |
| 66 | + .collect::<Vec<_>>() |
| 67 | + }); |
| 68 | + dbg!(applicable_language_servers.len()); |
| 69 | + if applicable_language_servers.is_empty() { |
| 70 | + return div(); |
| 71 | + } |
| 72 | + |
31 | 73 | div().child( |
32 | 74 | IconButton::new("zed-lsp-tool-button", IconName::Bolt) |
33 | 75 | .shape(IconButtonShape::Square) |
|
0 commit comments