This patch enables experimental scintilla changebar for geany. For testing only.
Signed-off-by: JiÅ™Ă Techet <techet(a)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);
}
--
1.7.0.4