private static int?GetIndentFromArguments(IFunction fc, IEditorLine prevLine, IREditorSettings settings) { // Fetch first argument on the previous line or first artument of the function // x < function(a, // | // x < function(a, // b, c // | var snapshot = prevLine.Snapshot; var offset = 0; // If previous line contains start of the function call, format it // so whitespace is correct and we can determine proper indentation // based on the argument or the opening brace if (prevLine.Contains(fc.Start)) { var start = snapshot.GetLineFromPosition(fc.Start).Start; var end = snapshot.GetLineFromPosition(fc.End).End; var fcText = snapshot.GetText(TextRange.FromBounds(start, end)); // Remember current indentation since formatter will remove it var currentIndent = IndentBuilder.TextIndentInSpaces(fcText, settings.TabSize); var formattedLineText = new RFormatter().Format(fcText); // Restore leading indent formattedLineText = IndentBuilder.GetIndentString(currentIndent, settings.IndentType, settings.TabSize) + formattedLineText; var ast = RParser.Parse(formattedLineText); var newFc = ast.FindFirstElement(n => n is IFunction) as IFunction; if (newFc != null) { offset = prevLine.Start; } fc = newFc; } if (fc != null) { var arg = fc.Arguments.FirstOrDefault(a => !(a is StubArgument) && prevLine.Contains(a.Start + offset)); if (arg != null) { var argPosition = arg.Start + offset; return(argPosition - snapshot.GetLineFromPosition(argPosition).Start); } var bracePosition = fc.OpenBrace.Start + offset; return(bracePosition - snapshot.GetLineFromPosition(bracePosition).Start + 1); } return(null); }
private static int IndentByIncompleteStatement(AstRoot ast, IEditorLine currentLine, IEditorLine prevLine, IAstNode scope, IREditorSettings settings) { // See if [ENTER] was hit in a middle of a statement. If it was hit in the first line of the statement, // indent one level deeper. Otherwise use block indent based on the previous line indent. // x <-[ENTER] // | // 1 // // x <-[ENTER] // | // // x <- // a +[ENTER] // | var snapshot = prevLine.Snapshot; var statement = ast.GetNodeOfTypeFromPosition <IStatement>(prevLine.End); if (statement != null) { return(prevLine.Contains(statement.Start) ? InnerIndentSizeFromNode(snapshot.EditorBuffer, scope, settings.FormatOptions) : GetBlockIndent(currentLine, settings)); } // The statement may be incomplete and hence expression parser // failed and hence there is no statement node in the AST. if (LineHasContinuation(prevLine)) { // We need to determine if last line was the first in the statement // or is it itself a continuation. if (prevLine.LineNumber > 0) { var prevPrevLine = snapshot.GetLineFromLineNumber(prevLine.LineNumber - 1); if (LineHasContinuation(prevPrevLine)) { return(GetBlockIndent(currentLine, settings)); } } return(InnerIndentSizeFromNode(snapshot.EditorBuffer, scope, settings.FormatOptions)); } return(0); }