/// <summary>
        /// This function sets the indentlevel in a range of lines.
        /// </summary>
        public override void IndentLines(TextArea textArea, int begin, int end)
        {
            if (textArea.Document.TextEditorProperties.IndentStyle != IndentStyle.Smart)
            {
                base.IndentLines(textArea, begin, end);
                return;
            }
            int cursorPos       = textArea.Caret.Position.Y;
            int oldIndentLength = 0;

            if (cursorPos >= begin && cursorPos <= end)
            {
                oldIndentLength = GetIndentation(textArea, cursorPos).Length;
            }

            IndentationSettings set = new IndentationSettings();

            set.IndentString = Tab.GetIndentationString(textArea.Document);
            IndentationReformatter r   = new IndentationReformatter();
            DocumentAccessor       acc = new DocumentAccessor(textArea.Document, begin, end);

            r.Reformat(acc, set);

            if (cursorPos >= begin && cursorPos <= end)
            {
                int newIndentLength = GetIndentation(textArea, cursorPos).Length;
                if (oldIndentLength != newIndentLength)
                {
                    // fix cursor position if indentation was changed
                    int newX = textArea.Caret.Position.X - oldIndentLength + newIndentLength;
                    textArea.Caret.Position = new TextLocation(Math.Max(newX, 0), cursorPos);
                }
            }
        }
		/// <summary>
		/// This function sets the indentlevel in a range of lines.
		/// </summary>
		public override void IndentLines(TextArea textArea, int begin, int end)
		{
			if (textArea.Document.TextEditorProperties.IndentStyle != IndentStyle.Smart) {
				base.IndentLines(textArea, begin, end);
				return;
			}
			int cursorPos = textArea.Caret.Position.Y;
			int oldIndentLength = 0;
			
			if (cursorPos >= begin && cursorPos <= end)
				oldIndentLength = GetIndentation(textArea, cursorPos).Length;
			
			IndentationSettings set = new IndentationSettings();
			set.IndentString = Tab.GetIndentationString(textArea.Document);
			IndentationReformatter r = new IndentationReformatter();
			DocumentAccessor acc = new DocumentAccessor(textArea.Document, begin, end);
			r.Reformat(acc, set);
			
			if (cursorPos >= begin && cursorPos <= end) {
				int newIndentLength = GetIndentation(textArea, cursorPos).Length;
				if (oldIndentLength != newIndentLength) {
					// fix cursor position if indentation was changed
					int newX = textArea.Caret.Position.X - oldIndentLength + newIndentLength;
					textArea.Caret.Position = new TextLocation(Math.Max(newX, 0), cursorPos);
				}
			}
		}
		/// <summary>
		/// Define CSharp specific smart indenting for a line :)
		/// </summary>
		protected override int SmartIndentLine(TextArea textArea, int lineNr)
		{
			if (lineNr <= 0) {
				return AutoIndentLine(textArea, lineNr);
			}
			
			string oldText = textArea.Document.GetText(textArea.Document.GetLineSegment(lineNr));
			
			DocumentAccessor acc = new DocumentAccessor(textArea.Document, lineNr, lineNr);
			
			IndentationSettings set = new IndentationSettings();
			set.IndentString = Tab.GetIndentationString(textArea.Document);
			set.LeaveEmptyLines = false;
			IndentationReformatter r = new IndentationReformatter();
			
			r.Reformat(acc, set);
			
			string t = acc.Text;
			if (t.Length == 0) {
				// use AutoIndentation for new lines in comments / verbatim strings.
				return AutoIndentLine(textArea, lineNr);
			} else {
				int newIndentLength = t.Length - t.TrimStart().Length;
				int oldIndentLength = oldText.Length - oldText.TrimStart().Length;
				if (oldIndentLength != newIndentLength && lineNr == textArea.Caret.Position.Y) {
					// fix cursor position if indentation was changed
					int newX = textArea.Caret.Position.X - oldIndentLength + newIndentLength;
					textArea.Caret.Position = new TextLocation(Math.Max(newX, 0), lineNr);
				}
				return newIndentLength;
			}
		}
Example #4
0
 public void Indent(IndentationSettings set, string str)
 {
     OuterIndent  = InnerIndent;
     InnerIndent += str;
     Continuation = false;
     OneLineBlock = false;
     LastWord     = "";
 }
