-
Notifications
You must be signed in to change notification settings - Fork 200
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
org-mode source code blocks #523
Comments
As far as I know, these blocks aren't real files, or rather, that aren't in
files by themselves. Or if they are, they are only temporarily so. This is
fundamentally contrary to how LSP works, it works with the concept of
source code documents, and each document as a unique path, is
opened/closed, and is persisted on some file system. It may be possible to
trick an LSP server into believing there is a project that consists of
multiple small files of which only one is opened at any given time, and
then extract this project from an org file. But this would vary with the
server, and needs lots of temporary files and management. No idea how
lsp-mode does this or where its glitches come from.
João
…On Mon, Aug 17, 2020, 21:50 wuqui ***@***.***> wrote:
How can use eglot for org-mode source code blocks? I'm using Doom Emacs
and have just activated eglot it via the module flags. It works fine in a
pure Python file, but it doesn't work in org-mode buffers (with
jupyter-python blocks), neither if I edit the block in a Python buffer
provided by org-src-edit. It's starting a project and connecting to the
server, but I don't get any completions etc.
Am I missing something? I couldn't find anything online and I'm quite
surprised because I'd assume many would want to use LSP with org source
blocks. lsp-mode kind of works both in the org-mode buffers and in the
dedicated ones, but with some glitches.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#523>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAC6PQ6GV3MZI7NTSCPJS4LSBGJZ5ANCNFSM4QCGHK3Q>
.
|
Sounds complicated indeed. Maybe some day when there is more people than just me interested in using LSP with org-mode and literate programming. Thanks for clarifying, João. |
I'm also interested in this type of support or learning how to modify my workflow to take advantage of LSP. I use Org Mode for a monthly report that has embedded python blocks to produce tables based on exported data in the directory. Works nice until something breaks and then it is a pain to step through the code to see if the exported CSV has changed the number of comment rows before the actual header row. To make it work with LSP, I have used org tangle to save the src blocks into a file. The trick is getting the file changes back into the src blocks again. |
@mbarton98 Take a look at test.org:
Tangle it, than edit |
@muffinmad Thanks for the suggestion! I was trying that out last night and it works well. It also mirrors what I do with Jupyter notebooks with the jupytext extension that mirrors the ipynb file with a py file. If I change the py file the ipynb file will be updated when launched in Jupyter lab. In that case I explore using the notebook, but want to use emacs to format the code. Anyway, my point is that the jupytext extension works for ipynb files like tangle/detangle does for Org babel source blocks. |
Based on the suggestions, I made a "tangle and go to block in tangled file" function here. |
+1 I have just migrated from @muffinmad Thanks for suggesting |
@salutis |
I've been thinking about this, and was wondering if a competent solution here may be based upon indirect buffers. For example, if you have an org file with python src-blocks (single session, same interpreter), all of their content would be mirrored in an indirect buffer to be used for LSP. This could be a flat python project, but if the org-file resides within a project, it could also be linked to the source there. The tricky bit to me seems like it would involve efficiently tracking all src-block content in that indirect buffer, keeping it up-to-date. I'm not an expert in elisp, so a) this may be impossible due to some technical constraint I'm not aware of or b) I may be vastly underestimating the complexity. Any expert opinions on this perhaps? This solution would really help my workflow, so I wouldn't mind spending time implementing something functional. |
Just skimmed your post @timlod and from my part you can try something. In other situations I thought about indirect buffers to solve other problems (the multi-mode problem, if I recall correctly) and I do remember @monnier reasonably competently trashing my idea :-) right away. But perhaps that criticism (the specifics of which I completely forgot) doesn't apply to this problem at all? And so it may be worth a try. |
OK! This doesn't sound too discouraging, so I'll give it a shot ;) Do you by any chance remember in which discussions @monnier discouraged the use of indirect buffers? Perhaps that criticism does applie here as well and I can learn from it. |
Do you by any chance remember in which discussions @monnier discouraged the
use of indirect buffers? Perhaps that criticism does applie here as well and
I can learn from it.
I consider indirect buffers as an attractive nuisance.
You might want to check the `lentic` package instead.
|
I researched this a bit today, and I think I agree 🙃 |
OK, this is silly, but bear with me: What I wanted is jumping to definition, and finding references, for python source blocks in org files. One does have to disable Do you see any major issues with this usage besides the obvious craziness of it? |
@timlod this is a bit silly indeed but there might be a slither of a possible elegant solution there. The way that LSP clients and servers communicate with each other involves transmitting between themselves the "view" of a certain file. That view does not have to correspond to what is stored in the hard drive (in fact it frequently doesn't: as you edit the file without saving, the LSP server "knows" about it). So it should be possible, though perhaps a bit laborious, to trick the LSP server into thinking you are editing a Python file when in fact you are editing an org-mode block with embedded Python blocks. I don't have much time to detail or even outline a solution but look here https://microsoft.github.io/language-server-protocol/specification#textSynchronization-side and particularly to the Just another thought: that untangling/tricking could be done by a completely independent LSP-aware and org-mode-aware proxy server. |
I had a quick look. I think I'm out of my depth here, but I assume (at least part of) your point is that the Unfortunately I don't think I have the time to undertake this, so I'll actually see how far I can take my dumb solution - for what it's worth, the main things work, and I'm just ignoring most of the events I know LSP is sending in the background (which say that something is very wrong with my python file :)) |
this is besides the point -- for specific org-src blocks, some functionality can be modified by matching against (defun dc/unless-org-src-fontification-activate (mode)
"enable mode unless in an org-mode block"
(unless (string-match (regexp-quote "*org-src-fontification:") (buffer-name))
(apply mode '(+1))))
(add-hook! (emacs-lisp-mode clojure-mode clojurescript-mode common-lisp-mode scheme-mode)
#'(lambda () (dc/unless-org-src-fontification-activate 'prism-mode)))
the best ways to do this are with either the detangling approach or by using the
if you look into several times, i've had |
I've just read that LSP 3.17.0 gained support for "Notebook Documents". At first glace, it seems the notebook feature might be useful for this issue. So, the |
Indeed that is good news, now the job to do is to figure out how well the "notebook documentes" LSP abstraction maps onto Emacs's org-mode. Do we have volunteers for that investigation? Org-mode is part of Emacs, so it's OK to make Eglot depend on it. Nevertheless, even so, I'd like to keep these dependencies to a well-defined minimum. |
There's also this recent post on reddit basically proposing a code that should work, only implemented for rust. https://www.reddit.com/r/emacs/comments/w4f4u3/using_rustic_eglot_and_orgbabel_for_literate/ EDIT: It relies on modifying org-babel functions to work with eglot more than by the solution of "Notebook Documents". I may try to implement that using a python workflow, to see if it still works. |
This comment was marked as off-topic.
This comment was marked as off-topic.
1 similar comment
This comment was marked as off-topic.
This comment was marked as off-topic.
eglot can be launched if (require 'eglot)
(defun sloth/org-babel-edit-prep (info)
(setq buffer-file-name (or (alist-get :file (caddr info))
"org-src-babel-tmp"))
(eglot-ensure))
(advice-add 'org-edit-src-code
:before (defun sloth/org-edit-src-code/before (&rest args)
(when-let* ((element (org-element-at-point))
(type (org-element-type element))
(lang (org-element-property :language element))
(mode (org-src-get-lang-mode lang))
((eglot--lookup-mode mode))
(edit-pre (intern
(format "org-babel-edit-prep:%s" lang))))
(if (fboundp edit-pre)
(advice-add edit-pre :after #'sloth/org-babel-edit-prep)
(fset edit-pre #'sloth/org-babel-edit-prep))))) |
(defun sloth/org-babel-edit-prep (info)
(setq buffer-file-name (or (alist-get :file (caddr info))
"org-src-babel.tmp"))
(eglot-ensure))
Hmmm... `setq` here is problematic (`let` would be expected instead,
tho I don't know if that would work as well).
And `buffer-file-name` should contain an absolute file name.
But more importantly this suggests Eglot should be adjusted so it can be
used in buffers that aren't "file buffers".
|
What would you suggest Eglot supply to the LSP server as the document URI in that case? See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_synchronization |
*would |
> But more importantly this suggests Eglot should be adjusted so it can be
> used in buffers that aren't "file buffers".
What would you suggest Eglot supply to the LSP server as the document URI in
that case?
Would it make sense to use the `default-directory`?
Not sure it need to work in any arbitrary buffers, so maybe
it could use an `eglot-document-uri` variable for that?
|
Not really. Not only doesn't that designate a document, we're not talking about a dummy or virtual value: same (most?) servers really do need to have access to the document, virtually always a file, via means other than the LSP description of its contents.
That sounds a lot like the buffer-file-name variable |
> Would it make sense to use the `default-directory`?
Not really. Not only doesn't that designate a document, we're not talking
about a dummy or virtual value: same (most?) servers really do need to have
access to the document, virtually always a file, via means other than the
LSP description of its contents.
Ah, so we really need a real file?
In that case, we may as well use a real "file buffer" (with a non-nil `buffer-file-name`).
> Not sure it need to work in any arbitrary buffers, so maybe it could use
> an `eglot-document-uri` variable for that?
That sounds a lot like the `buffer-file-name` variable
`buffer-file-name` has other consequences, e.g. with respect to
auto-save and various other things, so if there's no actual file by that
name, it's often better to avoid setting `buffer-file-name`.
|
Presumably. sometimes/often.
I tend to think that variables controlling those other consequences should be tweaked if they produce unwanted behaviour. |
How can use eglot for org-mode source code blocks? I'm using Doom Emacs and have just activated eglot it via the module flags. It works fine in a pure Python file, but it doesn't work in org-mode buffers (with
jupyter-python
blocks), neither if I edit the block in a Python buffer provided by org-src-edit. It's starting a project and connecting to the server, but I don't get any completions etc.Am I missing something? I couldn't find anything online and I'm quite surprised because I'd assume many would want to use LSP with org source blocks.
lsp-mode
kind of works both in the org-mode buffers and in the dedicated ones, but with some glitches.The text was updated successfully, but these errors were encountered: