1use super::Editor;
7use crate::input::commands::Suggestion;
8use crate::view::prompt::{Prompt, PromptType};
9use rust_i18n::t;
10
11impl Editor {
12 pub fn handle_lsp_restart(&mut self) {
17 let Some(metadata) = self.buffer_metadata.get(&self.active_buffer()) else {
19 return;
20 };
21
22 let Some(path) = metadata.file_path() else {
23 self.set_status_message(t!("lsp.buffer_has_no_file").to_string());
24 return;
25 };
26
27 let Some(language) =
28 crate::services::lsp::manager::detect_language(path, &self.config.languages)
29 else {
30 self.set_status_message(t!("lsp.no_server_configured").to_string());
31 return;
32 };
33
34 let Some(lsp) = self.lsp.as_mut() else {
36 self.set_status_message(t!("lsp.no_manager").to_string());
37 return;
38 };
39
40 let (success, message) = lsp.manual_restart(&language);
41 self.status_message = Some(message);
42
43 if !success {
44 return;
45 }
46
47 self.reopen_buffers_for_language(&language);
49 }
50
51 fn reopen_buffers_for_language(&mut self, language: &str) {
55 let buffers_for_language: Vec<_> = self
57 .buffer_metadata
58 .iter()
59 .filter_map(|(buf_id, meta)| {
60 let path = meta.file_path()?;
61 let detected =
62 crate::services::lsp::manager::detect_language(path, &self.config.languages)?;
63 if detected == language {
64 Some((*buf_id, path.clone()))
65 } else {
66 None
67 }
68 })
69 .collect();
70
71 for (buffer_id, buf_path) in buffers_for_language {
72 let Some(state) = self.buffers.get(&buffer_id) else {
73 continue;
74 };
75
76 let Some(content) = state.buffer.to_string() else {
77 continue; };
79
80 let Some(uri) = url::Url::from_file_path(&buf_path)
81 .ok()
82 .and_then(|u| u.as_str().parse::<lsp_types::Uri>().ok())
83 else {
84 continue;
85 };
86
87 let Some(lang_id) =
88 crate::services::lsp::manager::detect_language(&buf_path, &self.config.languages)
89 else {
90 continue;
91 };
92
93 if let Some(lsp) = self.lsp.as_mut() {
94 use crate::services::lsp::manager::LspSpawnResult;
96 if lsp.try_spawn(&lang_id) == LspSpawnResult::Spawned {
97 if let Some(handle) = lsp.get_handle_mut(&lang_id) {
98 let _ = handle.did_open(uri, content, lang_id);
99 }
100 }
101 }
102 }
103 }
104
105 pub fn handle_lsp_stop(&mut self) {
110 let running_servers: Vec<String> = self
111 .lsp
112 .as_ref()
113 .map(|lsp| lsp.running_servers())
114 .unwrap_or_default();
115
116 if running_servers.is_empty() {
117 self.set_status_message(t!("lsp.no_servers_running").to_string());
118 return;
119 }
120
121 let suggestions: Vec<Suggestion> = running_servers
123 .iter()
124 .map(|lang| {
125 let description = self
126 .lsp
127 .as_ref()
128 .and_then(|lsp| lsp.get_config(lang))
129 .filter(|c| !c.command.is_empty())
130 .map(|c| format!("Command: {}", c.command));
131
132 Suggestion {
133 text: lang.clone(),
134 description,
135 value: Some(lang.clone()),
136 disabled: false,
137 keybinding: None,
138 source: None,
139 }
140 })
141 .collect();
142
143 self.prompt = Some(Prompt::with_suggestions(
145 "Stop LSP server: ".to_string(),
146 PromptType::StopLspServer,
147 suggestions,
148 ));
149
150 if let Some(prompt) = self.prompt.as_mut() {
152 if running_servers.len() == 1 {
153 prompt.input = running_servers[0].clone();
155 prompt.cursor_pos = prompt.input.len();
156 prompt.selected_suggestion = Some(0);
157 } else if !prompt.suggestions.is_empty() {
158 prompt.selected_suggestion = Some(0);
160 }
161 }
162 }
163}