fixup auto indent broken and deprecate modes not based on the lexems

close #431
close #433
This commit is contained in:
Basile Burg 2019-02-01 23:08:58 +01:00
parent 9eabc9362b
commit 1dc0dab22b
2 changed files with 87 additions and 86 deletions

View File

@ -89,10 +89,11 @@ type
procedure setAutoDotDelay(value: Integer); procedure setAutoDotDelay(value: Integer);
procedure setCompletionMenuLines(value: byte); procedure setCompletionMenuLines(value: byte);
procedure setLineNumEvery(value: integer); procedure setLineNumEvery(value: integer);
procedure setAutoBraceClosingStyle(value: TBraceAutoCloseStyle);
published published
property alwaysAdvancedFeatures: boolean read fAlwaysAdvancedFeatures write fAlwaysAdvancedFeatures; property alwaysAdvancedFeatures: boolean read fAlwaysAdvancedFeatures write fAlwaysAdvancedFeatures;
property autoCallCompletion: boolean read fAutoCallCompletion write fAutoCallCompletion; property autoCallCompletion: boolean read fAutoCallCompletion write fAutoCallCompletion;
property autoCloseCurlyBrace: TBraceAutoCloseStyle read fAutoCloseCurlyBrace write fAutoCloseCurlyBrace default TBraceAutoCloseStyle.autoCloseNever; property autoCloseCurlyBrace: TBraceAutoCloseStyle read fAutoCloseCurlyBrace write setAutoBraceClosingStyle default TBraceAutoCloseStyle.autoCloseNever;
property autoClosedPairs: TAutoClosePairs read fAutoClosedPairs write fAutoClosedPairs default[]; property autoClosedPairs: TAutoClosePairs read fAutoClosedPairs write fAutoClosedPairs default[];
property autoDotDelay: integer read fAutoDotDelay write SetautoDotDelay; property autoDotDelay: integer read fAutoDotDelay write SetautoDotDelay;
property background: TColor read fBackground write fBackground default clWhite; property background: TColor read fBackground write fBackground default clWhite;
@ -395,6 +396,19 @@ begin
fLineNumEvery := value; fLineNumEvery := value;
end; end;
procedure TEditorOptionsBase.setAutoBraceClosingStyle(value: TBraceAutoCloseStyle);
begin
//TODO-cmaintenance: remove this two rlzs after 3.7.5
case value of
autoCloseAtEof, autoCloseOnNewLineEof: value := TBraceAutoCloseStyle.autoCloseNever;
autoCloseOnNewLineAlways: value := TBraceAutoCloseStyle.autoCloseOnNewLineLexically;
autoCloseAlways: value := TBraceAutoCloseStyle.autoCloseLexically;
end;
fAutoCloseCurlyBrace:= value;
end;
procedure TEditorOptionsBase.setShortcuts(value: TCollection); procedure TEditorOptionsBase.setShortcuts(value: TCollection);
begin begin
fShortCuts.Assign(value); fShortCuts.Assign(value);

View File

