Merge pull request #979 from jonathandturner/abbrev_ls

Abbreviate ls by default, add --full flag
This commit is contained in:
Jonathan Turner 2019-11-18 07:06:19 +13:00 committed by GitHub
commit 54c0603263
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 16 deletions

View file

@ -8,6 +8,7 @@ pub struct LS;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct LsArgs { pub struct LsArgs {
path: Option<Tagged<PathBuf>>, path: Option<Tagged<PathBuf>>,
full: bool,
} }
impl WholeStreamCommand for LS { impl WholeStreamCommand for LS {
@ -16,11 +17,13 @@ impl WholeStreamCommand for LS {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ls").optional( Signature::build("ls")
"path", .optional(
SyntaxShape::Pattern, "path",
"a path to get the directory contents from", SyntaxShape::Pattern,
) "a path to get the directory contents from",
)
.switch("full", "list all available columns for each entry")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -37,6 +40,6 @@ impl WholeStreamCommand for LS {
} }
} }
fn ls(LsArgs { path }: LsArgs, context: RunnableContext) -> Result<OutputStream, ShellError> { fn ls(LsArgs { path, full }: LsArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {
context.shell_manager.ls(path, &context) context.shell_manager.ls(path, &context, full)
} }

View file

@ -13,6 +13,7 @@ pub(crate) fn dir_entry_dict(
filename: &std::path::Path, filename: &std::path::Path,
metadata: &std::fs::Metadata, metadata: &std::fs::Metadata,
tag: impl Into<Tag>, tag: impl Into<Tag>,
full: bool,
) -> Result<Tagged<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
let mut dict = TaggedDictBuilder::new(tag); let mut dict = TaggedDictBuilder::new(tag);
dict.insert("name", Value::string(filename.to_string_lossy())); dict.insert("name", Value::string(filename.to_string_lossy()));
@ -26,10 +27,19 @@ pub(crate) fn dir_entry_dict(
}; };
dict.insert("type", Value::string(format!("{:?}", kind))); dict.insert("type", Value::string(format!("{:?}", kind)));
dict.insert(
"readonly", if full {
Value::boolean(metadata.permissions().readonly()), dict.insert(
); "readonly",
Value::boolean(metadata.permissions().readonly()),
);
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
dict.insert("mode", Value::int(metadata.permissions().mode()));
}
}
dict.insert("size", Value::bytes(metadata.len() as u64)); dict.insert("size", Value::bytes(metadata.len() as u64));

View file

@ -1,12 +1,13 @@
use crate::commands::classified::InternalCommand; use crate::commands::classified::InternalCommand;
use crate::commands::ClassifiedCommand; use crate::commands::ClassifiedCommand;
use crate::env::host::BasicHost; use crate::env::host::BasicHost;
use crate::parser::hir;
use crate::parser::hir::syntax_shape::*; use crate::parser::hir::syntax_shape::*;
use crate::parser::hir::TokensIterator; use crate::parser::hir::TokensIterator;
use crate::parser::hir::{self, named::NamedValue, NamedArguments};
use crate::parser::parse::token_tree_builder::{CurriedToken, TokenTreeBuilder as b}; use crate::parser::parse::token_tree_builder::{CurriedToken, TokenTreeBuilder as b};
use crate::parser::TokenNode; use crate::parser::TokenNode;
use crate::{HasSpan, Span, SpannedItem, Tag, Text}; use crate::{HasSpan, Span, SpannedItem, Tag, Text};
use indexmap::IndexMap;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use std::fmt::Debug; use std::fmt::Debug;
@ -67,6 +68,9 @@ fn test_parse_command() {
eprintln!("{:?} {:?} {:?}", bare, pat, bare.until(pat)); eprintln!("{:?} {:?} {:?}", bare, pat, bare.until(pat));
let mut map = IndexMap::new();
map.insert("full".to_string(), NamedValue::AbsentSwitch);
ClassifiedCommand::Internal(InternalCommand::new( ClassifiedCommand::Internal(InternalCommand::new(
"ls".to_string(), "ls".to_string(),
Tag { Tag {
@ -76,7 +80,7 @@ fn test_parse_command() {
hir::Call { hir::Call {
head: Box::new(hir::RawExpression::Command(bare).spanned(bare)), head: Box::new(hir::RawExpression::Command(bare).spanned(bare)),
positional: Some(vec![hir::Expression::pattern("*.txt", pat)]), positional: Some(vec![hir::Expression::pattern("*.txt", pat)]),
named: None, named: Some(NamedArguments { named: map }),
} }
.spanned(bare.until(pat)), .spanned(bare.until(pat)),
)) ))

View file

@ -86,6 +86,7 @@ impl Shell for FilesystemShell {
&self, &self,
pattern: Option<Tagged<PathBuf>>, pattern: Option<Tagged<PathBuf>>,
context: &RunnableContext, context: &RunnableContext,
full: bool,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let cwd = self.path(); let cwd = self.path();
let mut full_path = PathBuf::from(self.path()); let mut full_path = PathBuf::from(self.path());
@ -136,7 +137,7 @@ impl Shell for FilesystemShell {
Path::new(&filepath) Path::new(&filepath)
}; };
let value = dir_entry_dict(filename, &metadata, &name_tag)?; let value = dir_entry_dict(filename, &metadata, &name_tag, full)?;
yield ReturnSuccess::value(value); yield ReturnSuccess::value(value);
} }
} }
@ -175,7 +176,7 @@ impl Shell for FilesystemShell {
Path::new(&entry) Path::new(&entry)
}; };
if let Ok(value) = dir_entry_dict(filename, &metadata, &name_tag) { if let Ok(value) = dir_entry_dict(filename, &metadata, &name_tag, full) {
yield ReturnSuccess::value(value); yield ReturnSuccess::value(value);
} }
} }

View file

@ -129,6 +129,7 @@ impl Shell for HelpShell {
&self, &self,
_pattern: Option<Tagged<PathBuf>>, _pattern: Option<Tagged<PathBuf>>,
_context: &RunnableContext, _context: &RunnableContext,
_full: bool,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
Ok(self Ok(self
.commands() .commands()

View file

@ -16,6 +16,7 @@ pub trait Shell: std::fmt::Debug {
&self, &self,
pattern: Option<Tagged<PathBuf>>, pattern: Option<Tagged<PathBuf>>,
context: &RunnableContext, context: &RunnableContext,
full: bool,
) -> Result<OutputStream, ShellError>; ) -> Result<OutputStream, ShellError>;
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>; fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
fn cp(&self, args: CopyArgs, name: Tag, path: &str) -> Result<OutputStream, ShellError>; fn cp(&self, args: CopyArgs, name: Tag, path: &str) -> Result<OutputStream, ShellError>;

View file

@ -127,10 +127,11 @@ impl ShellManager {
&self, &self,
path: Option<Tagged<PathBuf>>, path: Option<Tagged<PathBuf>>,
context: &RunnableContext, context: &RunnableContext,
full: bool,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let env = self.shells.lock().unwrap(); let env = self.shells.lock().unwrap();
env[self.current_shell()].ls(path, context) env[self.current_shell()].ls(path, context, full)
} }
pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> { pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -90,6 +90,7 @@ impl Shell for ValueShell {
&self, &self,
target: Option<Tagged<PathBuf>>, target: Option<Tagged<PathBuf>>,
context: &RunnableContext, context: &RunnableContext,
_full: bool,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let mut full_path = PathBuf::from(self.path()); let mut full_path = PathBuf::from(self.path());
let name_tag = context.name.clone(); let name_tag = context.name.clone();