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

Insert GFM code block and edit-indirect #251

Closed
blaenk opened this issue Sep 2, 2017 · 7 comments
Closed

Insert GFM code block and edit-indirect #251

blaenk opened this issue Sep 2, 2017 · 7 comments

Comments

@blaenk
Copy link

blaenk commented Sep 2, 2017

I thought it would be nice to have a bind that does both of these in one go, so I created a function:

(defun my-markdown-insert-gfm-code-block-and-edit ()
  (interactive)

  (call-interactively #'markdown-insert-gfm-code-block)
  (markdown-edit-code-block))

The problem is that I get "Not inside a GFM or tilde code block," even though it clearly seems like the point is inside of the code block. Any ideas?

@blaenk
Copy link
Author

blaenk commented Sep 2, 2017

I instrumented markdown-edit-code-block with EDebug and noticed that when I step through it that way, it does work, even if I press C to continue fast, almost as if it meant that it gave time for the changes made by markdown-insert-gfm-code-block to take effect, even though that shouldn't be the case AFAIK. I tried to verify this by adding a (sleep-for 1.0) in between both calls and it didn't work, so I guess that's not it. Something about instrumenting the edit function did make it work though.

Another thing to note, once we do get this working, is that this ends up with the indirect buffer with the newline, so the point starts at line 2, since the codeblock as inserted by insert-gfm-code-block leaves an empty line, which is indeed what I would normally want, but it gets in the way when trying to edit-indirect in one go.

@blaenk
Copy link
Author

blaenk commented Sep 3, 2017

I'm not too familiar with this, but it seems like it finds the codeblock by the text properties, perhaps the edit-indirect function is running too quickly, before there's been a chance to propertize the text that was inserted by insert-gfm-codeblock. I guess I'll try to find a way to force the text to propertize before continuing on to the edit-indirect call. If that's inadvisable, another way would be to supply the edit call explicit bounds which can probably be deduced in a straightforward manner given that the insert-gfm-codeblock call is the one constructing it.

@blaenk
Copy link
Author

blaenk commented Sep 3, 2017

That was indeed the issue. Calling font-lock-ensure ensures that those text properties are applied so that the markdown-get-enclosing-fenced-block-construct function could find the codeblock based on them. It takes a region but for now I'm just letting it apply to the whole "accessible portion of the buffer" like the docstring for it says. I also added a kill-line call to remove the newline so that it doesn't show up in the indirect buffer, which would end up starting us on line 2.

This works well so far:

(defun my-markdown-insert-gfm-code-block-and-edit ()
  (interactive)

  (call-interactively #'markdown-insert-gfm-code-block)
  (kill-line)
  (font-lock-ensure)
  (markdown-edit-code-block))

I suppose if this package would like to add this kind of function (I think it would be great, it's a very fluid/fast way to edit with all of the modes and configuration for the codeblock's mode), some things to consider would be:

  • Perhaps computing the codeblock's region manually instead of relying on or having to wait for or force font locking, since after all, insert-gfm-code-block constructs the codeblock itself, so it should be trivial.

  • Gracefully handle aborting with C-g at the language selection part. If one aborts the interactive selection of the GFM language, it uses an empty string, which is desirable IMO. The problem is that when one goes to edit-indirect a GFM codeblock without a language identifier, instead of assuming plain text such as "text", markdown-code-block-lang returns nil. This ends up breaking things further down the road, eventually attempting to (funcall nil). I verified and fixed this on my end with:

    (define-advice markdown-code-block-lang
        (:filter-return (lang) default-to-plain-text)
      "Instead of returning `nil' when there is no lang, assume \"text\"."
      (or lang "text"))

@blaenk
Copy link
Author

blaenk commented Sep 3, 2017

Also the guess-mode-function can be made more resilient. Currently if the language's mode can't be detected in markdown-get-lang-mode it just returns nil, so then it tries to (funcall nil):

(let* ((lang (markdown-code-block-lang))
       (mode (and lang (markdown-get-lang-mode lang)))
       (edit-indirect-guess-mode-function
        (lambda (_parent-buffer _beg _end)
          (funcall mode))))
  (edit-indirect-region begin end 'display-buffer))

I think instead we should check if the mode is non-nil then do what we're doing, otherwise perhaps do what the edit-indirect package does out of the box and call (normal-mode) which automatically tries to deduce the correct mode. Something like (if mode (funcall mode) (normal-mode)).

jrblevin added a commit that referenced this issue Nov 8, 2017
jrblevin added a commit that referenced this issue Nov 8, 2017
@jrblevin
Copy link
Owner

jrblevin commented Nov 8, 2017

The commit above and the two previous ones I think should address all of the things you mentioned above. You can now insert-and-edit with C-u C-c C-s C (prefix the GFM insertion command). Let me know what you think, or if it doesn't work.

@blaenk
Copy link
Author

blaenk commented Nov 14, 2017

It appears to be working just fine! Thanks a ton as usual.

@blaenk
Copy link
Author

blaenk commented Nov 14, 2017

Ran into #284 which I think may be due to the changes made here, but I'm not sure.

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

No branches or pull requests

2 participants