Commits

aidan  committed 90ce50a

Robert Widhopf-Fenk's hexl-mode enhancement.

  • Participants
  • Parent commits 754dffa

Comments (0)

Files changed (2)

+2005-04-04  Robert Widhopf  <hack@robf.de>
+
+	* hexl.el: Adds as-you-type hex-input, i.e. when in the ASCII
+	columns you will enter in ASCII and when in the HEX columns you
+	will enter hex.  You may easily switch between the two columns
+	by TAB.
+
 2005-04-17  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 1.87 released.
   :group 'hexl)
 
 (defcustom hexl-follow-ascii t
-  "If non-nil then highlight the ASCII character corresponding to point."
+  "If non-nil then highlight the ASCII/HEX character corresponding to point."
   :type 'boolean
   :group 'hexl
   :version "20.3")
   "Maximum offset into hexl buffer.")
 
 (defvar hexl-mode-map nil)
-
 (defvar hexl-mode-old-local-map)
 (defvar hexl-mode-old-mode-name)
 (defvar hexl-mode-old-major-mode)
 (defvar hexl-ascii-extent nil
   "Extent used to highlight ASCII element corresponding to current point.")
 (make-variable-buffer-local 'hexl-ascii-extent)
+(defvar hexl-current-address)
+(make-variable-buffer-local 'hexl-current-address)
 
 ;; routines
 
     (make-local-hook 'change-major-mode-hook)
     (add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
 
+    (make-local-variable 'modeline-format)
+    (setq modeline-format (append '("--" hexl-current-address "--")
+                                  (default-value 'modeline-format)))
+    
     (if hexl-follow-ascii (hexl-follow-ascii 1)))
   (run-hooks 'hexl-mode-hook))
 
 	     (if (>= current-column 41)
 		 (- current-column 41)
 	       (/ (- current-column  (/ current-column 5)) 2))))
+    (if (interactive-p)
+        (message "Current address 0x%010x = %10d" hexl-address hexl-address))
     hexl-address))
 
+(defun hexl-hex-position (address)
+  "Return the ascii-position."
+  (+ (* (/ address 16) 68)
+     11
+     (* 2 (% address 16))
+     (/ (% address 16) 2)))
+
+(defun hexl-ascii-position (address)
+  "Return the ascii-position."
+  (+ (* (/ address 16) 68) 52 (% address 16)))
+
+(defun hexl-at-ascii-position (address)
+  "Return t if point is at ascii position."
+  (= (point) (hexl-ascii-position address)))
+
 (defun hexl-address-to-marker (address)
   "Return buffer position for ADDRESS."
   (interactive "nAddress: ")
   (+ (* (/ address 16) 68) 11 (/ (* (% address 16) 5) 2)))
 
-(defun hexl-goto-address (address)
+(defun hexl-goto-address (address &optional nipple)
   "Go to hexl-mode (decimal) address ADDRESS.
 Signal error if ADDRESS out of range."
   (interactive "nAddress: ")
   (if (or (< address 0) (> address hexl-max-address))
-	  (error "Out of hexl region"))
-  (goto-char (hexl-address-to-marker address)))
+      (error "Out of hexl region."))
+  (goto-char
+   (if (hexl-at-ascii-position (hexl-current-address))
+       (hexl-ascii-position address)
+     (+ (hexl-address-to-marker address) (or nipple 0)))))
 
 (defun hexl-goto-hex-address (hex-address)
   "Go to hexl-mode address (hex string) HEX-ADDRESS.
 (defun hexl-backward-char (arg)
   "Move to left ARG bytes (right if ARG negative) in hexl-mode."
   (interactive "p")
-  (hexl-goto-address (- (hexl-current-address) arg)))
+  (let ((col (current-column)))
+    (if (< col 50)
+        (if (member (% col 5) '(0 2))
+            (hexl-goto-address (- (hexl-current-address) arg) 1)
+          (hexl-goto-address (hexl-current-address) 0))
+      (hexl-goto-address (- (hexl-current-address) arg) col))))
 
 (defun hexl-forward-char (arg)
   "Move right ARG bytes (left if ARG negative) in hexl-mode."
   (interactive "p")
-  (hexl-goto-address (+ (hexl-current-address) arg)))
+  (let ((col (current-column)))
+    (if (< col 50)
+        (if (member (% col 5) '(0 2))
+            (hexl-goto-address (hexl-current-address) 1)
+          (hexl-goto-address (+ (hexl-current-address) arg) 0))
+      (hexl-goto-address (+ (hexl-current-address) arg) col))))
 
 (defun hexl-backward-short (arg)
   "Move to left ARG shorts (right if ARG negative) in hexl-mode."
 (defun hexl-beginning-of-line ()
   "Goto beginning of line in hexl mode."
   (interactive)
-  (goto-char (+ (* (/ (point) 68) 68) 11)))
+  (let ((address (hexl-current-address)))
+    (hexl-goto-address (- address (% address 16)))))
 
 (defun hexl-end-of-line ()
   "Goto end of line in hexl mode."
 			   (setq address hexl-max-address))
 		       address)))
 
+(defun hexl-switch-position ()
+  "Switch cursor from ASCII to HEX position or vice versa."
+  (interactive)
+  (goto-char
+   (let ((address (hexl-current-address)))
+     (if (hexl-at-ascii-position address)
+	 (hexl-address-to-marker address)
+       (hexl-ascii-position address)))))
+
 (defun hexl-scroll-down (arg)
   "Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
   (interactive "P")
 (defun hexl-self-insert-command (arg)
   "Insert this character."
   (interactive "p")
-  (hexl-insert-char last-command-char arg))
+  (let ((col (current-column)))
+    (if (and (>= col 10) ( <= col 48))
+        (let ((point (point))
+              (pos (% col 5)))
+          (if (member pos '(1 3))
+              (hexl-insert-char
+               (hexl-hex-string-to-integer
+                (concat (buffer-substring (- point 1) point)
+                        (char-to-string last-command-char)))
+               arg)
+            (hexl-insert-char
+             (hexl-hex-string-to-integer
+              (concat (char-to-string last-command-char)
+                      (buffer-substring (+ point 1) (+ point 2))))
+             arg)
+            (goto-char (1+ point))))
+      (if (not last-command-char)
+	  (setq last-command-char
+		(event-to-character last-input-event t t t)))
+      (hexl-insert-char last-command-char arg))))
 
 (defun hexl-insert-char (ch num)
   "Insert a character in a hexl buffer."
   (let ((address (hexl-current-address t)))
     (while (> num 0)
-      (let ((hex-position
-	     (+ (* (/ address 16) 68)
-		11
-		(* 2 (% address 16))
-		(/ (% address 16) 2)))
-	    (ascii-position
-	     (+ (* (/ address 16) 68) 52 (% address 16)))
-	    at-ascii-position)
-	(if (= (point) ascii-position)
-	    (setq at-ascii-position t))
-	(goto-char hex-position)
-	(delete-char 2)
-	(insert (format "%02x" ch))
-	(goto-char ascii-position)
-	(delete-char 1)
-	(insert (hexl-printable-character ch))
-	(or (eq address hexl-max-address)
-	    (setq address (1+ address)))
-	(hexl-goto-address address)
-	(if at-ascii-position
-	    (progn
-	      (beginning-of-line)
-	      (forward-char 51)
-	      (forward-char (% address 16)))))
+      (let* ((hex-position (hexl-hex-position address))
+	     (ascii-position (hexl-ascii-position address)))
+	(save-excursion
+	  (goto-char hex-position)
+	  (delete-char 2)
+	  (insert (format "%02x" ch))
+	  (goto-char ascii-position)
+	  (delete-char 1)
+	  (insert (hexl-printable-character ch))
+	  (or (eq address hexl-max-address)
+	      (setq address (1+ address))))
+	(hexl-goto-address address))
       (setq num (1- num)))))
 
 ;; hex conversion
 	    )))))
 
 (defun hexl-follow-ascii-find ()
-  "Find and highlight the ASCII element corresponding to current point."
-  (let ((pos (+ 51
-		(- (point) (current-column))
-		(mod (hexl-current-address) 16))))
-    (set-extent-endpoints hexl-ascii-extent pos (1+ pos))
-    ))
+  "Find and highlight the ASCII/HEX element corresponding to current point."
+  (setq hexl-current-address (hexl-current-address))
+  (condition-case nil
+      (let ((col (current-column))
+	    (point (point))
+	    start end)
+	(if (> col 48)
+	    (setq start (+ 10 (- point col) (/ (- col 51) 2)
+			   (* 2 (mod (hexl-current-address) 16)))
+		  end (+ start 2))
+	  (setq start (+ 51 (- point col) (mod hexl-current-address 16))
+		end (+ start 1)))
+	(set-extent-endpoints hexl-ascii-extent start end))
+    (error nil))
+  (setq hexl-current-address
+        (format "0x%x=%d" hexl-current-address hexl-current-address)))
 
 ;; startup stuff.
 
   (define-key hexl-mode-map "\C-x]" 'hexl-end-of-1k-page)
   (define-key hexl-mode-map "\C-x\C-p" 'undefined)
   (define-key hexl-mode-map "\C-x\C-s" 'hexl-save-buffer)
-  (define-key hexl-mode-map "\C-x\C-t" 'undefined))
+  (define-key hexl-mode-map "\C-x\C-t" 'undefined)
+
+  (define-key hexl-mode-map [tab] 'hexl-switch-position))
 
 (provide 'hexl)