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:
parent
7ee1983db6
commit
30aa9b837c
1 changed files with 75 additions and 2 deletions
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue