Skip to content

Commit

Permalink
Support going to specific positions in file
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI committed Dec 4, 2023
1 parent fcd564f commit 3ad8159
Showing 1 changed file with 74 additions and 2 deletions.
76 changes: 74 additions & 2 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,11 @@ fn goto_file_vsplit(cx: &mut Context) {

/// Goto files in selection.
fn goto_file_impl(cx: &mut Context, action: Action) {
struct OpenOption {
path: PathBuf,
location: Option<(usize, usize)>,
}

let (view, doc) = current_ref!(cx.editor);
let text = doc.text();
let selections = doc.selection(view.id);
Expand Down Expand Up @@ -1197,6 +1202,10 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
);
}

// Most compilers/linters print in this format
static REGEX_FILE_ROW_COL: Lazy<Regex> =
Lazy::new(|| Regex::new("^(?P<path>.[^:]+):(?P<row>\\d+)(:(?P<col>\\d+))?$").unwrap());

for sel in paths {
let p = sel.trim();
if p.is_empty() {
Expand All @@ -1211,8 +1220,71 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
if path.is_dir() {
let picker = ui::file_picker(path.into(), &cx.editor.config());
cx.push_layer(Box::new(overlaid(picker)));
} else if let Err(e) = cx.editor.open(path, action) {
cx.editor.set_error(format!("Open file failed: {:?}", e));
} else {
let open_option = match REGEX_FILE_ROW_COL.captures(p) {
Some(file_row_col) => {
let path = file_row_col.name("path").unwrap().as_str();
let loc = match file_row_col
.name("row")
.unwrap()
.as_str()
.parse::<NonZeroUsize>()
{
Ok(row) => match file_row_col.name("col") {
Some(col) => match col.as_str().parse::<NonZeroUsize>() {
Ok(col) => Some((row.get(), col.get())),
Err(_) => None,
},
None => Some((row.get(), 1)),
},
Err(_) => None,
};

OpenOption {
path: PathBuf::from(path),
location: loc,
}
}
None => OpenOption {
path: PathBuf::from(p),
location: None,
},
};

match cx.editor.open(&open_option.path, action) {
Ok(_) => {
if let Some((row, col)) = open_option.location {
let (view, doc) = current!(cx.editor);

let doc_text = doc.text();

// Number of lines is always positive even for empty buffers
let doc_lines = doc_text.len_lines();

// Zero-based line index
let ind_adjusted_line = usize::min(row, doc_lines) - 1;

let ind_dest = if row > doc_lines {
// Discard designated col and simply set to end of doc
doc_text.len_chars().saturating_sub(1)
} else {
let line_len = doc_text.line(ind_adjusted_line).len_chars();

let adjusted_ind_col = if line_len == 0 {
0
} else {
usize::min(col, line_len) - 1
};

doc_text.line_to_char(ind_adjusted_line) + adjusted_ind_col
};

doc.set_selection(view.id, Selection::point(ind_dest));
align_view(doc, view, Align::Center);
}
}
Err(e) => cx.editor.set_error(format!("Open file failed: {:?}", e)),
}
}
}
}
Expand Down

0 comments on commit 3ad8159

Please sign in to comment.