Loading ...
Sorry, an error occurred while loading the content.
 

Re: Variable width tabstops

Expand Messages
  • Benji Fisher
    ... [snip] ... Well, if you want to convert to ,28,105,115 then you would do ... ) ... or, if that regexp makes you go cross-eyed,
    Message 1 of 5 , Mar 1, 2001
      Tony Veale wrote:
      >
      > It appeared that Benji Fisher wrote:
      > >
      > > Tony Veale wrote:
      > > >
      > > > Is it possible to have variable width tabs within a single line?
      > > >
      > > > I'd like to replace a "Tab marker" in a line with a variable number of
      > > > spaces depending on the column, specifically I want to have tabstops at
      > > > the 28, 88, 105 and 115 columns.
      [snip]
      > >
      > > I thought this was an interesting problem, so I wrote a map and a function:
      > >
      > > imap <Tab> <C-R>=VarTab(virtcol("."), 28, 88, 105, 115)<CR>
      > >
      > > fun! VarTab(c, ...)
      > > let i = 1
      > > while i <= a:0
      > > execute "let num_sp = -a:c + a:" . i
      > > if num_sp > 0
      > > break
      > > endif
      > > let i = i+1
      > > endwhile
      > > if i > a:0
      > > return ""
      > > endif
      > > let spaces = " "
      > > let len = 1
      > > while len < num_sp
      > > let spaces = spaces . spaces
      > > let len = len + len
      > > endwhile
      > > return strpart(spaces, 0, num_sp)
      > > endfun
      > >
      > > You did not say what should happen if the cursor is already at or beyond
      > > the last tabstop, so I decided to do nothing. To understand how the map
      > > calls the function, see
      > >
      > > :help i_ctrl-r
      > > :help virtcol()
      > >
      > > HTH --Benji Fisher
      >
      > Thanks Benji - that was agreat help!
      >
      > Unfortunately, I have since discovered that the tabstop widths are not
      > fixed, but need to be extracted from an embedded code of the format:
      >
      > <ST.n.n.n.n.n.n>
      >
      > where n is each tabstop width and there may be between 1 and 9 of these
      > "n"'s.
      >
      > So what I need is to extract the tabstop values and pass them by
      > variable into the VarTab function, but I can't seem to be able to write
      > a regexp to describe a variable length format and use the
      > sub-expressions are arguments to VarTab.
      >
      > Any help as to how to do this would be appreciated!

      Well, if you want to convert "<ST.28.88.105.115>" to
      ",28,105,115" then you would do

      :s/<ST//
      :s/>//
      :s/\./,/g

      In a script, it is easier to use the substitute() function:

      :let params = substitute(getline("."), '.*<ST\([.[:digit:]]*\)>.*', '\1',
      '')
      :let params = substitute(params, '\.', ',', 'g')

      or, if that regexp makes you go cross-eyed, perhaps

      :let params = matchstr(getline("."), '<ST.*>')
      :let params = substitute(params, '<ST', '', '')
      :let params = substitute(params, '>', '', '')
      :let params = substitute(params, '\.', ',', 'g')

      Then, build a string that defines the :map command and :execute it.

      :execute ':map <Tab> <C-R>=VarTab(virtcol(".")' . params . ')'

      Now, wrap these commands in a function, and decide whether you want to
      invoke it manually (maybe with a command or menu item) or automatically,
      with an autocommand. If you want to search for the embedded code, use the
      regexp in the first substitute() line (without the .* at the beginning and
      end).

      HTH --Benji Fisher
    Your message has been successfully submitted and would be delivered to recipients shortly.