1 /*-------------------------------------------------------------------------
2  *
3  * commands.c
4  *	  a list of commands and translations between keys and commands
5  *
6  * Portions Copyright (c) 2017-2021 Pavel Stehule
7  *
8  * IDENTIFICATION
9  *	  src/commands.c
10  *
11  *-------------------------------------------------------------------------
12  */
13 
14 #include "pspg.h"
15 #include "commands.h"
16 
17 int		CTRL_HOME;
18 int		CTRL_END;
19 int		CTRL_SHIFT_HOME;
20 int		CTRL_SHIFT_END;
21 
22 static int
get_code(const char * capname,int fallback)23 get_code(const char *capname, int fallback)
24 {
25 
26 #ifdef NCURSES_EXT_FUNCS
27 
28 	char	*s;
29 	int		result;
30 
31 	s = tigetstr((NCURSES_CONST char *) capname);
32 
33 	if (s == NULL || s == (char *) -1)
34 		return fallback;
35 
36 	result = key_defined(s);
37 	return result > 0 ? result : fallback;
38 
39 #else
40 
41 	return fallback;
42 
43 #endif
44 
45 }
46 
47 /*
48  * Set a value of CTRL_HOME and CTRL_END key codes. These codes
49  * can be redefined on some plaforms.
50  */
51 void
initialize_special_keycodes()52 initialize_special_keycodes()
53 {
54 
55 #ifdef NCURSES_EXT_FUNCS
56 
57 	use_extended_names(TRUE);
58 
59 #endif
60 
61 	CTRL_HOME = get_code("kHOM5", 538);
62 	CTRL_END = get_code("kEND5", 533);
63 	CTRL_SHIFT_HOME = get_code("kHOM6", 537);
64 	CTRL_SHIFT_END = get_code("kEND6", 532);
65 }
66 
67 /*
68  * For debug purposes
69  */
70 const char *
cmd_string(int cmd)71 cmd_string(int cmd)
72 {
73 	switch (cmd)
74 	{
75 		case cmd_Invalid:
76 			return "Invalid";
77 		case cmd_RESIZE_EVENT:
78 			return "RESIZE";
79 		case cmd_MOUSE_EVENT:
80 			return "MOUSE";
81 
82 		case cmd_ReleaseCols:
83 			return "ReleaseCols";
84 		case cmd_FreezeOneCol:
85 			return "FreezeOneCol";
86 		case cmd_FreezeTwoCols:
87 			return "FreezeTwoCols";
88 		case cmd_FreezeThreeCols:
89 			return "FreezeThreeCols";
90 		case cmd_FreezeFourCols:
91 			return "FreezeFourCols";
92 		case cmd_FreezeFiveCols:
93 			return "FreezeFiveCols";
94 		case cmd_FreezeSixCols:
95 			return "FreezeSixCols";
96 		case cmd_FreezeSevenCols:
97 			return "FreezeSevenCols";
98 		case cmd_FreezeEightCols:
99 			return "FreezeEightCols";
100 		case cmd_FreezeNineCols:
101 			return "FreezeNineCols";
102 		case cmd_SoundToggle:
103 			return "SoundTogle";
104 		case cmd_MouseToggle:
105 			return "MouseTogle";
106 		case cmd_UtfArtToggle:
107 			return "UtfArtToggle";
108 		case cmd_MenuAsciiArtToggle:
109 			return "MenuAsciiArtToggle";
110 		case cmd_CSSearchSet:
111 			return "CSSearchSet";
112 		case cmd_CISearchSet:
113 			return "CISearchSet";
114 		case cmd_USSearchSet:
115 			return "USSearchSet";
116 		case cmd_HighlightLines:
117 			return "HighlightLines";
118 		case cmd_HighlightValues:
119 			return "HighlightValues";
120 		case cmd_NoHighlight:
121 			return "NoHighlight";
122 
123 		case cmd_SetTheme_MidnightBlack:
124 			return "SetTheme_MidnightBlack";
125 		case cmd_SetTheme_Midnight:
126 			return "SetTheme_Midnight";
127 		case cmd_SetTheme_Foxpro:
128 			return "SetTheme_Foxpro";
129 		case cmd_SetTheme_Pdmenu:
130 			return "SetTheme_Pdmenu";
131 		case cmd_SetTheme_White:
132 			return "SetTheme_White";
133 		case cmd_SetTheme_Mutt:
134 			return "SetTheme_Mutt";
135 		case cmd_SetTheme_Pcfand:
136 			return "SetTheme_Pcfand";
137 		case cmd_SetTheme_Green:
138 			return "SetTheme_Green";
139 		case cmd_SetTheme_Blue:
140 			return "SetTheme_Blue";
141 		case cmd_SetTheme_WP:
142 			return "SetTheme_WP";
143 		case cmd_SetTheme_Lowcontrast:
144 			return "SetTheme_Lowcontrast";
145 		case cmd_SetTheme_Darkcyan:
146 			return "SetTheme_Darkcyan";
147 		case cmd_SetTheme_Paradox:
148 			return "SetTheme_Paradox";
149 		case cmd_SetTheme_DBase:
150 			return "SetTheme_DBase";
151 		case cmd_SetTheme_DBasemagenta:
152 			return "SetTheme_DBasemagenta";
153 		case cmd_SetTheme_Red:
154 			return "SetTheme_Red";
155 		case cmd_SetTheme_Simple:
156 			return "SetTheme_Simple";
157 		case cmd_SetTheme_SolarDark:
158 			return "SetTheme_SolarDark";
159 		case cmd_SetTheme_SolarLight:
160 			return "SetTheme_SolarLight";
161 		case cmd_SetTheme_GruvboxLight:
162 			return "SetTheme_GruvboxLight";
163 		case cmd_SetTheme_TaoLight:
164 			return "SetTheme_TaoLight";
165 		case cmd_SetTheme_Flatwhite:
166 			return "SetTheme_Flatwhite";
167 		case cmd_SetTheme_RelationalPipes:
168 			return "SetThemeRelationalPipes";
169 		case cmd_SetTheme_PaperColor:
170 			return "SetTheme_PaperColor";
171 		case cmd_SetTheme:
172 			return "SetTheme";
173 
174 		case cmd_SaveSetup:
175 			return "SaveSetup";
176 
177 		case cmd_Escape:
178 			return "Escape";
179 		case cmd_Quit:
180 			return "Quit";
181 		case cmd_RawOutputQuit:
182 			return "RawOutputQuit";
183 		case cmd_ShowMenu:
184 			return "ShowMenu";
185 		case cmd_FlushBookmarks:
186 			return "FlushBookmarks";
187 		case cmd_ToggleBookmark:
188 			return "ToggleBookmark";
189 		case cmd_PrevBookmark:
190 			return "PrevBookmark";
191 		case cmd_NextBookmark:
192 			return "NextBookmark";
193 		case cmd_CursorUp:
194 			return "CursorUp";
195 		case cmd_CursorDown:
196 			return "CursorDown";
197 		case cmd_ScrollUp:
198 			return "ScrollUp";
199 		case cmd_ScrollDown:
200 			return "ScrollDown";
201 		case cmd_ScrollUpHalfPage:
202 			return "ScrollUpHalfPage";
203 		case cmd_ScrollDownHalfPage:
204 			return "ScrollDownHalfPage";
205 		case cmd_MoveLeft:
206 			return "MoveLeft";
207 		case cmd_MoveRight:
208 			return "MoveRight";
209 		case cmd_CursorFirstRow:
210 			return "CursorFirstRow";
211 		case cmd_CursorLastRow:
212 			return "CursorLastRow";
213 		case cmd_CursorFirstRowPage:
214 			return "CursorFirstRowPage";
215 		case cmd_CursorLastRowPage:
216 			return "CursorLastRowPage";
217 		case cmd_CursorHalfPage:
218 			return "CursorHalfPage";
219 		case cmd_PageUp:
220 			return "PageUp";
221 		case cmd_PageDown:
222 			return "PageDown";
223 		case cmd_ShowFirstCol:
224 			return "ShowFirstCol";
225 		case cmd_ShowLastCol:
226 			return "ShowLastCol";
227 		case cmd_SaveData:
228 			return "SaveData";
229 		case cmd_SaveAsCSV:
230 			return "SaveAsCSV";
231 		case cmd_ForwardSearch:
232 			return "ForwardSearch";
233 		case cmd_BackwardSearch:
234 			return "BackwardSearch";
235 		case cmd_ForwardSearchInSelection:
236 			return "ForwardSearchInSelection";
237 		case cmd_BackwardSearchInSelection:
238 			return "BackwardSearchInSelection";
239 		case cmd_SearchNext:
240 			return "SearchNext";
241 		case cmd_SearchPrev:
242 			return "SearchPrev";
243 		case cmd_SearchColumn:
244 			return "SearchColumn";
245 		case cmd_ShowTopBar:
246 			return "ShowTopBar";
247 		case cmd_ShowBottomBar:
248 			return "ShowBottomBar";
249 		case cmd_RowNumToggle:
250 			return "RowNumToggle";
251 		case cmd_GotoLine:
252 			return "GotoLine";
253 		case cmd_GotoLineRel:
254 			return "GotoLineRel";
255 
256 		case cmd_ShowCursor:
257 			return "ShowCursor";
258 		case cmd_ShowVerticalCursor:
259 			return "ShowVerticalCursor";
260 
261 		case cmd_BoldLabelsToggle:
262 			return "BoldLabelsToggle";
263 		case cmd_BoldCursorToggle:
264 			return "BoldCursorToggle";
265 
266 		case cmd_ShowScrollbar:
267 			return "ShowScrollBar";
268 
269 		case cmd_SortAsc:
270 			return "SortAsc";
271 		case cmd_SortDesc:
272 			return "SortDesc";
273 		case cmd_OriginalSort:
274 			return "OriginalSort";
275 
276 		case cmd_TogglePause:
277 			return "TogglePause";
278 
279 		case cmd_Refresh:
280 			return "Refresh";
281 
282 		case cmd_SetCopyFile:
283 			return "SetCopyFile";
284 		case cmd_SetCopyClipboard:
285 			return "SetCopyClipboard";
286 
287 		case cmd_UseClipboard_CSV:
288 			return "UseClipboardFormatCSV";
289 		case cmd_UseClipboard_TSVC:
290 			return "UseClipboardFormatTSVC";
291 		case cmd_UseClipboard_text:
292 			return "UseClipboardFormattext";
293 		case cmd_UseClipboard_SQL_values:
294 			return "UseClipboardFormatSQLValues";
295 		case cmd_UseClipboard_pipe_separated:
296 			return "UseClipboardFormatPipeSeparated";
297 		case cmd_UseClipboard_INSERT:
298 			return "UseClipboardFormatINSERT";
299 		case cmd_UseClipboard_INSERT_with_comments:
300 			return "UseClipboardFormatINSERTwithcomments";
301 		case cmd_TogleEmptyStringIsNULL:
302 			return "TogleEmptyStringIsNULL";
303 		case cmd_SetOwnNULLString:
304 			return "SetOwnNULLString";
305 		case cmd_Copy:
306 			return "Copy";
307 		case cmd_CopyAllLines:
308 			return "CopyAllLines";
309 		case cmd_CopyTopLines:
310 			return "CopyTopLines";
311 		case cmd_CopyBottomLines:
312 			return "CopyBottomLines";
313 		case cmd_CopyLine:
314 			return "CopyLine";
315 		case cmd_CopyLineExtended:
316 			return "CopyLineExtended";
317 		case cmd_CopyColumn:
318 			return "CopyColumn";
319 		case cmd_CopyMarkedLines:
320 			return "CopyMarkedLines";
321 		case cmd_CopySearchedLines:
322 			return "CopySearchedLines";
323 		case cmd_CopySelected:
324 			return "CopySelected";
325 
326 		case cmd_Mark:
327 			return "Mark";
328 		case cmd_MarkColumn:
329 			return "MarkColumn";
330 		case cmd_MarkAll:
331 			return "MarkAll";
332 		case cmd_Unmark:
333 			return "Unmark";
334 		case cmd_Mark_NestedCursorCommand:
335 			return "MarkNestedCursorCommand";
336 
337 		case cmd_BsCommand:
338 			return "BsCommand";
339 		case cmd_ShowPrimaryScreen:
340 			return "ShowPrimaryScreen";
341 
342 		default:
343 			return "unknown command";
344 	}
345 }
346 
347 bool
is_cmd_RowNumToggle(int c,bool alt)348 is_cmd_RowNumToggle(int c, bool alt)
349 {
350 	if (alt && c == 'n')
351 		return true;
352 
353 	return false;
354 }
355 
356 int
translate_event(int c,bool alt,Options * opts,int * nested_command)357 translate_event(int c, bool alt, Options *opts, int *nested_command)
358 {
359 	if (alt)
360 	{
361 		switch (c)
362 		{
363 			case 'b':
364 				return cmd_BoldLabelsToggle;
365 			case 'c':
366 				return cmd_ShowCursor;
367 			case 'l':
368 				return cmd_GotoLine;
369 			case 'm':
370 				return cmd_MouseToggle;
371 			case 'n':
372 				return cmd_RowNumToggle;
373 			case 'o':
374 				return cmd_FlushBookmarks;
375 			case 'k':
376 				return cmd_ToggleBookmark;
377 			case 'i':
378 				return cmd_PrevBookmark;
379 			case 'j':
380 				return cmd_NextBookmark;
381 			case 'q':
382 				return cmd_RawOutputQuit;
383 			case 'v':
384 				return cmd_ShowVerticalCursor;
385 			case '2':
386 				return cmd_SaveData;
387 			case '3':
388 				if (opts->quit_on_f3)
389 					return cmd_Quit;
390 				else
391 					return cmd_Mark;
392 				break;
393 			case '7':
394 				return cmd_ForwardSearch;
395 			case '9':
396 				return cmd_ShowMenu;
397 			case 27:
398 				return cmd_Escape;
399 			case '0':
400 				return cmd_Quit;
401 			case '/':
402 				return cmd_ForwardSearchInSelection;
403 			case '?':
404 				return cmd_BackwardSearchInSelection;
405 		}
406 	}
407 	else
408 	{
409 		switch (c)
410 		{
411 			case KEY_RESIZE:
412 				return cmd_RESIZE_EVENT;
413 			case KEY_MOUSE:
414 				return cmd_MOUSE_EVENT;
415 			case KEY_F(9):
416 				return cmd_ShowMenu;
417 			case KEY_F(10):
418 			case 'q':
419 				return cmd_Quit;
420 			case KEY_F(3):
421 				if (opts->quit_on_f3)
422 					return cmd_Quit;
423 				else
424 					return cmd_Mark;
425 				break;
426 			case KEY_F(15):
427 				return cmd_MarkColumn;
428 			case KEY_IC:
429 				return cmd_Copy;
430 			case KEY_UP:
431 			case 'k':
432 				return cmd_CursorUp;
433 			case KEY_DOWN:
434 			case 'j':
435 				return cmd_CursorDown;
436 			case '0':
437 				return cmd_ReleaseCols;
438 			case '1':
439 				return cmd_FreezeOneCol;
440 			case '2':
441 				return cmd_FreezeTwoCols;
442 			case '3':
443 				return cmd_FreezeThreeCols;
444 			case '4':
445 				return cmd_FreezeFourCols;
446 			case '5':
447 				return cmd_FreezeFiveCols;
448 			case '6':
449 				return cmd_FreezeSixCols;
450 			case '7':
451 				return cmd_FreezeSevenCols;
452 			case '8':
453 				return cmd_FreezeEightCols;
454 			case '9':
455 				return cmd_FreezeNineCols;
456 			case 4:		/* CTRL D */
457 				return cmd_ScrollDownHalfPage;
458 			case 21:	/* CTRL U */
459 				return cmd_ScrollUpHalfPage;
460 			case 5:		/* CTRL E */
461 				return cmd_ScrollDown;
462 			case 25:	/* CTRL Y */
463 				return cmd_ScrollUp;
464 			case KEY_LEFT:
465 			case 'h':
466 				return cmd_MoveLeft;
467 			case KEY_RIGHT:
468 			case 'l':
469 				return cmd_MoveRight;
470 			case 'H':
471 				return cmd_CursorFirstRowPage;
472 			case 'L':
473 				return cmd_CursorLastRowPage;
474 			case 'M':
475 				return cmd_CursorHalfPage;
476 			case KEY_PPAGE:
477 			case 2:		/* CTRL B */
478 				return cmd_PageUp;
479 			case ' ':
480 				return opts->watch_time > 0 ? cmd_TogglePause : cmd_PageDown;
481 			case 6:		/* CTRL F */
482 			case KEY_NPAGE:
483 				return cmd_PageDown;
484 			case KEY_HOME:
485 			case '^':
486 				return cmd_ShowFirstCol;
487 			case KEY_END:
488 			case '$':
489 				return cmd_ShowLastCol;
490 			case 's':
491 				return cmd_SaveData;
492 			case '/':
493 				return cmd_ForwardSearch;
494 			case '?':
495 				return cmd_BackwardSearch;
496 			case 'n':
497 				return cmd_SearchNext;
498 			case 'N':
499 				return cmd_SearchPrev;
500 			case 'g':
501 				return cmd_CursorFirstRow;
502 			case 'G':
503 				return cmd_CursorLastRow;
504 			case 'c':
505 				return cmd_SearchColumn;
506 			case 'a':
507 				return cmd_SortAsc;
508 			case 'd':
509 				return cmd_SortDesc;
510 			case 'u':
511 				return cmd_OriginalSort;
512 			case 'R':
513 			case 12:	/* CTRL L */
514 				return cmd_Refresh;
515 			case 15:	/* CTRL O */
516 				return cmd_ShowPrimaryScreen;
517 
518 			case '\\':
519 				return cmd_BsCommand;
520 
521 			case KEY_SR:
522 				*nested_command = cmd_CursorUp;
523 				return cmd_Mark_NestedCursorCommand;
524 			case KEY_SF:
525 				*nested_command = cmd_CursorDown;
526 				return cmd_Mark_NestedCursorCommand;
527 			case KEY_SNEXT:
528 				*nested_command = cmd_PageDown;
529 				return cmd_Mark_NestedCursorCommand;
530 			case KEY_SPREVIOUS:
531 				*nested_command = cmd_PageUp;
532 				return cmd_Mark_NestedCursorCommand;
533 		}
534 	}
535 
536 	if (c == CTRL_HOME)
537 		return cmd_CursorFirstRow;
538 	else if (c == CTRL_END)
539 		return cmd_CursorLastRow;
540 	else if (c == CTRL_SHIFT_END)
541 	{
542 		*nested_command = cmd_CursorLastRow;
543 		return cmd_Mark_NestedCursorCommand;
544 	}
545 	else if (c == CTRL_SHIFT_HOME)
546 	{
547 		*nested_command = cmd_CursorFirstRow;
548 		return cmd_Mark_NestedCursorCommand;
549 	}
550 
551 	return cmd_Invalid;
552 }
553 
554 /*
555  * Returns cmd for theme
556  *
557  */
558 int
theme_get_cmd(int theme)559 theme_get_cmd(int theme)
560 {
561 	switch (theme)
562 	{
563 		case 0:
564 			return cmd_SetTheme_MidnightBlack;
565 		case 1:
566 			return cmd_SetTheme_Midnight;
567 		case 2:
568 			return cmd_SetTheme_Foxpro;
569 		case 3:
570 			return cmd_SetTheme_Pdmenu;
571 		case 4:
572 			return cmd_SetTheme_White;
573 		case 5:
574 			return cmd_SetTheme_Mutt;
575 		case 6:
576 			return cmd_SetTheme_Pcfand;
577 		case 7:
578 			return cmd_SetTheme_Green;
579 		case 8:
580 			return cmd_SetTheme_Blue;
581 		case 9:
582 			return cmd_SetTheme_WP;
583 		case 10:
584 			return cmd_SetTheme_Lowcontrast;
585 		case 11:
586 			return cmd_SetTheme_Darkcyan;
587 		case 12:
588 			return cmd_SetTheme_Paradox;
589 		case 13:
590 			return cmd_SetTheme_DBase;
591 		case 14:
592 			return cmd_SetTheme_DBasemagenta;
593 		case 15:
594 			return cmd_SetTheme_Red;
595 		case 16:
596 			return cmd_SetTheme_Simple;
597 		case 17:
598 			return cmd_SetTheme_SolarDark;
599 		case 18:
600 			return cmd_SetTheme_SolarLight;
601 		case 19:
602 			return cmd_SetTheme_GruvboxLight;
603 		case 20:
604 			return cmd_SetTheme_TaoLight;
605 		case 21:
606 			return cmd_SetTheme_Flatwhite;
607 		case 22:
608 			return cmd_SetTheme_RelationalPipes;
609 		case 23:
610 			return cmd_SetTheme_PaperColor;
611 	};
612 
613 	return cmd_Invalid;
614 }
615 
616 /*
617  * Returns theme for cmd
618  *
619  */
620 int
cmd_get_theme(int cmd)621 cmd_get_theme(int cmd)
622 {
623 	switch (cmd)
624 	{
625 		case cmd_SetTheme_MidnightBlack:
626 			return 0;
627 		case cmd_SetTheme_Midnight:
628 			return 1;
629 		case cmd_SetTheme_Foxpro:
630 			return 2;
631 		case cmd_SetTheme_Pdmenu:
632 			return 3;
633 		case cmd_SetTheme_White:
634 			return 4;
635 		case cmd_SetTheme_Mutt:
636 			return 5;
637 		case cmd_SetTheme_Pcfand:
638 			return 6;
639 		case cmd_SetTheme_Green:
640 			return 7;
641 		case cmd_SetTheme_Blue:
642 			return 8;
643 		case cmd_SetTheme_WP:
644 			return 9;
645 		case cmd_SetTheme_Lowcontrast:
646 			return 10;
647 		case cmd_SetTheme_Darkcyan:
648 			return 11;
649 		case cmd_SetTheme_Paradox:
650 			return 12;
651 		case cmd_SetTheme_DBase:
652 			return 13;
653 		case cmd_SetTheme_DBasemagenta:
654 			return 14;
655 		case cmd_SetTheme_Red:
656 			return 15;
657 		case cmd_SetTheme_Simple:
658 			return 16;
659 		case cmd_SetTheme_SolarDark:
660 			return 17;
661 		case cmd_SetTheme_SolarLight:
662 			return 18;
663 		case cmd_SetTheme_GruvboxLight:
664 			return 19;
665 		case cmd_SetTheme_TaoLight:
666 			return 20;
667 		case cmd_SetTheme_Flatwhite:
668 			return 21;
669 		case cmd_SetTheme_RelationalPipes:
670 			return 22;
671 		case cmd_SetTheme_PaperColor:
672 			return 23;
673 	};
674 
675 	return 1;
676 }
677 
678 /*
679  * This is initial simple design. It can be much
680  * smarter, but it is good enough for start.
681  */
682 bool
require_complete_load(int cmd)683 require_complete_load(int cmd)
684 {
685 	switch (cmd)
686 	{
687 		case cmd_CursorLastRow:
688 		case cmd_SortAsc:
689 		case cmd_SortDesc:
690 		case cmd_OriginalSort:
691 		case cmd_SaveData:
692 		case cmd_Copy:
693 		case cmd_GotoLine:
694 		case cmd_ForwardSearch:
695 			return true;
696 
697 		default:
698 			return false;
699 	}
700 }
701