From 7895efc262de91144155bfbadcb9aa35654fee86 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sun, 23 Feb 2025 16:20:10 +0100 Subject: [PATCH] lisp-mode.el: A few more structural editing commands --- lisp/emacs-lisp/lisp-mode.el | 197 +++++++++++++++++++++++++++++++++-- lisp/files.el | 3 - lisp/minibuffer.el | 5 + 3 files changed, 191 insertions(+), 14 deletions(-) diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 8692402c4fc..76cb059a2a7 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -773,7 +773,8 @@ font-lock keywords will not be case sensitive." (let ((ppss (syntax-ppss))) (if (or (nth 8 ppss) (nth 5 ppss)) (self-insert-command (prefix-numeric-value arg)) - (insert-pair arg)))) + (insert-pair arg) + (save-excursion (backward-up-list) (indent-sexp))))) (defun lisp-delete-backward-1 () (delete-char -1) @@ -891,22 +892,196 @@ font-lock keywords will not be case sensitive." (insert "?\\" (read-char "Character: ")) (insert "?" char))))) +(defun lisp-close (n) + (interactive "p") + (if (nth 8 (syntax-ppss)) + (self-insert-command (prefix-numeric-value n)) + (when (nth 5 (syntax-ppss)) (forward-char)) ; foo + (up-list n) + (save-excursion (backward-char) (lisp-tidy-sexp)))) + +(defun lisp-kill-line (arg) + (interactive "P") + (cond + ((nth 3 (syntax-ppss)) + (save-restriction + (narrow-to-region + (1+ (nth 8 (syntax-ppss))) + (save-excursion + (goto-char (nth 8 (syntax-ppss))) + (forward-sexp) + (1- (point)))) + (kill-line arg))) + ((nth 4 (syntax-ppss)) + (kill-line arg)) + ((let ((beg (point)) + (eol (pos-eol))) + (if (beginning-of-defun--in-emptyish-line-p) + (kill-line arg) + (skip-syntax-forward " -") + (while (and (condition-case nil + (progn (forward-sexp) t) + (scan-error nil)) + (< (point) eol))) + (kill-region beg (point))))))) + +(defun lisp-tidy-sexp () + (interactive) + (save-excursion + (backward-up-list) + (indent-sexp) + (forward-char) + (delete-all-space) + (while (condition-case nil + (progn (forward-sexp) t) + (scan-error nil)) + (when (< fill-column (current-column)) + (backward-sexp) + (delete-horizontal-space) + (insert "\n")) + (indent-according-to-mode) + (delete-horizontal-space) + (cond + ((eq (char-after) ?\;) + (comment-indent) + (goto-char (nth 8 (syntax-ppss)))) + ((eq (char-after) ?\n)) + (t (insert " ")))) + (delete-all-space) + (when (eq (char-after) ?\;) + (comment-indent)))) + +(defun lisp-slurp-forward (n) + (interactive "p") + (save-excursion + (up-list) + (let ((close (char-before))) + (atomic-change-group + (delete-char -1) + (insert " ") + (condition-case nil + (progn (forward-sexp n) t) + (scan-error + (user-error "Not enough expressions to slurp"))) + (insert close)) + (backward-char) + (lisp-tidy-sexp)))) + +(defun lisp-slurp-backward (n) + (interactive "p") + (save-excursion + (backward-up-list) + (let ((open (char-after))) + (atomic-change-group + (delete-char 1) + (condition-case nil + (progn (backward-sexp n) t) + (scan-error + (user-error "Not enough expressions to slurp"))) + (insert open)) + (lisp-tidy-sexp)))) + +(defun lisp-barf-forward (n) + (interactive "p") + (save-excursion + (up-list) + (let ((close (char-before))) + (atomic-change-group + (delete-char -1) + (condition-case nil + (progn (backward-sexp n) t) + (scan-error + (user-error "Not enough expressions to barf"))) + (insert close)) + (lisp-tidy-sexp) + (backward-char) + (lisp-tidy-sexp)))) + +(defun lisp-barf-backward (n) + (interactive "p") + (save-excursion + (backward-up-list) + (let ((open (char-after))) + (atomic-change-group + (delete-char 1) + (condition-case nil + (progn (forward-sexp n) t) + (scan-error + (user-error "Not enough expressions to barf"))) + (insert open)) + (lisp-tidy-sexp) + (backward-char) + (lisp-tidy-sexp)))) + +(defun lisp-splice (n) + (interactive "p") + (dotimes (_ n) (save-excursion (lisp-splice-1)))) + +(defun lisp-splice-1 () + (backward-up-list) + (save-excursion (forward-sexp) (delete-char -1)) + (delete-char 1) + (lisp-tidy-sexp)) + +(defun lisp-splice-following (n) + (interactive "p") + (dotimes (_ n) + (save-excursion + (delete-region (save-excursion (backward-up-list) (1+ (point))) (point)) + (lisp-splice-1)))) + +(defun lisp-splice-preceding (n) + (interactive "p") + (dotimes (_ n) + (save-excursion + (delete-region (point) (save-excursion (up-list) (1- (point)))) + (lisp-splice-1)))) + +(defun lisp-split-sexp () + (interactive) + (let ((open (save-excursion (backward-up-list) (char-after))) + (close (save-excursion (up-list) (char-before)))) + (delete-horizontal-space) + (insert close) + (save-excursion + (insert " " open) + (backward-char) + (lisp-tidy-sexp)))) + +(defun lisp-join-sexps () + (interactive) + (save-excursion + (backward-sexp) + (forward-sexp) + (delete-char -1) + (forward-sexp) + (backward-sexp) + (delete-char 1))) + (defvar-keymap lisp-mode-shared-map :doc "Keymap for commands shared by all sorts of Lisp modes." :parent prog-mode-map - "C-M-q" #'indent-sexp - "DEL" #'lisp-delete-backward + "C-M-q" #'indent-sexp + "C-k" #'lisp-kill-line + "DEL" #'lisp-delete-backward ;; "C-d" #'lisp-delete-forward - ;; "C-k" #'lisp-kill ;; "M-d" #'lisp-kill-word-forward ;; "M-DEL" #'lisp-kill-word-backward - "?" #'lisp-character - "(" #'lisp-open - "[" #'lisp-open - ;; "]" #'lisp-close - ;; ")" #'lisp-close - "\"" #'lisp-doublequote - "\\" #'lisp-escape) + "M-r" #'raise-sexp + "M-S" #'lisp-split-sexp + "M-J" #'lisp-join-sexps + "M-" #'lisp-splice-following + "?" #'lisp-character + "C-)" #'lisp-slurp-forward + "C-(" #'lisp-slurp-backward + "C-}" #'lisp-barf-forward + "C-{" #'lisp-barf-backward + "(" #'lisp-open + ")" #'lisp-close + "[" #'lisp-open + "]" #'lisp-close + "\"" #'lisp-doublequote + "\\" #'lisp-escape) (defcustom lisp-mode-hook nil "Hook run when entering Lisp mode." diff --git a/lisp/files.el b/lisp/files.el index 445c730fbdb..b6e2d8f865c 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -3148,7 +3148,6 @@ since only a single case-insensitive search through the alist is made." ("\\.m[4c]\\'" . m4-mode) ("\\.mf\\'" . metafont-mode) ("\\.mp\\'" . metapost-mode) - ("\\.vhdl?\\'" . vhdl-mode) ("\\.article\\'" . text-mode) ("\\.letter\\'" . text-mode) ("\\.i?tcl\\'" . tcl-mode) @@ -3225,8 +3224,6 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" . ("\\.\\(?:PDF\\|EPUB\\|CBZ\\|FB2\\|O?XPS\\|DVI\\|OD[FGPST]\\|DOCX\\|XLSX?\\|PPTX?\\|pdf\\|epub\\|cbz\\|fb2\\|o?xps\\|djvu\\|dvi\\|od[fgpst]\\|docx\\|xlsx?\\|pptx?\\)\\'" . doc-view-mode-maybe) ("configure\\.\\(ac\\|in\\)\\'" . autoconf-mode) ("\\.s\\(v\\|iv\\|ieve\\)\\'" . sieve-mode) - ("BROWSE\\'" . ebrowse-tree-mode) - ("\\.ebrowse\\'" . ebrowse-tree-mode) ("#\\*mail\\*" . mail-mode) ("\\.g\\'" . antlr-mode) ("\\.mod\\'" . m2-mode) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index f05fc934da9..cdfed535d09 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1483,6 +1483,11 @@ Moves point to the end of the new text." (delete-region (point) (+ (point) length))) (forward-char suffix-len))) +(defvar completion-in-region-mode nil + "This variable is obsolete and no longer used.") + +(make-obsolete-variable 'completion-in-region-mode nil "31.1") + (defvar completion-cycle-threshold nil "This variable is obsolete and no longer used.") -- 2.39.5