Skip to content

Commit

Permalink
Merge pull request #2 from Araxeus/refactor
Browse files Browse the repository at this point in the history
v1.2.0 ✨
  • Loading branch information
Araxeus authored May 9, 2022
2 parents f04368f + fafe320 commit efeb629
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 114 deletions.
57 changes: 56 additions & 1 deletion Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ls-interactive"
description = "Interactive ls command"
version = "1.1.2"
version = "1.2.0"
authors = ["Araxeus <[email protected]>"]
homepage = "https://github.com/Araxeus/ls-interactive"
license = "MIT"
Expand All @@ -16,6 +16,7 @@ dialoguer = "0.10.0"
console = "0.15.0"
open = "2.1.2"
human-panic = "1.0.3"
lnk = "0.3.0"

[[bin]]
name = "lsi"
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,16 @@ clone/download the repo
run in project directory:
* `cargo run`: to run in dev mode
* `cargo build --release`: to build locally, output will be in `target\release` and named named `lsi`

## Contributing

Before submitting a Pull Request, verify your changes with all following commands:
```mcfunction
cargo check
```
```mcfunction
cargo fmt --all --check
```
```mcfunction
cargo clippy --all-targets --all-features -- -W clippy::pedantic -W clippy::cargo -W clippy::nursery
```
32 changes: 0 additions & 32 deletions src/icons.rs

This file was deleted.

118 changes: 38 additions & 80 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,120 +1,78 @@
mod icons;
mod structs;
mod utils;

use std::env;
use std::fmt;
use std::fs;
use std::path::Path;

struct Entry {
name: String,
path: String,
icon: String,
is_dir: bool,
is_link: bool,
}

impl fmt::Display for Entry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.icon, self.name)
}
}
use structs::{Entry, Filetype, Icons};
use utils::{display_choices, err, resolve_lnk};

fn main() {
human_panic::setup_panic!();

let args: Vec<String> = env::args().collect();
let path = if args.len() >= 2 { args[1].trim() } else { "." };

let path = fs::canonicalize(path);
let path = if args.len() >= 2 { args[1].trim() } else { "." };

match path {
Ok(path) => open_entry(path.to_str().unwrap()),
Err(_) => println!("Invalid path"),
match fs::canonicalize(path) {
Ok(path) => main_loop(path.to_string_lossy().to_string()),
Err(_) => err("Invalid path"),
}
}

fn open_entry(path: &str) {
let dir = get_dir(path);

let entry = &dir[select(&dir, path)];
if entry.is_dir || entry.is_link {
open_entry(&entry.path);
} else {
open::that(&entry.path).unwrap();
fn main_loop(initial_path: String) {
let mut path = initial_path;
loop {
let choices = get_choices(&path);
// make user select a choice and get the selected Entry
let entry = &choices[display_choices(&choices, &path)];

// exec file
if entry.filetype.should_exec() {
match open::that(&entry.path) {
// quit if file was opened
Ok(_) => break,
// else display error and open as directory
Err(_) => err(format!("Failed to open file \"{}\"", &entry.path[4..])),
}
}
// browse directory by continuing loop with new path
path = if entry.filetype == Filetype::Lnk {
resolve_lnk(&entry.path)
} else {
entry.path.to_string()
};
}
}

fn get_dir(path: &str) -> Vec<Entry> {
fn get_choices(path: &str) -> Vec<Entry> {
let mut result_vector: Vec<Entry> = Vec::new();

// .. Open parent directory
if let Ok(parent) = Path::new(path).parent().ok_or("No parent") {
result_vector.push(Entry {
name: String::from(".."),
path: parent.to_str().unwrap().to_string(),
icon: String::from(icons::DIR),
is_dir: true,
is_link: false,
icon: &Icons::DIR,
filetype: Filetype::Directory,
});
}

// Get files in directory
if let Ok(entries) = fs::read_dir(path) {
for entry in entries.flatten() {
if let Ok(file_type) = entry.file_type() {
let ext = entry.path();
let icon = String::from(if file_type.is_file() {
icons::from_ext(
ext.extension()
.unwrap_or_default()
.to_str()
.unwrap_or_default(),
)
} else if file_type.is_dir() {
icons::DIR
} else if file_type.is_symlink() {
icons::LINK
} else {
icons::UNKNOWN
});
let entry = Entry {
name: entry.file_name().to_str().unwrap().to_string(),
path: entry.path().to_str().unwrap().to_string(),
is_link: icon == icons::LINK,
is_dir: file_type.is_dir(),
icon,
};
result_vector.push(entry);
}
result_vector.push(Entry::from_dir_entry(entry));
}
}

// Open current directory in explorer
result_vector.push(Entry {
name: String::new(),
path: path.to_string(),
icon: String::from(icons::EXPLORER),
is_dir: false,
is_link: false,
icon: &Icons::EXPLORER,
filetype: Filetype::Executable,
});

result_vector
}

use console::Term;
use dialoguer::{theme::ColorfulTheme, Select};

fn select(items: &[Entry], path: &str) -> usize {
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt(&path[4..])
.report(false)
.items(items)
.default(0)
.interact_on_opt(&Term::stderr())
.ok()
.unwrap();

match selection {
Some(index) => index,
// exit process if none
None => std::process::exit(0),
}
}
39 changes: 39 additions & 0 deletions src/structs/entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use super::{Filetype, Icon, Icons};

use std::fmt;
use std::fs;

pub struct Entry {
pub name: String,
pub path: String,
pub icon: &'static Icon,
pub filetype: Filetype,
}

impl fmt::Display for Entry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.icon, self.name)
}
}

impl Entry {
// pub fn to_string(self) -> String {
// format!("{} {}", self.icon, self.name)
// }

#[allow(clippy::needless_pass_by_value)]
pub fn from_dir_entry(entry: fs::DirEntry) -> Self {
let path = entry.path();

let native_file_type = entry.file_type().unwrap();

let filetype = Filetype::from_native(native_file_type, &path);

Self {
name: entry.file_name().to_string_lossy().to_string(),
path: path.to_str().unwrap().to_string(),
icon: Icons::from_filetype(&filetype),
filetype,
}
}
}
Loading

0 comments on commit efeb629

Please sign in to comment.