1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:24:57 +00:00

Userland: Add minimal prompt support to less

GNU less has a pretty cool prompt format language. This patch adds
support for the language and specifiers for filename, linenumber, and
ending.
This commit is contained in:
Peter Elliott 2021-07-05 23:55:10 -06:00 committed by Ali Mohammad Pur
parent 7ee1983db6
commit 30aa9b837c

View file

@ -174,7 +174,19 @@ public:
void status_line()
{
out(m_tty, "\e[7m -- less -- (line {})\e[27m", m_line + 1);
out(m_tty, "\e[7m ");
render_status_line(m_prompt);
out(m_tty, " \e[27m");
}
void set_filename(StringView const& filename)
{
m_filename = filename;
}
void set_prompt(StringView const& prompt)
{
m_prompt = prompt;
}
bool read_line()
@ -191,7 +203,63 @@ public:
return true;
}
bool at_end()
{
return (m_line + m_height - 1) >= m_lines.size() && feof(m_file);
}
private:
size_t render_status_line(StringView const& prompt, size_t off = 0, char end = '\0', bool ignored = false)
{
for (; prompt[off] != end && off < prompt.length(); ++off) {
if (ignored)
continue;
if (off + 1 >= prompt.length()) {
// Don't parse any multi-character sequences if we are at the end of input.
out(m_tty, "{}", prompt[off]);
continue;
}
switch (prompt[off]) {
case '?':
switch (prompt[++off]) {
case 'f':
off = render_status_line(prompt, off + 1, ':', m_file == stdin);
off = render_status_line(prompt, off + 1, '.', m_file != stdin);
break;
case 'e':
off = render_status_line(prompt, off + 1, ':', !at_end());
off = render_status_line(prompt, off + 1, '.', at_end());
break;
default:
// Unknown flags are never true.
off = render_status_line(prompt, off + 1, ':', true);
off = render_status_line(prompt, off + 1, '.', false);
}
break;
case '%':
switch (prompt[++off]) {
case 'f':
out(m_tty, "{}", m_filename);
break;
case 'l':
out(m_tty, "{}", m_line);
break;
default:
out(m_tty, "?");
}
break;
case '\\':
++off;
[[fallthrough]];
default:
out(m_tty, "{}", prompt[off]);
}
}
return off;
}
Vector<String> m_lines;
size_t m_line { 0 };
FILE* m_file;
@ -214,9 +282,12 @@ static String get_key_sequence()
int main(int argc, char** argv)
{
const char* filename = "-";
char const* filename = "-";
char const* prompt = "?f%f :.(line %l)?e (END):.";
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.parse(argc, argv);
FILE* file;
@ -229,6 +300,8 @@ int main(int argc, char** argv)
setup_tty();
Pager pager(file, stdout, g_wsize.ws_col, g_wsize.ws_row);
pager.set_filename(filename);
pager.set_prompt(prompt);
pager.init();