diff lisp/play/decipher.el @ 14596:afb84c1d7750

(decipher-mode, decipher-set-map, decipher-insert, decipher-make-checkpoint, decipher-resync): Added special support for font-lock. (decipher-use-font-lock, decipher-font-lock-keywords): New vars. (decipher-toggle-font-lock, decipher-turn-on-font-lock): New funcs.
author Karl Heuer <kwzh@gnu.org>
date Mon, 19 Feb 1996 07:52:24 +0000
parents 3ae037e10c04
children 2e418434d5d5
line wrap: on
line diff
--- a/lisp/play/decipher.el	Mon Feb 19 07:40:38 1996 +0000
+++ b/lisp/play/decipher.el	Mon Feb 19 07:52:24 1996 +0000
@@ -38,6 +38,11 @@
 
 ;;; Commentary:
 ;;
+;; If you want Decipher to use its Font Lock mode, you should use
+;;     (setq decipher-use-font-lock t)
+;; See the variable `decipher-use-font-lock' if you want to customize
+;; the faces used.
+;;
 ;; This package is designed to help you crack simple substitution
 ;; ciphers where one letter stands for another.  It works for ciphers
 ;; with or without word divisions.  (You must set the variable
@@ -86,6 +91,28 @@
 (eval-when-compile
   (require 'cl))
 
+(eval-when-compile
+  (require 'font-lock))
+
+(defvar decipher-use-font-lock (featurep 'font-lock)
+  "Non-nil means Decipher should use its Font Lock mode.
+Do *not* turn on font-lock-mode yourself, it's too slow when used with
+Decipher.  Decipher contains special code to keep the buffer fontified
+without using Font Lock mode directly.
+
+You should set this in your `.emacs' file or before loading Decipher;
+use `\\[decipher-toggle-font-lock]' after Decipher is loaded.
+
+Ciphertext uses `font-lock-keyword-face', plaintext uses
+`font-lock-string-face', comments use `font-lock-comment-face', and
+checkpoints use `font-lock-reference-face'.
+
+For example, to display ciphertext in the `bold' face, use
+  (add-hook 'decipher-mode-hook
+            (lambda () (set (make-local-variable 'font-lock-keyword-face)
+                            'bold)))
+in your `.emacs' file.")
+
 (defvar decipher-force-uppercase t
   "*Non-nil means to convert ciphertext to uppercase.
 Nil means the case of the ciphertext is preserved.
@@ -106,6 +133,19 @@
 ;; End of user modifiable variables
 ;;--------------------------------------------------------------------
 
+(defvar decipher-font-lock-keywords
+  '(("^:.*\n"  . font-lock-keyword-face)
+    ("^>.*\n"  . font-lock-string-face)
+    ("^%!.*\n" . font-lock-reference-face)
+    ("^%.*\n"  . font-lock-comment-face)
+    ("\\`(\\([a-z]+\\) +\\([A-Z]+\\).+
+)\\([A-Z ]*\\)\\([a-z ]*\\)"
+     (1 font-lock-string-face)
+     (2 font-lock-keyword-face)
+     (3 font-lock-keyword-face)
+     (4 font-lock-string-face)))
+  "Expressions to fontify in Decipher mode.
+See the variable `decipher-use-font-lock'.")
 (defvar decipher-mode-map nil
   "Keymap for Decipher mode.")
 (if (not decipher-mode-map)
@@ -259,13 +299,22 @@
   (use-local-map decipher-mode-map)
   (set-syntax-table decipher-mode-syntax-table)
   (decipher-read-alphabet)
+  (set (make-local-variable 'font-lock-defaults)
+       '(decipher-font-lock-keywords t))
   ;; Make the buffer writable when we exit Decipher mode:
   (make-local-hook 'change-major-mode-hook)
   (add-hook 'change-major-mode-hook
             (lambda () (setq buffer-read-only nil
                              buffer-undo-list nil))
             nil t)
+  ;; If someone turns on Font Lock, turn it off and use our code instead:
+  (make-local-hook 'font-lock-mode-hook)
+  (add-hook 'font-lock-mode-hook 'decipher-turn-on-font-lock t t)
   (run-hooks 'decipher-mode-hook)
+  (and decipher-use-font-lock
+       ;; Fontify buffer after calling the mode hooks,
+       ;; in case they change the font-lock variables:
+       (font-lock-fontify-buffer))
   (setq buffer-read-only t))
 (put 'decipher-mode 'mode-class 'special)
 
@@ -426,10 +475,15 @@
                 (decipher-set-map (cdr mapping) ?\  t))
             (setcdr mapping cipher-char)
             (search-forward-regexp (concat "^([a-z]*" plain-string))
-            (decipher-insert cipher-char)
+            (and decipher-use-font-lock
+                 (put-text-property 0 1 'face font-lock-keyword-face
+                                    cipher-string))
+            (decipher-insert cipher-string)
             (beginning-of-line)))
       (search-forward-regexp (concat "^([a-z]+   [A-Z]*" cipher-string))
-      (decipher-insert plain-char)
+      (and decipher-use-font-lock
+           (put-text-property 0 1 'face font-lock-string-face plain-string))
+      (decipher-insert plain-string)
       (setq case-fold-search t          ;Case is not significant
             cipher-string    (downcase cipher-string))
       (while (search-forward-regexp "^:" nil t)
@@ -449,7 +503,7 @@
       (move-to-column col t)
       (or (eolp)
           (delete-char 1))
-      (insert char))))
+      (insert-and-inherit char))))
 
 ;;--------------------------------------------------------------------
 ;; Checkpoints:
@@ -490,7 +544,9 @@
       (insert "\n%" (make-string 69 ?\-)
               "\n% Checkpoints:\n% abcdefghijklmnopqrstuvwxyz\n"))
     (beginning-of-line)
-    (insert "%!" alphabet "! " desc ?\n)))
+    (insert "%!" alphabet "! " desc ?\n))
+  (and decipher-use-font-lock
+       (font-lock-fontify-buffer)))
 
 (defun decipher-restore-checkpoint ()
   "Restore the cipher alphabet from a checkpoint.
@@ -569,6 +625,8 @@
            (replace-match ")" nil nil))
       (while (re-search-forward "^>.+$" nil t)
         (replace-match ">" nil nil))
+      (and decipher-use-font-lock
+           (font-lock-fontify-buffer))
       (decipher-read-alphabet)
       (while (setq mapping (pop alphabet))
         (or (equal ?\  (cdr mapping))
@@ -577,6 +635,19 @@
         decipher-undo-list-size  0)
   (message "Reprocessing buffer...done"))
 
+(defun decipher-toggle-font-lock (&optional arg)
+  "Toggle Decipher's Font Lock mode in the current buffer.
+With arg, turn Font Lock mode on if and only if arg is positive.
+See the variable `decipher-use-font-lock' for more information."
+  (interactive "P")
+  (or (eq major-mode 'decipher-mode)
+      (error "This buffer is not in Decipher mode"))
+  (let ((on-p (if arg (> (prefix-numeric-value arg) 0)
+                (not decipher-use-font-lock))))
+    (if on-p (font-lock-fontify-buffer)
+      (font-lock-unfontify-region (point-min) (point-max)))
+    (make-local-variable 'decipher-use-font-lock)
+    (setq decipher-use-font-lock on-p)))
 ;;--------------------------------------------------------------------
 ;; Miscellaneous functions:
 ;;--------------------------------------------------------------------
@@ -593,6 +664,10 @@
         (backward-char)
         (push (cons plain-char (following-char)) decipher-alphabet)
         (decf plain-char)))))
+(defun decipher-turn-on-font-lock ()
+  "Turn on Decipher's Font Lock code and turn off normal Font Lock mode."
+  (font-lock-mode 0)
+  (decipher-toggle-font-lock 1))
 
 ;;;===================================================================
 ;;; Analyzing ciphertext: