mohkale / compile-multi

Multi target interface to compile.
GNU General Public License v3.0
24 stars 3 forks source link

+TITLE: compile-multi

+AUTHOR: Mohsin Kaleem

LocalWords: Makefiles alist

+html:

+html:

+html: MELPA

+html:

A multi-target =M-x compile= interface inspired by [[https://github.com/ReanGD/emacs-multi-compile][multi-compile]].

+CAPTION: Obligatory screenshot of compile-multi in action.

[[https://user-images.githubusercontent.com/23294780/246896395-eb920b00-1c0e-4d55-972f-1c4ac2b195cf.png]]

This package provides a framework for associating actions with triggers. A trigger is any predicate that applies to the current file, project or directory. An action is a shell command or interactive function or anything that can be invoked when the associated trigger is set. You can use this to construct rich command interfaces emulating those offered by more integrated development environments. You can also plug in compilation targets directly from build frameworks or test tools, etc. See [[https://github.com/mohkale/projection#projection-multi-compile][projection-multi-compile]] for a package that plugs compile-multi into various build tools.

** From MELPA This package is on [[https://github.com/melpa/melpa][MELPA]]. You can add this to your ~package-archives~ variable and then install through ~M-x package-install~.

+begin_src emacs-lisp

 (push '("melpa" . "https://melpa.org/packages/") package-archives)
 (package-refresh-contents)
 (package-install 'compile-multi)

+end_src

** Triggers Triggers can be mode-symbols, strings, interpreted as regexps for the buffer-file-name or if the buffer has no file name then its buffer-name, or any lisp form that is triggered when it evaluates to true.

This can be used alongside ~(setq compile-multi-default-directory #'projectile-project-root)~ to setup trigger based on project files.

+begin_src emacs-lisp

 (push '((file-exists-p "Makefile")
         ("make:build" . "make build")
         ("make:test" . "make test")
         ("make:all" . "make all"))
       compile-multi-config)

+end_src

** Actions As a special case an action can be inserted as a function instead of an cons cell. When this is the case the function will be called and expected to return a collection of actions to be put in place of the functions position in the configuration.

For example you can write a ~compile-multi-make~ that'll parse out all the targets from a Makefile and generate actions for them.

+begin_src emacs-lisp

 (require 'compile-multi-make)

 (defun compile-multi-make-targets+ ()
   ;; Read targets from Makefile.
   '(("make:foo" . "foo")))

 (push `((file-exists-p "Makefile")
         ("action-1" . command-1)
         ,#'compile-multi-make-targets+
         ("action-2" . command-2))
       compile-multi-config)

+end_src

When written as an alist the ~car~ of an action must always be the action name. The ~cdr~ can vary depending on what the user wants.

When it's a string then the string is taken as a shell command to run for compilation. When a list each argument of the list is evaluated, shell-quoted and then concatenated together. When a plist you can set the =:command= property and supply any alternative properties to customise the execution of the target. For example the ~:annotation~ property sets the affixated annotation for the action in the minibuffer.

Note: We don't shell quote strings, only evaluated lisp forms. Note: Symbols can be replaced instead of evaluated using ~compile-multi-forms~. For example

+begin_src emacs-lisp

 (push `(python-mode
         ("python:pylint" "python3" "-m" "pylint" (buffer-file-name)))
       compile-multi-config)

+end_src

Lastly the action can be a function. In this case the function is called when the action is selected. For example:

+begin_src emacs-lisp

 (defun byte-compile-this-file+ ()
   (byte-compile-file (buffer-file-name)))

 (push `(emacs-lisp-mode
         ("emacs:bytecompile" . ,#'byte-compile-this-file+))
       compile-multi-config)

+end_src

+html:

+html: MELPA

+html:

Is an extension for multi-compile that runs the interactive selection of targets through consult instead of completing-read. This is very similar to the existing completing-read interface but enhances it with some useful consult features such as narrowing.

+begin_src emacs-lisp

 (use-package consult-compile-multi
   :ensure t
   :after compile-multi
   :demand t
   :config (consult-compile-multi-mode))

+end_src

** compile-multi-all-the-icons

+html:

+html: MELPA

+html:

This extension adds a handler to [[https://github.com/iyefrat/all-the-icons-completion][all-the-icons-completion]] for affixating compile-multi with icons related to the compile-multi type. You have to setup =all-the-icons-completion= correctly before this package will work.

+begin_src emacs-lisp

 (use-package compile-multi-all-the-icons
   :ensure t
   :after all-the-icons-completion
   :after compile-multi
   :demand t)

+end_src

** compile-multi-nerd-icons

+html:

+html: MELPA

+html:

This extension adds a handler to [[https://github.com/rainstormstudio/nerd-icons-completion][nerd-icons-completion]] for affixating compile-multi with nerd icons related to the compile-multi type. You have to setup =nerd-icons-completion= correctly before this package will work.

+begin_src emacs-lisp

 (use-package compile-multi-nerd-icons
   :ensure t
   :after nerd-icons-completion
   :after compile-multi
   :demand t)

+end_src

** compile-multi-embark

+html:

+html: MELPA

+html:

This extension adds support between compile-multi embark. This has 2 affects:

  1. Defines a new compile-multi command map for Embark. This map has a command to let you edit a compile-multi target before executing it.
  2. Adds a transformer to embark so any actions you run on compile-multi through embark in the minibuffer actually route to the underlying command you wanted to run them on. For example this can be used with the =kill-new= feature to copy the compilation command compile-multi would have run.

    To use this extension you must install it and use enable =compile-multi-embark-mode=.

    +begin_src emacs-lisp

    (use-package compile-multi-embark :ensure t :after embark :after compile-multi :demand t :config (compile-multi-embark-mode +1))

    +end_src