Example #1
0
        public AbsoluteCodeLine(string code, IIndenterSettings settings, AbsoluteCodeLine previous)
        {
            _settings = settings;
            Previous  = previous;

            if (code.EndsWith(StupidLineEnding))
            {
                _code             = code.Substring(0, code.Length - StupidLineEnding.Length);
                _stupidLineEnding = true;
            }
            else
            {
                _code = code;
            }

            Original = code;

            _escaper = new StringLiteralAndBracketEscaper(_code);
            _code    = _escaper.EscapedString;

            ExtractLineNumber();
            ExtractEndOfLineComment();

            _segments = _code.Split(new[] { ": " }, StringSplitOptions.None);
        }
Example #2
0
        //The splitNamed parameter is a straight up hack for fixing https://github.com/rubberduck-vba/Rubberduck/issues/2402
        private int FunctionAlign(string line, bool splitNamed)
        {
            line = new StringLiteralAndBracketEscaper(line).EscapedString;
            var stackPos = _alignment.Count;

            for (var index = StartIgnoreRegex.Match(line).Length + 1; index <= line.Length; index++)
            {
                var character = line.Substring(index - 1, 1);
                switch (character)
                {
                case "\a":
                case "\x2":
                    break;

                case "(":
                    //Start of another function => remember this position
                    _alignment.Push(new AlignmentToken(AlignmentTokenType.Function, index, ++_nestingDepth));
                    _alignment.Push(new AlignmentToken(AlignmentTokenType.Parameter, index + 1, _nestingDepth));
                    break;

                case ")":
                    //Function finished => Remove back to the previous open bracket
                    while (_alignment.Any())
                    {
                        var finished = _alignment.Count == stackPos + 1;
                        var token    = _alignment.Pop();
                        if (token.Type == AlignmentTokenType.Function && token.NestingDepth == _nestingDepth - 1)
                        {
                            _alignment.Push(token);
                            finished = true;
                        }
                        if (finished)
                        {
                            _nestingDepth--;
                            break;
                        }
                    }
                    break;

                case " ":
                    if (index + 3 < line.Length && line.Substring(index - 1, 3).Equals(" = "))
                    {
                        //Space before an = sign => remember it to align to later
                        if (!_alignment.Any(a => a.Type == AlignmentTokenType.Equals || a.Type == AlignmentTokenType.Variable))
                        {
                            _alignment.Push(new AlignmentToken(AlignmentTokenType.Equals, index + 2, _nestingDepth));
                        }
                    }
                    else if (!_alignment.Any() && index < line.Length - 2)
                    {
                        //Space after a name before the end of the line => remember it for later
                        _alignment.Push(new AlignmentToken(AlignmentTokenType.Variable, index, _nestingDepth));
                    }
                    else if (index > 5 && line.Substring(index - 6, 6).Equals(" Then "))
                    {
                        //Clear the collection if we find a Then in an If...Then and set the
                        //indenting to align with the bit after the "If "
                        while (_alignment.Count > 1)
                        {
                            _alignment.Pop();
                        }
                    }
                    break;

                case ",":
                    //Start of a new parameter => remember it to align to
                    _alignment.Push(new AlignmentToken(AlignmentTokenType.Parameter, index + 1, _nestingDepth));
                    break;

                case ":":
                    if (line.Substring(index - 1, 2).Equals(":="))
                    {
                        //A named paremeter => remember to align to after the name
                        _alignment.Push(new AlignmentToken(AlignmentTokenType.Parameter, index + 3, _nestingDepth));
                    }
                    else if (line.Substring(index, 2).Equals(": "))
                    {
                        //A new line section, so clear the brackets
                        _alignment.Clear();
                        index++;
                    }
                    break;
                }
            }
            //If we end with a comma or a named parameter, get rid of all other comma alignments
            if (line.EndsWith(", _") || line.EndsWith(":= _") || splitNamed)
            {
                while (_alignment.Any() && _alignment.Peek().Type == AlignmentTokenType.Parameter)
                {
                    _alignment.Pop();
                }
            }
            else if (line.EndsWith("( _"))   //If we end with a "( _", remove it and the space alignment after it'
            {
                _alignment.Pop();
                _alignment.Pop();
            }

            var output   = 0;
            var fallback = 0;

            //Get the position of the unmatched bracket and align to that
            foreach (var align in _alignment.Reverse())
            {
                switch (align.Type)
                {
                case AlignmentTokenType.Parameter:
                    output = align.Position - 1;
                    break;

                case AlignmentTokenType.Function:
                case AlignmentTokenType.Equals:
                    output = align.Position;
                    break;

                default:
                    fallback = align.Position - 1;
                    break;
                }
            }

            if (fallback == 0 || fallback >= line.Length - 1)
            {
                fallback = !_alignment.Any() ? (_settings.IndentSpaces * 2) : 0;
            }
            else
            {
                fallback = fallback + 1;
            }

            return(output > 0 ? output : fallback);
        }