@@ -1,20 +1,21 @@
11use helix_core::{
22 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes, indent,
33 line_ending::{
4− get_line_ending, get_line_ending_of_str, line_end_char_index, rope_end_without_line_ending,
4+ get_line_ending_of_str, line_end_char_index, rope_end_without_line_ending,
55 str_is_line_ending,
66 },
77 match_brackets,
88 movement::{self, Direction},
99 object, pos_at_coords,
1010 regex::{self, Regex},
11− register::{self, Register, Registers},
12− search, selection, Change, ChangeSet, LineEnding, Position, Range, Rope, RopeGraphemes,
13− RopeSlice, Selection, SmallVec, Tendril, Transaction, DEFAULT_LINE_ENDING,
11+ register::Register,
12+ search, selection, LineEnding, Position, Range, Rope, RopeGraphemes, RopeSlice, Selection,
13+ SmallVec, Tendril, Transaction,
1414};
1515
1616use helix_view::{
1717 document::{IndentStyle, Mode},
18+ editor::Action,
1819 input::KeyEvent,
1920 keyboard::KeyCode,
2021 view::{View, PADDING},
@@ -25,19 +26,19 @@ use anyhow::anyhow;
2526use helix_lsp::{
2627 lsp,
2728 util::{lsp_pos_to_pos, lsp_range_to_range, pos_to_lsp_pos, range_to_lsp_range},
28− LspProgressMap, OffsetEncoding,
29+ OffsetEncoding,
2930};
3031use insert::*;
3132use movement::Movement;
3233
3334use crate::{
34− compositor::{self, Callback, Component, Compositor},
35− ui::{self, Completion, Picker, Popup, Prompt, PromptEvent},
35+ compositor::{self, Component, Compositor},
36+ ui::{self, Picker, Popup, Prompt, PromptEvent},
3637};
3738
38−use crate::job::{self, Job, JobFuture, Jobs};
39+use crate::job::{self, Job, Jobs};
3940use futures_util::{FutureExt, TryFutureExt};
40−use std::{fmt, future::Future, path::Display, str::FromStr};
41+use std::{fmt, future::Future};
4142
4243use std::{
4344 borrow::Cow,
@@ -59,7 +60,7 @@ pub struct Context<'a> {
5960
6061impl<'a> Context<'a> {
6162 /// Push a new component onto the compositor.
62− pub fn push_layer(&mut self, mut component: Box<dyn Component>) {
63+ pub fn push_layer(&mut self, component: Box<dyn Component>) {
6364 self.callback = Some(Box::new(|compositor: &mut Compositor| {
6465 compositor.push(component)
6566 }));
@@ -515,7 +516,7 @@ fn extend_next_word_start(cx: &mut Context) {
515516 let (view, doc) = current!(cx.editor);
516517 doc.set_selection(
517518 view.id,
518− doc.selection(view.id).clone().transform(|mut range| {
519+ doc.selection(view.id).clone().transform(|range| {
519520 let word = movement::move_next_word_start(doc.text().slice(..), range, count);
520521 let pos = word.head;
521522 Range::new(range.anchor, pos)
@@ -528,7 +529,7 @@ fn extend_prev_word_start(cx: &mut Context) {
528529 let (view, doc) = current!(cx.editor);
529530 doc.set_selection(
530531 view.id,
531− doc.selection(view.id).clone().transform(|mut range| {
532+ doc.selection(view.id).clone().transform(|range| {
532533 let word = movement::move_prev_word_start(doc.text().slice(..), range, count);
533534 let pos = word.head;
534535 Range::new(range.anchor, pos)
@@ -541,7 +542,7 @@ fn extend_next_word_end(cx: &mut Context) {
541542 let (view, doc) = current!(cx.editor);
542543 doc.set_selection(
543544 view.id,
544− doc.selection(view.id).clone().transform(|mut range| {
545+ doc.selection(view.id).clone().transform(|range| {
545546 let word = movement::move_next_word_end(doc.text().slice(..), range, count);
546547 let pos = word.head;
547548 Range::new(range.anchor, pos)
@@ -592,7 +593,7 @@ where
592593
593594 doc.set_selection(
594595 view.id,
595− doc.selection(view.id).clone().transform(|mut range| {
596+ doc.selection(view.id).clone().transform(|range| {
596597 search_fn(doc.text().slice(..), ch, range.head, count, inclusive).map_or(
597598 range,
598599 |pos| {
@@ -986,7 +987,7 @@ fn search_impl(doc: &mut Document, view: &mut View, contents: &str, regex: &Rege
986987
987988// TODO: use one function for search vs extend
988989fn search(cx: &mut Context) {
989− let (view, doc) = current!(cx.editor);
990+ let (_, doc) = current!(cx.editor);
990991
991992 // TODO: could probably share with select_on_matches?
992993
@@ -994,7 +995,6 @@ fn search(cx: &mut Context) {
994995 // feed chunks into the regex yet
995996 let contents = doc.text().slice(..).to_string();
996997
997− let view_id = view.id;
998998 let prompt = ui::regex_prompt(
999999 cx,
10001000 "search:".to_string(),
@@ -1046,7 +1046,7 @@ fn extend_line(cx: &mut Context) {
10461046 let line_start = text.char_to_line(pos.anchor);
10471047 let start = text.line_to_char(line_start);
10481048 let line_end = text.char_to_line(pos.head);
1049− let mut end = line_end_char_index(&text.slice(..), line_end);
1049+ let mut end = line_end_char_index(&text.slice(..), line_end + count.saturating_sub(1));
10501050
10511051 if pos.anchor == start && pos.head == end && line_end < (text.len_lines() - 2) {
10521052 end = line_end_char_index(&text.slice(..), line_end + 1);
@@ -1065,7 +1065,6 @@ fn delete_selection_impl(reg: &mut Register, doc: &mut Document, view_id: ViewId
10651065
10661066 // then delete
10671067 let transaction = Transaction::change_by_selection(doc.text(), &selection, |range| {
1068− let line = text.char_to_line(range.head);
10691068 (range.from(), range.to(), None)
10701069 });
10711070 doc.apply(&transaction, view_id);
@@ -1175,7 +1174,7 @@ mod cmd {
11751174 pub completer: Option<Completer>,
11761175 }
11771176
1178− fn quit(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1177+ fn quit(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
11791178 // last view and we have unsaved changes
11801179 if cx.editor.tree.views().count() == 1 && buffers_remaining_impl(cx.editor) {
11811180 return;
@@ -1184,16 +1183,16 @@ mod cmd {
11841183 .close(view!(cx.editor).id, /* close_buffer */ false);
11851184 }
11861185
1187− fn force_quit(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1186+ fn force_quit(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
11881187 cx.editor
11891188 .close(view!(cx.editor).id, /* close_buffer */ false);
11901189 }
11911190
1192− fn open(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1191+ fn open(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
11931192 match args.get(0) {
11941193 Some(path) => {
11951194 // TODO: handle error
1196− cx.editor.open(path.into(), Action::Replace);
1195+ let _ = cx.editor.open(path.into(), Action::Replace);
11971196 }
11981197 None => {
11991198 cx.editor.set_error("wrong argument count".to_string());
@@ -1205,9 +1204,8 @@ mod cmd {
12051204 cx: &mut compositor::Context,
12061205 path: Option<P>,
12071206 ) -> Result<tokio::task::JoinHandle<Result<(), anyhow::Error>>, anyhow::Error> {
1208− use anyhow::anyhow;
12091207 let jobs = &mut cx.jobs;
1210− let (view, doc) = current!(cx.editor);
1208+ let (_, doc) = current!(cx.editor);
12111209
12121210 if let Some(path) = path {
12131211 if let Err(err) = doc.set_path(path.as_ref()) {
@@ -1231,7 +1229,7 @@ mod cmd {
12311229 Ok(tokio::spawn(doc.format_and_save(fmt)))
12321230 }
12331231
1234− fn write(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1232+ fn write(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
12351233 match write_impl(cx, args.first()) {
12361234 Err(e) => cx.editor.set_error(e.to_string()),
12371235 Ok(handle) => {
@@ -1241,11 +1239,11 @@ mod cmd {
12411239 };
12421240 }
12431241
1244− fn new_file(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1242+ fn new_file(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
12451243 cx.editor.new_file(Action::Replace);
12461244 }
12471245
1248− fn format(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1246+ fn format(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
12491247 let (_, doc) = current!(cx.editor);
12501248
12511249 if let Some(format) = doc.format() {
@@ -1255,7 +1253,7 @@ mod cmd {
12551253 }
12561254 }
12571255
1258− fn set_indent_style(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1256+ fn set_indent_style(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
12591257 use IndentStyle::*;
12601258
12611259 // If no argument, report current indent style.
@@ -1293,7 +1291,7 @@ mod cmd {
12931291 }
12941292
12951293 /// Sets or reports the current document's line ending setting.
1296− fn set_line_ending(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1294+ fn set_line_ending(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
12971295 use LineEnding::*;
12981296
12991297 // If no argument, report current line ending setting.
@@ -1332,7 +1330,7 @@ mod cmd {
13321330 }
13331331 }
13341332
1335− fn earlier(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1333+ fn earlier(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
13361334 let uk = match args.join(" ").parse::<helix_core::history::UndoKind>() {
13371335 Ok(uk) => uk,
13381336 Err(msg) => {
@@ -1344,7 +1342,7 @@ mod cmd {
13441342 doc.earlier(view.id, uk)
13451343 }
13461344
1347− fn later(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1345+ fn later(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
13481346 let uk = match args.join(" ").parse::<helix_core::history::UndoKind>() {
13491347 Ok(uk) => uk,
13501348 Err(msg) => {
@@ -1372,7 +1370,6 @@ mod cmd {
13721370 }
13731371
13741372 fn force_write_quit(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1375− let (view, doc) = current!(cx.editor);
13761373 match write_impl(cx, args.first()) {
13771374 Ok(handle) => {
13781375 if let Err(e) = helix_lsp::block_on(handle) {
@@ -1414,20 +1411,22 @@ mod cmd {
14141411
14151412 fn write_all_impl(
14161413 editor: &mut Editor,
1417− args: &[&str],
1418− event: PromptEvent,
1414+ _args: &[&str],
1415+ _event: PromptEvent,
14191416 quit: bool,
14201417 force: bool,
14211418 ) {
14221419 let mut errors = String::new();
14231420
14241421 // save all documents
1425− for (id, mut doc) in &mut editor.documents {
1422+ for (_, doc) in &mut editor.documents {
14261423 if doc.path().is_none() {
14271424 errors.push_str("cannot write a buffer without a filename\n");
14281425 continue;
14291426 }
1430− helix_lsp::block_on(tokio::spawn(doc.save()));
1427+
1428+ // TODO: handle error.
1429+ let _ = helix_lsp::block_on(tokio::spawn(doc.save()));
14311430 }
14321431 editor.set_error(errors);
14331432
@@ -1456,7 +1455,7 @@ mod cmd {
14561455 write_all_impl(&mut cx.editor, args, event, true, true)
14571456 }
14581457
1459− fn quit_all_impl(editor: &mut Editor, args: &[&str], event: PromptEvent, force: bool) {
1458+ fn quit_all_impl(editor: &mut Editor, _args: &[&str], _event: PromptEvent, force: bool) {
14601459 if !force && buffers_remaining_impl(editor) {
14611460 return;
14621461 }
@@ -1476,7 +1475,7 @@ mod cmd {
14761475 quit_all_impl(&mut cx.editor, args, event, true)
14771476 }
14781477
1479− fn theme(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1478+ fn theme(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
14801479 let theme = if let Some(theme) = args.first() {
14811480 theme
14821481 } else {
@@ -1487,11 +1486,15 @@ mod cmd {
14871486 cx.editor.set_theme_from_name(theme);
14881487 }
14891488
1490− fn yank_main_selection_to_clipboard(cx: &mut compositor::Context, _: &[&str], _: PromptEvent) {
1489+ fn yank_main_selection_to_clipboard(
1490+ cx: &mut compositor::Context,
1491+ _args: &[&str],
1492+ _event: PromptEvent,
1493+ ) {
14911494 yank_main_selection_to_clipboard_impl(&mut cx.editor);
14921495 }
14931496
1494− fn yank_joined_to_clipboard(cx: &mut compositor::Context, args: &[&str], _: PromptEvent) {
1497+ fn yank_joined_to_clipboard(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
14951498 let (_, doc) = current!(cx.editor);
14961499 let separator = args
14971500 .first()
@@ -1500,15 +1503,19 @@ mod cmd {
15001503 yank_joined_to_clipboard_impl(&mut cx.editor, separator);
15011504 }
15021505
1503− fn paste_clipboard_after(cx: &mut compositor::Context, _: &[&str], _: PromptEvent) {
1506+ fn paste_clipboard_after(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
15041507 paste_clipboard_impl(&mut cx.editor, Paste::After);
15051508 }
15061509
1507− fn paste_clipboard_before(cx: &mut compositor::Context, _: &[&str], _: PromptEvent) {
1510+ fn paste_clipboard_before(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
15081511 paste_clipboard_impl(&mut cx.editor, Paste::After);
15091512 }
15101513
1511− fn replace_selections_with_clipboard(cx: &mut compositor::Context, _: &[&str], _: PromptEvent) {
1514+ fn replace_selections_with_clipboard(
1515+ cx: &mut compositor::Context,
1516+ _args: &[&str],
1517+ _event: PromptEvent,
1518+ ) {
15121519 let (view, doc) = current!(cx.editor);
15131520
15141521 match cx.editor.clipboard_provider.get_contents() {
@@ -1529,12 +1536,12 @@ mod cmd {
15291536 }
15301537 }
15311538
1532− fn show_clipboard_provider(cx: &mut compositor::Context, _: &[&str], _: PromptEvent) {
1539+ fn show_clipboard_provider(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
15331540 cx.editor
15341541 .set_status(cx.editor.clipboard_provider.name().into());
15351542 }
15361543
1537− fn change_current_directory(cx: &mut compositor::Context, args: &[&str], _: PromptEvent) {
1544+ fn change_current_directory(cx: &mut compositor::Context, args: &[&str], _event: PromptEvent) {
15381545 let dir = match args.first() {
15391546 Some(dir) => dir,
15401547 None => {
@@ -1562,7 +1569,7 @@ mod cmd {
15621569 }
15631570 }
15641571
1565− fn show_current_directory(cx: &mut compositor::Context, args: &[&str], _: PromptEvent) {
1572+ fn show_current_directory(cx: &mut compositor::Context, _args: &[&str], _event: PromptEvent) {
15661573 match std::env::current_dir() {
15671574 Ok(cwd) => cx
15681575 .editor
@@ -1782,7 +1789,6 @@ fn command_mode(cx: &mut Context) {
17821789 // simple heuristic: if there's no just one part, complete command name.
17831790 // if there's a space, per command completion kicks in.
17841791 if parts.len() <= 1 {
1785− use std::{borrow::Cow, ops::Range};
17861792 let end = 0..;
17871793 cmd::TYPABLE_COMMAND_LIST
17881794 .iter()
@@ -1812,8 +1818,6 @@ fn command_mode(cx: &mut Context) {
18121818 }
18131819 }, // completion
18141820 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
1815− use helix_view::editor::Action;
1816−
18171821 if event != PromptEvent::Validate {
18181822 return;
18191823 }
@@ -1851,7 +1855,6 @@ fn file_picker(cx: &mut Context) {
18511855}
18521856
18531857fn buffer_picker(cx: &mut Context) {
1854− use std::path::{Path, PathBuf};
18551858 let current = view!(cx.editor).doc;
18561859
18571860 let picker = Picker::new(
@@ -1874,7 +1877,6 @@ fn buffer_picker(cx: &mut Context) {
18741877 }
18751878 },
18761879 |editor: &mut Editor, (id, _path): &(DocumentId, Option<PathBuf>), _action| {
1877− use helix_view::editor::Action;
18781880 editor.switch(*id, Action::Replace);
18791881 },
18801882 );
@@ -1900,7 +1902,7 @@ fn symbol_picker(cx: &mut Context) {
19001902 nested_to_flat(list, file, child);
19011903 }
19021904 }
1903− let (view, doc) = current!(cx.editor);
1905+ let (_, doc) = current!(cx.editor);
19041906
19051907 let language_server = match doc.language_server() {
19061908 Some(language_server) => language_server,
@@ -1993,7 +1995,7 @@ async fn make_format_callback(
19931995 format: impl Future<Output = helix_lsp::util::LspFormatting> + Send + 'static,
19941996) -> anyhow::Result<job::Callback> {
19951997 let format = format.await;
1996− let call: job::Callback = Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
1998+ let call: job::Callback = Box::new(move |editor: &mut Editor, _compositor: &mut Compositor| {
19971999 let view_id = view!(editor).id;
19982000 if let Some(doc) = editor.document_mut(doc_id) {
19992001 if doc.version() == doc_version {
@@ -2168,9 +2170,6 @@ fn goto_mode(cx: &mut Context) {
21682170 (_, 't') | (_, 'm') | (_, 'b') => {
21692171 let (view, doc) = current!(cx.editor);
21702172
2171− let pos = doc.selection(view.id).cursor();
2172− let line = doc.text().char_to_line(pos);
2173−
21742173 let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
21752174
21762175 let last_line = view.last_line(doc);
@@ -2207,8 +2206,6 @@ fn goto_impl(
22072206 locations: Vec<lsp::Location>,
22082207 offset_encoding: OffsetEncoding,
22092208) {
2210− use helix_view::editor::Action;
2211−
22122209 push_jump(editor);
22132210
22142211 fn jump_to(
@@ -2221,7 +2218,7 @@ fn goto_impl(
22212218 .uri
22222219 .to_file_path()
22232220 .expect("unable to convert URI to filepath");
2224− let id = editor.open(path, action).expect("editor.open failed");
2221+ let _id = editor.open(path, action).expect("editor.open failed");
22252222 let (view, doc) = current!(editor);
22262223 let definition_pos = location.range.start;
22272224 // TODO: convert inside server
@@ -2243,7 +2240,7 @@ fn goto_impl(
22432240 editor.set_error("No definition found.".to_string());
22442241 }
22452242 _locations => {
2246− let mut picker = ui::Picker::new(
2243+ let picker = ui::Picker::new(
22472244 locations,
22482245 |location| {
22492246 let file = location.uri.as_str();
@@ -2410,9 +2407,8 @@ fn goto_pos(editor: &mut Editor, pos: usize) {
24102407
24112408fn goto_first_diag(cx: &mut Context) {
24122409 let editor = &mut cx.editor;
2413− let (view, doc) = current!(editor);
2410+ let (_, doc) = current!(editor);
24142411
2415− let cursor_pos = doc.selection(view.id).cursor();
24162412 let diag = if let Some(diag) = doc.diagnostics().first() {
24172413 diag.range.start
24182414 } else {
@@ -2424,9 +2420,8 @@ fn goto_first_diag(cx: &mut Context) {
24242420
24252421fn goto_last_diag(cx: &mut Context) {
24262422 let editor = &mut cx.editor;
2427− let (view, doc) = current!(editor);
2423+ let (_, doc) = current!(editor);
24282424
2429− let cursor_pos = doc.selection(view.id).cursor();
24302425 let diag = if let Some(diag) = doc.diagnostics().last() {
24312426 diag.range.start
24322427 } else {
@@ -2498,8 +2493,8 @@ fn signature_help(cx: &mut Context) {
24982493
24992494 cx.callback(
25002495 future,
2501− move |editor: &mut Editor,
2502− compositor: &mut Compositor,
2496+ move |_editor: &mut Editor,
2497+ _compositor: &mut Compositor,
25032498 response: Option<lsp::SignatureHelp>| {
25042499 if let Some(signature_help) = response {
25052500 log::info!("{:?}", signature_help);
@@ -3080,8 +3075,10 @@ fn format_selections(cx: &mut Context) {
30803075 .map(|range| range_to_lsp_range(doc.text(), *range, language_server.offset_encoding()))
30813076 .collect();
30823077
3083− for range in ranges {
3084− let language_server = match doc.language_server() {
3078+ // TODO: all of the TODO's and commented code inside the loop,
3079+ // to make this actually work.
3080+ for _range in ranges {
3081+ let _language_server = match doc.language_server() {
30853082 Some(language_server) => language_server,
30863083 None => return,
30873084 };
@@ -3129,7 +3126,7 @@ fn join_selections(cx: &mut Context) {
31293126 changes.reserve(lines.len());
31303127
31313128 for line in lines {
3132− let mut start = line_end_char_index(&slice, line);
3129+ let start = line_end_char_index(&slice, line);
31333130 let mut end = text.line_to_char(line + 1);
31343131 end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
31353132
@@ -3252,7 +3249,6 @@ fn completion(cx: &mut Context) {
32523249 if items.is_empty() {
32533250 return;
32543251 }
3255− use crate::compositor::AnyComponent;
32563252 let size = compositor.size();
32573253 let ui = compositor
32583254 .find(std::any::type_name::<ui::EditorView>())
@@ -3306,7 +3302,7 @@ fn hover(cx: &mut Context) {
33063302 // skip if contents empty
33073303
33083304 let contents = ui::Markdown::new(contents, editor.syn_loader.clone());
3309− let mut popup = Popup::new(contents);
3305+ let popup = Popup::new(contents);
33103306 compositor.push(Box::new(popup));
33113307 }
33123308 },
@@ -3350,7 +3346,7 @@ fn match_brackets(cx: &mut Context) {
33503346
33513347fn jump_forward(cx: &mut Context) {
33523348 let count = cx.count();
3353− let (view, doc) = current!(cx.editor);
3349+ let (view, _doc) = current!(cx.editor);
33543350
33553351 if let Some((id, selection)) = view.jumps.forward(count) {
33563352 view.doc = *id;
@@ -3403,11 +3399,7 @@ fn rotate_view(cx: &mut Context) {
34033399}
34043400
34053401// split helper, clear it later
3406−use helix_view::editor::Action;
3407−
3408−use self::cmd::TypableCommand;
34093402fn split(cx: &mut Context, action: Action) {
3410− use helix_view::editor::Action;
34113403 let (view, doc) = current!(cx.editor);
34123404 let id = doc.id();
34133405 let selection = doc.selection(view.id).clone();
@@ -3563,10 +3555,7 @@ fn match_mode(cx: &mut Context) {
35633555 'm' => match_brackets(cx),
35643556 's' => surround_add(cx),
35653557 'r' => surround_replace(cx),
3566− 'd' => {
3567− surround_delete(cx);
3568− let (view, doc) = current!(cx.editor);
3569− }
3558+ 'd' => surround_delete(cx),
35703559 _ => (),
35713560 }
35723561 }
@@ -3588,7 +3577,7 @@ fn surround_add(cx: &mut Context) {
35883577 let (open, close) = surround::get_pair(ch);
35893578
35903579 let mut changes = Vec::new();
3591− for (i, range) in selection.iter().enumerate() {
3580+ for range in selection.iter() {
35923581 changes.push((range.from(), range.from(), Some(Tendril::from_char(open))));
35933582 changes.push((range.to(), range.to(), Some(Tendril::from_char(close))));
35943583 }