Search code examples
mysqlvimsyntax-highlightingbnf

Vim BNF-like syntax highlighting for MySQL


I am trying to define a new vim syntax highlighter for MySQL, mostly for learning purposes. As a start, I took the ALTER DATABASE BNF from MySQL's manual and tried to convert it into syn commands. This is my result:

syn case ignore

" 13 SQL Statement Syntax
" 13.1 Data Definition Statements
" 13.1.1 ALTER DATABASE Syntax
syn match mysqlAlterDB "\<alter\>" skipwhite display nextgroup=mysqAlterSpec
syn match mysqlAlterDB "\<alter\>" skipwhite display nextgroup=mysqlDBAlterSpec
syn match mysqlAlterSpec "(default )? collate (= )?" skipwhite display nextgroup=mysqlCollationName
syn match mysqlAlterSpec "(default )? character set (= )?" skipwhite display nextgroup=mysqlCharsetName
syn match mysqlDBAlterSpec "[_a-zA-Z0-9]" skipwhite display nextgroup=mysqlAlterSpec
hi link mysqlAlterDB Statement

" Misc.
syn match mysqlCollationName "[_a-z0-9]*"
syn match mysqlCharsetName "[_a-z0-9]*"

However, this fails to highlight the following statement:

alter default collate = test

(also without the =). Any idea why?


Solution

  • For starters, you need to use the proper, non-magic regular expression syntax: Capturing groups are \(...\), (I prefer non-capturing grouping with \%(...\)), and the 0 or 1 multi is \?:

    syn match mysqlAlterSpec "\%(default \)\? collate \%(= \)\?" skipwhite display nextgroup=mysqlCollationName
    

    See :help :syn-pattern.

    Some more tips:

    For allowing (arbitrary) whitespace between the keywords, you probably want to use \s instead of a plain space.


    Instead of

    syn match mysqlAlterDB "\<alter\>"
    

    you can probably use

    syn keyword mysqlAlterDB alter
    

    This is the canonical way, and probably also slightly faster.


    The SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin is a great aid when developing a syntax script.