fix #62 - lexicon-based brace auto closing is still a bit dumb

- not trigered in comments anymore
- not trigered if the pair count is 0 (e.g between two functions)

still cases exist but they would need a more complex analysis
This commit is contained in:
Basile Burg 2016-06-15 12:35:56 +02:00
parent fb51972a58
commit 79b7b851ee
2 changed files with 85 additions and 56 deletions

View File

@ -23,6 +23,7 @@ type
fPreviousLineColum: Integer; fPreviousLineColum: Integer;
fBegColumnIndex: Integer; fBegColumnIndex: Integer;
fBegLineIndex: Integer; fBegLineIndex: Integer;
fBegOffset: Integer;
function getColAndLine: TPoint; function getColAndLine: TPoint;
public public
constructor Create(const aText: PChar; const aColAndLine: TPoint); constructor Create(const aText: PChar; const aColAndLine: TPoint);
@ -38,6 +39,7 @@ type
property LineAnColumn: TPoint read getColAndLine; property LineAnColumn: TPoint read getColAndLine;
property SavedLine: Integer read fBegLineIndex; property SavedLine: Integer read fBegLineIndex;
property SavedColumn: Integer read fBegColumnIndex; property SavedColumn: Integer read fBegColumnIndex;
property SavedOffset: Integer read fBegOffset;
// //
property head: PChar read fReaderHead; property head: PChar read fReaderHead;
end; end;
@ -65,6 +67,7 @@ type
PLexToken = ^TLexToken; PLexToken = ^TLexToken;
TLexToken = record TLexToken = record
offset: integer;
position: TPoint; position: TPoint;
kind: TLexTokenKind; kind: TLexTokenKind;
Data: string; Data: string;
@ -206,6 +209,7 @@ procedure TReaderHead.saveBeginning;
begin begin
fBegColumnIndex:= fColumnIndex; fBegColumnIndex:= fColumnIndex;
fBegLineIndex:= fLineIndex; fBegLineIndex:= fLineIndex;
fBegOffset:= fAbsoluteIndex;
end; end;
{$ENDREGION} {$ENDREGION}
@ -240,7 +244,8 @@ begin
for i:= 0 to self.count-1 do for i:= 0 to self.count-1 do
begin begin
tok := getToken(i); tok := getToken(i);
add(format('line %.5d - col %.3d: (%s): %s', [tok^.position.Y, tok^.position.X, add(format('line %.5d - col %.3d (%.8d): (%s): %s',
[tok^.position.Y, tok^.position.X, tok^.offset,
LexTokenKindString[tok^.kind], tok^.Data])); LexTokenKindString[tok^.kind], tok^.Data]));
end; end;
finally finally
@ -288,6 +293,7 @@ var
ptk^.kind := aTk; ptk^.kind := aTk;
ptk^.position.X := reader.SavedColumn; ptk^.position.X := reader.SavedColumn;
ptk^.position.Y := reader.SavedLine; ptk^.position.Y := reader.SavedLine;
ptk^.offset := reader.savedOffset;
ptk^.Data := identifier; ptk^.Data := identifier;
list.Add(ptk); list.Add(ptk);
end; end;

View File

