CE Source Edit.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. namespace Edit{
  5. /******************************************************************************/
  6. static Bool ClipFullLine;
  7. static Str ClipTemp;
  8. /******************************************************************************/
  9. void Source::startSel()
  10. {
  11. if(Kb.k.shift())
  12. {
  13. if(sel.x<0)sel=cur;
  14. }else
  15. {
  16. sel=-1;
  17. }
  18. }
  19. /******************************************************************************/
  20. void Source::highlight(Int line, Bool immediate)
  21. {
  22. highlight_line=line;
  23. highlight_time=1;
  24. sel =-1;
  25. cur.y=Mid(line, 0, lines.elms()-1);
  26. makeCurVisible(true, immediate);
  27. }
  28. /******************************************************************************/
  29. void Source::makeCurVisible(Bool center, Bool immediate)
  30. {
  31. VecI2 cur=T.cur; if(CE.view_mode())cur=realToView(cur);
  32. if(center)
  33. {
  34. scrollFitY(cur.y*CE.ts.lineHeight()-clientHeight()*0.5f, cur.y*CE.ts.lineHeight()+clientHeight()*0.5f, immediate);
  35. }else
  36. {
  37. if(cur.y <Ceil ( slidebar[1].offset() /CE.ts.lineHeight()))scrollToY( cur.y *CE.ts.lineHeight(), immediate);else
  38. if(cur.y+1>Trunc((slidebar[1].offset()+clientHeight())/CE.ts.lineHeight()))scrollToY((cur.y+1)*CE.ts.lineHeight(), immediate);
  39. }
  40. if(cur.x <Ceil ((slidebar[0].offset()+CE.lineNumberSize())/CE.ts.colWidth()))scrollToX( cur.x *CE.ts.colWidth(), true);else
  41. if(cur.x+1>Trunc((slidebar[0].offset()+clientWidth() )/CE.ts.colWidth()))scrollToX((cur.x+8)*CE.ts.colWidth(), true);
  42. setOffset();
  43. }
  44. /******************************************************************************/
  45. void Source::curLeft () {forceCreateNextUndo(); clearSuggestions(); if(sel.x>=0 && !Kb.k.shift()){if(sel.y<cur.y || (sel.y==cur.y && sel.x<cur.x))cur=sel; sel=-1;}else{startSel(); MAX(--cur.x, 0); if(0 && CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x , id, range))cur.x=range.x ;}} makeCurVisible();}
  46. void Source::curRight () {forceCreateNextUndo(); clearSuggestions(); if(sel.x>=0 && !Kb.k.shift()){if(sel.y>cur.y || (sel.y==cur.y && sel.x>cur.x))cur=sel; sel=-1;}else{startSel(); ++cur.x ; if(0 && CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x-1, id, range))cur.x=range.y+1;}} makeCurVisible();}
  47. void Source::curUp () {forceCreateNextUndo(); clearSuggestions(); if(sel.x>=0 && !Kb.k.shift())MIN(cur.y, sel.y); startSel(); MAX(--cur.y, 0 ); makeCurVisible();}
  48. void Source::curDown () {forceCreateNextUndo(); clearSuggestions(); if(sel.x>=0 && !Kb.k.shift())MAX(cur.y, sel.y); startSel(); MIN(++cur.y, Max(0, lines.elms()-1)); makeCurVisible();}
  49. void Source::curLineBegin() {forceCreateNextUndo(); clearSuggestions(); startSel(); if(InRange(cur.y, lines)){Int start=lines[cur.y].start(); cur.x=((cur.x==start) ? 0 : start);}else cur.x=0; makeCurVisible();}
  50. void Source::curLineEnd () {forceCreateNextUndo(); clearSuggestions(); startSel(); if(InRange(cur.y, lines)) cur.x=lines[cur.y].length() ; else cur.x=0; makeCurVisible();}
  51. void Source::selAll () {forceCreateNextUndo(); clearSuggestions(); CE.markCurPos(); sel=0; cur.y=Max(0, lines.elms()-1); if(InRange(cur.y, lines)) cur.x=lines[cur.y].length() ; else cur.x=0; makeCurVisible();}
  52. void Source::selWord ()
  53. {
  54. forceCreateNextUndo(); clearSuggestions();
  55. sel=cur;
  56. if(InRange(cur.y, lines))
  57. {
  58. Line &line=lines[cur.y];
  59. sel.x=line.wordStart(cur.x);
  60. cur.x=line.wordEnd (sel.x);
  61. }
  62. if(sel==cur)sel=-1;
  63. makeCurVisible();
  64. }
  65. /******************************************************************************/
  66. void Source::curPrevWord()
  67. {
  68. forceCreateNextUndo(); clearSuggestions(); startSel();
  69. if(cur.x)
  70. {
  71. cur.x--;
  72. if(InRange(cur.y, lines))for(CHAR_TYPE ct=CodeCharType(lines[cur.y][cur.x]); cur.x>0; cur.x--)
  73. {
  74. if(CE.view_elm_names){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x, id, range)){cur.x=range.x; break;}}
  75. CHAR_TYPE nt=CodeCharType(lines[cur.y][cur.x-1]);
  76. if(ct==CHART_SPACE || ct==CHART_NONE)ct=nt;
  77. if(ct!=nt || (ct==CHART_SIGN && (/*lines[cur.y].Type(cur.x-1)==TOKEN_OPERATOR || */lines[cur.y].Type(cur.x)==TOKEN_OPERATOR)))break;
  78. }
  79. }else
  80. {
  81. if(cur.y){cur.y--; cur.x=lines[cur.y].end();}
  82. }
  83. makeCurVisible();
  84. }
  85. void Source::curNextWord()
  86. {
  87. forceCreateNextUndo(); clearSuggestions(); startSel();
  88. if(InRange(cur.y, lines))
  89. {
  90. if(cur.x>=lines[cur.y].end()) // at the end of line
  91. {
  92. if(InRange(cur.y+1, lines))
  93. {
  94. cur.y++;
  95. for(cur.x=0; cur.x<lines[cur.y].length(); cur.x++)if(lines[cur.y][cur.x]!=' ')break;
  96. }
  97. }else
  98. {
  99. cur.x++;
  100. for(CHAR_TYPE ct=CodeCharType(lines[cur.y][cur.x-1]); cur.x<lines[cur.y].length(); cur.x++)
  101. {
  102. if(CE.view_elm_names){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x-1, id, range))cur.x=range.y+1;}
  103. CHAR_TYPE nt=CodeCharType(lines[cur.y][cur.x]);
  104. if(ct!=nt || (ct==CHART_SIGN && lines[cur.y].Type(cur.x)==TOKEN_OPERATOR)){for(; cur.x<lines[cur.y].length() && lines[cur.y][cur.x]==' '; cur.x++); break;}
  105. }
  106. }
  107. }
  108. makeCurVisible();
  109. }
  110. /******************************************************************************/
  111. void Source::curPrevBracket() {for(VecI2 p=cur; lineValid(dec(p)); )if((lines[p.y][p.x]=='{' || lines[p.y][p.x]=='}') && lines[p.y].Type(p.x)==TOKEN_OPERATOR){cur=p; makeCurVisible(); break;}}
  112. void Source::curNextBracket() {for(VecI2 p=cur; lineValid(inc(p)); )if((lines[p.y][p.x]=='{' || lines[p.y][p.x]=='}') && lines[p.y].Type(p.x)==TOKEN_OPERATOR){cur=p; makeCurVisible(); break;}}
  113. /******************************************************************************/
  114. void Source::curPrevLevelBracket()
  115. {
  116. Int level=((posValid(cur) && lines[cur.y][cur.x]=='{') ? 2 : 0); // if we're on '{' then break on any next brace
  117. for(VecI2 p=cur; lineValid(dec(p)); )if(lines[p.y].Type(p.x)==TOKEN_OPERATOR){if(lines[p.y][p.x]=='{')level++;else if(lines[p.y][p.x]=='}')level--;else continue; if(level>0){cur=p; makeCurVisible(); break;}}
  118. }
  119. void Source::curNextLevelBracket()
  120. {
  121. Int level=((posValid(cur) && lines[cur.y][cur.x]=='}') ? -2 : 0); // if we're on '}' then break on any next brace
  122. for(VecI2 p=cur; lineValid(inc(p)); )if(lines[p.y].Type(p.x)==TOKEN_OPERATOR){if(lines[p.y][p.x]=='{')level++;else if(lines[p.y][p.x]=='}')level--;else continue; if(level<0){cur=p; makeCurVisible(); break;}}
  123. }
  124. /******************************************************************************/
  125. void Source::curPageUp()
  126. {
  127. forceCreateNextUndo(); clearSuggestions(); startSel();
  128. Bool visible=isCurVisible();
  129. Int ys=Max(1, Trunc(clientHeight()/CE.ts.lineHeight()));
  130. MAX(cur.y-=ys, 0);
  131. if(visible)scrollY(-ys*CE.ts.lineHeight(), true);else makeCurVisible();
  132. }
  133. void Source::curPageDown()
  134. {
  135. forceCreateNextUndo(); clearSuggestions(); startSel();
  136. Bool visible=isCurVisible();
  137. Int ys=Max(1, Trunc(clientHeight()/CE.ts.lineHeight()));
  138. MIN(cur.y+=ys, Max(0, lines.elms()-1));
  139. if(visible)scrollY(ys*CE.ts.lineHeight(), true);else makeCurVisible();
  140. }
  141. /******************************************************************************/
  142. Int Source::viewBeginPos() {return Max(0, Ceil((slidebar[1].offset() )/CE.ts.lineHeight()) );}
  143. Int Source::viewEndPos () {return Min(Max(0, lines.elms()-1), Trunc((slidebar[1].offset()+clientHeight())/CE.ts.lineHeight())-1);}
  144. /******************************************************************************/
  145. void Source::curViewBegin()
  146. {
  147. forceCreateNextUndo(); clearSuggestions(); startSel();
  148. cur.y=viewBeginPos();
  149. makeCurVisible();
  150. }
  151. void Source::curViewEnd()
  152. {
  153. forceCreateNextUndo(); clearSuggestions(); startSel();
  154. cur.y=viewEndPos();
  155. makeCurVisible();
  156. }
  157. void Source::curDocBegin()
  158. {
  159. forceCreateNextUndo(); clearSuggestions(); startSel();
  160. cur=0;
  161. scrollToY(0, true);
  162. }
  163. void Source::curDocEnd()
  164. {
  165. forceCreateNextUndo(); clearSuggestions(); startSel();
  166. cur.y=Max(0, lines.elms()-1);
  167. if(InRange(cur.y, lines))cur.x=lines[cur.y].length();else cur.x=0;
  168. makeCurVisible();
  169. }
  170. /******************************************************************************/
  171. void Source::curClip()
  172. {
  173. if(CE.options.eol_clip())
  174. {
  175. MIN(cur.y, Max(0, lines.elms()-1));
  176. if(InRange(cur.y, lines))MIN(cur.x, lines[cur.y].length());
  177. else cur.x=0;
  178. }
  179. }
  180. /******************************************************************************/
  181. void Source::removeLine(Int i) {lines.removeValid(i, true);}
  182. /******************************************************************************/
  183. void Source::delSel(Bool set_undo, Bool clear_suggestions)
  184. {
  185. if(Const)return;
  186. if(set_undo )setUndo();
  187. if(clear_suggestions)clearSuggestions();
  188. if(sel.x>=0 && sel.y>=0)
  189. {
  190. VecI2 min, max; curSel(min, max);
  191. if(min.y==max.y)
  192. {
  193. if(InRange(min.y, lines))lines[min.y].remove(min.x, max.x-min.x);
  194. }else
  195. {
  196. if(InRange(min.y, lines)){lines[min.y].clip ( min.x); if(0)REP(min.x-lines[min.y].length())lines[min.y]+=' '; min.x=lines[min.y].length();}
  197. if(InRange(max.y, lines)) lines[max.y].remove(0, max.x);
  198. }
  199. REP(max.y-min.y-1)removeLine(min.y+1); // remove lines between
  200. if(min.y!=max.y && InRange(min.y+1, lines)) // merge first and last lines
  201. {
  202. lines[min.y].append(lines[min.y+1]);
  203. removeLine(min.y+1);
  204. }
  205. sel=-1;
  206. cur=min;
  207. changed(cur.y);
  208. makeCurVisible();
  209. }
  210. }
  211. /******************************************************************************/
  212. void Source::cut()
  213. {
  214. if(Const)return;
  215. copy();
  216. if(sel.x>=0)delSel();else
  217. {
  218. setUndo();
  219. if(InRange(cur.y, lines))
  220. {
  221. removeLine(cur.y);
  222. changed (cur.y);
  223. }
  224. }
  225. }
  226. /******************************************************************************/
  227. void Source::copy()
  228. {
  229. clearSuggestions();
  230. if(sel.x>=0 && sel.y>=0)
  231. {
  232. Str c; VecI2 min, max; curSel(min, max);
  233. writeAll(c, min, max);
  234. ClipFullLine=false;
  235. ClipSet(c);
  236. }else
  237. {
  238. if(InRange(cur.y, lines))
  239. {
  240. ClipFullLine=true;
  241. ClipSet(ClipTemp=(lines[cur.y]+'\n'));
  242. }else
  243. {
  244. ClipFullLine=false;
  245. ClipSet(S);
  246. }
  247. }
  248. }
  249. /******************************************************************************/
  250. void Source::paste(C Str *text, Bool move_cur)
  251. {
  252. if(Const)return;
  253. delSel(); // already calls undo
  254. Str c=(text ? *text : ClipGet());
  255. if( c.is())
  256. {
  257. VecI2 old=cur;
  258. CE.markCurPos();
  259. Str tab; REP(TabLength)tab+=' ';
  260. Int start=cur.y;
  261. if(!text && ClipFullLine && Equal(c, ClipTemp, true))
  262. {
  263. lines.NewAt(cur.y)=Replace(Replace(Replace(c, "\t", tab), '\r', '\0'), '\n', '\0');
  264. cur.y++;
  265. }else
  266. {
  267. Memc<Str> ln=Split(Replace(Replace(c, "\t", tab), '\r', '\0'), '\n');
  268. if(ln.elms())
  269. {
  270. exist(cur.x, cur.y);
  271. //sel=cur;
  272. FREPA(ln)
  273. {
  274. Str &l=ln[i];
  275. if(i)
  276. {
  277. Str &src=lines[cur.y];
  278. lines.NewAt(cur.y+1)=src()+cur.x;
  279. lines[cur.y].clip(cur.x);
  280. cur.y++;
  281. cur.x=0;
  282. }
  283. FREPA(l)lines[cur.y].insert(cur.x++, l[i]);
  284. }
  285. }
  286. }
  287. changed(start, cur.y-start+1);
  288. if(!move_cur)cur=old;
  289. makeCurVisible();
  290. }
  291. }
  292. /******************************************************************************/
  293. void Source::separator()
  294. {
  295. if(Const)return;
  296. delSel(); // already calls undo
  297. CE.markCurPos();
  298. Int start=cur.y;
  299. if(cur.y>=lines.elms())lines.setNum(cur.y+1);
  300. lines.NewAt(cur.y)=SEP_LINE;
  301. cur.y++;
  302. changed(start, cur.y-start+1);
  303. makeCurVisible();
  304. }
  305. /******************************************************************************/
  306. void Source::delForward()
  307. {
  308. if(Const)return;
  309. if(sel.x>=0)delSel();else
  310. {
  311. if(CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x, id, range)){setUndo(); clearSuggestions(); lines[cur.y].remove(range.x, range.y-range.x+1); cur.x=range.x; changed(cur.y); makeCurVisible(); return;}}
  312. clearSuggestions();
  313. setUndo(DEL_CHR);
  314. if(InRange(cur.y, lines))
  315. {
  316. if(cur.x<lines[cur.y].length())lines[cur.y].remove(cur.x);else
  317. if(InRange(cur.y+1, lines))
  318. {
  319. exist(cur.x, cur.y);
  320. lines[cur.y].append(lines[cur.y+1]);
  321. removeLine(cur.y+1);
  322. }
  323. changed(cur.y);
  324. }
  325. }
  326. }
  327. /******************************************************************************/
  328. void Source::delBack()
  329. {
  330. if(Const)return;
  331. if(sel.x>=0)delSel();else
  332. {
  333. if(CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x-1, id, range)){setUndo(); clearSuggestions(); lines[cur.y].remove(range.x, range.y-range.x+1); cur.x=range.x; changed(cur.y); makeCurVisible(); return;}}
  334. clearSuggestions();
  335. if(undos.lastChangeTypeI()==INS_CHRS)undoAsChange();else
  336. {
  337. setUndo(DEL_CHR);
  338. if(cur.x==0)
  339. {
  340. if(InRange(cur.y-1, lines)
  341. && InRange(cur.y , lines))
  342. {
  343. cur.x=lines[cur.y-1].length();
  344. lines[cur.y-1].append(lines[cur.y]);
  345. removeLine(cur.y);
  346. cur.y--;
  347. changed(cur.y);
  348. makeCurVisible();
  349. }else
  350. if(cur.y>=lines.elms())
  351. {
  352. cur.y=Max(0, lines.elms()-1);
  353. if(InRange(cur.y, lines))cur.x=lines[cur.y].length();
  354. makeCurVisible();
  355. }
  356. }else
  357. {
  358. if(InRange(cur.y, lines)){cur.x--; lines[cur.y].remove(cur.x); changed(cur.y); makeCurVisible(); listSuggestions(-1);}else cur.x=0;
  359. }
  360. }
  361. }
  362. }
  363. /******************************************************************************/
  364. // set undo before changing selection so pressing undo later will preserve the selection
  365. void Source::delWordForward()
  366. {
  367. if(Const)return; setUndo();
  368. if(sel.x<0)
  369. {
  370. if(CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x, id, range))cur.x=range.x;} // move to the beginning of the word
  371. VecI2 temp=cur; curNextWord(); sel=temp;
  372. }
  373. delSel(false);
  374. }
  375. void Source::delWordBack()
  376. {
  377. if(Const)return; setUndo();
  378. if(sel.x<0)
  379. {
  380. if(CE.view_elm_names && InRange(cur.y, lines)){UID id; VecI2 range; if(TextToIDInside(lines[cur.y], cur.x-1, id, range))cur.x=range.y+1;} // move to the end of the word
  381. VecI2 temp=cur; curPrevWord(); sel=temp;
  382. }
  383. delSel(false);
  384. }
  385. /******************************************************************************/
  386. static Char MakeCase(Char c, Bool upper) {return upper ? CaseUp(c) : CaseDown(c);}
  387. void Source::makeCase(Bool upper)
  388. {
  389. if(Const)return;
  390. if(sel.x>=0 && sel.y>=0)
  391. {
  392. setUndo();
  393. VecI2 min, max; curSel(min, max);
  394. for(Int y=min.y; y<=max.y; y++)if(InRange(y, lines))
  395. {
  396. Line &line=lines[y];
  397. for(Int max_x=((y==max.y) ? Min(max.x, line.length()) : line.length()),
  398. x=((y==min.y) ? Max(min.x, 0) : 0 ); x<max_x; x++)line.setChar(x, MakeCase(line[x], upper));
  399. }
  400. changed(min.y, max.y-min.y+1);
  401. }else
  402. if(InRange(cur.y, lines))
  403. {
  404. Line &line=lines[cur.y]; if(InRange(cur.x, line))
  405. {
  406. setUndo();
  407. line.setChar(cur.x, MakeCase(line[cur.x], upper));
  408. cur.x++;
  409. changed(cur.y);
  410. }
  411. }
  412. clearSuggestions();
  413. makeCurVisible ();
  414. }
  415. /******************************************************************************/
  416. // UNDO
  417. /******************************************************************************/
  418. void Source::UndoChange::create(Ptr source)
  419. {
  420. if(Source *src=(Source*)source)
  421. {
  422. File temp; temp.writeMem(); temp.putInt(src->lines.elms()); FREPA(src->lines)src->lines[i].saveData(temp); temp.pos(0); Compress(temp, data.writeMem(), COMPRESS_LZ4, 0, false);
  423. cur =src->cur;
  424. sel =src->sel;
  425. modify_time=src->modify_time;
  426. }
  427. }
  428. void Source::UndoChange::apply(Ptr source)
  429. {
  430. if(Source *src=(Source*)source)
  431. {
  432. File temp; data.pos(0); Decompress(data, temp, true); temp.pos(0); src->lines.clear(); REP(temp.getInt())src->lines.New().loadData(temp);
  433. src->cur=cur;
  434. src->sel=sel;
  435. src->changed(0, -1);
  436. src->clearSuggestions();
  437. src->makeCurVisible();
  438. //src->modify_time=modify_time; // after changed // EDIT: do not restore modification time, because VS will not recompile .cpp file if its modification time is older than compiled .obj file (VS checks if date(.cpp)>date(.obj) and not date!=data, so we need to always set newest date)
  439. }
  440. }
  441. void Source::forceCreateNextUndo() {undos.forceCreateNextUndo();}
  442. void Source::delUndo()
  443. {
  444. undos.del();
  445. undo_original_state=0;
  446. modify_time.getUTC();
  447. }
  448. void Source::setUndo(UNDO_TYPE undo_type)
  449. {
  450. Bool modified=T.modified();
  451. if(UndoChange *change=undos.set(undo_type, undo_type==DEFAULT || undo_type==INS_CHRS))
  452. {
  453. if(!InRange(undo_original_state, undos.changes()))undo_original_state=-1;
  454. if(CE.cur()==this && modified!=T.modified())CE.cei().sourceChanged();
  455. }
  456. }
  457. void Source::undoAsChange()
  458. {
  459. clearSuggestions();
  460. Bool modified=T.modified();
  461. if(undos.undoAsChange())
  462. if(CE.cur()==this && modified!=T.modified())CE.cei().sourceChanged();
  463. }
  464. void Source::undo()
  465. {
  466. clearSuggestions();
  467. Bool modified=T.modified();
  468. if(undos.undo())
  469. if(CE.cur()==this && modified!=T.modified())CE.cei().sourceChanged();
  470. }
  471. void Source::redo()
  472. {
  473. clearSuggestions();
  474. Bool modified=T.modified();
  475. if(undos.redo())
  476. if(CE.cur()==this && modified!=T.modified())CE.cei().sourceChanged();
  477. }
  478. /******************************************************************************/
  479. Str Source::asText()C
  480. {
  481. Str data; FREPA(lines){if(i)data+='\n'; data+=lines[i];}
  482. return data;
  483. }
  484. void Source::fromText(C Str &data)
  485. {
  486. lines.clear();
  487. FREPA(data)
  488. {
  489. if(!lines.elms())lines.New();
  490. Char c=data[i];
  491. if(c== 9){REP(TabLength)lines.last()+=' ';}else // tab
  492. if(c==0xA)lines.New ();else // new line
  493. if(c>= 32)lines.last()+=c; // any valid char
  494. }
  495. changed(0, -1);
  496. clearSuggestions();
  497. makeCurVisible ();
  498. }
  499. /******************************************************************************/
  500. }}
  501. /******************************************************************************/