branch: elpa/markdown-mode commit c6ac7447694eead585094da178f4b79d78afcc3f Merge: 7eb83053e4 74a695debb Author: Shohei YOSHIDA <syo...@gmail.com> Commit: GitHub <nore...@github.com>
Merge pull request #914 from knu/feat/edit-code-block-preserve-point Preserve the cursor position when entering and exiting `markdown-edit-code-block` --- CHANGES.md | 1 + markdown-mode.el | 77 +++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 53d3881294..6ec0fd4df6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ - Added cmark and cmark-gfm to the markdown command list. - Disable `imenu-submenus-on-top` by default [GH-882][] - Add $%*+/<=>_|&' to the markdown-mode syntax table as punctuation. + - Preserve the cursor position when entering and exiting `markdown-edit-code-block`. [gh-847]: https://github.com/jrblevin/markdown-mode/issues/847 [gh-861]: https://github.com/jrblevin/markdown-mode/pull/861 diff --git a/markdown-mode.el b/markdown-mode.el index 5de66b3867..a432093823 100644 --- a/markdown-mode.el +++ b/markdown-mode.el @@ -9324,6 +9324,37 @@ position." (require 'edit-indirect nil t) (defvar edit-indirect-guess-mode-function) (defvar edit-indirect-after-commit-functions) +(defvar edit-indirect--overlay) +(declare-function edit-indirect-commit "edit-indirect") +(declare-function edit-indirect--commit "edit-indirect") + +(defvar-local markdown--edit-indirect-committed-position nil) + +(defun markdown--edit-indirect-save-committed-position () + "Set where editing is committed to a local variable in the parent buffer." + (if-let* ((parent-buffer (overlay-buffer edit-indirect--overlay)) + ((with-current-buffer parent-buffer + (derived-mode-p 'markdown-mode))) + (pos (cons (line-number-at-pos) (current-column)))) + (with-current-buffer parent-buffer + (setq markdown--edit-indirect-committed-position pos)))) + +(with-eval-after-load 'edit-indirect + (advice-add #'edit-indirect--commit :after #'markdown--edit-indirect-save-committed-position)) + +(defun markdown--edit-indirect-move-to-committed-position () + "Move the point in the code block corresponding to the saved committed position'." + (when-let* ((pos markdown--edit-indirect-committed-position) + (bounds (markdown-get-enclosing-fenced-block-construct)) + (fence-begin (nth 0 bounds))) + (goto-char fence-begin) + (let ((block-indentation (current-indentation))) + (forward-line (car pos)) + (move-to-column (+ block-indentation (cdr pos))))) + (setq markdown--edit-indirect-committed-position nil)) + +(with-eval-after-load 'edit-indirect + (advice-add #'edit-indirect-commit :after #'markdown--edit-indirect-move-to-committed-position)) (defun markdown--edit-indirect-after-commit-function (beg end) "Corrective logic run on code block content from lines BEG to END. @@ -9345,18 +9376,23 @@ at the END of code blocks." (interactive) (save-excursion (if (fboundp 'edit-indirect-region) - (let* ((bounds (markdown-get-enclosing-fenced-block-construct)) - (begin (and bounds (not (null (nth 0 bounds))) (goto-char (nth 0 bounds)) (line-beginning-position 2))) - (end (and bounds(not (null (nth 1 bounds))) (goto-char (nth 1 bounds)) (line-beginning-position 1)))) - (if (and begin end) - (let* ((indentation (and (goto-char (nth 0 bounds)) (current-indentation))) - (lang (markdown-code-block-lang)) - (mode (or (and lang (markdown-get-lang-mode lang)) - markdown-edit-code-block-default-mode)) - (edit-indirect-guess-mode-function - (lambda (_parent-buffer _beg _end) - (funcall mode))) - (indirect-buf (edit-indirect-region begin end 'display-buffer))) + (if-let* ((bounds (markdown-get-enclosing-fenced-block-construct)) + (fence-begin (nth 0 bounds)) + (fence-end (nth 1 bounds)) + (original-point (point)) + (original-column (current-column)) + (begin (progn (goto-char fence-begin) (line-beginning-position 2))) + (end (progn (goto-char fence-end) (line-beginning-position 1))) + (original-line (- (line-number-at-pos original-point) (line-number-at-pos begin)))) + (let* ((indentation (progn (goto-char fence-begin) (current-indentation))) + (lang (markdown-code-block-lang)) + (mode (or (and lang (markdown-get-lang-mode lang)) + markdown-edit-code-block-default-mode)) + (edit-indirect-guess-mode-function + (lambda (_parent-buffer _beg _end) + (funcall mode))) + (indirect-buf (edit-indirect-region begin end 'display-buffer))) + (with-current-buffer indirect-buf ;; reset `sh-shell' when indirect buffer (when (and (not (member system-type '(ms-dos windows-nt))) (member mode '(shell-script-mode sh-mode)) @@ -9364,16 +9400,17 @@ at the END of code blocks." (mapcar (lambda (e) (symbol-name (car e))) sh-ancestor-alist) '("csh" "rc" "sh")))) - (with-current-buffer indirect-buf - (sh-set-shell lang))) + (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))))) - (user-error "Not inside a GFM or tilde fenced code block"))) + (indent-rigidly (point-min) (point-max) (- indentation))) + (goto-char (point-min)) + (forward-line (max 0 original-line)) + (move-to-column (max 0 (- original-column indentation))))) + (user-error "Not inside a GFM or tilde fenced code block")) (when (y-or-n-p "Package edit-indirect needed to edit code blocks. Install it now? ") - (progn (package-refresh-contents) - (package-install 'edit-indirect) - (markdown-edit-code-block)))))) + (package-refresh-contents) + (package-install 'edit-indirect) + (markdown-edit-code-block))))) ;;; Table Editing =============================================================