1 /***************************************************************************
2 Edit_events.cxx - Event handling for Edit
3 -------------------
4 begin : Thu Mar 1 13:15:18 IST 2001
5 copyright : (C) 2001 by Arie Tal
6 email : tal_arie@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #ifndef WIN32
19 # include <unistd.h> //PORT:
20 #endif
21 #include <signal.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include "Edit.h"
25 #include "Help.h"
26 #include "Action.h"
27 #include <stdlib.h>
28 #include "langdep.h"
29 #include "aSelectionBox.h"
30 #include "aDictionary.h"
31 #include "HebrewEditor.h"
32
33 #ifndef TRUE
34 #define TRUE 1
35 #define FALSE 0
36 #endif
37
38 #include "LineEdit.h"
39
40
41 void
processAction(Action::Actions act)42 Edit::processAction(Action::Actions act)
43 {
44 // int i ; // for general use
45 action.getLastChar() ;
46
47 if (screen_start_line != win->getLastLineNum())
48 win->MessageClear() ;
49 switch (act) {
50 case Action::LaxetCommandHelp:
51 _LaxetCommandHelp(act) ;
52 break ;
53
54 case Action::SpellWord:
55 _SpellWord(act) ;
56 break ;
57
58 case Action::SpellLearnAllWords:
59 _LearnAllWords(act) ;
60 break ;
61
62 case Action::Tab:
63 _Tab(act) ;
64 break ;
65
66 case Action::MarkBlockBegin:
67 _MarkBlockBegin(act) ;
68 break ;
69
70 case Action::MarkBlockEnd:
71 _MarkBlockEnd(act) ;
72 break ;
73
74 case Action::UnmarkBlock:
75 _UnmarkBlock(act) ;
76 break ;
77
78 case Action::DeleteBlock:
79 _DeleteBlock(act) ;
80 break ;
81
82 case Action::CopyBlock:
83 _CopyBlock(act) ;
84 break ;
85
86 case Action::MoveBlock:
87 _MoveBlock(act) ;
88 break ;
89
90 case Action::Suspend: // suspend this program
91 _Suspend(act) ;
92 break ;
93
94 case Action::Help:
95 _Help(act) ;
96 break ;
97
98 case Action::Find:
99 _Find(act) ;
100 break ;
101
102 case Action::FindReplace:
103 _FindReplace(act) ;
104 break ;
105
106 case Action::Undo:
107 _Undo(act) ;
108 break ;
109
110 case Action::Redo:
111 _Redo(act) ;
112 break ;
113
114 case Action::DeleteChar: // delete current char
115 _DeleteChar(act) ;
116 break ;
117
118
119 case Action::BackSpace: // delete previous char
120 _BackSpace(act) ;
121 break ;
122
123 case Action::DeleteLine: // delete line
124 _DeleteLine(act) ;
125 break ;
126
127 case Action::SaveFile:
128 _SaveFile(act) ;
129 break ;
130
131 case Action::ToggleLanguage:
132 _LanguageToggle(act) ;
133 break ;
134
135 case Action::ChangeDirection: // insert \sethebrew or \unsethebrew commands
136 _ChangeDirection(act) ;
137 break ;
138
139 case Action::Refresh:
140 _Refresh(act) ;
141 break ;
142
143 case Action::NewLine:
144 _NewLine(act) ;
145 break ;
146
147 case Action::Exit:
148 _Exit(act) ;
149 break ;
150
151 case Action::NextLogicalWord:
152 _NextLogicalWord(act) ;
153 break ;
154
155 case Action::PreviousLogicalWord:
156 _PreviousLogicalWord(act) ;
157 break ;
158
159 case Action::RealForwardChar:
160 _RealForwardChar(act) ;
161 break ;
162
163 case Action::RealBackwardChar:
164 _RealBackwardChar(act) ;
165 break ;
166
167 case Action::WordRight:
168 _WordRight(act) ;
169 break ;
170
171 case Action::WordLeft:
172 _WordLeft(act) ;
173 break ;
174
175 case Action::BackwardChar:
176 _BackwardChar(act) ;
177 break ;
178
179 case Action::ForwardChar:
180 _ForwardChar(act) ;
181 break ;
182
183 case Action::NextLine:
184 _NextLine(act) ;
185 break ;
186
187 case Action::PreviousLine:
188 _PreviousLine(act) ;
189 break ;
190
191 case Action::Home:
192 _Home(act) ;
193 break ;
194
195 case Action::End:
196 _End(act) ;
197 break ;
198
199 case Action::BeginningOfFile:
200 _BeginningOfFile(act) ;
201 break ;
202
203 case Action::EndOfFile:
204 _EndOfFile(act) ;
205 break ;
206
207 case Action::PgUp:
208 _PgUp(act) ;
209 break ;
210
211 case Action::PgDn:
212 _PgDn(act) ;
213 break ;
214
215 case Action::Char:
216 _Char(act) ;
217 break ;
218
219 default: // ignore Null action
220 break ;
221 }
222 if ((act != Action::Char)&&(act != Action::DeleteChar) && (act!= Action::BackSpace) && (delay_compilation > 0)) {
223 file.recompile_section(sizex) ;
224 delay_compilation = 0 ;
225 _refresh() ;
226 } else if (delay_compilation >= MAX_DELAY) {
227 file.recompile_section(sizex) ;
228 delay_compilation = 0 ;
229 _refresh() ;
230 }
231
232 _maketitle() ;
233 win->Move(cury-1+screen_start_line,_x_pos()+screen_start_column) ;
234 win->scr->Refresh() ;
235 win->Refresh() ;
236 last_action = act ;
237 }
238
239
240
241 ///////////////////////////////////////////////////////
242 //// ACTIONS
243 ///////////////////////////////////////////////////////
244
245
246 void
_LanguageToggle(Action::Actions act)247 Edit::_LanguageToggle(Action::Actions act) {
248 if (read_only) return ;
249 if (keyboard_mode == hebrew)
250 keyboard_mode = english ;
251 else
252 keyboard_mode = hebrew ;
253 input.set_mode(keyboard_mode) ;
254 }
255
256 void
_ChangeDirection(Action::Actions act)257 Edit::_ChangeDirection(Action::Actions act) {
258 if (read_only) return ;
259
260 undo.invalidate_current() ;
261
262 Marker _startm = file.getStartMarker() ;
263 Marker _endm = file.getEndMarker() ;
264 Marker before = where() ;
265 aString inserting="\\sethebrew\n" ;
266 if ((file.line(current_line)).getMajorMode()==StrHebrew)
267 inserting = "\\unsethebrew\n" ;
268
269 _insertDataBlock(before, (char *)(const char*)inserting) ;
270 Marker after = where() ;
271 undo.record_action(UndoSt::ActInsert, inserting, before, after, _startm, _endm) ;
272 _End(act) ;
273 _NextLine(act) ;
274 _Home(act) ;
275 _refresh() ;
276 }
277
278 void
_MarkBlockBegin(Action::Actions act)279 Edit::_MarkBlockBegin(Action::Actions act)
280 {
281 undo.invalidate_current() ;
282 file.setStartMarker(current_line, curx-1) ;
283 _markBlock(file.getStartMarker(), file.getEndMarker()) ;
284 _markBlock(1) ;
285 _refresh() ;
286 }
287
288 void
_MarkBlockEnd(Action::Actions act)289 Edit::_MarkBlockEnd(Action::Actions act)
290 {
291 undo.invalidate_current() ;
292 file.setEndMarker(current_line, curx-1) ;
293 _markBlock(file.getStartMarker(), file.getEndMarker()) ;
294 _markBlock(1) ;
295 _refresh() ;
296 }
297
298 void
_UnmarkBlock(Action::Actions act)299 Edit::_UnmarkBlock(Action::Actions act)
300 {
301 undo.invalidate_current() ;
302 file.unmarkBlock() ;
303 if (act == Action::UnmarkBlock) {
304 he->scratch->file.eraseContent() ;
305 he->scratch->current_offset = 0 ; he->scratch->curx = 1 ; he->scratch->current_line = 1 ;
306 he->scratch->file.recompile_file(sizex) ;
307 he->scratch->_relocate_curx(0) ;
308 he->scratch->modified = 1 ;
309 he->scratch->_calc_curx() ;
310 }
311 _refresh() ;
312 }
313
314 void
_DeleteBlock(Action::Actions act)315 Edit::_DeleteBlock(Action::Actions act)
316 {
317 if (read_only) return ;
318 undo.invalidate_current() ;
319
320 Marker _startm = file.getStartMarker() ;
321 Marker _endm = file.getEndMarker() ;
322 Marker before = _startm ;
323 aString data = "" ;
324 if (file.markActive()) {
325 _markBlock(1) ; // copy to he->scratch (sort of a 'cut')
326 Marker startm=file.getStartMarker() ;
327 Marker endm=file.getEndMarker() ;
328 _relocateAtMarker(startm) ;
329 if (act == Action::DeleteBlock) {
330 win->Refresh() ;
331 _refresh() ;
332 }
333 if (endm.line == startm.line) {
334 data += ((aString &)(file.line(startm.line))).at(startm.offset,endm.offset) ;
335 _deleteDataBlock(where(), (char *)(const char*)data) ;
336 } else {
337 // int cl=current_line ;
338 data += ((aString &)(file.line(startm.line))).at(startm.offset,
339 ((aString&)(file.line(startm.line))).length()-1) ;
340 data += " \n" ;
341 for (int l = startm.line+1; l <= endm.line ; l++) {
342 if (l < endm.line) {
343 data += ((aString &)(file.line(l))) ;
344 data += '\n' ;
345 } else
346 data += ((aString &)(file.line(endm.line))).at(0, endm.offset) ;
347 }
348 _deleteDataBlock(where(), (char *)(const char *)data) ;
349 }
350 if (act == Action::DeleteBlock) {
351 _UnmarkBlock(act) ;
352 file.line(startm.line) ;
353 modified = 1 ;
354 _relocate_curx(0) ;
355 Marker after = where() ;
356 undo.record_action(UndoSt::ActDelete, data, where(), after, _startm, _endm) ;
357 _refresh() ;
358 }
359 }
360 }
361
362 void
_CopyBlock(Action::Actions act)363 Edit::_CopyBlock(Action::Actions act)
364 {
365 if (read_only) return ;
366 undo.invalidate_current() ;
367
368 Marker _startm = file.getStartMarker() ;
369 Marker _endm = file.getEndMarker() ;
370 Marker before = where() ;
371 aString data = "" ;
372 if (act == Action::CopyBlock) {
373 Marker startm = file.getStartMarker() ;
374 Marker endm = file.getEndMarker() ;
375 if (((current_line > startm.line) ||
376 (current_line == startm.line)&&(curx > startm.offset+1)) &&
377 ((current_line < endm.line) ||
378 (current_line == endm.line)&&(curx < endm.offset+1))) {
379 // trying to copy a block into a marked block!, illegal now
380 win->Message(MSG_INVALID_COPY_BLOCK) ;
381 return ;
382 }
383 }
384 int curline = current_line ;
385 if (he->scratch->file.isFileEmpty()) {
386 if (file.markActive())
387 _markBlock(1) ;
388 } else if ((he->scratch->from == this) && (act == Action::CopyBlock))
389 _markBlock(1) ;
390
391 if (!he->scratch->file.isFileEmpty()) { // I can't use file.markActive now, because a block can be
392 // copied from another buffer,using the he->scratch buffer.
393 if ((he->scratch->file).lines() == 1) {
394 data += ((aString &)((he->scratch->file).line(1))) ; //.at(0,((aString &)((he->scratch->file).line(1))).length()) ; // he->scratch is not compiled anymore so there is no extra space
395 _insertDataBlock(where(), (char *)(const char *)data) ;
396 file.setStartMarker(current_line, curx-1) ;
397 file.setEndMarker(current_line, curx-1+((aString &)((he->scratch->file).line(1))).length()) ;
398 _markBlock() ;
399 } else {
400 file.setStartMarker(current_line, curx-1) ;
401 int cl=current_line ;
402 data += ((aString &)((he->scratch->file).line(1))).at(0,((aString &)((he->scratch->file).line(1))).length()) ;
403 for (int l = 2; l < he->scratch->file.lines() ; l++) {
404 data += '\n' ;
405 data += (aString &)(he->scratch->file.line(l)) ;
406 cl++ ;
407 }
408 aString tmp = ((aString &)((he->scratch->file).line(he->scratch->file.lines()))) ; //.at(0,
409 data += '\n' ;
410 data += tmp ; cl++ ;
411 _insertDataBlock(where(), (char *)(const char*)data) ;
412 file.setEndMarker(cl, tmp.length()) ;
413 _markBlock() ;
414 file.line(curline) ;
415 // file.recompile_section(sizex) ;
416 }
417 file.line(curline) ;
418 modified = 1 ;
419 _relocate_curx(0) ;
420 Marker after = where() ;
421 if (act == Action::CopyBlock)
422 undo.record_action(UndoSt::ActInsert, data, before, after, _startm, _endm) ;
423 else
424 work_data_block = data ;
425
426 _refresh() ;
427 }
428 }
429
430
431 void
_MoveBlock(Action::Actions act)432 Edit::_MoveBlock(Action::Actions act)
433 {
434 if (read_only) return ;
435 undo.invalidate_current() ;
436 if (he->scratch->file.isFileEmpty()) {
437 if (file.markActive())
438 _markBlock(1) ;
439 }
440 if (he->scratch->from)
441 if (he->scratch->from != this) {
442 win->Message(MSG_INVALID_MOVE_BLOCK_FROM_DIFFERENT_BUFFER) ;
443 return ;
444 }
445 Marker startm = file.getStartMarker() ;
446 Marker endm = file.getEndMarker() ;
447 Marker _startm = file.getStartMarker() ;
448 Marker _endm = file.getEndMarker() ;
449 Marker before = startm ;
450 if (((current_line > startm.line) ||
451 (current_line == startm.line)&&(curx > startm.offset+1)) &&
452 ((current_line < endm.line) ||
453 (current_line == endm.line)&&(curx < endm.offset+1))) {
454 // trying to move a block into a marked block!, illegal now
455 win->Message(MSG_INVALID_MOVE_BLOCK_INTO_MARKED_BLOCK) ;
456 return ;
457 }
458
459 if (((current_line == endm.line) && (curx == endm.offset+1)) ||
460 ((current_line == startm.line) && (curx == startm.offset+1)))
461 return ; // ignore, just like moving a block right after itself, or right before itself
462
463 // int curline = current_line ;
464 if (!he->scratch->file.isFileEmpty()) {
465 // I can't use file.markActive now, because a block can be
466 // copied from another buffer,using the scratch buffer.
467 if (he->scratch->from == this) {
468 Marker newLocale = { current_line, curx-1, cury } ;
469 if ((startm.line == current_line) && (curx > startm.offset+1)) {
470 newLocale.offset -= ( (aString&)(he->scratch->file.line(1)) ).length() ;
471 newLocale.offset_from_top = -1 ;
472 _relocateAtMarker(newLocale) ;
473 } else
474 if ((endm.line == current_line) && (curx > endm.offset+1)) {
475 newLocale.offset -= endm.offset-startm.offset ;
476 if (endm.line > startm.line)
477 newLocale.line -= (endm.line - startm.line)-1 ;
478 } else if (current_line > endm.line)
479 if (endm.line > startm.line)
480 newLocale.line -= (endm.line - startm.line) ;
481 _DeleteBlock(act) ;
482 _relocateAtMarker(newLocale) ; // with same offset from top if needed, so visually it would look as if
483 // the editor stayed in the same place.
484 // if (current_line > startm.line) {
485 // newLocale.line -= he->scratch->file.lines() -1;
486 // _relocateAtMarker(newLocale) ;
487 // }
488 }
489 _CopyBlock(act) ;
490 Marker after = where() ;
491 undo.record_action(UndoSt::ActMove, work_data_block, before, after, _startm, _endm) ;
492 }
493 }
494
495
496 void
_Suspend(Action::Actions act)497 Edit::_Suspend(Action::Actions act)
498 {
499 undo.invalidate_current() ;
500 action.getLastChar() ;
501 win->Erase() ;
502 if (getenv("HE2_NEW_SHELL_ON_SUSPEND") != NULL)
503 win->TemporaryExit() ;
504 else
505 win->Suspend() ;
506 win->GetMaxYX(&sizey,&sizex) ;
507 // --sizey ;
508 file.recompile_file(sizex) ;
509 win->Erase() ;
510 win->Refresh();
511 _refresh() ;
512 }
513
514 void
_Help(Action::Actions act)515 Edit::_Help(Action::Actions act)
516 {
517 if (!read_only) {
518 {
519 aWindow *tmpWin ;
520 win->Message("(Processing help text)") ;
521 aString helpFileName = he->programPrefix ;
522 helpFileName += "/" ;
523 helpFileName += HE_TUTORIAL_FILE_NAME ;
524 Help help(he, tmpWin=new aWindow(win->scr, sizey-6, sizex-11,3,5), (const char *)helpFileName) ;
525
526 help.processFile() ;
527 help.refresh() ;
528
529 while (!help.finished())
530 help.processAction(help.getNextAction()) ;
531 // enable to copy text from help
532 if (help.file.markActive())
533 help._markBlock(1) ;
534
535 delete tmpWin ;
536 }
537 // win->Erase() ;
538 win->Refresh();
539 _refresh() ;
540 }
541
542 }
543
544 void
_Find(Action::Actions act)545 Edit::_Find(Action::Actions act)
546 {
547 // if (!read_only) {
548 Marker startm = file.getStartMarker() ;
549 Marker endm = file.getEndMarker() ;
550
551 SearchFor *input_line ;
552
553 int c =win->Question(QTN_SEARCH_HEBREW_ENGLISH) ;
554 while ((c != 'h')&& (c!='H') && (c!= 'e') && (c!='E'))
555 c =win->Question(QTN_SEARCH_HEBREW_ENGLISH) ;
556 int sy, sx ;
557 win->scr->GetMaxYX(&sy,&sx) ;
558 aWindow *linewin=new aWindow(win->scr,1,sx,sy-1,0,0) ;
559
560 if ((c == 'h') || (c == 'H'))
561 input_line = new SearchForHebrew(he, HEBREW_SEARCH_MESSAGE,linewin,this) ;
562 else
563 input_line = new SearchFor(he, ENGLISH_SEARCH_MESSAGE,linewin,this) ;
564
565 Marker current = {current_line, curx-1, cury} ;
566 input_line->refresh() ;
567
568 while (!input_line->finished())
569 input_line->processAction(act=input_line->getNextAction()) ;
570 win->MessageClear(1) ;
571 if (act != Action::NewLine) {
572 _relocateAtMarker(current) ;
573 }
574 delete input_line ;
575 delete linewin ;
576
577 file.setStartMarker(startm.line, startm.offset) ;
578 file.setEndMarker(endm.line, endm.offset) ;
579 _markBlock() ;
580 win->Refresh() ;
581 _refresh() ;
582 // }
583 }
584
585 void
_FindReplace(Action::Actions act)586 Edit::_FindReplace(Action::Actions act)
587 {
588 if (!read_only) {
589 Marker startm = file.getStartMarker() ;
590 Marker endm = file.getEndMarker() ;
591
592 SearchFor *input_line ;
593
594 int c =win->Question(QTN_REPLACE_HEBREW_ENGLISH) ;
595 while ((c != 'h')&& (c!='H') && (c!= 'e') && (c!='E'))
596 c =win->Question(QTN_REPLACE_HEBREW_ENGLISH) ;
597 int sy, sx ;
598 win->scr->GetMaxYX(&sy,&sx) ;
599 aWindow *linewin=new aWindow(win->scr,1,sx,sy-1,0,0) ;
600
601 if ((c == 'h') || (c == 'H'))
602 input_line = new SearchForHebrew(he, HEBREW_REPLACE_SEARCH_MESSAGE,linewin,this) ;
603 else
604 input_line = new SearchFor(he, ENGLISH_REPLACE_SEARCH_MESSAGE,linewin,this) ;
605
606 Marker current = {current_line, curx-1, cury} ;
607 input_line->refresh() ;
608
609 while (!input_line->finished())
610 input_line->processAction(act=input_line->getNextAction()) ;
611 win->MessageClear(1) ;
612 if (act != Action::NewLine) {
613 _relocateAtMarker(current) ;
614 } else { // begin replacing:
615 aString textToReplace = input_line->getText() ;
616 SearchFor *input_line2 ;
617 if ((c == 'h') || (c == 'H'))
618 input_line2 = new SearchForHebrew(he, HEBREW_REPLACE_WITH_MESSAGE,linewin,0) ;
619 else
620 input_line2 = new SearchFor(he, ENGLISH_REPLACE_WITH_MESSAGE,linewin,0) ;
621 input_line2->refresh() ;
622
623 while (!input_line2->finished())
624 input_line2->processAction(act=input_line2->getNextAction()) ;
625 win->MessageClear(1) ;
626 if (act == Action::NewLine) { // the user wants to start replacing
627 int cont = 1 ;
628 int batch_mode = 0 , q = ' ';
629 while (cont) {
630 if (!batch_mode)
631 q = win->Question(QTN_ENGLISH_REPLACE_YES_NO_ALL_CANCEL) ;
632 switch (q) {
633 case 'y':
634 case 'Y': {
635 Marker before = where() ;
636 _deleteDataBlock(before, input_line->getText()) ;
637 _insertDataBlock(before, input_line2->getText()) ;
638 int len = strlen(input_line2->getText()) ;
639 for (int i=0; i<len; i++) _relocate_curx(1) ;
640 Marker after = where() ;
641 undo.record_action(UndoSt::ActReplace, textToReplace, before, after,
642 startm, endm, input_line2->getText()) ;
643 searchForNext(input_line->getText()) ;
644 if (after.isEqual(where())) cont = 0 ;
645 }
646 break ;
647 case 'n':
648 case 'N': {
649 Marker here = where() ;
650 searchForNext(input_line->getText()) ;
651 if (here.isEqual(where())) cont = 0 ;
652 }
653 break ;
654 case 'a':
655 case 'A':
656 q = 'Y' ;
657 batch_mode = 1 ;
658 break ;
659 case 'c':
660 case 'C':
661 cont = 0 ;
662 break ;
663 default:
664 break ;
665 }
666 } // end of while
667 win->MessageClear(1) ;
668 delete input_line2 ;
669 }
670 } // end else begin replacing
671 delete input_line ;
672 delete linewin ;
673 file.setStartMarker(startm.line, startm.offset) ;
674 file.setEndMarker(endm.line, endm.offset) ;
675 _markBlock() ;
676 win->Refresh() ;
677 _refresh() ;
678 }
679 }
680
681
682
683 void
_DeleteChar(Action::Actions act)684 Edit::_DeleteChar(Action::Actions act)
685 {
686 Marker endm=file.getEndMarker() ;
687 Marker startm=file.getStartMarker() ;
688 Marker _endm=file.getEndMarker() ;
689 Marker _startm=file.getStartMarker() ;
690 if (!read_only) {
691 Marker before ;
692 if (act == Action::DeleteChar) {
693 before = where() ;
694 if (act != last_action)
695 undo.invalidate_current() ;
696 } else
697 before = work_marker ;
698
699 aString data = "" ;
700
701 if (curx < (file.line(current_line)).length()) {
702 data = ((aString &)(file.line(current_line))).at(curx-1,curx) ;
703
704 (file.line(current_line))._delete_ch(curx, current_offset) ;
705 int change = 0 ;
706 if ((startm.line == current_line) && (startm.offset > curx-1)) {
707 file.setStartMarker(startm.line, startm.offset-1) ;
708 change = 1 ;
709 }
710 if ((endm.line == current_line) && (endm.offset > curx-1)) {
711 file.setEndMarker(endm.line, endm.offset-1) ;
712 change = 1 ;
713 }
714 if (change)
715 _markBlock() ;
716 modified =1 ;
717 delay_compilation++ ;
718 file.recompile_section(sizex,0) ;
719 }
720 else if (current_line < file.lines()) {
721 undo.invalidate_current() ;
722 data += " \n" ;
723 int change = 0 ;
724 if (startm.line > current_line+1) {
725 file.setStartMarker(startm.line-1, startm.offset) ;
726 change=1 ;
727 } else if (startm.line == current_line+1) {
728 file.setStartMarker(startm.line-1, startm.offset + (curx-1)) ;
729 change=1 ;
730 }
731 if (endm.line > current_line+1) {
732 file.setEndMarker(endm.line-1, endm.offset) ;
733 change=1 ;
734 } else if (endm.line == current_line+1) {
735 file.setEndMarker(endm.line-1, endm.offset + (curx-1)) ;
736 change=1 ;
737 }
738 // aString tmp = ((aString &)file.line(current_line)).at(0, ((aString&)file.line(current_line)).length()-1) ;
739 // tmp+=(const char *)((aString &)file.line(current_line+1)) ;
740 // ((aString &)file.line(current_line)) = tmp ;
741 // file.delete_line(current_line+1) ; // WATCH FOR TROUBLE HERE
742 _deleteDataBlock(where(), (char *)(const char*)data) ;
743 if (change)
744 _markBlock() ;
745 modified = 1 ;
746 // file.recompile_section(sizex) ;
747 }
748 _relocate_curx(0) ;
749 _calc_curx() ;
750 Marker after = where() ;
751 if (act == Action::DeleteChar)
752 undo.record_action(UndoSt::ActDelete, data, before, after, _startm, _endm) ;
753 else
754 undo.record_action(UndoSt::ActBackSpace, data, before, after, _startm, _endm) ;
755 _refresh() ;
756 }
757
758 }
759
760 void
_BackSpace(Action::Actions act)761 Edit::_BackSpace(Action::Actions act)
762 {
763 if (!read_only) {
764 if (act != last_action)
765 undo.invalidate_current() ;
766 work_marker = where() ;
767 if (_relocate_curx(-1)) {
768 _DeleteChar(act) ;
769 } /* end if !read_only */
770 }
771 }
772
773 void
_DeleteLine(Action::Actions act)774 Edit::_DeleteLine(Action::Actions act)
775 {
776 undo.invalidate_current() ;
777 Marker endm=file.getEndMarker() ;
778 Marker startm=file.getStartMarker() ;
779 Marker _endm = file.getEndMarker() ;
780 Marker _startm = file.getStartMarker() ;
781 if (!read_only) {
782 // this is done to imitate emacs behavior
783 // are we at the end of the line ?
784 if (where().offset >= ((aString &)file.line(current_line)).length()-1)
785 _Home(Action::Null) ;
786 Marker before = where() ;
787 aString data = "" ;
788 int changed = 0 ;
789
790 // if (file.lines() > 1) // there is no need for that anymore, since DeleteLine does not
791 // actually delete lines from the file, it let's DeleteChar handle
792 // that.
793 {
794 if (current_line == file.lines()) { // THE LAST LINE IS BEING DELETED
795 // the last line is also the only marked line
796 if ((startm.line == endm.line) && (startm.line == current_line)) {
797 file.unmarkBlock() ;
798 _markBlock() ;
799 } else // are we trying to delete a last marked line ?
800 if ((endm.line == current_line) && (endm.line > startm.line)) {
801 // endm.line-- ;
802 endm.offset = where().offset ; // ((aString &)(file.line(current_line-1))).length() ;
803 file.setEndMarker(endm.line, endm.offset) ;
804 changed = 1 ;
805 }
806
807 data += ((aString &)file.line(current_line)).at(where().offset, ((aString&)file.line(current_line)).length()-1) ;
808 // _previous_line() ;
809 // _End(Action::Null) ;
810 Marker after = where() ;
811 // data += '\n' ;
812 // data += ((aString &)file.line(current_line+1)).at(0, ((aString&)file.line(current_line+1)).length()-1) ;
813 // file.delete_line(current_line+1) ;
814 _deleteDataBlock(where(), (char *)(const char*)data) ;
815 undo.record_action(UndoSt::ActDelete, data, before, after, _startm, _endm) ;
816 // if we are at the beginning of the line, only then perform a backspace
817 if (where().offset == 0)
818 _BackSpace(Action::BackSpace) ;
819 } else { // STILL MORE LINES AHEAD
820 if ((startm.line == endm.line) && (startm.line == current_line)) {
821 file.unmarkBlock() ;
822 changed = 1;
823 } else
824 if ((endm.line == current_line) && (endm.line > startm.line)) {
825 // endm.line-- ;
826 endm.offset = where().offset ; // ((aString &)(file.line(current_line-1))).length() ;
827 file.setEndMarker(endm.line, endm.offset) ;
828 changed = 1 ;
829 } else
830 if ((startm.line == current_line) && (startm.line < endm.line) && (startm.offset >= where().offset)) {
831 startm.offset = 0 ;
832 startm.line++ ;
833 file.setStartMarker(startm.line, startm.offset) ;
834 // endm.line-- ;
835 file.setEndMarker(endm.line, endm.offset) ;
836 changed = 1 ;
837 } /* else {
838 if (startm.line > current_line) {
839 changed=1 ;
840 file.setStartMarker(startm.line-1, startm.offset) ;
841 }
842 if (endm.line > current_line) {
843 changed=1 ;
844 file.setEndMarker(endm.line-1, endm.offset) ;
845 }
846 } */
847 Marker after = before ;
848 data += ((aString &)file.line(current_line)).at(where().offset, ((aString&)file.line(current_line)).length()-1) ;
849 // data += '\n' ;
850 // file.delete_line(current_line) ;
851 _deleteDataBlock(where(), (char *)(const char*)data) ;
852 undo.record_action(UndoSt::ActDelete, data, before, after, _startm, _endm) ;
853 if (where().offset == 0) {
854 _BackSpace(Action::BackSpace) ;
855 _NextLine(Action::NextLine) ;
856 _Home(Action::Home) ;
857 }
858 }
859 if (changed)
860 _markBlock() ;
861 modified = 1 ;
862 } /*
863 else { // there is only a single line in the file
864 // _Home(Action::Null) ;
865 Marker after = before ;
866 data += ((aString &)file.line(1)).at(before.offset, ((aString&)file.line(1)).length()-1) ;
867 undo.record_action(UndoSt::ActDelete, data, before, after, _startm, _endm) ;
868 _deleteDataBlock(before, (char *)(const char *)data) ;
869 // (aString &)(file.line(1)) = " " ; // clear the first line
870 file.unmarkBlock() ;
871 _markBlock() ;
872 modified = 1 ;
873 } */
874 // file.recompile_section(sizex) ;
875 _refresh() ;
876 }
877 _relocate_curx(0) ;
878 }
879
880 void
_SaveFile(Action::Actions act)881 Edit::_SaveFile(Action::Actions act)
882 {
883 if (!read_only) {
884 if (file.write_file()) {
885 win->Message(MSG_FILE_SAVED) ;
886 undo.saved_here() ;
887 modified = 0 ;
888 } else {
889 win->Message(MSG_UNABLE_TO_SAVE_FILE) ;
890 }
891 }
892 }
893
894 void
_Refresh(Action::Actions act)895 Edit::_Refresh(Action::Actions act)
896 {
897 win->TemporaryExit(1) ;
898 win->GetMaxYX(&sizey,&sizex) ;
899 // --sizey ;
900 file.recompile_file(sizex) ;
901 // win->Erase() ;
902 // win->scr->Refresh() ;
903 win->Refresh();
904 _refresh() ;
905
906 }
907
908
909 void
_SpellWord(Action::Actions act)910 Edit::_SpellWord(Action::Actions act)
911 {
912 // find current word
913 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
914 char ch = *(const char *)(chr) ;
915 while ( (strchr(LETTERS,ch)) && ((current_line > 1) || (curx > 1))) {
916 _RealBackwardChar(act) ;
917 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
918 ch = *(const char *)(chr) ;
919 }
920 if ( (!strchr(LETTERS,ch))){
921 _RealForwardChar(act) ;
922 }
923 aString word = "" ;
924 int count = 0 ;
925 if ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_HEBREW_WORD) {
926 while ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_HEBREW_WORD) {
927 word += ((aString &)file.line(current_line)).at(curx-1,curx) ;
928 count++ ;
929 _RealForwardChar(act) ;
930 }
931 for (;count>0; count--) _RealBackwardChar(act) ;
932 suggestWords(he->hebrewDictionary, word) ;
933 }
934 if ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_ENGLISH_WORD) {
935 while ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_ENGLISH_WORD) {
936 word += ((aString &)file.line(current_line)).at(curx-1,curx) ;
937 count++ ;
938 _RealForwardChar(act) ;
939 }
940 for (;count>0; count--) _RealBackwardChar(act) ;
941 suggestWords(he->englishDictionary, word) ;
942 }
943 // if ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_LAXET_COMMAND) {
944 // while ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==INVALID_LAXET_COMMAND) {
945 // word += ((aString &)file.line(current_line)).at(curx-1,curx) ;
946 // count++ ;
947 // _RealForwardChar(act) ;
948 // }
949 // for (;count>0; count--) _RealBackwardChar(act) ;
950 // suggestWords(he->laxetDictionary, word) ;
951 // }
952 // exit(1) ;
953 }
954
955 #define MAX_SPELLING_RESULTS 10
956
957 char *
suggestWords(aDictionary * dict,aString & word)958 Edit::suggestWords(aDictionary *dict, aString &word) {
959 if (!read_only) {
960 Marker startm = file.getStartMarker() ;
961 Marker endm = file.getEndMarker() ;
962 // Marker current = {current_line, curx-1, cury} ;
963
964 static char *results[MAX_SPELLING_RESULTS] ;
965 int results_count ;
966 dict->findMatchingWords(5,(char *)(const char*)word, results, results_count, MAX_SPELLING_RESULTS) ;
967 aSelectionBox<char *> sb(he, 0, "Close matches", win->scr) ;
968 for (int i=0 ; i<results_count; i++) {
969 sb.addMember(results[i], results[i], 0) ;
970 }
971
972 char *response = sb.select() ;
973 he->currentEditBuffer->refresh() ;
974 char msg[1000] ;
975 if (response) {
976 sprintf(msg,"Replace '%s' with '%s' (Yes/No/All/Cancel) ? ",
977 (char *)(const char*)word, response) ;
978 searchFor((char *)(const char *)word) ;
979 int cont = 1 ;
980 int batch_mode = 0 , q = ' ';
981 while (cont) {
982 if (!batch_mode)
983 q = win->Question(msg) ;
984 switch (q) {
985 case 'y':
986 case 'Y': {
987 Marker before = where() ;
988 _deleteDataBlock(before, (char *)(const char *)word) ;
989 _insertDataBlock(before, response) ;
990 int len = strlen(response) ;
991 for (int i=0; i<len; i++) _relocate_curx(1) ;
992 Marker after = where() ;
993 undo.record_action(UndoSt::ActReplace, word,
994 before, after,
995 startm, endm, response) ;
996 searchForNext((char *)(const char *)word) ;
997 if (after.isEqual(where())) cont = 0 ;
998 }
999 break ;
1000 case 'n':
1001 case 'N': {
1002 Marker here = where() ;
1003 searchForNext((char *)(const char *)word) ;
1004 if (here.isEqual(where())) cont = 0 ;
1005 }
1006 break ;
1007 case 'a':
1008 case 'A':
1009 q = 'Y' ;
1010 batch_mode = 1 ;
1011 break ;
1012 case 'c':
1013 case 'C':
1014 cont = 0 ;
1015 break ;
1016 default:
1017 break ;
1018 }
1019 } // end of while
1020 win->MessageClear(1) ;
1021 file.setStartMarker(startm.line, startm.offset) ;
1022 file.setEndMarker(endm.line, endm.offset) ;
1023 _markBlock() ;
1024 } else {
1025 int resp=win->Question("Would you like to add this word to your local dictionary (Yes/No) ? ") ;
1026 win->MessageClear(1) ;
1027 if (strchr("yY",resp)) {
1028 dict->recordBadWordsOn() ;
1029 dict->findMatch((char *)(const char *)word) ;
1030 dict->recordBadWordsOff() ;
1031 file.recompile_file(sizex) ;
1032 }
1033 refresh() ;
1034 }
1035 return response ;
1036 } // end of if !read_only
1037 return (char *)NULL ;
1038 }
1039
1040 void
_LearnAllWords(Action::Actions act)1041 Edit::_LearnAllWords(Action::Actions act)
1042 {
1043 he->englishDictionary->recordBadWordsOn() ;
1044 he->hebrewDictionary->recordBadWordsOn() ;
1045 he->laxetDictionary->recordBadWordsOn() ;
1046 file.recompile_file(sizex) ;
1047 he->englishDictionary->recordBadWordsOff() ;
1048 he->hebrewDictionary->recordBadWordsOff() ;
1049 he->laxetDictionary->recordBadWordsOff() ;
1050 win->Refresh();
1051 _refresh() ;
1052
1053 }
1054
1055
1056 void
_NewLine(Action::Actions act)1057 Edit::_NewLine(Action::Actions act)
1058 {
1059 undo.invalidate_current() ;
1060 Marker endm=file.getEndMarker() ;
1061 Marker startm=file.getStartMarker() ;
1062 Marker _endm=file.getEndMarker() ;
1063 Marker _startm=file.getStartMarker() ;
1064 if (!read_only) {
1065 Marker before = where() ;
1066 aString data = "" ;
1067 int changed = 0 ;
1068 if ((startm.line == current_line) && (startm.offset+1 > curx)) {
1069 startm.line++ ;
1070 startm.offset -= (curx-1) ;
1071 changed = 1 ;
1072 } else if (startm.line > current_line) {
1073 startm.line++ ;
1074 changed = 1 ;
1075 }
1076 if ((endm.line == current_line) && (endm.offset >= curx)) {
1077 endm.line++ ;
1078 endm.offset -= (curx-1) ;
1079 changed = 1 ;
1080 } else if (endm.line > current_line) {
1081 endm.line++ ;
1082 changed = 1 ;
1083 }
1084 // int len = ((aString &)file.line(current_line)).length() ;
1085 // if (!(((aString &)file.line(current_line)).at(len-1,len) == " "))
1086 data += _newline() ;
1087 if (changed) {
1088 file.setStartMarker(startm.line, startm.offset) ;
1089 file.setEndMarker(endm.line, endm.offset) ;
1090 _markBlock() ;
1091 }
1092 Marker after = where() ;
1093 if (act == Action::NewLine)
1094 undo.record_action(UndoSt::ActInsert, data, before, after, _startm, _endm) ;
1095
1096 _refresh() ;
1097 modified = 1 ;
1098 // take care of autoindent
1099 }
1100 }
1101
1102 void
_Exit(Action::Actions act)1103 Edit::_Exit(Action::Actions act)
1104 {
1105 if (!(name == SCRATCH_BUFFER_NAME)) {
1106 if (file.markActive() && (!read_only))
1107 _markBlock(1) ;
1108 int c='y' ;
1109 if (undo.is_modified() && _need_to_save()) {
1110 c=win->Question(QTN_LOOSE_CHANGES) ;
1111 }
1112 while ((c != 'y')&& (c!='Y') && (c!= 'n') && (c!='N'))
1113 c=win->Question(QTN_LOOSE_CHANGES) ;
1114 if ((c == 'n') || (c == 'N')) {
1115 win->MessageClear() ;
1116 _refresh() ;
1117 } else {
1118 // win->Erase() ;
1119 win->Refresh() ;
1120 continue_edit = FALSE ;
1121 }
1122 }
1123 }
1124
1125 void
_RealForwardChar(Action::Actions act)1126 Edit::_RealForwardChar(Action::Actions act)
1127 {
1128 _relocate_curx(1) ;
1129 }
1130
1131 void
_RealBackwardChar(Action::Actions act)1132 Edit::_RealBackwardChar(Action::Actions act)
1133 {
1134 _relocate_curx(-1) ;
1135 }
1136
1137 void
_NextLogicalWord(Action::Actions act)1138 Edit::_NextLogicalWord(Action::Actions act)
1139 {
1140 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1141 char ch = *(const char *)(chr) ;
1142 while ( (strchr(LETTERS,ch)) && ((current_line < file.lines()) || (curx < ((aString&)file.line(current_line)).length()))) {
1143 _RealForwardChar(act) ;
1144 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1145 ch = *(const char *)(chr) ;
1146 }
1147 while ( (!strchr(LETTERS,ch)) && ((current_line < file.lines()) || (curx < ((aString&)file.line(current_line)).length()))) {
1148 _RealForwardChar(act) ;
1149 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1150 ch = *(const char *)(chr) ;
1151 }
1152 }
1153
1154 void
_PreviousLogicalWord(Action::Actions act)1155 Edit::_PreviousLogicalWord(Action::Actions act)
1156 {
1157 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1158 char ch = *(const char *)(chr) ;
1159 while ( (strchr(LETTERS,ch)) && ((current_line > 1) || (curx > 1))) {
1160 _RealBackwardChar(act) ;
1161 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1162 ch = *(const char *)(chr) ;
1163 }
1164 while ( (!strchr(LETTERS,ch)) &&((current_line > 1) || (curx > 1))) {
1165 _RealBackwardChar(act) ;
1166 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1167 ch = *(const char *)(chr) ;
1168 }
1169 }
1170
1171 void
_WordRight(Action::Actions act)1172 Edit::_WordRight(Action::Actions act)
1173 {
1174 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1175 char ch = *(const char *)(chr) ;
1176 int cur_line = current_line ;
1177 int cur_x = curx ;
1178 int ocur_line ;
1179 int ocur_x = 0 ;
1180
1181 while ( (strchr(LETTERS,ch)) && ((cur_line != ocur_line) || (cur_x != ocur_x)) ) {
1182 ocur_line = cur_line ;
1183 ocur_x = cur_x ;
1184 _ForwardChar(act) ;
1185 cur_line = current_line ;
1186 cur_x = curx ;
1187 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1188 ch = *(const char *)(chr) ;
1189 }
1190 while ( (!strchr(LETTERS,ch)) &&((cur_line != ocur_line) || (cur_x != ocur_x)) ) {
1191 ocur_line = cur_line ;
1192 ocur_x = cur_x ;
1193 _ForwardChar(act) ;
1194 cur_line = current_line ;
1195 cur_x = curx ;
1196 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1197 ch = *(const char *)(chr) ;
1198 }
1199 }
1200
1201 void
_WordLeft(Action::Actions act)1202 Edit::_WordLeft(Action::Actions act)
1203 {
1204 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1205 char ch = *(const char *)(chr) ;
1206 int cur_line = current_line ;
1207 int cur_x = curx ;
1208 int ocur_line = 0 ;
1209 int ocur_x = 0 ;
1210
1211 while ( (strchr(LETTERS,ch)) && ((cur_line != ocur_line) || (cur_x != ocur_x)) ) {
1212 ocur_line = cur_line ;
1213 ocur_x = cur_x ;
1214 _BackwardChar(act) ;
1215 cur_line = current_line ;
1216 cur_x = curx ;
1217 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1218 ch = *(const char *)(chr) ;
1219 }
1220 while ( (!strchr(LETTERS,ch)) &&((cur_line != ocur_line) || (cur_x != ocur_x)) ) {
1221 ocur_line = cur_line ;
1222 ocur_x = cur_x ;
1223 _BackwardChar(act) ;
1224 cur_line = current_line ;
1225 cur_x = curx ;
1226 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1227 ch = *(const char *)(chr) ;
1228 }
1229 }
1230
1231
1232 void
_ForwardChar(Action::Actions act)1233 Edit::_ForwardChar(Action::Actions act)
1234 {
1235 _forward() ;
1236 }
1237
1238 void
_BackwardChar(Action::Actions act)1239 Edit::_BackwardChar(Action::Actions act)
1240 {
1241 _backward() ;
1242 }
1243
1244 void
_NextLine(Action::Actions act)1245 Edit::_NextLine(Action::Actions act)
1246 {
1247 action.getLastChar() ;
1248 _next_line() ;
1249 }
1250
1251 void
_PreviousLine(Action::Actions act)1252 Edit::_PreviousLine(Action::Actions act)
1253 {
1254 action.getLastChar() ;
1255 _previous_line() ;
1256 }
1257
1258 void
_Home(Action::Actions act)1259 Edit::_Home(Action::Actions act)
1260 {
1261 for (;curx >1; _relocate_curx(-1)) ;
1262 }
1263
1264 void
_End(Action::Actions act)1265 Edit::_End(Action::Actions act)
1266 {
1267 int tmp = file.line(current_line).length() ;
1268 for (;curx<tmp ; _relocate_curx(+1)) ;
1269 }
1270
1271 void
_BeginningOfFile(Action::Actions act)1272 Edit::_BeginningOfFile(Action::Actions act)
1273 {
1274 for (;current_line>1 ; _previous_page(0)) ;
1275 for (;curx>1; _relocate_curx(-1)) ;
1276 win->Refresh() ;
1277 _refresh() ;
1278 }
1279
1280 void
_EndOfFile(Action::Actions act)1281 Edit::_EndOfFile(Action::Actions act)
1282 {
1283 for (;(current_line < file.lines()) ||
1284 ((current_line == file.lines()) &&
1285 (current_offset <
1286 (file.line(current_line)).line_count(sizex) - 1)) ;
1287 _next_page(0)) ;
1288 _End(Action::Null) ;
1289 win->Refresh() ;
1290 _refresh() ;
1291 }
1292
1293 void
_PgUp(Action::Actions act)1294 Edit::_PgUp(Action::Actions act)
1295 {
1296 _previous_page() ;
1297 esc = 0 ;
1298 }
1299
1300 void
_PgDn(Action::Actions act)1301 Edit::_PgDn(Action::Actions act)
1302 {
1303 _next_page() ;
1304 esc = 0 ;
1305 }
1306
1307 void
_Char(Action::Actions act)1308 Edit::_Char(Action::Actions act)
1309 {
1310 int ch = action.getLastChar() ;
1311 Marker startm = file.getStartMarker() ;
1312 Marker endm = file.getEndMarker() ;
1313 Marker _startm = file.getStartMarker() ;
1314 Marker _endm = file.getEndMarker() ;
1315
1316 if (act != last_action)
1317 undo.invalidate_current() ;
1318
1319 if (!read_only) {
1320 Marker before = where() ;
1321 aString data = "" ;
1322
1323 int changed = 0 ;
1324 int add = (file.line(current_line))._insert_ch(curx,current_offset,
1325 input.translate_char(ch),
1326 _x_position) ;
1327 data+= input.translate_char(ch) ;
1328 if ((startm.line == current_line) && (startm.offset+1 > curx)) {
1329 startm.offset++ ;
1330 changed = 1 ;
1331 }
1332 if ((endm.line == current_line) && (endm.offset >= curx)) {
1333 endm.offset++ ;
1334 changed = 1 ;
1335 }
1336
1337 if (changed) {
1338 file.setStartMarker(startm.line, startm.offset) ;
1339 file.setEndMarker(endm.line, endm.offset) ;
1340 _markBlock() ;
1341 }
1342
1343 delay_compilation++ ;
1344 // file.recompile_section(sizex, 0) ; // 0 tells recompile_section to not continue after the first line
1345 _relocate_curx(add) ;
1346 win->Move(cury-1+screen_start_line,_x_pos()+screen_start_column) ;
1347 modified = 1 ;
1348 _calc_curx() ;
1349 Marker after = where() ;
1350 undo.record_action(UndoSt::ActInsert, data, before, after, _startm, _endm) ;
1351 _refresh() ;
1352 }
1353 }
1354
1355
1356 void
_Undo(Action::Actions act)1357 Edit::_Undo(Action::Actions act)
1358 {
1359 undo.undo_last_action() ;
1360 _relocate_curx(0) ;
1361 int last = undo.get_last_saved() ;
1362 sprintf(buffer, "Undo: %d of %d..+%d modifications since last save", undo.get_current()-last,-last, undo.get_count()-last) ;
1363 win->Message(buffer) ;
1364 _refresh() ;
1365 }
1366
1367 void
_Redo(Action::Actions act)1368 Edit::_Redo(Action::Actions act)
1369 {
1370 undo.redo_last_action() ;
1371 _relocate_curx(0) ;
1372 int last = undo.get_last_saved() ;
1373 sprintf(buffer, "Redo: %d of %d..+%d modifications since last save", undo.get_current()-last,-last, undo.get_count()-last) ;
1374 win->Message(buffer) ;
1375 _refresh() ;
1376 }
1377
1378 void
_LaxetCommandHelp(Action::Actions act)1379 Edit::_LaxetCommandHelp(Action::Actions act)
1380 {
1381 // find current word
1382 if ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())!=VALID_LAXET_COMMAND) {
1383 win->scr->TemporaryExit(0,"latexman asdf",1) ;
1384 refresh() ;
1385 return ;
1386 }
1387
1388 aString chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1389 char ch = *(const char *)(chr) ;
1390 if (ch == '\\') {
1391 _RealForwardChar(act) ;
1392 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1393 ch = *(const char *)(chr) ;
1394 }
1395
1396 while ( (strchr(LETTERS,ch)) && ((current_line > 1) || (curx > 1))) {
1397 _RealBackwardChar(act) ;
1398 chr = ((aString &)file.line(current_line)).at(curx-1,curx) ;
1399 ch = *(const char *)(chr) ;
1400 }
1401 if ( (!strchr(LETTERS,ch))){
1402 _RealForwardChar(act) ;
1403 }
1404 aString word = "" ;
1405 int count = 0 ;
1406 if ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==VALID_LAXET_COMMAND) {
1407 while ((file.line(current_line)).getCurrentXcode(current_offset,_x_pos())==VALID_LAXET_COMMAND) {
1408 word += ((aString &)file.line(current_line)).at(curx-1,curx) ;
1409 count++ ;
1410 _RealForwardChar(act) ;
1411 }
1412 for (;count>0; count--) _RealBackwardChar(act) ;
1413 char buffer[100] ;
1414 sprintf(buffer, "latexman \\%s", (char *)(const char *)word) ;
1415 win->scr->TemporaryExit(0,buffer,1) ;
1416 refresh() ;
1417 }
1418 }
1419
1420