From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: ruler support in hexl mode Date: 08 Mar 2004 15:05:50 -0500 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: References: <20040305.142915.63122255.jet@gyve.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1079212643 7081 80.91.224.253 (13 Mar 2004 21:17:23 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 13 Mar 2004 21:17:23 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Sat Mar 13 22:17:18 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1B2GVS-0002Uu-00 for ; Sat, 13 Mar 2004 22:17:18 +0100 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1B2GVR-0005t1-00 for ; Sat, 13 Mar 2004 22:17:17 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.30) id 1B1QOn-0007pi-QE for emacs-devel@quimby.gnus.org; Thu, 11 Mar 2004 08:38:57 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1B0R1L-000762-Hs for emacs-devel@gnu.org; Mon, 08 Mar 2004 15:06:39 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1B0R0h-0006Yb-3i for emacs-devel@gnu.org; Mon, 08 Mar 2004 15:06:30 -0500 Original-Received: from [132.204.24.67] (helo=mercure.iro.umontreal.ca) by monty-python.gnu.org with esmtp (Exim 4.30) id 1B0R0g-0006YS-22 for emacs-devel@gnu.org; Mon, 08 Mar 2004 15:05:58 -0500 Original-Received: from asado.iro.umontreal.ca (asado.iro.umontreal.ca [132.204.24.84]) by mercure.iro.umontreal.ca (Postfix) with ESMTP id 3BBC420D15; Mon, 8 Mar 2004 15:05:51 -0500 (EST) Original-Received: by asado.iro.umontreal.ca (Postfix, from userid 20848) id 29A388C8E4; Mon, 8 Mar 2004 15:05:51 -0500 (EST) Original-To: Masatake YAMATO In-Reply-To: <20040305.142915.63122255.jet@gyve.org> Original-Lines: 160 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 X-DIRO-MailScanner-Information: Please contact the ISP for more information X-DIRO-MailScanner: Found to be clean X-DIRO-MailScanner-SpamCheck: n'est pas un polluriel, SpamAssassin (score=-0.001, requis 5, BAYES_44 -0.00) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:20403 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:20403 > +(defcustom hexl-follow-line t > + "If non-nil then highlight the line address corresponding to point." > + :type 'boolean > + :group 'hexl) Any reason why you do not simply use hl-line-mode ? Or, better yet, let the user select hl-line-mode if he wants it? > +(defcustom hexl-use-face-on-address-area t > + "If non-nil then put `hexl-address-area-face' on adderss area of hexl-mode buffer." > + :type 'face > + :group 'hexl) > +(defcustom hexl-use-face-on-ascii-area t > + "If non-nil then put `hexl-ascii-area-face' on ascii area of hexl-mode buffer." > + :type 'face > + :group 'hexl) You can probably just remove these variables and place the faces on the `font-lock-face' property, so the user can use M-x global-font-lock-mode to turn highlighting on/off. > @@ -89,11 +118,20 @@ > (defvar hexl-mode-old-isearch-search-fun-function) > (defvar hexl-mode-old-require-final-newline) > (defvar hexl-mode-old-syntax-table) > +(defvar hexl-mode-old-header-line-format) > (defvar hexl-ascii-overlay nil > "Overlay used to highlight ASCII element corresponding to current point.") > (make-variable-buffer-local 'hexl-ascii-overlay) > +(defvar hexl-line-overlay nil > + "Overlay used to highlight the address of line corresponding to current point.") > +(make-variable-buffer-local 'hexl-line-overlay) > + > +(defconst hexl-mode-header-line-format > + '(:eval (hexl-mode-ruler)) > + "`header-line-format' used in hexl mode.") > + > ;; routines > (put 'hexl-mode 'mode-class 'special) > @@ -245,8 +283,13 @@ > (eldoc-remove-command "hexl-save-buffer" > "hexl-current-address") > - (if hexl-follow-ascii (hexl-follow-ascii 1))) > - (run-hooks 'hexl-mode-hook)) > + (make-variable-buffer-local 'hexl-mode-old-header-line-format) > + (setq hexl-mode-old-header-line-format header-line-format) That should be (set (make-local-variable 'hexl-mode-old-header-line-format) header-line-format) `make-variable-buffer-local' should almost never be called from inside a function. > + (while (re-search-forward "^[0-9a-f]\\{8\\}:" nil t) I'd use `+' rather than `\\{8\\}' because it's shorter, easier to read, more efficient, and most importantly future-proof (for very large files). > + (put-text-property (match-beginning 0) (match-end 0) > + 'face 'hexl-address-area-face))) > + (goto-char (point-min)) > + (when hexl-use-face-on-ascii-area > + (while (re-search-forward " \\( .+$\\)" nil t) > + (put-text-property (match-beginning 1) (match-end 1) > + 'face 'hexl-ascii-area-face)))) Why do you put the face property on the space before the actual "ascii" data? > +;; This function is derived from `ruler-mode-ruler' in ruler-mode.el. > +(defun hexl-mode-ruler () > + "Return a string ruler for hexl mode." > + (when hexl-use-ruler > + (let* ((fullw (ruler-mode-full-window-width)) > + (w (window-width)) > + (m (window-margins)) > + (lsb (ruler-mode-left-scroll-bar-cols)) > + (lf (ruler-mode-left-fringe-cols)) > + (lm (or (car m) 0)) > + (ruler (make-string fullw ?\ )) We really need to move this out of ruler-mode into frame.el or some other "global" file. And to give it a clean interface so its implementation can be improved later. > + (o (+ lsb lf lm)) > + (x o) > + (highlight (mod (hexl-current-address) 16))) > + ;; "87654321" > + (do ((i 8 (1- i))) > + ((= i 0)) > + (aset ruler x (aref (number-to-string i) 0)) > + (setq x (1+ x))) > + ;; "87654321 " > + (setq x (+ x 2)) ; ": " > + ;; "87654321 0011 2233 4455 6677 8899 aabb ccdd eeff" > + (do* ((i 0 (1+ i)) > + (c (format "%x" i) (format "%x" i))) > + ((= i 16)) > + (aset ruler x (aref c 0)) > + (setq x (1+ x)) > + (aset ruler x (aref c 0)) > + (setq x (1+ x)) > + (if (= highlight i) > + (put-text-property (- x 2) x > + 'face 'highlight > + ruler)) > + (when (= (mod i 2) 1) > + (aset ruler x ?\ ) > + (setq x (1+ x)))) > + ;; "87654321 0011 2233 4455 6677 8899 aabb ccdd eeff " > + (setq x (1+ x)) ; " " > + ;; "87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef" > + (do* ((i 0 (1+ i)) > + (c (format "%x" i) (format "%x" i))) > + ((= i 16)) > + (aset ruler x (aref c 0)) > + (setq x (1+ x)) > + (if (= highlight i) > + (put-text-property (1- x) x > + 'face 'highlight > + ruler))) > + ruler))) Isn't this always building the exact same string, except for the size (which really does not need to depend on the window's width), the leading space (to align it), and the highlighting of the current column? Couldn't we just do (100% untested code, inspired from buff-menu.el): (let ((spaces (+ lsb lf lm)) (s "87654321 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef") (pos 0)) ;; 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 ,(+ spaces pos)) s)) ;; Highlight the current column. (put-text-property (+ 10 (/ (* 5 highlight) 2)) (+ 12 (/ (* 5 highlight) 2)) 'face 'highlight s) ;; Add the leading space. (concat (propertize (make-string (floor spaces) ? ) 'display `(space :width ,spaces)) s)) Note that the use of the display property also allows us to deal with fractional sizes, although lsb and lf don't take advantage of it yet. Also I wish we could put some more useful info up there, but admittedly, I can't think of any. Stefan