File src/hstr.c changed (mode: 100644) (index 5cccaa6..a6d2487) |
22 |
22 |
#include "include/hstr_utils.h" |
#include "include/hstr_utils.h" |
23 |
23 |
#include "include/hstr_history.h" |
#include "include/hstr_history.h" |
24 |
24 |
|
|
25 |
|
#define LABEL_HISTORY " HISTORY " |
|
26 |
25 |
#define FILE_BASHRC ".bashrc" |
#define FILE_BASHRC ".bashrc" |
27 |
26 |
#define SELECTION_CURSOR_IN_PROMPT -1 |
#define SELECTION_CURSOR_IN_PROMPT -1 |
28 |
27 |
#define SELECTION_PREFIX_MAX_LNG 500 |
#define SELECTION_PREFIX_MAX_LNG 500 |
|
... |
... |
static const char *BUILD_STRING= |
67 |
66 |
"HH build: "__DATE__" " __TIME__""; |
"HH build: "__DATE__" " __TIME__""; |
68 |
67 |
|
|
69 |
68 |
static const char *LABEL_HELP= |
static const char *LABEL_HELP= |
70 |
|
"Type to filter, UP/DOWN to move, Ctrl-r to remove, ENTER to select, Ctrl-x to exit"; |
|
|
69 |
|
"Type to filter, UP/DOWN to move, C-r to remove, ENTER to select, C-x to exit"; |
71 |
70 |
|
|
72 |
71 |
static char **selection=NULL; |
static char **selection=NULL; |
73 |
72 |
static unsigned selectionSize=0; |
static unsigned selectionSize=0; |
74 |
73 |
static bool terminalHasColors=FALSE; |
static bool terminalHasColors=FALSE; |
|
74 |
|
static bool caseSensitive=FALSE; |
|
75 |
|
static bool defaultOrder=FALSE; |
75 |
76 |
static char screenLine[1000]; |
static char screenLine[1000]; |
76 |
77 |
|
|
77 |
|
int print_prompt(WINDOW *win) |
|
|
78 |
|
int print_prompt() |
78 |
79 |
{ |
{ |
79 |
80 |
char *hostname = get_hostname(); |
char *hostname = get_hostname(); |
80 |
81 |
char *user = getenv(ENV_VAR_USER); |
char *user = getenv(ENV_VAR_USER); |
81 |
82 |
int xoffset = 1; |
int xoffset = 1; |
82 |
83 |
|
|
83 |
|
mvwprintw(win, xoffset, Y_OFFSET_PROMPT, "%s@%s$ ", user, hostname); |
|
|
84 |
|
mvwprintw(stdscr, xoffset, Y_OFFSET_PROMPT, "%s@%s$ ", user, hostname); |
84 |
85 |
refresh(); |
refresh(); |
85 |
86 |
|
|
86 |
87 |
return xoffset+strlen(user)+1+strlen(hostname)+1; |
return xoffset+strlen(user)+1+strlen(hostname)+1; |
87 |
88 |
} |
} |
88 |
89 |
|
|
89 |
|
void print_help_label(WINDOW *win) |
|
|
90 |
|
void print_help_label() |
90 |
91 |
{ |
{ |
91 |
|
snprintf(screenLine, getmaxx(win), "%s", LABEL_HELP); |
|
92 |
|
mvwprintw(win, Y_OFFSET_HELP, 0, screenLine); |
|
|
92 |
|
snprintf(screenLine, getmaxx(stdscr), "%s", LABEL_HELP); |
|
93 |
|
mvwprintw(stdscr, Y_OFFSET_HELP, 0, screenLine); |
93 |
94 |
refresh(); |
refresh(); |
94 |
95 |
} |
} |
95 |
96 |
|
|
96 |
|
void print_cmd_deleted_label(WINDOW *win, char *cmd, int occurences) |
|
|
97 |
|
void print_cmd_deleted_label(char *cmd, int occurences) |
97 |
98 |
{ |
{ |
98 |
|
snprintf(screenLine, getmaxx(win), "History item '%s' deleted (%d occurrence%s)", cmd, occurences, (occurences==1?"":"s")); |
|
99 |
|
mvwprintw(win, Y_OFFSET_HELP, 0, screenLine); |
|
|
99 |
|
snprintf(screenLine, getmaxx(stdscr), "History item '%s' deleted (%d occurrence%s)", cmd, occurences, (occurences==1?"":"s")); |
|
100 |
|
mvwprintw(stdscr, Y_OFFSET_HELP, 0, screenLine); |
100 |
101 |
clrtoeol(); |
clrtoeol(); |
101 |
102 |
refresh(); |
refresh(); |
102 |
103 |
} |
} |
103 |
104 |
|
|
104 |
|
void print_history_label(WINDOW *win) |
|
|
105 |
|
// make this status row |
|
106 |
|
void print_history_label(HistoryItems *history) |
105 |
107 |
{ |
{ |
106 |
|
char message[512]; |
|
107 |
|
|
|
108 |
|
int width=getmaxx(win); |
|
109 |
|
|
|
110 |
|
strcpy(message, LABEL_HISTORY); |
|
111 |
|
width -= strlen(LABEL_HISTORY); |
|
|
108 |
|
sprintf(screenLine, "- HISTORY - case:%s (C-i) - order:%s (C-h) - %d/%d ", |
|
109 |
|
(caseSensitive?"sensitive":"insensitive"), |
|
110 |
|
(defaultOrder?"history":"ranking"), |
|
111 |
|
history->count, |
|
112 |
|
history->rawCount); |
|
113 |
|
int width=getmaxx(stdscr); |
|
114 |
|
width -= strlen(screenLine); |
|
115 |
|
if(width<0) { |
|
116 |
|
width = 0; |
|
117 |
|
screenLine[getmaxx(stdscr)]=0; |
|
118 |
|
} |
112 |
119 |
unsigned i; |
unsigned i; |
113 |
120 |
for (i=0; i < width; i++) { |
for (i=0; i < width; i++) { |
114 |
|
strcat(message, " "); |
|
|
121 |
|
strcat(screenLine, "-"); |
115 |
122 |
} |
} |
116 |
|
|
|
117 |
|
wattron(win, A_REVERSE); |
|
118 |
|
mvwprintw(win, Y_OFFSET_HISTORY, 0, message); |
|
119 |
|
wattroff(win, A_REVERSE); |
|
120 |
|
|
|
|
123 |
|
wattron(stdscr, A_REVERSE); |
|
124 |
|
mvwprintw(stdscr, Y_OFFSET_HISTORY, 0, screenLine); |
|
125 |
|
wattroff(stdscr, A_REVERSE); |
121 |
126 |
refresh(); |
refresh(); |
122 |
127 |
} |
} |
123 |
128 |
|
|
124 |
|
unsigned get_max_history_items(WINDOW *win) |
|
|
129 |
|
unsigned get_max_history_items() |
125 |
130 |
{ |
{ |
126 |
|
return (getmaxy(win)-Y_OFFSET_ITEMS); |
|
|
131 |
|
return (getmaxy(stdscr)-Y_OFFSET_ITEMS); |
127 |
132 |
} |
} |
128 |
133 |
|
|
129 |
134 |
|
|
|
... |
... |
void alloc_selection(unsigned size) |
139 |
144 |
} |
} |
140 |
145 |
} |
} |
141 |
146 |
|
|
142 |
|
unsigned make_selection(char *prefix, HistoryItems *history, int maxSelectionCount, bool caseSensitive, bool raw) |
|
|
147 |
|
unsigned make_selection(char *prefix, HistoryItems *history, int maxSelectionCount) |
143 |
148 |
{ |
{ |
144 |
149 |
alloc_selection(sizeof(char*) * maxSelectionCount); // TODO realloc |
alloc_selection(sizeof(char*) * maxSelectionCount); // TODO realloc |
145 |
150 |
unsigned i, selectionCount=0; |
unsigned i, selectionCount=0; |
146 |
|
char **source=(raw?history->raw:history->items); |
|
|
151 |
|
char **source=(defaultOrder?history->raw:history->items); |
147 |
152 |
|
|
148 |
153 |
for(i=0; i<history->count && selectionCount<maxSelectionCount; i++) { |
for(i=0; i<history->count && selectionCount<maxSelectionCount; i++) { |
149 |
154 |
if(source[i]) { |
if(source[i]) { |
|
... |
... |
unsigned make_selection(char *prefix, HistoryItems *history, int maxSelectionCou |
184 |
189 |
return selectionCount; |
return selectionCount; |
185 |
190 |
} |
} |
186 |
191 |
|
|
187 |
|
char *print_selection(WINDOW *win, unsigned maxHistoryItems, char *prefix, HistoryItems *history, bool caseSensitive, bool raw) |
|
|
192 |
|
void color_init_pair(short int x, short int y, short int z) |
|
193 |
|
{ |
|
194 |
|
if(terminalHasColors) { |
|
195 |
|
init_pair(x, y, z); |
|
196 |
|
} |
|
197 |
|
} |
|
198 |
|
|
|
199 |
|
void color_attr_on(int c) |
|
200 |
|
{ |
|
201 |
|
if(terminalHasColors) { |
|
202 |
|
attron(c); |
|
203 |
|
} |
|
204 |
|
} |
|
205 |
|
|
|
206 |
|
void print_selection_row(char *text, int y, int width, char *prefix) { |
|
207 |
|
snprintf(screenLine, width, " %s", text); |
|
208 |
|
mvwprintw(stdscr, y, 0, screenLine); |
|
209 |
|
if(prefix!=NULL && strlen(prefix)>0) { |
|
210 |
|
wattron(stdscr,A_BOLD); |
|
211 |
|
char *p; |
|
212 |
|
if(caseSensitive) { |
|
213 |
|
p=strstr(text, prefix); |
|
214 |
|
mvwprintw(stdscr, y, 1+(p-text), "%s", prefix); |
|
215 |
|
} else { |
|
216 |
|
p=strcasestr(text, prefix); |
|
217 |
|
snprintf(screenLine, strlen(prefix)+1, "%s", p); |
|
218 |
|
mvwprintw(stdscr, y, 1+(p-text), "%s", screenLine); |
|
219 |
|
} |
|
220 |
|
wattroff(stdscr,A_BOLD); |
|
221 |
|
} |
|
222 |
|
|
|
223 |
|
} |
|
224 |
|
|
|
225 |
|
void print_highlighted_selection_row(char *text, int y, int width) { |
|
226 |
|
wattron(stdscr, A_REVERSE); |
|
227 |
|
wattron(stdscr, A_BOLD); |
|
228 |
|
snprintf(screenLine, getmaxx(stdscr), "%s%s", (terminalHasColors?" ":">"), text); |
|
229 |
|
mvprintw(y, 0, "%s", screenLine); |
|
230 |
|
wattroff(stdscr, A_BOLD); |
|
231 |
|
wattroff(stdscr, A_REVERSE); |
|
232 |
|
} |
|
233 |
|
|
|
234 |
|
char *print_selection(unsigned maxHistoryItems, char *prefix, HistoryItems *history) |
188 |
235 |
{ |
{ |
189 |
236 |
char *result=""; |
char *result=""; |
190 |
|
unsigned selectionCount=make_selection(prefix, history, maxHistoryItems, caseSensitive, raw); |
|
|
237 |
|
unsigned selectionCount=make_selection(prefix, history, maxHistoryItems); |
191 |
238 |
if (selectionCount > 0) { |
if (selectionCount > 0) { |
192 |
239 |
result = selection[0]; |
result = selection[0]; |
193 |
240 |
} |
} |
194 |
241 |
|
|
195 |
|
int height=get_max_history_items(win); |
|
196 |
|
int width=getmaxx(win); |
|
|
242 |
|
int height=get_max_history_items(stdscr); |
|
243 |
|
int width=getmaxx(stdscr); |
197 |
244 |
unsigned i; |
unsigned i; |
198 |
245 |
int y=Y_OFFSET_ITEMS; |
int y=Y_OFFSET_ITEMS; |
199 |
246 |
|
|
200 |
247 |
move(Y_OFFSET_ITEMS, 0); |
move(Y_OFFSET_ITEMS, 0); |
201 |
|
wclrtobot(win); |
|
|
248 |
|
wclrtobot(stdscr); |
202 |
249 |
|
|
203 |
|
char *p; |
|
204 |
250 |
for (i = 0; i<height; ++i) { |
for (i = 0; i<height; ++i) { |
205 |
251 |
if(i<selectionSize) { |
if(i<selectionSize) { |
206 |
|
snprintf(screenLine, width, " %s", selection[i]); |
|
207 |
|
mvwprintw(win, y++, 0, screenLine); |
|
208 |
|
if(prefix!=NULL && strlen(prefix)>0) { |
|
209 |
|
wattron(win,A_BOLD); |
|
210 |
|
if(caseSensitive) { |
|
211 |
|
p=strstr(selection[i], prefix); |
|
212 |
|
mvwprintw(win, (y-1), 1+(p-selection[i]), "%s", prefix); |
|
213 |
|
} else { |
|
214 |
|
p=strcasestr(selection[i], prefix); |
|
215 |
|
snprintf(screenLine, strlen(prefix)+1, "%s", p); |
|
216 |
|
mvwprintw(win, (y-1), 1+(p-selection[i]), "%s", screenLine); |
|
217 |
|
} |
|
218 |
|
|
|
219 |
|
wattroff(win,A_BOLD); |
|
220 |
|
} |
|
|
252 |
|
print_selection_row(selection[i], y++, width, prefix); |
221 |
253 |
} else { |
} else { |
222 |
|
mvwprintw(win, y++, 0, " "); |
|
|
254 |
|
mvwprintw(stdscr, y++, 0, " "); |
223 |
255 |
} |
} |
224 |
256 |
} |
} |
225 |
257 |
refresh(); |
refresh(); |
|
... |
... |
char *print_selection(WINDOW *win, unsigned maxHistoryItems, char *prefix, Histo |
227 |
259 |
return result; |
return result; |
228 |
260 |
} |
} |
229 |
261 |
|
|
230 |
|
void highlight_selection(int selectionCursorPosition, int previousSelectionCursorPosition) |
|
|
262 |
|
void highlight_selection(int selectionCursorPosition, int previousSelectionCursorPosition, char *prefix) |
231 |
263 |
{ |
{ |
232 |
264 |
if(previousSelectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) { |
if(previousSelectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) { |
233 |
|
mvprintw(Y_OFFSET_ITEMS+previousSelectionCursorPosition, 0, " "); |
|
|
265 |
|
print_selection_row( |
|
266 |
|
selection[previousSelectionCursorPosition], |
|
267 |
|
Y_OFFSET_ITEMS+previousSelectionCursorPosition, |
|
268 |
|
getmaxx(stdscr), |
|
269 |
|
prefix); |
234 |
270 |
} |
} |
235 |
271 |
if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) { |
if(selectionCursorPosition!=SELECTION_CURSOR_IN_PROMPT) { |
236 |
|
mvprintw(Y_OFFSET_ITEMS+selectionCursorPosition, 0, ">"); |
|
|
272 |
|
print_highlighted_selection_row( |
|
273 |
|
selection[selectionCursorPosition], |
|
274 |
|
Y_OFFSET_ITEMS+selectionCursorPosition, |
|
275 |
|
getmaxx(stdscr)); |
237 |
276 |
} |
} |
238 |
277 |
} |
} |
239 |
278 |
|
|
|
... |
... |
void color_start() |
245 |
284 |
} |
} |
246 |
285 |
} |
} |
247 |
286 |
|
|
248 |
|
void color_init_pair(short int x, short int y, short int z) |
|
249 |
|
{ |
|
250 |
|
if(terminalHasColors) { |
|
251 |
|
init_pair(x, y, z); |
|
252 |
|
} |
|
253 |
|
} |
|
254 |
|
|
|
255 |
|
void color_attr_on(int c) |
|
256 |
|
{ |
|
257 |
|
if(terminalHasColors) { |
|
258 |
|
attron(c); |
|
259 |
|
} |
|
260 |
|
} |
|
261 |
|
|
|
262 |
287 |
void color_attr_off(int c) |
void color_attr_off(int c) |
263 |
288 |
{ |
{ |
264 |
289 |
if(terminalHasColors) { |
if(terminalHasColors) { |
|
... |
... |
char *selection_loop(HistoryItems *history) |
287 |
312 |
|
|
288 |
313 |
color_init_pair(1, COLOR_WHITE, COLOR_BLACK); |
color_init_pair(1, COLOR_WHITE, COLOR_BLACK); |
289 |
314 |
color_attr_on(COLOR_PAIR(1)); |
color_attr_on(COLOR_PAIR(1)); |
290 |
|
print_history_label(stdscr); |
|
291 |
|
print_help_label(stdscr); |
|
292 |
|
bool caseSensitive=FALSE; |
|
293 |
|
bool raw=FALSE; |
|
294 |
|
print_selection(stdscr, get_max_history_items(stdscr), NULL, history, caseSensitive, raw); |
|
|
315 |
|
print_history_label(history); |
|
316 |
|
print_help_label(); |
|
317 |
|
print_selection(get_max_history_items(stdscr), NULL, history); |
295 |
318 |
int basex = print_prompt(stdscr); |
int basex = print_prompt(stdscr); |
296 |
319 |
int x = basex; |
int x = basex; |
297 |
320 |
int width=getmaxx(stdscr); |
int width=getmaxx(stdscr); |
|
... |
... |
char *selection_loop(HistoryItems *history) |
313 |
336 |
|
|
314 |
337 |
switch (c) { |
switch (c) { |
315 |
338 |
case KEY_RESIZE: |
case KEY_RESIZE: |
|
339 |
|
print_history_label(history); |
|
340 |
|
move(y, basex+strlen(prefix)); |
|
341 |
|
break; |
316 |
342 |
case K_CTRL_A: |
case K_CTRL_A: |
317 |
343 |
case K_CTRL_E: |
case K_CTRL_E: |
318 |
344 |
case K_ARROW_LEFT: |
case K_ARROW_LEFT: |
|
... |
... |
char *selection_loop(HistoryItems *history) |
326 |
352 |
strcpy(msg,delete); |
strcpy(msg,delete); |
327 |
353 |
selection_remove(delete, history); |
selection_remove(delete, history); |
328 |
354 |
deleteOccurences=history_mgmt_remove(delete); |
deleteOccurences=history_mgmt_remove(delete); |
329 |
|
result = print_selection(stdscr, maxHistoryItems, prefix, history, caseSensitive, raw); |
|
330 |
|
print_cmd_deleted_label(stdscr, msg, deleteOccurences); |
|
|
355 |
|
result = print_selection(maxHistoryItems, prefix, history); |
|
356 |
|
print_cmd_deleted_label(msg, deleteOccurences); |
331 |
357 |
move(y, basex+strlen(prefix)); |
move(y, basex+strlen(prefix)); |
332 |
358 |
} |
} |
|
359 |
|
print_history_label(history); |
333 |
360 |
break; |
break; |
334 |
361 |
case KEY_BACKSPACE: |
case KEY_BACKSPACE: |
335 |
362 |
case K_BACKSPACE: |
case K_BACKSPACE: |
|
... |
... |
char *selection_loop(HistoryItems *history) |
343 |
370 |
} |
} |
344 |
371 |
|
|
345 |
372 |
if(strlen(prefix)>0) { |
if(strlen(prefix)>0) { |
346 |
|
make_selection(prefix, history, maxHistoryItems, caseSensitive, raw); |
|
|
373 |
|
make_selection(prefix, history, maxHistoryItems); |
347 |
374 |
} else { |
} else { |
348 |
|
make_selection(NULL, history, maxHistoryItems, caseSensitive, raw); |
|
|
375 |
|
make_selection(NULL, history, maxHistoryItems); |
349 |
376 |
} |
} |
350 |
|
result = print_selection(stdscr, maxHistoryItems, prefix, history, caseSensitive, raw); |
|
|
377 |
|
result = print_selection(maxHistoryItems, prefix, history); |
351 |
378 |
|
|
352 |
379 |
move(y, basex+strlen(prefix)); |
move(y, basex+strlen(prefix)); |
353 |
380 |
break; |
break; |
|
... |
... |
char *selection_loop(HistoryItems *history) |
359 |
386 |
} else { |
} else { |
360 |
387 |
selectionCursorPosition=selectionSize-1; |
selectionCursorPosition=selectionSize-1; |
361 |
388 |
} |
} |
362 |
|
highlight_selection(selectionCursorPosition, previousSelectionCursorPosition); |
|
|
389 |
|
highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix); |
|
390 |
|
move(y, basex+strlen(prefix)); |
363 |
391 |
break; |
break; |
364 |
392 |
case KEY_DOWN: |
case KEY_DOWN: |
365 |
393 |
case K_DOWN: |
case K_DOWN: |
|
... |
... |
char *selection_loop(HistoryItems *history) |
373 |
401 |
selectionCursorPosition=0; |
selectionCursorPosition=0; |
374 |
402 |
} |
} |
375 |
403 |
} |
} |
376 |
|
highlight_selection(selectionCursorPosition, previousSelectionCursorPosition); |
|
|
404 |
|
highlight_selection(selectionCursorPosition, previousSelectionCursorPosition, prefix); |
|
405 |
|
move(y, basex+strlen(prefix)); |
377 |
406 |
break; |
break; |
378 |
407 |
case KEY_ENTER: |
case KEY_ENTER: |
379 |
408 |
case K_ENTER: |
case K_ENTER: |
|
... |
... |
char *selection_loop(HistoryItems *history) |
385 |
414 |
break; |
break; |
386 |
415 |
case K_CTRL_I: |
case K_CTRL_I: |
387 |
416 |
caseSensitive=!caseSensitive; |
caseSensitive=!caseSensitive; |
|
417 |
|
result = print_selection(maxHistoryItems, prefix, history); |
|
418 |
|
print_history_label(history); |
388 |
419 |
break; |
break; |
389 |
420 |
case K_CTRL_H: |
case K_CTRL_H: |
390 |
|
raw=!raw; |
|
391 |
|
result = print_selection(stdscr, maxHistoryItems, prefix, history, caseSensitive, raw); |
|
|
421 |
|
defaultOrder=!defaultOrder; |
|
422 |
|
result = print_selection(maxHistoryItems, prefix, history); |
|
423 |
|
print_history_label(history); |
392 |
424 |
break; |
break; |
393 |
425 |
case K_CTRL_X: |
case K_CTRL_X: |
394 |
426 |
result = NULL; |
result = NULL; |
|
... |
... |
char *selection_loop(HistoryItems *history) |
411 |
443 |
clrtoeol(); |
clrtoeol(); |
412 |
444 |
} |
} |
413 |
445 |
|
|
414 |
|
result = print_selection(stdscr, maxHistoryItems, prefix, history, caseSensitive, raw); |
|
|
446 |
|
result = print_selection(maxHistoryItems, prefix, history); |
415 |
447 |
move(cursorY, cursorX); |
move(cursorY, cursorX); |
416 |
448 |
refresh(); |
refresh(); |
417 |
449 |
} |
} |