134 lines
4.6 KiB
EmacsLisp
134 lines
4.6 KiB
EmacsLisp
;;; lisp-custom.el --- Customisations for working with lisp -*- lexical-binding: t -*-
|
||
|
||
;; This file is not part of GNU Emacs
|
||
|
||
;; This program is free software: you can redistribute it and/or modify
|
||
;; it under the terms of the GNU General Public License as published by
|
||
;; the Free Software Foundation, either version 3 of the License, or
|
||
;; (at your option) any later version.
|
||
|
||
;; This program is distributed in the hope that it will be useful,
|
||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
;; GNU General Public License for more details.
|
||
|
||
;; You should have received a copy of the GNU General Public License
|
||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
|
||
;;; Commentary:
|
||
|
||
;; commentary
|
||
|
||
;;; Code:
|
||
|
||
;; Paredit my beloved
|
||
(use-package paredit
|
||
:hook ((emacs-lisp-mode . enable-paredit-mode)
|
||
(eval-expression-minibuffer-setup . enable-paredit-mode)
|
||
(lisp-mode . enable-paredit-mode)
|
||
(lisp-interaction-mode . enable-paredit-mode)
|
||
(scheme-mode . enable-paredit-mode))
|
||
:config
|
||
(add-hook 'ielm-mode-hook (lambda ()
|
||
(enable-paredit-mode)
|
||
;; This fixes newline behavior in IELM, but breaks it everywhere else, hence it's wrapped here
|
||
(define-key paredit-mode-map (kbd "RET") nil)
|
||
(define-key paredit-mode-map (kbd "C-j") 'paredit-newline))))
|
||
|
||
;; Slimey
|
||
(use-package slime
|
||
:config
|
||
(setq inferior-lisp-program "sbcl"))
|
||
|
||
;; Scheme (with Chickens)
|
||
(use-package geiser
|
||
:config
|
||
;; Auto-start the geiser repl
|
||
(setq geiser-mode-start-repl-p t)
|
||
|
||
;; Put geiser in the bottom
|
||
(add-to-list 'display-buffer-alist
|
||
'("\\*Geiser .* REPL"
|
||
(display-buffer-in-side-window)
|
||
(side . bottom)
|
||
(slot . 1)
|
||
(window-height . 0.2)))
|
||
(add-to-list 'display-buffer-alist
|
||
`("\\*Geiser Documentation"
|
||
(display-buffer-in-side-window)
|
||
(side . ,(if (equal system-type 'android) 'bottom 'right))
|
||
(slot . ,(if (equal system-type 'android) 0 3))
|
||
(window-height . 0.2)))
|
||
(add-to-list 'display-buffer-alist
|
||
`("\\*Geiser Debug"
|
||
(display-buffer-in-side-window)
|
||
(side . ,(if (equal system-type 'android) 'bottom 'right))
|
||
(slot . ,(if (equal system-type 'android) 0 4))
|
||
(window-height . 0.2))))
|
||
|
||
(defcustom chicken-doc-repository ""
|
||
"Custom location for the chicken-doc repository."
|
||
:type 'string
|
||
:group 'scheme
|
||
:group 'geiser)
|
||
|
||
(use-package geiser-chicken
|
||
:after (geiser)
|
||
:config
|
||
(setenv "CHICKEN_DOC_REPOSITORY" chicken-doc-repository)
|
||
|
||
;; Annoying BS to prevent inline C code from fucking with the syntax table
|
||
;; This is really hacky and doesn't truly work properly especially with auto-indent
|
||
(defun scheme-propertize-chicken-comment (start)
|
||
"Find the matching <# for a #> at START and mark the whole region as a comment."
|
||
(save-excursion
|
||
(goto-char start)
|
||
(let ((pos (point)))
|
||
(if (re-search-forward "<#" nil t)
|
||
(progn
|
||
(put-text-property pos (point) 'syntax-table (string-to-syntax "< c"))
|
||
(put-text-property pos (1+ pos) 'syntax-table (string-to-syntax "<"))
|
||
(put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax ">")))
|
||
;; no matching <# found – maybe just mark the #> as invalid
|
||
(put-text-property pos (1+ pos) 'syntax-table (string-to-syntax "'"))))))
|
||
|
||
(defun chicken-scheme-syntax-propertize (start end)
|
||
"Extend scheme-syntax-propertize to also handle #> ... <#."
|
||
(goto-char start)
|
||
(funcall
|
||
(syntax-propertize-rules
|
||
("#>" (0 (ignore (scheme-propertize-chicken-comment (match-beginning 0)))))
|
||
("<#" (0 (ignore (scheme-propertize-chicken-comment (match-beginning 0)))))
|
||
)
|
||
start end))
|
||
|
||
;; Replace the default scheme-syntax-propertize when chicken is being used
|
||
(add-hook 'scheme-mode-hook
|
||
(lambda ()
|
||
(when (memq 'chicken geiser-active-implementations)
|
||
(setq-local syntax-propertize-function #'chicken-scheme-syntax-propertize)
|
||
(syntax-propertize (point-max)))))
|
||
|
||
;; Modifications for chicken
|
||
;; Indent module contents at column 0
|
||
(defun scheme-module-indent (state indent-point normal-indent) 0)
|
||
(put 'module 'scheme-indent-function 'scheme-module-indent)
|
||
|
||
(put 'and-let* 'scheme-indent-function 1)
|
||
(put 'parameterize 'scheme-indent-function 1)
|
||
(put 'handle-exceptions 'scheme-indent-function 1)
|
||
(put 'when 'scheme-indent-function 1)
|
||
(put 'unless 'scheme-indent-function 1)
|
||
(put 'match 'scheme-indent-function 1))
|
||
|
||
(use-package geiser-racket
|
||
:after (geiser))
|
||
|
||
;; SICP my beloved
|
||
(use-package sicp
|
||
:ensure t)
|
||
|
||
(provide 'lisp-custom)
|
||
|
||
;;; lisp-custom.el ends here
|