1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2004 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "aneditor-priv.h"
23 void AnEditor::IndentationIncrease(){
24 Sci_CharacterRange crange
= GetSelection();
25 if (crange
.cpMin
!= crange
.cpMax
)
30 int line
=SendEditor(SCI_LINEFROMPOSITION
, SendEditor (SCI_GETCURRENTPOS
));
31 int indent
=GetLineIndentation(line
);
32 indent
+=SendEditor(SCI_GETINDENT
);
33 SetLineIndentation(line
, indent
);
36 void AnEditor::IndentationDecrease(){
37 Sci_CharacterRange crange
= GetSelection();
38 if (crange
.cpMin
!= crange
.cpMax
)
40 SendEditor (SCI_BACKTAB
);
43 int line
=SendEditor(SCI_LINEFROMPOSITION
, SendEditor (SCI_GETCURRENTPOS
));
44 int indent
= GetLineIndentation(line
);
45 indent
-=SendEditor(SCI_GETINDENT
);
46 if (indent
< 0) indent
= 0;
47 SetLineIndentation(line
, indent
);
50 void AnEditor::SetLineIndentation(int line
, int indent
) {
53 Sci_CharacterRange crange
= GetSelection();
54 int posBefore
= GetLineIndentPosition(line
);
55 SendEditor(SCI_SETLINEINDENTATION
, line
, indent
);
56 int posAfter
= GetLineIndentPosition(line
);
57 int posDifference
= posAfter
- posBefore
;
58 if (posAfter
> posBefore
) {
60 if (crange
.cpMin
>= posBefore
) {
61 crange
.cpMin
+= posDifference
;
63 if (crange
.cpMax
>= posBefore
) {
64 crange
.cpMax
+= posDifference
;
66 } else if (posAfter
< posBefore
) {
67 // Move selection back
68 if (crange
.cpMin
>= posAfter
) {
69 if (crange
.cpMin
>= posBefore
)
70 crange
.cpMin
+= posDifference
;
72 crange
.cpMin
= posAfter
;
74 if (crange
.cpMax
>= posAfter
) {
75 if (crange
.cpMax
>= posBefore
)
76 crange
.cpMax
+= posDifference
;
78 crange
.cpMax
= posAfter
;
81 SetSelection(crange
.cpMin
, crange
.cpMax
);
84 int AnEditor::GetLineIndentation(int line
) {
85 return SendEditor(SCI_GETLINEINDENTATION
, line
);
88 int AnEditor::GetLineIndentPosition(int line
) {
89 return SendEditor(SCI_GETLINEINDENTPOSITION
, line
);
92 bool AnEditor::RangeIsAllWhitespace(int start
, int end
) {
93 char *buffer
= new char [end
- start
+ 1];
94 bool all_white
= true;
96 GetRange(wEditor
, start
, end
, buffer
);
98 for (int i
= start
;i
< end
;i
++) {
99 if ((buffer
[i
] != ' ') && (buffer
[i
] != '\t'))
107 void AnEditor::MaintainIndentation(char ch
) {
108 int eolMode
= SendEditor(SCI_GETEOLMODE
);
109 int curLine
= GetCurrentLineNumber();
110 int lastLine
= curLine
- 1;
111 int indentAmount
= 0;
113 if (((eolMode
== SC_EOL_CRLF
|| eolMode
== SC_EOL_LF
) && ch
== '\n') ||
114 (eolMode
== SC_EOL_CR
&& ch
== '\r')) {
115 if (props
->GetInt("indent.automatic")) {
116 while (lastLine
>= 0 && GetLineLength(lastLine
) == 0)
120 indentAmount
= GetLineIndentation(lastLine
);
122 if (indentAmount
> 0) {
123 SetLineIndentation(curLine
, indentAmount
);
129 void AnEditor::AutomaticIndentation(char ch
) {
130 Sci_CharacterRange crange
= GetSelection();
131 int selStart
= crange
.cpMin
;
132 int curLine
= GetCurrentLineNumber();
133 int thisLineStart
= SendEditor(SCI_POSITIONFROMLINE
, curLine
);
134 int indentSize
= SendEditor(SCI_GETINDENT
);
136 if (blockEnd
.IsSingleChar() && ch
== blockEnd
.words
[0]) {
138 if (!indentClosing
) {
139 if (RangeIsAllWhitespace(thisLineStart
, selStart
- 1)) {
140 int indentBlock
= IndentOfBlockProper(curLine
- 1);
141 SetLineIndentation(curLine
, indentBlock
- indentSize
);
144 } else if (!blockEnd
.IsSingleChar() && (ch
== ' ')) {
146 if (!indentClosing
&& (GetIndentState(curLine
) == isBlockEnd
)) {}
147 } else if (ch
== blockStart
.words
[0]) {
148 // Dedent maybe if first on line and previous line was starting keyword
149 if (!indentOpening
&&
150 (GetIndentState(curLine
- 1) == isKeyWordStart
)) {
151 if (RangeIsAllWhitespace(thisLineStart
, selStart
- 1)) {
152 int indentBlock
= IndentOfBlockProper(curLine
- 1);
153 SetLineIndentation(curLine
, indentBlock
- indentSize
);
156 } else if ((ch
== '\r' || ch
== '\n') && (selStart
== thisLineStart
)) {
157 // printf("New line block\n");
158 int indentBlock
= IndentOfBlock(curLine
- 1);
159 if (!indentClosing
&& !blockEnd
.IsSingleChar()) {
160 // Dedent previous line maybe
162 SString controlWords
[1];
163 // printf ("First if\n");
165 if (GetLinePartsInStyle(curLine
-1, blockEnd
.styleNumber
,
166 -1, controlWords
, ELEMENTS(controlWords
))) {
167 // printf ("Second if\n");
168 if (includes(blockEnd
, controlWords
[0])) {
169 // printf ("Third if\n");
170 // Check if first keyword on line is an ender
171 SetLineIndentation(curLine
-1,
172 IndentOfBlockProper(curLine
-2)
174 // Recalculate as may have changed previous line
175 indentBlock
= IndentOfBlock(curLine
- 1);
179 SetLineIndentation(curLine
, indentBlock
);
182 if (SendEditor (SCI_GETCOLUMN
,
183 SendEditor(SCI_GETCURRENTPOS
)) < indentBlock
)
184 SendEditor (SCI_VCHOME
);
186 } else if (lexLanguage
== SCLEX_CPP
) {
189 int indentBlock
= IndentOfBlock(curLine
- 1);
190 int indentState
= GetIndentState (curLine
);
192 if (blockStart
.IsSingleChar() && indentState
== isBlockStart
) {
193 if (!indentOpening
) {
194 if (RangeIsAllWhitespace(thisLineStart
, selStart
- 1)) {
195 // int indentBlock = IndentOfBlockProper(curLine - 1);
196 SetLineIndentation(curLine
, indentBlock
- indentSize
);
199 } else if (blockEnd
.IsSingleChar() && indentState
== isBlockEnd
) {
200 if (!indentClosing
) {
201 if (RangeIsAllWhitespace(thisLineStart
, selStart
- 1)) {
202 // int indentBlock = IndentOfBlockProper(curLine - 1);
203 SetLineIndentation(curLine
, indentBlock
- indentSize
);
207 SetLineIndentation(curLine
, indentBlock
);
211 if (SendEditor (SCI_GETCOLUMN
,
212 SendEditor(SCI_GETCURRENTPOS
)) < indentBlock
)
213 SendEditor (SCI_VCHOME
);