Skip to content

Commit

Permalink
Merge pull request #35 from tamada/release/v2.0.0-beta-7
Browse files Browse the repository at this point in the history
Release/v2.0.0 beta 7
  • Loading branch information
tamada authored Dec 31, 2024
2 parents 56d9d05 + 20c297c commit 785a10b
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sibling"
version = "2.0.0-beta-6"
version = "2.0.0-beta-7"
description = "get next/previous sibling directory name."
repository = "https://github.com/tamada/sibling"
homepage = "https://tamada.github.io/sibling"
Expand Down
16 changes: 10 additions & 6 deletions assets/completions/bash/sibling
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ _sibling() {

case "${cmd}" in
sibling)
opts="-a -l -p -P -s -i -t -h -V --csv --absolute --list --progress --parent --step --init --type --help --version [DIR]..."
opts="-a -l -p -P -s -t -i -h -V --csv --absolute --list --progress --parent --step --init --type --input --help --version [DIR]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand All @@ -37,10 +37,6 @@ _sibling() {
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-i)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--type)
COMPREPLY=($(compgen -W "first last previous next random keep" -- "${cur}"))
return 0
Expand All @@ -49,8 +45,16 @@ _sibling() {
COMPREPLY=($(compgen -W "first last previous next random keep" -- "${cur}"))
return 0
;;
--input)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-i)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=($(compgen -A directory -- "${cur}"))
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
Expand Down
3 changes: 2 additions & 1 deletion assets/completions/elvish/sibling
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ set edit:completion:arg-completer[sibling] = {|@words|
&'sibling'= {
cand -s 'specify the number of times to execute sibling'
cand --step 'specify the number of times to execute sibling'
cand -i 'generate the initialize script for the shell'
cand --init 'generate the initialize script for the shell'
cand -t 'specify the nexter type'
cand --type 'specify the nexter type'
cand -i 'directory list from file, if FILE is "-", reads from stdin.'
cand --input 'directory list from file, if FILE is "-", reads from stdin.'
cand --csv 'print the result in the csv format'
cand -a 'print the directory name in the absolute path'
cand --absolute 'print the directory name in the absolute path'
Expand Down
4 changes: 2 additions & 2 deletions assets/completions/fish/sibling
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
complete -c sibling -s s -l step -d 'specify the number of times to execute sibling' -r
complete -c sibling -s i -l init -d 'generate the initialize script for the shell' -r
complete -c sibling -l init -d 'generate the initialize script for the shell' -r
complete -c sibling -s t -l type -d 'specify the nexter type' -r -f -a "{first\t'',last\t'',previous\t'',next\t'',random\t'',keep\t''}"
complete -c sibling -s i -l input -d 'directory list from file, if FILE is "-", reads from stdin.' -r
complete -c sibling -l csv -d 'print the result in the csv format'
complete -c sibling -s a -l absolute -d 'print the directory name in the absolute path'
complete -c sibling -s l -l list -d 'list the sibling directories'
complete -c sibling -s p -l progress -d 'print the progress of traversing directories'
complete -c sibling -s P -l parent -d 'print parent directory, when no more sibling directories are found'
complete -c sibling -s h -l help -d 'Print help'
complete -c sibling -s V -l version -d 'Print version'
complete -c sibling -xa '(__fish_complete_directories)'
39 changes: 20 additions & 19 deletions assets/completions/powershell/sibling
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,26 @@ Register-ArgumentCompleter -Native -CommandName 'sibling' -ScriptBlock {

$completions = @(switch ($command) {
'sibling' {
[CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'specify the number of times to execute sibling')
[CompletionResult]::new('--step', 'step', [CompletionResultType]::ParameterName, 'specify the number of times to execute sibling')
[CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'generate the initialize script for the shell')
[CompletionResult]::new('--init', 'init', [CompletionResultType]::ParameterName, 'generate the initialize script for the shell')
[CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'specify the nexter type')
[CompletionResult]::new('--type', 'type', [CompletionResultType]::ParameterName, 'specify the nexter type')
[CompletionResult]::new('--csv', 'csv', [CompletionResultType]::ParameterName, 'print the result in the csv format')
[CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, 'print the directory name in the absolute path')
[CompletionResult]::new('--absolute', 'absolute', [CompletionResultType]::ParameterName, 'print the directory name in the absolute path')
[CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'list the sibling directories')
[CompletionResult]::new('--list', 'list', [CompletionResultType]::ParameterName, 'list the sibling directories')
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'print the progress of traversing directories')
[CompletionResult]::new('--progress', 'progress', [CompletionResultType]::ParameterName, 'print the progress of traversing directories')
[CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'print parent directory, when no more sibling directories are found')
[CompletionResult]::new('--parent', 'parent', [CompletionResultType]::ParameterName, 'print parent directory, when no more sibling directories are found')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'specify the number of times to execute sibling')
[CompletionResult]::new('--step', '--step', [CompletionResultType]::ParameterName, 'specify the number of times to execute sibling')
[CompletionResult]::new('--init', '--init', [CompletionResultType]::ParameterName, 'generate the initialize script for the shell')
[CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'specify the nexter type')
[CompletionResult]::new('--type', '--type', [CompletionResultType]::ParameterName, 'specify the nexter type')
[CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'directory list from file, if FILE is "-", reads from stdin.')
[CompletionResult]::new('--input', '--input', [CompletionResultType]::ParameterName, 'directory list from file, if FILE is "-", reads from stdin.')
[CompletionResult]::new('--csv', '--csv', [CompletionResultType]::ParameterName, 'print the result in the csv format')
[CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'print the directory name in the absolute path')
[CompletionResult]::new('--absolute', '--absolute', [CompletionResultType]::ParameterName, 'print the directory name in the absolute path')
[CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'list the sibling directories')
[CompletionResult]::new('--list', '--list', [CompletionResultType]::ParameterName, 'list the sibling directories')
[CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'print the progress of traversing directories')
[CompletionResult]::new('--progress', '--progress', [CompletionResultType]::ParameterName, 'print the progress of traversing directories')
[CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'print parent directory, when no more sibling directories are found')
[CompletionResult]::new('--parent', '--parent', [CompletionResultType]::ParameterName, 'print parent directory, when no more sibling directories are found')
[CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
[CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
break
}
})
Expand Down
9 changes: 5 additions & 4 deletions assets/completions/zsh/_sibling
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ _sibling() {

local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" : \
'-s+[specify the number of times to execute sibling]:COUNT: ' \
'--step=[specify the number of times to execute sibling]:COUNT: ' \
'-i+[generate the initialize script for the shell]:SHELL: ' \
'--init=[generate the initialize script for the shell]:SHELL: ' \
'-s+[specify the number of times to execute sibling]:COUNT:_default' \
'--step=[specify the number of times to execute sibling]:COUNT:_default' \
'--init=[generate the initialize script for the shell]:SHELL:_default' \
'-t+[specify the nexter type]:TYPE:(first last previous next random keep)' \
'--type=[specify the nexter type]:TYPE:(first last previous next random keep)' \
'-i+[directory list from file, if FILE is "-", reads from stdin.]:FILE:_default' \
'--input=[directory list from file, if FILE is "-", reads from stdin.]:FILE:_default' \
'--csv[print the result in the csv format]' \
'-a[print the directory name in the absolute path]' \
'--absolute[print the directory name in the absolute path]' \
Expand Down
2 changes: 1 addition & 1 deletion docs/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pygmentsStyle = "pygments"
project_tagline = "get next/previous sibling directory name"
dateFormat = "2006-01-02"
katex = true
version = "2.0.0-beta-6"
version = "2.0.0-beta-7"
footer = "[![GitHub](https://img.shields.io/badge/GitHub-tamada/sibling-blueviolet.svg?logo=github)](https://github.com/tamada/sibling) Made with [Hugo](https://gohugo.io/). Theme by [Cayman](https://github.com/zwbetz-gh/cayman-hugo-theme). Deployed to [GitHub Pages](https://pages.github.com/)."

[menu]
Expand Down
6 changes: 5 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum SiblingError {
NotFound(PathBuf),
NoParent(PathBuf),
NotDir(PathBuf),
NotFile(PathBuf),
Fatal(String),
Array(Vec<SiblingError>),
}
Expand Down Expand Up @@ -38,12 +39,15 @@ pub struct CliOpts {
#[arg(short, long, help = "specify the number of times to execute sibling", value_name = "COUNT", default_value_t = 1)]
pub step: i32,

#[arg(short, long, help = "generate the initialize script for the shell", value_name = "SHELL", hide = true, default_missing_value = "bash")]
#[arg(long, help = "generate the initialize script for the shell", value_name = "SHELL", hide = true, default_missing_value = "bash")]
pub init: Option<String>,

#[arg(short = 't', long = "type", help = "specify the nexter type", value_enum, default_value_t = NexterType::Next, value_name = "TYPE", ignore_case = true)]
pub nexter: NexterType,

#[arg(short, long, help = "directory list from file, if FILE is \"-\", reads from stdin.", value_name = "FILE")]
pub input: Option<String>,

#[arg(index = 1, help = "the target directory", value_name = "DIR")]
pub dirs: Vec<PathBuf>,
}
Expand Down
70 changes: 68 additions & 2 deletions src/dirs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{fs, path::{Path, PathBuf}};
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

use crate::cli::{Result, SiblingError};

Expand All @@ -20,7 +21,7 @@ impl Dirs {
}
} else if current_dir.exists() {
if current_dir.is_dir() {
let current = fs::canonicalize(&current_dir).unwrap();
let current = std::fs::canonicalize(&current_dir).unwrap();
build_dirs(current.clone().parent(), current)
} else {
Err(SiblingError::NotDir(current_dir))
Expand All @@ -29,6 +30,19 @@ impl Dirs {
Err(SiblingError::NotFound(current_dir))
}
}
pub fn new_from_file(file: String) -> Result<Self> {
if file == "-" {
return build_from_reader(Box::new(std::io::stdin().lock()));
}
let path = PathBuf::from(file);
if !path.exists() {
return Err(SiblingError::NotFound(path));
} else if path.is_dir() {
return Err(SiblingError::NotFile(path));
} else {
return build_from_list(path);
}
}

pub fn current_path(&self) -> PathBuf {
self.dirs[self.current].clone()
Expand Down Expand Up @@ -87,6 +101,48 @@ fn find_current(dirs: &[PathBuf], current: &PathBuf) -> usize {
dirs.iter().position(|dir| dir == current).unwrap_or(0)
}

fn build_from_reader(reader: Box<dyn BufRead>) -> Result<Dirs> {
let lines = reader.lines()
.filter_map(|line| line.map(|n| n.trim().to_string()).ok())
.collect::<Vec<String>>();
let base = if let Some(base) = lines.iter().find(|l| l.starts_with("parent:")) {
base.chars().skip(7).collect::<String>().trim().to_string()
} else {
".".to_string()
};
let dirs = lines.iter()
.filter(|l| !l.starts_with("parent:"))
.map(|line| PathBuf::from(line))
.collect::<Vec<PathBuf>>();
let current = find_current_dir_index(&dirs);
Ok(Dirs {
dirs,
parent: PathBuf::from(base),
current: current,
next: -1,
no_more_dir: false,
})
}

fn find_current_dir_index(dirs: &Vec<PathBuf>) -> usize {
if let Ok(pwd) = std::env::current_dir() {
let cwd = PathBuf::from(".");
if let Some(pos) = dirs.iter().position(|dir| dir == &cwd || pwd.ends_with(dir)) {
return pos;
}
}
0 as usize
}

fn build_from_list(filename: PathBuf) -> Result<Dirs> {
if let Ok(f) = std::fs::File::open(filename) {
let reader = BufReader::new(f);
build_from_reader(Box::new(reader))
} else {
Err(SiblingError::Io(std::io::Error::last_os_error()))
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -107,4 +163,14 @@ mod tests {
let dirs = dirs.unwrap();
assert_eq!(dirs.current_path().file_name().map(|s| s.to_str()), Some("sibling".into()));
}

#[test]
fn test_dir_from_file() {
let dirs = Dirs::new_from_file("testdata/dirlist.txt".into());
assert!(dirs.is_ok());
let dirs = dirs.unwrap();
assert_eq!(dirs.dirs.len(), 4);
assert_eq!(dirs.current, 1);
assert_eq!(dirs.parent, PathBuf::from("testdata"));
}
}
32 changes: 32 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::vec;

use clap::Parser;
use crate::cli::{CliOpts, PrintingOpts, Result, SiblingError};
Expand All @@ -15,6 +16,18 @@ fn perform_impl(mut dirs: dirs::Dirs, nexter: &Box<dyn Nexter>, step: i32, opts:
printer::result_string(&dirs, opts)
}

fn perform_from_file(opts: CliOpts) -> Vec<Result<String>> {
let nexter = nexter::build_nexter(opts.nexter);
let r = match opts.input {
None => Err(SiblingError::Fatal("input is not specified".into())),
Some(file) => match dirs::Dirs::new_from_file(file) {
Err(e) => Err(e),
Ok(dirs) => perform_impl(dirs, &nexter, opts.step, &opts.p_opts),
}
};
vec![r]
}

fn perform_each(dir: std::path::PathBuf, nexter: &Box<dyn Nexter>, step: i32, opts: &PrintingOpts) -> Result<String> {
match dirs::Dirs::new(dir) {
Err(e) => Err(e),
Expand Down Expand Up @@ -45,6 +58,8 @@ fn perform_sibling(opts: CliOpts) -> Vec<Result<String>> {
fn perform(opts: CliOpts) -> Vec<Result<String>> {
if let Some(shell) = opts.init {
vec![init::generate_init_script(shell)]
} else if opts.input.is_some() {
perform_from_file(opts)
} else {
perform_sibling(opts)
}
Expand All @@ -58,6 +73,7 @@ fn print_error(e: &SiblingError) {
SiblingError::Array(array) => {
array.iter().for_each(print_error);
},
SiblingError::NotFile(path) => eprintln!("{:?}: not a file", path),
SiblingError::NotFound(path) => eprintln!("{:?}: not found", path),
SiblingError::Fatal(message) => eprintln!("fatal error: {}", message)
}
Expand Down Expand Up @@ -98,4 +114,20 @@ mod tests {
Ok(result) => println!("{}", result),
}
}

#[test]
fn test_from_file() {
let opts_r = cli::CliOpts::try_parse_from(vec!["sibling", "--input", "testdata/dirlist.txt", "--type", "previous"]);

if let Err(e) = &opts_r {
eprintln!("{}", e);
}
assert!(opts_r.is_ok());
let r = perform(opts_r.unwrap());
assert_eq!(r.len(), 1);
match r.get(0).unwrap() {
Err(e) => print_error(&e),
Ok(result) => assert_eq!(result, "testdata/a")
}
}
}
5 changes: 5 additions & 0 deletions testdata/dirlist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
testdata/a
.
testdata/b
testdata/c
parent:testdata

0 comments on commit 785a10b

Please sign in to comment.