emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/blist 65ff602eee 30/31: blist: Add a variable to choose


From: ELPA Syncer
Subject: [elpa] externals/blist 65ff602eee 30/31: blist: Add a variable to choose features
Date: Tue, 28 Dec 2021 16:57:41 -0500 (EST)

branch: externals/blist
commit 65ff602eee1a33553c222f454208cfc8899066f9
Author: JSDurand <mmemmew@gmail.com>
Commit: JSDurand <mmemmew@gmail.com>

    blist: Add a variable to choose features
    
    * blist.el (blist-filter-default-label): A default label.
    
    (blist-filter-groups): Fixed filter groups.
    
    (blist-automatic-filter-groups,
    blist-automatic-filter-groups-default): Automatic filter groups.
    
    (blist-filter-features): Choose how to combine fixed and automatic
    filter groups.
    
    * README.org:
    * blist.texinfo: Update documentation files.
    
    * .gitignore: Add an ignore file to ignore some files produced while
      making the info file and the PDF file.
---
 .gitignore    |   5 ++
 ChangeLog     |   7 ++
 README.org    |  82 ++++++++++++++++++++--
 blist.el      | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 blist.elc     | Bin 46699 -> 51022 bytes
 blist.info    | Bin 36875 -> 46084 bytes
 blist.pdf     | Bin 448798 -> 470894 bytes
 blist.texinfo | 192 ++++++++++++++++++++++++++++++++++++++++++++++----
 8 files changed, 463 insertions(+), 45 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..355f8ae924
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.aux
+*.cp
+*.cps
+*.log
+*.toc
\ No newline at end of file
diff --git a/ChangeLog b/ChangeLog
index 519965ba59..771b311b3d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2021-12-28  李俊緯  <mmemmew@gmail.com>
+
+       * blist.el: Add the variable blist-filter-features to choose how
+       to combine the fixed and the automatic filter groups.
+
+       Also update documentation files accordingly.
+
 2021-12-23  Durand  <mmemmew@gmail.com>
 
        Update documentation.
diff --git a/README.org b/README.org
index f59516a92d..f2f3fad7a3 100644
--- a/README.org
+++ b/README.org
@@ -45,6 +45,9 @@ configuring the package.
   ;; Whether one wants to use the header line or not
   (setq blist-use-header-p nil)
 
