Могу ли я использовать подсветку синтаксиса Python и SQL в одном и том же файле в Vim? - PullRequest
9 голосов
/ 02 февраля 2011

Я использую многострочные строки для запросов SQL внутри программ Python.

Есть ли способ сказать Vim, чтобы он применял к ним различные правила подсветки, возможно, используя маркер --SQL?

Ответы [ 3 ]

11 голосов
/ 02 февраля 2011

Я скопировал-вставил-изменил с здесь :

function! TextEnableCodeSnip(filetype,start,end,textSnipHl) abort
  let ft=toupper(a:filetype)
  let group='textGroup'.ft
  if exists('b:current_syntax')
    let s:current_syntax=b:current_syntax
    " Remove current syntax definition, as some syntax files (e.g. cpp.vim)
    " do nothing if b:current_syntax is defined.
    unlet b:current_syntax
  endif
  execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
  try
    execute 'syntax include @'.group.' after/syntax/'.a:filetype.'.vim'
  catch
  endtry
  if exists('s:current_syntax')
    let b:current_syntax=s:current_syntax
  else
    unlet b:current_syntax
  endif
  execute 'syntax region textSnip'.ft.'
  \ matchgroup='.a:textSnipHl.'
  \ start="'.a:start.'" end="'.a:end.'"
  \ contains=@'.group
endfunction

au FileType python call TextEnableCodeSnip('sqlpostgres', "'''", "'''", 'SpecialComment')

Теперь каждая многострочная строка с тремя кавычками получает синтаксис sql. Строки с тройными двойными кавычками все еще просты. Я изменил sqlpostgres.vim, чтобы добавить в SQL нюансы зеленого цвета, чтобы различать два языка, и он выглядит красиво в схеме чернильницы 256 цветов.

Также связано: Подсветка встроенного синтаксиса в Vim

2 голосов
/ 20 апреля 2016

Я знаю, что есть принятый ответ, но, тем не менее, есть еще один способ сделать это:

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

" Need to add the keepend here
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).

0 голосов
/ 02 февраля 2011

Вы можете попробовать следующую опцию для вашего файла:
setfiletype=python.sql

Он присваивает вашему файлу оба типа файлов и должен применять подсветку обоих синтаксисов.

Если это работаетдля вас, вы можете добавить следующую строку в .vimrc, чтобы применить ее к каждому редактируемому вами файлу python:

autocmd BufRead,BufNewFile *.py setfiletype=python.sql

Однако на самом деле это не касается конфликта междудве выделенные группы ... Так что это может или не может работать в вашем случае.

Вы также можете создать функцию для быстрого переключения типа файла вашего открытого буфера:

function! ToggleFiletype()
  if &filetype=="sql"
    set filetype=python
  endif

  if &filetype=="python"
    set filetype=sql
  endif
endfunction

map <F11> <Esc>:call ToggleFiletype()<cr>
...