Hello!
I've implemented some things mentioned in the thread
"Changes to avoid (inappropriate) font-locking during hexl-find-file".
hexl-mode now behaves as I like it. You can avoid unneccessary
font-locking, revert-buffer works (without unnecc. prompting),
font-lock is switched off when entering hexl-mode and restored by
hexl-mode-exit. :-)
I would appreciate feedback, whether this is also how /you/ would like
hexl-mode to behave, or if I missed something and this changes could
break existing code.
The changes also need more testing, of course.
There are two independent (orthogonal) changes to hexl.el:
CHANGE 1:
There is a new custom. variable *hexl-find-file-raw*, which determines
if hexl-find-file uses find-file (default) or find-file-noselect with
RAWFILE non-nil. See the doc string and the comments in the patch
for further explanation.
find-file is called as (find-file filename), not as
(find-file filename 'binary) as before. See the comments in the patch
for my justification.
CHANGE 2:
A new custom. variable *hexl-switch-font-lock*, which determines if hexl
should leave font-lock alone (default) or if it should try to turn off
font-lock on entering hexl-mode and try to restore it on leaving
hexl-mode.
hexl-after-revert-hook was removed. hexl-mode now sets its own
revert-buffer-function, which calls the default revert-buffer, but
sets PRESERVE-MODES to non-nil, so the buffer stays in hexl-mode.
Restoring point after revert-buffer now works. (This change is not
entirely independent from the new font-lock handling, because the new
revert-buffer logic avoids unneccessary switching of major modes,
which also effects font-locking.)
END OF CHANGES
Here comes the patch, if you want to try it:
(Finally got rid of tab-ignorant Outlook Express :-))
-Edwin
Index: text-modes/hexl.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/text-modes/hexl.el,v
retrieving revision 1.5
diff -u -r1.5 hexl.el
--- text-modes/hexl.el 2001/07/20 14:09:16 1.5
+++ text-modes/hexl.el 2001/07/25 13:09:37
@@ -102,6 +102,30 @@
:group 'hexl
:version "20.3")
+(defcustom hexl-find-file-raw nil
+ "*If non-nil `hexl-find-file' reads the specified file literally.
+Per default hexl-find-file uses `find-file' to read the specified file,
+so that `hexl-mode-exit' gets you back to the appropriate major mode and
+coding-system for the file.
+Setting this variable to non-nil speeds up hexl-find-file, because no
+major mode (apart from hexl-mode) is loaded and no font-locking is done.
+Using hexl-mode-exit in this case will get you back to a buffer in
+fundamental-mode and the binary coding-system.
+NOTE: Regardless of hexl-find-file-raw's value hexl-mode itself always
+displays the literal binary contents of a file (in hex dump format)."
+ :type 'boolean
+ :group 'hexl)
+
+(defcustom hexl-switch-font-lock nil
+ "*If non-nil, turn off font-lock-mode when entering hexl-mode.
+When hexl-mode exits, it tries to restore font-lock to its previous settings.
+If this variable is non-nil, you can set customized font-locking for
+hexl-mode in your `hexl-mode-hook'.
+Set this variable to nil if you experience problems with font-lock after
+leaving hexl-mode."
+ :type 'boolean
+ :group 'hexl)
+
(defvar hexl-max-address 0
"Maximum offset into hexl buffer.")
@@ -113,6 +137,9 @@
(defvar hexl-mode-old-write-contents-hooks)
(defvar hexl-mode-old-require-final-newline)
(defvar hexl-mode-old-syntax-table)
+(defvar hexl-mode-old-revert-buffer-function nil)
+(defvar hexl-mode-old-font-lock-mode nil)
+(defvar hexl-mode-old-font-lock-defaults nil)
(defvar hexl-ascii-extent nil
"Extent used to highlight ASCII element corresponding to current point.")
@@ -243,8 +270,9 @@
(setq require-final-newline nil)
;; Add hooks to rehexlify or dehexlify on various events.
- (make-local-hook 'after-revert-hook)
- (add-hook 'after-revert-hook 'hexl-after-revert-hook nil t)
+ (setq hexl-mode-old-revert-buffer-function revert-buffer-function)
+ (make-local-variable 'revert-buffer-function)
+ (setq revert-buffer-function 'hexl-revert-buffer)
(make-local-hook 'change-major-mode-hook)
(add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
@@ -252,10 +280,17 @@
(if hexl-follow-ascii (hexl-follow-ascii 1)))
(run-hooks 'hexl-mode-hook))
-(defun hexl-after-revert-hook ()
- (setq hexl-max-address (1- (buffer-size)))
- (hexlify-buffer)
- (set-buffer-modified-p nil))
+(defun hexl-revert-buffer (ignore-auto noconfirm)
+ "hexl-mode installs this function as `revert-buffer-function'.
+This function makes sure that the major mode is not changed during
+`revert-buffer' and that the buffer is rehexlified after reverting."
+ (let ((revert-buffer-function hexl-mode-old-revert-buffer-function)
+ (opoint (point)))
+ (revert-buffer ignore-auto noconfirm t)
+ (setq hexl-max-address (1- (buffer-size)))
+ (hexlify-buffer)
+ (goto-char (min opoint (point-max)))
+ (set-buffer-modified-p nil)))
(defvar hexl-in-save-buffer nil)
@@ -293,7 +328,13 @@
"Edit file FILENAME in hexl-mode.
Switch to a buffer visiting file FILENAME, creating one if none exists."
(interactive "fFilename: ")
- (find-file filename 'binary)
+ (if hexl-find-file-raw
+ (let ((find-file-run-dired nil))
+ (switch-to-buffer (find-file-noselect filename nil t)))
+ ;; (find-file filename 'binary) makes no sense here IMO, since it mixes
+ ;; "automatic major mode" with "forced binary coding-system".
+ ;; See hexl-find-file-raw for further info. --Edwin Steiner
+ (find-file filename))
(if (not (eq major-mode 'hexl-mode))
(hexl-mode)))
@@ -310,17 +351,26 @@
(set-buffer-modified-p modified)
(goto-char original-point)))
- (remove-hook 'after-revert-hook 'hexl-after-revert-hook t)
(remove-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer t)
(remove-hook 'post-command-hook 'hexl-follow-ascii-find t)
(setq hexl-ascii-extent nil)
+ (setq revert-buffer-function hexl-mode-old-revert-buffer-function)
(setq write-contents-hooks hexl-mode-old-write-contents-hooks)
(setq require-final-newline hexl-mode-old-require-final-newline)
(setq mode-name hexl-mode-old-mode-name)
(use-local-map hexl-mode-old-local-map)
(set-syntax-table hexl-mode-old-syntax-table)
(setq major-mode hexl-mode-old-major-mode)
+
+ (if (and hexl-switch-font-lock (featurep 'font-lock))
+ ;; Restore pre hexl-mode font-lock settings
+ (progn
+ (font-lock-mode 0)
+ (setq font-lock-defaults hexl-mode-old-font-lock-defaults)
+ (if hexl-mode-old-font-lock-mode
+ (font-lock-set-defaults t))))
+
(force-mode-line-update)
(run-hooks 'hexl-mode-exit-hook))
@@ -613,6 +663,17 @@
(or (y-or-n-p "Converting to hexl format discards undo info; ok? ")
(error "Aborted")))
(setq buffer-undo-list nil)
+ ;; Switch font-lock-mode off if we are entering hexl-mode.
+ ;; This cannot be in the function hexl-mode, because it must be done after
+ ;; the y-or-no-p above and before the call to shell-command-on-region below.
+ (if (and hexl-switch-font-lock (featurep 'font-lock))
+ (if (eq major-mode 'hexl-mode)
+ nil
+ (make-local-variable 'hexl-mode-old-font-lock-mode)
+ (setq hexl-mode-old-font-lock-mode font-lock-mode)
+ (make-local-variable 'hexl-mode-old-font-lock-defaults)
+ (setq hexl-mode-old-font-lock-defaults font-lock-defaults)
+ (font-lock-mode 0)))
;; Don't decode text in the ASCII part of `hexl' program output.
(let ((coding-system-for-read 'raw-text)
(coding-system-for-write