10 * Replace tab as a multiple of 8 spaces in a line.
13 expand_tabs(char *line
)
16 char *converted
= malloc(sizeof(char) * (strlen(line
) * 8 + 1));
18 for (i
= 0, n
= 0; i
< strlen(line
); i
++, n
++) {
19 if (line
[i
] == '\t') {
20 for (; (n
) % 8 != 0; n
++) {
26 converted
[n
] = line
[i
];
36 * Print a line to stderr.
39 draw_line(Line
*line
, int current
, int cols
, Opt
*opt
)
43 char *content
= expand_tabs(line
->content
);
44 char *comment
= expand_tabs(line
->comment
);
46 /* clean the line in case it was not empty */
47 fputs("\033[K", stderr
);
49 /* line number if option set */
50 if (opt
->line_numbers
) {
52 fputs("\033[1m", stderr
);
54 fputs("\033[1;30m", stderr
);
57 fprintf(stderr
, "%7d\033[0m ", line
->number
);
63 /* highlight current line */
65 fputs("\033[1;33m", stderr
);
68 /* print content without overflowing terminal width */
69 for (i
= 0; i
< strlen(content
) && n
< cols
; n
++, i
++) {
70 fputc(content
[i
], stderr
);
73 /* print spaces without overflowing terminal width */
74 for (i
= n
; i
<= 40 && n
< cols
; n
++, i
++) {
78 /* comments in grey */
79 fputs("\033[1;30m", stderr
);
81 /* print comment without overflowing terminal width */
82 for (i
= 0; i
< strlen(comment
) && n
< cols
; n
++, i
++) {
83 fputc(comment
[i
], stderr
);
86 fputs("\033[0m\n", stderr
);
93 * Print a header title.
101 * Print all the lines from an array of pointer to lines.
103 * The total number oflines printed shall not excess 'count'.
106 draw_lines(Buffer
*buffer
, int count
, int offset
, int cols
, Opt
*opt
)
108 Line
*line
= buffer
->current
;
112 /* seek back from current line to the first line to print */
113 while (line
&& i
< count
- offset
) {
114 i
= line
->matches
? i
+ 1 : i
;
117 line
= line
? line
: buffer
->first
;
119 /* print up to count lines that match the input */
120 while (line
&& j
< count
) {
122 draw_line(line
, line
== buffer
->current
, cols
, opt
);
129 /* continue up to the end of the screen clearing it */
130 for (; j
< count
; j
++) {
131 fputs("\r\033[K\n", stderr
);
136 * Update the screen interface and print all candidates.
138 * This also has to clear the previous lines.
141 draw_screen(Buffer
*buffer
, int offset
, int tty_fd
, Opt
*opt
)
146 ioctl(tty_fd
, TIOCGWINSZ
, &w
);
147 count
= MIN(opt
->lines
, w
.ws_row
- 2);
150 draw_lines(buffer
, count
, offset
, w
.ws_col
, opt
);
152 /* go up to the prompt position and update it */
153 fprintf(stderr
, "\033[%dA", count
+ 1);
154 draw_prompt(buffer
, w
.ws_col
, opt
);
157 void draw_clear(int count
)
160 for (i
= 0; i
< count
+ 1; i
++) {
161 fputs("\r\033[K\n", stderr
);
164 fprintf(stderr
, "\033[%dA", count
+ 1);
169 * Print the prompt, before the input, with the number of candidates that
173 draw_prompt(Buffer
*buffer
, int cols
, Opt
*opt
)
176 int matching
= buffer
->matching
;
177 int total
= buffer
->total
;
178 char *input
= expand_tabs(buffer
->input
);
179 char *suggest
= expand_tabs(buffer
->current
->content
);
181 /* for the '/' separator between the numbers */
184 /* number of digits */
185 for (i
= matching
; i
; i
/= 10, cols
--)
187 for (i
= total
; i
; i
/= 10, cols
--)
190 /* 0 also has one digit*/
191 cols
-= !matching
? 1 : 0;
194 fprintf(stderr
, "\r%s\033[K> ", opt
->prompt
);
195 cols
-= 2 + strlen(opt
->prompt
);
197 /* input without overflowing terminal width */
198 for (i
= 0; i
< strlen(input
) && cols
> 0; cols
--, i
++) {
199 fputc(input
[i
], stderr
);
202 /* save the cursor position at the end of the input */
203 fputs("\033[s", stderr
);
206 fputs("\033[1;30m", stderr
);
208 /* suggest without overflowing terminal width */
209 if (opt
->complete_mode
) {
210 for (; i
< strlen(suggest
) && cols
> 0; cols
--, i
++) {
211 fputc(suggest
[i
], stderr
);
215 /* go to the end of the line */
216 for (i
= 0; cols
> 0; cols
--, i
++) {
220 /* total match and line count at the end of the line */
221 fprintf(stderr
, "%d/%d", matching
, total
);
223 /* restore cursor position at the end of the input */
224 fputs("\033[0m\033[u", stderr
);