aboutsummaryrefslogtreecommitdiff
path: root/core/pager.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/pager.c')
-rw-r--r--core/pager.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/core/pager.c b/core/pager.c
new file mode 100644
index 0000000..cda5300
--- /dev/null
+++ b/core/pager.c
@@ -0,0 +1,109 @@
+#include "../lib/container/container.h"
+#include "../lib/io/io.h"
+#include "../lib/aec/aec.h"
+#include "../lib/tctl/tctl.h"
+#include "../lib/cstr/cstr.h"
+
+
+#define BUFFER_SIZE 128
+char buf[BUFFER_SIZE];
+container_t *string;
+
+
+u64 scroll = 0;
+u64 maxscroll = 0;
+u64 num_lines = 0;
+termios_t original;
+termios_t current;
+
+
+void scroll_delta(int d)
+{
+ scroll += d;
+
+ if ((i64)(scroll) < 0) {
+ scroll = 0;
+ } else if (scroll > maxscroll) {
+ scroll = maxscroll;
+ }
+}
+
+void draw_screen()
+{
+ window_size_t ws = tctl_get_window_size();
+ clear_screen();
+ move_cursor(0, 0);
+
+ substr_t line = getline(string->data, scroll);
+
+ for (int i = 0; i < ws.height - 1 && line.begin; ++i) {
+ write(STDOUT_FD, line.begin, line.end - line.begin + 1);
+ line = nextline(line);
+ }
+
+ move_cursor(0, ws.height);
+ wstdf("%S Line: %i/%i %S", SGR_REVERSE, scroll + 1, num_lines, SGR_REVERSE_OFF);
+
+ flush(STDOUT_FD);
+}
+
+
+int main(int argc, const char **argv)
+{
+ if (argc != 1) {
+ wf(STDERR_FD, "pager\n");
+ return -1;
+ }
+
+ if (!isatty()) {
+ wf(STDERR_FD, "error: stdout is no tty! exiting.\n");
+ return -1;
+ }
+
+ string = new_container(sizeof(char));
+ u64 size;
+
+ while ((size = rstd(buf, BUFFER_SIZE))) {
+ container_append(string, buf, size);
+ }
+
+ container_push(string, 0);
+
+ tcgetattr(STDOUT_FD, &original);
+ current = original;
+ setcanonical(&current, 0);
+ setecho(&current, 0);
+ cursor_enabled(0);
+ tcsetattr(STDOUT_FD, &current);
+
+
+ char key;
+ int running = 1;
+ window_size_t ws = tctl_get_window_size();
+ num_lines = number_of_lines(string->data);
+ maxscroll = num_lines < ws.height ? 0 : num_lines - ws.height + 1;
+
+ draw_screen();
+
+ while (running && read(STDERR_FD, &key, 1) == 1) {
+ switch (key) {
+ case 'j': scroll_delta(1); break;
+ case 'k': scroll_delta(-1); break;
+ case 'g': scroll = 0; break;
+ case 'G': scroll = maxscroll; break;
+
+ case 'q':
+ case '\033': running = 0; break;
+ }
+
+ draw_screen();
+ }
+
+ tcsetattr(STDOUT_FD, &original);
+ cursor_enabled(1);
+
+ clear_screen();
+ move_cursor(0, 0);
+
+ return 0;
+}