Skip to content

Commit bc5466d

Browse files
committed
fix: action resolve
1 parent 3f10f39 commit bc5466d

File tree

2 files changed

+117
-47
lines changed

2 files changed

+117
-47
lines changed

src/action_inner.rs

Lines changed: 107 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{collections::HashMap, sync::OnceLock};
22

33
use async_lsp::lsp_types::{
4-
CodeAction, CodeActionKind, CodeActionOrCommand, CodeActionParams, TextEdit, WorkspaceEdit,
4+
CodeAction, CodeActionKind, CodeActionOrCommand, CodeActionParams, Position, Range, TextEdit,
5+
WorkspaceEdit,
56
};
67
use convert_case::{Case, Casing};
78
use regex::Regex;
@@ -44,8 +45,9 @@ pub(super) fn case_actions(
4445
Some(
4546
CodeAction {
4647
title: item.to_string(),
47-
kind: Some(CodeActionKind::REFACTOR_REWRITE),
48+
kind: Some(CodeActionKind::REFACTOR_INLINE),
4849
edit: Some(WorkspaceEdit::new(changes)),
50+
is_preferred: Some(true),
4951
..Default::default()
5052
}
5153
.into(),
@@ -63,74 +65,122 @@ fn md_table_line_rg() -> &'static Regex {
6365
pub(super) fn markdown_actions(
6466
lang_id: String,
6567
doc: &Rope,
66-
range_content: &String,
6768
params: &CodeActionParams,
6869
) -> Vec<CodeActionOrCommand> {
6970
if lang_id != "markdown" {
7071
return Vec::new();
7172
}
7273

74+
let range_content = get_range_content(doc, &params.range).unwrap_or("".into());
75+
7376
let mut items = Vec::new();
7477

7578
// 表格必须为三行以上,第二行起存在表头为 `- :|`
7679
if params.range.end.line - params.range.start.line > 1 {
77-
let has_table = doc
78-
.lines_at(params.range.start.line as usize)
80+
let has_table = range_content
81+
.lines()
7982
.skip(1)
8083
.any(|line| md_table_line_rg().is_match(line.to_string().trim()));
8184

8285
if has_table {
83-
let out = markdown_table_formatter::format_tables(range_content);
84-
items.push(("Table Format", out));
86+
let edits = vec![TextEdit {
87+
range: params.range,
88+
new_text: markdown_table_formatter::format_tables(range_content.to_string()),
89+
}];
90+
91+
items.push(("Table Format", edits));
8592
}
8693
}
8794

8895
if params.range.end.line != params.range.start.line {
89-
let range_content = get_range_content(doc, &params.range).unwrap_or("".into());
90-
9196
if !range_content.char(0).is_numeric() && range_content.char(1) != '.' {
92-
let order_content: String = range_content
97+
let content = range_content
9398
.lines()
9499
.enumerate()
95-
.map(|(index, line)| {
96-
let line = line.to_string();
97-
if (params.range.end.line - params.range.start.line) as usize == index
100+
.filter_map(|(index_line, line)| {
101+
// 最后一行为空
102+
if (params.range.end.line - params.range.start.line) as usize == index_line
98103
&& params.range.end.character == 0
99104
{
100-
return line;
105+
return None;
101106
}
102-
format!("{}. {line}", (index + 1))
107+
108+
let (index_char, _) = line
109+
.chars()
110+
.enumerate()
111+
.find(|(_index_char, c)| !c.is_ascii_whitespace())
112+
.unwrap_or_default();
113+
114+
let line = index_line as u32 + params.range.start.line;
115+
let character = index_char as u32;
116+
117+
Some(TextEdit {
118+
range: Range::new(
119+
Position::new(line, character),
120+
Position::new(line, character),
121+
),
122+
new_text: format!("{}. ", (index_line + 1)),
123+
})
103124
})
104125
.collect();
105-
items.push(("Ordered List", order_content));
126+
127+
items.push(("Ordered List", content));
106128
}
107129

108130
if range_content.char(0) != '-' && range_content.char(1) != ' ' {
109-
let unorder_content: String = range_content
131+
let unorder_content = range_content
110132
.lines()
111133
.enumerate()
112-
.map(|(index, line)| {
113-
let line = line.to_string();
114-
if (params.range.end.line - params.range.start.line) as usize == index
134+
.filter_map(|(index_line, line)| {
135+
if (params.range.end.line - params.range.start.line) as usize == index_line
115136
&& params.range.end.character == 0
116137
{
117-
return line;
138+
return None;
118139
}
119-
format!("- {line}")
140+
141+
let (index_char, _) = line
142+
.chars()
143+
.enumerate()
144+
.find(|(_index_char, c)| !c.is_ascii_whitespace())?;
145+
146+
let line = index_line as u32 + params.range.start.line;
147+
let character = index_char as u32;
148+
149+
Some(TextEdit {
150+
range: Range::new(
151+
Position::new(line, character),
152+
Position::new(line, character),
153+
),
154+
new_text: "- ".to_string(),
155+
})
120156
})
121157
.collect();
122158

123-
let task_content: String = range_content
159+
let task_content = range_content
124160
.lines()
125161
.enumerate()
126-
.map(|(index, line)| {
127-
let line = line.to_string();
128-
if (params.range.end.line - params.range.start.line) as usize == index
162+
.filter_map(|(index_line, line)| {
163+
if (params.range.end.line - params.range.start.line) as usize == index_line
129164
&& params.range.end.character == 0
130165
{
131-
return line;
166+
return None;
132167
}
133-
format!("- [ ] {line}")
168+
169+
let (index_char, _) = line
170+
.chars()
171+
.enumerate()
172+
.find(|(_index_char, c)| !c.is_ascii_whitespace())?;
173+
174+
let line = index_line as u32 + params.range.start.line;
175+
let character = index_char as u32;
176+
177+
Some(TextEdit {
178+
range: Range::new(
179+
Position::new(line, character),
180+
Position::new(line, character),
181+
),
182+
new_text: "- [ ] ".to_string(),
183+
})
134184
})
135185
.collect();
136186

@@ -141,20 +191,40 @@ pub(super) fn markdown_actions(
141191

142192
// 单行处理
143193
if params.range.start.line == params.range.end.line {
144-
items.push(("Bold", format!("**{range_content}**")));
145-
items.push(("Italic", format!("_{range_content}_")));
146-
items.push(("Strikethrough", format!("~~{range_content}~~")));
194+
items.push((
195+
"Bold",
196+
vec![TextEdit {
197+
range: params.range,
198+
new_text: format!("**{range_content}**"),
199+
}],
200+
));
201+
items.push((
202+
"Italic",
203+
vec![TextEdit {
204+
range: params.range,
205+
new_text: format!("_{range_content}_"),
206+
}],
207+
));
208+
items.push((
209+
"Strikethrough",
210+
vec![TextEdit {
211+
range: params.range,
212+
new_text: format!("~~{range_content}~~"),
213+
}],
214+
));
215+
216+
if params.range.start.character + 1 == params.range.end.character {
217+
// let line = doc.line(params.range.start.line as usize);
218+
// line.chars().find_map(f)
219+
// TODO TextEdit
220+
}
147221
}
148222

149223
items
150224
.iter()
151-
.map(|&(item, ref out)| {
225+
.map(|(item, edits)| {
152226
let mut changes = HashMap::new();
153-
let edits = vec![TextEdit {
154-
range: params.range,
155-
new_text: out.clone(),
156-
}];
157-
changes.insert(params.text_document.uri.clone(), edits);
227+
changes.insert(params.text_document.uri.clone(), edits.to_vec());
158228

159229
CodeAction {
160230
title: item.to_string(),

src/lsp.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ impl LanguageServer for Server {
137137
CodeActionOptions {
138138
code_action_kinds: Some(vec![
139139
CodeActionKind::EMPTY,
140+
CodeActionKind::REFACTOR,
141+
CodeActionKind::REFACTOR_INLINE,
140142
CodeActionKind::REFACTOR_REWRITE,
141143
]),
142144
resolve_provider: Some(true),
@@ -303,12 +305,7 @@ impl LanguageServer for Server {
303305
action.clone().into()
304306
})
305307
.chain(case_actions(range_content.to_string(), &params))
306-
.chain(markdown_actions(
307-
lang_id,
308-
&doc,
309-
&range_content.to_string(),
310-
&params,
311-
))
308+
.chain(markdown_actions(lang_id, &doc, &params))
312309
.collect();
313310

314311
Box::pin(async move { Ok(Some(actions)) })
@@ -319,10 +316,13 @@ impl LanguageServer for Server {
319316
params: CodeAction,
320317
) -> BoxFuture<'static, Result<CodeAction, ResponseError>> {
321318
// let data: ActionData = serde_json::from_value(params.data.clone().unwrap()).unwrap();
322-
let data = self
323-
.state
324-
.action_cache_get(params.title.clone())
325-
.expect("Unkown Action");
319+
let data = self.state.action_cache_get(params.title.clone());
320+
321+
if data.is_none() {
322+
return Box::pin(async move { Ok(params) });
323+
}
324+
325+
let data = data.unwrap();
326326

327327
let uri = data.params.text_document.uri;
328328

0 commit comments

Comments
 (0)