Bram Moolenaar wrote:
  > 
  > Suresh Govindachar wrote:
  >> Bram Moolenaar wrote:
  >>> Suresh Govindachar wrote:
  >>> 
  >>>>  Please consider supporting expressions for syntax matching.
  >>>>  An example of usage is indicated below:
  >>> 
  >>> I don't quite get it.  ":syn match" commands use a pattern.
  >>> You can use ":exec" to get the pattern from an expression.  
  >>   
  >>   Good, but how does one use :exec to get the pattern from an
  >>   expression?  
  >>   
  >>   As an example expression, the following expression returns 0
  >>   or 1 for line("."):  
  >> 
  >>         ( 
  >>      \    ( foldlevel(line(".")) != foldlevel(line(".")-1) ) && 
  >>      \    ( foldlevel(line(".")) != foldlevel(line(".")+1) ) &&
  >>      \    ( 4                    == foldlevel(line('.'))/2 )
  >>      \  ) 
  >>      \  ? 1 
  >>      \  : 0
  >>         
  >>   How would I use exec to get a pattern?
  
    [In the above, line(".") I does _not_ mean the line where the
    cursor currently is;  but means  "the line the syntax engine
    is currently dealing with".]
  
  > Obviously you can currently only evaluate the expression the
  > moment the syntax is defined, not when an item is used.
  >    
  > Each item may be used at every character in the file.
  > Evaluating all the expressions for every item at every character
  > would be very slow.  Even the current mechanism with patterns is
  > slow for some languages, and it includes all kinds of
  > optimizations to avoid trying a match at every character and
  > caching the result.  With an expression you never know what it
  > will do, thus these optimizations would not be possible.  And
  > evaluating the expression adds on top of that.
  
  Did not grasp this complexity.  However, the following special
  case (which my present needs fall under) seems to have a solution.
  
  Situation:  We have a function f(line_n) which takes in a line
              number and which returns a number between -1 and N.
              
              We have defined highlights level0, level1, ..., levelN. 
              We want to leave line_n un-colored if f(line_n) 
              is -1, otherwise we want to color it with 'Level'.f(line_n)

  Solution:   Create a syntax file as follows (for those not
              familiar with it, "oneline" below is an option to the
              syntax command):

              syn clear

              %g/./let i = line('.') | 
                  \ if( f(i) >= 0)   |
                  \     exec 'syn match level'.f(i) . 
                  \          ' /\%'.i.'l.*/ oneline [other-options] |
                  \ endif |
                  \ nohls

              rest of the file defines highlights level<n>
               
  I implemented the solution and have spent a little time working
  with it.  It is good enough for my needs, but some people might
  not like the occasional need to update the syntax (meaning issue
  'syn off | syn on').

  Curious if anyone else is confronting a similar situation and
  finds that the preceding solution is acceptable?
  
  By the way, although having the :g command in a syntax file works
  for me, I could not get the following example in :help /\%l

                :exe '/\%' . line(".") . 'l.*'

  to follow the current line.  (I know about cursorline;  just 
  mentioning that I could not make the preceding example work.)

  Thanks,

  --Suresh
   

Reply via email to