This file exists to gather resources related to implementing transclusion in Emacs.
The topic frequently reappears in discussions on Reddit, the mailing lists, etc, and usually only a few of the existing resources are mentioned. It’s time to gather them in one place.
Please send additions as pull requests. When adding a resource, please add a summary as of the date it’s added.
[2019-04-25 Thu] Dmitrii Korobeinikov’s report is extensive. The discussion on the report continues into April of 2020.
SUMMARY Buffer lens is an object inside a buffer which provides that buffer the lines to display and which is linked to another buffer (from which it can take and process data), while mapping the input back to that linked buffer. Composite lens is the extension of this idea to interface any sources of data (for which text interface is possible). Some Org-mode problems are addressed, particularly those concerning source block editing and viewing, syntax checking, completion and reference expansion.
This is a proposal for lenses. Hereby, I outline the general idea, the problems it solves, the features it introduces and its use cases.
See also Reddit discussion of the report from 2020, in which Ihor Radchenko mentions:
Here is my work-in-progress on the subject: https://github.com/yantar92/mirror-text. I have little time to work on it in near future, but hope the ideas and links could be useful.
[2020-04-03 Fri] Dmitrii Korobeinikov asks:
I want to explore the feasibility of displaying two (indirect) buffers inside a single window, one after another. Each buffer has to look like it’s rendered in its own mode. For the starters, each buffer can start on its own new line in the window. No interaction w/ text is required for now.
I have been entertaining the idea since my proposal for lenses , and now that I have some desire to get hacking a little, I want to see if I can get onto this first ladder step to the goal. What concerns me now is how to approach the problem. So, I come here to ask for your advice and comments. You know, “it’s dangerous to go alone, take this!” sort of deal.
I guess I would first have to learn how the renderer functions. Any good resources on that besides the source code?
Eventually, I would have to explore beyond the renderer and get to play with the data structures, so I can do the interaction w/ text possible. But that doesn’t concern me all that much until I get to actually draw some buffers together.
The discussion is extensive, including replies from Eli Zaretskii and Ihor Radchenko, and mentions modifying
xdisp.c, the buffer data structure, associated functions, etc.
[2018-07-23 Mon] fei xiaobo asks:
I am building a plan to implement Nested buffer in Emacs recently. Is it a good ideal?
Nested buffer what I mean here is the sub-buffers which embedded in a host buffer.
- Nested/Embed buffer’s content is linked to an arbitrary buffer.
- Host buffer’s content consists of the content of all the nested buffers.
If having this, we could embed multiple buffers’ content into a host buffer to get one virtual buffer. And, after updating the nested buffer’s content, the virtual host buffer’s content is updated too. I think it will be helpful for many special plugins.
Appreciated any comments or suggestion.
Includes responses by Stefan Monnier and Eli Zaretskii.
[2016-12-09 Fri] John Kitchin asks:
I have an idea for how I could transclude “copies” or links to org-elements in multiple places and keep them up to date. A prototypical example of this is I have a set of org-contacts in one place, and I want to create a new list of people for a committee in a new place made of “copies” of the contact headlines. But I do not really want to duplicate the headlines, and if I modify one, I want it reflected in the other places. I do not want just links to those contacts, because then I can not do things with org-map-entries, and other org-machinery which needs the actual headlines/properties present. Another example might be I want a table in two places, but the contents of them should stay synchronized, ditto for a code block.
This idea was inspired by https://github.com/gregdetre/emacs-freex.
The idea starts with creating (wait for it…) a new link ;) In a document where I want to transclude a headline, I would enter something like:
Then, I would rely on the font-lock system to replace that link with the headline and its contents (via the :activate-func link property), and to put an overlay on it with a bunch of useful properties, including modification hooks that would update the source if I change the the element in this document, and some visual indication that it is transcluded (e.g. light gray background/tooltip).
I would create a kill-buffer hook function that would replace that transcluded content with the original link. A focus-in hook function would make sure the transcluded content is updated when you enter the frame. So when the file is not open, there is just a transclude link indicating what should be put there, and when it is open, the overlay modification hooks and focus hook should ensure everything stays synchronized (as long as external processes are not modifying the contents).
It seems like this could work well for headlines, and named tables, src blocks, and probably any other element that can be addressed by a name/ID.
[2020-03-20 Fri] Protesilaos Stavros comments:
Good to know! The Emacs manual also has a chapter on “accumulating text”. Excerpt:
- ‘M-x append-to-buffer’
- Append region to the contents of a specified buffer.
- ‘M-x prepend-to-buffer’
- Prepend region to the contents of a specified buffer.
- ‘M-x copy-to-buffer’
- Copy region into a specified buffer, deleting that buffer’s old contents.
- ‘M-x insert-buffer’
- Insert the contents of a specified buffer into current buffer at point.
- ‘M-x append-to-file’
- Append region to the contents of a specified file, at the end.
[2020-10-07 Wed 10:55] Discussion of this video demo posted by Noboru Nobiot: Transclusion / Block Reference with Emacs (Org Mode) - Prototype - YouTube
Q: is there any way to do transclusion in emacs org-mode?
By “transclusion”, I mean stuff like, at some point in fileA.org and fileB.org, “including” fileInc.org - and having the tree from fileInc.org appear in both places. Actually appear, not just be linked to. (Possibly with conditional inclusion, transformation, e.g. nesting depth (number of ***s)).
I know about #setupfile, but that seems only to work for modes, not real text.
I know about http://orgmode.org/manual/Include-files.html, but AFAIK they only work at export time.
I am looking for something that works in a normal emacs org-mode buffer. (Actually, something that worked in non-org-mode buffers might be nice.)
I have boiler plate that I want to include in multiple files.
Does something like this exist?
Rob replies with an example of a simple Org dynamic block that provides read-only transclusion:
Hmm… I don’t think anything like this exists, but it was easy enough to write a dynamic block to do this. The following elisp works for me:
(defun org-dblock-write:transclusion (params) (progn (with-temp-buffer (insert-file-contents (plist-get params :filename)) (let ((range-start (or (plist-get params :min) (line-number-at-pos (point-min)))) (range-end (or (plist-get params :max) (line-number-at-pos (point-max))))) (copy-region-as-kill (line-beginning-position range-start) (line-end-position range-end)))) (yank)))
Then to include a line range from a given file, you can create a dynamic block like so:
And auto-populate with `C-c C-x C-u`. Skip the min and max args to include the entire file. Note that you can bind `org-update-all-dblocks` to a hook, so that this range is updated whenever you visit the file or save.
More info on dynamic blocks at http://orgmode.org/org.html#Dynamic-blocks. Hope this helps!
Say, I have a buffer A in which there is a region of text from some position pos1 to an other position pos2.
I switch to buffer B, call a function with buffer A, pos1 and pos2 as parameters and it copies the referred region to buffer B at point and lets me edit it at either place with all the edits made in buffer B’s relevant region mirrored to buffer A’s relevant region and vica versa.
Includes the following reply from Tobias, including some sample code (omitted here):
The documentation string for the command `text-clone-create`:
> (text-clone-create START END &optional SPREADP SYNTAX) > > Create a text clone of START…END at point. > Text clones are chunks of text that are automatically kept identical: > changes done to one of the clones will be immediately propagated to the other. > > The buffer’s content at point is assumed to be already identical to > the one between START and END. > If SYNTAX is provided it’s a regexp that describes the possible text of > the clones; the clone will be shrunk or killed if necessary to ensure that > its text matches the regexp. > If SPREADP is non-nil it indicates that text inserted before/after the > clone should be incorporated in the clone.
Note, that you must copy the text as the first action yourself.
Pityingly, the original version only works for one buffer. But it is easy to fix it for the case that original and clone do not have the same buffer. In the following Elisp code I marked the changed lines with `;;< Tobias`.
There is also an interactive helper command `my-clone` in the code.
- Mark the region you want to clone.
- Call <kbd>M-x</kbd> `my-clone` <kbd>RET</kbd>. Emacs goes into `recursive-edit` state.
- Navigate to the buffer and to the position where you want to clone the previously marked region.
- Finish `recursive-edit` with <kbd>C-M-c</kbd>.
- Now edit either the original region or the clone. The modifications are replicated in the other region.
I’d like to organize my headings in multiple ways at once. (with the same degree of flexibility that I have when organizing things in any one place - e.g. more than the Agenda provides)
Ideally I’d be able to make a heading in part of a document, and then create a “hard link” to the heading somewhere else, which would update both as the content of heading changed.
Next best would be “soft links” which only store the heading content in one canonical location, and just show it in the other location (and if you edit it in either, it just updates in the canonical location).
Right now the best I know how to do is just create normal links, which I need to manually follow to see the content. Is there any way to do better than this?
Replies point to
GitHub - gregdetre/emacs-freex: Emacs Freex mode is a minor mode for organizing and editing a massively-hyperlinked database of your notes and ideas. It’s a personal wiki on steroids.
GitHub - magnars/multifiles.el: Work in progress: View and edit parts of multiple files in one buffer