tags:

views:

156

answers:

7

There are times that I have a code snippet that I want to post on a defect tracker, wiki, forum, etc. but it's deeply indented in the code. I usually have to highlight the code snippet, hit <shift>-<tab> until the indents aren't so bad, then copy/paste and then revert the code. It gets somewhat painful.

Is there a tool that can remove the tabs in front of the each line? Note that I don't want to remove all tabs from all lines, just same preceding number of tabs from each line. I'm thinking some function of Emacs could do this.

Here's an extreme example:

Before:

                            //This is usually some method in an anonymous inner class' anonymous inner class.
                            @Override
                            public void method(){
                                doSomething();
                            }

After:

//This is usually some method in an anonymous inner class' anonymous inner class.
@Override
public void method(){
    doSomething();
}

Notice how doSomething() still has a single tab in front of it.

+2  A: 

in vi it's just << to left shift by one indent width

so to do 10 lines - you do 10<<

phatmanace
A: 

Use a regular expression to remove the leading whitespace.

In emacs

C-M-%^<TAB><TAB><TAB><ENTER><ENTER>!

In VIM

:%s/^\t\t\t//g
Will Bickford
Won't doSomething() will lose its indent?
User1
This only removes the first 3 tabs on each line. So a 4th or 5th indent would become a 1st or 2nd. The '^' character denotes "start-of-line".
Will Bickford
This doesn't answer the question, unless you are seriously suggesting that he should copy the text from emacs, paste into vim, modify, and copy that to paste elsewhere, and that doesn't seem like a useful answer. Also requires to count the number of unindents, and surely there's a better way.
Roger Pate
I didn't notice the 'emacs' tag, hence the solution in vim. Adding an emacs variant.
Will Bickford
@Roger - Yep Bahbar posted an elegant solution. Generally I don't mind counting, but in emacs his way is definitely better.
Will Bickford
+15  A: 

Rectangle selection is my preferred way of doing this.

Put yourself at the beginning of the first line, C-space, go to the last line, and the end of the indentation you want to remove and C-x r k (rectangular kill). That does it.

Bahbar
+1 Does exactly what User1 wants.
Will Bickford
I do not like this method, since whitespace is the problem you should only remove whitespace, this method removes all characters in the region.
AlexCombas
+1 for using rectangular-kill.
vedang
This is the way I've always done it as well. But I'm liking the indent-rigidly solution @ http://stackoverflow.com/questions/2060442/unindenting-code-snippets/2060803#2060803
Michael Paulukonis
I had to read it a couple of times to understand "go to the last line and the end of indentation". Now rectangular kill makes sense. If only there were an emacs function that could automatically kill the rectangle, copy the code to clipboard, then undo the kill.
User1
+4  A: 

The actual method to do this in Emacs is with this key combination.

First select the section you want to remove the tabs from.

You could select the entire buffer:

CTRL+x h

Or, if you just want a region simply set the mark CTRL+SPACE where you want to begin and then navigate to where you want to end.

Then remove whitespace, for 10 whitespace characters do this:

CTRL+- 10 CTRL+x TAB


Since this is quite big, I'll break it down for you.

1) First we give the negative-argument command:

(negative-argument ARG)

kbd shortcut: CTRL+-

2) Next supply the numerical argument, in this case the number 10:

10

3) Then we call the indent-rigidly command

(indent-rigidly START END ARG)

kbd shortcut: CTRL+x TAB

So what we are doing is giving the argument of -10 to the command to indent-rigidly and the result is that 10 whitespace characters will be removed from the beginning of each line which we have selected, in this case we have the entire document selected (CTRL+x h), so 10 lines of whitespace will be removed from the beginning of every line of the entire document.

If a particular line has less than 10 whitespace it will only remove as many whitespace as possible, if there are more than 10 whitespace then some may be left over after it is finished.

In your example it looks like you have about 30 leading whitespace, so this should do the trick:

CTRL+- 30 CTRL+x TAB

Try a larger number if you want to remove more.

AlexCombas
+1  A: 
Dave
+1  A: 

If you know exactly how many tabs prefix each line (as you state), you could use a simple query-replace-regex to replace "^\t\t\t...\t" with "".

Loadmaster
+1  A: 

If you have your emacs c-style settings correct, then simply highlighting the snippet and pressing C-M-\ will indent it properly (if you're in c++-mode).

Josh Matthews