Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 55 additions & 14 deletions src/codeactions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::Path;

use pathdiff::diff_paths;
use ropey::Rope;
use tower_lsp::lsp_types::{
CodeAction, CodeActionOrCommand, CodeActionParams, CreateFile, CreateFileOptions,
DocumentChangeOperation, DocumentChanges, OneOf, OptionalVersionedTextDocumentIdentifier,
Expand All @@ -14,6 +15,18 @@ use crate::{
vault::{Reference, Vault},
};

fn end_of_document_position(file: Option<&Rope>) -> Position {
let Some(file) = file else {
return Position::default();
};

let line = file.len_lines().saturating_sub(1);
Position {
line: line as u32,
character: file.line(line).len_chars() as u32,
}
}

pub fn code_actions(
vault: &Vault,
params: &CodeActionParams,
Expand Down Expand Up @@ -85,17 +98,12 @@ pub fn code_actions(

let file = vault.ropes.get(&new_path_buf);

let length = match file {
Some(file) => file.lines().len(),
None => 0
};


let new_text = match file {
Some(..) => format!("\n\n# {}", heading),
None => format!("# {}", heading)
}; // move this calculation to the vault somehow

let end_of_document = end_of_document_position(file);

Some(CodeActionOrCommand::CodeAction(CodeAction {
title: format!(
Expand All @@ -122,14 +130,8 @@ pub fn code_actions(
OneOf::Left(TextEdit{
new_text,
range: Range {
start: Position {
line: (length + 1) as u32,
character: 0
},
end: Position {
line: length as u32,
character: 0
}
start: end_of_document,
end: end_of_document,
}
})
]
Expand All @@ -147,3 +149,42 @@ pub fn code_actions(
.collect(),
)
}

#[cfg(test)]
mod tests {
use ropey::Rope;
use tower_lsp::lsp_types::Position;

use super::end_of_document_position;

#[test]
fn append_position_for_a_new_file_is_the_origin() {
assert_eq!(end_of_document_position(None), Position::default());
}

#[test]
fn append_position_uses_the_final_character_of_the_last_line() {
let file = Rope::from_str("first\nsecond");

assert_eq!(
end_of_document_position(Some(&file)),
Position {
line: 1,
character: 6,
}
);
}

#[test]
fn append_position_handles_a_trailing_newline() {
let file = Rope::from_str("first\nsecond\n");

assert_eq!(
end_of_document_position(Some(&file)),
Position {
line: 2,
character: 0,
}
);
}
}