branch: elpa/zig-mode commit 1552e0ebbcf748adc5c2058199050e68e0087fa4 Merge: fc7fde3 4eafa60 Author: Andrea Orru <and...@orru.io> Commit: GitHub <nore...@github.com>
Merge pull request #20 from mgxm/feat/add_zig_cli_integration Adds few Zig CLI commands --- zig-mode.el | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 13 deletions(-) diff --git a/zig-mode.el b/zig-mode.el index 1d90cad..f4052cc 100644 --- a/zig-mode.el +++ b/zig-mode.el @@ -27,6 +27,105 @@ ;;; Code: +(defgroup zig-mode nil + "Support for Zig code." + :link '(url-link "https://ziglang.org/") + :group 'languages) + +(defcustom zig-indent-offset 4 + "Indent Zig code by this number of spaces." + :type 'integer + :group 'zig-mode + :safe #'integerp) + +(defcustom zig-format-on-save t + "Format buffers before saving using zig fmt." + :type 'boolean + :safe #'booleanp + :group 'zig-mode) + +(defcustom zig-zig-bin "zig" + "Path to zig executable." + :type 'string + :safe #'stringp + :group 'zig-mode) + +;; zig CLI commands + +(defun zig--run-cmd (cmd &optional source &rest args) + "Use compile command to execute a zig CMD with ARGS if given. +If given a SOURCE, execute the CMD on it." + (let ((cmd-args + (if source + (mapconcat 'identity (cons source args) " ") + args))) + (compile (concat zig-zig-bin " " cmd " " cmd-args)))) + +;;;###autoload +(defun zig-toggle-format-on-save () + "Switch format before save on current buffer." + (interactive) + (if zig-format-on-save + (setq-local zig-format-on-save nil) + (setq-local zig-format-on-save t))) + +;;;###autoload +(defun zig-compile () + "Compile using `zig build`." + (interactive) + (zig--run-cmd "build")) + +;;;###autoload +(defun zig-build-exe () + "Create executable from source or object file." + (interactive) + (zig--run-cmd "build-exe" (buffer-file-name))) + +;;;###autoload +(defun zig-build-lib () + "Create library from source or assembly." + (interactive) + (zig--run-cmd "build-lib" (buffer-file-name))) + +;;;###autoload +(defun zig-build-obj () + "Create object from source or assembly." + (interactive) + (zig--run-cmd "build-obj" (buffer-file-name))) + +;;;###autoload +(defun zig-test-buffer () + "Test buffer using `zig test`." + (interactive) + (zig--run-cmd "test" (buffer-file-name) "--release-fast")) + +;;;###autoload +(defun zig-run () + "Create an executable from the current buffer and run it immediately." + (interactive) + (zig--run-cmd "run" (buffer-file-name))) + +;;;###autoload +(defun zig-format-buffer () + "Format the current buffer using the zig fmt." + (interactive) + (let ((fmt-buffer-name "*zig-fmt*")) + ;; If we have an old *zig-fmt* buffer, we want to kill + ;; it and start a new one to show the new errors + (when (get-buffer fmt-buffer-name) + (kill-buffer fmt-buffer-name)) + (let ((fmt-buffer (get-buffer-create fmt-buffer-name))) + (set-process-sentinel + (start-process "zig-fmt" + fmt-buffer + zig-zig-bin + "fmt" + (buffer-file-name)) + (lambda (process _e) + (when (> (process-exit-status process) 0) + (switch-to-buffer-other-window fmt-buffer) + (compilation-mode))))))) + (defun zig-re-word (inner) "Construct a regular expression for the word INNER." (concat "\\<" inner "\\>")) @@ -117,16 +216,6 @@ (defconst zig-electric-indent-chars '(?\; ?, ?\) ?\] ?})) -(defgroup zig-mode nil - "Support for Zig code." - :link '(url-link "https://ziglang.org/") - :group 'languages) - -(defcustom zig-indent-offset 4 - "Indent Zig code by this number of spaces." - :type 'integer - :group 'zig-mode - :safe #'integerp) (defface zig-multiline-string-face '((t :inherit font-lock-string-face)) @@ -313,9 +402,21 @@ (add-hook 'zig-mode-hook 'zig-file-coding-system) +(defvar zig-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-b") 'zig-compile) + (define-key map (kbd "C-c C-f") 'zig-format-buffer) + (define-key map (kbd "C-c C-r") 'zig-run) + (define-key map (kbd "C-c C-t") 'zig-test-buffer) + map) + "Keymap for Zig major mode.") + ;;;###autoload (define-derived-mode zig-mode prog-mode "Zig" - "A major mode for the Zig programming language." + "A major mode for the Zig programming language. + +\\{zig-mode-map}" + :group 'zig-mode (setq-local comment-start "// ") (setq-local comment-end "") (setq-local electric-indent-chars @@ -328,11 +429,22 @@ (setq-local imenu-generic-expression zig-imenu-generic-expression) (setq font-lock-defaults '(zig-font-lock-keywords nil nil nil nil - (font-lock-syntactic-face-function - . zig-mode-syntactic-face-function)))) + (font-lock-syntactic-face-function . zig-mode-syntactic-face-function))) + + (add-hook 'before-save-hook 'zig-before-save-hook nil t)) + +(defun zig-before-save-hook () + (when zig-format-on-save + (zig-format-buffer))) + +(defun colorize-compilation-buffer () + (toggle-read-only) + (ansi-color-apply-on-region compilation-filter-start (point)) + (toggle-read-only)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode)) +(add-hook 'compilation-filter-hook 'colorize-compilation-buffer) (provide 'zig-mode) ;;; zig-mode.el ends here