tags:

views:

40

answers:

1

Hi,

I currently have a syntax file that parses a log file, very similar to the following [this is for syslog]:

syn match   syslogText  /.*$/
syn match   syslogFacility  /.\{-1,}:/  nextgroup=syslogText skipwhite
syn match   syslogHost  /\S\+/  nextgroup=syslogFacility,syslogText skipwhite
syn match   syslogDate  /^.\{-}\d\d:\d\d:\d\d/  nextgroup=syslogHost skipwhite

I'd like to, using a map, toggle whether a given group (let's say, syslogHost) is concealed or not. Is there any way to do something like the following pseudocode:

map <leader>ch :syn match syslogHost conceal!

and thereby toggle the definition of syslogHost between:

syn match   syslogHost  /\S\+/  nextgroup=syslogFacility,syslogText skipwhite

and

syn match   syslogHost  /\S\+/  nextgroup=syslogFacility,syslogText skipwhite conceal

Thanks.

+2  A: 

I think the only way to do this is with a function:

map <leader>ch :call ToggleGroupConceal('sysLogHost')<CR>

function! ToggleGroupConceal(group)
    " Get the existing syntax definition
    redir => syntax_def
    exe 'silent syn list' a:group
    redir END
    " Split into multiple lines
    let lines = split(syntax_def, "\n")
    " Clear the existing syntax definitions
    exe 'syn clear' a:group
    for line in lines
            " Only parse the lines that mention the desired group
            " (so don't try to parse the "--- Syntax items ---" line)
        if line =~ a:group
                    " Get the required bits (the syntax type and the full definition)
            let matcher = a:group . '\s\+xxx\s\+\(\k\+\)\s\+\(.*\)'
            let type = substitute(line, matcher, '\1', '')
            let definition = substitute(line, matcher, '\2', '')
                    " Either add or remove 'conceal' from the definition
            if definition =~ 'conceal'
                let definition = substitute(definition, ' conceal\>', '', '')
                exe 'syn' type a:group definition
            else
                exe 'syn' type a:group definition 'conceal'
            endif
        endif
    endfor
endfunction
Al
Perfect! Thanks a lot; this is great! The only change I made was to add a <CR> to the map, but that's hardly a significant thing (although it's about the extent of my VIM scripting abilities... :) )
Mikeage
Ah yes! I tested the function and then added the mapping when I copied it into stackoverflow. I'll edit my answer.
Al