Search code examples
pythonvim

Use Vim Retab to solve TabError: inconsistent use of tabs and spaces in indentation?


Apologize for the newbie question, but I have read the manual, this question, and tried several times without results I expected.

So I was using vim to edit a file (attached). But when running, I got the TabError: inconsistent use of tabs and spaces in indentation error.

Here is what I have tried:

  • Open the file with Vim. type :retab, and :x. Run the file again. Still got the TabError message.
  • Open the file again and type :retab! and :x. Run the file again. Still got the TabError message.
  • Open the file again and type :retab! 4 and :x. Run the file again. This time it works but I have no idea why? Plus, in the files indentation seems excessively long. (I read here that the editor might display 8 spaces for a tab)

My questions are:

  • What does :retab, :retab!, and :retab! 4 mean?

  • Why doesn't :retab work on my file?

    #!/usr/bin/env python
    #Reduce function for computing matrix multiply A*B    
    #Input arguments:
    #variable n should be set to the inner dimension of the matrix product (i.e., the number of columns of A/rows of B) 
    import sys
    import string
    import numpy
    
    #number of columns of A/rows of B
    n = int(sys.argv[1]) 
    
    #Create data structures to hold the current row/column values (if needed; your code goes here)
    
    currentkey = None
    alist = [] # list for elelents in  A
    blist = [] # list for elements in B
    # input comes from STDIN (stream data that goes to the program)
    for line in sys.stdin:
        #Remove leading and trailing whitespace
        line = line.strip()
        #Get key/value 
        key, value = line.split('\t',1)
        print(key, value)
        #Parse key/value input (your code goes here)
        key = (key.split(',', 1)[0], key.split(',',1)[1])   
        value = (value.split(',', 1)[0], value.split(',',1)[1], value.split(',',1)[2])  
        #If we are still on the same key...
        if key==currentkey:
            #Process key/value pair (your code goes here)
            # store all values in a lisl
            if value[0]=='A':
            alist.append([value[1], value[2]])
            else:
            blist.append([value[1], value[2]])
            #Otherwise, if this is a new key...
        else:
        #If this is a new key and not the first key we've seen, i.e. currentkey!=None
            if currentkey:
        #compute/output result to STDOUT (your code goes here)
            alist = sorted(alist)
            blist = sorted(blist)
            newlist = [a[1]*b[1] for a,b in zip(alist, blist)]
            res = newlist.sum() 
            print(currentkey, res)
            currentkey = key
            #Process input for new key (your code goes here)
    

Solution

  • Just type :help retab in Vim and read. I think I can't explain it better than the help. Maybe you are missing the optional range part; use % prefix to apply to the whole file. Also useful is :set list to show you every chars; this will show you the tabs and line ends (disable with :set nolist) and :set <name> with no value to see the current value, ex : set tabstop or followed by some value to set.

    By showing all chars, enabling and disabling expansion of tabs into spaces with :set expandtab and :set noexpandtab, setting tabstop and by using for ex. :retab! 4 you can play your way around and switch from tabs only and spaces only, and change the tab column width.

    This link, vim settings for python might be useful also