;;; hexl.el --- edit a file in a hex dump format using the hexl filter
-;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 1994, 1998, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Author: Keith Gabryelski <ag@wheaties.ai.mit.edu>
;; Maintainer: FSF
;;; Code:
+(require 'eldoc)
+
;;
;; vars here
;;
:group 'hexl
:version "20.3")
+(defcustom hexl-mode-hook '(hexl-follow-line hexl-activate-ruler)
+ "Normal hook run when entering Hexl mode."
+ :type 'hook
+ :options '(hexl-follow-line hexl-activate-ruler turn-on-eldoc-mode)
+ :group 'hexl)
+
+(defface hexl-address-area
+ '((t (:inherit header-line)))
+ "Face used in address are of hexl-mode buffer."
+ :group 'hexl)
+
+(defface hexl-ascii-area
+ '((t (:inherit header-line)))
+ "Face used in ascii are of hexl-mode buffer."
+ :group 'hexl)
+
(defvar hexl-max-address 0
"Maximum offset into hexl buffer.")
(add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
+ ;; Set a callback function for eldoc.
+ (set (make-local-variable 'eldoc-print-current-symbol-info-function)
+ 'hexl-print-current-point-info)
+ (eldoc-add-command-completions "hexl-")
+ (eldoc-remove-command "hexl-save-buffer"
+ "hexl-current-address")
+
(if hexl-follow-ascii (hexl-follow-ascii 1)))
(run-hooks 'hexl-mode-hook))
(- current-column 41)
(/ (- current-column (/ current-column 5)) 2))))
(when (interactive-p)
- (message "Current address is %d" hexl-address))
+ (message "Current address is %d/0x%08x" hexl-address hexl-address))
hexl-address))
+(defun hexl-print-current-point-info ()
+ "Return current hexl-address in string.
+This function is indented to be used as eldoc callback."
+ (let ((addr (hexl-current-address)))
+ (format "Current address is %d/0x%08x" addr addr)))
+
(defun hexl-address-to-marker (address)
"Return buffer position for ADDRESS."
(interactive "nAddress: ")
(apply 'call-process-region (point-min) (point-max)
(expand-file-name hexl-program exec-directory)
t t nil (split-string hexl-options))
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^[0-9a-f]+:" nil t)
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'font-lock-face 'hexl-address-area))
+ (goto-char (point-min))
+ (while (re-search-forward " \\(.+$\\)" nil t)
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'font-lock-face 'hexl-ascii-area)))
(if (> (point) (hexl-address-to-marker hexl-max-address))
(hexl-goto-address hexl-max-address))))
CH must be a unibyte character whose value is between 0 and 255."
(if (or (< ch 0) (> ch 255))
- (error "Invalid character 0x%x -- must be in the range [0..255]"))
+ (error "Invalid character 0x%x -- must be in the range [0..255]" ch))
(let ((address (hexl-current-address t)))
(while (> num 0)
(let ((hex-position
(remove-hook 'post-command-hook 'hexl-follow-ascii-find t)
)))))
+(defun hexl-activate-ruler ()
+ "Activate `ruler-mode'"
+ (require 'ruler-mode)
+ (set (make-local-variable 'ruler-mode-ruler-function)
+ 'hexl-mode-ruler)
+ (ruler-mode 1))
+
+(defun hexl-follow-line ()
+ "Activate `hl-line-mode'"
+ (require 'frame)
+ (require 'fringe)
+ (require 'hl-line)
+ (set (make-local-variable 'hl-line-range-function)
+ 'hexl-highlight-line-range)
+ (set (make-local-variable 'hl-line-face)
+ 'highlight)
+ (hl-line-mode 1))
+
+(defun hexl-highlight-line-range ()
+ "Return the range of address area for the point.
+This function is assumed to be used as call back function for `hl-line-mode'."
+ (cons
+ (line-beginning-position)
+ ;; 9 stands for (length "87654321:")
+ (+ (line-beginning-position) 9)))
+
(defun hexl-follow-ascii-find ()
"Find and highlight the ASCII element corresponding to current point."
(let ((pos (+ 51
(move-overlay hexl-ascii-overlay pos (1+ pos))
))
+(defun hexl-mode-ruler ()
+ "Return a string ruler for hexl mode."
+ (let* ((highlight (mod (hexl-current-address) 16))
+ (s " 87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef")
+ (pos 0))
+ (set-text-properties 0 (length s) nil s)
+ ;; Turn spaces in the header into stretch specs so they work
+ ;; regardless of the header-line face.
+ (while (string-match "[ \t]+" s pos)
+ (setq pos (match-end 0))
+ (put-text-property (match-beginning 0) pos 'display
+ ;; Assume fixed-size chars
+ `(space :align-to ,(1- pos))
+ s))
+ ;; Highlight the current column.
+ (put-text-property (+ 11 (/ (* 5 highlight) 2))
+ (+ 13 (/ (* 5 highlight) 2))
+ 'face 'highlight s)
+ ;; Highlight the current ascii column
+ (put-text-property (+ 13 39 highlight) (+ 13 40 highlight)
+ 'face 'highlight s)
+ s))
+
;; startup stuff.
(if hexl-mode-map