1 ////////////////////////////////////////////////////////////////////////////////
2 static K8Term
*oldTerm
;
4 static K8Term
*newTerm
;
6 static int newTermSwitch
;
9 #define CMDLD(_t) (K8T_DATA(_t)->cmdline)
12 typedef void (*CmdHandlerFn
) (const char *cmdname
, char *argstr
);
20 static void cmdPastePrimary (const char *cmdname
, char *argstr
) {
21 selpaste(curterm
, XA_PRIMARY
);
25 static void cmdPasteSecondary (const char *cmdname
, char *argstr
) {
26 selpaste(curterm
, XA_SECONDARY
);
30 static void cmdPasteClipboard (const char *cmdname
, char *argstr
) {
31 selpaste(curterm
, XA_CLIPBOARD
);
35 static void cmdHideSelection (const char *cmdname
, char *argstr
) {
40 static void cmdExec (const char *cmdname
, char *argstr
) {
41 if (curterm
!= NULL
) {
42 if (K8T_DATA(curterm
)->execcmd
!= NULL
) free(K8T_DATA(curterm
)->execcmd
);
43 K8T_DATA(curterm
)->execcmd
= (argstr
[0] ? strdup(argstr
) : NULL
);
48 static int parseTabArgs (char *argstr
, int *noswitch
, int nowrap
, int idx
) {
52 while (*argstr
&& isspace(*argstr
)) ++argstr
;
53 if (!argstr
[0]) break;
54 if (iniParseArguments(argstr
, "s-R-", &arg
, &argstr
) != NULL
) break;
56 if (strcasecmp(arg
, "noswitch") == 0) *noswitch
= 1;
57 else if (strcasecmp(arg
, "switch") == 0) *noswitch
= 0;
58 else if (strcasecmp(arg
, "nowrap") == 0) nowrap
= 1;
59 else if (strcasecmp(arg
, "wrap") == 0) nowrap
= 0;
60 else if (strcasecmp(arg
, "first") == 0) idx
= 0;
61 else if (strcasecmp(arg
, "last") == 0) idx
= term_count
-1;
62 else if (strcasecmp(arg
, "prev") == 0) idx
= -1;
63 else if (strcasecmp(arg
, "next") == 0) idx
= -2;
68 n
= strtol(arg
, &eptr
, 0);
69 if (!eptr
[0] && n
>= 0 && n
< term_count
) idx
= n
;
74 if ((idx
= termidx
-1) < 0) idx
= nowrap
? 0 : term_count
-1;
77 if ((idx
= termidx
+1) >= term_count
) idx
= nowrap
? term_count
-1 : 0;
84 static void flushNewTerm (void) {
85 if (newTerm
!= NULL
) {
86 if (newTermSwitch
&& curterm
!= NULL
) curterm
->lastActiveTime
= mclock_ticks();
88 //termidx = newTermIdx;
89 k8t_tmInitialize(newTerm
, term_array
[0]->col
, term_array
[0]->row
, opt_maxhistory
);
90 //termCreateXPixmap(newTerm);
91 //newTerm->drawSetFG(newTerm, newTerm->defbg);
92 k8t_tmClearRegion(newTerm
, 0, 0, newTerm
->col
-1, newTerm
->row
-1);
93 k8t_tmFullDirty(newTerm
);
95 if (k8t_ttyNew(newTerm
) != 0) {
100 k8t_selInit(newTerm
);
101 k8t_ttyResize(newTerm
);
105 switchToTerm(newTermIdx
, 1);
107 oldTermIdx
= termidx
;
110 termidx
= oldTermIdx
;
118 static void cmdNewTab (const char *cmdname
, char *argstr
) {
119 int noswitch
= 0, idx
;
121 if (opt_disabletabs
) return;
123 if ((newTerm
= k8t_termalloc()) == NULL
) return;
124 k8t_tmInitialize(newTerm
, term_array
[0]->col
, term_array
[0]->row
, opt_maxhistory
);
125 /*idx =*/ parseTabArgs(argstr
, &noswitch
, 0, termidx
);
128 if (curterm
!= NULL
) curterm
->lastActiveTime
= mclock_ticks();
131 newTermIdx
= termidx
= idx
;
133 newTermSwitch
= !noswitch
;
137 static void cmdCloseTab (const char *cmdname
, char *argstr
) {
139 if (curterm
!= NULL
&& !curterm
->dead
) kill(K8T_DATA(curterm
)->pid
, SIGTERM
);
143 static void cmdKillTab (const char *cmdname
, char *argstr
) {
145 if (!curterm
->dead
) kill(K8T_DATA(curterm
)->pid
, SIGKILL
);
149 static void cmdSwitchToTab (const char *cmdname
, char *argstr
) {
150 int noswitch
= 0, idx
;
153 idx
= parseTabArgs(argstr
, &noswitch
, 0, -666);
155 switchToTerm(idx
, 1);
157 oldTermIdx
= termidx
;
162 static void cmdMoveTabTo (const char *cmdname
, char *argstr
) {
163 int noswitch
= 0, idx
;
166 idx
= parseTabArgs(argstr
, &noswitch
, 0, termidx
);
167 if (idx
!= termidx
&& idx
>= 0 && idx
< term_count
) {
168 K8Term
*t
= term_array
[termidx
];
170 // remove current term
171 for (int f
= termidx
+1; f
< term_count
; ++f
) term_array
[f
-1] = term_array
[f
];
173 for (int f
= term_count
-2; f
>= idx
; --f
) term_array
[f
+1] = term_array
[f
];
184 static void cmdDefaultFG (const char *cmdname
, char *argstr
) {
188 if (iniParseArguments(argstr
, "i{0,511}|s-", &c
, &s
) == NULL
) {
189 if (s
!= NULL
&& tolower(s
[0]) == 'g') defaultFG
= c
; else curterm
->deffg
= c
;
194 static void cmdDefaultBG (const char *cmdname
, char *argstr
) {
198 if (iniParseArguments(argstr
, "i{0,511}|s-", &c
) == NULL
) {
199 if (s
!= NULL
&& tolower(s
[0]) == 'g') {
203 XSetWindowBackground(xw
.dpy
, xw
.win
, getColor(curterm
->defbg
));
204 if (newTerm
== NULL
) {
205 k8t_tmFullDirty(curterm
);
206 k8t_drawTerm(curterm
, 1);
214 static void scrollHistory (K8Term
*term
, int delta
) {
215 if (term
== NULL
|| term
->maxhistory
< 1) return; // no history
216 term
->topline
+= delta
;
217 if (term
->topline
> term
->maxhistory
) term
->topline
= term
->maxhistory
;
218 if (term
->topline
< 0) term
->topline
= 0;
219 k8t_tmFullDirty(term
);
220 k8t_drawTerm(term
, 1);
224 static void cmdScrollHistoryLineUp (const char *cmdname
, char *argstr
) {
225 scrollHistory(curterm
, 1);
229 static void cmdScrollHistoryPageUp (const char *cmdname
, char *argstr
) {
230 scrollHistory(curterm
, curterm
->row
);
234 static void cmdScrollHistoryLineDown (const char *cmdname
, char *argstr
) {
235 scrollHistory(curterm
, -1);
239 static void cmdScrollHistoryPageDown (const char *cmdname
, char *argstr
) {
240 scrollHistory(curterm
, -curterm
->row
);
244 static void cmdScrollHistoryTop (const char *cmdname
, char *argstr
) {
245 scrollHistory(curterm
, curterm
->linecount
);
249 static void cmdScrollHistoryBottom (const char *cmdname
, char *argstr
) {
250 scrollHistory(curterm
, -curterm
->linecount
);
254 static void cmdCommandMode (const char *cmdname
, char *argstr
) {
255 if (curterm
!= NULL
) {
256 if (CMDLD(curterm
).cmdMode
== K8T_CMDMODE_NONE
) tcmdlineinit(curterm
, &CMDLD(curterm
)); else tcmdlinehide(curterm
, &CMDLD(curterm
));
262 static void cmdCursor (const char *cmdname
, char *argstr
) {
263 if (curterm
!= NULL
) {
266 if (iniParseArguments(argstr
, "s!-", &s
) != NULL
) {
267 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "cursor is %s", ((curterm
->c
.state
&K8T_CURSOR_HIDE
) ? "hidden" : "visible"));
269 if (strcasecmp(s
, "show") == 0) curterm
->c
.state
&= ~K8T_CURSOR_HIDE
;
270 else if (strcasecmp(s
, "hide") == 0) curterm
->c
.state
|= K8T_CURSOR_HIDE
;
271 k8t_tmWantRedraw(curterm
, 0);
277 static void cmdReset (const char *cmdname
, char *argstr
) {
280 if (curterm
!= NULL
) {
281 if (iniParseArguments(argstr
, "|s-", &s
) == NULL
) {
283 switch (tolower(s
[0])) {
285 k8t_tmResetMode(curterm
);
288 k8t_tmResetAttrs(curterm
);
290 case 'g': // graphics
291 curterm
->mode
&= ~(K8T_MODE_GFX0
|K8T_MODE_GFX1
);
292 curterm
->charset
= K8T_MODE_GFX0
;
295 curterm
->csaved
.state
= curterm
->c
.state
= K8T_CURSOR_DEFAULT
;
300 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "Reset (a)ll | (c)olor | (g)raphics | c(u)rsor");
306 static void cmdScreen (const char *cmdname
, char *argstr
) {
307 if (curterm
!= NULL
) {
310 if (iniParseArguments(argstr
, "s!-", &s
) != NULL
) {
311 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "screen: %s", (K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
) ? "alt" : "norm"));
313 if (strcasecmp(s
, "norm") == 0) {
314 if (K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
)) k8t_tmSwapScreen(curterm
);
315 } else if (strcasecmp(s
, "alt") == 0) {
316 if (!K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
)) k8t_tmSwapScreen(curterm
);
324 static void cmdMouseReports (const char *cmdname
, char *argstr
) {
325 if (curterm
!= NULL
) {
328 if (iniParseArguments(argstr
, "b", &b
) != NULL
) {
329 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "mouse reports are o%s", (K8T_ISSET(curterm
, K8T_MODE_MOUSE
) ? "n" : "ff"));
331 if (b
) curterm
->mode
|= K8T_MODE_MOUSEBTN
; else curterm
->mode
&= ~K8T_MODE_MOUSEBTN
;
337 static int cmd_parseIntArg (const char *fmt
, char *argstr
, int *b
, int *global
, int *toggle
) {
341 if (iniParseArguments(argstr
, "R-", &argstr
) != NULL
) break;
342 if (!argstr
[0]) break;
344 if (iniParseArguments(argstr
, "s!-R-", &s
, &argstr
) != NULL
) break;
345 if (global
&& tolower(s
[0]) == 'g') {
347 } else if (toggle
&& tolower(s
[0]) == 't') {
350 if (!b
|| iniParseArguments(s
, fmt
, b
) != NULL
) return -1;
357 static void cmdUTF8Locale (const char *cmdname
, char *argstr
) {
358 int b
= -1, toggle
= 0;
360 if (cmd_parseIntArg("b", argstr
, &b
, NULL
, &toggle
) != 0) return;
362 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "UTF8Locale: %s", ((needConversion
? !curterm
->needConv
: 1) ? "yes" : "no"));
364 if (!needConversion
) b
= 1;
365 if (curterm
!= NULL
) curterm
->needConv
= !b
;
370 static void cmdAudibleBell (const char *cmdname
, char *argstr
) {
371 int b
= -1, toggle
= 0, global
= 0;
373 if (curterm
== NULL
) return;
374 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
377 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "AudibleBell: %s", (global
? opt_audiblebell
: (curterm
->belltype
&K8T_BELL_AUDIO
)) ? "yes" : "no");
380 if (global
) opt_audiblebell
= !opt_audiblebell
; else curterm
->belltype
^= K8T_BELL_AUDIO
;
382 if (global
) opt_audiblebell
= b
; else curterm
->belltype
= (curterm
->belltype
&~K8T_BELL_AUDIO
)|(b
!=0?K8T_BELL_AUDIO
:0);
388 static void cmdUrgentBell (const char *cmdname
, char *argstr
) {
389 int b
= -1, toggle
= 0, global
= 0;
391 if (curterm
== NULL
) return;
392 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
395 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "UrgentBell: %s", (global
? opt_urgentbell
: (curterm
->belltype
&K8T_BELL_URGENT
)) ? "yes" : "no");
398 if (global
) opt_urgentbell
= !opt_urgentbell
; else curterm
->belltype
^= K8T_BELL_URGENT
;
400 if (global
) opt_urgentbell
= b
; else curterm
->belltype
= (curterm
->belltype
&~K8T_BELL_URGENT
)|(b
!=0?K8T_BELL_URGENT
:0);
406 static void cmdMonochrome (const char *cmdname
, char *argstr
) {
407 int b
= -1, global
= 0;
409 if (curterm
== NULL
) return;
410 if (cmd_parseIntArg("i{0,3}", argstr
, &b
, &global
, NULL
) != 0) return;
413 b
= (global
? globalBW
: curterm
->blackandwhite
);
414 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "Monochrome: %d", b
);
417 if (b
== 3) tcmdlinemsg(curterm
, &CMDLD(curterm
), "Monochrome-global can't be '3'!");
420 curterm
->blackandwhite
= b
;
423 k8t_tmFullDirty(curterm
);
428 static void cmdCursorBlink (const char *cmdname
, char *argstr
) {
429 int b
= -1, global
= 0;
431 if (curterm
== NULL
) return;
432 if (cmd_parseIntArg("i{0,10000}", argstr
, &b
, &global
, NULL
) != 0) return;
435 b
= (global
? opt_cursorBlink
: curterm
->curblink
);
436 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "CursorBlink: %d", b
);
441 curterm
->curblink
= b
;
442 curterm
->curbhidden
= 0;
445 k8t_tmFullDirty(curterm
);
450 static void cmdCursorBlinkInactive (const char *cmdname
, char *argstr
) {
451 int b
= -1, global
= 0, toggle
= 0, *iptr
;
453 if (curterm
== NULL
) return;
454 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
456 iptr
= (global
? &opt_cursorBlinkInactive
: &curterm
->curblinkinactive
);
458 if (toggle
) *iptr
= !(*iptr
); else *iptr
= b
;
459 k8t_drawTerm(curterm
, 0);
464 static void cmdIgnoreClose (const char *cmdname
, char *argstr
) {
467 if (curterm
== NULL
) return;
468 if (cmd_parseIntArg("i{-1,1}", argstr
, &b
, NULL
, NULL
) != 0) return;
471 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "IgnoreClose: %d", opt_ignoreclose
);
478 static void cmdMaxHistory (const char *cmdname
, char *argstr
) {
479 int b
= -1, global
= 0;
481 if (curterm
== NULL
) return;
482 if (cmd_parseIntArg("i{0,65535}", argstr
, &b
, &global
, NULL
) != 0) return;
485 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "MaxHistory: %d", (global
?opt_maxhistory
:curterm
->maxhistory
));
487 if (!global
) k8t_tmAdjMaxHistory(curterm
, b
); else opt_maxhistory
= b
;
492 static void cmdMaxDrawTimeout (const char *cmdname
, char *argstr
) {
495 if (curterm
== NULL
) return;
496 if (cmd_parseIntArg("i{100,60000}", argstr
, &b
, NULL
, NULL
) != 0) return;
499 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "MaxDrawTimeout: %d", opt_maxdrawtimeout
);
501 opt_maxdrawtimeout
= b
;
506 static void cmdSwapDrawTimeout (const char *cmdname
, char *argstr
) {
509 if (curterm
== NULL
) return;
510 if (cmd_parseIntArg("i{10,60000}", argstr
, &b
, NULL
, NULL
) != 0) return;
513 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "SwapDrawTimeout: %d", opt_swapdrawtimeout
);
515 opt_swapdrawtimeout
= b
;
520 static void cmdDrawTimeout (const char *cmdname
, char *argstr
) {
523 if (curterm
== NULL
) return;
524 if (cmd_parseIntArg("i{5,30000}", argstr
, &b
, NULL
, NULL
) != 0) return;
527 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "DrawTimeout: %d", opt_drawtimeout
);
534 static void cmdTabPosition (const char *cmdname
, char *argstr
) {
540 if (iniParseArguments(argstr
, "R-", &argstr
) != NULL
) break;
541 if (!argstr
[0]) break;
543 if (iniParseArguments(argstr
, "s!-R-", &s
, &argstr
) != NULL
) break;
544 if (tolower(s
[0]) == 't') newpos
= 1;
545 else if (tolower(s
[0]) == 'b') newpos
= 0;
546 else if (iniParseArguments(s
, "i{0,1}", &newpos
) != NULL
) return;
550 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabPostion: %s", (opt_tabposition
== 0 ? "bottom" : "top"));
551 } else if (opt_tabposition
!= newpos
) {
552 opt_tabposition
= newpos
;
554 k8t_tmFullDirty(curterm
);
555 k8t_drawTerm(curterm
, 1);
562 static void cmdTabCount (const char *cmdname
, char *argstr
) {
565 if (curterm
== NULL
) return;
566 if (cmd_parseIntArg("i{1,128}", argstr
, &b
, NULL
, NULL
) != 0) return;
569 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabCount: %d", opt_tabcount
);
570 } else if (opt_tabcount
!= b
) {
579 static void cmdDoFullRedraw (const char *cmdname
, char *argstr
) {
581 k8t_tmFullDirty(curterm
);
583 k8t_drawTerm(curterm
, 1);
588 static void cmdTitle (const char *cmdname
, char *argstr
) {
589 if (curterm
!= NULL
) {
592 if (iniParseArguments(argstr
, "s-", &s
) != NULL
|| s
== NULL
) return;
593 memset(curterm
->title
, 0, sizeof(curterm
->title
));
594 while (strlen(s
) > K8T_ESC_TITLE_SIZ
) k8t_UTF8ChopLast(s
);
595 fprintf(stderr
, "[%s]\n", s
);
596 strncpy(curterm
->title
, s
, K8T_ESC_TITLE_SIZ
);
597 fixWindowTitle(curterm
);
604 static void cmdFastRedraw (const char *cmdname
, char *argstr
) {
605 int b
= -1, global
= 0, toggle
= 0, *iptr
;
607 if (curterm
== NULL
) return;
608 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
610 iptr
= (global
? &opt_fastredraw
: &curterm
->fastredraw
);
612 if (toggle
) *iptr
= !(*iptr
); else *iptr
= b
;
613 k8t_drawTerm(curterm
, 0);
615 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "FastRedraw: %s", (*iptr
? "yes" : "no"));
620 static void cmdFastUpdate (const char *cmdname
, char *argstr
) {
621 int b
= -1, toggle
= 0, *iptr
;
623 if (curterm
== NULL
) return;
624 if (cmd_parseIntArg("b", argstr
, &b
, NULL
, &toggle
) != 0) return; // only global
626 iptr
= &opt_fastupdate
;
628 if (toggle
) *iptr
= !(*iptr
); else *iptr
= b
;
629 k8t_drawTerm(curterm
, 0);
631 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "FastUpdate: %s", (*iptr
? "yes" : "no"));
636 static void cmdScrollClear (const char *cmdname
, char *argstr
) {
637 int b
= -666, global
= 0, *iptr
;
639 if (curterm
== NULL
) return;
640 if (cmd_parseIntArg("i{-1,2}", argstr
, &b
, &global
, NULL
) != 0) return;
642 iptr
= (global
? &opt_scrollclear
: &curterm
->clearOnPartialScrollMode
);
644 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "ScrollClear: %d", *iptr
);
645 } else if (b
!= -666) {
651 static void cmdAbout (const char *cmdname
, char *argstr
) {
652 if (curterm
!= NULL
) {
653 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "k8sterm " VERSION
);
658 static void cmdDebugDump (const char *cmdname
, char *argstr
) {
659 if (curterm
!= NULL
) {
662 if (iniParseArguments(argstr
, "s-", &s
) == NULL
) {
664 switch (tolower(s
[0])) {
667 curterm
->dumpescapes
= 0;
668 curterm
->dumpeskeys
= 0;
671 curterm
->dumpescapes
= 1;
672 curterm
->dumpeskeys
= 1;
675 curterm
->dumpescapes
= !curterm
->dumpescapes
;
678 curterm
->dumpeskeys
= !curterm
->dumpeskeys
;
683 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "DbgDump (n)one | (a)ll | toggle (e)scapes | toggle extended (k)eys");
692 static void cmdTabEllipsis (const char *cmdname
, char *argstr
) {
695 if (curterm
== NULL
) return;
696 if (cmd_parseIntArg("i{0,3}", argstr
, &b
, NULL
, NULL
) != 0) return;
699 if (opt_tabellipsis
!= b
) {
705 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabEllipsis: %d", opt_tabellipsis
);
710 static const Command commandList
[] = {
711 {"PastePrimary", cmdPastePrimary
},
712 {"PasteSecondary", cmdPasteSecondary
},
713 {"PasteClipboard", cmdPasteClipboard
},
714 {"HideSelection", cmdHideSelection
},
716 {"NewTab", cmdNewTab
}, // 'noswitch' 'next' 'prev' 'first' 'last'
717 {"CloseTab", cmdCloseTab
},
718 {"KillTab", cmdKillTab
},
719 {"SwitchToTab", cmdSwitchToTab
}, // 'next' 'prev' 'first' 'last' 'nowrap' 'wrap'
720 {"MoveTabTo", cmdMoveTabTo
}, // 'next' 'prev' 'first' 'last' 'nowrap' 'wrap'
721 {"DefaultFG", cmdDefaultFG
},
722 {"DefaultBG", cmdDefaultBG
},
723 {"ScrollHistoryLineUp", cmdScrollHistoryLineUp
},
724 {"ScrollHistoryPageUp", cmdScrollHistoryPageUp
},
725 {"ScrollHistoryLineDown", cmdScrollHistoryLineDown
},
726 {"ScrollHistoryPageDown", cmdScrollHistoryPageDown
},
727 {"ScrollHistoryTop", cmdScrollHistoryTop
},
728 {"ScrollHistoryBottom", cmdScrollHistoryBottom
},
729 {"UTF8Locale", cmdUTF8Locale
}, // 'on', 'off'
730 {"AudibleBell", cmdAudibleBell
},
731 {"UrgentBell", cmdUrgentBell
},
732 {"CommandMode", cmdCommandMode
},
733 {"Cursor", cmdCursor
},
735 {"Screen", cmdScreen
},
736 {"MouseReports", cmdMouseReports
},
737 {"Monochrome", cmdMonochrome
},
738 {"Mono", cmdMonochrome
},
739 {"CursorBlink", cmdCursorBlink
},
740 {"CursorBlinkInactive", cmdCursorBlinkInactive
},
741 {"IgnoreClose", cmdIgnoreClose
},
742 {"MaxHistory", cmdMaxHistory
},
743 {"MaxDrawTimeout", cmdMaxDrawTimeout
},
744 {"SwapDrawTimeout", cmdSwapDrawTimeout
},
745 {"DrawTimeout", cmdDrawTimeout
},
746 {"TabPosition", cmdTabPosition
},
747 {"TabCount", cmdTabCount
},
748 {"DoFullRedraw", cmdDoFullRedraw
},
750 {"FastRedraw", cmdFastRedraw
},
751 {"FastUpdate", cmdFastUpdate
},
752 {"ScrollClear", cmdScrollClear
},
753 {"TabEllipsis", cmdTabEllipsis
},
760 {"DbgDump", cmdDebugDump
},
764 {"term", cmdTermName},
765 {"title", cmdWinTitle},
766 {"tabsize", cmdTabSize},
767 {"defaultcursorfg", cmdDefaultCursorFG},
768 {"defaultcursorbg", cmdDefaultCursorBG},
769 {"defaultinactivecursorfg", cmdDefaultInactiveCursorFG},
770 {"defaultinactivecursorbg", cmdDefaultInactiveCursorBG},
771 {"defaultboldfg", cmdDefaultBoldFG},
772 {"defaultunderlinefg", cmdDefaultUnderlineFG},
778 static const char *findCommandCompletion (const char *str
, int slen
, const char *prev
) {
779 const char *res
= NULL
;
782 if (slen
< 1) return NULL
;
783 for (int f
= 0; commandList
[f
].name
!= NULL
; ++f
) {
784 if (strlen(commandList
[f
].name
) >= slen
&& strncasecmp(commandList
[f
].name
, str
, slen
) == 0) {
785 if (prev
== NULL
|| phit
) return commandList
[f
].name
;
786 if (strcasecmp(commandList
[f
].name
, prev
) == 0) phit
= 1;
787 if (res
== NULL
) res
= commandList
[f
].name
;
794 // !0: NewTab command
795 static int executeCommand (const char *str
, int slen
) {
800 if (str
== NULL
) return 0;
801 if (slen
< 0) slen
= strlen(str
);
803 for (int f
= 0; f
< slen
; ++f
) if (!str
[f
]) { slen
= f
; break; }
805 while (slen
> 0 && isspace(*str
)) { ++str
; --slen
; }
806 if (slen
< 1 || !str
[0]) return 0;
808 for (e
= str
; slen
> 0 && !isspace(*e
); ++e
, --slen
) ;
810 if (e
-str
> 127) return 0;
811 cmdname
= alloca(e
-str
+8);
812 if (cmdname
== NULL
) return 0;
813 memcpy(cmdname
, str
, e
-str
);
815 if (opt_disabletabs
&& strcasecmp(cmdname
, "NewTab") == 0) return 1;
817 while (slen
> 0 && isspace(*e
)) { ++e
; --slen
; }
818 //FIXME: ugly copypaste!
820 for (int f
= 0; commandList
[f
].name
!= NULL
; ++f
) {
821 if (strcasecmp(commandList
[f
].name
, cmdname
) == 0 && commandList
[f
].fn
!= NULL
) {
822 char *left
= calloc(slen
+2, 1);
825 if (slen
> 0) memcpy(left
, e
, slen
);
826 //fprintf(stderr, "command: [%s]; args: [%s]\n", cmdname, left);
827 commandList
[f
].fn(cmdname
, left
);
836 char *left
= calloc(slen
+2, 1);
839 if (slen
> 0) memcpy(left
, e
, slen
);
840 processMiscCmds(cmdname
, left
);
850 static const char *cmdpSkipStr (const char *str) {
851 while (*str && isspace(*str)) ++str;
852 if (str[0] && str[0] != ';') {
856 if (*str == ';' && qch == ' ') break;
857 if (qch != ' ' && *str == qch) { qch = ' '; ++str; continue; }
858 if (*str == '"' || *str == '\'') {
859 if (qch == ' ') qch = *str;
863 if (*str++ == '\\' && *str) ++str;
871 static void executeCommands (const char *str
) {
873 oldTermIdx
= termidx
;
876 if (str
== NULL
) return;
881 while (*str
&& isspace(*str
)) ++str
;
883 if (*str
== ';') { ++str
; continue; }
888 if (*ce
== ';' && qch
== ' ') break;
889 if (qch
!= ' ' && *ce
== qch
) { qch
= ' '; ++ce
; continue; }
890 if (*ce
== '"' || *ce
== '\'') {
891 if (qch
== ' ') qch
= *ce
;
895 if (*ce
++ == '\\' && *ce
) ++ce
;
898 if (executeCommand(str
, ce
-str
)) break;
899 if (*ce
) str
= ce
+1; else break;
902 switchToTerm(oldTermIdx
, 1);