10 * Print a line to stderr.
13 draw_line(Line
*line
, int current
, int cols
, Opt
*opt
)
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
);
29 fputs(line
->header
? " " : " ", stderr
);
30 n
+= line
->header
? 1 : 2;
33 /* highlight current line */
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 /* MAX with '1' as \033[0C still move 1 to the right */
44 fprintf(stderr
, "\033[%dC", MAX(40 - n
, 1));
48 /* comments in grey */
49 fputs("\033[1;30m", stderr
);
51 /* print comment without overflowing terminal width */
52 for (i
= 0; i
< strlen(comment
) && n
< cols
; n
++, i
++)
53 fputc(comment
[i
], stderr
);
55 fputs("\033[0m\n", stderr
);
63 * Print all the lines from an array of pointer to lines.
65 * The total number oflines printed shall not excess 'count'.
68 draw_lines(Buffer
*buffer
, int count
, int cols
, Opt
*opt
)
70 Line
*line
= buffer
->current
;
74 /* seek back from current line to the first line to print */
75 while (line
&& i
< count
- OFFSET
) {
76 i
= line
->matches
? i
+ 1 : i
;
79 line
= line
? line
: buffer
->first
;
81 /* print up to count lines that match the input */
82 while (line
&& j
< count
) {
84 draw_line(line
, line
== buffer
->current
, cols
, opt
);
91 /* continue up to the end of the screen clearing it */
92 for (; j
< count
; j
++)
93 fputs("\r\033[K\n", stderr
);
98 * Update the screen interface and print all candidates.
100 * This also has to clear the previous lines.
103 draw_screen(Buffer
*buffer
, int tty_fd
, Opt
*opt
)
108 ioctl(tty_fd
, TIOCGWINSZ
, &w
);
109 count
= MIN(opt
->lines
, w
.ws_row
- 2);
112 draw_lines(buffer
, count
, w
.ws_col
, opt
);
114 /* go up to the prompt position and update it */
115 fprintf(stderr
, "\033[%dA", count
+ 1);
116 draw_prompt(buffer
, w
.ws_col
, opt
);
121 draw_clear(int lines
)
125 for (i
= 0; i
< lines
+ 1; i
++)
126 fputs("\r\033[K\n", stderr
);
127 fprintf(stderr
, "\033[%dA", lines
+ 1);
132 * Print the prompt, before the input, with the number of candidates that
136 draw_prompt(Buffer
*buffer
, int cols
, Opt
*opt
)
139 int matching
= buffer
->matching
;
140 int total
= buffer
->total
;
141 char *input
= expand_tabs(buffer
->input
);
142 char *suggest
= expand_tabs(buffer
->current
->content
);
144 /* for the '/' separator between the numbers */
147 /* number of digits */
148 for (i
= matching
; i
; i
/= 10, cols
--);
149 for (i
= total
; i
; i
/= 10, cols
--);
151 /* 0 also has one digit*/
152 cols
-= !matching
? 1 : 0;
155 fprintf(stderr
, "\r%s\033[K> ", opt
->prompt
);
156 cols
-= 2 + strlen(opt
->prompt
);
158 /* input without overflowing terminal width */
159 for (i
= 0; i
< strlen(input
) && cols
> 0; cols
--, i
++)
160 fputc(input
[i
], stderr
);
162 /* save the cursor position at the end of the input */
163 fputs("\033[s", stderr
);
166 fputs("\033[1;30m", stderr
);
168 /* suggest without overflowing terminal width */
169 if (opt
->complete
&& buffer
->matching
> 0) {
170 for (; i
< strlen(suggest
) && cols
> 0; cols
--, i
++)
171 fputc(suggest
[i
], stderr
);
174 /* go to the end of the line */
175 fprintf(stderr
, "\033[%dC", cols
);
177 /* total match and line count at the end of the line */
178 fprintf(stderr
, "%d/%d", matching
, total
);
180 /* restore cursor position at the end of the input */
181 fputs("\033[0m\033[u", stderr
);