From cb07a7715d8ff9b112466bfd6c7a48336f2cf989 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Mon, 24 Nov 2014 01:40:52 +0000 Subject: [PATCH] [NEW_FEATURE] Enhance the auto-insert (in progress). git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1295 f5eea248-9336-0410-98b8-ebc06183d4e3 --- .../src/ScitillaComponent/AutoCompletion.cpp | 136 +++++++++++------- .../src/ScitillaComponent/AutoCompletion.h | 23 ++- 2 files changed, 105 insertions(+), 54 deletions(-) diff --git a/PowerEditor/src/ScitillaComponent/AutoCompletion.cpp b/PowerEditor/src/ScitillaComponent/AutoCompletion.cpp index 10f621fac..35439cb53 100644 --- a/PowerEditor/src/ScitillaComponent/AutoCompletion.cpp +++ b/PowerEditor/src/ScitillaComponent/AutoCompletion.cpp @@ -402,6 +402,58 @@ void AutoCompletion::getCloseTag(char *closeTag, size_t closeTagSize, size_t car closeTag[foundTextLen+2] = '\0'; } +void InsertedMachedChars::add(MachedCharInserted mci) +{ + _insertedMachedChars.push_back(mci); +} + +// if current pos > matchedStartSybol Pos and current pos is on the same line of matchedStartSybolPos, it'll be checked then removed +// otherwise it is just removed +// return the pos of matchedEndSybol or -1 if matchedEndSybol not found +int InsertedMachedChars::search(char startChar, char endChar, int posToDetect) +{ + if (isEmpty()) + return -1; + int posToDetectLine = _pEditView->execute(SCI_LINEFROMPOSITION, posToDetect); + + for (int i = _insertedMachedChars.size() - 1; i >= 0; --i) + { + if (_insertedMachedChars[i]._pos < posToDetect) + { + + int startPosLine = _pEditView->execute(SCI_LINEFROMPOSITION, _insertedMachedChars[i]._pos); + if (posToDetectLine == startPosLine) + { + int endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, startPosLine); + + for (int j = posToDetect; j <= endPos; ++j) + { + char aChar = (char)_pEditView->execute(SCI_GETCHARAT, j); + if (aChar == startChar) + { + _insertedMachedChars.erase(_insertedMachedChars.begin() + i); + return -1; + } + if (aChar == endChar) // found it!!! + { + _insertedMachedChars.erase(_insertedMachedChars.begin() + i); + return j; + } + } + } + else // not in the same line + { + _insertedMachedChars.erase(_insertedMachedChars.begin() + i); + } + } + else // current position is before matchedStartSybol Pos + { + _insertedMachedChars.erase(_insertedMachedChars.begin() + i); + } + } + return -1; +} + void AutoCompletion::insertMatchedChars(int character, const MatchedPairConf & matchedPairConf) { const vector< pair > & matchedPairs = matchedPairConf._matchedPairs; @@ -421,7 +473,7 @@ void AutoCompletion::insertMatchedChars(int character, const MatchedPairConf & m } // if there's no user defined matched pair found, continue to check notepad++'s one - + const size_t closeTagLen = 256; char closeTag[closeTagLen]; closeTag[0] = '\0'; @@ -431,43 +483,26 @@ void AutoCompletion::insertMatchedChars(int character, const MatchedPairConf & m if (matchedPairConf._doParentheses) { matchedChars = ")"; - _doIgnoreParenthease = true; - _parenthesePos = caretPos - 1; + _insertedMachedChars.add(MachedCharInserted(char(character), caretPos - 1)); } - break; - case int(')') : - if (matchedPairConf._doParentheses && _doIgnoreParenthease) - { - matchedChars = ")"; - // if current pos is on the same line of _parenthesePos - // and current pos > _parenthesePos - if (_parenthesePos < caretPos) - { - // detect if ) is in between ( and ) - int pos = isInBetween(_parenthesePos, ')', caretPos); - if (pos != -1) - { - _pEditView->execute(SCI_DELETERANGE, pos, 1); - _pEditView->execute(SCI_GOTOPOS, pos); - } - } - - _doIgnoreParenthease = false; - _parenthesePos = -1; - return; - } - - break; case int('['): if (matchedPairConf._doBrackets) + { matchedChars = "]"; + _insertedMachedChars.add(MachedCharInserted(char(character), caretPos - 1)); + } break; + case int('{'): if (matchedPairConf._doCurlyBrackets) + { matchedChars = "}"; + _insertedMachedChars.add(MachedCharInserted(char(character), caretPos - 1)); + } break; + case int('"'): if (matchedPairConf._doDoubleQuotes) matchedChars = "\""; @@ -486,36 +521,35 @@ void AutoCompletion::insertMatchedChars(int character, const MatchedPairConf & m } } break; + + case int(')') : + case int(']') : + case int('}') : + if (matchedPairConf._doParentheses && !_insertedMachedChars.isEmpty()) + { + char startChar; + if (character == int(')')) + startChar = '('; + else if (character == int(']')) + startChar = '['; + else // if (character == int('}')) + startChar = '{'; + + int pos = _insertedMachedChars.search(startChar, char(character), caretPos); + if (pos != -1) + { + _pEditView->execute(SCI_DELETERANGE, pos, 1); + _pEditView->execute(SCI_GOTOPOS, pos); + } + return; + } + break; } if (matchedChars) _pEditView->execute(SCI_INSERTTEXT, caretPos, (LPARAM)matchedChars); } -int AutoCompletion::isInBetween(int startPos, char endChar, int posToDetect) -{ - int posToDetectLine = _pEditView->execute(SCI_LINEFROMPOSITION, posToDetect); - int startPosLine = _pEditView->execute(SCI_LINEFROMPOSITION, startPos); - - if (startPosLine != posToDetectLine) - return -1; - - int endPos = _pEditView->execute(SCI_GETLINEENDPOSITION, startPosLine); - - char startChar = (char)_pEditView->execute(SCI_GETCHARAT, startPos); - - - for (int i = posToDetect; i <= endPos; ++i) - { - char aChar = (char)_pEditView->execute(SCI_GETCHARAT, i); - if (aChar == startChar) - return -1; - if (aChar == endChar) - return i; - } - return -1; -} - void AutoCompletion::update(int character) { diff --git a/PowerEditor/src/ScitillaComponent/AutoCompletion.h b/PowerEditor/src/ScitillaComponent/AutoCompletion.h index daff884d5..a867f2fbb 100644 --- a/PowerEditor/src/ScitillaComponent/AutoCompletion.h +++ b/PowerEditor/src/ScitillaComponent/AutoCompletion.h @@ -39,6 +39,24 @@ class ScintillaEditView; +struct MachedCharInserted { + char _c; + int _pos; + MachedCharInserted(char c, int pos) : _c(c), _pos(pos) {}; +}; + +class InsertedMachedChars { +public: + void init(ScintillaEditView * pEditView) { _pEditView = pEditView; }; + void add(MachedCharInserted mci); + bool isEmpty() const { return _insertedMachedChars.size() == 0; }; + int search(char startChar, char endChar, int posToDetect); + +private: + std::vector _insertedMachedChars; + ScintillaEditView * _pEditView; +}; + class AutoCompletion { public: enum ActiveCompletion {CompletionNone = 0, CompletionAuto, CompletionWord, CompletionFunc, CompletionPath}; @@ -47,6 +65,7 @@ public: _curLang(L_TEXT), _pXmlFile(NULL), _keyWordMaxLen(0), _pXmlKeyword(NULL), _ignoreCase(true), _keyWords(TEXT("")) { //Do not load any language yet + _insertedMachedChars.init(_pEditView); }; ~AutoCompletion(){ @@ -79,8 +98,7 @@ private: TiXmlDocument *_pXmlFile; TiXmlElement *_pXmlKeyword; - bool _doIgnoreParenthease; - int _parenthesePos; + InsertedMachedChars _insertedMachedChars; bool _ignoreCase; @@ -92,7 +110,6 @@ private: const TCHAR * getApiFileName(); void getWordArray(vector & wordArray, TCHAR *beginChars); - int isInBetween(int startPos, char endChar, int posToDetect); }; #endif //AUTOCOMPLETION_H