0:   //  Indent.cs 
1:   //  Copyright (c) 2000 Mike Krueger
2:   //
3:   //  This program is free software; you can redistribute it and/or modify
4:   //  it under the terms of the GNU General Public License as published by
5:   //  the Free Software Foundation; either version 2 of the License, or
6:   //  (at your option) any later version.
7:   //
8:   //  This program is distributed in the hope that it will be useful,
9:   //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10:   //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11:   //  GNU General Public License for more details.
12:   //
13:   //  You should have received a copy of the GNU General Public License
14:   //  along with this program; if not, write to the Free Software
15:   //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16:  
17:   using System;
18:   using System.Collections;
19:   using System.Drawing;
20:   using System.Text;
21:  
22:   using SharpDevelop.Tool.Data;
23:  
24:   namespace SharpDevelop.Internal.Text {
25:       
26:       /// <summary>
27:       /// This class handles the auto and smart indenting in the textbuffer while
28:       /// you type.
29:       /// </summary>
30:       public class Indent
31:       {
32:           public static Point SearchBracketBackward(Point startTextBuffer bufferchar openingBracketchar closingBracket)
33:           {
34:               int brackets = -1;
35:               for (int start.>= 0; --y)
36:                   for (int = (== start.Y) ? start.: buffer[y].Text.Length 1>= 0; --x) {
37:                       char ch buffer[y].Text[x];
38:                       if (ch == closingBracket) {
39:                           --brackets;
40:                       else if (ch == openingBracket) {
41:                           ++brackets;
42:                           if (brackets == 0)
43:                               return new Point(xy);
44:                       }
45:                   }
46:                   return new Point(-1, -1);
47:           }
48:           
49:           public static Point SearchBracketForward(Point startTextBuffer bufferchar openingBracketchar closingBracket)
50:           {
51:               int brackets 1;
52:               for (int start.< buffer.Length; ++y)
53:                   for (int = (== start.Y) ? start.0< buffer[y].Text.Length; ++x) {
54:                       char ch buffer[y].Text[x];
55:                       if (ch == openingBracket) {
56:                           ++brackets;
57:                       else if (ch == closingBracket) {
58:                           --brackets;
59:                           if (brackets == 0) {
60:                               return new Point(xy);
61:                           }
62:                       }
63:                   }
64:                   return new Point(-1, -1);
65:           }
66:           
67:           /// <summary>
68:           /// returns the whitespaces which are before a non white space character in the line line
69:           /// as a string.
70:           /// </summary>
71:           static string GetIndentation(TextBuffer bufferint line)
72:           {
73:               StringBuilder whitespaces new StringBuilder();
74:               foreach (char ch in buffer[line].Text) {
75:                   if (Char.IsWhiteSpace(ch)) {
76:                       whitespaces.Append(ch);
77:                   else {
78:                       break;
79:                   }
80:               }
81:               return whitespaces.ToString();
82:           }
83:           
84:           /// <summary>
85:           /// This function sets the indentlevel in buffer in the line line. It returns the
86:           /// cursor position of the indenting;
87:           /// </summary>
88:           public static int IndentLine(TextBuffer bufferint lineIndentStyle indentstyle)
89:           {
90:               switch (indentstyle) {
91:                   case IndentStyle.None:
92:                       break;
93:                   case IndentStyle.Auto:
94:                       if (line > 0) {
95:                           string indentation GetIndentation(bufferline 1);
96:                           buffer[line ].SetText(lineindentation buffer[line].Text.Trim());
97:                           return indentation.Length;
98:                       }
99:                       break;
100:                   case IndentStyle.Smart:
101:                       bool isCsharp false;
102:                       foreach (string ext in buffer.Syntax.Extensions) {
103:                           isCsharp |= ext == ".cs";
104:                       }
105:                       if (!isCsharp) {
106:                           goto case IndentStyle.Auto;
107:                       }
108:                       if (line > 0) {
109:                           string lineBefore buffer[line 1].Text.Trim();
110:                           
111:                           if (lineBefore.EndsWith(")"&& buffer[line].Text.Trim().StartsWith("{")) {
112:                               string indentation GetIndentation(bufferline 1);
113:                               buffer[line].SetText(lineindentation buffer[line].Text.Trim());
114:                               return indentation.Length;
115:                           else if (buffer[line].Text.Trim().StartsWith("}")) { // indent closing bracket.
116:                               Point closingBracketPoint SearchBracketBackward(new Point(0line), buffer'{''}');
117:                               
118:                               if (closingBracketPoint.== -1) { // no closing bracket found -> autoindent
119:                               goto case IndentStyle.Auto;
120:                               }
121:                               
122:                               string indentation GetIndentation(bufferclosingBracketPoint.Y);
123:                               
124:                               
125:                               buffer[line].SetText(lineindentation buffer[line].Text.Trim());
126:                               
127:                               return indentation.Length;
128:                               //
129:                               //                            Point closingBracketPoint = SearchBracketBackward(new Point(0, line), buffer, '{', '}');
130:                               //
131:                               //                            if (closingBracketPoint.Y == -1) // no closing bracket found -> autoindent
132:                               //                                goto case IndentStyle.Auto;
133:                               //
134:                               //                            string indentation = GetIndentation(buffer, closingBracketPoint.Y);
135:                               //
136:                               //                            buffer[line].SetText(line, indentation + buffer[line].Text.Trim());
137:                               //
138:                               //                            return indentation.Length;
139:                           else if (lineBefore.EndsWith(";")) { // expression ended, reset to valid indent.
140:                               Point closingBracketPoint SearchBracketBackward(new Point(0line), buffer'{''}');
141:                               
142:                               if (closingBracketPoint.== -1) { // no closing bracket found -> autoindent
143:                                   goto case IndentStyle.Auto;
144:                               }
145:                               
146:                               // special handling for switch statement formatting.
147:                               if (buffer[closingBracketPoint.Y].Text.Trim().StartsWith("switch")) {
148:                                   string indentation2 GetIndentation(bufferclosingBracketPoint.Y);
149:                                   
150:                                   
151:                                   if (lineBefore.StartsWith("break;") ||
152:                                       lineBefore.StartsWith("goto") ||
153:                                       lineBefore.StartsWith("return")) {
154:                                           
155:                                           indentation2 += "\t";
156:                                       else {
157:                                           indentation2 += "\t\t";
158:                                       }
159:                                       
160:                                       buffer[line].SetText(lineindentation2 buffer[line].Text.Trim());
161:                                   return indentation2.Length;
162:                               }
163:                               
164:                               string indentation GetIndentation(bufferclosingBracketPoint.Y);
165:                               
166:                               indentation += "\t";
167:                               
168:                               buffer[line].SetText(lineindentation buffer[line].Text.Trim());
169:                               
170:                               return indentation.Length;
171:                           else
172:                               if (lineBefore.EndsWith("{") || // indent opening bracket.
173:                                   lineBefore.EndsWith(":") || // indent case xyz:
174:                                       
175:                                       (lineBefore.EndsWith(")"&&  // indent single line if, for ... etc
176:                                       (lineBefore.StartsWith("if") ||
177:                                        lineBefore.StartsWith("while") ||
178:                                        lineBefore.StartsWith("for"))) ||
179:                                        lineBefore.EndsWith("else")) {
180:                                            
181:                                            string indentation GetIndentation(bufferline 1);
182:                                            int    length      lineBefore.Length;
183:                                            
184:                                            indentation += "\t";
185:                                            
186:                                            buffer[line].SetText(lineindentation buffer[line].Text.Trim());
187:                                            
188:                                            return indentation.Length;
189:                                        else {
190:                                            
191:                                            // try to indent linewrap
192:                                            ArrayList bracketPos new ArrayList();
193:                                            for (int 0< lineBefore.Length; ++i) { // search for a ( bracket that isn't closed
194:                                               switch (lineBefore[i]) {
195:                                                   case '(':
196:                                                       bracketPos.Add(i);
197:                                                       break;
198:                                                   case ')':
199:                                                       if (bracketPos.Count > 0) {
200:                                                           bracketPos.RemoveAt(bracketPos.Count 1);
201:                                                       }
202:                                                       break;
203:                                               }
204:                                            }
205:                                            if (bracketPos.Count > 0) {
206:                                                int bracketIndex = (int)bracketPos[bracketPos.Count 1];
207:                                                string indentation GetIndentation(bufferline 1);
208:                                                
209:                                                for (int 0<= bracketIndex; ++i// insert enough spaces to match
210:                                                indentation += " ";                 // brace start in the next line
211:                                                
212:                                                buffer[line].SetText(lineindentation buffer[line].Text.Trim());
213:                                                
214:                                                return indentation.Length;
215:                                            }
216:                                            
217:                                            // no linewrap -> autoindent
218:                                            goto case IndentStyle.Auto;
219:                                        }
220:                               }
221:                               break;
222:                       }
223:                       return 0// default -> no indenting
224:               }
225:               
226:               public static void IndentLines(TextBuffer bufferint beginint endIndentStyle indentstyle)
227:               {
228:                   buffer.BeginUpdate();
229:                   for (int begin<= end; ++i)
230:                       IndentLine(bufferiindentstyle);
231:                   buffer.UndoStack.UndoLast(end begin 1);
232:                   buffer.EndUpdate();
233:               }
234:           }
235:       }

This page was automatically generated by SharpDevelop.