1 | # External Editor
|
---|
2 |
|
---|
3 | [![ExternalEditor on Travis CI](https://img.shields.io/travis/mrkmg/node-external-editor.svg?style=flat-square)](https://travis-ci.org/mrkmg/node-external-editor/branches)
|
---|
4 | [![ExternalEditor on NPM](https://img.shields.io/npm/v/external-editor.svg?style=flat-square)](https://www.npmjs.com/package/external-editor)
|
---|
5 | [![ExternalEditor uses the MIT](https://img.shields.io/npm/l/external-editor.svg?style=flat-square)](https://opensource.org/licenses/MIT)
|
---|
6 |
|
---|
7 |
|
---|
8 | A node module to edit a string with a users preferred text editor using $VISUAL or $ENVIRONMENT.
|
---|
9 |
|
---|
10 | Version: 3.1.0
|
---|
11 |
|
---|
12 | As of version 3.0.0, the minimum version of node supported is 4.
|
---|
13 |
|
---|
14 | ## Install
|
---|
15 |
|
---|
16 | `npm install external-editor --save`
|
---|
17 |
|
---|
18 | ## Usage
|
---|
19 |
|
---|
20 | A simple example using the `.edit` convenience method
|
---|
21 |
|
---|
22 | import {edit} from "external-editor";
|
---|
23 | const data = edit('\n\n# Please write your text above');
|
---|
24 | console.log(data);
|
---|
25 |
|
---|
26 | A full featured example
|
---|
27 |
|
---|
28 | import {ExternalEditor, CreateFileError, ReadFileError, RemoveFileError} from "external-editor"
|
---|
29 |
|
---|
30 | try {
|
---|
31 | const editor = new ExternalEditor();
|
---|
32 | const text = editor.run() // the text is also available in editor.text
|
---|
33 |
|
---|
34 | if (editor.last_exit_status !== 0) {
|
---|
35 | console.log("The editor exited with a non-zero code");
|
---|
36 | }
|
---|
37 | } catch (err) {
|
---|
38 | if (err instanceOf CreateFileError) {
|
---|
39 | console.log('Failed to create the temporary file');
|
---|
40 | } else if (err instanceOf ReadFileError) {
|
---|
41 | console.log('Failed to read the temporary file');
|
---|
42 | } else if (err instanceOf LaunchEditorError) {
|
---|
43 | console.log('Failed to launch your editor');
|
---|
44 | } else {
|
---|
45 | throw err;
|
---|
46 | }
|
---|
47 | }
|
---|
48 |
|
---|
49 | // Do things with the text
|
---|
50 |
|
---|
51 | // Eventually call the cleanup to remove the temporary file
|
---|
52 | try {
|
---|
53 | editor.cleanup();
|
---|
54 | } catch (err) {
|
---|
55 | if (err instanceOf RemoveFileError) {
|
---|
56 | console.log('Failed to remove the temporary file');
|
---|
57 | } else {
|
---|
58 | throw err
|
---|
59 | }
|
---|
60 | }
|
---|
61 |
|
---|
62 |
|
---|
63 | #### API
|
---|
64 | **Convenience Methods**
|
---|
65 |
|
---|
66 | - `edit(text, config)`
|
---|
67 | - `text` (string) *Optional* Defaults to empty string
|
---|
68 | - `config` (Config) *Optional* Options for temporary file creation
|
---|
69 | - **Returns** (string) The contents of the file
|
---|
70 | - Could throw `CreateFileError`, `ReadFileError`, or `LaunchEditorError`, or `RemoveFileError`
|
---|
71 | - `editAsync(text, callback, config)`
|
---|
72 | - `text` (string) *Optional* Defaults to empty string
|
---|
73 | - `callback` (function (error, text))
|
---|
74 | - `error` could be of type `CreateFileError`, `ReadFileError`, or `LaunchEditorError`, or `RemoveFileError`
|
---|
75 | - `text`(string) The contents of the file
|
---|
76 | - `config` (Config) *Optional* Options for temporary file creation
|
---|
77 |
|
---|
78 |
|
---|
79 | **Errors**
|
---|
80 |
|
---|
81 | - `CreateFileError` Error thrown if the temporary file could not be created.
|
---|
82 | - `ReadFileError` Error thrown if the temporary file could not be read.
|
---|
83 | - `RemoveFileError` Error thrown if the temporary file could not be removed during cleanup.
|
---|
84 | - `LaunchEditorError` Error thrown if the editor could not be launched.
|
---|
85 |
|
---|
86 | **External Editor Public Methods**
|
---|
87 |
|
---|
88 | - `new ExternalEditor(text, config)`
|
---|
89 | - `text` (string) *Optional* Defaults to empty string
|
---|
90 | - `config` (Config) *Optional* Options for temporary file creation
|
---|
91 | - Could throw `CreateFileError`
|
---|
92 | - `run()` Launches the editor.
|
---|
93 | - **Returns** (string) The contents of the file
|
---|
94 | - Could throw `LaunchEditorError` or `ReadFileError`
|
---|
95 | - `runAsync(callback)` Launches the editor in an async way
|
---|
96 | - `callback` (function (error, text))
|
---|
97 | - `error` could be of type `ReadFileError` or `LaunchEditorError`
|
---|
98 | - `text`(string) The contents of the file
|
---|
99 | - `cleanup()` Removes the temporary file.
|
---|
100 | - Could throw `RemoveFileError`
|
---|
101 |
|
---|
102 | **External Editor Public Properties**
|
---|
103 |
|
---|
104 | - `text` (string) *readonly* The text in the temporary file.
|
---|
105 | - `editor.bin` (string) The editor determined from the environment.
|
---|
106 | - `editor.args` (array) Default arguments for the bin
|
---|
107 | - `tempFile` (string) Path to temporary file. Can be changed, but be careful as the temporary file probably already
|
---|
108 | exists and would need be removed manually.
|
---|
109 | - `lastExitStatus` (number) The last exit code emitted from the editor.
|
---|
110 |
|
---|
111 | **Config Options**
|
---|
112 |
|
---|
113 | - `prefix` (string) *Optional* A prefix for the file name.
|
---|
114 | - `postfix` (string; *Optional* A postfix for the file name. Useful if you want to provide an extension.
|
---|
115 | - `mode` (number) *Optional* Which mode to create the file with. e.g. 644
|
---|
116 | - `template` (string) *Optional* A template for the filename. See [tmp](https://www.npmjs.com/package/tmp).
|
---|
117 | - `dir` (string) *Optional* Which path to store the file.
|
---|
118 |
|
---|
119 | ## Errors
|
---|
120 |
|
---|
121 | All errors have a simple message explaining what went wrong. They all also have an `originalError` property containing
|
---|
122 | the original error thrown for debugging purposes.
|
---|
123 |
|
---|
124 | ## Why Synchronous?
|
---|
125 |
|
---|
126 | Everything is synchronous to make sure the editor has complete control of the stdin and stdout. Testing has shown
|
---|
127 | async launching of the editor can lead to issues when using readline or other packages which try to read from stdin or
|
---|
128 | write to stdout. Seeing as this will be used in an interactive CLI environment, I made the decision to force the package
|
---|
129 | to be synchronous. If you know a reliable way to force all stdin and stdout to be limited only to the child_process,
|
---|
130 | please submit a PR.
|
---|
131 |
|
---|
132 | If async is really needed, you can use `editAsync` or `runAsync`. If you are using readline or have anything else
|
---|
133 | listening to the stdin or you write to stdout, you will most likely have problem, so make sure to remove any other
|
---|
134 | listeners on stdin, stdout, or stderr.
|
---|
135 |
|
---|
136 | ## Demo
|
---|
137 |
|
---|
138 | [![asciicast](https://asciinema.org/a/a1qh9lypbe65mj0ivfuoslz2s.png)](https://asciinema.org/a/a1qh9lypbe65mj0ivfuoslz2s)
|
---|
139 |
|
---|
140 | ## Breaking Changes from v2 to v3
|
---|
141 |
|
---|
142 | - NodeJS 0.12 support dropped.
|
---|
143 | - Switched to named imports.
|
---|
144 | - All "snake_cased" variables and properties are now "camelCased".
|
---|
145 | - `ExternalEditor.temp_file` is now `ExternalEditor.tempFile`.
|
---|
146 | - `ExternalEditor.last_exit_status` is now `ExternalEditor.lastExitStatus`.
|
---|
147 | - `Error.original_error` is now `Error.originalError`.
|
---|
148 |
|
---|
149 | ## License
|
---|
150 |
|
---|
151 | The MIT License (MIT)
|
---|
152 |
|
---|
153 | Copyright (c) 2016-2018 Kevin Gravier
|
---|
154 |
|
---|
155 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
156 | of this software and associated documentation files (the "Software"), to deal
|
---|
157 | in the Software without restriction, including without limitation the rights
|
---|
158 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
159 | copies of the Software, and to permit persons to whom the Software is
|
---|
160 | furnished to do so, subject to the following conditions:
|
---|
161 |
|
---|
162 | The above copyright notice and this permission notice shall be included in all
|
---|
163 | copies or substantial portions of the Software.
|
---|
164 |
|
---|
165 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
166 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
167 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
168 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
169 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
170 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
---|
171 | SOFTWARE.
|
---|