reddit / emacs

mode for editing .km files (The Knowledge Machine, a Lisp-based reasoning engine)

EdwardCoffin · 2022-11-15 14:32
Edit: to make it clear, I am asking whether anyone knows of a mode that would be better than lisp-mode. I'm currently using lisp-mode for [The Knowledge Machine](https://www.cs.utexas.edu/~mfkb/km.html) .km files, but it is not indenting things the way the documentation shows it. For example, this is how the handbook represents the following: (parts has (instance-of (Slot)) (domain (Physobj)) (range (Physobj)) (cardinality (1-to-N)) (inverse (part-of)) (subslots (mechanical-parts body-parts))) (mechanical-parts has (instance-of (Slot)) (superslots (parts))) (wheel-count has (instance-of (Slot)) (domain (Vehicle)) (range (Integer)) (cardinality (N-to-1))) but when I indent the region containing it in lisp-mode, I get: (parts has (instance-of (Slot)) (domain (Physobj)) (range (Physobj)) (cardinality (1-to-N)) (inverse (part-of)) (subslots (mechanical-parts body-parts))) (mechanical-parts has (instance-of (Slot)) (superslots (parts))) (wheel-count has (instance-of (Slot)) (domain (Vehicle)) (range (Integer)) (cardinality (N-to-1))) the problem (stuff pushed way out to the right) is worse for concepts that have longer names than `wheel-count`. I'm sure that there must be, if not a dedicated KM mode that I simply cannot find, an existing mode that can be customized to produce the handbook formatting, but I can't find it. Edit 2: added a couple of more example declarations, all from page 12 of the [KM user manual](https://www.cs.utexas.edu/users/mfkb/km/userman.pdf) (pdf).
usaoc · 2022-11-15 16:28
The easiest way is to put `1` to `wheel-count`’s `lisp-indent-function` property. This works the same as [`indent` declaration in `defmacro`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Indenting-Macros.html).
EdwardCoffin · 2022-11-15 16:51
The problem is wheel-count is more akin to a specific `defun`. There are 50+ such declarations in the km file I am looking at. If there was a way to cause `lisp-indent-function` to key off of the second argument in the s-exp, the `has`, I could put 1 in `has`'s `lisp-indent-function` property and that would work. Most of the declarations in a km file are of the form: (<entity name> has ;; a bunch of declarations) and (every <entity name> has ;; a bunch of declarations) I can at least get the `every` declarations with this method, but there are a lot of the former type too. I might have to just override `lisp-indent-function` with a custom version for KM, but I'd rather avoid that if possible.
usaoc · 2022-11-15 17:03
Well, it seems like [setting `lisp-indent-offset`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Indent.html) will be a better idea then? You can [set it file-locally](https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Local-Variables.html) or [define a derived mode](https://www.gnu.org/software/emacs/manual/html_node/elisp/Derived-Modes.html) that [sets it buffer-locally](https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Buffer_002dLocal.html). Otherwise you’ll have to define your own indent function.
EdwardCoffin · 2022-11-15 17:09
Perfect, thanks a lot. I just put it in the -*- header, which is way better than figuring out how to write an indent function.