Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TypeScript.sublime-commands
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
{ "caption" : "TypeScript: Format Selection", "command": "typescript_format_selection" },
{ "caption" : "TypeScript: Format Document", "command": "typescript_format_document" },
{ "caption" : "TypeScript: Find References", "command": "typescript_find_references" },
{ "caption" : "TypeScript: Request Code Fixes", "command": "typescript_request_code_fixes" },
{ "caption" : "TypeScript: Navigate To Symbol", "command": "typescript_nav_to" },
{ "caption" : "TypeScript: Rename", "command": "typescript_rename" },
{ "caption" : "TypeScript: Paste And Format", "command": "typescript_paste_and_format" },
Expand Down
6 changes: 6 additions & 0 deletions typescript/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
from .save import TypescriptSave
from .show_doc import TypescriptShowDoc
from .signature import TypescriptSignaturePanel, TypescriptSignaturePopup
from .get_code_fixes import (
TypescriptRequestCodeFixesCommand,
ReplaceTextCommand
)
from .format import (
TypescriptFormatBrackets,
TypescriptFormatDocument,
Expand Down Expand Up @@ -40,6 +44,8 @@
"TypescriptProjectErrorList",
"TypescriptGoToError",
"TypescriptFormatBrackets",
"TypescriptRequestCodeFixesCommand",
"ReplaceTextCommand",
"TypescriptFormatDocument",
"TypescriptFormatLine",
"TypescriptFormatOnKey",
Expand Down
103 changes: 103 additions & 0 deletions typescript/commands/get_code_fixes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import sublime_plugin
from ..libs.view_helpers import *
from ..libs import log
from .base_command import TypeScriptBaseTextCommand


class ReplaceTextCommand(TypeScriptBaseTextCommand):
"""The replace_text command implementation."""

def run(self, edit, start, end, text):
"""Replace the content of a region with new text.
Arguments:
edit (Edit):
The edit object to identify this operation.
start (int):
The beginning of the Region to replace.
end (int):
The end of the Region to replace.
text (string):
The new text to replace the content of the Region with.
"""
visible_region = self.view.visible_region()
region = sublime.Region(start, end)
text = text.replace('\r\n', '\n').replace('\r', '\n')
self.view.replace(edit, region, text)


class TypescriptRequestCodeFixesCommand(TypeScriptBaseTextCommand):
"""
Code Fixes command
Get all errors in the current view
Use errorCodes along with cursor offsets to get codeFixes
"""
all_code_fixes = []
all_errors = []

def get_errors_at_cursor(self, path, cursor):
line = cursor[0] + 1
column = cursor[1] + 1
errors_at_cursor = list(filter(lambda error:
error['start']['line'] == line and
error['end']['line'] == line and
error['start']['offset'] <= column and
error['end']['offset'] >= column, self.all_errors))
return errors_at_cursor

def handle_selection(self, idx):
if idx == -1:
return
all_changes = self.all_code_fixes['body'][idx]['changes'][0]['textChanges']
for change in all_changes:
text = change['newText']
if text[:1] == '\n':
start = self.view.text_point(
change['start']['line'] - 1, change['start']['offset'])
end = self.view.text_point(
change['end']['line'] - 1, change['end']['offset'])
else:
start = self.view.text_point(
change['start']['line'] - 1, change['start']['offset'] - 1)
end = self.view.text_point(
change['end']['line'] - 1, change['end']['offset'] - 1)
self.view.run_command(
'replace_text', {'start': start, 'end': end, 'text': text})

def run(self, text):
log.debug("running TypescriptRequestCodeFixesCommand")
if not is_typescript(self.view):
print("To run this command, please first assign a file name to the view")
return
check_update_view(self.view)
path = self.view.file_name()

semantic_errors = cli.service.get_semantic_errors(path)
syntactic_errors = cli.service.get_syntactic_errors(path)

if semantic_errors['success']:
self.all_errors = self.all_errors + semantic_errors['body']

if syntactic_errors['success']:
self.all_errors = self.all_errors + syntactic_errors['body']

pos = self.view.sel()[0].begin()
cursor = self.view.rowcol(pos)
errors = self.get_errors_at_cursor(path, cursor)

if len(errors):
error_codes = list(map(lambda error: error['code'], errors))
start_line = errors[0]['start']['line']
end_line = errors[0]['end']['line']
start_offset = errors[0]['start']['offset']
end_offset = errors[0]['end']['offset']
self.all_code_fixes = cli.service.get_code_fixes(
path, start_line, start_offset, end_line, end_offset, error_codes)
if self.all_code_fixes['success']:
if len(self.all_code_fixes['body']):
possibleFixesDescriptions = list(
map(lambda fix: fix['description'], self.all_code_fixes['body']))
if len(possibleFixesDescriptions) == 1:
self.handle_selection(0)
else:
self.view.window().show_quick_panel(
possibleFixesDescriptions, self.handle_selection, False, -1)
32 changes: 32 additions & 0 deletions typescript/libs/service_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,35 @@ def create_req_dict(self, command_name, args=None):
if args:
req_dict["arguments"] = args
return req_dict

def get_semantic_errors(self, path):
args = {
"file": path
}
req_dict = self.create_req_dict("semanticDiagnosticsSync", args)
json_str = json_helpers.encode(req_dict)
response_dict = self.__comm.sendCmdSync(json_str, req_dict["seq"])
return response_dict

def get_syntactic_errors(self, path):
args = {
"file": path
}
req_dict = self.create_req_dict("syntacticDiagnosticsSync", args)
json_str = json_helpers.encode(req_dict)
response_dict = self.__comm.sendCmdSync(json_str, req_dict["seq"])
return response_dict

def get_code_fixes(self, path, startLine, startOffset, endLine, endOffset, errorCodes):
args = {
"file": path,
"startLine": startLine,
"startOffset": startOffset,
"endLine": endLine,
"endOffset": endOffset,
"errorCodes": errorCodes
}
req_dict = self.create_req_dict("getCodeFixes", args)
json_str = json_helpers.encode(req_dict)
response_dict = self.__comm.sendCmdSync(json_str, req_dict["seq"])
return response_dict