瀏覽代碼

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 年之前
父節點
當前提交
c6fa2f196a
共有 4 個文件被更改,包括 38 次插入65 次删除
  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
     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)

+ 36 - 8
Userland/Utilities/less.cpp

@@ -5,6 +5,7 @@
  */
 
 #include <AK/Format.h>
+#include <AK/LexicalPath.h>
 #include <AK/String.h>
 #include <AK/StringBuilder.h>
 #include <AK/Utf8View.h>
@@ -20,7 +21,7 @@
 static struct termios g_save;
 static struct winsize g_wsize;
 
-static void setup_tty()
+static void setup_tty(bool switch_buffer)
 {
     // Save previous tty settings.
     if (tcgetattr(STDOUT_FILENO, &g_save) == -1) {
@@ -40,17 +41,21 @@ static void setup_tty()
         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) {
         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)
@@ -260,6 +265,7 @@ private:
         return off;
     }
 
+    // FIXME: Don't save scrollback when emulating more.
     Vector<String> m_lines;
     size_t m_line { 0 };
     FILE* m_file;
@@ -284,10 +290,19 @@ int main(int argc, char** argv)
 {
     char const* filename = "-";
     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;
     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(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);
 
     FILE* file;
@@ -297,7 +312,14 @@ int main(int argc, char** argv)
         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.set_filename(filename);
@@ -311,12 +333,18 @@ int main(int argc, char** argv)
         } else if (sequence == "j" || sequence == "\e[B" || sequence == "\n") {
             pager.down();
         } else if (sequence == "k" || sequence == "\e[A") {
-            pager.up();
+            if (!emulate_more)
+                pager.up();
         } else if (sequence == " ") {
             pager.down_page();
         }
+
+        if (quit_at_eof && pager.at_end())
+            break;
     }
 
-    teardown_tty();
+    pager.clear_status();
+
+    teardown_tty(!dont_switch_buffer);
     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;
-}