feat(lsp): implement LSP client and server management

- Added LspClient for handling communication with LSP servers, including methods for initialization, notifications, and requests.
- Introduced LspManager to manage multiple LSP server connections, allowing for connection, disconnection, and retrieval of server capabilities.
- Created tools for connecting to LSP servers, retrieving diagnostics, hover information, code completion, definitions, and references.
- Enhanced UI rendering to display token usage and settings in the overlay.
- Updated status bar to show current token usage and selected provider/model.
This commit is contained in:
asepharyana
2026-07-12 13:40:58 +07:00
parent 8ad042139e
commit abc7a58e31
19 changed files with 1317 additions and 60 deletions
+31 -2
View File
@@ -50,9 +50,38 @@ pub fn draw_status_bar(frame: &mut Frame, area: Rect, state: &crate::app::state:
status,
];
// Right chunk: provider · model
// Right chunk: token usage, provider, model
let right_str = if let Some(ref rt) = state.session_runtime {
let max_tokens = state.app_config.model_roles.values()
.find(|role| role.provider == state.settings.provider && role.model == state.settings.model)
.and_then(|role| role.context_window);
let total_chars: usize = rt.messages.iter()
.filter_map(|m| m.content.as_deref())
.map(|c| c.len())
.sum();
let current_tokens = total_chars / 4;
let mut parts = Vec::new();
if rt.usage.last_tokens_in > 0 || rt.usage.last_tokens_out > 0 {
parts.push(format!("{}{}", rt.usage.last_tokens_in, rt.usage.last_tokens_out));
}
let max_str = max_tokens.map(|v| v.to_string()).unwrap_or_else(|| "?".to_string());
parts.push(format!("{}/{}", current_tokens, max_str));
parts.push(state.settings.provider.clone());
parts.push(state.settings.model.clone());
format!(" {} ", parts.join(" · "))
} else {
let max_tokens = state.app_config.model_roles.values()
.find(|role| role.provider == state.settings.provider && role.model == state.settings.model)
.and_then(|role| role.context_window);
let max_str = max_tokens.map(|v| v.to_string()).unwrap_or_else(|| "?".to_string());
format!(" 0/{} · {} · {} ", max_str, state.settings.provider, state.settings.model)
};
spans.push(Span::styled(
format!(" {} · {} ", state.settings.provider, state.settings.model),
right_str,
Style::default().fg(Theme::DIM),
));