index.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Generated by CoffeeScript 1.12.7
  2. /*
  3. ExternalEditor
  4. Kevin Gravier <kevin@mrkmg.com>
  5. MIT
  6. */
  7. (function() {
  8. var ChatDet, CreateFileError, ExternalEditor, FS, IConvLite, LaunchEditorError, ReadFileError, RemoveFileError, Spawn, SpawnSync, Temp,
  9. bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
  10. FS = require('fs');
  11. Temp = require('tmp');
  12. SpawnSync = require('child_process').spawnSync;
  13. Spawn = require('child_process').spawn;
  14. IConvLite = require('iconv-lite');
  15. ChatDet = require('chardet');
  16. CreateFileError = require('./errors/CreateFileError');
  17. ReadFileError = require('./errors/ReadFileError');
  18. RemoveFileError = require('./errors/RemoveFileError');
  19. LaunchEditorError = require('./errors/LaunchEditorError');
  20. ExternalEditor = (function() {
  21. ExternalEditor.edit = function(text) {
  22. var editor;
  23. if (text == null) {
  24. text = '';
  25. }
  26. editor = new ExternalEditor(text);
  27. editor.run();
  28. editor.cleanup();
  29. return editor.text;
  30. };
  31. ExternalEditor.editAsync = function(text, callback) {
  32. var editor;
  33. if (text == null) {
  34. text = '';
  35. }
  36. editor = new ExternalEditor(text);
  37. return editor.runAsync(function(error_run, text) {
  38. var error_cleanup;
  39. if (!error_run) {
  40. try {
  41. editor.cleanup();
  42. if (typeof callback === 'function') {
  43. return setImmediate(callback, null, text);
  44. }
  45. } catch (error) {
  46. error_cleanup = error;
  47. if (typeof callback === 'function') {
  48. return setImmediate(callback, error_cleanup, null);
  49. }
  50. }
  51. } else {
  52. if (typeof callback === 'function') {
  53. return setImmediate(callback, error_run, null);
  54. }
  55. }
  56. });
  57. };
  58. ExternalEditor.CreateFileError = CreateFileError;
  59. ExternalEditor.ReadFileError = ReadFileError;
  60. ExternalEditor.RemoveFileError = RemoveFileError;
  61. ExternalEditor.LaunchEditorError = LaunchEditorError;
  62. ExternalEditor.prototype.text = '';
  63. ExternalEditor.prototype.temp_file = void 0;
  64. ExternalEditor.prototype.editor = {
  65. bin: void 0,
  66. args: []
  67. };
  68. ExternalEditor.prototype.last_exit_status = void 0;
  69. function ExternalEditor(text1) {
  70. this.text = text1 != null ? text1 : '';
  71. this.launchEditorAsync = bind(this.launchEditorAsync, this);
  72. this.launchEditor = bind(this.launchEditor, this);
  73. this.removeTemporaryFile = bind(this.removeTemporaryFile, this);
  74. this.readTemporaryFile = bind(this.readTemporaryFile, this);
  75. this.createTemporaryFile = bind(this.createTemporaryFile, this);
  76. this.determineEditor = bind(this.determineEditor, this);
  77. this.cleanup = bind(this.cleanup, this);
  78. this.runAsync = bind(this.runAsync, this);
  79. this.run = bind(this.run, this);
  80. this.determineEditor();
  81. this.createTemporaryFile();
  82. }
  83. ExternalEditor.prototype.run = function() {
  84. this.launchEditor();
  85. return this.readTemporaryFile();
  86. };
  87. ExternalEditor.prototype.runAsync = function(callback) {
  88. var error_launch;
  89. try {
  90. return this.launchEditorAsync((function(_this) {
  91. return function() {
  92. var error_read;
  93. try {
  94. _this.readTemporaryFile();
  95. if (typeof callback === 'function') {
  96. return setImmediate(callback, null, _this.text);
  97. }
  98. } catch (error) {
  99. error_read = error;
  100. if (typeof callback === 'function') {
  101. return setImmediate(callback, error_read, null);
  102. }
  103. }
  104. };
  105. })(this));
  106. } catch (error) {
  107. error_launch = error;
  108. if (typeof callback === 'function') {
  109. return setImmediate(callback, error_launch, null);
  110. }
  111. }
  112. };
  113. ExternalEditor.prototype.cleanup = function() {
  114. return this.removeTemporaryFile();
  115. };
  116. ExternalEditor.prototype.determineEditor = function() {
  117. var args, ed, editor;
  118. ed = /^win/.test(process.platform) ? 'notepad' : 'vim';
  119. editor = process.env.VISUAL || process.env.EDITOR || ed;
  120. args = editor.split(/\s+/);
  121. this.editor.bin = args.shift();
  122. return this.editor.args = args;
  123. };
  124. ExternalEditor.prototype.createTemporaryFile = function() {
  125. var e;
  126. try {
  127. this.temp_file = Temp.tmpNameSync({});
  128. return FS.writeFileSync(this.temp_file, this.text, {
  129. encoding: 'utf8'
  130. });
  131. } catch (error) {
  132. e = error;
  133. throw new CreateFileError(e);
  134. }
  135. };
  136. ExternalEditor.prototype.readTemporaryFile = function() {
  137. var buffer, e, encoding;
  138. try {
  139. buffer = FS.readFileSync(this.temp_file);
  140. if (!buffer.length) {
  141. return this.text = '';
  142. }
  143. encoding = ChatDet.detect(buffer);
  144. return this.text = IConvLite.decode(buffer, encoding);
  145. } catch (error) {
  146. e = error;
  147. throw new ReadFileError(e);
  148. }
  149. };
  150. ExternalEditor.prototype.removeTemporaryFile = function() {
  151. var e;
  152. try {
  153. return FS.unlinkSync(this.temp_file);
  154. } catch (error) {
  155. e = error;
  156. throw new RemoveFileError(e);
  157. }
  158. };
  159. ExternalEditor.prototype.launchEditor = function() {
  160. var e, run;
  161. try {
  162. run = SpawnSync(this.editor.bin, this.editor.args.concat([this.temp_file]), {
  163. stdio: 'inherit'
  164. });
  165. return this.last_exit_status = run.status;
  166. } catch (error) {
  167. e = error;
  168. throw new LaunchEditorError(e);
  169. }
  170. };
  171. ExternalEditor.prototype.launchEditorAsync = function(callback) {
  172. var child_process, e;
  173. try {
  174. child_process = Spawn(this.editor.bin, this.editor.args.concat([this.temp_file]), {
  175. stdio: 'inherit'
  176. });
  177. return child_process.on('exit', (function(_this) {
  178. return function(code) {
  179. _this.last_exit_status = code;
  180. if (typeof callback === 'function') {
  181. return callback();
  182. }
  183. };
  184. })(this));
  185. } catch (error) {
  186. e = error;
  187. throw new LaunchEditorError(e);
  188. }
  189. };
  190. return ExternalEditor;
  191. })();
  192. module.exports = ExternalEditor;
  193. }).call(this);