Skip to content

Commit

Permalink
feat: add lsp client specific handling for helix (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
gimalay authored Feb 17, 2025
1 parent 923d92f commit fa88f51
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 2 deletions.
12 changes: 11 additions & 1 deletion crates/iwes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ use lsp_server::Connection;

use liwe::fs::new_for_path;
use liwe::state::new_form_indoc;
use router::{Router, ServerConfig};
use router::{LspClient, Router, ServerConfig};

mod router;

#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq, Hash)]
pub struct InitializeParams {
pub state: Option<String>,
pub sequential_ids: Option<bool>,
pub client_name: Option<String>,
}

pub fn main_loop(
Expand All @@ -25,13 +26,21 @@ pub fn main_loop(
) -> Result<()> {
let initialize_params: InitializeParams = serde_json::from_value(params_value).unwrap();

let client = initialize_params
.clone()
.client_name
.filter(|name| name.eq("helix"))
.map(|_| LspClient::Helix)
.unwrap_or(LspClient::Unknown);

let router = if let Some(state) = &(&initialize_params).state {
Router::new(
connection.sender,
ServerConfig {
base_path: base_path.clone(),
state: new_form_indoc(state),
sequential_ids: Some(true),
lsp_client: client,
markdown_options,
},
)
Expand All @@ -42,6 +51,7 @@ pub fn main_loop(
base_path: base_path.clone(),
state: new_for_path(&PathBuf::from_str(&base_path).expect("to work")),
sequential_ids: None,
lsp_client: client,
markdown_options,
},
)
Expand Down
7 changes: 7 additions & 0 deletions crates/iwes/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ use self::server::Server;

pub mod server;

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum LspClient {
Unknown,
Helix,
}

pub struct ServerConfig {
pub base_path: String,
pub state: State,
pub sequential_ids: Option<bool>,
pub markdown_options: MarkdownOptions,
pub lsp_client: LspClient,
}

pub struct Router {
Expand Down
6 changes: 6 additions & 0 deletions crates/iwes/src/router/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use liwe::model::{self, InlineRange};

use liwe::parser::Parser;

use super::LspClient;
use super::ServerConfig;
use liwe::database::Database;
use liwe::database::DatabaseContext;
Expand All @@ -25,6 +26,7 @@ pub struct Server {
base_path: BasePath,
database: Database,
refs_extension: String,
lsp_client: LspClient,
}

pub struct BasePath {
Expand Down Expand Up @@ -66,6 +68,7 @@ impl Server {
config.markdown_options.clone(),
),
refs_extension: config.markdown_options.refs_extension.clone(),
lsp_client: config.lsp_client,
}
}
pub fn database(&self) -> impl DatabaseContext + '_ {
Expand Down Expand Up @@ -396,11 +399,14 @@ impl Server {
let context = self.database.graph();
let base_path: &BasePath = &self.base_path;

dbg!(self.lsp_client);

context
.get_node_id_at(
&params.text_document.uri.to_key(base_path),
params.range.start.line as usize,
)
.filter(|_| params.range.empty() || self.lsp_client == LspClient::Helix)
.map(|node_id| {
vec![
ActionType::SectionExtract,
Expand Down
75 changes: 75 additions & 0 deletions crates/iwes/tests/extract_section_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ fn extract_section() {
);
}

#[test]
fn extract_helix_section() {
assert_extracted_helix(
indoc! {"
# test
## test2
"},
2,
indoc! {"
# test
[test2](2)
"},
indoc! {"
# test2
"},
);
}

#[test]
fn extract_middle_section_test() {
assert_extracted(
Expand Down Expand Up @@ -259,6 +279,61 @@ fn assert_extracted(source: &str, line: u32, target: &str, extracted: &str) {
)
}

fn assert_extracted_helix(source: &str, line: u32, target: &str, extracted: &str) {
let fixture = Fixture::with_client(source, "helix");

fixture.code_action(
CodeActionParams {
text_document: TextDocumentIdentifier { uri: uri(1) },
range: Range::new(Position::new(line, 0), Position::new(line, 1)),
work_done_progress_params: Default::default(),
partial_result_params: Default::default(),
context: CodeActionContext {
diagnostics: Default::default(),
only: action_kinds("refactor.extract.section"),
trigger_kind: None,
},
},
vec![CodeActionOrCommand::CodeAction(CodeAction {
title: "Extract section".to_string(),
kind: action_kind("refactor.extract.section"),
edit: Some(lsp_types::WorkspaceEdit {
document_changes: Some(DocumentChanges::Operations(vec![
DocumentChangeOperation::Op(ResourceOp::Create(CreateFile {
uri: uri(2),
options: Some(CreateFileOptions {
overwrite: Some(false),
ignore_if_exists: Some(false),
}),
annotation_id: None,
})),
DocumentChangeOperation::Edit(TextDocumentEdit {
text_document: OptionalVersionedTextDocumentIdentifier {
uri: uri(2),
version: None,
},
edits: vec![OneOf::Left(TextEdit {
range: Range::new(Position::new(0, 0), Position::new(u32::MAX, 0)),
new_text: extracted.to_string(),
})],
}),
DocumentChangeOperation::Edit(TextDocumentEdit {
text_document: OptionalVersionedTextDocumentIdentifier {
uri: uri(1),
version: None,
},
edits: vec![OneOf::Left(TextEdit {
range: Range::new(Position::new(0, 0), Position::new(u32::MAX, 0)),
new_text: target.to_string(),
})],
}),
])),
..Default::default()
}),
..Default::default()
})],
)
}
fn assert_no_action(source: &str, line: u32) {
let fixture = Fixture::with(source);

Expand Down
15 changes: 15 additions & 0 deletions crates/iwes/tests/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,22 @@ impl Fixture {
pub fn with(indoc: &str) -> Fixture {
Self::with_options(indoc, MarkdownOptions::default())
}

pub fn with_options(indoc: &str, markdown_options: MarkdownOptions) -> Fixture {
Self::with_options_and_client(indoc, markdown_options, "")
}

pub fn with_client(indoc: &str, client: &str) -> Fixture {
Self::with_options_and_client(indoc, MarkdownOptions::default(), client)
}

pub fn with_options_and_client(
indoc: &str,
markdown_options: MarkdownOptions,
lsp_client_name: &str,
) -> Fixture {
let (connection, client) = Connection::memory();
let client_name = Some(lsp_client_name.to_string());

let content = indoc.to_string();

Expand All @@ -89,6 +103,7 @@ impl Fixture {
} else {
Some(content.clone())
},
client_name,
sequential_ids: Some(true),
})
.unwrap(),
Expand Down
2 changes: 1 addition & 1 deletion crates/iwes/tests/inline_section_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ fn assert_inlined(source: &str, line: u32, inlined: &str) {
range: Range::new(
Position::new(line, 0),
// helix editor provides range even if nothing selected.
Position::new(line + 1, 1),
Position::new(line, 0),
),
work_done_progress_params: Default::default(),
partial_result_params: Default::default(),
Expand Down

0 comments on commit fa88f51

Please sign in to comment.