From 32d6065654ea0b582774cbfda318a79babcffd2b Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Tue, 10 Aug 2021 21:49:01 +0200 Subject: Update markdown-mode and yaml-mode --- .emacs.d/lisp/markdown-mode.el | 234 +++++++++++++++++++++++++---------------- .emacs.d/lisp/yaml-mode.el | 4 + 2 files changed, 147 insertions(+), 91 deletions(-) diff --git a/.emacs.d/lisp/markdown-mode.el b/.emacs.d/lisp/markdown-mode.el index 502eb26..b42760e 100644 --- a/.emacs.d/lisp/markdown-mode.el +++ b/.emacs.d/lisp/markdown-mode.el @@ -47,8 +47,10 @@ (defvar jit-lock-end) (defvar flyspell-generic-check-word-predicate) (defvar electric-pair-pairs) +(defvar sh-ancestor-alist) (declare-function project-roots "project") +(declare-function sh-set-shell "sh-script") ;;; Constants ================================================================= @@ -498,7 +500,7 @@ If this value is 'any and `display-buffer-alist' is set then :package-version '(markdown-mode . "2.2")) (defcustom markdown-live-preview-window-function - 'markdown-live-preview-window-eww + #'markdown-live-preview-window-eww "Function to display preview of Markdown output within Emacs. Function must update the buffer containing the preview and return the buffer." @@ -617,7 +619,14 @@ requires Emacs to be built with ImageMagick support." "Non-nil means mouse on a link will follow the link. This variable must be set before loading markdown-mode." :group 'markdown - :type 'bool + :type 'boolean + :safe 'booleanp + :package-version '(markdown-mode . "2.5")) + +(defcustom markdown-table-align-p t + "Non-nil means that table is aligned after table operation." + :group 'markdown + :type 'boolean :safe 'booleanp :package-version '(markdown-mode . "2.5")) @@ -1098,9 +1107,16 @@ Function is called repeatedly until it returns nil. For details, see (max end (match-beginning 0)) (point-max)))) (code-match (markdown-code-block-at-pos new-start)) - (new-start (or (and code-match (cl-first code-match)) new-start)) - (code-match (and (< end (point-max)) (markdown-code-block-at-pos end))) - (new-end (or (and code-match (cl-second code-match)) new-end))) + ;; FIXME: The `code-match' can return bogus values + ;; when text has been inserted/deleted! + (new-start (min (or (and code-match (cl-first code-match)) + (point-max)) + new-start)) + (code-match (and (< end (point-max)) + (markdown-code-block-at-pos end))) + (new-end (max (or (and code-match (cl-second code-match)) 0) + new-end))) + (unless (and (eq new-start start) (eq new-end end)) (cons new-start (min new-end (point-max)))))))) @@ -1536,7 +1552,8 @@ MIDDLE-BEGIN is the start of the \"middle\" section of the block." (cl-third fence-spec) (list middle-begin close-begin)) ;; If the block is a YAML block, propertize the declarations inside - (markdown-syntax-propertize-yaml-metadata middle-begin close-begin) + (when (< middle-begin close-begin) ;; workaround #634 + (markdown-syntax-propertize-yaml-metadata middle-begin close-begin)) ;; Propertize closing line of fenced block. (put-text-property close-begin close-end (cl-cadadr fence-spec) close-data)))) @@ -1969,7 +1986,7 @@ When non-nil, `markdown-header-face' will inherit from `markdown-header-scaling-values' will be applied to headers of levels one through six respectively." :type 'boolean - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :set (lambda (symbol value) (set-default symbol value) (markdown-update-header-faces value)) @@ -1981,37 +1998,39 @@ headers of levels one through six respectively." "List of scaling values for headers of level one through six. Used when `markdown-header-scaling' is non-nil." :type 'list - :initialize 'custom-initialize-default + :initialize #'custom-initialize-default :set (lambda (symbol value) (set-default symbol value) - (markdown-update-header-faces markdown-header-scaling value)) - :group 'markdown-faces) - -(defun markdown-make-header-faces () - "Build the faces used for Markdown headers." - (let ((inherit-faces '(font-lock-function-name-face))) - (when markdown-header-scaling - (setq inherit-faces (cons 'variable-pitch inherit-faces))) - (defface markdown-header-face - `((t (:inherit ,inherit-faces :weight bold))) - "Base face for headers." - :group 'markdown-faces)) - (dotimes (num 6) - (let* ((num1 (1+ num)) - (face-name (intern (format "markdown-header-face-%s" num1))) - (scale (if markdown-header-scaling - (float (nth num markdown-header-scaling-values)) - 1.0))) - (eval - `(defface ,face-name - '((t (:inherit markdown-header-face :height ,scale))) - (format "Face for level %s headers. + (markdown-update-header-faces markdown-header-scaling value))) + +(defmacro markdown--dotimes-when-compile (i-n body) + (declare (indent 1) (debug ((symbolp form) form))) + (let ((var (car i-n)) + (n (cadr i-n)) + (code ())) + (dotimes (i (eval n t)) + (push (eval body `((,var . ,i))) code)) + `(progn ,@(nreverse code)))) + +(defface markdown-header-face + `((t (:inherit (,@(when markdown-header-scaling '(variable-pitch)) + font-lock-function-name-face) + :weight bold))) + "Base face for headers.") + +(markdown--dotimes-when-compile (num 6) + (let* ((num1 (1+ num)) + (face-name (intern (format "markdown-header-face-%s" num1)))) + `(defface ,face-name + (,'\` ((t (:inherit markdown-header-face + :height + (,'\, (if markdown-header-scaling + (float (nth ,num markdown-header-scaling-values)) + 1.0)))))) + (format "Face for level %s headers. You probably don't want to customize this face directly. Instead you can customize the base face `markdown-header-face' or the -variable-height variable `markdown-header-scaling'." ,num1) - :group 'markdown-faces))))) - -(markdown-make-header-faces) +variable-height variable `markdown-header-scaling'." ,num1)))) (defun markdown-update-header-faces (&optional scaling scaling-values) "Update header faces, depending on if header SCALING is desired. @@ -3299,17 +3318,24 @@ Group 7: closing filename delimiter" ;;; Markdown Font Fontification Functions ===================================== +(defvar markdown--first-displayable-cache (make-hash-table :test #'equal)) + (defun markdown--first-displayable (seq) "Return the first displayable character or string in SEQ. SEQ may be an atom or a sequence." - (let ((seq (if (listp seq) seq (list seq)))) - (cond ((stringp (car seq)) - (cl-find-if - (lambda (str) - (and (mapcar #'char-displayable-p (string-to-list str)))) - seq)) - ((characterp (car seq)) - (cl-find-if #'char-displayable-p seq))))) + (let ((c (gethash seq markdown--first-displayable-cache t))) + (if (not (eq c t)) + c + (puthash seq + (let ((seq (if (listp seq) seq (list seq)))) + (cond ((stringp (car seq)) + (cl-find-if + (lambda (str) + (and (mapcar #'char-displayable-p (string-to-list str)))) + seq)) + ((characterp (car seq)) + (cl-find-if #'char-displayable-p seq)))) + markdown--first-displayable-cache)))) (defun markdown--marginalize-string (level) "Generate atx markup string of given LEVEL for left margin." @@ -3394,7 +3420,8 @@ SEQ may be an atom or a sequence." (defun markdown-fontify-list-items (last) "Apply font-lock properties to list markers from point to LAST." - (when (markdown-match-list-items last) + (when (and (markdown-match-list-items last) + (not (markdown-code-block-at-point-p (match-beginning 2)))) (let* ((indent (length (match-string-no-properties 1))) (level (/ indent markdown-list-indent-width)) ;; level = 0, 1, 2, ... (bullet (nth (mod level (length markdown-list-item-bullets)) @@ -4890,7 +4917,7 @@ duplicate positions, which are handled up by calling functions." ;; Return reversed list (reverse positions))) -(defun markdown-enter-key () +(defun markdown-enter-key () ;FIXME: Partly obsoleted by electric-indent "Handle RET depending on the context. If the point is at a table, move to the next row. Otherwise, indent according to value of `markdown-indent-on-enter'. @@ -5097,7 +5124,7 @@ Handle all elements of `markdown-complete-alist' in order." (interactive "*") (let ((list markdown-complete-alist) found changed) (while list - (let ((regexp (eval (caar list))) + (let ((regexp (eval (caar list) t)) ;FIXME: Why `eval'? (function (cdar list))) (setq list (cdr list)) (when (thing-at-point-looking-at regexp) @@ -5117,7 +5144,7 @@ match." (let ((end-marker (set-marker (make-marker) end)) previous) (dolist (element markdown-complete-alist) - (let ((regexp (eval (car element))) + (let ((regexp (eval (car element) t)) ;FIXME: Why `eval'? (function (cdr element))) (goto-char beg) (while (re-search-forward regexp end-marker 'limit) @@ -5324,14 +5351,16 @@ Assumes match data is available for `markdown-regex-italic'." (define-key map (kbd "C-c C-d") 'markdown-do) (define-key map (kbd "C-c '") 'markdown-edit-code-block) ;; Indentation - (define-key map (kbd "C-m") 'markdown-enter-key) + (define-key map (kbd "RET") 'markdown-enter-key) (define-key map (kbd "DEL") 'markdown-outdent-or-delete) (define-key map (kbd "C-c >") 'markdown-indent-region) (define-key map (kbd "C-c <") 'markdown-outdent-region) ;; Visibility cycling (define-key map (kbd "TAB") 'markdown-cycle) - (define-key map (kbd "") 'markdown-shifttab) - (define-key map (kbd "") 'markdown-shifttab) + ;; S-iso-lefttab and S-tab should both be mapped to `backtab' by + ;; (local-)function-key-map. + ;;(define-key map (kbd "") 'markdown-shifttab) + ;;(define-key map (kbd "") 'markdown-shifttab) (define-key map (kbd "") 'markdown-shifttab) ;; Heading and list navigation (define-key map (kbd "C-c C-n") 'markdown-outline-next) @@ -5682,6 +5711,7 @@ See `imenu-create-index-function' and `imenu--index-alist' for details." (setcdr sibling-alist alist) (setq cur-alist alist)) (setq cur-level level))))) + (setq root (copy-tree root)) ;; Footnotes (let ((fn (markdown-get-defined-footnotes))) (if (or (zerop (length fn)) @@ -7031,8 +7061,8 @@ ones already marked." (goto-char (mark)) (markdown-forward-paragraph) (point))) - (let ((beginning-of-defun-function 'markdown-backward-paragraph) - (end-of-defun-function 'markdown-forward-paragraph)) + (let ((beginning-of-defun-function #'markdown-backward-paragraph) + (end-of-defun-function #'markdown-forward-paragraph)) (mark-defun)))) (defun markdown-mark-block () @@ -7050,16 +7080,16 @@ ones already marked." (goto-char (mark)) (markdown-forward-block) (point))) - (let ((beginning-of-defun-function 'markdown-backward-block) - (end-of-defun-function 'markdown-forward-block)) + (let ((beginning-of-defun-function #'markdown-backward-block) + (end-of-defun-function #'markdown-forward-block)) (mark-defun)))) (defun markdown-narrow-to-block () "Make text outside current block invisible. The current block is the one that contains point or follows point." (interactive) - (let ((beginning-of-defun-function 'markdown-backward-block) - (end-of-defun-function 'markdown-forward-block)) + (let ((beginning-of-defun-function #'markdown-backward-block) + (end-of-defun-function #'markdown-forward-block)) (narrow-to-defun))) (defun markdown-mark-text-block () @@ -7077,8 +7107,8 @@ ones already marked." (goto-char (mark)) (markdown-end-of-text-block) (point))) - (let ((beginning-of-defun-function 'markdown-beginning-of-text-block) - (end-of-defun-function 'markdown-end-of-text-block)) + (let ((beginning-of-defun-function #'markdown-beginning-of-text-block) + (end-of-defun-function #'markdown-end-of-text-block)) (mark-defun)))) (defun markdown-mark-page () @@ -7097,16 +7127,16 @@ ones already marked." (goto-char (mark)) (markdown-forward-page) (point))) - (let ((beginning-of-defun-function 'markdown-backward-page) - (end-of-defun-function 'markdown-forward-page)) + (let ((beginning-of-defun-function #'markdown-backward-page) + (end-of-defun-function #'markdown-forward-page)) (mark-defun)))) (defun markdown-narrow-to-page () "Make text outside current top level section invisible. The current section is the one that contains point or follows point." (interactive) - (let ((beginning-of-defun-function 'markdown-backward-page) - (end-of-defun-function 'markdown-forward-page)) + (let ((beginning-of-defun-function #'markdown-backward-page) + (end-of-defun-function #'markdown-forward-page)) (narrow-to-defun))) (defun markdown-mark-subtree () @@ -7731,15 +7761,17 @@ returns nil." (process-file markdown-open-image-command nil nil nil link-file)) (find-file link-file))))))) -(defun markdown-follow-link-at-point () - "Open the current non-wiki link. +(defun markdown-follow-link-at-point (&optional event) + "Open the non-wiki link at point or EVENT. If the link is a complete URL, open in browser with `browse-url'. Otherwise, open with `find-file' after stripping anchor and/or query string. Translate filenames using `markdown-filename-translate-function'." - (interactive) - (if (markdown-link-p) - (markdown--browse-url (markdown-link-url)) - (user-error "Point is not at a Markdown link or URL"))) + (interactive (list last-command-event)) + (save-excursion + (if event (posn-set-point (event-start event))) + (if (markdown-link-p) + (markdown--browse-url (markdown-link-url)) + (user-error "Point is not at a Markdown link or URL")))) (defun markdown-fontify-inline-links (last) "Add text properties to next inline link from point to LAST." @@ -8117,9 +8149,9 @@ These are only enabled when `markdown-wiki-link-fontify-missing' is non-nil." (if (and markdown-enable-wiki-links markdown-wiki-link-fontify-missing) (add-hook 'after-change-functions - 'markdown-check-change-for-wiki-link-after-change t t) + #'markdown-check-change-for-wiki-link-after-change t t) (remove-hook 'after-change-functions - 'markdown-check-change-for-wiki-link-after-change t)) + #'markdown-check-change-for-wiki-link-after-change t)) ;; If we left the buffer there is a really good chance we were ;; creating one of the wiki link documents. Make sure we get ;; refontified when we come back. @@ -8127,10 +8159,10 @@ These are only enabled when `markdown-wiki-link-fontify-missing' is non-nil." markdown-wiki-link-fontify-missing) (progn (add-hook 'window-configuration-change-hook - 'markdown-fontify-buffer-wiki-links t t) + #'markdown-fontify-buffer-wiki-links t t) (markdown-fontify-buffer-wiki-links)) (remove-hook 'window-configuration-change-hook - 'markdown-fontify-buffer-wiki-links t) + #'markdown-fontify-buffer-wiki-links t) (markdown-unfontify-region-wiki-links (point-min) (point-max)))) @@ -8593,7 +8625,7 @@ mode to use. The language to mode mapping may be customized by setting the variable `markdown-code-lang-modes'." :group 'markdown :type 'boolean - :safe 'booleanp + :safe #'booleanp :package-version '(markdown-mode . "2.3")) (defcustom markdown-fontify-code-block-default-mode nil @@ -8756,6 +8788,15 @@ at the END of code blocks." (lambda (_parent-buffer _beg _end) (funcall mode))) (indirect-buf (edit-indirect-region begin end 'display-buffer))) + ;; reset `sh-shell' when indirect buffer + (when (and (not (member system-type '(ms-dos windows-nt))) + (member mode '(shell-script-mode sh-mode)) + (member lang (append + (mapcar (lambda (e) (symbol-name (car e))) + sh-ancestor-alist) + '("csh" "rc" "sh")))) + (with-current-buffer indirect-buf + (sh-set-shell lang))) (when (> indentation 0) ;; un-indent in edit-indirect buffer (with-current-buffer indirect-buf (indent-rigidly (point-min) (point-max) (- indentation))))) @@ -8837,7 +8878,7 @@ This version removes characters with invisibility property ;; Functions for maintaining tables -(defvar markdown-table-at-point-p-function nil +(defvar markdown-table-at-point-p-function #'markdown--table-at-point-p "Function to decide if point is inside a table. The indirection serves to differentiate between standard markdown @@ -8854,9 +8895,7 @@ tables and gfm tables which are less strict about the markup.") (defun markdown-table-at-point-p () "Return non-nil when point is inside a table." - (if (functionp markdown-table-at-point-p-function) - (funcall markdown-table-at-point-p-function) - (markdown--table-at-point-p))) + (funcall markdown-table-at-point-p-function)) (defun markdown--table-at-point-p () "Return non-nil when point is inside a table." @@ -8961,7 +9000,8 @@ This function assumes point is on a table." (save-excursion (beginning-of-line) (while (search-forward "|" pos t) - (unless (markdown--thing-at-wiki-link (match-beginning 0)) + (when (and (not (looking-back "\\\\|" (line-beginning-position))) + (not (markdown--thing-at-wiki-link (match-beginning 0)))) (setq cnt (1+ cnt))))) cnt)) @@ -9000,7 +9040,8 @@ table." (beginning-of-line 1) (when (> n 0) (while (and (> n 0) (search-forward "|" (point-at-eol) t)) - (unless (markdown--thing-at-wiki-link (match-beginning 0)) + (when (and (not (looking-back "\\\\|" (line-beginning-position))) + (not (markdown--thing-at-wiki-link (match-beginning 0)))) (cl-decf n))) (if on-delim (backward-char 1) @@ -9203,7 +9244,8 @@ With optional argument UP, move it up." (insert "| ")) (forward-line))) (set-marker end nil) - (markdown-table-align))) + (when markdown-table-align-p + (markdown-table-align)))) (defun markdown-table-delete-column () "Delete column at point from table." @@ -9217,12 +9259,13 @@ With optional argument UP, move it up." (goto-char begin) (while (< (point) end) (markdown-table-goto-column col t) - (and (looking-at "|[^|\n]+|") + (and (looking-at "|\\(?:\\\\|\\|[^|\n]\\)+|") (replace-match "|")) (forward-line))) (set-marker end nil) (markdown-table-goto-column (max 1 (1- col))) - (markdown-table-align))) + (when markdown-table-align-p + (markdown-table-align)))) (defun markdown-table-move-column (&optional left) "Move table column at point to the right. @@ -9243,12 +9286,13 @@ With optional argument LEFT, move it to the left." (goto-char begin) (while (< (point) end) (markdown-table-goto-column col1 t) - (when (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|") + (when (looking-at "|\\(\\(?:\\\\|\\|[^|\n]\\|\\)+\\)|\\(\\(?:\\\\|\\|[^|\n]\\|\\)+\\)|") (replace-match "|\\2|\\1|")) (forward-line))) (set-marker end nil) (markdown-table-goto-column colpos) - (markdown-table-align))) + (when markdown-table-align-p + (markdown-table-align)))) (defun markdown-table-move-column-left () "Move table column at point to the left." @@ -9269,7 +9313,8 @@ Create new table lines if required." (if (or (looking-at "[ \t]*$") (save-excursion (skip-chars-backward " \t") (bolp))) (newline) - (markdown-table-align) + (when markdown-table-align-p + (markdown-table-align)) (let ((col (markdown-table-get-column))) (beginning-of-line 2) (if (or (not (markdown-table-at-point-p)) @@ -9287,7 +9332,8 @@ Create new table lines if required." (interactive) (unless (markdown-table-at-point-p) (user-error "Not at a table")) - (markdown-table-align) + (when markdown-table-align-p + (markdown-table-align)) (let ((end (markdown-table-end))) (when (markdown-table-hline-at-point-p) (end-of-line 1)) (condition-case nil @@ -9310,7 +9356,8 @@ Create new table lines if required." (interactive) (unless (markdown-table-at-point-p) (user-error "Not at a table")) - (markdown-table-align) + (when markdown-table-align-p + (markdown-table-align)) (when (markdown-table-hline-at-point-p) (beginning-of-line 1)) (condition-case nil (progn @@ -9366,7 +9413,8 @@ Horizontal separator lines will be eliminated." contents ""))) (markdown-table-goto-dline col_old) (markdown-table-goto-column dline_old)) - (markdown-table-align)) + (when markdown-table-align-p + (markdown-table-align))) (defun markdown-table-sort-lines (&optional sorting-type) "Sort table lines according to the column at point. @@ -9505,7 +9553,8 @@ spaces, or alternatively a TAB should be used as the separator." (t (error "Invalid cell separator")))) (while (re-search-forward re end t) (replace-match "| " t t))) (goto-char begin) - (markdown-table-align))) + (when markdown-table-align-p + (markdown-table-align)))) (defun markdown-insert-table (&optional rows columns align) "Insert an empty pipe table. @@ -9594,6 +9643,9 @@ rows and columns and the column alignment." ;;;###autoload (define-derived-mode markdown-mode text-mode "Markdown" "Major mode for editing Markdown files." + (when buffer-read-only + (when (or (not (buffer-file-name)) (file-writable-p (buffer-file-name))) + (setq-local buffer-read-only nil))) ;; Natural Markdown tab width (setq tab-width 4) ;; Comments @@ -9607,7 +9659,7 @@ rows and columns and the column alignment." (setq-local sentence-end-base "[.?!…‽][]\"'”’)}»›*_`~]*") ;; Syntax (add-hook 'syntax-propertize-extend-region-functions - #'markdown-syntax-propertize-extend-region) + #'markdown-syntax-propertize-extend-region nil t) (add-hook 'jit-lock-after-change-extend-region-functions #'markdown-font-lock-extend-region-function t t) (setq-local syntax-propertize-function #'markdown-syntax-propertize) @@ -9746,7 +9798,7 @@ rows and columns and the column alignment." "Major mode for editing GitHub Flavored Markdown files." (setq markdown-link-space-sub-char "-") (setq markdown-wiki-link-search-subdirectories t) - (setq-local markdown-table-at-point-p-function 'gfm--table-at-point-p) + (setq-local markdown-table-at-point-p-function #'gfm--table-at-point-p) (add-hook 'post-self-insert-hook #'gfm--electric-pair-fence-code-block 'append t) (markdown-gfm-parse-buffer-for-languages)) @@ -9757,7 +9809,7 @@ rows and columns and the column alignment." "Enable hidden markup mode in `markdown-view-mode' and `gfm-view-mode'." :group 'markdown :type 'boolean - :safe 'booleanp) + :safe #'booleanp) (defvar markdown-view-mode-map (let ((map (make-sparse-keymap))) diff --git a/.emacs.d/lisp/yaml-mode.el b/.emacs.d/lisp/yaml-mode.el index 91db316..9d619d5 100644 --- a/.emacs.d/lisp/yaml-mode.el +++ b/.emacs.d/lisp/yaml-mode.el @@ -484,6 +484,10 @@ this will do usual adaptive fill behaviors." ;;;###autoload (add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode)) +;;;###autoload +(add-to-list 'magic-mode-alist + '("^%YAML\\s-+[0-9]+\\.[0-9]+\\(\\s-+#\\|\\s-*$\\)" . yaml-mode)) + (provide 'yaml-mode) ;;; yaml-mode.el ends here -- cgit v1.3