7

It is a common practice to write Emacs configuration files using literate-programming style in Org mode.

Unfortunately, while improving readability, this comes with significant programming disadvantages. In particular, since there is no backing .el file, Emacs is only aware of the code in the current source block. This means that except for the currently-edited block, navigation, symbol definition, and flycheck are all unavailable.

#+BEGIN_SRC emacs-lisp
  (defun literate-but-invisible ()
    (interactive)
    (message "I close my eyes..."))
#+END_SRC

#+BEGIN_SRC emacs-lisp
  (defun humans-can-read-but-emacs-cannot ()
    (interactive)
    (literate-but-invisible) ; No navigation! Flycheck reports undefined symbol!
    (message "...so that the room will be empty"))
#+END_SRC

Is there any way to tell Emacs to tangle and use the generated .el file to provide these features in Org mode? Such a feature would improve the maintainability of literate Emacs Lisp code.

Note that while it would be a fantastic feature to see Flycheck working for Org and Emacs Lisp simultaneously in one buffer, I am only asking about how to instrument org-edit buffers (the environment you get when you invoke org-edit-special (usually C-c ')). This should be easier since there is only one active mode for the buffer.

I have opened a feature request on the Flycheck repository here, and there is some relevant research in another issue here. However, I am not yet able to construct a solution.

2
  • You can evaluate all elisp src blocks when open this file. add a hook on find-file-hook etc to detect whether opening emacs config org file. Commented Oct 13, 2018 at 4:04
  • @stardiviner Would you be willing to expand your comment into an answer? As it is I do not have enough context to understand your proposed solution. Commented Oct 13, 2018 at 4:35

2 Answers 2

2
+50

For navigation and symbol definition see https://github.com/jkitchin/scimax/blob/master/scimax-literate-programming.el

You can generate a TAGS file with M-x scimax-lp-generate-tags.

After this, I can navigate to function definitions with M-. and M-,. You need to refresh the TAGS file with that function as things move around and get added, but maybe that can be done in a save-buffer hook or something. Also note that this gives tags relative to the org-file, not to where the definitions are in the source files.

M-x scimax-lp-signature-doc will get some information about the symbol at point if it is defined in the org-file.

I worked out a conceptual way to get flycheck to work in src-blocks in org-files. The idea is to have a proxy file that has the tangled code in it, in exactly the same character positions (ie you change all the other characters to spaces). Then, let flycheck work on that file. Then, transfer the flycheck overlays from the proxy file to the original file. You setup a hook function to update the proxy file on saving, and then update the overlays. Surprisingly, this works pretty well.

You can see the code at https://github.com/jkitchin/scimax/blob/master/scimax-ob-flycheck.org.

This is what a bad bit of code usually looks like Before scimax-ob-flycheck

After turning on scimax-ob-flycheck-mode it looks like:

After turning on scimax-ob-flycheck-mode

8
  • Note that for something like Flycheck, I think it would be completely acceptable if it were only active when org-edit is invoked. In that case there would be only one mode active for the buffer. I've edited my question to add some nuance there. Commented Oct 13, 2018 at 19:04
  • I have created a solution for this at github.com/jkitchin/scimax/blob/master/scimax-ob-flycheck.org. It does more or less what I outlined above using flycheck on a proxy file. There are probably some issues in it still, but it works for me so far! Commented Oct 14, 2018 at 18:39
  • This is brilliant! However, I have trouble reproducing it. I have launched an emacs -q, installed dependencies, and then ran (org-babel-load-file "scimax-ob-flycheck.org") followed by (scimax-ob-flycheck-mode +1). I do not see any Flycheck errors when I create broken code as a test. Commented Oct 14, 2018 at 20:39
  • You have to save the file, which should create the proxy files, and then run flycheck in them after the file is done being checked then the overlays should get transferred. While the org-file is open, there should be a file created in the same directory with an md5 hash and .el extension, if you look in that, you should see the flycheck overlays there. If not, something else is going on. I haven't tried this with a vanilla emacs/setup, maybe you can post your init for that and I could try it out. Commented Oct 14, 2018 at 21:29
  • Okay, yes. I can see flycheck overlays in the md5-hash.el file. However I cannot see any overlaps in scimax-ob-flycheck.org (with scimax-ob-flycheck-mode on), nor when using org-edit-special. Commented Oct 15, 2018 at 18:48
-2
 (defun org-literate-programming-eval-src-blocks ()
   "Auto evaluate Org buffer all source blocks to get a complete
 project environment when Literate Programming."
   (if (string= (buffer-name) "init.org")
       (org-babel-execute-buffer)))

 (add-hook 'find-file-hook #'org-literate-programming-eval-src-blocks :before)

The upper code add a function to evaluate all source blocks in buffer which matches your file "init.org". The filename can be modified as you needed.

5
  • I'm afraid this does not do anything except evaluate the blocks and add RESULTS blocks. Flycheck remains unusable. Commented Oct 13, 2018 at 13:24
  • flycheck seems to work fine for me in org-edit mode for emacs-lisp. What does it not do for you? Commented Oct 13, 2018 at 19:36
  • @MatthewPiziak If all your source blocks are emacs-lisp blocks, and evaluated, then all your elisp code should be available for Emacs, flycheck will be aware of that. And also, flycheck works fine on my org-edit-src-block too. Commented Oct 14, 2018 at 0:52
  • @JohnKitchin @stardiviner I get emacs-lisp predicate:nil flycheck-verify-setup due to the fact that buffer-file-name is nil in the Org Src buffers. Commented Oct 14, 2018 at 22:16
  • Can set buffer-file-name to a temporary fake file. But if want to disable flycheck I think disable that is a good solution. Commented Oct 15, 2018 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.