Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: code actions - document edits #478

Merged
merged 18 commits into from
Jul 24, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
47 changes: 47 additions & 0 deletions helix-lsp/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,26 @@ impl Client {
content_format: Some(vec![lsp::MarkupKind::Markdown]),
..Default::default()
}),
code_action: Some(lsp::CodeActionClientCapabilities {
code_action_literal_support: Some(lsp::CodeActionLiteralSupport {
code_action_kind: lsp::CodeActionKindLiteralSupport {
value_set: [
lsp::CodeActionKind::EMPTY,
lsp::CodeActionKind::QUICKFIX,
lsp::CodeActionKind::REFACTOR,
lsp::CodeActionKind::REFACTOR_EXTRACT,
lsp::CodeActionKind::REFACTOR_INLINE,
lsp::CodeActionKind::REFACTOR_REWRITE,
lsp::CodeActionKind::SOURCE,
lsp::CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
]
.iter()
.map(|kind| kind.as_str().to_string())
.collect(),
},
}),
..Default::default()
}),
..Default::default()
}),
window: Some(lsp::WindowClientCapabilities {
Expand Down Expand Up @@ -713,4 +733,31 @@ impl Client {

self.call::<lsp::request::DocumentSymbolRequest>(params)
}

// empty string to get all symbols
pub fn workspace_symbols(&self, query: String) -> impl Future<Output = Result<Value>> {
let params = lsp::WorkspaceSymbolParams {
query,
work_done_progress_params: lsp::WorkDoneProgressParams::default(),
partial_result_params: lsp::PartialResultParams::default(),
};

self.call::<lsp::request::WorkspaceSymbol>(params)
}

pub fn code_actions(
&self,
text_document: lsp::TextDocumentIdentifier,
range: lsp::Range,
) -> impl Future<Output = Result<Value>> {
let params = lsp::CodeActionParams {
text_document,
range,
context: lsp::CodeActionContext::default(),
work_done_progress_params: lsp::WorkDoneProgressParams::default(),
partial_result_params: lsp::PartialResultParams::default(),
};

self.call::<lsp::request::CodeActionRequest>(params)
}
}
82 changes: 82 additions & 0 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl Command {
append_mode,
command_mode,
file_picker,
code_action,
buffer_picker,
symbol_picker,
prepend_to_line,
Expand Down Expand Up @@ -2091,6 +2092,85 @@ fn symbol_picker(cx: &mut Context) {
)
}

pub fn workspace_symbol_picker(cx: &mut Context) {
let (view, doc) = current!(cx.editor);

let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};
let offset_encoding = language_server.offset_encoding();

let future = language_server.workspace_symbols("".to_string());

cx.callback(
future,
move |editor: &mut Editor,
compositor: &mut Compositor,
response: Option<Vec<lsp::SymbolInformation>>| {
if let Some(symbols) = response {
let picker = Picker::new(
symbols,
|symbol| (&symbol.name).into(),
move |editor: &mut Editor, symbol, _action| {
push_jump(editor);
let (view, doc) = current!(editor);

// if let Some(range) =
// lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
// {
// doc.set_selection(view.id, Selection::single(range.to(), range.from()));
// align_view(doc, view, Align::Center);
// }
},
);
compositor.push(Box::new(picker))
}
},
)
}

pub fn code_action(cx: &mut Context) {
let (view, doc) = current!(cx.editor);

let language_server = match doc.language_server() {
Some(language_server) => language_server,
None => return,
};
let offset_encoding = language_server.offset_encoding();

let range = range_to_lsp_range(
doc.text(),
doc.selection(view.id).primary(),
language_server.offset_encoding(),
);

let future = language_server.code_actions(doc.identifier(), range);

cx.callback(
future,
move |editor: &mut Editor,
compositor: &mut Compositor,
response: Option<lsp::CodeActionResponse>| {
if let Some(actions) = response {
let picker = Picker::new(
actions,
|action| match action {
lsp::CodeActionOrCommand::CodeAction(action) => {
action.title.as_str().into()
}
lsp::CodeActionOrCommand::Command(command) => command.title.as_str().into(),
},
move |editor: &mut Editor, code_action, _action| {
//
},
);
compositor.push(Box::new(picker))
}
},
)
}

// I inserts at the first nonwhitespace character of each line with a selection
fn prepend_to_line(cx: &mut Context) {
goto_first_nonwhitespace(cx);
Expand Down Expand Up @@ -3767,6 +3847,8 @@ mode_info! {
"P" => paste_clipboard_before,
/// replace selections with clipboard
"R" => replace_selections_with_clipboard,
/// show available code actions for current selection
gbaranski marked this conversation as resolved.
Show resolved Hide resolved
"a" => code_action,
/// keep primary selection
"space" => keep_primary_selection,
}
Expand Down