diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Document.cxx | 83 | ||||
-rw-r--r-- | src/Document.h | 4 | ||||
-rw-r--r-- | src/Editor.cxx | 20 |
3 files changed, 107 insertions, 0 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index 46d1bd2be..69cf2a438 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -958,3 +958,86 @@ void Document::NotifyModified(DocModification mh) { watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData); } } + +bool Document::IsWordPartSeparator(char ch) { + return ispunct(ch) && IsWordChar(ch); +} + +int Document::WordPartLeft(int pos) { + if (pos > 0) { + --pos; + char startChar = cb.CharAt(pos); + if (IsWordPartSeparator(startChar)) { + while (pos > 0 && IsWordPartSeparator(cb.CharAt(pos))) { + --pos; + } + startChar = cb.CharAt(pos); + } + if (pos > 0) { + startChar = cb.CharAt(pos); + --pos; + if (islower(startChar)) { + while (pos > 0 && islower(cb.CharAt(pos))) + --pos; + if (!isupper(cb.CharAt(pos)) && !islower(cb.CharAt(pos))) + ++pos; + } else if (isupper(startChar)) { + while (pos > 0 && isupper(cb.CharAt(pos))) + --pos; + if (!isupper(cb.CharAt(pos))) + ++pos; + } else if (isdigit(startChar)) { + while (pos > 0 && isdigit(cb.CharAt(pos))) + --pos; + if (!isdigit(cb.CharAt(pos))) + ++pos; + } else if (ispunct(startChar)) { + while (pos > 0 && ispunct(cb.CharAt(pos))) + --pos; + if (!ispunct(cb.CharAt(pos))) + ++pos; + } else if (isspace(startChar)) { + while (pos > 0 && isspace(cb.CharAt(pos))) + --pos; + if (!isspace(cb.CharAt(pos))) + ++pos; + } + } + } + return pos; +} + +int Document::WordPartRight(int pos) { + char startChar = cb.CharAt(pos); + int length = Length(); + if (IsWordPartSeparator(startChar)) { + while (pos < length && IsWordPartSeparator(cb.CharAt(pos))) + ++pos; + startChar = cb.CharAt(pos); + } + if (islower(startChar)) { + while (pos < length && islower(cb.CharAt(pos))) + ++pos; + } else if (isupper(startChar)) { + if (islower(cb.CharAt(pos + 1))) { + ++pos; + while (pos < length && islower(cb.CharAt(pos))) + ++pos; + } else { + while (pos < length && isupper(cb.CharAt(pos))) + ++pos; + } + if (islower(cb.CharAt(pos)) && isupper(cb.CharAt(pos - 1))) + --pos; + } else if (isdigit(startChar)) { + while (pos < length && isdigit(cb.CharAt(pos))) + ++pos; + } else if (ispunct(startChar)) { + while (pos < length && ispunct(cb.CharAt(pos))) + ++pos; + } else if (isspace(startChar)) { + while (pos < length && isspace(cb.CharAt(pos))) + ++pos; + } + return pos; +} diff --git a/src/Document.h b/src/Document.h index af477dd79..c89d677a2 100644 --- a/src/Document.h +++ b/src/Document.h @@ -188,6 +188,10 @@ public: const WatcherWithUserData *GetWatchers() const { return watchers; } int GetLenWatchers() const { return lenWatchers; } + bool IsWordPartSeparator(char ch); + int WordPartLeft(int pos); + int WordPartRight(int pos); + private: bool IsDBCS(int pos); bool IsWordChar(unsigned char ch); diff --git a/src/Editor.cxx b/src/Editor.cxx index 16049e20d..d6eea354f 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2263,6 +2263,22 @@ int Editor::KeyCommand(unsigned int iMessage) { case SCI_UPPERCASE: ChangeCaseOfSelection(true); break; + case SCI_WORDPARTLEFT: + MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1)); + SetLastXChosen(); + break; + case SCI_WORDPARTLEFTEXTEND: + MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1), true); + SetLastXChosen(); + break; + case SCI_WORDPARTRIGHT: + MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1)); + SetLastXChosen(); + break; + case SCI_WORDPARTRIGHTEXTEND: + MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1), true); + SetLastXChosen(); + break; } return 0; } @@ -4224,6 +4240,10 @@ long Editor::WndProc(unsigned int iMessage, unsigned long wParam, long lParam) { case SCI_UPPERCASE: case SCI_LINESCROLLDOWN: case SCI_LINESCROLLUP: + case SCI_WORDPARTLEFT: + case SCI_WORDPARTLEFTEXTEND: + case SCI_WORDPARTRIGHT: + case SCI_WORDPARTRIGHTEXTEND: return KeyCommand(iMessage); case SCI_BRACEHIGHLIGHT: |