1 ////////////////////////////////////////////////////////////////////////////////
2 static void tcmdlinedirty (K8Term
*term
, K8TCmdLine
*cmdline
) {
4 k8t_tmDirtyMark(term
, term
->row
-term
->topline
-1, 2);
5 k8t_tmWantRedraw(term
, 1);
10 static void tcmdlinefixofs (K8Term
*term
, K8TCmdLine
*cmdline
) {
13 len
= k8t_UTF8strlen(cmdline
->cmdline
);
14 ofs
= len
-(term
->col
-1);
16 for (cmdline
->cmdofs
= 0; ofs
> 0; --ofs
) cmdline
->cmdofs
+= k8t_UTF8Size(cmdline
->cmdline
+cmdline
->cmdofs
);
17 tcmdlinedirty(term
, cmdline
);
21 static void tcmdlinehide (K8Term
*term
, K8TCmdLine
*cmdline
) {
22 cmdline
->cmdMode
= K8T_CMDMODE_NONE
;
23 cmdline
->cmdcurtabc
= NULL
;
24 tcmdlinedirty(term
, cmdline
);
29 static void tcmdlinemsg (K8Term
*term
, K8TCmdLine
*cmdline
, const char *msg
) {
33 cmdline
->cmdMode
= K8T_CMDMODE_MESSAGE
;
35 cmdline
->cmdtabpos
= -1;
36 cmdline
->cmdcurtabc
= NULL
;
39 int len
= k8t_UTF8Size(msg
);
41 if (len
< 1 || ofs
+len
>= sizeof(cmdline
->cmdline
)-1) break;
42 memcpy(cmdline
->cmdline
+ofs
, msg
, len
);
47 cmdline
->cmdline
[ofs
] = 0;
48 tcmdlinedirty(term
, cmdline
);
53 static __attribute__((format(printf
,3,4))) void tcmdlinemsgf (K8Term
*term
, K8TCmdLine
*cmdline
, const char *fmt
, ...) {
56 int size
= sizeof(buf
)-1;
64 n
= vsnprintf(xbuf
, size
, fmt
, ap
);
66 if (n
> -1 && n
< size
) break;
67 if (n
> -1) size
= n
+1; else size
+= 4096;
68 if (xbuf
== buf
) xbuf
= NULL
;
69 if ((t
= realloc(xbuf
, size
)) == NULL
) { if (xbuf
) free(xbuf
); return; }
72 tcmdlinemsg(term
, cmdline
, xbuf
);
73 if (xbuf
!= buf
) free(xbuf
);
77 static void tcmdlineinitex (K8Term
*term
, K8TCmdLine
*cmdline
, const char *msg
) {
78 cmdline
->cmdMode
= K8T_CMDMODE_INPUT
;
80 cmdline
->cmdline
[0] = 0;
83 cmdline
->cmdtabpos
= -1;
84 cmdline
->cmdcurtabc
= NULL
;
85 cmdline
->cmdreslen
= 0;
86 cmdline
->cmdexecfn
= NULL
;
87 if (msg
!= NULL
&& msg
[0]) {
88 strcpy(cmdline
->cmdline
, msg
);
89 cmdline
->cmdreslen
= strlen(cmdline
->cmdline
);
91 tcmdlinefixofs(term
, cmdline
);
95 static void tcmdlineinit (K8Term
*term
, K8TCmdLine
*cmdline
) {
96 tcmdlineinitex(term
, cmdline
, NULL
);
100 static void tcmdlinechoplast (K8Term
*term
, K8TCmdLine
*cmdline
) {
101 if (cmdline
->cmdcl
!= 0) {
104 if (strlen(cmdline
->cmdline
) > cmdline
->cmdreslen
) k8t_UTF8ChopLast(cmdline
->cmdline
);
106 tcmdlinefixofs(term
, cmdline
);
111 static void tcmdaddchar (K8Term
*term
, K8TCmdLine
*cmdline
, const char *s
) {
112 int len
= k8t_UTF8Size(s
);
115 int slen
= strlen(cmdline
->cmdline
);
117 if (slen
+len
< sizeof(cmdline
->cmdline
)) {
118 memcpy(cmdline
->cmdline
+slen
, s
, len
);
119 cmdline
->cmdline
[slen
+len
] = 0;
120 tcmdlinefixofs(term
, cmdline
);
126 static void tcmdput (K8Term
*term
, K8TCmdLine
*cmdline
, const char *s
, int len
) {
130 cmdline
->cmdc
[cmdline
->cmdcl
++] = *s
++;
131 cmdline
->cmdc
[cmdline
->cmdcl
] = 0;
133 if ((ok
= k8t_UTF8IsFull(cmdline
->cmdc
, cmdline
->cmdcl
)) != 0 || cmdline
->cmdcl
== K8T_UTF_SIZ
) {
134 if (ok
) tcmdaddchar(term
, cmdline
, cmdline
->cmdc
);
141 ////////////////////////////////////////////////////////////////////////////////
142 // return !0 if event was eaten
143 static int tcmdlProcessKeys (K8Term
*term
, K8TCmdLine
*cmdline
, KeySym ksym
, const char *ksbuf
, int ksbuflen
, XKeyEvent
*e
) {
144 int mode
= cmdline
->cmdMode
;
148 if (cmdline
->cmdline
[0] && !(e
->state
&(Mod1Mask
|ShiftMask
)) && (e
->state
&ControlMask
)) {
150 if (lastSelStr
!= NULL
) free(lastSelStr
);
151 lastSelStr
= strdup(cmdline
->cmdline
);
156 tcmdlinehide(term
, cmdline
);
157 if (cmdline
->cmdexecfn
!= NULL
) cmdline
->cmdexecfn(term
, cmdline
, 0);
158 else if (mode
== K8T_CMDMODE_INPUT
) executeCommands(cmdline
->cmdline
);
161 if (mode
== K8T_CMDMODE_INPUT
) {
162 tcmdlinechoplast(term
, cmdline
);
163 cmdline
->cmdtabpos
= -1;
164 cmdline
->cmdcurtabc
= NULL
;
166 tcmdlinehide(term
, cmdline
);
167 if (cmdline
->cmdexecfn
!= NULL
) cmdline
->cmdexecfn(term
, cmdline
, 1);
171 tcmdlinehide(term
, cmdline
);
172 if (cmdline
->cmdexecfn
!= NULL
) cmdline
->cmdexecfn(term
, cmdline
, 1);
175 if (mode
== K8T_CMDMODE_INPUT
&& cmdline
->cmdline
[0] && cmdline
->cmdcl
== 0 && cmdline
->cmdexecfn
== NULL
) {
178 if (cmdline
->cmdtabpos
< 0) {
179 cmdline
->cmdtabpos
= 0;
180 while (cmdline
->cmdline
[cmdline
->cmdtabpos
] && isalnum(cmdline
->cmdline
[cmdline
->cmdtabpos
])) ++cmdline
->cmdtabpos
;
181 if (cmdline
->cmdline
[cmdline
->cmdtabpos
]) {
182 cmdline
->cmdtabpos
= -1;
185 cmdline
->cmdcurtabc
= NULL
;
187 cpl
= findCommandCompletion(cmdline
->cmdline
, cmdline
->cmdtabpos
, cmdline
->cmdcurtabc
);
188 if (cpl
== NULL
&& cmdline
->cmdcurtabc
!= NULL
) cpl
= findCommandCompletion(cmdline
->cmdline
, cmdline
->cmdtabpos
, NULL
);
189 cmdline
->cmdcurtabc
= cpl
;
190 if (cpl
!= NULL
) { strcpy(cmdline
->cmdline
, cpl
); tcmdaddchar(term
, cmdline
, " "); }
191 tcmdlinefixofs(term
, cmdline
);
192 } else if (mode
!= K8T_CMDMODE_INPUT
) {
193 tcmdlinehide(term
, cmdline
);
194 if (cmdline
->cmdexecfn
!= NULL
) cmdline
->cmdexecfn(term
, cmdline
, 1);
198 if (mode
!= K8T_CMDMODE_INPUT
) {
199 tcmdlinehide(term
, cmdline
);
204 if (mode
== K8T_CMDMODE_INPUT
) {
205 if (ksbuflen
> 0 && (unsigned char)ksbuf
[0] >= 32) {
206 tcmdput(term
, cmdline
, ksbuf
, ksbuflen
);
207 cmdline
->cmdtabpos
= -1;
208 cmdline
->cmdcurtabc
= NULL
;
214 return 1; // eat any event