|
| 1 | +;;; typescript-comint.el --- Run a TypeScript interpreter in comint -*- lexical-binding: t; -*- |
| 2 | + |
| 3 | +;; Copyright (C) 2008 Paul Huff |
| 4 | +;; Copyright (C) 2015 Stefano Mazzucco |
| 5 | +;; Copyright (C) 2016 Jostein Kjonigsen |
| 6 | +;; Copyright (C) 2025 Kang Tu |
| 7 | +;; |
| 8 | +;; Author: Paul Huff <paul.huff@gmail.com> |
| 9 | +;; Maintainer: TypeScript.el maintainers |
| 10 | +;; URL: http://github.com/ananthakumaran/typescript.el |
| 11 | +;; Keywords: typescript languages processes |
| 12 | +;; Package-Requires: ((emacs "24.3")) |
| 13 | +;; Version: 0.5 |
| 14 | +;; |
| 15 | +;; This file is not part of GNU Emacs. |
| 16 | +;; |
| 17 | +;; This file is derived from the standalone ts-comint.el by |
| 18 | +;; Paul Huff, Stefano Mazzucco, and Jostein Kjonigsen. |
| 19 | +;; The TypeScript.el maintainers preserved their original work and |
| 20 | +;; integrated it here to provide an optional TypeScript REPL. |
| 21 | +;; |
| 22 | +;; This program is free software: you can redistribute it and/or modify |
| 23 | +;; it under the terms of the GNU General Public License as published by |
| 24 | +;; the Free Software Foundation, either version 3 of the License, or |
| 25 | +;; (at your option) any later version. |
| 26 | +;; |
| 27 | +;; This program is distributed in the hope that it will be useful, |
| 28 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 29 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 30 | +;; GNU General Public License for more details. |
| 31 | +;; |
| 32 | +;; You should have received a copy of the GNU General Public License |
| 33 | +;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 34 | + |
| 35 | +;;; Commentary: |
| 36 | + |
| 37 | +;; Run a TypeScript interpreter in a comint buffer and provide helpers |
| 38 | +;; for sending code from `typescript-mode'. Usage: |
| 39 | +;; |
| 40 | +;; (autoload 'typescript-run-repl "typescript-comint") |
| 41 | +;; (autoload 'typescript-send-region "typescript-comint") |
| 42 | +;; |
| 43 | +;; M-x typescript-run-repl |
| 44 | +;; |
| 45 | +;; The functions keep the `ts-*' aliases for compatibility with the |
| 46 | +;; original ts-comint.el interface. |
| 47 | + |
| 48 | +;;; Code: |
| 49 | + |
| 50 | +(require 'ansi-color) |
| 51 | +(require 'comint) |
| 52 | + |
| 53 | +(defgroup typescript-comint nil |
| 54 | + "Run a TypeScript process in a buffer." |
| 55 | + :group 'typescript) |
| 56 | + |
| 57 | +(defcustom typescript-comint-program-command "tsun" |
| 58 | + "Program name of the TypeScript interpreter." |
| 59 | + :type 'string |
| 60 | + :group 'typescript-comint) |
| 61 | + |
| 62 | +(defcustom typescript-comint-program-arguments nil |
| 63 | + "List of command line arguments to pass to the TypeScript interpreter." |
| 64 | + :type '(repeat string) |
| 65 | + :group 'typescript-comint) |
| 66 | + |
| 67 | +(defcustom typescript-comint-mode-hook nil |
| 68 | + "Hook for customizing `typescript-comint-mode'." |
| 69 | + :type 'hook |
| 70 | + :group 'typescript-comint) |
| 71 | + |
| 72 | +(defcustom typescript-comint-mode-ansi-color t |
| 73 | + "Whether to enable ANSI colors in the inferior TypeScript buffer." |
| 74 | + :type 'boolean |
| 75 | + :group 'typescript-comint) |
| 76 | + |
| 77 | +(defvar typescript-comint-buffer nil |
| 78 | + "Name of the inferior TypeScript buffer.") |
| 79 | + |
| 80 | +(defvaralias 'ts-comint-program-command 'typescript-comint-program-command) |
| 81 | +(defvaralias 'ts-comint-program-arguments 'typescript-comint-program-arguments) |
| 82 | +(defvaralias 'ts-comint-mode-hook 'typescript-comint-mode-hook) |
| 83 | +(defvaralias 'ts-comint-mode-ansi-color 'typescript-comint-mode-ansi-color) |
| 84 | +(defvaralias 'ts-comint-buffer 'typescript-comint-buffer) |
| 85 | + |
| 86 | +(defun typescript-comint--get-load-file-cmd (filename) |
| 87 | + "Generate a TypeScript import statement for FILENAME." |
| 88 | + (concat "import * as " |
| 89 | + (file-name-base filename) |
| 90 | + " from \"" |
| 91 | + (file-name-base filename) |
| 92 | + "\"\n")) |
| 93 | + |
| 94 | +;;;###autoload |
| 95 | +(defun typescript-run-repl (&optional cmd dont-switch-p) |
| 96 | + "Run an inferior TypeScript process in buffer `*Typescript*'. |
| 97 | +If a process already exists, reuse it. With prefix CMD, prompt |
| 98 | +for the full command line instead of `typescript-comint-program-command'. |
| 99 | +When DONT-SWITCH-P is non-nil, do not switch to the process buffer." |
| 100 | + (interactive |
| 101 | + (list |
| 102 | + (when current-prefix-arg |
| 103 | + (read-string |
| 104 | + "Run TypeScript: " |
| 105 | + (mapconcat |
| 106 | + #'identity |
| 107 | + (cons typescript-comint-program-command |
| 108 | + typescript-comint-program-arguments) |
| 109 | + " "))))) |
| 110 | + |
| 111 | + (when cmd |
| 112 | + (setq typescript-comint-program-arguments (split-string cmd)) |
| 113 | + (setq typescript-comint-program-command |
| 114 | + (pop typescript-comint-program-arguments))) |
| 115 | + |
| 116 | + (unless (comint-check-proc "*Typescript*") |
| 117 | + (with-current-buffer |
| 118 | + (apply #'make-comint |
| 119 | + "Typescript" |
| 120 | + typescript-comint-program-command |
| 121 | + nil typescript-comint-program-arguments) |
| 122 | + (typescript-comint-mode))) |
| 123 | + |
| 124 | + (setq typescript-comint-buffer "*Typescript*") |
| 125 | + |
| 126 | + (unless dont-switch-p |
| 127 | + (pop-to-buffer "*Typescript*")) |
| 128 | + |
| 129 | + (if typescript-comint-mode-ansi-color |
| 130 | + (progn |
| 131 | + (ansi-color-for-comint-mode-on) |
| 132 | + (make-local-variable 'comint-preoutput-filter-functions) |
| 133 | + (add-to-list |
| 134 | + 'comint-preoutput-filter-functions |
| 135 | + (lambda (output) |
| 136 | + (replace-regexp-in-string "\033\\[[0-9]+[GKJ]" "" output)))) |
| 137 | + (setenv "NODE_NO_READLINE" "1"))) |
| 138 | + |
| 139 | +;;;###autoload |
| 140 | +(defun typescript-send-string (text) |
| 141 | + "Send TEXT to the inferior TypeScript process." |
| 142 | + (interactive "r") |
| 143 | + (typescript-run-repl typescript-comint-program-command t) |
| 144 | + (comint-send-string (get-buffer-process typescript-comint-buffer) |
| 145 | + (concat text "\n"))) |
| 146 | + |
| 147 | +;;;###autoload |
| 148 | +(defun typescript-send-region (start end) |
| 149 | + "Send the current region between START and END to the TypeScript process." |
| 150 | + (interactive "r") |
| 151 | + (typescript-send-string (buffer-substring-no-properties start end))) |
| 152 | + |
| 153 | +;;;###autoload |
| 154 | +(defun typescript-send-region-and-go (start end) |
| 155 | + "Send the current region to the TypeScript process and focus the REPL." |
| 156 | + (interactive "r") |
| 157 | + (typescript-send-region start end) |
| 158 | + (typescript-switch-to-repl typescript-comint-buffer)) |
| 159 | + |
| 160 | +;;;###autoload |
| 161 | +(defun typescript-send-last-sexp-and-go () |
| 162 | + "Send the previous sexp to the TypeScript process and focus the REPL." |
| 163 | + (interactive) |
| 164 | + (typescript-send-region-and-go |
| 165 | + (save-excursion |
| 166 | + (backward-sexp) |
| 167 | + (move-beginning-of-line nil) |
| 168 | + (point)) |
| 169 | + (point))) |
| 170 | + |
| 171 | +;;;###autoload |
| 172 | +(defun typescript-send-last-sexp () |
| 173 | + "Send the previous sexp to the inferior TypeScript process." |
| 174 | + (interactive) |
| 175 | + (typescript-send-region |
| 176 | + (save-excursion |
| 177 | + (backward-sexp) |
| 178 | + (move-beginning-of-line nil) |
| 179 | + (point)) |
| 180 | + (point))) |
| 181 | + |
| 182 | +;;;###autoload |
| 183 | +(defun typescript-send-buffer () |
| 184 | + "Send the current buffer to the inferior TypeScript process." |
| 185 | + (interactive) |
| 186 | + (typescript-send-region (point-min) (point-max))) |
| 187 | + |
| 188 | +;;;###autoload |
| 189 | +(defun typescript-send-buffer-and-go () |
| 190 | + "Send the current buffer to the TypeScript process and focus the REPL." |
| 191 | + (interactive) |
| 192 | + (typescript-send-region-and-go (point-min) (point-max))) |
| 193 | + |
| 194 | +;;;###autoload |
| 195 | +(defun typescript-load-file (filename) |
| 196 | + "Load FILENAME inside the TypeScript interpreter." |
| 197 | + (interactive "f") |
| 198 | + (typescript-send-string |
| 199 | + (typescript-comint--get-load-file-cmd (expand-file-name filename)))) |
| 200 | + |
| 201 | +;;;###autoload |
| 202 | +(defun typescript-load-file-and-go (filename) |
| 203 | + "Load FILENAME inside the TypeScript interpreter and focus the REPL." |
| 204 | + (interactive "f") |
| 205 | + (typescript-load-file filename) |
| 206 | + (typescript-switch-to-repl typescript-comint-buffer)) |
| 207 | + |
| 208 | +;;;###autoload |
| 209 | +(defun typescript-switch-to-repl (eob-p) |
| 210 | + "Switch to the TypeScript process buffer. |
| 211 | +When EOB-P is non-nil, move point to the end of the buffer." |
| 212 | + (interactive "P") |
| 213 | + (if (and typescript-comint-buffer (get-buffer typescript-comint-buffer)) |
| 214 | + (pop-to-buffer typescript-comint-buffer) |
| 215 | + (error "No current process buffer. See `typescript-comint-buffer'")) |
| 216 | + (when eob-p |
| 217 | + (push-mark) |
| 218 | + (goto-char (point-max)))) |
| 219 | + |
| 220 | +;;;###autoload |
| 221 | +(define-derived-mode typescript-comint-mode comint-mode "Inferior TypeScript" |
| 222 | + "Major mode for interacting with an inferior TypeScript process. |
| 223 | +
|
| 224 | +A TypeScript process can be started with \\[typescript-run-repl]. |
| 225 | +
|
| 226 | +Customization: entry runs `comint-mode-hook' then `typescript-comint-mode-hook'." |
| 227 | + :group 'typescript-comint) |
| 228 | + |
| 229 | +(define-key typescript-comint-mode-map (kbd "C-x C-e") #'typescript-send-last-sexp) |
| 230 | +(define-key typescript-comint-mode-map (kbd "C-x l") #'typescript-load-file) |
| 231 | + |
| 232 | +;;; Compatibility aliases (kept for users of the original ts-comint.el) |
| 233 | +(define-obsolete-function-alias 'run-ts 'typescript-run-repl "0.5") |
| 234 | +(define-obsolete-function-alias 'ts-send-string 'typescript-send-string "0.5") |
| 235 | +(define-obsolete-function-alias 'ts-send-region 'typescript-send-region "0.5") |
| 236 | +(define-obsolete-function-alias 'ts-send-region-and-go 'typescript-send-region-and-go "0.5") |
| 237 | +(define-obsolete-function-alias 'ts-send-last-sexp 'typescript-send-last-sexp "0.5") |
| 238 | +(define-obsolete-function-alias 'ts-send-last-sexp-and-go 'typescript-send-last-sexp-and-go "0.5") |
| 239 | +(define-obsolete-function-alias 'ts-send-buffer 'typescript-send-buffer "0.5") |
| 240 | +(define-obsolete-function-alias 'ts-send-buffer-and-go 'typescript-send-buffer-and-go "0.5") |
| 241 | +(define-obsolete-function-alias 'ts-load-file 'typescript-load-file "0.5") |
| 242 | +(define-obsolete-function-alias 'ts-load-file-and-go 'typescript-load-file-and-go "0.5") |
| 243 | +(define-obsolete-function-alias 'switch-to-ts 'typescript-switch-to-repl "0.5") |
| 244 | +(define-obsolete-function-alias 'ts-comint-mode 'typescript-comint-mode "0.5") |
| 245 | + |
| 246 | +(provide 'typescript-comint) |
| 247 | + |
| 248 | +;;; typescript-comint.el ends here |
0 commit comments