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

This patch also removes the existing implementation of more, as it is
now redundant.
This commit is contained in:
Peter Elliott 2021-07-06 00:30:34 -06:00 committed by Ali Mohammad Pur
parent 30aa9b837c
commit c6fa2f196a
Notes: sideshowbarker 2024-07-18 10:13:13 +09:00
4 changed files with 38 additions and 65 deletions

1
Base/bin/more Symbolic link
View File

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

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}