Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 28 additions & 0 deletions src/uu/more/locales/en-US.ftl
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
more-about = Display the contents of a text file
more-usage = more [OPTIONS] FILE...

# Error messages
more-error-is-directory = {$path} is a directory.
more-error-cannot-open-no-such-file = cannot open {$path}: No such file or directory
more-error-cannot-open-io-error = cannot open {$path}: {$error}
more-error-bad-usage = bad usage
more-error-cannot-seek-to-line = Cannot seek to line number {$line}
more-error-pattern-not-found = Pattern not found
more-error-unknown-key = Unknown key: '{$key}'. Press 'h' for instructions. (unimplemented)

# Help messages
more-help-silent = Display help instead of ringing bell when an illegal key is pressed
more-help-logical = Do not pause after any line containing a ^L (form feed)
more-help-exit-on-eof = Exit on End-Of-File
more-help-no-pause = Count logical lines, rather than screen lines
more-help-print-over = Do not scroll, clear screen and display text
more-help-clean-print = Do not scroll, display text and clean line ends
more-help-squeeze = Squeeze multiple blank lines into one
more-help-plain = Suppress underlining
more-help-lines = The number of lines per screen full
more-help-number = Same as --lines option argument
more-help-from-line = Start displaying each file at line number
more-help-pattern = The string to be searched in each file before starting to display it
more-help-files = Path to the files to be read

# Other messages
more-help-message = [Press space to continue, 'q' to quit.]
more-press-return = press RETURN
30 changes: 30 additions & 0 deletions src/uu/more/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
more-about = Afficher le contenu d'un fichier texte
more-usage = more [OPTIONS] FICHIER...

# Messages d'erreur
more-error-is-directory = {$path} est un répertoire.
more-error-cannot-open-no-such-file = impossible d'ouvrir {$path} : Aucun fichier ou répertoire de ce nom
more-error-cannot-open-io-error = impossible d'ouvrir {$path} : {$error}
more-error-bad-usage = mauvaise utilisation
more-error-cannot-seek-to-line = Impossible d'atteindre la ligne numéro {$line}
more-error-pattern-not-found = Motif non trouvé
more-error-unknown-key = Touche inconnue : '{$key}'. Appuyez sur 'h' pour les instructions. (non implémenté)

# Messages d'aide
more-help-silent = Afficher l'aide au lieu de sonner la cloche lorsqu'une touche illégale est pressée
more-help-logical = Ne pas faire de pause après une ligne contenant un ^L (saut de page)
more-help-exit-on-eof = Quitter à la fin du fichier
more-help-no-pause = Compter les lignes logiques plutôt que les lignes d'écran
more-help-print-over = Ne pas défiler, effacer l'écran et afficher le texte
more-help-clean-print = Ne pas défiler, afficher le texte et nettoyer les fins de ligne
more-help-squeeze = Compresser plusieurs lignes vides en une seule
more-help-plain = Supprimer le soulignement
more-help-lines = Le nombre de lignes par écran complet
more-help-number = Identique à l'argument de l'option --lines
more-help-from-line = Commencer l'affichage de chaque fichier au numéro de ligne
more-help-pattern = La chaîne à rechercher dans chaque fichier avant de commencer à l'afficher
more-help-files = Chemin vers les fichiers à lire

# Autres messages
more-help-message = [Appuyez sur espace pour continuer, 'q' pour quitter.]
more-press-return = appuyez sur ENTRÉE
132 changes: 103 additions & 29 deletions src/uu/more/src/more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// file that was distributed with this source code.

