Among suggested uses for tabs, :help tabstop lists
--
4. Always set 'tabstop' and 'shiftwidth' to the same value, and
'noexpandtab'. This should then work (for initial indents only)
for any tabstop setting that people use. It might be nice to have
tabs after the first non-blank inserted as spaces if you do this
though. Otherwise aligned comments will be wrong when 'tabstop' is
changed.
--
I like to format code like this, but I haven't found a setting to avoid
having to enter spaces manually. Is there an easy way to expand tabs
automatically after non-blanks?
Regards, Andreas
The "nice to have"-part is not supported by an option yet. There isn't
even an entry in the todo list - at least I haven't found one. The help
for :retab is satisfied with a warning
| Careful: This command modifies any <Tab> characters inside of strings
| in a C program. Use "\t" to avoid this (that's a good habit anyway).
| ":retab!" may also change a sequence of spaces by <Tab> characters,
| which can mess up a printf().
As a workaround, you could remove hard tabs within lines with
:set et| retab| set noet| %>| %<
before finally saving a file.
It would be nice to have an option 'indenttab': If on, hard tabs are
only inserted for the indent (default off). But currently, there is no
such option.
> I like to format code like this, but I haven't found a setting to avoid
> having to enter spaces manually. Is there an easy way to expand tabs
> automatically after non-blanks?
>
> Regards, Andreas
You have to go along with a script, like this one:
""""""""""""""""""""""""""""""""""""""""""""""""""
ino <silent><tab> <c-r>=<sid>tabet()<cr><c-o>:call<sid>restoret()<cr>
" set 'expandtab' when needed and return <Tab>
func! <sid>tabet()
if !&expandtab && virtcol(".")-1 > indent(".")
let s:restoret = 1
set expandtab
else
let s:restoret = 0
endif
return "\<tab>"
endfunc
" restore 'expandtab'
func! <sid>restoret()
if s:restoret
set noexpandtab
endif
endfunc
""""""""""""""""""""""""""""""""""""""""""""""""""
It looks ugly, but an easier variant fails:
""""""""""""""""""""""""""""""""""""""""""""""""""
" Script2:
if &ts != &sw || !&et
echo "Script2 requires tabstop==shiftwidth and expandtab on"
finish
endif
ino <silent><tab> <c-r>=<sid>mytab()<cr>
func! <sid>mytab()
if virtcol(".")-1 > indent(".")
return "\<tab>"
else
return "\<c-v>\<tab>"
endif
endfunc
""""""""""""""""""""""""""""""""""""""""""""""""""
... because with 'expandtab' on, spaces are inserted for the
auto-indent.
Remaining problem: Won't probably work together with scripts like
supertab.
See also: Converting tabs to spaces
http://vim.wikia.com/wiki/VimTip12
I'd also like to hear about an easy solution for the issue.
--
Andy
I've done something like this with a substitute command:
:%s/\S.*/\=substitute(submatch(0), '\t', ' ', 'g')
where the number of spaces in the 3rd parameter is the number.
In Vim7+, you can make that
:%s/\S.*/\=substitute(submatch(0), '\t', repeat(' ', &ts), 'g')
to deal with whatever your 'tabstop' setting happens to be.
Granted, it's not dynamic, but it can be mapped to retab things
at a keypress.
-tim
Hmm: The assumption is wrong. Spaces within the line don't help keeping
comments aligned when 'tabstop' changes, example (here ":---" means a
hardtab with ts=4):
:---:---Code // comment
:---Code // comment
Now :set ts=3 . Either the help is wrong or I misunderstood sth here.
--
Andy
> It would be nice to have an option 'indenttab': If on, hard tabs are
> only inserted for the indent (default off). But currently, there is no
> such option.
I would have been quite surprised if there was such an option - I've
been looking for exactly that everywhere ...
> You have to go along with a script, like this one:
>
> """"""""""""""""""""""""""""""""""""""""""""""""""
> ino <silent><tab> <c-r>=<sid>tabet()<cr><c-o>:call<sid>restoret()<cr>
>
> " set 'expandtab' when needed and return <Tab>
> func! <sid>tabet()
> if !&expandtab && virtcol(".")-1 > indent(".")
> let s:restoret = 1
> set expandtab
> else
> let s:restoret = 0
> endif
> return "\<tab>"
> endfunc
>
> " restore 'expandtab'
> func! <sid>restoret()
> if s:restoret
> set noexpandtab
> endif
> endfunc
> """"""""""""""""""""""""""""""""""""""""""""""""""
This works very nicely, thanks!
Regards, Andreas
I know that it wont work for different indents, but without expanding
tabs, even comments aligned behind code of the same indent may get
broken. e.g.:
<tab>Code<tab>// comment
<tab>XYZ<tab><tab>// comment
is aligned with sw=4 and ts=4, but changing to ts=5 or ts=3 will break
it. For this, expanding the tabs is already quite an improvement.
Regards, Andreas