~mgmarlow/deno-ts-mode

c6f827b998b5d0fbc8bb3254c4d3b1efca0c5c6f — Graham Marlow 1 year, 11 days ago d3e2716
Parse Deno config file to a struct
3 files changed, 80 insertions(+), 9 deletions(-)

A Makefile
A deno-ts-mode-test.el
M deno-ts-mode.el
A Makefile => Makefile +20 -0
@@ 0,0 1,20 @@
EMACS := emacs -Q -batch

LOADPATH := -L .

PACKAGE_FILES := $(filter-out $(wildcard *-test.el), $(wildcard *.el))

TEST_FILES := $(wildcard *-test.el)

COMPILED_FILES := $(wildcard *.elc)

.PHONY: compile test clean

test: compile
	$(EMACS) $(LOADPATH) -l ert -l $(TEST_FILES) -f ert-run-tests-batch-and-exit

compile: clean
	$(EMACS) $(LOADPATH) -f batch-byte-compile $(PACKAGE_FILES)

clean:
	rm -f $(COMPILED_FILES)

A deno-ts-mode-test.el => deno-ts-mode-test.el +33 -0
@@ 0,0 1,33 @@
(require 'ert)
(require 'deno-ts-mode)

(defvar sample-config
"{
  \"lint\": {
    \"rules\": {
      \"tags\": [\"recommended\"]
    }
  },
  \"fmt\": {
    \"useTabs\": true,
    \"lineWidth\": 80
  },
  \"test\": {
    \"include\": [\"src/\"],
    \"exclude\": [\"src/testdata/\"]
  },
  \"tasks\": {
    \"start\": \"deno run --allow-read main.ts\"
  }
}")

(ert-deftest test-deno-ts--build-config ()
  (let ((config (deno-ts--build-config sample-config)))
    (should (equal (deno-ts-config-tasks config)
                   '((start . "deno run --allow-read main.ts"))))
    (should (equal (deno-ts-config-test config)
                   '((include . ["src/"]) (exclude . ["src/testdata/"]))))
    (should (equal (deno-ts-config-lint config)
                   '((rules (tags . ["recommended"])))))
    (should (equal (deno-ts-config-fmt config)
                   '((useTabs . t) (lineWidth . 80))))))

M deno-ts-mode.el => deno-ts-mode.el +27 -9
@@ 58,6 58,7 @@
(require 'project)
(require 'typescript-ts-mode) ; Make sure to load auto-mode-alist here first
(require 'json)
(require 'cl-lib)

(defgroup deno-ts nil
  "Major mode for Deno."


@@ 94,19 95,36 @@ current project cannot be read."
  (add-to-list 'eglot-server-programs
               '(deno-ts-mode . ("deno" "lsp" :initializationOptions (:enable t :lint t)))))

(defun deno-ts--project-tasks ()
  "List tasks from the current project's deno config."
  (let ((p-config (deno-ts--project-config-path)))
    (unless p-config
      (error "Cannot find Deno configuration file"))
    (alist-get 'tasks (json-read-file p-config))))
(cl-defstruct deno-ts-config
  "Deno configuration file struct."
  tasks lint fmt test)

(defun deno-ts--build-config (json)
  "Return an instance of `deno-ts-config' from JSON string."
  (let ((raw (json-read-from-string json)))
    (make-deno-ts-config :tasks (alist-get 'tasks raw)
                         :lint (alist-get 'lint raw)
                         :fmt (alist-get 'fmt raw)
                         :test (alist-get 'test raw))))

(defun deno-ts-project-config ()
  "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)))
    (deno-ts--build-config
     (with-temp-buffer
       (insert-file-contents p-config-path)
       (buffer-string)))))

(defun deno-ts-run-task ()
  "Execute a deno task from the current project's deno config."
  (interactive)
  (let ((tasks (mapcar 'car (deno-ts--project-tasks))))
    (compile (format "deno task %s"
                     (completing-read "Run task: " tasks nil t)))))
  (if-let* ((config (deno-ts-project-config))
            (tasks (mapcar 'car (deno-ts-config-tasks config))))
      (compile (format "deno task %s"
                       (completing-read "Run task: " tasks nil t)))
    (error "Cannot find Deno configuration file")))

(define-derived-mode deno-ts-mode
  typescript-ts-mode "Deno"