diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Document.cxx | 23 | ||||
-rw-r--r-- | src/Document.h | 38 | ||||
-rw-r--r-- | src/Editor.cxx | 139 |
3 files changed, 129 insertions, 71 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index befae4570..1ea2da012 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -44,6 +44,8 @@ Document::Document() { tabInChars = 8; indentInChars = 0; useTabs = true; + tabIndents = true; + backspaceUnindents = false; watchers = 0; lenWatchers = 0; @@ -150,8 +152,8 @@ int Document::VCHomePosition(int position) { int Document::SetLevel(int line, int level) { int prev = cb.SetLevel(line, level); if (prev != level) { - DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, - LineStart(line), 0, 0, 0); + DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, + LineStart(line), 0, 0, 0); mh.line = line; mh.foldLevelNow = level; mh.foldLevelPrev = prev; @@ -331,6 +333,7 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { //Platform::DebugPrintf("DBCS %s\n", atlead ? "D" : "-"); } + if (atLeadByte) { // Position is between a lead byte and a trail byte if (moveDir > 0) @@ -837,7 +840,7 @@ long Document::FindText(int minPos, int maxPos, const char *s, int lineRangeStart = LineFromPosition(startPos); int lineRangeEnd = LineFromPosition(endPos); if ((startPos >= LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) { - // the start position is at end of line or between line end characters. + // the start position is at end of line or between line end characters. lineRangeStart++; startPos = LineStart(lineRangeStart); } @@ -851,7 +854,7 @@ long Document::FindText(int minPos, int maxPos, const char *s, startPos++; } else if (s[0] == '$') { if ((startPos == LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) - startPos = LineStart(lineRangeStart+1); + startPos = LineStart(lineRangeStart + 1); } lineRangeStart = LineFromPosition(startPos); lineRangeEnd = LineFromPosition(endPos); @@ -955,9 +958,9 @@ const char *Document::SubstituteByPosition(const char *text, int *length) { if (!pre->GrabMatches(di)) return 0; unsigned int lenResult = 0; - for (int i=0; i<*length; i++) { - if ((text[i] == '\\') && (text[i+1] >= '1' && text[i+1] <= '9')) { - unsigned int patNum = text[i+1] - '0'; + for (int i = 0; i < *length; i++) { + if ((text[i] == '\\') && (text[i + 1] >= '1' && text[i + 1] <= '9')) { + unsigned int patNum = text[i + 1] - '0'; lenResult += pre->eopat[patNum] - pre->bopat[patNum]; i++; } else { @@ -968,9 +971,9 @@ const char *Document::SubstituteByPosition(const char *text, int *length) { if (!substituted) return 0; char *o = substituted; - for (int j=0; j<*length; j++) { - if ((text[j] == '\\') && (text[j+1] >= '1' && text[j+1] <= '9')) { - unsigned int patNum = text[j+1] - '0'; + for (int j = 0; j < *length; j++) { + if ((text[j] == '\\') && (text[j + 1] >= '1' && text[j + 1] <= '9')) { + unsigned int patNum = text[j + 1] - '0'; unsigned int len = pre->eopat[patNum] - pre->bopat[patNum]; if (pre->pat[patNum]) // Will be null if try for a match that did not occur memcpy(o, pre->pat[patNum], len); diff --git a/src/Document.h b/src/Document.h index aac0a971b..581957257 100644 --- a/src/Document.h +++ b/src/Document.h @@ -25,18 +25,18 @@ class Range { public: Position start; Position end; - + Range(Position pos=0) : start(pos), end(pos) { }; Range(Position start_, Position end_) : start(start_), end(end_) { }; - + bool Valid() const { return (start != invalidPosition) && (end != invalidPosition); } - + bool Contains(Position pos) const { if (start < end) { return (pos >= start && pos <= end); @@ -44,11 +44,11 @@ public: return (pos <= start && pos >= end); } } - + bool Contains(Range other) const { return Contains(other.start) && Contains(other.end); } - + bool Overlaps(Range other) const { return Contains(other.start) || @@ -77,7 +77,7 @@ public: userData = 0; } }; - + private: int refCount; CellBuffer cb; @@ -87,7 +87,7 @@ private: int endStyled; int enteredCount; int enteredReadOnlyCount; - + WatcherWithUserData *watchers; int lenWatchers; @@ -98,20 +98,22 @@ private: public: int stylingBits; int stylingBitsMask; - + int eolMode; /// Can also be SC_CP_UTF8 to enable UTF-8 mode int dbcsCodePage; int tabInChars; int indentInChars; bool useTabs; - + bool tabIndents; + bool backspaceUnindents; + Document(); virtual ~Document(); - + int AddRef(); int Release(); - + int LineFromPosition(int pos); int ClampPositionIntoDocument(int pos); bool IsCrLf(int pos); @@ -182,9 +184,9 @@ public: long FindText(int iMessage, unsigned long wParam, long lParam); const char *SubstituteByPosition(const char *text, int *length); int LinesTotal(); - + void ChangeCase(Range r, bool makeUpperCase); - + void SetWordChars(unsigned char *chars); void SetStylingBits(int bits); void StartStyling(int position, char mask); @@ -196,12 +198,12 @@ public: int SetLineState(int line, int state) { return cb.SetLineState(line, state); } int GetLineState(int line) { return cb.GetLineState(line); } int GetMaxLineState() { return cb.GetMaxLineState(); } - + bool AddWatcher(DocWatcher *watcher, void *userData); bool RemoveWatcher(DocWatcher *watcher, void *userData); const WatcherWithUserData *GetWatchers() const { return watchers; } int GetLenWatchers() const { return lenWatchers; } - + bool IsWordPartSeparator(char ch); int WordPartLeft(int pos); int WordPartRight(int pos); @@ -213,11 +215,11 @@ private: bool IsWordEndAt(int pos); bool IsWordAt(int start, int end); void ModifiedAt(int pos); - + void NotifyModifyAttempt(); void NotifySavePoint(bool atSavePoint); void NotifyModified(DocModification mh); - + int IndentSize() { return indentInChars ? indentInChars : tabInChars; } }; @@ -266,7 +268,7 @@ public: class DocWatcher { public: virtual ~DocWatcher() {} - + virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; diff --git a/src/Editor.cxx b/src/Editor.cxx index 01eb02241..cf490c603 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -16,7 +16,7 @@ #if PLAT_WX || PLAT_GTK #include "WinDefs.h" -#endif +#endif #include "ContractionState.h" #include "SVector.h" @@ -95,7 +95,7 @@ Editor::Editor() { targetStart = 0; targetEnd = 0; searchFlags = 0; - + topLine = 0; posTopLine = 0; @@ -119,7 +119,7 @@ Editor::Editor() { #ifdef MACRO_SUPPORT recordingMacro = 0; -#endif +#endif foldFlags = 0; } @@ -1345,6 +1345,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { // Right column limit indicator + PRectangle rcBeyondEOF = rcClient; rcBeyondEOF.left = vs.fixedColumnWidth; rcBeyondEOF.right = rcBeyondEOF.right; @@ -1543,6 +1544,7 @@ void Editor::SetScrollBarsTo(PRectangle) { //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); } + void Editor::SetScrollBars() { PRectangle rsClient = GetClientRectangle(); SetScrollBarsTo(rsClient); @@ -1713,8 +1715,19 @@ void Editor::DelChar() { void Editor::DelCharBack() { if (currentPos == anchor) { - int newPos = pdoc->DelCharBack(currentPos); - SetEmptySelection(newPos); + int lineCurrentPos = pdoc->LineFromPosition(currentPos); + if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) && + pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) { + pdoc->BeginUndoAction(); + int indentation = pdoc->GetLineIndentation(lineCurrentPos); + int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); + SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); + pdoc->EndUndoAction(); + } else { + int newPos = pdoc->DelCharBack(currentPos); + SetEmptySelection(newPos); + } } else { ClearSelection(); SetEmptySelection(currentPos); @@ -1748,7 +1761,7 @@ void Editor::NotifyChar(char ch) { txt[1] = '\0'; NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<long>(txt)); } -#endif +#endif } void Editor::NotifySavePoint(bool isSavePoint) { @@ -1946,6 +1959,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { NotifyChange(); // Send EN_CHANGE } + SCNotification scn; scn.nmhdr.code = SCN_MODIFIED; scn.position = mh.position; @@ -2040,6 +2054,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long default: // printf("Filtered out %ld of macro recording\n", iMessage); + return ; } @@ -2051,7 +2066,7 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, unsigned long wParam, long scn.lParam = lParam; NotifyParent(scn); } -#endif +#endif // Force scroll and keep position relative to top of window void Editor::PageMove(int direction, bool extend) { @@ -2243,7 +2258,7 @@ int Editor::KeyCommand(unsigned int iMessage) { ShowCaretAtCurrentPosition(); NotifyUpdateUI(); break; - case SCI_CANCEL: // Cancel any modes - handled in subclass + case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text CancelModes(); break; @@ -2415,28 +2430,48 @@ void Editor::Indent(bool forwards) { if (lineOfAnchor == lineCurrentPos) { if (forwards) { ClearSelection(); - if (pdoc->useTabs) { - pdoc->InsertChar(currentPos, '\t'); - SetEmptySelection(currentPos + 1); + if (pdoc->GetColumn(currentPos) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) && + pdoc->tabIndents) { + pdoc->BeginUndoAction(); + int indentation = pdoc->GetLineIndentation(lineCurrentPos); + int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep); + SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); + pdoc->EndUndoAction(); } else { - int numSpaces = (pdoc->tabInChars) - - (pdoc->GetColumn(currentPos) % (pdoc->tabInChars)); - if (numSpaces < 1) - numSpaces = pdoc->tabInChars; - for (int i = 0; i < numSpaces; i++) { - pdoc->InsertChar(currentPos, ' '); + if (pdoc->useTabs) { + pdoc->InsertChar(currentPos, '\t'); + SetEmptySelection(currentPos + 1); + } else { + int numSpaces = (pdoc->tabInChars) - + (pdoc->GetColumn(currentPos) % (pdoc->tabInChars)); + if (numSpaces < 1) + numSpaces = pdoc->tabInChars; + for (int i = 0; i < numSpaces; i++) { + pdoc->InsertChar(currentPos, ' '); + } + SetEmptySelection(currentPos + numSpaces); } - SetEmptySelection(currentPos + numSpaces); } } else { - int newColumn = ((pdoc->GetColumn(currentPos) - 1) / pdoc->tabInChars) * - pdoc->tabInChars; - if (newColumn < 0) - newColumn = 0; - int newPos = currentPos; - while (pdoc->GetColumn(newPos) > newColumn) - newPos--; - SetEmptySelection(newPos); + if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) && + pdoc->tabIndents) { + pdoc->BeginUndoAction(); + int indentation = pdoc->GetLineIndentation(lineCurrentPos); + int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); + SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); + pdoc->EndUndoAction(); + } else { + int newColumn = ((pdoc->GetColumn(currentPos) - 1) / pdoc->tabInChars) * + pdoc->tabInChars; + if (newColumn < 0) + newColumn = 0; + int newPos = currentPos; + while (pdoc->GetColumn(newPos) > newColumn) + newPos--; + SetEmptySelection(newPos); + } } } else { int anchorPosOnLine = anchor - pdoc->LineStart(lineOfAnchor); @@ -2468,8 +2503,8 @@ void Editor::Indent(bool forwards) { * @return The position of the found text, -1 if not found. */ long Editor::FindText( - unsigned int iMessage, ///< Can be @c EM_FINDTEXT or @c EM_FINDTEXTEX or @c SCI_FINDTEXT. - unsigned long wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + unsigned int iMessage, ///< Can be @c EM_FINDTEXT or @c EM_FINDTEXTEX or @c SCI_FINDTEXT. + unsigned long wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. long lParam) { ///< @c TextToFind structure: The text to search for in the given range. @@ -2511,8 +2546,8 @@ void Editor::SearchAnchor() { * @return The position of the found text, -1 if not found. */ long Editor::SearchText( - unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. - unsigned long wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, + unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. + unsigned long wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. long lParam) { ///< The text to search for. @@ -2676,6 +2711,7 @@ void Editor::StartDrag() { //DisplayCursor(Window::cursorArrow); } + void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) { //Platform::DebugPrintf("DropAt %d\n", inDragDrop); if (inDragDrop) @@ -2886,6 +2922,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b //lineAnchor = lineStart; // Keep the same anchor for ButtonMove } + SetDragPosition(invalidPosition); SetMouseCapture(true); selectionType = selLine; @@ -2972,6 +3009,7 @@ void Editor::ButtonMove(Point pt) { return ; // No need to test for selection } + } // Display regular (drag) cursor over selection if (PointInSelection(pt)) @@ -3316,7 +3354,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { #ifdef MACRO_SUPPORT if (recordingMacro) NotifyMacroRecord(iMessage, wParam, lParam); -#endif +#endif switch (iMessage) { @@ -3629,34 +3667,34 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETTARGETSTART: return targetStart; - + case SCI_SETTARGETEND: targetEnd = wParam; break; case SCI_GETTARGETEND: return targetEnd; - + case SCI_REPLACETARGET: PLATFORM_ASSERT(lParam); return ReplaceTarget(wParam, reinterpret_cast<char *>(lParam)); - + case SCI_REPLACETARGETCOUNTED: PLATFORM_ASSERT(lParam); return ReplaceTarget(false, reinterpret_cast<char *>(lParam), wParam); - + case SCI_REPLACETARGETRECOUNTED: PLATFORM_ASSERT(lParam); return ReplaceTarget(true, reinterpret_cast<char *>(lParam), wParam); - + case SCI_SEARCHINTARGET: PLATFORM_ASSERT(lParam); return SearchInTarget(reinterpret_cast<char *>(lParam), wParam); - + case SCI_SETSEARCHFLAGS: searchFlags = wParam; break; - + case SCI_GETSEARCHFLAGS: return searchFlags; @@ -3744,15 +3782,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return len; // Not including NUL } + case EM_SELECTIONTYPE: #ifdef SEL_EMPTY if (currentPos == anchor) return SEL_EMPTY; else return SEL_TEXT; -#else +#else return 0; -#endif +#endif case EM_HIDESELECTION: hideSelection = wParam; @@ -3786,7 +3825,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { vs.rightMarginWidth = vs.aveCharWidth / 2; } InvalidateStyleRedraw(); -#endif +#endif break; case SCI_SETMARGINLEFT: @@ -4018,7 +4057,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->SetStyleFor(wParam, static_cast<char>(lParam)); break; - case SCI_SETSTYLINGEX: // Specify a complete styling buffer + case SCI_SETSTYLINGEX: // Specify a complete styling buffer if (lParam == 0) return 0; pdoc->SetStyles(wParam, reinterpret_cast<char *>(lParam)); @@ -4066,6 +4105,20 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETLINEINDENTPOSITION: return pdoc->GetLineIndentPosition(wParam); + case SCI_SETTABINDENTS: + pdoc->tabIndents = wParam; + break; + + case SCI_GETTABINDENTS: + return pdoc->tabIndents; + + case SCI_SETBACKSPACEUNINDENTS: + pdoc->backspaceUnindents = wParam; + break; + + case SCI_GETBACKSPACEUNINDENTS: + return pdoc->backspaceUnindents; + case SCI_GETCOLUMN: return pdoc->GetColumn(wParam); @@ -4657,7 +4710,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_STOPRECORD: recordingMacro = 0; return 0; -#endif +#endif case SCI_MOVECARETINSIDEVIEW: MoveCaretInsideView(); |