[6a3a178] | 1 | "use strict";
|
---|
| 2 | /***
|
---|
| 3 | * Node External Editor
|
---|
| 4 | *
|
---|
| 5 | * Kevin Gravier <kevin@mrkmg.com>
|
---|
| 6 | * MIT 2019
|
---|
| 7 | */
|
---|
| 8 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
| 9 | var chardet_1 = require("chardet");
|
---|
| 10 | var child_process_1 = require("child_process");
|
---|
| 11 | var fs_1 = require("fs");
|
---|
| 12 | var iconv_lite_1 = require("iconv-lite");
|
---|
| 13 | var tmp_1 = require("tmp");
|
---|
| 14 | var CreateFileError_1 = require("./errors/CreateFileError");
|
---|
| 15 | exports.CreateFileError = CreateFileError_1.CreateFileError;
|
---|
| 16 | var LaunchEditorError_1 = require("./errors/LaunchEditorError");
|
---|
| 17 | exports.LaunchEditorError = LaunchEditorError_1.LaunchEditorError;
|
---|
| 18 | var ReadFileError_1 = require("./errors/ReadFileError");
|
---|
| 19 | exports.ReadFileError = ReadFileError_1.ReadFileError;
|
---|
| 20 | var RemoveFileError_1 = require("./errors/RemoveFileError");
|
---|
| 21 | exports.RemoveFileError = RemoveFileError_1.RemoveFileError;
|
---|
| 22 | function edit(text, fileOptions) {
|
---|
| 23 | if (text === void 0) { text = ""; }
|
---|
| 24 | var editor = new ExternalEditor(text, fileOptions);
|
---|
| 25 | editor.run();
|
---|
| 26 | editor.cleanup();
|
---|
| 27 | return editor.text;
|
---|
| 28 | }
|
---|
| 29 | exports.edit = edit;
|
---|
| 30 | function editAsync(text, callback, fileOptions) {
|
---|
| 31 | if (text === void 0) { text = ""; }
|
---|
| 32 | var editor = new ExternalEditor(text, fileOptions);
|
---|
| 33 | editor.runAsync(function (err, result) {
|
---|
| 34 | if (err) {
|
---|
| 35 | setImmediate(callback, err, null);
|
---|
| 36 | }
|
---|
| 37 | else {
|
---|
| 38 | try {
|
---|
| 39 | editor.cleanup();
|
---|
| 40 | setImmediate(callback, null, result);
|
---|
| 41 | }
|
---|
| 42 | catch (cleanupError) {
|
---|
| 43 | setImmediate(callback, cleanupError, null);
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
| 46 | });
|
---|
| 47 | }
|
---|
| 48 | exports.editAsync = editAsync;
|
---|
| 49 | var ExternalEditor = /** @class */ (function () {
|
---|
| 50 | function ExternalEditor(text, fileOptions) {
|
---|
| 51 | if (text === void 0) { text = ""; }
|
---|
| 52 | this.text = "";
|
---|
| 53 | this.fileOptions = {};
|
---|
| 54 | this.text = text;
|
---|
| 55 | if (fileOptions) {
|
---|
| 56 | this.fileOptions = fileOptions;
|
---|
| 57 | }
|
---|
| 58 | this.determineEditor();
|
---|
| 59 | this.createTemporaryFile();
|
---|
| 60 | }
|
---|
| 61 | ExternalEditor.splitStringBySpace = function (str) {
|
---|
| 62 | var pieces = [];
|
---|
| 63 | var currentString = "";
|
---|
| 64 | for (var strIndex = 0; strIndex < str.length; strIndex++) {
|
---|
| 65 | var currentLetter = str[strIndex];
|
---|
| 66 | if (strIndex > 0 && currentLetter === " " && str[strIndex - 1] !== "\\" && currentString.length > 0) {
|
---|
| 67 | pieces.push(currentString);
|
---|
| 68 | currentString = "";
|
---|
| 69 | }
|
---|
| 70 | else {
|
---|
| 71 | currentString += currentLetter;
|
---|
| 72 | }
|
---|
| 73 | }
|
---|
| 74 | if (currentString.length > 0) {
|
---|
| 75 | pieces.push(currentString);
|
---|
| 76 | }
|
---|
| 77 | return pieces;
|
---|
| 78 | };
|
---|
| 79 | Object.defineProperty(ExternalEditor.prototype, "temp_file", {
|
---|
| 80 | get: function () {
|
---|
| 81 | console.log("DEPRECATED: temp_file. Use tempFile moving forward.");
|
---|
| 82 | return this.tempFile;
|
---|
| 83 | },
|
---|
| 84 | enumerable: true,
|
---|
| 85 | configurable: true
|
---|
| 86 | });
|
---|
| 87 | Object.defineProperty(ExternalEditor.prototype, "last_exit_status", {
|
---|
| 88 | get: function () {
|
---|
| 89 | console.log("DEPRECATED: last_exit_status. Use lastExitStatus moving forward.");
|
---|
| 90 | return this.lastExitStatus;
|
---|
| 91 | },
|
---|
| 92 | enumerable: true,
|
---|
| 93 | configurable: true
|
---|
| 94 | });
|
---|
| 95 | ExternalEditor.prototype.run = function () {
|
---|
| 96 | this.launchEditor();
|
---|
| 97 | this.readTemporaryFile();
|
---|
| 98 | return this.text;
|
---|
| 99 | };
|
---|
| 100 | ExternalEditor.prototype.runAsync = function (callback) {
|
---|
| 101 | var _this = this;
|
---|
| 102 | try {
|
---|
| 103 | this.launchEditorAsync(function () {
|
---|
| 104 | try {
|
---|
| 105 | _this.readTemporaryFile();
|
---|
| 106 | setImmediate(callback, null, _this.text);
|
---|
| 107 | }
|
---|
| 108 | catch (readError) {
|
---|
| 109 | setImmediate(callback, readError, null);
|
---|
| 110 | }
|
---|
| 111 | });
|
---|
| 112 | }
|
---|
| 113 | catch (launchError) {
|
---|
| 114 | setImmediate(callback, launchError, null);
|
---|
| 115 | }
|
---|
| 116 | };
|
---|
| 117 | ExternalEditor.prototype.cleanup = function () {
|
---|
| 118 | this.removeTemporaryFile();
|
---|
| 119 | };
|
---|
| 120 | ExternalEditor.prototype.determineEditor = function () {
|
---|
| 121 | var editor = process.env.VISUAL ? process.env.VISUAL :
|
---|
| 122 | process.env.EDITOR ? process.env.EDITOR :
|
---|
| 123 | /^win/.test(process.platform) ? "notepad" :
|
---|
| 124 | "vim";
|
---|
| 125 | var editorOpts = ExternalEditor.splitStringBySpace(editor).map(function (piece) { return piece.replace("\\ ", " "); });
|
---|
| 126 | var bin = editorOpts.shift();
|
---|
| 127 | this.editor = { args: editorOpts, bin: bin };
|
---|
| 128 | };
|
---|
| 129 | ExternalEditor.prototype.createTemporaryFile = function () {
|
---|
| 130 | try {
|
---|
| 131 | this.tempFile = tmp_1.tmpNameSync(this.fileOptions);
|
---|
| 132 | var opt = { encoding: "utf8" };
|
---|
| 133 | if (this.fileOptions.hasOwnProperty("mode")) {
|
---|
| 134 | opt.mode = this.fileOptions.mode;
|
---|
| 135 | }
|
---|
| 136 | fs_1.writeFileSync(this.tempFile, this.text, opt);
|
---|
| 137 | }
|
---|
| 138 | catch (createFileError) {
|
---|
| 139 | throw new CreateFileError_1.CreateFileError(createFileError);
|
---|
| 140 | }
|
---|
| 141 | };
|
---|
| 142 | ExternalEditor.prototype.readTemporaryFile = function () {
|
---|
| 143 | try {
|
---|
| 144 | var tempFileBuffer = fs_1.readFileSync(this.tempFile);
|
---|
| 145 | if (tempFileBuffer.length === 0) {
|
---|
| 146 | this.text = "";
|
---|
| 147 | }
|
---|
| 148 | else {
|
---|
| 149 | var encoding = chardet_1.detect(tempFileBuffer).toString();
|
---|
| 150 | if (!iconv_lite_1.encodingExists(encoding)) {
|
---|
| 151 | // Probably a bad idea, but will at least prevent crashing
|
---|
| 152 | encoding = "utf8";
|
---|
| 153 | }
|
---|
| 154 | this.text = iconv_lite_1.decode(tempFileBuffer, encoding);
|
---|
| 155 | }
|
---|
| 156 | }
|
---|
| 157 | catch (readFileError) {
|
---|
| 158 | throw new ReadFileError_1.ReadFileError(readFileError);
|
---|
| 159 | }
|
---|
| 160 | };
|
---|
| 161 | ExternalEditor.prototype.removeTemporaryFile = function () {
|
---|
| 162 | try {
|
---|
| 163 | fs_1.unlinkSync(this.tempFile);
|
---|
| 164 | }
|
---|
| 165 | catch (removeFileError) {
|
---|
| 166 | throw new RemoveFileError_1.RemoveFileError(removeFileError);
|
---|
| 167 | }
|
---|
| 168 | };
|
---|
| 169 | ExternalEditor.prototype.launchEditor = function () {
|
---|
| 170 | try {
|
---|
| 171 | var editorProcess = child_process_1.spawnSync(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
|
---|
| 172 | this.lastExitStatus = editorProcess.status;
|
---|
| 173 | }
|
---|
| 174 | catch (launchError) {
|
---|
| 175 | throw new LaunchEditorError_1.LaunchEditorError(launchError);
|
---|
| 176 | }
|
---|
| 177 | };
|
---|
| 178 | ExternalEditor.prototype.launchEditorAsync = function (callback) {
|
---|
| 179 | var _this = this;
|
---|
| 180 | try {
|
---|
| 181 | var editorProcess = child_process_1.spawn(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
|
---|
| 182 | editorProcess.on("exit", function (code) {
|
---|
| 183 | _this.lastExitStatus = code;
|
---|
| 184 | setImmediate(callback);
|
---|
| 185 | });
|
---|
| 186 | }
|
---|
| 187 | catch (launchError) {
|
---|
| 188 | throw new LaunchEditorError_1.LaunchEditorError(launchError);
|
---|
| 189 | }
|
---|
| 190 | };
|
---|
| 191 | return ExternalEditor;
|
---|
| 192 | }());
|
---|
| 193 | exports.ExternalEditor = ExternalEditor;
|
---|