On 27/10/06, Benji Fisher <[EMAIL PROTECTED]> wrote:
On Fri, Oct 27, 2006 at 04:46:02PM +0100, A. S. Budden wrote:
> Dear all,
>
> I've recently started using the CleverTab function below, modified from
> the bottom of the comments page on tip 102. This is brilliant from my
> point of view:
>
> - tab produces tabs at the start of the line for indenting*;
> - tab shows the longest unique option in the omnicomplete list
> when using omnicompletion;
> - tab cycles through the list of completions if the popup menu is
> visible but omnicompletion isn't used;
> - otherwise, it returns a tab.
>
> What I'd like to do is change the last one of those so that it puts in
> enough spaces to reach the next tabstop so that good formatting is
> maintained regardless of the tabstop setting on a users editor.
>
> However, I can't figure out how to achieve this.
>
> The 'expandtab' option is no use as it will change the tabs at the start
> of the line (used for indentation) to spaces, which will result in a
> really badly formatted piece of source code (as it is edited by several
> people who all like different tab stops)*. Similarly, replacing "\<Tab>"
> in the last return line with " " is no use as it will always insert
> four spaces, even if we're halfway through a tab stop (it's also not
> very flexible for different tabstop settings).
>
> Can anyone offer any suggestions for this?
[snip]
The 'expandtab' option does not affect existing tabs in the file
(unless you :retab) so it should be safe to have your function reset/set
it depending on whether you are at the start of the line or not. I have
not tested this.
Many thanks for your help Benji, both suggestions look useful. I've
been playing around with the first option (as the code _should_ be a bit
neater I think), but I'd quite like to ensure that expandtab is left off
at the end of the insertion (as I'd like to be able to enable and
disable use of CleverTab).
The problem with this is that inside one of the 'if/elseif/else' blocks,
I need to set expandtab, print something into the insert buffer and then
reset expandtab. I'm struggling with this, despite having played around
with lots of possibilities and done what I feel is a fairly
comprehensive trawl of the documentation.
What I've tried:
---
let &expandtab = 1
return "\<Tab>"
let &expandtab = 0 " Never gets executed
---
let &expandtab = 1
feedkeys("\<Tab>", 'n') " Gets executed AFTER the return
let &expandtab = 0
return ""
---
I've also tried a simple one with the first two lines of the first
example, combined with:
inoremap <Tab> <C-R>=CleverTab()<CR><C-O>:set noet<CR>
This one works fine for the start of line and mid-line examples, but on
the omnifunc version (see updated CleverTab below), it fails as the
<C-O> just breaks it out of the menu (which I don't want) and the
mapping then prints ":set noet" to the buffer.
Is there a way to do the equivalent of feedkeys, but without it waiting
for mappings to be completed? Alternatively, can you suggest a
different way of using expandtab?
If not, then I'll look into the while loop approach I guess.
Many thanks again for your help,
Al
" A clever tab function
function! CleverTab()
" If we've only had spaces/tabs thus far, add a tab
if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
" This is the simple case"
return "\<Tab>"
" If last character was a space, use spaces
elseif getline('.')[col(".")-2] =~ ' '
let &expandtab = 1
call feedkeys("\<Tab>", 'n') " This gets executed too late
let &expandtab = 0
return ""
" If we're omnifuncing, act on it
elseif exists('&omnifunc') && &omnifunc != ''
" This causes problems if noet is set in a mapping
return "\<C-X>\<C-O>"
elseif pumvisible()
" This probably does too, but I haven't tested it yet
return "\<C-N>"
else
" This should ideally be 'spaced tab'
let &expandtab = 1
return "\<Tab>"
let &expandtab = 0 " This never gets executed
endif
endfunction