Fixing missing highlight in man page
[iomenu.git] / draw.c
blob8538ae5a67c1f14a74960ea02acb42224348b22c
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, const int cols, Opt *opt)
15 char *content = expand_tabs(line->content);
16 char *comment = expand_tabs(line->comment);
17 char output[LINE_SIZE * sizeof(char)] = "\033[K";
18 int n = 0;
20 if (!line->header) {
21 strcat(output, current ? "\033[1;31m>" : " ");
22 n++;
25 if (opt->line_numbers) {
26 strcat(output, current ? "\033[1;37m" : "\033[1;30m");
27 sprintf(output + strlen(output), "%7d \033[0m", line->number);
28 n += 8;
29 } else {
30 strcat(output, " ");
31 n++;
34 /* highlight current line */
35 if (current)
36 strcat(output, "\033[1;33m");
38 /* content */
39 strncat(output, content, cols - n);
40 n += strlen(content);
42 /* align comment */
43 if (!line->header && line->comment[0] != '\0') {
44 /* MAX with '1' as \033[0C still move 1 to the right */
45 sprintf(output + strlen(output), "\033[%dC",
46 MAX(1, 40 - n));
47 n += MAX(1, 40 - n);
48 } else if (line->header)
50 /* comment */
51 strcat(output, "\033[1;30m");
52 strncat(output, comment, cols - n);
53 n += strlen(comment);
55 strcat(output, "\033[0m\n");
57 fputs(output, stderr);
59 free(content);
60 free(comment);
65 * Print all the lines from an array of pointer to lines.
67 * The total number oflines printed shall not excess 'count'.
69 void
70 draw_lines(Buffer *buffer, int count, int cols, Opt *opt)
72 Line *line = buffer->current;
73 int i = 0;
74 int j = 0;
76 /* seek back from current line to the first line to print */
77 while (line && i < count - OFFSET) {
78 i = line->matches ? i + 1 : i;
79 line = line->prev;
81 line = line ? line : buffer->first;
83 /* print up to count lines that match the input */
84 while (line && j < count) {
85 if (line->matches) {
86 draw_line(line, line == buffer->current, cols, opt);
87 j++;
90 line = line->next;
93 /* continue up to the end of the screen clearing it */
94 for (; j < count; j++)
95 fputs("\r\033[K\n", stderr);
100 * Update the screen interface and print all candidates.
102 * This also has to clear the previous lines.
104 void
105 draw_screen(Buffer *buffer, int tty_fd, Opt *opt)
107 struct winsize w;
108 int count;
110 if (ioctl(tty_fd, TIOCGWINSZ, &w) < 0)
111 die("could not get terminal size");
113 count = MIN(opt->lines, w.ws_row - 2);
115 fputs("\n", stderr);
116 draw_lines(buffer, count, w.ws_col, opt);
118 /* go up to the prompt position and update it */
119 fprintf(stderr, "\033[%dA", count + 1);
120 draw_prompt(buffer, w.ws_col, opt);
124 void
125 draw_clear(int lines)
127 int i;
129 for (i = 0; i < lines + 1; i++)
130 fputs("\r\033[K\n", stderr);
131 fprintf(stderr, "\033[%dA", lines + 1);
136 * Print the prompt, before the input, with the number of candidates that
137 * match.
139 void
140 draw_prompt(Buffer *buffer, int cols, Opt *opt)
142 size_t i;
143 int matching = buffer->matching;
144 int total = buffer->total;
145 char *input = expand_tabs(buffer->input);
146 char *suggest = expand_tabs(buffer->current->content);
148 /* for the '/' separator between the numbers */
149 cols--;
151 /* number of digits */
152 for (i = matching; i; i /= 10, cols--);
153 for (i = total; i; i /= 10, cols--);
154 cols -= !matching ? 1 : 0; /* 0 also has one digit*/
156 /* actual prompt */
157 fprintf(stderr, "\r%s\033[K> ", opt->prompt);
158 cols -= 2 + strlen(opt->prompt);
160 /* input without overflowing terminal width */
161 for (i = 0; i < strlen(input) && cols > 0; cols--, i++)
162 fputc(input[i], stderr);
164 /* save the cursor position at the end of the input */
165 fputs("\033[s", stderr);
167 /* grey */
168 fputs("\033[1;30m", stderr);
170 /* go to the end of the line */
171 fprintf(stderr, "\033[%dC", cols);
173 /* total match and line count at the end of the line */
174 fprintf(stderr, "%d/%d", matching, total);
176 /* restore cursor position at the end of the input */
177 fputs("\033[0m\033[u", stderr);
179 free(input);
180 free(suggest);