MCPcopy Create free account
hub / github.com/microsoft/typescript-go / GetIndentation

Function GetIndentation

internal/format/indent.go:24–109  ·  view source on GitHub ↗

GetIndentation computes the expected indentation for a position in a source file. This is the Go port of SmartIndenter.getIndentation from TypeScript.

(position int, sourceFile *ast.SourceFile, options lsutil.FormatCodeSettings, assumeNewLineBeforeCloseBrace bool)

Source from the content-addressed store, hash-verified

22// GetIndentation computes the expected indentation for a position in a source file.
23// This is the Go port of SmartIndenter.getIndentation from TypeScript.
24func GetIndentation(position int, sourceFile *ast.SourceFile, options lsutil.FormatCodeSettings, assumeNewLineBeforeCloseBrace bool) int {
25 if position > len(sourceFile.Text()) {
26 return options.BaseIndentSize // past EOF
27 }
28
29 // no indentation when the indent style is set to none,
30 // so we can return fast
31 if options.IndentStyle == lsutil.IndentStyleNone {
32 return 0
33 }
34
35 precedingToken := astnav.FindPrecedingTokenEx(sourceFile, position, nil /*startNode*/, true /*excludeJSDoc*/)
36
37 enclosingCommentRange := getRangeOfEnclosingComment(sourceFile, position, precedingToken)
38 if enclosingCommentRange != nil && enclosingCommentRange.Kind == ast.KindMultiLineCommentTrivia {
39 return getCommentIndent(sourceFile, position, options, enclosingCommentRange)
40 }
41
42 if precedingToken == nil {
43 return options.BaseIndentSize
44 }
45
46 // no indentation in string/regex/template literals
47 if isStringOrRegularExpressionOrTemplateLiteral(precedingToken.Kind) {
48 tokenStart := scanner.GetTokenPosOfNode(precedingToken, sourceFile, false)
49 if tokenStart <= position && position < precedingToken.End() {
50 return 0
51 }
52 }
53
54 lineAtPosition := scanner.GetECMALineOfPosition(sourceFile, position)
55
56 // indentation is first non-whitespace character in a previous line
57 // for block indentation, we should look for a line which contains something that's not
58 // whitespace.
59 currentToken := astnav.GetTokenAtPosition(sourceFile, position)
60 // For object literals, we want indentation to work just like with blocks.
61 // If the `{` starts in any position (even in the middle of a line), then
62 // the following indentation should treat `{` as the start of that line (including leading whitespace).
63 // ```
64 // const a: { x: undefined, y: undefined } = {} // leading 4 whitespaces and { starts in the middle of line
65 // ->
66 // const a: { x: undefined, y: undefined } = {
67 // x: undefined,
68 // y: undefined,
69 // }
70 // ---------------------
71 // const a: {x : undefined, y: undefined } =
72 // {}
73 // ->
74 // const a: { x: undefined, y: undefined } =
75 // { // leading 5 whitespaces and { starts at 6 column
76 // x: undefined,
77 // y: undefined,
78 // }
79 // ```
80 isObjectLiteral := currentToken.Kind == ast.KindOpenBraceToken && currentToken.Parent != nil && currentToken.Parent.Kind == ast.KindObjectLiteralExpression
81 if options.IndentStyle == lsutil.IndentStyleBlock || isObjectLiteral {

Calls 15

FindPrecedingTokenExFunction · 0.92
GetTokenPosOfNodeFunction · 0.92
GetECMALineOfPositionFunction · 0.92
GetTokenAtPositionFunction · 0.92
lenFunction · 0.85
getCommentIndentFunction · 0.85
getBlockIndentFunction · 0.85
getListByPositionFunction · 0.85
getSmartIndentFunction · 0.85