-
Notifications
You must be signed in to change notification settings - Fork 12.8k
multi-line comment formatting fix and handler #16385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
35b16ab
6b4cd0b
a819e4e
8f28a02
b02963b
8fc3fd9
cc88091
efdbeba
777bc57
091376f
2f5b1d3
7c402d5
de92e98
b2188ad
472ad9d
f3e0cbb
a209db7
a08d18a
ad9c29b
153b94a
70e4f34
4b9f5a0
62f16be
23ca368
b7bc7d8
19e2fa6
6029b5c
760ef44
e7d2af0
e4e969a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ namespace ts.server.protocol { | |
/* @internal */ | ||
BraceFull = "brace-full", | ||
BraceCompletion = "braceCompletion", | ||
GetSpanOfEnclosingComment = "getSpanOfEnclosingComment", | ||
Change = "change", | ||
Close = "close", | ||
Completions = "completions", | ||
|
@@ -241,6 +242,21 @@ namespace ts.server.protocol { | |
body?: TodoComment[]; | ||
} | ||
|
||
/** | ||
* A request to determine if the caret is inside a comment. | ||
*/ | ||
export interface SpanOfEnclosingCommentRequest extends FileLocationRequest { | ||
command: CommandTypes.GetSpanOfEnclosingComment; | ||
arguments: SpanOfEnclosingCommentRequestArgs; | ||
} | ||
|
||
export interface SpanOfEnclosingCommentRequestArgs extends FileLocationRequestArgs { | ||
/** | ||
* Requires that the enclosing span be a multi-line comment, or else the request returns undefined. | ||
*/ | ||
onlyMultiLine: boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this just here for the generality of the API? We don't appear to actually use it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We only ever pass in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have mixed feeling about this but don't object as long as we have test coverage (which we do). |
||
} | ||
|
||
/** | ||
* Request to obtain outlining spans in file. | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,12 +107,14 @@ namespace ts { | |
scanner.setTextPos(pos); | ||
while (pos < end) { | ||
const token = scanner.scan(); | ||
Debug.assert(token !== SyntaxKind.EndOfFileToken); // Else it would infinitely loop | ||
const textPos = scanner.getTextPos(); | ||
if (textPos <= end) { | ||
nodes.push(createNode(token, pos, textPos, this)); | ||
} | ||
pos = textPos; | ||
if (token === SyntaxKind.EndOfFileToken) { | ||
break; | ||
} | ||
} | ||
return pos; | ||
} | ||
|
@@ -1757,17 +1759,20 @@ namespace ts { | |
function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] { | ||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); | ||
const settings = toEditorSettings(options); | ||
if (key === "{") { | ||
return formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === "}") { | ||
return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === ";") { | ||
return formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === "\n") { | ||
return formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings); | ||
|
||
if (!isInComment(sourceFile, position)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be worthwhile to test this change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding a test to fourslash and will add an integration test on the managed side to make sure the experience works end-to-end. |
||
if (key === "{") { | ||
return formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === "}") { | ||
return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === ";") { | ||
return formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
else if (key === "\n") { | ||
return formatting.formatOnEnter(position, sourceFile, getRuleProvider(settings), settings); | ||
} | ||
} | ||
|
||
return []; | ||
|
@@ -1826,6 +1831,12 @@ namespace ts { | |
return true; | ||
} | ||
|
||
function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean) { | ||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); | ||
const range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine); | ||
return range && createTextSpanFromRange(range); | ||
} | ||
|
||
function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { | ||
// Note: while getting todo comments seems like a syntactic operation, we actually | ||
// treat it as a semantic operation here. This is because we expect our host to call | ||
|
@@ -2050,6 +2061,7 @@ namespace ts { | |
getFormattingEditsAfterKeystroke, | ||
getDocCommentTemplateAtPosition, | ||
isValidBraceCompletionAtPosition, | ||
getSpanOfEnclosingComment, | ||
getCodeFixesAtPosition, | ||
getEmitOutput, | ||
getNonBoundSourceFile, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's special about jsx? Does it apply to tsx as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JsxText
nodes are children ofJsxElement
s that are notJsxElements
themselves or curly-brace-delimited assignment expressions. In the following example, the underlined isJsxText
:We essentially treat them like string literals, though differences in the way they are delimited mean that
getLeadingCommentRanges
cannot handle them correctly without some information from the parser, whichgetLeadingCommentRanges
has been designed to avoid.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And that covers tsx as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.