|
| 1 | +;;; racket-lisp-mode.el -*- lexical-binding: t; -*- |
| 2 | + |
| 3 | +;; Copyright (c) 2013-2024 by Greg Hendershott. |
| 4 | +;; Portions Copyright (C) 1985-1986, 1999-2013 Free Software Foundation, Inc. |
| 5 | + |
| 6 | +;; Author: Greg Hendershott |
| 7 | +;; URL: https://github.com/greghendershott/racket-mode |
| 8 | + |
| 9 | +;; SPDX-License-Identifier: GPL-3.0-or-later |
| 10 | + |
| 11 | +;; 1. Some packages like paredit and lispy directly call `lisp-mode' |
| 12 | +;; functions `lisp-indent-line' and `indent-sexp'. (As opposed to |
| 13 | +;; calling functions like `indent-line-to' and `prog-indent-sexp' |
| 14 | +;; that a mode can specialize via `indent-line-function' and |
| 15 | +;; `indent-region-function'.) |
| 16 | +;; |
| 17 | +;; 2. Although that's OK for modes like `scheme-mode' that are derived |
| 18 | +;; from `lisp-mode', `racket-mode' is not. |
| 19 | +;; |
| 20 | +;; Therefore if users want to use such packages hardwired to call |
| 21 | +;; those two `lisp-mode' function, AFAICT we have no choice but to |
| 22 | +;; advise those two functions. :( |
| 23 | +;; |
| 24 | +;; Furthermore lisp-mode's `indent-sexp' differs from |
| 25 | +;; `prog-indent-sexp' as explained below in the doc string for |
| 26 | +;; `racket-indent-sexp-contents'. |
| 27 | + |
| 28 | +(require 'lisp-mode) |
| 29 | +(require 'racket-util) |
| 30 | + |
| 31 | +(defun racket--lisp-indent-line-advice (orig &rest args) |
| 32 | + "If `racket--mode-edits-racket-p' use the variable `indent-line-function'." |
| 33 | + (apply (if (racket--mode-edits-racket-p) indent-line-function orig) |
| 34 | + args)) |
| 35 | +(advice-add 'lisp-indent-line :around #'racket--lisp-indent-line-advice) |
| 36 | + |
| 37 | +(defun racket--indent-sexp-advice (orig &rest args) |
| 38 | + "If `racket--mode-edits-racket-p' use `racket-indent-sexp-contents'." |
| 39 | + (apply (if (racket--mode-edits-racket-p) #'racket-indent-sexp-contents orig) |
| 40 | + args)) |
| 41 | +(advice-add 'indent-sexp :around #'racket--indent-sexp-advice) |
| 42 | + |
| 43 | +(defun racket-indent-sexp-contents () |
| 44 | + "Indent each line of the sexp starting just after point. |
| 45 | +
|
| 46 | +Unlike `prog-indent-sexp', which indents the entire sexp, this |
| 47 | +does /not/ indent the first line, at point, just subsequent lines |
| 48 | +if any. In other words it does not indent the sexp as a whole, |
| 49 | +just its contents. In this regard it is similar to the |
| 50 | +`lisp-mode'-specific function `indent-sexp'." |
| 51 | + (interactive) |
| 52 | + (let ((beg-of-2nd-line (save-excursion (forward-line 1) (point))) |
| 53 | + (end-of-expression (save-excursion (forward-sexp 1) (point)))) |
| 54 | + (when (< beg-of-2nd-line end-of-expression) |
| 55 | + (indent-region beg-of-2nd-line end-of-expression)))) |
| 56 | + |
| 57 | +(provide 'racket-lisp-mode) |
| 58 | + |
| 59 | +;; racket-lisp-mode.el ends here |
0 commit comments