Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Formatter/Indent.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 5.2 KB
Line 
1//
2// Indent.cs
3// 
4// Author:
5//       Mike Krüger <mkrueger@novell.com>
6//
7// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26using System;
27using System.Collections.Generic;
28using System.Linq;
29
30namespace ICSharpCode.NRefactory.CSharp
31{
32  public enum IndentType
33  {
34    Block,
35    DoubleBlock,
36    Continuation,
37    Alignment,
38    Label,
39    Empty
40  }
41
42  public class Indent
43  {
44    readonly CloneableStack<IndentType> indentStack = new CloneableStack<IndentType>();
45    readonly TextEditorOptions options;
46    int curIndent;
47    int extraSpaces;
48    string indentString;
49
50    public int CurIndent {
51      get {
52        return curIndent;
53      }
54    }
55
56    public Indent(TextEditorOptions options)
57    {
58      this.options = options;
59      Reset();
60    }
61
62    Indent(Indent engine)
63    {
64      this.indentStack = engine.indentStack.Clone();
65      this.options = engine.options;
66      this.curIndent = engine.curIndent;
67      this.extraSpaces = engine.extraSpaces;
68      this.indentString = engine.indentString;
69    }
70
71    public Indent Clone()
72    {
73      return new Indent(this);
74    }
75
76    public void Reset()
77    {
78      curIndent = 0;
79      indentString = "";
80      indentStack.Clear();
81    }
82
83    public void Push(IndentType type)
84    {
85      indentStack.Push(type);
86      curIndent += GetIndent(type);
87      Update();
88    }
89
90    public void Push(Indent indent)
91    {
92      foreach (var i in indent.indentStack)
93        Push(i);
94    }
95
96    public void Pop()
97    {
98      curIndent -= GetIndent(indentStack.Pop());
99      Update();
100    }
101
102    public bool PopIf(IndentType type)
103    {
104      if (Count > 0 && Peek() == type)
105      {
106        Pop();
107        return true;
108      }
109
110      return false;
111    }
112
113    public void PopWhile(IndentType type)
114    {
115      while (Count > 0 && Peek() == type)
116      {
117        Pop();
118      }
119    }
120
121    public bool PopTry()
122    {
123      if (Count > 0)
124      {
125        Pop();
126        return true;
127      }
128
129      return false;
130    }
131
132    public int Count {
133      get {
134        return indentStack.Count;
135      }
136    }
137
138    public IndentType Peek()
139    {
140      return indentStack.Peek();
141    }
142
143    int GetIndent(IndentType indentType)
144    {
145      switch (indentType) {
146        case IndentType.Block:
147          return options.IndentSize;
148        case IndentType.DoubleBlock:
149          return options.IndentSize * 2;
150        case IndentType.Alignment:
151        case IndentType.Continuation:
152          return options.ContinuationIndent;
153        case IndentType.Label:
154          return options.LabelIndent;
155        case IndentType.Empty:
156          return 0;
157        default:
158          throw new ArgumentOutOfRangeException();
159      }
160    }
161
162    void Update()
163    {
164      if (options.TabsToSpaces) {
165        indentString = new string(' ', curIndent + ExtraSpaces);
166        return;
167      }
168      indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize) + new string(' ', ExtraSpaces);
169    }
170
171    public int ExtraSpaces {
172      get {
173        return extraSpaces;
174      }
175      set {
176        if (value < 0)
177          throw new ArgumentOutOfRangeException("ExtraSpaces >= 0 but was " + value);
178        extraSpaces = value;
179        Update();
180      }
181    }
182
183
184    public string IndentString {
185      get {
186        return indentString;
187      }
188    }
189
190    public override string ToString()
191    {
192      return string.Format("[Indent: curIndent={0}]", curIndent);
193    }
194
195    public Indent GetIndentWithoutSpace ()
196    {
197      var result = new Indent(options);
198      foreach (var i in indentStack)
199          result.Push(i);
200      return result;
201    }
202
203    public static Indent ConvertFrom(string indentString, Indent correctIndent, TextEditorOptions options = null)
204    {
205      options = options ?? TextEditorOptions.Default;
206      var result = new Indent(options);
207
208      var indent = string.Concat(indentString.Where(c => c == ' ' || c == '\t'));
209      var indentTypes = new Stack<IndentType>(correctIndent.indentStack);
210
211      foreach (var _ in indent.TakeWhile(c => c == '\t'))
212      {
213        if (indentTypes.Count > 0)
214          result.Push(indentTypes.Pop());
215        else
216          result.Push(IndentType.Continuation);
217      }
218
219      result.ExtraSpaces = indent
220        .SkipWhile(c => c == '\t')
221        .TakeWhile(c => c == ' ')
222        .Count();
223
224      return result;
225    }
226
227    public void RemoveAlignment()
228    {
229      ExtraSpaces = 0;
230      if (Count > 0 && Peek() == IndentType.Alignment)
231        Pop();
232    }
233
234    public void SetAlignment(int i, bool forceSpaces = false)
235    {
236      var alignChars = Math.Max(0, i);
237      if (forceSpaces) {
238        ExtraSpaces = alignChars;
239        return;
240      }
241      RemoveAlignment();
242      Push(IndentType.Alignment);
243    }
244
245  }
246}
Note: See TracBrowser for help on using the repository browser.