diff lisp/prim/syntax.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 0293115a14e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/prim/syntax.el	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,313 @@
+;; Syntax-table hacking stuff, moved from syntax.c
+;; Copyright (C) 1993 Free Software Foundation, Inc.
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; 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, 675 Mass Ave, Cambridge, MA 02139, 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.
+
+(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)))
+
+(defun modify-syntax-entry (char spec &optional table)
+  "Set syntax for character CHAR according to string S.
+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:
+  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'.
+
+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,
+ 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.
+ 1 means C is the first of a two-char comment start sequence of style a.
+ 2 means C is the second character of such a sequence.
+ 3 means C is the first of a two-char comment end sequence of style a.
+ 4 means C is the second character of such a sequence.
+ 5 means C is the first of a two-char comment start sequence of style b.
+ 6 means C is the second character of such a sequence.
+ 7 means C is the first of a two-char comment end sequence of style b.
+ 8 means C is the second character of such a sequence.
+ p means C is a prefix character for `backward-prefix-chars';
+   such characters are treated as whitespace when they occur
+   between expressions.
+ a means C is comment starter or comment ender for comment style a (default)
+ b means C is comment starter or comment ender for comment style b."
+  (interactive 
+   ;; I really don't know why this is interactive
+   ;; help-form should at least be made useful whilst reading the second arg
+   "cSet syntax for character: \nsSet syntax for %c to: ")
+  (cond ((syntax-table-p table))
+        ((not table)
+         (setq table (syntax-table)))
+        (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))
+
+;(defun test-xm ()
+;  (let ((o (copy-syntax-table))
+;        (n (copy-syntax-table))
+;        (codes (syntax-designator-chars))
+;        (flags "12345678abp"))
+;    (while t
+;      (let ((spec (concat (char-to-string (elt codes
+;						(random (length codes))))))
+;                          (if (= (random 4) 0)
+;                              "b"
+;                              " ")
+;                          (let* ((n (random 4))
+;                                 (s (make-string n 0)))
+;                            (while (> n 0)
+;                              (setq n (1- n))
+;                              (aset s n (aref flags (random (length flags)))))
+;                            s))))
+;        (message "%S..." spec)
+;        (modify-syntax-entry ?a spec o)
+;        (xmodify-syntax-entry ?a spec n)
+;        (or (= (aref o ?a) (aref n ?a))
+;            (error "%s"
+;                   (format "fucked with %S: %x %x"
+;                           spec (aref o ?a) (aref n ?a))))))))
+
+
+(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))))))
+
+(defun describe-syntax-code (code stream)
+  (let ((codes (syntax-designator-chars))
+	(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 invalid)
+      (let* ((spec (elt codes (logand code 127)))
+	     (match (logand (lsh code -8) 255))
+	     (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 (= 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))))
+	(if start1
+	    (if single-char-p
+		(princ ", style A")
+              (funcall in (gettext "first character of comment-start sequence A"))))
+	(if start2
+	    (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"))))
+	(if end2
+	    (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"))))
+	(if start2b
+	    (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"))))
+	(if end2b
+	    (funcall in (gettext "second character of comment-end sequence B")))
+	(if prefix
+	    (funcall in (gettext "prefix character for `backward-prefix-chars'")))))
+    (terpri stream)))
+
+(defun symbol-near-point ()
+  "Return the first textual item to the nearest point."
+  (interactive)
+  ;alg stolen from etag.el
+  (save-excursion
+	(if (not (memq (char-syntax (preceding-char)) '(?w ?_)))
+	    (while (not (looking-at "\\sw\\|\\s_\\|\\'"))
+	      (forward-char 1)))
+	(while (looking-at "\\sw\\|\\s_")
+	  (forward-char 1))
+	(if (re-search-backward "\\sw\\|\\s_" nil t)
+	    (regexp-quote
+	     (progn (forward-char 1)
+		    (buffer-substring (point)
+				      (progn (forward-sexp -1)
+					     (while (looking-at "\\s'")
+					       (forward-char 1))
+					     (point)))))
+	  nil)))