Example #5
0
		char lastRealChar = ' '; // last non-comment char
		
		public void Reformat(IDocumentAccessor doc, IndentationSettings set)
		{
			Init();
			
			while (doc.Next()) {
				Step(doc, set);
			}
		}
Example #6
0
			public void Indent(IndentationSettings set, string str)
			{
				OuterIndent = InnerIndent;
				InnerIndent += str;
				Continuation = false;
				OneLineBlock = false;
				LastWord = "";
			}
Example #7
0
        char lastRealChar = ' ';         // last non-comment char

        public void Reformat(IDocumentAccessor doc, IndentationSettings set)
        {
            Init();

            while (doc.Next())
            {
                Step(doc, set);
            }
        }
Example #8
0
        /// <summary>
        /// Define CSharp specific smart indenting for a line :)
        /// </summary>
        protected override int SmartIndentLine(TextArea textArea, int lineNr)
        {
            if (lineNr <= 0)
            {
                return(AutoIndentLine(textArea, lineNr));
            }

            string oldText = textArea.Document.GetText(textArea.Document.GetLineSegment(lineNr));

            DocumentAccessor acc = new DocumentAccessor(textArea.Document, lineNr, lineNr);

            IndentationSettings set = new IndentationSettings();

            set.IndentString    = Tab.GetIndentationString(textArea.Document);
            set.LeaveEmptyLines = false;
            IndentationReformatter r = new IndentationReformatter();

            r.Reformat(acc, set);

            if (acc.ChangedLines > 0)
            {
                textArea.Document.UndoStack.CombineLast(2);
            }

            string t = acc.Text;

            if (t.Length == 0)
            {
                // use AutoIndentation for new lines in comments / verbatim strings.
                return(AutoIndentLine(textArea, lineNr));
            }
            else
            {
                int newIndentLength = t.Length - t.TrimStart().Length;
                int oldIndentLength = oldText.Length - oldText.TrimStart().Length;
                if (oldIndentLength != newIndentLength && lineNr == textArea.Caret.Position.Y)
                {
                    // fix cursor position if indentation was changed
                    int newX = textArea.Caret.Position.X - oldIndentLength + newIndentLength;
                    textArea.Caret.Position = new Point(Math.Max(newX, 0), lineNr);
                }
                return(newIndentLength);
            }
        }
