mirror of https://gitlab.com/basile.b/dexed.git
Fix inconsistencies in brace closing behavior.
This commit is contained in:
parent
1335208d25
commit
5698637bec
|
@ -44,6 +44,12 @@ type
|
||||||
|
|
||||||
TAutoClosePairs = set of TAutoClosedPair;
|
TAutoClosePairs = set of TAutoClosedPair;
|
||||||
|
|
||||||
|
TBraceCloseOption = (
|
||||||
|
braceClosePositive,
|
||||||
|
braceCloseLessEven,
|
||||||
|
braceCloseInvalid
|
||||||
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
||||||
autoClosePair2Char: array[TAutoClosedPair] of char = (#39, '"', '`', ']');
|
autoClosePair2Char: array[TAutoClosedPair] of char = (#39, '"', '`', ']');
|
||||||
|
@ -279,8 +285,9 @@ type
|
||||||
procedure completionCodeCompletion(var value: string; SourceValue: string;
|
procedure completionCodeCompletion(var value: string; SourceValue: string;
|
||||||
var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char; Shift: TShiftState);
|
var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char; Shift: TShiftState);
|
||||||
procedure showCallTipsString(const tips: string; indexOfExpected: integer);
|
procedure showCallTipsString(const tips: string; indexOfExpected: integer);
|
||||||
function lexCanCloseBrace: boolean;
|
function lexCanCloseBrace: TBraceCloseOption;
|
||||||
function canInsertLeadingDdocSymbol: char;
|
function canInsertLeadingDdocSymbol: char;
|
||||||
|
function autoIndentationLevel(line: Integer): Integer;
|
||||||
procedure handleStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
|
procedure handleStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
|
||||||
procedure goToChangedArea(next: boolean);
|
procedure goToChangedArea(next: boolean);
|
||||||
procedure goToProtectionGroup(next: boolean);
|
procedure goToProtectionGroup(next: boolean);
|
||||||
|
@ -339,7 +346,7 @@ type
|
||||||
procedure forceIndentation(m: TIndentationMode; w: integer);
|
procedure forceIndentation(m: TIndentationMode; w: integer);
|
||||||
procedure addBreakPoint(line: integer);
|
procedure addBreakPoint(line: integer);
|
||||||
procedure removeBreakPoint(line: integer);
|
procedure removeBreakPoint(line: integer);
|
||||||
procedure curlyBraceCloseAndIndent;
|
procedure curlyBraceCloseAndIndent(close: boolean = true);
|
||||||
procedure insertLeadingDDocSymbol(c: char);
|
procedure insertLeadingDDocSymbol(c: char);
|
||||||
procedure commentSelection;
|
procedure commentSelection;
|
||||||
procedure commentIdentifier;
|
procedure commentIdentifier;
|
||||||
|
@ -1671,35 +1678,33 @@ begin
|
||||||
EndUndoBlock;
|
EndUndoBlock;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDexedMemo.curlyBraceCloseAndIndent;
|
function TDexedMemo.autoIndentationLevel(line: Integer): Integer;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
beg: string = '';
|
beg: string = '';
|
||||||
|
balanceInBeg: Integer = 0;
|
||||||
numTabs: integer = 0;
|
numTabs: integer = 0;
|
||||||
numSpac: integer = 0;
|
numSpac: integer = 0;
|
||||||
numSkip: integer = 0;
|
numSkip: integer = 0;
|
||||||
|
c: Char;
|
||||||
begin
|
begin
|
||||||
if not fIsDSource and not alwaysAdvancedFeatures then
|
if not fIsDSource and not alwaysAdvancedFeatures or
|
||||||
exit;
|
not (eoAutoIndent in Options) then
|
||||||
|
exit(0);
|
||||||
|
|
||||||
i := CaretY - 1;
|
for i := line - 2 downto 0 do
|
||||||
while true do
|
|
||||||
begin
|
begin
|
||||||
if i < 0 then
|
|
||||||
break;
|
|
||||||
beg := Lines[i];
|
beg := Lines[i];
|
||||||
if (Pos('}', beg) <> 0) then
|
balanceInBeg := 0;
|
||||||
begin
|
for c in beg do
|
||||||
numSkip += 1;
|
if c = '}' then
|
||||||
end
|
balanceInBeg -= 1
|
||||||
else if (Pos('{', beg) <> 0) then
|
else if c = '{' then
|
||||||
begin
|
balanceInBeg += 1;
|
||||||
numSkip -= 1;
|
numSkip -= balanceInBeg;
|
||||||
end;
|
|
||||||
if numSkip < 0 then
|
if numSkip < 0 then
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
i -= 1;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for i:= 1 to beg.length do
|
for i:= 1 to beg.length do
|
||||||
|
@ -1710,22 +1715,35 @@ begin
|
||||||
else break;
|
else break;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
numTabs += numSpac div TabWidth;
|
result := numTabs + numSpac div TabWidth;
|
||||||
|
if balanceInBeg > 0 then
|
||||||
|
result += 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDexedMemo.curlyBraceCloseAndIndent(close: boolean = true);
|
||||||
|
var
|
||||||
|
numTabs, i: integer;
|
||||||
|
begin
|
||||||
|
if not fIsDSource and not alwaysAdvancedFeatures then
|
||||||
|
exit;
|
||||||
|
|
||||||
BeginUndoBlock;
|
BeginUndoBlock;
|
||||||
|
|
||||||
CommandProcessor(ecInsertLine, '', nil);
|
CommandProcessor(ecLineBreak, '', nil);
|
||||||
CommandProcessor(ecDown, '', nil);
|
numTabs := autoIndentationLevel(CaretY);
|
||||||
|
if close then
|
||||||
CommandProcessor(ecInsertLine, '', nil);
|
begin
|
||||||
CommandProcessor(ecDown, '', nil);
|
if not isBlank(lineText) then // put rest of line on a new one after the `}`
|
||||||
while CaretX <> 1 do CommandProcessor(ecLeft, '' , nil);
|
CommandProcessor(ecInsertLine, '', nil);
|
||||||
for i:= 0 to numTabs-1 do CommandProcessor(ecTab, '', nil);
|
CommandProcessor(ecLineBreak, '', nil);
|
||||||
CommandProcessor(ecChar, '}', nil);
|
CommandProcessor(ecDeleteBOL, '', nil);
|
||||||
|
for i:= 1 to numTabs-1 do CommandProcessor(ecTab, '', nil);
|
||||||
CommandProcessor(ecUp, '', nil);
|
CommandProcessor(ecChar, '}', nil);
|
||||||
while CaretX <> 1 do CommandProcessor(ecLeft, '' , nil);
|
CommandProcessor(ecUp, '', nil);
|
||||||
for i:= 0 to numTabs do CommandProcessor(ecTab, '', nil);
|
CommandProcessor(ecLineEnd, '', nil);
|
||||||
|
end;
|
||||||
|
CommandProcessor(ecDeleteBOL, '', nil);
|
||||||
|
for i:= 1 to numTabs do CommandProcessor(ecTab, '', nil);
|
||||||
|
|
||||||
EndUndoBlock;
|
EndUndoBlock;
|
||||||
end;
|
end;
|
||||||
|
@ -3148,7 +3166,7 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDexedMemo.lexCanCloseBrace: boolean;
|
function TDexedMemo.lexCanCloseBrace: TBraceCloseOption;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
p: integer;
|
p: integer;
|
||||||
|
@ -3168,16 +3186,18 @@ begin
|
||||||
end else
|
end else
|
||||||
bet := false;
|
bet := false;
|
||||||
if bet and (tok^.kind = ltkComment) then
|
if bet and (tok^.kind = ltkComment) then
|
||||||
exit(false);
|
exit(braceCloseInvalid);
|
||||||
c += byte((tok^.kind = TLexTokenKind.ltkSymbol) and (((tok^.Data = '{')) or (tok^.Data = 'q{')));
|
c += byte((tok^.kind = TLexTokenKind.ltkSymbol) and (((tok^.Data = '{')) or (tok^.Data = 'q{')));
|
||||||
c -= byte((tok^.kind = TLexTokenKind.ltkSymbol) and (tok^.Data = '}'));
|
c -= byte((tok^.kind = TLexTokenKind.ltkSymbol) and (tok^.Data = '}'));
|
||||||
if bet and (c = 0) then
|
if bet and (c = 0) then
|
||||||
exit(false);
|
exit(braceCloseLessEven);
|
||||||
end;
|
end;
|
||||||
if (tok <> nil) and (tok^.kind = ltkIllegal) then
|
if (tok <> nil) and (tok^.kind = ltkIllegal) then
|
||||||
result := false
|
result := braceCloseInvalid
|
||||||
|
else if c > 0 then
|
||||||
|
result := braceClosePositive
|
||||||
else
|
else
|
||||||
result := c > 0;
|
result := braceCloseLessEven;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDexedMemo.SetHighlighter(const Value: TSynCustomHighlighter);
|
procedure TDexedMemo.SetHighlighter(const Value: TSynCustomHighlighter);
|
||||||
|
@ -3481,6 +3501,7 @@ var
|
||||||
line: string;
|
line: string;
|
||||||
ddc: char;
|
ddc: char;
|
||||||
lxd: boolean;
|
lxd: boolean;
|
||||||
|
ccb: TBraceCloseOption;
|
||||||
begin
|
begin
|
||||||
case Key of
|
case Key of
|
||||||
VK_BACK:
|
VK_BACK:
|
||||||
|
@ -3496,52 +3517,58 @@ begin
|
||||||
line := LineText;
|
line := LineText;
|
||||||
if [ssCtrl] <> Shift then
|
if [ssCtrl] <> Shift then
|
||||||
begin
|
begin
|
||||||
|
lxd := false;
|
||||||
case fAutoCloseCurlyBrace of
|
case fAutoCloseCurlyBrace of
|
||||||
autoCloseOnNewLineAlways: if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
|
autoCloseAlways, autoCloseOnNewLineAlways:
|
||||||
|
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
|
||||||
begin
|
begin
|
||||||
Key := 0;
|
Key := 0;
|
||||||
curlyBraceCloseAndIndent;
|
curlyBraceCloseAndIndent;
|
||||||
end;
|
end;
|
||||||
autoCloseOnNewLineEof: if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
|
autoCloseAtEof, autoCloseOnNewLineEof:
|
||||||
|
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
|
||||||
if (CaretY = Lines.Count) and (CaretX = line.length+1) then
|
if (CaretY = Lines.Count) and (CaretX = line.length+1) then
|
||||||
begin
|
begin
|
||||||
Key := 0;
|
Key := 0;
|
||||||
curlyBraceCloseAndIndent;
|
curlyBraceCloseAndIndent;
|
||||||
end;
|
end;
|
||||||
end;
|
autoCloseNever:
|
||||||
if (fAutoCloseCurlyBrace = autoCloseOnNewLineLexically) or
|
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
|
||||||
fSmartDdocNewline then
|
begin
|
||||||
begin
|
Key := 0;
|
||||||
lxd := false;
|
curlyBraceCloseAndIndent(false);
|
||||||
if (LogicalCaretXY.X - 1 >= line.length)
|
end;
|
||||||
or isBlank(line[LogicalCaretXY.X .. line.length]) then
|
autoCloseLexically, autoCloseOnNewLineLexically:
|
||||||
|
if ((LogicalCaretXY.X - 1 >= line.length) or
|
||||||
|
isBlank(line[LogicalCaretXY.X .. line.length])) then
|
||||||
begin
|
begin
|
||||||
lxd := true;
|
|
||||||
fLexToks.Clear;
|
fLexToks.Clear;
|
||||||
lex(lines.Text, fLexToks);
|
lex(lines.Text, fLexToks);
|
||||||
if lexCanCloseBrace then
|
lxd := true;
|
||||||
|
ccb := lexCanCloseBrace;
|
||||||
|
if ccb <> braceCloseInvalid then
|
||||||
begin
|
begin
|
||||||
Key := 0;
|
Key := 0;
|
||||||
curlyBraceCloseAndIndent;
|
curlyBraceCloseAndIndent(ccb = braceClosePositive);
|
||||||
lxd := false;
|
lxd := false;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if (fSmartDdocNewline) then
|
end;
|
||||||
|
if (fSmartDdocNewline) then
|
||||||
|
begin
|
||||||
|
if not lxd then
|
||||||
begin
|
begin
|
||||||
if not lxd then
|
fLexToks.Clear;
|
||||||
begin
|
lex(lines.Text, fLexToks);
|
||||||
fLexToks.Clear;
|
end;
|
||||||
lex(lines.Text, fLexToks);
|
ddc := canInsertLeadingDdocSymbol;
|
||||||
end;
|
if ddc in ['*', '+'] then
|
||||||
ddc := canInsertLeadingDdocSymbol;
|
begin
|
||||||
if ddc in ['*', '+'] then
|
inherited;
|
||||||
begin
|
insertLeadingDDocSymbol(ddc);
|
||||||
inherited;
|
fCanShowHint:=false;
|
||||||
insertLeadingDDocSymbol(ddc);
|
fDDocWin.Hide;
|
||||||
fCanShowHint:=false;
|
exit;
|
||||||
fDDocWin.Hide;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
@ -3643,8 +3670,10 @@ begin
|
||||||
begin
|
begin
|
||||||
fLexToks.Clear;
|
fLexToks.Clear;
|
||||||
lex(lines.Text, fLexToks);
|
lex(lines.Text, fLexToks);
|
||||||
if lexCanCloseBrace then
|
case lexCanCloseBrace of
|
||||||
curlyBraceCloseAndIndent;
|
braceClosePositive: curlyBraceCloseAndIndent;
|
||||||
|
braceCloseLessEven: curlyBraceCloseAndIndent(false);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
Loading…
Reference in New Issue