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 cmdExec (const char *cmdname
, char *argstr
) {
36 if (curterm
!= NULL
) {
37 if (K8T_DATA(curterm
)->execcmd
!= NULL
) free(K8T_DATA(curterm
)->execcmd
);
38 K8T_DATA(curterm
)->execcmd
= (argstr
[0] ? strdup(argstr
) : NULL
);
43 static int parseTabArgs (char *argstr
, int *noswitch
, int nowrap
, int idx
) {
47 while (*argstr
&& isspace(*argstr
)) ++argstr
;
48 if (!argstr
[0]) break;
49 if (iniParseArguments(argstr
, "s-R-", &arg
, &argstr
) != NULL
) break;
51 if (strcasecmp(arg
, "noswitch") == 0) *noswitch
= 1;
52 else if (strcasecmp(arg
, "switch") == 0) *noswitch
= 0;
53 else if (strcasecmp(arg
, "nowrap") == 0) nowrap
= 1;
54 else if (strcasecmp(arg
, "wrap") == 0) nowrap
= 0;
55 else if (strcasecmp(arg
, "first") == 0) idx
= 0;
56 else if (strcasecmp(arg
, "last") == 0) idx
= term_count
-1;
57 else if (strcasecmp(arg
, "prev") == 0) idx
= -1;
58 else if (strcasecmp(arg
, "next") == 0) idx
= -2;
63 n
= strtol(arg
, &eptr
, 0);
64 if (!eptr
[0] && n
>= 0 && n
< term_count
) idx
= n
;
69 if ((idx
= termidx
-1) < 0) idx
= nowrap
? 0 : term_count
-1;
72 if ((idx
= termidx
+1) >= term_count
) idx
= nowrap
? term_count
-1 : 0;
79 static void flushNewTerm (void) {
80 if (newTerm
!= NULL
) {
81 if (newTermSwitch
&& curterm
!= NULL
) curterm
->lastActiveTime
= mclock_ticks();
83 //termidx = newTermIdx;
84 k8t_tmInitialize(newTerm
, term_array
[0]->col
, term_array
[0]->row
, opt_maxhistory
);
85 //termCreateXPixmap(newTerm);
86 //newTerm->drawSetFG(newTerm, newTerm->defbg);
87 k8t_tmFullDirty(newTerm
);
89 if (k8t_ttyNew(newTerm
) != 0) {
95 k8t_ttyResize(newTerm
);
99 switchToTerm(newTermIdx
, 1);
101 oldTermIdx
= termidx
;
104 termidx
= oldTermIdx
;
112 static void cmdNewTab (const char *cmdname
, char *argstr
) {
113 int noswitch
= 0, idx
;
115 if (opt_disabletabs
) return;
117 if ((newTerm
= k8t_termalloc()) == NULL
) return;
118 k8t_tmInitialize(newTerm
, term_array
[0]->col
, term_array
[0]->row
, opt_maxhistory
);
119 /*idx =*/ parseTabArgs(argstr
, &noswitch
, 0, termidx
);
122 if (curterm
!= NULL
) curterm
->lastActiveTime
= mclock_ticks();
125 newTermIdx
= termidx
= idx
;
127 newTermSwitch
= !noswitch
;
131 static void cmdCloseTab (const char *cmdname
, char *argstr
) {
133 if (curterm
!= NULL
&& !curterm
->dead
) kill(K8T_DATA(curterm
)->pid
, SIGTERM
);
137 static void cmdKillTab (const char *cmdname
, char *argstr
) {
139 if (!curterm
->dead
) kill(K8T_DATA(curterm
)->pid
, SIGKILL
);
143 static void cmdSwitchToTab (const char *cmdname
, char *argstr
) {
144 int noswitch
= 0, idx
;
147 idx
= parseTabArgs(argstr
, &noswitch
, 0, -666);
149 switchToTerm(idx
, 1);
151 oldTermIdx
= termidx
;
156 static void cmdMoveTabTo (const char *cmdname
, char *argstr
) {
157 int noswitch
= 0, idx
;
160 idx
= parseTabArgs(argstr
, &noswitch
, 0, termidx
);
161 if (idx
!= termidx
&& idx
>= 0 && idx
< term_count
) {
162 K8Term
*t
= term_array
[termidx
];
164 // remove current term
165 for (int f
= termidx
+1; f
< term_count
; ++f
) term_array
[f
-1] = term_array
[f
];
167 for (int f
= term_count
-2; f
>= idx
; --f
) term_array
[f
+1] = term_array
[f
];
178 static void cmdDefaultFG (const char *cmdname
, char *argstr
) {
182 if (iniParseArguments(argstr
, "i{0,511}|s-", &c
, &s
) == NULL
) {
183 if (s
!= NULL
&& tolower(s
[0]) == 'g') defaultFG
= c
; else curterm
->deffg
= c
;
188 static void cmdDefaultBG (const char *cmdname
, char *argstr
) {
192 if (iniParseArguments(argstr
, "i{0,511}|s-", &c
) == NULL
) {
193 if (s
!= NULL
&& tolower(s
[0]) == 'g') {
197 XSetWindowBackground(xw
.dpy
, xw
.win
, getColor(curterm
->defbg
));
198 if (newTerm
== NULL
) {
199 k8t_tmFullDirty(curterm
);
200 k8t_drawTerm(curterm
, 1);
208 static void scrollHistory (K8Term
*term
, int delta
) {
209 if (term
== NULL
|| term
->maxhistory
< 1) return; // no history
210 term
->topline
+= delta
;
211 if (term
->topline
> term
->maxhistory
) term
->topline
= term
->maxhistory
;
212 if (term
->topline
< 0) term
->topline
= 0;
213 k8t_tmFullDirty(term
);
214 k8t_drawTerm(term
, 1);
218 static void cmdScrollHistoryLineUp (const char *cmdname
, char *argstr
) {
219 scrollHistory(curterm
, 1);
223 static void cmdScrollHistoryPageUp (const char *cmdname
, char *argstr
) {
224 scrollHistory(curterm
, curterm
->row
);
228 static void cmdScrollHistoryLineDown (const char *cmdname
, char *argstr
) {
229 scrollHistory(curterm
, -1);
233 static void cmdScrollHistoryPageDown (const char *cmdname
, char *argstr
) {
234 scrollHistory(curterm
, -curterm
->row
);
238 static void cmdScrollHistoryTop (const char *cmdname
, char *argstr
) {
239 scrollHistory(curterm
, curterm
->linecount
);
243 static void cmdScrollHistoryBottom (const char *cmdname
, char *argstr
) {
244 scrollHistory(curterm
, -curterm
->linecount
);
248 static void cmdCommandMode (const char *cmdname
, char *argstr
) {
249 if (curterm
!= NULL
) {
250 if (CMDLD(curterm
).cmdMode
== K8T_CMDMODE_NONE
) tcmdlineinit(curterm
, &CMDLD(curterm
)); else tcmdlinehide(curterm
, &CMDLD(curterm
));
256 static void cmdCursor (const char *cmdname
, char *argstr
) {
257 if (curterm
!= NULL
) {
260 if (iniParseArguments(argstr
, "s!-", &s
) != NULL
) {
261 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "cursor is %s", ((curterm
->c
.state
&K8T_CURSOR_HIDE
) ? "hidden" : "visible"));
263 if (strcasecmp(s
, "show") == 0) curterm
->c
.state
&= ~K8T_CURSOR_HIDE
;
264 else if (strcasecmp(s
, "hide") == 0) curterm
->c
.state
|= K8T_CURSOR_HIDE
;
265 k8t_tmWantRedraw(curterm
, 0);
271 static void cmdReset (const char *cmdname
, char *argstr
) {
274 if (curterm
!= NULL
) {
275 if (iniParseArguments(argstr
, "|s-", &s
) == NULL
) {
277 switch (tolower(s
[0])) {
279 k8t_tmResetMode(curterm
);
282 k8t_tmResetAttrs(curterm
);
284 case 'g': // graphics
285 curterm
->mode
&= ~(K8T_MODE_GFX0
|K8T_MODE_GFX1
);
286 curterm
->charset
= K8T_MODE_GFX0
;
289 curterm
->csaved
.state
= curterm
->c
.state
= K8T_CURSOR_DEFAULT
;
294 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "Reset (a)ll | (c)olor | (g)raphics | c(u)rsor");
300 static void cmdScreen (const char *cmdname
, char *argstr
) {
301 if (curterm
!= NULL
) {
304 if (iniParseArguments(argstr
, "s!-", &s
) != NULL
) {
305 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "screen: %s", (K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
) ? "alt" : "norm"));
307 if (strcasecmp(s
, "norm") == 0) {
308 if (K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
)) k8t_tmSwapScreen(curterm
);
309 } else if (strcasecmp(s
, "alt") == 0) {
310 if (!K8T_ISSET(curterm
, K8T_MODE_ALTSCREEN
)) k8t_tmSwapScreen(curterm
);
318 static void cmdMouseReports (const char *cmdname
, char *argstr
) {
319 if (curterm
!= NULL
) {
322 if (iniParseArguments(argstr
, "b", &b
) != NULL
) {
323 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "mouse reports are o%s", (K8T_ISSET(curterm
, K8T_MODE_MOUSE
) ? "n" : "ff"));
325 if (b
) curterm
->mode
|= K8T_MODE_MOUSEBTN
; else curterm
->mode
&= ~K8T_MODE_MOUSEBTN
;
331 static int cmd_parseIntArg (const char *fmt
, char *argstr
, int *b
, int *global
, int *toggle
) {
335 if (iniParseArguments(argstr
, "R-", &argstr
) != NULL
) break;
336 if (!argstr
[0]) break;
338 if (iniParseArguments(argstr
, "s!-R-", &s
, &argstr
) != NULL
) break;
339 if (global
&& tolower(s
[0]) == 'g') {
341 } else if (toggle
&& tolower(s
[0]) == 't') {
344 if (!b
|| iniParseArguments(s
, fmt
, b
) != NULL
) return -1;
351 static void cmdUTF8Locale (const char *cmdname
, char *argstr
) {
352 int b
= -1, toggle
= 0;
354 if (cmd_parseIntArg("b", argstr
, &b
, NULL
, &toggle
) != 0) return;
356 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "UTF8Locale: %s", ((needConversion
? !curterm
->needConv
: 1) ? "yes" : "no"));
358 if (!needConversion
) b
= 1;
359 if (curterm
!= NULL
) curterm
->needConv
= !b
;
364 static void cmdAudibleBell (const char *cmdname
, char *argstr
) {
365 int b
= -1, toggle
= 0, global
= 0;
367 if (curterm
== NULL
) return;
368 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
371 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "AudibleBell: %s", (global
? opt_audiblebell
: (curterm
->belltype
&K8T_BELL_AUDIO
)) ? "yes" : "no");
374 if (global
) opt_audiblebell
= !opt_audiblebell
; else curterm
->belltype
^= K8T_BELL_AUDIO
;
376 if (global
) opt_audiblebell
= b
; else curterm
->belltype
= (curterm
->belltype
&~K8T_BELL_AUDIO
)|(b
!=0?K8T_BELL_AUDIO
:0);
382 static void cmdUrgentBell (const char *cmdname
, char *argstr
) {
383 int b
= -1, toggle
= 0, global
= 0;
385 if (curterm
== NULL
) return;
386 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
389 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "UrgentBell: %s", (global
? opt_urgentbell
: (curterm
->belltype
&K8T_BELL_URGENT
)) ? "yes" : "no");
392 if (global
) opt_urgentbell
= !opt_urgentbell
; else curterm
->belltype
^= K8T_BELL_URGENT
;
394 if (global
) opt_urgentbell
= b
; else curterm
->belltype
= (curterm
->belltype
&~K8T_BELL_URGENT
)|(b
!=0?K8T_BELL_URGENT
:0);
400 static void cmdMonochrome (const char *cmdname
, char *argstr
) {
401 int b
= -1, global
= 0;
403 if (curterm
== NULL
) return;
404 if (cmd_parseIntArg("i{0,3}", argstr
, &b
, &global
, NULL
) != 0) return;
407 b
= (global
? globalBW
: curterm
->blackandwhite
);
408 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "Monochrome: %d", b
);
411 if (b
== 3) tcmdlinemsg(curterm
, &CMDLD(curterm
), "Monochrome-global can't be '3'!");
414 curterm
->blackandwhite
= b
;
417 k8t_tmFullDirty(curterm
);
422 static void cmdCursorBlink (const char *cmdname
, char *argstr
) {
423 int b
= -1, global
= 0;
425 if (curterm
== NULL
) return;
426 if (cmd_parseIntArg("i{0,10000}", argstr
, &b
, &global
, NULL
) != 0) return;
429 b
= (global
? opt_cursorBlink
: curterm
->curblink
);
430 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "CursorBlink: %d", b
);
435 curterm
->curblink
= b
;
436 curterm
->curbhidden
= 0;
439 k8t_tmFullDirty(curterm
);
444 static void cmdCursorBlinkInactive (const char *cmdname
, char *argstr
) {
445 int b
= -1, global
= 0, toggle
= 0, *iptr
;
447 if (curterm
== NULL
) return;
448 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
450 iptr
= (global
? &opt_cursorBlinkInactive
: &curterm
->curblinkinactive
);
452 if (toggle
) *iptr
= !(*iptr
); else *iptr
= b
;
453 k8t_drawTerm(curterm
, 0);
458 static void cmdIgnoreClose (const char *cmdname
, char *argstr
) {
461 if (curterm
== NULL
) return;
462 if (cmd_parseIntArg("i{-1,1}", argstr
, &b
, NULL
, NULL
) != 0) return;
465 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "IgnoreClose: %d", opt_ignoreclose
);
472 static void cmdMaxHistory (const char *cmdname
, char *argstr
) {
473 int b
= -1, global
= 0;
475 if (curterm
== NULL
) return;
476 if (cmd_parseIntArg("i{0,65535}", argstr
, &b
, &global
, NULL
) != 0) return;
479 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "MaxHistory: %d", (global
?opt_maxhistory
:curterm
->maxhistory
));
481 if (!global
) k8t_tmAdjMaxHistory(curterm
, b
); else opt_maxhistory
= b
;
486 static void cmdMaxDrawTimeout (const char *cmdname
, char *argstr
) {
489 if (curterm
== NULL
) return;
490 if (cmd_parseIntArg("i{100,60000}", argstr
, &b
, NULL
, NULL
) != 0) return;
493 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "MaxDrawTimeout: %d", opt_maxdrawtimeout
);
495 opt_maxdrawtimeout
= b
;
500 static void cmdSwapDrawTimeout (const char *cmdname
, char *argstr
) {
503 if (curterm
== NULL
) return;
504 if (cmd_parseIntArg("i{10,60000}", argstr
, &b
, NULL
, NULL
) != 0) return;
507 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "SwapDrawTimeout: %d", opt_swapdrawtimeout
);
509 opt_swapdrawtimeout
= b
;
514 static void cmdTabPosition (const char *cmdname
, char *argstr
) {
520 if (iniParseArguments(argstr
, "R-", &argstr
) != NULL
) break;
521 if (!argstr
[0]) break;
523 if (iniParseArguments(argstr
, "s!-R-", &s
, &argstr
) != NULL
) break;
524 if (tolower(s
[0]) == 't') newpos
= 1;
525 else if (tolower(s
[0]) == 'b') newpos
= 0;
526 else if (iniParseArguments(s
, "i{0,1}", &newpos
) != NULL
) return;
530 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabPostion: %s", (opt_tabposition
== 0 ? "bottom" : "top"));
531 } else if (opt_tabposition
!= newpos
) {
532 opt_tabposition
= newpos
;
534 k8t_tmFullDirty(curterm
);
535 k8t_drawTerm(curterm
, 1);
542 static void cmdTabCount (const char *cmdname
, char *argstr
) {
545 if (curterm
== NULL
) return;
546 if (cmd_parseIntArg("i{1,128}", argstr
, &b
, NULL
, NULL
) != 0) return;
549 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabCount: %d", opt_tabcount
);
550 } else if (opt_tabcount
!= b
) {
559 static void cmdDoFullRedraw (const char *cmdname
, char *argstr
) {
561 k8t_tmFullDirty(curterm
);
563 k8t_drawTerm(curterm
, 1);
568 static void cmdTitle (const char *cmdname
, char *argstr
) {
569 if (curterm
!= NULL
) {
572 if (iniParseArguments(argstr
, "s-", &s
) != NULL
|| s
== NULL
) return;
573 memset(curterm
->title
, 0, sizeof(curterm
->title
));
574 while (strlen(s
) > K8T_ESC_TITLE_SIZ
) k8t_UTF8ChopLast(s
);
575 fprintf(stderr
, "[%s]\n", s
);
576 strncpy(curterm
->title
, s
, K8T_ESC_TITLE_SIZ
);
577 fixWindowTitle(curterm
);
584 static void cmdFastRedraw (const char *cmdname
, char *argstr
) {
585 int b
= -1, global
= 0, toggle
= 0, *iptr
;
587 if (curterm
== NULL
) return;
588 if (cmd_parseIntArg("b", argstr
, &b
, &global
, &toggle
) != 0) return;
590 iptr
= (global
? &opt_fastredraw
: &curterm
->fastredraw
);
592 if (toggle
) *iptr
= !(*iptr
); else *iptr
= b
;
593 k8t_drawTerm(curterm
, 0);
595 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "FastRedraw: %s", (*iptr
? "yes" : "no"));
600 static void cmdAbout (const char *cmdname
, char *argstr
) {
601 if (curterm
!= NULL
) {
602 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "k8sterm " VERSION
);
607 static void cmdDebugDump (const char *cmdname
, char *argstr
) {
608 if (curterm
!= NULL
) {
611 if (iniParseArguments(argstr
, "s-", &s
) == NULL
) {
613 switch (tolower(s
[0])) {
616 curterm
->dumpescapes
= 0;
617 curterm
->dumpeskeys
= 0;
620 curterm
->dumpescapes
= 1;
621 curterm
->dumpeskeys
= 1;
624 curterm
->dumpescapes
= !curterm
->dumpescapes
;
627 curterm
->dumpeskeys
= !curterm
->dumpeskeys
;
632 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "DbgDump (n)one | (a)ll | toggle (e)scapes | toggle extended (k)eys");
641 static void cmdTabEllipsis (const char *cmdname
, char *argstr
) {
644 if (curterm
== NULL
) return;
645 if (cmd_parseIntArg("i{0,3}", argstr
, &b
, NULL
, NULL
) != 0) return;
648 if (opt_tabellipsis
!= b
) {
654 tcmdlinemsgf(curterm
, &CMDLD(curterm
), "TabEllipsis: %d", opt_tabellipsis
);
659 static const Command commandList
[] = {
660 {"PastePrimary", cmdPastePrimary
},
661 {"PasteSecondary", cmdPasteSecondary
},
662 {"PasteClipboard", cmdPasteClipboard
},
664 {"NewTab", cmdNewTab
}, // 'noswitch' 'next' 'prev' 'first' 'last'
665 {"CloseTab", cmdCloseTab
},
666 {"KillTab", cmdKillTab
},
667 {"SwitchToTab", cmdSwitchToTab
}, // 'next' 'prev' 'first' 'last' 'nowrap' 'wrap'
668 {"MoveTabTo", cmdMoveTabTo
}, // 'next' 'prev' 'first' 'last' 'nowrap' 'wrap'
669 {"DefaultFG", cmdDefaultFG
},
670 {"DefaultBG", cmdDefaultBG
},
671 {"ScrollHistoryLineUp", cmdScrollHistoryLineUp
},
672 {"ScrollHistoryPageUp", cmdScrollHistoryPageUp
},
673 {"ScrollHistoryLineDown", cmdScrollHistoryLineDown
},
674 {"ScrollHistoryPageDown", cmdScrollHistoryPageDown
},
675 {"ScrollHistoryTop", cmdScrollHistoryTop
},
676 {"ScrollHistoryBottom", cmdScrollHistoryBottom
},
677 {"UTF8Locale", cmdUTF8Locale
}, // 'on', 'off'
678 {"AudibleBell", cmdAudibleBell
},
679 {"UrgentBell", cmdUrgentBell
},
680 {"CommandMode", cmdCommandMode
},
681 {"Cursor", cmdCursor
},
683 {"Screen", cmdScreen
},
684 {"MouseReports", cmdMouseReports
},
685 {"Monochrome", cmdMonochrome
},
686 {"Mono", cmdMonochrome
},
687 {"CursorBlink", cmdCursorBlink
},
688 {"CursorBlinkInactive", cmdCursorBlinkInactive
},
689 {"IgnoreClose", cmdIgnoreClose
},
690 {"MaxHistory", cmdMaxHistory
},
691 {"MaxDrawTimeout", cmdMaxDrawTimeout
},
692 {"SwapDrawTimeout", cmdSwapDrawTimeout
},
693 {"TabPosition", cmdTabPosition
},
694 {"TabCount", cmdTabCount
},
695 {"DoFullRedraw", cmdDoFullRedraw
},
697 {"FastRedraw", cmdFastRedraw
},
698 {"TabEllipsis", cmdTabEllipsis
},
705 {"DbgDump", cmdDebugDump
},
709 {"term", cmdTermName},
710 {"title", cmdWinTitle},
711 {"tabsize", cmdTabSize},
712 {"defaultcursorfg", cmdDefaultCursorFG},
713 {"defaultcursorbg", cmdDefaultCursorBG},
714 {"defaultinactivecursorfg", cmdDefaultInactiveCursorFG},
715 {"defaultinactivecursorbg", cmdDefaultInactiveCursorBG},
716 {"defaultboldfg", cmdDefaultBoldFG},
717 {"defaultunderlinefg", cmdDefaultUnderlineFG},
723 static const char *findCommandCompletion (const char *str
, int slen
, const char *prev
) {
724 const char *res
= NULL
;
727 if (slen
< 1) return NULL
;
728 for (int f
= 0; commandList
[f
].name
!= NULL
; ++f
) {
729 if (strlen(commandList
[f
].name
) >= slen
&& strncasecmp(commandList
[f
].name
, str
, slen
) == 0) {
730 if (prev
== NULL
|| phit
) return commandList
[f
].name
;
731 if (strcasecmp(commandList
[f
].name
, prev
) == 0) phit
= 1;
732 if (res
== NULL
) res
= commandList
[f
].name
;
739 // !0: NewTab command
740 static int executeCommand (const char *str
, int slen
) {
745 if (str
== NULL
) return 0;
746 if (slen
< 0) slen
= strlen(str
);
748 for (int f
= 0; f
< slen
; ++f
) if (!str
[f
]) { slen
= f
; break; }
750 while (slen
> 0 && isspace(*str
)) { ++str
; --slen
; }
751 if (slen
< 1 || !str
[0]) return 0;
753 for (e
= str
; slen
> 0 && !isspace(*e
); ++e
, --slen
) ;
755 if (e
-str
> 127) return 0;
756 cmdname
= alloca(e
-str
+8);
757 if (cmdname
== NULL
) return 0;
758 memcpy(cmdname
, str
, e
-str
);
760 if (opt_disabletabs
&& strcasecmp(cmdname
, "NewTab") == 0) return 1;
762 while (slen
> 0 && isspace(*e
)) { ++e
; --slen
; }
763 //FIXME: ugly copypaste!
765 for (int f
= 0; commandList
[f
].name
!= NULL
; ++f
) {
766 if (strcasecmp(commandList
[f
].name
, cmdname
) == 0 && commandList
[f
].fn
!= NULL
) {
767 char *left
= calloc(slen
+2, 1);
770 if (slen
> 0) memcpy(left
, e
, slen
);
771 //fprintf(stderr, "command: [%s]; args: [%s]\n", cmdname, left);
772 commandList
[f
].fn(cmdname
, left
);
781 char *left
= calloc(slen
+2, 1);
784 if (slen
> 0) memcpy(left
, e
, slen
);
785 processMiscCmds(cmdname
, left
);
795 static const char *cmdpSkipStr (const char *str) {
796 while (*str && isspace(*str)) ++str;
797 if (str[0] && str[0] != ';') {
801 if (*str == ';' && qch == ' ') break;
802 if (qch != ' ' && *str == qch) { qch = ' '; ++str; continue; }
803 if (*str == '"' || *str == '\'') {
804 if (qch == ' ') qch = *str;
808 if (*str++ == '\\' && *str) ++str;
816 static void executeCommands (const char *str
) {
818 oldTermIdx
= termidx
;
821 if (str
== NULL
) return;
826 while (*str
&& isspace(*str
)) ++str
;
828 if (*str
== ';') { ++str
; continue; }
833 if (*ce
== ';' && qch
== ' ') break;
834 if (qch
!= ' ' && *ce
== qch
) { qch
= ' '; ++ce
; continue; }
835 if (*ce
== '"' || *ce
== '\'') {
836 if (qch
== ' ') qch
= *ce
;
840 if (*ce
++ == '\\' && *ce
) ++ce
;
843 if (executeCommand(str
, ce
-str
)) break;
844 if (*ce
) str
= ce
+1; else break;
847 switchToTerm(oldTermIdx
, 1);