Fixing line pointing to header while adding chars
[iomenu.git] / draw.c
blob1ee25ebc4303c8ae9a08a440dc5968324469d847
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <sys/ioctl.h>
6 #include "main.h"
9 /*
10 * Print a line to stderr.
12 void
13 draw_line(Line *line, int current, int cols, Opt *opt)
15 size_t i;
16 int n = 0;
17 char *content = expand_tabs(line->content);
18 char *comment = expand_tabs(line->comment);
20 /* clean the line and add a small margin */
21 fputs("\033[K", stderr);
23 /* line number if option set */
24 if (opt->line_numbers) {
25 fputs(current ? "\033[1m" : "\033[1;30m", stderr);
26 fprintf(stderr, "%7d\033[0m ", line->number);
27 n += 8;
28 } else {
29 fputs(" ", stderr);
30 n += 2;
33 /* highlight current line */
34 if (current)
35 fputs("\033[1;33m", stderr);
37 /* print content without overflowing terminal width */
38 for (i = 0; i < strlen(content) && n < cols; n++, i++)
39 fputc(content[i], stderr);
41 /* shift without overflowing terminal width */
42 if (!line->header && line->comment[0] != '\0') {
43 fprintf(stderr, "\033[%dC", MAX(40 - n, 1));
44 n += MAX(40 - n, 1);
47 /* comments in grey */
48 fputs("\033[1;30m", stderr);
50 /* print comment without overflowing terminal width */
51 for (i = 0; i < strlen(comment) && n < cols; n++, i++)
52 fputc(comment[i], stderr);
54 fputs("\033[0m\n", stderr);
56 free(content);
57 free(comment);
62 * Print all the lines from an array of pointer to lines.
64 * The total number oflines printed shall not excess 'count'.
66 void
67 draw_lines(Buffer *buffer, int count, int cols, Opt *opt)
69 Line *line = buffer->current;
70 int i = 0;
71 int j = 0;
73 /* seek back from current line to the first line to print */
74 while (line && i < count - OFFSET) {
75 i = line->matches ? i + 1 : i;
76 line = line->prev;
78 line = line ? line : buffer->first;
80 /* print up to count lines that match the input */
81 while (line && j < count) {
82 if (line->matches) {
83 draw_line(line, line == buffer->current, cols, opt);
84 j++;
87 line = line->next;
90 /* continue up to the end of the screen clearing it */
91 for (; j < count; j++)
92 fputs("\r\033[K\n", stderr);
97 * Update the screen interface and print all candidates.
99 * This also has to clear the previous lines.
101 void
102 draw_screen(Buffer *buffer, int tty_fd, Opt *opt)
104 struct winsize w;
105 int count;
107 ioctl(tty_fd, TIOCGWINSZ, &w);
108 count = MIN(opt->lines, w.ws_row - 2);
110 fputs("\n", stderr);
111 draw_lines(buffer, count, w.ws_col, opt);
113 /* go up to the prompt position and update it */
114 fprintf(stderr, "\033[%dA", count + 1);
115 draw_prompt(buffer, w.ws_col, opt);
119 void
120 draw_clear(int lines)
122 int i;
124 for (i = 0; i < lines + 1; i++)
125 fputs("\r\033[K\n", stderr);
126 fprintf(stderr, "\033[%dA", lines + 1);
131 * Print the prompt, before the input, with the number of candidates that
132 * match.
134 void
135 draw_prompt(Buffer *buffer, int cols, Opt *opt)
137 size_t i;
138 int matching = buffer->matching;
139 int total = buffer->total;
140 char *input = expand_tabs(buffer->input);
141 char *suggest = expand_tabs(buffer->current->content);
143 /* for the '/' separator between the numbers */
144 cols--;
146 /* number of digits */
147 for (i = matching; i; i /= 10, cols--);
148 for (i = total; i; i /= 10, cols--);
150 /* 0 also has one digit*/
151 cols -= !matching ? 1 : 0;
153 /* actual prompt */
154 fprintf(stderr, "\r%s\033[K> ", opt->prompt);
155 cols -= 2 + strlen(opt->prompt);
157 /* input without overflowing terminal width */
158 for (i = 0; i < strlen(input) && cols > 0; cols--, i++)
159 fputc(input[i], stderr);
161 /* save the cursor position at the end of the input */
162 fputs("\033[s", stderr);
164 /* grey */
165 fputs("\033[1;30m", stderr);
167 /* suggest without overflowing terminal width */
168 if (opt->complete) {
169 for (; i < strlen(suggest) && cols > 0; cols--, i++)
170 fputc(suggest[i], stderr);
173 /* go to the end of the line */
174 fprintf(stderr, "\033[%dC", cols);
176 /* total match and line count at the end of the line */
177 fprintf(stderr, "%d/%d", matching, total);
179 /* restore cursor position at the end of the input */
180 fputs("\033[0m\033[u", stderr);
182 free(input);
183 free(suggest);