Am 09.02.2010 13:36, schrieb Stahlman Family:
Dan S wrote:
Hi -

I have a project where I'd like code in vim to be coloured, with the
colours changing in real time (to reflect some audio-related data
being generated). For example, say the text "Merti()" represents an
audio object - I'd like to be able to update the colouring of that
text to reflect the current loudness of that object.

Although the incoming data is 'continuous' it'd be fine to use a
predefined palette of (say) 25 colours which I could define as 25
syntax categories.

The loudness data I can derive externally, that's no problem, but I'd
like to know if I can efficiently achieve the rapid color changes in
vim. Some questions:
* Is vim's syntax highlighting efficient enough to be run many (e.g.
10) times per second? e.g. if I dynamically tweak a syntax-
highlighting file from outside and force it to be re-read.

Not the best approach.

* Is there a more efficient approach you could suggest, such as syntax-
highlighting information coming through a pipe, or by executing
commands rather than reading a file?

You can execute the :highlight command to change the color of specific
syntax groups. For example, if you have defined a syntax group for the
text "Merti()" as follows...
:syn match Merti /Merti()/

...you could cause it to be highlighted blue with the following
:highlight command:
:hi Merti guifg=#0000FF ctermfg=Blue

Changing the Merti() object to red is as simple as executing the
following command:
:hi Merti guifg=#FF0000 ctermfg=Red

Out of curiosity, I prepared a little color demo (see attachment), but
it requires gVim and the +float feature.

The demo opens a new tab page for processing.  It takes a string and
creates a syntax item for each character (static part).  Then the
animation starts and continuously changes the colors of the highlight
groups (rainbow colors with overlayed sinus of different frequency to
change brightness).  Currently uses 58 highlight groups.  Contains some
german comments, sorry for that ...

--
Andy

--
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
" File:         C570.vim
" Created:      2010 Feb 08
" Last Change:  2010 Feb 09
" Rev Days:     1
" Author:       Andy Wokula <[email protected]>

" This is an immediate script, it executes when sourced.
" Main Func: ColorDemo()

" I have a project where I'd like code in vim to be coloured, with the
" colours changing in real time
" - this is for gVim only
" - requires +float
"
" The demo opens a new tab page for processing.
"
" Static Part: the demo takes a string and creates a syntax item for each
" character.
" Dynamic Part: colors of the hlgroups

if !has("gui_running")
    echoerr "ColorDemo: sorry, only for GUI (gVim)"
    finish
endif

if !has("float")
    echoerr "ColorDemo: sorry, needs a gVim with the +float feature"
    finish
endif

func! ColorDemo() "{{{
    tabnew
    setl buftype=nofile
    put = 'Press Ctrl-C to stop'
    syn clear

    let str = "I have a project where I'd like code in vim to be coloured"
        " with the colours changing in real time (to reflect some
        " audio-related data being generated)."

    put = strlen(str).' different highlight groups!'
    let foo = str
    let fooL = []
    while strlen(foo) > 40
        call add(fooL, strpart(foo, 0, 40))
        let foo = strpart(foo, 40)
    endwhile
    call add(fooL, foo)

    put = fooL
    put = fooL
    put = fooL
    put = fooL

    let tw = strlen(str)

    call s:Syntaxify(str)
    let swL = s:SinWeightList(tw)
    let rbL = s:RainbowList(tw)

    " animation!
    let sinoff = 0
    let rboff = 0

    while 1
        let vidx = 0
        while vidx < tw

            let rb = rbL[(vidx + rboff) % tw]
            let sw = swL[(vidx + sinoff) % tw]

            let rval = rb[0] * sw
            let gval = rb[1] * sw
            let bval = rb[2] * sw

            let letnum = s:LetterNum(vidx)
            call s:DefHlGroup("merti".letnum, [rval, gval, bval])

            let vidx += 1
        endwhile

        let sinoff -= 3
        if sinoff < 0
            let sinoff += tw
        endif
        let rboff -= 1
        if rboff < 0
            let rboff += tw
        endif

        redraw
        sleep 10m
    endwhile
endfunc "}}}

let s:pi = 3.1415926536

