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 =============================================================

Reply via email to