Heuristically determine the indent style
use Text::FindIndent; my $indentation_type = Text::FindIndent->parse($text, skip_pod => 1); if ($indentation_type =~ /^s(\d+)/) { print "Indentation with $1 spaces\n"; } elsif ($indentation_type =~ /^t(\d+)/) { print "Indentation with tabs, a tab should indent by $1 characters\n"; } elsif ($indentation_type =~ /^m(\d+)/) { print "Indentation with $1 characters in tab/space mixed mode\n"; } else { print "Indentation style unknown\n"; }
This is a module that attempts to intuit the underlying indent \*(L"policy\*(R" for a text file (most likely a source code file).
The class method \*(C`parse\*(C' tries to determine the indentation style of the given piece of text (which must start at a new line and can be passed in either as a string or as a reference to a scalar containing the string).
Returns a letter followed by a number. If the letter is \*(C`s\*(C', then the text is most likely indented with spaces. The number indicates the number of spaces used for indentation. A \*(C`t\*(C' indicates tabs. The number after the \*(C`t\*(C' indicates the number characters each level of indentation corresponds to. A \*(C`u\*(C' indicates that the indenation style could not be determined. Finally, an \*(C`m\*(C' followed by a number means that this many characters are used for each indentation level, but the indentation is an arbitrary number of tabs followed by 0-7 spaces. This can happen if your editor is stupid enough to do smart indentation/whitespace compression. (I.e. replaces all indentations many tabs as possible but leaves the rest as spaces.)
The function supports parsing of \*(C`vim\*(C' modelines. Those settings override the heuristics. The modeline's options that are recognized are \*(C`sts\*(C'/\*(C`softtabstob\*(C', \*(C`et\*(C'/\*(C`noet\*(C'/\*(C`expandtabs\*(C'/\*(C`noexpandtabs\*(C', and \*(C`ts\*(C'/\*(C`tabstop\*(C'.
Similarly, parsing of \*(C`emacs\*(C' Local Variables is somewhat supported. \*(C`parse\*(C' use explicit settings to override the heuristics but uses style settings only as a fallback. The following options are recognized: \*(C`tab-width\*(C', \*(C`indent-tabs-mode\*(C', \*(C`c-basic-offset\*(C', and \*(C`style\*(C'.
There is one named option that you can pass to \*(C`parse()\*(C': \*(C`skip_pod\*(C'. When set to true, any section of \s-1POD\s0 (see perlpod) will be ignored for indentation finding. This is because verbatim paragraphs and examples embedded in \s-1POD\s0 or quite often indented differently from normal Perl code around the \s-1POD\s0 section. Defaults to false. Example:
my $mode = Text::FindIndent->parse(\$text, skip_pod => 1);
A class method that converts the output of \*(C`parse(\$text)\*(C' into a series of vi(m) commands that will configure vim to use the detected indentation setting. Returns zero (failure) or more lines of text that are suitable for passing to \*(C`VIM::DoCommand()\*(C' one by one.
As a convenience, if the argument to \*(C`to_vim_commands\*(C' doesn't look like the output of \*(C`parse\*(C', it is redirected to \*(C`parse\*(C' first.
To use this, you can put the following line in your .vimrc if your vim has Perl support. Suggestions on how to do this in a more elegant way are welcome. The code should be on one line but is broken up for displaying:
map <F5> <Esc> :perl use Text::FindIndent;VIM::DoCommand($_) for Text::FindIndent->to_vim_commands(join "\n", $curbuf->Get(1..$curbuf->Count()));<CR>
(Patches to implement the equivalent for emacs would be welcome as well.)
Bugs should be reported via the \s-1CPAN\s0 bug tracker at
<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Text-FindIndent>
For other issues, contact the author.
Steffen Mueller <[email protected]>
Adam Kennedy <[email protected]>
Copyright 2008 - 2010 Steffen Mueller.
Copyright 2008 - 2010 Adam Kennedy,
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the \s-1LICENSE\s0 file included with this module.