| 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 |
} |
} |