1 |
;;; hexl.el --- edit a file in a hex dump format using the hexl filter |
;;; hexl.el --- edit a file in a hex dump format using the hexl filter |
2 |
|
|
3 |
;; Copyright (C) 1989, 1994, 1998, 2001 Free Software Foundation, Inc. |
;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. |
4 |
|
|
5 |
;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu> |
;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu> |
6 |
;; Maintainer: FSF |
;; Maintainer: FSF |
84 |
(defvar hexl-mode-old-local-map) |
(defvar hexl-mode-old-local-map) |
85 |
(defvar hexl-mode-old-mode-name) |
(defvar hexl-mode-old-mode-name) |
86 |
(defvar hexl-mode-old-major-mode) |
(defvar hexl-mode-old-major-mode) |
87 |
(defvar hexl-mode-old-write-contents-hooks) |
(defvar hexl-mode-old-isearch-search-fun-function) |
88 |
(defvar hexl-mode-old-require-final-newline) |
(defvar hexl-mode-old-require-final-newline) |
89 |
(defvar hexl-mode-old-syntax-table) |
(defvar hexl-mode-old-syntax-table) |
90 |
|
|
100 |
(defun hexl-mode (&optional arg) |
(defun hexl-mode (&optional arg) |
101 |
"\\<hexl-mode-map>A mode for editing binary files in hex dump format. |
"\\<hexl-mode-map>A mode for editing binary files in hex dump format. |
102 |
This is not an ordinary major mode; it alters some aspects |
This is not an ordinary major mode; it alters some aspects |
103 |
if the current mode's behavior, but not all; also, you can exit |
of the current mode's behavior, but not all; also, you can exit |
104 |
Hexl mode and return to the previous mode using `hexl-mode-exit'. |
Hexl mode and return to the previous mode using `hexl-mode-exit'. |
105 |
|
|
106 |
This function automatically converts a buffer into the hexl format |
This function automatically converts a buffer into the hexl format |
130 |
00000050: 6162 6c65 2041 5343 4949 2063 6861 7261 able ASCII chara |
00000050: 6162 6c65 2041 5343 4949 2063 6861 7261 able ASCII chara |
131 |
00000060: 6374 6572 732e 2020 416e 7920 636f 6e74 cters. Any cont |
00000060: 6374 6572 732e 2020 416e 7920 636f 6e74 cters. Any cont |
132 |
00000070: 726f 6c20 6f72 206e 6f6e 2d41 5343 4949 rol or non-ASCII |
00000070: 726f 6c20 6f72 206e 6f6e 2d41 5343 4949 rol or non-ASCII |
133 |
00000080: 2063 6861 7261 6374 6572 730a 6172 6520 characters.are |
00000080: 2063 6861 7261 6374 6572 730a 6172 6520 characters.are |
134 |
00000090: 6469 7370 6c61 7965 6420 6173 2070 6572 displayed as per |
00000090: 6469 7370 6c61 7965 6420 6173 2070 6572 displayed as per |
135 |
000000a0: 696f 6473 2069 6e20 7468 6520 7072 696e iods in the prin |
000000a0: 696f 6473 2069 6e20 7468 6520 7072 696e iods in the prin |
136 |
000000b0: 7461 626c 6520 6368 6172 6163 7465 7220 table character |
000000b0: 7461 626c 6520 6368 6172 6163 7465 7220 table character |
137 |
000000c0: 7265 6769 6f6e 2e0a region.. |
000000c0: 7265 6769 6f6e 2e0a region.. |
138 |
|
|
139 |
Movement is as simple as movement in a normal emacs text buffer. Most |
Movement is as simple as movement in a normal emacs text buffer. Most |
174 |
(unless (eq major-mode 'hexl-mode) |
(unless (eq major-mode 'hexl-mode) |
175 |
(let ((modified (buffer-modified-p)) |
(let ((modified (buffer-modified-p)) |
176 |
(inhibit-read-only t) |
(inhibit-read-only t) |
177 |
(original-point (1- (point))) |
(original-point (- (point) (point-min))) |
178 |
max-address) |
max-address) |
179 |
(and (eobp) (not (bobp)) |
(and (eobp) (not (bobp)) |
180 |
(setq original-point (1- original-point))) |
(setq original-point (1- original-point))) |
211 |
(setq hexl-mode-old-mode-name mode-name) |
(setq hexl-mode-old-mode-name mode-name) |
212 |
(setq mode-name "Hexl") |
(setq mode-name "Hexl") |
213 |
|
|
214 |
|
(set (make-local-variable 'hexl-mode-old-isearch-search-fun-function) |
215 |
|
isearch-search-fun-function) |
216 |
|
(set (make-local-variable 'isearch-search-fun-function) |
217 |
|
'hexl-isearch-search-function) |
218 |
|
|
219 |
(make-local-variable 'hexl-mode-old-major-mode) |
(make-local-variable 'hexl-mode-old-major-mode) |
220 |
(setq hexl-mode-old-major-mode major-mode) |
(setq hexl-mode-old-major-mode major-mode) |
221 |
(setq major-mode 'hexl-mode) |
(setq major-mode 'hexl-mode) |
224 |
(setq hexl-mode-old-syntax-table (syntax-table)) |
(setq hexl-mode-old-syntax-table (syntax-table)) |
225 |
(set-syntax-table (standard-syntax-table)) |
(set-syntax-table (standard-syntax-table)) |
226 |
|
|
227 |
(make-local-variable 'hexl-mode-old-write-contents-hooks) |
(add-hook 'write-contents-functions 'hexl-save-buffer nil t) |
|
(setq hexl-mode-old-write-contents-hooks write-contents-hooks) |
|
|
(make-local-variable 'write-contents-hooks) |
|
|
(add-hook 'write-contents-hooks 'hexl-save-buffer) |
|
228 |
|
|
229 |
(make-local-variable 'hexl-mode-old-require-final-newline) |
(make-local-variable 'hexl-mode-old-require-final-newline) |
230 |
(setq hexl-mode-old-require-final-newline require-final-newline) |
(setq hexl-mode-old-require-final-newline require-final-newline) |
239 |
(if hexl-follow-ascii (hexl-follow-ascii 1))) |
(if hexl-follow-ascii (hexl-follow-ascii 1))) |
240 |
(run-hooks 'hexl-mode-hook)) |
(run-hooks 'hexl-mode-hook)) |
241 |
|
|
242 |
|
|
243 |
|
(defun hexl-isearch-search-function () |
244 |
|
(if (and (not isearch-regexp) (not isearch-word)) |
245 |
|
(lambda (string &optional bound noerror count) |
246 |
|
(funcall |
247 |
|
(if isearch-forward 're-search-forward 're-search-backward) |
248 |
|
(if (> (length string) 80) |
249 |
|
(regexp-quote string) |
250 |
|
(mapconcat 'string string "\\(?:\n\\(?:[:a-f0-9]+ \\)+ \\)?")) |
251 |
|
bound noerror count)) |
252 |
|
(let ((isearch-search-fun-function nil)) |
253 |
|
(isearch-search-fun)))) |
254 |
|
|
255 |
(defun hexl-after-revert-hook () |
(defun hexl-after-revert-hook () |
256 |
(setq hexl-max-address (1- (buffer-size))) |
(setq hexl-max-address (1- (buffer-size))) |
257 |
(hexlify-buffer) |
(hexlify-buffer) |
292 |
(defun hexl-find-file (filename) |
(defun hexl-find-file (filename) |
293 |
"Edit file FILENAME in hexl-mode. |
"Edit file FILENAME in hexl-mode. |
294 |
Switch to a buffer visiting file FILENAME, creating one in none exists." |
Switch to a buffer visiting file FILENAME, creating one in none exists." |
295 |
(interactive "fFilename: ") |
(interactive |
296 |
(find-file-literally filename) |
(list |
297 |
|
(let ((completion-ignored-extensions nil)) |
298 |
|
(read-file-name "Filename: " nil nil 'ret-must-match)))) |
299 |
|
;; Ignore the user's setting of default-major-mode. |
300 |
|
(let ((default-major-mode 'hexl-mode)) |
301 |
|
(find-file-literally filename)) |
302 |
(if (not (eq major-mode 'hexl-mode)) |
(if (not (eq major-mode 'hexl-mode)) |
303 |
(hexl-mode))) |
(hexl-mode))) |
304 |
|
|
311 |
(inhibit-read-only t) |
(inhibit-read-only t) |
312 |
(original-point (1+ (hexl-current-address)))) |
(original-point (1+ (hexl-current-address)))) |
313 |
(dehexlify-buffer) |
(dehexlify-buffer) |
314 |
(remove-hook 'write-contents-hooks 'hexl-save-buffer) |
(remove-hook 'write-contents-functions 'hexl-save-buffer t) |
315 |
(set-buffer-modified-p modified) |
(set-buffer-modified-p modified) |
316 |
(goto-char original-point) |
(goto-char original-point) |
317 |
;; Maybe adjust point for the removed CR characters. |
;; Maybe adjust point for the removed CR characters. |
326 |
(remove-hook 'post-command-hook 'hexl-follow-ascii-find t) |
(remove-hook 'post-command-hook 'hexl-follow-ascii-find t) |
327 |
(setq hexl-ascii-overlay nil) |
(setq hexl-ascii-overlay nil) |
328 |
|
|
|
(setq write-contents-hooks hexl-mode-old-write-contents-hooks) |
|
329 |
(setq require-final-newline hexl-mode-old-require-final-newline) |
(setq require-final-newline hexl-mode-old-require-final-newline) |
330 |
(setq mode-name hexl-mode-old-mode-name) |
(setq mode-name hexl-mode-old-mode-name) |
331 |
|
(setq isearch-search-fun-function hexl-mode-old-isearch-search-fun-function) |
332 |
(use-local-map hexl-mode-old-local-map) |
(use-local-map hexl-mode-old-local-map) |
333 |
(set-syntax-table hexl-mode-old-syntax-table) |
(set-syntax-table hexl-mode-old-syntax-table) |
334 |
(setq major-mode hexl-mode-old-major-mode) |
(setq major-mode hexl-mode-old-major-mode) |
342 |
(inhibit-read-only t) |
(inhibit-read-only t) |
343 |
(original-point (1+ (hexl-current-address)))) |
(original-point (1+ (hexl-current-address)))) |
344 |
(dehexlify-buffer) |
(dehexlify-buffer) |
345 |
(remove-hook 'write-contents-hooks 'hexl-save-buffer) |
(remove-hook 'write-contents-functions 'hexl-save-buffer t) |
346 |
(set-buffer-modified-p modified) |
(set-buffer-modified-p modified) |
347 |
(goto-char original-point)))) |
(goto-char original-point)))) |
348 |
|
|
349 |
(defun hexl-current-address (&optional validate) |
(defun hexl-current-address (&optional validate) |
350 |
"Return current hexl-address." |
"Return current hexl-address." |
351 |
(interactive) |
(interactive) |
352 |
(let ((current-column (- (% (point) 68) 11)) |
(let ((current-column (- (% (- (point) (point-min) -1) 68) 11)) |
353 |
(hexl-address 0)) |
(hexl-address 0)) |
354 |
(if (< current-column 0) |
(if (< current-column 0) |
355 |
(if validate |
(if validate |
356 |
(error "Point is not on a character in the file") |
(error "Point is not on a character in the file") |
357 |
(setq current-column 0))) |
(setq current-column 0))) |
358 |
(setq hexl-address |
(setq hexl-address |
359 |
(+ (* (/ (point) 68) 16) |
(+ (* (/ (- (point) (point-min) -1) 68) 16) |
360 |
(if (>= current-column 41) |
(if (>= current-column 41) |
361 |
(- current-column 41) |
(- current-column 41) |
362 |
(/ (- current-column (/ current-column 5)) 2)))) |
(/ (- current-column (/ current-column 5)) 2)))) |
367 |
(defun hexl-address-to-marker (address) |
(defun hexl-address-to-marker (address) |
368 |
"Return buffer position for ADDRESS." |
"Return buffer position for ADDRESS." |
369 |
(interactive "nAddress: ") |
(interactive "nAddress: ") |
370 |
(+ (* (/ address 16) 68) 11 (/ (* (% address 16) 5) 2))) |
(+ (* (/ address 16) 68) 10 (point-min) (/ (* (% address 16) 5) 2))) |
371 |
|
|
372 |
(defun hexl-goto-address (address) |
(defun hexl-goto-address (address) |
373 |
"Goto hexl-mode (decimal) address ADDRESS. |
"Goto hexl-mode (decimal) address ADDRESS. |
747 |
(while (> num 0) |
(while (> num 0) |
748 |
(let ((hex-position |
(let ((hex-position |
749 |
(+ (* (/ address 16) 68) |
(+ (* (/ address 16) 68) |
750 |
11 |
10 (point-min) |
751 |
(* 2 (% address 16)) |
(* 2 (% address 16)) |
752 |
(/ (% address 16) 2))) |
(/ (% address 16) 2))) |
753 |
(ascii-position |
(ascii-position |
754 |
(+ (* (/ address 16) 68) 52 (% address 16))) |
(+ (* (/ address 16) 68) 51 (point-min) (% address 16))) |
755 |
at-ascii-position) |
at-ascii-position) |
756 |
(if (= (point) ascii-position) |
(if (= (point) ascii-position) |
757 |
(setq at-ascii-position t)) |
(setq at-ascii-position t)) |
829 |
element under the point is highlighted. |
element under the point is highlighted. |
830 |
Customize the variable `hexl-follow-ascii' to disable this feature." |
Customize the variable `hexl-follow-ascii' to disable this feature." |
831 |
(interactive "P") |
(interactive "P") |
832 |
(let ((on-p (if arg |
(let ((on-p (if arg |
833 |
(> (prefix-numeric-value arg) 0) |
(> (prefix-numeric-value arg) 0) |
834 |
(not hexl-ascii-overlay)))) |
(not hexl-ascii-overlay)))) |
835 |
|
|
866 |
;; Make all self-inserting keys go through hexl-self-insert-command, |
;; Make all self-inserting keys go through hexl-self-insert-command, |
867 |
;; because we need to convert them to unibyte characters before |
;; because we need to convert them to unibyte characters before |
868 |
;; inserting them into the buffer. |
;; inserting them into the buffer. |
869 |
(substitute-key-definition 'self-insert-command 'hexl-self-insert-command |
(define-key hexl-mode-map [remap self-insert-command] 'hexl-self-insert-command) |
|
hexl-mode-map (current-global-map)) |
|
870 |
|
|
871 |
|
(define-key hexl-mode-map "\C-m" 'hexl-self-insert-command) |
872 |
(define-key hexl-mode-map [left] 'hexl-backward-char) |
(define-key hexl-mode-map [left] 'hexl-backward-char) |
873 |
(define-key hexl-mode-map [right] 'hexl-forward-char) |
(define-key hexl-mode-map [right] 'hexl-forward-char) |
874 |
(define-key hexl-mode-map [up] 'hexl-previous-line) |
(define-key hexl-mode-map [up] 'hexl-previous-line) |