PageRenderTime 66ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/old-archive/epoch/tek-epoch-stuff-1.1/syntax-decode.el

https://github.com/emacsmirror/ohio-archive
Emacs Lisp | 262 lines | 157 code | 21 blank | 84 comment | 6 complexity | e15435cbf54e3fc70c90acbbb818e3b9 MD5 | raw file
  1. ;*****************************************************************************
  2. ;
  3. ; Filename: syntax-decode.el
  4. ;
  5. ; Copyright (C) 1991 Ken Wood
  6. ;
  7. ; This program is free software; you can redistribute it and/or modify
  8. ; it under the terms of the GNU General Public License as published by
  9. ; the Free Software Foundation; either version 1, or (at your option)
  10. ; any later version.
  11. ;
  12. ; This program is distributed in the hope that it will be useful,
  13. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ; GNU General Public License for more details.
  16. ;
  17. ; You should have received a copy of the GNU General Public License
  18. ; along with this program; if not, write to the Free Software
  19. ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;
  21. ; Author: Ken Wood, <kwood@austek.oz.au>
  22. ; Organisation: Austek Microsystems Pty Ltd, Australia.
  23. ; Released with permission from Austek Microsystems.
  24. ;
  25. ; Description: Calculate regular expressions used to match comments in the
  26. ; current major mode. Also calculates strings that may be used
  27. ; to begin & end comments in the major mode.
  28. ;
  29. ; The values calculated are assigned to the buffer-local
  30. ; variables syndecode-comment-start-regexp,
  31. ; syndecode-comment-end-regexp, syndecode-comment-start-string,
  32. ; and syndecode-comment-end-string.
  33. ;
  34. ; If the function decode-syntax-table is run more than once in
  35. ; the same buffer, later invocations do nothing. Each time a new
  36. ; syntax table is decoded, its data is "cached" for use next
  37. ; time that mode is encountered.
  38. ;
  39. ; It should prove fairly simple to extract extra features from
  40. ; the syntax table - drop me a line if you need something else
  41. ; and we can work something out.
  42. ;
  43. ; To install this package so that other packages can use it,
  44. ; add this line to your .emacs:
  45. ;
  46. ; (autoload 'decode-syntax-table "syntax-decode" "autoloadable function" t)
  47. ;
  48. ;*****************************************************************************
  49. ; $Id: syntax-decode.el,v 1.7 1991/10/23 02:16:57 kwood Exp $
  50. (provide 'syntax-decode)
  51. (defvar syndecode-comment-start-regexp nil
  52. "\
  53. Regexp to match the start of comments in the current mode. This value
  54. is more reliable than the comment-start variable, since it is
  55. determined directly from the syntax table. Will be nil if comments are
  56. not defined in the current syntax table.")
  57. (defvar syndecode-comment-end-regexp nil
  58. "\
  59. Regexp to match the end of comments in the current mode. This value is
  60. more reliable than the comment-end variable, since it is determined
  61. directly from the syntax table. Will be nil if comments are not
  62. defined in the current syntax table.")
  63. (defvar syndecode-comment-start-string nil
  64. "\
  65. Preferred string to be used to begin comments in the current mode.
  66. Will be nil if comments are not defined in the current syntax table.")
  67. (defvar syndecode-comment-end-string nil
  68. "\
  69. Preferred string to be used to terminate comments in the current mode.
  70. Will be nil if comments are not defined in the current syntax table or if
  71. comments can be terminated by a newline.")
  72. (defvar syndecode-done-this-buffer nil
  73. "\
  74. Buffer-local variable indicating whether the syntax table for this buffer
  75. has been decoded or not.")
  76. (make-variable-buffer-local 'syndecode-comment-start-regexp)
  77. (make-variable-buffer-local 'syndecode-comment-end-regexp)
  78. (make-variable-buffer-local 'syndecode-comment-start-string)
  79. (make-variable-buffer-local 'syndecode-comment-end-string)
  80. (make-variable-buffer-local 'syndecode-done-this-buffer)
  81. (defvar syndecode-mode-feature-alist nil
  82. "\
  83. Alist of major modes and their associated comment data as extracted
  84. from the syntax table. Acts as a cache when syntax-decode is run
  85. under the same major mode more than once.")
  86. ; ***** decode-syntax-table *****
  87. (defun decode-syntax-table ()
  88. "\
  89. Parse the syntax table for the current mode and figure set the variables
  90. `syndecode-comment-start-regexp', `syndecode-comment-end-regexp',
  91. `syndecode-comment-start-string' and `syndecode-comment-end-string'."
  92. ; Check to make sure this buffer hasn't already been done first.
  93. (if (not syndecode-done-this-buffer)
  94. ; First check to see if the syntax table for this mode has been
  95. ; decoded at some time in the past, by checking in the "cache"
  96. ; for the previously extracted values.
  97. (let* ((cached-syntax-list (assq major-mode
  98. syndecode-mode-feature-alist)))
  99. (if cached-syntax-list
  100. (progn
  101. (setq cached-syntax-list (cadr cached-syntax-list))
  102. (setq syndecode-comment-start-regexp (nth 0 cached-syntax-list))
  103. (setq syndecode-comment-end-regexp (nth 1 cached-syntax-list))
  104. (setq syndecode-comment-start-string (nth 2 cached-syntax-list))
  105. (setq syndecode-comment-end-string (nth 3 cached-syntax-list))
  106. )
  107. ; If not cached, then must calculate the value from the current
  108. ; syntax table.
  109. (progn
  110. ; Iterate over the syntax table & decode each character.
  111. (let (
  112. (debug-on-error t)
  113. (tmp-syntax-table (append (syntax-table) nil))
  114. (table-index 0)
  115. (code nil)
  116. (stripped-code nil)
  117. (char nil)
  118. (comm-start-string nil)
  119. (comm-end-string nil)
  120. (char1-long-comm-start nil)
  121. (char2-long-comm-start nil)
  122. (char1-long-comm-end nil)
  123. (char2-long-comm-end nil)
  124. (long-comm-start-string nil)
  125. (long-comm-end-string nil)
  126. temp-alist-cell
  127. )
  128. (while (and (< table-index 255) tmp-syntax-table)
  129. (progn
  130. ; Extract the current code & character
  131. (setq code (car tmp-syntax-table))
  132. (setq char (char-to-string table-index))
  133. (setq stripped-code (logand code 255))
  134. ; First, check if the flags for two-character comments are set
  135. (if (/= 0 (logand (lsh code -16) 1))
  136. (setq char1-long-comm-start char))
  137. (if (/= 0 (logand (lsh code -17) 1))
  138. (setq char2-long-comm-start char))
  139. (if (/= 0 (logand (lsh code -18) 1))
  140. (setq char1-long-comm-end char))
  141. (if (/= 0 (logand (lsh code -19) 1))
  142. (setq char2-long-comm-end char))
  143. ; Now check for single-character comments
  144. (if (= stripped-code 11)
  145. (setq comm-start-string (concat comm-start-string char)))
  146. ; else
  147. (if (= stripped-code 12)
  148. (setq comm-end-string (concat comm-end-string char)))
  149. ; Move to the next element of the syntax table.
  150. (setq table-index (+ table-index 1))
  151. (setq tmp-syntax-table (cdr tmp-syntax-table))
  152. ))
  153. ; Now, build the long (two character) comment strings, if their
  154. ; component variables are defined.
  155. (if (and char1-long-comm-start char2-long-comm-start)
  156. (progn
  157. (setq long-comm-start-string (concat char1-long-comm-start
  158. char2-long-comm-start))
  159. (setq syndecode-comment-start-regexp
  160. (concat (regexp-quote char1-long-comm-start)
  161. (regexp-quote char2-long-comm-start)))))
  162. (if (and char1-long-comm-end char2-long-comm-end)
  163. (progn
  164. (setq long-comm-end-string (concat char1-long-comm-end
  165. char2-long-comm-end))
  166. (setq syndecode-comment-end-regexp
  167. (concat (regexp-quote char1-long-comm-end)
  168. (regexp-quote char2-long-comm-end)))))
  169. ; Now create the comment start & end regexps from the comment start &
  170. ; end strings.
  171. ; Extract each character from comm-start-string and add it
  172. ; verbatim to comment-start-regexp, a list of alternatives.
  173. (let ((comm-start-index 0)
  174. (comm-start-length (length comm-start-string)))
  175. (while (< comm-start-index comm-start-length)
  176. (progn
  177. (if syndecode-comment-start-regexp
  178. (setq syndecode-comment-start-regexp
  179. (concat syndecode-comment-start-regexp "\\|"
  180. (regexp-quote (substring comm-start-string
  181. comm-start-index
  182. (1+ comm-start-index)))))
  183. (setq syndecode-comment-start-regexp
  184. (regexp-quote (substring comm-start-string
  185. comm-start-index
  186. (1+ comm-start-index)))))
  187. (setq comm-start-index (1+ comm-start-index)))))
  188. ; Extract each character from comm-end-string and add it
  189. ; verbatim to comment-end-regexp, a list of alternatives.
  190. (let ((comm-end-index 0)
  191. (comm-end-length (length comm-end-string)))
  192. (while (< comm-end-index comm-end-length)
  193. (progn
  194. (if syndecode-comment-end-regexp
  195. (setq syndecode-comment-end-regexp
  196. (concat syndecode-comment-end-regexp "\\|"
  197. (regexp-quote (substring comm-end-string
  198. comm-end-index
  199. (1+ comm-end-index)))))
  200. (setq syndecode-comment-end-regexp
  201. (regexp-quote (substring comm-end-string
  202. comm-end-index
  203. (1+ comm-end-index)))))
  204. (setq comm-end-index (1+ comm-end-index)))))
  205. ; Set up the comment start string.
  206. (setq syndecode-comment-start-string
  207. ; Prefer the two-character comment sequence
  208. (or long-comm-start-string
  209. ; Failing that, use one of the single character comment starting
  210. ; sequences.
  211. (if comm-start-string
  212. (substring comm-start-string -1))))
  213. ; Now, set up the comment end string.
  214. (setq syndecode-comment-end-string
  215. ; Set it to nil if newlines can terminate comments
  216. (and (not (and comm-end-string
  217. (string-match "\n" comm-end-string)))
  218. ; Otherwise, prefer the two character comment sequence
  219. (or long-comm-end-string
  220. ; Failing that, one of the single character comment
  221. ; terminators.
  222. (if comm-end-string
  223. (substring comm-end-string -1)))))
  224. ; Store the newly determined syntax features into the syntax
  225. ; "cache" for lookup if this mode is encountered again later.
  226. (setq temp-alist-cell
  227. (list (list major-mode
  228. (list syndecode-comment-start-regexp
  229. syndecode-comment-end-regexp
  230. syndecode-comment-start-string
  231. syndecode-comment-end-string))))
  232. ; Add the current syntax features to the cache.
  233. (if syndecode-mode-feature-alist
  234. (setq syndecode-mode-feature-alist
  235. (append temp-alist-cell syndecode-mode-feature-alist))
  236. (setq syndecode-mode-feature-alist temp-alist-cell))
  237. ))))
  238. ; Set a flag to indicate the syntax table in this buffer has been
  239. ; decoded.
  240. (setq syndecode-done-this-buffer t)
  241. )) ; end of defun