diff options
author | nyamatongwe <unknown> | 2001-05-14 03:26:53 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2001-05-14 03:26:53 +0000 |
commit | 466ec638ae719c9256286862355b33a39c7f136b (patch) | |
tree | 130d3d877cd2b55ce719a4dec978ce3bc8e8b3fe /src | |
parent | 94eccf378241a5cefbfe7cec6734694cc85ee8b8 (diff) | |
download | scintilla-mirror-466ec638ae719c9256286862355b33a39c7f136b.tar.gz |
Merged patch from Michele to add ability for tab key to perform indent when
selection is empty and within indentation and for backspace to unindent in
the same circumstances.
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(); |