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