Skip to content

Instantly share code, notes, and snippets.

@dacap
Created March 24, 2020 16:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacap/a87e52faae2138a470b2183a996322e3 to your computer and use it in GitHub Desktop.
Save dacap/a87e52faae2138a470b2183a996322e3 to your computer and use it in GitHub Desktop.
handy-compile
;; ==================================================
;; 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