Emacs
Нужен Emacs 29+ (eglot и tree-sitter встроены). OxL не поставляется с готовым режимом, ниже минимальный.
Режим файла#
;; ~/.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))С грамматикой tree-sitter (после tree-sitter generate в share/oxl/tree-sitter-oxl, затем собрать библиотеку
libtree-sitter-oxl.so в каталог ~/.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))Имена захватов в queries/highlights.scm (@keyword, @type, …) переводятся в faces Emacs font-lock-*-face таблицей
по вкусу; семантические токены от сервера eglot отображает сам (Emacs 30+), поэтому минимальный режим выше уже даёт осмысленную подсветку.
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)))Команды: M-. определение, M-? ссылки, C-c r (eglot-rename), C-c a (eglot-code-actions), C-c h (eldoc).
Параметры init_options передаются так: (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)Отладка#
С 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 → oxl-launch. С dap-mode: (dap-register-debug-provider "oxl" ...) с адаптером oxl dap по stdio; параметры те же. См. отладка.