[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/m-buffer 5166d21792 081/115: Lentic documentation for m
From: |
ELPA Syncer |
Subject: |
[elpa] externals/m-buffer 5166d21792 081/115: Lentic documentation for m-buffer.el. |
Date: |
Tue, 19 Jul 2022 15:58:50 -0400 (EDT) |
branch: externals/m-buffer
commit 5166d21792c1035e79a5d77f86e51f3e8acbeb7c
Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
Commit: Phillip Lord <phillip.lord@newcastle.ac.uk>
Lentic documentation for m-buffer.el.
---
Makefile | 2 +-
README.md | 27 ++++++++
m-buffer-doc.org | 21 +++++-
m-buffer.el | 198 +++++++++++++++++++++++++++++++++++++------------------
4 files changed, 181 insertions(+), 67 deletions(-)
diff --git a/Makefile b/Makefile
index 4eae36d16a..9b1fc0b0fb 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ test: install
clean:
find . -name "m-buffer*org" -not -name "m-buffer-doc.org" \
-exec rm {} \;
- rm m-buffer-doc.html
+ - rm m-buffer-doc.html
.PHONY: test
diff --git a/README.md b/README.md
index 0f2bff0243..3b8b23a25b 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,33 @@ with the FSF.
## Change Log
+### 0.11
+
+This release mostly includes considerably improved documentation.
+
+There is one change which is half-way between a breaking change and a bug fix.
+Previously, in the m-buffer-match-* functions "match" arguments could take any
+keyword argument and these would over-ride any arguments already set. This
+means that a call such as:
+
+ (m-buffer-match-page (current-buffer) :regexp "this")
+
+would behave the same as:
+
+ (m-buffer-match (current-buffer) :regexp "this")
+
+rather than matching pages. Alternatively, this call:
+
+ (m-buffer-match-line
+ (current-buffer)
+ :post-match (lambda () t))
+
+never terminates. Both of these now throw an error instead.
+
+#### Breaking Changes
+
+- m-buffer-match-* functions now error
+
### 0.10
#### Bug Fixes
diff --git a/m-buffer-doc.org b/m-buffer-doc.org
index b649eca038..c869136dd4 100644
--- a/m-buffer-doc.org
+++ b/m-buffer-doc.org
@@ -16,7 +16,13 @@ side-effects. And, it adds some macros for cleanup, so
again, helping to
manage the process of global state where it can be avoided.
-** Caveat
+** Status
+
+`m-buffer' is a work in progress, but much of it is now stable and the
+interface should change only in forward-compatible ways for 1.0 release.
+The individual files have statements about their stability.
+
+** Caveat to Documentation
This is the first version of m-buffer with full
[[http://github.com/phillord/lentic][lenticular]] documentation. Both
lentic and this documentation are a work in progress. They will improve.
@@ -31,6 +37,7 @@ matches.
#+include: "m-buffer.org" :minlevel 2
+
* m-buffer-at
m-buffer-at.el provides a set of stateless functions which for accessing data
@@ -38,6 +45,7 @@ about buffers, without requiring changing the
`current-buffer'.
#+include: "m-buffer-at.org" :minlevel 2
+
* m-buffer-macro
m-buffer-macro.el provides some general purpose macros for:
@@ -46,3 +54,14 @@ m-buffer-macro.el provides some general purpose macros for:
- running code at a specific location
#+include: "m-buffer-macro.org" :minlevel 2
+
+
+* Roadmap
+
+** 0.11
+
+Full lentic documentation using lentic-server
+
+** 0.12
+
+Completion of m-buffer-at with all the core buffer functions.
diff --git a/m-buffer.el b/m-buffer.el
index ecf884cf98..cdbc4d75f0 100644
--- a/m-buffer.el
+++ b/m-buffer.el
@@ -29,30 +29,36 @@
;;; Commentary:
;; This file provides a set of list-oriented functions for operating over the
-;; contents of buffers. They avoid the use of looping, manipulating global
state
-;; with `match-data'. Many high-level functions exist for matching sentences,
-;; lines and so on.
-
-;; Functions are generally purish: i.e. they may change the state of one
-;; buffer by side-effect, but should not affect point, current buffer, match
-;; data or so forth. Generally, markers are returned rather than point
-;; locations, so that it is possible for example, to search for regexp
-;; matches, and then replace them all without the early replacement
-;; invalidating the location of the later ones.
-
-;; Other files provide something similar: stateless alternatives to existing
-;; emacs functions. `m-buffer-macro' provides macros to operate in the context
of
-;; a marker, and for marker cleanup. `m-buffer-at' provides functions for
-;; operating at point (without using point!).
-
-;; This file is documented using lentic.el.
+;; contents of buffers, mostly revolving around regexp searching, and regions.
+;; They avoid the use of looping, manipulating global state with `match-data'.
+;; Many high-level functions exist for matching sentences, lines and so on.
+
+;; Functions are generally purish: i.e. that is those functions which do
+;; change state, by for example replacing text or adding overlays, should only
+;; change state in one way; they will not affect point, current buffer, match
+;; data or so forth.
+
+;; Likewise to protect against changes in state, markers are used rather than
+;; integer positions. This means that it is possible, for example, to search
+;; for regexp matches and then replace them all without the earlier
+;; replacements invalidating the location of the later ones. Otherwise
+;; replacements need to be made in reverse order. This can have implications
+;; for performance, so m-buffer also provides functions for making markers nil;
+;; there are also macros which help manage markers in `m-buffer-macro'.
+
+;; Where possible, functions share interfaces. So most of the match functions
+;; take a list of "match" arguments, either position or as a plist, which
avoids
+;; using lots of `nil' arguments. Functions operating on matches take a list of
+;; `match-data' as returned by the match functions, making it easy to chain
+;; matches.
+
+;; This file is documented using lentic.el. Use
+;; [[http://github.com/phillord/lentic-server][lentic-server]] to view.
;;; Status:
-;; This library is early release at the moment. I write it become I got fed up
-;; with writing (while (re-search-forward) do-stuff) forms. I found that it
-;; considerably simplified writing `linked-buffer'. The API is beginning to
-;; stablize now and should not undergo major changes.
+;; m-buffer.el is now stable and is expected to change only in
+;; forward-compatible ways.
;;; Code:
@@ -64,10 +70,11 @@
;; ** Regexp Matching
-;; This section provides the core functions which convert between Emacs'
stateful
-;; matching and a more sequence oriented approach.
+;; We first provide a single match function, `m-bufffer-match' which converts
+;; between Emacs' stateful matching and a more sequence-oriented interface.
-;; `m-buffer-match' provides the main interface for this.
+;; This function also defines the "match" arguments which are a standard set of
+;; arguments used throughout this package.
;; #+begin_src emacs-lisp
(defun m-buffer-match (&rest match)
@@ -101,11 +108,10 @@ function will loop infinitely. POST-MATCH can be used to
avoid
this. The buffer is searched forward."
(apply 'm-buffer--match-1
(m-buffer--normalize-args match)))
-
-
;; #+end_src
-;; All match functions route through here at some point.
+;; The match function is actually implemented here in the `m-buffer--match-1'
+;; function, with positional arguments.
;; #+begin_src emacs-lisp
(defun m-buffer--match-1 (buffer regexp begin end
@@ -129,7 +135,8 @@ NUMERIC -- Non-nil if we should return integers not
markers."
;; #+end_src
;; We start by saving everything to ensure that we do not pollute the global
-;; state. This means match-data, point, narrowing and current buffer!
+;; state. This means match-data, point, narrowing and current buffer! Hopefully
+;; this is all the global state that exists and that we are changing.
;; #+begin_src emacs-lisp
(save-match-data
@@ -141,8 +148,9 @@ NUMERIC -- Non-nil if we should return integers not
markers."
;; #+end_src
;; This let form is doing a number of things. It sets up a dynamic binding for
-;; `case-fold-search', ensures a non-nil value for =end-bound= and defines a
-;; sentinal value that =post-match-return= can use to end early.
+;; `case-fold-search' (which works even though we are using lexical binding),
+;; ensures a non-nil value for =end-bound= and defines a sentinal value that
+;; =post-match-return= can use to end early.
;; #+begin_src emacs-lisp
(let ((rtn nil)
@@ -155,7 +163,8 @@ NUMERIC -- Non-nil if we should return integers not
markers."
cfs)))
;; #+end_src
-;; To begin at the beginning.
+;; We start at the beginning. There was no particularly good reason for this,
and
+;; it would have made just as much sense to go backward.
;; #+begin_src emacs-lisp
(goto-char
@@ -170,6 +179,12 @@ NUMERIC -- Non-nil if we should return integers not
markers."
;; terminates. Unfortunately, avoiding this depends on the regexp being called,
;; so we provide the most general solution of all.
+;; As well as this, we check the return value of =post-match-return=, so as
well
+;; as advancing `point' by side-effect, we can also use it to terminate the
look
+;; at any point that we want; for example, we can terminate after the first
match
+;; which feels more efficient than searching the whole buffer then taking the
+;; first match.
+
;; #+begin_src emacs-lisp
post-match-return
;; we need to check we are less than the end-bound
@@ -196,15 +211,21 @@ NUMERIC -- Non-nil if we should return integers not
markers."
(reverse rtn)))))))
;; #+end_src
-;; While this is all fairly nasty, it means that I can provide a keyword
argument
-;; interface to all the functions which follow. At the time of writing, we have
-;; eight arguments, most of which are not essential, so this is well worth the
-;; effort.
+;; This method implements the argument list processing. I find this interface
+;; fairly attractive to use since it takes the two "main" arguments -- buffer
and
+;; regexp -- as positional args optionally, and everything else as keywords.
The
+;; use of keywords is pretty much essential as have eight arguments most of
which
+;; are not essential.
+
+;; This is fairly close to the logic provided by `cl-defun' which I wasn't
aware
+;; of when I wrote this. However `cl-defun' does not allow optional arguments
+;; before keyword arguments -- all the optional arguments have to be given if
we
+;; are to use keywords.
;; #+begin_src emacs-lisp
(defun m-buffer--normalize-args (match-with)
"Manipulate args into a standard form and return as a list.
-MATCH-WITH are these args.This is an internal function."
+MATCH-WITH are these args. This is an internal function."
(let* (
;; split up into keyword and non keyword limits
(args
@@ -246,7 +267,7 @@ MATCH-WITH are these args.This is an internal function."
(plist-get pargs :widen))
;; case-fold-search this needs to overwrite the buffer contents iff
- ;; set, otherwise be ignore, so we need to distinguish a missing
+ ;; set, otherwise be ignored, so we need to distinguish a missing
;; property and a nil one
(cfs
(if (plist-member pargs :case-fold-search)
@@ -265,8 +286,17 @@ MATCH-WITH are these args.This is an internal function."
;; of arguments and then apply multiple manipulations on the returned match
data.
;; Or just use the match manipulation function directly.
-;; #+begin_src emacs-lisp
+;; The first version of `m-buffer' did not include this but it required lots of
+;; nested calls which seem inconvenient.
+
+;; #+begin_example
+;; (m-buffer-match-manipulate
+;; (m-buffer-match (current-buffer) "hello"))
+;; #+end_example
+;; I think that convienience is worth the overhead.
+
+;; #+begin_src emacs-lisp
(defun m-buffer-ensure-match (&rest match)
"Ensure that we have MATCH data.
If a single arg, assume it is match data and return. If multiple
@@ -280,13 +310,12 @@ args, assume they are of the form accepted by
(apply 'm-buffer-match match))
(t
(error "Invalid arguments"))))
-
;; #+end_src
;; ** Match Data Manipulation Functions
-;; These functions take either a list of match-data or arguments for a match,
-;; and manipulate it in some way.
+;; These functions manipulate lists of either match-data or match arguments in
+;; some way.
;; #+begin_src emacs-lisp
(defun m-buffer-buffer-for-match (match-data)
@@ -385,7 +414,6 @@ function. See `m-buffer-nil-marker' for details."
"Return true if M and N are cover the same region.
Matches are equal if they match the same region; subgroups are
ignored."
- ;; can we speed this up by not making subsets?
(and
(equal
(car m)
@@ -393,7 +421,12 @@ ignored."
(equal
(cadr m)
(cadr n))))
+;; #+end_src
+
+;; A nice simple implementation for the general purpose solution.
+;; Unfortunately, performance sucks, running in quadratic time.
+;; #+begin_src emacs-lisp
(defun m-buffer-match-subtract (m n)
"Remove from M any match in N.
Matches are equivalent if overall they match the same
@@ -407,7 +440,12 @@ runs faster but has some restrictions."
(m-buffer-match-equal o p))
n))
m))
+;; #+end_src
+
+;; The ugly and complicated and less general solution. But it runs in linear
+;; time.
+;; #+begin_src emacs-lisp
(defun m-buffer-match-exact-subtract (m n)
"Remove from M any match in N.
Both M and N must be fully ordered, and any element in N must be
@@ -452,16 +490,16 @@ in M."
(<= (car match) position)
(<= position (cadr match))))
matches))
-
;; #+end_src
-;; ** Marker Position Utility
+;; ** Marker manipulation functions
-;; Functions for transforming between markers and positions, and
-;; for niling markers, to prevent buffer slow down before GC.
+;; These functions do things to markers rather than the areas of the buffers
+;; indicated by the markers. This includes transforming between markers and
+;; integer positions, and niling markers explicitly, which prevents slow down
+;; before garbage collection.
;; #+begin_src emacs-lisp
-
(defun m-buffer-nil-marker (markers)
"Takes a (nested) list of MARKERS and nils them all.
Markers slow buffer movement while they are pointing at a
@@ -579,13 +617,16 @@ Remove all properties from return."
'substring-no-properties
(m-buffer-match-string
match-data subexp)))
-
;; #+end_src
;; ** Match Things
-;; These functions provide a set of pre-defined args for matching common
-;; entities.
+;; Emacs comes with a set of in-built regexps most of which we use here.
+
+;; We define `m-buffer-apply-snoc' first. The reason for this function is that
+;; we want to take a list of match arguments and add to with, for instance, a
+;; regular expression. We need to add these at the end because most of our
+;; functions contain some positional arguments.
;; #+begin_src emacs-lisp
@@ -593,17 +634,26 @@ Remove all properties from return."
"Apply FN to LIST and all ELEMENT."
(apply
fn (append list element)))
+;; #+end_src
+;; For the following code, we use Emacs core regexps where possible.
+
+;; #+begin_src emacs-lisp
(defun m-buffer-match-page (&rest match)
"Return a list of match data to all pages in MATCH.
-MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc 'm-buffer-match
match :regexp page-delimiter))
+;; #+end_src
+
+;; The `paragraph-separate' regexp can match an empty region, so we need to
start
+;; each search at the beginning of the next line.
+;; #+begin_src emacs-lisp
(defun m-buffer-match-paragraph-separate (&rest match)
"Return a list of match data to `paragraph-separate' in MATCH.
-MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for futher details."
(m-buffer-apply-snoc
'm-buffer-match match :regexp paragraph-separate
@@ -624,7 +674,7 @@ See `m-buffer-match for further details."
(defun m-buffer-match-line-start (&rest match)
"Return a list of match data to all line start.
-MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc
'm-buffer-match-begin
@@ -633,25 +683,37 @@ MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
(defun m-buffer-match-line-end (&rest match)
"Return a list of match to line end.
-MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc
'm-buffer-match-begin
match :regexp "$"
:post-match 'm-buffer-post-match-forward-char))
+;; #+end_src
+
+;; This is the first use of the =post-match= to terminate the loop, and was
+;; actually the motivation for adding it. We automatically terminate after the
+;; first match by simply returning nil.
+;; #+begin_src emacs-lisp
(defun m-buffer-match-first-line (&rest match)
- "Returns a match to the first line of MATCH.
+ "Return a match to the first line of MATCH.
This matches more efficiently than matching all lines and taking
-the car. See `m-buffer-match' for further details of MATCH."
+the car. See `m-buffer-match' for further details of MATCH."
(m-buffer-apply-snoc
'm-buffer-match match
:regexp m-buffer--line-regexp
:post-match (lambda () nil)))
+;; #+end_src
+
+;; Emacs has a rather inconsistent interface here -- suddenly, we have a
function
+;; rather than a variable for accessing a regexp.
+
+;; #+begin_src emacs-lisp
(defun m-buffer-match-sentence-end (&rest match)
"Return a list of match to sentence end.
-MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc
'm-buffer-match-begin
@@ -659,7 +721,7 @@ MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
(defun m-buffer-match-word (&rest match)
"Return a list of match to all words.
-MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc
'm-buffer-match
@@ -667,7 +729,7 @@ MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
(defun m-buffer-match-empty-line (&rest match)
"Return a list of match to all empty lines.
-MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
+MATCH is of the form BUFFER-OR-WINDOW MATCH-OPTIONS. See
`m-buffer-match' for further details."
(m-buffer-apply-snoc
'm-buffer-match
@@ -691,6 +753,12 @@ further details."
'm-buffer-match
match :regexp "^\\s-+$"))
+;; #+end_src
+
+;; I don't think that there is a way to do this with regexps entirely, so we
use
+;; substraction.
+
+;; #+begin_src emacs-lisp
(defun m-buffer-match-non-whitespace-line (&rest match)
"Return match data to all lines with at least one non-whitespace character.
Note empty lines do not contain any non-whitespace lines.
@@ -714,14 +782,13 @@ Returns true if succeeds."
t)
(error 'end-of-buffer
nil)))
-
-
;; #+end_src
;; ** Apply Function to Match
-;; These functions call a function to some match data.
+;; These functions apply another function to some match-data. This is pretty
+;; useful generically, but also I use it for many of the following functions.
;; #+begin_src emacs-lisp
(defun m-buffer-on-region (fn match-data)
@@ -738,18 +805,19 @@ MATCH-DATA can be any list of lists with two elements (or
more)."
(lambda (x)
(apply fn x))
(m-buffer-match-nth-group n match-data)))
-
;; #+end_src
;; ** Overlay and Property Functions
-;; Add properties or overlays to matches
+;; Adding properties or overlays to match-data. The functionality here somewhat
+;; overlaps with [[https://github.com/ShingoFukuyama/ov.el][ov.el]], which I
didn't know about when I wrote this. It generally
+;; works over overlays, or regexps, while m-buffer works over match-data.
;; #+begin_src emacs-lisp
(defun m-buffer-overlay-match (match-data &optional front-advance rear-advance)
"Return an overlay for all match to MATCH-DATA.
FRONT-ADVANCE and REAR-ADVANCE controls the borders of the
-overlay as defined in `make-overlay'. Overlays do not scale that
+overlay as defined in `make-overlay'. Overlays do not scale that
well, so use `m-buffer-propertize-match' if you intend to make
and keep many of these.
- [elpa] externals/m-buffer e4ec4daa87 027/115: replace-match now returns marker to the end of the replacements., (continued)
- [elpa] externals/m-buffer e4ec4daa87 027/115: replace-match now returns marker to the end of the replacements., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 41ca2908a3 032/115: Added documentation for four functions., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer b7c9738f31 037/115: Update readme for 0.4 release., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 93f64edf1b 046/115: Added support for case-fold-search, ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 761ba8e4b7 049/115: Equals and subtract functionality added., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer a8d5ce9755 050/115: Performance enhancements to subtract., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer fd9d92a0aa 052/115: Added marmalade for noflet., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 8d351bb5fd 054/115: m-buffer-with-current-marker added., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer d6701d8ce2 044/115: Remove extraneous dash dependency to dash., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 25c2b37969 071/115: m-buffer-point renamed to m-buffer-at-point., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 5166d21792 081/115: Lentic documentation for m-buffer.el.,
ELPA Syncer <=
- [elpa] externals/m-buffer 22ef3ac985 005/115: Emacs 24 only!, ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer cbd9d12b3d 023/115: Functions for colourizing text. Improved documentation., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 6e8e29e12d 022/115: Fix some typos, ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 05846a92bc 035/115: Removed "-data" from m-buffer-match-data., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 11990bba65 045/115: Version 0.5 release., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer bc7dd63016 051/115: Emacs 24.4 Unit testing., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 115663a882 056/115: Updates for 0.6., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 02feebf931 058/115: Test update due to function private namechange., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer 7c5eef2304 067/115: More org documentation changes., ELPA Syncer, 2022/07/19
- [elpa] externals/m-buffer b67897c833 070/115: Reduce Emacs versions in testing., ELPA Syncer, 2022/07/19