Example #9
0
        public void Step(IDocumentAccessor doc, IndentationSettings set)
        {
            string line = doc.Text;

            if (set.LeaveEmptyLines && line.Length == 0)
            {
                return;                                                      // leave empty lines empty
            }
            line = line.TrimStart();

            StringBuilder indent = new StringBuilder();

            if (line.Length == 0)
            {
                // Special treatment for empty lines:
                if (blockComment || (inString && verbatim))
                {
                    return;
                }
                indent.Append(block.InnerIndent);
                if (block.OneLineBlock)
                {
                    indent.Append(set.IndentString);
                }
                if (block.Continuation)
                {
                    indent.Append(set.IndentString);
                }
                if (doc.Text != indent.ToString())
                {
                    doc.Text = indent.ToString();
                }
                return;
            }

            if (TrimEnd(doc))
            {
                line = doc.Text.TrimStart();
            }

            Block oldBlock       = block;
            bool  startInComment = blockComment;
            bool  startInString  = (inString && verbatim);

            #region Parse char by char
            lineComment = false;
            inChar      = false;
            escape      = false;
            if (!verbatim)
            {
                inString = false;
            }

            lastRealChar = '\n';

            char lastchar = ' ';
            char c        = ' ';
            char nextchar = line[0];
            for (int i = 0; i < line.Length; i++)
            {
                if (lineComment)
                {
                    break;                              // cancel parsing current line
                }
                lastchar = c;
                c        = nextchar;
                if (i + 1 < line.Length)
                {
                    nextchar = line[i + 1];
                }
                else
                {
                    nextchar = '\n';
                }

                if (escape)
                {
                    escape = false;
                    continue;
                }

                #region Check for comment/string chars
                switch (c)
                {
                case '/':
                    if (blockComment && lastchar == '*')
                    {
                        blockComment = false;
                    }
                    if (!inString && !inChar)
                    {
                        if (!blockComment && nextchar == '/')
                        {
                            lineComment = true;
                        }
                        if (!lineComment && nextchar == '*')
                        {
                            blockComment = true;
                        }
                    }
                    break;

                case '#':
                    if (!(inChar || blockComment || inString))
                    {
                        lineComment = true;
                    }
                    break;

                case '"':
                    if (!(inChar || lineComment || blockComment))
                    {
                        inString = !inString;
                        if (!inString && verbatim)
                        {
                            if (nextchar == '"')
                            {
                                escape   = true;                                       // skip escaped quote
                                inString = true;
                            }
                            else
                            {
                                verbatim = false;
                            }
                        }
                        else if (inString && lastchar == '@')
                        {
                            verbatim = true;
                        }
                    }
                    break;

                case '\'':
                    if (!(inString || lineComment || blockComment))
                    {
                        inChar = !inChar;
                    }
                    break;

                case '\\':
                    if ((inString && !verbatim) || inChar)
                    {
                        escape = true;                                 // skip next character
                    }
                    break;
                }
                #endregion

                if (lineComment || blockComment || inString || inChar)
                {
                    if (wordBuilder.Length > 0)
                    {
                        block.LastWord = wordBuilder.ToString();
                    }
                    wordBuilder.Length = 0;
                    continue;
                }

                if (!Char.IsWhiteSpace(c) && c != '[' && c != '/')
                {
                    if (block.Bracket == '{')
                    {
                        block.Continuation = true;
                    }
                }

                if (Char.IsLetterOrDigit(c))
                {
                    wordBuilder.Append(c);
                }
                else
                {
                    if (wordBuilder.Length > 0)
                    {
                        block.LastWord = wordBuilder.ToString();
                    }
                    wordBuilder.Length = 0;
                }

                #region Push/Pop the blocks
                switch (c)
                {
                case '{':
                    block.OneLineBlock = false;
                    blocks.Push(block);
                    block.StartLine = doc.LineNumber;
                    if (block.LastWord == "switch")
                    {
                        block.Indent(set, set.IndentString + set.IndentString);

                        /* oldBlock refers to the previous line, not the previous block
                         * The block we want is not available anymore because it was never pushed.
                         * } else if (oldBlock.OneLineBlock) {
                         * // Inside a one-line-block is another statement
                         * // with a full block: indent the inner full block
                         * // by one additional level
                         * block.Indent(set, set.IndentString + set.IndentString);
                         * block.OuterIndent += set.IndentString;
                         * // Indent current line if it starts with the '{' character
                         * if (i == 0) {
                         *      oldBlock.InnerIndent += set.IndentString;
                         * }*/
                    }
                    else
                    {
                        block.Indent(set);
                    }
                    block.Bracket = '{';
                    break;

                case '}':
                    while (block.Bracket != '{')
                    {
                        if (blocks.Count == 0)
                        {
                            break;
                        }
                        block = blocks.Pop();
                    }
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    block = blocks.Pop();
                    block.Continuation = false;
                    block.OneLineBlock = false;
                    break;

                case '(':
                case '[':
                    blocks.Push(block);
                    if (block.StartLine == doc.LineNumber)
                    {
                        block.InnerIndent = block.OuterIndent;
                    }
                    else
                    {
                        block.StartLine = doc.LineNumber;
                    }
                    block.Indent(set,
                                 (oldBlock.OneLineBlock ? set.IndentString : "") +
                                 (oldBlock.Continuation ? set.IndentString : "") +
                                 (i == line.Length - 1 ? set.IndentString : new String(' ', i + 1)));
                    block.Bracket = c;
                    break;

                case ')':
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    if (block.Bracket == '(')
                    {
                        block = blocks.Pop();
                        if (IsSingleStatementKeyword(block.LastWord))
                        {
                            block.Continuation = false;
                        }
                    }
                    break;

                case ']':
                    if (blocks.Count == 0)
                    {
                        break;
                    }
                    if (block.Bracket == '[')
                    {
                        block = blocks.Pop();
                    }
                    break;

                case ';':
                case ',':
                    block.Continuation = false;
                    block.OneLineBlock = false;
                    break;

                case ':':
                    if (block.LastWord == "case" || line.StartsWith("case ") || line.StartsWith(block.LastWord + ":"))
                    {
                        block.Continuation = false;
                        block.OneLineBlock = false;
                    }
                    break;
                }

                if (!Char.IsWhiteSpace(c))
                {
                    // register this char as last char
                    lastRealChar = c;
                }
                #endregion
            }
            #endregion

            if (wordBuilder.Length > 0)
            {
                block.LastWord = wordBuilder.ToString();
            }
            wordBuilder.Length = 0;

            if (startInString)
            {
                return;
            }
            if (startInComment && line[0] != '*')
            {
                return;
            }
            if (doc.Text.StartsWith("//\t") || doc.Text == "//")
            {
                return;
            }

            if (line[0] == '}')
            {
                indent.Append(oldBlock.OuterIndent);
                oldBlock.OneLineBlock = false;
                oldBlock.Continuation = false;
            }
            else
            {
                indent.Append(oldBlock.InnerIndent);
            }

            if (indent.Length > 0 && oldBlock.Bracket == '(' && line[0] == ')')
            {
                indent.Remove(indent.Length - 1, 1);
            }
            else if (indent.Length > 0 && oldBlock.Bracket == '[' && line[0] == ']')
            {
                indent.Remove(indent.Length - 1, 1);
            }

            if (line[0] == ':')
            {
                oldBlock.Continuation = true;
            }
            else if (lastRealChar == ':' && indent.Length >= set.IndentString.Length)
            {
                if (block.LastWord == "case" || line.StartsWith("case ") || line.StartsWith(block.LastWord + ":"))
                {
                    indent.Remove(indent.Length - set.IndentString.Length, set.IndentString.Length);
                }
            }
            else if (lastRealChar == ')')
            {
                if (IsSingleStatementKeyword(block.LastWord))
                {
                    block.OneLineBlock = true;
                }
            }
            else if (lastRealChar == 'e' && block.LastWord == "else")
            {
                block.OneLineBlock = true;
                block.Continuation = false;
            }

            if (doc.ReadOnly)
            {
                // We can't change the current line, but we should accept the existing
                // indentation if possible (=if the current statement is not a multiline
                // statement).
                if (!oldBlock.Continuation && !oldBlock.OneLineBlock &&
                    oldBlock.StartLine == block.StartLine &&
                    block.StartLine < doc.LineNumber && lastRealChar != ':')
                {
                    // use indent StringBuilder to get the indentation of the current line
                    indent.Length = 0;
                    line          = doc.Text;            // get untrimmed line
                    for (int i = 0; i < line.Length; ++i)
                    {
                        if (!Char.IsWhiteSpace(line[i]))
                        {
                            break;
                        }
                        indent.Append(line[i]);
                    }
                    // /* */ multiline comments have an extra space - do not count it
                    // for the block's indentation.
                    if (startInComment && indent.Length > 0 && indent[indent.Length - 1] == ' ')
                    {
                        indent.Length -= 1;
                    }
                    block.InnerIndent = indent.ToString();
                }
                return;
            }

            if (line[0] != '{')
            {
                if (line[0] != ')' && oldBlock.Continuation && oldBlock.Bracket == '{')
                {
                    indent.Append(set.IndentString);
                }
                if (oldBlock.OneLineBlock)
                {
                    indent.Append(set.IndentString);
                }
            }

            // this is only for blockcomment lines starting with *,
            // all others keep their old indentation
            if (startInComment)
            {
                indent.Append(' ');
            }

            if (indent.Length != (doc.Text.Length - line.Length) ||
                !doc.Text.StartsWith(indent.ToString()) ||
                Char.IsWhiteSpace(doc.Text[indent.Length]))
            {
                doc.Text = indent.ToString() + line;
            }
        }
