From f6a91e549fe34f047acdb03e806e0f7dce9ffce1 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Wed, 5 Feb 2025 19:25:11 +0100 Subject: Upgrade markdown-mode, rust-prog-mode and yasnippet --- .emacs.d/lisp/markdown-mode.el | 17 +++++- .emacs.d/lisp/rust-prog-mode.el | 119 +++++++++++++++++++++++++++++++++++++++- .emacs.d/lisp/yasnippet.el | 42 +++++++------- 3 files changed, 155 insertions(+), 23 deletions(-) diff --git a/.emacs.d/lisp/markdown-mode.el b/.emacs.d/lisp/markdown-mode.el index 89d8962..f99897d 100644 --- a/.emacs.d/lisp/markdown-mode.el +++ b/.emacs.d/lisp/markdown-mode.el @@ -287,6 +287,13 @@ cause lag when typing on slower machines." :safe 'booleanp :package-version '(markdown-mode . "2.2")) +(defcustom markdown-wiki-link-retain-case nil + "When non-nil, wiki link file names do not have their case changed." + :group 'markdown + :type 'boolean + :safe 'booleanp + :package-version '(markdown-mode . "2.7")) + (defcustom markdown-uri-types '("acap" "cid" "data" "dav" "fax" "file" "ftp" "geo" "gopher" "http" "https" "imap" "ldap" "mailto" @@ -370,6 +377,7 @@ Math support can be enabled, disabled, or toggled later using (defcustom markdown-css-paths nil "List of URLs of CSS files to link to in the output XHTML." :group 'markdown + :safe (lambda (x) (and (listp x) (cl-every #'stringp x))) :type '(repeat (string :tag "CSS File Path"))) (defcustom markdown-content-type "text/html" @@ -5180,6 +5188,7 @@ list simply adds a blank line)." (markdown-indent-on-enter (let (bounds) (if (and (memq markdown-indent-on-enter '(indent-and-new-item)) + (not (markdown-code-block-at-point-p)) (setq bounds (markdown-cur-list-item-bounds))) (let ((beg (cl-first bounds)) (end (cl-second bounds)) @@ -7735,7 +7744,7 @@ Standalone XHTML output is identified by an occurrence of (defun markdown-stylesheet-link-string (stylesheet-path) (concat "")) @@ -8373,7 +8382,7 @@ in parent directories if ;; This function must not overwrite match data(PR #590) (let* ((basename (replace-regexp-in-string "[[:space:]\n]" markdown-link-space-sub-char name)) - (basename (if (derived-mode-p 'gfm-mode) + (basename (if (and (derived-mode-p 'gfm-mode) (not markdown-wiki-link-retain-case)) (concat (upcase (substring basename 0 1)) (downcase (substring basename 1 nil))) basename)) @@ -9091,6 +9100,10 @@ LANG is a string, and the returned major mode is a symbol." (and mode (fboundp mode) (or + (not (string-match-p "ts-mode\\'" (symbol-name mode))) + ;; Don't load tree-sitter mode if the mode is in neither auto-mode-alist nor major-mode-remap-alist + ;; Because some ts-mode overwrites auto-mode-alist and it might break user configurations + ;; https://github.com/jrblevin/markdown-mode/issues/787 ;; major-mode-remap-alist was introduced at Emacs 29.1 (cl-loop for pair in (bound-and-true-p major-mode-remap-alist) diff --git a/.emacs.d/lisp/rust-prog-mode.el b/.emacs.d/lisp/rust-prog-mode.el index 05bc5e0..6263949 100644 --- a/.emacs.d/lisp/rust-prog-mode.el +++ b/.emacs.d/lisp/rust-prog-mode.el @@ -567,7 +567,7 @@ buffer." ;; foo.bar (t (funcall skip-dot-identifier))))))) -(defun rust-mode-indent-line () +(defun rust-mode--indent-line () (interactive) (let ((indent (save-excursion @@ -769,6 +769,123 @@ buffer." (save-excursion (= (progn (goto-char pos1) (line-end-position)) (progn (goto-char pos2) (line-end-position))))) +(defun rust-mode-indent-line () + "Indent the current line, and indent code examples in comments. + +Indent the current line as `rust-mode-indent-line' does. If +point is inside a block comment containing a Markdown code +example (delimited by triple backquotes), then also indent the +current line within the code example." + (interactive) + + ;; First, reindent the current line. + (rust-mode--indent-line) + + ;; If point is inside a comment: + (let ((ppss (syntax-ppss))) + (when (nth 4 ppss) + (rust-with-comment-fill-prefix + (lambda () + (let* ((orig-buf (current-buffer)) + (orig-point (point)) + (orig-eol (line-end-position)) + (orig-bol (line-beginning-position)) + (orig-mode major-mode) + (com-start (nth 8 ppss)) + (com-prefix (replace-regexp-in-string "\\s-*\\'" "" + (or fill-prefix ""))) + (com-re (regexp-quote com-prefix)) + (cb-re (concat "^" com-re "\\(\\s-*\\)```")) + cb-start cb-pad cb-hidden-marker indented rel-point) + + ;; If point is within the prefix (not inside the comment + ;; body), don't do anything fancy. + (when (>= orig-point (+ orig-bol (length com-prefix))) + (save-excursion + ;; If we're in a // comment block, use the fill prefix to + ;; find the start of the block. If we're in a /* + ;; comment, the start is determined by ppss. + (when (string-match "^\\s-*//" com-prefix) + (setq com-start orig-bol) + (while (and (= (forward-line -1) 0) + (looking-at com-re)) + (setq com-start (point)))) + + ;; Search for ``` lines within the comment block, and + ;; identify the start of the current code block if any. + (goto-char com-start) + (while (re-search-forward cb-re orig-bol t) + (setq cb-start (unless cb-start (line-end-position)) + cb-pad (match-string 1)))) + + (when cb-start + ;; We're inside a code block. Copy preceding contents to + ;; a temporary buffer. + (with-temp-buffer + (insert-buffer-substring orig-buf cb-start orig-eol) + (forward-char (- orig-point orig-eol)) + (save-excursion + ;; For each line in the temporary buffer, remove + ;; the comment prefix, left padding if present, and + ;; hidden-line marker if present. For example, if + ;; the code block begins with: + ;; + ;; ^ /// ```$ + ;; + ;; then trim lines as follows: + ;; + ;; ^ ///$ becomes ^$ + ;; ^ /// let x = 2;$ becomes ^ let x = 2;$ + ;; ^ /// # fn main() {$ becomes ^fn main() {$ + ;; + ;; If the line we're indenting isn't a hidden line, + ;; then remove hidden lines completely - non-hidden + ;; lines are indented as if the hidden lines don't + ;; exist. + (let ((trim-re (concat com-re "\\(?:" cb-pad "\\)?" + "\\(\\s-*# \\)?"))) + (beginning-of-line) + (if (and (looking-at trim-re) (match-beginning 1)) + (setq cb-hidden-marker "# ") + (setq cb-hidden-marker "" + trim-re (concat com-re "\\(?:" cb-pad "\\)?" + "\\(\\s-*# .*\\)?"))) + + (goto-char (point-min)) + (while (not (eobp)) + (when (looking-at trim-re) + (delete-region (point) (match-end 0))) + (forward-line 1)))) + + ;; Reindent the line. Copy local settings from the + ;; parent buffer, but disable indent-tabs-mode unless + ;; it is enabled in the parent buffer and the code + ;; block is already tab-aligned. + (funcall orig-mode) + (mapc (lambda (v) + (when (custom-variable-p (or (car-safe v) v)) + (if (symbolp v) + (makunbound (make-local-variable v)) + (set (make-local-variable (car v)) (cdr v))))) + (buffer-local-variables orig-buf)) + (or (string-suffix-p "\t" cb-pad) + (= 0 (length com-prefix) (length cb-pad)) + (setq-local indent-tabs-mode nil)) + (rust-mode--indent-line) + + ;; Extract the indented line and copy back into the + ;; original buffer. + (setq rel-point (- (point) (point-max))) + (beginning-of-line) + (setq indented + (concat com-prefix cb-pad cb-hidden-marker + (buffer-substring (point) (point-max))))) + (goto-char orig-eol) + (unless (equal indented (buffer-substring orig-bol orig-eol)) + (delete-region orig-bol orig-eol) + (insert indented)) + (forward-char rel-point))))))))) + ;;; Font-locking definitions and helpers (defun rust-next-string-interpolation (limit) diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el index 782c440..602e74e 100644 --- a/.emacs.d/lisp/yasnippet.el +++ b/.emacs.d/lisp/yasnippet.el @@ -1,6 +1,6 @@ ;;; yasnippet.el --- Yet another snippet extension for Emacs -*- lexical-binding: t; -*- -;; Copyright (C) 2008-2024 Free Software Foundation, Inc. +;; Copyright (C) 2008-2025 Free Software Foundation, Inc. ;; Authors: pluskid , ;; João Távora , ;; Noam Postavsky @@ -1000,7 +1000,7 @@ Honour `yas-dont-activate-functions', which see." ;;; Major mode stuff (defvar yas--font-lock-keywords - (append '(("^#.*$" . font-lock-comment-face)) + (append '(("^#.*$" (0 'font-lock-comment-face))) (with-temp-buffer (let ((prog-mode-hook nil) (emacs-lisp-mode-hook nil)) @@ -1011,14 +1011,14 @@ Honour `yas-dont-activate-functions', which see." (cadr font-lock-keywords) font-lock-keywords)) '(("\\$\\([0-9]+\\)" - (0 font-lock-keyword-face) - (1 font-lock-string-face t)) + (0 'font-lock-keyword-face) + (1 'font-lock-string-face t)) ("\\${\\([0-9]+\\):?" - (0 font-lock-keyword-face) - (1 font-lock-warning-face t)) - ("\\(\\$(\\)" 1 font-lock-preprocessor-face) + (0 'font-lock-keyword-face) + (1 'font-lock-warning-face t)) + ("\\(\\$(\\)" 1 'font-lock-preprocessor-face) ("}" - (0 font-lock-keyword-face))))) + (0 'font-lock-keyword-face))))) (defvar snippet-mode-map (let ((map (make-sparse-keymap))) @@ -2784,18 +2784,20 @@ Return the `yas--template' object created" (defun yas-maybe-load-snippet-buffer () "Added to `after-save-hook' in `snippet-mode'." - (let* ((mode (intern (file-name-sans-extension - (file-name-nondirectory - (directory-file-name default-directory))))) - (current-snippet - (apply #'yas--define-snippets-2 (yas--table-get-create mode) - (yas--parse-template buffer-file-name))) - (uuid (yas--template-uuid current-snippet))) - (unless (equal current-snippet - (if uuid (yas--get-template-by-uuid mode uuid) - (yas--lookup-snippet-1 - (yas--template-name current-snippet) mode))) - (yas-load-snippet-buffer mode t)))) + (save-excursion ;; Issue #1146. Here or in `yas--parse-template`? + (let* ((mode (intern (file-name-sans-extension + (file-name-nondirectory + (directory-file-name default-directory))))) + (current-snippet + (apply #'yas--define-snippets-2 (yas--table-get-create mode) + ;; FIXME: `yas-load-snippet-buffer' will *re*parse! + (yas--parse-template buffer-file-name))) + (uuid (yas--template-uuid current-snippet))) + (unless (equal current-snippet + (if uuid (yas--get-template-by-uuid mode uuid) + (yas--lookup-snippet-1 + (yas--template-name current-snippet) mode))) + (yas-load-snippet-buffer mode t))))) (defun yas-load-snippet-buffer-and-close (table &optional kill) "Load and save the snippet, then `quit-window' if saved. -- cgit v1.3