Add a rough prototype

This commit is contained in:
Kirill Bulatov 2023-10-17 12:11:39 +03:00
parent 31241f48be
commit 33296802fb

View File

@ -36,7 +36,7 @@ struct ProjectState {
}
struct LanguageServerState {
log_buffer: ModelHandle<Buffer>,
log_storage: Vec<String>,
rpc_state: Option<LanguageServerRpcState>,
_io_logs_subscription: Option<lsp::Subscription>,
_lsp_logs_subscription: Option<lsp::Subscription>,
@ -168,15 +168,14 @@ impl LogStore {
project: &ModelHandle<Project>,
id: LanguageServerId,
cx: &mut ModelContext<Self>,
) -> Option<ModelHandle<Buffer>> {
) -> Option<&mut Vec<String>> {
let project_state = self.projects.get_mut(&project.downgrade())?;
let server_state = project_state.servers.entry(id).or_insert_with(|| {
cx.notify();
LanguageServerState {
rpc_state: None,
log_buffer: cx
.add_model(|cx| Buffer::new(0, cx.model_id() as u64, ""))
.clone(),
// TODO kb move this to settings?
log_storage: Vec::with_capacity(10_000),
_io_logs_subscription: None,
_lsp_logs_subscription: None,
}
@ -186,7 +185,7 @@ impl LogStore {
if let Some(server) = server.as_deref() {
if server.has_notification_handler::<lsp::notification::LogMessage>() {
// Another event wants to re-add the server that was already added and subscribed to, avoid doing it again.
return Some(server_state.log_buffer.clone());
return Some(&mut server_state.log_storage);
}
}
@ -215,7 +214,7 @@ impl LogStore {
}
})
});
Some(server_state.log_buffer.clone())
Some(&mut server_state.log_storage)
}
fn add_language_server_log(
@ -225,25 +224,23 @@ impl LogStore {
message: &str,
cx: &mut ModelContext<Self>,
) -> Option<()> {
let buffer = match self
let log_lines = match self
.projects
.get_mut(&project.downgrade())?
.servers
.get(&id)
.map(|state| state.log_buffer.clone())
.get_mut(&id)
.map(|state| &mut state.log_storage)
{
Some(existing_buffer) => existing_buffer,
None => self.add_language_server(&project, id, cx)?,
};
buffer.update(cx, |buffer, cx| {
let len = buffer.len();
let has_newline = message.ends_with("\n");
buffer.edit([(len..len, message)], None, cx);
if !has_newline {
let len = buffer.len();
buffer.edit([(len..len, "\n")], None, cx);
}
});
// TODO kb something better VecDequeue?
if log_lines.capacity() == log_lines.len() {
log_lines.drain(..log_lines.len() / 2);
}
log_lines.push(message.trim().to_string());
cx.notify();
Some(())
}
@ -260,15 +257,15 @@ impl LogStore {
Some(())
}
pub fn log_buffer_for_server(
fn server_logs(
&self,
project: &ModelHandle<Project>,
server_id: LanguageServerId,
) -> Option<ModelHandle<Buffer>> {
) -> Option<&[String]> {
let weak_project = project.downgrade();
let project_state = self.projects.get(&weak_project)?;
let server_state = project_state.servers.get(&server_id)?;
Some(server_state.log_buffer.clone())
Some(&server_state.log_storage)
}
fn enable_rpc_trace_for_language_server(
@ -487,14 +484,24 @@ impl LspLogView {
}
fn show_logs_for_server(&mut self, server_id: LanguageServerId, cx: &mut ViewContext<Self>) {
let buffer = self
let log_contents = self
.log_store
.read(cx)
.log_buffer_for_server(&self.project, server_id);
if let Some(buffer) = buffer {
.server_logs(&self.project, server_id)
.map(|lines| lines.join("\n"));
if let Some(log_contents) = log_contents {
self.current_server_id = Some(server_id);
self.is_showing_rpc_trace = false;
self.editor = Self::editor_for_buffer(self.project.clone(), buffer, cx);
let buffer = cx.add_model(|cx| Buffer::new(0, cx.model_id() as u64, log_contents));
let editor = cx.add_view(|cx| {
let mut editor = Editor::for_buffer(buffer, Some(self.project.clone()), cx);
editor.set_read_only(true);
editor.move_to_end(&Default::default(), cx);
editor
});
cx.subscribe(&editor, |_, _, event, cx| cx.emit(event.clone()))
.detach();
self.editor = editor;
cx.notify();
}
}
@ -505,6 +512,7 @@ impl LspLogView {
cx: &mut ViewContext<Self>,
) {
let buffer = self.log_store.update(cx, |log_set, cx| {
// TODO kb save this buffer from overflows too
log_set.enable_rpc_trace_for_language_server(&self.project, server_id, cx)
});
if let Some(buffer) = buffer {