Skip to content

Commit

Permalink
feat: react to lsp folder changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ebastien committed Jan 8, 2024
1 parent 5dbd58b commit 84dedba
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
46 changes: 36 additions & 10 deletions oal-client/src/bin/oal-lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ use anyhow::anyhow;
use crossbeam_channel::select;
use lsp_server::{Connection, Message, Notification};
use lsp_types::notification::{
DidChangeTextDocument, DidCloseTextDocument, DidOpenTextDocument, PublishDiagnostics,
DidChangeTextDocument, DidChangeWorkspaceFolders, DidCloseTextDocument, DidOpenTextDocument,
PublishDiagnostics,
};
use lsp_types::request::{GotoDefinition, PrepareRenameRequest, References, Rename};
use lsp_types::{
InitializeParams, PositionEncodingKind, PublishDiagnosticsParams, ServerCapabilities,
TextDocumentSyncCapability, TextDocumentSyncKind,
TextDocumentSyncCapability, TextDocumentSyncKind, WorkspaceFileOperationsServerCapabilities,
WorkspaceFoldersServerCapabilities, WorkspaceServerCapabilities,
};
use lsp_types::{OneOf, RenameOptions};
use oal_client::lsp::dispatcher::{NotificationDispatcher, RequestDispatcher};
use oal_client::lsp::state::GlobalState;
use oal_client::lsp::{handlers, Folder, Workspace};
use std::collections::HashMap;
use std::time::Duration;

fn main() -> anyhow::Result<()> {
Expand All @@ -35,6 +38,16 @@ fn main() -> anyhow::Result<()> {
prepare_provider: Some(true),
work_done_progress_options: Default::default(),
})),
workspace: Some(WorkspaceServerCapabilities {
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
supported: Some(true),
change_notifications: Some(OneOf::Left(true)),
}),
file_operations: Some(WorkspaceFileOperationsServerCapabilities {
// TODO: register for operations on configuration files
..Default::default()
}),
}),
..Default::default()
})
.unwrap();
Expand All @@ -49,12 +62,13 @@ fn main() -> anyhow::Result<()> {
.and_then(|e| e.contains(&PositionEncodingKind::UTF16).then_some(()))
.ok_or_else(|| anyhow!("UTF-16 not supported by client"))?;

let folders = params
.workspace_folders
.unwrap_or_default()
.into_iter()
.flat_map(Folder::new)
.collect::<Vec<_>>();
let mut folders = HashMap::new();
for f in params.workspace_folders.unwrap_or_default().into_iter() {
let uri = f.uri.clone();
if let Ok(folder) = Folder::new(f) {
folders.insert(uri, folder);
}
}

let workspace = Workspace::default();

Expand Down Expand Up @@ -88,7 +102,7 @@ fn refresh(state: &mut GlobalState) -> anyhow::Result<()> {
return Ok(());
}
state.is_stale = false;
for f in state.folders.iter_mut() {
for (_, f) in state.folders.iter_mut() {
f.eval(&mut state.workspace);
let diags = state.workspace.diagnostics()?;
for (loc, diagnostics) in diags {
Expand Down Expand Up @@ -121,7 +135,6 @@ fn main_loop(state: &mut GlobalState) -> anyhow::Result<()> {
}
Message::Response(_resp) => {}
Message::Notification(not) => {
// TODO: react to folder changes
NotificationDispatcher::new(state, not)
.on::<DidOpenTextDocument>(|state, params| {
state.workspace.open(params)?;
Expand All @@ -137,6 +150,19 @@ fn main_loop(state: &mut GlobalState) -> anyhow::Result<()> {
state.workspace.change(params)?;
state.is_stale = true;
Ok(())
})?
.on::<DidChangeWorkspaceFolders>(|state, params| {
for f in params.event.removed {
state.folders.remove(&f.uri);
}
for f in params.event.added {
let uri = f.uri.clone();
if let Ok(folder) = Folder::new(f) {
state.folders.insert(uri, folder);
}
}
state.is_stale = true;
Ok(())
})?;
}
}
Expand Down
8 changes: 4 additions & 4 deletions oal-client/src/lsp/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn go_to_definition(
let pos = params.text_document_position_params.position;
let loc = Locator::from(params.text_document_position_params.text_document.uri);

let Some(folder) = state.folders.iter().find(|f| f.contains(&loc)) else {
let Some((_, folder)) = state.folders.iter().find(|(_, f)| f.contains(&loc)) else {
// Location not found in any folder.
return Ok(None);
};
Expand Down Expand Up @@ -112,7 +112,7 @@ pub fn references(
let pos = params.text_document_position.position;
let loc = Locator::from(params.text_document_position.text_document.uri);

let Some(folder) = state.folders.iter().find(|f| f.contains(&loc)) else {
let Some((_, folder)) = state.folders.iter().find(|(_, f)| f.contains(&loc)) else {
// Location not found in any folder.
return Ok(None);
};
Expand All @@ -134,7 +134,7 @@ pub fn prepare_rename(
let pos = params.position;
let loc = Locator::from(params.text_document.uri);

let Some(folder) = state.folders.iter().find(|f| f.contains(&loc)) else {
let Some((_, folder)) = state.folders.iter().find(|(_, f)| f.contains(&loc)) else {
// Location not found in any folder.
return Ok(None);
};
Expand Down Expand Up @@ -167,7 +167,7 @@ pub fn rename(
let loc = Locator::from(params.text_document_position.text_document.uri);
let new_name = params.new_name;

let Some(folder) = state.folders.iter().find(|f| f.contains(&loc)) else {
let Some((_, folder)) = state.folders.iter().find(|(_, f)| f.contains(&loc)) else {
// Location not found in any folder.
return Ok(None);
};
Expand Down
4 changes: 3 additions & 1 deletion oal-client/src/lsp/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use super::{Folder, Workspace};
use lsp_server::Connection;
use std::collections::HashMap;
use url::Url;

pub struct GlobalState {
pub conn: Connection,
pub workspace: Workspace,
pub folders: Vec<Folder>,
pub folders: HashMap<Url, Folder>,
pub is_stale: bool,
}

0 comments on commit 84dedba

Please sign in to comment.