+  ;; Just use manual filter groups for this example
+  (setq blist-filter-features (list 'manual))
+
   ;; Eshell and Default are defined in the package by default
 
   (blist-define-criterion "elisp" "ELisp"
@@ -96,6 +99,11 @@ An important feature of this package is the /filter groups/. 
 They are
 criteria that group bookmarks together under various sections.  So one
 can find all bookmarks of, say, "Eshell buffers" in one section.
 
+There are two types of filter groups: the fixed filter groups and the
+automatic filter groups.
+
+*** Fixed filter groups
+
 The groups are stored in the variable =blist-filter-groups=.  One can
 add or remove filter groups to that variable.  That variable is a list
 of filter groups, while each filter group is a cons cell of the form
@@ -115,11 +123,68 @@ to multiple groups, it will be classified under the group 
that is the
 earliest on the list.
 
 Note that the default filter group, which always returns =t= for every
-bookmark, is not needed.  If =blist-filter-groups= does not include a
-filter group whose filter function is =blist-default-p=, then a
-default group will be added automatically.  This is to avoid surprises
-to the users.  This is a feature of "blist", and not of "ilist": you
-can display a list without default groups.
+bookmark, is not needed.  If a bookmark does not belong to any filter
+group, it will be grouped into a default group, whose name is given by
+=blist-filter-default-label=.
+
+Note that this is a feature of "blist", and not of "ilist": you can
+display a list without default groups.
+
+*** Automatic filter groups
+
+An automatic filter group is a function that can give labels to
+elements in a list.  These labels will be used to group elements
+automatically: the elements with the same label will be grouped
+together.  Besides, an automatic filter group is also responsible for
+sorting group labels, and for giving a default label, if no default
+labels are specified.
+
+To be precise, an automatic filter group is a function with the
+signature: =(ELEMENT &optional TYPE)=.  The optional argument =TYPE=
+says what the caller wants from the function:
+
+- =nil=: If it is omitted or nil, the function should just return the
+  label for =ELEMENT=.
+
+- =default=: If it is the symbol =default=, the function should return
+  a default label.
+  
+- =sorter=: If it is the symbol =sorter=, the function should return a
+  function with two arguments, =X= and =Y=.  This returned function
+  should return a non-nil value if and only if group =X= should be
+  placed earlier than group =Y=.
+
+The automatic filter group to use is stored in the variable
+=blist-automatic-filter-groups=.  Its default value is
+=blist-automatic-filter-groups-default=.
+
+If you want to define your own automatic filter group, then the macro
+=ilist-define-automatic-group=, or =ilist-dag=, defined in "ilist",
+might come in handy.  The default automatic filter group is defined by
+that macro, for your information.
+
+*** Combine fixed and automatic filter groups
+
+What if one wants to use both the fixed filter groups and the
+automatic filter group to group elements?  Then one can set the
+variable =blist-filter-features=.  This variable should be a list of
+/featuers/ to use.  Currently there are two features: =manual= and
+=auto=.  If one adds =manual= to the list of features, then the fixed
+filter groups will be used; if one adds =auto= to the list of
+features, then the automatic filter groups will be used.
+
+Further, if one adds both =manual= and =auto= to the list of features,
+then both filter groups will be used.  The elements will first go
+through the fixed filter groups to see if it belongs to some fixed
+filter group.  If an element belongs to none of the fixed filter
+groups, then the automatic filter group will be used to find the label
+for the element.  If a poor element is given no labels, then the
+default label =blist-filter-default-label= will be used.
+
+Wait, one asks, what if the list contains no features?  Don't worry,
+it is not the end of blist.  In this case all elements will be
+considered as belonging to the default group
+=blist-filter-default-label=.
 
 ** Calling convention(s)
 
@@ -131,6 +196,9 @@ a specification of how the arguments to a function are 
supposed to be
 obtained when called interactively.  Here the letters "XYZ" have
 special meanings:
 
+*Note:* It is implicitly implied that the bookmarks in the folded
+groups are not operated upon by user commands.
+
 - "M": marked bookmarks
 - "R": the bookmarks in the region, if the region is active
 - "G": the bookmarks of a group, if the point is at the heading of
@@ -142,7 +210,7 @@ special meanings:
 ** Navigations
 
 The following is a list of default key-bindings to navigate in the
-list of bookmarks.  Except for the two "jump" commands, they all
+list of bookmarks.  Except for the two /jump/ commands, they all
 follow the P-convention.
 
 - =n=, =p=: go to next/previous line.  Whether it treats the top of
@@ -160,7 +228,7 @@ follow the P-convention.
 The following is a list of default key-bindings to mark bookmarks and
 to operate on the bookmarks.
 
-Unless stated otherwise, they all follow the P-convention.
+Unless stated otherwise, they all follow the *P-convention*.
 
 - =m=: Mark the bookmark with the default mark (=blist-default-mark=)
   and advance.
diff --git a/blist.el b/blist.el
index 657d4339b7..6020d2e1e2 100644
--- a/blist.el
+++ b/blist.el
@@ -64,35 +64,203 @@
 
 ;;;; Filter groups
 
-(defcustom blist-add-default-filter-automatically t
-  "The default filter for blist.
-If non-nil, and if `blist-default-p' is not an element of the
-variable `blist-filter-groups', then a default filter will be
-added."
+;;;;; Default label
+
+(defcustom blist-filter-default-label "Default"
+  "The label used for the default group automatically added."
   :group 'blist
-  :type 'boolean)
+  :type 'string)
+
+;;;;; fixed filter groups
 
 (defcustom blist-filter-groups (list
                                 (cons "Eshell" #'blist-eshell-p)
                                 (cons "Default" #'blist-default-p))
   "The filter groups for display.
-If `blist-default-p' is not used as a criterion, and if
-`blist-add-default-filter-automatically' is non-nil, then append
-a default filter group at the end."
+This specifies a fixed filter group.  For the automatic filter
+groups, see the user option `blist-automatic-filter-groups'.
+
+See the documentation string of `ilist-string' to know the
+differences between the two.
+
+And see the user option `blist-filter-features' for how to
+combine fixed groups and automatic ones.
+
+If `blist-default-p' is not used as a criterion, then a default
+filter group will be appended at the end."
   :group 'blist
   :type '(repeat (cons string function)))
 
-(defun blist-filter-groups ()
-  "Return the filter groups to use.
-See the doc strings of the variable `blist-filter-groups' and
-`blist-add-default-filter-automatically' for details."
-  (declare (side-effect-free 'error-free))
-  (cond
-   ((and blist-add-default-filter-automatically
-         (null (rassq #'blist-default-p blist-filter-groups)))
-    (append blist-filter-groups
-            (list (cons "Default" #'blist-default-p))))
-   (blist-filter-groups)))
+;;;;; automatic filter groups
+
+(defcustom blist-automatic-filter-groups
+  #'blist-automatic-filter-groups-default
+  "The automatic filter group for display.
+See the documentation string of `ilist-string' for how an
+automatic filter group should behave.
+
+And see the user option `blist-filter-features' for how to
+combine fixed groups and automatic ones."
+  :group 'blist
+  :type 'function)
+
+;;;;; Default automatic grouping
+
+;; See the documentation string of `ilist-dag' for more details.
+
+(ilist-dag "blist-default" blist-filter-default-label
+           (cond
+            ((string= x "Default") nil)
+            ((string= y "Default"))
+            ((string-lessp x y)))
+  (save-match-data
+    (let* ((handler (bookmark-get-handler element))
+           (handler-name (and handler (format "%S" handler)))
+           (location (bookmark-location element)))
+      ;; replace repeating parts
+      (cond
+       ((and handler-name
+             (string-match "\\([^z-a]+\\)-jump" handler-name))
+        (setq
+         handler-name
+         (replace-regexp-in-string
+          "-bookmark$" "" (match-string 1 handler-name)))))
+      ;; take case of file extensions
+      (cond
+       ((and (null handler-name) location
+             (string-match "\\.\\([^.]+\\)\\'" location))
+        (setq handler-name (match-string 1 location))))
+      (cond
+       (handler-name
+        (cond
+         ;; Some special cases
+         ((string-match-p "pdf" handler-name) "PDF") ; to handle pdf-view.
+         ((string-match-p "^el$" handler-name) "ELisp")
+         ((<= (length handler-name) 3) (upcase handler-name))
+         ((capitalize handler-name))))))))
+
+;; the function defined above
+(defalias 'blist-automatic-filter-groups-default
+  #'ilist-automatic-group-blist-default)
+
+;;;;; Method to combine fixed and automatic groups
+
+(defcustom blist-filter-features '(manual)
+  "How to combine the fixed filter groups and the automatic one.
+This is a list of symbols.
+
+If the symbol 'manual' is an element of this list, then the fixed
+filter group specified by the variable `blist-filter-groups' will
+be used.
+
+If the symbol 'auto' is an element of this list, then the
+automatic filter group specified by the variable
+`blist-automatic-filter-groups' will be used.
+
+If both symbols 'auto' and 'manual' are elements of the list,
+then the elements will be grouped by the fixed groups first.
+Those elements that are not classified as belonging to any of the
+fixed groups will then be grouped by the automatic filter
+groups.
+
+If neither of the symbols 'auto' and 'manual' is an element of
+the list, then every bookmark will be displayed under the
+group labelled with `blist-filter-default-label'."
+  :group 'blist
+  :type '(repeat
+          (choice
+           (const :tag "use fixed filter groups" manual)
+           (const :tag "use automatic filter groups" auto))))
+
+;;;;; Combine both fixed grouping and automatic grouping
+
+(defun blist-filter-groups (element &optional type)
+  "The actual filter group that is passed to `ilist-string'.
+See the documentation strings of the variables
+`blist-filter-groups', `blist-automatic-filter-groups', and
+`blist-filter-features' for details.
+
+See the documentation string of `ilist-string' for the meaning of
+ELEMENT and TYPE."
+  (let ((level 0)
+        (fixed-group-labels (mapcar #'car blist-filter-groups)))
+    ;; convert the list of features to a number for easier
+    ;; identification of the situation
+    (cond ((memq 'manual blist-filter-features)
+           (setq level (1+ level))))
+    (cond ((memq 'auto blist-filter-features)
+           (setq level (+ level 2))))
+    (cond
+     ((= level 0)
+      ;; no user filtering in effect: we just return the default label
+      ;; for the default, and return nil for the rest.  This works
+      ;; because if type is nil, then this function will return nil,
+      ;; and then `ilist-string' will use the default label.  When it
+      ;; asks for the sorter, this returns nil as well, which tells
+      ;; `ilist-string' that groups should not be sorted.
+      ;;
+      ;; Perfect design, right?
+      (cond ((eq type 'default) blist-filter-default-label)))
+     ((= level 1)
+      ;; Only manual filtering is in effect.
+      (cond
+       ;; Return the default label no matter what
+       ((eq type 'default) blist-filter-default-label)
+       ((eq type 'sorter)
+        (lambda (x y)
+          ;; If member returns a longer string, that means the element
+          ;; comes first.  This includes the case if the label is not
+          ;; on the list.
+          (<= (length (member y fixed-group-labels))
+              (length (member x fixed-group-labels)))))
+       ;; Emulate fixed grouping by automatic grouping
+       ((let ((temp-ls blist-filter-groups)
+              result)
+          (while (and (null result) (consp temp-ls))
+            (cond
+             ((funcall (cdar temp-ls) element)
+              (setq result (caar temp-ls))))
+            (setq temp-ls (cdr temp-ls)))
+          result))))
+     ((= level 2)
+      ;; Only automatic grouping in effect.
+      (funcall blist-automatic-filter-groups element type))
+     ((= level 3)
+      ;; Both the manual and the automatic grouping are in effect.
+      (cond
+       ((eq type 'default)
+        ;; Why not use or, you ask?  Because I like cond.  :D
+        (cond
+         ;; If the fixed group has a default group, then why use
+         ;; automatic grouping as well?  But who am I to judge?
+         ((car (rassq #'blist-default-p blist-filter-groups)))
+         ((funcall blist-automatic-filter-groups t 'default))
+         (blist-filter-default-label)))
+       ((eq type 'sorter)
+        ;; Manual groups should come before automatic groups.
+        (lambda (x y)
+          (cond
+           ((and (member x fixed-group-labels)
+                 (member y fixed-group-labels))
+            (<= (length (member y fixed-group-labels))
+                (length (member x fixed-group-labels))))
+           ((member x fixed-group-labels))
+           ((member y fixed-group-labels) nil)
+           ((functionp
+             (funcall blist-automatic-filter-groups t 'sorter))
+            (funcall
+             (funcall blist-automatic-filter-groups t 'sorter)
+             x y)))))
+       ((let ((temp-ls blist-filter-groups)
+              result)
+          (while (and (null result) (consp temp-ls))
+            (cond
+             ((funcall (cdar temp-ls) element)
+              (setq result (caar temp-ls))))
+            (setq temp-ls (cdr temp-ls)))
+          (cond
+           (result)
+           ((funcall blist-automatic-filter-groups element))))))))))
 
 ;;;; Empty groups
 
@@ -338,10 +506,9 @@ of the required type."
 
 ;; an alias for discoverability
 
-(fset 'blist #'blist-list-bookmarks)
+(defalias 'blist #'blist-list-bookmarks)
 
 ;; REVIEW: Is it a good idea to preserve the hidden status of groups?
-;; REVIEW: Use the header?
 
 ;;;###autoload
 (defun blist-list-bookmarks (&rest _args)
@@ -415,7 +582,7 @@ used as a `revert-buffer-function'."
                  (blist-name-column))
            (cond
             (blist-display-location-p (list blist-location-column))))
-          (blist-filter-groups)
+          #'blist-filter-groups
           blist-discard-empty-p
           blist-sorter
           t))
@@ -465,7 +632,9 @@ used as a `revert-buffer-function'."
 ;;; Major mode
 
 (define-derived-mode blist-mode ilist-mode "BList"
-  "Major mode used in the display of `blist-list-bookmarks'."
+  "Major mode used in the display of `blist-list-bookmarks'.
+
+\\{blist-mode-map}"
   :group 'blist
   (setq-local revert-buffer-function #'blist-list-bookmarks))
 
@@ -1004,6 +1173,7 @@ annotations."
 (define-derived-mode blist-edit-annotation-mode
   bookmark-edit-annotation-mode "BListea"
   "The major mode for editing bookmark annotations.
+\\<blist-edit-annotation-mode-map>\
 When editing is done, type \\[blist-send-edit-annotation].
 
 Simply delete the buffer if you want to cancel this edit.  Or you
@@ -1013,7 +1183,9 @@ quit the window at the same time.
 This differs from `bookmark-edit-annotation-mode' only in that it
 will always regenerate the list of bookmarks and go to the list
 of bookmarks after the edit is done, since this mode is not used
-for editing annotation in other situations."
+for editing annotation in other situations.
+
+\\{blist-edit-annotation-mode-map}"
   :group 'blist)
 
 (let ((map blist-edit-annotation-mode-map))
diff --git a/blist.elc b/blist.elc
index 3dc54fa5cb..a825549563 100644
Binary files a/blist.elc and b/blist.elc differ
diff --git a/blist.info b/blist.info
index bbf1bab005..56f637e0dd 100644
Binary files a/blist.info and b/blist.info differ
diff --git a/blist.pdf b/blist.pdf
index c426fb0109..eb99192ae8 100644
Binary files a/blist.pdf and b/blist.pdf differ
diff --git a/blist.texinfo b/blist.texinfo
index bd41564a14..6be681151e 100644
--- a/blist.texinfo
+++ b/blist.texinfo
@@ -45,6 +45,11 @@ The document was typeset with
 @insertcopying
 @end ifnottex
 
+@c Merge indices
+
+@syncodeindex fn cp
+@syncodeindex vr cp
+
 @c Generate the nodes for this menu with `C-c C-u C-m'.
 @menu
 * About::
@@ -58,6 +63,7 @@ The document was typeset with
 @c Insert new nodes with `C-c C-c n'.
 @node About, Dependency, Top, Top
 @chapter About
+@cindex motivation
 
 The built-in library @file{bookmark.el} is useful for storing
 information that can be retrieved later.  But I find the built-in
@@ -68,6 +74,8 @@ way.
 @node Dependency, Usage, About, Top
 @comment  node-name,  next,  previous,  up
 @chapter Dependency
+@cindex engine
+@cindex ilist
 
 This package is driven by another package:
 @url{https://gitlab.com/mmemmew/ilist.git, ilist}.  So make sure to
@@ -78,6 +86,9 @@ package.
 @node Usage, Copying This Manual, Dependency, Top
 @comment  node-name,  next,  previous,  up
 @chapter Usage
+@cindex How to use
+@findex blist
+@findex blist-list-bookmarks
 
 After installing, one can call the function @code{blist-list-bookmarks},
 or simply @code{blist}, to display the list of bookmarks.  Of course,
@@ -100,6 +111,7 @@ one can bind a key to that function for easier invocations.
 @node Screenshot, Example configuration, Usage, Usage
 @comment  node-name,  next,  previous,  up
 @section Screenshot
+@cindex picture
 
 A picture says more about the package than a thousand words.  Below is
 how the list of bookmarks looks like on my end:
@@ -109,10 +121,18 @@ how the list of bookmarks looks like on my end:
 @node Example configuration, Header, Screenshot, Usage
 @comment  node-name,  next,  previous,  up
 @section Example configuration
+@cindex example
+@cindex config
+@cindex fixed filter groups
 
 An example configuration is included so that it is easier to begin
 configuring the package.
 
+@vindex blist-filter-groups
+@vindex blist-use-header-p
+@vindex blist-filter-features
+@findex blist-define-criterion
+
 @lisp
 (setq blist-filter-groups
       (list
@@ -125,6 +145,9 @@ configuring the package.
 ;; Whether one wants to use the header line or not
 (setq blist-use-header-p nil)
 
+;; Just use manual filter groups for this example
+(setq blist-filter-features (list 'manual))
+
 ;; Eshell and Default are defined in the package by default
 
 (blist-define-criterion "elisp" "ELisp"
@@ -146,6 +169,8 @@ See the following subsections for more details.
 @node Header, Columns, Example configuration, Usage
 @comment  node-name,  next,  previous,  up
 @section Header
+@cindex Always display column names
+@vindex blist-use-header-p
 
 Some users prefer to display the names of columns in the @emph{header
 line}.  It has the advantage that it will always be visible, even though
@@ -157,6 +182,8 @@ header line.
 @node Columns, Groups, Header, Usage
 @comment  node-name,  next,  previous,  up
 @section Columns
+@cindex columns
+@cindex locations
 
 As one can see, the display has two columns: a name column and a
 location column.  The name column shows the names of the bookmarks,
@@ -164,14 +191,24 @@ while the location column shows the @emph{locations}, 
which are either
 the @strong{filename} or the @strong{location} attributes of the
 bookmarks.
 
+@cindex display locations, toggle
+@vindex blist-display-location-p
+@findex blist-toggle-location
+
 The variable @code{blist-display-location-p} controls whether to display
 the locations or not.  Also, one can toggle the display of the locations
 interactively by @code{blist-toggle-location}.
 
+@vindex blist-maximal-name-len
+@vindex blist-elide-string
+
 The variable @code{blist-maximal-name-len} determines the maximal length
 of the name column.  And the variable @code{blist-elide-string}
 determines how to elide the name, when it gets too long.
 
+@cindex column function
+@findex blist-name-column
+
 If one feels like so, then one can play with the function
 @code{blist-name-column} to control the name column.
 
@@ -179,40 +216,150 @@ If one feels like so, then one can play with the function
 @comment  node-name,  next,  previous,  up
 @section Groups
 
+@cindex filter groups
+@cindex sections
+
 An important feature of this package is the @emph{filter groups}.  They
 are criteria that group bookmarks together under various sections.  So
 one can find all bookmarks of, say, @emph{Eshell buffers} in one
 section.
 
-The groups are stored in the variable @code{blist-filter-groups}.  One
-can add or remove filter groups to that variable.  That variable is a
-list of filter groups, while each filter group is a cons cell of the
-form @code{(NAME . FUN)}, where @code{NAME} is a string which will be
-displayed as the section header, and @code{FUN} is a function that
-accepts a bookmark as its argument, and returns non-nil when and only
-when that bookmark belongs to the group.
+There are two types of filter groups: the fixed filter groups and the
+automatic filter groups.
+
+@menu
+* Fixed filter groups::
+* Automatic filter groups::
+* Combine fixed and automatic filter groups::
+@end menu
+
+@node Fixed filter groups, Automatic filter groups, Groups, Groups
+@comment  node-name,  next,  previous,  up
+@subsection Fixed filter groups
+
+@cindex fixed filter groups, format
+@vindex blist-filter-groups
+
+The fixed filter groups are stored in the variable
+@code{blist-filter-groups}.  One can add or remove filter groups to that
+variable.  That variable is a list of filter groups, while each filter
+group is a cons cell of the form @code{(NAME . FUN)}, where @code{NAME}
+is a string which will be displayed as the section header, and
+@code{FUN} is a function that accepts a bookmark as its argument, and
+returns non-nil when and only when that bookmark belongs to the group.
+
+@findex blist-define-criterion
 
 Since defining the group functions might be tedious, the package also
 provides a convenient macro @code{blist-define-criterion} for the users
 to define filter groups easily.  See the documentation string of that
 macro for details.
 
+@cindex fixed filter groups, order
+
 Also, the order of the filter groups matters: the filter groups that
 occur earlier on the list have higher priority.  So if an item belongs
 to multiple groups, it will be classified under the group that is the
 earliest on the list.
 
+@cindex fixed filter groups, default
+@vindex blist-filter-groups
+@vindex blist-filter-default-label
+
 Note that the default filter group, which always returns @code{t} for
-every bookmark, is not needed.  If @code{blist-filter-groups} does not
-include a filter group whose filter function is @code{blist-default-p},
-then a default group will be added automatically.  This is to avoid
-surprises to the users.  This is a feature of ``blist'', and not of
-``ilist'': you can display a list without default groups.
+every bookmark, is not needed.  If a bookmark does not belong to any
+filter group, it will be grouped into a default group, whose name is
+given by @code{blist-filter-default-label}.
+
+@cindex flexibility
+
+Note that this is a feature of ``blist'', and not of ``ilist'': you can
+display a list without default groups.
+
+@node Automatic filter groups, Combine fixed and automatic filter groups, 
Fixed filter groups, Groups
+@comment  node-name,  next,  previous,  up
+@subsection Automatic filter groups
+
+@cindex automatic filter groups, mechanism
+
+An automatic filter group is a function that can give labels to elements
+in a list.  These labels will be used to group elements automatically:
+the elements with the same label will be grouped together.  Besides, an
+automatic filter group is also responsible for sorting group labels, and
+for giving a default label, if no default labels are specified.
+
+To be precise, an automatic filter group is a function with the
+signature: @code{(ELEMENT &optional TYPE)}.  The optional argument
+@code{TYPE} says what the caller wants from the function:
+
+@cindex automatic filter groups, types
+
+@table@code
+@item nil
+If it is omitted or nil, the function should just return the label for
+@code{ELEMENT}.
+@item default
+If it is the symbol @code{default}, the function should return a default
+label.
+@item sorter
+If it is the symbol @code{sorter}, the function should return a function
+with two arguments, @code{X} and @code{Y}.  This returned function
+should return a non-nil value if and only if group @code{X} should be
+placed earlier than group @code{Y}.
+@end table
+
+@vindex blist-automatic-filter-groups
+@findex blist-automatic-filter-groups-default
+
+The automatic filter group to use is stored in the variable
+@code{blist-automatic-filter-groups}.  Its default value is
+@code{blist-automatic-filter-groups-default}.
+
+@cindex custom automatic filter groups
+@findex ilist-define-automatic-group
+@findex ilist-dag
+
+If you want to define your own automatic filter group, then the macro
+@code{ilist-define-automatic-group}, or @code{ilist-dag}, defined in
+``ilist'', might come in handy.  The default automatic filter group is
+defined by that macro, for your information.
+
+@node Combine fixed and automatic filter groups,  , Automatic filter groups, 
Groups
+@comment  node-name,  next,  previous,  up
+@subsection Combine fixed and automatic filter groups
+
+@cindex filter groups, combine
+@vindex blist-filter-features
+@findex blist-filter-groups
+
+What if one wants to use both the fixed filter groups and the automatic
+filter group to group elements?  Then one can set the variable
+@code{blist-filter-features}.  This variable should be a list of
+@emph{featuers} to use.  Currently there are two features: @code{manual}
+and @code{auto}.  If one adds @code{manual} to the list of features,
+then the fixed filter groups will be used; if one adds @code{auto} to
+the list of features, then the automatic filter groups will be used.
+
+@vindex blist-filter-default-label
+
+Further, if one adds both @code{manual} and @code{auto} to the list of
+features, then both filter groups will be used.  The elements will first
+go through the fixed filter groups to see if it belongs to some fixed
+filter group.  If an element belongs to none of the fixed filter groups,
+then the automatic filter group will be used to find the label for the
+element.  If a poor element is given no labels, then the default label
+@code{blist-filter-default-label} will be used.
+
+Wait, one asks, what if the list contains no features?  Don't worry, it
+is not the end of blist.  In this case all elements will be considered
+as belonging to the default group @code{blist-filter-default-label}.
 
 @node Calling convention(s), Navigations, Groups, Usage
 @comment  node-name,  next,  previous,  up
 @section Calling convention(s)
 
+@cindex calling conventions
+
 For the ease and brevity of writing, let's establish a convention for
 describing the interactive arguments of functions.
 
@@ -221,6 +368,9 @@ understood as a specification of how the arguments to a 
function are
 supposed to be obtained when called interactively.  Here the letters
 @strong{XYZ} have special meanings:
 
+@strong{Note:} It is implicitly implied that the bookmarks in the folded
+groups are not operated upon by user commands.
+
 @table @kbd
 @item M
 Use marked bookmarks.
@@ -246,6 +396,10 @@ Use the ARG next bookmarks, where ARG is the prefix 
argument.
 @comment  node-name,  next,  previous,  up
 @section Navigations
 
+@cindex navigations
+@cindex move, moving
+@cindex command
+
 The following is a list of default key-bindings to navigate in the list
 of bookmarks.  Except for the two @emph{jump} commands, they all follow
 the @strong{P-convention}.
@@ -253,6 +407,7 @@ the @strong{P-convention}.
 @table @kbd
 @item n
 @itemx p
+@vindex blist-movement-cycle
 go to next/previous line.  Whether it treats the top of the buffer as
 identified with the bottom of the buffer is controlled by the variable
 @code{blist-movement-cycle}.
@@ -281,6 +436,8 @@ go to the next marked bookmark.
 @comment  node-name,  next,  previous,  up
 @section Marking
 
+@cindex marks
+
 The following is a list of default key-bindings to mark bookmarks and to
 operate on the bookmarks.
 
@@ -288,6 +445,7 @@ Unless stated otherwise, they all follow the 
@strong{P-convention}.
 
 @table @kbd
 @item m
+@vindex blist-default-mark
 Mark the bookmark with the default mark (@code{blist-default-mark}) and
 advance.
 @item d
@@ -321,6 +479,8 @@ Change the marks from OLD to NEW (using @code{read-char})
 @comment  node-name,  next,  previous,  up
 @section Jump to bookmarks
 
+@cindex jumping
+
 The following lists the default key-bindings for jumping to, or opening
 bookmarks.  Except for @kbd{v}, they operate on the bookmark (or group)
 at point.
@@ -331,6 +491,7 @@ Either open the bookmark in this window or toggle the group 
at point.
 @item o
 Open the bookmark in another window.
 @item v
+@vindex blist-select-manner
 Select the bookmarks (the @strong{MG0-convention}).  How multiple
 bookmarks are opened is controlled by the variable
 @code{blist-select-manner}.  See its documentation for details.
@@ -340,6 +501,9 @@ bookmarks are opened is controlled by the variable
 @comment  node-name,  next,  previous,  up
 @section Annotations
 
+@cindex annotations
+@cindex decorations
+
 The following lists the default key-bindings for operating on the
 annotations of bookmarks.
 
@@ -358,6 +522,8 @@ completion.
 @comment  node-name,  next,  previous,  up
 @section Others
 
+@cindex miscellaneous
+
 Some functions are too minor to record here.  Use @code{describe-mode}
 in the list of bookmarks to see all available key-bindings.
 
@@ -372,7 +538,7 @@ in the list of bookmarks to see all available key-bindings.
 @include fdl-1.3.texi
 
 @node Index,  , Copying This Manual, Top
-@unnumbered Index
+@appendix Index
 
 @printindex cp
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]