1 /*    e_cmds.cpp
2  *
3  *    Copyright (c) 1994-1996, Marko Macek
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9 
10 #include "egui.h"
11 #include "i_modelview.h"
12 #include "o_buflist.h"
13 #include "s_util.h"
14 
MoveLeft()15 int EBuffer::MoveLeft() {
16     if (CP.Col == 0 || !VCount) return 0;
17     SetPos(CP.Col - 1, CP.Row, tmLeft);
18     return 1;
19 }
20 
MoveRight()21 int EBuffer::MoveRight() {
22     if (!VCount) return 0;
23     SetPos(CP.Col + 1, CP.Row, tmRight);
24     return 1;
25 }
26 
MoveUp()27 int EBuffer::MoveUp() {
28     if (CP.Row == 0) return 0;
29     SetPos(CP.Col, CP.Row - 1, tmLeft);
30     return 1;
31 }
32 
MoveDown()33 int EBuffer::MoveDown() {
34     if (CP.Row + 1 >= VCount) return 0;
35     SetPos(CP.Col, CP.Row + 1, tmLeft);
36     return 1;
37 }
38 
MovePrev()39 int EBuffer::MovePrev() {
40     if (MoveLeft()) return 1;
41     if (MoveUp() && MoveLineEnd()) return 1;
42     return 0;
43 }
44 
MoveNext()45 int EBuffer::MoveNext() {
46     if (CP.Col < LineLen())
47         if (MoveRight()) return 1;
48     if (MoveDown() && MoveLineStart()) return 1;
49     return 0;
50 }
51 
52 
MoveWordLeftX(int start)53 int EBuffer::MoveWordLeftX(int start) {
54     if (CP.Col > 0) {
55         int wS = start, wE = 1 - start;
56         PELine L = VLine(CP.Row);
57         int C, P;
58 
59         C = CP.Col;
60         P = CharOffset(L, C);
61 
62         if (P > L->Count) P = L->Count;
63         if (P > 0) {
64             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == wE)) P--;
65             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == wS)) P--;
66             C = ScreenPos(L, P);
67             return SetPos(C, CP.Row);
68         } else return 0;
69     } else return 0;
70 }
71 
72 
MoveWordRightX(int start)73 int EBuffer::MoveWordRightX(int start) {
74     PELine L = VLine(CP.Row);
75     int C, P;
76     int wS = start, wE = 1 - start;
77 
78     C = CP.Col;
79     P = CharOffset(L, C);
80 
81     if (P >= L->Count) return 0;
82 
83     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == wS)) P++;
84     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == wE)) P++;
85     C = ScreenPos(L, P);
86     return SetPos(C, CP.Row);
87 }
88 
MoveWordLeft()89 int EBuffer::MoveWordLeft() {
90     return MoveWordLeftX(1);
91 }
92 
MoveWordRight()93 int EBuffer::MoveWordRight() {
94     return MoveWordRightX(1);
95 }
96 
MoveWordPrev()97 int EBuffer::MoveWordPrev() {
98     if (MoveWordLeft()) return 1;
99     if (MoveUp() && MoveLineEnd()) return 1;
100     return 0;
101 }
102 
MoveWordNext()103 int EBuffer::MoveWordNext() {
104     if (MoveWordRight()) return 1;
105     if (MoveDown() && MoveLineStart()) return 1;
106     return 0;
107 }
108 
MoveWordEndLeft()109 int EBuffer::MoveWordEndLeft() {
110     return MoveWordLeftX(0);
111 }
112 
MoveWordEndRight()113 int EBuffer::MoveWordEndRight() {
114     return MoveWordRightX(0);
115 }
116 
MoveWordEndPrev()117 int EBuffer::MoveWordEndPrev() {
118     if (MoveWordEndLeft()) return 1;
119     if (MoveUp() && MoveLineEnd()) return 1;
120     return 0;
121 }
122 
MoveWordEndNext()123 int EBuffer::MoveWordEndNext() {
124     if (MoveWordEndRight()) return 1;
125     if (MoveDown() && MoveLineStart()) return 1;
126     return 0;
127 }
128 
MoveWordOrCapLeft()129 int EBuffer::MoveWordOrCapLeft() {
130     if (CP.Col > 0) {
131         PELine L = VLine(CP.Row);
132         int C, P;
133 
134         C = CP.Col;
135         P = CharOffset(L, C);
136 
137         if (P > L->Count) P = L->Count;
138         if (P > 0) {
139             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 0)) P--;
140             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 0)) P--;
141             while ((P > 0) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 1)) P--;
142             C = ScreenPos(L, P);
143             return SetPos(C, CP.Row);
144         } else return 0;
145     } else return 0;
146 }
147 
MoveWordOrCapRight()148 int EBuffer::MoveWordOrCapRight() {
149     PELine L = VLine(CP.Row);
150     int C, P;
151 
152     C = CP.Col;
153     P = CharOffset(L, C);
154 
155     if (P >= L->Count) return 0;
156 
157     while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++;
158     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++;
159     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 0)) P++;
160     C = ScreenPos(L, P);
161     return SetPos(C, CP.Row);
162 }
163 
MoveWordOrCapPrev()164 int EBuffer::MoveWordOrCapPrev() {
165     if (MoveWordOrCapLeft()) return 1;
166     if (MoveUp() && MoveLineEnd()) return 1;
167     return 0;
168 }
169 
MoveWordOrCapNext()170 int EBuffer::MoveWordOrCapNext() {
171     if (MoveWordOrCapRight()) return 1;
172     if (MoveDown() && MoveLineStart()) return 1;
173     return 0;
174 }
175 
MoveWordOrCapEndLeft()176 int EBuffer::MoveWordOrCapEndLeft() {
177     if (CP.Col > 0) {
178         PELine L = VLine(CP.Row);
179         int C, P;
180 
181         C = CP.Col;
182         P = CharOffset(L, C);
183 
184         if (P > L->Count) P = L->Count;
185         if (P > 0) {
186             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 0)) P--;
187             while ((P > 0) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 1)) P--;
188             while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 0)) P--;
189             C = ScreenPos(L, P);
190             return SetPos(C, CP.Row);
191         } else return 0;
192     } else return 0;
193 }
194 
MoveWordOrCapEndRight()195 int EBuffer::MoveWordOrCapEndRight() {
196     PELine L = VLine(CP.Row);
197     int C, P;
198 
199     C = CP.Col;
200     P = CharOffset(L, C);
201 
202     if (P >= L->Count) return 0;
203 
204     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 0)) P++;
205     while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++;
206     while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++;
207     C = ScreenPos(L, P);
208     return SetPos(C, CP.Row);
209 }
210 
MoveWordOrCapEndPrev()211 int EBuffer::MoveWordOrCapEndPrev() {
212     if (MoveWordOrCapEndLeft()) return 1;
213     if (MoveUp() && MoveLineEnd()) return 1;
214     return 0;
215 }
216 
MoveWordOrCapEndNext()217 int EBuffer::MoveWordOrCapEndNext() {
218     if (MoveWordOrCapEndRight()) return 1;
219     if (MoveDown() && MoveLineStart()) return 1;
220     return 0;
221 }
222 
MoveLineStart()223 int EBuffer::MoveLineStart() {
224     SetPos(0, CP.Row);
225     return 1;
226 }
227 
MoveLineEnd()228 int EBuffer::MoveLineEnd() {
229     SetPos(LineLen(VToR(CP.Row)), CP.Row);
230     return 1;
231 }
232 
MovePageUp()233 int EBuffer::MovePageUp() {
234     return ScrollDown(GetVPort()->Rows);
235 }
236 
MovePageDown()237 int EBuffer::MovePageDown() {
238     return ScrollUp(GetVPort()->Rows);
239 }
240 
MovePageLeft()241 int EBuffer::MovePageLeft() {
242     return ScrollRight(GetVPort()->Cols);
243 }
244 
MovePageRight()245 int EBuffer::MovePageRight() {
246     return ScrollRight(GetVPort()->Cols);
247 }
248 
MovePageStart()249 int EBuffer::MovePageStart() {
250     SetPos(CP.Col, GetVPort()->TP.Row, tmLeft);
251     return 1;
252 }
253 
MovePageEnd()254 int EBuffer::MovePageEnd() {
255     SetNearPos(CP.Col,
256                GetVPort()->TP.Row +
257                GetVPort()->Rows - 1, tmLeft);
258     return 1;
259 }
260 
MoveFileStart()261 int EBuffer::MoveFileStart() {
262     SetPos(0, 0);
263     return 1;
264 }
265 
MoveFileEnd()266 int EBuffer::MoveFileEnd() {
267     SetPos(LineLen(VToR(VCount - 1)), VCount - 1);
268     return 1;
269 }
270 
MoveBlockStart()271 int EBuffer::MoveBlockStart() {
272     if (BB.Col == -1 && BB.Row == -1)
273         return 0;
274     assert(BB.Col >= 0 && BB.Row >= 0 && BB.Row < RCount);
275     if (SetPosR(BB.Col, BB.Row))
276         return 1;
277     return 0;
278 }
279 
MoveBlockEnd()280 int EBuffer::MoveBlockEnd() {
281     if (BE.Col == -1 && BE.Row == -1)
282         return 0;
283     assert(BE.Col >= 0 && BE.Row >= 0 && BE.Row < RCount);
284     if (SetPosR(BE.Col, BE.Row))
285         return 1;
286     return 0;
287 }
288 
MoveFirstNonWhite()289 int EBuffer::MoveFirstNonWhite() {
290     int C = 0, P = 0;
291     PELine L = VLine(CP.Row);
292 
293     while (C < L->Count) {
294         if (L->Chars[C] == ' ') P++;
295         else if (L->Chars[C] == 9) P = NextTab(P, BFI(this, BFI_TabSize));
296         else break;
297         C++;
298     }
299     if (SetPos(P, CP.Row) == 0) return 0;
300     return 1;
301 }
302 
MoveLastNonWhite()303 int EBuffer::MoveLastNonWhite() {
304     int C = LineLen(), P;
305     PELine L = VLine(CP.Row);
306 
307     while (C > 0) {
308         if (L->Chars[C - 1] == ' ' || L->Chars[C - 1] == 9) C--;
309         else break;
310     }
311     P = ScreenPos(VLine(CP.Row), C);
312     if (SetPos(P, CP.Row) == 0) return 0;
313     return 1;
314 }
315 
MovePrevEqualIndent()316 int EBuffer::MovePrevEqualIndent() {
317     int L = VToR(CP.Row);
318     int I = LineIndented(L);
319 
320     while (--L >= 0)
321         if ((RLine(L)->Count > 0) && (LineIndented(L) == I))
322             return SetPosR(I, L);
323     return 0;
324 }
325 
MoveNextEqualIndent()326 int EBuffer::MoveNextEqualIndent() {
327     int L = VToR(CP.Row);
328     int I = LineIndented(L);
329 
330     while (L++ < RCount - 1)
331         if ((RLine(L)->Count > 0) && (LineIndented(L) == I))
332             return SetPosR(I, L);
333     return 0;
334 }
335 
MoveNextTab()336 int EBuffer::MoveNextTab() {
337     int P = CP.Col;
338 
339     P = NextTab(P, BFI(this, BFI_TabSize));
340     return SetPos(P, CP.Row);
341 }
342 
MovePrevTab()343 int EBuffer::MovePrevTab() {
344     int P = CP.Col;
345 
346     if (P > 0) {
347         P = ((P - 1) / BFI(this, BFI_TabSize)) * BFI(this, BFI_TabSize);
348         return SetPos(P, CP.Row);
349     } else return 0;
350 }
351 
MoveLineTop()352 int EBuffer::MoveLineTop() {
353     if (View)
354         if (GetVPort()->SetTop(GetVPort()->TP.Col, CP.Row) == 0) return 0;
355     return 1;
356 }
357 
MoveLineCenter()358 int EBuffer::MoveLineCenter() {
359     if (View) {
360         int Row = CP.Row - GetVPort()->Rows / 2;
361 
362         if (Row < 0) Row = 0;
363         if (GetVPort()->SetTop(GetVPort()->TP.Col, Row) == 0) return 0;
364     }
365     return 1;
366 }
367 
MoveLineBottom()368 int EBuffer::MoveLineBottom() {
369     if (View) {
370         int Row = CP.Row - GetVPort()->Rows + 1;
371 
372         if (Row < 0) Row = 0;
373         if (GetVPort()->SetTop(GetVPort()->TP.Col, Row) == 0) return 0;
374     }
375     return 1;
376 }
377 
MovePrevPos()378 int EBuffer::MovePrevPos() {
379     if (PrevPos.Col == -1 || PrevPos.Row == -1) return 0;
380     if (SetPosR(PrevPos.Col, PrevPos.Row) == 0) return 0;
381     return 1;
382 }
383 
MoveSavedPosCol()384 int EBuffer::MoveSavedPosCol() {
385     if (SavedPos.Col == -1) return 0;
386     if (SetPos(SavedPos.Col, CP.Row) == 0) return 0;
387     return 1;
388 }
389 
MoveSavedPosRow()390 int EBuffer::MoveSavedPosRow() {
391     if (SavedPos.Row == -1) return 0;
392     if (SetPosR(CP.Col, SavedPos.Row) == 0) return 0;
393     return 1;
394 }
395 
MoveSavedPos()396 int EBuffer::MoveSavedPos() {
397     if (SavedPos.Col == -1 || SavedPos.Row == -1) return 0;
398     if (SetPosR(SavedPos.Col, SavedPos.Row) == 0) return 0;
399     return 1;
400 }
401 
SavePos()402 int EBuffer::SavePos() {
403     SavedPos = CP;
404     SavedPos.Row = VToR(CP.Row);
405     return 1;
406 }
407 
MoveTabStart()408 int EBuffer::MoveTabStart() {
409     PELine X = VLine(CP.Row);
410     int C = CharOffset(X, CP.Col);
411 
412     if (C < X->Count)
413         if (X->Chars[C] == 9)
414             return SetPos(ScreenPos(X, C), CP.Row);
415     return 1;
416 }
417 
MoveTabEnd()418 int EBuffer::MoveTabEnd() {
419     PELine X = VLine(CP.Row);
420     int C = CharOffset(X, CP.Col);
421 
422     if (C < X->Count)
423         if (X->Chars[C] == 9)
424             if (ScreenPos(X, C) < CP.Col)
425                 return SetPos(ScreenPos(X, C + 1), CP.Row);
426     return 1;
427 }
428 
ScrollLeft(int Cols)429 int EBuffer::ScrollLeft(int Cols) {
430     int C = GetVPort()->TP.Col;
431     if (SetNearPos(CP.Col + Cols, CP.Row, tmLeft) == 0) return 0;
432     if (GetVPort()->SetTop(C + Cols, GetVPort()->TP.Row) == 0) return 0;
433     return 1;
434 }
435 
ScrollRight(int Cols)436 int EBuffer::ScrollRight(int Cols) {
437     int C = GetVPort()->TP.Col;
438     if (SetNearPos(CP.Col - Cols, CP.Row, tmLeft) == 0) return 0;
439     if (GetVPort()->SetTop(C - Cols, GetVPort()->TP.Row) == 0) return 0;
440     return 1;
441 }
442 
ScrollDown(int Lines)443 int EBuffer::ScrollDown(int Lines) {
444     int L = GetVPort()->TP.Row;
445     if (SetNearPos(CP.Col, CP.Row - Lines, tmLeft) == 0) return 0;
446     if (GetVPort()->SetTop(GetVPort()->TP.Col, L - Lines) == 0) return 0;
447     return 1;
448 }
449 
ScrollUp(int Lines)450 int EBuffer::ScrollUp(int Lines) {
451     int L = GetVPort()->TP.Row;
452     if (SetNearPos(CP.Col, CP.Row + Lines, tmLeft) == 0) return 0;
453     if (GetVPort()->SetTop(GetVPort()->TP.Col, L + Lines) == 0) return 0;
454     return 1;
455 }
456 
MoveBeginOrNonWhite()457 int EBuffer::MoveBeginOrNonWhite() {
458     if (CP.Col == 0)
459         return MoveFirstNonWhite();
460 
461     return MoveLineStart();
462 }
463 
MoveBeginLinePageFile()464 int EBuffer::MoveBeginLinePageFile() {
465     int L = GetVPort()->TP.Row;
466 
467     if (CP.Col == 0 && CP.Row == L)
468         return MoveFileStart();
469     else if (CP.Col == 0)
470         return MovePageStart();
471 
472     return MoveLineStart();
473 }
474 
MoveEndLinePageFile()475 int EBuffer::MoveEndLinePageFile() {
476     int L = GetVPort()->TP.Row + GetVPort()->Rows - 1;
477     int Len = LineLen();
478 
479     if (CP.Col == Len && CP.Row == L)
480         return MoveFileEnd();
481     else if (CP.Col == Len)
482         if (MovePageEnd() == 0)
483             return 0;
484     return MoveLineEnd();
485 }
486 
KillLine()487 int EBuffer::KillLine() {
488     int Y = VToR(CP.Row);
489 
490     if (Y == RCount - 1) {
491         if (DelText(Y, 0, LineLen())) return 1;
492     } else
493         if (DelLine(Y)) return 1;
494     return 0;
495 }
496 
KillChar()497 int EBuffer::KillChar() {
498     int Y = VToR(CP.Row);
499     if (CP.Col < LineLen()) {
500         if (DelText(Y, CP.Col, 1)) return 1;
501     } else if (LineJoin()) return 1;
502     return 0;
503 }
504 
KillCharPrev()505 int EBuffer::KillCharPrev() {
506     if (CP.Col == 0) {
507         if (CP.Row > 0)
508             if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0;
509         if (!MoveUp()) return 0;
510         if (!MoveLineEnd()) return 0;
511         if (LineJoin()) return 1;
512     } else {
513         if (!MovePrev()) return 0;
514         if (DelText(CP.Row, CP.Col, 1)) return 1;
515     }
516     return 0;
517 }
518 
KillWord()519 int EBuffer::KillWord() {
520     int Y = VToR(CP.Row);
521     if (CP.Col >= LineLen()) {
522         if (KillChar() == 0) return 0;
523     } else {
524         PELine L = RLine(Y);
525         int P = CharOffset(L, CP.Col);
526         int C;
527         int Class = ChClassK(L->Chars[P]);
528 
529         while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++;
530         C = ScreenPos(L, P);
531         if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0;
532     }
533     return 1;
534 }
535 
KillWordPrev()536 int EBuffer::KillWordPrev() {
537     int Y = VToR(CP.Row);
538 
539     if (CP.Col == 0) {
540         if (KillCharPrev() == 0) return 0;
541     } else if (CP.Col > LineLen()) {
542         if (SetPos(LineLen(), CP.Row) == 0) return 0;
543     } else {
544         PELine L = RLine(Y);
545         int P = CharOffset(L, CP.Col);
546         int C;
547         int Class = ChClassK(L->Chars[P - 1]);
548 
549         while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--;
550         C = ScreenPos(L, P);
551         if (DelText(Y, C, CP.Col - C) == 0) return 0;
552         if (SetPos(C, CP.Row) == 0) return 0;
553     }
554     return 1;
555 }
556 
KillWordOrCap()557 int EBuffer::KillWordOrCap() {
558     int Y = VToR(CP.Row);
559     if (CP.Col >= LineLen()) {
560         if (KillChar() == 0) return 0;
561     } else {
562         PELine L = VLine(CP.Row);
563         int P = CharOffset(L, CP.Col);
564         int C;
565         int Class = ChClassK(L->Chars[P]);
566 
567         if (Class == 1) {
568             if (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)
569                 while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++;
570             while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++;
571         } else while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++;
572         C = ScreenPos(L, P);
573         if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0;
574     }
575     return 1;
576 }
577 
KillWordOrCapPrev()578 int EBuffer::KillWordOrCapPrev() {
579     int Y = VToR(CP.Row);
580 
581     if (CP.Col == 0) {
582         if (KillCharPrev() == 0) return 0;
583     } else if (CP.Col > LineLen()) {
584         if (SetPos(LineLen(), CP.Row) == 0) return 0;
585     } else {
586         PELine L = RLine(Y);
587         int P = CharOffset(L, CP.Col);
588         int C;
589         int Class = ChClassK(L->Chars[P - 1]);
590 
591         if (Class == 1) {
592             if (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 0)
593                 while ((P > 0) && (WGETBIT(Flags.WordChars, L->Chars[P - 1]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 0)) P--;
594             while ((P > 0) && (WGETBIT(Flags.CapitalChars, L->Chars[P - 1]) == 1)) P--;
595         } else while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--;
596         C = ScreenPos(L, P);
597         if (DelText(Y, C, CP.Col - C) == 0) return 0;
598         if (SetPos(C, CP.Row) == 0) return 0;
599     }
600     return 1;
601 }
602 
KillToLineStart()603 int EBuffer::KillToLineStart() {
604     int Y = VToR(CP.Row);
605     if (DelText(Y, 0, CP.Col) == 0) return 0;
606     if (MoveLineStart() == 0) return 0;
607     return 1;
608 }
609 
KillToLineEnd()610 int EBuffer::KillToLineEnd() {
611     int Y = VToR(CP.Row);
612     if (DelText(Y, CP.Col, LineLen() - CP.Col)) return 1;
613     return 0;
614 }
615 
KillBlock()616 int EBuffer::KillBlock() {
617     return BlockKill();
618 }
619 
KillBlockOrChar()620 int EBuffer::KillBlockOrChar() {
621     if (CheckBlock() == 0)
622         return KillChar();
623     else
624         return BlockKill();
625 }
626 
KillBlockOrCharPrev()627 int EBuffer::KillBlockOrCharPrev() {
628     if (CheckBlock() == 0)
629         return KillCharPrev();
630     else
631         return BlockKill();
632 }
633 
BackSpace()634 int EBuffer::BackSpace() {
635     int Y = VToR(CP.Row);
636 
637     if (CheckBlock() == 1 && BFI(this, BFI_BackSpKillBlock)) {
638         if (BlockKill() == 0)
639             return 0;
640     } else if (BFI(this, BFI_WordWrap) == 2 && CP.Row > 0 && !IsLineBlank(Y - 1) &&
641                CP.Col <= BFI(this, BFI_LeftMargin) && CP.Col <= LineIndented(Y))
642     {
643         if (SetPos(LineLen(Y - 1), CP.Row - 1) == 0) return 0;
644     } else if (CP.Col == 0) {
645         if (CP.Row > 0)
646             if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0;
647         if (MoveUp() == 0) return 0;
648         if (MoveLineEnd() == 0) return 0;
649         if (LineJoin() == 0) return 0;
650     } else {
651         if (BFI(this, BFI_BackSpUnindents) && (LineIndented(Y) >= CP.Col)) {
652             int C = CP.Col, C1 = 0;
653             int L = VToR(CP.Row);
654 
655             C1 = C;
656             while (L > 0 && (IsLineBlank(L - 1) || (C1 = LineIndented(L - 1)) >= C)) L--;
657             if (L == 0) C1 = 0;
658             if (C1 == C) C1--;
659             if (C1 < 0) C1 = 0;
660             if (C1 > C) C1 = C;
661             if (SetPos(C1, CP.Row) == 0) return 0;
662             if (C > LineIndented(Y)) return 0;
663             if (DelText(Y, C1, C - C1) == 0) return 0;
664         } else if (BFI(this, BFI_BackSpKillTab)) {
665             int P;
666             int C = CP.Col, C1;
667 
668             P = CharOffset(RLine(Y), C - 1);
669             C1 = ScreenPos(RLine(Y), P);
670             if (SetPos(C1, CP.Row) == 0) return 0;
671             if (DelText(Y, C1, C - C1) == 0) return 0;
672         } else {
673             if (MovePrev() == 0) return 0;
674             if (DelText(Y, CP.Col, 1) == 0) return 0;
675         }
676     }
677 #ifdef CONFIG_WORDWRAP
678     if (BFI(this, BFI_WordWrap) == 2) {
679         if (DoWrap(0) == 0) return 0;
680     }
681 #endif
682     if (BFI(this, BFI_Trim)) {
683         Y = VToR(CP.Row);
684         if (TrimLine(Y) == 0) return 0;
685     }
686     return 1;
687 }
688 
Delete()689 int EBuffer::Delete() {
690     int Y = VToR(CP.Row);
691     if (CheckBlock() == 1 && BFI(this, BFI_DeleteKillBlock)) {
692         if (BlockKill() == 0)
693             return 0;
694     } else if (CP.Col < LineLen()) {
695         if (BFI(this, BFI_DeleteKillTab)) {
696             int P;
697             int C = CP.Col, C1;
698 
699             P = CharOffset(RLine(Y), C);
700             C1 = ScreenPos(RLine(Y), P + 1);
701             if (DelText(Y, C, C1 - C) == 0) return 0;
702         } else
703             if (DelText(Y, CP.Col, 1) == 0) return 0;
704     } else
705         if (LineJoin() == 0) return 0;
706 #ifdef CONFIG_WORDWRAP
707     if (BFI(this, BFI_WordWrap) == 2) {
708         if (DoWrap(0) == 0) return 0;
709         if (CP.Col >= LineLen(Y))
710             if (CP.Row + 1 < VCount) {
711                 if (SetPos(BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0;
712             }
713     }
714 #endif
715     if (BFI(this, BFI_Trim))
716         if (TrimLine(VToR(CP.Row)) == 0)
717             return 0;
718     return 1;
719 }
720 
LineInsert()721 int EBuffer::LineInsert() {
722     if (InsLine(VToR(CP.Row), 0)) return 1;
723     return 0;
724 }
725 
LineAdd()726 int EBuffer::LineAdd() {
727     if (InsLine(VToR(CP.Row), 1) && MoveDown()) return 1;
728     return 0;
729 }
730 
LineSplit()731 int EBuffer::LineSplit() {
732     if (SplitLine(VToR(CP.Row), CP.Col) == 0) return 0;
733     if (BFI(this, BFI_Trim))
734 	if (TrimLine(VToR(CP.Row)) == 0) return 0;
735     return 1;
736 }
737 
LineJoin()738 int EBuffer::LineJoin() {
739     if (JoinLine(VToR(CP.Row), CP.Col)) return 1;
740     return 0;
741 }
742 
LineNew()743 int EBuffer::LineNew() {
744     if (SplitLine(VToR(CP.Row), CP.Col) == 0)
745         return 0;
746 
747     if (!MoveDown())
748         return 0;
749 
750     if (CP.Col > 0) {
751 
752         if (!MoveLineStart())
753             return 0;
754 
755         //int Indent = LineIndented(VToR(CP.Row));
756 
757         if (!LineIndent())
758             return 0;
759 
760         //if (Indent > 0)
761         //  if (InsText(Row, C, Indent, 0) == 0)
762         //    return 0;
763 
764         if (BFI(this, BFI_Trim))
765             if (TrimLine(VToR(CP.Row - 1)) == 0)
766                 return 0;
767     }
768     return 1;
769 }
770 
LineIndent()771 int EBuffer::LineIndent() {
772     int rc = 1;
773 
774     if (BFI(this, BFI_AutoIndent)) {
775         int L = VToR(CP.Row);
776 
777         switch (BFI(this, BFI_IndentMode)) {
778 #ifdef CONFIG_INDENT_C
779         case INDENT_C: rc = Indent_C(this, L, 1); break;
780 #endif
781 #ifdef CONFIG_INDENT_REXX
782         case INDENT_REXX: rc = Indent_REXX(this, L, 1); break;
783 #endif
784 #ifdef CONFIG_INDENT_SIMPLE
785         case INDENT_SIMPLE: rc = Indent_SIMPLE(this, L, 1); break;
786 #endif
787         default: rc = Indent_Plain(this, L, 1); break;
788         }
789     }
790     if (rc == 0) return 0;
791     if (BFI(this, BFI_Trim))
792         if (TrimLine(VToR(CP.Row)) == 0) return 0;
793     return 1;
794 }
795 
LineLen()796 int EBuffer::LineLen() {
797     return LineLen(VToR(CP.Row));
798 }
799 
LineCount()800 int EBuffer::LineCount() {
801     assert(1 == 0);
802     return RCount;
803 }
804 
CLine()805 int EBuffer::CLine() {
806     assert(1 == 0);
807     return VToR(CP.Row);
808 }
809 
CColumn()810 int EBuffer::CColumn() {
811     return CP.Col;
812 }
813 
InsertChar(char aCh)814 int EBuffer::InsertChar(char aCh) {
815     return InsertString(&aCh, 1);
816 }
817 
TypeChar(char aCh)818 int EBuffer::TypeChar(char aCh) { // does abbrev expansion if appropriate
819     if (BFI(this, BFI_InsertKillBlock) == 1)
820         if (CheckBlock() == 1)
821             if (BlockKill() == 0)
822                 return 0;
823 #ifdef CONFIG_ABBREV    //fprintf(stderr, "TypeChar\n");
824     if (ChClass(aCh) == 0 && BFI(this, BFI_Abbreviations) == 1) {
825         PELine L = VLine(CP.Row);
826         int C, P, P1, C1, Len, R;
827         char Str[256];
828         EAbbrev *ab;
829 
830         R = VToR(CP.Row);
831         C = CP.Col;
832         P = CharOffset(L, C);
833         if (P >= 0 && P <= L->Count) {
834             //fprintf(stderr, "TypeChar 1\n");
835             P1 = P;
836             C1 = ScreenPos(L, P);
837             while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_'))) P--;
838             Len = P1 - P;
839             C = ScreenPos(L, P);
840             assert(C1 - C == Len);
841 	    if (Len > 0 && Len < int (sizeof(Str))) {
842                 //fprintf(stderr, "TypeChar 2\n");
843                 memcpy(Str, L->Chars + P, Len);
844                 Str[Len] = 0;
845                 ab = Mode->FindAbbrev(Str);
846                 if (ab) {
847                     //fprintf(stderr, "TypeChar 3\n");
848                     if (ab->Replace != 0) {
849                         //fprintf(stderr, "TypeChar 4\n");
850                         if (DelText(R, C, C1 - C) == 0)
851                             return 0;
852                         if (ab->Replace) {
853                             //fprintf(stderr, "TypeChar 5 %s <- %s\n", ab->Replace, ab->Match);
854                             Len = strlen(ab->Replace);
855                             if (InsText(R, C, Len, ab->Replace) == 0)
856                                 return 0;
857                             if (SetPos(C + Len, CP.Row) == 0)
858                                 return 0;
859                         } else {
860                             if (SetPos(C, CP.Row) == 0)
861                                 return 0;
862                         }
863                     } else {
864                         if (((EGUI *)gui)->ExecMacro(View->MView->Win, ab->Cmd) == 0)
865                             return 0;
866                     }
867                 }
868             }
869         }
870     }
871 #endif
872     return InsertString(&aCh, 1);
873 }
874 
InsertString(const char * aStr,size_t aCount)875 int EBuffer::InsertString(const char *aStr, size_t aCount) {
876     int P;
877     int C, L;
878     int Y = VToR(CP.Row);
879 
880     if (BFI(this, BFI_InsertKillBlock) == 1)
881         if (CheckBlock() == 1)
882             if (BlockKill() == 0)
883                 return 0;
884 
885     if (BFI(this, BFI_Insert) == 0)
886         if (CP.Col < LineLen())
887             if (KillChar() == 0)
888                 return 0;
889     if (InsText(Y, CP.Col, aCount, aStr) == 0)
890         return 0;
891     C = CP.Col;
892     L = VToR(CP.Row);
893     P = CharOffset(RLine(L), C);
894     P += aCount;
895     C = ScreenPos(RLine(L), P);
896     if (SetPos(C, CP.Row) == 0)
897         return 0;
898     if (BFI(this, BFI_Trim))
899         if (TrimLine(L) == 0)
900             return 0;
901 #ifdef CONFIG_WORDWRAP
902     if (BFI(this, BFI_WordWrap) == 2) {
903         if (DoWrap(0) == 0) return 0;
904     } else if (BFI(this, BFI_WordWrap) == 1) {
905         int P, C = CP.Col;
906         PELine LP;
907         int L;
908 
909         if (C > BFI(this, BFI_RightMargin)) {
910             L = CP.Row;
911 
912             C = BFI(this, BFI_RightMargin);
913             P = CharOffset(LP = RLine(L), C);
914             while ((C > BFI(this, BFI_LeftMargin)) &&
915                    ((LP->Chars[P] != ' ') &&
916                     (LP->Chars[P] != 9)))
917                 C = ScreenPos(LP, --P);
918 
919             if (P <= BFI(this, BFI_LeftMargin)) {
920                 C = BFI(this, BFI_RightMargin);
921             } else
922                 C = ScreenPos(LP, P);
923             if (SplitLine(L, C) == 0) return 0;
924             IndentLine(L + 1, BFI(this, BFI_LeftMargin));
925             if (SetPos(CP.Col - C - 1 + BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0;
926         }
927     }
928 #endif
929     return 1;
930 }
931 
InsertSpacesToTab(int TSize)932 int EBuffer::InsertSpacesToTab(int TSize) {
933     int P = CP.Col, P1;
934 
935     if (BFI(this, BFI_InsertKillBlock) == 1)
936         if (CheckBlock() == 1)
937             if (BlockKill() == 0)
938                 return 0;
939 
940     if (TSize <= 0)
941         TSize = BFI(this, BFI_TabSize);
942 
943     P1 = NextTab(P, TSize);
944     if (BFI(this, BFI_Insert) == 0) {
945         if (CP.Col < LineLen())
946             if (DelText(VToR(CP.Row), CP.Col, P1 - P) == 0) return 0;
947     }
948     if (InsText(VToR(CP.Row), CP.Col, P1 - P, 0) == 0) return 0;
949     if (SetPos(P1, CP.Row) == 0) return 0;
950     return 1;
951 }
952 
InsertTab()953 int EBuffer::InsertTab() {
954     return (BFI(this, BFI_SpaceTabs)) ?
955 	InsertSpacesToTab(BFI(this, BFI_TabSize)) : InsertChar(9);
956 }
957 
InsertSpace()958 int EBuffer::InsertSpace() {
959     return TypeChar(32);
960 }
961 
LineIndented(int Row,const char * indentchars)962 int EBuffer::LineIndented(int Row, const char *indentchars) {
963     ELine *l;
964 
965     if (Row < 0) return 0;
966     if (Row >= RCount) return 0;
967     l = RLine(Row);
968     return ScreenPos(l, LineIndentedCharCount(l, indentchars));
969 }
970 
LineIndentedCharCount(ELine * l,const char * indentchars)971 int EBuffer::LineIndentedCharCount(ELine *l, const char *indentchars) {
972     char *PC;
973     int CC, i;
974 
975     if (! l)
976         return 0;
977     if (! indentchars)
978         indentchars = " \t";
979     CC = l->Count;
980     PC = l->Chars;
981     for(i = 0; i < CC; i++) {
982         if (! strchr(indentchars, PC[i]))
983             break;
984     }
985     return i;
986 }
987 
IndentLine(int Row,int Indent)988 int EBuffer::IndentLine(int Row, int Indent) {
989     int I, C;
990     int Ind = Indent;
991 
992     if (Row < 0) return 0;
993     if (Row >= RCount) return 0;
994     if (Indent < 0) Indent = 0;
995     I = LineIndented(Row);
996     if (Indent != I) {
997         if (I > 0)
998             if (DelText(Row, 0, I) == 0) return 0;
999         if (Indent > 0) {
1000             C = 0;
1001             if (BFI(this, BFI_IndentWithTabs)) {
1002                 char ch = 9;
1003 
1004                 while (BFI(this, BFI_TabSize) <= Indent) {
1005                     if (InsText(Row, C, 1, &ch) == 0) return 0;
1006                     Indent -= BFI(this, BFI_TabSize);
1007                     C += BFI(this, BFI_TabSize);
1008                 }
1009             }
1010             if (Indent > 0)
1011                 if (InsText(Row, C, Indent, 0) == 0) return 0;
1012         }
1013     }
1014     return Ind - I;
1015 }
1016 
1017 #ifdef CONFIG_UNDOREDO
CanUndo()1018 int EBuffer::CanUndo() {
1019     if (BFI(this, BFI_Undo) == 0) return 0;
1020     if (US.Num == 0 || US.UndoPtr == 0) return 0;
1021     return 1;
1022 }
1023 
CanRedo()1024 int EBuffer::CanRedo() {
1025     if (BFI(this, BFI_Undo) == 0) return 0;
1026     if (US.Num == 0 || US.UndoPtr == US.Num) return 0;
1027     return 1;
1028 }
1029 #endif
1030 
IsLineBlank(int Row)1031 int EBuffer::IsLineBlank(int Row) {
1032     PELine X = RLine(Row);
1033     int P;
1034 
1035     for (P = 0; P < X->Count; P++)
1036         if (X->Chars[P] != ' ' && X->Chars[P] != 9)
1037             return 0;
1038     return 1;
1039 }
1040 
1041 #ifdef CONFIG_WORDWRAP
1042 #define WFAIL(x) return 0	/*do { puts(#x "\x7"); return -1; } while (0) */
1043 
DoWrap(int WrapAll)1044 int EBuffer::DoWrap(int WrapAll) {
1045     int L, Len, C, P, Ind;
1046     PELine LP;
1047     int Left = BFI(this, BFI_LeftMargin), Right = BFI(this, BFI_RightMargin);
1048     int FirstParaLine;
1049     int NoChange = 0, NoChangeX = 0;
1050 
1051     if (Left >= Right) return 0;
1052 
1053     L = VToR(CP.Row);
1054 
1055     FirstParaLine = 0;
1056     if (L > 0)
1057         if (IsLineBlank(L - 1)) FirstParaLine = L;
1058 
1059     while (L < RCount) {
1060         NoChange = 1;
1061 
1062         if (VToR(CP.Row) != L || L != FirstParaLine) {
1063             if (VToR(CP.Row) == L)
1064                 if (CP.Col <= LineIndented(L))
1065                     if (SetPos(Left, CP.Row) == 0) WFAIL(1);
1066             Ind = IndentLine(L, Left);
1067             if (VToR(CP.Row) == L)
1068                 if (SetPos((CP.Col + Ind > 0) ? CP.Col + Ind : 0, CP.Row) == 0) WFAIL(2);
1069             NoChange = 0;
1070         }
1071         Len = LineLen(L);
1072 
1073         if (IsLineBlank(L)) break;
1074 
1075         if (Len < Right) {
1076             int firstwordbeg = -1;
1077             int firstwordend = -1;
1078             int X;
1079             PELine lp;
1080 
1081             if (L < RCount - 1) {
1082                 IndentLine(L + 1, 0);
1083                 if ((ScreenPos(RLine(L + 1), RLine(L + 1)->Count) == 0) ||
1084                     (RLine(L + 1)->Chars[0] == '>') || (RLine(L + 1)->Chars[0] == '<')) break;
1085             } else
1086                 break;
1087             if (L + 1 >= RCount) break;
1088 
1089             lp = RLine(L + 1);
1090             for (X = 0; X < lp->Count; X++) {
1091                 if (firstwordbeg == -1 &&
1092                     ((lp->Chars[X] != ' ') && (lp->Chars[X] != '\t')))
1093                 {
1094                     firstwordbeg = X;
1095                 } else if (firstwordend == -1 &&
1096                            ((lp->Chars[X] == ' ' || lp->Chars[X] == '\t')))
1097                 {
1098                     firstwordend = X - 1;
1099                 }
1100             }
1101             if (firstwordbeg != -1)
1102                 if (firstwordend == -1)
1103                     firstwordend = lp->Count;
1104 
1105             if (firstwordend == -1) break;
1106             if (Right - Len > firstwordend - firstwordbeg) {
1107                 if (JoinLine(L, Len + 1) == 0) WFAIL(3);
1108                 NoChange = 0;
1109                 continue;
1110             } else
1111                 IndentLine(L + 1, Left);
1112         } else if (Len > Right) {
1113             C = Right;
1114             P = CharOffset(LP = RLine(L), C);
1115             while ((C > Left) &&
1116                    ((LP->Chars[P] != ' ') &&
1117                     (LP->Chars[P] != 9)))
1118                 C = ScreenPos(LP, --P);
1119 
1120             if (P <= Left) {
1121                 L++;
1122                 continue;
1123             }
1124             C = ScreenPos(LP, P);
1125             if (SplitLine(L, C) == 0) WFAIL(4);
1126             IndentLine(L + 1, Left);
1127             if (L < RCount - 2 && LineLen(L + 1) == Left) {
1128                 if (!IsLineBlank(L + 2)) {
1129                     if (JoinLine(L + 1, Left) == 0) WFAIL(5);
1130                 }
1131             }
1132             if (L == VToR(CP.Row) && CP.Col > C) {
1133                 if (SetPos(Left + CP.Col - C - 1, CP.Row + 1) == 0) WFAIL(6);
1134             }
1135             NoChange = 0;
1136             L++;
1137             continue;
1138         }
1139         if (WrapAll == 0)
1140             if (NoChangeX) {
1141                 //printf("\n\nBreak OUT = %d\n\x7", L);
1142                 break;
1143             }
1144         L++;
1145         NoChangeX = NoChange;
1146     }
1147     if (WrapAll == 1)
1148         if (SetPosR(Left,
1149                     (L < RCount - 2) ? (L + 2) :
1150                     (L < RCount - 1) ? (L + 1) :
1151                     (RCount - 1)) == 0) WFAIL(7);
1152     return 1;
1153 }
1154 
WrapPara()1155 int EBuffer::WrapPara() {
1156     while (VToR(CP.Row) < RCount - 1 && IsLineBlank(VToR(CP.Row)))
1157         if (SetPos(CP.Col, CP.Row + 1) == 0) return 0;
1158     return DoWrap(1);
1159 }
1160 #endif
1161 
LineCenter()1162 int EBuffer::LineCenter() {
1163     if (LineTrim() == 0)
1164         return 0;
1165     int ind = LineIndented(VToR(CP.Row));
1166     int left = BFI(this, BFI_LeftMargin);
1167     int right = BFI(this, BFI_RightMargin);
1168     int len = LineLen();
1169 
1170     //int chs = len - ind;
1171     int newind = left + ((right - left) - (len - ind)) / 2;
1172     if (newind < left)
1173         newind = left;
1174     return IndentLine(VToR(CP.Row), newind);
1175 }
1176 
InsPrevLineChar()1177 int EBuffer::InsPrevLineChar() {
1178     int L = VToR(CP.Row);
1179     int C = CP.Col, P;
1180 
1181     if (L > 0) {
1182         L--;
1183         if (C < LineLen(L)) {
1184             P = CharOffset(RLine(L), C);
1185             return InsertChar(RLine(L)->Chars[P]);
1186         }
1187     }
1188     return 0;
1189 }
1190 
InsPrevLineToEol()1191 int EBuffer::InsPrevLineToEol() {
1192     int L = VToR(CP.Row);
1193     int C = CP.Col, P;
1194     int Len;
1195 
1196     if (L > 0) {
1197         L--;
1198         P = CharOffset(RLine(L), C);
1199         Len = RLine(L)->Count - P;
1200         if (Len > 0)
1201             return InsertString(RLine(L)->Chars + P, Len);
1202     }
1203     return 0;
1204 }
1205 
LineDuplicate()1206 int EBuffer::LineDuplicate() {
1207     int Y = VToR(CP.Row);
1208     if (InsLine(Y, 1) == 0) return 0;
1209     if (InsChars(Y + 1, 0, RLine(Y)->Count, RLine(Y)->Chars) == 0) return 0;
1210     return 1;
1211 }
1212 
TrimLine(int Row)1213 int EBuffer::TrimLine(int Row) {
1214     PELine L = RLine(Row);
1215     int P, X, E;
1216 
1217     if (L->Count == 0) return 1;
1218     P = L->Count;
1219     while ((P > 0) && ((L->Chars[P - 1] == ' ') || (L->Chars[P - 1] == 9)))
1220         P--;
1221     X = ScreenPos(L, P);
1222     E = ScreenPos(L, L->Count);
1223     if (E - X > 0)
1224         if (DelText(Row, X, E - X, 1) == 0) return 0;
1225     return 1;
1226 }
1227 
LineTrim()1228 int EBuffer::LineTrim() {
1229     return TrimLine(VToR(CP.Row));
1230 }
1231 
FileTrim()1232 int EBuffer::FileTrim() {
1233     for (int L = 0; L < RCount; L++)
1234         if (TrimLine(L) == 0)
1235             return 0;
1236     return 1;
1237 }
1238 
BlockTrim()1239 int EBuffer::BlockTrim() {
1240     EPoint B, E;
1241     int L;
1242 
1243     AutoExtend = 0;
1244     if (CheckBlock() == 0) return 0;
1245     if (RCount <= 0) return 0;
1246     B = BB;
1247     E = BE;
1248     Draw(B.Row, E.Row);
1249     for (L = B.Row; L <= E.Row; L++) {
1250         switch (BlockMode) {
1251         case bmStream:
1252             if (L < E.Row || E.Col != 0)
1253                 if (TrimLine(L) == 0)
1254                     return 0;
1255             break;
1256         case bmLine:
1257         case bmColumn:
1258             if (L < E.Row)
1259                 if (TrimLine(L) == 0)
1260                     return 0;
1261             break;
1262         }
1263     }
1264     return 1;
1265 }
1266 
1267 #define TOGGLE(x) \
1268     Flags.num[BFI_##x] = (Flags.num[BFI_##x]) ? 0 : 1; \
1269     /*Msg(INFO, #x " is now %s.", Flags.num[BFI_##x] ? "ON" : "OFF");*/ \
1270     return 1;
1271 
1272 #define TOGGLE_R(x) \
1273     Flags.num[BFI_##x] = (Flags.num[BFI_##x]) ? 0 : 1; \
1274     /*Msg(INFO, #x " is now %s.", Flags.num[BFI_##x] ? "ON" : "OFF");*/ \
1275     FullRedraw(); \
1276     return 1;
1277 
1278 
ToggleAutoIndent()1279 int EBuffer::ToggleAutoIndent() { TOGGLE(AutoIndent); }
ToggleInsert()1280 int EBuffer::ToggleInsert() { TOGGLE(Insert); }
ToggleExpandTabs()1281 int EBuffer::ToggleExpandTabs() { TOGGLE_R(ExpandTabs); }
ToggleShowTabs()1282 int EBuffer::ToggleShowTabs() { TOGGLE_R(ShowTabs); }
ToggleUndo()1283 int EBuffer::ToggleUndo() {
1284 #ifdef CONFIG_UNDOREDO
1285     FreeUndo();
1286     TOGGLE(Undo);
1287 #endif
1288 }
ToggleReadOnly()1289 int EBuffer::ToggleReadOnly() { TOGGLE(ReadOnly); }
ToggleKeepBackups()1290 int EBuffer::ToggleKeepBackups() { TOGGLE(KeepBackups); }
ToggleMatchCase()1291 int EBuffer::ToggleMatchCase() { TOGGLE(MatchCase); }
ToggleBackSpKillTab()1292 int EBuffer::ToggleBackSpKillTab() { TOGGLE(BackSpKillTab); }
ToggleDeleteKillTab()1293 int EBuffer::ToggleDeleteKillTab() { TOGGLE(DeleteKillTab); }
ToggleSpaceTabs()1294 int EBuffer::ToggleSpaceTabs() { TOGGLE(SpaceTabs); }
ToggleIndentWithTabs()1295 int EBuffer::ToggleIndentWithTabs() { TOGGLE(IndentWithTabs); }
ToggleBackSpUnindents()1296 int EBuffer::ToggleBackSpUnindents() { TOGGLE(BackSpUnindents); }
ToggleTrim()1297 int EBuffer::ToggleTrim() { TOGGLE(Trim); }
ToggleShowMarkers()1298 int EBuffer::ToggleShowMarkers() { TOGGLE_R(ShowMarkers); }
ToggleHilitTags()1299 int EBuffer::ToggleHilitTags() { TOGGLE_R(HilitTags); }
ToggleShowBookmarks()1300 int EBuffer::ToggleShowBookmarks() { TOGGLE_R(ShowBookmarks); }
ToggleMakeBackups()1301 int EBuffer::ToggleMakeBackups() { TOGGLE(MakeBackups); }
1302 
ToggleWordWrap()1303 int EBuffer::ToggleWordWrap() {
1304     BFI(this, BFI_WordWrap) = (BFI(this, BFI_WordWrap) + 1) % 3;
1305     /*Msg(INFO,
1306         "WordWrap is now %s.",
1307         (BFI(this, BFI_WordWrap) == 2) ? "AUTO" :
1308        (BFI(this, BFI_WordWrap) == 1) ? "ON" : "OFF"); */
1309     return 1;
1310 }
1311 
SetLeftMargin()1312 int EBuffer::SetLeftMargin() {
1313     BFI(this, BFI_LeftMargin) = CP.Col;
1314     Msg(S_INFO, "LeftMargin set to %d.", BFI(this, BFI_LeftMargin) + 1);
1315     return 1;
1316 }
1317 
SetRightMargin()1318 int EBuffer::SetRightMargin() {
1319     BFI(this, BFI_RightMargin) = CP.Col;
1320     Msg(S_INFO, "RightMargin set to %d.", BFI(this, BFI_RightMargin) + 1);
1321     return 1;
1322 }
1323 
ChangeMode(const char * AMode)1324 int EBuffer::ChangeMode(const char *AMode) {
1325     if (FindMode(AMode) != 0) {
1326         Mode = FindMode(AMode);
1327         Flags = Mode->Flags;
1328 #ifdef CONFIG_SYNTAX_HILIT
1329 	HilitProc = 0;
1330         if (Mode && Mode->fColorize)
1331             HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
1332 #endif
1333 	FullRedraw();
1334         return 1;
1335     }
1336     Msg(S_ERROR, "Mode '%s' not found.", AMode);
1337     return 0;
1338 }
1339 
ChangeKeys(const char * AMode)1340 int EBuffer::ChangeKeys(const char *AMode) {
1341     if (FindMode(AMode) != 0) {
1342         Mode = FindMode(AMode);
1343 #ifdef CONFIG_SYNTAX_HILIT
1344         HilitProc = 0;
1345         if (Mode && Mode->fColorize)
1346             HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
1347 #endif
1348 	FullRedraw();
1349         return 1;
1350     }
1351     Msg(S_ERROR, "Mode '%s' not found.", AMode);
1352     return 0;
1353 }
1354 
ChangeFlags(const char * AMode)1355 int EBuffer::ChangeFlags(const char *AMode) {
1356     if (FindMode(AMode) != 0) {
1357         EMode *XMode;
1358         XMode = FindMode(AMode);
1359         Flags = XMode->Flags;
1360 #ifdef CONFIG_SYNTAX_HILIT
1361         HilitProc = 0;
1362         if (Mode && Mode->fColorize)
1363             HilitProc = GetHilitProc(Mode->fColorize->SyntaxParser);
1364 #endif
1365 	FullRedraw();
1366         return 1;
1367     }
1368     Msg(S_ERROR, "Mode '%s' not found.", AMode);
1369     return 0;
1370 }
1371