cursor.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2019 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  19. ******************************************************************************/
  20. /******************************************************************************
  21. * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
  22. * *
  23. * coded by Igor van den Hoven 2006 *
  24. ******************************************************************************/
  25. #include "tintin.h"
  26. DO_COMMAND(do_cursor)
  27. {
  28. char all[BUFFER_SIZE], arg1[BUFFER_SIZE], right[BUFFER_SIZE], temp[BUFFER_SIZE];
  29. int cnt;
  30. get_arg_in_braces(ses, arg, all, GET_ALL);
  31. arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
  32. arg = sub_arg_in_braces(ses, arg, right, GET_ALL, SUB_VAR|SUB_FUN);
  33. if (*arg1 == 0)
  34. {
  35. tintin_header(ses, " CURSOR OPTIONS ");
  36. for (cnt = 0 ; *cursor_table[cnt].fun ; cnt++)
  37. {
  38. if (*cursor_table[cnt].name)
  39. {
  40. convert_meta(cursor_table[cnt].code, temp, FALSE);
  41. tintin_printf2(ses, " [%-18s] [%-6s] %s", cursor_table[cnt].name, temp, cursor_table[cnt].desc);
  42. }
  43. }
  44. tintin_header(ses, "");
  45. }
  46. else
  47. {
  48. for (cnt = 0 ; ; cnt++)
  49. {
  50. if (HAS_BIT(cursor_table[cnt].flags, CURSOR_FLAG_GET_ALL))
  51. {
  52. if (is_abbrev(all, cursor_table[cnt].name))
  53. {
  54. cursor_table[cnt].fun(ses, right);
  55. return ses;
  56. }
  57. }
  58. else if (HAS_BIT(cursor_table[cnt].flags, CURSOR_FLAG_GET_ONE))
  59. {
  60. if (is_abbrev(arg1, cursor_table[cnt].name))
  61. {
  62. cursor_table[cnt].fun(ses, right);
  63. return ses;
  64. }
  65. }
  66. else
  67. {
  68. break;
  69. }
  70. }
  71. show_error(ses, LIST_COMMAND, "#ERROR: #CURSOR {%s} IS NOT A VALID OPTION.", capitalize(all));
  72. }
  73. return ses;
  74. }
  75. int inputline_str_str_len(int start, int end)
  76. {
  77. int raw_cnt, str_cnt, ret_cnt, width;
  78. raw_cnt = str_cnt = ret_cnt = 0;
  79. while (raw_cnt < gtd->input_len)
  80. {
  81. if (str_cnt >= end)
  82. {
  83. break;
  84. }
  85. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(&gtd->input_buf[raw_cnt]))
  86. {
  87. raw_cnt += get_utf8_width(&gtd->input_buf[raw_cnt], &width);
  88. if (str_cnt >= start)
  89. {
  90. ret_cnt += width;
  91. }
  92. str_cnt += width;
  93. }
  94. else
  95. {
  96. if (str_cnt >= start)
  97. {
  98. ret_cnt++;
  99. }
  100. raw_cnt++;
  101. str_cnt++;
  102. }
  103. }
  104. return ret_cnt;
  105. }
  106. // raw range
  107. int inputline_raw_str_len(int start, int end)
  108. {
  109. int raw_cnt, ret_cnt, width;
  110. raw_cnt = start;
  111. ret_cnt = 0;
  112. while (raw_cnt < gtd->input_len)
  113. {
  114. if (raw_cnt >= end)
  115. {
  116. break;
  117. }
  118. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(&gtd->input_buf[raw_cnt]))
  119. {
  120. raw_cnt += get_utf8_width(&gtd->input_buf[raw_cnt], &width);
  121. ret_cnt += width;
  122. }
  123. else
  124. {
  125. raw_cnt++;
  126. ret_cnt++;
  127. }
  128. }
  129. return ret_cnt;
  130. }
  131. // display range
  132. int inputline_str_raw_len(int start, int end)
  133. {
  134. int raw_cnt, str_cnt, ret_cnt, width, tmp_cnt;
  135. raw_cnt = str_cnt = ret_cnt = 0;
  136. while (raw_cnt < gtd->input_len)
  137. {
  138. if (str_cnt >= end)
  139. {
  140. break;
  141. }
  142. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(&gtd->input_buf[raw_cnt]))
  143. {
  144. tmp_cnt = get_utf8_width(&gtd->input_buf[raw_cnt], &width);
  145. if (str_cnt >= start)
  146. {
  147. ret_cnt += tmp_cnt;
  148. }
  149. raw_cnt += tmp_cnt;
  150. str_cnt += width;
  151. }
  152. else
  153. {
  154. if (str_cnt >= start)
  155. {
  156. ret_cnt++;
  157. }
  158. raw_cnt++;
  159. str_cnt++;
  160. }
  161. }
  162. return ret_cnt;
  163. }
  164. int inputline_raw_raw_len(int start, int end)
  165. {
  166. if (start > end)
  167. {
  168. return 0;
  169. }
  170. return end - start;
  171. }
  172. // Get string length of the input area
  173. int inputline_max_str_len(void)
  174. {
  175. return gtd->screen->cols + 1 - gtd->input_off - (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH) ? 11 : 0);
  176. }
  177. int inputline_cur_str_len(void)
  178. {
  179. return inputline_str_str_len(gtd->input_hid, gtd->input_hid + inputline_max_str_len());
  180. }
  181. // Get the position of the cursor
  182. int inputline_cur_pos(void)
  183. {
  184. return gtd->input_off + gtd->input_pos - gtd->input_hid;
  185. }
  186. // Check for invalid characters.
  187. int inputline_str_chk(int offset, int totlen)
  188. {
  189. int size;
  190. while (offset < totlen)
  191. {
  192. if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_BIG5))
  193. {
  194. if (HAS_BIT(gtd->input_buf[offset], 128) && (unsigned char) gtd->input_buf[offset] < 255)
  195. {
  196. if (offset + 1 >= totlen)
  197. {
  198. return FALSE;
  199. }
  200. if (is_big5(&gtd->input_buf[offset]))
  201. {
  202. offset += 2;
  203. }
  204. else
  205. {
  206. offset += 1;
  207. }
  208. }
  209. else
  210. {
  211. offset += 1;
  212. }
  213. }
  214. else if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8))
  215. {
  216. if (is_utf8_head(&gtd->input_buf[offset]))
  217. {
  218. size = get_utf8_size(&gtd->input_buf[offset]);
  219. if (size == 1 || offset + size > totlen)
  220. {
  221. return FALSE;
  222. }
  223. offset += size;
  224. }
  225. else
  226. {
  227. offset += 1;
  228. }
  229. }
  230. else
  231. {
  232. return TRUE;
  233. }
  234. }
  235. return TRUE;
  236. }
  237. DO_CURSOR(cursor_backspace)
  238. {
  239. if (gtd->input_cur == 0)
  240. {
  241. return;
  242. }
  243. cursor_left(ses, "");
  244. cursor_delete(ses, "");
  245. modified_input();
  246. }
  247. DO_CURSOR(cursor_brace_open)
  248. {
  249. ins_sprintf(&gtd->input_buf[gtd->input_cur], "{");
  250. gtd->input_len++;
  251. gtd->input_cur++;
  252. gtd->input_pos += inputline_raw_str_len(gtd->input_cur - 1, gtd->input_cur);
  253. cursor_redraw_line(ses, "");
  254. modified_input();
  255. }
  256. DO_CURSOR(cursor_brace_close)
  257. {
  258. ins_sprintf(&gtd->input_buf[gtd->input_cur], "}");
  259. gtd->input_len++;
  260. gtd->input_cur++;
  261. gtd->input_pos += inputline_raw_str_len(gtd->input_cur - 1, gtd->input_cur);
  262. cursor_redraw_line(ses, "");
  263. modified_input();
  264. }
  265. DO_CURSOR(cursor_buffer_down)
  266. {
  267. do_buffer(ses, "DOWN");
  268. }
  269. DO_CURSOR(cursor_buffer_end)
  270. {
  271. do_buffer(ses, "END");
  272. }
  273. DO_CURSOR(cursor_buffer_home)
  274. {
  275. do_buffer(ses, "HOME");
  276. }
  277. DO_CURSOR(cursor_buffer_lock)
  278. {
  279. do_buffer(ses, "LOCK");
  280. }
  281. DO_CURSOR(cursor_buffer_up)
  282. {
  283. do_buffer(ses, "UP");
  284. }
  285. DO_CURSOR(cursor_check_line)
  286. {
  287. if (gtd->input_pos - gtd->input_hid > inputline_max_str_len() - 3)
  288. {
  289. return cursor_redraw_line(ses, "");
  290. }
  291. if (gtd->input_hid && gtd->input_pos - gtd->input_hid < 2)
  292. {
  293. return cursor_redraw_line(ses, "");
  294. }
  295. }
  296. DO_CURSOR(cursor_check_line_modified)
  297. {
  298. if (gtd->input_hid + inputline_max_str_len() < inputline_raw_str_len(0, gtd->input_len))
  299. {
  300. return cursor_redraw_line(ses, "");
  301. }
  302. return cursor_check_line(ses, "");
  303. }
  304. DO_CURSOR(cursor_clear_left)
  305. {
  306. if (gtd->input_cur == 0)
  307. {
  308. return;
  309. }
  310. sprintf(gtd->paste_buf, "%.*s", gtd->input_cur, gtd->input_buf);
  311. input_printf("\e[%dG\e[%dP", gtd->input_off, gtd->input_pos - gtd->input_hid);
  312. memmove(&gtd->input_buf[0], &gtd->input_buf[gtd->input_cur], gtd->input_len - gtd->input_cur);
  313. gtd->input_len -= gtd->input_cur;
  314. gtd->input_buf[gtd->input_len] = 0;
  315. gtd->input_cur = 0;
  316. gtd->input_pos = 0;
  317. cursor_check_line_modified(ses, "");
  318. modified_input();
  319. }
  320. DO_CURSOR(cursor_clear_line)
  321. {
  322. if (gtd->input_len == 0)
  323. {
  324. return;
  325. }
  326. sprintf(gtd->paste_buf, "%s", gtd->input_buf);
  327. input_printf("\e[%dG\e[%dP", gtd->input_off, inputline_cur_str_len());
  328. gtd->input_len = 0;
  329. gtd->input_cur = 0;
  330. gtd->input_hid = 0;
  331. gtd->input_pos = 0;
  332. gtd->input_buf[0] = 0;
  333. modified_input();
  334. }
  335. DO_CURSOR(cursor_clear_right)
  336. {
  337. if (gtd->input_cur == gtd->input_len)
  338. {
  339. return;
  340. }
  341. strcpy(gtd->paste_buf, &gtd->input_buf[gtd->input_cur]);
  342. input_printf("\e[%dP", inputline_max_str_len() - inputline_str_str_len(gtd->input_hid, gtd->input_pos));
  343. gtd->input_buf[gtd->input_cur] = 0;
  344. gtd->input_len = gtd->input_cur;
  345. modified_input();
  346. }
  347. DO_CURSOR(cursor_convert_meta)
  348. {
  349. SET_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR);
  350. }
  351. DO_CURSOR(cursor_delete_or_exit)
  352. {
  353. if (gtd->input_len == 0)
  354. {
  355. cursor_exit(ses, "");
  356. }
  357. else
  358. {
  359. cursor_delete(ses, "");
  360. }
  361. }
  362. DO_CURSOR(cursor_delete)
  363. {
  364. int size, width;
  365. if (gtd->input_len == 0)
  366. {
  367. return;
  368. }
  369. if (gtd->input_len == gtd->input_cur)
  370. {
  371. return;
  372. }
  373. if (HAS_BIT(ses->charset, CHARSET_FLAG_BIG5) && is_big5(&gtd->input_buf[gtd->input_cur]))
  374. {
  375. gtd->input_len--;
  376. memmove(&gtd->input_buf[gtd->input_cur+1], &gtd->input_buf[gtd->input_cur+2], gtd->input_len - gtd->input_cur + 1);
  377. input_printf("\e[2P");
  378. }
  379. else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
  380. {
  381. size = get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  382. gtd->input_len -= size;
  383. memmove(&gtd->input_buf[gtd->input_cur], &gtd->input_buf[gtd->input_cur + size], gtd->input_len - gtd->input_cur + 1);
  384. if (width)
  385. {
  386. input_printf("\e[%dP", width);
  387. }
  388. while (gtd->input_len > gtd->input_cur)
  389. {
  390. size = get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  391. if (width)
  392. {
  393. break;
  394. }
  395. gtd->input_len -= size;
  396. memmove(&gtd->input_buf[gtd->input_cur], &gtd->input_buf[gtd->input_cur + size], gtd->input_len - gtd->input_cur + 1);
  397. }
  398. }
  399. else
  400. {
  401. gtd->input_len--;
  402. memmove(&gtd->input_buf[gtd->input_cur], &gtd->input_buf[gtd->input_cur+1], gtd->input_len - gtd->input_cur + 1);
  403. input_printf("\e[1P");
  404. }
  405. if (gtd->input_hid + inputline_max_str_len() <= inputline_raw_str_len(0, gtd->input_len))
  406. {
  407. cursor_redraw_line(ses, "");
  408. }
  409. modified_input();
  410. }
  411. DO_CURSOR(cursor_delete_word_left)
  412. {
  413. int index_cur, width;
  414. if (gtd->input_cur == 0)
  415. {
  416. return;
  417. }
  418. index_cur = gtd->input_cur;
  419. while (gtd->input_cur > 0 && gtd->input_buf[gtd->input_cur - 1] == ' ')
  420. {
  421. gtd->input_pos--;
  422. gtd->input_cur--;
  423. }
  424. while (gtd->input_cur > 0 && gtd->input_buf[gtd->input_cur - 1] != ' ')
  425. {
  426. if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
  427. {
  428. if (is_utf8_tail(&gtd->input_buf[gtd->input_cur]))
  429. {
  430. gtd->input_cur--;
  431. }
  432. else if (is_utf8_head(&gtd->input_buf[gtd->input_cur]))
  433. {
  434. get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  435. gtd->input_cur -= 1;
  436. gtd->input_pos -= width;
  437. }
  438. else
  439. {
  440. gtd->input_cur--;
  441. gtd->input_pos--;
  442. }
  443. }
  444. else
  445. {
  446. gtd->input_pos--;
  447. gtd->input_cur--;
  448. }
  449. }
  450. sprintf(gtd->paste_buf, "%.*s", index_cur - gtd->input_cur, &gtd->input_buf[gtd->input_cur]);
  451. memmove(&gtd->input_buf[gtd->input_cur], &gtd->input_buf[index_cur], gtd->input_len - index_cur + 1);
  452. // input_printf("\e[%dD\e[%dP", index_cur - gtd->input_cur, index_cur - gtd->input_cur);
  453. gtd->input_len -= index_cur - gtd->input_cur;
  454. cursor_redraw_line(ses, "");
  455. modified_input();
  456. }
  457. DO_CURSOR(cursor_delete_word_right)
  458. {
  459. int index_cur;
  460. if (gtd->input_cur == gtd->input_len)
  461. {
  462. return;
  463. }
  464. index_cur = gtd->input_cur;
  465. while (gtd->input_cur != gtd->input_len && gtd->input_buf[gtd->input_cur] == ' ')
  466. {
  467. gtd->input_cur++;
  468. }
  469. while (gtd->input_cur != gtd->input_len && gtd->input_buf[gtd->input_cur] != ' ')
  470. {
  471. gtd->input_cur++;
  472. }
  473. sprintf(gtd->paste_buf, "%.*s", gtd->input_cur - index_cur, &gtd->input_buf[gtd->input_cur]);
  474. memmove(&gtd->input_buf[index_cur], &gtd->input_buf[gtd->input_cur], gtd->input_len - gtd->input_cur + 1);
  475. // input_printf("\e[%dP", gtd->input_cur - index_cur);
  476. gtd->input_len -= gtd->input_cur - index_cur;
  477. gtd->input_cur = index_cur;
  478. cursor_redraw_line(ses, "");
  479. modified_input();
  480. }
  481. DO_CURSOR(cursor_echo)
  482. {
  483. if (*arg == 0)
  484. {
  485. TOG_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  486. }
  487. else if (!strcasecmp(arg, "ON"))
  488. {
  489. SET_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  490. }
  491. else if (!strcasecmp(arg, "OFF"))
  492. {
  493. DEL_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  494. }
  495. else
  496. {
  497. show_error(gtd->ses, LIST_COMMAND, "#SYNTAX: #CURSOR {ECHO} {ON|OFF}.");
  498. }
  499. }
  500. DO_CURSOR(cursor_end)
  501. {
  502. gtd->input_cur = gtd->input_len;
  503. gtd->input_pos = inputline_raw_str_len(0, gtd->input_len);
  504. cursor_redraw_line(ses, "");
  505. }
  506. DO_CURSOR(cursor_enter)
  507. {
  508. input_printf("\n");
  509. gtd->input_buf[gtd->input_len] = 0;
  510. gtd->input_len = 0;
  511. gtd->input_cur = 0;
  512. gtd->input_pos = 0;
  513. gtd->input_off = 1;
  514. gtd->input_hid = 0;
  515. gtd->macro_buf[0] = 0;
  516. gtd->input_tmp[0] = 0;
  517. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  518. {
  519. struct listroot *root = ses->list[LIST_HISTORY];
  520. if (root->update >= 0 && root->update < root->used)
  521. {
  522. strcpy(gtd->input_buf, root->list[root->update]->arg1);
  523. }
  524. DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH);
  525. gtd->input_off = 1;
  526. }
  527. SET_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT);
  528. modified_input();
  529. }
  530. DO_CURSOR(cursor_exit)
  531. {
  532. if (ses == gts)
  533. {
  534. do_end(ses, "");
  535. }
  536. else
  537. {
  538. cleanup_session(ses);
  539. }
  540. }
  541. DO_CURSOR(cursor_get)
  542. {
  543. if (*arg == 0)
  544. {
  545. show_error(ses, LIST_COMMAND, "#SYNTAX: #CURSOR GET {variable}");
  546. }
  547. else
  548. {
  549. set_nest_node(ses->list[LIST_VARIABLE], arg, "%s", gtd->input_buf);
  550. }
  551. }
  552. DO_CURSOR(cursor_history_next)
  553. {
  554. struct listroot *root = ses->list[LIST_HISTORY];
  555. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  556. {
  557. if (root->update == root->used)
  558. {
  559. return;
  560. }
  561. for (root->update++ ; root->update < root->used ; root->update++)
  562. {
  563. if (*gtd->input_buf && find(ses, root->list[root->update]->arg1, gtd->input_buf, SUB_NONE, REGEX_FLAG_NONE))
  564. {
  565. break;
  566. }
  567. }
  568. if (root->update < root->used)
  569. {
  570. input_printf("\e[%dG \e[0K%.*s\e[%dG", gtd->input_off + inputline_cur_str_len() + 2, gtd->input_off + inputline_max_str_len() - inputline_cur_str_len() - 4, root->list[root->update]->arg1, gtd->input_off + gtd->input_pos - gtd->input_hid);
  571. }
  572. return;
  573. }
  574. if (root->list[0] == NULL)
  575. {
  576. return;
  577. }
  578. if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE))
  579. {
  580. return;
  581. }
  582. else if (root->update < root->used)
  583. {
  584. for (root->update++ ; root->update < root->used ; root->update++)
  585. {
  586. if (!strncmp(gtd->input_tmp, root->list[root->update]->arg1, strlen(gtd->input_tmp)))
  587. {
  588. break;
  589. }
  590. }
  591. }
  592. cursor_clear_line(ses, "");
  593. if (root->update == root->used)
  594. {
  595. strcpy(gtd->input_buf, gtd->input_tmp);
  596. }
  597. else
  598. {
  599. strcpy(gtd->input_buf, root->list[root->update]->arg1);
  600. }
  601. gtd->input_len = strlen(gtd->input_buf);
  602. cursor_end(ses, "");
  603. SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE);
  604. }
  605. DO_CURSOR(cursor_history_prev)
  606. {
  607. struct listroot *root = ses->list[LIST_HISTORY];
  608. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  609. {
  610. if (root->update <= 0)
  611. {
  612. return;
  613. }
  614. for (root->update-- ; root->update >= 0 ; root->update--)
  615. {
  616. if (*gtd->input_buf && find(ses, root->list[root->update]->arg1, gtd->input_buf, SUB_NONE, REGEX_FLAG_NONE))
  617. {
  618. break;
  619. }
  620. }
  621. if (root->update >= 0)
  622. {
  623. input_printf("\e[%dG \e[0K%.*s\e[%dG", gtd->input_off + inputline_cur_str_len() + 2, gtd->input_off + inputline_max_str_len() - inputline_cur_str_len() - 4, root->list[root->update]->arg1, gtd->input_off + gtd->input_pos - gtd->input_hid);
  624. }
  625. return;
  626. }
  627. if (root->list[0] == NULL)
  628. {
  629. return;
  630. }
  631. if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE))
  632. {
  633. strcpy(gtd->input_tmp, gtd->input_buf);
  634. for (root->update = root->used - 1 ; root->update >= 0 ; root->update--)
  635. {
  636. if (!strncmp(gtd->input_tmp, root->list[root->update]->arg1, strlen(gtd->input_tmp)))
  637. {
  638. break;
  639. }
  640. }
  641. }
  642. else if (root->update >= 0)
  643. {
  644. for (root->update-- ; root->update >= 0 ; root->update--)
  645. {
  646. if (!strncmp(gtd->input_tmp, root->list[root->update]->arg1, strlen(gtd->input_tmp)))
  647. {
  648. break;
  649. }
  650. }
  651. }
  652. cursor_clear_line(ses, "");
  653. if (root->update == -1)
  654. {
  655. strcpy(gtd->input_buf, gtd->input_tmp);
  656. }
  657. else
  658. {
  659. strcpy(gtd->input_buf, root->list[root->update]->arg1);
  660. }
  661. gtd->input_len = strlen(gtd->input_buf);
  662. cursor_end(ses, "");
  663. SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE);
  664. }
  665. DO_CURSOR(cursor_history_search)
  666. {
  667. struct listroot *root = ses->list[LIST_HISTORY];
  668. if (root->list[0] == NULL)
  669. {
  670. return;
  671. }
  672. if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  673. {
  674. strcpy(gtd->input_tmp, gtd->input_buf);
  675. cursor_clear_line(ses, "");
  676. SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH);
  677. gtd->input_off = 11;
  678. root->update = root->used - 1;
  679. input_printf("(search) [ ] \e[3D");
  680. }
  681. else
  682. {
  683. if (root->update >= 0 && root->update < root->used)
  684. {
  685. strcpy(gtd->input_buf, root->list[root->update]->arg1);
  686. }
  687. input_printf("\e[1G\e[0K");
  688. gtd->input_len = strlen(gtd->input_buf);
  689. gtd->input_cur = gtd->input_len;
  690. gtd->input_pos = 0;
  691. root->update = -1;
  692. DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH);
  693. gtd->input_off = 1;
  694. cursor_redraw_line(ses, "");
  695. }
  696. }
  697. DO_CURSOR(cursor_history_find)
  698. {
  699. struct listroot *root = ses->list[LIST_HISTORY];
  700. push_call("cursor_history_find(%s)", gtd->input_buf);
  701. if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8|CHARSET_FLAG_BIG5))
  702. {
  703. if (inputline_str_chk(0, gtd->input_len) == FALSE)
  704. {
  705. pop_call();
  706. return;
  707. }
  708. }
  709. gtd->level->quiet++;
  710. for (root->update = root->used - 1 ; root->update >= 0 ; root->update--)
  711. {
  712. if (*gtd->input_buf && find(ses, root->list[root->update]->arg1, gtd->input_buf, SUB_NONE, REGEX_FLAG_NONE))
  713. {
  714. break;
  715. }
  716. }
  717. gtd->level->quiet--;
  718. if (root->update >= 0)
  719. {
  720. input_printf("\e[%dG ] %.*s\e[%dG", gtd->input_off + inputline_cur_str_len(), gtd->input_off + inputline_max_str_len() - inputline_cur_str_len() - 4, root->list[root->update]->arg1, gtd->input_off + gtd->input_pos - gtd->input_hid);
  721. }
  722. else
  723. {
  724. input_printf("\e[%dG ] \e[0K\e[%dG", gtd->input_off + inputline_cur_str_len(), gtd->input_off + gtd->input_pos - gtd->input_hid);
  725. }
  726. pop_call();
  727. return;
  728. }
  729. DO_CURSOR(cursor_home)
  730. {
  731. if (gtd->input_cur == 0)
  732. {
  733. return;
  734. }
  735. input_printf("\e[%dD", gtd->input_pos - gtd->input_hid);
  736. gtd->input_cur = 0;
  737. gtd->input_pos = 0;
  738. if (gtd->input_hid)
  739. {
  740. gtd->input_hid = 0;
  741. cursor_redraw_line(ses, "");
  742. }
  743. }
  744. DO_CURSOR(cursor_insert)
  745. {
  746. if (*arg == 0)
  747. {
  748. TOG_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT);
  749. }
  750. else if (!strcasecmp(arg, "ON"))
  751. {
  752. SET_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT);
  753. }
  754. else if (!strcasecmp(arg, "OFF"))
  755. {
  756. DEL_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT);
  757. }
  758. else
  759. {
  760. show_error(gtd->ses, LIST_COMMAND, "#SYNTAX: #CURSOR {INSERT} {ON|OFF}.");
  761. }
  762. }
  763. DO_CURSOR(cursor_left)
  764. {
  765. int width;
  766. if (gtd->input_cur > 0)
  767. {
  768. if (HAS_BIT(ses->charset, CHARSET_FLAG_BIG5))
  769. {
  770. gtd->input_cur--;
  771. gtd->input_pos--;
  772. input_printf("\e[1D");
  773. if (inputline_str_chk(0, gtd->input_cur) == FALSE)
  774. {
  775. gtd->input_cur--;
  776. gtd->input_pos--;
  777. input_printf("\e[1D");
  778. }
  779. }
  780. else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
  781. {
  782. gtd->input_cur--;
  783. if (gtd->input_cur > 0 && is_utf8_tail(&gtd->input_buf[gtd->input_cur]))
  784. {
  785. do
  786. {
  787. gtd->input_cur--;
  788. }
  789. while (gtd->input_cur > 0 && is_utf8_tail(&gtd->input_buf[gtd->input_cur]));
  790. get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  791. if (width == 0)
  792. {
  793. return cursor_left(ses, "");
  794. }
  795. input_printf("\e[%dD", width);
  796. gtd->input_pos -= width;
  797. }
  798. else
  799. {
  800. gtd->input_pos--;
  801. input_printf("\e[1D");
  802. }
  803. }
  804. else
  805. {
  806. gtd->input_cur--;
  807. gtd->input_pos--;
  808. input_printf("\e[1D");
  809. }
  810. cursor_check_line(ses, "");
  811. }
  812. }
  813. DO_CURSOR(cursor_left_word)
  814. {
  815. int width;
  816. // int index_pos;
  817. if (gtd->input_cur == 0)
  818. {
  819. return;
  820. }
  821. // index_pos = gtd->input_pos;
  822. while (gtd->input_cur > 0 && gtd->input_buf[gtd->input_cur - 1] == ' ')
  823. {
  824. gtd->input_pos--;
  825. gtd->input_cur--;
  826. }
  827. while (gtd->input_cur > 0 && gtd->input_buf[gtd->input_cur - 1] != ' ')
  828. {
  829. gtd->input_cur--;
  830. if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
  831. {
  832. if (!is_utf8_tail(&gtd->input_buf[gtd->input_cur]))
  833. {
  834. get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  835. gtd->input_pos -= width;
  836. }
  837. }
  838. else
  839. {
  840. gtd->input_pos--;
  841. }
  842. }
  843. // input_printf("\e[%dD", index_pos - gtd->input_pos);
  844. cursor_redraw_line(ses, "");
  845. }
  846. DO_CURSOR(cursor_paste_buffer)
  847. {
  848. if (*gtd->paste_buf == 0)
  849. {
  850. return;
  851. }
  852. ins_sprintf(&gtd->input_buf[gtd->input_cur], "%s", gtd->paste_buf);
  853. gtd->input_len += strlen(gtd->paste_buf);
  854. gtd->input_cur += strlen(gtd->paste_buf);
  855. gtd->input_pos += inputline_raw_str_len(gtd->input_cur - strlen(gtd->paste_buf), gtd->input_cur);
  856. cursor_redraw_line(ses, "");
  857. modified_input();
  858. }
  859. DO_CURSOR(cursor_redraw_input)
  860. {
  861. if (IS_SPLIT(ses))
  862. {
  863. cursor_redraw_line(ses, "");
  864. }
  865. else
  866. {
  867. /* if (*gtd->ses->scroll->input)
  868. {
  869. input_printf("\e[G%s", gtd->ses->scroll->input);
  870. }*/
  871. cursor_redraw_line(ses, "");
  872. /*
  873. gtd->input_cur = gtd->input_len;
  874. gtd->input_pos = gtd->input_len % gtd->screen->cols;
  875. */
  876. }
  877. }
  878. DO_CURSOR(cursor_redraw_line)
  879. {
  880. if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8|CHARSET_FLAG_BIG5))
  881. {
  882. if (inputline_str_chk(0, gtd->input_len) == FALSE)
  883. {
  884. return;
  885. }
  886. }
  887. // Erase current input
  888. input_printf("\e[%dG\e[%dP", gtd->input_off, inputline_max_str_len());
  889. // Center long lines of input
  890. if (gtd->input_pos > inputline_max_str_len() - 3)
  891. {
  892. while (gtd->input_pos - gtd->input_hid > inputline_max_str_len() - 3)
  893. {
  894. gtd->input_hid += inputline_max_str_len() / 2;
  895. }
  896. while (gtd->input_pos - gtd->input_hid < 2)
  897. {
  898. gtd->input_hid -= inputline_max_str_len() / 2;
  899. }
  900. }
  901. else
  902. {
  903. if (gtd->input_hid && gtd->input_pos - gtd->input_hid < 2)
  904. {
  905. gtd->input_hid = 0;
  906. }
  907. }
  908. // Print the entire thing
  909. if (gtd->input_hid)
  910. {
  911. if (gtd->input_hid + inputline_max_str_len() >= inputline_raw_str_len(0, gtd->input_len))
  912. {
  913. input_printf("<%.*s\e[%dG", inputline_str_raw_len(gtd->input_hid + 1, gtd->input_hid + inputline_max_str_len() - 0), &gtd->input_buf[inputline_str_raw_len(0, gtd->input_hid + 1)], gtd->input_off + gtd->input_pos - gtd->input_hid);
  914. }
  915. else
  916. {
  917. input_printf("<%.*s>\e[%dG", inputline_str_raw_len(gtd->input_hid + 1, gtd->input_hid + inputline_max_str_len() - 1), &gtd->input_buf[inputline_str_raw_len(0, gtd->input_hid + 1)], gtd->input_off + gtd->input_pos - gtd->input_hid);
  918. }
  919. }
  920. else
  921. {
  922. if (gtd->input_hid + inputline_max_str_len() >= inputline_raw_str_len(0, gtd->input_len))
  923. {
  924. input_printf("%.*s\e[%dG", inputline_str_raw_len(gtd->input_hid + 0, gtd->input_hid + inputline_max_str_len() - 0), &gtd->input_buf[inputline_str_raw_len(0, gtd->input_hid + 0)], gtd->input_off + gtd->input_pos - gtd->input_hid);
  925. }
  926. else
  927. {
  928. input_printf("%.*s>\e[%dG", inputline_str_raw_len(gtd->input_hid + 0, gtd->input_hid + inputline_max_str_len() - 1), &gtd->input_buf[inputline_str_raw_len(0, gtd->input_hid + 0)], gtd->input_off + gtd->input_pos - gtd->input_hid);
  929. }
  930. }
  931. }
  932. DO_CURSOR(cursor_right)
  933. {
  934. int size, width;
  935. if (gtd->input_cur < gtd->input_len)
  936. {
  937. if (HAS_BIT(ses->charset, CHARSET_FLAG_BIG5) && (gtd->input_buf[gtd->input_cur] & 128) == 128)
  938. {
  939. if (gtd->input_cur + 1 < gtd->input_len && gtd->input_buf[gtd->input_cur+1])
  940. {
  941. gtd->input_cur += 2;
  942. gtd->input_pos += 2;
  943. input_printf("\e[2C");
  944. }
  945. }
  946. else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
  947. {
  948. gtd->input_cur += get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  949. if (width == 0)
  950. {
  951. return cursor_right(ses, "");
  952. }
  953. input_printf("\e[%dC", width);
  954. gtd->input_pos += width;
  955. while (gtd->input_cur < gtd->input_len)
  956. {
  957. size = get_utf8_width(&gtd->input_buf[gtd->input_cur], &width);
  958. if (width)
  959. {
  960. break;
  961. }
  962. gtd->input_cur += size;
  963. }
  964. }
  965. else
  966. {
  967. input_printf("\e[1C");
  968. gtd->input_cur++;
  969. gtd->input_pos++;
  970. }
  971. }
  972. cursor_check_line(ses, "");
  973. }
  974. DO_CURSOR(cursor_right_word)
  975. {
  976. if (gtd->input_cur == gtd->input_len)
  977. {
  978. return;
  979. }
  980. while (gtd->input_cur < gtd->input_len && gtd->input_buf[gtd->input_cur] == ' ')
  981. {
  982. gtd->input_cur++;
  983. gtd->input_pos++;
  984. }
  985. while (gtd->input_cur < gtd->input_len && gtd->input_buf[gtd->input_cur] != ' ')
  986. {
  987. if (!HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) || (gtd->input_buf[gtd->input_cur] & 192) != 128)
  988. {
  989. gtd->input_pos++;
  990. }
  991. gtd->input_cur++;
  992. }
  993. cursor_redraw_line(ses, "");
  994. }
  995. DO_CURSOR(cursor_set)
  996. {
  997. if (*arg == 0)
  998. {
  999. return;
  1000. }
  1001. ins_sprintf(&gtd->input_buf[gtd->input_cur], "%s", arg);
  1002. gtd->input_len += strlen(arg);
  1003. gtd->input_cur += strlen(arg);
  1004. gtd->input_pos += inputline_raw_str_len(gtd->input_cur - strlen(arg), gtd->input_cur);
  1005. cursor_redraw_line(ses, "");
  1006. modified_input();
  1007. }
  1008. DO_CURSOR(cursor_suspend)
  1009. {
  1010. do_suspend(ses, "");
  1011. }
  1012. DO_CURSOR(cursor_info)
  1013. {
  1014. tintin_printf2(ses, "Width of input bar: %10d", inputline_max_str_len());
  1015. tintin_printf2(ses, "Offset of input bar: %10d", gtd->input_off);
  1016. tintin_printf2(ses, "Width of hidden text on left: %10d", gtd->input_hid);
  1017. tintin_printf2(ses, "VT100 position of cursor: %10d", gtd->input_pos);
  1018. tintin_printf2(ses, "internal position of cursor: %10d", gtd->input_cur);
  1019. tintin_printf2(ses, "internal length of input line: %10d", gtd->input_len);
  1020. tintin_printf2(ses, "VT100 length of displayed line: %10d", inputline_cur_str_len());
  1021. }
  1022. /*
  1023. Improved tab handling by Ben Love
  1024. */
  1025. int cursor_tab_add(int input_now, int stop_after_first)
  1026. {
  1027. struct listroot *root = gtd->ses->list[LIST_TAB];
  1028. struct listnode *node;
  1029. char tab[BUFFER_SIZE];
  1030. if (!HAS_BIT(root->flags, LIST_FLAG_IGNORE))
  1031. {
  1032. for (root->update = 0 ; root->update < root->used ; root->update++)
  1033. {
  1034. node = root->list[root->update];
  1035. substitute(gtd->ses, node->arg1, tab, SUB_VAR|SUB_FUN);
  1036. if (!strncmp(tab, &gtd->input_buf[input_now], strlen(&gtd->input_buf[input_now])))
  1037. {
  1038. if (search_node_list(gtd->ses->list[LIST_COMMAND], tab))
  1039. {
  1040. continue;
  1041. }
  1042. insert_node_list(gtd->ses->list[LIST_COMMAND], tab, "", "", "");
  1043. if (HAS_BIT(node->flags, NODE_FLAG_ONESHOT))
  1044. {
  1045. delete_node_list(gtd->ses, LIST_TAB, node);
  1046. }
  1047. if (stop_after_first)
  1048. {
  1049. return TRUE;
  1050. }
  1051. }
  1052. }
  1053. }
  1054. return FALSE;
  1055. }
  1056. int cursor_auto_tab_add(int input_now, int stop_after_first)
  1057. {
  1058. char tab[BUFFER_SIZE], buf[BUFFER_SIZE];
  1059. int scroll_cnt, line_cnt, tab_len;
  1060. char *arg;
  1061. line_cnt = 0;
  1062. for (scroll_cnt = gtd->ses->scroll->used - 1 ; scroll_cnt > 0 ; scroll_cnt--)
  1063. {
  1064. if (HAS_BIT(gtd->ses->scroll->buffer[scroll_cnt]->flags, BUFFER_FLAG_GREP))
  1065. {
  1066. continue;
  1067. }
  1068. if (line_cnt++ >= gtd->ses->auto_tab)
  1069. {
  1070. break;
  1071. }
  1072. strip_vt102_codes(gtd->ses->scroll->buffer[scroll_cnt]->str, buf);
  1073. arg = buf;
  1074. while (*arg)
  1075. {
  1076. arg = get_arg_in_braces(gtd->ses, arg, tab, GET_ONE);
  1077. if (!strncmp(tab, &gtd->input_buf[input_now], strlen(&gtd->input_buf[input_now])))
  1078. {
  1079. tab_len = strlen(tab) -1;
  1080. if (tab_len > 0)
  1081. {
  1082. if (tab[tab_len] == '.' || tab[tab_len] == ',' || tab[tab_len] == ';')
  1083. {
  1084. tab[tab_len] = 0;
  1085. }
  1086. }
  1087. if (search_node_list(gtd->ses->list[LIST_COMMAND], tab))
  1088. {
  1089. continue;
  1090. }
  1091. insert_node_list(gtd->ses->list[LIST_COMMAND], tab, "", "", "");
  1092. if (stop_after_first)
  1093. {
  1094. return TRUE;
  1095. }
  1096. }
  1097. if (*arg == COMMAND_SEPARATOR)
  1098. {
  1099. arg++;
  1100. }
  1101. }
  1102. }
  1103. return FALSE;
  1104. }
  1105. void cursor_hide_completion(int input_now)
  1106. {
  1107. struct listroot *root = gtd->ses->list[LIST_COMMAND];
  1108. struct listnode *f_node;
  1109. struct listnode *l_node;
  1110. int len_change;
  1111. f_node = root->list[0];
  1112. l_node = root->list[root->used - 1];
  1113. if (root->used && !strcmp(l_node->arg1, gtd->input_buf + input_now))
  1114. {
  1115. len_change = strlen(l_node->arg1) - strlen(f_node->arg1);
  1116. if (len_change > 0)
  1117. {
  1118. /*
  1119. if (gtd->input_cur < gtd->input_len)
  1120. {
  1121. input_printf("\e[%dC", gtd->input_len - gtd->input_cur);
  1122. }
  1123. input_printf("\e[%dD\e[%dP", len_change, len_change);
  1124. */
  1125. gtd->input_len = gtd->input_len - len_change;
  1126. gtd->input_buf[gtd->input_len] = 0;
  1127. gtd->input_cur = gtd->input_len;
  1128. gtd->input_pos = gtd->input_pos;
  1129. }
  1130. }
  1131. return;
  1132. }
  1133. void cursor_show_completion(int input_now, int show_last_node)
  1134. {
  1135. struct listroot *root = gtd->ses->list[LIST_COMMAND];
  1136. struct listnode *node;
  1137. if (!root->used)
  1138. {
  1139. return;
  1140. }
  1141. node = show_last_node ? root->list[root->used - 1] : root->list[0];
  1142. /*
  1143. if (gtd->input_cur < gtd->input_len)
  1144. {
  1145. input_printf("\e[%dC", gtd->input_len - gtd->input_cur);
  1146. }
  1147. if (gtd->input_len > input_now)
  1148. {
  1149. input_printf("\e[%dD\e[%dP", gtd->input_len - input_now, gtd->input_len - input_now);
  1150. }
  1151. if (input_now + (int) strlen(node->arg1) < gtd->ses->cols - 2)
  1152. {
  1153. input_printf("%s", node->arg1);
  1154. }
  1155. */
  1156. strcpy(&gtd->input_buf[input_now], node->arg1);
  1157. gtd->input_len = input_now + strlen(node->arg1);
  1158. gtd->input_cur = gtd->input_len;
  1159. cursor_end(gtd->ses, "");
  1160. if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH))
  1161. {
  1162. cursor_history_find(gtd->ses, "");
  1163. }
  1164. if (node == root->list[0])
  1165. {
  1166. kill_list(root);
  1167. }
  1168. return;
  1169. }
  1170. int cursor_calc_input_now(void)
  1171. {
  1172. int input_now;
  1173. if (gtd->input_len == 0 || gtd->input_buf[gtd->input_len - 1] == ' ')
  1174. {
  1175. return -1;
  1176. }
  1177. for (input_now = gtd->input_len - 1 ; input_now ; input_now--)
  1178. {
  1179. if (gtd->input_buf[input_now] == ' ')
  1180. {
  1181. return input_now + 1;
  1182. }
  1183. }
  1184. return input_now;
  1185. }
  1186. DO_CURSOR(cursor_tab_forward)
  1187. {
  1188. struct listroot *root = ses->list[LIST_COMMAND];
  1189. int tab_found;
  1190. if (!root->list[0])
  1191. {
  1192. gtd->input_tab = cursor_calc_input_now();
  1193. }
  1194. if (gtd->input_tab == -1)
  1195. {
  1196. return;
  1197. }
  1198. cursor_hide_completion(gtd->input_tab);
  1199. if (!root->list[0])
  1200. {
  1201. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1202. }
  1203. tab_found = cursor_tab_add(gtd->input_tab, TRUE);
  1204. cursor_show_completion(gtd->input_tab, tab_found);
  1205. }
  1206. DO_CURSOR(cursor_tab_backward)
  1207. {
  1208. struct listroot *root = ses->list[LIST_COMMAND];
  1209. if (!root->list[0])
  1210. {
  1211. gtd->input_tab = cursor_calc_input_now();
  1212. }
  1213. if (gtd->input_tab == -1)
  1214. {
  1215. return;
  1216. }
  1217. cursor_hide_completion(gtd->input_tab);
  1218. if (root->used)
  1219. {
  1220. delete_index_list(root, root->used - 1);
  1221. }
  1222. if (!root->list[0])
  1223. {
  1224. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1225. cursor_tab_add(gtd->input_tab, FALSE);
  1226. }
  1227. cursor_show_completion(gtd->input_tab, TRUE);
  1228. }
  1229. DO_CURSOR(cursor_auto_tab_forward)
  1230. {
  1231. struct listroot *root = ses->list[LIST_COMMAND];
  1232. int tab_found;
  1233. if (!root->list[0])
  1234. {
  1235. gtd->input_tab = cursor_calc_input_now();
  1236. }
  1237. if (gtd->input_tab == -1)
  1238. {
  1239. return;
  1240. }
  1241. cursor_hide_completion(gtd->input_tab);
  1242. if (!root->list[0])
  1243. {
  1244. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1245. }
  1246. tab_found = cursor_auto_tab_add(gtd->input_tab, TRUE);
  1247. cursor_show_completion(gtd->input_tab, tab_found);
  1248. }
  1249. DO_CURSOR(cursor_auto_tab_backward)
  1250. {
  1251. struct listroot *root = ses->list[LIST_COMMAND];
  1252. if (!root->list[0])
  1253. {
  1254. gtd->input_tab = cursor_calc_input_now();
  1255. }
  1256. if (gtd->input_tab == -1)
  1257. {
  1258. return;
  1259. }
  1260. cursor_hide_completion(gtd->input_tab);
  1261. if (root->used)
  1262. {
  1263. delete_index_list(root, root->used - 1);
  1264. }
  1265. if (!root->list[0])
  1266. {
  1267. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1268. cursor_auto_tab_add(gtd->input_tab, FALSE);
  1269. }
  1270. cursor_show_completion(gtd->input_tab, TRUE);
  1271. }
  1272. DO_CURSOR(cursor_mixed_tab_forward)
  1273. {
  1274. struct listroot *root = ses->list[LIST_COMMAND];
  1275. int tab_found;
  1276. if (!root->list[0])
  1277. {
  1278. gtd->input_tab = cursor_calc_input_now();
  1279. }
  1280. if (gtd->input_tab == -1)
  1281. {
  1282. return;
  1283. }
  1284. cursor_hide_completion(gtd->input_tab);
  1285. if (!root->list[0])
  1286. {
  1287. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1288. }
  1289. tab_found = cursor_tab_add(gtd->input_tab, TRUE) || cursor_auto_tab_add(gtd->input_tab, TRUE);
  1290. cursor_show_completion(gtd->input_tab, tab_found);
  1291. }
  1292. DO_CURSOR(cursor_mixed_tab_backward)
  1293. {
  1294. struct listroot *root = ses->list[LIST_COMMAND];
  1295. if (!root->list[0])
  1296. {
  1297. gtd->input_tab = cursor_calc_input_now();
  1298. }
  1299. if (gtd->input_tab == -1)
  1300. {
  1301. return;
  1302. }
  1303. cursor_hide_completion(gtd->input_tab);
  1304. if (root->used)
  1305. {
  1306. delete_index_list(root, root->used - 1);
  1307. }
  1308. if (!root->list[0])
  1309. {
  1310. insert_node_list(root, &gtd->input_buf[gtd->input_tab], "", "", "");
  1311. cursor_tab_add(gtd->input_tab, FALSE);
  1312. cursor_auto_tab_add(gtd->input_tab, FALSE);
  1313. }
  1314. cursor_show_completion(gtd->input_tab, TRUE);
  1315. }
  1316. DO_CURSOR(cursor_screen_focus_in)
  1317. {
  1318. gtd->screen->focus = 1;
  1319. check_all_events(gtd->ses, SUB_ARG, 1, 1, "SCREEN FOCUS", ntos(gtd->screen->focus));
  1320. msdp_update_all("SCREEN_FOCUS", "%d", gtd->screen->focus);
  1321. }
  1322. DO_CURSOR(cursor_screen_focus_out)
  1323. {
  1324. gtd->screen->focus = 0;
  1325. check_all_events(gtd->ses, SUB_ARG, 0, 1, "SCREEN FOCUS", ntos(gtd->screen->focus));
  1326. msdp_update_all("SCREEN_FOCUS", "%d", gtd->screen->focus);
  1327. }