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

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

[elpa] master fa31d3a: * nhexl-mode.el: Improve handling of mouse events


From: Stefan Monnier
Subject: [elpa] master fa31d3a: * nhexl-mode.el: Improve handling of mouse events
Date: Wed, 7 Nov 2018 11:10:16 -0500 (EST)

branch: master
commit fa31d3a8482c220f2f850ce33d244be108dfaae5
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * nhexl-mode.el: Improve handling of mouse events
    
    (nhexl--posn-hexadjust): New function extracted from nhexl-mouse-set-point.
    (nhexl-mouse-set-point): Use it.
    (nhexl-mouse-drag-region, nhexl-mouse-set-region): New commands.
    (nhexl-mode-map): Remap to them.
    (nhexl--make-line): Circumvent some misbehavior in the presence of buttons.
---
 packages/nhexl-mode/nhexl-mode.el | 72 ++++++++++++++++++++++++++++-----------
 1 file changed, 52 insertions(+), 20 deletions(-)

diff --git a/packages/nhexl-mode/nhexl-mode.el 
b/packages/nhexl-mode/nhexl-mode.el
index b7221bf..b58b81d 100644
--- a/packages/nhexl-mode/nhexl-mode.el
+++ b/packages/nhexl-mode/nhexl-mode.el
@@ -328,6 +328,8 @@ existing text, if needed with `nhexl-overwrite-clear-byte'."
     (define-key map [remap scroll-up-command] #'nhexl-scroll-up)
     (define-key map [remap scroll-down-command] #'nhexl-scroll-down)
     (define-key map [remap mouse-set-point] #'nhexl-mouse-set-point)
+    (define-key map [remap mouse-drag-region] #'nhexl-mouse-drag-region)
+    (define-key map [remap mouse-set-region] #'nhexl-mouse-set-region)
     ;; FIXME: Find a key binding for nhexl-nibble-edit-mode!
     map))
 
@@ -466,35 +468,55 @@ existing text, if needed with 
`nhexl-overwrite-clear-byte'."
 (eval-and-compile
   (defvar nhexl--put-LF-in-string nil))
 
-(defun nhexl-mouse-set-point (event)
-  "Move point to the position clicked on with the mouse."
-  (interactive "e")
-  ;; (cl-assert (eq last-))
-  (let* ((posn (event-end event))
-         (str-data (posn-string posn))
+(defun nhexl--posn-hexadjust (posn)
+  "Adjust POSN when clicking on the hex area.
+Return the corresponding nibble, if applicable."
+  ;; When clicking in the hex area, (nth 1 posn) contains the first position
+  ;; covered by the before-string, and (nth 5 posn) as well.  Improve this by
+  ;; setting nth-5 (the one used by `posn-point') to the closest buffer
+  ;; position corresponding to the hex on which we clicked.
+  (let* ((str-data (posn-string posn))
+         (base-pos (nth 1 posn))
          (addr-offset (eval-when-compile
                         (+ (if nhexl--put-LF-in-string 1 0)
-                           9            ;for "<address>:"
-                           1))))        ;for the following (stretch)space
+                           9           ;for "<address>:"
+                           1))))       ;for the following (stretch)space
     ;; (message "NMSP: strdata=%S" str-data)
-    (cond
-     ((and (consp str-data) (stringp (car str-data))
-           (integerp (cdr str-data)) (> (cdr str-data) addr-offset))
+    (when (and (consp str-data) (stringp (car str-data)) (integerp base-pos)
+               (integerp (cdr str-data)) (> (cdr str-data) addr-offset))
       (let* ((hexchars (- (cdr str-data) addr-offset))
              ;; FIXME: Calculations here go wrong in the presence of
              ;; chars with code > 255.
              (hex-no-spaces (- hexchars (/ (1+ hexchars) 5)))
              (bytes (min (/ hex-no-spaces 2)
                          ;; Bound, for clicks between the hex and ascii areas.
-                         (1- (nhexl--line-width)))))
-        ;; This will select the window if needed and move point to the
-        ;; beginning of the line.
-        (posn-set-point posn)
-        (forward-char bytes)
-        (when nhexl-nibble-edit-mode
-          (let* ((nibble (- hex-no-spaces (* bytes 2))))
-            (nhexl--nibble-set (min nibble 1))))))
-     (t (call-interactively #'mouse-set-point)))))
+                         (1- (nhexl--line-width))))
+             (newpos (min (+ base-pos bytes) (point-max))))
+        (setf (nth 5 posn) newpos)
+        (let* ((nibble (- hex-no-spaces (* bytes 2))))
+          (min nibble 1))))))
+
+(defun nhexl-mouse-set-point (event)
+  "Move point to the position clicked on with the mouse."
+  (interactive "e")
+  (let* ((nibble (nhexl--posn-hexadjust (event-end event))))
+    (call-interactively #'mouse-set-point)
+    (when (and nibble nhexl-nibble-edit-mode)
+      (nhexl--nibble-set nibble)
+      (nhexl--refresh-cursor))))
+
+(defun nhexl-mouse-drag-region (event)
+  "Set the region to the text that the mouse is dragged over."
+  (interactive "e")
+  (nhexl--posn-hexadjust (event-start event))
+  (call-interactively #'mouse-drag-region))
+
+(defun nhexl-mouse-set-region (event)
+  "Set the region to the text dragged over, and copy to kill ring."
+  (interactive "e")
+  (nhexl--posn-hexadjust (event-start event))
+  (nhexl--posn-hexadjust (event-end event))
+  (call-interactively #'mouse-set-region))
 
 (defun nhexl--change-function (beg end len)
   ;; Round modifications up-to the hexl-line length since nhexl--jit will need
@@ -616,6 +638,16 @@ existing text, if needed with 
`nhexl-overwrite-clear-byte'."
                                  ,(+ (/ (* lw 5) 2)
                                      12 3))))))
     (font-lock-append-text-property 0 (length s) prop 'default s)
+    ;; If the first char of the text has a button (e.g. it's part of
+    ;; a hyperlink), clicking in the hex part of the display might signal
+    ;; an error because it thinks we're clicking on the hyperlink.
+    ;; So override the relevant properties.
+    (put-text-property 0 (length s) 'keymap (make-sparse-keymap) s)
+    (put-text-property 0 (length s) 'follow-link #'ignore s)
+    ;; Override any `category' property that might otherwise be inherited from
+    ;; the text (e.g. that of some button).
+    ;; FIXME: This doesn't have the intended effect!
+    (put-text-property 0 (length s) 'category t s)
     s))
 
 (defun nhexl--jit (from to)



reply via email to

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