@ -8,7 +8,7 @@ uses
Classes, SysUtils, controls,lcltype, Forms, graphics, ExtCtrls, crc, Classes, SysUtils, controls,lcltype, Forms, graphics, ExtCtrls, crc,
SynEdit, SynPluginSyncroEdit, SynCompletion, SynEditKeyCmds, LazSynEditText, SynEdit, SynPluginSyncroEdit, SynCompletion, SynEditKeyCmds, LazSynEditText,
SynHighlighterLFM, SynEditHighlighter, SynEditMouseCmds, SynEditFoldedView, SynHighlighterLFM, SynEditHighlighter, SynEditMouseCmds, SynEditFoldedView,
SynEditMarks, SynEditTypes, SynHighlighterJScript, dialogs, SynEditMarks, SynEditTypes, SynHighlighterJScript, dialogs, Clipbrd,
ce_common, ce_observer, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs, ce_common, ce_observer, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs,
ce_sharedres, ce_dlang, ce_stringrange; ce_sharedres, ce_dlang, ce_stringrange;
@ -210,6 +210,7 @@ type
procedure showDDocs; procedure showDDocs;
procedure hideDDocs; procedure hideDDocs;
procedure ShowPhobosDoc; procedure ShowPhobosDoc;
procedure copy;
// //
function breakPointsCount: integer; function breakPointsCount: integer;
function breakPointLine(index: integer): integer; function breakPointLine(index: integer): integer;
@ -795,6 +796,59 @@ begin
end; end;
end; end;
procedure TCESynMemo.DoOnProcessCommand(var Command: TSynEditorCommand;
var AChar: TUTF8Char; Data: pointer);
begin
inherited;
case Command of
ecCompletionMenu:
begin
fCanAutoDot:=false;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
fCompletion.Execute(GetWordAtRowCol(LogicalCaretXY),
ClientToScreen(point(CaretXPix, CaretYPix + LineHeight)));
end;
ecPreviousLocation:
fPositions.back;
ecNextLocation:
fPositions.next;
ecShowDdoc:
begin
hideCallTips;
hideDDocs;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
showDDocs;
end;
ecShowCallTips:
begin
hideCallTips;
hideDDocs;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
showCallTips(true);
end;
ecCurlyBraceClose:
curlyBraceCloseAndIndent;
ecCommentSelection:
commentSelection;
ecSwapVersionAllNone:
invertVersionAllNone;
ecRenameIdentifier:
renameIdentifier;
ecCommentIdentifier:
commentIdentifier;
ecShowPhobosDoc:
ShowPhobosDoc;
end;
if fOverrideColMode and not SelAvail then
begin
fOverrideColMode := false;
Options := Options - [eoScrollPastEol];
end;
end;
procedure TCESynMemo.curlyBraceCloseAndIndent; procedure TCESynMemo.curlyBraceCloseAndIndent;
var var
i: integer; i: integer;
@ -976,59 +1030,6 @@ begin
end; end;
end; end;
procedure TCESynMemo.DoOnProcessCommand(var Command: TSynEditorCommand;
var AChar: TUTF8Char; Data: pointer);
begin
inherited;
case Command of
ecCompletionMenu:
begin
fCanAutoDot:=false;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
fCompletion.Execute(GetWordAtRowCol(LogicalCaretXY),
ClientToScreen(point(CaretXPix, CaretYPix + LineHeight)));
end;
ecPreviousLocation:
fPositions.back;
ecNextLocation:
fPositions.next;
ecShowDdoc:
begin
hideCallTips;
hideDDocs;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
showDDocs;
end;
ecShowCallTips:
begin
hideCallTips;
hideDDocs;
if not fIsDSource and not alwaysAdvancedFeatures then
exit;
showCallTips(true);
end;
ecCurlyBraceClose:
curlyBraceCloseAndIndent;
ecCommentSelection:
commentSelection;
ecSwapVersionAllNone:
invertVersionAllNone;
ecRenameIdentifier:
renameIdentifier;
ecCommentIdentifier:
commentIdentifier;
ecShowPhobosDoc:
ShowPhobosDoc;
end;
if fOverrideColMode and not SelAvail then
begin
fOverrideColMode := false;
Options := Options - [eoScrollPastEol];
end;
end;
procedure TCESynMemo.invertVersionAllNone; procedure TCESynMemo.invertVersionAllNone;
var var
i: integer; i: integer;
@ -1212,6 +1213,14 @@ begin
shellOpen(pth); shellOpen(pth);
end; end;
procedure TCESynMemo.copy;
begin
{$IFDEF WINDOWS}
{$ELSE}
// workaround https://github.com/BBasile/Coedit/issues/39
{$ENDIF}
end;
{$ENDREGION} {$ENDREGION}
{$REGION DDoc & CallTip --------------------------------------------------------} {$REGION DDoc & CallTip --------------------------------------------------------}
@ -1422,14 +1431,28 @@ end;
function TCESynMemo.lexCanCloseBrace: boolean; function TCESynMemo.lexCanCloseBrace: boolean;
var var
i: integer; i: integer;
p: integer;
c: integer = 0; c: integer = 0;
tok: PLexToken; tok: PLexToken;
ton: PLexToken;
bet: boolean;
begin begin
p := SelStart;
for i := 0 to fLexToks.Count-1 do for i := 0 to fLexToks.Count-1 do
begin begin
tok := fLexToks[i]; tok := fLexToks[i];
if (i <> fLexToks.Count-1) then
begin
ton := fLexToks[i+1];
bet := (tok^.offset + 1 <= p) and (ton^.offset + 1 > p);
end else
bet := false;
if bet and (tok^.kind = ltkComment) then
exit(false);
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
exit(false);
end; end;
if (tok <> nil) and (tok^.kind = ltkIllegal) then if (tok <> nil) and (tok^.kind = ltkIllegal) then
result := false result := false