Allow reinitialization of font lock regexps
In `plantuml-mode`, initialization of the font locking regular expressions is done by asking the current version of plantuml for its supported keywords, builtins, etc. Every so often, this might fail for any reason, leaving the current Emacs session with invalid font lock information for plantuml. Redoing the initialization process is tedious, as the corresponding function `plantuml-init-once` does not allow for that to be done easily (one would have to undefine a lot of global variables to do so). This commit introduces a force parameter for `plantuml-init-once` to conduct reinitialization of all font lock information. It also moves regular expressions meant for indentation out of `plantuml-init-once`, as those are initialized by literal values that do not depend on any runtime information.
This commit is contained in:
parent
ea45a13707
commit
d7721971f0
243
plantuml-mode.el
243
plantuml-mode.el
|
@ -539,131 +539,140 @@ Uses prefix (as PREFIX) to choose where to display it:
|
|||
(plantuml-preview-region prefix (region-beginning) (region-end))
|
||||
(plantuml-preview-buffer prefix)))
|
||||
|
||||
(defun plantuml-init-once (&optional mode)
|
||||
"Ensure initialization only happens once. Use exec mode MODE to load the language details or by first querying `plantuml-get-exec-mode'."
|
||||
(let ((mode (or mode (plantuml-get-exec-mode))))
|
||||
(unless plantuml-kwdList
|
||||
(plantuml-init mode)
|
||||
(defvar plantuml-types-regexp (concat "^\\s *\\(" (regexp-opt plantuml-types 'words) "\\|\\<\\(note\\s +over\\|note\\s +\\(left\\|right\\|bottom\\|top\\)\\s +\\(of\\)?\\)\\>\\|\\<\\(\\(left\\|center\\|right\\)\\s +\\(header\\|footer\\)\\)\\>\\)"))
|
||||
(defvar plantuml-keywords-regexp (concat "^\\s *" (regexp-opt plantuml-keywords 'words) "\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}"))
|
||||
(defvar plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words))
|
||||
(defvar plantuml-preprocessors-regexp (concat "^\\s *" (regexp-opt plantuml-preprocessors 'words)))
|
||||
;; Below are the regexp's for indentation.
|
||||
;; Notes:
|
||||
;; - there is some control on what it is indented by overriding some of below
|
||||
;; X-start and X-end regexp before plantuml-mode is loaded. E.g., to disable
|
||||
;; indentation on activate, you might define in your .emacs something like
|
||||
;; (setq plantuml-indent-regexp-activate-start
|
||||
;; "NEVER MATCH THIS EXPRESSION"); define _before_ load plantuml-mode!
|
||||
;; (setq plantuml-indent-regexp-activate-end
|
||||
;; "NEVER MATCH THIS EXPRESSION"); define _before_ load plantuml-mode!
|
||||
;; - due to the nature of using (context-insensitive) regexp, indentation have
|
||||
;; following limitations
|
||||
;; - commands commented out by /' ... '/ will _not_ be ignored
|
||||
;; and potentially lead to miss-indentation
|
||||
;; - you can though somewhat correct mis-indentation by adding in '-comment lines
|
||||
;; PLANTUML_MODE_INDENT_INCREASE and/or PLANTUML_MODE_INDENT_DECREASE
|
||||
;; to increase and/or decrease the level of indentation
|
||||
;; (Note: the line with the comment should not contain any text matching other indent
|
||||
;; regexp or this user-control instruction will be ignored; also at most will count
|
||||
;; per line ...)
|
||||
|
||||
;; Below are the regexp's for indentation.
|
||||
;; Notes:
|
||||
;; - there is some control on what it is indented by overriding some of below
|
||||
;; X-start and X-end regexp before plantuml-mode is loaded. E.g., to disable
|
||||
;; indentation on activate, you might define in your .emacs something like
|
||||
;; (setq plantuml-indent-regexp-activate-start
|
||||
;; "NEVER MATCH THIS EXPRESSION"); define _before_ load plantuml-mode!
|
||||
;; (setq plantuml-indent-regexp-activate-end
|
||||
;; "NEVER MATCH THIS EXPRESSION"); define _before_ load plantuml-mode!
|
||||
;; - due to the nature of using (context-insensitive) regexp, indentation have
|
||||
;; following limitations
|
||||
;; - commands commented out by /' ... '/ will _not_ be ignored
|
||||
;; and potentially lead to miss-indentation
|
||||
;; - you can though somewhat correct mis-indentation by adding in '-comment lines
|
||||
;; PLANTUML_MODE_INDENT_INCREASE and/or PLANTUML_MODE_INDENT_DECREASE
|
||||
;; to increase and/or decrease the level of indentation
|
||||
;; (Note: the line with the comment should not contain any text matching other indent
|
||||
;; regexp or this user-control instruction will be ignored; also at most will count
|
||||
;; per line ...)
|
||||
(defvar plantuml-indent-regexp-block-start "^.*{\s*$"
|
||||
"Indentation regex for all plantuml elements that might define a {} block.
|
||||
(defvar plantuml-indent-regexp-block-start "^.*{\s*$"
|
||||
"Indentation regex for all plantuml elements that might define a {} block.
|
||||
Plantuml elements like skinparam, rectangle, sprite, package, etc.
|
||||
The opening { has to be the last visible character in the line (whitespace
|
||||
might follow).")
|
||||
(defvar plantuml-indent-regexp-note-start "^\s*\\(floating\s+\\)?[hr]?note\s+\\(right\\|left\\|top\\|bottom\\|over\\)[^:]*?$" "simplyfied regex; note syntax is especially inconsistent across diagrams")
|
||||
(defvar plantuml-indent-regexp-group-start "^\s*\\(alt\\|else\\|opt\\|loop\\|par\\|break\\|critical\\|group\\)\\(?:\s+.+\\|$\\)"
|
||||
"Indentation regex for plantuml group elements that are defined for sequence diagrams.
|
||||
(defvar plantuml-indent-regexp-note-start "^\s*\\(floating\s+\\)?[hr]?note\s+\\(right\\|left\\|top\\|bottom\\|over\\)[^:]*?$"
|
||||
"simplyfied regex; note syntax is especially inconsistent across diagrams")
|
||||
(defvar plantuml-indent-regexp-group-start "^\s*\\(alt\\|else\\|opt\\|loop\\|par\\|break\\|critical\\|group\\)\\(?:\s+.+\\|$\\)"
|
||||
"Indentation regex for plantuml group elements that are defined for sequence diagrams.
|
||||
Two variants for groups: keyword is either followed by whitespace and some text
|
||||
or it is followed by line end.")
|
||||
(defvar plantuml-indent-regexp-activate-start "^\s*activate\s+.+$")
|
||||
(defvar plantuml-indent-regexp-box-start "^\s*box\s+.+$")
|
||||
(defvar plantuml-indent-regexp-ref-start "^\s*ref\s+over\s+[^:]+?$")
|
||||
(defvar plantuml-indent-regexp-title-start "^\s*title\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-header-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+header\\|header\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-footer-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+footer\\|footer\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-legend-start "^\s*\\(?:legend\\|legend\s+\\(?:bottom\\|top\\)\\|legend\s+\\(?:center\\|left\\|right\\)\\|legend\s+\\(?:bottom\\|top\\)\s+\\(?:center\\|left\\|right\\)\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-oldif-start "^.*if\s+\".*\"\s+then\s*\\('.*\\)?$" "used in current activity diagram, sometimes already mentioned as deprecated")
|
||||
(defvar plantuml-indent-regexp-newif-start "^\s*\\(?:else\\)?if\s+(.*)\s+then\s*.*$")
|
||||
(defvar plantuml-indent-regexp-loop-start "^\s*\\(?:repeat\s*\\|while\s+(.*).*\\)$")
|
||||
(defvar plantuml-indent-regexp-fork-start "^\s*\\(?:fork\\|split\\)\\(?:\s+again\\)?\s*$")
|
||||
(defvar plantuml-indent-regexp-macro-start "^\s*!definelong.*$")
|
||||
(defvar plantuml-indent-regexp-user-control-start "^.*'.*\s*PLANTUML_MODE_INDENT_INCREASE\s*.*$")
|
||||
(defvar plantuml-indent-regexp-start (list plantuml-indent-regexp-block-start
|
||||
plantuml-indent-regexp-group-start
|
||||
plantuml-indent-regexp-activate-start
|
||||
plantuml-indent-regexp-box-start
|
||||
plantuml-indent-regexp-ref-start
|
||||
plantuml-indent-regexp-legend-start
|
||||
plantuml-indent-regexp-note-start
|
||||
plantuml-indent-regexp-newif-start
|
||||
plantuml-indent-regexp-loop-start
|
||||
plantuml-indent-regexp-fork-start
|
||||
plantuml-indent-regexp-title-start
|
||||
plantuml-indent-regexp-header-start
|
||||
plantuml-indent-regexp-footer-start
|
||||
plantuml-indent-regexp-macro-start
|
||||
plantuml-indent-regexp-oldif-start
|
||||
plantuml-indent-regexp-user-control-start))
|
||||
(defvar plantuml-indent-regexp-block-end "^\s*\\(?:}\\|endif\\|else\s*.*\\|end\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-note-end "^\s*\\(end\s+note\\|end[rh]note\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-group-end "^\s*end\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-activate-end "^\s*deactivate\s+.+$")
|
||||
(defvar plantuml-indent-regexp-box-end "^\s*end\s+box\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-ref-end "^\s*end\s+ref\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-title-end "^\s*end\s+title\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-header-end "^\s*endheader\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-footer-end "^\s*endfooter\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-legend-end "^\s*endlegend\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-oldif-end "^\s*\\(endif\\|else\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-newif-end "^\s*\\(endif\\|elseif\\|else\\)\s*.*$")
|
||||
(defvar plantuml-indent-regexp-loop-end "^\s*\\(repeat\s*while\\|endwhile\\)\s*.*$")
|
||||
(defvar plantuml-indent-regexp-fork-end "^\s*\\(\\(fork\\|split\\)\s+again\\|end\s+\\(fork\\|split\\)\\)\s*$")
|
||||
(defvar plantuml-indent-regexp-macro-end "^\s*!enddefinelong\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-user-control-end "^.*'.*\s*PLANTUML_MODE_INDENT_DECREASE\s*.*$")
|
||||
(defvar plantuml-indent-regexp-end (list plantuml-indent-regexp-block-end
|
||||
plantuml-indent-regexp-group-end
|
||||
plantuml-indent-regexp-activate-end
|
||||
plantuml-indent-regexp-box-end
|
||||
plantuml-indent-regexp-ref-end
|
||||
plantuml-indent-regexp-legend-end
|
||||
plantuml-indent-regexp-note-end
|
||||
plantuml-indent-regexp-newif-end
|
||||
plantuml-indent-regexp-loop-end
|
||||
plantuml-indent-regexp-fork-end
|
||||
plantuml-indent-regexp-title-end
|
||||
plantuml-indent-regexp-header-end
|
||||
plantuml-indent-regexp-footer-end
|
||||
plantuml-indent-regexp-macro-end
|
||||
plantuml-indent-regexp-oldif-end
|
||||
plantuml-indent-regexp-user-control-end))
|
||||
(setq plantuml-font-lock-keywords
|
||||
`(
|
||||
(,plantuml-types-regexp . font-lock-type-face)
|
||||
(,plantuml-keywords-regexp . font-lock-keyword-face)
|
||||
(,plantuml-builtins-regexp . font-lock-builtin-face)
|
||||
(,plantuml-preprocessors-regexp . font-lock-preprocessor-face)
|
||||
;; note: order matters
|
||||
))
|
||||
(defvar plantuml-indent-regexp-activate-start "^\s*activate\s+.+$")
|
||||
(defvar plantuml-indent-regexp-box-start "^\s*box\s+.+$")
|
||||
(defvar plantuml-indent-regexp-ref-start "^\s*ref\s+over\s+[^:]+?$")
|
||||
(defvar plantuml-indent-regexp-title-start "^\s*title\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-header-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+header\\|header\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-footer-start "^\s*\\(?:\\(?:center\\|left\\|right\\)\s+footer\\|footer\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-legend-start "^\s*\\(?:legend\\|legend\s+\\(?:bottom\\|top\\)\\|legend\s+\\(?:center\\|left\\|right\\)\\|legend\s+\\(?:bottom\\|top\\)\s+\\(?:center\\|left\\|right\\)\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-oldif-start "^.*if\s+\".*\"\s+then\s*\\('.*\\)?$"
|
||||
"used in current activity diagram, sometimes already mentioned as deprecated")
|
||||
(defvar plantuml-indent-regexp-newif-start "^\s*\\(?:else\\)?if\s+(.*)\s+then\s*.*$")
|
||||
(defvar plantuml-indent-regexp-loop-start "^\s*\\(?:repeat\s*\\|while\s+(.*).*\\)$")
|
||||
(defvar plantuml-indent-regexp-fork-start "^\s*\\(?:fork\\|split\\)\\(?:\s+again\\)?\s*$")
|
||||
(defvar plantuml-indent-regexp-macro-start "^\s*!definelong.*$")
|
||||
(defvar plantuml-indent-regexp-user-control-start "^.*'.*\s*PLANTUML_MODE_INDENT_INCREASE\s*.*$")
|
||||
(defvar plantuml-indent-regexp-start (list plantuml-indent-regexp-block-start
|
||||
plantuml-indent-regexp-group-start
|
||||
plantuml-indent-regexp-activate-start
|
||||
plantuml-indent-regexp-box-start
|
||||
plantuml-indent-regexp-ref-start
|
||||
plantuml-indent-regexp-legend-start
|
||||
plantuml-indent-regexp-note-start
|
||||
plantuml-indent-regexp-newif-start
|
||||
plantuml-indent-regexp-loop-start
|
||||
plantuml-indent-regexp-fork-start
|
||||
plantuml-indent-regexp-title-start
|
||||
plantuml-indent-regexp-header-start
|
||||
plantuml-indent-regexp-footer-start
|
||||
plantuml-indent-regexp-macro-start
|
||||
plantuml-indent-regexp-oldif-start
|
||||
plantuml-indent-regexp-user-control-start))
|
||||
(defvar plantuml-indent-regexp-block-end "^\s*\\(?:}\\|endif\\|else\s*.*\\|end\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-note-end "^\s*\\(end\s+note\\|end[rh]note\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-group-end "^\s*end\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-activate-end "^\s*deactivate\s+.+$")
|
||||
(defvar plantuml-indent-regexp-box-end "^\s*end\s+box\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-ref-end "^\s*end\s+ref\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-title-end "^\s*end\s+title\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-header-end "^\s*endheader\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-footer-end "^\s*endfooter\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-legend-end "^\s*endlegend\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-oldif-end "^\s*\\(endif\\|else\\)\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-newif-end "^\s*\\(endif\\|elseif\\|else\\)\s*.*$")
|
||||
(defvar plantuml-indent-regexp-loop-end "^\s*\\(repeat\s*while\\|endwhile\\)\s*.*$")
|
||||
(defvar plantuml-indent-regexp-fork-end "^\s*\\(\\(fork\\|split\\)\s+again\\|end\s+\\(fork\\|split\\)\\)\s*$")
|
||||
(defvar plantuml-indent-regexp-macro-end "^\s*!enddefinelong\s*\\('.*\\)?$")
|
||||
(defvar plantuml-indent-regexp-user-control-end "^.*'.*\s*PLANTUML_MODE_INDENT_DECREASE\s*.*$")
|
||||
(defvar plantuml-indent-regexp-end (list plantuml-indent-regexp-block-end
|
||||
plantuml-indent-regexp-group-end
|
||||
plantuml-indent-regexp-activate-end
|
||||
plantuml-indent-regexp-box-end
|
||||
plantuml-indent-regexp-ref-end
|
||||
plantuml-indent-regexp-legend-end
|
||||
plantuml-indent-regexp-note-end
|
||||
plantuml-indent-regexp-newif-end
|
||||
plantuml-indent-regexp-loop-end
|
||||
plantuml-indent-regexp-fork-end
|
||||
plantuml-indent-regexp-title-end
|
||||
plantuml-indent-regexp-header-end
|
||||
plantuml-indent-regexp-footer-end
|
||||
plantuml-indent-regexp-macro-end
|
||||
plantuml-indent-regexp-oldif-end
|
||||
plantuml-indent-regexp-user-control-end))
|
||||
|
||||
(setq plantuml-kwdList (make-hash-table :test 'equal))
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-types)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-keywords)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-builtins)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-preprocessors)
|
||||
(put 'plantuml-kwdList 'risky-local-variable t)
|
||||
(defun plantuml-init-once (&optional mode force)
|
||||
"Initialize regular expressions for font locking.
|
||||
Use exec mode MODE to load the language details or by first
|
||||
querying `plantuml-get-exec-mode'. Ensure that initialization is
|
||||
only performed when not already done. To force reinitalization,
|
||||
provide a non-nil value for FORCE."
|
||||
(let ((mode (or mode (plantuml-get-exec-mode))))
|
||||
(when (or (not plantuml-kwdList)
|
||||
force)
|
||||
(plantuml-init mode)
|
||||
(let ((plantuml-types-regexp (concat "^\\s *\\("
|
||||
(regexp-opt plantuml-types 'words)
|
||||
"\\|\\<\\(note\\s +over\\|note\\s +\\(left\\|right\\|bottom\\|top\\)\\s +\\(of\\)?\\)\\>\\|\\<\\(\\(left\\|center\\|right\\)\\s +\\(header\\|footer\\)\\)\\>\\)"))
|
||||
(plantuml-keywords-regexp (concat "^\\s *"
|
||||
(regexp-opt plantuml-keywords 'words)
|
||||
"\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}"))
|
||||
(plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words))
|
||||
(plantuml-preprocessors-regexp (concat "^\\s *"
|
||||
(regexp-opt plantuml-preprocessors 'words))))
|
||||
|
||||
;; clear memory
|
||||
(setq plantuml-types nil)
|
||||
(setq plantuml-keywords nil)
|
||||
(setq plantuml-builtins nil)
|
||||
(setq plantuml-preprocessors nil)
|
||||
(setq plantuml-types-regexp nil)
|
||||
(setq plantuml-keywords-regexp nil)
|
||||
(setq plantuml-builtins-regexp nil)
|
||||
(setq plantuml-preprocessors-regexp nil))))
|
||||
(setq plantuml-font-lock-keywords
|
||||
`(
|
||||
(,plantuml-types-regexp . font-lock-type-face)
|
||||
(,plantuml-keywords-regexp . font-lock-keyword-face)
|
||||
(,plantuml-builtins-regexp . font-lock-builtin-face)
|
||||
(,plantuml-preprocessors-regexp . font-lock-preprocessor-face)
|
||||
;; note: order matters
|
||||
))
|
||||
|
||||
(setq plantuml-kwdList (make-hash-table :test 'equal))
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-types)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-keywords)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-builtins)
|
||||
(mapc (lambda (x) (puthash x t plantuml-kwdList)) plantuml-preprocessors)
|
||||
(put 'plantuml-kwdList 'risky-local-variable t)
|
||||
|
||||
(setq plantuml-types nil
|
||||
plantuml-keywords nil
|
||||
plantuml-builtins nil
|
||||
plantuml-preprocessors nil)))))
|
||||
|
||||
(defun plantuml-complete-symbol ()
|
||||
"Perform keyword completion on word before cursor."
|
||||
|
|
Loading…
Reference in New Issue