:title: Using jj from Emacs
:date: 2025-12-27
:tags: jj
:identifier: 20251227T122017
:signature: 5=9
Using ``jj`` from Emacs
=======================
As I'm starting to use `jj `__ more and more, it's inevitable that I'm going to want some integration between ``jj`` and Emacs.
There are many packages already available that do this, including but not limited to
- `jujutsu.el `__
- `jj-mode `__
- `vc-jj `__
However, I want to use this as an excuse to learn how to write my own extensions/utilities for Emacs.
.. code-block:: emacs-lisp
:filename: emacs/init.el
(use-package alc-jj)
``eshell`` helpers
------------------
I'm trying to use ``eshell`` more and more, it's very cool being able to seamlessly switch between regular shell commands like ``cd``, ``ls`` etc. and calling Emacs functions like ``find-file`` or ``compile``!
.. TODO: Add bib citation for the video.
So, after seeing `this episode `__ of Álvaro Ramírez's Bending Emacs series I've been eager to find an excuse to try it out.
``jj-diff``
^^^^^^^^^^^
Rather than dumping the output of ``jj diff`` into the eshell window, wouldn't it be great to redirect it to a dedicated buffer instead?
*What, like this?*
.. code-block:: console
$ jj diff --no-pager --color never > #
Well, yes but that's a lot to type, plus the buffer is created uses ``fundamental-mode`` it would be nice to have it automatically enable ``diff-mode`` at least.
A better option would be to define my own eshell command that wrapped the underlying ``jj`` command to handle this for me.
.. code-block:: emacs-lisp
:filename: emacs/lisp/alc-jj.el
(defun eshell/jj-diff (&rest args)
"Eshell wrapper around 'jj diff'"
(let ((current-dir default-directory))
(with-current-buffer (get-buffer-create "*jj-diff*")
;; Ensure the command uses the current directory from where the command was invoked.
(setq default-directory current-dir)
;; Clear any previous content
(read-only-mode -1)
(erase-buffer)
;; Call jj, insert output into current buffer
(call-process "jj" nil t nil "diff" "--no-pager" "--color" "never")
(diff-mode)
;; Re-enable read-only mode and show the buffer
(read-only-mode)
(pop-to-buffer (current-buffer)))))
.. code-block:: emacs-lisp
:filename: emacs/lisp/alc-jj.el
(provide 'alc-jj)