@@ -1,6 +1,8 @@
1pub(crate) mod dap;
1pub(crate) mod dap;
3pub use dap::*;
4pub use dap::*;
5use helix_core::{
7use helix_core::{
6 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes,
8 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes,
@@ -33,11 +35,6 @@ use helix_view::{
34use anyhow::{anyhow, bail, ensure, Context as _};
36use anyhow::{anyhow, bail, ensure, Context as _};
35use fuzzy_matcher::FuzzyMatcher;
37use fuzzy_matcher::FuzzyMatcher;
38− util::{lsp_pos_to_pos, lsp_range_to_range, pos_to_lsp_pos, range_to_lsp_range},
41use insert::*;
38use insert::*;
42use movement::Movement;
39use movement::Movement;
@@ -2754,7 +2751,7 @@ pub mod cmd {
2754 // TODO: support no frame_id
2751 // TODO: support no frame_id
2756 let frame_id = debugger.stack_frames[&thread_id][frame].id;
2753 let frame_id = debugger.stack_frames[&thread_id][frame].id;
2757− let response = block_on(debugger.eval(args.join(" "), Some(frame_id)))?;
2754+ let response = helix_lsp::block_on(debugger.eval(args.join(" "), Some(frame_id)))?;
2758 cx.editor.set_status(response.result);
2755 cx.editor.set_status(response.result);
@@ -3474,217 +3471,6 @@ fn buffer_picker(cx: &mut Context) {
3474 cx.push_layer(Box::new(overlayed(picker)));
3471 cx.push_layer(Box::new(overlayed(picker)));
3478− symbols: Vec<lsp::SymbolInformation>,
3479− current_path: Option<lsp::Url>,
3480− offset_encoding: OffsetEncoding,
3481−) -> FilePicker<lsp::SymbolInformation> {
3482− // TODO: drop current_path comparison and instead use workspace: bool flag?
3483− let current_path2 = current_path.clone();
3484− let mut picker = FilePicker::new(
3487− if current_path.as_ref() == Some(&symbol.location.uri) {
3488− symbol.name.as_str().into()
3490− let path = symbol.location.uri.to_file_path().unwrap();
3491− let relative_path = helix_core::path::get_relative_path(path.as_path())
3494− format!("{} ({})", &symbol.name, relative_path).into()
3497− move |cx, symbol, action| {
3498− if current_path2.as_ref() == Some(&symbol.location.uri) {
3499− push_jump(cx.editor);
3501− let path = symbol.location.uri.to_file_path().unwrap();
3502− cx.editor.open(path, action).expect("editor.open failed");
3505− let (view, doc) = current!(cx.editor);
3507− if let Some(range) =
3508− lsp_range_to_range(doc.text(), symbol.location.range, offset_encoding)
3510− // we flip the range so that the cursor sits on the start of the symbol
3511− // (for example start of the function).
3512− doc.set_selection(view.id, Selection::single(range.head, range.anchor));
3513− align_view(doc, view, Align::Center);
3516− move |_editor, symbol| {
3517− let path = symbol.location.uri.to_file_path().unwrap();
3519− symbol.location.range.start.line as usize,
3520− symbol.location.range.end.line as usize,
3525− picker.truncate_start = false;
3529−fn symbol_picker(cx: &mut Context) {
3531− list: &mut Vec<lsp::SymbolInformation>,
3532− file: &lsp::TextDocumentIdentifier,
3533− symbol: lsp::DocumentSymbol,
3535− #[allow(deprecated)]
3536− list.push(lsp::SymbolInformation {
3540− deprecated: symbol.deprecated,
3541− location: lsp::Location::new(file.uri.clone(), symbol.selection_range),
3542− container_name: None,
3544− for child in symbol.children.into_iter().flatten() {
3545− nested_to_flat(list, file, child);
3548− let doc = doc!(cx.editor);
3550− let language_server = match doc.language_server() {
3551− Some(language_server) => language_server,
3554− let current_url = doc.url();
3555− let offset_encoding = language_server.offset_encoding();
3557− let future = language_server.document_symbols(doc.identifier());
3561− move |editor: &mut Editor,
3562− compositor: &mut Compositor,
3563− response: Option<lsp::DocumentSymbolResponse>| {
3564− if let Some(symbols) = response {
3565− // lsp has two ways to represent symbols (flat/nested)
3566− // convert the nested variant to flat, so that we have a homogeneous list
3567− let symbols = match symbols {
3568− lsp::DocumentSymbolResponse::Flat(symbols) => symbols,
3569− lsp::DocumentSymbolResponse::Nested(symbols) => {
3570− let doc = doc!(editor);
3571− let mut flat_symbols = Vec::new();
3572− for symbol in symbols {
3573− nested_to_flat(&mut flat_symbols, &doc.identifier(), symbol)
3579− let picker = sym_picker(symbols, current_url, offset_encoding);
3580− compositor.push(Box::new(overlayed(picker)))
3586−fn workspace_symbol_picker(cx: &mut Context) {
3587− let doc = doc!(cx.editor);
3588− let current_url = doc.url();
3589− let language_server = match doc.language_server() {
3590− Some(language_server) => language_server,
3593− let offset_encoding = language_server.offset_encoding();
3594− let future = language_server.workspace_symbols("".to_string());
3598− move |_editor: &mut Editor,
3599− compositor: &mut Compositor,
3600− response: Option<Vec<lsp::SymbolInformation>>| {
3601− if let Some(symbols) = response {
3602− let picker = sym_picker(symbols, current_url, offset_encoding);
3603− compositor.push(Box::new(overlayed(picker)))
3609−impl ui::menu::Item for lsp::CodeActionOrCommand {
3610− fn label(&self) -> &str {
3612− lsp::CodeActionOrCommand::CodeAction(action) => action.title.as_str(),
3613− lsp::CodeActionOrCommand::Command(command) => command.title.as_str(),
3618−pub fn code_action(cx: &mut Context) {
3619− let (view, doc) = current!(cx.editor);
3621− let language_server = match doc.language_server() {
3622− Some(language_server) => language_server,
3626− let range = range_to_lsp_range(
3628− doc.selection(view.id).primary(),
3629− language_server.offset_encoding(),
3632− let future = language_server.code_actions(doc.identifier(), range);
3633− let offset_encoding = language_server.offset_encoding();
3637− move |editor: &mut Editor,
3638− compositor: &mut Compositor,
3639− response: Option<lsp::CodeActionResponse>| {
3640− let actions = match response {
3644− if actions.is_empty() {
3645− editor.set_status("No code actions available");
3649− let mut picker = ui::Menu::new(actions, move |editor, code_action, event| {
3650− if event != PromptEvent::Validate {
3654− // always present here
3655− let code_action = code_action.unwrap();
3657− match code_action {
3658− lsp::CodeActionOrCommand::Command(command) => {
3659− log::debug!("code action command: {:?}", command);
3660− execute_lsp_command(editor, command.clone());
3662− lsp::CodeActionOrCommand::CodeAction(code_action) => {
3663− log::debug!("code action: {:?}", code_action);
3664− if let Some(ref workspace_edit) = code_action.edit {
3665− log::debug!("edit: {:?}", workspace_edit);
3666− apply_workspace_edit(editor, offset_encoding, workspace_edit);
3669− // if code action provides both edit and command first the edit
3670− // should be applied and then the command
3671− if let Some(command) = &code_action.command {
3672− execute_lsp_command(editor, command.clone());
3677− picker.move_down(); // pre-select the first item
3679− let popup = Popup::new("code-action", picker).margin(helix_view::graphics::Margin {
3683− compositor.replace_or_push("code-action", Box::new(popup));
3688pub fn command_palette(cx: &mut Context) {
3474pub fn command_palette(cx: &mut Context) {
3689 cx.callback = Some(Box::new(
3475 cx.callback = Some(Box::new(
3690 move |compositor: &mut Compositor, cx: &mut compositor::Context| {
3476 move |compositor: &mut Compositor, cx: &mut compositor::Context| {
@@ -3748,180 +3534,6 @@ pub fn command_palette(cx: &mut Context) {
3751−pub fn execute_lsp_command(editor: &mut Editor, cmd: lsp::Command) {
3752− let doc = doc!(editor);
3753− let language_server = match doc.language_server() {
3754− Some(language_server) => language_server,
3758− // the command is executed on the server and communicated back
3759− // to the client asynchronously using workspace edits
3760− let command_future = language_server.command(cmd);
3761− tokio::spawn(async move {
3762− let res = command_future.await;
3764− if let Err(e) = res {
3765− log::error!("execute LSP command: {}", e);
3770−pub fn apply_document_resource_op(op: &lsp::ResourceOp) -> std::io::Result<()> {
3771− use lsp::ResourceOp;
3774− ResourceOp::Create(op) => {
3775− let path = op.uri.to_file_path().unwrap();
3776− let ignore_if_exists = op.options.as_ref().map_or(false, |options| {
3777− !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)
3779− if ignore_if_exists && path.exists() {
3782− fs::write(&path, [])
3785− ResourceOp::Delete(op) => {
3786− let path = op.uri.to_file_path().unwrap();
3791− .and_then(|options| options.recursive)
3795− fs::remove_dir_all(&path)
3797− fs::remove_dir(&path)
3799− } else if path.is_file() {
3800− fs::remove_file(&path)
3805− ResourceOp::Rename(op) => {
3806− let from = op.old_uri.to_file_path().unwrap();
3807− let to = op.new_uri.to_file_path().unwrap();
3808− let ignore_if_exists = op.options.as_ref().map_or(false, |options| {
3809− !options.overwrite.unwrap_or(false) && options.ignore_if_exists.unwrap_or(false)
3811− if ignore_if_exists && to.exists() {
3814− fs::rename(&from, &to)
3820−pub fn apply_workspace_edit(
3821− editor: &mut Editor,
3822− offset_encoding: OffsetEncoding,
3823− workspace_edit: &lsp::WorkspaceEdit,
3825− let mut apply_edits = |uri: &helix_lsp::Url, text_edits: Vec<lsp::TextEdit>| {
3828− .expect("unable to convert URI to filepath");
3830− let current_view_id = view!(editor).id;
3831− let doc_id = editor.open(path, Action::Load).unwrap();
3833− .document_mut(doc_id)
3834− .expect("Document for document_changes not found");
3836− // Need to determine a view for apply/append_changes_to_history
3837− let selections = doc.selections();
3838− let view_id = if selections.contains_key(¤t_view_id) {
3839− // use current if possible
3842− // Hack: we take the first available view_id
3847− .expect("No view_id available")
3850− let transaction = helix_lsp::util::generate_transaction_from_edits(
3855− doc.apply(&transaction, view_id);
3856− doc.append_changes_to_history(view_id);
3859− if let Some(ref changes) = workspace_edit.changes {
3860− log::debug!("workspace changes: {:?}", changes);
3861− for (uri, text_edits) in changes {
3862− let text_edits = text_edits.to_vec();
3863− apply_edits(uri, text_edits);
3866− // Not sure if it works properly, it'll be safer to just panic here to avoid breaking some parts of code on which code actions will be used
3867− // TODO: find some example that uses workspace changes, and test it
3868− // for (url, edits) in changes.iter() {
3869− // let file_path = url.origin().ascii_serialization();
3870− // let file_path = std::path::PathBuf::from(file_path);
3871− // let file = std::fs::File::open(file_path).unwrap();
3872− // let mut text = Rope::from_reader(file).unwrap();
3873− // let transaction = edits_to_changes(&text, edits);
3874− // transaction.apply(&mut text);
3878− if let Some(ref document_changes) = workspace_edit.document_changes {
3879− match document_changes {
3880− lsp::DocumentChanges::Edits(document_edits) => {
3881− for document_edit in document_edits {
3882− let edits = document_edit
3885− .map(|edit| match edit {
3886− lsp::OneOf::Left(text_edit) => text_edit,
3887− lsp::OneOf::Right(annotated_text_edit) => {
3888− &annotated_text_edit.text_edit
3893− apply_edits(&document_edit.text_document.uri, edits);
3896− lsp::DocumentChanges::Operations(operations) => {
3897− log::debug!("document changes - operations: {:?}", operations);
3898− for operateion in operations {
3900− lsp::DocumentChangeOperation::Op(op) => {
3901− apply_document_resource_op(op).unwrap();
3904− lsp::DocumentChangeOperation::Edit(document_edit) => {
3905− let edits = document_edit
3908− .map(|edit| match edit {
3909− lsp::OneOf::Left(text_edit) => text_edit,
3910− lsp::OneOf::Right(annotated_text_edit) => {
3911− &annotated_text_edit.text_edit
3916− apply_edits(&document_edit.text_document.uri, edits);
3925fn last_picker(cx: &mut Context) {
3537fn last_picker(cx: &mut Context) {
3926 // TODO: last picker does not seem to work well with buffer_picker
3538 // TODO: last picker does not seem to work well with buffer_picker
3927 cx.callback = Some(Box::new(|compositor: &mut Compositor, _| {
3539 cx.callback = Some(Box::new(|compositor: &mut Compositor, _| {
@@ -4250,247 +3862,6 @@ fn exit_select_mode(cx: &mut Context) {
4254− editor: &mut Editor,
4255− compositor: &mut Compositor,
4256− locations: Vec<lsp::Location>,
4257− offset_encoding: OffsetEncoding,
4261− // TODO: share with symbol picker(symbol.location)
4263− editor: &mut Editor,
4264− location: &lsp::Location,
4265− offset_encoding: OffsetEncoding,
4268− let path = location
4271− .expect("unable to convert URI to filepath");
4272− let _id = editor.open(path, action).expect("editor.open failed");
4273− let (view, doc) = current!(editor);
4274− let definition_pos = location.range.start;
4275− // TODO: convert inside server
4277− if let Some(new_pos) = lsp_pos_to_pos(doc.text(), definition_pos, offset_encoding) {
4282− doc.set_selection(view.id, Selection::point(new_pos));
4283− align_view(doc, view, Align::Center);
4286− let cwdir = std::env::current_dir().expect("couldn't determine current directory");
4288− match locations.as_slice() {
4290− jump_to(editor, location, offset_encoding, Action::Replace);
4293− editor.set_error("No definition found.");
4296− let picker = FilePicker::new(
4299− let file: Cow<'_, str> = (location.uri.scheme() == "file")
4305− // strip root prefix
4306− path.strip_prefix(&cwdir)
4307− .map(|path| path.to_path_buf())
4310− .map(|path| Cow::from(path.to_string_lossy().into_owned()))
4314− .unwrap_or_else(|| location.uri.as_str().into());
4315− let line = location.range.start.line;
4316− format!("{}:{}", file, line).into()
4318− move |cx, location, action| jump_to(cx.editor, location, offset_encoding, action),
4319− |_editor, location| {
4320− // TODO: share code for symbol.location and location
4321− let path = location.uri.to_file_path().unwrap();
4323− location.range.start.line as usize,
4324− location.range.end.line as usize,
4329− compositor.push(Box::new(overlayed(picker)));
4334−fn goto_definition(cx: &mut Context) {
4335− let (view, doc) = current!(cx.editor);
4336− let language_server = match doc.language_server() {
4337− Some(language_server) => language_server,
4341− let offset_encoding = language_server.offset_encoding();
4343− let pos = pos_to_lsp_pos(
4345− doc.selection(view.id)
4347− .cursor(doc.text().slice(..)),
4351− let future = language_server.goto_definition(doc.identifier(), pos, None);
4355− move |editor: &mut Editor,
4356− compositor: &mut Compositor,
4357− response: Option<lsp::GotoDefinitionResponse>| {
4358− let items = match response {
4359− Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
4360− Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
4361− Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
4363− .map(|location_link| lsp::Location {
4364− uri: location_link.target_uri,
4365− range: location_link.target_range,
4368− None => Vec::new(),
4371− goto_impl(editor, compositor, items, offset_encoding);
4376−fn goto_type_definition(cx: &mut Context) {
4377− let (view, doc) = current!(cx.editor);
4378− let language_server = match doc.language_server() {
4379− Some(language_server) => language_server,
4383− let offset_encoding = language_server.offset_encoding();
4385− let pos = pos_to_lsp_pos(
4387− doc.selection(view.id)
4389− .cursor(doc.text().slice(..)),
4393− let future = language_server.goto_type_definition(doc.identifier(), pos, None);
4397− move |editor: &mut Editor,
4398− compositor: &mut Compositor,
4399− response: Option<lsp::GotoDefinitionResponse>| {
4400− let items = match response {
4401− Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
4402− Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
4403− Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
4405− .map(|location_link| lsp::Location {
4406− uri: location_link.target_uri,
4407− range: location_link.target_range,
4410− None => Vec::new(),
4413− goto_impl(editor, compositor, items, offset_encoding);
4418−fn goto_implementation(cx: &mut Context) {
4419− let (view, doc) = current!(cx.editor);
4420− let language_server = match doc.language_server() {
4421− Some(language_server) => language_server,
4425− let offset_encoding = language_server.offset_encoding();
4427− let pos = pos_to_lsp_pos(
4429− doc.selection(view.id)
4431− .cursor(doc.text().slice(..)),
4435− let future = language_server.goto_implementation(doc.identifier(), pos, None);
4439− move |editor: &mut Editor,
4440− compositor: &mut Compositor,
4441− response: Option<lsp::GotoDefinitionResponse>| {
4442− let items = match response {
4443− Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
4444− Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
4445− Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
4447− .map(|location_link| lsp::Location {
4448− uri: location_link.target_uri,
4449− range: location_link.target_range,
4452− None => Vec::new(),
4455− goto_impl(editor, compositor, items, offset_encoding);
4460−fn goto_reference(cx: &mut Context) {
4461− let (view, doc) = current!(cx.editor);
4462− let language_server = match doc.language_server() {
4463− Some(language_server) => language_server,
4467− let offset_encoding = language_server.offset_encoding();
4469− let pos = pos_to_lsp_pos(
4471− doc.selection(view.id)
4473− .cursor(doc.text().slice(..)),
4477− let future = language_server.goto_reference(doc.identifier(), pos, None);
4481− move |editor: &mut Editor,
4482− compositor: &mut Compositor,
4483− items: Option<Vec<lsp::Location>>| {
4487− items.unwrap_or_default(),
4494fn goto_pos(editor: &mut Editor, pos: usize) {
3865fn goto_pos(editor: &mut Editor, pos: usize) {
4495 push_jump(editor);
3866 push_jump(editor);
@@ -4565,46 +3936,6 @@ fn goto_prev_diag(cx: &mut Context) {
4565 goto_pos(editor, pos);
3936 goto_pos(editor, pos);
4568−fn signature_help(cx: &mut Context) {
4569− let (view, doc) = current!(cx.editor);
4571− let language_server = match doc.language_server() {
4572− Some(language_server) => language_server,
4576− let pos = pos_to_lsp_pos(
4578− doc.selection(view.id)
4580− .cursor(doc.text().slice(..)),
4581− language_server.offset_encoding(),
4584− let future = language_server.text_document_signature_help(doc.identifier(), pos, None);
4588− move |_editor: &mut Editor,
4589− _compositor: &mut Compositor,
4590− response: Option<lsp::SignatureHelp>| {
4591− if let Some(signature_help) = response {
4592− log::info!("{:?}", signature_help);
4594− // active_signature
4595− // active_parameter
4602− // with active param highlighted
4608pub mod insert {
3939pub mod insert {
4609 use super::*;
3940 use super::*;
4610 pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;
3941 pub type Hook = fn(&Rope, &Selection, char) -> Option<Transaction>;
@@ -4630,6 +3961,7 @@ pub mod insert {
4632 fn language_server_completion(cx: &mut Context, ch: char) {
3963 fn language_server_completion(cx: &mut Context, ch: char) {
3964+ use helix_lsp::lsp;
4633 // if ch matches completion char, trigger completion
3965 // if ch matches completion char, trigger completion
4634 let doc = doc_mut!(cx.editor);
3966 let doc = doc_mut!(cx.editor);
4635 let language_server = match doc.language_server() {
3967 let language_server = match doc.language_server() {
@@ -4653,6 +3985,7 @@ pub mod insert {
4655 fn signature_help(cx: &mut Context, ch: char) {
3987 fn signature_help(cx: &mut Context, ch: char) {
3988+ use helix_lsp::lsp;
4656 // if ch matches signature_help char, trigger
3989 // if ch matches signature_help char, trigger
4657 let doc = doc_mut!(cx.editor);
3990 let doc = doc_mut!(cx.editor);
4658 let language_server = match doc.language_server() {
3991 let language_server = match doc.language_server() {
@@ -5360,6 +4693,8 @@ fn unindent(cx: &mut Context) {
5362fn format_selections(cx: &mut Context) {
4695fn format_selections(cx: &mut Context) {
4696+ use helix_lsp::{lsp, util::range_to_lsp_range};
5363 let (view, doc) = current!(cx.editor);
4698 let (view, doc) = current!(cx.editor);
5365 // via lsp if available
4700 // via lsp if available
@@ -5504,6 +4839,8 @@ fn remove_primary_selection(cx: &mut Context) {
5506pub fn completion(cx: &mut Context) {
4841pub fn completion(cx: &mut Context) {
4842+ use helix_lsp::{lsp, util::pos_to_lsp_pos};
5507 // trigger on trigger char, or if user calls it
4844 // trigger on trigger char, or if user calls it
5508 // (or on word char typing??)
4845 // (or on word char typing??)
5509 // after it's triggered, if response marked is_incomplete, update on every subsequent keypress
4846 // after it's triggered, if response marked is_incomplete, update on every subsequent keypress
@@ -5618,66 +4955,6 @@ pub fn completion(cx: &mut Context) {
5621−fn hover(cx: &mut Context) {
5622− let (view, doc) = current!(cx.editor);
5624− let language_server = match doc.language_server() {
5625− Some(language_server) => language_server,
5629− // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier
5631− let pos = pos_to_lsp_pos(
5633− doc.selection(view.id)
5635− .cursor(doc.text().slice(..)),
5636− language_server.offset_encoding(),
5639− let future = language_server.text_document_hover(doc.identifier(), pos, None);
5643− move |editor: &mut Editor, compositor: &mut Compositor, response: Option<lsp::Hover>| {
5644− if let Some(hover) = response {
5645− // hover.contents / .range <- used for visualizing
5647− fn marked_string_to_markdown(contents: lsp::MarkedString) -> String {
5649− lsp::MarkedString::String(contents) => contents,
5650− lsp::MarkedString::LanguageString(string) => {
5651− if string.language == "markdown" {
5654− format!("```{}\n{}\n```", string.language, string.value)
5660− let contents = match hover.contents {
5661− lsp::HoverContents::Scalar(contents) => marked_string_to_markdown(contents),
5662− lsp::HoverContents::Array(contents) => contents
5664− .map(marked_string_to_markdown)
5665− .collect::<Vec<_>>()
5667− lsp::HoverContents::Markup(contents) => contents.value,
5670− // skip if contents empty
5673− ui::Markdown::new(contents, editor.syn_loader.clone()).style_group("hover");
5674− let popup = Popup::new("hover", contents);
5675− compositor.replace_or_push("hover", Box::new(popup));
5681// comments
4958// comments
5682fn toggle_comments(cx: &mut Context) {
4959fn toggle_comments(cx: &mut Context) {
5683 let (view, doc) = current!(cx.editor);
4960 let (view, doc) = current!(cx.editor);
@@ -6406,43 +5683,6 @@ fn add_newline_impl(cx: &mut Context, open: Open) {
6406 doc.apply(&transaction, view.id);
5683 doc.apply(&transaction, view.id);
6409−fn rename_symbol(cx: &mut Context) {
6410− let prompt = Prompt::new(
6411− "rename-to:".into(),
6413− ui::completers::none,
6414− move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6415− if event != PromptEvent::Validate {
6419− log::debug!("renaming to: {:?}", input);
6421− let (view, doc) = current!(cx.editor);
6422− let language_server = match doc.language_server() {
6423− Some(language_server) => language_server,
6427− let offset_encoding = language_server.offset_encoding();
6429− let pos = pos_to_lsp_pos(
6431− doc.selection(view.id)
6433− .cursor(doc.text().slice(..)),
6437− let task = language_server.rename_symbol(doc.identifier(), pos, input.to_string());
6438− let edits = block_on(task).unwrap_or_default();
6439− log::debug!("Edits from LSP: {:?}", edits);
6440− apply_workspace_edit(cx.editor, offset_encoding, &edits);
6443− cx.push_layer(Box::new(prompt));
6446/// Increment object under cursor by count.
5686/// Increment object under cursor by count.
6447fn increment(cx: &mut Context) {
5687fn increment(cx: &mut Context) {
6448 increment_impl(cx, cx.count() as i64);
5688 increment_impl(cx, cx.count() as i64);