diff --git a/Base/bin/more b/Base/bin/more new file mode 120000 index 00000000000..cbce297ba8e --- /dev/null +++ b/Base/bin/more @@ -0,0 +1 @@ +/bin/less \ No newline at end of file diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 8849c33a810..59ff1aba109 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/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) diff --git a/Userland/Utilities/less.cpp b/Userland/Utilities/less.cpp index 59c923f3619..7ac07186b2c 100644 --- a/Userland/Utilities/less.cpp +++ b/Userland/Utilities/less.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -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 wrap_line(Utf8View const& string, size_t width) @@ -260,6 +265,7 @@ private: return off; } + // FIXME: Don't save scrollback when emulating more. Vector 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; } diff --git a/Userland/Utilities/more.cpp b/Userland/Utilities/more.cpp deleted file mode 100644 index ef115ff167b..00000000000 --- a/Userland/Utilities/more.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include - -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; -}