use std::{
collections::HashMap,
fs::File,
io::{BufRead, BufReader, Stdin, Stdout, Write, stdin, stdout},
panic::set_hook,
Expand All @@ -26,13 +27,66 @@
use uucore::format_usage;
use uucore::{display::Quotable, show};

use uucore::locale::get_message;
use uucore::locale::{get_message, get_message_with_args};

#[derive(Debug)]
enum MoreError {
IsDirectory(String),
CannotOpenNoSuchFile(String),
CannotOpenIOError(String, std::io::ErrorKind),
BadUsage,
}

impl std::fmt::Display for MoreError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MoreError::IsDirectory(path) => {
write!(
f,
"{}",
get_message_with_args(
"more-error-is-directory",
HashMap::from([("path".to_string(), path.quote().to_string())])

Check warning on line 49 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L41-L49

Added lines #L41 - L49 were not covered by tests
)
)
}
MoreError::CannotOpenNoSuchFile(path) => {
write!(
f,
"{}",
get_message_with_args(
"more-error-cannot-open-no-such-file",
HashMap::from([("path".to_string(), path.quote().to_string())])

Check warning on line 59 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L53-L59

Added lines #L53 - L59 were not covered by tests
)
)
}
MoreError::CannotOpenIOError(path, error) => {
write!(
f,
"{}",
get_message_with_args(
"more-error-cannot-open-io-error",
HashMap::from([
("path".to_string(), path.quote().to_string()),
("error".to_string(), error.to_string())
])

Check warning on line 72 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L63-L72

Added lines #L63 - L72 were not covered by tests
)
)
}
MoreError::BadUsage => {
write!(f, "{}", get_message("more-error-bad-usage"))

Check warning on line 77 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L77

Added line #L77 was not covered by tests
}
}
}

Check warning on line 80 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L80

Added line #L80 was not covered by tests
}

impl std::error::Error for MoreError {}

const BELL: char = '\x07'; // Printing this character will ring the bell

// The prompt to be displayed at the top of the screen when viewing multiple files,
// with the file name in the middle
const MULTI_FILE_TOP_PROMPT: &str = "\r::::::::::::::\n\r{}\n\r::::::::::::::\n";
const HELP_MESSAGE: &str = "[Press space to continue, 'q' to quit.]";

