aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Dasmohapatra2012-04-12 17:58:53 +0200
committerLars Magne Ingebrigtsen2012-04-12 17:58:53 +0200
commit0d15b5ba4d6ef49b2cc398dca9181acb353658d1 (patch)
tree626fe94875fe75b16216f925a40900da54acca19
parent64a440db710570f2a38cb604ad876d35bc99daab (diff)
downloademacs-0d15b5ba4d6ef49b2cc398dca9181acb353658d1.tar.gz
emacs-0d15b5ba4d6ef49b2cc398dca9181acb353658d1.zip
Allow the user to alter the bit grouping in hexl.el
* hexl.el (hexl-bits): New variable. (hexl-options): Mention the variable in the doc string. (hexl-rulerise): New function. (hexl-line-displen): New function (hexl-mode): Mention the new variable. (hexl-mode, hexl-current-address, hexl-current-address): Use the displen. (hexl-ascii-start-column): New function. (hexl-address-to-marker, hexl-beginning-of-line, hexl-options) (hexl-insert-char, hexl-mode-ruler): Use the displen. Fixes: debbugs:4941
-rw-r--r--lisp/ChangeLog13
-rw-r--r--lisp/hexl.el105
2 files changed, 93 insertions, 25 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1f6b7d3dfaf..0e50a9e7ada 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,16 @@
12012-04-12 Vivek Dasmohapatra <vivek@etla.org>
2
3 * hexl.el (hexl-bits): New variable.
4 (hexl-options): Mention the variable in the doc string.
5 (hexl-rulerise): New function.
6 (hexl-line-displen): New function
7 (hexl-mode): Mention the new variable.
8 (hexl-mode, hexl-current-address, hexl-current-address): Use the
9 displen.
10 (hexl-ascii-start-column): New function.
11 (hexl-address-to-marker, hexl-beginning-of-line, hexl-options)
12 (hexl-insert-char, hexl-mode-ruler): Use the displen (bug#4941).
13
12012-04-12 Agustín Martín Domingo <agustin.martin@hispalinux.es> 142012-04-12 Agustín Martín Domingo <agustin.martin@hispalinux.es>
2 15
3 * textmodes/flyspell.el (flyspell-large-region): For hunspell, use 16 * textmodes/flyspell.el (flyspell-large-region): For hunspell, use
diff --git a/lisp/hexl.el b/lisp/hexl.el
index 538d218e38e..db4f3319b79 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -51,6 +51,13 @@
51 "Edit a file in a hex dump format using the hexl filter." 51 "Edit a file in a hex dump format using the hexl filter."
52 :group 'data) 52 :group 'data)
53 53
54(defcustom hexl-bits 16
55 "The bit grouping that hexl will use."
56 :type '(choice (const 8 )
57 (const 16)
58 (const 32)
59 (const 64))
60 :group 'hexl)
54 61
55(defcustom hexl-program "hexl" 62(defcustom hexl-program "hexl"
56 "The program that will hexlify and dehexlify its stdin. 63 "The program that will hexlify and dehexlify its stdin.
@@ -67,7 +74,9 @@ and \"-de\" when dehexlifying a buffer."
67 74
68(defcustom hexl-options (format "-hex %s" hexl-iso) 75(defcustom hexl-options (format "-hex %s" hexl-iso)
69 "Space separated options to `hexl-program' that suit your needs. 76 "Space separated options to `hexl-program' that suit your needs.
70Quoting cannot be used, so the arguments cannot themselves contain spaces." 77Quoting cannot be used, so the arguments cannot themselves contain spaces.
78If you wish to set the `-group-by-X-bits' options, set `hexl-bits' instead,
79as that will override any bit grouping options set here."
71 :type 'string 80 :type 'string
72 :group 'hexl) 81 :group 'hexl)
73 82
@@ -212,10 +221,34 @@ Quoting cannot be used, so the arguments cannot themselves contain spaces."
212 (2 'hexl-ascii-region t t))) 221 (2 'hexl-ascii-region t t)))
213 "Font lock keywords used in `hexl-mode'.") 222 "Font lock keywords used in `hexl-mode'.")
214 223
224(defun hexl-rulerise (string bits)
225 (let ((size (/ bits 4)) (strlen (length string)) (pos 0) (ruler ""))
226 (while (< pos strlen)
227 (setq ruler (concat ruler " " (substring string pos (+ pos size))))
228 (setq pos (+ pos size)))
229 (substring ruler 1) ))
230
231(defvar hexl-rulers
232 (mapcar
233 (lambda (bits)
234 (cons bits
235 (concat " 87654321 "
236 (hexl-rulerise "00112233445566778899aabbccddeeff" bits)
237 " 0123456789abcdef")))
238 '(8 16 32 64)))
215;; routines 239;; routines
216 240
217(put 'hexl-mode 'mode-class 'special) 241(put 'hexl-mode 'mode-class 'special)
218 242
243;; 10 chars for the "address: "
244;; 32 chars for the hexlified bytes
245;; 1 char for the space
246;; 16 chars for the character display
247;; X chars for the spaces (128 bits divided by the hexl-bits)
248;; 1 char for the newline.
249(defun hexl-line-displen ()
250 "The length of a hexl display line (varies with `hexl-bits')."
251 (+ 60 (/ 128 (or hexl-bits 16))))
219 252
220(defun hexl-mode--minor-mode-p (var) 253(defun hexl-mode--minor-mode-p (var)
221 (memq var '(ruler-mode hl-line-mode))) 254 (memq var '(ruler-mode hl-line-mode)))
@@ -248,7 +281,7 @@ using the function `hexlify-buffer'.
248Each line in the buffer has an \"address\" (displayed in hexadecimal) 281Each line in the buffer has an \"address\" (displayed in hexadecimal)
249representing the offset into the file that the characters on this line 282representing the offset into the file that the characters on this line
250are at and 16 characters from the file (displayed as hexadecimal 283are at and 16 characters from the file (displayed as hexadecimal
251values grouped every 16 bits) and as their ASCII values. 284values grouped every `hexl-bits' bits) and as their ASCII values.
252 285
253If any of the characters (displayed as ASCII characters) are 286If any of the characters (displayed as ASCII characters) are
254unprintable (control or meta characters) they will be replaced as 287unprintable (control or meta characters) they will be replaced as
@@ -330,10 +363,7 @@ You can use \\[hexl-find-file] to visit a file in Hexl mode.
330 (hexlify-buffer) 363 (hexlify-buffer)
331 (restore-buffer-modified-p modified)) 364 (restore-buffer-modified-p modified))
332 (set (make-local-variable 'hexl-max-address) 365 (set (make-local-variable 'hexl-max-address)
333 (let* ((full-lines (/ (buffer-size) 68)) 366 (+ (* (/ (1- (buffer-size)) (hexl-line-displen)) 16) 15))
334 (last-line (% (buffer-size) 68))
335 (last-line-bytes (% last-line 52)))
336 (+ last-line-bytes (* full-lines 16) -1)))
337 (condition-case nil 367 (condition-case nil
338 (hexl-goto-address original-point) 368 (hexl-goto-address original-point)
339 (error nil))) 369 (error nil)))
@@ -510,17 +540,20 @@ Ask the user for confirmation."
510(defun hexl-current-address (&optional validate) 540(defun hexl-current-address (&optional validate)
511 "Return current hexl-address." 541 "Return current hexl-address."
512 (interactive) 542 (interactive)
513 (let ((current-column (- (% (- (point) (point-min) -1) 68) 11)) 543 (let ((current-column
544 (- (% (- (point) (point-min) -1) (hexl-line-displen)) 11))
514 (hexl-address 0)) 545 (hexl-address 0))
515 (if (< current-column 0) 546 (if (< current-column 0)
516 (if validate 547 (if validate
517 (error "Point is not on a character in the file") 548 (error "Point is not on a character in the file")
518 (setq current-column 0))) 549 (setq current-column 0)))
519 (setq hexl-address 550 (setq hexl-address
520 (+ (* (/ (- (point) (point-min) -1) 68) 16) 551 (+ (* (/ (- (point) (point-min) -1)
521 (if (>= current-column 41) 552 (hexl-line-displen)) 16)
522 (- current-column 41) 553 (if (>= current-column (- (hexl-ascii-start-column) 10))
523 (/ (- current-column (/ current-column 5)) 2)))) 554 (- current-column (- (hexl-ascii-start-column) 10))
555 (/ (- current-column
556 (/ current-column (1+ (/ hexl-bits 4)))) 2))))
524 (when (called-interactively-p 'interactive) 557 (when (called-interactively-p 'interactive)
525 (message "Current address is %d/0x%08x" hexl-address hexl-address)) 558 (message "Current address is %d/0x%08x" hexl-address hexl-address))
526 hexl-address)) 559 hexl-address))
@@ -531,10 +564,18 @@ This function is intended to be used as eldoc callback."
531 (let ((addr (hexl-current-address))) 564 (let ((addr (hexl-current-address)))
532 (format "Current address is %d/0x%08x" addr addr))) 565 (format "Current address is %d/0x%08x" addr addr)))
533 566
567(defun hexl-ascii-start-column ()
568 "Column at which the ascii portion of the hexl display starts."
569 (+ 43 (/ 128 hexl-bits)))
570
534(defun hexl-address-to-marker (address) 571(defun hexl-address-to-marker (address)
535 "Return buffer position for ADDRESS." 572 "Return buffer position for ADDRESS."
536 (interactive "nAddress: ") 573 (interactive "nAddress: ")
537 (+ (* (/ address 16) 68) 10 (point-min) (/ (* (% address 16) 5) 2))) 574 (let ((N (* (% address 16) 2)))
575 (+ (* (/ address 16) (hexl-line-displen)) ; hexl line no * display length
576 10 ; 10 chars for the "address: " prefix
577 (point-min) ; base offset (point usually starts at 1, not 0)
578 (+ N (/ N (/ hexl-bits 4))) )) ) ; char offset into hexl display line
538 579
539(defun hexl-goto-address (address) 580(defun hexl-goto-address (address)
540 "Go to hexl-mode (decimal) address ADDRESS. 581 "Go to hexl-mode (decimal) address ADDRESS.
@@ -700,7 +741,7 @@ With prefix arg N, puts point N bytes of the way from the true beginning."
700(defun hexl-beginning-of-line () 741(defun hexl-beginning-of-line ()
701 "Goto beginning of line in hexl mode." 742 "Goto beginning of line in hexl mode."
702 (interactive) 743 (interactive)
703 (goto-char (+ (* (/ (point) 68) 68) 11))) 744 (goto-char (+ (* (/ (point) (hexl-line-displen)) (hexl-line-displen)) 11)))
704 745
705(defun hexl-end-of-line () 746(defun hexl-end-of-line ()
706 "Goto end of line in hexl mode." 747 "Goto end of line in hexl mode."
@@ -776,6 +817,17 @@ You may also type octal digits, to insert a character with that code."
776 817
777;00000000: 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789ABCDEF 818;00000000: 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789ABCDEF
778 819
820(defun hexl-options (&optional test)
821 "Combine `hexl-bits' with `hexl-options', altering `hexl-options' as needed
822to produce the command line options to pass to the hexl command."
823 (let ((opts (or test hexl-options)))
824 (when (memq hexl-bits '(8 16 32 64))
825 (when (string-match "\\(.*\\)-group-by-[0-9]+-bits\\(.*\\)" opts)
826 (setq opts (concat (match-string 1 opts)
827 (match-string 2 opts))))
828 (setq opts (format "%s -group-by-%d-bits " opts hexl-bits)) )
829 opts))
830
779;;;###autoload 831;;;###autoload
780(defun hexlify-buffer () 832(defun hexlify-buffer ()
781 "Convert a binary buffer to hexl format. 833 "Convert a binary buffer to hexl format.
@@ -798,7 +850,7 @@ This discards the buffer's undo information."
798 (mapcar (lambda (s) 850 (mapcar (lambda (s)
799 (if (not (multibyte-string-p s)) s 851 (if (not (multibyte-string-p s)) s
800 (encode-coding-string s locale-coding-system))) 852 (encode-coding-string s locale-coding-system)))
801 (split-string hexl-options))) 853 (split-string (hexl-options))))
802 (if (> (point) (hexl-address-to-marker hexl-max-address)) 854 (if (> (point) (hexl-address-to-marker hexl-max-address))
803 (hexl-goto-address hexl-max-address)))) 855 (hexl-goto-address hexl-max-address))))
804 856
@@ -815,7 +867,7 @@ This discards the buffer's undo information."
815 (buffer-undo-list t)) 867 (buffer-undo-list t))
816 (apply 'call-process-region (point-min) (point-max) 868 (apply 'call-process-region (point-min) (point-max)
817 (expand-file-name hexl-program exec-directory) 869 (expand-file-name hexl-program exec-directory)
818 t t nil "-de" (split-string hexl-options)))) 870 t t nil "-de" (split-string (hexl-options)))))
819 871
820(defun hexl-char-after-point () 872(defun hexl-char-after-point ()
821 "Return char for ASCII hex digits at point." 873 "Return char for ASCII hex digits at point."
@@ -912,12 +964,15 @@ CH must be a unibyte character whose value is between 0 and 255."
912 (let ((address (hexl-current-address t))) 964 (let ((address (hexl-current-address t)))
913 (while (> num 0) 965 (while (> num 0)
914 (let ((hex-position 966 (let ((hex-position
915 (+ (* (/ address 16) 68) 967 (+ (* (/ address 16) (hexl-line-displen))
916 10 (point-min) 968 10 (point-min)
917 (* 2 (% address 16)) 969 (* 2 (% address 16))
918 (/ (% address 16) 2))) 970 (/ (% address 16) 2)))
919 (ascii-position 971 (ascii-position
920 (+ (* (/ address 16) 68) 51 (point-min) (% address 16))) 972 (+ (* (/ address 16) (hexl-line-displen))
973 (hexl-ascii-start-column)
974 (point-min)
975 (% address 16)))
921 at-ascii-position) 976 at-ascii-position)
922 (if (= (point) ascii-position) 977 (if (= (point) ascii-position)
923 (setq at-ascii-position t)) 978 (setq at-ascii-position t))
@@ -933,7 +988,7 @@ CH must be a unibyte character whose value is between 0 and 255."
933 (if at-ascii-position 988 (if at-ascii-position
934 (progn 989 (progn
935 (beginning-of-line) 990 (beginning-of-line)
936 (forward-char 51) 991 (forward-char (hexl-ascii-start-column))
937 (forward-char (% address 16))))) 992 (forward-char (% address 16)))))
938 (setq num (1- num))))) 993 (setq num (1- num)))))
939 994
@@ -1041,7 +1096,7 @@ This function is assumed to be used as callback function for `hl-line-mode'."
1041 1096
1042(defun hexl-follow-ascii-find () 1097(defun hexl-follow-ascii-find ()
1043 "Find and highlight the ASCII element corresponding to current point." 1098 "Find and highlight the ASCII element corresponding to current point."
1044 (let ((pos (+ 51 1099 (let ((pos (+ (hexl-ascii-start-column)
1045 (- (point) (current-column)) 1100 (- (point) (current-column))
1046 (mod (hexl-current-address) 16)))) 1101 (mod (hexl-current-address) 16))))
1047 (move-overlay hexl-ascii-overlay pos (1+ pos)) 1102 (move-overlay hexl-ascii-overlay pos (1+ pos))
@@ -1050,7 +1105,7 @@ This function is assumed to be used as callback function for `hl-line-mode'."
1050(defun hexl-mode-ruler () 1105(defun hexl-mode-ruler ()
1051 "Return a string ruler for hexl mode." 1106 "Return a string ruler for hexl mode."
1052 (let* ((highlight (mod (hexl-current-address) 16)) 1107 (let* ((highlight (mod (hexl-current-address) 16))
1053 (s " 87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef") 1108 (s (cdr (assq hexl-bits hexl-rulers)))
1054 (pos 0)) 1109 (pos 0))
1055 (set-text-properties 0 (length s) nil s) 1110 (set-text-properties 0 (length s) nil s)
1056 ;; Turn spaces in the header into stretch specs so they work 1111 ;; Turn spaces in the header into stretch specs so they work
@@ -1062,12 +1117,12 @@ This function is assumed to be used as callback function for `hl-line-mode'."
1062 `(space :align-to ,(1- pos)) 1117 `(space :align-to ,(1- pos))
1063 s)) 1118 s))
1064 ;; Highlight the current column. 1119 ;; Highlight the current column.
1065 (put-text-property (+ 11 (/ (* 5 highlight) 2)) 1120 (let ( (offset (+ (* 2 highlight) (/ (* 8 highlight) hexl-bits))) )
1066 (+ 13 (/ (* 5 highlight) 2)) 1121 (put-text-property (+ 11 offset) (+ 13 offset) 'face 'highlight s))
1067 'face 'highlight s)
1068 ;; Highlight the current ascii column 1122 ;; Highlight the current ascii column
1069 (put-text-property (+ 13 39 highlight) (+ 13 40 highlight) 1123 (put-text-property (+ (hexl-ascii-start-column) highlight 1)
1070 'face 'highlight s) 1124 (+ (hexl-ascii-start-column) highlight 2)
1125 'face 'highlight s)
1071 s)) 1126 s))
1072 1127
1073;; startup stuff. 1128;; startup stuff.