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

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

[elpa] externals/hyperbole f0172c0 1/3: kotl-mode - add pre-command-hook


From: ELPA Syncer
Subject: [elpa] externals/hyperbole f0172c0 1/3: kotl-mode - add pre-command-hook to prevent invalid loc editing
Date: Sun, 2 May 2021 02:57:08 -0400 (EDT)

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

    kotl-mode - add pre-command-hook to prevent invalid loc editing
---
 ChangeLog         | 22 +++++++++++++++++++--
 hibtypes.el       | 26 +++++++++++++++++++------
 hmouse-key.el     |  3 ++-
 hmouse-sh.el      |  2 +-
 hpath.el          |  5 ++++-
 kotl/kotl-mode.el | 22 +++++++++++++++++++++
 kotl/kview.el     | 58 +++++++++++++++++++++++++++++++------------------------
 7 files changed, 102 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b7d2646..1e2d4e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2021-05-01  Bob Weiner  <rsw@gnu.org>
 
+* hibtypes.el (pathname): Update to treat "-simple" as an Elisp
+    library to load only if such a library exists; otherwise,
+    is not treated as a pathname.
+
+* kotl/kotl-mode.el (kotl-mode, kotl-mode:pre-self-insert-command):
+    Update kotl-mode to add this new function as a pre-command-hook
+    to prevent Koutline editing with point in an invalid location,
+    after a mouse-set-point outside of editable bounds (which could
+    corrupt the Koutline structure).
+
+* kotl/kview.el (kview:valid-position-p, kcell-view:previous-kcell):
+    Handle when mouse has moved point to a non-editable location at
+    the end of a Koutline.
+
+* hpath.el (hpath:auto-variable-alist): Add doc summarizing valid
+    values of the cdr of each pair, the path variable.
+
 * ChangeLog: Renamed this file from Changes so change-log-mode will
     be used (now that Elpa release builds no longer overwrite files
     named ChangeLog with git log information).
@@ -461,8 +478,9 @@
   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:expand): Add to generalize file suffixes that trigger
+     Hyperbole to use a path search for files of the type (implicit
+     pathname expansion).
   hpath.el (hpath:find, hpath:file-line-and-column):
   hibtypes.el (pathname-line-and-column): Use hpath:expand.
 
