Bläddra i källkod

Userland: Add more(1) emulation to less(1)

This patch also removes the existing implementation of more, as it is
now redundant.
Peter Elliott 4 år sedan
förälder
incheckning
c6fa2f196a
4 ändrade filer med 38 tillägg och 65 borttagningar
  1. 1 0
      Base/bin/more
  2. 1 1
      Userland/Utilities/CMakeLists.txt
  3. 36 8
      Userland/Utilities/less.cpp
  4. 0 56
      Userland/Utilities/more.cpp

+ 1 - 0
Base/bin/more

@@ -0,0 +1 @@
+/bin/less

+ 1 - 1
Userland/Utilities/CMakeLists.txt

@@ -8,7 +8,7 @@ list(APPEND REQUIRED_TARGETS
 )
 )
 list(APPEND RECOMMENDED_TARGETS
 list(APPEND RECOMMENDED_TARGETS
     adjtime aplay avol bt checksum chres cksum copy fortune gunzip gzip init keymap lsirq lsof lspci man mknod mktemp
     adjtime aplay avol bt checksum chres cksum copy fortune gunzip gzip init keymap lsirq lsof lspci man mknod mktemp
-    modload modunload more nc netstat notify ntpquery open pape passwd pls printf pro shot tar tt unzip zip
+    modload modunload nc netstat notify ntpquery open pape passwd pls printf pro shot tar tt unzip zip
 )
 )
 
 
 # FIXME: Support specifying component dependencies for utilities (e.g. WebSocket for telws)
 # FIXME: Support specifying component dependencies for utilities (e.g. WebSocket for telws)

+ 36 - 8
Userland/Utilities/less.cpp

@@ -5,6 +5,7 @@
  */
  */
 
 
 #include <AK/Format.h>
 #include <AK/Format.h>
+#include <AK/LexicalPath.h>
 #include <AK/String.h>
 #include <AK/String.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringBuilder.h>
 #include <AK/Utf8View.h>
 #include <AK/Utf8View.h>
@@ -20,7 +21,7 @@
 static struct termios g_save;
 static struct termios g_save;
 static struct winsize g_wsize;
 static struct winsize g_wsize;
 
 
-static void setup_tty()
+static void setup_tty(bool switch_buffer)
 {
 {
     // Save previous tty settings.
     // Save previous tty settings.
     if (tcgetattr(STDOUT_FILENO, &g_save) == -1) {
     if (tcgetattr(STDOUT_FILENO, &g_save) == -1) {
@@ -40,17 +41,21 @@ static void setup_tty()
         perror("tcsetattr(3)");
         perror("tcsetattr(3)");
     }
     }
 
 
-    // Save cursor and switch to alternate buffer.
-    out("\e[s\e[?1047h");
+    if (switch_buffer) {
+        // Save cursor and switch to alternate buffer.
+        out("\e[s\e[?1047h");
+    }
 }
 }
 
 
-static void teardown_tty()
+static void teardown_tty(bool switch_buffer)
 {
 {
     if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &g_save) == -1) {
     if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &g_save) == -1) {
         perror("tcsetattr(3)");
         perror("tcsetattr(3)");
     }
     }
 
 
-    out("\e[?1047l\e[u");
+    if (switch_buffer) {
+        out("\e[?1047l\e[u");
+    }
 }
 }
 
 
 static Vector<String> wrap_line(Utf8View const& string, size_t width)
 static Vector<String> wrap_line(Utf8View const& string, size_t width)
@@ -260,6 +265,7 @@ private:
         return off;
         return off;
     }
     }
 
 
+    // FIXME: Don't save scrollback when emulating more.
     Vector<String> m_lines;
     Vector<String> m_lines;
     size_t m_line { 0 };
     size_t m_line { 0 };
     FILE* m_file;
     FILE* m_file;
