Emacs
Emacs 29+ is needed (eglot and tree-sitter are built in). OxL does not ship a ready major mode; a minimal one follows.
File mode#
;; ~/.emacs.d/init.el
(define-derived-mode oxl-mode prog-mode "OxL"
"Major mode for OxL."
(setq-local comment-start "// " comment-end "")
(setq-local indent-tabs-mode nil tab-width 2))
(add-to-list 'auto-mode-alist '("\\.oxl\\'" . oxl-mode))With the tree-sitter grammar (after tree-sitter generate in share/oxl/tree-sitter-oxl, then build the library
libtree-sitter-oxl.so into ~/.emacs.d/tree-sitter/):
cd /opt/oxl-1.0.0-beta/share/oxl/tree-sitter-oxl && npx tree-sitter generate
cc -shared -fPIC -O2 -Isrc src/parser.c -o ~/.emacs.d/tree-sitter/libtree-sitter-oxl.so(define-derived-mode oxl-ts-mode prog-mode "OxL[ts]"
(when (treesit-ready-p 'oxl)
(treesit-parser-create 'oxl)
(setq-local treesit-font-lock-settings
(treesit-font-lock-rules :language 'oxl :feature 'all
;; содержимое queries/highlights.scm: переведите capture-имена в faces
'((comment) @font-lock-comment-face (string) @font-lock-string-face))
treesit-font-lock-feature-list '((all)))
(treesit-major-mode-setup)))
(add-to-list 'auto-mode-alist '("\\.oxl\\'" . oxl-ts-mode))Translate the capture names of queries/highlights.scm (@keyword, @type, …) into Emacs font-lock-*-face faces with a table
of your taste; semantic tokens from the server are shown by eglot itself (Emacs 30+), so the minimal mode above already highlights
meaningfully.
eglot#
(require 'eglot)
(add-to-list 'eglot-server-programs '((oxl-mode oxl-ts-mode) . ("oxl" "lsp")))
(add-hook 'oxl-mode-hook #'eglot-ensure)
(add-hook 'oxl-ts-mode-hook #'eglot-ensure)
;; форматирование при сохранении, inlay-подсказки
(add-hook 'oxl-mode-hook (lambda () (add-hook 'before-save-hook #'eglot-format-buffer nil t)
(eglot-inlay-hints-mode 1)))Commands: M-. definition, M-? references, eglot-rename, eglot-code-actions, eldoc. init_options are passed like this:
(add-to-list 'eglot-server-programs '(oxl-mode . ("oxl" "lsp" :initializationOptions (:debounceMs 150)))).
lsp-mode#
(require 'lsp-mode)
(add-to-list 'lsp-language-id-configuration '(oxl-mode . "oxl"))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection '("oxl" "lsp"))
:activation-fn (lsp-activate-on "oxl")
:server-id 'oxl-lsp
:priority 1))
(add-hook 'oxl-mode-hook #'lsp-deferred)Debugging#
With dape:
(with-eval-after-load 'dape
(add-to-list 'dape-configs
`(oxl-launch
modes (oxl-mode oxl-ts-mode)
command "oxl" command-args ("dap")
:type "oxl" :request "launch"
:program "." :cwd "." :oxlProfile "dev")))M-x dape then oxl-launch. With dap-mode: (dap-register-debug-provider "oxl" ...) with the adapter oxl dap over stdio; the
parameters are the same. See debugging.