Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
7.7 KiB

4 years ago
  1. ;; haskell-c2hs.el --- -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2016 Sergey Vinokurov
  3. ;;
  4. ;; Author: Sergey Vinokurov <serg.foo@gmail.com>
  5. ;; Created: Monday, 7 March 2016
  6. ;; This program is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; This program is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; This mode is mostly intended for highlighting {#...#} hooks.
  18. ;;
  19. ;; Quick setup:
  20. ;; (autoload 'haskell-c2hs-mode "haskell-c2hs-mode" nil t)
  21. ;; (add-to-list 'auto-mode-alist '("\\.chs\\'" . haskell-c2hs-mode))
  22. ;;
  23. (require 'haskell-mode)
  24. (require 'haskell-font-lock)
  25. (require 'haskell-utils)
  26. ;;;###autoload
  27. (add-to-list 'auto-mode-alist '("\\.chs\\'" . haskell-c2hs-mode))
  28. (defface haskell-c2hs-hook-pair-face
  29. '((t (:inherit 'font-lock-preprocessor-face)))
  30. "Face for highlighting {#...#} pairs."
  31. :group 'haskell)
  32. (defface haskell-c2hs-hook-name-face
  33. '((t (:inherit 'font-lock-keyword-face)))
  34. "Face for highlighting c2hs hook names."
  35. :group 'haskell)
  36. (defvar haskell-c2hs-font-lock-keywords
  37. `((,(eval-when-compile
  38. (let* ((ws '(any ?\s ?\t ?\n ?\r))
  39. (anychar '(or (not (any ?#))
  40. (seq "#"
  41. (not (any ?\})))))
  42. (any-nonquote '(or (not (any ?# ?\"))
  43. (seq "#"
  44. (not (any ?\} ?\")))))
  45. (cid '(seq (any (?a . ?z) (?A . ?Z) ?_)
  46. (* (any (?a . ?z) (?A . ?Z) (?0 . ?9) ?_))))
  47. (hsid-type '(seq (? "'")
  48. (any (?A . ?Z))
  49. (* (any (?a . ?z) (?A . ?Z) (?0 . ?9) ?_ ?'))))
  50. (equals-str-val `(seq (* ,ws)
  51. "="
  52. (* ,ws)
  53. "\""
  54. (* ,any-nonquote)
  55. "\"")))
  56. (eval
  57. `(rx
  58. (seq
  59. (group-n 1 "{#")
  60. (* ,ws)
  61. (or (seq (group-n 2
  62. "import"
  63. (opt (+ ,ws)
  64. "qualified"))
  65. (+ ,ws))
  66. (seq (group-n 2
  67. "context")
  68. (opt (+ ,ws)
  69. (group-n 3
  70. "lib")
  71. ,equals-str-val)
  72. (opt (+ ,ws)
  73. (group-n 4
  74. "prefix")
  75. ,equals-str-val)
  76. (opt (+ ,ws)
  77. (group-n 5
  78. "add"
  79. (+ ,ws)
  80. "prefix")
  81. ,equals-str-val))
  82. (seq (group-n 2
  83. "type")
  84. (+ ,ws)
  85. ,cid)
  86. (seq (group-n 2
  87. "sizeof")
  88. (+ ,ws)
  89. ,cid)
  90. (seq (group-n 2
  91. "enum"
  92. (+ ,ws)
  93. "define")
  94. (+ ,ws)
  95. ,cid)
  96. ;; TODO: vanilla enum fontification is incomplete
  97. (seq (group-n 2
  98. "enum")
  99. (+ ,ws)
  100. ,cid
  101. (opt (+ ,ws)
  102. (group-n 3
  103. "as")))
  104. ;; TODO: fun hook highlighting is incompelete
  105. (seq (group-n 2
  106. (or "call"
  107. "fun")
  108. (opt (+ ,ws)
  109. "pure")
  110. (opt (+ ,ws)
  111. "unsafe"))
  112. (+ ,ws)
  113. ,cid
  114. (opt (+ ,ws)
  115. (group-n 3
  116. "as")
  117. (opt (+ ,ws)
  118. (group-n 8
  119. "^"))))
  120. (group-n 2
  121. "get")
  122. (group-n 2
  123. "set")
  124. (seq (group-n 2
  125. "pointer")
  126. (or (seq (* ,ws)
  127. (group-n 3 "*")
  128. (* ,ws))
  129. (+ ,ws))
  130. ,cid
  131. (opt (+ ,ws)
  132. (group-n 4 "as")
  133. (+ ,ws)
  134. ,hsid-type)
  135. (opt (+ ,ws)
  136. (group-n 5
  137. (or "foreign"
  138. "stable")))
  139. (opt
  140. (or (seq (+ ,ws)
  141. (group-n 6
  142. "newtype"))
  143. (seq (* ,ws)
  144. "->"
  145. (* ,ws)
  146. ,hsid-type)))
  147. (opt (+ ,ws)
  148. (group-n 7
  149. "nocode")))
  150. (group-n 2
  151. "class")
  152. (group-n 2
  153. "alignof")
  154. (group-n 2
  155. "offsetof")
  156. (seq (group-n 2
  157. "const")
  158. (+ ,ws)
  159. ,cid)
  160. (seq (group-n 2
  161. "typedef")
  162. (+ ,ws)
  163. ,cid
  164. (+ ,ws)
  165. ,hsid-type)
  166. (group-n 2
  167. "nonGNU")
  168. ;; TODO: default hook not implemented
  169. )
  170. (* ,anychar)
  171. (group-n 9 "#}"))))))
  172. ;; Override highlighting for pairs in order to always distinguish them.
  173. (1 'haskell-c2hs-hook-pair-face t)
  174. (2 'haskell-c2hs-hook-name-face)
  175. ;; Make matches lax, i.e. do not signal error if nothing
  176. ;; matched.
  177. (3 'haskell-c2hs-hook-name-face nil t)
  178. (4 'haskell-c2hs-hook-name-face nil t)
  179. (5 'haskell-c2hs-hook-name-face nil t)
  180. (6 'haskell-c2hs-hook-name-face nil t)
  181. (7 'haskell-c2hs-hook-name-face nil t)
  182. (8 'font-lock-negation-char-face nil t)
  183. ;; Override highlighting for pairs in order to always distinguish them.
  184. (9 'haskell-c2hs-hook-pair-face t))
  185. ,@(haskell-font-lock-keywords)))
  186. ;;;###autoload
  187. (define-derived-mode haskell-c2hs-mode haskell-mode "C2HS"
  188. "Mode for editing *.chs files of the c2hs haskell tool."
  189. (setq-local font-lock-defaults
  190. (cons 'haskell-c2hs-font-lock-keywords
  191. (cdr font-lock-defaults))))
  192. (provide 'haskell-c2hs)
  193. ;; haskell-c2hs.el ends here