Created
March 24, 2020 16:34
-
-
Save dacap/a87e52faae2138a470b2183a996322e3 to your computer and use it in GitHub Desktop.
handy-compile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; ================================================== | |
;; handy-compile (redefined) | |
;; ================================================== | |
(require 'bookmark) | |
(defun handy-current-buffer-path () | |
(cond | |
((buffer-file-name) (file-name-directory (buffer-file-name))) | |
((eq major-mode 'dired-mode) (dired-current-directory)) | |
((eq major-mode 'eshell-mode) (eshell/pwd)) | |
(t default-directory))) | |
(defun handy-compile-call-cmd (cmd) | |
(save-selected-window | |
(setq compile-command cmd) | |
(compile compile-command) | |
(select-window (get-buffer-window "*compilation*")) | |
(message (concat default-directory "$ " compile-command)) | |
) | |
t) | |
(defun handy-compile-recompile () | |
(let ((list (buffer-list)) | |
(found nil)) | |
;; First we try to find the *compilation* buffer | |
(while (and list (equal nil found)) | |
(if (equal (buffer-name (car list)) "*compilation*") | |
(let () | |
;; Recompile | |
(recompile) | |
(setq found t))) | |
(setq list (cdr list))) | |
;; Return `found' variable | |
found)) | |
(defun handy-compile-in-builds () | |
(let* ((frame (car (car (cdr (current-frame-configuration))))) | |
(title (frame-parameter frame 'title)) | |
;; (project-dir (projectile-project-root)) | |
(project-dir default-directory) | |
(project-name (file-name-nondirectory (directory-file-name project-dir))) | |
(expected-build-dirname | |
(concat | |
(file-name-as-directory (bookmark-get-filename "builds")) | |
project-name "-" title))) | |
;; Create the builds dir automatically | |
(when (or (file-directory-p expected-build-dirname) | |
(if (not (y-or-n-p (concat "Create " expected-build-dirname "?"))) | |
nil | |
(make-directory expected-build-dirname) | |
(cd expected-build-dirname) | |
;; (if (eq (window-system) 'w32) | |
;; (handy-compile-call-cmd (concat "cmake " project-dir " -G Ninja")) | |
;; (handy-compile-call-cmd (concat "cmake " project-dir " -G 'Unix Makefiles'"))) | |
(handy-compile-call-cmd (concat "cmake " project-dir " -G Ninja")) | |
t)) | |
(cd expected-build-dirname) | |
(handy-compile-makefiles nil)))) | |
(defun handy-compile-makefiles (&rest recursive) | |
(if (file-regular-p "build.sh") | |
(handy-compile-call-cmd "bash build.sh") | |
(if (file-regular-p "_build.sh") | |
(handy-compile-call-cmd "bash _build.sh") | |
;; We try to find a "Makefile" (and then we stop in the root of emacs-desktop) | |
(if (or (file-regular-p "Makefile") | |
(file-regular-p "MAKEFILE") | |
(file-regular-p "makefile")) | |
;; Open the Makefile generated by CMake | |
(with-temp-buffer | |
(insert-file-contents "Makefile") | |
(beginning-of-buffer) | |
;; Search the generator and execute the command to build that Makefile | |
(if (search-forward "\"NMake Makefiles JOM\"" nil t) | |
(handy-compile-call-cmd "jom -k") | |
(if (search-forward "\"NMake Makefiles\"" nil t) | |
(handy-compile-call-cmd "nmake -k") | |
(handy-compile-call-cmd "make -k -j 4")))) | |
;; Try build.ninja | |
(if (file-regular-p "build.ninja") | |
(handy-compile-call-cmd "ninja") | |
;; End of project path (when .emacs-desktop is found). | |
(if (or (file-regular-p ".emacs-desktop") | |
(file-regular-p ".emacs") | |
(file-regular-p ".projectile") | |
(file-directory-p ".git")) | |
nil | |
;; Go to parent dir. | |
(let ((up (file-name-directory (directory-file-name default-directory)))) | |
(if (or (eq up nil) | |
(eq up "/") | |
(string-match "^[a-zA-Z]:[/\\\\]$" up)) | |
nil | |
(when recursive | |
(cd up) | |
(handy-compile-makefiles t)))))))))) | |
;; (defvar handy-compile-list | |
;; "List of functions to call step by step from `handy-compile'." | |
;; '(handy-compile--recompile | |
;; handy-compile--build.sh | |
;; handy-compile--make | |
;; handy-compile--cmake-on-builds | |
;; handy-compile--ninja-on-builds)) | |
;; (defun handy-compile-step (x) | |
;; (if (not x) | |
;; nil | |
;; (if (funcall (car x)) | |
;; t | |
;; (handy-compile-step (cdr x))))) | |
(defun handy-compile () | |
"Calls each function in `handy-compile-list' until one returns t. | |
By default it tries: | |
1. to recompile the *compilation* buffer (`handy-try-recompile') | |
2. if a build.sh file exist in the project root directory, it tries to run it with 'bash build.sh' (`handy-try-build.sh') | |
3. then if a Makefile is found, it tries to run the 'make' command (`handy-try-make') | |
4. if a CMakeLists.txt is found, it tries to run cmake in a new folder inside the 'builds' directory (specified by the 'builds' bookmark) (`handy-try-cmake-on-builds') | |
4. if a ninja.build is found in the build folder, ninja is executed (`handy-try-ninja-on-builds')" | |
(interactive) | |
(cl-flet ((yes-or-no-p (&rest args) t)) | |
(let ((initial-directory default-directory)) | |
(cd (handy-current-buffer-path)) | |
;; (if (not (handy-compile-step handy-compile-list)) | |
;; (message (concat "No makefile found from " (handy-current-buffer-path)))) | |
;; Remove this | |
(or (handy-compile-recompile) ; Try to recompile using the existent *compilation* buffer | |
(and (cd default-directory) | |
(handy-compile-makefiles t)) ; If the *compilation* buffer does not exist | |
(handy-compile-in-builds) | |
(message (concat "No makefile found from " (handy-current-buffer-path)))) | |
(cd-absolute initial-directory)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment