【问题标题】:Highlight SQL inside Python string literals突出显示 Python 字符串文字中的 SQL
【发布时间】:2015-06-29 17:38:43
【问题描述】:

我有一些 Python 文件,我想在其中突出显示字符串文字中的 SQL 查询。假设这些文件中的所有字符串文字都包含 SQL 查询。

我将以下语法文件保存为 pysql.vim:

if exists("b:current_syntax")
  finish
endif

" Include Python syntax
runtime! syntax/python.vim
unlet b:current_syntax

syn include @SQL syntax/sql.vim
syn region SQLEmbedded start=+'+ end=+'+ contains=@SQL
syn region SQLEmbedded start=+%+ end=+%+ contains=@SQL

let b:current_syntax = "pysql"

我添加了百分号语法以检查它是否有效。

加载以下 python 文件(忽略第一行在 Python 中无效的事实):

a = %select * from mytab%
b = 'select * from mytab'

然后运行 ​​vim 命令set syntax=pysql。它适用于百分号内的 SQL 查询,但不适用于引号。奇怪的是,字符串文字后面的任何单词都被突出显示为 SQL。例如,'1' select * from mytab '2' 中的 select * from mytab 会突出显示。

你能在我的语法文件中找到错误吗?

【问题讨论】:

  • 我不确定如何修复,但 '1' select * from mytab '2' 中的 select * from mytab 忽略了 '1' 中的 12,因为它们不是与 select ... 匹配的 SQL在 1 之后和 2 之前使用 '
  • 但是使用'select * from mytab' select * from mytab 'select * from mytab',中间的SQL查询(字符串文字之外)被突出显示。

标签: vim vim-syntax-highlighting


【解决方案1】:

我在https://github.com/krisajenkins/vim-java-sql/blob/master/after/syntax/java.vim 找到了提示。我的语法不起作用的原因是它干扰了 sql.vim 中的 sqlString 组。我将语法更改如下,现在效果很好:

if exists("b:current_syntax")
  finish
endif

" Load Python syntax at the top level
runtime! syntax/python.vim
unlet b:current_syntax

" Load SQL syntax
syn include @SQL syntax/sql.vim

" Reference: https://github.com/krisajenkins/vim-java-sql/blob/master/after/syntax/java.vim
" Take care not to consume the double-quotes (\zs & \ze)
" Case-insensitive (no \C)
syn region SQLEmbedded start=+\z(['"]\)\zs[\s\n]*\v(ALTER|CALL|COMMENT|COMMIT|CONNECT|CREATE|DELETE|DROP|EXPLAIN|EXPORT|GRANT|IMPORT|INSERT|LOAD|LOCK|MERGE|REFRESH|RENAME|REPLACE|REVOKE|ROLLBACK|SELECT|SET|TRUNCATE|UNLOAD|UNSET|UPDATE|UPSERT)+ skip=+\\\z1+ end=+\ze\z1+ contains=@SQL containedin=pythonString

let b:current_syntax = "pysql"

【讨论】:

    【解决方案2】:

    您的回答不适用于以下版本的 vim:

    VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 18 2015 21:31:31)
    Included patches: 1-882
    Modified by pkg-vim-maintainers@lists.alioth.debian.org
    

    我修改了一下你的回答。

    if exists("b:current_syntax")
      finish
    endif
    
    " Load Python syntax at the top level
    runtime! syntax/python.vim
    
    " Needed to make syntax/sql.vim do something
    unlet b:current_syntax
    
    " Load SQL syntax
    syntax include @SQL syntax/sql.vim
    
    " Copied from syntax/python.vim to add the keepend
    syn region pythonString matchgroup=pythonQuotes
          \ start=+[uU]\=\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1"
          \ contains=pythonEscape,@Spell keepend
    syn region  pythonRawString matchgroup=pythonQuotes
          \ start=+[uU]\=[rR]\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1"
          \ contains=@Spell keepend
    
    syn region SQLEmbedded contains=@SQL containedin=pythonString,pythonRawString contained
        \ start=+\v(ALTER|BEGIN|CALL|COMMENT|COMMIT|CONNECT|CREATE|DELETE|DROP|END|EXPLAIN|EXPORT|GRANT|IMPORT|INSERT|LOAD|LOCK|MERGE|REFRESH|RENAME|REPLACE|REVOKE|ROLLBACK|SELECT|SET|TRUNCATE|UNLOAD|UNSET|UPDATE|UPSERT)+
        \ end=+;+
    
    let b:current_syntax = "pysql"
    

    这样,突出显示从给定的 SQL 关键字之一开始,并在第一个 ; 处停止,并且可以在下一个 SQL 关键字处重新开始,或者在 python 字符串的末尾停止(请参阅keepend)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-01
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      • 2020-10-12
      • 1970-01-01
      • 2014-08-20
      相关资源
      最近更新 更多