diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CellBuffer.cxx | 316 | ||||
-rw-r--r-- | src/CellBuffer.h | 49 | ||||
-rw-r--r-- | src/Document.cxx | 48 | ||||
-rw-r--r-- | src/Document.h | 5 | ||||
-rw-r--r-- | src/Editor.cxx | 98 | ||||
-rw-r--r-- | src/Editor.h | 2 | ||||
-rw-r--r-- | src/KeyMap.cxx | 45 | ||||
-rw-r--r-- | src/KeyMap.h | 1 | ||||
-rw-r--r-- | src/LexCPP.cxx | 23 |
9 files changed, 420 insertions, 167 deletions
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index 777688511..4d667dcf4 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -344,31 +344,199 @@ void Action::Grab(Action *source) { source->lenData = 0; } -CellBuffer::CellBuffer(int initialLength) { - body = new char[initialLength]; - size = initialLength; - length = 0; - part1len = 0; - gaplen = initialLength; - part2body = body + gaplen; - readOnly = false; +// The undo history stores a sequence of user operations that represent the user's view of the +// commands executed on the text. +// Each user operation contains a sequence of text insertion and text deletion actions. +// All the user operations are stored in a list of individual actions with 'start' actions used +// as delimiters between user operations. +// Initially there is one start action in the history. +// As each action is performed, it is recorded in the history. The action may either become +// part of the current user operation or may start a new user operation. If it is to be part of the +// current operation, then it overwrites the current last action. If it is to be part of a new +// operation, it is appended after the current last action. +// After writing the new action, a new start action is appended at the end of the history. +// The decision of whether to start a new user operation is based upon two factors. If a +// compound operation has been explicitly started by calling BeginUndoAction and no matching +// EndUndoAction (these calls nest) has been called, then the action is coalesced into the current +// operation. If there is no outstanding BeginUndoAction call then a new operation is started +// unless it looks as if the new action is caused by the user typing or deleting a stream of text. +// Sequences that look like typing or deletion are coalesced into a single user operation. + +UndoHistory::UndoHistory() { lenActions = 100; actions = new Action[lenActions]; maxAction = 0; currentAction = 0; - collectingUndo = undoCollectAutoStart; undoSequenceDepth = 0; savePoint = 0; actions[currentAction].Create(startAction); } +UndoHistory::~UndoHistory() { + delete []actions; + actions = 0; +} + +void UndoHistory::EnsureUndoRoom() { + //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); + if (currentAction >= 2) { + // Have to test that there is room for 2 more actions in the array + // as two actions may be created by this function + if (currentAction >= (lenActions - 2)) { + // Run out of undo nodes so extend the array + int lenActionsNew = lenActions * 2; + Action *actionsNew = new Action[lenActionsNew]; + if (!actionsNew) + return; + for (int act = 0; act <= currentAction; act++) + actionsNew[act].Grab(&actions[act]); + delete []actions; + lenActions = lenActionsNew; + actions = actionsNew; + } + } +} + +void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData) { + EnsureUndoRoom(); + Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); + Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at, + actions[currentAction - 1].position, actions[currentAction - 1].lenData); + if (0 == undoSequenceDepth) { + // Top level actions may not always be coalesced + if (currentAction >= 2) { + Action &actPrevious = actions[currentAction - 1]; + // See if current action can be coalesced into previous action + // Will work if both are inserts or deletes and position is same + if (at != actPrevious.at) { + currentAction++; + } else if (currentAction == savePoint) { + currentAction++; + } else if ((at == removeAction) && + ((position + lengthData * 2) != actPrevious.position)) { + // Removals must be at same position to coalesce + currentAction++; + } else if ((at == insertAction) && + (position != (actPrevious.position + actPrevious.lenData*2))) { + // Insertions must be immediately after to coalesce + currentAction++; + } else { + Platform::DebugPrintf("action coalesced\n"); + } + } else { + currentAction++; + } + } + actions[currentAction].Create(at, position, data, lengthData); + //if ((collectingUndo == undoCollectAutoStart) && (0 == undoSequenceDepth)) { + currentAction++; + actions[currentAction].Create(startAction); + //} + maxAction = currentAction; +} + +void UndoHistory::BeginUndoAction() { + EnsureUndoRoom(); + if (undoSequenceDepth == 0) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } + undoSequenceDepth++; +} + +void UndoHistory::EndUndoAction() { + EnsureUndoRoom(); + undoSequenceDepth--; + if (0 == undoSequenceDepth) { + if (actions[currentAction].at != startAction) { + currentAction++; + actions[currentAction].Create(startAction); + maxAction = currentAction; + } + } +} + +void UndoHistory::DropUndoSequence() { + undoSequenceDepth = 0; +} + +void UndoHistory::DeleteUndoHistory() { + for (int i = 1; i < maxAction; i++) + actions[i].Destroy(); + maxAction = 0; + currentAction = 0; + savePoint = 0; +} + +void UndoHistory::SetSavePoint() { + savePoint = currentAction; +} + +bool UndoHistory::IsSavePoint() const { + return savePoint == currentAction; +} + +bool UndoHistory::CanUndo() const { + return (currentAction > 0) && (maxAction > 0); +} + +int UndoHistory::StartUndo() { + // Drop any trailing startAction + if (actions[currentAction].at == startAction && currentAction > 0) + currentAction--; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act > 0) { + act--; + } + return currentAction - act; +} + +const Action &UndoHistory::UndoStep() { + return actions[currentAction--]; +} + +bool UndoHistory::CanRedo() const { + return maxAction > currentAction; +} + +int UndoHistory::StartRedo() { + // Drop any leading startAction + if (actions[currentAction].at == startAction && currentAction < maxAction) + currentAction++; + + // Count the steps in this action + int act = currentAction; + while (actions[act].at != startAction && act < maxAction) { + act++; + } + return act - currentAction; +} + +const Action &UndoHistory::RedoStep() { + return actions[currentAction++]; +} + +CellBuffer::CellBuffer(int initialLength) { + body = new char[initialLength]; + size = initialLength; + length = 0; + part1len = 0; + gaplen = initialLength; + part2body = body + gaplen; + readOnly = false; + collectingUndo = undoCollectAutoStart; +} + CellBuffer::~CellBuffer() { delete []body; body = 0; - delete []actions; - actions = 0; } void CellBuffer::GapTo(int position) { @@ -486,7 +654,7 @@ const char *CellBuffer::InsertString(int position, char *s, int insertLength) { for (int i = 0; i < insertLength / 2; i++) { data[i] = s[i * 2]; } - AppendAction(insertAction, position, data, insertLength / 2); + uh.AppendAction(insertAction, position, data, insertLength / 2); } BasicInsertString(position, s, insertLength); @@ -525,48 +693,6 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas return changed; } -void CellBuffer::EnsureUndoRoom() { - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction); - if (currentAction >= 2) { - // Have to test that there is room for 2 more actions in the array - // as two actions may be created by this function - if (currentAction >= (lenActions - 2)) { - // Run out of undo nodes so extend the array - int lenActionsNew = lenActions * 2; - Action *actionsNew = new Action[lenActionsNew]; - if (!actionsNew) - return; - for (int act = 0; act <= currentAction; act++) - actionsNew[act].Grab(&actions[act]); - delete []actions; - lenActions = lenActionsNew; - actions = actionsNew; - } - } -} - -void CellBuffer::AppendAction(actionType at, int position, char *data, int lengthData) { - EnsureUndoRoom(); - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); - if (currentAction >= 2) { - // See if current action can be coalesced into previous action - // Will work if both are inserts or deletes and position is same or two different - if ((at != actions[currentAction - 1].at) || (abs(position - actions[currentAction - 1].position) > 2)) { - currentAction++; - } else if (currentAction == savePoint) { - currentAction++; - } - } else { - currentAction++; - } - actions[currentAction].Create(at, position, data, lengthData); - if ((collectingUndo == undoCollectAutoStart) && (0 == undoSequenceDepth)) { - currentAction++; - actions[currentAction].Create(startAction); - } - maxAction = currentAction; -} - const char *CellBuffer::DeleteChars(int position, int deleteLength) { // InsertString and DeleteChars are the bottleneck though which all changes occur char *data = 0; @@ -577,7 +703,7 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength) { for (int i = 0; i < deleteLength / 2; i++) { data[i] = ByteAt(position + i * 2); } - AppendAction(removeAction, position, data, deleteLength / 2); + uh.AppendAction(removeAction, position, data, deleteLength / 2); } BasicDeleteChars(position, deleteLength); @@ -616,11 +742,11 @@ void CellBuffer::SetReadOnly(bool set) { } void CellBuffer::SetSavePoint() { - savePoint = currentAction; + uh.SetSavePoint(); } bool CellBuffer::IsSavePoint() { - return savePoint == currentAction; + return uh.IsSavePoint(); } int CellBuffer::AddMark(int line, int markerNum) { @@ -659,7 +785,7 @@ int CellBuffer::LineFromHandle(int markerHandle) { // Without undo void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { - //Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength); + Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength); if (insertLength == 0) return; RoomFor(insertLength); @@ -719,7 +845,7 @@ void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { } void CellBuffer::BasicDeleteChars(int position, int deleteLength) { - //Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength); + Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength); if (deleteLength == 0) return; @@ -792,7 +918,7 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) { collectingUndo = collectUndo; - undoSequenceDepth = 0; + uh.DropUndoSequence(); return collectingUndo; } @@ -800,69 +926,28 @@ bool CellBuffer::IsCollectingUndo() { return collectingUndo; } -void CellBuffer::AppendUndoStartAction() { - EnsureUndoRoom(); - // Finish any currently active undo sequence - undoSequenceDepth = 0; - if (actions[currentAction].at != startAction) { - undoSequenceDepth++; - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } -} - void CellBuffer::BeginUndoAction() { - EnsureUndoRoom(); - if (undoSequenceDepth == 0) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } - undoSequenceDepth++; + uh.BeginUndoAction(); } void CellBuffer::EndUndoAction() { - EnsureUndoRoom(); - undoSequenceDepth--; - if (0 == undoSequenceDepth) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - } + uh.EndUndoAction(); } void CellBuffer::DeleteUndoHistory() { - for (int i = 1; i < maxAction; i++) - actions[i].Destroy(); - maxAction = 0; - currentAction = 0; - savePoint = 0; + uh.DeleteUndoHistory(); } bool CellBuffer::CanUndo() { - return (!readOnly) && ((currentAction > 0) && (maxAction > 0)); + return (!readOnly) && (uh.CanUndo()); } int CellBuffer::StartUndo() { - // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) - currentAction--; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act > 0) { - act--; - } - return currentAction - act; + return uh.StartUndo(); } const Action &CellBuffer::UndoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.UndoStep(); if (actionStep.at == insertAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } else if (actionStep.at == removeAction) { @@ -874,29 +959,19 @@ const Action &CellBuffer::UndoStep() { BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - currentAction--; return actionStep; } bool CellBuffer::CanRedo() { - return (!readOnly) && (maxAction > currentAction); + return (!readOnly) && (uh.CanRedo()); } int CellBuffer::StartRedo() { - // Drop any leading startAction - if (actions[currentAction].at == startAction && currentAction < maxAction) - currentAction++; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act < maxAction) { - act++; - } - return act - currentAction; + return uh.StartRedo(); } const Action &CellBuffer::RedoStep() { - const Action &actionStep = actions[currentAction]; + const Action &actionStep = uh.RedoStep(); if (actionStep.at == insertAction) { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { @@ -908,7 +983,6 @@ const Action &CellBuffer::RedoStep() { } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - currentAction++; return actionStep; } diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 5fbe2ea8a..6e052077e 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -89,6 +89,42 @@ public: enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart }; +class UndoHistory { + Action *actions; + int lenActions; + int maxAction; + int currentAction; + int undoSequenceDepth; + int savePoint; + + void EnsureUndoRoom(); + +public: + UndoHistory(); + ~UndoHistory(); + + void AppendAction(actionType at, int position, char *data, int length); + + void BeginUndoAction(); + void EndUndoAction(); + void DropUndoSequence(); + void DeleteUndoHistory(); + + // The save point is a marker in the undo stack where the container has stated that + // the buffer was saved. Undo and redo can move over the save point. + void SetSavePoint(); + bool IsSavePoint() const; + + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is + // called that many times. Similarly for redo. + bool CanUndo() const; + int StartUndo(); + const Action &UndoStep(); + bool CanRedo() const; + int StartRedo(); + const Action &RedoStep(); +}; + // Holder for an expandable array of characters that supports undo and line markers // Based on article "Data Structures in a Bit-Mapped Text Editor" // by Wilfred J. Hansen, Byte January 1987, page 183 @@ -102,13 +138,8 @@ private: char *part2body; bool readOnly; - Action *actions; - int lenActions; - int maxAction; - int currentAction; undoCollectionType collectingUndo; - int undoSequenceDepth; - int savePoint; + UndoHistory uh; LineVector lv; @@ -117,9 +148,6 @@ private: void GapTo(int position); void RoomFor(int insertionLength); - void EnsureUndoRoom(); - void AppendAction(actionType at, int position, char *data, int length); - inline char ByteAt(int position); void SetByteAt(int position, char ch); @@ -170,12 +198,11 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo); bool IsCollectingUndo(); - void AppendUndoStartAction(); void BeginUndoAction(); void EndUndoAction(); void DeleteUndoHistory(); - // To perform an undo, StartUndo is called to retreive the number of steps, then UndoStep is + // To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is // called that many times. Similarly for redo. bool CanUndo(); int StartUndo(); diff --git a/src/Document.cxx b/src/Document.cxx index b50b9691a..bfb52d36e 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -94,22 +94,25 @@ int Document::LineStart(int line) { return cb.LineStart(line); } -int Document::LineFromPosition(int pos) { - return cb.LineFromPosition(pos); -} - -int Document::LineEndPosition(int position) { - int line = LineFromPosition(position); +int Document::LineEnd(int line) { if (line == LinesTotal() - 1) { - position = LineStart(line + 1); + return LineStart(line + 1); } else { - position = LineStart(line + 1) - 1; + int position = LineStart(line + 1) - 1; // When line terminator is CR+LF, may need to go back one more if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) { position--; } + return position; } - return position; +} + +int Document::LineFromPosition(int pos) { + return cb.LineFromPosition(pos); +} + +int Document::LineEndPosition(int position) { + return LineEnd(LineFromPosition(position)); } int Document::VCHomePosition(int position) { @@ -335,6 +338,7 @@ int Document::Undo() { enteredCount++; bool startSavePoint = cb.IsSavePoint(); int steps = cb.StartUndo(); + Platform::DebugPrintf("Steps=%d\n", steps); for (int step=0; step<steps; step++) { int prevLinesTotal = LinesTotal(); const Action &action = cb.UndoStep(); @@ -345,9 +349,11 @@ int Document::Undo() { int modFlags = SC_PERFORMED_UNDO; // With undo, an insertion action becomes a deletion notification if (action.at == removeAction) { + Platform::DebugPrintf("Insert of %d\n", action.lenData); newPos += action.lenData; modFlags |= SC_MOD_INSERTTEXT; } else { + Platform::DebugPrintf("Remove of %d\n", action.lenData); modFlags |= SC_MOD_DELETETEXT; } if (step == steps-1) @@ -423,6 +429,11 @@ void Document::InsertString(int position, const char *s, int insertLength) { } } +void Document::ChangeChar(int pos, char ch) { + DeleteChars(pos, 1); + InsertChar(pos, ch); +} + void Document::DelChar(int pos) { if (IsCrLf(pos)) { DeleteChars(pos, 2); @@ -633,6 +644,25 @@ int Document::LinesTotal() { return cb.Lines(); } +void Document::ChangeCase(Range r, bool makeUpperCase) { + for (int pos=r.start; pos<r.end; pos++) { + char ch = CharAt(pos); + if (dbcsCodePage && IsDBCS(pos)) { + pos++; + } else { + if (makeUpperCase) { + if (islower(ch)) { + ChangeChar(pos, toupper(ch)); + } + } else { + if (isupper(ch)) { + ChangeChar(pos, tolower(ch)); + } + } + } + } +} + void Document::SetWordChars(unsigned char *chars) { int ch; for (ch = 0; ch < 256; ch++) { diff --git a/src/Document.h b/src/Document.h index 59215c75a..4c212b7bd 100644 --- a/src/Document.h +++ b/src/Document.h @@ -111,7 +111,6 @@ public: undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { return cb.SetUndoCollection(collectUndo); } - void AppendUndoStartAction() { cb.AppendUndoStartAction(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void SetSavePoint(); @@ -123,6 +122,7 @@ public: void InsertChar(int pos, char ch); void InsertString(int position, const char *s); void InsertString(int position, const char *s, int insertLength); + void ChangeChar(int pos, char ch); void DelChar(int pos); int DelCharBack(int pos); @@ -138,6 +138,7 @@ public: void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } int LineStart(int line); + int LineEnd(int line); int LineEndPosition(int position); int VCHomePosition(int position); @@ -154,6 +155,8 @@ public: long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); int LinesTotal(); + void ChangeCase(Range r, bool makeUpperCase); + void SetWordChars(unsigned char *chars); void SetStylingBits(int bits); void StartStyling(int position, char mask); diff --git a/src/Editor.cxx b/src/Editor.cxx index 8550286ac..226184db2 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1700,6 +1700,11 @@ void Editor::NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_VCHOMEEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: break; // Filter out all others (display changes, etc) @@ -1735,6 +1740,60 @@ void Editor::PageMove(int direction, bool extend) { } } +void Editor::ChangeCaseOfSelection(bool makeUpperCase) { + pdoc->BeginUndoAction(); + int startCurrent = currentPos; + int startAnchor = anchor; + if (selType == selRectangle) { + int lineStart = pdoc->LineFromPosition(SelectionStart()); + int lineEnd = pdoc->LineFromPosition(SelectionEnd()); + for (int line=lineStart; line <= lineEnd; line++) { + pdoc->ChangeCase( + Range(SelectionStart(line), SelectionEnd(line)), + makeUpperCase); + } + // Would be nicer to keep the rectangular selection but this is complex + selType = selStream; + SetSelection(startCurrent, startCurrent); + } else { + pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()), + makeUpperCase); + SetSelection(startCurrent, startAnchor); + } + pdoc->EndUndoAction(); +} + + +void Editor::LineTranspose() { + int line = pdoc->LineFromPosition(currentPos); + if (line > 0) { + int startPrev = pdoc->LineStart(line-1); + int endPrev = pdoc->LineEnd(line-1); + int start = pdoc->LineStart(line); + int end = pdoc->LineEnd(line); + int startNext = pdoc->LineStart(line+1); + if (end < pdoc->Length()) { + end = startNext; + char *thisLine = CopyRange(start, end); + pdoc->DeleteChars(start, end-start); + pdoc->InsertString(startPrev, thisLine, end-start); + MovePositionTo(startPrev+end-start); + delete []thisLine; + } else { + // Last line so line has no line end + char *thisLine = CopyRange(start, end); + char *prevEnd = CopyRange(endPrev, start); + pdoc->DeleteChars(endPrev, end-endPrev); + pdoc->InsertString(startPrev, thisLine, end-start); + pdoc->InsertString(startPrev + end-start, prevEnd, start-endPrev); + MovePositionTo(startPrev + end-endPrev); + delete []thisLine; + delete []prevEnd; + } + + } +} + int Editor::KeyCommand(UINT iMessage) { Point pt = LocationFromPosition(currentPos); @@ -1910,6 +1969,37 @@ int Editor::KeyCommand(UINT iMessage) { MovePositionTo(currentPos); } break; + case SCI_LINECUT: { + int lineStart = pdoc->LineFromPosition(currentPos); + int lineEnd = pdoc->LineFromPosition(anchor); + if (lineStart > lineEnd) { + int t = lineEnd; + lineEnd = lineStart; + lineStart = t; + } + int start = pdoc->LineStart(lineStart); + int end = pdoc->LineStart(lineEnd+1); + SetSelection(start,end); + Cut(); + } + break; + case SCI_LINEDELETE: { + int line = pdoc->LineFromPosition(currentPos); + int start = pdoc->LineStart(line); + int end = pdoc->LineStart(line+1); + pdoc->DeleteChars(start, end-start); + MovePositionTo(start); + } + break; + case SCI_LINETRANSPOSE: + LineTranspose(); + break; + case SCI_LOWERCASE: + ChangeCaseOfSelection(false); + break; + case SCI_UPPERCASE: + ChangeCaseOfSelection(true); + break; } return 0; } @@ -3094,7 +3184,8 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_APPENDUNDOSTARTACTION: - pdoc->AppendUndoStartAction(); + // Not just deprecated - now dead + //pdoc->AppendUndoStartAction(); return 0; #endif @@ -3649,6 +3740,11 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { case SCI_ZOOMOUT: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: + case SCI_LINECUT: + case SCI_LINEDELETE: + case SCI_LINETRANSPOSE: + case SCI_LOWERCASE: + case SCI_UPPERCASE: return KeyCommand(iMessage); case SCI_BRACEHIGHLIGHT: diff --git a/src/Editor.h b/src/Editor.h index 16bcd4b22..d1281be5a 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -228,6 +228,8 @@ protected: // ScintillaBase subclass needs access to much of Editor #endif void PageMove(int direction, bool extend=false); + void ChangeCaseOfSelection(bool makeUpperCase); + void LineTranspose(); virtual int KeyCommand(UINT iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDown(int key, bool shift, bool ctrl, bool alt); diff --git a/src/KeyMap.cxx b/src/KeyMap.cxx index f339cd275..9ab9694df 100644 --- a/src/KeyMap.cxx +++ b/src/KeyMap.cxx @@ -61,36 +61,36 @@ UINT KeyMap::Find(int key, int modifiers) { } KeyToCommand KeyMap::MapDefault[] = { - VK_DOWN, SCI_NORM, SCI_LINEDOWN, - VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, - VK_UP, SCI_NORM, SCI_LINEUP, - VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, + VK_DOWN, SCI_NORM, SCI_LINEDOWN, + VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND, + VK_UP, SCI_NORM, SCI_LINEUP, + VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND, VK_LEFT, SCI_NORM, SCI_CHARLEFT, VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND, VK_LEFT, SCI_CTRL, SCI_WORDLEFT, VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND, - VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, - VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, - VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, - VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, - VK_HOME, SCI_NORM, SCI_VCHOME, - VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, - VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, - VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, + VK_RIGHT, SCI_NORM, SCI_CHARRIGHT, + VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND, + VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT, + VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND, + VK_HOME, SCI_NORM, SCI_VCHOME, + VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND, + VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART, + VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND, VK_END, SCI_NORM, SCI_LINEEND, VK_END, SCI_SHIFT, SCI_LINEENDEXTEND, VK_END, SCI_CTRL, SCI_DOCUMENTEND, VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND, - VK_PRIOR, SCI_NORM, SCI_PAGEUP, - VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, - VK_NEXT, SCI_NORM, SCI_PAGEDOWN, - VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, + VK_PRIOR, SCI_NORM, SCI_PAGEUP, + VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND, + VK_NEXT, SCI_NORM, SCI_PAGEDOWN, + VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND, VK_DELETE, SCI_NORM, WM_CLEAR, VK_DELETE, SCI_SHIFT, WM_CUT, VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT, - VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, - VK_INSERT, SCI_SHIFT, WM_PASTE, - VK_INSERT, SCI_CTRL, WM_COPY, + VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE, + VK_INSERT, SCI_SHIFT, WM_PASTE, + VK_INSERT, SCI_CTRL, WM_COPY, VK_ESCAPE, SCI_NORM, SCI_CANCEL, VK_BACK, SCI_NORM, SCI_DELETEBACK, VK_BACK, SCI_CTRL, SCI_DELWORDLEFT, @@ -103,9 +103,14 @@ KeyToCommand KeyMap::MapDefault[] = { VK_TAB, SCI_NORM, SCI_TAB, VK_TAB, SCI_SHIFT, SCI_BACKTAB, VK_RETURN, SCI_NORM, SCI_NEWLINE, - 'L', SCI_CTRL, SCI_FORMFEED, VK_ADD, SCI_CTRL, SCI_ZOOMIN, VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT, + //'L', SCI_CTRL, SCI_FORMFEED, + 'L', SCI_CTRL, SCI_LINECUT, + 'L', SCI_CSHIFT, SCI_LINEDELETE, + 'T', SCI_CTRL, SCI_LINETRANSPOSE, + 'U', SCI_CTRL, SCI_LOWERCASE, + 'U', SCI_CSHIFT, SCI_UPPERCASE, 0,0,0, }; diff --git a/src/KeyMap.h b/src/KeyMap.h index 814f3aa3b..bc435e197 100644 --- a/src/KeyMap.h +++ b/src/KeyMap.h @@ -11,6 +11,7 @@ #define SCI_CTRL LEFT_CTRL_PRESSED #define SCI_ALT LEFT_ALT_PRESSED #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) +#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) class KeyToCommand { public: diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index c6d56702e..4afae231f 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -17,9 +17,10 @@ #include "Scintilla.h" #include "SciLexer.h" -static void classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { +static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, StylingContext &styler) { char s[100]; bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); + bool wordIsUUID = false; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; @@ -28,10 +29,13 @@ static void classifyWordCpp(unsigned int start, unsigned int end, WordList &keyw if (wordIsNumber) chAttr = SCE_C_NUMBER; else { - if (keywords.InList(s)) + if (keywords.InList(s)) { chAttr = SCE_C_WORD; + wordIsUUID = strcmp(s, "uuid") == 0; + } } styler.ColourTo(end, chAttr); + return wordIsUUID; } static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], @@ -52,6 +56,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo unsigned int lengthDoc = startPos + length; int visChars = 0; styler.StartSegment(startPos); + bool lastWordWasUUID = false; for (unsigned int i = startPos; i <= lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); @@ -86,7 +91,12 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo if (state == SCE_C_DEFAULT) { if (iswordstart(ch)) { styler.ColourTo(i-1, state); - state = SCE_C_WORD; + if (lastWordWasUUID) { + state = SCE_C_UUID; + lastWordWasUUID = false; + } else { + state = SCE_C_WORD; + } } else if (ch == '/' && chNext == '*') { styler.ColourTo(i-1, state); if (styler.SafeGetCharAt(i + 2) == '*') @@ -114,7 +124,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo } } else if (state == SCE_C_WORD) { if (!iswordchar(ch)) { - classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); + lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; if (ch == '/' && chNext == '*') { if (styler.SafeGetCharAt(i + 2) == '*') @@ -199,6 +209,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } + } else if (state == SCE_C_UUID) { + if (ch == '\r' || ch == '\n' || ch == ')') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } } if (state == SCE_C_DEFAULT) { // One of the above succeeded if (ch == '/' && chNext == '*') { |