;;; hexl.el --- edit a file in a hex dump format using the hexl filter.
-;; Copyright (C) 1989 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 1994 Free Software Foundation, Inc.
;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu>
;; Maintainer: FSF
(defvar hexl-mode-map nil)
+(defvar hexl-mode-old-local-map)
+(defvar hexl-mode-old-mode-name)
+(defvar hexl-mode-old-major-mode)
+
;; routines
;;;###autoload
(make-local-variable 'write-contents-hooks)
(add-hook 'write-contents-hooks 'hexl-save-buffer)
+ (make-local-hook 'after-revert-hook)
+ (add-hook 'after-revert-hook 'hexl-after-revert-hook nil t)
+
+ (make-local-variable 'hexl-max-address)
+
+ (make-local-variable 'change-major-mode-hook)
+ (add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer)
+
+ (make-local-variable 'require-final-newline)
+ (setq require-final-newline nil)
+
(let ((modified (buffer-modified-p))
(inhibit-read-only t)
(original-point (1- (point))))
+ (and (eobp) (not (bobp))
+ (setq original-point (1- original-point)))
(if (not (or (eq arg 1) (not arg)))
;; if no argument then we guess at hexl-max-address
(setq hexl-max-address (+ (* (/ (1- (buffer-size)) 68) 16) 15))
(set-buffer-modified-p modified)
(hexl-goto-address original-point)))))
+(defun hexl-after-revert-hook ()
+ (hexlify-buffer)
+ (set-buffer-modified-p nil))
+
(defvar hexl-in-save-buffer nil)
(defun hexl-save-buffer ()
(set-buffer name)
(dehexlify-buffer)
;; Prevent infinite recursion.
- (let ((hexl-in-save-buffer t))
+ (let ((hexl-in-save-buffer t)
+ (buffer-file-type t)) ; for ms-dos
(save-buffer))
(setq modified (buffer-modified-p))
(delete-region (point-min) (point-max))
"Edit file FILENAME in hexl-mode.
Switch to a buffer visiting file FILENAME, creating one in none exists."
(interactive "fFilename: ")
- (if (eq system-type 'ms-dos)
+ (if (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))
(find-file-binary filename)
(find-file filename))
(if (not (eq major-mode 'hexl-mode))
(setq mode-name hexl-mode-old-mode-name)
(use-local-map hexl-mode-old-local-map)
(setq major-mode hexl-mode-old-major-mode)
-;; Kludge to update mode-line
- (switch-to-buffer (current-buffer))
-)
+ (force-mode-line-update))
+
+(defun hexl-maybe-dehexlify-buffer ()
+ "Convert a hexl format buffer to binary.
+Ask the user for confirmation."
+ (if (y-or-n-p "Convert contents back to binary format? ")
+ (let ((modified (buffer-modified-p))
+ (inhibit-read-only t)
+ (original-point (1+ (hexl-current-address))))
+ (dehexlify-buffer)
+ (remove-hook 'write-contents-hook 'hexl-save-buffer)
+ (set-buffer-modified-p modified)
+ (goto-char original-point))))
-(defun hexl-current-address ()
+(defun hexl-current-address (&optional validate)
"Return current hexl-address."
(interactive)
(let ((current-column (- (% (point) 68) 11))
(hexl-address 0))
- (setq hexl-address (+ (* (/ (point) 68) 16)
- (/ (- current-column (/ current-column 5)) 2)))
+ (if (< current-column 0)
+ (if validate
+ (error "Point is not on a character in the file")
+ (setq current-column 0)))
+ (setq hexl-address
+ (+ (* (/ (point) 68) 16)
+ (if (>= current-column 41)
+ (- current-column 41)
+ (/ (- current-column (/ current-column 5)) 2))))
hexl-address))
(defun hexl-address-to-marker (address)
(defun hexl-goto-address (address)
"Goto hexl-mode (decimal) address ADDRESS.
-
Signal error if ADDRESS out of range."
(interactive "nAddress: ")
(if (or (< address 0) (> address hexl-max-address))
(defun hexl-goto-hex-address (hex-address)
"Go to hexl-mode address (hex string) HEX-ADDRESS.
-
Signal error if HEX-ADDRESS is out of range."
(interactive "sHex Address: ")
(hexl-goto-address (hexl-hex-string-to-integer hex-address)))
;;;###autoload
(defun hexlify-buffer ()
- "Convert a binary buffer to hexl format"
+ "Convert a binary buffer to hexl format."
(interactive)
- (shell-command-on-region (point-min) (point-max) hexlify-command t))
+ (let ((binary-process-output nil) ; for Ms-Dos
+ (binary-process-input t))
+ (shell-command-on-region (point-min) (point-max) hexlify-command t)))
(defun dehexlify-buffer ()
"Convert a hexl format buffer to binary."
(interactive)
- (let ((binary-process t)) ; for Ms-Dos
+ (let ((binary-process-output t) ; for Ms-Dos
+ (binary-process-input nil))
(shell-command-on-region (point-min) (point-max) dehexlify-command t)))
(defun hexl-char-after-point ()
(defun hexl-insert-char (ch num)
"Insert a character in a hexl buffer."
- (let ((address (hexl-current-address)))
+ (let ((address (hexl-current-address t)))
(while (> num 0)
- (delete-char 2)
- (insert (format "%02x" ch))
- (goto-char
- (+ (* (/ address 16) 68) 52 (% address 16)))
- (delete-char 1)
- (insert (hexl-printable-character ch))
- (if (eq address hexl-max-address)
- (hexl-goto-address address)
- (hexl-goto-address (1+ address)))
+ (let ((hex-position
+ (+ (* (/ address 16) 68)
+ 11
+ (* 2 (% address 16))
+ (/ (% address 16) 2)))
+ (ascii-position
+ (+ (* (/ address 16) 68) 52 (% address 16)))
+ at-ascii-position)
+ (if (= (point) ascii-position)
+ (setq at-ascii-position t))
+ (goto-char hex-position)
+ (delete-char 2)
+ (insert (format "%02x" ch))
+ (goto-char ascii-position)
+ (delete-char 1)
+ (insert (hexl-printable-character ch))
+ (or (eq address hexl-max-address)
+ (setq address (1+ address)))
+ (hexl-goto-address address)
+ (if at-ascii-position
+ (progn
+ (beginning-of-line)
+ (forward-char 51)
+ (forward-char (% address 16)))))
(setq num (1- num)))))
;; hex conversion
nil
(setq hexl-mode-map (make-sparse-keymap))
+ (define-key hexl-mode-map [left] 'hexl-backward-char)
+ (define-key hexl-mode-map [right] 'hexl-forward-char)
+ (define-key hexl-mode-map [up] 'hexl-previous-line)
+ (define-key hexl-mode-map [down] 'hexl-next-line)
+ (define-key hexl-mode-map [M-left] 'hexl-backward-short)
+ (define-key hexl-mode-map [M-right] 'hexl-forward-short)
+ (define-key hexl-mode-map [next] 'hexl-scroll-up)
+ (define-key hexl-mode-map [prev] 'hexl-scroll-down)
+
(define-key hexl-mode-map "\C-a" 'hexl-beginning-of-line)
(define-key hexl-mode-map "\C-b" 'hexl-backward-char)
(define-key hexl-mode-map "\C-d" 'undefined)
(define-key hexl-mode-map "\C-f" 'hexl-forward-char)
(if (not (eq (key-binding (char-to-string help-char)) 'help-command))
- (define-key hexl-mode-map help-char 'undefined))
+ (define-key hexl-mode-map (char-to-string help-char) 'undefined))
(define-key hexl-mode-map "\C-i" 'hexl-self-insert-command)
(define-key hexl-mode-map "\C-j" 'hexl-self-insert-command)