Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to enforce using tabs instead of spaces in Java?

CheckStyle offers to check for consistent use of spaces, but sadly lacks the opposite idea: Force source code to use tabs. Is there some way to add this functionality? It does not have to be CheckStyle, other tools are welcome as well.

Same as this question but for Java.

EDIT

I don't need a code beautifier, since the normal state of the codebase will be all tabs. I just need a tool which can report the presence of alternate indentation. That way I can set up a new continuous build configuration which will fail when spaces are introduced.

like image 647
Craig P. Motlin Avatar asked Apr 15 '11 15:04

Craig P. Motlin


People also ask

How do I insert a tab instead of spaces?

The tab character can be inserted by holding the Alt and pressing 0 and 9 together.

Does Java use tabs or spaces?

Java: 4 spaces, tabs must be set at 8 spaces. Both are acceptable. Data from Github suggests that around 10-33% of the Java repositories prefer tabs, and the majority use spaces in different formations, preferring 4 spaces over 2.

Why tabs are better than spaces?

They're better than spaces because they turn “number of spaces per indent” into text text editor setting. One tab == one indent == one keypress in any editor.


2 Answers

Although Checkstyle has no builtin check for this, you can enforce tabs-only indentation using the RegexpSinglelineJava check. Note that this only checks which character is used for indentation, not for the correct level of indentation.

Shamelessly stolen from the Hibernate OGM source:

<module name="RegexpSinglelineJava">
    <property name="format" value="^\t* +\t*\S"/>
    <property name="message" value="Line has leading space characters; indentation should be performed with tabs only."/>
    <property name="ignoreComments" value="true"/>
</module>
like image 124
Ben Blank Avatar answered Sep 20 '22 20:09

Ben Blank


Using spaces instead of tabs to indent is preferred because it offers consistency of layout across all editors/viewers. But if you still want it, you can always make your own custom check for checkstyle or a custom maven plugin /ant task. Logic shouldnt be difficult to implement either - all you have to check whether leading space on any line is greater than the tab length.

Edit: including an ant example. Its two weeks now since you posted and you're still not happy, and I had some free time :) So I cooked up a little ant custom task solution for you.

The Ant task

public class SpaceDetectorTask extends Task {
    public static final String REGEX = "^[ ]+";
    public static final Pattern p = Pattern.compile(REGEX);

    private FileSet fileSet;
    private boolean failOnDetection;

    // Usual getters/setters

    public void addFileSet(FileSet fileSet) {
        this.fileSet = fileSet;
    }

    public void execute() {
        DirectoryScanner ds = fileSet.getDirectoryScanner();
        String[] files = ds.getIncludedFiles();
        for (int x = 0; x <= files.length -1; x++) {
            process(ds.getBasedir(), files[x]);
        }
    }

    public void process(File dir, String file) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(dir, file)));
            String line;
            int linecount = 0;
            System.out.println("File: " + file);
            boolean ignore = false;
            while((line = reader.readLine()) != null) {
                linecount++;

                // exclude comment blocks
                if (line.contains("/**") || line.contains("*/")) {
                    ignore = !ignore;
                    continue;
                }

                if (!ignore) {
                    if (p.matcher(line).find()) {
                        int spcCount = line.length() - (line.replaceAll(REGEX, "")).length();
                        if (spcCount >= 4) { // break whenever 4 leading spaces are detected. Configure as you need.
                            String msg = "File: "+ file + " is using spaces as indentation.";
                            if (failOnDetection) {
                                throw new BuildException(msg);
                            } else {
                                getProject().log(msg);
                            }
                        }
                    }
                    reader.close();
                }
            }
        } catch (IOException e) {
            if (failOnDetection) {
                throw new BuildException(e);
            } else {
                getProject().log("File: " + file + "\n" + e.getMessage());
            }
        }
    }

In ant build.xml

  1. Compile the task first
  2. Declare it

    <taskdef name="detect-spaces"
             classname="com.blah.blah.build.tools.SpaceDetectorTask">
            <classpath>
                <pathelement path="${dir.classes}"/>
                <fileset dir="C:/apache-ant-1.7.1/lib">
                    <include name="**/*.jar"/>
                </fileset>
            </classpath>
    </taskdef>
    
  3. use it

    <target name="rules.spaces">
        <detect-spaces
            failOnDetection="true">
            <fileset dir="${dir.src.java}">
                <include name="**/*.java"/>
            </fileset>
        </detect-spaces>
    </target>
    

Writing up a maven/checkstyle plugin shoulnt be difficult either.

like image 37
d-live Avatar answered Sep 17 '22 20:09

d-live