|
523 | 523 | <a href="#523" id="523">523</a>
|
524 | 524 | <a href="#524" id="524">524</a>
|
525 | 525 | <a href="#525" id="525">525</a>
|
| 526 | +<a href="#526" id="526">526</a> |
| 527 | +<a href="#527" id="527">527</a> |
| 528 | +<a href="#528" id="528">528</a> |
| 529 | +<a href="#529" id="529">529</a> |
| 530 | +<a href="#530" id="530">530</a> |
| 531 | +<a href="#531" id="531">531</a> |
| 532 | +<a href="#532" id="532">532</a> |
| 533 | +<a href="#533" id="533">533</a> |
| 534 | +<a href="#534" id="534">534</a> |
| 535 | +<a href="#535" id="535">535</a> |
| 536 | +<a href="#536" id="536">536</a> |
| 537 | +<a href="#537" id="537">537</a> |
| 538 | +<a href="#538" id="538">538</a> |
| 539 | +<a href="#539" id="539">539</a> |
| 540 | +<a href="#540" id="540">540</a> |
| 541 | +<a href="#541" id="541">541</a> |
| 542 | +<a href="#542" id="542">542</a> |
| 543 | +<a href="#543" id="543">543</a> |
| 544 | +<a href="#544" id="544">544</a> |
| 545 | +<a href="#545" id="545">545</a> |
| 546 | +<a href="#546" id="546">546</a> |
| 547 | +<a href="#547" id="547">547</a> |
| 548 | +<a href="#548" id="548">548</a> |
| 549 | +<a href="#549" id="549">549</a> |
| 550 | +<a href="#550" id="550">550</a> |
| 551 | +<a href="#551" id="551">551</a> |
| 552 | +<a href="#552" id="552">552</a> |
| 553 | +<a href="#553" id="553">553</a> |
| 554 | +<a href="#554" id="554">554</a> |
| 555 | +<a href="#555" id="555">555</a> |
| 556 | +<a href="#556" id="556">556</a> |
| 557 | +<a href="#557" id="557">557</a> |
| 558 | +<a href="#558" id="558">558</a> |
| 559 | +<a href="#559" id="559">559</a> |
| 560 | +<a href="#560" id="560">560</a> |
| 561 | +<a href="#561" id="561">561</a> |
| 562 | +<a href="#562" id="562">562</a> |
| 563 | +<a href="#563" id="563">563</a> |
| 564 | +<a href="#564" id="564">564</a> |
| 565 | +<a href="#565" id="565">565</a> |
526 | 566 | </pre><pre class="rust"><code><span class="comment">// * This file is part of the uutils coreutils package.
|
527 | 567 | // *
|
528 | 568 | // * (c) Martin Kysel <code@martinkysel.com>
|
|
539 | 579 | time::Duration,
|
540 | 580 | };
|
541 | 581 |
|
542 |
| -<span class="kw">use </span>clap::{crate_version, Arg, ArgAction, Command}; |
| 582 | +<span class="kw">use </span>clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; |
543 | 583 | <span class="kw">use </span>crossterm::event::KeyEventKind;
|
544 | 584 | <span class="kw">use </span>crossterm::{
|
| 585 | + cursor::MoveTo, |
545 | 586 | event::{<span class="self">self</span>, Event, KeyCode, KeyEvent, KeyModifiers},
|
546 | 587 | execute, queue,
|
547 | 588 | style::Attribute,
|
548 |
| - terminal, |
| 589 | + terminal::{<span class="self">self</span>, Clear, ClearType}, |
549 | 590 | };
|
550 | 591 |
|
551 | 592 | <span class="kw">use </span>is_terminal::IsTerminal;
|
|
576 | 617 |
|
577 | 618 | <span class="kw">const </span>MULTI_FILE_TOP_PROMPT: <span class="kw-2">&</span>str = <span class="string">"::::::::::::::\n{}\n::::::::::::::\n"</span>;
|
578 | 619 |
|
| 620 | +<span class="kw">struct </span>Options { |
| 621 | + silent: bool, |
| 622 | + clean_print: bool, |
| 623 | + print_over: bool, |
| 624 | +} |
| 625 | + |
| 626 | +<span class="kw">impl </span>Options { |
| 627 | + <span class="kw">fn </span>from(matches: <span class="kw-2">&</span>ArgMatches) -> <span class="self">Self </span>{ |
| 628 | + <span class="self">Self </span>{ |
| 629 | + silent: matches.get_flag(options::SILENT), |
| 630 | + clean_print: matches.get_flag(options::CLEAN_PRINT), |
| 631 | + print_over: matches.get_flag(options::PRINT_OVER), |
| 632 | + } |
| 633 | + } |
| 634 | +} |
| 635 | + |
579 | 636 | <span class="attr">#[uucore::main]
|
580 | 637 | </span><span class="kw">pub fn </span>uumain(args: <span class="kw">impl </span>uucore::Args) -> UResult<()> {
|
581 |
| - <span class="kw">let </span>matches = uu_app().get_matches_from(args); |
| 638 | + <span class="kw">let </span>args = args.collect_lossy(); |
| 639 | + <span class="kw">let </span>matches = <span class="kw">match </span>uu_app().try_get_matches_from(<span class="kw-2">&</span>args) { |
| 640 | + <span class="prelude-val">Ok</span>(m) => m, |
| 641 | + <span class="prelude-val">Err</span>(e) => <span class="kw">return </span><span class="prelude-val">Err</span>(e.into()), |
| 642 | + }; |
| 643 | + |
| 644 | + <span class="kw">let </span>options = Options::from(<span class="kw-2">&</span>matches); |
582 | 645 |
|
583 | 646 | <span class="kw">let </span><span class="kw-2">mut </span>buff = String::new();
|
584 |
| - <span class="kw">let </span>silent = matches.get_flag(options::SILENT); |
| 647 | + |
585 | 648 | <span class="kw">if let </span><span class="prelude-val">Some</span>(files) = matches.get_many::<String>(options::FILES) {
|
586 | 649 | <span class="kw">let </span><span class="kw-2">mut </span>stdout = setup_term();
|
587 | 650 | <span class="kw">let </span>length = files.len();
|
|
608 | 671 | }
|
609 | 672 | <span class="kw">let </span><span class="kw-2">mut </span>reader = BufReader::new(File::open(file).unwrap());
|
610 | 673 | reader.read_to_string(<span class="kw-2">&mut </span>buff).unwrap();
|
611 |
| - more(<span class="kw-2">&</span>buff, <span class="kw-2">&mut </span>stdout, next_file.copied(), silent)<span class="question-mark">?</span>; |
| 674 | + more(<span class="kw-2">&</span>buff, <span class="kw-2">&mut </span>stdout, next_file.copied(), <span class="kw-2">&</span>options)<span class="question-mark">?</span>; |
612 | 675 | buff.clear();
|
613 | 676 | }
|
614 | 677 | reset_term(<span class="kw-2">&mut </span>stdout);
|
615 | 678 | } <span class="kw">else if </span>!std::io::stdin().is_terminal() {
|
616 | 679 | stdin().read_to_string(<span class="kw-2">&mut </span>buff).unwrap();
|
617 | 680 | <span class="kw">let </span><span class="kw-2">mut </span>stdout = setup_term();
|
618 |
| - more(<span class="kw-2">&</span>buff, <span class="kw-2">&mut </span>stdout, <span class="prelude-val">None</span>, silent)<span class="question-mark">?</span>; |
| 681 | + more(<span class="kw-2">&</span>buff, <span class="kw-2">&mut </span>stdout, <span class="prelude-val">None</span>, <span class="kw-2">&</span>options)<span class="question-mark">?</span>; |
619 | 682 | reset_term(<span class="kw-2">&mut </span>stdout);
|
620 | 683 | } <span class="kw">else </span>{
|
621 | 684 | <span class="kw">return </span><span class="prelude-val">Err</span>(UUsageError::new(<span class="number">1</span>, <span class="string">"bad usage"</span>));
|
|
629 | 692 | .override_usage(format_usage(USAGE))
|
630 | 693 | .version(<span class="macro">crate_version!</span>())
|
631 | 694 | .infer_long_args(<span class="bool-val">true</span>)
|
| 695 | + .arg( |
| 696 | + Arg::new(options::PRINT_OVER) |
| 697 | + .short(<span class="string">'c'</span>) |
| 698 | + .long(options::PRINT_OVER) |
| 699 | + .help(<span class="string">"Do not scroll, display text and clean line ends"</span>) |
| 700 | + .action(ArgAction::SetTrue), |
| 701 | + ) |
632 | 702 | .arg(
|
633 | 703 | Arg::new(options::SILENT)
|
634 | 704 | .short(<span class="string">'d'</span>)
|
635 | 705 | .long(options::SILENT)
|
636 | 706 | .help(<span class="string">"Display help instead of ringing bell"</span>)
|
637 | 707 | .action(ArgAction::SetTrue),
|
638 | 708 | )
|
| 709 | + .arg( |
| 710 | + Arg::new(options::CLEAN_PRINT) |
| 711 | + .short(<span class="string">'p'</span>) |
| 712 | + .long(options::CLEAN_PRINT) |
| 713 | + .help(<span class="string">"Do not scroll, clean screen and display text"</span>) |
| 714 | + .action(ArgAction::SetTrue), |
| 715 | + ) |
639 | 716 | <span class="comment">// The commented arguments below are unimplemented:
|
640 | 717 | /*
|
641 | 718 | .arg(
|
|
650 | 727 | .long(options::NO_PAUSE)
|
651 | 728 | .help("Suppress pause after form feed"),
|
652 | 729 | )
|
653 |
| - .arg( |
654 |
| - Arg::new(options::PRINT_OVER) |
655 |
| - .short('c') |
656 |
| - .long(options::PRINT_OVER) |
657 |
| - .help("Do not scroll, display text and clean line ends"), |
658 |
| - ) |
659 |
| - .arg( |
660 |
| - Arg::new(options::CLEAN_PRINT) |
661 |
| - .short('p') |
662 |
| - .long(options::CLEAN_PRINT) |
663 |
| - .help("Do not scroll, clean screen and display text"), |
664 |
| - ) |
665 | 730 | .arg(
|
666 | 731 | Arg::new(options::SQUEEZE)
|
667 | 732 | .short('s')
|
|
734 | 799 | </span><span class="kw">fn </span>reset_term(stdout: <span class="kw-2">&mut </span>std::io::Stdout) {
|
735 | 800 | terminal::disable_raw_mode().unwrap();
|
736 | 801 | <span class="comment">// Clear the prompt
|
737 |
| - </span><span class="macro">queue!</span>(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap(); |
| 802 | + </span><span class="macro">queue!</span>(stdout, terminal::Clear(ClearType::CurrentLine)).unwrap(); |
738 | 803 | <span class="comment">// Move cursor to the beginning without printing new line
|
739 | 804 | </span><span class="macro">print!</span>(<span class="string">"\r"</span>);
|
740 | 805 | stdout.flush().unwrap();
|
|
744 | 809 | #[inline(always)]
|
745 | 810 | </span><span class="kw">fn </span>reset_term(<span class="kw">_</span>: <span class="kw-2">&mut </span>usize) {}
|
746 | 811 |
|
747 |
| -<span class="kw">fn </span>more(buff: <span class="kw-2">&</span>str, stdout: <span class="kw-2">&mut </span>Stdout, next_file: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>, silent: bool) -> UResult<()> { |
| 812 | +<span class="kw">fn </span>more( |
| 813 | + buff: <span class="kw-2">&</span>str, |
| 814 | + stdout: <span class="kw-2">&mut </span>Stdout, |
| 815 | + next_file: <span class="prelude-ty">Option</span><<span class="kw-2">&</span>str>, |
| 816 | + options: <span class="kw-2">&</span>Options, |
| 817 | +) -> UResult<()> { |
748 | 818 | <span class="kw">let </span>(cols, rows) = terminal::size().unwrap();
|
749 | 819 | <span class="kw">let </span>lines = break_buff(buff, usize::from(cols));
|
750 | 820 |
|
751 |
| - <span class="kw">let </span><span class="kw-2">mut </span>pager = Pager::new(rows, lines, next_file, silent); |
| 821 | + <span class="kw">let </span><span class="kw-2">mut </span>pager = Pager::new(rows, lines, next_file, options); |
752 | 822 | pager.draw(stdout, <span class="prelude-val">None</span>);
|
753 | 823 | <span class="kw">if </span>pager.should_close() {
|
754 | 824 | <span class="kw">return </span><span class="prelude-val">Ok</span>(());
|
|
838 | 908 | <span class="kw">_ </span>=> <span class="kw">continue</span>,
|
839 | 909 | }
|
840 | 910 |
|
| 911 | + <span class="kw">if </span>options.print_over { |
| 912 | + <span class="macro">execute!</span>( |
| 913 | + std::io::stdout(), |
| 914 | + MoveTo(<span class="number">0</span>, <span class="number">0</span>), |
| 915 | + Clear(ClearType::FromCursorDown) |
| 916 | + ) |
| 917 | + .unwrap(); |
| 918 | + } <span class="kw">else if </span>options.clean_print { |
| 919 | + <span class="macro">execute!</span>(std::io::stdout(), Clear(ClearType::All), MoveTo(<span class="number">0</span>, <span class="number">0</span>)).unwrap(); |
| 920 | + } |
841 | 921 | pager.draw(stdout, wrong_key);
|
842 | 922 | }
|
843 | 923 | }
|
|
855 | 935 | }
|
856 | 936 |
|
857 | 937 | <span class="kw">impl</span><<span class="lifetime">'a</span>> Pager<<span class="lifetime">'a</span>> {
|
858 |
| - <span class="kw">fn </span>new(rows: u16, lines: Vec<String>, next_file: <span class="prelude-ty">Option</span><<span class="kw-2">&</span><span class="lifetime">'a </span>str>, silent: bool) -> <span class="self">Self </span>{ |
| 938 | + <span class="kw">fn </span>new(rows: u16, lines: Vec<String>, next_file: <span class="prelude-ty">Option</span><<span class="kw-2">&</span><span class="lifetime">'a </span>str>, options: <span class="kw-2">&</span>Options) -> <span class="self">Self </span>{ |
859 | 939 | <span class="kw">let </span>line_count = lines.len();
|
860 | 940 | <span class="self">Self </span>{
|
861 | 941 | upper_mark: <span class="number">0</span>,
|
862 | 942 | content_rows: rows.saturating_sub(<span class="number">1</span>),
|
863 | 943 | lines,
|
864 | 944 | next_file,
|
865 | 945 | line_count,
|
866 |
| - silent, |
| 946 | + silent: options.silent, |
867 | 947 | }
|
868 | 948 | }
|
869 | 949 |
|
|
0 commit comments