From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Ihor Radchenko Newsgroups: gmane.emacs.bugs Subject: bug#35419: [Proposal] Buffer Lenses and the Case of Org-Mode (also, Jupyter) Date: Sat, 01 Jun 2019 22:49:51 +0800 Message-ID: <87v9xpfjhs.fsf@yantar92-laptop.i-did-not-set--mail-host-address--so-tickle-me> References: <87muk1fn90.fsf@yantar92-laptop.i-did-not-set--mail-host-address--so-tickle-me> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="268677"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Philipp Stephani , 35419@debbugs.gnu.org, Noam Postavsky To: Dmitrii Korobeinikov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jun 01 16:51:20 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hX5Ls-0017gK-1y for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Jun 2019 16:51:20 +0200 Original-Received: from localhost ([127.0.0.1]:37915 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hX5Lq-00088Z-JT for geb-bug-gnu-emacs@m.gmane.org; Sat, 01 Jun 2019 10:51:18 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:51347) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hX5Lg-00086E-O2 for bug-gnu-emacs@gnu.org; Sat, 01 Jun 2019 10:51:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hX5Le-0003X9-OY for bug-gnu-emacs@gnu.org; Sat, 01 Jun 2019 10:51:08 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:53100) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hX5La-0003Vc-E0; Sat, 01 Jun 2019 10:51:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hX5La-00025O-BH; Sat, 01 Jun 2019 10:51:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Ihor Radchenko Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, emacs-orgmode@gnu.org Resent-Date: Sat, 01 Jun 2019 14:51:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 35419 X-GNU-PR-Package: emacs,org-mode Original-Received: via spool by 35419-submit@debbugs.gnu.org id=B35419.15594006588007 (code B ref 35419); Sat, 01 Jun 2019 14:51:02 +0000 Original-Received: (at 35419) by debbugs.gnu.org; 1 Jun 2019 14:50:58 +0000 Original-Received: from localhost ([127.0.0.1]:38411 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hX5LV-000255-Sd for submit@debbugs.gnu.org; Sat, 01 Jun 2019 10:50:58 -0400 Original-Received: from mail-pf1-f178.google.com ([209.85.210.178]:35551) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hX5LT-00024s-Sx for 35419@debbugs.gnu.org; Sat, 01 Jun 2019 10:50:56 -0400 Original-Received: by mail-pf1-f178.google.com with SMTP id d126so8003577pfd.2 for <35419@debbugs.gnu.org>; Sat, 01 Jun 2019 07:50:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:in-reply-to:references:date:message-id :mime-version; bh=Yu7NMccY+7yY2QycIom3/PzjSUDujJ0JqQ+s3+3sKBM=; b=vYgzQJp6bKlp/rWoBjWgwnYRqLoW+moxfR4OYqDS3VFdpGnL+pMuaWr4VUAuseiAZH dHou+91d7e3YoETpaIVHw/5kJTDG8kC3bWh3bOPKDj7hyL4WFe+qCpufiaXpO28r4mb1 f/nqjXjvoPTbR7eUnoIhgzQrQxhd2MgmV1LAKGehj0B5UHG1z0dCzrZB/3tqgOuDowQK mTY4UhTCyPyimMNlPHxaI21rMMv/R0kdFYlyqTJX0ZP46V/u24zt4qVXfBPEaPHFsha0 XE/cYn29VGq0zf9nseXPQxLtFANqxnktIYpWmtjOLpUYJAiUnQdZFdEyuuLxGKfGY4C2 L7KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=Yu7NMccY+7yY2QycIom3/PzjSUDujJ0JqQ+s3+3sKBM=; b=lAF915+t5IxPYtl4tHU7rF+p/mkSgKlrjWM4ATwDm56ZfdwFMLiXKSMEmVYZW688Xu MlXOrpwNMx3qJ9TAFPnaphuEcsy9tP87Dszurh2LZTyoILiyDCvQBcGF26zT1UFnmhgH RCABHwqwkOePfX/hEtbb/sSpujNQvr8l78Is3XxXgzvzbaOZmavItJM/K3RqUxLElSt6 4712zPQF2UPHNqSm5kWQXsGdtavbOhJhwLTHw9B0pKXqEcWSTQaM95eWKaqZwpWHCQ+R c0PKEroI4NVEbUH+M9GRkmTWOqCz9aeNVkGE/mF5IcieIK0t94us+ekEYbYldj3ed7US iNbw== X-Gm-Message-State: APjAAAWRfmaldkwvAbwljlQKhtA3FrRFLLXxAVR9LULGIjfPnRb0uPBB KailtXJTZDJzLK3ZZiuicUg= X-Google-Smtp-Source: APXvYqzzE+tyaH95GTB0IMYeSvAu7pJ3alKL2Hv7yKpHZiPhfFFdMcGCYhoInay5Ho4G92FSDmXWfg== X-Received: by 2002:a65:6284:: with SMTP id f4mr3028671pgv.14.1559400649786; Sat, 01 Jun 2019 07:50:49 -0700 (PDT) Original-Received: from localhost ([2409:8a70:ff2c:bb80:f0f5:854b:57ac:24ef]) by smtp.gmail.com with ESMTPSA id f186sm11074664pfb.5.2019.06.01.07.50.47 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Sat, 01 Jun 2019 07:50:48 -0700 (PDT) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:160002 Archived-At: Dear Dmitrii, Regarding the question about buffer-lens interaction. Let's take even more complicated example: To run the command, the user hits some key combination, which happens to be bound to different commands in the main buffer and in the lense buffer (i.e. the main buffer is in org-mode, the lense is in mingus-mode, and the key is C-d). What should be the behaviour in such a case? run the commands in both the buffers? decide depending on the point position? It is easy to make up similar complicated examples if you consider some exotic major modes in the lense buffer. I think that it would be more effective if someone decide on some basic approach for the low-level implementation of the lense-mode (which probably involves modifying emacs C-level source code) and continue the discussion according to the benefits/limitations of that kind of implementation. Best, Ihor Dmitrii Korobeinikov writes: > Dear Ihor, > >> Note that indirect buffers always share *all* the contents with the master >> buffer. As a result, it may not be easy to make things like flyspell >> work on code blocks in org-mode, if these code blocks are treated as >> lenses. > > I tried flyspell w/ different dictionaries on 2 buffers. > The dictionary is switched every time I switch into one of the buffers. > You are right, ispell and the like working w/ a file directly would have to > learn to work w/ indirect buffers by managing multiple simultaneous > processes. > Fortunately, that doesn't seem like a big hurdle. > >>> (1) A question: when an indirect buffer is created and some region is >>> narrowed to, is the rest of the buffer duplicated in memory somewhere? If >>> this is so, there could be a useful efficiency-related modification to >>> indirect buffers, which would allow "hard-narrowing": not duplicating the >>> rest of the base buffer. >> >> There is no duplication of the buffer content in indirect buffers. >> Internally, indirect buffer's content is a pointer to the main buffer >> content. If you modify text in any of the indirect buffers or in the >> main buffer, the text is modified in all of them and in the main buffer. >> Only the buffer-local variables are duplicated. >> You can refer to "27.11 Indirect Buffers" in the elisp manual for >> details. > > Bad choice of wording on my side, I didn't mean duplication, but rather > keeping unnecessary info, like text properties in the newly created > indirect buffer, in the regions which were "permanently" chosen to be > narrowed-out. > Anyway, this is a premature optimization for now. > >> > The next immediately outstanding question is: >> > (2) how can "embedding" (of a buffer as a part of another buffer as an >> > area) be done efficiently? This could possibly be approached as two >> > problems: (i) displaying the area and (ii) interacting with it. >> > Any ideas? >> >> These issues have been discussed in >> https://lists.gnu.org/archive/html/emacs-devel/2018-07/msg00863.html. >> As I remember, the discussion stopped without a clear conclusion. It was >> not clear how to separate the main buffer contents from the nested >> buffer (I treat them as analogue of the buffer lenses). Another issue >> was how the keymaps and buffer-local variables would interact when the >> point is within a lense. It was not clear what should be the priority. > > The short answer is probably that lens-mode looks at the changes to the > buffer and decides what's what. > Here is my vision for this. > > Say, you have an indirect buffer, call it A, it's base has contents: > >> line 1 >> line 2 >> line 3 > > Also, there is a buffer, call it B, where we want to embed A, with contents: > >> word 1 >> instruction: lens that displays A >> word 2 > > Lens-mode decides to identify the second line as a lens and constructs > layout of the file. > >> [text] >> [lens#A] >> [text] > > Now, construct and display the final buffer as: > >> word 1 >> line 1 >> line 2 >> line 3 >> word 2 > > The core question: how is this "displaying" done. > In part, somewhat like how indirect buffers function. > A displayed piece of text is a pointer/reference to the text in the > indirect buffer. > Of course, this should be done in a way so that the modes running in B > don't change the properties of the text (following the layout constructed > by lens-mode as in the example above). Though, this might better&easier be > done at the display unit level. > > What about interaction? > Well, when the cursor is inside the lens, the controller decides what to do > w/ each keybinding, whether to redirect it to the indirect buffer or not. > And what about the case when borders are crossed? > As I see it, any code that executes - does so as is. > For instance, consider a buffer with a lens (contents: "lens"), which looks > like this: "word1 lens word2". > Place the cursor on the first word, run a command to remove 2 words. > Now there are to possibilities here, depending on the implementation of the > function which does the removal: > 1. Implementation identifies the boundaries of deletion and removes the > words as contents of the main buffer. Lens-mode identifies the removal and > deletes the lens altogether. > 2. Delete "word1" -> the cursor is on "lens" -> next deletion command is > redirected to the indirect buffer, which does the removal. Lens-mode > identifies the lens as empty and removes it. > > The second way might not be always desirable, so whenever a function is > called with the cursor outside a lens, as an option, decide to never > redirect the input to a lens while the function runs. > > For another case, consider the first example with lines and, cursor being > in the beginning of the file, remove three lines. > To make this interesting, assume the first kind of implementation runs, > identifying the bounds, never redirecting a command to the lens. > Well, if the implementation of the lens is inspired by how indirect buffers > work, I imagine, the necessary changes in the embedded buffer take place > directly, in which case everything works as desirable. > > Afterwards, lens-mode processes the changes and decides if some lens was > removed or added, updating the file layout. > > Best regards, > Dmitrii.