" must be executed in the right (not the wrong) buffer
func! s:Syntaxify(str) "{{{
    if strlen(a:str) < 2
        return
    endif
    " syn case match
    " syn match mertiAA /I/ nextgroup=mertiAB
    " syn match mertiAB / / contained nextgroup=mertiAC
    " syn match mertiAC /h/ contained nextgroup=mertiAD
    " syn match mertiAD /a/ contained nextgroup=mertiAE
    " ...
    " syn match mertiCF /d/ contained
    syn case match
    syn sync fromstart
    let letnum0 = s:LetterNum(0)
    let letnum = s:LetterNum(1)
    exec 'syn match merti'.letnum0 '/'.escape(a:str[0], '/\.*$^~[').
        \ '/ nextgroup=merti'.letnum
    call s:DefHlGroup('merti'.letnum0, [0,0,0])
    let idx = 1
    let max = strlen(a:str) - 1
    while idx < max
        let next_letnum = s:LetterNum(idx + 1)
        exec 'syn match merti'.letnum '/'.escape(a:str[idx], '/\.*$^~[').
            \ '/ contained nextgroup=merti'.next_letnum 'skipnl'

        call s:DefHlGroup('merti'.letnum, [0,0,0])
        let letnum = next_letnum
        let idx += 1
    endwhile
    exec 'syn match merti'.letnum '/'.escape(a:str[max], '/\.*$^~[').
        \ '/ contained'
    call s:DefHlGroup('merti'.letnum, [0,0,0])
endfunc "}}}

func! s:DefHlGroup(name, rgb) "{{{
    exec 'hi' a:name 'guifg=#'.printf('%02X%02x%02x',
        \ float2nr(a:rgb[0]), float2nr(a:rgb[1]), float2nr(a:rgb[2]))
        \ 'guibg=NONE gui=NONE'
endfunc "}}}

let s:letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
func! s:LetterNum(number) "{{{
    return s:letters[a:number/26]. s:letters[a:number%26]
endfunc "}}}

" Generate Static Data:
" {tw} - "textwidth", number of columns -- only to denote a count, resulting
" list is 0-based
func! s:SinWeightList(tw) "{{{
    let omg = 2 * s:pi / a:tw
    let sinres = range(a:tw)
    call map(sinres, '0.4 * (1.5 + sin(omg * v:val))')
    return sinres
endfunc "}}}

func! s:RainbowList(tw) "{{{
    let rgbres = []

    let damp = 256.0 * 5 / a:tw

    " Start: rot [255.0, 0.0, 0.0]

    " mehr grün
    let vidx = 0
    let vright = a:tw/5
    let gval = 0.0
    while vidx < vright
        call add(rgbres, [255.0, gval, 0.0])
        let gval += damp
        let vidx += 1
    endwhile

    " weniger rot
    let vidx = vright
    let vright = a:tw*2/5
    let rval = 255.0
    while vidx < vright
        call add(rgbres, [rval, 255.0, 0.0])
        let rval -= damp
        let vidx += 1
    endwhile

    " weniger grün, mehr blau
    let vidx = vright
    let vright = a:tw*3/5
    let gval = 255.0
    let bval = 0.0
    while vidx < vright
        call add(rgbres, [0.0, gval, bval])
        let gval -= damp
        let bval += damp
        let vidx += 1
    endwhile

    " mehr rot
    let vidx = vright
    let vright = a:tw*4/5
    let rval = 0.0
    while vidx < vright
        call add(rgbres, [rval, 0.0, 255.0])
        let rval += damp
        let vidx += 1
    endwhile

    " weniger blau
    let vidx = vright
    let vright = a:tw
    let bval = 255.0
    while vidx < vright
        call add(rgbres, [255.0, 0.0, bval])
        let bval -= damp
        let vidx += 1
    endwhile

    return rgbres
endfunc "}}}

" Farbe     R   G   B   Palettenindex
" Rot     (255,000,000)  0- 20
" Gelb    (255,255,000) 20- 40
" Grün    (000,255,000) 40- 60
" Blau    (000,000,255) 60- 80
" Violett (255,000,255) 80-100
"
" Start: nur rot
" rot->gelb         mehr grün
" gelb->grün        weniger rot
" grün->blau        weniger grün, mehr blau
" blau->violett     mehr rot
" violett->rot      weniger blau
"
" Fünf Abschnitte

call ColorDemo()

Reply via email to