This patch enables experimental scintilla changebar for geany. For testing only.
Signed-off-by: Jiří Techet techet@gmail.com --- scintilla/CellBuffer.cxx | 366 ++++++++++++++++++++++++++++++++++--- scintilla/CellBuffer.h | 94 +++++++++- scintilla/Document.cxx | 48 +++++- scintilla/Document.h | 13 ++- scintilla/Editor.cxx | 76 ++++++++- scintilla/RunStyles.cxx | 42 +++++ scintilla/RunStyles.h | 6 + scintilla/include/Scintilla.h | 15 ++- scintilla/include/Scintilla.iface | 9 +- src/editor.c | 2 +- src/highlighting.c | 21 ++- src/sciwrappers.c | 10 +- 12 files changed, 649 insertions(+), 53 deletions(-)
diff --git a/scintilla/CellBuffer.cxx b/scintilla/CellBuffer.cxx index 064ef1a..0a47249 100644 --- a/scintilla/CellBuffer.cxx +++ b/scintilla/CellBuffer.cxx @@ -21,6 +21,88 @@ using namespace Scintilla; #endif
+/* CHANGEBAR begin */ +LineChanges::LineChanges() : collecting(0), edition(0) { +} + +LineChanges::~LineChanges() { +} + +void LineChanges::AdvanceEdition() { + edition = (edition + 1) % 0x40000000; +} + +int LineChanges::GetEdition() const { + return edition; +} + +char *LineChanges::PersistantForm() const { + if (collecting) + return state.PersistantForm(); + else + return 0; +} + +void LineChanges::SetChanges(const char *changesState) { + if (collecting && changesState) { + state.FromPersistant(changesState); + AdvanceEdition(); + } +} + +void LineChanges::InsertText(int line, int edition, bool undoing) { + if (collecting && !undoing) { + int position = line; + int fillLength = 1; + if (state.FillRange(position, edition, fillLength)) { + if (fillLength > 0) { + AdvanceEdition(); + } + } + } +} + +void LineChanges::InsertLine(int line, int edition, bool undoing) { + if (collecting && !undoing) { + state.InsertSpace(line, 1); + int linePosition = line; + int fillLength = 1; + if (state.FillRange(linePosition, edition, fillLength)) + AdvanceEdition(); + } +} + +void LineChanges::RemoveLine(int line, bool undoing) { + if (collecting && !undoing) { + state.DeleteRange(line, 1); + AdvanceEdition(); + } +} + +void LineChanges::EnableChangeCollection(bool collecting_, int lines) { + collecting = collecting_; + if (collecting) { + state.InsertSpace(0, lines); + } +} + +void LineChanges::ClearChanged() { + if (collecting) { + int position = 0; + int length = state.Length(); + if (state.FillRange(position, 0, length)) + AdvanceEdition(); + } +} + +int LineChanges::GetChanged(int line) const { + if (collecting) { + return state.ValueAt(line); + } + return 0; +} +/* CHANGEBAR end */ + LineVector::LineVector() : starts(256), perLine(0) { Init(); } @@ -40,33 +122,78 @@ void LineVector::SetPerLine(PerLine *pl) { perLine = pl; }
-void LineVector::InsertText(int line, int delta) { +/* CHANGEBAR begin */ +void LineVector::InsertText(int line, int delta, int edition, bool undoing) { +/* CHANGEBAR end */ starts.InsertText(line, delta); +/* CHANGEBAR begin */ + changes.InsertText(line, edition, undoing); +/* CHANGEBAR end */ }
-void LineVector::InsertLine(int line, int position, bool lineStart) { +/* CHANGEBAR begin */ +void LineVector::InsertLine(int line, int position, bool lineStart, int edition, bool undoing) { +/* CHANGEBAR end */ starts.InsertPartition(line, position); if (perLine) { if ((line > 0) && lineStart) line--; perLine->InsertLine(line); } +/* CHANGEBAR begin */ + changes.InsertLine(line, edition, undoing); +/* CHANGEBAR end */ }
void LineVector::SetLineStart(int line, int position) { starts.SetPartitionStartPosition(line, position); }
-void LineVector::RemoveLine(int line) { +/* CHANGEBAR begin */ +void LineVector::RemoveLine(int line, bool undoing) { +/* CHANGEBAR end */ starts.RemovePartition(line); if (perLine) { perLine->RemoveLine(line); } +/* CHANGEBAR begin */ + changes.RemoveLine(line, undoing); +/* CHANGEBAR end */ }
int LineVector::LineFromPosition(int pos) const { return starts.PartitionFromPosition(pos); } +/* CHANGEBAR begin */ +void LineVector::EnableChangeCollection(bool changesCollecting_) { + DeleteChangeCollection(); + changes.EnableChangeCollection(changesCollecting_, Lines()); +} + +void LineVector::DeleteChangeCollection() { + changes.ClearChanged(); +} + +int LineVector::GetChanged(int line) const { + return changes.GetChanged(line); +} + +int LineVector::GetChangesEdition() const { + return changes.GetEdition(); +} + +void LineVector::SetSavePoint() { + changes.AdvanceEdition(); +} + +char *LineVector::PersistantForm() const { + return changes.PersistantForm(); +} + +void LineVector::SetChanges(const char *changesState) { + changes.SetChanges(changesState); +} +/* CHANGEBAR end */
Action::Action() { at = startAction; @@ -137,11 +264,19 @@ UndoHistory::UndoHistory() { currentAction = 0; undoSequenceDepth = 0; savePoint = 0; +/* CHANGEBAR begin */ + savePointEffective = 0; + + changeActions = 0; +/* CHANGEBAR end */
actions[currentAction].Create(startAction); }
UndoHistory::~UndoHistory() { +/* CHANGEBAR begin */ + DeleteChangeHistory(); +/* CHANGEBAR end */ delete []actions; actions = 0; } @@ -152,6 +287,20 @@ void UndoHistory::EnsureUndoRoom() { if (currentAction >= (lenActions - 2)) { // Run out of undo nodes so extend the array int lenActionsNew = lenActions * 2; + +/* CHANGEBAR begin */ + if (changeActions) { + int **changeActionsNew = new int *[lenActionsNew]; + if (!changeActionsNew) + return; + for (int i=0;i<lenActionsNew;i++) { + changeActionsNew[i] = (i < lenActions) ? changeActions[i] : 0; + } + delete []changeActions; + changeActions = changeActionsNew; + } +/* CHANGEBAR end */ + Action *actionsNew = new Action[lenActionsNew]; for (int act = 0; act <= currentAction; act++) actionsNew[act].Grab(&actions[act]); @@ -161,13 +310,18 @@ void UndoHistory::EnsureUndoRoom() { } }
+/* CHANGEBAR begin */ void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData, - bool &startSequence, bool mayCoalesce) { + bool &startSequence, char *persistantChanges, bool mayCoalesce) { +/* CHANGEBAR end */ 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 (currentAction < savePoint) { +/* CHANGEBAR begin */ + savePointEffective = currentAction; +/* CHANGEBAR end */ savePoint = -1; } int oldCurrentAction = currentAction; @@ -226,6 +380,14 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng } startSequence = oldCurrentAction != currentAction; actions[currentAction].Create(at, position, data, lengthData, mayCoalesce); + +/* CHANGEBAR begin */ + if (changeActions) { + delete []changeActions[currentAction]; + changeActions[currentAction] = (int *)persistantChanges; + } +/* CHANGEBAR end */ + currentAction++; actions[currentAction].Create(startAction); maxAction = currentAction; @@ -269,16 +431,53 @@ void UndoHistory::DeleteUndoHistory() { currentAction = 0; actions[currentAction].Create(startAction); savePoint = 0; -} +/* CHANGEBAR begin */ + savePointEffective = 0; +/* CHANGEBAR end */ +} + +/* CHANGEBAR begin */ +void UndoHistory::DeleteChangeHistory() { + if (changeActions) { + for (int i=0;i<lenActions;i++) { + delete []changeActions[i]; + } + delete []changeActions; + changeActions = 0; + } +} + +void UndoHistory::EnableChangeHistory(bool enable) { + if (enable) { + if (!changeActions) { + changeActions = new int *[lenActions]; + for (int i=0;i<lenActions;i++) { + changeActions[i] = 0; + } + } + } else { + DeleteChangeHistory(); + } +} +/* CHANGEBAR end */
void UndoHistory::SetSavePoint() { savePoint = currentAction; +/* CHANGEBAR begin */ + savePointEffective = currentAction; +/* CHANGEBAR end */ }
bool UndoHistory::IsSavePoint() const { return savePoint == currentAction; }
+/* CHANGEBAR begin */ +bool UndoHistory::BeforeSavePointEffective(int action) const { + return action <= savePointEffective; +} +/* CHANGEBAR end */ + bool UndoHistory::CanUndo() const { return (currentAction > 0) && (maxAction > 0); } @@ -304,6 +503,12 @@ void UndoHistory::CompletedUndoStep() { currentAction--; }
+/* CHANGEBAR begin */ +char *UndoHistory::GetChangesStep() const { + return changeActions ? (char *)changeActions[currentAction] : 0; +} +/* CHANGEBAR end */ + bool UndoHistory::CanRedo() const { return maxAction > currentAction; } @@ -329,6 +534,12 @@ void UndoHistory::CompletedRedoStep() { currentAction++; }
+/* CHANGEBAR begin */ +int UndoHistory::Edition() const { + return currentAction; +} +/* CHANGEBAR end */ + CellBuffer::CellBuffer() { readOnly = false; collectingUndo = true; @@ -377,10 +588,15 @@ const char *CellBuffer::InsertString(int position, const char *s, int insertLeng for (int i = 0; i < insertLength; i++) { data[i] = s[i]; } - uh.AppendAction(insertAction, position, data, insertLength, startSequence); +/* CHANGEBAR begin */ + char *persistantForm = lv.PersistantForm(); + uh.AppendAction(insertAction, position, data, insertLength, startSequence, persistantForm); +/* CHANGEBAR end */ }
- BasicInsertString(position, s, insertLength); +/* CHANGEBAR begin */ + BasicInsertString(position, s, insertLength, false); +/* CHANGEBAR end */ } return data; } @@ -423,10 +639,15 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startS for (int i = 0; i < deleteLength; i++) { data[i] = substance.ValueAt(position + i); } - uh.AppendAction(removeAction, position, data, deleteLength, startSequence); +/* CHANGEBAR begin */ + char *persistantForm = lv.PersistantForm(); + uh.AppendAction(removeAction, position, data, deleteLength, startSequence, persistantForm); +/* CHANGEBAR end */ }
- BasicDeleteChars(position, deleteLength); +/* CHANGEBAR begin */ + BasicDeleteChars(position, deleteLength, false); +/* CHANGEBAR end */ } return data; } @@ -467,23 +688,48 @@ void CellBuffer::SetReadOnly(bool set) {
void CellBuffer::SetSavePoint() { uh.SetSavePoint(); +/* CHANGEBAR begin */ + lv.SetSavePoint(); +/* CHANGEBAR end */ }
bool CellBuffer::IsSavePoint() { return uh.IsSavePoint(); }
+/* CHANGEBAR begin */ +int CellBuffer::GetChanged(int line) const { + int changed = lv.GetChanged(line); + if (changed == 0) + return 0; + else if (uh.BeforeSavePointEffective(changed)) + return 2; + else + return 1; +} + +int CellBuffer::GetChangesEdition() const { + return lv.GetChangesEdition(); +} +/* CHANGEBAR end */ + // Without undo
-void CellBuffer::InsertLine(int line, int position, bool lineStart) { - lv.InsertLine(line, position, lineStart); +/* CHANGEBAR begin */ +void CellBuffer::InsertLine(int line, int position, bool lineStart, int edition, bool undoing) { + lv.InsertLine(line, position, lineStart, edition, undoing); +/* CHANGEBAR end */ }
-void CellBuffer::RemoveLine(int line) { - lv.RemoveLine(line); +/* CHANGEBAR begin */ +void CellBuffer::RemoveLine(int line, bool undoing) { + lv.RemoveLine(line, undoing); +/* CHANGEBAR end */ }
-void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) { +/* CHANGEBAR begin */ +void CellBuffer::BasicInsertString(int position, const char *s, int insertLength, bool undoing) { +/* CHANGEBAR end */ if (insertLength == 0) return; PLATFORM_ASSERT(insertLength > 0); @@ -494,26 +740,34 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength int lineInsert = lv.LineFromPosition(position) + 1; bool atLineStart = lv.LineStart(lineInsert-1) == position; // Point all the lines after the insertion point further along in the buffer - lv.InsertText(lineInsert-1, insertLength); +/* CHANGEBAR begin */ + lv.InsertText(lineInsert-1, insertLength, uh.Edition(), undoing); +/* CHANGEBAR end */ char chPrev = substance.ValueAt(position - 1); char chAfter = substance.ValueAt(position + insertLength); if (chPrev == '\r' && chAfter == '\n') { // Splitting up a crlf pair at position - InsertLine(lineInsert, position, false); +/* CHANGEBAR begin */ + InsertLine(lineInsert, position, false, uh.Edition(), undoing); +/* CHANGEBAR end */ lineInsert++; } char ch = ' '; for (int i = 0; i < insertLength; i++) { ch = s[i]; if (ch == '\r') { - InsertLine(lineInsert, (position + i) + 1, atLineStart); +/* CHANGEBAR begin */ + InsertLine(lineInsert, (position + i) + 1, atLineStart, uh.Edition(), undoing); +/* CHANGEBAR end */ lineInsert++; } else if (ch == '\n') { if (chPrev == '\r') { // Patch up what was end of line lv.SetLineStart(lineInsert - 1, (position + i) + 1); } else { - InsertLine(lineInsert, (position + i) + 1, atLineStart); +/* CHANGEBAR begin */ + InsertLine(lineInsert, (position + i) + 1, atLineStart, uh.Edition(), undoing); +/* CHANGEBAR end */ lineInsert++; } } @@ -523,12 +777,16 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength if (chAfter == '\n') { if (ch == '\r') { // End of line already in buffer so drop the newly created one - RemoveLine(lineInsert - 1); +/* CHANGEBAR begin */ + RemoveLine(lineInsert - 1, undoing); +/* CHANGEBAR end */ } } }
-void CellBuffer::BasicDeleteChars(int position, int deleteLength) { +/* CHANGEBAR begin */ +void CellBuffer::BasicDeleteChars(int position, int deleteLength, bool undoing) { +/* CHANGEBAR end */ if (deleteLength == 0) return;
@@ -541,7 +799,9 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { // to work out which lines have been removed
int lineRemove = lv.LineFromPosition(position) + 1; - lv.InsertText(lineRemove-1, - (deleteLength)); +/* CHANGEBAR begin */ + lv.InsertText(lineRemove-1, - (deleteLength), uh.Edition(), undoing); +/* CHANGEBAR end */ char chPrev = substance.ValueAt(position - 1); char chBefore = chPrev; char chNext = substance.ValueAt(position); @@ -558,13 +818,17 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { chNext = substance.ValueAt(position + i + 1); if (ch == '\r') { if (chNext != '\n') { - RemoveLine(lineRemove); +/* CHANGEBAR begin */ + RemoveLine(lineRemove, undoing); +/* CHANGEBAR end */ } } else if (ch == '\n') { if (ignoreNL) { ignoreNL = false; // Further \n are real deletions } else { - RemoveLine(lineRemove); +/* CHANGEBAR begin */ + RemoveLine(lineRemove, undoing); +/* CHANGEBAR end */ } }
@@ -575,7 +839,9 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) { char chAfter = substance.ValueAt(position + deleteLength); if (chBefore == '\r' && chAfter == '\n') { // Using lineRemove-1 as cr ended line before start of deletion - RemoveLine(lineRemove - 1); +/* CHANGEBAR begin */ + RemoveLine(lineRemove - 1, undoing); +/* CHANGEBAR end */ lv.SetLineStart(lineRemove - 1, position + 1); } } @@ -603,13 +869,36 @@ void CellBuffer::EndUndoAction() {
void CellBuffer::AddUndoAction(int token, bool mayCoalesce) { bool startSequence; - uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce); +/* CHANGEBAR begin */ + char *persistantForm = lv.PersistantForm(); + uh.AppendAction(containerAction, token, 0, 0, startSequence, persistantForm, mayCoalesce); +/* CHANGEBAR end */ }
-void CellBuffer::DeleteUndoHistory() { +/* CHANGEBAR begin */ +void CellBuffer::DeleteUndoHistory(bool collectChangeHistory) { +/* CHANGEBAR end */ uh.DeleteUndoHistory(); +/* CHANGEBAR begin */ + uh.EnableChangeHistory(collectChangeHistory); + lv.EnableChangeCollection(collectChangeHistory); +/* CHANGEBAR end */ +} + +/* CHANGEBAR begin */ +bool CellBuffer::SetChangeCollection(bool collectChange) { + uh.EnableChangeHistory(collectChange); + lv.EnableChangeCollection(collectChange); + return collectChange; }
+void CellBuffer::DeleteChangeCollection() { + uh.DeleteChangeHistory(); + lv.DeleteChangeCollection(); +} +/* CHANGEBAR end */ + + bool CellBuffer::CanUndo() { return uh.CanUndo(); } @@ -623,11 +912,19 @@ const Action &CellBuffer::GetUndoStep() const { }
void CellBuffer::PerformUndoStep() { +/* CHANGEBAR begin */ + const char *changesState = uh.GetChangesStep(); + lv.SetChanges(changesState); +/* CHANGEBAR end */ const Action &actionStep = uh.GetUndoStep(); if (actionStep.at == insertAction) { - BasicDeleteChars(actionStep.position, actionStep.lenData); +/* CHANGEBAR begin */ + BasicDeleteChars(actionStep.position, actionStep.lenData, true); +/* CHANGEBAR end */ } else if (actionStep.at == removeAction) { - BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); +/* CHANGEBAR begin */ + BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData, true); +/* CHANGEBAR end */ } uh.CompletedUndoStep(); } @@ -647,10 +944,19 @@ const Action &CellBuffer::GetRedoStep() const { void CellBuffer::PerformRedoStep() { const Action &actionStep = uh.GetRedoStep(); if (actionStep.at == insertAction) { - BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); +/* CHANGEBAR begin */ + BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData, false); +/* CHANGEBAR end */ } else if (actionStep.at == removeAction) { - BasicDeleteChars(actionStep.position, actionStep.lenData); +/* CHANGEBAR begin */ + BasicDeleteChars(actionStep.position, actionStep.lenData, false); +/* CHANGEBAR end */ } uh.CompletedRedoStep(); +/* CHANGEBAR begin */ + if (IsSavePoint()) { + lv.SetSavePoint(); + } +/* CHANGEBAR end */ }
diff --git a/scintilla/CellBuffer.h b/scintilla/CellBuffer.h index 78f586e..05098d9 100644 --- a/scintilla/CellBuffer.h +++ b/scintilla/CellBuffer.h @@ -21,6 +21,29 @@ public: virtual void RemoveLine(int)=0; };
+/* CHANGEBAR begin */ +#include "RunStyles.h" +class LineChanges { + bool collecting; + RunStyles state; + int edition; +public: + LineChanges(); + ~LineChanges(); + void AdvanceEdition(); + int GetEdition() const; + char *PersistantForm() const; + void SetChanges(const char *changesState); + void InsertText(int line, int edition, bool undoing); + void InsertLine(int line, int edition, bool undoing); + void RemoveLine(int line, bool undoing); + void EnableChangeCollection(bool collecting_, int lines); + void ClearChanged(); + int GetChanged(int line) const; +}; +/* CHANGEBAR end */ + + /** * The line vector contains information about each of the lines in a cell buffer. */ @@ -28,6 +51,9 @@ class LineVector {
Partitioning starts; PerLine *perLine; +/* CHANGEBAR begin */ + LineChanges changes; +/* CHANGEBAR end */
public:
@@ -36,10 +62,14 @@ public: void Init(); void SetPerLine(PerLine *pl);
- void InsertText(int line, int delta); - void InsertLine(int line, int position, bool lineStart); +/* CHANGEBAR begin */ + void InsertText(int line, int delta, int edition, bool undoing); + void InsertLine(int line, int position, bool lineStart, int edition, bool undoing); +/* CHANGEBAR end */ void SetLineStart(int line, int position); - void RemoveLine(int line); +/* CHANGEBAR begin */ + void RemoveLine(int line, bool undoing); +/* CHANGEBAR end */ int Lines() const { return starts.Partitions(); } @@ -63,6 +93,17 @@ public: int GetLineState(int line); int GetMaxLineState();
+ +/* CHANGEBAR begin */ + void EnableChangeCollection(bool changesCollecting_); + void DeleteChangeCollection(); + int GetChanged(int line) const; + void SetSavePoint(); + int GetChangesEdition() const; + void PerformingUndo(bool undo); + char *PersistantForm() const; + void SetChanges(const char *changesState); +/* CHANGEBAR end */ };
enum actionType { insertAction, removeAction, startAction, containerAction }; @@ -95,6 +136,10 @@ class UndoHistory { int currentAction; int undoSequenceDepth; int savePoint; +/* CHANGEBAR begin */ + int savePointEffective; + int **changeActions; +/* CHANGEBAR end */
void EnsureUndoRoom();
@@ -102,17 +147,27 @@ public: UndoHistory(); ~UndoHistory();
- void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true); +/* CHANGEBAR begin */ + void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, char *persistantChanges, bool mayCoalesce=true); +/* CHANGEBAR end */
void BeginUndoAction(); void EndUndoAction(); void DropUndoSequence(); void DeleteUndoHistory();
+/* CHANGEBAR begin */ + void DeleteChangeHistory(); + void EnableChangeHistory(bool enable); +/* CHANGEBAR end */ + /// 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; +/* CHANGEBAR begin */ + bool BeforeSavePointEffective(int action) const; +/* CHANGEBAR end */
/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. @@ -120,10 +175,17 @@ public: int StartUndo(); const Action &GetUndoStep() const; void CompletedUndoStep(); +/* CHANGEBAR begin */ + char *GetChangesStep() const; +/* CHANGEBAR end */ bool CanRedo() const; int StartRedo(); const Action &GetRedoStep() const; void CompletedRedoStep(); + +/* CHANGEBAR begin */ + int Edition() const; +/* CHANGEBAR end */ };
/** @@ -159,8 +221,10 @@ public: int Lines() const; int LineStart(int line) const; int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); } - void InsertLine(int line, int position, bool lineStart); - void RemoveLine(int line); +/* CHANGEBAR begin */ + void InsertLine(int line, int position, bool lineStart, int edition, bool undoing); + void RemoveLine(int line, bool undoing); +/* CHANGEBAR end */ const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
/// Setting styles for positions outside the range of the buffer is safe and has no effect. @@ -178,16 +242,28 @@ public: void SetSavePoint(); bool IsSavePoint();
+/* CHANGEBAR begin */ + void EnableChangeCollection(bool changesCollecting_); + bool SetChangeCollection(bool collectChange); + void DeleteChangeCollection(); + int GetChanged(int line) const; + int GetChangesEdition() const; +/* CHANGEBAR end */ + /// Actions without undo - void BasicInsertString(int position, const char *s, int insertLength); - void BasicDeleteChars(int position, int deleteLength); +/* CHANGEBAR begin */ + void BasicInsertString(int position, const char *s, int insertLength, bool undoing); + void BasicDeleteChars(int position, int deleteLength, bool undoing); +/* CHANGEBAR end */
bool SetUndoCollection(bool collectUndo); bool IsCollectingUndo() const; void BeginUndoAction(); void EndUndoAction(); void AddUndoAction(int token, bool mayCoalesce); - void DeleteUndoHistory(); +/* CHANGEBAR begin */ + void DeleteUndoHistory(bool collectChangeHistory); +/* CHANGEBAR end */
/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. diff --git a/scintilla/Document.cxx b/scintilla/Document.cxx index 3c90d1f..57dc30a 100644 --- a/scintilla/Document.cxx +++ b/scintilla/Document.cxx @@ -148,7 +148,15 @@ int Document::Release() { }
void Document::SetSavePoint() { +/* CHANGEBAR begin */ + int changesEdition = cb.GetChangesEdition(); +/* CHANGEBAR end */ cb.SetSavePoint(); +/* CHANGEBAR begin */ + if (cb.GetChangesEdition() != changesEdition) { + NotifyModified(DocModification(SC_MOD_CHANGEMARKER, 0, 0, 0, 0, -1)); + } +/* CHANGEBAR end */ NotifySavePoint(true); }
@@ -504,6 +512,10 @@ bool Document::DeleteChars(int pos, int len) { SC_MOD_BEFOREDELETE | SC_PERFORMED_USER, pos, len, 0, 0)); + +/* CHANGEBAR begin */ + int changesEdition = cb.GetChangesEdition(); +/* CHANGEBAR end */ int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); bool startSequence = false; @@ -514,9 +526,15 @@ bool Document::DeleteChars(int pos, int len) { ModifiedAt(pos); else ModifiedAt(pos-1); +/* CHANGEBAR begin */ + int changeBarFlags = (cb.GetChangesEdition() == changesEdition) ? + 0 : SC_MOD_CHANGEMARKER | SC_MOD_CHANGEFOLD; +/* CHANGEBAR end */ NotifyModified( DocModification( - SC_MOD_DELETETEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), +/* CHANGEBAR begin */ + SC_MOD_DELETETEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0) | changeBarFlags, +/* CHANGEBAR end */ pos, len, LinesTotal() - prevLinesTotal, text)); } @@ -543,6 +561,10 @@ bool Document::InsertString(int position, const char *s, int insertLength) { SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, position, insertLength, 0, s)); + +/* CHANGEBAR begin */ + int changesEdition = cb.GetChangesEdition(); +/* CHANGEBAR end */ int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); bool startSequence = false; @@ -550,9 +572,15 @@ bool Document::InsertString(int position, const char *s, int insertLength) { if (startSavePoint && cb.IsCollectingUndo()) NotifySavePoint(!startSavePoint); ModifiedAt(position); +/* CHANGEBAR begin */ + int changeBarFlags = (cb.GetChangesEdition() == changesEdition) ? + 0 : SC_MOD_CHANGEMARKER | SC_MOD_CHANGEFOLD; +/* CHANGEBAR end */ NotifyModified( DocModification( - SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), +/* CHANGEBAR begin */ + SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0) | changeBarFlags, +/* CHANGEBAR end */ position, insertLength, LinesTotal() - prevLinesTotal, text)); } @@ -569,6 +597,9 @@ int Document::Undo() { if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; +/* CHANGEBAR begin */ + int changesEdition = cb.GetChangesEdition(); +/* CHANGEBAR end */ int steps = cb.StartUndo(); //Platform::DebugPrintf("Steps=%d\n", steps); for (int step = 0; step < steps; step++) { @@ -610,6 +641,11 @@ int Document::Undo() { if (multiLine) modFlags |= SC_MULTILINEUNDOREDO; } +/* CHANGEBAR begin */ + int changeBarFlags = (cb.GetChangesEdition() == changesEdition) ? + 0 : SC_MOD_CHANGEMARKER | SC_MOD_CHANGEFOLD; + modFlags |= changeBarFlags; +/* CHANGEBAR end */ NotifyModified(DocModification(modFlags, cellPosition, action.lenData, linesAdded, action.data)); } @@ -631,6 +667,9 @@ int Document::Redo() { if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; +/* CHANGEBAR begin */ + int changesEdition = cb.GetChangesEdition(); +/* CHANGEBAR end */ int steps = cb.StartRedo(); for (int step = 0; step < steps; step++) { const int prevLinesTotal = LinesTotal(); @@ -669,6 +708,11 @@ int Document::Redo() { if (multiLine) modFlags |= SC_MULTILINEUNDOREDO; } +/* CHANGEBAR begin */ + int changeBarFlags = (cb.GetChangesEdition() == changesEdition) ? + 0 : SC_MOD_CHANGEMARKER | SC_MOD_CHANGEFOLD; + modFlags |= changeBarFlags; +/* CHANGEBAR end */ NotifyModified( DocModification(modFlags, action.position, action.lenData, linesAdded, action.data)); diff --git a/scintilla/Document.h b/scintilla/Document.h index 1c270a5..0bd0a04 100644 --- a/scintilla/Document.h +++ b/scintilla/Document.h @@ -213,11 +213,19 @@ public: int Redo(); bool CanUndo() { return cb.CanUndo(); } bool CanRedo() { return cb.CanRedo(); } - void DeleteUndoHistory() { cb.DeleteUndoHistory(); } +/* CHANGEBAR begin */ + void DeleteUndoHistory(bool collectChangeHistory=false) { cb.DeleteUndoHistory(collectChangeHistory); } +/* CHANGEBAR end */ bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } bool IsCollectingUndo() { return cb.IsCollectingUndo(); } +/* CHANGEBAR begin */ + void DeleteChangeCollection() { cb.DeleteChangeCollection(); } + bool SetChangeCollection(bool collectChange) { + return cb.SetChangeCollection(collectChange); + } +/* CHANGEBAR end */ void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } @@ -265,6 +273,9 @@ public: void ClearLevels(); int GetLastChild(int lineParent, int level=-1); int GetFoldParent(int line); +/* CHANGEBAR begin */ + int GetChanged(int line) { return cb.GetChanged(line); } +/* CHANGEBAR end */
void Indent(bool forwards); int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); diff --git a/scintilla/Editor.cxx b/scintilla/Editor.cxx index 2bc6580..e16b837 100644 --- a/scintilla/Editor.cxx +++ b/scintilla/Editor.cxx @@ -1750,6 +1750,14 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { } }
+/* CHANGEBAR begin */ + int changed = pdoc->GetChanged(lineDoc); + if (changed == 1) + marks |= 1 << SC_MARKNUM_CHANGEUNSAVED; + if (changed == 2) + marks |= 1 << SC_MARKNUM_CHANGESAVED; +/* CHANGEBAR end */ + marks &= vs.ms[margin].mask; PRectangle rcMarker = rcSelMargin; rcMarker.top = yposScreen; @@ -6726,9 +6734,75 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0;
case SCI_EMPTYUNDOBUFFER: - pdoc->DeleteUndoHistory(); +/* CHANGEBAR begin */ + pdoc->DeleteUndoHistory(wParam != 0); + Redraw(); +/* CHANGEBAR end */ + return 0; + +/* CHANGEBAR begin */ + case SCI_SETCHANGECOLLECTION: + pdoc->SetChangeCollection(wParam != 0); return 0;
+ case SCI_GETCHANGEDLINE: { + int fromLine = static_cast<int>(wParam); + if (fromLine < 0) + { + fromLine = 0; + } + int toLine = static_cast<int>(lParam); + if (toLine > pdoc->LinesTotal()) + { + toLine = pdoc->LinesTotal(); + } + + if(fromLine <= toLine) + { + for (int i = fromLine; i <= toLine; i++) + { + if(pdoc->GetChanged(i) != 0) + { + return i; + } + } + // if nothing found we wrap and start from the beginning + if (fromLine > 0) + { + for (int i = 0; i <= fromLine; i++) + { + if(pdoc->GetChanged(i) != 0) + { + return i; + } + } + } + } + else + { + for (int i = fromLine; i >= toLine; i--) + { + if(pdoc->GetChanged(i) != 0) + { + return i; + } + } + // if nothing found we wrap and start from the end + if (fromLine < (pdoc->LinesTotal() - 1)) + { + for (int i = (pdoc->LinesTotal() - 1); i >= fromLine; i--) + { + if(pdoc->GetChanged(i) != 0) + { + return i; + } + } + } + } + return -1; + } +/* CHANGEBAR end */ + case SCI_GETFIRSTVISIBLELINE: return topLine;
diff --git a/scintilla/RunStyles.cxx b/scintilla/RunStyles.cxx index ae32c73..446b1ec 100644 --- a/scintilla/RunStyles.cxx +++ b/scintilla/RunStyles.cxx @@ -214,3 +214,45 @@ void RunStyles::DeleteRange(int position, int deleteLength) { } }
+/* CHANGEBAR begin */ +char *RunStyles::PersistantForm() const { + int len = starts->Partitions(); + char *form = new char[(len * 2 + 1) * sizeof(int)]; + int *data = reinterpret_cast<int *>(form); + data[0] = len; + for (int i=0;i<len;i++) { + data[i*2+1] = starts->PositionFromPartition(i+1) - starts->PositionFromPartition(i); + data[i*2+2] = styles->ValueAt(i); + } + return form; +} + +void RunStyles::FromPersistant(const char *form) { + DeleteAll(); + const int *data = reinterpret_cast<const int *>(form); + int len = data[0]; + int pos = 0; + for (int i=0;i<len;i++) { + int runLength = data[i*2+1]; + int value = data[i*2+2]; + InsertSpace(pos, runLength); + int posTemp = pos; + int fillLength = runLength; + FillRange(posTemp, value, fillLength); + pos += runLength; + } +} + +bool RunStyles::PersistantSame(const char *form1, const char *form2) { + const int *data1 = reinterpret_cast<const int *>(form1); + const int *data2 = reinterpret_cast<const int *>(form2); + if (data1[0] != data2[0]) + return false; + int len = data1[0]; + for (int i=1;i<len*2+1;i++) { + if (data1[i] != data2[i]) + return false; + } + return true; +} +/* CHANGEBAR end */ diff --git a/scintilla/RunStyles.h b/scintilla/RunStyles.h index 0a333ca..e2734a6 100644 --- a/scintilla/RunStyles.h +++ b/scintilla/RunStyles.h @@ -37,6 +37,12 @@ public: void InsertSpace(int position, int insertLength); void DeleteAll(); void DeleteRange(int position, int deleteLength); + +/* CHANGEBAR begin */ + char *PersistantForm() const; + void FromPersistant(const char *form); + static bool PersistantSame(const char *form1, const char *form2); +/* CHANGEBAR end */ };
#ifdef SCI_NAMESPACE diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index b91c78c..f70f8b7 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -126,6 +126,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MARK_AVAILABLE 28 #define SC_MARK_UNDERLINE 29 #define SC_MARK_CHARACTER 10000 +/* CHANGEBAR begin */ +#define SC_MARKNUM_CHANGEUNSAVED 23 +#define SC_MARKNUM_CHANGESAVED 24 +/* CHANGEBAR end */ #define SC_MARKNUM_FOLDEREND 25 #define SC_MARKNUM_FOLDEROPENMID 26 #define SC_MARKNUM_FOLDERMIDTAIL 27 @@ -133,7 +137,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MARKNUM_FOLDERSUB 29 #define SC_MARKNUM_FOLDER 30 #define SC_MARKNUM_FOLDEROPEN 31 -#define SC_MASK_FOLDERS 0xFE000000 +/* CHANGEBAR begin */ +#define SC_MASK_FOLDERS 0xFF800000 +/* CHANGEBAR end */ #define SCI_MARKERDEFINE 2040 #define SCI_MARKERSETFORE 2041 #define SCI_MARKERSETBACK 2042 @@ -152,6 +158,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_MARGIN_FORE 3 #define SC_MARGIN_TEXT 4 #define SC_MARGIN_RTEXT 5 +/* CHANGEBAR begin */ +#define SC_MARGIN_CHANGED 6 +/* CHANGEBAR end */ #define SCI_SETMARGINTYPEN 2240 #define SCI_GETMARGINTYPEN 2241 #define SCI_SETMARGINWIDTHN 2242 @@ -402,6 +411,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_VISIBLEFROMDOCLINE 2220 #define SCI_DOCLINEFROMVISIBLE 2221 #define SCI_WRAPCOUNT 2235 +/* CHANGEBAR begin */ +#define SCI_SETCHANGECOLLECTION 2236 +#define SCI_GETCHANGEDLINE 2237 +/* CHANGEBAR end */ #define SC_FOLDLEVELBASE 0x400 #define SC_FOLDLEVELWHITEFLAG 0x1000 #define SC_FOLDLEVELHEADERFLAG 0x2000 diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index 7d64f2d..154413d 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -275,7 +275,11 @@ val SC_MARK_UNDERLINE=29 val SC_MARK_CHARACTER=10000
enu MarkerOutline=SC_MARKNUM_ -# Markers used for outlining column. +# CHANGEBAR begin # +# Markers used for outlining and changed column. +val SC_MARKNUM_CHANGEUNSAVED=23 +val SC_MARKNUM_CHANGESAVED=24 +# CHANGEBAR end # val SC_MARKNUM_FOLDEREND=25 val SC_MARKNUM_FOLDEROPENMID=26 val SC_MARKNUM_FOLDERMIDTAIL=27 @@ -329,6 +333,9 @@ val SC_MARGIN_BACK=2 val SC_MARGIN_FORE=3 val SC_MARGIN_TEXT=4 val SC_MARGIN_RTEXT=5 +# CHANGEBAR begin # +val SC_MARGIN_CHANGED=6 +# CHANGEBAR end #
# Set a margin to be either numeric or symbolic. set void SetMarginTypeN=2240(int margin, int marginType) diff --git a/src/editor.c b/src/editor.c index d51623a..af602fa 100644 --- a/src/editor.c +++ b/src/editor.c @@ -373,7 +373,7 @@ static void on_margin_click(GeanyEditor *editor, SCNotification *nt) sci_toggle_marker_at_line(editor->sci, line, 1); /* toggle the marker */ } /* left click on the folding margin to toggle folding state of current line */ - else if (nt->margin == 2 && editor_prefs.folding) + else if (nt->margin == 3 && editor_prefs.folding) { gint line = sci_get_line_from_position(editor->sci, nt->position); editor_toggle_fold(editor, line, nt->modifiers); diff --git a/src/highlighting.c b/src/highlighting.c index c5794de..5d71fd7 100644 --- a/src/highlighting.c +++ b/src/highlighting.c @@ -679,9 +679,26 @@ static void styleset_common(ScintillaObject *sci, filetype_id ft_id) SSM(sci, SCI_MARKERSETBACK, 1, invert(common_style_set.styling[GCS_MARKER_MARK].background)); SSM(sci, SCI_MARKERSETALPHA, 1, common_style_set.styling[GCS_MARKER_TRANSLUCENCY].background);
- /* 2 -> folding marker, other folding settings */ + /* 2 -> changebar */ + guint mask = (1 << SC_MARKNUM_CHANGEUNSAVED) | (1 << SC_MARKNUM_CHANGESAVED); + SSM(sci, SCI_SETMARGINTYPEN, 2, SC_MARGIN_SYMBOL); - SSM(sci, SCI_SETMARGINMASKN, 2, SC_MASK_FOLDERS); + SSM(sci, SCI_SETMARGINMASKN, 2, mask); + SSM(sci, SCI_SETMARGINWIDTHN, 2, 4 ); + + SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_CHANGEUNSAVED, SC_MARK_LEFTRECT); + SSM(sci, SCI_MARKERSETBACK, SC_MARKNUM_CHANGEUNSAVED, 0xFF | (0xE6 << 8) | (0x04 << 16)); + SSM(sci, SCI_MARKERSETFORE, SC_MARKNUM_CHANGEUNSAVED, 0xFF | (0xFF << 8) | (0xFF << 16)); + + SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_CHANGESAVED, SC_MARK_LEFTRECT); + SSM(sci, SCI_MARKERSETBACK, SC_MARKNUM_CHANGESAVED, 0x04 | (0xFF << 8) | (0x50 << 16)); + SSM(sci, SCI_MARKERSETFORE, SC_MARKNUM_CHANGESAVED, 0xFF | (0xFF << 8) | (0xFF << 16)); + + SSM(sci, SCI_SETCHANGECOLLECTION, 1, 0); + + /* 3 -> folding marker, other folding settings */ + SSM(sci, SCI_SETMARGINTYPEN, 3, SC_MARGIN_SYMBOL); + SSM(sci, SCI_SETMARGINMASKN, 3, SC_MASK_FOLDERS ^ mask);
/* drawing a horizontal line when text if folded */ switch (common_style_set.fold_draw_line) diff --git a/src/sciwrappers.c b/src/sciwrappers.c index 3b00b55..0f14418 100644 --- a/src/sciwrappers.c +++ b/src/sciwrappers.c @@ -116,13 +116,13 @@ void sci_set_folding_margin_visible(ScintillaObject *sci, gboolean set) { if (set) { - SSM(sci, SCI_SETMARGINWIDTHN, 2, 12); - SSM(sci, SCI_SETMARGINSENSITIVEN, 2, TRUE); + SSM(sci, SCI_SETMARGINWIDTHN, 3, 12); + SSM(sci, SCI_SETMARGINSENSITIVEN, 3, TRUE); } else { - SSM(sci, SCI_SETMARGINSENSITIVEN, 2, FALSE); - SSM(sci, SCI_SETMARGINWIDTHN, 2, 0); + SSM(sci, SCI_SETMARGINSENSITIVEN, 3, FALSE); + SSM(sci, SCI_SETMARGINWIDTHN, 3, 0); } }
@@ -242,7 +242,7 @@ void sci_set_undo_collection(ScintillaObject *sci, gboolean set)
void sci_empty_undo_buffer(ScintillaObject *sci) { - SSM(sci, SCI_EMPTYUNDOBUFFER, 0, 0); + SSM(sci, SCI_EMPTYUNDOBUFFER, 1, 0); }