aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Document.cxx90
-rw-r--r--src/Document.h7
-rw-r--r--src/Editor.cxx19
3 files changed, 97 insertions, 19 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 44e55671f..7e4b888fc 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -34,6 +34,8 @@ Document::Document() {
enteredCount = 0;
enteredReadOnlyCount = 0;
tabInChars = 8;
+ indentInChars = 0;
+ useTabs = true;
watchers = 0;
lenWatchers = 0;
}
@@ -501,26 +503,76 @@ int Document::DelCharBack(int pos) {
}
}
-void Document::Indent(bool forwards, int lineBottom, int lineTop) {
- if (forwards) {
- // Indent by a tab
- for (int line = lineBottom; line >= lineTop; line--) {
- InsertChar(LineStart(line), '\t');
+static bool isindentchar(char ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+static int NextTab(int pos, int tabSize) {
+ return ((pos / tabSize) + 1) * tabSize;
+}
+
+static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {
+ length--; // ensure space for \0
+ if (!insertSpaces) {
+ while ((indent >= tabSize) && (length > 0)) {
+ *linebuf++ = '\t';
+ indent -= tabSize;
+ length--;
}
- } else {
- // Dedent - suck white space off the front of the line to dedent by equivalent of a tab
- for (int line = lineBottom; line >= lineTop; line--) {
- int ispc = 0;
- while (ispc < tabInChars && cb.CharAt(LineStart(line) + ispc) == ' ')
- ispc++;
- int posStartLine = LineStart(line);
- if (ispc == tabInChars) {
- DeleteChars(posStartLine, ispc);
- } else if (cb.CharAt(posStartLine + ispc) == '\t') {
- DeleteChars(posStartLine, ispc + 1);
- } else { // Hit a non-white
- DeleteChars(posStartLine, ispc);
- }
+ }
+ while ((indent > 0) && (length > 0)) {
+ *linebuf++ = ' ';
+ indent--;
+ length--;
+ }
+ *linebuf = '\0';
+}
+
+int Document::GetLineIndentation(int line) {
+ int indent = 0;
+ if (line >= 0) {
+ int lineStart = LineStart(line);
+ int length = Length();
+ for (int i=lineStart;i<length;i++) {
+ char ch = cb.CharAt(i);
+ if (ch == ' ')
+ indent++;
+ else if (ch == '\t')
+ indent = NextTab(indent, tabInChars);
+ else
+ return indent;
+ }
+ }
+ return indent;
+}
+
+int Document::GetLineIndentPosition(int line) {
+ int pos = LineStart(line);
+ int length = Length();
+ while ((pos < length) && isindentchar(cb.CharAt(pos))) {
+ pos++;
+ }
+ return pos;
+}
+
+void Document::Indent(bool forwards, int lineBottom, int lineTop) {
+ char linebuf[1000];
+ // Dedent - suck white space off the front of the line to dedent by equivalent of a tab
+ for (int line = lineBottom; line >= lineTop; line--) {
+ int indentOfLine = GetLineIndentation(line);
+ int indentNew = indentOfLine;
+ if (forwards)
+ indentNew += IndentSize();
+ else
+ indentNew -= IndentSize();
+ if (indentNew < 0)
+ indentNew = 0;
+ if (indentNew != indentOfLine) {
+ CreateIndentation(linebuf, sizeof(linebuf), indentNew, tabInChars, !useTabs);
+ int thisLineStart = LineStart(line);
+ int indentPos = GetLineIndentPosition(line);
+ DeleteChars(thisLineStart, indentPos - thisLineStart);
+ InsertString(thisLineStart, linebuf);
}
}
}
diff --git a/src/Document.h b/src/Document.h
index 2e00efee5..af449ac73 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -90,6 +90,8 @@ public:
// dbcsCodePage can also be SC_CP_UTF8 to enable UTF-8 mode
int dbcsCodePage;
int tabInChars;
+ int indentInChars;
+ bool useTabs;
Document();
virtual ~Document();
@@ -182,10 +184,15 @@ private:
bool IsWordChar(unsigned char ch);
bool IsWordAt(int start, int end);
void ModifiedAt(int pos);
+
+ int GetLineIndentation(int line);
+ int GetLineIndentPosition(int line);
void NotifyModifyAttempt();
void NotifySavePoint(bool atSavePoint);
void NotifyModified(DocModification mh);
+
+ int IndentSize() { return indentInChars ? indentInChars : tabInChars; }
};
// To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 677013a00..ef6b4b450 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -3365,6 +3365,25 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
InvalidateStyleRedraw();
break;
+ case SCI_GETTABWIDTH:
+ return pdoc->tabInChars;
+
+ case SCI_SETINDENT:
+ pdoc->indentInChars = wParam;
+ InvalidateStyleRedraw();
+ break;
+
+ case SCI_GETINDENT:
+ return pdoc->indentInChars;
+
+ case SCI_SETUSETABS:
+ pdoc->useTabs = wParam;
+ InvalidateStyleRedraw();
+ break;
+
+ case SCI_GETUSETABS:
+ return pdoc->useTabs;
+
case SCI_SETCODEPAGE:
pdoc->dbcsCodePage = wParam;
break;