Example #10
0
 public void Indent(IndentationSettings set)
 {
     Indent(set, set.IndentString);
 }
Example #11
0
			public void Indent(IndentationSettings set)
			{
				Indent(set, set.IndentString);
			}
Example #12
0
		public void Step(IDocumentAccessor doc, IndentationSettings set)
		{
			string line = doc.Text;
			if (set.LeaveEmptyLines && line.Length == 0) return; // leave empty lines empty
			line = line.TrimStart();
			
			StringBuilder indent = new StringBuilder();
			if (line.Length == 0) {
				// Special treatment for empty lines:
				if (blockComment || (inString && verbatim))
					return;
				indent.Append(block.InnerIndent);
				indent.Append(Repeat(set.IndentString, block.OneLineBlock));
				if (block.Continuation)
					indent.Append(set.IndentString);
				if (doc.Text != indent.ToString())
					doc.Text = indent.ToString();
				return;
			}
			
			if (TrimEnd(doc))
				line = doc.Text.TrimStart();
			
			Block oldBlock = block;
			bool startInComment = blockComment;
			bool startInString = (inString && verbatim);
			
			#region Parse char by char
			lineComment = false;
			inChar = false;
			escape = false;
			if (!verbatim) inString = false;
			
			lastRealChar = '\n';
			
			char lastchar = ' ';
			char c = ' ';
			char nextchar = line[0];
			for (int i = 0; i < line.Length; i++) {
				if (lineComment) break; // cancel parsing current line
				
				lastchar = c;
				c = nextchar;
				if (i + 1 < line.Length)
					nextchar = line[i + 1];
				else
					nextchar = '\n';
				
				if (escape) {
					escape = false;
					continue;
				}
				
				#region Check for comment/string chars
				switch (c) {
					case '/':
						if (blockComment && lastchar == '*')
							blockComment = false;
						if (!inString && !inChar) {
							if (!blockComment && nextchar == '/')
								lineComment = true;
							if (!lineComment && nextchar == '*')
								blockComment = true;
						}
						break;
					case '#':
						if (!(inChar || blockComment || inString))
							lineComment = true;
						break;
					case '"':
						if (!(inChar || lineComment || blockComment)) {
							inString = !inString;
							if (!inString && verbatim) {
								if (nextchar == '"') {
									escape = true; // skip escaped quote
									inString = true;
								} else {
									verbatim = false;
								}
							} else if (inString && lastchar == '@') {
								verbatim = true;
							}
						}
						break;
					case '\'':
						if (!(inString || lineComment || blockComment)) {
							inChar = !inChar;
						}
						break;
					case '\\':
						if ((inString && !verbatim) || inChar)
							escape = true; // skip next character
						break;
				}
				#endregion
				
				if (lineComment || blockComment || inString || inChar) {
					if (wordBuilder.Length > 0)
						block.LastWord = wordBuilder.ToString();
					wordBuilder.Length = 0;
					continue;
				}
				
				if (!Char.IsWhiteSpace(c) && c != '[' && c != '/') {
					if (block.Bracket == '{')
						block.Continuation = true;
				}
				
				if (Char.IsLetterOrDigit(c)) {
					wordBuilder.Append(c);
				} else {
					if (wordBuilder.Length > 0)
						block.LastWord = wordBuilder.ToString();
					wordBuilder.Length = 0;
				}
				
				#region Push/Pop the blocks
				switch (c) {
					case '{':
						block.ResetOneLineBlock();
						blocks.Push(block);
						block.StartLine = doc.LineNumber;
						if (block.LastWord == "switch") {
							block.Indent(set, set.IndentString + set.IndentString);
							/* oldBlock refers to the previous line, not the previous block
							 * The block we want is not available anymore because it was never pushed.
							 * } else if (oldBlock.OneLineBlock) {
							// Inside a one-line-block is another statement
							// with a full block: indent the inner full block
							// by one additional level
							block.Indent(set, set.IndentString + set.IndentString);
							block.OuterIndent += set.IndentString;
							// Indent current line if it starts with the '{' character
							if (i == 0) {
								oldBlock.InnerIndent += set.IndentString;
							}*/
						} else {
							block.Indent(set);
						}
						block.Bracket = '{';
						break;
					case '}':
						while (block.Bracket != '{') {
							if (blocks.Count == 0) break;
							block = blocks.Pop();
						}
						if (blocks.Count == 0) break;
						block = blocks.Pop();
						block.Continuation = false;
						block.ResetOneLineBlock();
						break;
					case '(':
					case '[':
						blocks.Push(block);
						if (block.StartLine == doc.LineNumber)
							block.InnerIndent = block.OuterIndent;
						else
							block.StartLine = doc.LineNumber;
						block.Indent(set,
						             Repeat(set.IndentString, oldBlock.OneLineBlock) +
						             (oldBlock.Continuation ? set.IndentString : "") +
						             (i == line.Length - 1 ? set.IndentString : new String(' ', i + 1)));
						block.Bracket = c;
						break;
					case ')':
						if (blocks.Count == 0) break;
						if (block.Bracket == '(') {
							block = blocks.Pop();
							if (IsSingleStatementKeyword(block.LastWord))
								block.Continuation = false;
						}
						break;
					case ']':
						if (blocks.Count == 0) break;
						if (block.Bracket == '[')
							block = blocks.Pop();
						break;
					case ';':
					case ',':
						block.Continuation = false;
						block.ResetOneLineBlock();
						break;
					case ':':
						if (block.LastWord == "case" || line.StartsWith("case ") || line.StartsWith(block.LastWord + ":")) {
							block.Continuation = false;
							block.ResetOneLineBlock();
						}
						break;
				}
				
				if (!Char.IsWhiteSpace(c)) {
					// register this char as last char
					lastRealChar = c;
				}
				#endregion
			}
			#endregion
			
			if (wordBuilder.Length > 0)
				block.LastWord = wordBuilder.ToString();
			wordBuilder.Length = 0;
			
			if (startInString) return;
			if (startInComment && line[0] != '*') return;
			if (doc.Text.StartsWith("//\t") || doc.Text == "//")
				return;
			
			if (line[0] == '}') {
				indent.Append(oldBlock.OuterIndent);
				oldBlock.ResetOneLineBlock();
				oldBlock.Continuation = false;
			} else {
				indent.Append(oldBlock.InnerIndent);
			}
			
			if (indent.Length > 0 && oldBlock.Bracket == '(' && line[0] == ')') {
				indent.Remove(indent.Length - 1, 1);
			} else if (indent.Length > 0 && oldBlock.Bracket == '[' && line[0] == ']') {
				indent.Remove(indent.Length - 1, 1);
			}
			
			if (line[0] == ':') {
				oldBlock.Continuation = true;
			} else if (lastRealChar == ':' && indent.Length >= set.IndentString.Length) {
				if (block.LastWord == "case" || line.StartsWith("case ") || line.StartsWith(block.LastWord + ":"))
					indent.Remove(indent.Length - set.IndentString.Length, set.IndentString.Length);
			} else if (lastRealChar == ')') {
				if (IsSingleStatementKeyword(block.LastWord)) {
					block.OneLineBlock++;
				}
			} else if (lastRealChar == 'e' && block.LastWord == "else") {
				block.OneLineBlock = Math.Max(1, block.PreviousOneLineBlock);
				block.Continuation = false;
				oldBlock.OneLineBlock = block.OneLineBlock - 1;
			}
			
			if (doc.ReadOnly) {
				// We can't change the current line, but we should accept the existing
				// indentation if possible (=if the current statement is not a multiline
				// statement).
				if (!oldBlock.Continuation && oldBlock.OneLineBlock == 0 &&
				    oldBlock.StartLine == block.StartLine &&
				    block.StartLine < doc.LineNumber && lastRealChar != ':')
				{
					// use indent StringBuilder to get the indentation of the current line
					indent.Length = 0;
					line = doc.Text; // get untrimmed line
					for (int i = 0; i < line.Length; ++i) {
						if (!Char.IsWhiteSpace(line[i]))
							break;
						indent.Append(line[i]);
					}
					// /* */ multiline comments have an extra space - do not count it
					// for the block's indentation.
					if (startInComment && indent.Length > 0 && indent[indent.Length - 1] == ' ') {
						indent.Length -= 1;
					}
					block.InnerIndent = indent.ToString();
				}
				return;
			}
			
			if (line[0] != '{') {
				if (line[0] != ')' && oldBlock.Continuation && oldBlock.Bracket == '{')
					indent.Append(set.IndentString);
				indent.Append(Repeat(set.IndentString, oldBlock.OneLineBlock));
			}
			
			// this is only for blockcomment lines starting with *,
			// all others keep their old indentation
			if (startInComment)
				indent.Append(' ');
			
			if (indent.Length != (doc.Text.Length - line.Length) ||
			    !doc.Text.StartsWith(indent.ToString()) ||
			    Char.IsWhiteSpace(doc.Text[indent.Length]))
			{
				doc.Text = indent.ToString() + line;
			}
		}