Support brace matching

This commit is contained in:
Mohamed Hegazy
2015-02-12 13:35:11 -08:00
parent 3e86e557d5
commit c0b1254072
4 changed files with 125 additions and 5 deletions

View File

@@ -488,7 +488,24 @@ module ts.server {
}
getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] {
throw new Error("Not Implemented Yet.");
var lineCol = this.positionToOneBasedLineCol(fileName, position);
var args: ServerProtocol.CodeLocationRequestArgs = {
file: fileName,
line: lineCol.line,
col: lineCol.col,
};
var request = this.processRequest<ServerProtocol.BraceRequest>(CommandNames.Brace, args);
var response = this.processResponse<ServerProtocol.BraceResponse>(request);
return response.body.map(entry => {
var start = this.lineColToPosition(fileName, entry.start);
var end = this.lineColToPosition(fileName, entry.end);
return {
start: start,
length: end - start,
};
});
}
getIndentationAtPosition(fileName: string, position: number, options: EditorOptions): number {

View File

@@ -333,7 +333,7 @@ module ts.server {
return true;
}
module CommandNames {
export module CommandNames {
export var Abbrev = "abbrev";
export var Change = "change";
export var Close = "close";
@@ -350,6 +350,7 @@ module ts.server {
export var Rename = "rename";
export var Saveto = "saveto";
export var Type = "type";
export var Brace = "brace";
export var Unknown = "unknown";
}
@@ -1056,6 +1057,38 @@ module ts.server {
}
}
getMatchingBrace(line: number, col: number, rawfile: string, reqSeq = 0) {
var file = ts.normalizePath(rawfile);
var project = this.projectService.getProjectForFile(file);
if (project) {
var compilerService = project.compilerService;
var pos = compilerService.host.lineColToPosition(file, line, col);
var spans: ts.TextSpan[];
try {
spans = compilerService.languageService.getBraceMatchingAtPosition(file, pos);
}
catch (err) {
this.logError(err, CommandNames.Brace);
spans = undefined;
}
if (spans) {
var bakedSpans: ServerProtocol.TextSpan[] = spans.map(span => ({
start: span &&
compilerService.host.positionToLineCol(file, span.start),
end: span &&
compilerService.host.positionToLineCol(file, span.start + span.length)
}));
this.output(bakedSpans, CommandNames.Brace, reqSeq);
}
else {
this.output(undefined, CommandNames.Brace, reqSeq, "no matching braces");
}
}
else {
this.output(undefined, CommandNames.Brace, reqSeq, "no matching braces");
}
}
executeJSONcmd(cmd: string) {
try {
var req = <ServerProtocol.Request>JSON.parse(cmd);
@@ -1143,6 +1176,11 @@ module ts.server {
this.sendAbbrev();
break;
}
case CommandNames.Brace: {
var defArgs = <ServerProtocol.CodeLocationRequestArgs>req.arguments;
this.getMatchingBrace(defArgs.line, defArgs.col, defArgs.file, req.seq);
break;
}
default: {
this.projectService.log("Unrecognized JSON command: " + cmd);
break;

View File

@@ -89,15 +89,22 @@ declare module ServerProtocol {
Object found in response messages defining a span of text in
source code.
*/
export interface CodeSpan {
/** File containing the definition */
file: string;
export interface TextSpan {
/** First character of the definition */
start: LineCol;
/** One character past last character of the definition */
end: LineCol;
}
/**
Object found in response messages defining a span of text in
a specific source file.
*/
export interface CodeSpan extends TextSpan {
/** File containing the definition */
file: string;
}
/**
Definition response message. Gives text range for definition.
*/
@@ -582,6 +589,21 @@ declare module ServerProtocol {
[fullString: string]: string;
}
}
/** Response to "brace" request. */
export interface BraceResponse extends Response {
body?: TextSpan[];
}
/**
Brace matching request; value of command field is "brace".
Return response giving the code locations of matching braces
found in file at location line, col.
*/
export interface BraceRequest extends CodeLocationRequest {
}
}

View File

@@ -0,0 +1,43 @@
/// <reference path="fourslash.ts"/>
//////curly braces
////module Foo [|{
//// class Bar [|{
//// private f() [|{
//// }|]
////
//// private f2() [|{
//// if (true) [|{ }|] [|{ }|];
//// }|]
//// }|]
////}|]
////
//////parenthesis
////class FooBar {
//// private f[|()|] {
//// return [|([|(1 + 1)|])|];
//// }
////
//// private f2[|()|] {
//// if [|(true)|] { }
//// }
////}
////
//////square brackets
////class Baz {
//// private f() {
//// var a: any[|[]|] = [|[[|[1, 2]|], [|[3, 4]|], 5]|];
//// }
////}
////
////// angular brackets
////class TemplateTest [|<T1, T2 extends Array>|] {
//// public foo(a, b) {
//// return [|<any>|] a;
//// }
////}
test.ranges().forEach((range) => {
verify.matchingBracePositionInCurrentFile(range.start, range.end - 1);
verify.matchingBracePositionInCurrentFile(range.end - 1, range.start);
});