ctrl+shift+p filters: :st2 :st3 :win :osx :linux
Browse

Auto​Aligner

Sublime Text plugin for automatic code alignment.

Details

Installs

  • Total 45K
  • Win 30K
  • Mac 8K
  • Linux 7K
Oct 23 Oct 22 Oct 21 Oct 20 Oct 19 Oct 18 Oct 17 Oct 16 Oct 15 Oct 14 Oct 13 Oct 12 Oct 11 Oct 10 Oct 9 Oct 8 Oct 7 Oct 6 Oct 5 Oct 4 Oct 3 Oct 2 Oct 1 Sep 30 Sep 29 Sep 28 Sep 27 Sep 26 Sep 25 Sep 24 Sep 23 Sep 22 Sep 21 Sep 20 Sep 19 Sep 18 Sep 17 Sep 16 Sep 15 Sep 14 Sep 13 Sep 12 Sep 11 Sep 10 Sep 9
Windows 0 0 2 2 0 2 0 2 1 0 1 0 2 1 1 3 0 1 0 1 0 0 1 1 2 2 3 0 1 0 0 1 2 1 1 1 2 0 1 1 1 0 1 0 1
Mac 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1
Linux 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0

Readme

Source
raw.​githubusercontent.​com

Aligner Build Status

Sublime Text plugin for automatic code alignment.

This project is a tool for automatic code alignment. Formatting source code so that similar syntactic structures are arranged one above the other is often used to improve readability.

First of all, for convenience, the lines of code are split into tokens having a generic type. For example, the identifiers have type :id, and the brackets have type :bracket. The project implemented a type hierarchy, which simplifies the setup. It is defined in heirarchy.rb.

Each type must match the regular expression that recognizes token of this type. Moreover, the sequence of regular expressions must follow the hierarchy. That is more general regular expressions are used later. This sequence is described in the class TypeData, the file staff.rb.

To achieve maximum flexibility and independence of the type of language in which the source code is written, parser of the context-free grammars is implemented.

It works in conjunction with the algorithm based on dynamic programming, which finds matching having a maximum weight of two arrays of tokens.

The grammar in BNF is in file grammar.rb. Grammar should be designed so that if the rule of convolution can be applied, it should be applied, otherwise any sequence of tokens should still be correct.

Here is the example of grammar:

@@grammar.add_rule(:main, [:expr    ], [:reducible]);
@@grammar.add_rule(:expr, [:expr, :p], [:reducible]);
@@grammar.add_rule(:expr, [:p       ], [:reducible]);
t1 = [:expr, TokenTemplate.new(['=']), :expr]
@@grammar.add_rule(:expr, t1)
@@grammar.add_rule(:p, [:t], [:reducible])
@@grammar.add_rule(:t, [TokenTemplate.new(:id)], [:reducible]);

This grammar defines the assignment operation. The first argument to the procedure of adding rules - nonterminal. :main - axiom of the grammar. The second argument is the rule itself. It may consist of nonterminals and templates of tokens. A template can define a valid token type, a specific value, and excluded values.

Grammar shown corresponds to the following recorded in the canonical Backus–Naur form:

main ::= expr
expr ::= expr p | p | expr '=' expr
p    ::= t
t    ::= <any identifier>

Flag :reducible indicates that this rule has no effect on meta-expression being fitted. Meta-expression is an array of tokens, which also contains other meta-expression. Each level of the obtained tree structure is compared in the matching process only with the corresponding level of the other meta-expression. Consider the example: “ f(a, b + c ) f( b + c, a)

and

f(a , b + c) f(b + c, a )

When using the grammar, the program causes the alignment of the second type,
in spite of the fact that different function arguments are similar in spelling.
Such behavior is, of course, leads to improvement of readability.

To maximize the quality for each language you need to write its own grammar.

## Examples of work

From

@@types_inheritance[:space] = nil; @@types_inheritance[:quote] = nil; @@types_inheritance[:regexp] = nil; @@types_inheritance[:id] = nil; @@types_inheritance[:spchar] = nil;

To

@@types_inheritance[:space ] = nil; @@types_inheritance[:quote ] = nil; @@types_inheritance[:regexp] = nil; @@types_inheritance[:id ] = nil; @@types_inheritance[:spchar] = nil;

---

From

switch (state)
{
case State.QLD: city = "Brisbane”; break; case State.WA: city = “Perth”; break;
case State.NSW: city = “Sydney”; break;
default: city = “???”; break;
}

To

switch (state)
{ case State.QLD:city = “Brisbane”; break; case State.WA :city = “Perth” ; break; case State.NSW:city = “Sydney” ; break; default :city = “???” ; break; }

##Learning

Due to the fact that different people are accustomed to different ways of setting padding between tokens,
you must use the simplest method of fine-tuning.
The project implements a method of learning. The input is properly formatted string.
The resulting information is aggregated and used in the future for proper indenting.

There are 2 types of training: minimum and maximum indents.

Training starts with the command `ruby learner_test.rb <lang_type>`.
It is not required by default.
The resulting information is stored in files `max_by_type_<lang_type>.dat` and `min_by_type_<lang_type>.dat`.

##Installation

First of all, make sure that your system has a ruby interpreter `ver. >= 1.9`.
In Ubuntu you can use following command:

sudo apt-get install ruby

To install the plugin, clone it to your Siblime Text 2/3 Package directory with following command:

cd ~/.config/sublime-text-3/Packages git clone https://github.com/generall/aligner.git AutoAligner

Or you may install it with Package Control using name `AutoAligner`.

Default hotkey for alignment is: `["ctrl+k","ctrl+a"]`.

##Prospection

Here is a list of things that have to be improved.

* Automatic detection of similar lines for fully automated code alignment.
* Customization for different languages.
    * extended grammar
    * extended set of types of token
    * Customized languages:
        * C
        * java
* Extended machine learning for alignment decision
    * experiments with Markov chain learing
* to be continued...

## The expected course of action to add the grammar.

In file `staff.rb` add new regexp array by following pattern:

@@regexp_array[:new_grammar_name] = [ # [, , , , , ] [/'(.|['])*'/ , :quote , true , 0.1, 0, 1], … ]

Add BNF to file `grammar.rb`.