aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJambunathan K2012-12-04 16:13:47 -0500
committerStefan Monnier2012-12-04 16:13:47 -0500
commitb85aec936c85449faeaca36f52994487633e2e48 (patch)
treedf8d13f220ee277e7c847c12bc2eea020fdbf63b
parent47a6e6df2b6430c1047538260750cdbe78c566d5 (diff)
downloademacs-b85aec936c85449faeaca36f52994487633e2e48.tar.gz
emacs-b85aec936c85449faeaca36f52994487633e2e48.zip
* lisp/hi-lock.el (hi-lock-auto-select-face): New user variable.
(hi-lock-auto-select-face-defaults): New buffer local variable. (hi-lock-read-face-name): Honor `hi-lock-auto-select-face'. (hi-lock-unface-buffer): Prompt user with useful defaults. With prefix arg, unhighlight all hi-lock patterns in buffer. Fixes: debbugs:11095
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/hi-lock.el160
2 files changed, 116 insertions, 52 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 352e5a7e970..ff9b0e2a86f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
12012-12-04 Jambunathan K <kjambunathan@gmail.com>
2
3 * hi-lock.el (hi-lock-auto-select-face): New user variable.
4 (hi-lock-auto-select-face-defaults): New buffer local variable.
5 (hi-lock-read-face-name): Honor `hi-lock-auto-select-face'.
6 (hi-lock-unface-buffer): Prompt user with useful defaults.
7 With prefix arg, unhighlight all hi-lock patterns in buffer.
8
12012-12-04 Stefan Monnier <monnier@iro.umontreal.ca> 92012-12-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 10
3 * obsolete/terminal.el, obsolete/longlines.el: Add obsolecence info. 11 * obsolete/terminal.el, obsolete/longlines.el: Add obsolecence info.
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index 59743124cc5..5496a7581c3 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -135,6 +135,13 @@ patterns."
135;; It can have a function value. 135;; It can have a function value.
136(put 'hi-lock-file-patterns-policy 'risky-local-variable t) 136(put 'hi-lock-file-patterns-policy 'risky-local-variable t)
137 137
138(defcustom hi-lock-auto-select-face nil
139 "Non-nil if highlighting commands should not prompt for face names.
140When non-nil, each hi-lock command will cycle through faces in
141`hi-lock-face-defaults'."
142 :type 'boolean
143 :version "24.4")
144
138(defgroup hi-lock-faces nil 145(defgroup hi-lock-faces nil
139 "Faces for hi-lock." 146 "Faces for hi-lock."
140 :group 'hi-lock 147 :group 'hi-lock
@@ -211,8 +218,13 @@ patterns."
211 "hi-blue-b" "hi-red-b" "hi-green-b" "hi-black-hb") 218 "hi-blue-b" "hi-red-b" "hi-green-b" "hi-black-hb")
212 "Default faces for hi-lock interactive functions.") 219 "Default faces for hi-lock interactive functions.")
213 220
214;;(dolist (f hi-lock-face-defaults) 221(defvar-local hi-lock--auto-select-face-defaults
215;; (unless (facep f) (error "%s not a face" f))) 222 (let ((l (copy-sequence hi-lock-face-defaults)))
223 (setcdr (last l) l))
224 "Circular list of faces used for interactive highlighting.
225When `hi-lock-auto-select-face' is non-nil, use the face at the
226head of this list for next interactive highlighting. See also
227`hi-lock-read-face-name'.")
216 228
217(define-obsolete-variable-alias 'hi-lock-regexp-history 229(define-obsolete-variable-alias 'hi-lock-regexp-history
218 'regexp-history 230 'regexp-history
@@ -463,50 +475,87 @@ updated as you type."
463 475
464(declare-function x-popup-menu "menu.c" (position menu)) 476(declare-function x-popup-menu "menu.c" (position menu))
465 477
478(defun hi-lock--regexps-at-point ()
479 (let ((regexps '()))
480 ;; When using overlays, there is no ambiguity on the best
481 ;; choice of regexp.
482 (let ((desired-serial (get-char-property
483 (point) 'hi-lock-overlay-regexp)))
484 (when desired-serial
485 (catch 'regexp
486 (maphash
487 (lambda (regexp serial)
488 (when (= serial desired-serial)
489 (push regexp regexps)))
490 hi-lock-string-serialize-hash))))
491 ;; With font-locking on, check if the cursor is on an highlighted text.
492 ;; Checking for hi-lock face is a good heuristic.
493 (and (string-match "\\`hi-lock-" (face-name (face-at-point)))
494 (let* ((hi-text
495 (buffer-substring-no-properties
496 (previous-single-property-change (point) 'face)
497 (next-single-property-change (point) 'face))))
498 ;; Compute hi-lock patterns that match the
499 ;; highlighted text at point. Use this later in
500 ;; during completing-read.
501 (dolist (hi-lock-pattern hi-lock-interactive-patterns)
502 (let ((regexp (car hi-lock-pattern)))
503 (if (string-match regexp hi-text)
504 (push regexp regexps))))))))
505
466;;;###autoload 506;;;###autoload
467(defalias 'unhighlight-regexp 'hi-lock-unface-buffer) 507(defalias 'unhighlight-regexp 'hi-lock-unface-buffer)
468;;;###autoload 508;;;###autoload
469(defun hi-lock-unface-buffer (regexp) 509(defun hi-lock-unface-buffer (regexp)
470 "Remove highlighting of each match to REGEXP set by hi-lock. 510 "Remove highlighting of each match to REGEXP set by hi-lock.
471Interactively, prompt for REGEXP, accepting only regexps 511Interactively, prompt for REGEXP, accepting only regexps
472previously inserted by hi-lock interactive functions." 512previously inserted by hi-lock interactive functions.
513If REGEXP is t (or if \\[universal-argument] was specified interactively),
514then remove all hi-lock highlighting."
473 (interactive 515 (interactive
474 (if (and (display-popup-menus-p) 516 (cond
475 (listp last-nonmenu-event) 517 (current-prefix-arg (list t))
476 use-dialog-box) 518 ((and (display-popup-menus-p)
477 (catch 'snafu 519 (listp last-nonmenu-event)
478 (or 520 use-dialog-box)
479 (x-popup-menu 521 (catch 'snafu
480 t 522 (or
481 (cons 523 (x-popup-menu
482 `keymap 524 t
483 (cons "Select Pattern to Unhighlight" 525 (cons
484 (mapcar (lambda (pattern) 526 `keymap
485 (list (car pattern) 527 (cons "Select Pattern to Unhighlight"
486 (format 528 (mapcar (lambda (pattern)
487 "%s (%s)" (car pattern) 529 (list (car pattern)
488 (symbol-name 530 (format
489 (car 531 "%s (%s)" (car pattern)
490 (cdr (car (cdr (car (cdr pattern)))))))) 532 (symbol-name
491 (cons nil nil) 533 (car
492 (car pattern))) 534 (cdr (car (cdr (car (cdr pattern))))))))
493 hi-lock-interactive-patterns)))) 535 (cons nil nil)
494 ;; If the user clicks outside the menu, meaning that they 536 (car pattern)))
495 ;; change their mind, x-popup-menu returns nil, and 537 hi-lock-interactive-patterns))))
496 ;; interactive signals a wrong number of arguments error. 538 ;; If the user clicks outside the menu, meaning that they
497 ;; To prevent that, we return an empty string, which will 539 ;; change their mind, x-popup-menu returns nil, and
498 ;; effectively disable the rest of the function. 540 ;; interactive signals a wrong number of arguments error.
499 (throw 'snafu '("")))) 541 ;; To prevent that, we return an empty string, which will
500 (let ((history-list (mapcar (lambda (p) (car p)) 542 ;; effectively disable the rest of the function.
501 hi-lock-interactive-patterns))) 543 (throw 'snafu '("")))))
502 (unless hi-lock-interactive-patterns 544 (t
503 (error "No highlighting to remove")) 545 ;; Un-highlighting triggered via keyboard action.
546 (unless hi-lock-interactive-patterns
547 (error "No highlighting to remove"))
548 ;; Infer the regexp to un-highlight based on cursor position.
549 (let* ((defaults (hi-lock--regexps-at-point)))
504 (list 550 (list
505 (completing-read "Regexp to unhighlight: " 551 (completing-read (if (null defaults)
506 hi-lock-interactive-patterns nil t 552 "Regexp to unhighlight: "
507 (car (car hi-lock-interactive-patterns)) 553 (format "Regexp to unhighlight (default %s): "
508 (cons 'history-list 1)))))) 554 (car defaults)))
509 (let ((keyword (assoc regexp hi-lock-interactive-patterns))) 555 hi-lock-interactive-patterns
556 nil t nil nil defaults))))))
557 (dolist (keyword (if (eq regexp t) hi-lock-interactive-patterns
558 (list (assoc regexp hi-lock-interactive-patterns))))
510 (when keyword 559 (when keyword
511 (font-lock-remove-keywords nil (list keyword)) 560 (font-lock-remove-keywords nil (list keyword))
512 (setq hi-lock-interactive-patterns 561 (setq hi-lock-interactive-patterns
@@ -567,20 +616,25 @@ not suitable."
567 regexp)) 616 regexp))
568 617
569(defun hi-lock-read-face-name () 618(defun hi-lock-read-face-name ()
570 "Read face name from minibuffer with completion and history." 619 "Return face name for interactive highlighting.
571 (intern (completing-read 620When `hi-lock-auto-select-face' is non-nil, just return the next face.
572 "Highlight using face: " 621Otherwise, read face name from minibuffer with completion and history."
573 obarray 'facep t 622 (if hi-lock-auto-select-face
574 (cons (car hi-lock-face-defaults) 623 ;; Return current head and rotate the face list.
575 (let ((prefix 624 (pop hi-lock--auto-select-face-defaults)
576 (try-completion 625 (intern (completing-read
577 (substring (car hi-lock-face-defaults) 0 1) 626 "Highlight using face: "
578 hi-lock-face-defaults))) 627 obarray 'facep t
579 (if (and (stringp prefix) 628 (cons (car hi-lock-face-defaults)
580 (not (equal prefix (car hi-lock-face-defaults)))) 629 (let ((prefix
581 (length prefix) 0))) 630 (try-completion
582 'face-name-history 631 (substring (car hi-lock-face-defaults) 0 1)
583 (cdr hi-lock-face-defaults)))) 632 hi-lock-face-defaults)))
633 (if (and (stringp prefix)
634 (not (equal prefix (car hi-lock-face-defaults))))
635 (length prefix) 0)))
636 'face-name-history
637 (cdr hi-lock-face-defaults)))))
584 638
585(defun hi-lock-set-pattern (regexp face) 639(defun hi-lock-set-pattern (regexp face)
586 "Highlight REGEXP with face FACE." 640 "Highlight REGEXP with face FACE."
@@ -656,6 +710,8 @@ not suitable."
656 (font-lock-add-keywords nil hi-lock-interactive-patterns t))) 710 (font-lock-add-keywords nil hi-lock-interactive-patterns t)))
657 711
658(defvar hi-lock-string-serialize-hash 712(defvar hi-lock-string-serialize-hash
713 ;; FIXME: don't map strings to numbers but to unique strings via
714 ;; hash-consing, with a weak hash-table.
659 (make-hash-table :test 'equal) 715 (make-hash-table :test 'equal)
660 "Hash table used to assign unique numbers to strings.") 716 "Hash table used to assign unique numbers to strings.")
661 717