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

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

[elpa] externals/hyperbole 2f307a8 1/2: Fix a number of issues, especial


From: ELPA Syncer
Subject: [elpa] externals/hyperbole 2f307a8 1/2: Fix a number of issues, especially in complex pathname handling
Date: Fri, 16 Apr 2021 02:57:08 -0400 (EDT)

branch: externals/hyperbole
commit 2f307a8cadc36e5c3befaa4f287fd8b810a8ac82
Author: Bob Weiner <rsw@gnu.org>
Commit: Bob Weiner <rsw@gnu.org>

    Fix a number of issues, especially in complex pathname handling
---
 Changes                      |  82 +++++++++-
 HY-TALK/HY-TALK-ANNOUNCE.txt |  38 +++++
 MANIFEST                     |   2 +-
 Makefile                     |   6 +-
 hact.el                      |  22 +--
 hargs.el                     |   5 +-
 hbdata.el                    |   2 +-
 hbut.el                      |  42 +++++-
 hibtypes.el                  |  15 +-
 hmouse-drv.el                |   6 +-
 hpath.el                     | 346 +++++++++++++++++++++++++++----------------
 hsettings.el                 |  16 +-
 hui-window.el                |  41 ++---
 hypb-ert.el                  |   2 +-
 hyperbole.el                 |  22 ++-
 kotl/kotl-autoloads.el       |  76 ++++++++--
 16 files changed, 500 insertions(+), 223 deletions(-)

diff --git a/Changes b/Changes
index 6231d30..21e5b3b 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,69 @@
+2021-04-16  Bob Weiner  <rsw@gnu.org>
+
+* hpath.el (hpath:at-p): Fix to allow non-existent paths (or those
+    that possibly can't be resolved) if path at point starts with
+    a special prefix character, e.g. "!date", to run the POSIX date
+    cmd.
+           (hpath:compressed-suffix-regexp): Add this variable and
+    use in hpath:expand-with-variable to properly expand compressed
+    pathnames.
+           (hpath:expand): For compressed Elisp libraries, add any
+    found compressed suffix to the path.
+
+2021-04-15  Bob Weiner  <rsw@gnu.org>
+
+* hpath.el (hpath:call): Add to wrap functions that test path validity,
+    stripping and then re-adding Hyperbole recognized path prefix and suffix
+    after path validity is verified.
+           (hpath:is-p): Use hpath:call wrapper and document stripping of
+    file:// prefix.
+
+* hui-window.el (hmouse-drag-same-window): Rewrite to actually detect a drag.
+    (hmouse-press-release-same-window): Detect if Action or Assist Key (based
+       on assist-flag) has been pressed and released in the same window.
+
+2021-04-14  Bob Weiner  <rsw@gnu.org>
+
+* hmouse-drv.el (hkey-toggle-debug): Fix doc string.
+
+* hpath.el (hpath:is-p): Add support for :line-num:col-num.
+
+2021-04-13  Bob Weiner  <rsw@gnu.org>
+
+* hibtypes.el (hibtypes-path-line-and-column-regexp): Rename to
+   hpath:section-line-and-col-regexp and move to hpath.el
+  hpath.el (hpath:file-line-and-column): Use hpath:line-and-col-regexp.
+
+* hpath.el (hpath:expand-with-variable, hpath:auto-variable-alist,
+            hpath:expand): Add to generalize implicit load variable
+    pathname expansion.
+  hpath.el (hpath:find, hpath:file-line-and-column):
+  hibtypes.el (pathname-line-and-column): Use hpath:expand.
+
+* Makefile (HY-TALK): Add to Hyperbole distribution; slides and demo file
+    discussing the history and utility of Hyperbole.
+
+* hact.el (hact): Simplify macro.
+          (action:path-args-abs, action:path-args-rel):
+    Rename to hpath:absolute-arguments and hpath:relative-argumentss
+    and move to hpath.el to eliminate circular dependency (hpath.el
+    requires hact macro).
+
+* hsettings.el (hyperbole-web-search): Optimize and make service-name
+    matching case-insensitive.
+
+2021-04-07  Bob Weiner  <rsw@gnu.org>
+
+* hbut.el (ibut:label-separator): Explain usage properly in doc string.
+          (ibut:to-text): Add to leave point in button text of ibuts with
+    separate labels.
+          (hbut:act): Move point with ibut:to-text to fix bug where an
+     ibtype expects point to be within the button text but previously
+      was left within the label.
+
+* hpath.el (hpath:url-regexp, hpath:url-regexp2, hpath:url-regexp3):
+    Allow @ symbols in URLs
+
 2021-04-07  Mats Lidell  <matsl@gnu.org>
 
 * test/hypb-tests.el: Rename test file
@@ -54,7 +120,21 @@
 * hbut.el (defal): Add support for use of %s format-style grouping 1 arg
     substitution.
   man/hyperbole.texi (Action Button Link Types): Documented.
-  DEMO (defal): Added new example of Google file type search button.
+  DEMO (defal): Add new example of Google file type search button.
+
+2021-03-20  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+* test/demo-tests.el (demo-factorial-ebutton-test):
+  test/hibtypes-tests.el: Mark those files as not-compilable since they
+    require packages that may not be available during compilation.
+
+* hyperbole.el: Fix release version to one accepted by ELPA.
+    (hyperb:init): Don't use `after-load-alist` as a hook, since it isn't one.
+    (hyperbole-mode): New minor mode.  Loading a file should not change
+    Emacs's behavior, so move the toplevel code to this minor mode: users
+    should enable this minor mode instead of loading the file.
+
+* hypb-maintenance.el: Fix compilation failure in elpa.git checkout.
 
 2021-03-14  Bob Weiner  <rsw@gnu.org>
 
diff --git a/HY-TALK/HY-TALK-ANNOUNCE.txt b/HY-TALK/HY-TALK-ANNOUNCE.txt
new file mode 100644
index 0000000..1072c6a
--- /dev/null
+++ b/HY-TALK/HY-TALK-ANNOUNCE.txt
@@ -0,0 +1,38 @@
+       Bring Your Text to Life the Easy Way with GNU Hyperbole
+
+                 A talk by the author, Bob Weiner
+
+
+Like Emacs itself, GNU Hyperbole is an integrated, extensible,
+self-documenting, and programmable hypertextual editing environment
+delivered as a single ELPA package for quick installation and
+evaluation.  But where to start with such a large package?
+
+This talk will provide a detailed, interactive overview of GNU
+Hyperbole's major capabilities and how they can speed knowledge
+work, including:
+
+   1. Implicit, Explicit and Global Buttons for interlinking your
+      textual information regardless of type or mode;
+
+   2. Org Mode Integration that reduces the complexity of dealing with
+      Org constructs and lets you leverage Hyperbole in Org documents;
+
+   3. The Koutliner for rapid outlining with multi-level autonumbering
+      (like legal numbering), per outline heading/cell permanent
+      hyperlink anchors, and dynamic views that can be triggered by
+      links themselves;
+  
+   4. HyRolo for fast contact or any hierarchical record management
+      including Org files or normal Emacs outlines;
+
+   5. HyControl for fast control over your Emacs windows and frames:
+      interactively increase or decrease your your face sizes, adjust
+      window sizes and layouts; replicate frame sizes and attributes
+      precisely; show what you want where you want it.
+
+Whatever you like about Emacs you'll likely find similar in Hyperbole.
+Hyperbole grows with you as your knowledge and work complexity
+increases.  An hour invested in Hyperbole has the potential to save
+you hundreds of hours in your future knowledge work.  Come find out
+about the magic and why its not all hyperbole.
diff --git a/MANIFEST b/MANIFEST
index 18fdf6a..32e4b204 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -95,6 +95,6 @@ topwin.py            - Python script to find the topmost 
macOS app window at a s
 .hypb & _hypb        - Button data files used by the Hyperbole DEMO file
 
 --- EXTERNAL SYSTEM ENCAPSULATIONS ---
-hsys-org.el          - GNU Hyperbole support functions for Support for 
hib-org.el
+hsys-org.el          - GNU Hyperbole support functions for hib-org.el
 hsys-www.el          - GNU Hyperbole support for Emacs W3 World-Wide Web (WWW) 
browsing
 
diff --git a/Makefile b/Makefile
index e427a90..97bb5df 100644
--- a/Makefile
+++ b/Makefile
@@ -182,9 +182,11 @@ ELC_KOTL = kotl/kexport.elc kotl/kfile.elc kotl/kfill.elc 
kotl/kimport.elc kotl/
            kotl/kcell.elc kotl/kproperty.elc \
            kotl/kview.elc kotl/kvspec.elc
 
+HY-TALK  = HY-TALK/.hypb HY-TALK/HYPB HY-TALK/HY-TALK.org
+
 HYPERBOLE_FILES = dir info html $(EL_SRC) $(EL_COMPILE) $(EL_KOTL) \
-       $(ELC_COMPILE) Changes COPYING Makefile HY-ABOUT HY-ANNOUNCE HY-NEWS \
-       HY-WHY.kotl INSTALL DEMO DEMO-ROLO.otl MANIFEST README _hypb .hypb 
smart-clib-sym \
+       $(ELC_COMPILE) $(HY-TALK) Changes COPYING Makefile HY-ABOUT HY-ANNOUNCE 
HY-NEWS \
+       HY-WHY.kotl INSTALL DEMO DEMO-ROLO.otl MANIFEST README README.md _hypb 
.hypb smart-clib-sym \
        topwin.py hyperbole-banner.png $(man_dir)/hkey-help.txt \
        $(man_dir)/hyperbole.texi $(man_dir)/hyperbole.css 
$(man_dir)/version.texi
 
diff --git a/hact.el b/hact.el
index dcc579d..b4841ea 100644
--- a/hact.el
+++ b/hact.el
@@ -374,24 +374,6 @@ Autoloads action function if need be to get the parameter 
list."
                          nil param))
              (action:params action))))
 
