Python + vim + spaces vs tab

  • Thread starter Jean-Michel Pichavant
  • Start date
J

Jean-Michel Pichavant

Hello,

Does anyone knows a way to configure vim so it automatically select to
correct expandtab value depending on the current buffer 'way of doing' ?
I need to edit different files, some are using spaces, others tabs.
Those belong to different projects, and changing all spaces to tabs is
not an option for me.

I can't make vim automatically comply with the current buffer coding
style, anyone knows if it is possible ?

JM
 
N

Neil Cerutti

Hello,

Does anyone knows a way to configure vim so it automatically
select to correct expandtab value depending on the current
buffer 'way of doing' ? I need to edit different files, some
are using spaces, others tabs. Those belong to different
projects, and changing all spaces to tabs is not an option for
me.

I can't make vim automatically comply with the current buffer
coding style, anyone knows if it is possible ?

:h filetypes will get you started on the right path. It'll be up
to you to program the recognition logic. Do you have a heuristic
in mind?

You will be better off converting tabbed files to be tabless,
which is pretty easy in vim.

:set expandtab
:set tabstop=N
:retab

N should be whatever value makes the file look right, usually 4
or 8.
 
H

Hans Mulder

Jean-Michel Pichavant said:
Hello,

Does anyone knows a way to configure vim so it automatically select to
correct expandtab value depending on the current buffer 'way of doing' ?
I need to edit different files, some are using spaces, others tabs.
Those belong to different projects, and changing all spaces to tabs is
not an option for me.

I can't make vim automatically comply with the current buffer coding
style, anyone knows if it is possible ?

If you can't get vim to automatically recognize the different styles you
have to work with, then you could look into adding a "modeline" to each
file. Typing ":help modeline" in vim will tell you how they work.

Adding such a line to each and every file may be a bit of work, and you
may have to convince other people working on the project that "explicit
is better than implicit".

-- HansM
 
R

Robin Becker

If you can't get vim to automatically recognize the different styles you
have to work with, then you could look into adding a "modeline" to each
file. Typing ":help modeline" in vim will tell you how they work.

Adding such a line to each and every file may be a bit of work, and you
may have to convince other people working on the project that "explicit
is better than implicit".

-- HansM

I use the following at the end of my vimrc
if exists("loaded_python_tabs") || &cp || exists("#BufReadPre#*.py")
finish
endif

augroup python_tabs
" Remove all python_tabs autocommands
au!
autocmd BufWritePre,FileWritePre *.py,*.pyw,<PYTHON;python> call s:writepre()
autocmd BufWritePost,FileWritePost *.py,*.pyw,<PYTHON;python> call s:writepost()
autocmd BufAdd,BufFilePost,BufReadPost,FileReadPost,FilterReadPost *.py,*.pyw,<PYTHON;python> call s:readpost()
augroup END
fun s:readpost()
if &expandtab
return
endif
let l = line(".")
let c = col(".")
let v:errmsg=""
silent! /^\t
let tabbed_python = v:errmsg==""
silent nohls
if !exists("b:was_tabbed_python")
let b:was_tabbed_python = tabbed_python
endif
if !tabbed_python
let mod_save=&modified
try
'[,']retab!
catch
endtry
let &l:modified=mod_save
endif
call cursor(l,c)
endfun
fun s:writepre()
let b:tabs_expanded = 0
if &expandtab || (exists("b:was_tabbed_python") && b:was_tabbed_python)
return
endif
setlocal expandtab
execute "silent '[,']retab!"
let s:ma_save = &ma
setlocal ma
let b:tabs_expanded = 1
endfun
fun s:writepost()
if b:tabs_expanded
setlocal noexpandtab
execute "silent '[,']retab!"
let &l:ma = s:ma_save
endif
unlet b:tabs_expanded
endfun
let loaded_python_tabs = 1

the idea is to switch between using tabs and spaces depending on the original
source. If the input is all spaces we switch to tabs internally and then convert
on output. If it was tabbed we keep that, if mixed I think it keeps that. This
works for me as I often work with long latency connections and prefer tabs to
spaces.
 
J

Jean-Michel Pichavant

Robin said:
If you can't get vim to automatically recognize the different styles you
have to work with, then you could look into adding a "modeline" to each
file. Typing ":help modeline" in vim will tell you how they work.

Adding such a line to each and every file may be a bit of work, and you
may have to convince other people working on the project that "explicit
is better than implicit".

-- HansM

I use the following at the end of my vimrc

the idea is to switch between using tabs and spaces depending on the
original source. If the input is all spaces we switch to tabs
internally and then convert on output. If it was tabbed we keep that,
if mixed I think it keeps that. This works for me as I often work with
long latency connections and prefer tabs to spaces.

Thanks, this is no exactly what I needed, but from your code I managed
to write something that suits me.
It basically counts the occurrence of tabs and 4-spaces at the beginning
of lines, and use the greatest number as criterion for setting tab or
space mode
Something usefull is to get also the current mode in the status bar.

Because of my poor knowledge of the vim scripting language I sometimes
had to switch to python, but I guess it won't bother anyone in this list :)


set statusline=%t\ %y\ format:\ %{&ff};\ %{Statusline_expandtab()}\ [%c,%l]

function! Statusline_expandtab()
if &expandtab == 0
return "ind:tabs"
else
return "ind:space"
endif
endfunction

autocmd BufAdd,BufFilePost,BufReadPost,FileReadPost,FilterReadPost
*.py,*.pyw,<PYTHON;python> call s:guessType()

function! WordCount(word)
python <<EOF

import vim
import re

word = vim.eval("a:word")
txt = '\n'.join(vim.current.buffer[:])
match = re.findall(word, txt)
count = len(match)
vim.command("let l:_count=%s" % count)
EOF
return l:_count
endfunction

function! s:guessType()
let _tab = WordCount('\n\t')
let _space = WordCount('\n ')
if _tab > _space
set noexpandtab
else
set expandtab
endif
endfunction
 
J

Jorgen Grahn

:h filetypes will get you started on the right path. It'll be up
to you to program the recognition logic. Do you have a heuristic
in mind?

You will be better off converting tabbed files to be tabless,
which is pretty easy in vim.

But as he wrote, that is not an option. And I can believe that -- if
you are many programmers, working in parallel on some fairly big and
mature project, the *last* thing you want is someone coming in and
reindenting everything.

/Jorgen
 
R

Robin Becker

On 09/06/2010 13:06, Jean-Michel Pichavant wrote:
.........
the idea is to switch between using tabs and spaces depending on the
original source. If the input is all spaces we switch to tabs
internally and then convert on output. If it was tabbed we keep that,
if mixed I think it keeps that. This works for me as I often work with
long latency connections and prefer tabs to spaces.

Thanks, this is no exactly what I needed, but from your code I managed
to write something that suits me.
It basically counts the occurrence of tabs and 4-spaces at the beginning
of lines, and use the greatest number as criterion for setting tab or
space mode
Something usefull is to get also the current mode in the status bar.

Because of my poor knowledge of the vim scripting language I sometimes
had to switch to python, but I guess it won't bother anyone in this list :)


set statusline=%t\ %y\ format:\ %{&ff};\ %{Statusline_expandtab()}\ [%c,%l]

function! Statusline_expandtab()
.......
I'm not exactly an expert at vim programming either :(

nice idea to show the mode in the status.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top