Exemple #1
0
        private string CountAndReplaceIndentSpaces(string line, out int count)
        {
            StringBuilder sb = new StringBuilder();

            count = 0;

            for (int i = 0; i < line.Length; i++)
            {
                char c = line[i];
                if (c == ' ')
                {
                    sb.Append(' ');
                    count++;
                }
                else if (c == '\t')
                {
                    int newCount = CharHelper.AddTab(count);
                    sb.Append(' ', newCount - count);
                    count = newCount;
                }
                else
                {
                    sb.Append(line, i, line.Length - i);
                    break;
                }
            }

            return(sb.ToString());
        }
Exemple #2
0
        /// <summary>
        /// Parses the indentation from the current position in the line, updating <see cref="StartBeforeIndent"/>,
        /// <see cref="ColumnBeforeIndent"/>, <see cref="Start"/> and <see cref="Column"/> accordingly
        /// taking into account space taken by tabs.
        /// </summary>
        public void ParseIndent()
        {
            var c = CurrentChar;
            var previousStartBeforeIndent  = StartBeforeIndent;
            var startBeforeIndent          = Start;
            var previousColumnBeforeIndent = ColumnBeforeIndent;
            var columnBeforeIndent         = Column;

            while (c != '\0')
            {
                if (c == '\t')
                {
                    Column = CharHelper.AddTab(Column);
                }
                else if (c == ' ')
                {
                    Column++;
                }
                else
                {
                    break;
                }
                c = Line.NextChar();
            }
            if (columnBeforeIndent == Column)
            {
                StartBeforeIndent  = previousStartBeforeIndent;
                ColumnBeforeIndent = previousColumnBeforeIndent;
            }
            else
            {
                StartBeforeIndent  = startBeforeIndent;
                ColumnBeforeIndent = columnBeforeIndent;
            }
        }
Exemple #3
0
        /// <summary>
        /// Appends the specified line to this instance.
        /// </summary>
        /// <param name="slice">The slice.</param>
        /// <param name="column">The column.</param>
        /// <param name="line">The line.</param>
        /// <param name="sourceLinePosition"></param>
        public void AppendLine(ref StringSlice slice, int column, int line, int sourceLinePosition)
        {
            if (Lines.Lines == null)
            {
                Lines = new StringLineGroup(4);
            }

            var stringLine = new StringLine(ref slice, line, column, sourceLinePosition);

            // Regular case, we are not in the middle of a tab
            if (slice.CurrentChar != '\t' || !CharHelper.IsAcrossTab(column))
            {
                Lines.Add(ref stringLine);
            }
            else
            {
                // We need to expand tabs to spaces
                var builder = StringBuilderCache.Local();
                for (int i = column; i < CharHelper.AddTab(column); i++)
                {
                    builder.Append(' ');
                }
                builder.Append(slice.Text, slice.Start + 1, slice.Length - 1);
                stringLine.Slice = new StringSlice(builder.ToString());
                Lines.Add(ref stringLine);
            }
        }
Exemple #4
0
        /// <summary>
        /// Unwind any previous indent from the current character back to the first space.
        /// </summary>
        public void UnwindAllIndents()
        {
            // Find the previous first space on the current line
            var previousStart = Line.Start;

            for (; Line.Start > originalLineStart; Line.Start--)
            {
                var c = Line.PeekCharAbsolute(Line.Start - 1);
                if (c == 0)
                {
                    break;
                }
                if (!c.IsSpaceOrTab())
                {
                    break;
                }
            }
            var targetStart = Line.Start;

            // Nothing changed? Early exit
            if (previousStart == targetStart)
            {
                return;
            }

            // TODO: factorize the following code with what is done with GoToColumn

            // If we have found the first space, we need to recalculate the correct column
            Line.Start         = originalLineStart;
            Column             = 0;
            ColumnBeforeIndent = 0;
            StartBeforeIndent  = originalLineStart;

            for (; Line.Start < targetStart; Line.Start++)
            {
                var c = Line.Text[Line.Start];
                if (c == '\t')
                {
                    Column = CharHelper.AddTab(Column);
                }
                else
                {
                    if (!c.IsSpaceOrTab())
                    {
                        ColumnBeforeIndent = Column + 1;
                        StartBeforeIndent  = Line.Start + 1;
                    }

                    Column++;
                }
            }

            // Reset the indent
            ColumnBeforeIndent = Column;
            StartBeforeIndent  = Start;
        }
Exemple #5
0
        /// <summary>
        /// Returns the next character in the line being processed. Update <see cref="Start"/> and <see cref="Column"/>.
        /// </summary>
        /// <returns>The next character or `\0` if end of line is reached</returns>
        public char NextChar()
        {
            var c = Line.CurrentChar;

            if (c == '\t')
            {
                Column = CharHelper.AddTab(Column);
            }
            else
            {
                Column++;
            }
            return(Line.NextChar());
        }
Exemple #6
0
        /// <summary>
        /// Moves to the position to the specified column position, taking into account spaces in tabs.
        /// </summary>
        /// <param name="newColumn">The new column position to move the cursor to.</param>
        public void GoToColumn(int newColumn)
        {
            // Optimized path when we are moving above the previous start of indent
            if (newColumn >= ColumnBeforeIndent)
            {
                Line.Start = StartBeforeIndent;
                Column     = ColumnBeforeIndent;
            }
            else
            {
                Line.Start         = originalLineStart;
                Column             = 0;
                ColumnBeforeIndent = 0;
                StartBeforeIndent  = originalLineStart;
            }
            for (; Line.Start <= Line.End && Column < newColumn; Line.Start++)
            {
                var c = Line.Text[Line.Start];
                if (c == '\t')
                {
                    Column = CharHelper.AddTab(Column);
                }
                else
                {
                    if (!c.IsSpaceOrTab())
                    {
                        ColumnBeforeIndent = Column + 1;
                        StartBeforeIndent  = Line.Start + 1;
                    }

                    Column++;
                }
            }
            if (Column > newColumn)
            {
                Column = newColumn;
                if (Line.Start > 0)
                {
                    Line.Start--;
                }
            }
        }