From dba48e020c0a68a84f4f5f11d5600bba90598da3 Mon Sep 17 00:00:00 2001 From: nyamatongwe Date: Mon, 10 Apr 2000 03:29:08 +0000 Subject: Tab size and indent size can now be different. Indentation can contain either a mixture of tabs and spaces or only spaces. --- doc/ScintillaDoc.html | 8 +++-- include/Scintilla.h | 6 ++++ src/Document.cxx | 90 ++++++++++++++++++++++++++++++++++++++++----------- src/Document.h | 7 ++++ src/Editor.cxx | 19 +++++++++++ 5 files changed, 109 insertions(+), 21 deletions(-) diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index fde329522..6678f3aac 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -408,10 +408,14 @@ SCI_SETBUFFEREDDRAW(bool isbuffered)

 SCI_SETTABWIDTH(int widthinchars)
+SCI_SETINDENT(int widthinchars)
+SCI_SETUSETABS(bool usetabs)
 

- Sets the size of a tab as a multiple of the size of a space character in the style of the - first style definition + SCI_SETTABWIDTH sets the size of a tab as a multiple of the size of a space character in the style of the + first style definition. SCI_SETINDENT sets the size of indentation in terms of characters. + SCI_SETUSETABS determines whether indentation should be created out of a micture of tabs + and space or be based purely on spaces.

 SCI_SETCODEPAGE(int codepage)
diff --git a/include/Scintilla.h b/include/Scintilla.h
index f39ce4535..58fc6777b 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -217,6 +217,12 @@ extern "C" {
 #define SCI_AUTOCCOMPLETE SCI_START + 104
 #define SCI_AUTOCSTOPS SCI_START + 105
 
+#define SCI_GETTABWIDTH SCI_START + 121
+#define SCI_SETINDENT SCI_START + 122
+#define SCI_GETINDENT SCI_START + 123
+#define SCI_SETUSETABS SCI_START + 124
+#define SCI_GETUSETABS SCI_START + 125
+
 #define SCI_CALLTIPSHOW SCI_START + 200
 #define SCI_CALLTIPCANCEL SCI_START + 201
 #define SCI_CALLTIPACTIVE SCI_START + 202
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= 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;
-- 
cgit v1.2.3