;;; build.el --- Project build, set up for Evil -*- lexical-binding: t; -*- ;;; Commentary: ;; Loaded from init.el after Evil. ;; ;; :build Run ./build.sh from the nearest ancestor dir containing it. ;; :build ARGS Run ./build.sh ARGS, e.g. :build release -v ;; ;; If no build.sh is found (or it isn't executable), report it and do nothing. ;; ;; The compilation buffer opens at the bottom (45% height, full width) and ;; takes focus when the build starts. ANSI colours are rendered. ;; Kill a running build with M-x kill-compilation. ;;; Code: (setq compilation-read-command nil ; run without prompting compilation-ask-about-save nil compilation-scroll-output t) (add-hook 'compilation-filter-hook #'ansi-color-compilation-filter) ;; Compilation buffer at the bottom, full frame width. (add-to-list 'display-buffer-alist '((derived-mode . compilation-mode) (display-buffer-reuse-window display-buffer-at-bottom) (window-height . 0.45))) ;; Focus the compilation window when a build starts. (add-hook 'compilation-start-hook (lambda (proc) (when-let* ((win (get-buffer-window (process-buffer proc)))) (select-window win)))) ;; :build runs ./build.sh; :build ARGS appends ARGS. (evil-define-command my/ex-build (args) "Run `./build.sh ARGS' from the nearest directory containing build.sh." (interactive "") (let ((root (locate-dominating-file default-directory "build.sh"))) (unless root (user-error "No build.sh found")) (let ((default-directory root)) (unless (file-executable-p "build.sh") (user-error "build.sh is not executable")) (compile (string-trim (concat "./build.sh " args)))))) ; nil args -> "" (evil-ex-define-cmd "build" #'my/ex-build) ;;; build.el ends here