Fix newlines in language server logs when switching log types + misc (#32659)
Mistake in #31863 where the stored log entries no longer had a format that could simply have `\n` added after each entry. Also fixes a potential crash in the long line folding logic if unicode was in the logs - introduced in #22996. Also updates the log line truncation logic to never exceed the pre-allocated capacity Release Notes: - N/A
This commit is contained in:
parent
9a6e8a19b5
commit
babf846ef9
1 changed files with 47 additions and 40 deletions
|
@ -6,6 +6,7 @@ use gpui::{
|
||||||
AnyView, App, Context, Corner, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
|
AnyView, App, Context, Corner, Entity, EventEmitter, FocusHandle, Focusable, IntoElement,
|
||||||
ParentElement, Render, Styled, Subscription, WeakEntity, Window, actions, div,
|
ParentElement, Render, Styled, Subscription, WeakEntity, Window, actions, div,
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use language::{LanguageServerId, language_settings::SoftWrap};
|
use language::{LanguageServerId, language_settings::SoftWrap};
|
||||||
use lsp::{
|
use lsp::{
|
||||||
IoKind, LanguageServer, LanguageServerName, MessageType, SetTraceParams, TraceValue,
|
IoKind, LanguageServer, LanguageServerName, MessageType, SetTraceParams, TraceValue,
|
||||||
|
@ -20,8 +21,8 @@ use workspace::{
|
||||||
searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle},
|
searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle},
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEND_LINE: &str = "// Send:\n";
|
const SEND_LINE: &str = "\n// Send:";
|
||||||
const RECEIVE_LINE: &str = "// Receive:\n";
|
const RECEIVE_LINE: &str = "\n// Receive:";
|
||||||
const MAX_STORED_LOG_ENTRIES: usize = 2000;
|
const MAX_STORED_LOG_ENTRIES: usize = 2000;
|
||||||
|
|
||||||
pub struct LogStore {
|
pub struct LogStore {
|
||||||
|
@ -421,7 +422,7 @@ impl LogStore {
|
||||||
log_lines,
|
log_lines,
|
||||||
id,
|
id,
|
||||||
LogMessage {
|
LogMessage {
|
||||||
message: message.trim_end().to_string(),
|
message: message.trim().to_string(),
|
||||||
typ,
|
typ,
|
||||||
},
|
},
|
||||||
language_server_state.log_level,
|
language_server_state.log_level,
|
||||||
|
@ -444,7 +445,7 @@ impl LogStore {
|
||||||
log_lines,
|
log_lines,
|
||||||
id,
|
id,
|
||||||
TraceMessage {
|
TraceMessage {
|
||||||
message: message.trim_end().to_string(),
|
message: message.trim().to_string(),
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
LogKind::Trace,
|
LogKind::Trace,
|
||||||
|
@ -461,15 +462,15 @@ impl LogStore {
|
||||||
kind: LogKind,
|
kind: LogKind,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
while log_lines.len() >= MAX_STORED_LOG_ENTRIES {
|
while log_lines.len() + 1 >= MAX_STORED_LOG_ENTRIES {
|
||||||
log_lines.pop_front();
|
log_lines.pop_front();
|
||||||
}
|
}
|
||||||
let entry = format!("{}\n", message.as_ref().trim());
|
let text = message.as_ref().to_string();
|
||||||
let visible = message.should_include(current_severity);
|
let visible = message.should_include(current_severity);
|
||||||
log_lines.push_back(message);
|
log_lines.push_back(message);
|
||||||
|
|
||||||
if visible {
|
if visible {
|
||||||
cx.emit(Event::NewServerLogEntry { id, entry, kind });
|
cx.emit(Event::NewServerLogEntry { id, kind, text });
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,6 +557,9 @@ impl LogStore {
|
||||||
|
|
||||||
let rpc_log_lines = &mut state.rpc_messages;
|
let rpc_log_lines = &mut state.rpc_messages;
|
||||||
if state.last_message_kind != Some(kind) {
|
if state.last_message_kind != Some(kind) {
|
||||||
|
while rpc_log_lines.len() + 1 >= MAX_STORED_LOG_ENTRIES {
|
||||||
|
rpc_log_lines.pop_front();
|
||||||
|
}
|
||||||
let line_before_message = match kind {
|
let line_before_message = match kind {
|
||||||
MessageKind::Send => SEND_LINE,
|
MessageKind::Send => SEND_LINE,
|
||||||
MessageKind::Receive => RECEIVE_LINE,
|
MessageKind::Receive => RECEIVE_LINE,
|
||||||
|
@ -565,22 +569,23 @@ impl LogStore {
|
||||||
});
|
});
|
||||||
cx.emit(Event::NewServerLogEntry {
|
cx.emit(Event::NewServerLogEntry {
|
||||||
id: language_server_id,
|
id: language_server_id,
|
||||||
entry: line_before_message.to_string(),
|
|
||||||
kind: LogKind::Rpc,
|
kind: LogKind::Rpc,
|
||||||
|
text: line_before_message.to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
while rpc_log_lines.len() >= MAX_STORED_LOG_ENTRIES {
|
while rpc_log_lines.len() + 1 >= MAX_STORED_LOG_ENTRIES {
|
||||||
rpc_log_lines.pop_front();
|
rpc_log_lines.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = message.trim();
|
let message = message.trim();
|
||||||
rpc_log_lines.push_back(RpcMessage {
|
rpc_log_lines.push_back(RpcMessage {
|
||||||
message: message.to_string(),
|
message: message.to_string(),
|
||||||
});
|
});
|
||||||
cx.emit(Event::NewServerLogEntry {
|
cx.emit(Event::NewServerLogEntry {
|
||||||
id: language_server_id,
|
id: language_server_id,
|
||||||
entry: format!("{}\n\n", message),
|
|
||||||
kind: LogKind::Rpc,
|
kind: LogKind::Rpc,
|
||||||
|
text: message.to_string(),
|
||||||
});
|
});
|
||||||
cx.notify();
|
cx.notify();
|
||||||
Some(())
|
Some(())
|
||||||
|
@ -634,24 +639,37 @@ impl LspLogView {
|
||||||
&log_store,
|
&log_store,
|
||||||
window,
|
window,
|
||||||
move |log_view, _, e, window, cx| match e {
|
move |log_view, _, e, window, cx| match e {
|
||||||
Event::NewServerLogEntry { id, entry, kind } => {
|
Event::NewServerLogEntry { id, kind, text } => {
|
||||||
if log_view.current_server_id == Some(*id)
|
if log_view.current_server_id == Some(*id)
|
||||||
&& *kind == log_view.active_entry_kind
|
&& *kind == log_view.active_entry_kind
|
||||||
{
|
{
|
||||||
log_view.editor.update(cx, |editor, cx| {
|
log_view.editor.update(cx, |editor, cx| {
|
||||||
editor.set_read_only(false);
|
editor.set_read_only(false);
|
||||||
let last_point = editor.buffer().read(cx).len(cx);
|
let last_offset = editor.buffer().read(cx).len(cx);
|
||||||
let newest_cursor_is_at_end =
|
let newest_cursor_is_at_end =
|
||||||
editor.selections.newest::<usize>(cx).start >= last_point;
|
editor.selections.newest::<usize>(cx).start >= last_offset;
|
||||||
editor.edit(vec![(last_point..last_point, entry.as_str())], cx);
|
editor.edit(
|
||||||
let entry_length = entry.len();
|
vec![
|
||||||
if entry_length > 1024 {
|
(last_offset..last_offset, text.as_str()),
|
||||||
editor.fold_ranges(
|
(last_offset..last_offset, "\n"),
|
||||||
vec![last_point + 1024..last_point + entry_length],
|
],
|
||||||
false,
|
cx,
|
||||||
window,
|
);
|
||||||
cx,
|
if text.len() > 1024 {
|
||||||
);
|
if let Some((fold_offset, _)) =
|
||||||
|
text.char_indices().dropping(1024).next()
|
||||||
|
{
|
||||||
|
if fold_offset < text.len() {
|
||||||
|
editor.fold_ranges(
|
||||||
|
vec![
|
||||||
|
last_offset + fold_offset..last_offset + text.len(),
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if newest_cursor_is_at_end {
|
if newest_cursor_is_at_end {
|
||||||
|
@ -997,23 +1015,12 @@ impl LspLogView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_filter<T: Message>(line: &T, cmp: <T as Message>::Level) -> Option<&str> {
|
fn log_contents<T: Message>(lines: &VecDeque<T>, level: <T as Message>::Level) -> String {
|
||||||
if line.should_include(cmp) {
|
lines
|
||||||
Some(line.as_ref())
|
.iter()
|
||||||
} else {
|
.filter(|message| message.should_include(level))
|
||||||
None
|
.flat_map(|message| [message.as_ref(), "\n"])
|
||||||
}
|
.collect()
|
||||||
}
|
|
||||||
|
|
||||||
fn log_contents<T: Message>(lines: &VecDeque<T>, cmp: <T as Message>::Level) -> String {
|
|
||||||
let (a, b) = lines.as_slices();
|
|
||||||
let a = a.iter().filter_map(move |v| log_filter(v, cmp));
|
|
||||||
let b = b.iter().filter_map(move |v| log_filter(v, cmp));
|
|
||||||
a.chain(b).fold(String::new(), |mut acc, el| {
|
|
||||||
acc.push_str(el);
|
|
||||||
acc.push('\n');
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for LspLogView {
|
impl Render for LspLogView {
|
||||||
|
@ -1597,8 +1604,8 @@ impl LspLogToolbarItemView {
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
NewServerLogEntry {
|
NewServerLogEntry {
|
||||||
id: LanguageServerId,
|
id: LanguageServerId,
|
||||||
entry: String,
|
|
||||||
kind: LogKind,
|
kind: LogKind,
|
||||||
|
text: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue