From fcead6739a6a95fd3c96c2ea48f9ab27c3008aef Mon Sep 17 00:00:00 2001 From: nkxxll Date: Fri, 12 Dec 2025 17:45:31 +0100 Subject: [PATCH 1/4] add ignore current file to code actions --- crates/codebook-lsp/src/lsp.rs | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/crates/codebook-lsp/src/lsp.rs b/crates/codebook-lsp/src/lsp.rs index 13c2ebe..59293dd 100644 --- a/crates/codebook-lsp/src/lsp.rs +++ b/crates/codebook-lsp/src/lsp.rs @@ -38,6 +38,7 @@ pub struct Backend { enum CodebookCommand { AddWord, AddWordGlobal, + IgnoreFile, Unknown, } @@ -46,6 +47,7 @@ impl From<&str> for CodebookCommand { match command { "codebook.addWord" => CodebookCommand::AddWord, "codebook.addWordGlobal" => CodebookCommand::AddWordGlobal, + "codebook.ignoreFile" => CodebookCommand::IgnoreFile, _ => CodebookCommand::Unknown, } } @@ -56,6 +58,7 @@ impl From for String { match command { CodebookCommand::AddWord => "codebook.addWord".to_string(), CodebookCommand::AddWordGlobal => "codebook.addWordGlobal".to_string(), + CodebookCommand::IgnoreFile => "codebook.ignoreFile".to_string(), CodebookCommand::Unknown => "codebook.unknown".to_string(), } } @@ -93,6 +96,7 @@ impl LanguageServer for Backend { commands: vec![ CodebookCommand::AddWord.into(), CodebookCommand::AddWordGlobal.into(), + CodebookCommand::IgnoreFile.into(), ], work_done_progress_options: Default::default(), }), @@ -256,6 +260,21 @@ impl LanguageServer for Backend { data: None, })); } + let relative_path = self.get_relative_path(¶ms.text_document.uri); + actions.push(CodeActionOrCommand::CodeAction(CodeAction { + title: format!("Add current file to ignore list"), + kind: Some(CodeActionKind::QUICKFIX), + diagnostics: None, + edit: None, + command: Some(Command { + title: format!("Add current file to ignore list"), + command: CodebookCommand::IgnoreFile.into(), + arguments: Some(vec![relative_path.into()]), + }), + is_preferred: None, + disabled: None, + data: None, + })); match actions.is_empty() { true => Ok(None), false => Ok(Some(actions)), @@ -294,6 +313,24 @@ impl LanguageServer for Backend { } Ok(None) } + CodebookCommand::IgnoreFile => { + let config = self.config_handle(); + let file_uri = params + .arguments + .first() + .expect("CodebookCommand::IgnoreFile: There has to be a file URI here!"); + let updated = self.add_ignore_file( + config.as_ref(), + file_uri.as_str().expect( + "CodebookCommand::IgnoreFile: Argument should be convertable to a String!", + ), + ); + if updated { + let _ = config.save(); + self.recheck_all().await; + } + Ok(None) + } CodebookCommand::Unknown => Ok(None), } } @@ -382,6 +419,7 @@ impl Backend { } should_save } + fn add_words_global( &self, config: &CodebookConfigFile, @@ -404,6 +442,36 @@ impl Backend { should_save } + fn get_relative_path(&self, uri: &Url) -> String { + let file_path = uri.to_file_path().unwrap_or_default(); + let absolute_workspace_dir = &self.workspace_dir.canonicalize(); + + match absolute_workspace_dir { + Ok(dir) => match file_path.strip_prefix(dir) { + Ok(relative) => relative.to_string_lossy().to_string(), + Err(_) => file_path.to_string_lossy().to_string(), + }, + Err(err) => { + info!("Could not get absolute path from workspace directory. Error: {err}."); + file_path.to_string_lossy().to_string() + } + } + } + + fn add_ignore_file(&self, config: &CodebookConfigFile, file_uri: &str) -> bool { + match config.add_ignore(file_uri) { + Ok(true) => true, + Ok(false) => { + info!("File {file_uri} already exists in the ignored files."); + false + } + Err(e) => { + error!("Failed to add ignore file: {e}"); + false + } + } + } + fn make_suggestion(&self, suggestion: &str, range: &Range, uri: &Url) -> CodeAction { let title = format!("Replace with '{suggestion}'"); let mut map = HashMap::new(); From b1bcd8f8ae7ae9560a0e2b9ea6bfd530e24af73d Mon Sep 17 00:00:00 2001 From: nkxxll Date: Sun, 14 Dec 2025 01:41:52 +0100 Subject: [PATCH 2/4] compute relative path only if the action is called --- crates/codebook-lsp/src/lsp.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/crates/codebook-lsp/src/lsp.rs b/crates/codebook-lsp/src/lsp.rs index 59293dd..ea39b6b 100644 --- a/crates/codebook-lsp/src/lsp.rs +++ b/crates/codebook-lsp/src/lsp.rs @@ -260,7 +260,6 @@ impl LanguageServer for Backend { data: None, })); } - let relative_path = self.get_relative_path(¶ms.text_document.uri); actions.push(CodeActionOrCommand::CodeAction(CodeAction { title: format!("Add current file to ignore list"), kind: Some(CodeActionKind::QUICKFIX), @@ -269,7 +268,7 @@ impl LanguageServer for Backend { command: Some(Command { title: format!("Add current file to ignore list"), command: CodebookCommand::IgnoreFile.into(), - arguments: Some(vec![relative_path.into()]), + arguments: Some(vec![params.text_document.uri.to_string().into()]), }), is_preferred: None, disabled: None, @@ -318,13 +317,12 @@ impl LanguageServer for Backend { let file_uri = params .arguments .first() - .expect("CodebookCommand::IgnoreFile: There has to be a file URI here!"); - let updated = self.add_ignore_file( - config.as_ref(), - file_uri.as_str().expect( - "CodebookCommand::IgnoreFile: Argument should be convertable to a String!", - ), - ); + .expect("CodebookCommand::IgnoreFile: There has to be a file URI here!") + .as_str() + .expect( + "CodebookCommand::IgnoreFile: Argument should be convertible to a String.", + ); + let updated = self.add_ignore_file(config.as_ref(), file_uri); if updated { let _ = config.save(); self.recheck_all().await; @@ -442,7 +440,9 @@ impl Backend { should_save } - fn get_relative_path(&self, uri: &Url) -> String { + fn get_relative_path(&self, uri: &str) -> String { + let uri = Url::parse(uri) + .expect("This is a correctly formatted URL because it comes from the LSP protocol."); let file_path = uri.to_file_path().unwrap_or_default(); let absolute_workspace_dir = &self.workspace_dir.canonicalize(); @@ -459,7 +459,8 @@ impl Backend { } fn add_ignore_file(&self, config: &CodebookConfigFile, file_uri: &str) -> bool { - match config.add_ignore(file_uri) { + let relative_path = &self.get_relative_path(file_uri); + match config.add_ignore(relative_path) { Ok(true) => true, Ok(false) => { info!("File {file_uri} already exists in the ignored files."); From 739673cec616773b9948779253e54e39557123fa Mon Sep 17 00:00:00 2001 From: nkxxll Date: Sun, 14 Dec 2025 01:41:52 +0100 Subject: [PATCH 3/4] canonicalize both paths to ensure match if there is one --- crates/codebook-lsp/src/lsp.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/codebook-lsp/src/lsp.rs b/crates/codebook-lsp/src/lsp.rs index ea39b6b..efbb179 100644 --- a/crates/codebook-lsp/src/lsp.rs +++ b/crates/codebook-lsp/src/lsp.rs @@ -447,8 +447,11 @@ impl Backend { let absolute_workspace_dir = &self.workspace_dir.canonicalize(); match absolute_workspace_dir { - Ok(dir) => match file_path.strip_prefix(dir) { - Ok(relative) => relative.to_string_lossy().to_string(), + Ok(dir) => match file_path.canonicalize() { + Ok(canon_file_path) => match canon_file_path.strip_prefix(dir) { + Ok(relative) => relative.to_string_lossy().to_string(), + Err(_) => file_path.to_string_lossy().to_string(), + }, Err(_) => file_path.to_string_lossy().to_string(), }, Err(err) => { From 7a04410da4b5f6f1bd515e16ee45a69ffdf9349b Mon Sep 17 00:00:00 2001 From: nkxxll <84667783+nkxxll@users.noreply.github.com> Date: Sun, 14 Dec 2025 23:37:01 +0100 Subject: [PATCH 4/4] use `.to_string()` instead of `format!(...)` --- crates/codebook-lsp/src/lsp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/codebook-lsp/src/lsp.rs b/crates/codebook-lsp/src/lsp.rs index efbb179..14881f7 100644 --- a/crates/codebook-lsp/src/lsp.rs +++ b/crates/codebook-lsp/src/lsp.rs @@ -261,12 +261,12 @@ impl LanguageServer for Backend { })); } actions.push(CodeActionOrCommand::CodeAction(CodeAction { - title: format!("Add current file to ignore list"), + title: "Add current file to ignore list".to_string(), kind: Some(CodeActionKind::QUICKFIX), diagnostics: None, edit: None, command: Some(Command { - title: format!("Add current file to ignore list"), + title: "Add current file to ignore list".to_string(), command: CodebookCommand::IgnoreFile.into(), arguments: Some(vec![params.text_document.uri.to_string().into()]), }),