(debug): Quieten Drew Adams.
[bpt/emacs.git] / lisp / hexl.el
CommitLineData
55535639 1;;; hexl.el --- edit a file in a hex dump format using the hexl filter
e5167999 2
45ad49ba 3;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
a2535589 4
3a801d0c 5;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu>
b7f66977
RS
6;; Maintainer: FSF
7;; Keywords: data
3a801d0c 8
a2535589
JA
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
e5167999 13;; the Free Software Foundation; either version 2, or (at your option)
a2535589
JA
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
a2535589 25
e5167999
ER
26;;; Commentary:
27
e41b2db1
ER
28;; This package implements a major mode for editing binary files. It uses
29;; a program called hexl, supplied with the GNU Emacs distribution, that
30;; can filter a binary into an editable format or from the format back into
31;; binary. For full instructions, invoke `hexl-mode' on an empty buffer and
a0164df5 32;; do M-x `describe-mode'.
e41b2db1 33;;
a0164df5 34;; NOTE: Remember to change `hexl-program' or `hexl-options' if needed.
a2535589
JA
35;;
36;; Currently hexl only supports big endian hex output with 16 bit
37;; grouping.
38;;
39;; -iso in `hexl-options' will allow iso characters to display in the
40;; ASCII region of the screen (if your emacs supports this) instead of
41;; changing them to dots.
42
e5167999
ER
43;;; Code:
44
01ff9136
MY
45(require 'eldoc)
46
a2535589
JA
47;;
48;; vars here
49;;
50
00ed33e7
RS
51(defgroup hexl nil
52 "Edit a file in a hex dump format using the hexl filter."
53 :group 'data)
54
55
56(defcustom hexl-program "hexl"
65e5f4bc 57 "The program that will hexlify and dehexlify its stdin.
57f07931 58`hexl-program' will always be concatenated with `hexl-options'
00ed33e7
RS
59and \"-de\" when dehexlifying a buffer."
60 :type 'string
61 :group 'hexl)
a2535589 62
00ed33e7 63(defcustom hexl-iso ""
a2535589 64 "If your emacs can handle ISO characters, this should be set to
00ed33e7
RS
65\"-iso\" otherwise it should be \"\"."
66 :type 'string
67 :group 'hexl)
a2535589 68
00ed33e7 69(defcustom hexl-options (format "-hex %s" hexl-iso)
b8c49a19
SM
70 "Space separated options to `hexl-program' that suit your needs.
71Quoting cannot be used, so the arguments cannot themselves contain spaces."
00ed33e7
RS
72 :type 'string
73 :group 'hexl)
a2535589 74
db6c5b92
SE
75(defcustom hexl-follow-ascii t
76 "If non-nil then highlight the ASCII character corresponding to point."
77 :type 'boolean
cd32a7ba
DN
78 :group 'hexl
79 :version "20.3")
db6c5b92 80
9fd76d04
MY
81(defcustom hexl-mode-hook '(hexl-follow-line hexl-activate-ruler)
82 "Normal hook run when entering Hexl mode."
83 :type 'hook
84 :options '(hexl-follow-line hexl-activate-ruler turn-on-eldoc-mode)
85 :group 'hexl)
86
87(defface hexl-address-area
88 '((t (:inherit header-line)))
89 "Face used in address are of hexl-mode buffer."
90 :group 'hexl)
91
92(defface hexl-ascii-area
93 '((t (:inherit header-line)))
94 "Face used in ascii are of hexl-mode buffer."
95 :group 'hexl)
96
a2535589
JA
97(defvar hexl-max-address 0
98 "Maximum offset into hexl buffer.")
99
100(defvar hexl-mode-map nil)
101
b27ce24f
RS
102(defvar ruler-mode)
103(defvar ruler-mode-ruler-function)
104(defvar hl-line-mode)
105
106(defvar hexl-mode-old-hl-line-mode)
f39c6650
RS
107(defvar hexl-mode-old-local-map)
108(defvar hexl-mode-old-mode-name)
109(defvar hexl-mode-old-major-mode)
b27ce24f 110(defvar hexl-mode-old-ruler-mode)
87b3b78a 111(defvar hexl-mode-old-isearch-search-fun-function)
0e4889b2
RS
112(defvar hexl-mode-old-require-final-newline)
113(defvar hexl-mode-old-syntax-table)
639b8e4d 114(defvar hexl-mode-old-font-lock-keywords)
f39c6650 115
db6c5b92
SE
116(defvar hexl-ascii-overlay nil
117 "Overlay used to highlight ASCII element corresponding to current point.")
118(make-variable-buffer-local 'hexl-ascii-overlay)
119
639b8e4d
MY
120(defvar hexl-font-lock-keywords
121 '(("^\\([0-9a-f]+:\\).\\{40\\} \\(.+$\\)"
122 ;; "^\\([0-9a-f]+:\\).+ \\(.+$\\)"
123 (1 'hexl-address-area t t)
124 (2 'hexl-ascii-area t t)))
125 "Font lock keywords used in `hexl-mode'.")
126
a2535589
JA
127;; routines
128
2d902813
RS
129(put 'hexl-mode 'mode-class 'special)
130
31c75fa7 131;;;###autoload
a2535589 132(defun hexl-mode (&optional arg)
330bd7c3
PR
133 "\\<hexl-mode-map>A mode for editing binary files in hex dump format.
134This is not an ordinary major mode; it alters some aspects
fe0a77c6 135of the current mode's behavior, but not all; also, you can exit
330bd7c3 136Hexl mode and return to the previous mode using `hexl-mode-exit'.
a2535589
JA
137
138This function automatically converts a buffer into the hexl format
139using the function `hexlify-buffer'.
140
8a1281b5 141Each line in the buffer has an \"address\" (displayed in hexadecimal)
a2535589
JA
142representing the offset into the file that the characters on this line
143are at and 16 characters from the file (displayed as hexadecimal
144values grouped every 16 bits) and as their ASCII values.
145
146If any of the characters (displayed as ASCII characters) are
147unprintable (control or meta characters) they will be replaced as
148periods.
149
8a1281b5
RS
150If `hexl-mode' is invoked with an argument the buffer is assumed to be
151in hexl format.
a2535589
JA
152
153A sample format:
154
155 HEX ADDR: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f ASCII-TEXT
156 -------- ---- ---- ---- ---- ---- ---- ---- ---- ----------------
157 00000000: 5468 6973 2069 7320 6865 786c 2d6d 6f64 This is hexl-mod
158 00000010: 652e 2020 4561 6368 206c 696e 6520 7265 e. Each line re
159 00000020: 7072 6573 656e 7473 2031 3620 6279 7465 presents 16 byte
160 00000030: 7320 6173 2068 6578 6164 6563 696d 616c s as hexadecimal
161 00000040: 2041 5343 4949 0a61 6e64 2070 7269 6e74 ASCII.and print
162 00000050: 6162 6c65 2041 5343 4949 2063 6861 7261 able ASCII chara
163 00000060: 6374 6572 732e 2020 416e 7920 636f 6e74 cters. Any cont
164 00000070: 726f 6c20 6f72 206e 6f6e 2d41 5343 4949 rol or non-ASCII
71296446 165 00000080: 2063 6861 7261 6374 6572 730a 6172 6520 characters.are
a2535589
JA
166 00000090: 6469 7370 6c61 7965 6420 6173 2070 6572 displayed as per
167 000000a0: 696f 6473 2069 6e20 7468 6520 7072 696e iods in the prin
71296446 168 000000b0: 7461 626c 6520 6368 6172 6163 7465 7220 table character
a2535589
JA
169 000000c0: 7265 6769 6f6e 2e0a region..
170
171Movement is as simple as movement in a normal emacs text buffer. Most
172cursor movement bindings are the same (ie. Use \\[hexl-backward-char], \\[hexl-forward-char], \\[hexl-next-line], and \\[hexl-previous-line]
173to move the cursor left, right, down, and up).
174
175Advanced cursor movement commands (ala \\[hexl-beginning-of-line], \\[hexl-end-of-line], \\[hexl-beginning-of-buffer], and \\[hexl-end-of-buffer]) are
176also supported.
177
178There are several ways to change text in hexl mode:
179
180ASCII characters (character between space (0x20) and tilde (0x7E)) are
181bound to self-insert so you can simply type the character and it will
182insert itself (actually overstrike) into the buffer.
183
184\\[hexl-quoted-insert] followed by another keystroke allows you to insert the key even if
185it isn't bound to self-insert. An octal number can be supplied in place
186of another key to insert the octal number's ASCII representation.
187
188\\[hexl-insert-hex-char] will insert a given hexadecimal value (if it is between 0 and 0xFF)
189into the buffer at the current point.
190
191\\[hexl-insert-octal-char] will insert a given octal value (if it is between 0 and 0377)
192into the buffer at the current point.
193
194\\[hexl-insert-decimal-char] will insert a given decimal value (if it is between 0 and 255)
195into the buffer at the current point.
196
a2535589
JA
197\\[hexl-mode-exit] will exit hexl-mode.
198
31c75fa7
RS
199Note: saving the file with any of the usual Emacs commands
200will actually convert it back to binary format while saving.
a2535589 201
330bd7c3 202You can use \\[hexl-find-file] to visit a file in Hexl mode.
a2535589
JA
203
204\\[describe-bindings] for advanced commands."
205 (interactive "p")
330bd7c3 206 (unless (eq major-mode 'hexl-mode)
753c1309
RS
207 (let ((modified (buffer-modified-p))
208 (inhibit-read-only t)
87b3b78a 209 (original-point (- (point) (point-min)))
753c1309
RS
210 max-address)
211 (and (eobp) (not (bobp))
212 (setq original-point (1- original-point)))
213 (if (not (or (eq arg 1) (not arg)))
214 ;; if no argument then we guess at hexl-max-address
215 (setq max-address (+ (* (/ (1- (buffer-size)) 68) 16) 15))
216 (setq max-address (1- (buffer-size)))
7851eb98
EZ
217 ;; If the buffer's EOL type is -dos, we need to account for
218 ;; extra CR characters added when hexlify-buffer writes the
219 ;; buffer to a file.
220 (when (eq (coding-system-eol-type buffer-file-coding-system) 1)
221 (setq max-address (+ (count-lines (point-min) (point-max))
222 max-address))
223 ;; But if there's no newline at the last line, we are off by
224 ;; one; adjust.
225 (or (eq (char-before (point-max)) ?\n)
226 (setq max-address (1- max-address)))
227 (setq original-point (+ (count-lines (point-min) (point))
228 original-point))
229 (or (bolp) (setq original-point (1- original-point))))
753c1309
RS
230 (hexlify-buffer)
231 (set-buffer-modified-p modified))
232 (make-local-variable 'hexl-max-address)
233 (setq hexl-max-address max-address)
55391f5e
RS
234 (condition-case nil
235 (hexl-goto-address original-point)
236 (error nil)))
753c1309 237
0e4889b2
RS
238 ;; We do not turn off the old major mode; instead we just
239 ;; override most of it. That way, we can restore it perfectly.
a2535589
JA
240 (make-local-variable 'hexl-mode-old-local-map)
241 (setq hexl-mode-old-local-map (current-local-map))
242 (use-local-map hexl-mode-map)
243
244 (make-local-variable 'hexl-mode-old-mode-name)
245 (setq hexl-mode-old-mode-name mode-name)
246 (setq mode-name "Hexl")
247
87b3b78a
SM
248 (set (make-local-variable 'hexl-mode-old-isearch-search-fun-function)
249 isearch-search-fun-function)
250 (set (make-local-variable 'isearch-search-fun-function)
251 'hexl-isearch-search-function)
252
a2535589
JA
253 (make-local-variable 'hexl-mode-old-major-mode)
254 (setq hexl-mode-old-major-mode major-mode)
255 (setq major-mode 'hexl-mode)
256
b27ce24f
RS
257 (make-local-variable 'hexl-mode-old-ruler-mode)
258 (setq hexl-mode-old-ruler-mode
259 (and (boundp 'ruler-mode) ruler-mode))
260
261 (make-local-variable 'hexl-mode-old-hl-line-mode)
262 (setq hexl-mode-old-hl-line-mode
263 (and (boundp 'hl-line-mode) hl-line-mode))
264
0e4889b2
RS
265 (make-local-variable 'hexl-mode-old-syntax-table)
266 (setq hexl-mode-old-syntax-table (syntax-table))
267 (set-syntax-table (standard-syntax-table))
268
87b3b78a 269 (add-hook 'write-contents-functions 'hexl-save-buffer nil t)
31c75fa7 270
0e4889b2
RS
271 (make-local-variable 'hexl-mode-old-require-final-newline)
272 (setq hexl-mode-old-require-final-newline require-final-newline)
273 (make-local-variable 'require-final-newline)
274 (setq require-final-newline nil)
275
639b8e4d
MY
276 (make-local-variable 'hexl-mode-old-font-lock-keywords)
277 (setq hexl-mode-old-font-lock-keywords font-lock-defaults)
278 (make-local-variable 'font-lock-defaults)
279 (setq font-lock-defaults '(hexl-font-lock-keywords t))
280
0e4889b2 281 ;; Add hooks to rehexlify or dehexlify on various events.
c3de2bf0
RS
282 (add-hook 'after-revert-hook 'hexl-after-revert-hook nil t)
283
db6c5b92
SE
284 (add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
285
01ff9136 286 ;; Set a callback function for eldoc.
881e0a3c 287 (set (make-local-variable 'eldoc-documentation-function)
01ff9136
MY
288 'hexl-print-current-point-info)
289 (eldoc-add-command-completions "hexl-")
290 (eldoc-remove-command "hexl-save-buffer"
291 "hexl-current-address")
292
db6c5b92 293 (if hexl-follow-ascii (hexl-follow-ascii 1)))
36555efc 294 (run-mode-hooks 'hexl-mode-hook))
a2535589 295
87b3b78a
SM
296
297(defun hexl-isearch-search-function ()
298 (if (and (not isearch-regexp) (not isearch-word))
299 (lambda (string &optional bound noerror count)
300 (funcall
301 (if isearch-forward 're-search-forward 're-search-backward)
302 (if (> (length string) 80)
303 (regexp-quote string)
304 (mapconcat 'string string "\\(?:\n\\(?:[:a-f0-9]+ \\)+ \\)?"))
305 bound noerror count))
306 (let ((isearch-search-fun-function nil))
307 (isearch-search-fun))))
308
c3de2bf0 309(defun hexl-after-revert-hook ()
059c2e18 310 (setq hexl-max-address (1- (buffer-size)))
c3de2bf0
RS
311 (hexlify-buffer)
312 (set-buffer-modified-p nil))
313
ac2e902d
JB
314(defvar hexl-in-save-buffer nil)
315
a2535589
JA
316(defun hexl-save-buffer ()
317 "Save a hexl format buffer as binary in visited file if modified."
318 (interactive)
ac2e902d
JB
319 (if hexl-in-save-buffer nil
320 (set-buffer-modified-p (if (buffer-modified-p)
321 (save-excursion
322 (let ((buf (generate-new-buffer " hexl"))
323 (name (buffer-name))
324 (file-name (buffer-file-name))
325 (start (point-min))
326 (end (point-max))
327 modified)
328 (set-buffer buf)
329 (insert-buffer-substring name start end)
330 (set-buffer name)
331 (dehexlify-buffer)
332 ;; Prevent infinite recursion.
338992a5 333 (let ((hexl-in-save-buffer t))
ac2e902d
JB
334 (save-buffer))
335 (setq modified (buffer-modified-p))
336 (delete-region (point-min) (point-max))
337 (insert-buffer-substring buf start end)
338 (kill-buffer buf)
339 modified))
340 (message "(No changes need to be saved)")
341 nil))
342 ;; Return t to indicate we have saved t
343 t))
a2535589 344
31c75fa7 345;;;###autoload
a2535589
JA
346(defun hexl-find-file (filename)
347 "Edit file FILENAME in hexl-mode.
a2535589 348Switch to a buffer visiting file FILENAME, creating one in none exists."
e49a45ad
MB
349 (interactive
350 (list
351 (let ((completion-ignored-extensions nil))
352 (read-file-name "Filename: " nil nil 'ret-must-match))))
3db6aff6 353 ;; Ignore the user's setting of default-major-mode.
45e8e6e7 354 (let ((default-major-mode 'fundamental-mode))
3db6aff6 355 (find-file-literally filename))
a2535589
JA
356 (if (not (eq major-mode 'hexl-mode))
357 (hexl-mode)))
358
359(defun hexl-mode-exit (&optional arg)
31c75fa7 360 "Exit Hexl mode, returning to previous mode.
a2535589
JA
361With arg, don't unhexlify buffer."
362 (interactive "p")
363 (if (or (eq arg 1) (not arg))
364 (let ((modified (buffer-modified-p))
900014dd 365 (inhibit-read-only t)
a2535589 366 (original-point (1+ (hexl-current-address))))
a2535589 367 (dehexlify-buffer)
87b3b78a 368 (remove-hook 'write-contents-functions 'hexl-save-buffer t)
a2535589 369 (set-buffer-modified-p modified)
7851eb98
EZ
370 (goto-char original-point)
371 ;; Maybe adjust point for the removed CR characters.
372 (when (eq (coding-system-eol-type buffer-file-coding-system) 1)
373 (setq original-point (- original-point
374 (count-lines (point-min) (point))))
375 (or (bobp) (setq original-point (1+ original-point))))
a2535589 376 (goto-char original-point)))
0e4889b2
RS
377
378 (remove-hook 'after-revert-hook 'hexl-after-revert-hook t)
379 (remove-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer t)
8e7df2e6
SE
380 (remove-hook 'post-command-hook 'hexl-follow-ascii-find t)
381 (setq hexl-ascii-overlay nil)
0e4889b2 382
b27ce24f
RS
383 (if (and (boundp 'ruler-mode) ruler-mode (not hexl-mode-old-ruler-mode))
384 (ruler-mode 0))
385 (if (and (boundp 'hl-line-mode) hl-line-mode (not hexl-mode-old-hl-line-mode))
386 (hl-line-mode 0))
0e4889b2 387 (setq require-final-newline hexl-mode-old-require-final-newline)
a2535589 388 (setq mode-name hexl-mode-old-mode-name)
87b3b78a 389 (setq isearch-search-fun-function hexl-mode-old-isearch-search-fun-function)
a2535589 390 (use-local-map hexl-mode-old-local-map)
0e4889b2 391 (set-syntax-table hexl-mode-old-syntax-table)
639b8e4d 392 (setq font-lock-defaults hexl-mode-old-font-lock-keywords)
a2535589 393 (setq major-mode hexl-mode-old-major-mode)
8eeac2ce
RS
394 (force-mode-line-update))
395
396(defun hexl-maybe-dehexlify-buffer ()
397 "Convert a hexl format buffer to binary.
398Ask the user for confirmation."
399 (if (y-or-n-p "Convert contents back to binary format? ")
400 (let ((modified (buffer-modified-p))
401 (inhibit-read-only t)
402 (original-point (1+ (hexl-current-address))))
403 (dehexlify-buffer)
87b3b78a 404 (remove-hook 'write-contents-functions 'hexl-save-buffer t)
8eeac2ce
RS
405 (set-buffer-modified-p modified)
406 (goto-char original-point))))
a2535589 407
6bbb008e 408(defun hexl-current-address (&optional validate)
a2535589
JA
409 "Return current hexl-address."
410 (interactive)
87b3b78a 411 (let ((current-column (- (% (- (point) (point-min) -1) 68) 11))
a2535589 412 (hexl-address 0))
6bbb008e
RS
413 (if (< current-column 0)
414 (if validate
415 (error "Point is not on a character in the file")
416 (setq current-column 0)))
417 (setq hexl-address
87b3b78a 418 (+ (* (/ (- (point) (point-min) -1) 68) 16)
6bbb008e
RS
419 (if (>= current-column 41)
420 (- current-column 41)
421 (/ (- current-column (/ current-column 5)) 2))))
48f56596 422 (when (interactive-p)
01ff9136 423 (message "Current address is %d/0x%08x" hexl-address hexl-address))
a2535589
JA
424 hexl-address))
425
01ff9136
MY
426(defun hexl-print-current-point-info ()
427 "Return current hexl-address in string.
428This function is indented to be used as eldoc callback."
429 (let ((addr (hexl-current-address)))
430 (format "Current address is %d/0x%08x" addr addr)))
431
a2535589 432(defun hexl-address-to-marker (address)
059c2e18 433 "Return buffer position for ADDRESS."
a2535589 434 (interactive "nAddress: ")
87b3b78a 435 (+ (* (/ address 16) 68) 10 (point-min) (/ (* (% address 16) 5) 2)))
a2535589
JA
436
437(defun hexl-goto-address (address)
438 "Goto hexl-mode (decimal) address ADDRESS.
a2535589
JA
439Signal error if ADDRESS out of range."
440 (interactive "nAddress: ")
441 (if (or (< address 0) (> address hexl-max-address))
55391f5e 442 (error "Out of hexl region"))
a2535589
JA
443 (goto-char (hexl-address-to-marker address)))
444
445(defun hexl-goto-hex-address (hex-address)
4c8c7ae9 446 "Go to hexl-mode address (hex string) HEX-ADDRESS.
a2535589
JA
447Signal error if HEX-ADDRESS is out of range."
448 (interactive "sHex Address: ")
449 (hexl-goto-address (hexl-hex-string-to-integer hex-address)))
450
451(defun hexl-hex-string-to-integer (hex-string)
452 "Return decimal integer for HEX-STRING."
453 (interactive "sHex number: ")
454 (let ((hex-num 0))
455 (while (not (equal hex-string ""))
456 (setq hex-num (+ (* hex-num 16)
457 (hexl-hex-char-to-integer (string-to-char hex-string))))
458 (setq hex-string (substring hex-string 1)))
459 hex-num))
460
461(defun hexl-octal-string-to-integer (octal-string)
462 "Return decimal integer for OCTAL-STRING."
463 (interactive "sOctal number: ")
464 (let ((oct-num 0))
465 (while (not (equal octal-string ""))
466 (setq oct-num (+ (* oct-num 8)
467 (hexl-oct-char-to-integer
468 (string-to-char octal-string))))
469 (setq octal-string (substring octal-string 1)))
470 oct-num))
471
472;; move point functions
473
474(defun hexl-backward-char (arg)
475 "Move to left ARG bytes (right if ARG negative) in hexl-mode."
476 (interactive "p")
477 (hexl-goto-address (- (hexl-current-address) arg)))
478
479(defun hexl-forward-char (arg)
480 "Move right ARG bytes (left if ARG negative) in hexl-mode."
481 (interactive "p")
482 (hexl-goto-address (+ (hexl-current-address) arg)))
483
484(defun hexl-backward-short (arg)
485 "Move to left ARG shorts (right if ARG negative) in hexl-mode."
486 (interactive "p")
487 (hexl-goto-address (let ((address (hexl-current-address)))
488 (if (< arg 0)
489 (progn
490 (setq arg (- arg))
491 (while (> arg 0)
492 (if (not (equal address (logior address 3)))
493 (if (> address hexl-max-address)
494 (progn
495 (message "End of buffer.")
496 (setq address hexl-max-address))
497 (setq address (logior address 3)))
498 (if (> address hexl-max-address)
499 (progn
500 (message "End of buffer.")
501 (setq address hexl-max-address))
502 (setq address (+ address 4))))
503 (setq arg (1- arg)))
504 (if (> address hexl-max-address)
505 (progn
506 (message "End of buffer.")
507 (setq address hexl-max-address))
508 (setq address (logior address 3))))
509 (while (> arg 0)
510 (if (not (equal address (logand address -4)))
511 (setq address (logand address -4))
512 (if (not (equal address 0))
513 (setq address (- address 4))
514 (message "Beginning of buffer.")))
515 (setq arg (1- arg))))
516 address)))
517
518(defun hexl-forward-short (arg)
519 "Move right ARG shorts (left if ARG negative) in hexl-mode."
520 (interactive "p")
521 (hexl-backward-short (- arg)))
522
523(defun hexl-backward-word (arg)
524 "Move to left ARG words (right if ARG negative) in hexl-mode."
525 (interactive "p")
526 (hexl-goto-address (let ((address (hexl-current-address)))
527 (if (< arg 0)
528 (progn
529 (setq arg (- arg))
530 (while (> arg 0)
531 (if (not (equal address (logior address 7)))
532 (if (> address hexl-max-address)
533 (progn
534 (message "End of buffer.")
535 (setq address hexl-max-address))
536 (setq address (logior address 7)))
537 (if (> address hexl-max-address)
538 (progn
539 (message "End of buffer.")
540 (setq address hexl-max-address))
541 (setq address (+ address 8))))
542 (setq arg (1- arg)))
543 (if (> address hexl-max-address)
544 (progn
545 (message "End of buffer.")
546 (setq address hexl-max-address))
547 (setq address (logior address 7))))
548 (while (> arg 0)
549 (if (not (equal address (logand address -8)))
550 (setq address (logand address -8))
551 (if (not (equal address 0))
552 (setq address (- address 8))
553 (message "Beginning of buffer.")))
554 (setq arg (1- arg))))
555 address)))
556
557(defun hexl-forward-word (arg)
558 "Move right ARG words (left if ARG negative) in hexl-mode."
559 (interactive "p")
560 (hexl-backward-word (- arg)))
561
562(defun hexl-previous-line (arg)
4c8c7ae9
JB
563 "Move vertically up ARG lines [16 bytes] (down if ARG negative) in hexl-mode.
564If there is byte at the target address move to the last byte in that line."
a2535589
JA
565 (interactive "p")
566 (hexl-next-line (- arg)))
567
568(defun hexl-next-line (arg)
4c8c7ae9
JB
569 "Move vertically down ARG lines [16 bytes] (up if ARG negative) in hexl-mode.
570If there is no byte at the target address move to the last byte in that line."
a2535589 571 (interactive "p")
e8a57935 572 (hexl-goto-address (let ((address (+ (hexl-current-address) (* arg 16))))
a2535589
JA
573 (if (and (< arg 0) (< address 0))
574 (progn (message "Out of hexl region.")
575 (setq address
576 (% (hexl-current-address) 16)))
577 (if (and (> address hexl-max-address)
578 (< (% hexl-max-address 16) (% address 16)))
579 (setq address hexl-max-address)
580 (if (> address hexl-max-address)
581 (progn (message "Out of hexl region.")
582 (setq
583 address
584 (+ (logand hexl-max-address -16)
585 (% (hexl-current-address) 16)))))))
586 address)))
587
588(defun hexl-beginning-of-buffer (arg)
4c8c7ae9
JB
589 "Move to the beginning of the hexl buffer.
590Leaves `hexl-mark' at previous position.
591With prefix arg N, puts point N bytes of the way from the true beginning."
a2535589
JA
592 (interactive "p")
593 (push-mark (point))
594 (hexl-goto-address (+ 0 (1- arg))))
595
596(defun hexl-end-of-buffer (arg)
4c8c7ae9 597 "Go to `hexl-max-address' minus ARG."
a2535589
JA
598 (interactive "p")
599 (push-mark (point))
600 (hexl-goto-address (- hexl-max-address (1- arg))))
601
602(defun hexl-beginning-of-line ()
603 "Goto beginning of line in hexl mode."
604 (interactive)
605 (goto-char (+ (* (/ (point) 68) 68) 11)))
606
607(defun hexl-end-of-line ()
608 "Goto end of line in hexl mode."
609 (interactive)
610 (hexl-goto-address (let ((address (logior (hexl-current-address) 15)))
611 (if (> address hexl-max-address)
612 (setq address hexl-max-address))
613 address)))
614
615(defun hexl-scroll-down (arg)
616 "Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
617 (interactive "P")
618 (if (null arg)
619 (setq arg (1- (window-height)))
620 (setq arg (prefix-numeric-value arg)))
621 (hexl-scroll-up (- arg)))
622
623(defun hexl-scroll-up (arg)
d565f6aa
EZ
624 "Scroll hexl buffer window upward ARG lines; or near full window if no ARG.
625If there's no byte at the target address, move to the first or last line."
a2535589
JA
626 (interactive "P")
627 (if (null arg)
628 (setq arg (1- (window-height)))
629 (setq arg (prefix-numeric-value arg)))
d565f6aa
EZ
630 (let* ((movement (* arg 16))
631 (address (hexl-current-address))
632 (dest (+ address movement)))
633 (cond
634 ;; If possible, try to stay at the same offset from the beginning
635 ;; of the 16-byte group, even if we move to the first or last
636 ;; group.
637 ((and (> dest hexl-max-address)
638 (>= (% hexl-max-address 16) (% address 16)))
639 (setq dest (+ (logand hexl-max-address -16) (% address 16))))
640 ((> dest hexl-max-address)
641 (setq dest hexl-max-address))
642 ((< dest 0)
643 (setq dest (% address 16))))
644 (if (/= dest (+ address movement))
645 (message "Out of hexl region."))
646 (hexl-goto-address dest)
647 (recenter 0)))
a2535589
JA
648
649(defun hexl-beginning-of-1k-page ()
65e5f4bc 650 "Go to beginning of 1k boundary."
a2535589
JA
651 (interactive)
652 (hexl-goto-address (logand (hexl-current-address) -1024)))
653
654(defun hexl-end-of-1k-page ()
65e5f4bc 655 "Go to end of 1k boundary."
a2535589
JA
656 (interactive)
657 (hexl-goto-address (let ((address (logior (hexl-current-address) 1023)))
658 (if (> address hexl-max-address)
659 (setq address hexl-max-address))
660 address)))
661
662(defun hexl-beginning-of-512b-page ()
65e5f4bc 663 "Go to beginning of 512 byte boundary."
a2535589
JA
664 (interactive)
665 (hexl-goto-address (logand (hexl-current-address) -512)))
666
667(defun hexl-end-of-512b-page ()
65e5f4bc 668 "Go to end of 512 byte boundary."
a2535589
JA
669 (interactive)
670 (hexl-goto-address (let ((address (logior (hexl-current-address) 511)))
671 (if (> address hexl-max-address)
672 (setq address hexl-max-address))
673 address)))
674
675(defun hexl-quoted-insert (arg)
676 "Read next input character and insert it.
02aec07b
EZ
677Useful for inserting control characters and non-ASCII characters given their
678numerical code.
679You may also type octal digits, to insert a character with that code."
a2535589 680 (interactive "p")
02aec07b 681 (hexl-insert-multibyte-char (read-quoted-char) arg))
a2535589
JA
682
683;00000000: 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789ABCDEF
684
f4e3d4eb 685;;;###autoload
a2535589 686(defun hexlify-buffer ()
aa3757b8
RS
687 "Convert a binary buffer to hexl format.
688This discards the buffer's undo information."
a2535589 689 (interactive)
aa3757b8
RS
690 (and buffer-undo-list
691 (or (y-or-n-p "Converting to hexl format discards undo info; ok? ")
692 (error "Aborted")))
693 (setq buffer-undo-list nil)
a749e5e5
EZ
694 ;; Don't decode text in the ASCII part of `hexl' program output.
695 (let ((coding-system-for-read 'raw-text)
0716afa2 696 (coding-system-for-write buffer-file-coding-system)
aa3757b8 697 (buffer-undo-list t))
b8c49a19
SM
698 (apply 'call-process-region (point-min) (point-max)
699 (expand-file-name hexl-program exec-directory)
700 t t nil (split-string hexl-options))
059c2e18
PR
701 (if (> (point) (hexl-address-to-marker hexl-max-address))
702 (hexl-goto-address hexl-max-address))))
a2535589
JA
703
704(defun dehexlify-buffer ()
aa3757b8
RS
705 "Convert a hexl format buffer to binary.
706This discards the buffer's undo information."
a2535589 707 (interactive)
aa3757b8
RS
708 (and buffer-undo-list
709 (or (y-or-n-p "Converting from hexl format discards undo info; ok? ")
710 (error "Aborted")))
711 (setq buffer-undo-list nil)
a749e5e5 712 (let ((coding-system-for-write 'raw-text)
0716afa2 713 (coding-system-for-read buffer-file-coding-system)
aa3757b8 714 (buffer-undo-list t))
b8c49a19
SM
715 (apply 'call-process-region (point-min) (point-max)
716 (expand-file-name hexl-program exec-directory)
717 t t nil "-de" (split-string hexl-options))))
a2535589
JA
718
719(defun hexl-char-after-point ()
720 "Return char for ASCII hex digits at point."
686fc9ab
RS
721 (hexl-htoi (char-after (point))
722 (char-after (1+ (point)))))
a2535589
JA
723
724(defun hexl-htoi (lh rh)
725 "Hex (char) LH (char) RH to integer."
726 (+ (* (hexl-hex-char-to-integer lh) 16)
727 (hexl-hex-char-to-integer rh)))
728
729(defun hexl-hex-char-to-integer (character)
730 "Take a char and return its value as if it was a hex digit."
731 (if (and (>= character ?0) (<= character ?9))
732 (- character ?0)
733 (let ((ch (logior character 32)))
734 (if (and (>= ch ?a) (<= ch ?f))
735 (- ch (- ?a 10))
19e31f7c 736 (error "Invalid hex digit `%c'" ch)))))
a2535589
JA
737
738(defun hexl-oct-char-to-integer (character)
739 "Take a char and return its value as if it was a octal digit."
740 (if (and (>= character ?0) (<= character ?7))
741 (- character ?0)
19e31f7c 742 (error "Invalid octal digit `%c'" character)))
a2535589
JA
743
744(defun hexl-printable-character (ch)
745 "Return a displayable string for character CH."
746 (format "%c" (if hexl-iso
747 (if (or (< ch 32) (and (>= ch 127) (< ch 160)))
748 46
749 ch)
750 (if (or (< ch 32) (>= ch 127))
751 46
752 ch))))
753
02aec07b
EZ
754(defun hexl-insert-multibyte-char (ch num)
755 "Insert a possibly multibyte character CH NUM times.
756
757Non-ASCII characters are first encoded with `buffer-file-coding-system',
758and their encoded form is inserted byte by byte."
759 (let ((charset (char-charset ch))
760 (coding (if (or (null buffer-file-coding-system)
761 ;; coding-system-type equals t means undecided.
762 (eq (coding-system-type buffer-file-coding-system) t))
763 default-buffer-file-coding-system
764 buffer-file-coding-system)))
765 (cond ((and (> ch 0) (< ch 256))
766 (hexl-insert-char ch num))
767 ((eq charset 'unknown)
768 (error
165b4283 769 "0x%x -- invalid character code; use \\[hexl-insert-hex-string]"
02aec07b
EZ
770 ch))
771 (t
772 (let ((encoded (encode-coding-char ch coding))
773 (internal (string-as-unibyte (char-to-string ch)))
774 internal-hex)
775 ;; If encode-coding-char returns nil, it means our character
776 ;; cannot be safely encoded with buffer-file-coding-system.
777 ;; In that case, we offer to insert the internal representation
778 ;; of that character, byte by byte.
779 (when (null encoded)
780 (setq internal-hex
781 (mapconcat (function (lambda (c) (format "%x" c)))
782 internal " "))
783 (if (yes-or-no-p
784 (format
785 "Insert char 0x%x's internal representation \"%s\"? "
786 ch internal-hex))
787 (setq encoded internal)
788 (error
165b4283 789 "Can't encode `0x%x' with this buffer's coding system; try \\[hexl-insert-hex-string]"
02aec07b
EZ
790 ch)))
791 (while (> num 0)
792 (mapc
793 (function (lambda (c) (hexl-insert-char c 1))) encoded)
794 (setq num (1- num))))))))
795
a2535589 796(defun hexl-self-insert-command (arg)
02aec07b
EZ
797 "Insert this character.
798Interactively, with a numeric argument, insert this character that many times.
799
800Non-ASCII characters are first encoded with `buffer-file-coding-system',
801and their encoded form is inserted byte by byte."
a2535589 802 (interactive "p")
02aec07b 803 (hexl-insert-multibyte-char last-command-char arg))
a2535589
JA
804
805(defun hexl-insert-char (ch num)
02aec07b
EZ
806 "Insert the character CH NUM times in a hexl buffer.
807
808CH must be a unibyte character whose value is between 0 and 255."
809 (if (or (< ch 0) (> ch 255))
45ad49ba 810 (error "Invalid character 0x%x -- must be in the range [0..255]" ch))
6bbb008e 811 (let ((address (hexl-current-address t)))
a2535589 812 (while (> num 0)
6bbb008e
RS
813 (let ((hex-position
814 (+ (* (/ address 16) 68)
87b3b78a 815 10 (point-min)
6bbb008e
RS
816 (* 2 (% address 16))
817 (/ (% address 16) 2)))
818 (ascii-position
87b3b78a 819 (+ (* (/ address 16) 68) 51 (point-min) (% address 16)))
6bbb008e
RS
820 at-ascii-position)
821 (if (= (point) ascii-position)
822 (setq at-ascii-position t))
823 (goto-char hex-position)
824 (delete-char 2)
825 (insert (format "%02x" ch))
826 (goto-char ascii-position)
827 (delete-char 1)
828 (insert (hexl-printable-character ch))
829 (or (eq address hexl-max-address)
830 (setq address (1+ address)))
831 (hexl-goto-address address)
832 (if at-ascii-position
833 (progn
834 (beginning-of-line)
835 (forward-char 51)
836 (forward-char (% address 16)))))
a2535589
JA
837 (setq num (1- num)))))
838
839;; hex conversion
840
841(defun hexl-insert-hex-char (arg)
02aec07b 842 "Insert a character given by its hexadecimal code ARG times at point."
a2535589
JA
843 (interactive "p")
844 (let ((num (hexl-hex-string-to-integer (read-string "Hex number: "))))
02aec07b 845 (if (< num 0)
19e31f7c 846 (error "Hex number out of range")
02aec07b 847 (hexl-insert-multibyte-char num arg))))
a2535589 848
9f6bff44
GM
849(defun hexl-insert-hex-string (str arg)
850 "Insert hexadecimal string STR at point ARG times.
851Embedded whitespace, dashes, and periods in the string are ignored."
852 (interactive "sHex string: \np")
853 (setq str (replace-regexp-in-string "[- \t.]" "" str))
854 (let ((chars '()))
855 (let ((len (length str))
856 (idx 0))
857 (if (eq (logand len 1) 1)
858 (let ((num (hexl-hex-string-to-integer (substring str 0 1))))
859 (setq chars (cons num chars))
860 (setq idx 1)))
861 (while (< idx len)
862 (let* ((nidx (+ idx 2))
863 (num (hexl-hex-string-to-integer (substring str idx nidx))))
864 (setq chars (cons num chars))
865 (setq idx nidx))))
866 (setq chars (nreverse chars))
867 (while (> arg 0)
868 (let ((chars chars))
869 (while chars
870 (hexl-insert-char (car chars) 1)
871 (setq chars (cdr chars))))
872 (setq arg (- arg 1)))))
873
a2535589 874(defun hexl-insert-decimal-char (arg)
02aec07b 875 "Insert a character given by its decimal code ARG times at point."
a2535589 876 (interactive "p")
027a4b6b 877 (let ((num (string-to-number (read-string "Decimal Number: "))))
02aec07b 878 (if (< num 0)
19e31f7c 879 (error "Decimal number out of range")
02aec07b 880 (hexl-insert-multibyte-char num arg))))
a2535589
JA
881
882(defun hexl-insert-octal-char (arg)
02aec07b 883 "Insert a character given by its octal code ARG times at point."
a2535589
JA
884 (interactive "p")
885 (let ((num (hexl-octal-string-to-integer (read-string "Octal Number: "))))
02aec07b 886 (if (< num 0)
19e31f7c 887 (error "Decimal number out of range")
02aec07b 888 (hexl-insert-multibyte-char num arg))))
a2535589 889
db6c5b92
SE
890(defun hexl-follow-ascii (&optional arg)
891 "Toggle following ASCII in Hexl buffers.
892With prefix ARG, turn on following if and only if ARG is positive.
893When following is enabled, the ASCII character corresponding to the
894element under the point is highlighted.
895Customize the variable `hexl-follow-ascii' to disable this feature."
896 (interactive "P")
71296446 897 (let ((on-p (if arg
db6c5b92
SE
898 (> (prefix-numeric-value arg) 0)
899 (not hexl-ascii-overlay))))
900
db6c5b92
SE
901 (if on-p
902 ;; turn it on
903 (if (not hexl-ascii-overlay)
904 (progn
905 (setq hexl-ascii-overlay (make-overlay 1 1)
906 hexl-follow-ascii t)
907 (overlay-put hexl-ascii-overlay 'face 'highlight)
908 (add-hook 'post-command-hook 'hexl-follow-ascii-find nil t)))
909 ;; turn it off
910 (if hexl-ascii-overlay
911 (progn
912 (delete-overlay hexl-ascii-overlay)
913 (setq hexl-ascii-overlay nil
914 hexl-follow-ascii nil)
915 (remove-hook 'post-command-hook 'hexl-follow-ascii-find t)
916 )))))
917
9fd76d04
MY
918(defun hexl-activate-ruler ()
919 "Activate `ruler-mode'"
920 (require 'ruler-mode)
921 (set (make-local-variable 'ruler-mode-ruler-function)
922 'hexl-mode-ruler)
923 (ruler-mode 1))
924
925(defun hexl-follow-line ()
926 "Activate `hl-line-mode'"
927 (require 'frame)
9fd76d04 928 (require 'hl-line)
9bbe3927
RS
929 (with-no-warnings
930 (set (make-local-variable 'hl-line-range-function)
931 'hexl-highlight-line-range)
932 (set (make-local-variable 'hl-line-face)
933 'highlight))
9fd76d04
MY
934 (hl-line-mode 1))
935
936(defun hexl-highlight-line-range ()
937 "Return the range of address area for the point.
938This function is assumed to be used as call back function for `hl-line-mode'."
939 (cons
940 (line-beginning-position)
941 ;; 9 stands for (length "87654321:")
942 (+ (line-beginning-position) 9)))
943
db6c5b92
SE
944(defun hexl-follow-ascii-find ()
945 "Find and highlight the ASCII element corresponding to current point."
d565f6aa 946 (let ((pos (+ 51
db6c5b92
SE
947 (- (point) (current-column))
948 (mod (hexl-current-address) 16))))
949 (move-overlay hexl-ascii-overlay pos (1+ pos))
950 ))
951
9fd76d04
MY
952(defun hexl-mode-ruler ()
953 "Return a string ruler for hexl mode."
954 (let* ((highlight (mod (hexl-current-address) 16))
4c4ac516
KS
955 (s " 87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef")
956 (pos 0))
9fd76d04
MY
957 (set-text-properties 0 (length s) nil s)
958 ;; Turn spaces in the header into stretch specs so they work
959 ;; regardless of the header-line face.
960 (while (string-match "[ \t]+" s pos)
961 (setq pos (match-end 0))
962 (put-text-property (match-beginning 0) pos 'display
963 ;; Assume fixed-size chars
4c4ac516 964 `(space :align-to ,(1- pos))
9fd76d04
MY
965 s))
966 ;; Highlight the current column.
4c4ac516
KS
967 (put-text-property (+ 11 (/ (* 5 highlight) 2))
968 (+ 13 (/ (* 5 highlight) 2))
9fd76d04
MY
969 'face 'highlight s)
970 ;; Highlight the current ascii column
4c4ac516 971 (put-text-property (+ 13 39 highlight) (+ 13 40 highlight)
9fd76d04 972 'face 'highlight s)
4c4ac516 973 s))
9fd76d04 974
a2535589
JA
975;; startup stuff.
976
977(if hexl-mode-map
978 nil
4b7dd7e2 979 (setq hexl-mode-map (make-keymap))
02aec07b
EZ
980 ;; Make all self-inserting keys go through hexl-self-insert-command,
981 ;; because we need to convert them to unibyte characters before
982 ;; inserting them into the buffer.
340c4d85 983 (define-key hexl-mode-map [remap self-insert-command] 'hexl-self-insert-command)
ae2d451b 984
d9c8518d 985 (define-key hexl-mode-map "\C-m" 'hexl-self-insert-command)
ae2d451b
RS
986 (define-key hexl-mode-map [left] 'hexl-backward-char)
987 (define-key hexl-mode-map [right] 'hexl-forward-char)
988 (define-key hexl-mode-map [up] 'hexl-previous-line)
989 (define-key hexl-mode-map [down] 'hexl-next-line)
990 (define-key hexl-mode-map [M-left] 'hexl-backward-short)
480c8cd3 991 (define-key hexl-mode-map [?\e left] 'hexl-backward-short)
ae2d451b 992 (define-key hexl-mode-map [M-right] 'hexl-forward-short)
480c8cd3 993 (define-key hexl-mode-map [?\e right] 'hexl-forward-short)
ae2d451b
RS
994 (define-key hexl-mode-map [next] 'hexl-scroll-up)
995 (define-key hexl-mode-map [prior] 'hexl-scroll-down)
d565f6aa
EZ
996 (define-key hexl-mode-map [home] 'hexl-beginning-of-line)
997 (define-key hexl-mode-map [end] 'hexl-end-of-line)
998 (define-key hexl-mode-map [C-home] 'hexl-beginning-of-buffer)
999 (define-key hexl-mode-map [C-end] 'hexl-end-of-buffer)
ae2d451b
RS
1000 (define-key hexl-mode-map [deletechar] 'undefined)
1001 (define-key hexl-mode-map [deleteline] 'undefined)
1002 (define-key hexl-mode-map [insertline] 'undefined)
1003 (define-key hexl-mode-map [S-delete] 'undefined)
1004 (define-key hexl-mode-map "\177" 'undefined)
1005
1006 (define-key hexl-mode-map "\C-a" 'hexl-beginning-of-line)
1007 (define-key hexl-mode-map "\C-b" 'hexl-backward-char)
1008 (define-key hexl-mode-map "\C-d" 'undefined)
1009 (define-key hexl-mode-map "\C-e" 'hexl-end-of-line)
1010 (define-key hexl-mode-map "\C-f" 'hexl-forward-char)
1011
1012 (if (not (eq (key-binding (char-to-string help-char)) 'help-command))
1013 (define-key hexl-mode-map (char-to-string help-char) 'undefined))
1014
ae2d451b 1015 (define-key hexl-mode-map "\C-k" 'undefined)
ae2d451b
RS
1016 (define-key hexl-mode-map "\C-n" 'hexl-next-line)
1017 (define-key hexl-mode-map "\C-o" 'undefined)
1018 (define-key hexl-mode-map "\C-p" 'hexl-previous-line)
1019 (define-key hexl-mode-map "\C-q" 'hexl-quoted-insert)
1020 (define-key hexl-mode-map "\C-t" 'undefined)
1021 (define-key hexl-mode-map "\C-v" 'hexl-scroll-up)
1022 (define-key hexl-mode-map "\C-w" 'undefined)
1023 (define-key hexl-mode-map "\C-y" 'undefined)
1024
02aec07b
EZ
1025 (fset 'hexl-ESC-prefix (copy-keymap 'ESC-prefix))
1026 (define-key hexl-mode-map "\e" 'hexl-ESC-prefix)
ae2d451b
RS
1027 (define-key hexl-mode-map "\e\C-a" 'hexl-beginning-of-512b-page)
1028 (define-key hexl-mode-map "\e\C-b" 'hexl-backward-short)
ae2d451b
RS
1029 (define-key hexl-mode-map "\e\C-d" 'hexl-insert-decimal-char)
1030 (define-key hexl-mode-map "\e\C-e" 'hexl-end-of-512b-page)
1031 (define-key hexl-mode-map "\e\C-f" 'hexl-forward-short)
ae2d451b
RS
1032 (define-key hexl-mode-map "\e\C-i" 'undefined)
1033 (define-key hexl-mode-map "\e\C-j" 'undefined)
1034 (define-key hexl-mode-map "\e\C-k" 'undefined)
ae2d451b 1035 (define-key hexl-mode-map "\e\C-o" 'hexl-insert-octal-char)
ae2d451b 1036 (define-key hexl-mode-map "\e\C-q" 'undefined)
ae2d451b 1037 (define-key hexl-mode-map "\e\C-t" 'undefined)
ae2d451b 1038 (define-key hexl-mode-map "\e\C-x" 'hexl-insert-hex-char)
ae2d451b
RS
1039 (define-key hexl-mode-map "\eb" 'hexl-backward-word)
1040 (define-key hexl-mode-map "\ec" 'undefined)
1041 (define-key hexl-mode-map "\ed" 'undefined)
ae2d451b
RS
1042 (define-key hexl-mode-map "\ef" 'hexl-forward-word)
1043 (define-key hexl-mode-map "\eg" 'hexl-goto-hex-address)
ae2d451b
RS
1044 (define-key hexl-mode-map "\ei" 'undefined)
1045 (define-key hexl-mode-map "\ej" 'hexl-goto-address)
1046 (define-key hexl-mode-map "\ek" 'undefined)
1047 (define-key hexl-mode-map "\el" 'undefined)
ae2d451b 1048 (define-key hexl-mode-map "\eq" 'undefined)
ae2d451b
RS
1049 (define-key hexl-mode-map "\es" 'undefined)
1050 (define-key hexl-mode-map "\et" 'undefined)
1051 (define-key hexl-mode-map "\eu" 'undefined)
1052 (define-key hexl-mode-map "\ev" 'hexl-scroll-down)
1053 (define-key hexl-mode-map "\ey" 'undefined)
1054 (define-key hexl-mode-map "\ez" 'undefined)
1055 (define-key hexl-mode-map "\e<" 'hexl-beginning-of-buffer)
1056 (define-key hexl-mode-map "\e>" 'hexl-end-of-buffer)
1057
02aec07b
EZ
1058 (fset 'hexl-C-c-prefix (copy-keymap mode-specific-map))
1059 (define-key hexl-mode-map "\C-c" 'hexl-C-c-prefix)
ae2d451b
RS
1060 (define-key hexl-mode-map "\C-c\C-c" 'hexl-mode-exit)
1061
02aec07b
EZ
1062 (fset 'hexl-C-x-prefix (copy-keymap 'Control-X-prefix))
1063 (define-key hexl-mode-map "\C-x" 'hexl-C-x-prefix)
ae2d451b
RS
1064 (define-key hexl-mode-map "\C-x[" 'hexl-beginning-of-1k-page)
1065 (define-key hexl-mode-map "\C-x]" 'hexl-end-of-1k-page)
1066 (define-key hexl-mode-map "\C-x\C-p" 'undefined)
1067 (define-key hexl-mode-map "\C-x\C-s" 'hexl-save-buffer)
1068 (define-key hexl-mode-map "\C-x\C-t" 'undefined))
a2535589 1069
19e31f7c
RS
1070(provide 'hexl)
1071
ab5796a9 1072;;; arch-tag: d5a7aa8a-9bce-480b-bcff-6c4c7ca5ea4a
1a06eabd 1073;;; hexl.el ends here