pub mod options {
pub const SILENT: &str = "silent";
Expand Down Expand Up @@ -111,22 +165,26 @@
if file.is_dir() {
show!(UUsageError::new(
0,
format!("{} is a directory.", file.quote()),
MoreError::IsDirectory(file.to_string_lossy().to_string()).to_string(),

Check warning on line 168 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L168

Added line #L168 was not covered by tests
));
continue;
}
if !file.exists() {
show!(USimpleError::new(
0,
format!("cannot open {}: No such file or directory", file.quote()),
MoreError::CannotOpenNoSuchFile(file.to_string_lossy().to_string()).to_string(),

Check warning on line 175 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L175

Added line #L175 was not covered by tests
));
continue;
}
let opened_file = match File::open(file) {
Err(why) => {
show!(USimpleError::new(
0,
format!("cannot open {}: {}", file.quote(), why.kind()),
MoreError::CannotOpenIOError(
file.to_string_lossy().to_string(),
why.kind()
)
.to_string(),

Check warning on line 187 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L183-L187

Added lines #L183 - L187 were not covered by tests
));
continue;
}
Expand All @@ -144,7 +202,7 @@
let stdin = stdin();
if stdin.is_tty() {
// stdin is not a pipe
return Err(UUsageError::new(1, "bad usage"));
return Err(UUsageError::new(1, MoreError::BadUsage.to_string()));

Check warning on line 205 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L205

Added line #L205 was not covered by tests
}
more(InputType::Stdin(stdin), false, None, None, &mut options)?;
}
Expand All @@ -163,57 +221,57 @@
.short('d')
.long(options::SILENT)
.action(ArgAction::SetTrue)
.help("Display help instead of ringing bell when an illegal key is pressed"),
.help(get_message("more-help-silent")),

Check warning on line 224 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L224

Added line #L224 was not covered by tests
)
.arg(
Arg::new(options::LOGICAL)
.short('l')
.long(options::LOGICAL)
.action(ArgAction::SetTrue)
.help("Do not pause after any line containing a ^L (form feed)"),
.help(get_message("more-help-logical")),

Check warning on line 231 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L231

Added line #L231 was not covered by tests
)
.arg(
Arg::new(options::EXIT_ON_EOF)
.short('e')
.long(options::EXIT_ON_EOF)
.action(ArgAction::SetTrue)
.help("Exit on End-Of-File"),
.help(get_message("more-help-exit-on-eof")),

Check warning on line 238 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L238

Added line #L238 was not covered by tests
)
.arg(
Arg::new(options::NO_PAUSE)
.short('f')
.long(options::NO_PAUSE)
.action(ArgAction::SetTrue)
.help("Count logical lines, rather than screen lines"),
.help(get_message("more-help-no-pause")),

Check warning on line 245 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L245

Added line #L245 was not covered by tests
)
.arg(
Arg::new(options::PRINT_OVER)
.short('p')
.long(options::PRINT_OVER)
.action(ArgAction::SetTrue)
.help("Do not scroll, clear screen and display text"),
.help(get_message("more-help-print-over")),

Check warning on line 252 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L252

Added line #L252 was not covered by tests
)
.arg(
Arg::new(options::CLEAN_PRINT)
.short('c')
.long(options::CLEAN_PRINT)
.action(ArgAction::SetTrue)
.help("Do not scroll, display text and clean line ends"),
.help(get_message("more-help-clean-print")),

Check warning on line 259 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L259

Added line #L259 was not covered by tests
)
.arg(
Arg::new(options::SQUEEZE)
.short('s')
.long(options::SQUEEZE)
.action(ArgAction::SetTrue)
.help("Squeeze multiple blank lines into one"),
.help(get_message("more-help-squeeze")),

Check warning on line 266 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L266

Added line #L266 was not covered by tests
)
.arg(
Arg::new(options::PLAIN)
.short('u')
.long(options::PLAIN)
.action(ArgAction::SetTrue)
.hide(true)
.help("Suppress underlining"),
.help(get_message("more-help-plain")),

Check warning on line 274 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L274

Added line #L274 was not covered by tests
)
.arg(
Arg::new(options::LINES)
Expand All @@ -222,14 +280,14 @@
.value_name("number")
.num_args(1)
.value_parser(value_parser!(u16).range(0..))
.help("The number of lines per screen full"),
.help(get_message("more-help-lines")),

Check warning on line 283 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L283

Added line #L283 was not covered by tests
)
.arg(
Arg::new(options::NUMBER)
.long(options::NUMBER)
.num_args(1)
.value_parser(value_parser!(u16).range(0..))
.help("Same as --lines option argument"),
.help(get_message("more-help-number")),

Check warning on line 290 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L290

Added line #L290 was not covered by tests
)
.arg(
Arg::new(options::FROM_LINE)
Expand All @@ -238,7 +296,7 @@
.num_args(1)
.value_name("number")
.value_parser(value_parser!(usize))
.help("Start displaying each file at line number"),
.help(get_message("more-help-from-line")),

Check warning on line 299 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L299

Added line #L299 was not covered by tests
)
.arg(
Arg::new(options::PATTERN)
Expand All @@ -247,13 +305,13 @@
.allow_hyphen_values(true)
.required(false)
.value_name("pattern")
.help("The string to be searched in each file before starting to display it"),
.help(get_message("more-help-pattern")),

Check warning on line 308 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L308

Added line #L308 was not covered by tests
)
.arg(
Arg::new(options::FILES)
.required(false)
.action(ArgAction::Append)
.help("Path to the files to be read")
.help(get_message("more-help-files"))

Check warning on line 314 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L314

Added line #L314 was not covered by tests
.value_hint(clap::ValueHint::FilePath),
)
}
Expand Down Expand Up @@ -454,9 +512,13 @@
if !self.read_until_line(self.upper_mark)? {
write!(
self.stdout,
"\r{}Cannot seek to line number {} (press RETURN){}",
"\r{}{} ({}){}",

Check warning on line 515 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L515

Added line #L515 was not covered by tests
Attribute::Reverse,
self.upper_mark + 1,
get_message_with_args(
"more-error-cannot-seek-to-line",
HashMap::from([("line".to_string(), (self.upper_mark + 1).to_string())])

Check warning on line 519 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L517-L519

Added lines #L517 - L519 were not covered by tests
),
get_message("more-press-return"),

Check warning on line 521 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L521

Added line #L521 was not covered by tests
Attribute::Reset,
)?;
self.stdout.flush()?;
Expand Down Expand Up @@ -515,8 +577,10 @@
self.pattern = None;
write!(
self.stdout,
"\r{}Pattern not found (press RETURN){}",
"\r{}{} ({}){}",

Check warning on line 580 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L580

Added line #L580 was not covered by tests
Attribute::Reverse,
get_message("more-error-pattern-not-found"),
get_message("more-press-return"),

Check warning on line 583 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L582-L583

Added lines #L582 - L583 were not covered by tests
Attribute::Reset,
)?;
self.stdout.flush()?;
Expand Down Expand Up @@ -807,9 +871,13 @@
// - In normal mode: ring bell (BELL char) on wrong key or show basic prompt
let banner = match (self.silent, wrong_key) {
(true, Some(key)) => format!(
"{status}[Unknown key: '{key}'. Press 'h' for instructions. (unimplemented)]"
"{status}[{}]",
get_message_with_args(
"more-error-unknown-key",
HashMap::from([("key".to_string(), key.to_string())])

Check warning on line 877 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L874-L877

Added lines #L874 - L877 were not covered by tests
)
),
(true, None) => format!("{status}{HELP_MESSAGE}"),
(true, None) => format!("{status}{}", get_message("more-help-message")),

Check warning on line 880 in src/uu/more/src/more.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/more/src/more.rs#L880

Added line #L880 was not covered by tests
(false, Some(_)) => format!("{status}{BELL}"),
(false, None) => status,
};
Expand Down Expand Up @@ -1007,7 +1075,7 @@
.build();
pager.draw_status_bar(None);
let stdout = String::from_utf8_lossy(&pager.stdout);
assert!(stdout.contains(HELP_MESSAGE));
assert!(stdout.contains(&get_message("more-help-message")));
}

