Skip to content

Commit

Permalink
Changed file picker (helix-editor#5645)
Browse files Browse the repository at this point in the history
Co-authored-by: WJH <hou32hou@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Pascal Kuthe <pascalkuthe@pm.me>
  • Loading branch information
4 people authored and Desdaemon committed Apr 3, 2024
1 parent 5eca24b commit a96d737
Show file tree
Hide file tree
Showing 9 changed files with 380 additions and 24 deletions.
67 changes: 67 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions book/src/themes.md
Expand Up @@ -251,6 +251,7 @@ We use a similar set of scopes as
- `gutter` - gutter indicator
- `delta` - modifications
- `moved` - renamed or moved files/changes
- `conflict` - merge conflicts
- `gutter` - gutter indicator

#### Interface
Expand Down
100 changes: 97 additions & 3 deletions helix-term/src/commands.rs
Expand Up @@ -3,10 +3,14 @@ pub(crate) mod lsp;
pub(crate) mod typed;

pub use dap::*;
use helix_event::status;
use helix_stdx::rope::{self, RopeSliceExt};
use helix_vcs::Hunk;
use helix_vcs::{FileChange, Hunk};
pub use lsp::*;
use tui::widgets::Row;
use tui::{
text::Span,
widgets::{Cell, Row},
};
pub use typed::*;

use helix_core::{
Expand Down Expand Up @@ -39,6 +43,7 @@ use helix_view::{
info::Info,
input::KeyEvent,
keyboard::KeyCode,
theme::Style,
tree,
view::View,
Document, DocumentId, Editor, ViewId,
Expand All @@ -54,7 +59,7 @@ use crate::{
filter_picker_entry,
job::Callback,
keymap::ReverseKeymap,
ui::{self, overlay::overlaid, Picker, Popup, Prompt, PromptEvent},
ui::{self, menu::Item, overlay::overlaid, Picker, Popup, Prompt, PromptEvent},
};

use crate::job::{self, Jobs};
Expand Down Expand Up @@ -324,6 +329,7 @@ impl MappableCommand {
buffer_picker, "Open buffer picker",
jumplist_picker, "Open jumplist picker",
symbol_picker, "Open symbol picker",
changed_file_picker, "Open changed file picker",
select_references_to_symbol_under_cursor, "Select symbol references",
workspace_symbol_picker, "Open workspace symbol picker",
diagnostics_picker, "Open diagnostic picker",
Expand Down Expand Up @@ -2996,6 +3002,94 @@ fn jumplist_picker(cx: &mut Context) {
cx.push_layer(Box::new(overlaid(picker)));
}

fn changed_file_picker(cx: &mut Context) {
pub struct FileChangeData {
cwd: PathBuf,
style_untracked: Style,
style_modified: Style,
style_conflict: Style,
style_deleted: Style,
style_renamed: Style,
}

impl Item for FileChange {
type Data = FileChangeData;

fn format(&self, data: &Self::Data) -> Row {
let process_path = |path: &PathBuf| {
path.strip_prefix(&data.cwd)
.unwrap_or(path)
.display()
.to_string()
};

let (sign, style, content) = match self {
Self::Untracked { path } => ("[+]", data.style_untracked, process_path(path)),
Self::Modified { path } => ("[~]", data.style_modified, process_path(path)),
Self::Conflict { path } => ("[x]", data.style_conflict, process_path(path)),
Self::Deleted { path } => ("[-]", data.style_deleted, process_path(path)),
Self::Renamed { from_path, to_path } => (
"[>]",
data.style_renamed,
format!("{} -> {}", process_path(from_path), process_path(to_path)),
),
};

Row::new([Cell::from(Span::styled(sign, style)), Cell::from(content)])
}
}

let cwd = helix_stdx::env::current_working_dir();
if !cwd.exists() {
cx.editor
.set_error("Current working directory does not exist");
return;
}

let added = cx.editor.theme.get("diff.plus");
let modified = cx.editor.theme.get("diff.delta");
let conflict = cx.editor.theme.get("diff.delta.conflict");
let deleted = cx.editor.theme.get("diff.minus");
let renamed = cx.editor.theme.get("diff.delta.moved");

let picker = Picker::new(
Vec::new(),
FileChangeData {
cwd: cwd.clone(),
style_untracked: added,
style_modified: modified,
style_conflict: conflict,
style_deleted: deleted,
style_renamed: renamed,
},
|cx, meta: &FileChange, action| {
let path_to_open = meta.path();
if let Err(e) = cx.editor.open(path_to_open, action) {
let err = if let Some(err) = e.source() {
format!("{}", err)
} else {
format!("unable to open \"{}\"", path_to_open.display())
};
cx.editor.set_error(err);
}
},
)
.with_preview(|_editor, meta| Some((meta.path().to_path_buf().into(), None)));
let injector = picker.injector();

cx.editor
.diff_providers
.clone()
.for_each_changed_file(cwd, move |change| match change {
Ok(change) => injector.push(change).is_ok(),
Err(err) => {
status::report_blocking(err);
true
}
});
cx.push_layer(Box::new(overlaid(picker)));
}

impl ui::menu::Item for MappableCommand {
type Data = ReverseKeymap;

Expand Down
3 changes: 2 additions & 1 deletion helix-term/src/keymap/default.rs
Expand Up @@ -225,9 +225,10 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"S" => workspace_symbol_picker,
"d" => diagnostics_picker,
"D" => workspace_diagnostics_picker,
"g" => changed_file_picker,
"a" => code_action,
"'" => last_picker,
"g" => { "Debug (experimental)" sticky=true
"G" => { "Debug (experimental)" sticky=true
"l" => dap_launch,
"r" => dap_restart,
"b" => dap_toggle_breakpoint,
Expand Down
2 changes: 1 addition & 1 deletion helix-vcs/Cargo.toml
Expand Up @@ -19,7 +19,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "p
parking_lot = "0.12"
arc-swap = { version = "1.7.1" }

gix = { version = "0.61.0", features = ["attributes"], default-features = false, optional = true }
gix = { version = "0.61.0", features = ["attributes", "status"], default-features = false, optional = true }
imara-diff = "0.1.5"
anyhow = "1"

Expand Down

0 comments on commit a96d737

Please sign in to comment.