Setting up Emacs for VuFind® development
I've gotten more involved in PHP development lately, mostly working on VuFind®-related packages. My editor of choice is GNU Emacs, and today I finally finished my Emacs setup. Lo and behold!
(use-package php-mode
:ensure t
:hook
(php-mode . eglot-ensure)
(php-mode . completion-preview-mode)
(php-mode . subword-mode)
:custom
(php-manual-url "http://127.0.0.1:8118/php/")
(php-manual-path (expand-file-name "webdocs/php/" user-emacs-directory))
(php-search-documentation-function 'php-local-manual-search)
(php-search-documentation-browser-function 'eww-browse-url)
(lsp-phpactor-path (executable-find "phpactor")))
I use php-mode for editing pure PHP code and web-mode (not shown here) for working with PHP templates. I run the
latest Emacs version (GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.35, cairo version
1.18.0) of 2024-02-17
) which ships with Eglot, the built-in Emacs Client
for LSP servers. A local copy of the PHP manual is installed inside my GNU Emacs user directory and served by a Simple http server in Rust.
To make working with project files easier I define a PHP project type. This project type allows me to execute
project-specific commands such as finding a project file (project-find-file
or execute local tests
project-compile
.
(use-package project
:config
(setq project-find-functions
(cons #'project-try-maven
(cons #'project-try-composer project-find-functions)))
:init
(put 'project-name 'safe-local-variable 'stringp)
(put 'project-owner 'safe-local-variable 'stringp)
(defun project-try-maven (dir)
(let ((root (locate-dominating-file dir "pom.xml")))
(when root
(list 'java root))))
(cl-defmethod project-root ((project (head java)))
(nth 1 project))
(defun project-try-composer (dir)
(let ((root (locate-dominating-file dir "composer.json")))
(when root
(list 'php root))))
(cl-defmethod project-root ((project (head php)))
(nth 1 project)))
In the project definition you also see me declaring two symbols project-name
and
project-owner
as safe local variables. I use those when inserting the license blurb (defined as a Skeleton) and
define them as directory-local variables at the project root.
;;; Directory Local Variables -*- no-byte-compile: t; -*-
;;; For more information see (info "(emacs) Directory Variables")
((nil . ((project-name . "DAIA Model")
(project-owner . "Staats- und Universitätsbibliothek Hamburg"))))
Combine all this with Magit and the versality of a mature text editor & putting architecture into code is a breeze.