Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#195): display current path in the strider #1681

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions default-plugins/strider/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ impl ZellijPlugin for State {
Mouse::ScrollUp(_) => {
*self.selected_mut() = self.selected().saturating_sub(1);
},
Mouse::Release(line, _) => {
if line < 0 {
Mouse::Release(mut line, _) => {
// we need to shift the line with line -=1 because one line
// is occupied by the current path, and all clicks on it are
// to be ignored
if line < 1 {
return;
}
line -= 1;
let mut should_select = true;
if let Some((Event::Mouse(Mouse::Release(prev_line, _)), t)) = prev_event {
if prev_line == line
tlinford marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -85,7 +89,14 @@ impl ZellijPlugin for State {
}

fn render(&mut self, rows: usize, cols: usize) {
for i in 0..rows {
let display_current_dir = FsEntry::DisplayDir(self.current_dir.clone())
.as_line(cols)
.normal()
.on_yellow()
.black();
println!("{}", display_current_dir);

for i in 0..rows - 1 {
if self.selected() < self.scroll() {
*self.scroll_mut() = self.selected();
}
Expand Down
67 changes: 60 additions & 7 deletions default-plugins/strider/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct State {
pub cursor_hist: HashMap<PathBuf, (usize, usize)>,
pub hide_hidden_files: bool,
pub ev_history: VecDeque<(Event, Instant)>, // stores last event, can be expanded in future
pub current_dir: PathBuf,
}

impl State {
Expand All @@ -41,6 +42,7 @@ impl State {
refresh_directory(self);
},
FsEntry::File(p, _) => open_file(p.strip_prefix(ROOT).unwrap()),
FsEntry::DisplayDir(_) => {},
}
}
}
Expand All @@ -50,38 +52,89 @@ impl State {
pub enum FsEntry {
Dir(PathBuf, usize),
File(PathBuf, u64),
DisplayDir(PathBuf),
}

impl FsEntry {
pub fn name(&self) -> String {
let path = match self {
FsEntry::Dir(p, _) => p,
FsEntry::File(p, _) => p,
FsEntry::DisplayDir(p) => p,
};
path.file_name().unwrap().to_string_lossy().into_owned()
match self {
FsEntry::File(..) | FsEntry::Dir(..) => {
// only use the filename
path.file_name().unwrap().to_string_lossy().into_owned()
},
FsEntry::DisplayDir(..) => {
// use full path, but we need to remove the host part
let path = path.to_string_lossy().into_owned().replace("/host", "");
".".to_string() + &path
knidarkness marked this conversation as resolved.
Show resolved Hide resolved
},
}
}

pub fn as_line(&self, width: usize) -> String {
let name = self.name();
let info = match self {
FsEntry::Dir(_, s) => s.to_string(),
FsEntry::File(_, s) => pb::convert(*s as f64),
FsEntry::DisplayDir(..) => {
let current_path = name.clone();
FsEntry::display_with_shortened_name_start(current_path, width)
Comment on lines +83 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should just return empty string? just did another run and i'm seeing extra output on the right

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, thanks for pointing this out. I will check this today in the evening.

},
};
let space = width.saturating_sub(info.len());
let name = self.name();
if space.saturating_sub(1) < name.len() {
[&name[..space.saturating_sub(2)], &info].join("~ ")
// + 1 since we want to have a space between name and info
let content_width = name.len() + info.len() + 1;
if width < content_width {
// The content doesn't fit on the screen
match self {
FsEntry::File(..) | FsEntry::Dir(..) => {
FsEntry::display_with_shortened_name_end(name, info, width)
},
FsEntry::DisplayDir(..) => {
let current_path = name;
FsEntry::display_with_shortened_name_start(current_path, width)
},
}
} else {
let padding = " ".repeat(space - name.len());
[name, padding, info].concat()
// The content does fit on the screen
FsEntry::display_with_padding(name, info, width)
}
}

fn display_with_shortened_name_end(name: String, extra_info: String, width: usize) -> String {
const ENDING: &str = "~ ";
let shortened_name_len = width.saturating_sub(ENDING.len() + extra_info.len());
let shortened_name = &name[..shortened_name_len];
[shortened_name, &extra_info].join(ENDING)
}

fn display_with_shortened_name_start(current_path: String, width: usize) -> String {
const FRONT: &str = "./...";
const END: &str = " ";
const NEEDED_SPACE: usize = FRONT.len() + END.len();
let current_path_len = current_path.len();
let displayed_path_len = width.saturating_sub(NEEDED_SPACE);
let display_path_start_index = current_path_len.saturating_sub(displayed_path_len);
let shortened_path = &current_path[display_path_start_index..];
[FRONT, shortened_path, END].join("")
}

fn display_with_padding(name: String, extra_info: String, width: usize) -> String {
let content_len = name.len() + extra_info.len();
let padding = " ".repeat(width - content_len);
[name, padding, extra_info].concat()
}

pub fn is_hidden_file(&self) -> bool {
self.name().starts_with('.')
}
}

pub(crate) fn refresh_directory(state: &mut State) {
state.current_dir = state.path.clone();
state.files = read_dir(Path::new(ROOT).join(&state.path))
.unwrap()
.filter_map(|res| {
Expand Down