-(defun action:path-args-abs (args-list &optional default-dirs)
-  "Return any paths in ARGS-LIST made absolute.
-Uses optional DEFAULT-DIRS or `default-directory'.
-Other arguments are returned unchanged."
-  (mapcar (lambda (arg) (hpath:absolute-to arg default-dirs))
-         args-list))
-
-(defun action:path-args-rel (args-list)
-  "Return any paths in ARGS-LIST below button source loc directory made 
relative.
-Other paths are simply expanded.  Non-path arguments are returned unchanged."
-  (let ((loc (hattr:get 'hbut:current 'loc)))
-    (mapcar (lambda (arg)
-             (hpath:relative-to arg (if (stringp loc)
-                                        (file-name-directory loc)
-                                      (buffer-local-value 'default-directory 
loc))))
-           args-list)))
-
-
 ;;; ========================================================================
 ;;; action type class, actype
 ;;; ========================================================================
@@ -402,7 +384,7 @@ The value of `hrule:action' determines what effect this has.
 Alternatively act as a no-op when testing implicit button type contexts.
 First arg may be a symbol or symbol name for either an action type or a
 function.  Runs `action-act-hook' before performing action."
-  (eval `(cons 'funcall (cons 'hrule:action ',args))))
+  `(funcall hrule:action ,@args))
 
 (defun    actype:act (actype &rest args)
   "Perform action formed from ACTYPE and rest of ARGS and return value.
@@ -420,7 +402,7 @@ performing ACTION."
       ;; being used as a path.  So do this only if actype is a defact
       ;; and not a defun to limit any potential impact. RSW - 9/22/2017
       (and (symbolp action) (symtable:actype-p action)
-          (setq args (action:path-args-abs args)))
+          (setq args (hpath:absolute-arguments args)))
       (let ((hist-elt (hhist:element)))
        (run-hooks 'action-act-hook)
        (prog1 (or (if (or (symbolp action) (listp action)
diff --git a/hargs.el b/hargs.el
index b21fe54..36b841f 100644
--- a/hargs.el
+++ b/hargs.el
@@ -85,7 +85,7 @@ interactive form or takes no arguments."
   (and (or (hypb:emacs-byte-code-p action) (listp action))
        (let ((interactive-form (action:commandp action)))
         (when interactive-form
-          (action:path-args-rel
+          (hpath:relative-arguments
            (hargs:iform-read interactive-form modifying))))))
 
 (defun hargs:buffer-substring (start end)
@@ -437,8 +437,7 @@ Insert in minibuffer if active or in other window if 
minibuffer is inactive."
                     ;; newline or two whitespace characters.
                     (looking-at
                      "[^ \t\n]+\\( [^ \t\n]+\\)*\\( [ 
\t\n]\\|[\t\n]\\|\\'\\)"))
-           (setq entry (buffer-substring (match-beginning 0)
-                                         (match-beginning 2)))
+           (setq entry (hypb:get-completion))
            (select-window insert-window)
            (let ((str (or hargs:string-to-complete
                           (buffer-substring
diff --git a/hbdata.el b/hbdata.el
index 33d542f..0db9fe1 100644
--- a/hbdata.el
+++ b/hbdata.el
@@ -204,7 +204,7 @@ Nil BUT-SYM means use 'hbut:current'.  If successful, 
returns a cons of
                                         (mapcar 'hpath:substitute-var
                                                 (if mail-dir
                                                     ;; Make pathname args 
absolute for outgoing mail and news messages.
-                                                    (action:path-args-abs args 
mail-dir)
+                                                    (hpath:absolute-arguments 
args mail-dir)
                                                   args))))
                            (hattr:set b 'creator (or creator 
hyperb:user-email))
                            (hattr:set b 'create-time (or create-time 
(htz:date-sortable-gmt)))
diff --git a/hbut.el b/hbut.el
index 7c7fd76..6c8d126 100644
--- a/hbut.el
+++ b/hbut.el
@@ -811,9 +811,21 @@ Default is 'hbut:current."
   (unless hbut
     (setq hbut 'hbut:current))
   (cond ((hbut:is-p hbut)
-        (apply hrule:action
-               (hattr:get hbut 'actype)
-               (hattr:get hbut 'args)))
+        (let ((orig-point (point-marker))
+              text-point)
+          (when (ibut:is-p hbut)
+            (ibut:to-text (hattr:get hbut 'lbl-key)))
+          (setq text-point (point-marker))
+          (prog1 (apply hrule:action
+                        (hattr:get hbut 'actype)
+                        (hattr:get hbut 'args))
+            ;; Restore original point prior to ibut:to-text call if action 
switched buffers or did not move point within the current buffer
+            (when (or (equal text-point (point-marker))
+                      (not (eq (current-buffer) (marker-buffer orig-point))))
+              (set-buffer (marker-buffer orig-point))
+              (goto-char orig-point))
+            (set-marker orig-point nil)
+            (set-marker text-point nil))))
        ((and hbut (symbolp hbut))
         (hypb:error "(hbut:act): Symbol, %s, has invalid Hyperbole button 
attributes:\n  %S" hbut (hattr:list hbut)))
        (t
@@ -1156,7 +1168,8 @@ include delimiters when INCLUDE-DELIMS is non-nil)."
 
 (defvar   hbut:syntax-table (copy-syntax-table emacs-lisp-mode-syntax-table)
   "Modified Elisp syntax table for use with Action and Key Series buttons.
-Makes < > and { } into syntactically matching pairs.")
+Makes < > and { } into syntactically matching pairs after `hyperb:init'
+calls `hbut:modify-syntax'.")
 
 ;;;###autoload
 (defun    hbut:modify-syntax ()
@@ -1668,13 +1681,32 @@ Return the symbol for the button, else nil."
        (goto-char pos)
        (ibut:at-p)))))
 
+(defun    ibut:to-text (lbl-key)
+  "Find the nearest implicit button with LBL-KEY (a label or label key) within 
the visible portion of the current buffer and move to within its button text.
+Return the symbol for the button, else nil."
+    (let ((ibut (ibut:to lbl-key))
+         (lbl-key-end (nth 2 (ibut:label-p nil nil nil t t))))
+      (when ibut
+       ;; Skip past any optional label and separators
+       (goto-char lbl-key-end)
+       (when (and (not (hbut:outside-comment-p))
+                  (looking-at ibut:label-separator-regexp))
+         ;; Move past up to 2 possible characters of ibut
+         ;; delimiters; this prevents recognizing labeled,
+         ;; delimited ibuts of a single character but no one
+         ;; should need that.
+         (goto-char (min (+ 2 (match-end 0)) (point-max))))
+       ibut)))
+
 ;;; ------------------------------------------------------------------------
 (defconst ibut:label-start "<["
   "String matching the start of a Hyperbole implicit button label.")
 (defconst ibut:label-end   "]>"
   "String matching the end of a Hyperbole implicit button label.")
+
 (defvar   ibut:label-separator " "
-  "Regular expression that separates an implicit button label from its 
implicit button text.")
+  "String inserted immediately after a newly created implicit button label to 
separate it from the implicit button text.
+See also `ibut:label-separator-regexp' for all valid characters that may 
manually inserted to separate an implicit button label from its text.")
 
 (defvar   ibut:label-separator-regexp "\\s-*[-:=]*\\s-+"
   "Regular expression that separates an implicit button label from its 
implicit button text.")
diff --git a/hibtypes.el b/hibtypes.el
index d4b87f9..ae8f0c6 100644
--- a/hibtypes.el
+++ b/hibtypes.el
@@ -182,8 +182,8 @@ Texinfo @file{} entries, and hash-style link references to 
HTML,
 XML, SGML, Markdown or Emacs outline headings, shell script
 comments, and MSWindows paths (see \"${hyperb:dir}/DEMO#POSIX and
 MSWindows Paths\" for details).  Emacs Lisp library
-files (filenames without any directory component that end in .el
-and .elc) are looked up using the `load-path' directory list.
+files (filenames without any directory component that end in .el,
+.elc or .eln) are looked up using the `load-path' directory list.
 
 The pathname may contain references to Emacs Lisp variables or
 shell environment variables using the syntax, \"${variable-name}\".
@@ -209,7 +209,7 @@ display options."
         ;;
         ;; Match to Emacs Lisp and Info files without any directory component.
         (when (setq path (hpath:delimited-possible-path))
-          (cond ((string-match "\\`[^\\\\/~]+\\.elc?\\(\\.gz\\)?\\'" path)
+          (cond ((string-match "\\`[^\\\\/~]+\\.el[cn]?\\(\\.gz\\)?\\'" path)
                  (apply #'ibut:label-set path (hpath:start-end path))
                  (if (string-match hpath:prefix-regexp path)
                      (hact 'hpath:find path)
@@ -991,11 +991,6 @@ This works with JavaScript and Python tracebacks, gdb, 
dbx, and xdb.  Such lines
 ;;; locations.
 ;;; ========================================================================
 
-(defconst hibtypes-path-line-and-col-regexp
-  ;; Allow for 'c:' single letter drive prefixes on MSWindows and
-  ;; Elisp vars with colons in them.
-  "\\([^ 
\t\n\r\f:][^\t\n\r\f:]+\\(:[^0-9\t\n\r\f]*\\)*\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?$")
-
 (defib pathname-line-and-column ()
   "Make a valid pathname:line-num[:column-num] pattern display the path at 
line-num and optional column-num.
 Also works for remote pathnames.
@@ -1008,8 +1003,8 @@ removed from pathname when searching for a valid match.
 See `hpath:find' function documentation for special file display options."
   (let ((path-line-and-col (hpath:delimited-possible-path)))
     (when (and (stringp path-line-and-col)
-               (string-match hibtypes-path-line-and-col-regexp 
path-line-and-col))
-      (let ((file (save-match-data (expand-file-name (hpath:substitute-value 
(match-string-no-properties 1 path-line-and-col)))))
+               (string-match hpath:section-line-and-column-regexp 
path-line-and-col))
+      (let ((file (save-match-data (hpath:expand (match-string-no-properties 1 
path-line-and-col))))
             (line-num (string-to-number (match-string-no-properties 3 
path-line-and-col)))
             (col-num (when (match-end 4)
                        (string-to-number (match-string-no-properties 5 
path-line-and-col)))))
diff --git a/hmouse-drv.el b/hmouse-drv.el
index 869a468..82715b8 100644
--- a/hmouse-drv.el
+++ b/hmouse-drv.el
@@ -956,7 +956,7 @@ Return non-nil iff associated help documentation is found."
   "Display doc associated with Assist Key command in current context.
 Return non-nil iff associated documentation is found."
   (interactive)
-  (hkey-help 'assist))
+  (hkey-help t))
 
 ;; Overload help-mode quit-window function to support Hyperbole
 ;; hkey--wconfig window configurations.
@@ -1116,8 +1116,8 @@ the current window.  By default, it is displayed in 
another window."
 
 
 (defun hkey-toggle-debug (&optional arg)
-  "Toggle whether conflicting local key bindings are overridden by Hyperbole.
-With optional ARG, override them iff ARG is positive."
+  "Toggle whether Hyperbole logs Smart Key events for later 
analysis/submission using {C-h h m c}.
+With optional ARG, enable iff ARG is positive."
   (interactive "P")
   (if (or (and arg (<= (prefix-numeric-value arg) 0))
          (and (not (and arg (> (prefix-numeric-value arg) 0)))
diff --git a/hpath.el b/hpath.el
index 533d04b..b7300e5 100644
--- a/hpath.el
+++ b/hpath.el
@@ -32,6 +32,13 @@
 ;;; Public Variables
 ;;; ************************************************************************
 
+(defvar hpath:auto-variable-alist
+  '(("\\.el[cn]?\\'" . load-path)
+    ("\\.org\\'" . org-directory)
+    ("\\.py\\'" . "PYTHONPATH"))
+  "Alist of filename patterns and corresponding variables to prepend to 
resolve them.
+Each element looks like FILENAME-REGEXP . LISP-VARIABLE-OR-ENV-VARIABLE-STR.")
+
 (defcustom hpath:find-file-urls-mode nil
   "This is t when a remote file access library is available and use of ftp and 
http urls in file finding commands has been enabled.
 Default is nil since this can slow down normal file finding."
@@ -40,6 +47,23 @@ Default is nil since this can slow down normal file finding."
   :set (lambda (_symbol _value) (call-interactively 
#'hpath:find-file-urls-mode))
   :group 'hyperbole-buttons)
 
+(defconst hpath:markup-link-anchor-regexp
+  "\\`\\(#?[^#]*[^#.]\\)?\\(#\\)\\([^\]\[#^{}<>\"`'\\\n\t\f\r]*\\)"
+  "Regexp that matches a markup filename followed by a hash (#) and an 
optional in-file anchor name.
+# is group 2.  Group 3 is the anchor name.")
+
+(defconst hpath:line-and-column-regexp
+  ":\\([-+]?[0-9]+\\)\\(:\\([-+]?[0-9]+\\)\\)?\\s-*\\'"
+  "Regexp that matches a trailing colon separated line number folowed by an 
optional column number.
+Group 1 is the line number.  Group 3 is the column number.")
+
+(defconst hpath:section-line-and-column-regexp
+  "\\([^ 
\t\n\r\f:][^\t\n\r\f:]+\\(:[^0-9\t\n\r\f]*\\)*\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?$"
+  "Regexp that matches to a path with optional #section and :line-num:col-num.
+Grouping 1 is path, grouping 3 is line number, grouping 4 is
+column number.  Allow for 'c:' single letter drive prefixes on
+MSWindows and Elisp vars with colons in them.")
+
 ;;; ************************************************************************
 ;;; MS WINDOWS PATH CONVERSIONS
 ;;; ************************************************************************
@@ -47,7 +71,7 @@ Default is nil since this can slow down normal file finding."
 ;; This section adds automatic recognition of MSWindows implicit path
 ;; links and converts disk drive and path separators to whatever
 ;; format is needed by the underlying OS upon which Emacs is one,
-;; notably either for POSIX or MSWindows (with no POSIC layer).
+;; notably either for POSIX or MSWindows (with no POSIX layer).
 
 ;; Especially useful when running Emacs under Windows Subsystem for
 ;; Linux (WSL) where the system-type variable is gnu/linux but
@@ -444,7 +468,7 @@ to create a path to the RFC document for `rfc-num'.")
 ;;             or   URL[:=][<user>@]<domain>[:<port>][<path>]  (no protocol 
specified)
 ;; Avoid [a-z]:/path patterns since these may be disk paths on OS/2, DOS or
 ;; Windows.
-(defvar hpath:url-regexp 
"<?\\(URL[:=]\\)?\\(\\([a-zA-Z][a-zA-Z]+\\)://?/?\\([^/:@ 
\t\n\r\"`'|]+@\\)?\\([^/:@ 
\t\n\r\"`'|]+\\)\\(\\)\\(:[0-9]+\\)?\\([/~]\\([^\]\[@ 
\t\n\r\"`'|(){}<>]+[^\]\[@ \t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?"
+(defvar hpath:url-regexp 
"<?\\(URL[:=]\\)?\\(\\([a-zA-Z][a-zA-Z]+\\)://?/?\\([^/:@ 
\t\n\r\"`'|]+@\\)?\\([^/:@ \t\n\r\"`'|]+\\)\\(\\)\\(:[0-9]+\\)?\\([/~]\\([^\]\[ 
\t\n\r\"`'|(){}<>]+[^\]\[ \t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?"
   "Regular expression which matches a Url in a string or buffer.
 Its match groupings and their names are:
   1 = hpath:url-keyword-grpn = optional `URL:' or `URL=' literal
@@ -463,7 +487,7 @@ Its match groupings and their names are:
   (concat
    "<?\\(URL[:=]\\|[^/@]\\|\\)\\(\\(\\)\\(\\)\\("
    hpath:url-hostnames-regexp
-   "\\.[^/:@ \t\n\r\"`'|]+\\):?\\([0-9]+\\)?\\([/~]\\([^\]\[@ 
\t\n\r\"`'|(){}<>]+[^\]\[@ \t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?")
+   "\\.[^/:@ \t\n\r\"`'|]+\\):?\\([0-9]+\\)?\\([/~]\\([^\]\[ 
\t\n\r\"`'|(){}<>]+[^\]\[ \t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?")
   "Regular expression which matches a Url in a string or buffer.
 Its match groupings and their names are:
   1 = hpath:url-keyword-grpn = optional `URL:' or `URL=' literal
@@ -479,7 +503,7 @@ Its match groupings and their names are:
   (concat
    "<?\\(URL[:=]\\)\\(\\(\\)\\(\\)"
    "\\([a-zA-Z0-9][^/:@ \t\n\r\"`'|]*\\.[^/:@ \t\n\r\"`'|]+\\)"
-   ":?\\([0-9]+\\)?\\([/~]\\([^\]\[@ \t\n\r\"`'|(){}<>]+[^\]\[@ 
\t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?")
+   ":?\\([0-9]+\\)?\\([/~]\\([^\]\[ \t\n\r\"`'|(){}<>]+[^\]\[ 
\t\n\r\"`'|(){}<>.,?#!*]\\)*\\)?\\)>?")
   "Regular expression which matches a Url in a string or buffer.
 Its match groupings and their names are:
   1 = hpath:url-keyword-grpn = required `URL:' or `URL=' literal
@@ -540,16 +564,6 @@ use with `string-match'.")
 (defconst hpath:markdown-suffix-regexp "\\.[mM][dD]"
   "Regexp that matches to a Markdown file suffix.")
 
-(defconst hpath:markup-link-anchor-regexp
-  "\\`\\(#?[^#]*[^#.]\\)?\\(#\\)\\([^\]\[#^{}<>\"`'\\\n\t\f\r]*\\)"
-  "Regexp that matches a markup filename followed by a hash (#) and an 
optional in-file anchor name.
-Group 3 is the anchor name.")
-
-(defconst hpath:line-and-column-regexp
-  ":\\([-+]?[0-9]+\\)\\(:\\([-+]?[0-9]+\\)\\)?\\s-*\\'"
-  "Regexp that matches a trailing colon separated line number folowed by an 
optional column number.
-Group 1 is the line number.  Group 3 is the column number.")
-
 (defconst hpath:outline-section-pattern "^\*+[ \t]+%s\\([ \t[:punct:]]*\\)$"
   "Regexp matching an Emacs outline section header and containing a %s for 
replacement of a specific section name.")
 
@@ -580,6 +594,13 @@ This prevents improper processing of hargs with colons in 
them, e.g. `actypes::l
   (let (tramp-mode)
     (abbreviate-file-name path)))
 
+(defun hpath:absolute-arguments (args-list &optional default-dirs)
+  "Return any paths in ARGS-LIST made absolute.
+Uses optional DEFAULT-DIRS or `default-directory'.
+Other arguments are returned unchanged."
+  (mapcar (lambda (arg) (hpath:absolute-to arg default-dirs))
+         args-list))
+
 (defun hpath:absolute-to (path &optional default-dirs)
   "Return PATH as an absolute path relative to one directory from optional 
DEFAULT-DIRS or `default-directory'.
 Return PATH unchanged when it is not a valid path or when DEFAULT-DIRS
@@ -622,7 +643,8 @@ See the `(emacs)Remote Files' info documentation for 
pathname format details.
 Always returns nil if (hpath:remote-available-p) returns nil."
   (let ((remote-package (hpath:remote-available-p))
        (user (hpath:remote-default-user))
-       (path))
+       path
+       path-no-site)
     (when remote-package
       (setq path
            (save-excursion
@@ -670,9 +692,11 @@ Always returns nil if (hpath:remote-available-p) returns 
nil."
                (concat "/" user (match-string-no-properties 0)))
               ;; site and path
               ((and (looking-at
-                     "/?\\(\\([^/:@ \t\n\r\"`'|]+\\):[^]@:, 
\t\n\r\"`'|\)\}]+\\)[] \t\n\r,.\"`'|\)\}]")
-                    (setq path (match-string-no-properties 1))
-                    (string-match "[^.]\\.[^.]" (match-string-no-properties 
2)))
+                     "/?\\(\\([^/:@ \t\n\r\"`'|]+\\):\\([^]@:, 
\t\n\r\"`'|\)\}]+\\)\\)[] \t\n\r,.\"`'|\)\}]")
+                    (setq path (match-string-no-properties 1) ;; includes site
+                          path-no-site (match-string-no-properties 3))
+                    (string-match "[^.]\\.[^.]" (match-string-no-properties 2))
+                    (not (string-match "\\(\\`\\|:\\)[:0-9]+\\'" 
path-no-site))) ;; prevent matching to line:col suffixes
                (concat "/" user "@" path))
               ;; host and path
               ((and (looking-at "/\\([^/:@ \t\n\r\"`'|]+:[^]@:, 
\t\n\r\"`'|\)\}]+\\)")
@@ -763,7 +787,66 @@ paths are allowed.  Absolute pathnames must begin with a 
`/' or `~'."
    ;; ((hpath:is-p (hargs:delimited "file://" "[ \t\n\r\"\'\}]" nil t)))
    ((hpath:remote-at-p))
    ((hpath:www-at-p) nil)
-   ((hpath:is-p (hpath:delimited-possible-path non-exist) type non-exist))))
+   ((let ((path (hpath:delimited-possible-path non-exist)))
+     (when (and path (not non-exist) (string-match hpath:prefix-regexp path))
+       (setq non-exist t))
+     (hpath:is-p path type non-exist)))))
+
+(defun hpath:call (func path)
+  "Call FUNC with one argument, a PATH, stripped of any prefix operator and 
suffix location.
+Return the result of calling FUNC, which must be either nil or the
+possibly modified path, but with the prefix and suffix reattached.
+Make any path within a file buffer absolute before returning. "
+  (unless (or (functionp func) (subrp func))
+    (error "(hpath:call): Invalid function: %s" func))
+  (unless (stringp path)
+    (error "(%s): '%s' must be a string" func path))
+  ;; Convert tabs and newlines to space.
+  (setq path (hbut:key-to-label (hbut:label-to-key path)))
+  (let* ((orig-path path)
+        (prefix (car (delq nil (list (when (string-match hpath:prefix-regexp 
path)
+                                       (prog1 (match-string 0 path)
+                                         (setq path (substring path (match-end 
0)))))
+                                     (when (string-match "\\`file://" path)
+                                       (setq path (substring path (match-end 
0)))
+                                       nil)
+                                     (when (string-match hpath:prefix-regexp 
path)
+                                       (prog1 (match-string 0 path)
+                                         (setq path (substring path (match-end 
0)))))))))
+        (suffix (apply #'concat (nreverse (list (when (string-match 
hpath:line-and-column-regexp path)
+                                                  (prog1 (match-string 0 path)
+                                                    (setq path (substring path 
0 (match-beginning 0)))))
+                                                (if (string-match 
"\\$@?\{[^\}]+@?\}" path)
+                                                    ;; Path may be a link 
reference with a suffix component
+                                                    ;; following a comma or # 
symbol, so temporarily strip
+                                                    ;; these, if any, before 
expanding any embedded variables.
+                                                    (when (string-match "[ 
\t\n\r]*[#,]" path)
+                                                      (prog1 (substring path 
(1- (match-end 0)))
+                                                        (setq path (substring 
path 0 (match-beginning 0)))))
+                                                  (when (string-match 
hpath:markup-link-anchor-regexp path)
+                                                    (prog1 (concat "#" 
(match-string 3 path))
+                                                      (setq path (substring 
path 0 (match-beginning 2))))))))))
+        (func-result (funcall func path)))
+    (when (stringp func-result)
+      (setq path (concat prefix func-result suffix))
+      ;; If path is just a local reference that begins with #,
+      ;; in a file buffer, prepend the file name to it.  If an HTML
+      ;; file, prepend file:// to it.
+      (let ((mode-prefix (if (memq major-mode '(js2-mode js-mode js3-mode 
javascript-mode html-mode web-mode))
+                            "file://" "")))
+       (cond ((and buffer-file-name
+                   ;; ignore HTML color strings
+                   (not (string-match 
"\\`#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]\\'" 
path))
+                   ;; match to in-file HTML references
+                   (string-match "\\`#[^\'\"<>#]+\\'" path))
+              (setq path (concat mode-prefix buffer-file-name path)))
+             ((string-match "\\`[^#]+\\(#[^#]*\\)\\'" path)
+              ;; file and # reference
+              (if (memq (aref path 0) '(?/ ?~))
+                  ;; absolute
+                  (setq path (concat mode-prefix path))
+                (setq path (concat mode-prefix default-directory path))))
+             (t path))))))
 
 (defun hpath:delimited-possible-path (&optional non-exist include-positions)
   "Return delimited possible path or non-delimited remote path at point, if 
any.
@@ -842,12 +925,43 @@ window in which the buffer is displayed."
   "Return the function to display a Hyperbole path using optional symbol 
DISPLAY-WHERE or `hpath:display-where'."
   (hpath:display-where-function display-where hpath:display-where-alist))
 
+(defun hpath:expand (path)
+  "Expand relative PATH using the load variable from the first file matching 
regexp in `hpath:auto-variable-alist'."
+  (setq path (hpath:substitute-value
+             (if (string-match "\\`[\\/~.]" path)
+                 (expand-file-name path)
+               (hpath:expand-with-variable path))))
+  ;; For compressed Elisp libraries, add any found compressed suffix to the 
path.
+  (or (locate-library path) path))
+
+(defvar hpath:compressed-suffix-regexp (concat (regexp-opt '(".gz" ".Z" ".zip" 
".bz2" ".xz" ".zst")) "\\'")
+   "Regexp of compressed file name suffixes.")
+
+(defun hpath:expand-with-variable (path)
+  "Assume PATH is relative and prepend to it the ${load variable name} from 
the first file matching regexp in `hpath:auto-variable-alist' sans any 
compression suffix in `hpath:compressed-suffix-regexp'."
+  (let ((auto-variable-alist hpath:auto-variable-alist)
+       (compression-suffix (when (string-match hpath:compressed-suffix-regexp 
path)
+                             (prog1 (match-string 0 path)
+                               (setq path (substring path 0 (match-beginning 
0))))))
+       regexp
+       variable)
+    (while auto-variable-alist
+      (setq regexp (caar auto-variable-alist)
+           variable (cdar auto-variable-alist)
+           auto-variable-alist (cdr auto-variable-alist))
+      (when (string-match regexp path)
+       (when (or (and (stringp variable) (getenv variable))
+                 (and (symbolp variable) (boundp variable)))
+         (setq path (format "${%s}/%s" variable path)))
+       (setq auto-variable-alist nil)))
+    (concat path compression-suffix)))
+
 (defun hpath:file-line-and-column (path-line-and-col)
   "Given a `path-line-and-col' string of format: path:line:col, return a list 
with the parts parsed out, else nil."
   (when (and (stringp path-line-and-col)
-            (string-match hibtypes-path-line-and-col-regexp path-line-and-col))
+            (string-match hpath:section-line-and-column-regexp 
path-line-and-col))
     ;; Ensure any variables and heading suffixes following [#,] are removed 
before returning file.
-    (let ((file (save-match-data (expand-file-name (hpath:substitute-value 
(match-string-no-properties 1 path-line-and-col)))))
+    (let ((file (save-match-data (hpath:expand (match-string-no-properties 1 
path-line-and-col))))
          (line-num (string-to-number (match-string-no-properties 3 
path-line-and-col)))
          (col-num (when (match-end 4)
                     (string-to-number (match-string-no-properties 5 
path-line-and-col)))))
@@ -933,7 +1047,7 @@ buffer but don't display it."
            path (if (match-end 1)
                     (substring path 0 (match-end 1))
                   buffer-file-name)))
-    (setq path (hpath:substitute-value path)
+    (setq path (hpath:expand path)
          filename (hpath:absolute-to path default-directory))
     (if noselect
        (let ((buf (find-file-noselect filename)))
@@ -1129,115 +1243,74 @@ of existing pathnames, but not at the start or end.
 
 Before the pathname is checked for existence, tabs and newlines
 are converted to a single space, `hpath:prefix-regexp' matches at
-the start are temporarily stripped, link anchors at the end
-following a # or , character are temporarily stripped, and path
-variables are expanded with `hpath:substitute-value'.  This normalized
-path form is what is returned for PATH."
+the start are temporarily stripped, \"file://\" prefixes are
+stripped, link anchors at the end following a # or , character
+are temporarily stripped, and path variables are expanded with
+`hpath:substitute-value'.  This normalized path form is what is
+returned for PATH."
   (when (stringp path)
-    (let (modifier
-         suffix)
-      (when (string-match hpath:prefix-regexp path)
-       (setq modifier (substring path 0 1)
-             path (substring path (match-end 0))))
-      (when (string-match "\\`file://" path)
-       (setq path (substring path (match-end 0))))
-      (when (string-match hpath:prefix-regexp path)
-       (setq modifier (substring path 0 1)
-             path (substring path (match-end 0))))
-      (setq path (hpath:mswindows-to-posix path))
-      (and (not (or (string-equal path "")
-                   (string-match "\\`\\s-\\|\\s-\\'" path)))
-          ;; Convert tabs and newlines to space.
-          (setq path (hbut:key-to-label (hbut:label-to-key path)))
-          (or (not (string-match "[()]" path))
-              (string-match "\\`([^ \t\n\r\)]+)[ *A-Za-z0-9]" path))
-          ;; Allow for @{ and @} in texinfo-mode
-          (if (string-match "\\$@?\{[^\}]+@?\}" path)
-              ;; Path may be a link reference with a suffix component
-              ;; following a comma or # symbol, so temporarily strip
-              ;; these, if any, before expanding any embedded variables.
-              (if (string-match "[ \t\n\r]*[#,]" path)
-                  (progn (setq suffix (substring path (match-beginning 0))
-                               path (substring path 0 (match-beginning 0))
-                               path (concat (hpath:substitute-value path)
-                                            suffix)
-                               suffix nil)
-                         t)
-                (setq path (hpath:substitute-value path))
-                (unless (string-empty-p path)
-                  path))
-            t)
-          (not (string-match "[\t\n\r\"`'|{}\\]" path))
-          (let ((rtn-path path))
-            ;; Strip any path suffix component before checking path.
-            (and (if (string-match "\\`[^#][^#,]*\\([ \t\n\r]*[#,]\\)" path)
-                     (setq rtn-path (concat (substring path 0 (match-beginning 
1))
-                                            "%s" (substring path 
(match-beginning 1)))
-                           path (substring path 0 (match-beginning 1)))
-                   (setq rtn-path (concat rtn-path "%s")))
-                 ;; If path is just a local reference that begins with #,
-                 ;; prepend the file name to it.  Remove # and
-                 ;; everything after for path checking.
-                 (cond ((and buffer-file-name
-                             ;; ignore HTML color strings
-                             (not (string-match 
"\\`#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]\\'" 
path))
-                             ;; match to in-file HTML references
-                             (string-match "\\`#[^\'\"<>#]+\\'" path))
-                        (setq rtn-path (concat "file://" buffer-file-name 
rtn-path)
-                              path buffer-file-name))
-                       ((string-match "\\`[^#]+\\(#[^#]*\\)\\'" path)
-                        ;; file and # reference
-                        (setq path (substring path 0 (match-beginning 1)))
-                        (if (memq (aref path 0) '(?/ ?~))
-                            ;; absolute
-                            (setq rtn-path (concat "file://" rtn-path))
-                          (setq path (concat default-directory path)
-                                rtn-path (concat "file://" default-directory 
rtn-path))))
-                       (t))
-                 (or (not (hpath:www-p path))
-                     (string-match "\\`ftp[:.]" path))
-                 (let ((remote-path (string-match 
"\\(@.+:\\|^/.+:\\|..+:/\\).*[^:0-9/]" path)))
-                   (when (cond (remote-path
-                                (cond ((eq type 'file)
-                                       (not (string-equal "/" (substring path 
-1))))
-                                      ((eq type 'directory)
-                                       (string-equal "/" (substring path -1)))
-                                      (t)))
-                               ((or (and non-exist
-                                         (or
-                                          ;; Info or remote path, so don't 
check for.
-                                          (string-match "[()]" path)
-                                          (hpath:remote-p path)
-                                          (setq suffix (hpath:exists-p path t))
-                                          ;; Don't allow spaces in non-existent
-                                          ;; pathnames.
-                                          (not (string-match " " path))))
-                                    (setq suffix (hpath:exists-p path t)))
-                                (cond ((eq type 'file)
-                                       (not (file-directory-p path)))
-                                      ((eq type 'directory)
-                                       (file-directory-p path))
-                                      (t))))
-                     ;; Might be an encoded URL with % characters, so
-                     ;; decode it before calling format below.
-                     (when (string-match "%" rtn-path)
-                       (let (decoded-path)
-                         (while (not (equal rtn-path (setq decoded-path 
(hypb:decode-url rtn-path))))
-                           (setq rtn-path decoded-path))))
-                     ;; Quote any % except for one %s at the end of the
-                     ;; path part of rtn-path (immediately preceding a #
-                     ;; or , character or the end of string).
-                     (setq rtn-path (hypb:replace-match-string "%" rtn-path 
"%%" nil t)
-                           rtn-path (hypb:replace-match-string 
"%%s\\([#,]\\|\\'\\)" rtn-path "%s\\1" nil t))
-                     ;; Return path if non-nil return value.
-                     (if (stringp suffix) ;; suffix could = t, which we ignore
-                         (if (string-match (concat (regexp-quote suffix) "%s") 
rtn-path)
-                             ;; remove suffix
-                             (concat (substring rtn-path 0 (match-beginning 0))
-                                     (substring rtn-path (match-end 0)))
-                           ;; add suffix
-                           (concat modifier (format rtn-path suffix)))
-                       (concat modifier (format rtn-path "")))))))))))
+    (hpath:call
+     (lambda (path)
+       (let (modifier
+            suffix)
+        (setq path (hpath:mswindows-to-posix path))
+        (and (not (or (string-equal path "")
+                      (string-match "\\`\\s-\\|\\s-\\'" path)))
+             (or (not (string-match "[()]" path))
+                 (string-match "\\`([^ \t\n\r\)]+)[ *A-Za-z0-9]" path))
+             ;; Allow for @{ and @} in texinfo-mode
+             (or (when (string-match "\\$@?\{[^\}]+@?\}" path)
+                   ;; Path may be a link reference with embedded
+                   ;; variables that must be expanded.
+                   (setq path (hpath:substitute-value path)))
+                 t)
+             (not (string-match "[\t\n\r\"`'|{}\\]" path))
+             (let ((rtn-path (concat path "%s")))
+               (and (or (not (hpath:www-p path))
+                        (string-match "\\`ftp[:.]" path))
+                    (let ((remote-path (string-match 
"\\(@.+:\\|^/.+:\\|..+:/\\).*[^:0-9/]" path)))
+                      (when (cond (remote-path
+                                   (cond ((eq type 'file)
+                                          (not (string-equal "/" (substring 
path -1))))
+                                         ((eq type 'directory)
+                                          (string-equal "/" (substring path 
-1)))
+                                         (t)))
+                                  ((or (and non-exist
+                                            (or
+                                             ;; Info or remote path, so don't 
check for.
+                                             (string-match "[()]" path)
+                                             (hpath:remote-p path)
+                                             (setq suffix (hpath:exists-p path 
t))
+                                             ;; Don't allow spaces in 
non-existent
+                                             ;; pathnames.
+                                             (not (string-match " " path))))
+                                       (setq suffix (hpath:exists-p path t)))
+                                   (cond ((eq type 'file)
+                                          (not (file-directory-p path)))
+                                         ((eq type 'directory)
+                                          (file-directory-p path))
+                                         (t))))
+                        ;; Might be an encoded URL with % characters, so
+                        ;; decode it before calling format below.
+                        (when (string-match "%" rtn-path)
+                          (let (decoded-path)
+                            (while (not (equal rtn-path (setq decoded-path 
(hypb:decode-url rtn-path))))
+                              (setq rtn-path decoded-path))))
+                        ;; Quote any % except for one %s at the end of the
+                        ;; path part of rtn-path (immediately preceding a #
+                        ;; or , character or the end of string).
+                        (setq rtn-path (hypb:replace-match-string "%" rtn-path 
"%%" nil t)
+                              rtn-path (hypb:replace-match-string 
"%%s\\([#,]\\|\\'\\)" rtn-path "%s\\1" nil t))
+                        ;; Return path if non-nil return value.
+                        (if (stringp suffix) ;; suffix could = t, which we 
ignore
+                            (if (string-match (concat (regexp-quote suffix) 
"%s") rtn-path)
+                                ;; remove suffix
+                                (concat (substring rtn-path 0 (match-beginning 
0))
+                                        (substring rtn-path (match-end 0)))
+                              ;; add suffix
+                              (concat modifier (format rtn-path suffix)))
+                          (concat modifier (format rtn-path ""))))))))))
+     path)))
 
 (defun hpath:push-tag-mark ()
   "Add a tag return marker at point if within a programming language file 
buffer.
@@ -1253,6 +1326,16 @@ Is a no-op if the function `push-tag-mark' is not 
available."
                ;; push old position
                (push-tag-mark)))))
 
+(defun hpath:relative-arguments (args-list)
+  "Return any paths in ARGS-LIST below button source loc directory made 
relative.
+Other paths are simply expanded.  Non-path arguments are returned unchanged."
+  (let ((loc (hattr:get 'hbut:current 'loc)))
+    (mapcar (lambda (arg)
+             (hpath:relative-to arg (if (stringp loc)
+                                        (file-name-directory loc)
+                                      (buffer-local-value 'default-directory 
loc))))
+           args-list)))
+
 (defun hpath:relative-to (path &optional default-dir)
   "Return PATH relative to optional DEFAULT-DIR or `default-directory'.
 Expand any other valid path.  Return PATH unchanged when it is not a
@@ -1695,6 +1778,7 @@ pathname is returned.
 
 With optional SUFFIX-FLAG and PATH exists, return suffix added or removed
 from path or t."
+  (setq path (hpath:expand path))
   (let ((return-path)
        (suffix) suffixes)
     (if (file-exists-p path)
@@ -1708,7 +1792,7 @@ from path or t."
          ;; Add suffix
          (setq return-path (concat path suffix)))
        (if (file-exists-p return-path)
-           (setq suffixes nil);; found a match
+           (setq suffixes nil) ;; found a match
          (setq suffix nil
                suffixes (cdr suffixes)
                return-path nil))))
diff --git a/hsettings.el b/hsettings.el
index 1a3606f..570497f 100644
--- a/hsettings.el
+++ b/hsettings.el
@@ -157,13 +157,15 @@ package to display search results."
   (interactive)
   (cl-multiple-value-bind (service-name search-term)
       (hyperbole-read-web-search-arguments service-name search-term)
-    (if (assoc service-name hyperbole-web-search-alist)
-       (let ((browse-url-browser-function
-              hyperbole-web-search-browser-function))
-         (browse-url
-          (format (cdr (assoc service-name hyperbole-web-search-alist))
-                  (browse-url-url-encode-chars search-term "[*\"()',=;?% ]"))))
-      (user-error "(Hyperbole): Invalid web search service `%s'" 
service-name))))
+    (let ((search-pat (cdr (assoc service-name hyperbole-web-search-alist
+                                 (lambda (service1 service2)
+                                   (equal (downcase service1) (downcase 
service2)))))))
+      (if search-pat
+         (let ((browse-url-browser-function
+                hyperbole-web-search-browser-function))
+           (browse-url
+            (format search-pat (browse-url-url-encode-chars search-term 
"[*\"()',=;?% ]"))))
+       (user-error "(Hyperbole): Invalid web search service `%s'" 
service-name)))))
 
 ;; This must be defined before the defcustom `inhbit-hyperbole-messaging'.
 ;;;###autoload
diff --git a/hui-window.el b/hui-window.el
index 51246b4..feef69a 100644
--- a/hui-window.el
+++ b/hui-window.el
@@ -496,9 +496,9 @@ If free variable `assist-flag' is non-nil, uses Assist Key."
         (window-live-p action-key-release-window)
         (not (eq action-key-depress-window action-key-release-window)))))
 
-(defun hmouse-drag-same-window ()
+(defun hmouse-press-release-same-window ()
   "Return non-nil if last Action Key depress and release were in the same 
window.
-If free variable `assist-flag' is non-nil, uses Assist Key."
+If free variable `assist-flag' is non-nil, use Assist Key."
   (if assist-flag
       (and (window-live-p assist-key-depress-window)
           (window-live-p assist-key-release-window)
@@ -533,12 +533,17 @@ items in other modes."
     (hmouse-item-to-window new-window)
     t))
 
+(defun hmouse-drag-same-window ()
+  "Return non-nil if last Action Key depress and release were in the same 
window and minimum drag distance was exceeded.
+If free variable `assist-flag' is non-nil, uses Assist Key."
+  (or (hmouse-drag-horizontally) (hmouse-drag-vertically) 
(hmouse-drag-diagonally)))
+
 (defun hmouse-drag-diagonally ()
   "Return non-nil iff last Action Key use was a diagonal drag within a single 
window.
-If free variable `assist-flag' is non-nil, uses Assist Key.
+If free variable `assist-flag' is non-nil, use Assist Key.
 Value returned is nil if not a diagonal drag, or one of the following symbols
 depending on the direction of the drag: southeast, southwest, northwest, 
northeast."
-  (when (hmouse-drag-same-window)
+  (when (hmouse-press-release-same-window)
     (let ((last-depress-x) (last-release-x)
          (last-depress-y) (last-release-y))
       (if assist-flag
@@ -566,10 +571,10 @@ depending on the direction of the drag: southeast, 
southwest, northwest, northea
 
 (defun hmouse-drag-horizontally ()
   "Return non-nil iff last Action Key use was a horizontal drag within a 
single window.
-If free variable `assist-flag' is non-nil, uses Assist Key.
+If free variable `assist-flag' is non-nil, use Assist Key.
 Value returned is nil if not a horizontal drag, 'left if drag moved left or
 'right otherwise."
-  (when (hmouse-drag-same-window)
+  (when (hmouse-press-release-same-window)
     (let ((last-depress-x) (last-release-x)
          (last-depress-y) (last-release-y))
       (if assist-flag
@@ -594,7 +599,7 @@ Value returned is nil if not a horizontal drag, 'left if 
drag moved left or
 
 (defun hmouse-drag-vertically-within-emacs ()
   "Return non-nil iff last Action Key use was a vertical drag that started and 
ended within the same Emacs frame.
-If free variable `assist-flag' is non-nil, uses Assist Key.
+If free variable `assist-flag' is non-nil, use Assist Key.
 Value returned is nil if not a vertical line drag, 'up if drag moved up or
 'down otherwise."
   (unless (or (hmouse-drag-between-frames) (hmouse-drag-outside-all-windows))
@@ -626,7 +631,7 @@ Value returned is nil if not a vertical line drag, 'up if 
drag moved up or
 If free variable `assist-flag' is non-nil, uses Assist Key.
 Value returned is nil if not a vertical line drag, 'up if drag moved up or
 'down otherwise."
-  (when (hmouse-drag-same-window)
+  (when (hmouse-press-release-same-window)
     (hmouse-drag-vertically-within-emacs)))
 
 (defun hmouse-drag-window-side ()
@@ -963,18 +968,14 @@ If the Assist Key is:
   "Return non-nil if last Smart Key depress and release locations differ.
 Even if the mouse pointer stays within the same position within a
 window, its frame may have been moved by a bottommost modeline drag."
-  (not (and (eq (if assist-flag
-                   assist-key-depress-window
-                 action-key-depress-window)
-               (if assist-flag
-                   assist-key-release-window
-                 action-key-release-window))
-           (equal (if assist-flag
-                      assist-key-depress-position
-                    action-key-depress-position)
-                  (if assist-flag
-                      assist-key-release-position
-                    action-key-release-position)))))
+  (or (not (eq (if assist-flag
+                  assist-key-depress-window
+                action-key-depress-window)
+              (if assist-flag
+                  assist-key-release-window
+                action-key-release-window)))
+      ;; Depress and release were in the same window; test if there is a drag.
+      (hmouse-drag-same-window)))
 
 (defun hmouse-modeline-click ()
   "Return non-nil if last Smart Key depress and release were at a single point 
(less than drag tolerance apart) in a modeline."
diff --git a/hypb-ert.el b/hypb-ert.el
index 45a37a2..3a593b3 100644
--- a/hypb-ert.el
+++ b/hypb-ert.el
@@ -25,7 +25,7 @@
 
 ;;; Code:
 
-(eval-when-compile (require 'ert))
+(require 'ert)
 (require 'hbut)
 (require 'hargs)
 
diff --git a/hyperbole.el b/hyperbole.el
index fa269d4..d5bc877 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -713,13 +713,21 @@ This is used only when running from git source and not a 
package release."
 ;; This call loads the rest of the Hyperbole system.
 (require 'hinit)
 
-;; Prevent multiple initializations of Hyperbole
-(unless (featurep 'hyperbole)
-  (if after-init-time
-      ;; This call initializes Hyperbole key bindings and hooks.
-      (hyperb:init)
-    ;; Initialize after other key bindings are loaded at startup.
-    (add-hook 'after-init-hook #'hyperb:init t)))
+;;;###autoload
+(define-minor-mode hyperbole-mode
+  "The Everyday Hypertextual Information Manager global minor mode."
+  :global t
+  :lighter " Hypb"
+  (if hyperbole-mode
+      (if after-init-time
+          ;; This call initializes Hyperbole key bindings and hooks.
+          (hyperb:init)
+        ;; Initialize after other key bindings are loaded at startup.
+        (add-hook 'after-init-hook #'hyperb:init t))
+    ;; FIXME: hyperb:uninit?
+    (remove-hook 'after-init-hook #'hyperb:init)))
+
+(hyperbole-mode 1)
 
 (makunbound 'hyperbole-loading)
 
diff --git a/kotl/kotl-autoloads.el b/kotl/kotl-autoloads.el
index 9499b87..126d42a 100644
--- a/kotl/kotl-autoloads.el
+++ b/kotl/kotl-autoloads.el
@@ -23,7 +23,60 @@ STILL TODO:
 
 \(fn EXPORT-FROM OUTPUT-TO &optional SOFT-NEWLINES-FLAG)" t nil)
 
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"kexport" '("kexport:")))
+(register-definition-prefixes "kexport" '("kexport:"))
+
+;;;***
+
+;;;### (autoloads nil "kexport-collapse" "kexport-collapse.el" (0
+;;;;;;  0 0 0))
+;;; Generated autoloads from kexport-collapse.el
+
+(autoload 'kexport:html "kexport-collapse" "\
+Export a koutline buffer or file in EXPORT-FROM to html format in OUTPUT-TO.
+By default, this retains newlines within cells as they are.  With optional 
prefix arg, SOFT-NEWLINES-FLAG,
+hard newlines are not used.  Also converts Urls and Klinks into Html 
hyperlinks.
+STILL TODO:
+  Make delimited pathnames into file links (but not if within klinks).
+  Copy attributes stored in cell 0 and attributes from each cell.
+
+\(fn EXPORT-FROM OUTPUT-TO &optional SOFT-NEWLINES-FLAG)" t nil)
+
+(register-definition-prefixes "kexport-collapse" '("kexport:"))
+
+;;;***
+
+;;;### (autoloads nil "kexport-collapse-try" "kexport-collapse-try.el"
+;;;;;;  (0 0 0 0))
+;;; Generated autoloads from kexport-collapse-try.el
+
+(autoload 'kexport:html "kexport-collapse-try" "\
+Export a koutline buffer or file in EXPORT-FROM to html format in OUTPUT-TO.
+By default, this retains newlines within cells as they are.  With optional 
prefix arg, SOFT-NEWLINES-FLAG,
+hard newlines are not used.  Also converts Urls and Klinks into Html 
hyperlinks.
+STILL TODO:
+  Make delimited pathnames into file links (but not if within klinks).
+  Copy attributes stored in cell 0 and attributes from each cell.
+
+\(fn EXPORT-FROM OUTPUT-TO &optional SOFT-NEWLINES-FLAG)" t nil)
+
+(register-definition-prefixes "kexport-collapse-try" '("kexport:"))
+
+;;;***
+
+;;;### (autoloads nil "kexport-menu" "kexport-menu.el" (0 0 0 0))
+;;; Generated autoloads from kexport-menu.el
+
+(autoload 'kexport:html "kexport-menu" "\
+Export a koutline buffer or file in EXPORT-FROM to html format in OUTPUT-TO.
+By default, this retains newlines within cells as they are.  With optional 
prefix arg, SOFT-NEWLINES-FLAG,
+hard newlines are not used.  Also converts Urls and Klinks into Html 
hyperlinks.
+STILL TODO:
+  Make delimited pathnames into file links (but not if within klinks).
+  Copy attributes stored in cell 0 and attributes from each cell.
+
+\(fn EXPORT-FROM OUTPUT-TO &optional SOFT-NEWLINES-FLAG)" t nil)
+
+(register-definition-prefixes "kexport-menu" '("kexport:"))
 
 ;;;***
 
@@ -194,14 +247,10 @@ See documentation for `kcell:ref-to-id' for valid 
cell-ref formats.
 (autoload 'kotl-mode "kotl-mode" "\
 The major mode used to edit and view koutlines.
 It provides the following keys:
-\\{kotl-mode-map}
-
-\(fn)" t nil)
+\\{kotl-mode-map}" t nil)
 
 (autoload 'kotl-mode:example "kotl-mode" "\
-Display the Koutliner example file for demonstration use by a user.
-
-\(fn)" t nil)
+Display the Koutliner example file for demonstration use by a user." t nil)
 
 (autoload 'kotl-mode:overview "kotl-mode" "\
 Show the first line of each cell.
@@ -233,11 +282,16 @@ Display fully expanded tree rooted at CELL-REF.
 \(fn &optional CELL-REF)" t nil)
 
 (autoload 'kotl-mode:is-p "kotl-mode" "\
-Signal an error if current buffer is not a Hyperbole outline, else return t.
+Signal an error if current buffer is not a Hyperbole outline, else return t." 
nil nil)
+
+(register-definition-prefixes "kotl-mode" '("delete-selection-pre-hook" 
"kotl-mode" "yank-"))
 
-\(fn)" nil nil)
+;;;***
+
+;;;### (autoloads nil "kotl-orgtbl" "kotl-orgtbl.el" (0 0 0 0))
+;;; Generated autoloads from kotl-orgtbl.el
 
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"kotl-mode" '("delete-selection-pre-hook" "kotl-mode" "yank-")))
+(register-definition-prefixes "kotl-orgtbl" '("kotl-mode:transpose-lines-" 
"orgtbl-"))
 
 ;;;***
 
@@ -258,7 +312,7 @@ Signal an error if current buffer is not a Hyperbole 
outline, else return t.
 ;;;### (autoloads nil "kview" "kview.el" (0 0 0 0))
 ;;; Generated autoloads from kview.el
 
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"kview" '("kcell-view:" "kview:")))
+(register-definition-prefixes "kview" '("kcell-view:" "kview:"))
 
 ;;;***
 



reply via email to

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