UNPKG

alm

Version:

The best IDE for TypeScript

255 lines (254 loc) 12.6 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var ReactDOM = require("react-dom"); var csx = require("../../base/csx"); var ui_1 = require("../../ui"); var ui = require("../../ui"); var utils = require("../../../common/utils"); var styles = require("../../styles/styles"); var state = require("../../state/state"); var uix = require("../../uix"); var commands = require("../../commands/commands"); var Modal = require("react-modal"); var socketClient_1 = require("../../../socket/socketClient"); var styles_1 = require("../../styles/styles"); var codeEditor_1 = require("../editor/codeEditor"); var typestyle = require("typestyle"); var inputClassName = typestyle.style(styles.modal.inputStyleBase); var validationErrorStyle = { color: 'red', fontFamily: 'monospace', fontSize: '1.2rem', padding: '5px', }; var summaryStyle = { padding: '5px', backgroundColor: '#222', color: '#CCC', fontSize: '.8rem', }; var RenameVariable = /** @class */ (function (_super) { __extends(RenameVariable, _super); function RenameVariable(props) { var _this = _super.call(this, props) || this; _this.onChangeFilter = function (e) { var newText = ReactDOM.findDOMNode(_this.refs.mainInput).value; if (newText.replace(/\s/g, '') !== newText.trim()) { _this.setState({ invalidMessage: 'The new variable must not contain a space' }); } else if (!newText.trim()) { _this.setState({ invalidMessage: 'Please provide a new name or press esc to abort rename' }); } else { _this.setState({ invalidMessage: '' }); } }; _this.onChangeSelected = function (event) { var keyStates = ui.getKeyStates(event); if (keyStates.up || keyStates.tabPrevious) { event.preventDefault(); var selectedIndex = utils.rangeLimited({ num: _this.state.selectedIndex - 1, min: 0, max: _this.state.flattened.length - 1, loopAround: true }); _this.setState({ selectedIndex: selectedIndex }); } if (keyStates.down || keyStates.tabNext) { event.preventDefault(); var selectedIndex = utils.rangeLimited({ num: _this.state.selectedIndex + 1, min: 0, max: _this.state.flattened.length - 1, loopAround: true }); _this.setState({ selectedIndex: selectedIndex }); } if (keyStates.enter) { event.preventDefault(); var newText_1 = ReactDOM.findDOMNode(_this.refs.mainInput).value.trim(); var refactorings_1 = {}; Object.keys(_this.props.info.locations).map(function (filePath) { refactorings_1[filePath] = []; var forPath = refactorings_1[filePath]; _this.props.info.locations[filePath].forEach(function (loc) { var refactoring = { filePath: filePath, span: loc, newText: newText_1 }; forPath.push(refactoring); }); }); uix.API.applyRefactorings(refactorings_1); setTimeout(function () { _this.props.unmount(); }); } }; _this.selectAndRefocus = function (index) { _this.setState({ selectedIndex: index }); _this.focus(); }; _this.focus = function () { var input = ReactDOM.findDOMNode(_this.refs.mainInput); input.focus(); }; var flattended = utils.selectMany(Object.keys(props.info.locations).map(function (filePath) { var refs = props.info.locations[filePath].slice().reverse(); return refs.map(function (preview, i) { return { filePath: filePath, preview: preview, indexForFilePath: i + 1, totalForFilePath: refs.length, }; }); })); _this.state = { selectedIndex: 0, flattened: flattended }; return _this; } RenameVariable.prototype.componentDidMount = function () { var _this = this; this.disposible.add(commands.esc.on(function () { _this.props.unmount(); })); setTimeout(function () { _this.focus(); var input = ReactDOM.findDOMNode(_this.refs.mainInput); var len = input.value.length; input.setSelectionRange(0, len); }); }; RenameVariable.prototype.componentDidUpdate = function () { var _this = this; setTimeout(function () { var selected = ReactDOM.findDOMNode(_this.refs.selectedTabTitle); if (selected) { selected.scrollIntoViewIfNeeded(false); } }); }; RenameVariable.prototype.render = function () { var _this = this; var selectedPreview = this.state.flattened[this.state.selectedIndex]; var filePathsRendered = this.state.flattened.map(function (item, i) { var selected = i == _this.state.selectedIndex; var active = selected ? styles.tabHeaderActive : {}; var ref = selected && "selectedTabTitle"; return (React.createElement("div", { ref: ref, key: item.filePath + i, style: csx.extend(styles.tabHeader, active, { overflow: 'hidden' }), onClick: function () { return _this.selectAndRefocus(i); } }, React.createElement("div", { title: item.filePath, style: { overflow: 'hidden', textOverflow: 'ellipsis' } }, utils.getFileName(item.filePath), " (", item.indexForFilePath, " of ", item.totalForFilePath, ")"))); }); var previewRendered = React.createElement(codeEditor_1.CodeEditor, { key: selectedPreview.filePath, filePath: selectedPreview.filePath, readOnly: true, preview: selectedPreview.preview }); return (React.createElement(Modal, { isOpen: true, onRequestClose: this.props.unmount }, React.createElement("div", { style: csx.extend(csx.vertical, csx.flex) }, React.createElement("div", { style: csx.extend(csx.horizontal, csx.content) }, React.createElement("h4", null, "Rename"), React.createElement("div", { style: csx.flex }), React.createElement("div", { style: { fontSize: '0.9rem', color: 'grey' } }, React.createElement("code", { style: styles_1.modal.keyStrokeStyle }, "Esc"), " to exit ", React.createElement("code", { style: styles_1.modal.keyStrokeStyle }, "Enter"), " to select", ' ', React.createElement("code", { style: styles_1.modal.keyStrokeStyle }, "Up / Down"), " to see usages")), React.createElement("div", { style: csx.extend(styles.padded1TopBottom, csx.vertical, csx.content) }, React.createElement("input", { defaultValue: this.props.info.displayName, className: inputClassName, type: "text", ref: "mainInput", placeholder: "Filter", onChange: this.onChangeFilter, onKeyDown: this.onChangeSelected })), this.state.invalidMessage && React.createElement("div", { style: csx.extend(csx.content, validationErrorStyle) }, this.state.invalidMessage), React.createElement("div", { style: csx.extend(csx.content, summaryStyle) }, this.state.flattened.length, " usages, ", this.props.alreadyOpenFilePaths.length, " files open, ", this.props.currentlyClosedFilePaths.length, " files closed"), React.createElement("div", { style: csx.extend(csx.horizontal, csx.flex, { overflow: 'hidden' }) }, React.createElement("div", { style: { width: '200px', overflow: 'auto' } }, filePathsRendered), React.createElement("div", { style: csx.extend(csx.flex, csx.flexRoot, styles.modal.previewContainerStyle) }, previewRendered))))); }; return RenameVariable; }(ui_1.BaseComponent)); exports.RenameVariable = RenameVariable; var monacoUtils = require("../monacoUtils"); var CommonEditorRegistry = monaco.CommonEditorRegistry; var EditorAction = monaco.EditorAction; var KeyCode = monaco.KeyCode; var EditorContextKeys = monaco.EditorContextKeys; var RenameVariableAction = /** @class */ (function (_super) { __extends(RenameVariableAction, _super); function RenameVariableAction() { return _super.call(this, { id: 'editor.action.renameVariable', label: 'TypeScript: Rename Variable', alias: 'TypeScript: Rename Variable', precondition: EditorContextKeys.Writable, kbOpts: { kbExpr: EditorContextKeys.TextFocus, primary: KeyCode.F2 } }) || this; } RenameVariableAction.prototype.run = function (accessor, editor) { var filePath = editor.filePath; if (!state.inActiveProjectFilePath(filePath)) { ui.notifyInfoNormalDisappear('The current file is no in the active project'); return; } var position = monacoUtils.getCurrentPosition(editor); socketClient_1.server.getRenameInfo({ filePath: filePath, position: position }).then(function (res) { if (!res.canRename) { ui.notifyInfoNormalDisappear("Rename not available at cursor location"); } else { var filePaths = Object.keys(res.locations); // if there is only a single file path and that is the current and there aren't that many usages // we do the rename inline if (filePaths.length == 1 && filePaths[0] == filePath && res.locations[filePath].length < 5) { selectName(editor, res.locations[filePath]); } else { var _a = uix.API.getClosedVsOpenFilePaths(filePaths), alreadyOpenFilePaths = _a.alreadyOpenFilePaths, currentlyClosedFilePaths = _a.currentlyClosedFilePaths; var _b = ui.getUnmountableNode(), node = _b.node, unmount = _b.unmount; ReactDOM.render(React.createElement(RenameVariable, { info: res, alreadyOpenFilePaths: alreadyOpenFilePaths, currentlyClosedFilePaths: currentlyClosedFilePaths, unmount: unmount }), node); } } }); }; return RenameVariableAction; }(EditorAction)); CommonEditorRegistry.registerEditorAction(new RenameVariableAction()); /** Selects the locations keeping the current one as the first (to allow easy escape back to current cursor) */ function selectName(editor, locations) { var ranges = []; var curPos = editor.getSelection(); for (var i = 0; i < locations.length; i++) { var ref = locations[i]; var from = editor.getModel().getPositionAt(ref.start); var to = editor.getModel().getPositionAt(ref.start + ref.length); var range = new monaco.Range(from.lineNumber, from.column, to.lineNumber, to.column); var selection = { selectionStartLineNumber: from.lineNumber, selectionStartColumn: from.column, positionLineNumber: to.lineNumber, positionColumn: to.column }; if (!monaco.Range.containsRange(range, curPos)) ranges.push(selection); else ranges.unshift(selection); } editor.setSelections(ranges); }