Skip to content

Commit 10122c3

Browse files
committed
Changed file picker
1 parent a4751db commit 10122c3

File tree

8 files changed

+558
-6
lines changed

8 files changed

+558
-6
lines changed

Cargo.lock

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

helix-term/src/commands.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ impl MappableCommand {
284284
buffer_picker, "Open buffer picker",
285285
jumplist_picker, "Open jumplist picker",
286286
symbol_picker, "Open symbol picker",
287+
changed_file_picker, "Open changed file picker",
287288
select_references_to_symbol_under_cursor, "Select symbol references",
288289
workspace_symbol_picker, "Open workspace symbol picker",
289290
diagnostics_picker, "Open diagnostic picker",
@@ -2579,6 +2580,46 @@ fn jumplist_picker(cx: &mut Context) {
25792580
cx.push_layer(Box::new(overlayed(picker)));
25802581
}
25812582

2583+
fn changed_file_picker(cx: &mut Context) {
2584+
let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("./"));
2585+
2586+
let entries = match cx.editor.diff_providers.get_changed_files(&cwd) {
2587+
Ok(entries) => entries,
2588+
Err(err) => {
2589+
cx.editor.set_error(format!("{err}"));
2590+
return;
2591+
}
2592+
};
2593+
2594+
let added = cx.editor.theme.get("diff.plus");
2595+
let deleted = cx.editor.theme.get("diff.minus");
2596+
let modified = cx.editor.theme.get("diff.delta");
2597+
2598+
let picker = FilePicker::new(
2599+
entries,
2600+
ui::menu::FileChangeData {
2601+
cwd,
2602+
style_untracked: added,
2603+
style_modified: modified,
2604+
style_deleted: deleted,
2605+
style_renamed: modified,
2606+
},
2607+
|cx, meta, action| {
2608+
let path_to_open = meta.path();
2609+
if let Err(e) = cx.editor.open(path_to_open, action) {
2610+
let err = if let Some(err) = e.source() {
2611+
format!("{}", err)
2612+
} else {
2613+
format!("unable to open \"{}\"", path_to_open.display())
2614+
};
2615+
cx.editor.set_error(err);
2616+
}
2617+
},
2618+
|_editor, meta| Some((meta.path().to_path_buf().into(), None)),
2619+
);
2620+
cx.push_layer(Box::new(overlayed(picker)));
2621+
}
2622+
25822623
impl ui::menu::Item for MappableCommand {
25832624
type Data = ReverseKeymap;
25842625

helix-term/src/keymap/default.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,10 @@ pub fn default() -> HashMap<Mode, Keymap> {
219219
"S" => workspace_symbol_picker,
220220
"d" => diagnostics_picker,
221221
"D" => workspace_diagnostics_picker,
222+
"g" => changed_file_picker,
222223
"a" => code_action,
223224
"'" => last_picker,
224-
"g" => { "Debug (experimental)" sticky=true
225+
"G" => { "Debug (experimental)" sticky=true
225226
"l" => dap_launch,
226227
"b" => dap_toggle_breakpoint,
227228
"c" => dap_continue,

helix-term/src/ui/menu.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ pub use tui::widgets::{Cell, Row};
1111
use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
1212
use fuzzy_matcher::FuzzyMatcher;
1313

14-
use helix_view::{graphics::Rect, Editor};
14+
use helix_vcs::FileChange;
15+
use helix_view::{graphics::Rect, theme::Style, Editor};
1516
use tui::layout::Constraint;
1617

1718
pub trait Item {
@@ -45,6 +46,37 @@ impl Item for PathBuf {
4546

4647
pub type MenuCallback<T> = Box<dyn Fn(&mut Editor, Option<&T>, MenuEvent)>;
4748

49+
pub struct FileChangeData {
50+
pub cwd: PathBuf,
51+
pub style_untracked: Style,
52+
pub style_modified: Style,
53+
pub style_deleted: Style,
54+
pub style_renamed: Style,
55+
}
56+
57+
impl Item for FileChange {
58+
type Data = FileChangeData;
59+
60+
fn format(&self, data: &Self::Data) -> Row {
61+
let (sign, style) = match self {
62+
Self::Untracked { .. } => ("[+]", data.style_untracked),
63+
Self::Modified { .. } => ("[~]", data.style_modified),
64+
Self::Deleted { .. } => ("[-]", data.style_deleted),
65+
Self::Renamed { .. } => ("[>]", data.style_modified),
66+
};
67+
let path = self.path();
68+
69+
Row::new(vec![
70+
sign.to_owned(),
71+
path.strip_prefix(&data.cwd)
72+
.unwrap_or(path)
73+
.to_string_lossy()
74+
.to_string(),
75+
])
76+
.style(style)
77+
}
78+
}
79+
4880
pub struct Menu<T: Item> {
4981
options: Vec<T>,
5082
editor_data: T::Data,

helix-vcs/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ homepage = "https://helix-editor.com"
1313
[dependencies]
1414
helix-core = { version = "0.6", path = "../helix-core" }
1515

16+
anyhow = "1.0"
1617
tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] }
1718
parking_lot = "0.12"
1819

20+
content_inspector = "0.2.4"
1921
git-repository = { version = "0.32", default-features = false , optional = true }
22+
ignore = "0.4"
2023
imara-diff = "0.1.5"
24+
sha1 = "0.10.0"
2125

2226
log = "0.4"
2327

helix-vcs/src/diff.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::ops::Range;
2+
use std::path::{Path, PathBuf};
23
use std::sync::Arc;
34

45
use helix_core::Rope;
@@ -277,3 +278,30 @@ impl FileHunks<'_> {
277278
}
278279
}
279280
}
281+
282+
pub enum FileChange {
283+
Untracked {
284+
path: PathBuf,
285+
},
286+
Modified {
287+
path: PathBuf,
288+
},
289+
Deleted {
290+
path: PathBuf,
291+
},
292+
Renamed {
293+
from_path: PathBuf,
294+
to_path: PathBuf,
295+
},
296+
}
297+
298+
impl FileChange {
299+
pub fn path(&self) -> &Path {
300+
match self {
301+
Self::Untracked { path } => path,
302+
Self::Modified { path } => path,
303+
Self::Deleted { path } => path,
304+
Self::Renamed { to_path, .. } => to_path,
305+
}
306+
}
307+
}

0 commit comments

Comments
 (0)