{
5 |
6 | private header: JQuery;
7 | private documentation: JQuery;
8 | static content() {
9 | return this.div({ class: 'atom-ts-documentation padded top' },
10 | () => this.div( // TODO: repeat for each documentation entry
11 | () => {
12 | this.h2({ outlet: 'header' });
13 | this.p({ outlet: 'documentation' });
14 | })
15 | );
16 | }
17 |
18 |
19 | private shown = false;
20 | show() { this.$.addClass('active'); this.shown = true; }
21 | hide() { this.$.removeClass('active'); this.shown = false; }
22 | toggle() { if (this.shown) { this.hide(); } else { this.show(); } }
23 |
24 | setContent(content: { display: string; documentation: string; filePath: string }) {
25 | this.header.html(content.display);
26 | content.documentation = content.documentation.replace(/(?:\r\n|\r|\n)/g, '
');
27 | this.documentation.html(content.documentation);
28 | }
29 |
30 | autoPosition() {
31 | var editor = atom.workspace.getActiveTextEditor();
32 | var cursor = editor.getCursors()[0];
33 | var cursorTop = cursor.getPixelRect().top - editor.getScrollTop();
34 | var editorHeight = editor.getHeight();
35 |
36 | if (editorHeight - cursorTop < 100) {
37 | this.$.removeClass('bottom');
38 | this.$.addClass('top');
39 | }
40 | else {
41 | this.$.removeClass('top');
42 | this.$.addClass('bottom')
43 | }
44 | }
45 | }
46 |
47 | export var docView: DocumentationView;
48 |
49 | export function attach() {
50 | if (docView) return;
51 | docView = new DocumentationView({});
52 | $(atom.views.getView(atom.workspace)).append(docView.$);
53 | // testDocumentationView();
54 | }
55 |
56 | export function testDocumentationView() {
57 | docView.setContent({
58 | display: "this is awesome", documentation: `
59 | some docs
60 | over
61 | many
62 | many li
63 |
64 | lines
65 | long
66 | so
67 | long
68 | that
69 | it
70 | should
71 |
72 | start
73 | to
74 | scroll
75 | `, filePath: "some filepath"
76 | });
77 | docView.show();
78 | }
79 |
--------------------------------------------------------------------------------
/lib/main/atom/editorSetup.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Setup all the stuff we need from an editor instance and clear on editor close
3 | */
4 | import {debounce} from "../lang/utils";
5 | import * as parent from "../../worker/parent";
6 | import * as atomUtils from "./atomUtils";
7 | import {isTransformerFile} from "../lang/transformers/transformer";
8 |
9 | export function setupEditor(editor: AtomCore.IEditor) {
10 |
11 | // Quick fix decoration stuff
12 | var quickFixDecoration: AtomCore.Decoration = null;
13 | var quickFixMarker: any = null;
14 | function clearExistingQuickfixDecoration() {
15 | if (quickFixDecoration) {
16 | quickFixDecoration.destroy();
17 | quickFixDecoration = null;
18 | }
19 | if (quickFixMarker) {
20 | quickFixMarker.destroy();
21 | quickFixMarker = null;
22 | }
23 | }
24 | var queryForQuickFix = debounce((filePathPosition:{filePath:string;position:number}) => {
25 | parent.getQuickFixes(filePathPosition).then(res=> {
26 | clearExistingQuickfixDecoration();
27 | if (res.fixes.length) {
28 | quickFixMarker = editor.markBufferRange(editor.getSelectedBufferRange());
29 | quickFixDecoration = editor.decorateMarker(quickFixMarker,
30 | { type: "line-number", class: "quickfix" });
31 | }
32 | })
33 | }, 500);
34 | var cursorObserver = editor.onDidChangeCursorPosition(() => {
35 | try {
36 | // This line seems to throw an exception sometimes.
37 | // https://github.com/TypeStrong/atom-typescript/issues/325
38 | // https://github.com/TypeStrong/atom-typescript/issues/310
39 | let pathPos = atomUtils.getFilePathPosition();
40 |
41 | // TODO: implement quickfix logic for transformed files
42 | if (isTransformerFile(pathPos.filePath)) {
43 | clearExistingQuickfixDecoration();
44 | return;
45 | }
46 |
47 | queryForQuickFix(pathPos);
48 | }
49 | catch (ex) {
50 | clearExistingQuickfixDecoration();
51 | }
52 | });
53 |
54 |
55 | /**
56 | * On final dispose
57 | */
58 | var destroyObserver = editor.onDidDestroy(() => {
59 | // Clear editor observers
60 | cursorObserver.dispose();
61 | destroyObserver.dispose();
62 | });
63 | }
64 |
--------------------------------------------------------------------------------
/dist/main/tsconfig/simpleValidator.js:
--------------------------------------------------------------------------------
1 | exports.types = {
2 | string: 'string',
3 | boolean: 'boolean',
4 | number: 'number'
5 | };
6 | var SimpleValidator = (function () {
7 | function SimpleValidator(validationInfo) {
8 | var _this = this;
9 | this.validationInfo = validationInfo;
10 | this.potentialLowerCaseMatch = {};
11 | Object.keys(validationInfo).forEach(function (k) { return _this.potentialLowerCaseMatch[k.toLowerCase()] = k; });
12 | }
13 | SimpleValidator.prototype.validate = function (config) {
14 | var _this = this;
15 | var keys = Object.keys(config);
16 | var errors = { invalidValues: [], extraKeys: [], errorMessage: '' };
17 | keys.forEach(function (k) {
18 | if (!_this.validationInfo[k]) {
19 | if (_this.potentialLowerCaseMatch[k]) {
20 | errors.extraKeys.push("Key: '" + k + "' is a potential lower case match for '" + _this.potentialLowerCaseMatch[k] + "'. Fix the casing.");
21 | }
22 | else {
23 | errors.extraKeys.push("Unknown Option: " + k);
24 | }
25 | }
26 | else {
27 | var validationInfo = _this.validationInfo[k];
28 | var value = config[k];
29 | if (validationInfo.validValues && validationInfo.validValues.length) {
30 | var validValues = validationInfo.validValues;
31 | if (!validValues.some(function (valid) { return valid.toLowerCase() === value.toLowerCase(); })) {
32 | errors.invalidValues.push("Key: '" + k + "' has an invalid value: " + value);
33 | }
34 | }
35 | if (validationInfo.type && typeof value !== validationInfo.type) {
36 | errors.invalidValues.push("Key: '" + k + "' has an invalid type: " + typeof value);
37 | }
38 | }
39 | });
40 | var total = errors.invalidValues.concat(errors.extraKeys);
41 | if (total.length) {
42 | errors.errorMessage = total.join("\n");
43 | }
44 | return errors;
45 | };
46 | return SimpleValidator;
47 | })();
48 | exports.SimpleValidator = SimpleValidator;
49 | function createMap(arr) {
50 | return arr.reduce(function (result, key) {
51 | result[key] = true;
52 | return result;
53 | }, {});
54 | }
55 | exports.createMap = createMap;
56 |
--------------------------------------------------------------------------------
/dist/main/atom/views/fileSymbolsView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var sp = require('atom-space-pen-views');
7 | var atomUtils = require("../atomUtils");
8 | var FileSymbolsView = (function (_super) {
9 | __extends(FileSymbolsView, _super);
10 | function FileSymbolsView() {
11 | _super.apply(this, arguments);
12 | this.panel = null;
13 | }
14 | Object.defineProperty(FileSymbolsView.prototype, "$", {
15 | get: function () {
16 | return this;
17 | },
18 | enumerable: true,
19 | configurable: true
20 | });
21 | FileSymbolsView.prototype.setNavBarItems = function (tsItems, filePath) {
22 | var items = tsItems;
23 | this.filePath = filePath;
24 | _super.prototype.setItems.call(this, items);
25 | };
26 | FileSymbolsView.prototype.viewForItem = function (item) {
27 | return "\n \n " + (Array(item.indent * 2).join(' ') + (item.indent ? "\u221F " : '') + item.text) + "
\n " + item.kind + "
\n line: " + (item.position.line + 1) + "
\n \n ";
28 | };
29 | FileSymbolsView.prototype.confirmed = function (item) {
30 | atom.workspace.open(this.filePath, {
31 | initialLine: item.position.line,
32 | initialColumn: item.position.col
33 | });
34 | this.hide();
35 | };
36 | FileSymbolsView.prototype.getFilterKey = function () { return 'text'; };
37 | FileSymbolsView.prototype.show = function () {
38 | this.storeFocusedElement();
39 | if (!this.panel)
40 | this.panel = atom.workspace.addModalPanel({ item: this });
41 | this.panel.show();
42 | this.focusFilterEditor();
43 | };
44 | FileSymbolsView.prototype.hide = function () {
45 | this.panel.hide();
46 | this.restoreFocus();
47 | };
48 | FileSymbolsView.prototype.cancelled = function () {
49 | this.hide();
50 | };
51 | return FileSymbolsView;
52 | })(sp.SelectListView);
53 | exports.FileSymbolsView = FileSymbolsView;
54 |
--------------------------------------------------------------------------------
/lib/main/atom/commands/outputFileCommands.ts:
--------------------------------------------------------------------------------
1 | import * as atomUtils from "../atomUtils";
2 | import * as parent from "../../../worker/parent";
3 | import {spawn, exec} from "child_process";
4 | import * as path from "path";
5 |
6 | /**
7 | * Command related to output files
8 | */
9 | export function register() {
10 | atom.commands.add('atom-workspace', 'typescript:output-toggle', (e) => {
11 | if (!atomUtils.commandForTypeScript(e)) return;
12 |
13 | var query = atomUtils.getFilePath();
14 | var previousActivePane = atom.workspace.getActivePane()
15 | parent.getOutputJs(query).then(res=> {
16 | if (!res.jsFilePath) {
17 | atom.notifications.addInfo('AtomTS: No emit for this file');
18 | return;
19 | }
20 | else {
21 | // pane for uri needs file system path so:
22 | var uri = res.jsFilePath.split("/").join(path.sep);
23 | let previewPane = atom.workspace.paneForURI(uri);
24 | if (previewPane) {
25 | previewPane.destroyItem(previewPane.itemForURI(uri))
26 | }
27 | else {
28 | atom.workspace.open(res.jsFilePath, { split: "right" }).then(() => {
29 | previousActivePane.activate();
30 | });
31 | }
32 | }
33 | });
34 | });
35 |
36 | atom.commands.add('atom-workspace', 'typescript:output-file-execute-in-node', (e) => {
37 | if (!atomUtils.commandForTypeScript(e)) return;
38 |
39 | var query = atomUtils.getFilePath();
40 | parent.getOutputJs(query).then(res=> {
41 | if (!res.jsFilePath) {
42 | atom.notifications.addInfo('AtomTS: No emit for this file');
43 | return;
44 | }
45 | else {
46 | // spawn('cmd', ['/C', 'start ' + "node " + res.output.outputFiles[0].name]);
47 | var command = `node ${path.basename(res.jsFilePath) }`;
48 | console.log(command);
49 |
50 | exec(command, { cwd: path.dirname(res.jsFilePath), env: { ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1' } }, (err, stdout, stderr) => {
51 | console.log(stdout);
52 | if (stderr.toString().trim().length) {
53 | console.error(stderr);
54 | }
55 | });
56 | }
57 | });
58 | });
59 | }
60 |
--------------------------------------------------------------------------------
/lib/main/atom/views/simpleSelectionView.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A functional form of the SelectListView
3 | * Only one of these bad boys is allowed on the screen at one time
4 | */
5 |
6 | export interface SelectListViewOptions {
7 | items: T[];
8 | /** everything except the `li` which is required */
9 | viewForItem: (item: T) => string | JQuery;
10 |
11 | /** some property on item */
12 | filterKey: string;
13 | confirmed: (item: T) => any;
14 | }
15 |
16 | var singleton: SimpleSelectListView;
17 |
18 | export function simpleSelectionView(options: SelectListViewOptions): SimpleSelectListView {
19 | if (!singleton) singleton = new SimpleSelectListView(options);
20 | else { singleton.options = options; }
21 |
22 | singleton.setItems();
23 | singleton.show();
24 | return singleton;
25 | }
26 |
27 | /**
28 | * Various Utility section
29 | */
30 |
31 | import sp = require('atom-space-pen-views');
32 | import $ = sp.$;
33 | import * as atomUtils from "../atomUtils";
34 |
35 | export class SimpleSelectListView extends sp.SelectListView {
36 |
37 | constructor(public options: SelectListViewOptions) {
38 | super();
39 | }
40 |
41 | get $(): JQuery {
42 | return this;
43 | }
44 |
45 | public setItems() {
46 | super.setItems(this.options.items)
47 | }
48 |
49 | /** override */
50 | viewForItem(item: T): any {
51 | var view = this.options.viewForItem(item);
52 | if (typeof view === "string") {
53 | return `
54 | ${view}
55 | `;
56 | }
57 | else {
58 | return $('').append(view);
59 | };
60 | }
61 |
62 | /** override */
63 | confirmed(item: T) {
64 | this.options.confirmed(item);
65 | this.hide();
66 | }
67 |
68 | /** override */
69 | getFilterKey() {
70 | return this.options.filterKey;
71 | }
72 |
73 | panel: AtomCore.Panel = null;
74 | show() {
75 | this.storeFocusedElement();
76 | if (!this.panel) this.panel = atom.workspace.addModalPanel({ item: this });
77 | this.panel.show()
78 |
79 | this.focusFilterEditor();
80 | // debugger; // DEBUG: the UI in the inspector so that it doesn't change on you
81 | }
82 | hide() {
83 | this.panel.hide();
84 | this.restoreFocus();
85 | }
86 |
87 | cancelled() {
88 | this.hide();
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/lib/main/lang/fixmyts/quickFixes/typeAssertPropertyAccessToType.ts:
--------------------------------------------------------------------------------
1 | import {QuickFix, QuickFixQueryInformation, Refactoring, CanProvideFixResponse} from "../quickFix";
2 | import * as ast from "../astUtils";
3 |
4 |
5 | export class TypeAssertPropertyAccessToType implements QuickFix {
6 | key = TypeAssertPropertyAccessToType.name;
7 |
8 | canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse {
9 | var relevantError = info.positionErrors.filter(x=> x.code == ts.Diagnostics.Property_0_does_not_exist_on_type_1.code)[0];
10 | if (!relevantError) return;
11 | if (info.positionNode.kind !== ts.SyntaxKind.Identifier) return;
12 |
13 | var match = getIdentifierName(info.positionErrorMessages[0]);
14 |
15 | if (!match) return;
16 |
17 | var {identifierName} = match;
18 | return {display: `Assert for property access "${identifierName}"`, isNewTextSnippet: true};
19 | }
20 |
21 | provideFix(info: QuickFixQueryInformation): Refactoring[] {
22 | /**
23 | * We want the largest property access expressing `a.b.c` starting at the identifer `c`
24 | * Since this gets tokenized as `a.b` `.` `c` so its just the parent :)
25 | */
26 | let parent = info.positionNode.parent;
27 | if (parent.kind == ts.SyntaxKind.PropertyAccessExpression) {
28 | let propertyAccess = parent;
29 | let start = propertyAccess.getStart();
30 | let end = propertyAccess.dotToken.getStart();
31 |
32 | let oldText = propertyAccess.getText().substr(0, end - start);
33 |
34 | let refactoring: Refactoring = {
35 | filePath: info.filePath,
36 | span: {
37 | start: start,
38 | length: propertyAccess.name.end - start,
39 | },
40 | newText: `(${oldText} as \${1:any})\${2:.${propertyAccess.name.getText()}}\${3}`,
41 | isNewTextSnippet: true,
42 | };
43 |
44 | return [refactoring];
45 | }
46 | return [];
47 | }
48 | }
49 |
50 | function getIdentifierName(errorText: string) {
51 | // see https://github.com/Microsoft/TypeScript/blob/6637f49209ceb5ed719573998381eab010fa48c9/src/compiler/diagnosticMessages.json#L842
52 | var match = /Property \'(\w+)\' does not exist on type \.*/.exec(errorText);
53 |
54 | if (!match) return;
55 |
56 | var [, identifierName] = match;
57 | return { identifierName };
58 | }
59 |
--------------------------------------------------------------------------------
/lib/main/atom/buildView.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | ///ts:import=utils
4 | import utils = require('../lang/utils'); ///ts:import:generated
5 | ///ts:import=project
6 | import project = require('../lang/core/project'); ///ts:import:generated
7 |
8 | import os = require('os')
9 |
10 | import mainPanelView = require('./views/mainPanelView');
11 | import lineMessageView = require('./views/lineMessageView');
12 | import gotoHistory = require('./gotoHistory');
13 |
14 | function getTitle(errorCount: number): string {
15 | var title = ' TypeScript Build';
16 | if (errorCount > 0) {
17 | title = title + ` (
18 | ${errorCount}
19 | error${errorCount === 1 ? "" : "s"}
20 | )`;
21 | }
22 | return title;
23 | }
24 |
25 |
26 | export function setBuildOutput(buildOutput: BuildOutput) {
27 |
28 | mainPanelView.panelView.clearBuild();
29 |
30 | if (buildOutput.counts.errors) {
31 | mainPanelView.panelView.setBuildPanelCount(buildOutput.counts.errors);
32 | }
33 | else {
34 | mainPanelView.panelView.setBuildPanelCount(0);
35 | }
36 |
37 | // Update the errors list for goto history
38 | gotoHistory.buildOutput.members = [];
39 |
40 | buildOutput.outputs.forEach(output => {
41 | if (output.success) {
42 | return;
43 | }
44 | output.errors.forEach(error => {
45 | mainPanelView.panelView.addBuild(new lineMessageView.LineMessageView({
46 | goToLine: (filePath, line, col) => gotoHistory.gotoLine(filePath, line, col, gotoHistory.buildOutput),
47 | message: error.message,
48 | line: error.startPos.line + 1,
49 | col: error.startPos.col,
50 | file: error.filePath,
51 | preview: error.preview
52 | }));
53 | // Update the errors list for goto history
54 | gotoHistory.buildOutput.members.push({ filePath: error.filePath, line: error.startPos.line + 1, col: error.startPos.col });
55 | });
56 | });
57 |
58 | if (!buildOutput.counts.errors) {
59 | atom.notifications.addSuccess("Build success");
60 | }
61 | else if (buildOutput.counts.emitErrors) {
62 | atom.notifications.addError("Emits errors: " + buildOutput.counts.emitErrors + " files.");
63 | } else {
64 | atom.notifications.addWarning('Compile failed but emit succeeded');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/dist/main/atom/gotoHistory.js:
--------------------------------------------------------------------------------
1 | exports.errorsInOpenFiles = { members: [] };
2 | exports.buildOutput = { members: [] };
3 | exports.referencesOutput = { members: [] };
4 | exports.activeList = exports.errorsInOpenFiles;
5 | function gotoLine(filePath, line, col, list) {
6 | var activeFile, activeEditor = atom.workspace.getActiveTextEditor();
7 | if (activeEditor !== undefined && activeEditor !== null) {
8 | activeFile = activeEditor.getPath();
9 | }
10 | if (filePath !== activeFile) {
11 | atom.workspace.open(filePath, {
12 | initialLine: line - 1,
13 | initialColumn: col
14 | });
15 | }
16 | else {
17 | atom.workspace.getActiveTextEditor().cursors[0].setBufferPosition([line - 1, col]);
18 | }
19 | list.lastPosition = { filePath: filePath, line: line, col: col };
20 | }
21 | exports.gotoLine = gotoLine;
22 | function findCurrentIndexInList() {
23 | if (!exports.activeList.members.length) {
24 | atom.notifications.addInfo('AtomTS: no go-to members in active list');
25 | return -1;
26 | }
27 | if (!exports.activeList.lastPosition)
28 | return 0;
29 | var lastPosition = exports.activeList.lastPosition;
30 | var index = indexOf(exports.activeList.members, function (item) { return item.filePath == lastPosition.filePath && item.line == lastPosition.line; });
31 | if (index == -1) {
32 | return 0;
33 | }
34 | return index;
35 | }
36 | function gotoNext() {
37 | var currentIndex = findCurrentIndexInList();
38 | if (currentIndex == -1)
39 | return;
40 | var nextIndex = currentIndex + 1;
41 | if (nextIndex == exports.activeList.members.length) {
42 | nextIndex = 0;
43 | }
44 | var next = exports.activeList.members[nextIndex];
45 | gotoLine(next.filePath, next.line, next.col, exports.activeList);
46 | }
47 | exports.gotoNext = gotoNext;
48 | function gotoPrevious() {
49 | var currentIndex = findCurrentIndexInList();
50 | if (currentIndex == -1)
51 | return;
52 | var previousIndex = currentIndex - 1;
53 | if (previousIndex == -1) {
54 | previousIndex = exports.activeList.members.length - 1;
55 | }
56 | var previous = exports.activeList.members[previousIndex];
57 | gotoLine(previous.filePath, previous.line, previous.col, exports.activeList);
58 | }
59 | exports.gotoPrevious = gotoPrevious;
60 | function indexOf(items, filter) {
61 | for (var i = 0; i < items.length; i++) {
62 | if (filter(items[i])) {
63 | return i;
64 | }
65 | }
66 | return -1;
67 | }
68 |
--------------------------------------------------------------------------------
/dist/main/atom/views/rView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var atomUtils_1 = require("../atomUtils");
7 | var sp = require("atom-space-pen-views");
8 | var React = require('react');
9 | var MyComponent = (function (_super) {
10 | __extends(MyComponent, _super);
11 | function MyComponent(props) {
12 | var _this = this;
13 | _super.call(this, props);
14 | this.state = { count: 0 };
15 | this.stop = function () {
16 | clearInterval(_this.interval);
17 | };
18 | }
19 | MyComponent.prototype.componentDidMount = function () {
20 | var _this = this;
21 | this.interval = setInterval(function () {
22 | _this.setState({ count: _this.state.count + 1 });
23 | });
24 | };
25 | MyComponent.prototype.render = function () {
26 | return React.createElement("div", {"onClick": this.stop}, "This is a test: ", this.state.count);
27 | };
28 | MyComponent.defaultProps = { count: 0 };
29 | return MyComponent;
30 | })(React.Component);
31 | var RView = (function (_super) {
32 | __extends(RView, _super);
33 | function RView(config) {
34 | var _this = this;
35 | _super.call(this);
36 | this.config = config;
37 | this.getURI = function () { return atomUtils_1.uriForPath(_this.constructor.protocol, _this.config.filePath); };
38 | this.getTitle = function () { return _this.config.title; };
39 | this.getIconName = function () { return _this.config.icon; };
40 | React.render(React.createElement(MyComponent, {}), this.rootDomElement);
41 | }
42 | Object.defineProperty(RView.prototype, "rootDomElement", {
43 | get: function () {
44 | return this.mainContent[0];
45 | },
46 | enumerable: true,
47 | configurable: true
48 | });
49 | RView.content = function () {
50 | var _this = this;
51 | return this.div({ class: 'atomts atomts-r-view native-key-bindings' }, function () {
52 | _this.div({ outlet: 'mainContent layout' });
53 | });
54 | };
55 | Object.defineProperty(RView.prototype, "$", {
56 | get: function () { return this; },
57 | enumerable: true,
58 | configurable: true
59 | });
60 | RView.protocol = 'atomtsview:';
61 | return RView;
62 | })(sp.ScrollView);
63 | exports.RView = RView;
64 |
--------------------------------------------------------------------------------
/lib/main/lang/fixmyts/quickFix.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Interfaces for quick fixes
3 | */
4 | import project = require("../core/project");
5 |
6 |
7 |
8 | export interface Refactoring extends ts.TextChange {
9 | filePath: string;
10 |
11 | /** If you want to insert a snippet. Be careful that you shouldn't return more than one refatoring if you want to use this */
12 | isNewTextSnippet?: boolean;
13 | }
14 |
15 |
16 | /** Note this interface has a few redundant stuff. This is intentional to precompute once */
17 | export interface QuickFixQueryInformation {
18 | project: project.Project;
19 | service: ts.LanguageService;
20 | program: ts.Program;
21 | typeChecker: ts.TypeChecker;
22 | sourceFile: ts.SourceFile;
23 | sourceFileText: string;
24 | fileErrors: ts.Diagnostic[];
25 | positionErrors: ts.Diagnostic[];
26 | positionErrorMessages: string[];
27 | position: number;
28 | positionNode: ts.Node;
29 | filePath: string;
30 |
31 | /**
32 | * Either the previous or the current.
33 | * This needs more thinking e.g. 'rename' already does the right thing. See how it is implemented
34 | */
35 | oneOfPositionNodesOfType?(kind: ts.SyntaxKind): boolean;
36 | }
37 |
38 | export interface CanProvideFixResponse {
39 | /**
40 | * Return '' if you can't provide a fix
41 | * return 'Some string to display' if you can provide a string
42 | */
43 | display: string;
44 | isNewTextSnippet?: boolean;
45 | }
46 |
47 | export interface QuickFix {
48 | /** Some unique key. Classname works best ;) */
49 | key: string;
50 |
51 | canProvideFix(info: QuickFixQueryInformation): CanProvideFixResponse;
52 |
53 | provideFix(info: QuickFixQueryInformation): Refactoring[];
54 | }
55 |
56 |
57 | /** You don't need to create this manually. Just use the util function */
58 | export interface RefactoringsByFilePath {
59 | [filePath: string]: Refactoring[];
60 | }
61 |
62 | /** Utility method. Reason is we want to transact by file path */
63 | export function getRefactoringsByFilePath(refactorings: Refactoring[]) {
64 | var loc: RefactoringsByFilePath = {};
65 | for (let refac of refactorings) {
66 | if (!loc[refac.filePath]) loc[refac.filePath] = [];
67 | loc[refac.filePath].push(refac);
68 | }
69 |
70 | // sort each of these in descending by start location
71 | for (let filePath in loc) {
72 | let refactorings = loc[filePath];
73 | refactorings.sort((a: Refactoring, b: Refactoring) => {
74 | return (b.span.start - a.span.start);
75 | });
76 | }
77 |
78 | return loc;
79 | }
80 |
--------------------------------------------------------------------------------
/dist/main/atom/views/simpleSelectionView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var singleton;
7 | function simpleSelectionView(options) {
8 | if (!singleton)
9 | singleton = new SimpleSelectListView(options);
10 | else {
11 | singleton.options = options;
12 | }
13 | singleton.setItems();
14 | singleton.show();
15 | return singleton;
16 | }
17 | exports.simpleSelectionView = simpleSelectionView;
18 | var sp = require('atom-space-pen-views');
19 | var $ = sp.$;
20 | var SimpleSelectListView = (function (_super) {
21 | __extends(SimpleSelectListView, _super);
22 | function SimpleSelectListView(options) {
23 | _super.call(this);
24 | this.options = options;
25 | this.panel = null;
26 | }
27 | Object.defineProperty(SimpleSelectListView.prototype, "$", {
28 | get: function () {
29 | return this;
30 | },
31 | enumerable: true,
32 | configurable: true
33 | });
34 | SimpleSelectListView.prototype.setItems = function () {
35 | _super.prototype.setItems.call(this, this.options.items);
36 | };
37 | SimpleSelectListView.prototype.viewForItem = function (item) {
38 | var view = this.options.viewForItem(item);
39 | if (typeof view === "string") {
40 | return "\n " + view + "\n ";
41 | }
42 | else {
43 | return $('').append(view);
44 | }
45 | ;
46 | };
47 | SimpleSelectListView.prototype.confirmed = function (item) {
48 | this.options.confirmed(item);
49 | this.hide();
50 | };
51 | SimpleSelectListView.prototype.getFilterKey = function () {
52 | return this.options.filterKey;
53 | };
54 | SimpleSelectListView.prototype.show = function () {
55 | this.storeFocusedElement();
56 | if (!this.panel)
57 | this.panel = atom.workspace.addModalPanel({ item: this });
58 | this.panel.show();
59 | this.focusFilterEditor();
60 | };
61 | SimpleSelectListView.prototype.hide = function () {
62 | this.panel.hide();
63 | this.restoreFocus();
64 | };
65 | SimpleSelectListView.prototype.cancelled = function () {
66 | this.hide();
67 | };
68 | return SimpleSelectListView;
69 | })(sp.SelectListView);
70 | exports.SimpleSelectListView = SimpleSelectListView;
71 |
--------------------------------------------------------------------------------
/dist/main/atom/views/lineMessageView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var view = require('./view');
7 | var $ = view.$;
8 | var LineMessageView = (function (_super) {
9 | __extends(LineMessageView, _super);
10 | function LineMessageView() {
11 | _super.apply(this, arguments);
12 | }
13 | LineMessageView.content = function () {
14 | var _this = this;
15 | return this.div({
16 | class: 'line-message'
17 | }, function () {
18 | _this.div({
19 | class: 'text-subtle inline-block',
20 | outlet: 'position',
21 | click: 'goToLine',
22 | style: 'cursor: pointer;'
23 | });
24 | _this.div({
25 | class: 'message inline-block',
26 | outlet: 'contents'
27 | });
28 | _this.pre({
29 | class: 'preview',
30 | outlet: 'code',
31 | click: 'goToLine',
32 | style: 'cursor: pointer;'
33 | });
34 | });
35 | };
36 | LineMessageView.prototype.init = function () {
37 | var message = 'at line ' + this.options.line;
38 | if (this.options.file !== undefined) {
39 | message += ', file ' + this.options.file;
40 | }
41 | this.position.text(message);
42 | this.contents.text(this.options.message);
43 | if (this.options.preview) {
44 | this.code.text(this.options.preview);
45 | }
46 | else {
47 | this.code.remove();
48 | }
49 | };
50 | LineMessageView.prototype.goToLine = function () {
51 | this.options.goToLine(this.options.file, this.options.line, this.options.col);
52 | };
53 | LineMessageView.prototype.getSummary = function () {
54 | var pos = this.options.line.toString();
55 | if (this.options.file !== undefined) {
56 | pos += ', ' + this.options.file;
57 | }
58 | return {
59 | summary: pos + ' ' + this.options.message,
60 | rawSummary: true,
61 | handler: function (element) {
62 | $(element)
63 | .css('cursor', 'pointer')
64 | .click(this.goToLine.bind(this));
65 | }.bind(this)
66 | };
67 | };
68 | return LineMessageView;
69 | })(view.View);
70 | exports.LineMessageView = LineMessageView;
71 |
--------------------------------------------------------------------------------
/dist/main/lang/fixmyts/quickFixes/addImportStatement.js:
--------------------------------------------------------------------------------
1 | var os_1 = require("os");
2 | var displayPartsToString = ts.displayPartsToString, typeToDisplayParts = ts.typeToDisplayParts;
3 | var getPathCompletions_1 = require("../../modules/getPathCompletions");
4 | function getIdentifierAndFileNames(error, project) {
5 | var errorText = error.messageText;
6 | if (typeof errorText !== 'string') {
7 | return undefined;
8 | }
9 | ;
10 | var match = errorText.match(/Cannot find name \'(\w+)\'./);
11 | if (!match)
12 | return;
13 | var identifierName = match[1];
14 | var files = getPathCompletions_1.getPathCompletions({
15 | project: project,
16 | filePath: error.file.fileName,
17 | prefix: identifierName,
18 | includeExternalModules: false
19 | }).files;
20 | var file = files.length > 0 ? files[0].relativePath : undefined;
21 | var basename = files.length > 0 ? files[0].name : undefined;
22 | return { identifierName: identifierName, file: file, basename: basename };
23 | }
24 | var AddImportStatement = (function () {
25 | function AddImportStatement() {
26 | this.key = AddImportStatement.name;
27 | }
28 | AddImportStatement.prototype.canProvideFix = function (info) {
29 | var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0];
30 | if (!relevantError)
31 | return;
32 | if (info.positionNode.kind !== ts.SyntaxKind.Identifier)
33 | return;
34 | var matches = getIdentifierAndFileNames(relevantError, info.project);
35 | if (!matches)
36 | return;
37 | var identifierName = matches.identifierName, file = matches.file;
38 | return file ? { display: "import " + identifierName + " = require(\"" + file + "\")" } : undefined;
39 | };
40 | AddImportStatement.prototype.provideFix = function (info) {
41 | var relevantError = info.positionErrors.filter(function (x) { return x.code == 2304; })[0];
42 | var identifier = info.positionNode;
43 | var identifierName = identifier.text;
44 | var fileNameforFix = getIdentifierAndFileNames(relevantError, info.project);
45 | var refactorings = [{
46 | span: {
47 | start: 0,
48 | length: 0
49 | },
50 | newText: "import " + identifierName + " = require(\"" + fileNameforFix.file + "\");" + os_1.EOL,
51 | filePath: info.sourceFile.fileName
52 | }];
53 | return refactorings;
54 | };
55 | return AddImportStatement;
56 | })();
57 | exports.AddImportStatement = AddImportStatement;
58 |
--------------------------------------------------------------------------------
/lib/typings/pathwatcher/pathwatcher.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for pathwatcher
2 | // Project: https://github.com/atom/node-pathwatcher
3 | // Definitions by: vvakame
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | ///
7 | ///
8 |
9 | declare module PathWatcher {
10 | interface IFileStatic {
11 | new (path:string, symlink?:boolean):IFile;
12 | }
13 |
14 | interface IFile {
15 | realPath:string;
16 | path:string;
17 | symlink:boolean;
18 | cachedContents:string;
19 | digest:string;
20 |
21 | handleEventSubscriptions():void;
22 | setPath(path:string):void;
23 | getPath():string;
24 | getRealPathSync():string;
25 | getBaseName():string;
26 | write(text:string):void;
27 | readSync(flushCache:boolean):string;
28 | read(flushCache?:boolean):Q.Promise;
29 | exists():boolean;
30 | setDigest(contents:string):void;
31 | getDigest():string;
32 | writeFileWithPrivilegeEscalationSync (filePath:string, text:string):void;
33 | handleNativeChangeEvent(eventType:string, eventPath:string):void;
34 | detectResurrectionAfterDelay():void;
35 | detectResurrection():void;
36 | subscribeToNativeChangeEvents():void;
37 | unsubscribeFromNativeChangeEvents():void;
38 | }
39 |
40 | interface IDirectoryStatic {
41 | new (path:string, symlink?:boolean):IDirectory;
42 | }
43 |
44 | interface IDirectory {
45 | realPath:string;
46 | path:string;
47 | symlink:boolean;
48 |
49 | getBaseName():string;
50 | getPath():void;
51 | getRealPathSync():string;
52 | contains(pathToCheck:string):boolean;
53 | relativize(fullPath:string):string;
54 | getEntriesSync():any[]; // return type are {File | Directory}[]
55 | getEntries(callback:Function):void;
56 | subscribeToNativeChangeEvents():void;
57 | unsubscribeFromNativeChangeEvents():void;
58 | isPathPrefixOf(prefix:string, fullPath:string):boolean;
59 | }
60 | }
61 |
62 | declare module "pathwatcher" {
63 |
64 | import events = require("events");
65 |
66 | interface IHandleWatcher extends events.EventEmitter {
67 | onEvent(event:any, filePath:any, oldFilePath:any):any;
68 | start():void;
69 | closeIfNoListener():void;
70 | close():void;
71 | }
72 |
73 | interface IPathWatcher {
74 | isWatchingParent:boolean;
75 | path:any;
76 | handleWatcher:IHandleWatcher;
77 |
78 | close():void;
79 | }
80 |
81 | function watch(path:string, callback:Function):IPathWatcher;
82 |
83 | function closeAllWatchers():void;
84 |
85 | function getWatchedPaths():string[];
86 |
87 | var File:PathWatcher.IFileStatic;
88 | var Directory:PathWatcher.IDirectoryStatic;
89 | }
90 |
--------------------------------------------------------------------------------
/dist/main/lang/fixmyts/quickFixes/implementInterface.js:
--------------------------------------------------------------------------------
1 | var ast = require("../astUtils");
2 | var os_1 = require("os");
3 | function getClassAndInterfaceName(error) {
4 | var errorText = ts.flattenDiagnosticMessageText(error.messageText, os_1.EOL);
5 | var match = errorText.match(/Class \'(\w+)\' incorrectly implements interface \'(\w+)\'./);
6 | if (!match || match.length !== 3)
7 | return;
8 | var className = match[1], interfaceName = match[2];
9 | return { className: className, interfaceName: interfaceName };
10 | }
11 | var ImplementInterface = (function () {
12 | function ImplementInterface() {
13 | this.key = ImplementInterface.name;
14 | }
15 | ImplementInterface.prototype.canProvideFix = function (info) {
16 | var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code; })[0];
17 | if (!relevantError)
18 | return;
19 | if (info.positionNode.kind !== ts.SyntaxKind.Identifier)
20 | return;
21 | var match = getClassAndInterfaceName(relevantError);
22 | if (!match)
23 | return;
24 | var className = match.className, interfaceName = match.interfaceName;
25 | return { display: "Implement members of " + interfaceName + " in " + className };
26 | };
27 | ImplementInterface.prototype.provideFix = function (info) {
28 | var relevantError = info.positionErrors.filter(function (x) { return x.code == ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code; })[0];
29 | if (!relevantError)
30 | return;
31 | if (info.positionNode.kind !== ts.SyntaxKind.Identifier)
32 | return;
33 | var match = getClassAndInterfaceName(relevantError);
34 | var className = match.className, interfaceName = match.interfaceName;
35 | var interfaceTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.InterfaceDeclaration, className);
36 | var classTarget = ast.getNodeByKindAndName(info.program, ts.SyntaxKind.ClassDeclaration, className);
37 | var braces = classTarget.getChildren().filter(function (x) { return x.kind == ts.SyntaxKind.CloseBraceToken; });
38 | var lastBrace = braces[braces.length - 1];
39 | var indentLength = info.service.getIndentationAtPosition(classTarget.getSourceFile().fileName, lastBrace.getStart(), info.project.projectFile.project.formatCodeOptions);
40 | var indent = Array(indentLength + info.project.projectFile.project.formatCodeOptions.IndentSize + 1).join(' ');
41 | var refactorings = [];
42 | return refactorings;
43 | };
44 | return ImplementInterface;
45 | })();
46 | exports.ImplementInterface = ImplementInterface;
47 |
--------------------------------------------------------------------------------
/lib/main/lang/modules/getPathCompletions.ts:
--------------------------------------------------------------------------------
1 | import * as path from "path";
2 | import {Project} from "../core/project";
3 | import * as tsconfig from "../../tsconfig/tsconfig";
4 | import * as utils from "../utils";
5 | var fuzzaldrin: { filter: (list: any[], prefix: string, property?: { key: string }) => any } = require('fuzzaldrin');
6 |
7 | /** From https://github.com/Microsoft/TypeScript/pull/2173/files */
8 | function getExternalModuleNames(program: ts.Program): string[] {
9 | var entries: string[] = [];
10 |
11 | program.getSourceFiles().forEach(sourceFile => {
12 |
13 | // Look for ambient external module declarations
14 | ts.forEachChild(sourceFile, child => {
15 | if (child.kind === ts.SyntaxKind.ModuleDeclaration && (child).name.kind === ts.SyntaxKind.StringLiteral) {
16 | entries.push((child).name.text);
17 | }
18 | });
19 | });
20 |
21 | return entries;
22 | }
23 |
24 | export interface GetRelativePathsInProjectResponse {
25 | files: {
26 | name: string;
27 | relativePath: string;
28 | fullPath: string;
29 | }[];
30 | endsInPunctuation: boolean;
31 | }
32 |
33 | export interface GetPathCompletions {
34 | project: Project;
35 | filePath: string;
36 | prefix: string;
37 | includeExternalModules: boolean;
38 | }
39 |
40 | export function getPathCompletions(query: GetPathCompletions): GetRelativePathsInProjectResponse {
41 | var project = query.project;
42 | var sourceDir = path.dirname(query.filePath);
43 | var filePaths = project.projectFile.project.files.filter(p=> p !== query.filePath);
44 | var files: {
45 | name: string;
46 | relativePath: string;
47 | fullPath: string;
48 | }[] = [];
49 |
50 | if (query.includeExternalModules) {
51 | var externalModules = getExternalModuleNames(project.languageService.getProgram());
52 | externalModules.forEach(e=> files.push({
53 | name: `${e}`,
54 | relativePath: e,
55 | fullPath: e
56 | }));
57 | }
58 |
59 | filePaths.forEach(p=> {
60 | files.push({
61 | name: path.basename(p, '.ts'),
62 | relativePath: tsconfig.removeExt(tsconfig.makeRelativePath(sourceDir, p)),
63 | fullPath: p
64 | });
65 | });
66 |
67 | var endsInPunctuation: boolean = utils.prefixEndsInPunctuation(query.prefix);
68 |
69 | if (!endsInPunctuation)
70 | files = fuzzaldrin.filter(files, query.prefix, { key: 'name' });
71 |
72 | var response: GetRelativePathsInProjectResponse = {
73 | files: files,
74 | endsInPunctuation: endsInPunctuation
75 | };
76 |
77 | return response;
78 | }
79 |
--------------------------------------------------------------------------------
/dist/main/atom/atomConfig.js:
--------------------------------------------------------------------------------
1 | var utils_1 = require("../lang/utils");
2 | var packageName = 'atom-typescript';
3 | function getConfig(nameLambda) {
4 | return atom.config.get(packageName + '.' + utils_1.getName(nameLambda));
5 | }
6 | function setConfig(nameLambda, value) {
7 | return atom.config.set(packageName + '.' + utils_1.getName(nameLambda), value);
8 | }
9 | var Config = (function () {
10 | function Config() {
11 | this.schema = {
12 | debugAtomTs: {
13 | title: 'Debug: Atom-TypeScript. Please do not use.',
14 | type: 'boolean',
15 | default: false
16 | },
17 | preferredQuoteCharacter: {
18 | title: 'Preferred quote character',
19 | type: 'string',
20 | default: 'none'
21 | },
22 | typescriptServices: {
23 | title: 'Full path (including file name) to a custom `typescriptServices.js`',
24 | type: 'string',
25 | default: ''
26 | },
27 | showSemanticView: {
28 | title: 'Show semantic view',
29 | type: 'boolean',
30 | default: false
31 | }
32 | };
33 | }
34 | Object.defineProperty(Config.prototype, "debugAtomTs", {
35 | get: function () {
36 | var _this = this;
37 | return getConfig(function () { return _this.schema.debugAtomTs; });
38 | },
39 | enumerable: true,
40 | configurable: true
41 | });
42 | Object.defineProperty(Config.prototype, "preferredQuoteCharacter", {
43 | get: function () {
44 | var _this = this;
45 | return getConfig(function () { return _this.schema.preferredQuoteCharacter; });
46 | },
47 | enumerable: true,
48 | configurable: true
49 | });
50 | Object.defineProperty(Config.prototype, "typescriptServices", {
51 | get: function () {
52 | var _this = this;
53 | return getConfig(function () { return _this.schema.typescriptServices; });
54 | },
55 | enumerable: true,
56 | configurable: true
57 | });
58 | Object.defineProperty(Config.prototype, "showSemanticView", {
59 | get: function () {
60 | var _this = this;
61 | return getConfig(function () { return _this.schema.showSemanticView; });
62 | },
63 | set: function (value) {
64 | var _this = this;
65 | setConfig(function () { return _this.schema.showSemanticView; }, value);
66 | },
67 | enumerable: true,
68 | configurable: true
69 | });
70 | return Config;
71 | })();
72 | var config = new Config();
73 | module.exports = config;
74 |
--------------------------------------------------------------------------------
/lib/main/atom/views/lineMessageView.ts:
--------------------------------------------------------------------------------
1 | import view = require('./view');
2 | var $ = view.$;
3 | import path = require('path');
4 |
5 | export interface ViewOptions {
6 | /** This is needed to support good goto next / goto previous logic
7 | * We inform the parent about our navigation
8 | */
9 | goToLine: (filePath: string, line: number, col: number) => any;
10 | /** your message to the people */
11 | message: string;
12 | /** what line are we talking about? */
13 | line: number;
14 | /** which column */
15 | col: number;
16 | /** so, was that in some other file? */
17 | file: string;
18 | /** lets you display a code snippet inside a pre tag */
19 | preview: string;
20 | }
21 |
22 | export class LineMessageView extends view.View {
23 |
24 | public index: number;
25 | private position: JQuery;
26 | private contents: JQuery;
27 | private code: JQuery;
28 | static content() {
29 | return this.div({
30 | class: 'line-message'
31 | }, () => {
32 | this.div({
33 | class: 'text-subtle inline-block',
34 | outlet: 'position',
35 | click: 'goToLine',
36 | style: 'cursor: pointer;'
37 | });
38 | this.div({
39 | class: 'message inline-block',
40 | outlet: 'contents'
41 | });
42 |
43 | this.pre({
44 | class: 'preview',
45 | outlet: 'code',
46 | click: 'goToLine',
47 | style: 'cursor: pointer;'
48 | });
49 | });
50 | }
51 |
52 | init() {
53 | var message = 'at line ' + this.options.line;
54 |
55 | if (this.options.file !== undefined) {
56 | message += ', file ' + this.options.file;
57 | }
58 | this.position.text(message);
59 | this.contents.text(this.options.message);
60 |
61 | if (this.options.preview) {
62 | this.code.text(this.options.preview);
63 | } else {
64 | this.code.remove();
65 | }
66 | }
67 |
68 | goToLine() {
69 | this.options.goToLine(this.options.file, this.options.line, this.options.col);
70 | }
71 |
72 | getSummary() {
73 | var pos = this.options.line.toString();
74 | if (this.options.file !== undefined) {
75 | pos += ', ' + this.options.file;
76 | }
77 | return {
78 | summary: pos + ' ' + this.options.message,
79 | rawSummary: true,
80 | handler: function(element) {
81 | $(element)
82 | .css('cursor', 'pointer')
83 | .click(this.goToLine.bind(this));
84 | }.bind(this)
85 | };
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/dist/main/atom/views/projectSymbolsView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var sp = require('atom-space-pen-views');
7 | var atomUtils = require("../atomUtils");
8 | var ProjectSymbolsView = (function (_super) {
9 | __extends(ProjectSymbolsView, _super);
10 | function ProjectSymbolsView() {
11 | _super.apply(this, arguments);
12 | this.panel = null;
13 | }
14 | Object.defineProperty(ProjectSymbolsView.prototype, "$", {
15 | get: function () {
16 | return this;
17 | },
18 | enumerable: true,
19 | configurable: true
20 | });
21 | Object.defineProperty(ProjectSymbolsView.prototype, "filterView", {
22 | get: function () {
23 | return {
24 | $: this.filterEditorView,
25 | model: this.filterEditorView.model
26 | };
27 | },
28 | enumerable: true,
29 | configurable: true
30 | });
31 | ProjectSymbolsView.prototype.setNavBarItems = function (tsItems) {
32 | _super.prototype.setMaxItems.call(this, 40);
33 | var items = tsItems;
34 | _super.prototype.setItems.call(this, items);
35 | };
36 | ProjectSymbolsView.prototype.viewForItem = function (item) {
37 | return "\n \n " + item.name + "
\n " + item.kind + "
\n " + item.fileName + " : " + (item.position.line + 1) + "
\n \n ";
38 | };
39 | ProjectSymbolsView.prototype.confirmed = function (item) {
40 | atom.workspace.open(item.filePath, {
41 | initialLine: item.position.line,
42 | initialColumn: item.position.col
43 | });
44 | this.hide();
45 | };
46 | ProjectSymbolsView.prototype.getFilterKey = function () { return 'name'; };
47 | ProjectSymbolsView.prototype.show = function () {
48 | this.storeFocusedElement();
49 | if (!this.panel)
50 | this.panel = atom.workspace.addModalPanel({ item: this });
51 | this.panel.show();
52 | this.focusFilterEditor();
53 | };
54 | ProjectSymbolsView.prototype.hide = function () {
55 | this.panel.hide();
56 | this.restoreFocus();
57 | };
58 | ProjectSymbolsView.prototype.cancelled = function () {
59 | this.hide();
60 | };
61 | return ProjectSymbolsView;
62 | })(sp.SelectListView);
63 | exports.ProjectSymbolsView = ProjectSymbolsView;
64 |
--------------------------------------------------------------------------------
/dist/main/atom/views/contextView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var sp = require('atom-space-pen-views');
7 | var mainPanelView = require('./mainPanelView');
8 | var semanticView = require("./semanticView");
9 | var titles = {
10 | togglePanel: 'Toggle TypeScript Panel',
11 | tabErrors: 'Tab: Errors in Open Files',
12 | tabLastBuild: 'Tab: Last Build Output',
13 | tabReferences: 'Tab: Find References',
14 | fileSemantics: 'Toggle: File Semantics',
15 | };
16 | var items = Object.keys(titles).map(function (item) { return { title: titles[item] }; });
17 | var ContextView = (function (_super) {
18 | __extends(ContextView, _super);
19 | function ContextView() {
20 | _super.apply(this, arguments);
21 | this.panel = null;
22 | }
23 | Object.defineProperty(ContextView.prototype, "$", {
24 | get: function () {
25 | return this;
26 | },
27 | enumerable: true,
28 | configurable: true
29 | });
30 | ContextView.prototype.setItems = function (items) { _super.prototype.setItems.call(this, items); };
31 | ContextView.prototype.viewForItem = function (item) {
32 | return "" + item.title + "";
33 | };
34 | ContextView.prototype.confirmed = function (item) {
35 | if (item.title == titles.togglePanel) {
36 | mainPanelView.panelView.toggle();
37 | }
38 | if (item.title == titles.tabErrors) {
39 | mainPanelView.panelView.errorPanelSelected();
40 | }
41 | if (item.title == titles.tabLastBuild) {
42 | mainPanelView.panelView.buildPanelSelected();
43 | }
44 | if (item.title == titles.tabReferences) {
45 | mainPanelView.panelView.referencesPanelSelected();
46 | }
47 | if (item.title == titles.fileSemantics) {
48 | semanticView.toggle();
49 | }
50 | this.hide();
51 | };
52 | ContextView.prototype.getFilterKey = function () { return 'title'; };
53 | ContextView.prototype.show = function () {
54 | this.storeFocusedElement();
55 | if (!this.panel)
56 | this.panel = atom.workspace.addModalPanel({ item: this });
57 | this.panel.show();
58 | this.setItems(items);
59 | this.focusFilterEditor();
60 | };
61 | ContextView.prototype.hide = function () {
62 | this.panel.hide();
63 | this.restoreFocus();
64 | };
65 | ContextView.prototype.cancelled = function () {
66 | this.hide();
67 | };
68 | return ContextView;
69 | })(sp.SelectListView);
70 | exports.ContextView = ContextView;
71 |
--------------------------------------------------------------------------------
/lib/main/atom/views/simpleOverlaySelectionView.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A functional form of the SelectListView
3 | * Only one of these bad boys is allowed on the screen at one time
4 | */
5 |
6 | export interface SelectListViewOptions {
7 | items: T[];
8 | /** everything except the `li` which is required and we add for you */
9 | viewForItem: (item: T) => string;
10 |
11 | /** some property on item */
12 | filterKey: string;
13 | confirmed: (item: T) => any;
14 | }
15 |
16 | var singleton: SimpleOverlaySelectListView;
17 |
18 | export default function (options: SelectListViewOptions, editor: AtomCore.IEditor): SimpleOverlaySelectListView {
19 | if (!singleton) singleton = new SimpleOverlaySelectListView(options, editor);
20 | else {
21 | singleton.options = options;
22 | singleton.editor = editor;
23 | }
24 |
25 | singleton.setItems();
26 | singleton.show();
27 | return singleton;
28 | }
29 |
30 | /**
31 | * Various Utility section
32 | */
33 |
34 | import sp = require('atom-space-pen-views');
35 | import * as atomUtils from "../atomUtils";
36 |
37 | export class SimpleOverlaySelectListView extends sp.SelectListView {
38 |
39 | private _overlayDecoration: AtomCore.Decoration;
40 |
41 |
42 | constructor(public options: SelectListViewOptions, public editor: AtomCore.IEditor) {
43 | super();
44 |
45 | this.$.addClass('atomts-overlay');
46 | (this.filterEditorView).model.placeholderText = 'Filter list';
47 | }
48 |
49 | get $(): JQuery {
50 | return this;
51 | }
52 |
53 | public setItems() {
54 | super.setItems(this.options.items)
55 | }
56 |
57 | /** override */
58 | viewForItem(item: T) {
59 | return `
60 | ${this.options.viewForItem(item) }
61 | `;
62 | }
63 |
64 | /** override */
65 | confirmed(item: T) {
66 | this.options.confirmed(item);
67 | this.hide();
68 | }
69 |
70 | /** override */
71 | getFilterKey() {
72 | return this.options.filterKey;
73 | }
74 |
75 | show() {
76 | this.storeFocusedElement();
77 | this._overlayDecoration = this.editor.decorateMarker(this.editor.getLastCursor().getMarker(),
78 | { type: "overlay", position: "tail", item: this });
79 |
80 | /** I've need to do this timeout otherwise we don't get focus. I suspect its an artifact of creating an overlay decoration */
81 | // Comment this out if you want to test styles ;)
82 | setTimeout(() => this.focusFilterEditor(), 100);
83 | }
84 |
85 | hide() {
86 | this.restoreFocus();
87 |
88 | if (this._overlayDecoration)
89 | this._overlayDecoration.destroy();
90 | }
91 |
92 | cancelled() {
93 | this.hide();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/lib/main/tsconfig/simpleValidator.ts:
--------------------------------------------------------------------------------
1 | /// Not useful for user input validation
2 | // But great for simple config validation
3 | // works only by "n" valid options
4 |
5 | export var types = {
6 | string: 'string',
7 | boolean: 'boolean',
8 | number: 'number'
9 | }
10 |
11 | export interface ValidationInfo {
12 | [name: string]: {
13 | validValues?: string[];
14 | type?: string;
15 | }
16 | }
17 |
18 | export interface Errors {
19 | invalidValues: string[];
20 | extraKeys: string[];
21 | errorMessage: string;
22 | }
23 |
24 | export class SimpleValidator {
25 |
26 | private potentialLowerCaseMatch: { [key: string]: string };
27 | constructor(public validationInfo: ValidationInfo) {
28 | this.potentialLowerCaseMatch = {};
29 | Object.keys(validationInfo).forEach(k=> this.potentialLowerCaseMatch[k.toLowerCase()] = k);
30 | }
31 |
32 | validate(config: any): Errors {
33 | var keys = Object.keys(config);
34 | var errors = { invalidValues: [], extraKeys: [], errorMessage: '' };
35 | keys.forEach(k=> {
36 | // Check extra keys
37 | if (!this.validationInfo[k]) {
38 | if (this.potentialLowerCaseMatch[k]) {
39 | errors.extraKeys.push(`Key: '${k}' is a potential lower case match for '${this.potentialLowerCaseMatch[k]}'. Fix the casing.`);
40 | }
41 | else {
42 | errors.extraKeys.push(`Unknown Option: ${k}`)
43 | }
44 | }
45 | // Do validation
46 | else {
47 | var validationInfo = this.validationInfo[k];
48 | var value: any = config[k];
49 | if (validationInfo.validValues && validationInfo.validValues.length) {
50 | var validValues = validationInfo.validValues;
51 | if (!validValues.some(valid => valid.toLowerCase() === value.toLowerCase())) {
52 | errors.invalidValues.push(`Key: '${k}' has an invalid value: ${value}`);
53 | }
54 | }
55 | if (validationInfo.type && typeof value !== validationInfo.type) {
56 | errors.invalidValues.push(`Key: '${k}' has an invalid type: ${typeof value}`)
57 | }
58 | }
59 | });
60 |
61 | var total = errors.invalidValues.concat(errors.extraKeys);
62 | if (total.length) {
63 | errors.errorMessage = total.join("\n");
64 | }
65 |
66 | return errors;
67 | }
68 | }
69 |
70 |
71 | export function createMap(arr: string[]): { [key: string]: boolean } {
72 | return arr.reduce((result: { [key: string]: boolean }, key: string) => {
73 | result[key] = true;
74 | return result;
75 | }, <{ [key: string]: boolean }>{});
76 | }
77 |
--------------------------------------------------------------------------------
/dist/main/atom/views/simpleOverlaySelectionView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var singleton;
7 | function default_1(options, editor) {
8 | if (!singleton)
9 | singleton = new SimpleOverlaySelectListView(options, editor);
10 | else {
11 | singleton.options = options;
12 | singleton.editor = editor;
13 | }
14 | singleton.setItems();
15 | singleton.show();
16 | return singleton;
17 | }
18 | Object.defineProperty(exports, "__esModule", { value: true });
19 | exports.default = default_1;
20 | var sp = require('atom-space-pen-views');
21 | var SimpleOverlaySelectListView = (function (_super) {
22 | __extends(SimpleOverlaySelectListView, _super);
23 | function SimpleOverlaySelectListView(options, editor) {
24 | _super.call(this);
25 | this.options = options;
26 | this.editor = editor;
27 | this.$.addClass('atomts-overlay');
28 | this.filterEditorView.model.placeholderText = 'Filter list';
29 | }
30 | Object.defineProperty(SimpleOverlaySelectListView.prototype, "$", {
31 | get: function () {
32 | return this;
33 | },
34 | enumerable: true,
35 | configurable: true
36 | });
37 | SimpleOverlaySelectListView.prototype.setItems = function () {
38 | _super.prototype.setItems.call(this, this.options.items);
39 | };
40 | SimpleOverlaySelectListView.prototype.viewForItem = function (item) {
41 | return "\n " + this.options.viewForItem(item) + "\n ";
42 | };
43 | SimpleOverlaySelectListView.prototype.confirmed = function (item) {
44 | this.options.confirmed(item);
45 | this.hide();
46 | };
47 | SimpleOverlaySelectListView.prototype.getFilterKey = function () {
48 | return this.options.filterKey;
49 | };
50 | SimpleOverlaySelectListView.prototype.show = function () {
51 | var _this = this;
52 | this.storeFocusedElement();
53 | this._overlayDecoration = this.editor.decorateMarker(this.editor.getLastCursor().getMarker(), { type: "overlay", position: "tail", item: this });
54 | setTimeout(function () { return _this.focusFilterEditor(); }, 100);
55 | };
56 | SimpleOverlaySelectListView.prototype.hide = function () {
57 | this.restoreFocus();
58 | if (this._overlayDecoration)
59 | this._overlayDecoration.destroy();
60 | };
61 | SimpleOverlaySelectListView.prototype.cancelled = function () {
62 | this.hide();
63 | };
64 | return SimpleOverlaySelectListView;
65 | })(sp.SelectListView);
66 | exports.SimpleOverlaySelectListView = SimpleOverlaySelectListView;
67 |
--------------------------------------------------------------------------------
/dist/main/atom/views/documentationView.js:
--------------------------------------------------------------------------------
1 | var __extends = (this && this.__extends) || function (d, b) {
2 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 | function __() { this.constructor = d; }
4 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5 | };
6 | var view = require('./view');
7 | var $ = view.$;
8 | var DocumentationView = (function (_super) {
9 | __extends(DocumentationView, _super);
10 | function DocumentationView() {
11 | _super.apply(this, arguments);
12 | this.shown = false;
13 | }
14 | DocumentationView.content = function () {
15 | var _this = this;
16 | return this.div({ class: 'atom-ts-documentation padded top' }, function () { return _this.div(function () {
17 | _this.h2({ outlet: 'header' });
18 | _this.p({ outlet: 'documentation' });
19 | }); });
20 | };
21 | DocumentationView.prototype.show = function () { this.$.addClass('active'); this.shown = true; };
22 | DocumentationView.prototype.hide = function () { this.$.removeClass('active'); this.shown = false; };
23 | DocumentationView.prototype.toggle = function () { if (this.shown) {
24 | this.hide();
25 | }
26 | else {
27 | this.show();
28 | } };
29 | DocumentationView.prototype.setContent = function (content) {
30 | this.header.html(content.display);
31 | content.documentation = content.documentation.replace(/(?:\r\n|\r|\n)/g, '
');
32 | this.documentation.html(content.documentation);
33 | };
34 | DocumentationView.prototype.autoPosition = function () {
35 | var editor = atom.workspace.getActiveTextEditor();
36 | var cursor = editor.getCursors()[0];
37 | var cursorTop = cursor.getPixelRect().top - editor.getScrollTop();
38 | var editorHeight = editor.getHeight();
39 | if (editorHeight - cursorTop < 100) {
40 | this.$.removeClass('bottom');
41 | this.$.addClass('top');
42 | }
43 | else {
44 | this.$.removeClass('top');
45 | this.$.addClass('bottom');
46 | }
47 | };
48 | return DocumentationView;
49 | })(view.View);
50 | exports.DocumentationView = DocumentationView;
51 | function attach() {
52 | if (exports.docView)
53 | return;
54 | exports.docView = new DocumentationView({});
55 | $(atom.views.getView(atom.workspace)).append(exports.docView.$);
56 | }
57 | exports.attach = attach;
58 | function testDocumentationView() {
59 | exports.docView.setContent({
60 | display: "this is awesome", documentation: "\n some docs\n over\n many\n many li\n\n lines\n long\n so\n long\n that\n it\n should\n\n start\n to\n scroll\n ", filePath: "some filepath"
61 | });
62 | exports.docView.show();
63 | }
64 | exports.testDocumentationView = testDocumentationView;
65 |
--------------------------------------------------------------------------------
/styles/semantic-view.less:
--------------------------------------------------------------------------------
1 | // From https://github.com/xndcn/symbols-tree-view
2 | @import "ui-variables";
3 | @font-face {
4 | font-family: 'symbol-icons';
5 | src: url('atom://atom-typescript/images/symbol-icons.woff') format('woff');
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | @symbol-class: '\e600';
11 | @symbol-struct: '\e601';
12 | @symbol-macro: '\e602';
13 | @symbol-typedef: '\e603';
14 | @symbol-union: '\e604';
15 | @symbol-interface: '\e605';
16 | @symbol-enum: '\e606';
17 | @symbol-variable: '\e607';
18 | @symbol-function: '\e608';
19 | @symbol-namespace: '\e609';
20 | .symbol-icon(@name) {
21 | font-family: 'symbol-icons';
22 | content: @@name;
23 | }
24 | .atomts-semantic-view {
25 | max-width: 250px;
26 | // needed otherwise the panel takes up all the space and doesn't scroll
27 | max-height: 100%;
28 | overflow-y: auto;
29 | padding: 10px;
30 | .selected {
31 | background: @background-color-highlight;
32 | }
33 |
34 | .node{
35 | cursor: pointer;
36 | }
37 |
38 | .icon-class::before {
39 | .symbol-icon(symbol-class);
40 | }
41 | .icon-struct::before {
42 | .symbol-icon(symbol-struct);
43 | }
44 | .icon-variable::before {
45 | .symbol-icon(symbol-variable);
46 | }
47 |
48 | .icon-field::before {
49 | .symbol-icon(symbol-variable);
50 | }
51 | .icon-member::before {
52 | .symbol-icon(symbol-variable);
53 | }
54 | .icon-interface::before {
55 | .symbol-icon(symbol-interface);
56 | }
57 | .icon-enum::before {
58 | .symbol-icon(symbol-enum);
59 | }
60 | .icon-typedef::before {
61 | .symbol-icon(symbol-typedef);
62 | }
63 | .icon-macro::before {
64 | .symbol-icon(symbol-macro);
65 | }
66 | .icon-union::before {
67 | .symbol-icon(symbol-union);
68 | }
69 |
70 |
71 |
72 | .icon-module::before {
73 | .symbol-icon(symbol-macro);
74 | }
75 |
76 | // variable like
77 | .icon-var::before {
78 | .symbol-icon(symbol-variable);
79 | }
80 | .icon-property::before {
81 | .symbol-icon(symbol-variable);
82 | }
83 | .icon-alias::before {
84 | .symbol-icon(symbol-variable);
85 | }
86 |
87 | // function like
88 | .icon-function::before {
89 | .symbol-icon(symbol-function);
90 | }
91 | .icon-constructor::before {
92 | .symbol-icon(symbol-function);
93 | }
94 | .icon-method::before {
95 | .symbol-icon(symbol-function);
96 | }
97 | .icon-setter::before {
98 | .symbol-icon(symbol-function);
99 | }
100 | .icon-getter::before {
101 | .symbol-icon(symbol-function);
102 | }
103 |
104 | // module like
105 | .icon-namespace::before {
106 | .symbol-icon(symbol-namespace);
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------