@ -26,12 +26,12 @@ type
); );
TBraceAutoCloseStyle = ( TBraceAutoCloseStyle = (
autoCloseNever, autoCloseNever, // TODO-cmaintenace: remove the deprecated values two rlzs after 3.7.5
autoCloseAtEof, autoCloseAtEof, // deprecated
autoCloseAlways, autoCloseAlways, // deprecated
autoCloseLexically, autoCloseLexically,
autoCloseOnNewLineEof, autoCloseOnNewLineEof, // deprecated
autoCloseOnNewLineAlways, autoCloseOnNewLineAlways, // deprecated
autoCloseOnNewLineLexically autoCloseOnNewLineLexically
); );
@ -1680,44 +1680,61 @@ end;
function TDexedMemo.autoIndentationLevel(line: Integer): Integer; function TDexedMemo.autoIndentationLevel(line: Integer): Integer;
var var
i: integer; leftTokIndex: integer = -1;
beg: string = ''; t: PLexToken = nil;
balanceInBeg: Integer = 0; i: integer = 0;
numTabs: integer = 0; j: integer = 0;
numSpac: integer = 0; s: integer = $7FFFFFFF;
numSkip: integer = 0; b: boolean = false;
c: Char; x,y: integer;
begin begin
if not fIsDSource and not alwaysAdvancedFeatures or if not fIsDSource and not alwaysAdvancedFeatures or
not (eoAutoIndent in Options) then not (eoAutoIndent in Options) then
exit(0); exit(0);
for i := line - 2 downto 0 do // locate the token at the left of the caret
for i := fLexToks.Count-1 downto 0 do
begin begin
beg := Lines[i]; t := fLexToks[i];
balanceInBeg := 0; x := CaretX ;
for c in beg do y := CaretY ;
if c = '}' then if fLexToks[i]^.position.y > y then
balanceInBeg -= 1 continue;
else if c = '{' then if ((fLexToks[i]^.position.y = y) and (fLexToks[i]^.position.x <= x))
balanceInBeg += 1; or (fLexToks[i]^.position.y < y) then
numSkip -= balanceInBeg; begin
if numSkip < 0 then leftTokIndex := i;
break break;
else
end;
for i:= 1 to beg.length do
begin
case beg[i] of
#9: numTabs += 1;
' ': numSpac += 1;
else break;
end; end;
end; end;
result := numTabs + numSpac div TabWidth;
if balanceInBeg > 0 then if leftTokIndex = -1 then
result += 1; exit(0);
// compute indentation
for i := leftTokIndex downto 0 do
begin
t := fLexToks[i];
if t^.kind <> ltkSymbol then
continue;
case t^.Data[1] of
'{':
begin
b := true;
j += 1;
end;
'}': j -= 1;
end;
if t^.position.x > s then
break;
if b then
s := min(s, t^.position.x)
else
s := 0;
end;
// note: the leftmost openening brace might be on a column <> 0
// but the fix breaks the K&R brace style...
result := j ;//+ (s div TabWidth);
end; end;
procedure TDexedMemo.curlyBraceCloseAndIndent(close: boolean = true); procedure TDexedMemo.curlyBraceCloseAndIndent(close: boolean = true);
@ -1729,8 +1746,9 @@ begin
BeginUndoBlock; BeginUndoBlock;
CommandProcessor(ecLineBreak, '', nil);
numTabs := autoIndentationLevel(CaretY); numTabs := autoIndentationLevel(CaretY);
CommandProcessor(ecLineBreak, '', nil);
if close then if close then
begin begin
if not isBlank(lineText) then // put rest of line on a new one after the `}` if not isBlank(lineText) then // put rest of line on a new one after the `}`
@ -3518,40 +3536,18 @@ begin
if [ssCtrl] <> Shift then if [ssCtrl] <> Shift then
begin begin
lxd := false; lxd := false;
case fAutoCloseCurlyBrace of if ((LogicalCaretXY.X - 1 >= line.length) or
autoCloseAlways, autoCloseOnNewLineAlways: isBlank(line[LogicalCaretXY.X .. line.length])) then
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then begin
fLexToks.Clear;
lex(lines.Text, fLexToks);
lxd := true;
ccb := lexCanCloseBrace;
if ccb <> braceCloseInvalid then
begin begin
Key := 0; Key := 0;
curlyBraceCloseAndIndent; curlyBraceCloseAndIndent((ccb = braceClosePositive) and not (fAutoCloseCurlyBrace = autoCloseNever));
end; lxd := false;
autoCloseAtEof, autoCloseOnNewLineEof:
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
if (CaretY = Lines.Count) and (CaretX = line.length+1) then
begin
Key := 0;
curlyBraceCloseAndIndent;
end;
autoCloseNever:
if (CaretX > 1) and (line[LogicalCaretXY.X - 1] = '{') then
begin
Key := 0;
curlyBraceCloseAndIndent(false);
end;
autoCloseLexically, autoCloseOnNewLineLexically:
if ((LogicalCaretXY.X - 1 >= line.length) or
isBlank(line[LogicalCaretXY.X .. line.length])) then
begin
fLexToks.Clear;
lex(lines.Text, fLexToks);
lxd := true;
ccb := lexCanCloseBrace;
if ccb <> braceCloseInvalid then
begin
Key := 0;
curlyBraceCloseAndIndent(ccb = braceClosePositive);
lxd := false;
end;
end; end;
end; end;
if (fSmartDdocNewline) then if (fSmartDdocNewline) then
@ -3658,24 +3654,15 @@ begin
autoClosePair(autoCloseSquareBracket); autoClosePair(autoCloseSquareBracket);
'(': showCallTips(false); '(': showCallTips(false);
')': if fCallTipWin.Visible then decCallTipsLvl; ')': if fCallTipWin.Visible then decCallTipsLvl;
'{': if GetKeyShiftState <> [ssShift] then '{': if (fAutoCloseCurlyBrace = autoCloseLexically) and
(GetKeyShiftState <> [ssShift]) then
begin begin
case fAutoCloseCurlyBrace of fLexToks.Clear;
autoCloseAlways: lex(lines.Text, fLexToks);
curlyBraceCloseAndIndent; case lexCanCloseBrace of
autoCloseAtEof: braceClosePositive: curlyBraceCloseAndIndent;
if (CaretY = Lines.Count) and (CaretX = LineText.length+1) then braceCloseLessEven: curlyBraceCloseAndIndent(false);
curlyBraceCloseAndIndent; end;
autoCloseLexically:
begin
fLexToks.Clear;
lex(lines.Text, fLexToks);
case lexCanCloseBrace of
braceClosePositive: curlyBraceCloseAndIndent;
braceCloseLessEven: curlyBraceCloseAndIndent(false);
end;
end;
end;
end; end;
end; end;
if fCompletion.IsActive then if fCompletion.IsActive then