sieve-mode.el 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. ;;; sieve-mode.el --- Sieve code editing commands for Emacs
  2. ;; Copyright (C) 2001-2017 Free Software Foundation, Inc.
  3. ;; Author: Simon Josefsson <simon@josefsson.org>
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; This file contain editing mode functions and font-lock support for
  17. ;; editing Sieve scripts. It sets up C-mode with support for
  18. ;; sieve-style #-comments and a lightly hacked syntax table. It was
  19. ;; strongly influenced by awk-mode.el.
  20. ;;
  21. ;; Put something similar to the following in your .emacs to use this file:
  22. ;;
  23. ;; (load "~/lisp/sieve")
  24. ;; (setq auto-mode-alist (cons '("\\.siv\\'" . sieve-mode) auto-mode-alist))
  25. ;;
  26. ;; References:
  27. ;;
  28. ;; RFC 3028,
  29. ;; "Sieve: A Mail Filtering Language",
  30. ;; by Tim Showalter.
  31. ;;
  32. ;; Release history:
  33. ;;
  34. ;; 2001-03-02 version 1.0 posted to gnu.emacs.sources
  35. ;; version 1.1 change file extension into ".siv" (official one)
  36. ;; added keymap and menubar to hook into sieve-manage
  37. ;; 2001-10-31 version 1.2 committed to Oort Gnus
  38. ;;; Code:
  39. (autoload 'sieve-manage "sieve")
  40. (autoload 'sieve-upload "sieve")
  41. (eval-when-compile
  42. (require 'font-lock))
  43. (defgroup sieve nil
  44. "Sieve."
  45. :group 'languages)
  46. (defcustom sieve-mode-hook nil
  47. "Hook run in sieve mode buffers."
  48. :type 'hook)
  49. ;; Font-lock
  50. (defface sieve-control-commands
  51. '((((type tty) (class color)) (:foreground "blue" :weight light))
  52. (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
  53. (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
  54. (((class color) (background light)) (:foreground "Orchid"))
  55. (((class color) (background dark)) (:foreground "LightSteelBlue"))
  56. (t (:bold t)))
  57. "Face used for Sieve Control Commands.")
  58. (defface sieve-action-commands
  59. '((((type tty) (class color)) (:foreground "blue" :weight bold))
  60. (((class color) (background light)) (:foreground "Blue"))
  61. (((class color) (background dark)) (:foreground "LightSkyBlue"))
  62. (t (:inverse-video t :bold t)))
  63. "Face used for Sieve Action Commands.")
  64. (defface sieve-test-commands
  65. '((((type tty) (class color)) (:foreground "magenta"))
  66. (((class grayscale) (background light))
  67. (:foreground "LightGray" :bold t :underline t))
  68. (((class grayscale) (background dark))
  69. (:foreground "Gray50" :bold t :underline t))
  70. (((class color) (background light)) (:foreground "CadetBlue"))
  71. (((class color) (background dark)) (:foreground "Aquamarine"))
  72. (t (:bold t :underline t)))
  73. "Face used for Sieve Test Commands.")
  74. (defface sieve-tagged-arguments
  75. '((((type tty) (class color)) (:foreground "cyan" :weight bold))
  76. (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
  77. (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
  78. (((class color) (background light)) (:foreground "Purple"))
  79. (((class color) (background dark)) (:foreground "Cyan"))
  80. (t (:bold t)))
  81. "Face used for Sieve Tagged Arguments.")
  82. (defconst sieve-font-lock-keywords
  83. (eval-when-compile
  84. (list
  85. ;; control commands
  86. (cons (regexp-opt '("require" "if" "else" "elsif" "stop")
  87. 'words)
  88. 'sieve-control-commands)
  89. ;; action commands
  90. (cons (regexp-opt '("fileinto" "redirect" "reject" "keep" "discard")
  91. 'words)
  92. 'sieve-action-commands)
  93. ;; test commands
  94. (cons (regexp-opt '("address" "allof" "anyof" "exists" "false"
  95. "true" "header" "not" "size" "envelope"
  96. "body")
  97. 'words)
  98. 'sieve-test-commands)
  99. (cons "\\Sw+:\\sw+"
  100. 'sieve-tagged-arguments))))
  101. ;; Syntax table
  102. (defvar sieve-mode-syntax-table
  103. (let ((st (make-syntax-table)))
  104. (modify-syntax-entry ?\\ "\\" st)
  105. (modify-syntax-entry ?\n "> " st)
  106. (modify-syntax-entry ?\f "> " st)
  107. (modify-syntax-entry ?\# "< " st)
  108. (modify-syntax-entry ?/ ". 14" st)
  109. (modify-syntax-entry ?* ". 23b" st)
  110. (modify-syntax-entry ?+ "." st)
  111. (modify-syntax-entry ?- "." st)
  112. (modify-syntax-entry ?= "." st)
  113. (modify-syntax-entry ?% "." st)
  114. (modify-syntax-entry ?< "." st)
  115. (modify-syntax-entry ?> "." st)
  116. (modify-syntax-entry ?& "." st)
  117. (modify-syntax-entry ?| "." st)
  118. (modify-syntax-entry ?_ "_" st)
  119. (modify-syntax-entry ?\' "\"" st)
  120. st)
  121. "Syntax table in use in sieve-mode buffers.")
  122. ;; Key map definition
  123. (defvar sieve-mode-map
  124. (let ((map (make-sparse-keymap)))
  125. (define-key map "\C-c\C-l" 'sieve-upload)
  126. (define-key map "\C-c\C-c" 'sieve-upload-and-kill)
  127. (define-key map "\C-c\C-m" 'sieve-manage)
  128. map)
  129. "Key map used in sieve mode.")
  130. ;; Menu
  131. (easy-menu-define sieve-mode-menu sieve-mode-map
  132. "Sieve Menu."
  133. '("Sieve"
  134. ["Upload script" sieve-upload t]
  135. ["Manage scripts on server" sieve-manage t]))
  136. ;; Code for Sieve editing mode.
  137. (defun sieve-syntax-propertize (beg end)
  138. (goto-char beg)
  139. (sieve-syntax-propertize-text end)
  140. (funcall
  141. (syntax-propertize-rules
  142. ;; FIXME: When there's a "text:" with a # comment, the \n plays dual role:
  143. ;; it closes the comment and starts the string. This is problematic for us
  144. ;; since syntax-table entries can either close a comment or
  145. ;; delimit a string, but not both.
  146. ("\\_<text:[ \t]*\\(?:#.*\\(.\\)\\)?\\(\n\\)"
  147. (1 ">")
  148. (2 (prog1 (unless (save-excursion
  149. (nth 8 (syntax-ppss (match-beginning 0))))
  150. (string-to-syntax "|"))
  151. (sieve-syntax-propertize-text end)))))
  152. beg end))
  153. (defun sieve-syntax-propertize-text (end)
  154. (let ((ppss (syntax-ppss)))
  155. (when (and (eq t (nth 3 ppss))
  156. (re-search-forward "^\\.\\(\n\\)" end 'move))
  157. (put-text-property (match-beginning 1) (match-end 1)
  158. 'syntax-table (string-to-syntax "|")))))
  159. ;;;###autoload
  160. (define-derived-mode sieve-mode c-mode "Sieve"
  161. "Major mode for editing Sieve code.
  162. This is much like C mode except for the syntax of comments. Its keymap
  163. inherits from C mode's and it has the same variables for customizing
  164. indentation. It has its own abbrev table and its own syntax table.
  165. Turning on Sieve mode runs `sieve-mode-hook'."
  166. (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
  167. (set (make-local-variable 'paragraph-separate) paragraph-start)
  168. (set (make-local-variable 'comment-start) "#")
  169. (set (make-local-variable 'comment-end) "")
  170. ;;(set (make-local-variable 'comment-start-skip) "\\(^\\|\\s-\\);?#+ *")
  171. (set (make-local-variable 'comment-start-skip) "#+ *")
  172. (set (make-local-variable 'syntax-propertize-function)
  173. #'sieve-syntax-propertize)
  174. (set (make-local-variable 'font-lock-defaults)
  175. '(sieve-font-lock-keywords nil nil ((?_ . "w"))))
  176. (easy-menu-add-item nil nil sieve-mode-menu))
  177. (provide 'sieve-mode)
  178. ;; sieve-mode.el ends here