branch: externals/bnf-mode commit 5a483ed7ad1b846db3faa2410932ccb796b9956c Author: Serghei Iakovlev <serg...@phalconphp.com> Commit: Serghei Iakovlev <serg...@phalconphp.com>
Introduce ALGOL 60 comments style --- bnf-mode.el | 107 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 23 deletions(-) diff --git a/bnf-mode.el b/bnf-mode.el index 77c1b0a..0637dfa 100644 --- a/bnf-mode.el +++ b/bnf-mode.el @@ -84,6 +84,23 @@ :type 'hook :group 'bnf) +(defcustom bnf-mode-algol-commets-style nil + "Non-nil means use for BNF comments style introduced in ALGOL 60. + +For the purpose of including text among the symbols of a program the following +\"comment\" conventions will hold: + + :------------------------------------------------:------------------: + | The sequence of basic symbols: | is equivalent to | + :------------------------------------------------:------------------: + | ; comment <any sequence not containing ;>; | ; | + | begin comment <any sequence not containing ;>; | begin | + :------------------------------------------------:------------------: + +Note: Enabling this feature disables ABNF/EBN comments style (just \";\")." + :group 'bnf + :type 'boolean) + ;;; Specialized rx @@ -160,33 +177,43 @@ See `rx' documentation for more information about REGEXPS param." (let ((table (make-syntax-table))) ;; Give CR the same syntax as newline (modify-syntax-entry ?\^m "> b" table) - ;; Comments setup - (modify-syntax-entry ?\; "<" table) - (modify-syntax-entry ?\n ">" table) + ;; Treat ::= as sequence of symbols - (modify-syntax-entry ?\: "_" table) - (modify-syntax-entry ?\= "_" table) + (modify-syntax-entry ?\: "_" table) + (modify-syntax-entry ?\= "_" table) + ;; Treat | as a symbol - (modify-syntax-entry ?\| "_" table) + (modify-syntax-entry ?\| "_" table) + ;; In BNF there are no strings ;; so treat ' and " as a symbols - (modify-syntax-entry ?\" "_" table) - (modify-syntax-entry ?\' "_" table) + (modify-syntax-entry ?\" "_" table) + (modify-syntax-entry ?\' "_" table) + ;; In BNF there are no grouping ;; brackets except angle ones - (modify-syntax-entry ?\( "_" table) - (modify-syntax-entry ?\) "_" table) - (modify-syntax-entry ?\{ "_" table) - (modify-syntax-entry ?\} "_" table) - (modify-syntax-entry ?\[ "_" table) - (modify-syntax-entry ?\] "_" table) + (modify-syntax-entry ?\( "_" table) + (modify-syntax-entry ?\) "_" table) + (modify-syntax-entry ?\{ "_" table) + (modify-syntax-entry ?\} "_" table) + (modify-syntax-entry ?\[ "_" table) + (modify-syntax-entry ?\] "_" table) + ;; Group angle brackets - (modify-syntax-entry ?\< "(>" table) - (modify-syntax-entry ?\> ")<" table) + (modify-syntax-entry ?\< "(>" table) + (modify-syntax-entry ?\> ")<" table) + + ;; Comments setup + (if bnf-mode-algol-commets-style + (modify-syntax-entry ?\; ">" table) + (progn + (modify-syntax-entry ?\; "<" table) + (modify-syntax-entry ?\n ">" table))) + table) "Syntax table in use in `bnf-mode' buffers.") -(defun bnf--syntax-propertize (start end) +(defun bnf--bnf-syntax-propertize-function (start end) "Apply syntax table properties to special constructs in region START to END. Currently handled: @@ -205,18 +232,52 @@ Currently handled: ;;; Initialization +(defconst bnf--bnf-syntax-propertize-macro + (syntax-propertize-rules + ("\\(?:begin\\_>\\|;\\)\\(?:$\\|\\s-\\|\n\\)+\\(\\(?:comment\\_>\\)[^;]*;\\)" + (1 "<"))) + "Fontify comments in ALGOL 60 style. +Provide a macro to apply syntax table properties to comments in ALGOL 60 style. +Will used only if `bnf-mode-algol-commets-style' is set to t") + ;;;###autoload (define-derived-mode bnf-mode prog-mode "BNF" "A major mode for editing BNF grammars." :syntax-table bnf-mode-syntax-table :group 'bnf-mode - ;; Comments setup. + + ;; Comments setup (setq-local comment-use-syntax nil) - (setq-local comment-start "; ") - (setq-local comment-end "") - (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\);+\\)\\s-*") - ;; Tune up syntax `syntax-table' - (setq-local syntax-propertize-function #'bnf--syntax-propertize) + (if bnf-mode-algol-commets-style + (progn + (setq-local comment-start "; comment ") + (setq-local comment-end ";") + (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\)comment\\_>\\)\\s-+") + (setq-local syntax-propertize-function + bnf--bnf-syntax-propertize-macro)) + (progn + (setq-local comment-start "; ") + (setq-local comment-end "") + (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\);+\\)\\s-+") + (setq-local syntax-propertize-function + #'bnf--bnf-syntax-propertize-function))) + + ;; Basically `syntax-propertize-function' is a construct which belongs + ;; to `font-lock'. But correct indentation depends on + ;; syntax properties of the text, and that should ideally be + ;; independent of font-lock being activated or not. + ;; + ;; For `bnf-mode', this means that with `font-lock' disabled, we wont + ;; have our syntax properties set correctly, and indentation will + ;; suffer. + ;; + ;; To patch our way around this, we issue a `syntax-propertize' call + ;; manually, `font-lock' enabled or not. + (with-silent-modifications + (if bnf-mode-algol-commets-style + (funcall syntax-propertize-function (point-min) (point-max)) + (bnf--bnf-syntax-propertize-function (point-min) (point-max)))) + ;; Font locking (setq font-lock-defaults '(