orgmode
orgmode copied to clipboard
Added tangle functionality to org files
This PR has been created to propose a way to implement the tangling functionality existing in ORG Mode (following Discussion #275 ).
The current code will add a tangle function as a method of an Org File, since this seemed the most flexible way to implement this.
With this PR, you can write the following in order to tangle block files found under specific headings:
* Heading 1
:PROPERTY:
:TANGLE: ./filename.lua
:END:
#+begin_src lua
print("Test")
#+end_src
Since this is a stub, I've not yet thought if the action should be triggered by a keymap or by a command. Currently, you can tangle the file from lua using this code:
local file = require("orgmode.parse.files").get_current_file()
file:tangle()
This is not a 1:1 copy of the syntax that is implemented in the original Org Mode, since it seems like treesitter isn't able to comprehend the original one.
Things that I'd like to discuss about this implementations are:
- The currently used syntax is different from what Org Mode does. It was meant to be more easily parsed by treesitter, but other options are welcome
- How to handle when the filename isn't defined (the original uses the filename + an extension based on the code block language)
- How to expose this functionality to the user
- I've added a function that changes a relative path to an absolute one. This has been done elsewere in the code, but I think it could need some improment, maybe we can create a function in
utils.lua?
Of course, if there are other questions or suggestions, don't hold back! Hope this can be of some help 🙂
@andreadev-it Thanks for the PR. From what I see in Emacs docs https://orgmode.org/manual/Extracting-Source-Code.html, it seems this is handled differently. Looks like it needs to be defined like this:
* Heading 1
#+begin_src lua :tangle yes
print("Test")
#+end_src
Did you use property for some specific reason?
Hi @kristijanhusak, thank for taking a look at this PR 🙂 Yes, the syntax I integrated is different right now, mostly for semplicity reasons. I saw that treesitter isn't (or maybe wasn't) detecting code blocks properties and other similar-looking syntax. It seemed to me that there are also different ways of setting that option in orgmode that I couldn't completely understand.
You should be able to parse this with treesitter. See how we do it for detecting filetype blocks https://github.com/nvim-orgmode/orgmode/blob/60e8700469a96e839c5e776a1849034af5f830a4/lua/orgmode/parser/file.lua#L398-L414
Thank you for the info, I took a look at the code and, the treesitter tree and the org grammar. If I understood correctly, to support tangling files there are three syntax that should be handled:
- document properties
#+PROPERTY: header-args :tangle yes
- header properties
* Heading 1
:PROPERTIES:
:header-args: :tangle yes
:END:
- block properties
#+BEGIN_SRC lua :tangle yes
-- code here
#+END_SRC
Is this correct? I wrote them here both as a way to ask for confirmation about this and to have a local reference to the spec.
Yeah, this seems right. But I would say to implement only point 3, since the first 2 points are just used to propagate the values to its children, in terms that if you set the top level #+PROPERTY, it sets that property to each headline, and if you have :header-args: :tangle yes property on a headline, it applies that to each block inside.
This inheritance of properties needs to be generally added so it's out of scope for this feature.
Ok, I understand. It should be easy to change the code to support only point 3. I'll do it as soon as I can 👍 However I do think that, for this functionality to be useful, it should support at least one of the other methods too... When property inheritance is added, I could implement it for the tangling functionality with a new PR, if needed
Few notes while you are updating it:
- Move the
tangle()method fromparser/file.luatotreesitter/init.lua. We are generally trying to move from this parsed file and move everything to parsing via treesitter. - Use custom query similar to what we have for block filetypes (thing I posted above) to figure out the nodes that have tangle. Iterating children is generally fine, but custom query should be simpler and it will not require doing any recursion.
Some support was added in https://github.com/nvim-orgmode/orgmode/pull/685. We can build up on that. Closing this. Thanks for the PR anyway!