CEdit: highlighting of escape sequences; ctrl+up/down moves multiline text

git-svn-id: svn://kolibrios.org@9413 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Anton Krotov 2021-12-11 18:27:02 +00:00
parent f786997b1b
commit 22deb5b5cb
8 changed files with 204 additions and 37 deletions

Binary file not shown.

View File

@ -18,6 +18,7 @@ numback=230,230,230
comment=78,106,135 comment=78,106,135
string=245,238,162 string=245,238,162
escape=245,238,162
num=237,110,85 num=237,110,85
delim=255,79,104 delim=255,79,104
key1=255,79,104 key1=255,79,104
@ -37,6 +38,7 @@ numback=230,230,230
comment=128,0,128 comment=128,0,128
string=0,128,0 string=0,128,0
escape=0,128,0
num=128,0,0 num=128,0,0
delim=0,0,128 delim=0,0,128
key1=0,0,128 key1=0,0,128

View File

@ -19,8 +19,8 @@
ctrl+G перейти на строку... ctrl+G перейти на строку...
ctrl+Del удалить строку ctrl+Del удалить строку
ctrl+D дублировать строку ctrl+D дублировать строку
ctrl+Up переместить строку вверх ctrl+Up переместить текст вверх
ctrl+Down переместить строку вниз ctrl+Down переместить текст вниз
ctrl+E выделить слово ctrl+E выделить слово
Tab увеличить отступ для выделенного текста Tab увеличить отступ для выделенного текста

View File

@ -28,7 +28,7 @@ IMPORT
RW, Ini, EB := EditBox, Icons, Tabs, Timer; RW, Ini, EB := EditBox, Icons, Tabs, Timer;
CONST CONST
HEADER = "CEdit (08-dec-2021)"; HEADER = "CEdit (11-dec-2021)";
ShellFilter = ""; ShellFilter = "";
EditFilter = "SH|INC|TXT|ASM|OB07|C|CPP|H|PAS|PP|LUA|INI|JSON"; EditFilter = "SH|INC|TXT|ASM|OB07|C|CPP|H|PAS|PP|LUA|INI|JSON";
@ -1364,9 +1364,9 @@ BEGIN
|menuColors..menuMaxColors: |menuColors..menuMaxColors:
Ini.selectSection(IPC[2] - menuColors) Ini.selectSection(IPC[2] - menuColors)
|menuMoveUp: |menuMoveUp:
T.upLine(text) T.MoveLines(text, FALSE)
|menuMoveDown: |menuMoveDown:
T.downLine(text) T.MoveLines(text, TRUE)
|menuDuplicate: |menuDuplicate:
T.dupLine(text) T.dupLine(text)
|menuRemove: |menuRemove:

View File

@ -104,7 +104,7 @@ VAR
section: tSection; section: tSection;
text, back, seltext, selback, modified, saved, curline, numtext, numback, text, back, seltext, selback, modified, saved, curline, numtext, numback,
comment, string, num, delim, key1, key2, key3: INTEGER; comment, string, escape, num, delim, key1, key2, key3: INTEGER;
BEGIN BEGIN
IF (0 <= idx) & (idx < sections.count) THEN IF (0 <= idx) & (idx < sections.count) THEN
curSectionNum := idx; curSectionNum := idx;
@ -140,9 +140,10 @@ BEGIN
key1 := getColor("key1", 0000080H); key1 := getColor("key1", 0000080H);
key2 := getColor("key2", 0008080H); key2 := getColor("key2", 0008080H);
key3 := getColor("key3", 0008080H); key3 := getColor("key3", 0008080H);
escape := getColor("escape", string);
Text.setColors(text, back, seltext, selback, modified, saved, curline, numtext, numback, Text.setColors(text, back, seltext, selback, modified, saved, curline, numtext, numback,
comment, string, num, delim, key1, key2, key3); comment, string, escape, num, delim, key1, key2, key3);
END selectSection; END selectSection;

View File