#[test]
Expand Down Expand Up @@ -1080,7 +1148,10 @@
assert!(pager.handle_from_line().is_ok());
assert_eq!(pager.upper_mark, 0);
let stdout = String::from_utf8_lossy(&pager.stdout);
assert!(stdout.contains("Cannot seek to line number 100"));
assert!(stdout.contains(&get_message_with_args(
"more-error-cannot-seek-to-line",
HashMap::from([("line".to_string(), "100".to_string())])
)));
}

#[test]
Expand All @@ -1101,7 +1172,7 @@
let mut pager = TestPagerBuilder::new(content).pattern("qux").build();
assert!(pager.handle_pattern_search().is_ok());
let stdout = String::from_utf8_lossy(&pager.stdout);
assert!(stdout.contains("Pattern not found"));
assert!(stdout.contains(&get_message("more-error-pattern-not-found")));
assert_eq!(pager.pattern, None);
assert_eq!(pager.upper_mark, 0);
}
Expand All @@ -1111,11 +1182,14 @@
let mut pager = TestPagerBuilder::default().silent().build();
pager.draw_status_bar(Some('x'));
let stdout = String::from_utf8_lossy(&pager.stdout);
assert!(stdout.contains("Unknown key: 'x'"));
assert!(stdout.contains(&get_message_with_args(
"more-error-unknown-key",
HashMap::from([("key".to_string(), "x".to_string())])
)));

pager = TestPagerBuilder::default().build();
pager.draw_status_bar(Some('x'));
let stdout = String::from_utf8_lossy(&pager.stdout);
assert!(stdout.contains(BELL));
assert!(stdout.contains(&BELL.to_string()));
}
}
Loading