diff --git a/hibtypes.el b/hibtypes.el
index 9b856dd..a86e11e 100644
--- a/hibtypes.el
+++ b/hibtypes.el
@@ -208,12 +208,27 @@ display options."
                                   (string-match substring (format-mode-line 
mode-name)))
                                 '("Buffer Menu" "IBuffer" "Dired"))))
     (let ((path (hpath:at-p))
+         elisp-suffix
           full-path)
       (if path
-          (progn (when (string-match "\\`file://" path)
-                   (setq path (substring path (match-end 0))))
-                 (apply #'ibut:label-set path (hpath:start-end path))
-                 (hact 'link-to-file path))
+         (cond ((and (not (string-empty-p path))
+                     (= (aref path 0) ?-)
+                     (or (setq elisp-suffix (string-match 
"\\`[^\\\\/~]+\\.el[cn]?\\(\\.gz\\)?\\'" path))
+                         (string-match "\\`[^.\\/\t\n\r\f]+\\'" path))
+                     (string-match hpath:prefix-regexp path))
+                 (setq path (substring path (match-end 0))
+                      full-path (locate-library path elisp-suffix))
+                 (cond (full-path
+                       (hact 'hpath:find (concat "-" path)))
+                      (elisp-suffix
+                       (hact 'error "(pathname): \"%s\" not found in 
`load-path'" path))
+                      ;; Don't match as a pathname ibut; could be a Lisp
+                      ;; symbol or something else starting with a '-'.
+                      (t nil)))
+               (t (when (string-match "\\`file://" path)
+                     (setq path (substring path (match-end 0))))
+                   (apply #'ibut:label-set path (hpath:start-end path))
+                   (hact 'link-to-file path)))
         ;;
         ;; Match PATH-related Environment and Lisp variable names and
        ;; Emacs Lisp and Info files without any directory component.
@@ -237,8 +252,7 @@ display options."
                    (setq full-path (locate-library path t))
                    (if full-path
                        (hact 'link-to-file full-path)
-                     (hact 'error "(pathname): \"%s\" not found in `load-path'"
-                           path))))
+                     (hact 'error "(pathname): \"%s\" not found in 
`load-path'" path))))
                 ;; Match only if "(filename)" references a valid Info file
                 ;; and point is within the filename, not on any delimiters
                 ;; so that delimited thing matches trigger later.
diff --git a/hmouse-key.el b/hmouse-key.el
index a9bce96..23b2740 100644
--- a/hmouse-key.el
+++ b/hmouse-key.el
@@ -80,7 +80,8 @@ Assist Key = shift-right mouse key."
       (hmouse-set-bindings hmouse-previous-bindings))
   (setq hmouse-bindings-flag nil
        hmouse-previous-bindings nil)
-  ;; This function does the actual binding of the Hyperbole mouse keys.
+  ;; This function does the actual binding of the Hyperbole mouse keys
+  ;; and the setup of the mouse-set-point command via 
`hmouse-set-point-command'.
   (hmouse-shifted-setup hmouse-middle-flag)
   (if (called-interactively-p 'interactive)
       ;; Assume emacs has support for 3 mouse keys.
diff --git a/hmouse-sh.el b/hmouse-sh.el
index 41fb9d5..442206b 100644
--- a/hmouse-sh.el
+++ b/hmouse-sh.el
@@ -474,7 +474,7 @@ point determined by 
`mouse-select-region-move-to-beginning'."
     ;; this.
     (setq kmacro-call-mouse-event nil)
     ;;
-    (setq hmouse-set-point-command 'hmouse-move-point-emacs)
+    (setq hmouse-set-point-command #'hmouse-move-point-emacs)
     (if (eq window-system 'dps)
        ;; NEXTSTEP offers only 2 shift-mouse buttons which we use as the Smart 
Keys.
        (progn
diff --git a/hpath.el b/hpath.el
index 5a3f2e9..1459365 100644
--- a/hpath.el
+++ b/hpath.el
@@ -43,7 +43,10 @@
     ("\\.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.")
+Each element looks like FILENAME-REGEXP . LISP-VARIABLE-OR-ENV-VARIABLE-STR.
+
+The VARIABLE value may be: a directory path, a list of directory paths
+or a colon or semicolon delimited string of directory paths.")
 
 (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.
diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el
index e209ff2..e47e51b 100644
--- a/kotl/kotl-mode.el
+++ b/kotl/kotl-mode.el
@@ -80,6 +80,9 @@ It provides the following keys:
       ;; defined in kfill.el, so reload it.
       (load "kfill"))
   (setq-local fill-paragraph-function #'kfill:fill-paragraph)
+  ;; Prevent insertion of characters outside of editable bounds,
+  ;; e.g. after the mouse sets point to a non-editable position
+  (add-hook 'pre-command-hook #'kotl-mode:pre-self-insert-command)
   ;; Ensure that outline structure data is saved when save-buffer is called
   ;; from save-some-buffers, {C-x s}.
   (add-hook 'local-write-file-hooks #'kotl-mode:update-buffer)
@@ -2894,6 +2897,25 @@ newlines at end of tree."
                               temporary-goal-column))))
     (move-to-column (if (numberp col) (round col) 0) nil)))
 
+;; Consult this: (kotl-mode:to-visible-position)
+(defun kotl-mode:pre-self-insert-command ()
+  "If within a Koutline, prior to inserting a character, ensure point is in an 
editable position.
+Mouse may have moved point outside of an editable area. kotl-mode adds
+this function to `pre-command-hook'."
+  (when (and (eq major-mode 'kotl-mode)
+            (not (kview:valid-position-p)))
+    (let ((start (kcell-view:start))
+         (end (kcell-view:end-contents)))
+      (cond ((and (<= start (point)) (<= (point) end))
+            ;; in-between paragraph breaks within a single cell
+            (move-to-column (kcell-view:indent nil label-sep-len)))
+           ((< (- (point) (or (kview:label-separator-length kview) 1))
+               (kcell-view:to-visible-label-end))
+            ;; Skip past cell label
+            (goto-char (kcell-view:start)))
+           ;; Move to cell end
+           (t (goto-char (kcell-view:end-contents)))))))
+
 (defun kotl-mode:print-attributes (kview)
   "Print to the `standard-output' stream the attributes of the current visible 
kcell.
 Takes argument KVIEW (so it can be used with `kview:map-tree' and so that
diff --git a/kotl/kview.el b/kotl/kview.el
index 6c5e8f5..cd2f006 100644
--- a/kotl/kview.el
+++ b/kotl/kview.el
@@ -364,6 +364,11 @@ Return t unless no next cell."
       (progn (goto-char (kcell-view:start nil label-sep-len))
             t)))
 
+(defun kcell-view:next-invisible-p (&optional pos label-sep-len)
+  "Return t if there is a next cell after optional POS or point and it is 
invisible."
+  (save-excursion (and (kcell-view:next nil label-sep-len)
+                      (kcell-view:invisible-p (point) label-sep-len))))
+
 (defun kcell-view:operate (function &optional start end)
   "Invoke FUNCTION with view restricted to current cell contents.
 Optional START and END are start and endpoints of cell to use."
@@ -412,12 +417,13 @@ Return t unless no previous cell."
 (defun kcell-view:to-label-end (&optional pos)
   "Move point from optional POS to the end of the current cell's label (before 
the label separator) and return point.
 If between kcells, move to the previous one.  The current cell may be hidden."
-  (if pos (goto-char pos))
+  (when pos (goto-char pos))
   (kview:end-of-actual-line)
   (cond ((null kview)
-        (error "(kcell-view:to-label-end): Invalid kview; try {M-x kotl-mode 
RET} to fix it"))
+        (error "(kcell-view:to-label-end): Invalid kview in %s; try {M-x 
kotl-mode RET} to fix it"
+               (current-buffer)))
        (t
-        (let ((found))
+        (let (found)
           (if (not (setq found (kproperty:get (1- (point)) 'kcell)))
               ;; If not at beginning of cell contents, move there.
               (goto-char (kproperty:previous-single-change (point) 'kcell)))
@@ -486,14 +492,14 @@ With optional VISIBLE-P, consider only visible siblings."
 
 (defun kcell-view:to-visible-label-end (&optional pos)
   "Move point to the end of the current visible cell's label (before the label 
separator).
-If between kcells, move to the previous one."
+If between kcells, move to the previous one.  Return final point location."
   (if pos (goto-char pos))
   ;; Ensure point is within a visible part of the current cell, not
   ;; within some collapsed sub-cell.
   (beginning-of-line)
-  (end-of-visible-line)
-  (if (setq pos (kproperty:previous-single-change (point) 'kcell))
-      (goto-char pos))
+  (end-of-line)
+  (when (setq pos (kproperty:previous-single-change (point) 'kcell))
+    (goto-char pos))
   ;; Now move to end of label via embedded kcell property.
   (goto-char (kproperty:previous-single-change (point) 'kcell)))
 
@@ -679,11 +685,6 @@ the lines displayed, since it has hidden branches."
           (t 0)))
    kview t start end))
 
-(defun kcell-view:next-invisible-p (&optional pos label-sep-len)
-  "Return t if there is a next cell after optional POS or point and it is 
invisible."
-  (save-excursion (and (kcell-view:next nil label-sep-len)
-                      (kcell-view:invisible-p (point) label-sep-len))))
-
 (defun kview:goto-cell-id (id-string)
   "Move point to start of cell with idstamp ID-STRING and return t, else nil."
   (let ((cell-id (string-to-number id-string))
@@ -1168,17 +1169,23 @@ valid values of NEW-TYPE."
 (defun kview:valid-position-p (&optional pos)
   "Return non-nil iff point or optional POS is at a position where editing may 
occur.
 The read-only positions between cells and within cell indentations are 
invalid."
-  (cond ((null pos)
-        (>= (current-column) (kcell-view:indent)))
-       ((not (integer-or-marker-p pos))
-        (error "(kview:valid-position-p): Argument POS not an integer
+  (when (cond ((null pos)
+              (>= (current-column) (kcell-view:indent)))
+             ((not (integer-or-marker-p pos))
+              (error "(kview:valid-position-p): Argument POS not an integer
 or marker, `%s'" pos))
-       ((or (< pos (point-min)) (> pos (point-max)))
-        (error "(kview:valid-position-p): Invalid POS argument, `%d'"
-               pos))
-       (t (save-excursion
-            (goto-char pos)
-            (>= (current-column) (kcell-view:indent))))))
+             ((or (< pos (point-min)) (> pos (point-max)))
+              (error "(kview:valid-position-p): Invalid POS argument, `%d'"
+                     pos))
+             (t (save-excursion
+                  (goto-char pos)
+                  (>= (current-column) (kcell-view:indent)))))
+    ;; Still might be in spurious characters after the end of the
+    ;; outline; check for this.
+    (<= (point)
+       (save-excursion
+         (goto-char (kcell-view:start))
+         (kcell-view:end-contents)))))
 
 ;;; ************************************************************************
 ;;; Private functions
@@ -1207,9 +1214,10 @@ With optional VISIBLE-P, consider only visible cells.  
Return t
 unless no previous cell."
   (let* ((opoint (point))
         (pos opoint))
-    ;; First skip past the 2 changes for the current kcell property.
-    (setq pos (kproperty:previous-single-change pos 'kcell)
-         pos (kproperty:previous-single-change pos 'kcell))
+    (when (kview:valid-position-p)
+      ;; First skip past the 2 changes for the current kcell property.
+      (setq pos (kproperty:previous-single-change pos 'kcell)
+           pos (kproperty:previous-single-change pos 'kcell)))
     (while (and pos (setq pos (kproperty:previous-single-change pos 'kcell))
                (or (not (kproperty:get pos 'kcell))
                    (and visible-p (kcell-view:invisible-p pos 
label-sep-len)))))



reply via email to

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