Function: haskell-font-lock-keywords
haskell-font-lock-keywords is a natively compiled function defined in
haskell-font-lock.el.
Signature
(haskell-font-lock-keywords)
Documentation
Generate font lock eywords.
Source Code
;; Defined in /nix/store/9lz2mhw95f9fqxr9mnq46k3f6qz3aq83-emacs-packages-deps/share/emacs/site-lisp/elpa/haskell-mode-20260904.1042/haskell-font-lock.el
(defun haskell-font-lock-keywords ()
;; this has to be a function because it depends on global value of
;; `haskell-font-lock-symbols'
"Generate font lock eywords."
(let* (;; Bird-style literate scripts start a line of code with
;; "^>", otherwise a line of code starts with "^".
(line-prefix "^\\(?:> ?\\)?")
(varid "[[:lower:]_][[:alnum:]'_]*")
;; We allow ' preceding conids because of DataKinds/PolyKinds
(conid "'?[[:upper:]][[:alnum:]'_]*")
(sym "\\s.+")
;; Top-level declarations
(topdecl-var
(concat line-prefix "\\(" varid "\\(?:\\s-*,\\s-*" varid "\\)*" "\\)"
;; optionally allow for a single newline after identifier
"\\(\\s-+\\|\\s-*[\n]\\s-+\\)"
;; A toplevel declaration can be followed by a definition
;; (=), a type (::) or (∷), a guard, or a pattern which can
;; either be a variable, a constructor, a parenthesized
;; thingy, or an integer or a string.
"\\(" varid "\\|" conid "\\|::\\|∷\\|=\\||\\|\\s(\\|[0-9\"']\\)"))
(topdecl-var2
(concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*`\\(" varid "\\)`"))
(topdecl-bangpat
(concat line-prefix "\\(" varid "\\)\\s-*!"))
(topdecl-sym
(concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*\\(" sym "\\)"))
(topdecl-sym2 (concat line-prefix "(\\(" sym "\\))"))
keywords)
(setq keywords
`(;; NOTICE the ordering below is significant
;;
("^#\\(?:[^\\\n]\\|\\\\\\(?:.\\|\n\\|\\'\\)\\)*\\(?:\n\\|\\'\\)" 0 'font-lock-preprocessor-face t)
,@(haskell-font-lock-symbols-keywords)
;; Special case for `as', `hiding', `safe' and `qualified', which are
;; keywords in import statements but are not otherwise reserved.
("\\<import[ \t]+\\(?:\\(safe\\>\\)[ \t]*\\)?\\(?:\\(qualified\\>\\)[ \t]*\\)?\\(?:\"[^\"]*\"[\t ]*\\)?[^ \t\n()]+[ \t]*\\(?:\\(qualified\\>\\)[ \t]*\\)?\\(?:\\(\\<as\\>\\)[ \t]*[^ \t\n()]+[ \t]*\\)?\\(\\<hiding\\>\\)?"
(1 'haskell-keyword-face nil lax)
(2 'haskell-keyword-face nil lax)
(3 'haskell-keyword-face nil lax)
(4 'haskell-keyword-face nil lax)
(5 'haskell-keyword-face nil lax))
;; Special case for `foreign import'
;; keywords in foreign import statements but are not otherwise reserved.
("\\<\\(foreign\\)[ \t]+\\(import\\)[ \t]+\\(?:\\(ccall\\|capi\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?\\(?:\\(safe\\|unsafe\\|interruptible\\)[ \t]+\\)?"
(1 'haskell-keyword-face nil lax)
(2 'haskell-keyword-face nil lax)
(3 'haskell-keyword-face nil lax)
(4 'haskell-keyword-face nil lax))
;; Special case for `foreign export'
;; keywords in foreign export statements but are not otherwise reserved.
("\\<\\(foreign\\)[ \t]+\\(export\\)[ \t]+\\(?:\\(ccall\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?"
(1 'haskell-keyword-face nil lax)
(2 'haskell-keyword-face nil lax)
(3 'haskell-keyword-face nil lax))
;; Special case for `type family' and `data family'.
;; `family' is only reserved in these contexts.
("\\<\\(type\\|data\\)[ \t]+\\(family\\>\\)"
(1 'haskell-keyword-face nil lax)
(2 'haskell-keyword-face nil lax))
;; Special case for `type role'
;; `role' is only reserved in this context.
("\\<\\(type\\)[ \t]+\\(role\\>\\)"
(1 'haskell-keyword-face nil lax)
(2 'haskell-keyword-face nil lax))
;; Toplevel Declarations.
;; Place them *before* generic id-and-op highlighting.
(,topdecl-var (1 (unless (member (match-string 1) haskell-font-lock-keywords)
'haskell-definition-face)))
(,topdecl-var2 (2 (unless (member (match-string 2) haskell-font-lock-keywords)
'haskell-definition-face)))
(,topdecl-bangpat (1 (unless (member (match-string 1) haskell-font-lock-keywords)
'haskell-definition-face)))
(,topdecl-sym (2 (unless (member (match-string 2) '("\\" "=" "->" "→" "<-" "←" "::" "∷" "," ";" "`"))
'haskell-definition-face)))
(,topdecl-sym2 (1 (unless (member (match-string 1) '("\\" "=" "->" "→" "<-" "←" "::" "∷" "," ";" "`"))
'haskell-definition-face)))
;; These four are debatable...
("(\\(,*\\|->\\))" 0 'haskell-constructor-face)
("\\[\\]" 0 'haskell-constructor-face)
("`"
(0 (if (or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
(parse-partial-sexp (point) (point-max) nil nil (syntax-ppss)
'syntax-table)
(when (save-excursion
(goto-char (match-beginning 0))
(haskell-lexeme-looking-at-backtick))
(goto-char (match-end 0))
(unless (text-property-not-all (match-beginning 1) (match-end 1) 'face nil)
(put-text-property (match-beginning 1) (match-end 1) 'face 'haskell-operator-face))
(unless (text-property-not-all (match-beginning 2) (match-end 2) 'face nil)
(put-text-property (match-beginning 2) (match-end 2) 'face 'haskell-operator-face))
(unless (text-property-not-all (match-beginning 4) (match-end 4) 'face nil)
(put-text-property (match-beginning 4) (match-end 4) 'face 'haskell-operator-face))
(add-text-properties
(match-beginning 0) (match-end 0)
'(font-lock-fontified t fontified t font-lock-multiline t))))))
(,haskell-lexeme-idsym-first-char
(0 (if (or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
(parse-partial-sexp (point) (point-max) nil nil (syntax-ppss)
'syntax-table)
(when (save-excursion
(goto-char (match-beginning 0))
(haskell-lexeme-looking-at-qidsym))
(goto-char (match-end 0))
;; note that we have to put face ourselves here because font-lock
;; will use match data from the original matcher
(haskell-font-lock--put-face-on-type-or-constructor)))))))
keywords))