lwl | Less with links. |
| download: http://git.y1.nz/archives/lwl.tar.gz | |
| README | Files | Log | Refs |
main.c
1 #include <stdio.h> /* printf, stdin/out/err, etc */
2 #include <termios.h> /* termios struct, tsetattr */
3 #include <stdlib.h> /* exit, popen */
4 #include <unistd.h> /* exec */
5 #include <sys/wait.h> /* waitpid */
6
7 #include "config.h"
8 #include "term.h"
9 #include "text.h"
10 #include "draw.h"
11 #include "state.h"
12
13 /* helper macros, for specifying keybindings in config.h */
14 #define START_MODE(m) if (state->mode == m) { \
15 switch (ch) {
16 #define END_MODE \
17 } \
18 return 0; \
19 }
20 #define ESCAPE return 1
21 #define SCROLL_TO(index) scroll_to(state, wrap, (index))
22 #define SCROLL_BY(step) scroll_to(state, wrap, state->line_offset + (step))
23 #define STEP_BY(step) next_markup(state, wrap, (step))
24 #define SET_MODE(new_mode) set_mode(state, (new_mode))
25 #define FORK_COMMAND(command) fork_command(state, (command))
26 #define EXEC_COMMAND(command) exec_command(state, (command))
27 #define TYPE_CHAR type_input_char(state, wrap, ch)
28 #define TYPE_BACKSPACE type_input_backspace(state)
29 #define DO_SEARCH do_search(contents, state, wrap)
30 #define WRAP_END wrap->line_count
31 #define WRAP_H wrap->height
32 #define ACTION(trigger, action) case trigger: action; break;
33 #define DEFAULT_ACTION(action) default: action; break;
34
35 /* GLOBAL VARS (sowwy,, ill cwean dis up l8r >w<) */
36 struct termios termios0;
37 FileContents *contents;
38 Wrap *wrap;
39 State *state;
40
41 void
42 set_termios_raw(FILE *fd)
43 {
44 struct termios termios1;
45 tcgetattr(fileno(fd), &termios0);
46 tcgetattr(fileno(fd), &termios1);
47 cfmakeraw(&termios1);
48 tcsetattr(fileno(fd), TCSANOW, &termios1);
49 }
50
51 void
52 reset_termios(FILE *fd)
53 {
54 tcsetattr(fileno(stdin), TCSANOW, &termios0);
55 }
56
57 // TODO catch SIGWINCH and trigger this
58 void
59 change_width(int nw, int nh)
60 {
61 int w = wrap->width, h = wrap->height;
62 free(wrap);
63 wrap = wrap_to(contents, nw, nh);
64 }
65
66 // TODO move these to proc (?) module
67 void
68 exec_command(State *state, char *command)
69 {
70 char *link = state->markups[state->markup_index]->data;
71 setenv("INPUT", state->input, 1);
72 setenv("LINK", link, 1);
73 // TODO how can this be made safer...
74
75 reset_termios(stdin);
76 printf("\n");
77
78 execlp("/bin/sh", "/bin/sh", "-c", command, NULL);
79 }
80
81 void
82 fork_command(State *state, char *command)
83 {
84 /* fork and execute in child */
85 pid_t pid = fork();
86 if (!pid) exec_command(state, command);
87
88 /* parent: wait for child, then wait for keypress */
89 waitpid(pid, NULL, 0);
90 printf("\033[0;1m" "[process terminated]" "\033[0m");
91 set_termios_raw(stdin);
92 fflush(stdout);
93 fgetc(stdin);
94 state->mode = MODE_GROUND;
95 }
96
97 int
98 handle_input(char ch)
99 {
100 ACTIONS;
101 return 0;
102 }
103
104 int
105 main(int argc, const char *argv[])
106 {
107 FILE *fin;
108 int result;
109 int screen_width, screen_height;
110
111 state = init_state();
112
113 // TODO use getopt prolly
114 if (argc != 2) {
115 printf("Usage: %s FILENAME" "\n", argv[0]);
116 exit(1);
117 }
118
119 result = get_root_size(stdin, stdout, &screen_width, &screen_height);
120 if (screen_width > 80) screen_width = 80;
121 screen_height--; /* accounts for status line */
122 if (!result) {
123 printf("Failed to measure terminal :(" "\n");
124 exit(1);
125 }
126
127 fin = fopen(argv[1], "r");
128 if (fin == NULL) {
129 printf("Failed to open \"%s\"." "\n", argv[1]);
130 exit(1);
131 }
132 state->message = state->filename = argv[1];
133 contents = read_contents(fin);
134 wrap = wrap_to(contents, screen_width, screen_height);
135 fclose(fin);
136
137 set_markups(state, contents->links, contents->link_count);
138 set_termios_raw(stdin);
139
140 redraw(contents, wrap, state);
141
142 char ch;
143 for (;;) {
144 redraw(contents, wrap, state);
145
146 ch = fgetc(stdin);
147 /* clear message on input. */
148 state->message = NULL;
149
150 result = handle_input(ch);
151 if (result > 0) break;
152 }
153
154 reset_termios(stdin);
155
156 /* clear the line and move cursor to left */
157 printf("\033[2K" "\033[9999D");
158 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.