@@ -284,10 +290,19 @@ int main(int argc, char** argv)
 {
 {
     char const* filename = "-";
     char const* filename = "-";
     char const* prompt = "?f%f :.(line %l)?e (END):.";
     char const* prompt = "?f%f :.(line %l)?e (END):.";
+    bool dont_switch_buffer = false;
+    bool quit_at_eof = false;
+    bool emulate_more = false;
+
+    if (LexicalPath::basename(argv[0]) == "more"sv)
+        emulate_more = true;
 
 
     Core::ArgsParser args_parser;
     Core::ArgsParser args_parser;
     args_parser.add_positional_argument(filename, "The paged file", "file", Core::ArgsParser::Required::No);
     args_parser.add_positional_argument(filename, "The paged file", "file", Core::ArgsParser::Required::No);
     args_parser.add_option(prompt, "Prompt line", "prompt", 'P', "Prompt");
     args_parser.add_option(prompt, "Prompt line", "prompt", 'P', "Prompt");
+    args_parser.add_option(dont_switch_buffer, "Don't use xterm alternate buffer", "no-init", 'X');
+    args_parser.add_option(quit_at_eof, "Exit when the end of the file is reached", "quit-at-eof", 'e');
+    args_parser.add_option(emulate_more, "Pretend that we are more(1)", "emulate-more", 'm');
     args_parser.parse(argc, argv);
     args_parser.parse(argc, argv);
 
 
     FILE* file;
     FILE* file;
@@ -297,7 +312,14 @@ int main(int argc, char** argv)
         file = fopen(filename, "r");
         file = fopen(filename, "r");
     }
     }
 
 
-    setup_tty();
+    if (emulate_more) {
+        // Configure options that match more's behavior
+        dont_switch_buffer = true;
+        quit_at_eof = true;
+        prompt = "--More--";
+    }
+
+    setup_tty(!dont_switch_buffer);
 
 
     Pager pager(file, stdout, g_wsize.ws_col, g_wsize.ws_row);
     Pager pager(file, stdout, g_wsize.ws_col, g_wsize.ws_row);
     pager.set_filename(filename);
     pager.set_filename(filename);
@@ -311,12 +333,18 @@ int main(int argc, char** argv)
         } else if (sequence == "j" || sequence == "\e[B" || sequence == "\n") {
         } else if (sequence == "j" || sequence == "\e[B" || sequence == "\n") {
             pager.down();
             pager.down();
         } else if (sequence == "k" || sequence == "\e[A") {
         } else if (sequence == "k" || sequence == "\e[A") {
-            pager.up();
+            if (!emulate_more)
+                pager.up();
         } else if (sequence == " ") {
         } else if (sequence == " ") {
             pager.down_page();
             pager.down_page();
         }
         }
+
+        if (quit_at_eof && pager.at_end())
+            break;
     }
     }
 
 
-    teardown_tty();
+    pager.clear_status();
+
+    teardown_tty(!dont_switch_buffer);
     return 0;
     return 0;
 }
 }

+ 0 - 56
Userland/Utilities/more.cpp

@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/Format.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-static int key_fd;
-
-static void wait_for_key()
-{
-    out("\033[7m--[ more ]--\033[0m");
-    fflush(stdout);
-    char dummy;
-    [[maybe_unused]] auto rc = read(key_fd, &dummy, 1);
-    outln();
-}
-
-int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
-{
-    if (pledge("stdio rpath tty", nullptr) < 0) {
-        perror("pledge");
-        return 1;
-    }
-
-    key_fd = STDOUT_FILENO;
-
-    struct winsize ws;
-    ioctl(1, TIOCGWINSZ, &ws);
-
-    if (pledge("stdio", nullptr) < 0) {
-        perror("pledge");
-        return 1;
-    }
-
-    unsigned lines_printed = 0;
-    while (!feof(stdin)) {
-        char buffer[BUFSIZ];
-        auto* str = fgets(buffer, sizeof(buffer), stdin);
-        if (!str)
-            break;
-        out("{}", str);
-        ++lines_printed;
-        if ((lines_printed % (ws.ws_row - 1)) == 0) {
-            wait_for_key();
-        }
-    }
-
-    close(key_fd);
-    return 0;
-}