From 7f1bba909415e96031cfa7fa22b366dee20e7b54 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Tue, 5 Jul 2016 17:50:37 +0200 Subject: [PATCH] improve detection of invalid auto close pair --- src/ce_dcd.pas | 2 +- src/ce_dlang.pas | 29 ++++++++++++++++++----------- src/ce_synmemo.pas | 31 +++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/ce_dcd.pas b/src/ce_dcd.pas index 027c8a89..000428c6 100644 --- a/src/ce_dcd.pas +++ b/src/ce_dcd.pas @@ -468,7 +468,7 @@ begin if not fServerListening then exit; if fDoc = nil then exit; // - i := fDoc.MouseStart; + i := fDoc.MouseBytePosition; if i = 0 then exit; // terminateClient; diff --git a/src/ce_dlang.pas b/src/ce_dlang.pas index b8ef592e..47224a82 100644 --- a/src/ce_dlang.pas +++ b/src/ce_dlang.pas @@ -45,7 +45,7 @@ type end; TLexTokenKind = (ltkIllegal, ltkChar, ltkComment, ltkIdentifier, ltkKeyword, - ltkNumber, ltkOperator, ltkString, ltkSymbol); + ltkNumber, ltkOperator, ltkString, ltkSymbol, ltkWhite); const LexTokenKindString: array[TLexTokenKind] of string = @@ -57,7 +57,8 @@ const 'Number ', 'Operator ', 'String ', - 'Symbol '); + 'Symbol ', + 'White '); type @@ -73,7 +74,7 @@ type Data: string; end; - TLexOption = (lxoNoComments); + TLexOption = (lxoNoComments, lxoNoWhites); TLexOptions = set of TLexOption; TLexFoundEvent = procedure(const aToken: PLexToken; out doStop: boolean) of Object; @@ -140,12 +141,12 @@ procedure lex(const text: string; list: TLexTokenList; clbck: TLexFoundEvent = n (** * Outputs the module name from a tokenized D source. *) -function getModuleName(const list: TLexTokenList): string; +function getModuleName(list: TLexTokenList): string; (** * Fills a list with all the modules imported in a tokenized D source. *) -procedure getImports(const list: TLexTokenList; imports: TStrings); +procedure getImports(list: TLexTokenList; imports: TStrings); (** * Compares two TPoints. @@ -333,11 +334,17 @@ begin identifier := ''; // skip blanks - while isWhite(reader.head^) do + if isWhite(reader.head^) then begin - if isOutOfBound then - exit; - reader.Next; + reader.saveBeginning; + while isWhite(reader.head^) do + begin + if isOutOfBound then + exit; + reader.Next; + end; + if not (lxoNoWhites in Options) then + addToken(ltkWhite); end; // line comment @@ -989,7 +996,7 @@ begin Result.fIndex := -1; end; -function getModuleName(const list: TLexTokenList): string; +function getModuleName(list: TLexTokenList): string; var ltk: PLexToken; mtok: boolean = false; @@ -1016,7 +1023,7 @@ begin end; end; -procedure getImports(const list: TLexTokenList; imports: TStrings); +procedure getImports(list: TLexTokenList; imports: TStrings); var i: integer; imp: boolean = false; diff --git a/src/ce_synmemo.pas b/src/ce_synmemo.pas index ba10c859..f48cda25 100644 --- a/src/ce_synmemo.pas +++ b/src/ce_synmemo.pas @@ -167,7 +167,7 @@ type fAutoClosedPairs: TAutoClosePairs; procedure decCallTipsLvl; procedure setMatchOpts(value: TIdentifierMatchOptions); - function getMouseFileBytePos: Integer; + function getMouseBytePosition: Integer; procedure changeNotify(Sender: TObject); procedure highlightCurrentIdentifier; procedure saveCache; @@ -257,7 +257,7 @@ type property phobosDocRoot: string read fPhobosDocRoot write fPhobosDocRoot; property detectIndentMode: boolean read fDetectIndentMode write fDetectIndentMode; property disableFileDateCheck: boolean read fDisableFileDateCheck write fDisableFileDateCheck; - property MouseStart: Integer read getMouseFileBytePos; + property MouseBytePosition: Integer read getMouseBytePosition; property D2Highlighter: TSynD2Syn read fD2Highlighter; property TxtHighlighter: TSynTxtSyn read fTxtHighlighter; property defaultFontSize: Integer read fDefaultFontSize write setDefaultFontSize; @@ -1355,9 +1355,10 @@ procedure TCESynMemo.autoClosePair(value: TAutoClosedPair); var i, p: integer; tk0, tk1: PLexToken; + str: string; begin // TODO: editor SelStart doesnt match exactly, see why, also a problem in lexCanCloseBrace(). - if value <> autoCloseSquareBracket then + if value in [autoCloseBackTick, autoCloseDoubleQuote] then begin p := selStart; lex(Lines.Text, fLexToks); @@ -1369,6 +1370,24 @@ begin if tk0^.kind = TLexTokenKind.ltkString then exit; end; + end else if value = autoCloseSingleQuote then + begin + p := selStart; + lex(Lines.Text, fLexToks); + for i:=0 to fLexToks.Count-2 do + begin + tk0 := fLexToks[i]; + tk1 := fLexToks[i+1]; + if (tk0^.offset+1 <= p) and (tk1^.offset+1 > p) then + if tk0^.kind = TLexTokenKind.ltkChar then + exit; + end; + end else if value = autoCloseSquareBracket then + begin + str := lineText; + i := LogicalCaretXY.X; + if (i <= str.length) and (lineText[i] = ']') then + exit; end; BeginUndoBlock; ExecuteCommand(ecChar, autoClosePair2Char[value], nil); @@ -1839,7 +1858,7 @@ begin fFileDate := newDate; end; -function TCESynMemo.getMouseFileBytePos: Integer; +function TCESynMemo.getMouseBytePosition: Integer; var i, len, llen: Integer; begin @@ -1847,10 +1866,6 @@ begin if fMousePos.y-1 > Lines.Count-1 then exit; llen := Lines[fMousePos.y-1].length; if fMousePos.X > llen then exit; - // - // something note really clear: - // TCEEditorWidget.getSymbolLoc works when using the line ending of the file. - // TCESynMemo.getMouseFileBytePos works when using the line ending from the system. len := getSysLineEndLen; for i:= 0 to fMousePos.y-2 do result += Lines[i].length + len;