@ -28,6 +28,7 @@ CONST
langFasm* = 4; langLua* = 5; langIni* = 6; langJSON* = 7; langFasm* = 4; langLua* = 5; langIni* = 6; langJSON* = 7;
csLang = {langC, langOberon, langLua, langIni, langJSON}; csLang = {langC, langOberon, langLua, langIni, langJSON};
escLang* = {langC, langLua, langJSON};
TYPE TYPE
@ -87,17 +88,98 @@ BEGIN
END isDelim; END isDelim;
PROCEDURE SkipString* (line: tLine; VAR pos: INTEGER; n: INTEGER); PROCEDURE SkipString* (line: tLine; VAR pos: INTEGER; n: INTEGER; lang: INTEGER);
VAR VAR
quot: WCHAR; quot, cur, prev: WCHAR;
BEGIN BEGIN
quot := Lines.getChar(line, pos); quot := Lines.getChar(line, pos);
REPEAT cur := quot;
prev := 0X;
INC(pos);
WHILE pos <= n DO
IF lang IN escLang THEN
prev := cur
END;
cur := Lines.getChar(line, pos);
IF (cur = "\") & (prev = "\") THEN
cur := 0X
ELSIF (cur = quot) & (prev # "\") THEN
n := 0; (* exit *)
DEC(pos)
END;
INC(pos) INC(pos)
UNTIL (pos > n) OR (Lines.getChar(line, pos) = quot) END
END SkipString; END SkipString;
PROCEDURE SkipEsc* (line: tLine; VAR pos: INTEGER; n: INTEGER; lang: INTEGER);
VAR
c, c1: WCHAR;
k: INTEGER;
BEGIN
IF pos < n THEN
c := Lines.getChar(line, pos + 1);
CASE lang OF
|langC:
IF Utils.inString(c, "abfnrtv\'?" + '"') THEN
INC(pos)
ELSIF Utils.isOct(c) THEN
k := 0;
REPEAT
INC(pos);
IF Utils.isOct(Lines.getChar(line, pos)) THEN
INC(k)
ELSE
k := 0
END
UNTIL (k = 0) OR (k = 4);
DEC(pos)
ELSIF (c = "x") OR (c = "u") OR (c = "U") THEN
c1 := c;
k := 0;
INC(pos);
REPEAT
INC(pos);
c := Lines.getChar(line, pos);
IF Utils.cap(c) THEN END;
IF Utils.isHex(c) THEN
INC(k)
ELSE
k := 0
END;
IF (c1 = "u") & (k = 5) OR (c1 = "U") & (k = 9) THEN
k := 0
END
UNTIL k = 0;
DEC(pos)
END
|langLua:
IF Utils.inString(c, "abfnrtv\'[]" + '"') THEN
INC(pos)
END
|langJSON:
IF Utils.inString(c, 'bfnrt\/"') THEN
INC(pos)
ELSIF c = "u" THEN
k := 0;
INC(pos);
REPEAT
INC(pos);
c := Lines.getChar(line, pos);
IF Utils.cap(c) THEN END;
IF Utils.isHex(c) THEN
INC(k)
ELSE
k := 0
END
UNTIL (k = 0) OR (k = 5);
DEC(pos)
END
END
END
END SkipEsc;
PROCEDURE C (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER); PROCEDURE C (line: tLine; VAR depth, cond, pos: INTEGER; n: INTEGER);
VAR VAR
c: WCHAR; c: WCHAR;
@ -115,7 +197,7 @@ BEGIN
depth := 1; depth := 1;
cond := 0 cond := 0
ELSIF (c = "'") OR (c = '"') THEN ELSIF (c = "'") OR (c = '"') THEN
SkipString(line, pos, n); SkipString(line, pos, n, langC);
cond := 0 cond := 0
ELSE ELSE
cond := 0 cond := 0
@ -193,7 +275,7 @@ BEGIN
depth := (k + 1)*2 depth := (k + 1)*2
END END
ELSIF (c = "'") OR (c = '"') THEN ELSIF (c = "'") OR (c = '"') THEN
SkipString(line, pos, n); SkipString(line, pos, n, langLua);
cond := 0 cond := 0
ELSE ELSE
cond := 0 cond := 0
@ -232,7 +314,7 @@ BEGIN
depth := 2; depth := 2;
cond := 0 cond := 0
ELSIF c = "'" THEN ELSIF c = "'" THEN
SkipString(line, pos, n); SkipString(line, pos, n, langPascal);
cond := 0 cond := 0
ELSIF c = "{" THEN ELSIF c = "{" THEN
IF Lines.getChar(line, pos + 1) = "$" THEN IF Lines.getChar(line, pos + 1) = "$" THEN
@ -274,7 +356,7 @@ BEGIN
cond := 3 cond := 3
END END
ELSIF (depth = 0) & ((c = "'") OR (c = '"')) THEN ELSIF (depth = 0) & ((c = "'") OR (c = '"')) THEN
SkipString(line, pos, n); SkipString(line, pos, n, langOberon);
cond := 0 cond := 0
ELSIF c = "(" THEN ELSIF c = "(" THEN
cond := 1 cond := 1
@ -308,7 +390,7 @@ BEGIN
IF c = ";" THEN IF c = ";" THEN
pos := n pos := n
ELSIF c = '"' THEN ELSIF c = '"' THEN
SkipString(line, pos, n) SkipString(line, pos, n, langIni)
ELSIF c = "[" THEN ELSIF c = "[" THEN
depth := 1 depth := 1
END END

View File

@ -93,7 +93,7 @@ VAR
colors*: RECORD colors*: RECORD
text, back, seltext, selback, modified, saved, curline, numtext, numback: INTEGER; text, back, seltext, selback, modified, saved, curline, numtext, numback: INTEGER;
comment, string, num, delim, key1, key2, key3: INTEGER comment, string, escape, num, delim, key1, key2, key3: INTEGER
END; END;
canvas: G.tCanvas; canvas: G.tCanvas;
drawCursor: BOOLEAN; drawCursor: BOOLEAN;
@ -351,11 +351,26 @@ VAR
PROCEDURE String (text: tText; line: tLine; VAR i: INTEGER; y: INTEGER; backColor: INTEGER); PROCEDURE String (text: tText; line: tLine; VAR i: INTEGER; y: INTEGER; backColor: INTEGER);
VAR VAR
k: INTEGER; k, j, Start, End: INTEGER;
c: WCHAR;
BEGIN BEGIN
k := i; k := i;
Lang.SkipString(line, i, line.length - 1); Lang.SkipString(line, i, line.length - 1, text.lang);
PrintLex(text, line, k, i, y, colors.string, backColor) PrintLex(text, line, k, i, y, colors.string, backColor);
IF text.lang IN Lang.escLang THEN
Start := k + 1;
End := i - 1;
k := Start;
WHILE k <= End DO
c := getChar(line, k);
IF c = "\" THEN
j := k;
Lang.SkipEsc(line, k, line.length - 1, text.lang);
PrintLex(text, line, j, k, y, colors.escape, backColor)
END;
INC(k)
END
END
END String; END String;
@ -1762,26 +1777,72 @@ BEGIN
END exchange; END exchange;
PROCEDURE upLine* (text: tText); PROCEDURE upLine (text: tText);
BEGIN BEGIN
resetSelect(text);
IF text.cursor.Y > 0 THEN
DEC(text.cursor.Y); DEC(text.cursor.Y);
exchange(text, text.curLine.prev(tLine), text.curLine) exchange(text, text.curLine.prev(tLine), text.curLine)
END
END upLine; END upLine;
PROCEDURE downLine* (text: tText); PROCEDURE downLine (text: tText);
BEGIN BEGIN
resetSelect(text);
IF text.cursor.Y < text.count - 1 THEN
INC(text.cursor.Y); INC(text.cursor.Y);
exchange(text, text.curLine, text.curLine.next(tLine)) exchange(text, text.curLine, text.curLine.next(tLine))
END
END downLine; END downLine;
PROCEDURE MoveLines* (text: tText; down: BOOLEAN);
VAR
last: tLine;
selBeg, selEnd, temp: tPoint;
n, step: INTEGER;
frw: BOOLEAN;
moveLine: PROCEDURE (text: tText);
BEGIN
getSelect(text, selBeg, selEnd);
IF (selBeg.Y > 0) & ~down OR (selEnd.Y < text.count - 1) & down THEN
IF down THEN
step := -2;
moveLine := downLine
ELSE
step := 2;
moveLine := upLine
END;
frw := (text.cursor.X = selEnd.X) & (text.cursor.Y = selEnd.Y);
IF selEnd.Y # selBeg.Y THEN
IF down # frw THEN
temp := text.cursor^;
SetPos(text, 0, text.select.Y);
setSelect(text);
text.select^ := temp
END;
last := getLine(text, selEnd.Y);
selBeg.X := 0;
selEnd.X := last.length;
n := selEnd.Y - selBeg.Y + 1;
WHILE n > 0 DO
moveLine(text);
SetPos(text, 0, text.cursor.Y + step);
DEC(n)
END
ELSE
moveLine(text)
END;
IF frw THEN
temp := selBeg;
selBeg := selEnd;
selEnd := temp
END;
step := step DIV 2;
SetPos(text, selBeg.X, selBeg.Y - step);
setSelect(text);
text.select.X := selEnd.X;
text.select.Y := selEnd.Y - step
END
END MoveLines;
PROCEDURE isWordChar (c: WCHAR): BOOLEAN; PROCEDURE isWordChar (c: WCHAR): BOOLEAN;
RETURN U.isLetter(c) OR U.isDigit(c) OR (c = "_") RETURN U.isLetter(c) OR U.isDigit(c) OR (c = "_")
END isWordChar; END isWordChar;
@ -1861,8 +1922,10 @@ BEGIN
setSelect(text) setSelect(text)
ELSE ELSE
IF (33 <= code) & (code <= 40) THEN IF (33 <= code) & (code <= 40) THEN
IF ~(((code = 38) OR (code = 40)) & ctrl) THEN
resetSelect(text) resetSelect(text)
END END
END
END; END;
CASE code OF CASE code OF
@ -1914,7 +1977,7 @@ BEGIN
END END
|38: |38:
IF ctrl THEN IF ctrl THEN
upLine(text) MoveLines(text, FALSE)
ELSE ELSE
UpDown(text, -1) UpDown(text, -1)
END END
@ -1930,7 +1993,7 @@ BEGIN
END END
|40: |40:
IF ctrl THEN IF ctrl THEN
downLine(text) MoveLines(text, TRUE)
ELSE ELSE
UpDown(text, 1) UpDown(text, 1)
END END
@ -2294,7 +2357,7 @@ END create;
PROCEDURE setColors* (text, back, seltext, selback, modified, saved, curline, numtext, numback, PROCEDURE setColors* (text, back, seltext, selback, modified, saved, curline, numtext, numback,
comment, string, num, delim, key1, key2, key3: INTEGER); comment, string, escape, num, delim, key1, key2, key3: INTEGER);
BEGIN BEGIN
colors.text := text; colors.text := text;
colors.back := back; colors.back := back;
@ -2307,6 +2370,7 @@ BEGIN
colors.numback := numback; colors.numback := numback;
colors.comment := comment; colors.comment := comment;
colors.string := string; colors.string := string;
colors.escape := escape;
colors.num := num; colors.num := num;
colors.delim := delim; colors.delim := delim;
colors.key1 := key1; colors.key1 := key1;

View File

@ -144,6 +144,11 @@ PROCEDURE isDigit* (ch: WCHAR): BOOLEAN;
END isDigit; END isDigit;
PROCEDURE isOct* (ch: WCHAR): BOOLEAN;
RETURN ("0" <= ch) & (ch <= "7")
END isOct;
PROCEDURE isHex* (ch: WCHAR): BOOLEAN; PROCEDURE isHex* (ch: WCHAR): BOOLEAN;
RETURN ("0" <= ch) & (ch <= "9") OR ("A" <= ch) & (ch <= "F") RETURN ("0" <= ch) & (ch <= "9") OR ("A" <= ch) & (ch <= "F")
END isHex; END isHex;
@ -367,4 +372,17 @@ PROCEDURE between* (a, b, c: INTEGER): BOOLEAN;
END between; END between;
PROCEDURE inString* (c: WCHAR; s: ARRAY OF WCHAR): BOOLEAN;
VAR
i, L: INTEGER;
BEGIN
L := LENGTH(s);
i := 0;
WHILE (i < L) & (c # s[i]) DO
INC(i)
END
RETURN i < L
END inString;
END Utils. END Utils.