Skip to content

Commit a2cf09e

Browse files
dariooddeninothe-mikedavis
authored andcommitted
Trim quotes and braces from paths in goto_file_impl (helix-editor#4370)
Co-authored-by: Michael Davis <[email protected]>
1 parent 55fe542 commit a2cf09e

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

helix-term/src/commands.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ fn goto_file_vsplit(cx: &mut Context) {
10231023
goto_file_impl(cx, Action::VerticalSplit);
10241024
}
10251025

1026+
/// Goto files in selection.
10261027
fn goto_file_impl(cx: &mut Context, action: Action) {
10271028
let (view, doc) = current_ref!(cx.editor);
10281029
let text = doc.text();
@@ -1032,15 +1033,25 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
10321033
.map(|r| text.slice(r.from()..r.to()).to_string())
10331034
.collect();
10341035
let primary = selections.primary();
1035-
if selections.len() == 1 && primary.to() - primary.from() == 1 {
1036-
let current_word = movement::move_next_long_word_start(
1037-
text.slice(..),
1038-
movement::move_prev_long_word_start(text.slice(..), primary, 1),
1039-
1,
1036+
// Checks whether there is only one selection with a width of 1
1037+
if selections.len() == 1 && primary.len() == 1 {
1038+
let count = cx.count();
1039+
let text_slice = text.slice(..);
1040+
// In this case it selects the WORD under the cursor
1041+
let current_word = textobject::textobject_word(
1042+
text_slice,
1043+
primary,
1044+
textobject::TextObject::Inside,
1045+
count,
1046+
true,
10401047
);
1048+
// Trims some surrounding chars so that the actual file is opened.
1049+
let surrounding_chars: &[_] = &['\'', '"', '(', ')'];
10411050
paths.clear();
10421051
paths.push(
1043-
text.slice(current_word.from()..current_word.to())
1052+
current_word
1053+
.fragment(text_slice)
1054+
.trim_matches(surrounding_chars)
10441055
.to_string(),
10451056
);
10461057
}

helix-term/tests/test/commands.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::ops::RangeInclusive;
22

33
use helix_core::diagnostic::Severity;
4+
use helix_term::application::Application;
45

56
use super::*;
67

@@ -133,3 +134,62 @@ async fn test_selection_duplication() -> anyhow::Result<()> {
133134
.await?;
134135
Ok(())
135136
}
137+
138+
#[tokio::test(flavor = "multi_thread")]
139+
async fn test_goto_file_impl() -> anyhow::Result<()> {
140+
let file = tempfile::NamedTempFile::new()?;
141+
142+
fn match_paths(app: &Application, matches: Vec<&str>) -> usize {
143+
app.editor
144+
.documents()
145+
.filter_map(|d| d.path()?.file_name())
146+
.filter(|n| matches.iter().any(|m| *m == n.to_string_lossy()))
147+
.count()
148+
}
149+
150+
// Single selection
151+
test_key_sequence(
152+
&mut AppBuilder::new().with_file(file.path(), None).build()?,
153+
Some("ione.js<esc>%gf"),
154+
Some(&|app| {
155+
assert_eq!(1, match_paths(app, vec!["one.js"]));
156+
}),
157+
false,
158+
)
159+
.await?;
160+
161+
// Multiple selection
162+
test_key_sequence(
163+
&mut AppBuilder::new().with_file(file.path(), None).build()?,
164+
Some("ione.js<ret>two.js<esc>%<A-s>gf"),
165+
Some(&|app| {
166+
assert_eq!(2, match_paths(app, vec!["one.js", "two.js"]));
167+
}),
168+
false,
169+
)
170+
.await?;
171+
172+
// Cursor on first quote
173+
test_key_sequence(
174+
&mut AppBuilder::new().with_file(file.path(), None).build()?,
175+
Some("iimport 'one.js'<esc>B;gf"),
176+
Some(&|app| {
177+
assert_eq!(1, match_paths(app, vec!["one.js"]));
178+
}),
179+
false,
180+
)
181+
.await?;
182+
183+
// Cursor on last quote
184+
test_key_sequence(
185+
&mut AppBuilder::new().with_file(file.path(), None).build()?,
186+
Some("iimport 'one.js'<esc>bgf"),
187+
Some(&|app| {
188+
assert_eq!(1, match_paths(app, vec!["one.js"]));
189+
}),
190+
false,
191+
)
192+
.await?;
193+
194+
Ok(())
195+
}

0 commit comments

Comments
 (0)