Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use both Python and SQL syntax highlighting in the same file in Vim?

I use multiline strings for SQL queries inside Python programs.

Is there a way to tell Vim to apply different highlighting rules inside them, possibly by using a --SQL marker?

like image 589
Marco Mariani Avatar asked Feb 02 '11 10:02

Marco Mariani


2 Answers

I copy-pasted-changed from here:

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')

Now every multiline triple-single-quote string gets the sql syntax. Triple-double-quoted strings are still plain. I've changed sqlpostgres.vim to give SQL nuances of green to differentiate the two languages, and it looks sweet in the 256 colors inkpot scheme.

Also related: Embedded syntax highligting in Vim

like image 176
Marco Mariani Avatar answered Sep 22 '22 03:09

Marco Mariani


I know there's an accepted answer, but still, here is another way of doing it:

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"

With that, highlighting starts at one of the given SQL keywords and stops either at the first ; and can restart on next SQL keyword, or stops at the end of the python string (see keepend).

like image 27
ibizaman Avatar answered Sep 21 '22 03:09

ibizaman