Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

markdown-edit-code-block incorrectly indents code in the indirect buffer #375

Closed
phst opened this issue Nov 21, 2018 · 8 comments
Closed

Comments

@phst
Copy link
Contributor

phst commented Nov 21, 2018

Expected Behavior

If a GFM block itself is indented, C-c ' should not add indentation to the indirect buffer.

Actual Behavior

C-c ' adds indentation to such block.

Steps to Reproduce

  1. Create a test file such as

    $ cat /tmp/a.md 
    *   a
    
        ``` shell
        abc
        ```
    
  2. emacs -Q -l ../edit-indirect/edit-indirect.el -l markdown-mode.el /tmp/a.md
    
  3. move point into the code block

  4. C-c '

  5. Code block will be indented by 4 spaces in the indirect buffer

Software Versions

  • Markdown Mode: markdown-mode, version 2.4-dev, Git version d18a8f8
  • Emacs: GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.24), modified by Debian
  • OS: Debian testing
@syohex
Copy link
Collaborator

syohex commented May 13, 2020

I suppose it is difficult to support this feature with current edit-indirect package specification/implementation.

@MyriaCore
Copy link
Contributor

If edit-indirect mode interpreted rectangular regions properly, maybe we could specify a rectangular region whose width spans from the start of the codeblock to the end of the line? Writing a proposal for edit-indirect mode now.

@MyriaCore
Copy link
Contributor

Writing a proposal for edit-indirect mode now.

Just finished the proposal, it's over at Fanael/edit-indirect#17.

@Fanael
Copy link

Fanael commented Nov 11, 2020

You shouldn't need rectangular regions (they're a right mess anyway, and supporting them properly is hard) to do that. Instead, find out if the code block, including its start and end lines, is indented, and if it is, save the indentation level in a buffer local variable in the edit-indirect buffer. Then dedenting in the after creation hook and indenting back in the before commit hook should do the trick.

@MyriaCore
Copy link
Contributor

I agree that that'd probably be a pretty OK solution. I might try and hack that into markdown-mode.el to see if i can implement that.

@MyriaCore
Copy link
Contributor

MyriaCore commented Nov 11, 2020

Here's the current definition of markdown-edit-code-block:

markdown-mode/markdown-mode.el

Lines 8584 to 8604 in cf64031

(defun markdown-edit-code-block ()
"Edit Markdown code block in an indirect buffer."
(interactive)
(save-excursion
(if (fboundp 'edit-indirect-region)
(let* ((bounds (markdown-get-enclosing-fenced-block-construct))
(begin (and bounds (goto-char (nth 0 bounds)) (point-at-bol 2)))
(end (and bounds (goto-char (nth 1 bounds)) (point-at-bol 1))))
(if (and begin end)
(let* ((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))))
(edit-indirect-region begin end 'display-buffer))
(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))))))

I ended up settling on this edit to save the indentation depth of the code block to markdown--code-block-indirect-indentation:

(defun markdown-edit-code-block ()
  "Edit Markdown code block in an indirect buffer."
  (interactive)
  (save-excursion
    (if (fboundp 'edit-indirect-region)
        (let* ((bounds (markdown-get-enclosing-fenced-block-construct))
               (begin (and bounds (goto-char (nth 0 bounds)) (point-at-bol 2)))
               (end (and bounds (goto-char (nth 1 bounds)) (point-at-bol 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)))
                (when (> indentation 0)
                  (with-current-buffer indirect-buf
                    (setq-local markdown--code-block-indirect-indentation
                                indentation)
                    (indent-rigidly (point-min) (point-max) (- 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))))))

I'll note that this solution won't work for the following cases:

<!-- code block in list -->
- ```
  code
  ```
* ```
  code
  ```
1. ```
   code
   ```


<!-- in quote -->
> ```
> code
> ```

... but then again, code block detection was spotty for me in these cases before.

MyriaCore added a commit to MyriaCore/markdown-mode that referenced this issue Nov 11, 2020
@MyriaCore
Copy link
Contributor

@syohex this issue should be closed, as #559 was merged via 09c9934^...2ac9be1

@syohex syohex closed this as completed Nov 15, 2020
@syohex
Copy link
Collaborator

syohex commented Nov 15, 2020

Oh, sorry I forgot. I have closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants