From 6bc2ff0352df2d1f7e5a62614b5b50dd8e9b31c7 Mon Sep 17 00:00:00 2001 From: Graham Marlow Date: Sat, 2 Sep 2023 09:53:06 -0700 Subject: [PATCH] fix: Autoload behavior --- deno-ts-mode.el | 64 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/deno-ts-mode.el b/deno-ts-mode.el index 56b08b1..41cf149 100644 --- a/deno-ts-mode.el +++ b/deno-ts-mode.el @@ -43,8 +43,7 @@ ;; Example configuration: ;; ;; (use-package deno-ts-mode -;; :config -;; (deno-ts-setup-auto-mode-alist)) +;; :ensure t) ;; ;; (use-package eglot ;; :ensure t @@ -56,7 +55,6 @@ (require 'eglot) (require 'project) -(require 'typescript-ts-mode) ; Make sure to load auto-mode-alist here first (require 'json) (require 'cl-lib) @@ -70,7 +68,7 @@ :type 'string :group 'deno) -(defun deno-ts--project-config-path () +(defun deno-ts-project-config-path () "Return the filepath of the current project's deno config. Return nil if `project-current' is nil or if a deno config file @@ -87,7 +85,7 @@ cannot be found." Return nil if `project-current' is not a Deno project or the current project cannot be read." - (and (deno-ts--project-config-path) t)) + (and (deno-ts-project-config-path) t)) ;; https://deno.land/manual@v1.36.1/getting_started/setup_your_environment#eglot (defun deno-ts-setup-eglot () @@ -111,7 +109,7 @@ current project cannot be read." "Return an instance of `deno-ts-config' built from the current project. Return nil if no project is found." - (when-let ((p-config-path (deno-ts--project-config-path))) + (when-let ((p-config-path (deno-ts-project-config-path))) (deno-ts--build-config (with-temp-buffer (insert-file-contents p-config-path) @@ -126,29 +124,51 @@ Return nil if no project is found." (completing-read "Run task: " tasks nil t))) (error "Cannot find Deno configuration file"))) +;;;###autoload (define-derived-mode deno-ts-mode typescript-ts-mode "Deno" "Major mode for Deno." :group 'deno-ts-mode) -(defun deno-ts--ts-auto-mode () - "Return `deno-ts-mode' if project is a Deno project, else `typescript-ts-mode'." - (cond ((deno-ts-project-p) (deno-ts-mode)) - (t (typescript-ts-mode)))) - -(defun deno-ts--tsx-auto-mode () - "Return `deno-ts-mode' if project is a Deno project, else `tsx-ts-mode'." - (cond ((deno-ts-project-p) (deno-ts-mode)) - (t (tsx-ts-mode)))) +;;;###autoload +(defun deno-ts-mode-maybe () + "Turn on `deno-ts-mode' if a Deno config file is found. + +Otherwise, fallback to either `typescript-ts-mode' or +`tsx-ts-mode' depending on the visited file extension." + (if-let* ((filename (buffer-file-name)) + (ext (file-name-extension filename))) + (cond ((and (equal "ts" ext) (deno-ts-project-p)) + (deno-ts-mode)) + ((equal "ts" ext) + (typescript-ts-mode)) + ((and (equal "tsx" ext) (deno-ts-project-p)) + (deno-ts-mode)) + ((equal "tsx" ext) + (tsx-ts-mode))))) + +;; `deno-ts-mode' is competing with `typescript-ts-mode' and +;; `tsx-ts-mode' for precedence of the ".ts" and ".tsx" file +;; extensions. `deno-ts-mode' is derived from `typescript-ts-mode' +;; and will load it implicitly. This is a problem for +;; `auto-mode-alist' because `typescript-ts-mode' adds itself to +;; `auto-mode-alist', meaning that it will come first in the +;; association list since it's loaded after the `deno-ts-mode' +;; autoloads. To work around this, remove the `typescript-ts-mode' and +;; `tsx-ts-mode' entries from `auto-mode-alist'. This library assumes +;; that users want to check for Deno files in all cases. +(with-eval-after-load 'typescript-ts-mode + (setq auto-mode-alist (seq-filter + (lambda (x) + (not (or (equal (cdr x) 'typescript-ts-mode) + (equal (cdr x) 'tsx-ts-mode)))) + auto-mode-alist))) -(defun deno-ts-setup-auto-mode-alist () - "Add Deno to `auto-mode-alist' for .ts and .tsx files. +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.ts\\'" . deno-ts-mode-maybe)) -If the visited .ts file does not detect a Deno project (as -determined by `deno-project-p') this function will fallback to -`typescript-ts-mode'." - (add-to-list 'auto-mode-alist '("\\.ts\\'" . deno-ts--ts-auto-mode)) - (add-to-list 'auto-mode-alist '("\\.tsx\\'" . deno-ts--tsx-auto-mode))) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.tsx\\'" . deno-ts-mode-maybe)) ;; Required for Deno's color output. (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) -- 2.45.2