[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/lentic 71017538d7 211/333: Multiple lentic-buffers are
From: |
ELPA Syncer |
Subject: |
[elpa] externals/lentic 71017538d7 211/333: Multiple lentic-buffers are now possible. |
Date: |
Tue, 27 Feb 2024 13:00:36 -0500 (EST) |
branch: externals/lentic
commit 71017538d7da6707a8f26941cb771acdf4a469c0
Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
Commit: Phillip Lord <phillip.lord@newcastle.ac.uk>
Multiple lentic-buffers are now possible.
Previously only two buffers could exist. Now this can be any number.
This has been achieved by turning lentic-config and lentic-init into
lists, replumbing all of the hooks to operate over these.
lentic-clone has changed it's return value also (previously this was
ignored, now it is used to percolate to further lentic-buffers).
---
.ert-runner | 2 +-
Cask | 2 +-
Makefile | 2 +-
README.md | 20 +-
examples/many-multi-block-comment.clj | 39 ++++
examples/multi-block-comment-copy.clj | 40 ++++
examples/multi-block-comment.clj | 39 ++++
examples/multi-lentic-copy.txt | 4 +
examples/multi-lentic.txt | 4 +
lentic-block.el | 117 +++++++-----
lentic-delayed.el | 120 ------------
lentic-dev.el | 27 ++-
lentic-mode.el | 72 +++++--
lentic.el | 351 ++++++++++++++++++++++------------
lenticular.org | 6 -
test/lentic-test.el | 81 +++++---
16 files changed, 582 insertions(+), 344 deletions(-)
diff --git a/.ert-runner b/.ert-runner
index 0300cb2882..16731e3bee 100644
--- a/.ert-runner
+++ b/.ert-runner
@@ -1 +1 @@
---load lentic.el lentic-block.el lentic-latex-code lentic-asciidoc lentic-org
lentic-delayed lentic-rot13 test/lentic-test.el
\ No newline at end of file
+--load lentic.el lentic-block.el lentic-latex-code.el lentic-asciidoc.el
lentic-org.el lentic-rot13.el test/lentic-test.el
\ No newline at end of file
diff --git a/Cask b/Cask
index 11f9120e0d..e4db189fb1 100644
--- a/Cask
+++ b/Cask
@@ -1,6 +1,6 @@
;; -*- emacs-lisp -*-
(source gnu)
-(source melpa-stable)
+(source melpa)
(source marmalade)
(package-file "lentic.el")
diff --git a/Makefile b/Makefile
index 930d0c9339..50a8a74a14 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ install:
cask install
test:
- cask exec ert-runner
+ cask exec ert-runner $(TESTS)
org:
cask exec emacs --debug --script build.el -- gen-org
diff --git a/README.md b/README.md
index 8a0583c909..640ea82397 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,25 @@ completed the relevant paperwork with the FSF.
## ChangeLog
-### 0.7.1
+### 0.8
+
+This buffer introduces multiple lentic buffers. This is important because
+lentic has more than one use -- both for maintaining two syntactic views (for
+example for literate programming) and for maintaining two identical persistent
+views (for example, for editing a file in two places at once). It's now
+possible to do both of these at the same time.
+
+This necessitates a change to the return value of lentic-clone to enable the
+percolation of changes between several buffers. In this default usage of two
+lentic buffers this will have no effect.
+
+#### New Features
+
+- Multiple lentic buffers are now possible.
+
+#### Breaking Changes
+
+- The return value of lentic-clone has now changed.
### 0.7
diff --git a/examples/many-multi-block-comment.clj
b/examples/many-multi-block-comment.clj
new file mode 100644
index 0000000000..50f27cb4f3
--- /dev/null
+++ b/examples/many-multi-block-comment.clj
@@ -0,0 +1,39 @@
+;; This buffer shows a "block-comment" where we wish to comment large blocks
+;; of the buffer between one lentic buffer and the other.
+
+;; In this case, we use latex tags to indicate the code blocks. Outside of
+;; these tags, we start every line with comments. Inside we do not (although
+;; we leave comments that are there.
+
+;; \begin{code}
+(println "It is now broken")
+;; \end{code}
+
+;; We can have multiple code blocks, of course, after the first.
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "Hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And we can put more comments after the final text. And finally, we finish
+;; with a file local variable to tell lentic what kind of text this is. Note
+;; that start characters which are comments in both clojure and latex. In real
+;; use dir-local variables work better.
+
+;; %%
+;; %% Local Variables:
+;; %% lentic-init: (lentic-clojure-latex-init lentic-default-init
lentic-default-init lentic-default-init)
+;; %% End:
+;; %%
diff --git a/examples/multi-block-comment-copy.clj
b/examples/multi-block-comment-copy.clj
new file mode 100644
index 0000000000..a14bf9fb51
--- /dev/null
+++ b/examples/multi-block-comment-copy.clj
@@ -0,0 +1,40 @@
+;; And this is all working too....
+;; This buffer shows a "block-comment" where we wish to comment large blocks
+;; of the buffer between one lentic buffer and the other.
+;; hello well this is all working
+;; In this case, we use latex tags to indicate the code blocks. Outside of
+;; these tags, we start every line with comments. Inside we do not (although
+;; we leave comments that are there.
+
+;; \begin{code}
+(println "It is now broken")
+;; \end{code}
+
+;; We can have multiple code blocks, of course, after the first.
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "Hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And we can put more comments after the final text. And finally, we finish
+;; with a file local variable to tell lentic what kind of text this is. Note
+;; that start characters which are comments in both clojure and latex. In real
+;; use dir-local variables work better.
+
+;; %%
+;; %% Local Variables:
+;; %% lentic-init: (lentic-default-init lentic-clojure-latex-init)
+;; %% End:
+;; %%
diff --git a/examples/multi-block-comment.clj b/examples/multi-block-comment.clj
new file mode 100644
index 0000000000..9dcd074d73
--- /dev/null
+++ b/examples/multi-block-comment.clj
@@ -0,0 +1,39 @@
+;; This buffer shows a "block-comment" where we wish to comment large blocks
+;; of the buffer between one lentic buffer and the other.
+
+;; In this case, we use latex tags to indicate the code blocks. Outside of
+;; these tags, we start every line with comments. Inside we do not (although
+;; we leave comments that are there.
+
+;; \begin{code}
+(println "It is now broken")
+;; \end{code}
+
+;; We can have multiple code blocks, of course, after the first.
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "Hello")
+;; \end{code}
+
+;; And more
+
+;; \begin{code}
+(println "hello")
+;; \end{code}
+
+;; And we can put more comments after the final text. And finally, we finish
+;; with a file local variable to tell lentic what kind of text this is. Note
+;; that start characters which are comments in both clojure and latex. In real
+;; use dir-local variables work better.
+
+;; %%
+;; %% Local Variables:
+;; %% lentic-init: (lentic-clojure-latex-init lentic-default-init)
+;; %% End:
+;; %%
diff --git a/examples/multi-lentic-copy.txt b/examples/multi-lentic-copy.txt
new file mode 100644
index 0000000000..855842aa22
--- /dev/null
+++ b/examples/multi-lentic-copy.txt
@@ -0,0 +1,4 @@
+hello here we are and here and ehre
+Local Variables:
+lentic-init: (lentic-default-init lentic-default-init)
+End:
diff --git a/examples/multi-lentic.txt b/examples/multi-lentic.txt
new file mode 100644
index 0000000000..0471b9b68f
--- /dev/null
+++ b/examples/multi-lentic.txt
@@ -0,0 +1,4 @@
+
+Local Variables:
+lentic-init: (lentic-default-init lentic-default-init)
+End:
diff --git a/lentic-block.el b/lentic-block.el
index a69785cd13..06b4ca648a 100644
--- a/lentic-block.el
+++ b/lentic-block.el
@@ -341,34 +341,40 @@ between the two buffers; we don't care which one has
comments."
"start")
(when stop-in-comment
"stop")))
- ;; now clone the buffer
- (call-next-method conf start stop length-before
- start-converted stop-converted)
- ;; remove the line comments in the to buffer
- ;; if the delimitors are unmatched, then we can do nothing other than
clone.
- (condition-case e
- (lentic-blk-uncomment-buffer
- conf
- ;; the buffer at this point has been copied over, but is in an
- ;; inconsistent state (because it may have comments that it should
- ;; not). Still, the convertor should still work because it counts from
- ;; the end
- (lentic-convert
- conf
- ;; point-min if we know nothing else
- (or start (point-min)))
- (lentic-convert
- conf
- ;; if we have a stop
- (if stop
- ;; take stop (if we have got longer) or
- ;; start length before (if we have got shorter)
- (max stop
- (+ start length-before))
- (point-max)))
- (lentic-that conf))
- (unmatched-delimiter-error
- nil))))
+ ;; now clone the buffer, recording the return value unless either the
+ ;; start or the stop is in comment, in which case we need a nil.
+ (let* ((clone-return
+ (call-next-method conf start stop length-before
+ start-converted stop-converted))
+ (clone-return
+ (unless (or start-in-comment stop-in-comment)
+ clone-return)))
+ ;; remove the line comments in the to buffer
+ ;; if the delimitors are unmatched, then we can do nothing other than
clone.
+ (condition-case e
+ (lentic-blk-uncomment-buffer
+ conf
+ ;; the buffer at this point has been copied over, but is in an
+ ;; inconsistent state (because it may have comments that it should
+ ;; not). Still, the convertor should still work because it counts
from
+ ;; the end
+ (lentic-convert
+ conf
+ ;; point-min if we know nothing else
+ (or start (point-min)))
+ (lentic-convert
+ conf
+ ;; if we have a stop
+ (if stop
+ ;; take stop (if we have got longer) or
+ ;; start length before (if we have got shorter)
+ (max stop
+ (+ start length-before))
+ (point-max)))
+ (lentic-that conf))
+ (unmatched-delimiter-error
+ nil))
+ clone-return)))
(defmethod lentic-invert
((conf lentic-commented-block-configuration))
@@ -395,7 +401,7 @@ between the two buffers; we don't care which one has
comments."
(defmethod lentic-clone
((conf lentic-uncommented-block-configuration)
&optional start stop length-before start-converted stop-converted)
- "Update the contents in the lentic with comments."
+ "Update the contents in the lentic without comments."
;;(lentic-log "blk-clone-comment conf):(%s)" conf)
(let*
((start-at-bolp
@@ -412,30 +418,35 @@ between the two buffers; we don't care which one has
comments."
(lentic-log "In comment: %s"
(when start-at-bolp
"start")))
- (call-next-method conf start stop length-before
- start-converted stop-converted)
- (condition-case e
- (lentic-blk-comment-buffer
- conf
- ;; the buffer at this point has been copied over, but is in an
- ;; inconsistent state (because it may have comments that it should
- ;; not). Still, the convertor should still work because it counts from
- ;; the end
- (lentic-convert
- conf
- ;; point-min if we know nothing else
- (or start (point-min)))
- (lentic-convert
- conf
- ;; if we have a stop
- (if stop
- ;; take stop (if we have got longer) or
- ;; start length before (if we have got shorter)
- (max stop
- (+ start length-before))
- (point-max)))
- (lentic-that conf))
- (unmatched-delimiter-error nil))))
+ (let* ((clone-return
+ (call-next-method conf start stop length-before
+ start-converted stop-converted))
+ (clone-return
+ (unless start-at-bolp
+ clone-return)))
+ (condition-case e
+ (lentic-blk-comment-buffer
+ conf
+ ;; the buffer at this point has been copied over, but is in an
+ ;; inconsistent state (because it may have comments that it should
+ ;; not). Still, the convertor should still work because it counts
from
+ ;; the end
+ (lentic-convert
+ conf
+ ;; point-min if we know nothing else
+ (or start (point-min)))
+ (lentic-convert
+ conf
+ ;; if we have a stop
+ (if stop
+ ;; take stop (if we have got longer) or
+ ;; start length before (if we have got shorter)
+ (max stop
+ (+ start length-before))
+ (point-max)))
+ (lentic-that conf))
+ (unmatched-delimiter-error nil))
+ clone-return)))
(defmethod lentic-invert
((conf lentic-uncommented-block-configuration))
diff --git a/lentic-delayed.el b/lentic-delayed.el
deleted file mode 100644
index 60d1ddf1d1..0000000000
--- a/lentic-delayed.el
+++ /dev/null
@@ -1,120 +0,0 @@
-;; lentic-delayed.el --- lentics but slowly -*- lexical-binding: t -*-
-
-;;; Header:
-
-;; This file is not part of Emacs
-
-;; Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
-;; Maintainer: Phillip Lord <phillip.lord@newcastle.ac.uk>
-
-;; The contents of this file are subject to the GPL License, Version 3.0.
-;;
-;; Copyright (C) 2014, 2015, Phillip Lord, Newcastle University
-;;
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This runs lentic updates in the idle cycle. It is not really necessary now,
-;; as lentic now percolates updates incrementally, rather than copying entire
-;; buffers with every keypress.
-
-;; However, incremental updates are a lot harder to implement than cloning the
-;; entire buffer, so this might still be useful.
-
-;;; Code:
-;; #+begin_src emacs-lisp
-(require 'lentic)
-(require 'dash)
-
-(defvar lentic-delayed-queue nil)
-(defvar lentic-delayed-timer nil)
-
-(defun lentic-delayed-ensure-timer ()
- (unless lentic-delayed-timer
- (setq lentic-delayed-timer
- (run-with-idle-timer 0.2 t 'lentic-delayed-timer-function))))
-
-(defun lentic-delayed-timer-function ()
- (let ((repeat t))
- (while
- (and repeat
- lentic-delayed-queue)
- (lentic-delayed-clone
- (pop lentic-delayed-queue))
- ;; redisplay and wait
- (setq repeat (sit-for 0.1))))
- ;; kill timer if we have finished
- (unless lentic-delayed-queue
- (when lentic-delayed-timer
- (cancel-timer lentic-delayed-timer))
- (setq lentic-delayed-timer nil)))
-
-(defclass lentic-delayed-configuration
- (lentic-configuration)
- ((delayed
- :initarg :delayed))
- "lentic in the idle cycle.")
-
-(defmethod lentic-this ((conf lentic-delayed-configuration))
- (lentic-this (oref conf :delayed)))
-
-(defmethod lentic-that ((conf lentic-delayed-configuration))
- (lentic-that (oref conf :delayed)))
-
-(defmethod lentic-create ((conf lentic-delayed-configuration))
- (let ((buf (lentic-create (oref conf :delayed))))
- ;; we should now have set up that-buffer and config, which will be the
- ;; undelayed form -- so swap a new one in
- (with-current-buffer
- (lentic-that conf)
- (setq lentic-config
- (lentic-delayed-configuration
- "inverted-delayed"
- :delayed lentic-config)))
- buf))
-
-
-(defmethod lentic-convert ((conf lentic-delayed-configuration)
- location)
- (lentic-convert (oref conf :delayed) location))
-
-(defmethod lentic-clone ((conf lentic-delayed-configuration)
- &rest _rest)
- (add-to-list 'lentic-delayed-queue
- conf t)
- (lentic-delayed-ensure-timer))
-
-(defmethod lentic-delayed-clone ((conf
- lentic-delayed-configuration))
- ;; inhibit-modification-hooks or we percolate back to the start
- (let ((inhibit-modification-hooks t))
- (lentic-clone (oref conf :delayed))
- (lentic-update-point (oref conf :delayed))))
-
-;;;###autoload
-(defun lentic-delayed-init (delayed)
- (unless lentic-config
- (lentic-delayed-configuration
- "delayed"
- :delayed (funcall delayed))))
-
-;;;###autoload
-(defun lentic-delayed-default-init ()
- (lentic-delayed-init
- 'lentic-default-init))
-
-(provide 'lentic-delayed)
-;;; lentic-delayed.el ends here
-;; #+end_src
diff --git a/lentic-dev.el b/lentic-dev.el
index efe5b7aaf2..0450e1fede 100644
--- a/lentic-dev.el
+++ b/lentic-dev.el
@@ -77,7 +77,31 @@ Using this function is the easiest way to test an new
painful for debugging. Set variable `lentic-emergency' to
true to disable command loop functionality."
(interactive)
- (lentic-post-command-hook-1))
+ (lentic-post-command-hook-1 (current-buffer) '()))
+
+;;;###autoload
+(defun lentic-dev-after-save-hook ()
+ (interactive)
+ (let ((lentic-emergency nil))
+ (lentic-mode-after-save-hook)))
+
+;;;###autoload
+(defun lentic-dev-mode-buffer-list-update-hook ()
+ (interactive)
+ (let ((lentic-emergency nil))
+ (lentic-mode-buffer-list-update-hook)))
+
+;;;###autoload
+(defun lentic-dev-kill-buffer-hook ()
+ (interactive)
+ (let ((lentic-emergency nil))
+ (lentic-kill-buffer-hook)))
+
+;;;###autoload
+(defun lentic-dev-kill-emacs-hook ()
+ (interactive)
+ (let ((lentic-emergency nil))
+ (lentic-kill-emacs-hook)))
;;;###autoload
(defun lentic-dev-reinit ()
@@ -87,7 +111,6 @@ to make sure there is a new one."
(interactive)
(funcall lentic-init))
-
;; #+end_src
;; ** Font-Lock changes
diff --git a/lentic-mode.el b/lentic-mode.el
index f77356e5fc..2473507004 100644
--- a/lentic-mode.el
+++ b/lentic-mode.el
@@ -36,6 +36,36 @@
(require 'lentic-doc)
;; #+end_src
+;; ** Utility
+(defun lentic-mode-lentic-list (buffer)
+ "Return a list of all lentics for BUFFER.
+Lentics are listed in an undefined order."
+ (lentic-mode--lentic-list-1 buffer nil))
+
+(defun lentic-mode--lentic-list-1 (buffer seen-buffer)
+ (when buffer
+ (with-current-buffer buffer
+ (lentic-when-lentic
+ (setq seen-buffer (cons buffer seen-buffer))
+ (-map
+ (lambda (config)
+ (unless (-contains? seen-buffer (lentic-that config))
+ (lentic-mode--lentic-list-1
+ (lentic-that config)
+ seen-buffer)))
+ (lentic-config))))))
+
+(defun lentic-mode-buffer-list (buffer &optional frame)
+ "Returns a list of all lentics for BUFFER.
+Lentics are listed in the same order as in fundamental
+`buffer-list'. or the frame local if FRAME is specified."
+ (let ((lentic-list
+ (lentic-mode-lentic-list buffer)))
+ (-filter
+ (lambda (b)
+ (-contains? lentic-list b))
+ (buffer-list frame))))
+
;; ** Window and Buffer Functions
;; #+begin_src emacs-lisp
@@ -51,7 +81,8 @@ then the current-buffer will be moved into that window. See
also
(point)))
(lentic-mode-swap-buffer-windows
(current-buffer)
- (lentic-that lentic-config))
+ (lentic-that
+ (car lentic-config)))
(set-window-start
(selected-window)
before-window-start)
@@ -65,7 +96,8 @@ See also `lentic-mode-move-lentic-window'."
(interactive)
(lentic-mode-swap-buffer-windows
(current-buffer)
- (lentic-that lentic-config))
+ (lentic-that
+ (car lentic-config)))
(when (window-live-p
(get-buffer-window
(current-buffer)))
@@ -85,6 +117,7 @@ A and B are the buffers."
(set-window-buffer
window-b a))))
+;;;###autoload
(defun lentic-mode-create-in-selected-window ()
"Create a lentic buffer and move it to the current window."
(interactive)
@@ -92,30 +125,30 @@ A and B are the buffers."
(window-start (get-buffer-window)))
(before-window-point
(point)))
- (lentic-ensure-init)
(set-window-buffer
(selected-window)
- (lentic-create lentic-config))
+ (-take 1
+ (lentic-init-all-create lentic-config)))
(set-window-start
(selected-window)
before-window-start)
(goto-char before-window-point)))
+;;;###autoload
(defun lentic-mode-split-window-below ()
"Create a lentic buffer in a new window below."
(interactive)
- (lentic-ensure-init)
(set-window-buffer
(split-window-below)
- (lentic-create lentic-config)))
+ (car (lentic-init-all-create))))
+;;;###autoload
(defun lentic-mode-split-window-right ()
"Create a lentic buffer in a new window right."
(interactive)
- (lentic-ensure-init)
(set-window-buffer
(split-window-right)
- (lentic-create lentic-config)))
+ (car (lentic-init-all-create))))
;; #+end_src
;; ** Minor Mode
@@ -161,20 +194,27 @@ A and B are the buffers."
(format " %s[%s]"
lentic-mode-line-lighter
(if lentic-config
- (lentic-mode-line-string lentic-config)
+ (s-join ","
+ (-map
+ (lambda (conf)
+ (lentic-mode-line-string conf))
+ lentic-config))
"")))
(force-mode-line-update))
(defun lentic-mode-buffer-list-update-hook ()
- (-map
- (lambda (b)
- (with-current-buffer
- b
- (lentic-mode-update-mode-line)))
- (buffer-list)))
+ (if lentic-emergency
+ (setq lentic-mode-line
+ (format " %s[Emergency]" lentic-mode-line-lighter))
+ (-map
+ (lambda (b)
+ (with-current-buffer
+ b
+ (lentic-mode-update-mode-line)))
+ (buffer-list))))
(add-hook 'buffer-list-update-hook
- 'lentic-mode-buffer-list-update-hook)
+ 'lentic-mode-buffer-list-update-hook)
;;;###autoload
(define-minor-mode lentic-mode
diff --git a/lentic.el b/lentic.el
index 026b39fac2..21cdb589d4 100644
--- a/lentic.el
+++ b/lentic.el
@@ -6,8 +6,8 @@
;; Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
;; Maintainer: Phillip Lord <phillip.lord@newcastle.ac.uk>
-;; Version: 0.7.1
-;; Package-Requires: ((emacs "24.4")(m-buffer "0.8")(dash "2.5.0")(f "0.17.2"))
+;; Version: 0.8
+;; Package-Requires: ((emacs "24.4")(m-buffer "0.9")(dash "2.5.0")(f "0.17.2"))
;; The contents of this file are subject to the GPL License, Version 3.0.
@@ -175,6 +175,7 @@
(require 'eieio)
(require 'm-buffer)
+(require 'm-buffer-at)
(defvar lentic-init 'lentic-default-init
"Function that initializes a lentic.
@@ -200,9 +201,10 @@ of mode in the current buffer.")
"A list of all functions that can be used as lentic-init
functions.")
+(defvar lentic-counter 0)
(defun lentic-config-name (buffer)
"Given BUFFER, return a name for the configuration object."
- (format "lentic: %s" buffer))
+ (format "lentic \"%s:%s\"" buffer (setq lentic-counter (+ 1
lentic-counter))))
;; #+end_src
;; ** Base Configuration
@@ -214,7 +216,7 @@ of mode in the current buffer.")
;; #+begin_src emacs-lisp
;;
;; Base Configuration:
-;;
+
(defclass lentic-configuration ()
((this-buffer
:initarg :this-buffer)
@@ -252,6 +254,7 @@ by which linking happens.")
(defgeneric lentic-convert (conf location))
(defgeneric lentic-invert (conf that-buffer))
+
(defmethod lentic-this ((conf lentic-configuration))
(oref conf :this-buffer))
@@ -328,29 +331,37 @@ created."
(let* ((this-buffer
(lentic-this conf))
(that-buffer
- (get-buffer-create
+ (generate-new-buffer
(format "*lentic: %s*"
(buffer-name
this-buffer))))
+ ;; TODO this is broken -- it's setting clojure mode when I don't want
+ ;; it for instance with tex
+ (sec-file (oref conf :lentic-file))
(sec-mode
- (or (oref conf :lentic-mode)
- major-mode))
- (sec-file (oref conf :lentic-file)))
+ (or
+ ;; the specified normal mode
+ (oref conf :lentic-mode)
+ ;; if we have a file try normal mode
+ (if sec-file
+ 'normal-mode
+ ;; otherwise the same mode as the main file
+ major-mode))))
(oset conf :creator t)
;; make sure this-buffer knows about that-buffer
(oset conf :that-buffer that-buffer)
- ;; insert the contents
- (lentic-update-contents conf)
;; init that-buffer with mode, file and config
;; the mode must be init'd after adding content in case there are any
;; file-local variables need to be evaled
+ ;; insert the contents
+ (lentic-update-contents conf)
(with-current-buffer that-buffer
(when sec-mode
(funcall sec-mode))
(when sec-file
(set-visited-file-name sec-file))
(setq lentic-config
- (lentic-invert conf)))
+ (list (lentic-invert conf))))
that-buffer))
(defmethod lentic-invert ((conf lentic-default-configuration))
@@ -370,7 +381,16 @@ the lentic."
start-converted stop-converted)
"Updates that-buffer to reflect the contents in this-buffer.
-Currently, this is just a clone all method but may use regions in future."
+Updates at least the region that has been given between start and
+stop in the this-buffer, into the region start-converted and
+stop-converted in that-buffer.
+
+Returns a list of the start location in that-buffer of the
+change, the stop location in that-buffer of the change and the
+length-before in that buffer of the region changed before the
+change, if and only if the changes are exactly that suggested by
+the START, STOP, _LENGTH-BEFORE, START-CONVERTED and
+STOP-CONVERTED. Otherwise, this should return nil."
(let ((this-b (lentic-this conf))
(that-b (lentic-that conf)))
(with-current-buffer this-b
@@ -385,14 +405,17 @@ Currently, this is just a clone all method but may use
regions in future."
;; lentic-convert is not reliable now, because the two
;; buffers do not share state until we have percolated it
(let ((converted-start
- (or start-converted
- (point-min)))
+ (max (point-min)
+ (or start-converted
+ (point-min))))
(converted-stop
- (or stop-converted
- (point-max))))
+ (min (point-max)
+ (or stop-converted
+ (point-max)))))
+ ;; does this widen do anything?
(widen)
- (delete-region (max (point-min) converted-start)
- (min (point-max) converted-stop))
+ (delete-region converted-start
+ converted-stop)
(save-excursion
(goto-char converted-start)
;; so this insertion is happening at the wrong place in block
@@ -403,7 +426,10 @@ Currently, this is just a clone all method but may use
regions in future."
;; hence the property
(lentic-insertion-string-transform
(buffer-substring-no-properties
- start stop)))))))))))))
+ start stop))))
+ (list converted-start
+ (+ converted-start (- stop start))
+ (- converted-stop converted-start)))))))))))
;;;###autoload
(defun lentic-default-init ()
@@ -429,13 +455,44 @@ see `lentic-init' for details."
(declare (debug t))
`(when (and
lentic-config
- (lentic-that
- lentic-config)
- (buffer-live-p
- (lentic-that
- lentic-config)))
+ (-any?
+ (lambda (conf)
+ (-when-let
+ (buf (lentic-that conf))
+ (buffer-live-p buf)))
+ lentic-config))
,@body))
+(defmacro lentic-when-with-current-buffer (buffer &rest body)
+ (declare (debug t)
+ (indent 1))
+ `(when (and buffer
+ (buffer-live-p buffer))
+ (with-current-buffer
+ buffer
+ ,@body)))
+
+(defun lentic-each (buffer fn &optional seen-buffer)
+ "Starting at buffer, call fn on every lentic-buffer in the
+excluding buffer. fn should take a single argument which is the
+buffer."
+ ;; when buffer is sane
+ (when (and buffer
+ (buffer-live-p buffer))
+ ;; and is lentic
+ (with-current-buffer buffer
+ (when lentic-config
+ (setq seen-buffer (cons buffer seen-buffer))
+ (-map
+ (lambda (conf)
+ (let ((that
+ (lentic-that conf)))
+ (when (and (not (-contains? seen-buffer that))
+ (buffer-live-p that))
+ (funcall fn that)
+ (lentic-each that fn seen-buffer))))
+ lentic-config)))))
+
(defun lentic-ensure-hooks ()
"Ensures that the hooks that this mode requires are in place."
(add-hook 'post-command-hook
@@ -507,39 +564,43 @@ repeated errors.")
(interactive)
(setq lentic-emergency nil))
-(defvar lentic-saving-p nil)
-
(defun lentic-after-save-hook ()
- (lentic-when-lentic
- ;; don't want to recurse!
- (when (not lentic-saving-p)
- (let ((lentic-saving-p t))
+ (unless lentic-emergency
+ (lentic-each
+ (current-buffer)
+ (lambda (buffer)
(with-current-buffer
- (lentic-that lentic-config)
- (when (buffer-file-name)
- (save-buffer)))))))
+ buffer
+ (save-buffer))))))
(defvar lentic-kill-retain nil
"If non-nil retain files even if requested to delete on exit.")
(defun lentic-kill-buffer-hook ()
(lentic-when-lentic
- (progn
- ;; remove files
- (when
- (and (oref lentic-config :delete-on-exit)
- ;; might not exist if we not saved yet!
- (file-exists-p buffer-file-name)
- ;; if we are cloning in batch, we really do not want to kill
- ;; everything at the end
- (not noninteractive)
- ;; or we have blocked this anyway
- (not lentic-kill-retain))
- (delete-file (buffer-file-name)))
- ;; kill lentic-buffers
- (when (oref lentic-config :creator)
- (kill-buffer
- (lentic-that lentic-config))))))
+ (when
+ (and
+ (--any?
+ (oref it :delete-on-exit)
+ lentic-config)
+ ;; might not exist if we not saved yet!
+ (file-exists-p buffer-file-name)
+ ;; if we are cloning in batch, we really do not want to kill
+ ;; everything at the end
+ (not noninteractive)
+ ;; or we have blocked this anyway
+ (not lentic-kill-retain))
+ (delete-file (buffer-file-name)))
+ ;; if we were the creator buffer, blitz the lentics (which causes their
+ ;; files to delete also).
+ (when
+ (--any?
+ (oref it :creator)
+ lentic-config)
+ (lentic-each
+ (current-buffer)
+ (lambda (buffer)
+ (kill-buffer buffer))))))
(defun lentic-kill-emacs-hook ()
(-map
@@ -547,55 +608,86 @@ repeated errors.")
(with-current-buffer
b
(when
- (and lentic-config
- (oref lentic-config :delete-on-exit)
- (file-exists-p buffer-file-name)
- (not noninteractive))
- (delete-file (buffer-file-name)))))
+ lentic-config
+ ;; delete if any delete-on-exit
+ (-map
+ (lambda (conf)
+ (and
+ (oref conf :delete-on-exit)
+ (file-exists-p buffer-file-name)
+ (not noninteractive)
+ (delete-file (buffer-file-name))))
+ lentic-config))))
(buffer-list)))
(defun lentic-post-command-hook ()
"Update point according to config, with error handling."
- ;;(message "Entering post-command-hook")
(unless lentic-emergency
(condition-case err
- (lentic-post-command-hook-1)
+ (progn
+ (lentic-post-command-hook-1 (current-buffer)))
(error
(lentic-hook-fail err "post-command-hook")))))
-(defun lentic-post-command-hook-1 ()
+(defun lentic-post-command-hook-1 (buffer &optional seen-buffer)
"Update point according to config."
- (progn
- (lentic-when-lentic
- (lentic-update-point lentic-config))))
+ (lentic-when-with-current-buffer
+ buffer
+ ;; only if at least one config is live
+ (when lentic-config
+ ;; now we have seen this buffer don't look again
+ (setq seen-buffer (cons buffer seen-buffer))
+ ;; for all configurations
+ (-map
+ (lambda (config)
+ ;; check for the termination condition
+ (unless (-contains? seen-buffer (lentic-that config))
+ ;; then update and recurse
+ (lentic-update-point config)
+ (lentic-post-command-hook-1 (lentic-that config) seen-buffer)))
+ lentic-config))))
(defun lentic-hook-fail (err hook)
"Give an informative message when we have to fail.
ERR is the error. HOOK is the hook type."
- (message "lentic mode has failed on %s hook: %s "
+ (message "lentic mode has failed on \"%s\" hook: %s "
hook (error-message-string err))
(lentic-emergency)
(with-output-to-temp-buffer "*lentic-fail*"
(princ "There has been an error in lentic-mode.\n")
(princ "The following is debugging information\n\n")
+ (princ (format "Hook: %s" hook))
(princ (error-message-string err)))
(select-window (get-buffer-window "*lentic-fail*")))
(defun lentic-ensure-init ()
"Ensure that the `lentic-init' has been run."
(unless (and lentic-config
- (slot-boundp
- lentic-config :that-buffer)
- (buffer-live-p (lentic-that
- lentic-config)))
+ (-any?
+ (lambda (conf)
+ (and
+ (slot-boundp conf :that-buffer)
+ (buffer-live-p
+ (lentic-that conf))))
+ lentic-config))
(setq lentic-config
- (funcall lentic-init))))
+ (-map
+ (lambda (init)
+ (funcall init))
+ (-list lentic-init)))))
-(defun lentic-init-create ()
- "Create the lentic for current-buffer."
+(defun lentic-init-create (conf)
+ "Create the lentic for CONF."
(lentic-ensure-init)
- (lentic-create lentic-config))
+ (lentic-create conf))
+(defun lentic-init-all-create ()
+ "Create all lentics fo the current buffer."
+ (lentic-ensure-init)
+ (-map
+ (lambda (conf)
+ (lentic-create conf))
+ (-list lentic-config)))
(defvar lentic-emergency-last-change nil)
(make-variable-buffer-local 'lentic-emergency-last-change)
@@ -608,20 +700,35 @@ Errors are handled. REST is currently just ignored."
(setq lentic-emergency-last-change (list start stop length-before)))
(unless lentic-emergency
(condition-case err
- (lentic-after-change-function-1 start stop length-before)
+ (lentic-after-change-function-1
+ (current-buffer) start stop length-before)
(error
(lentic-hook-fail err "after change")))))
-(defun lentic-after-change-function-1 (start stop length-before)
+(defun lentic-after-change-function-1
+ (buffer start stop
+ length-before &optional seen-buffer)
"run change update according to `lentic-config'.
rest is currently just ignored."
- (lentic-when-lentic
- (lentic-log
- "after-change (start, stop, length-before): %s,%s,%s"
- start stop length-before)
- (lentic-update-contents lentic-config
- start stop length-before)))
-
+ (when buffer
+ (with-current-buffer buffer
+ (lentic-when-lentic
+ (setq seen-buffer (cons buffer seen-buffer))
+ (-map
+ (lambda (config)
+ (unless (-contains? seen-buffer (lentic-that config))
+ (let ((updates
+ (or
+ (lentic-update-contents config
+ start stop length-before)
+ '(nil nil nil))))
+ (lentic-after-change-function-1
+ (lentic-that config)
+ (nth 0 updates)
+ (nth 1 updates)
+ (nth 2 updates)
+ seen-buffer))))
+ lentic-config)))))
;; convert the start position and store it. we need to do this before
;; the change so that we can use the value during clone. after the
@@ -634,31 +741,38 @@ rest is currently just ignored."
lentic-emergency
(not lentic-emergency-debug))
(condition-case err
- (progn
- (lentic-when-lentic
- (oset lentic-config :last-change-start start)
- (oset lentic-config
- :last-change-start-converted
- (lentic-convert
- lentic-config
- start))
- (oset lentic-config :last-change-stop stop)
- (oset lentic-config
- :last-change-stop-converted
- (lentic-convert
- lentic-config
- stop)))
- (lentic-log
- "before change:(start,stop,start-c,stop-c,command): %s,%s,%s,%s,%s"
- start stop
- (oref lentic-config
- :last-change-start-converted)
- (oref lentic-config
- :last-change-stop-converted)
- this-command))
+ (lentic-before-change-function-1 (current-buffer) start stop)
(error
(lentic-hook-fail err "before change")))))
+(defun lentic-before-change-function-1 (buffer start stop &optional
seen-buffer)
+ (when buffer
+ (with-current-buffer buffer
+ (setq seen-buffer (cons buffer seen-buffer))
+ (lentic-when-lentic
+ (-map
+ (lambda (config)
+ (unless
+ (-contains? seen-buffer (lentic-that config))
+ (oset config :last-change-start start)
+ (oset config
+ :last-change-start-converted
+ (lentic-convert
+ config
+ start))
+ (oset config :last-change-stop stop)
+ (oset config
+ :last-change-stop-converted
+ (lentic-convert
+ config
+ stop))
+ (lentic-before-change-function-1
+ (lentic-that config)
+ (oref config :last-change-start-converted)
+ (oref config :last-change-stop-converted)
+ seen-buffer)))
+ lentic-config)))))
+
(defun lentic-update-contents (conf &optional start stop length-before)
"update the contents of that-buffer with the contents of this-buffer.
update mechanism depends on conf."
@@ -675,16 +789,20 @@ update mechanism depends on conf."
;; Currently, the best solution I have for this is to fall-back to a full
;; clone.
(let ((skewed
- (when (and
- ;; we can't be skewed where we have no region!
- start stop length-before
- ;; skews only occur in insertions which result in a positive
- ;; length-before. This also picks up no-insertion changes
- (and (< 0 length-before)
- ;; = start stop means we have a deletion because
- ;; there is no range after. Deletions seem to be
- ;; safe.
- (not (= start stop))))
+ (when
+ (or
+ ;; previously this was not skewed if no region, but actually,
+ ;; if there is no region we need to copy everything, we can
+ ;; also do by declaring skew -- this is important for the
+ ;; multi-lentic situation
+ (not (or start stop length-before))
+ ;; skews only occur in insertions which result in a positive
+ ;; length-before. This also picks up no-insertion changes
+ (and (< 0 length-before)
+ ;; = start stop means we have a deletion because
+ ;; there is no range after. Deletions seem to be
+ ;; safe.
+ (not (= start stop))))
(lentic-log "Skew detected: %s" this-command)
t)))
(m-buffer-with-markers
@@ -707,8 +825,6 @@ update mechanism depends on conf."
(oset conf :last-change-start-converted nil)
(oset conf :last-change-stop nil)
(oset conf :last-change-stop-converted nil)
- ;;(lentic-log
- ;;"Update config: %s" lentic-config)
(if skewed
(lentic-clone conf)
(lentic-clone conf start stop length-before
@@ -723,9 +839,8 @@ same top-left location. Update details depend on CONF."
(let* ((from-point
(lentic-convert
conf
- (with-current-buffer
- (lentic-this conf)
- (point))))
+ (m-buffer-at-point
+ (lentic-this conf))))
(from-window-start
(lentic-convert
conf
@@ -773,7 +888,8 @@ lentic is open already."
(find-file-noselect filename)
(setq lentic-init init)
(with-current-buffer
- (lentic-init-create)
+ (car
+ (lentic-init-all-create))
(save-buffer)
(kill-buffer))
(kill-buffer)))
@@ -788,7 +904,8 @@ Return the lentic contents without properties."
(find-file-noselect filename)
(setq lentic-init init)
(with-current-buffer
- (lentic-init-create)
+ (car
+ (lentic-init-all-create))
(setq retn
(buffer-substring-no-properties
(point-min)
diff --git a/lenticular.org b/lenticular.org
index 6a56c90f3b..92c9908676 100644
--- a/lenticular.org
+++ b/lenticular.org
@@ -86,12 +86,6 @@ Tools for developers of new configurations.
#+include: "lentic-dev.org" :minlevel 2
-* Lentic Delayed
-
-A slightly useful package for cloning in the idle cycle.
-
-#+include: "lentic-delayed.org" :minlevel 2
-
* Lentic Doc
Lentic has a self-hosting documentation system which is defined here.
diff --git a/test/lentic-test.el b/test/lentic-test.el
index 31aaeb0337..14e8cf2364 100644
--- a/test/lentic-test.el
+++ b/test/lentic-test.el
@@ -2,7 +2,6 @@
(require 'lentic-latex-code)
(require 'lentic-asciidoc)
(require 'lentic-org)
-(require 'lentic-delayed)
(require 'lentic-rot13)
(require 'f)
@@ -61,22 +60,32 @@
(buffer-string))))
nil)))
+(defun lentic-test-clone-with-cleanup (file init)
+ (unwind-protect
+ (lentic-batch-clone-with-config (lentic-test-file file) init)
+ (let ((this (get-file-buffer (lentic-test-file file))))
+ (when this
+ (with-current-buffer this
+ (let ((this (lentic-that (car lentic-config))))
+ (kill-buffer that)))
+ (kill-buffer this)))))
+
(defun lentic-test-clone-equal (init file cloned-file)
(let ((cloned-file
(f-read
(lentic-test-file cloned-file)))
(cloned-results
- (lentic-batch-clone-with-config
- (lentic-test-file file) init)))
+ (lentic-test-clone-with-cleanup
+ file init)))
(lentic-test-equal-loudly cloned-file cloned-results)))
(defun lentic-test-clone-equal-generate
(init file cloned-file)
"Generates the test file for `lentic-batch-clone-equal'."
(f-write
- (lentic-batch-clone-with-config
+ (lentic-test-clone-with-cleanup
(lentic-test-file file) init)
- 'utf-8
+ o'utf-8
(concat lentic-test-dir cloned-file))
;; return nil, so if we use this in a test by mistake, it will crash out.
nil)
@@ -91,15 +100,16 @@
(ert-deftest lentic-simple ()
(should
(equal "simple\n"
- (lentic-batch-clone-with-config
- (lentic-test-file "simple-contents.txt")
+ (lentic-test-clone-with-cleanup
+ "simple-contents.txt"
'lentic-default-init))))
(ert-deftest lentic-clojure-latex ()
(should
(lentic-test-clone-equal
'lentic-clojure-latex-init
- "block-comment.clj" "block-comment-out.tex")))
+ "block-comment.clj"
+ "block-comment-out.tex")))
(ert-deftest lentic-asciidoc-clojure ()
@@ -146,8 +156,25 @@
(should
(lentic-test-clone-equal
'lentic-rot13-init
- "abc.txt" "rot13-abc.txt"))
- )
+ "abc.txt" "rot13-abc.txt")))
+
+(ert-deftest three-way ()
+ (should
+ (with-current-buffer
+ (find-file-noselect
+ (lentic-test-file "block-comment.clj"))
+ (setq lentic-init
+ '(lentic-clojure-latex-init
+ lentic-default-init))
+ (lentic-init-all-create)
+ (let ((tex
+ (get-buffer "block-comment.tex"))
+ (clj
+ (get-buffer "*lentic: block-comment.clj*")))
+ (kill-buffer tex)
+ (kill-buffer clj)
+ (and clj tex)))))
+
;; incremental testing
@@ -172,10 +199,10 @@ results."
(with-current-buffer
(setq this
(find-file-noselect filename))
- (setq lentic-init init)
+ (setq lentic-init (-list init))
(progn
(setq that
- (lentic-init-create))
+ (car (lentic-init-all-create)))
(funcall f-this)
(with-current-buffer
that
@@ -196,8 +223,7 @@ results."
;; unwind forms
(when this (kill-buffer this))
- (when that (kill-buffer that))))
- ))
+ (when that (kill-buffer that))))))
(defun lentic-test-clone-and-change-equal
(init file cloned-file
@@ -360,18 +386,21 @@ This mostly checks my test machinary."
t)))
;; ** delayed init
-(ert-deftest lentic-simple-delayed ()
- (should
- (equal
- (concat "x" abc-txt)
- (lentic-test-clone-and-change-with-config
- (lentic-test-file "abc.txt")
- 'lentic-delayed-default-init
- (lambda ()
- (goto-char (point-min))
- (insert "x")
- ;; run timer by ourselves.
- (lentic-delayed-timer-function))))))
+
+;; Probably time to deprecate this package now
+
+;; (ert-deftest lentic-simple-delayed ()
+;; (should
+;; (equal
+;; (concat "x" abc-txt)
+;; (lentic-test-clone-and-change-with-config
+;; (lentic-test-file "abc.txt")
+;; 'lentic-delayed-default-init
+;; (lambda ()
+;; (goto-char (point-min))
+;; (insert "x")
+;; ;; run timer by ourselves.
+;; (lentic-delayed-timer-function))))))
;; tests for lots of types of change and whether they break the incremental
;; updates.
- [elpa] externals/lentic 11a35ea3ac 181/333: Prepare for next iteration., (continued)
- [elpa] externals/lentic 11a35ea3ac 181/333: Prepare for next iteration., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 4003ae1a41 194/333: Travis badge., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic d6ac74dc73 191/333: No error if m-buffer is not present., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 6587a9a0f7 198/333: Missing dev-resource added., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic a5a001f999 183/333: Lentic-mode menu corrected and extended., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 3431295354 195/333: License updates in some files., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 450de96809 187/333: Remove file on exit., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 9c60f116a8 200/333: Lentic top level documentation added., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 66a056211c 202/333: Copyright and Documentation updates., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 2e290c74e3 207/333: Multiple oset added, and factor constructors., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 71017538d7 211/333: Multiple lentic-buffers are now possible.,
ELPA Syncer <=
- [elpa] externals/lentic 0b8b94003d 214/333: Multiple buffer support for org/orgel., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 849dc0dc24 209/333: Default mode is now the same as main buffer., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 61d6ea4ac5 222/333: Save lentic buffers only when file-associated., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 28a1951c14 216/333: Use default-browser for external view., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 8a007a60c5 218/333: Default for init is now a list., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 35db8a038a 219/333: Major-mode functions reworked totally., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic 243d2710d1 224/333: Advance m-buffer version to fix point bug., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic bc6e3db510 237/333: Merge branch 'Prathyvsh-patch-1', ELPA Syncer, 2024/02/27
- [elpa] externals/lentic d4d494bb20 232/333: Full documentation for lentic.el., ELPA Syncer, 2024/02/27
- [elpa] externals/lentic e97bc286d7 241/333: Lentic-self doc moved to lentic-mode., ELPA Syncer, 2024/02/27