A JavaScript development environment for Emacs https://indium.readthedocs.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

102 lines
3.6 KiB

  1. ;;; indium-nodejs.el --- NodeJS support for indium -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2016-2018 Nicolas Petton
  3. ;; Author: Nicolas Petton <nicolas@petton.fr>
  4. ;; Keywords: tools, javascript
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; Handle indium connections to a NodeJS process using the v8 backend.
  17. ;;
  18. ;; Important note: For this package to work, NodeJS version 7.0 (or any newer
  19. ;; version) is required.
  20. ;;; Code:
  21. (require 'url)
  22. (require 'url-parse)
  23. (require 'json)
  24. (require 'map)
  25. (require 'seq)
  26. (require 'subr-x)
  27. (declare-function indium-client-connect "indium-client.el")
  28. (defun indium-launch-nodejs (conf)
  29. "Start a NodeJS process.
  30. Execute the command specified in CONF, adding the `--inspect'
  31. flag. When the process is ready, open an Indium connection on
  32. it.
  33. If the configuration setting `inspect-brk' is non-nil, break the
  34. execution at the first statement."
  35. (let-alist conf
  36. (unless .program
  37. (user-error "No NodeJS program specified in the .indium.json file"))
  38. (let* ((default-directory .resolvedRoot)
  39. (filter (indium-nodejs--process-filter-function conf))
  40. (command-with-flags (indium-nodejs--command-with-flags
  41. .program
  42. .args
  43. .inspect-brk
  44. .port))
  45. (process (make-process :name "indium-nodejs-process"
  46. :buffer "*node process*"
  47. :filter filter
  48. :command (list shell-file-name
  49. shell-command-switch
  50. command-with-flags))))
  51. (message "Running node command \"%s\"" command-with-flags)
  52. (switch-to-buffer (process-buffer process)))))
  53. (defun indium-nodejs--command-with-flags (program args inspect-brk &optional port)
  54. "Return a command string with flags to start the V8 inspector.
  55. PROGRAM is the executable to run, with ARGS being the passed to the program.
  56. If INSPECT-BRK is nil, use the `--inspect', use the
  57. `--inspect-brk' flag otherwise.
  58. If PORT is non-nil, start the debugging process on that port,
  59. otherwise use Node's default port (9229)."
  60. (let ((inspect-flag (if (eq inspect-brk t) " --inspect-brk" " --inspect"))
  61. (inspect-port-flag (if port (format " --inspect-port=%s" port) "")))
  62. (format "%s%s%s %s" program inspect-flag inspect-port-flag args)))
  63. (defun indium-nodejs--process-filter-function (conf)
  64. "Return a process filter function for CONF.
  65. The function detects the socket URL to connect to from the
  66. process output."
  67. (let ((connected))
  68. (lambda (process output)
  69. ;; Append output to the process buffer
  70. (with-current-buffer (process-buffer process)
  71. (goto-char (point-max))
  72. (insert output))
  73. (when (and (not connected)
  74. (string-match-p "Debugger listening on" output))
  75. ;; Node will keep outputting the "Debugger listening on" message after
  76. ;; each deconnection, so only try to connect one.
  77. (setq connected t)
  78. (let-alist conf
  79. (indium-client-connect (file-name-directory .projectFile) .name))))))
  80. (provide 'indium-nodejs)
  81. ;;; indium-nodejs.el ends here