Mercurial > hg > xemacs-beta
diff lisp/prim/syntax.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 0293115a14e9 |
children | 3bb7ccffb0c0 |
line wrap: on
line diff
--- a/lisp/prim/syntax.el Mon Aug 13 09:00:04 2007 +0200 +++ b/lisp/prim/syntax.el Mon Aug 13 09:02:59 2007 +0200 @@ -1,5 +1,6 @@ ;; Syntax-table hacking stuff, moved from syntax.c ;; Copyright (C) 1993 Free Software Foundation, Inc. +;; Copyright (C) 1995 Sun Microsystems. ;; This file is part of XEmacs. @@ -15,55 +16,147 @@ ;; You should have received a copy of the GNU General Public License ;; along with XEmacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Synched up with: FSF 19.28. ;;; Note: FSF does not have a file syntax.el. This stuff is ;;; in syntax.c. See comments there about not merging past 19.28. +;; Significantly hacked upon by Ben Wing. + (defun make-syntax-table (&optional oldtable) "Return a new syntax table. -It inherits all letters and control characters from the standard -syntax table; other characters are copied from the standard syntax table." - (if oldtable - (copy-syntax-table oldtable) - (let ((table (copy-syntax-table)) - i) - (setq i 0) - (while (<= i 31) - (aset table i 13) - (setq i (1+ i))) - (setq i ?A) - (while (<= i ?Z) - (aset table i 13) - (setq i (1+ i))) - (setq i ?a) - (while (<= i ?z) - (aset table i 13) - (setq i (1+ i))) - (setq i 128) - (while (<= i 255) - (aset table i 13) - (setq i (1+ i))) - table))) +It inherits all characters from the standard syntax table." + (make-char-table 'syntax)) + +(defun simple-set-syntax-entry (char spec table) + (put-char-table char spec table)) + +(defun char-syntax-from-code (code) + "Extract the syntax designator from the internal syntax code CODE. +CODE is the value actually contained in the syntax table." + (if (consp code) + (setq code (car code))) + (aref (syntax-designator-chars) (logand code 127))) + +(defun set-char-syntax-in-code (code desig) + "Return a new internal syntax code whose syntax designator is DESIG. +Other characteristics are the same as in CODE." + (let ((newcode (if (consp code) (car code) code))) + (setq newcode (logior (string-match + (regexp-quote (char-to-string desig)) + (syntax-designator-chars)) + (logand newcode (lognot 127)))) + (if (consp code) (cons newcode (cdr code)) + newcode))) -(defun modify-syntax-entry (char spec &optional table) - "Set syntax for character CHAR according to string S. +(defun syntax-code-to-string (code) + "Return a string equivalent to internal syntax code CODE. +The string can be passed to `modify-syntax-entry'. +If CODE is invalid, return nil." + (let ((match (and (consp code) (cdr code))) + (codes (syntax-designator-chars))) + (if (consp code) + (setq code (car code))) + (if (or (not (integerp code)) + (> (logand code 127) (length codes))) + nil + (with-output-to-string + (let* ((spec (elt codes (logand code 127))) + (b3 (lsh code -16)) + (start1 (/= 0 (logand b3 128))) ;logtest! + (start1b (/= 0 (logand b3 64))) + (start2 (/= 0 (logand b3 32))) + (start2b (/= 0 (logand b3 16))) + (end1 (/= 0 (logand b3 8))) + (end1b (/= 0 (logand b3 4))) + (end2 (/= 0 (logand b3 2))) + (end2b (/= 0 (logand b3 1))) + (prefix (/= 0 (logand code 128))) + (single-char-p (or (= spec ?<) (= spec ?>))) + ) + (write-char spec) + (write-char (if match match 32)) +;;; (if start1 (if single-char-p (write-char ?a) (write-char ?1))) + (if start1 (if single-char-p (write-char ? ) (write-char ?1))) + (if start2 (write-char ?2)) +;;; (if end1 (if single-char-p (write-char ?a) (write-char ?3))) + (if end1 (if single-char-p (write-char ? ) (write-char ?3))) + (if end2 (write-char ?4)) + (if start1b (if single-char-p (write-char ?b) (write-char ?5))) + (if start2b (write-char ?6)) + (if end1b (if single-char-p (write-char ?b) (write-char ?7))) + (if end2b (write-char ?8)) + (if prefix (write-char ?p))))))) + +(defun syntax-string-to-code (string) + "Return the internal syntax code equivalent to STRING. +STRING should be something acceptable as the second argument to +`modify-syntax-entry'. +If STRING is invalid, signal an error." + (let* ((bflag nil) + (b3 0) + (ch0 (aref string 0)) + (len (length string)) + (code (string-match (regexp-quote (char-to-string ch0)) + (syntax-designator-chars))) + (i 2) + ch) + (or code + (error "Invalid syntax designator: %S" string)) + (while (< i len) + (setq ch (aref string i)) + (incf i) + (case ch + (?1 (setq b3 (logior b3 128))) + (?2 (setq b3 (logior b3 32))) + (?3 (setq b3 (logior b3 8))) + (?4 (setq b3 (logior b3 2))) + (?5 (setq b3 (logior b3 64))) + (?6 (setq b3 (logior b3 16))) + (?7 (setq b3 (logior b3 4))) + (?8 (setq b3 (logior b3 1))) + (?a (case ch0 + (?< (setq b3 (logior b3 128))) + (?> (setq b3 (logior b3 8))))) + (?b (case ch0 + (?< (setq b3 (logior b3 64) bflag t)) + (?> (setq b3 (logior b3 4) bflag t)))) + (?p (setq code (logior code (lsh 1 7)))) + (?\ nil) ;; ignore for compatibility + (otherwise + (error "Invalid syntax description flag: %S" string)))) + ;; default single char style if `b' has not been seen + (if (not bflag) + (case ch0 + (?< (setq b3 (logior b3 128))) + (?> (setq b3 (logior b3 8))))) + (setq code (logior code (lsh b3 16))) + (if (and (> len 1) + ;; tough luck if you want to make space a paren! + (/= (aref string 1) ?\ )) + (setq code (cons code (aref string 1)))) + code)) + +(defun modify-syntax-entry (char-range spec &optional table) + "Set syntax for the characters CHAR-RANGE according to string SPEC. +CHAR-RANGE is a single character or a range of characters, + as per `put-char-table'. The syntax is changed only for table TABLE, which defaults to the current buffer's syntax table. -The first character of S should be one of the following: +The first character of SPEC should be one of the following: Space whitespace syntax. w word constituent. _ symbol constituent. . punctuation. \( open-parenthesis. \) close-parenthesis. \" string quote. \\ character-quote. $ paired delimiter. ' expression quote or prefix operator. < comment starter. > comment ender. - / character-quote. @ inherit from `standard-syntax-table'. + / character-quote. @ inherit from `standard-syntax-table'. Only single-character comment start and end sequences are represented thus. Two-character sequences are represented as described below. -The second character of S is the matching parenthesis, +The second character of SPEC is the matching parenthesis, used only if the first character is `(' or `)'. Any additional characters are flags. Defined flags are the characters 1, 2, 3, 4, 5, 6, 7, 8, p, a, and b. @@ -90,70 +183,25 @@ (t (setq table (wrong-type-argument 'syntax-table-p table)))) - (let* ((code nil) - (bflag nil) - (b3 0) - i) - (setq code (string-match (regexp-quote (char-to-string (elt spec 0))) - (syntax-designator-chars))) - (or code - (error "Invalid syntax designator: %S" spec)) - (setq i 2) - (while (< i (length spec)) - (let ((ch (elt spec i))) - (setq i (1+ i)) - (cond ((= ch ?1) - (setq b3 (logior b3 128))) - ((= ch ?2) - (setq b3 (logior b3 32))) - ((= ch ?3) - (setq b3 (logior b3 8))) - ((= ch ?4) - (setq b3 (logior b3 2))) - ((= ch ?5) - (setq b3 (logior b3 64))) - ((= ch ?6) - (setq b3 (logior b3 16))) - ((= ch ?7) - (setq b3 (logior b3 4))) - ((= ch ?8) - (setq b3 (logior b3 1))) - ((= ch ?a) - (cond ((= (elt spec 0) ?<) - (setq b3 (logior b3 128))) - ((= (elt spec 0) ?>) - (setq b3 (logior b3 8))))) - ((= ch ?b) - (cond ((= (elt spec 0) ?<) - (setq b3 (logior b3 64) - bflag t)) - ((= (elt spec 0) ?>) - (setq b3 (logior b3 4) - bflag t)))) - ((= ch ?p) - (setq code (logior code (lsh 1 7)))) - ((= ch ?\ ) - ;; ignore for compatibility - ) - (t - (error "Invalid syntax description flag: %S" spec))))) - ;; default single char style is a if b has not been seen - (if (not bflag) - (cond ((= (elt spec 0) ?<) - (setq b3 (logior b3 128))) - ((= (elt spec 0) ?>) - (setq b3 (logior b3 8))))) - (aset table - char - (logior code - (if (and (> (length spec) 1) - ;; tough luck if you want to make space a paren! - (/= (elt spec 1) ?\ )) - ;; tough luck if you want to make \000 a paren! - (lsh (elt spec 1) 8) - 0) - (lsh b3 16))) - nil)) + (let ((code (syntax-string-to-code spec))) + (simple-set-syntax-entry char-range code table)) + nil) + +(defun map-syntax-table (__function __table &optional __range) + "Map FUNCTION over entries in syntax table TABLE, collapsing inheritance. +This is similar to `map-char-table', but works only on syntax tables, and + collapses any entries that call for inheritance by invisibly substituting + the inherited values from the standard syntax table." + (check-argument-type 'syntax-table-p __table) + (map-char-table #'(lambda (__key __value) + (if (eq ?@ (char-syntax-from-code __value)) + (map-char-table #'(lambda (__key __value) + (funcall __function + __key __value)) + (standard-syntax-table) + __key) + (funcall __function __key __value))) + __table __range)) ;(defun test-xm () ; (let ((o (copy-syntax-table)) @@ -182,51 +230,115 @@ (defun describe-syntax-table (table stream) - (let* (;(limit (cond ((numberp ctl-arrow) ctl-arrow) -; ((memq ctl-arrow '(t nil)) 256) -; (t 160))) - (describe-one #'(lambda (first last) - (let* ((tem (text-char-description first)) - (pos (length tem))) - (princ tem stream) - (if (> last first) - (progn - (princ " .. " stream) - (setq tem (text-char-description last)) - (princ tem stream) - (setq pos (+ pos (length tem) 4)))) - (while (progn (write-char ?\ stream) - (setq pos (1+ pos)) - (< pos 16)))) - (describe-syntax-code (elt table first) stream)))) - (let ((range 0) - (i 0) - (code (elt table 0))) - (while (cond ((= i (length table)) - (funcall describe-one (1- i) (1- i)) - nil) - ((eq code (elt table i)) - t) - (t - (funcall describe-one range (1- i)) - (setq code (elt table i) - range i) - t)) - (setq i (1+ i)))))) + (let (first-char + last-char + prev-val + (describe-one + (if (featurep 'mule) + #'(lambda (first last value stream) + (if (equal first last) + (cond ((vectorp first) + (princ (format "%s, row %d\t" + (charset-name + (aref first 0)) + (aref first 1)) + stream)) + ((symbolp first) + (princ first stream) + (princ "\t" stream)) + (t + (princ (text-char-description first) stream) + (princ "\t" stream))) + (cond ((vectorp first) + (princ (format "%s, rows %d .. %d\t" + (charset-name + (aref first 0)) + (aref first 1) + (aref last 1)) + stream)) + ((symbolp first) + (princ (format "%s .. %s\t" first last) stream)) + (t + (princ (format "%s .. %s\t" + (text-char-description first) + (text-char-description last)) + stream)))) + (describe-syntax-code value stream)) + #'(lambda (first last value stream) + (let* ((tem (text-char-description first)) + (pos (length tem)) + ;;(limit (cond ((numberp ctl-arrow) ctl-arrow) + ;; ((memq ctl-arrow '(t nil)) 256) + ;; (t 160))) + ) + (princ tem stream) + (if (> last first) + (progn + (princ " .. " stream) + (setq tem (text-char-description last)) + (princ tem stream) + (setq pos (+ pos (length tem) 4)))) + (while (progn (write-char ?\ stream) + (setq pos (1+ pos)) + (< pos 16)))) + (describe-syntax-code value stream))))) + (map-syntax-table + #'(lambda (range value) + (cond + ((not first-char) + (setq first-char range + last-char range + prev-val value)) + ((and (equal value prev-val) + (or + (and (characterp range) + (characterp first-char) + (or (not (featurep 'mule)) + (eq (char-charset range) + (char-charset first-char))) + (= (char-int last-char) (1- (char-int range)))) + (and (vectorp range) + (vectorp first-char) + (eq (aref range 0) (aref first-char 0)) + (= (aref last-char 1) (1- (aref range 1)))))) + (setq last-char range)) + (t + (funcall describe-one first-char last-char prev-val stream) + (setq first-char range + last-char range + prev-val value))) + nil) + table) + (if first-char + (funcall describe-one first-char last-char prev-val stream)))) (defun describe-syntax-code (code stream) - (let ((codes (syntax-designator-chars)) + (let ((match (and (consp code) (cdr code))) (invalid (gettext "**invalid**")) ;(empty "") ;constants (standard-output (or stream standard-output)) ;; #### I18N3 should temporarily set buffer to output-translatable (in #'(lambda (string) (princ ",\n\t\t\t\t ") - (princ string)))) - (if (or (not (integerp code)) - (> (logand code 127) (length codes))) + (princ string))) + (syntax-string (syntax-code-to-string code))) + (if (consp code) + (setq code (car code))) + (if (null syntax-string) (princ invalid) - (let* ((spec (elt codes (logand code 127))) - (match (logand (lsh code -8) 255)) + (princ syntax-string) + (princ "\tmeaning: ") + (princ (aref ["whitespace" "punctuation" "word-constituent" + "symbol-constituent" "open-paren" "close-paren" + "expression-prefix" "string-quote" "paired-delimiter" + "escape" "character-quote" "comment-begin" "comment-end" + "inherit" "extended-word-constituent"] + (logand code 127))) + + (if match + (progn + (princ ", matches ") + (princ (text-char-description match)))) + (let* ((spec (elt syntax-string 0)) (b3 (lsh code -16)) (start1 (/= 0 (logand b3 128))) ;logtest! (start1b (/= 0 (logand b3 64))) @@ -237,61 +349,43 @@ (end2 (/= 0 (logand b3 2))) (end2b (/= 0 (logand b3 1))) (prefix (/= 0 (logand code 128))) - (single-char-p (or (= spec ?<) (= spec ?>))) - ) - (write-char spec) - (write-char (if (= 0 match) 32 match)) -;; (if start1 (if single-char-p (write-char ?a) (write-char ?1))) - (if start1 (if single-char-p (write-char ? ) (write-char ?1))) - (if start2 (write-char ?2)) -;; (if end1 (if single-char-p (write-char ?a) (write-char ?3))) - (if end1 (if single-char-p (write-char ? ) (write-char ?3))) - (if end2 (write-char ?4)) - (if start1b (if single-char-p (write-char ?b) (write-char ?5))) - (if start2b (write-char ?6)) - (if end1b (if single-char-p (write-char ?b) (write-char ?7))) - (if end2b (write-char ?8)) - (if prefix (write-char ?p)) - - (princ "\tmeaning: ") - (princ (aref ["whitespace" "punctuation" "word-constituent" - "symbol-constituent" "open-paren" "close-paren" - "expression-prefix" "string-quote" "paired-delimiter" - "escape" "character-quote" "comment-begin" "comment-end" - "inherit" "extended-word-constituent"] - (logand code 127))) - - (if (/= 0 match) - (progn - (princ ", matches ") - (princ (text-char-description match)))) + (single-char-p (or (= spec ?<) (= spec ?>)))) (if start1 (if single-char-p (princ ", style A") - (funcall in (gettext "first character of comment-start sequence A")))) + (funcall in + (gettext "first character of comment-start sequence A")))) (if start2 - (funcall in (gettext "second character of comment-start sequence A"))) + (funcall in + (gettext "second character of comment-start sequence A"))) (if end1 (if single-char-p (princ ", style A") - (funcall in (gettext "first character of comment-end sequence A")))) + (funcall in + (gettext "first character of comment-end sequence A")))) (if end2 - (funcall in (gettext "second character of comment-end sequence A"))) + (funcall in + (gettext "second character of comment-end sequence A"))) (if start1b (if single-char-p (princ ", style B") - (funcall in (gettext "first character of comment-start sequence B")))) + (funcall in + (gettext "first character of comment-start sequence B")))) (if start2b - (funcall in (gettext "second character of comment-start sequence B"))) + (funcall in + (gettext "second character of comment-start sequence B"))) (if end1b (if single-char-p (princ ", style B") - (funcall in (gettext "first character of comment-end sequence B")))) + (funcall in + (gettext "first character of comment-end sequence B")))) (if end2b - (funcall in (gettext "second character of comment-end sequence B"))) + (funcall in + (gettext "second character of comment-end sequence B"))) (if prefix - (funcall in (gettext "prefix character for `backward-prefix-chars'"))))) - (terpri stream))) + (funcall in + (gettext "prefix character for `backward-prefix-chars'")))) + (terpri stream)))) (defun symbol-near-point () "Return the first textual item to the nearest point."