ctrl+shift+p filters: :st2 :st3 :win :osx :linux
浏览

multiAlign

作者: shwk86 全部

Sublime Text插件,用于逐步对多行中的多个对齐字符进行对齐

详细信息

  • 1.0.2
  • github.com
  • github.com
  • 6年前
  • 28分钟前
  • 6年前

安装量

  • 总计 2K
  • Win 1K
  • Mac 410
  • Linux 364
8月6日 8月5日 8月4日 8月3日 8月2日 8月1日 7月31日 7月30日 7月29日 7月28日 7月27日 7月26日 7月25日 7月24日 7月23日 7月22日 7月21日 7月20日 7月19日 7月18日 7月17日 7月16日 7月15日 7月14日 7月13日 7月12日 7月11日 7月10日 7月9日 7月8日 7月7日 7月6日 7月5日 7月4日 7月3日 7月2日 7月1日 6月30日 6月29日 6月28日 6月27日 6月26日 6月25日 6月24日 6月23日
Windows 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
Mac 1 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Linux 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

README

源代码
raw.githubusercontent.com

multiAlign

[功能] [用法] [配置] [可用设置] [安装] [许可证]

我已经尝试了一些Sublime Text(https://text.sublime.net.cn)现有的各种对齐插件,但是我对它们的性能并不满意。例如,我想在同一行中对多个字符进行对齐,并且能够使用更复杂的方式对行内注释和关键字进行对齐。最后,我决定从头开始编写自己的插件以实现我希望拥有的所有功能。由于实现非常灵活,并且可以轻松地根据用户的需求进行配置,所以我希望与所有对此感兴趣的人分享它。

我在Windows上为Sublime Text 3开发了此插件,但它也应该适用于Linux/OS X和Sublime Text 2。


功能

  • 在不同缩进级别上持续地对多个光标周围的多个行中的多个对齐字符进行逐步对齐(因此我相信multiAlign的名字很合适:sweat_smile)。
  • 可以在同一行中多次调用插件以对多个连续的行中的对齐字符进行对齐。
  • 对齐字符可以在其左右留有特定的必须间隔数。
  • 对齐字符可以有条件的前缀,这些前缀在对齐过程中被考虑。
  • 对齐字符可以由多个字符组成(也可以对关键字进行对齐)。
  • 对齐字符可以限制在特定的作用域中(编程语言)。
  • 可以对齐字符设置为排除特定的作用域(编程语言)。
  • 对齐字符可以设置在它们被认为是有效的对齐时的条件。

重要:对齐字符不匹配周围的空格,因此对关键字进行对齐可能会在代码的子字符串中产生匹配。请确保为关键字对齐字符定义严格的限制

[top]


用法

请将一个或多个光标放在您想要对齐代码的位置,然后按

(Windows/Linux): (Ctrl+Alt+A)

    (OS X):          (Ctrl+Cmd+A)

请注意:

  • 如果设置了多个光标,它们都将得到相同的对齐。
  • 如果可以逐键对齐多个对齐字符,则每个按键将对齐第一行中未对齐的字符。
  • 如果对齐字符位于行首,则其左侧的空格数量不会改变。
  • 如果对齐字符位于行尾,则不会在其右侧添加空格。

以下是它是如何工作的

  • 将包含所有对齐字符的总体正则表达式(总体正则式)进行编译。
  • 使用此总体正则表达式,解析主要光标所在的行以获取可对齐的对齐字符的参考列表(主要对齐字符)。
  • 对于所有光标,使用总体正则表达式解析光标行并与主要对齐字符进行比较。
  • 为了被视为有效的对齐,对齐字符的顺序必须与主要行的顺序相同。
  • 如果对齐字符无效,则其右侧的对齐字符也无效。
  • 如果在光标行中检测到至少一个有效的对齐字符,则将检查上方和下方的行,直到至少满足一个条件。
    • 缩进级别会变化(基于单个光标缩进级别)。
    • 检测到空行(可以关闭 -参见配置)。
    • 找不到有效的对齐字符。
    • 到达文件开头或结尾。
  • 识别所有可能对齐的对齐字符和行后,确定公共对齐位置(目标位置)。
  • 对于每个主要对齐字符,检查所有可能对齐的行中对齐字符的位置。
  • 如果对齐字符已正确对齐在所有已识别的行中,则检查下一个主要对齐字符。
  • 如果在至少一行中,对齐未正确定位,则在所有已识别的行中对齐当前主要对齐字符。

[top]


配置

multiAlign附带一些基本对齐字符的默认配置,但用户可以通过单独的插件设置文件multiAlign.sublime-settings)或输入它们到通用的Sublime Text设置文件Preferences.sublime-settings)来覆盖这些设置。

重要性的顺序是

  1. 插件设置文件
  2. Sublime Text设置文件
  3. 默认设置

请参阅可用的设置以获取有关每个设置的更多信息。


默认设置

以下是多对齐插件中附带的一些默认设置。由于我目前正在使用Python和Fortran,我只添加了针对这两种编程语言的具体设置,但您可以在插件设置文件Sublime Text设置文件中轻松设置自己的对齐字符。

{
    "break_at_empty_lines": true,
    "break_at_non_matching_lines": true,
    "align_chars": [
        {
            'char':            ' import ',
            'alignment':       'right',
            'spaces_left':     0,
            'spaces_right':    0,
            'is_in_scope':     ['source.python'],
            'is_left_of_char': ['from ']
        },
        {
            'char':            ' as ',
            'alignment':       'right',
            'spaces_left':     0,
            'spaces_right':    0,
            'is_in_scope':     ['source.python'],
            'is_left_of_char': ['import ']
        },
        {
            'char':         '#',
            'alignment':    'right',
            'spaces_left':  3,
            'spaces_right': 1,
            'is_in_scope':  ['source.python']
        },
        {
            'char':         '::',
            'alignment':    'right',
            'spaces_left':  1,
            'spaces_right': 1,
            'is_in_scope':  ['source.modern-fortran', 'source.fixedform-fortran']
        },
        {
            'char':             ' intent',
            'alignment':        'right',
            'spaces_left':      0,
            'spaces_right':     0,
            'is_in_scope':      ['source.modern-fortran', 'source.fixedform-fortran'],
            'is_right_of_char': ['::']
        },
        {
            'char':         '&',
            'alignment':    'right',
            'spaces_left':  1,
            'spaces_right': 0,
            'is_in_scope':  ['source.modern-fortran', 'source.fixedform-fortran']
        },
        {
            'char':         '=>',
            'alignment':    'right',
            'spaces_left':  1,
            'spaces_right': 1
        },
        {
            'char':            '=',
            'alignment':       'right',
            'spaces_left':     1,
            'spaces_right':    1,
            'prefixes':        ['+', '-', '*', '/', '.', '%', '<', '>', '!', '=', '~', '&', '|'],
            'not_enclosed_by': ['()', '[]']
        },
        {
            'char':            ':',
            'alignment':       'left',
            'spaces_left':     0,
            'spaces_right':    1,
            'not_enclosed_by': ['[]']
        }
    ]
}

[top]


插件设置文件

  • 通过Sublime Text转到您的包目录

    (Windows/Linux): Preferences -> Browse Packages...
    
    (OS X):          Sublime Text -> Preferences -> Browse Packages...
    
  • 转到User目录并创建或编辑multiAlign.sublime-settings文件。

  • 使用您想要覆盖的设置的键break_at_empty_linesalign_chars添加您自己的自定义配置。

{
    "break_at_empty_lines": true,
    "break_at_non_matching_lines": true,
    "align_chars": [
        {
            "char": "=",
            "alignment":       "right",
            "spaces_left":     1,
            "spaces_right":    1
        }
    ]
}

[top]


Sublime Text设置文件

  • 通过Sublime Text打开通用的Preferences.sublime-settings文件

    (Windows/Linux): Preferences -> Settings...
    
    (OS X):          Sublime Text -> Preferences -> Settings...
    
  • 使用您想要覆盖的设置的键mulitAlign_break_at_empty_linesmulitAlign_align_chars添加您自己的自定义配置。

{
    "multiAlign_break_at_empty_lines": true,
    "multiAlign_break_at_non_matching_lines": true,
    "multiAlign_align_chars": [
        {
            "char": "=",
            "alignment":       "right",
            "spaces_left":     1,
            "spaces_right":    1
        }
    ]
}

[top]


可用的设置

顶级设置

break_at_empty_lines: <bool> / multiAlign_break_at_empty_lines: <bool>

布尔值指定是否应在空行处中断对齐检查过程。如果设置为false,则插件将在空行之后继续检查行,直到它们具有相同的缩进级别。


break_at_non_matching_lines: <bool> / multiAlign_break_at_non_matching_lines: <bool>

Boolean值,用于指定是否应在对齐字符不匹配的行上中断对齐检查过程。如果设置为false,则插件在查看具有相同缩进级别的行之后,会继续检查空行。


align_chars: <list> / multiAlign_align_chars: <list>

字典对象的列表,指定单个对齐字符的配置。由于对齐字符的配置对插件正确工作至关重要,我将详细解释每个设置。


align_chars设置的列表

除了基本的char设置外,对齐字符配置的所有其他设置都是可选的。如果没有为对齐字符配置,将使用以下默认值进行对齐

default_settings = {
    "alignment":         "right",
    "spaces_left":       1,
    "spaces_right":      1,
    "prefixes":          [],
    "is_in_scope":       [],
    "not_in_scope":      [],
    "not_enclosed_by":   [],
    "not_left_of_char":  [],
    "not_right_of_char": [],
    "is_enclosed_by":    [],
    "is_left_of_char":   [],
    "is_right_of_char":  []
}

示例

{
    "align_chars": [
        {
            'char':              'bar',
            'alignment':         'right',
            'spaces_left':       4,
            'spaces_right':      1,
            'prefixes':          ['+', '-', 'foo'],
            'is_in_scope':       ['source.python'],
            'not_in_scope':      ['source.perl'],
            'not_enclosed_by':   ['()', ('[', ']'), ['{', '}']],
            'not_left_of_char':  ['baz'],
            'not_right_of_char': ['bar'],
            'is_enclosed_by':    [('<', '>'), ';;'],
            'is_left_of_char':   ['#'],
            'is_right_of_char':  ['baz']
        }
    ]
}

以下是对各个设置的说明及其使用时需要考虑的因素

设置列表


char: <str>

对齐应发生的字符。更确切地说,char可以由多个字符组成,因此可能在关键字上进行对齐。由于char不匹配空格,请考虑为关键字对齐字符添加强制空格,并定义严格的限制,以避免代码子字符串中的意外匹配。

示例

'char': '='

对齐前 “ foobar= 1 baz =2

_after alignment_
foobar = 1
baz    = 2
**Example**

> `'char': 'import'`

_before alignment_
from os import path
from sys   import exit
_after alignment_
from os  import path
from sys import exit
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="alignment"></a>
**`alignment: <str>`**

The direction where the alignment character should be positioned after alignment.

-`left`: Places the alignment character to the left and fills in spaces right of it in order to align the characters following the alignment character. It is for example used for `:` alignment in the [default setting](#default-settings).


**Example** (`'char': ':'`)

> `'alignment': 'left'`

_before alignment_
foobar  : 1
baz :  2
_after 'left' alignment_
foobar: 1
baz:    2
-`right`: Places the alignment character to the right and fills in spaces left of it in order to align the characters following the alignment character. It is for example used for `=` alignment in the [default setting](#default-settings).

**Example** (`'char': '='`)

> `'alignment': 'right'`

_before alignment_
foobar= 1
baz =2
_after 'right' alignment_
foobar = 1
baz    = 2
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="spaces_left"></a>
**`spaces_left: <int>`**

An integer number specifying the minimum number of spaces that should be left of the alignment character when the alignment has been completed. The actual number of spaces left of the alignment character might be higher depending on the `alignment` and position of corresponding alignment character in the other lines getting aligned.

**Example** (`'char': '='`)

> `'spaces_left': 0`

_before alignment_
foobar= 1
baz =2
_after alignment_
foobar= 1
baz   = 2
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="spaces_right"></a>
**`spaces_right: <int>`**

An integer number specifying the minimum number of spaces that should be right of the alignment character when the alignment has been completed. The actual number of spaces right of the alignment character might be higher depending on the `alignment` and position of corresponding alignment character in the other lines getting aligned.

**Example** (`'char': '='`)

> `'spaces_right': 0`

_before alignment_
foobar= 1
baz =2
_after alignment_
foobar =1
baz    =2
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="prefixes"></a>
**`prefixes: <list>`**

A list of strings containing the potential prefixes the alignment character might have. If a prefix exists it will be treated as if it was part of the `char` during the alignment process. The prefixes can consist of multiple characters in case there is a use case for that.

**Example** (`'char': '='`)

> `'prefixes': ['+', '-']`

_before alignment_
foobar+= 1
baz =2
_after alignment_
foobar += 1
baz     = 2
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="is_in_scope"></a>
**`is_in_scope: <list>`**

A list of strings specifying the programming languages the alignment character should be applied to. The strings have to match the [scope](https://text.sublime.net.cn/docs/3/scope_naming.html) in Sublime Text. To determine the scope place your cursor in a corresponding file and press:

        (Windows/Linux): (Ctrl+Alt+Shift+P)

        (OS X):          (Ctrl+Shift+P)

If the list is empty the alignment character is used for every alignment regardless of the current programming language. If the list `is_in_scope` is not empty and the current scope is not one of them the alignment character will not even be added to the [overall regex](#usage). As a result the same character can have different alignment character settings for different programming languages.

**Example**

> `'is_in_scope': ['source.python', 'source.modern-fortran', 'source.fixedform-fortran']`

[[list of settings]](#list_of_settings)

------------------------------------------

<a name="not_in_scope"></a>
**`not_in_scope: <list>`**

A list of strings specifying the programming languages the alignment character should not be applied to. The strings have to match the [scope](https://text.sublime.net.cn/docs/3/scope_naming.html) in Sublime Text. To determine the scope place your cursor in a corresponding file and press:

        (Windows/Linux): (Ctrl+Alt+Shift+P)

        (OS X):          (Ctrl+Shift+P)

If the list is empty the alignment character is used for every alignment regardless of the current programming language. If the list `not_in_scope` is not empty and the current scope is one of them the alignment character will not even be added to the [overall regex](#usage). As a result the application of the alignment character can be suppressed for specific programming languages only.

**Example**

> `'not_in_scope': ['source.perl']`

[[list of settings]](#list_of_settings)

------------------------------------------

<a name="is_enclosed_by"></a>
**`is_enclosed_by: <list>`**

A list of indexable data types (string, list or tuple) specifying characters the alignment character has to be enclosed by to be considered valid. The feature is intended to be used to **enforce** the alignment character being enclosed by brackets. The first index [0] of the list element is considered the opening bracket and the second index [1] is considered the closing bracket.

For each potential match of the alignment character the plugin will parse the string left of the alignment character and determine the bracket level (+1 for opening and -1 for closing bracket characters). In case for both the opening and the closing bracket the same character is defined the plugin will just check if the opening/closing bracket character is at least once left and right of the alignment character.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': '='`)

> `'is_enclosed_by': ['()', ('[', ']'), ['{', '}']]`

_before alignment_
foobar= foo(bar   =1)
baz =bar(foo=  2)
_after alignment_
foobar= foo(bar = 1)
baz =bar(foo    = 2)
**Example** (`'char': '='`)

> `'is_enclosed_by': [';;']`

_before alignment_
;foo;bar= foo;(bar =1)
baz =bar;(foo= 2);
_after alignment_
;foo;bar      = foo;(bar =1)
baz =bar;(foo = 2);
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="not_enclosed_by"></a>
**`not_enclosed_by: <list>`**

A list of indexable data types (string, list or tuple) specifying characters the alignment character must not be enclosed by to be considered valid. The feature is intended to be used to **suppress** the alignment character being enclosed by brackets. The first index [0] of the list element is considered the opening bracket and the second index [1] is considered the closing bracket.

For each potential match of the alignment character the plugin will parse the string left of the alignment character and determine the bracket level (+1 for opening and -1 for closing bracket characters). In case for both the opening and the closing bracket the same character is defined the plugin will just check if the opening/closing bracket character is at least once left and right of the alignment character.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': '='`)

> `'not_enclosed_by': ['()', ('[', ']'), ['{', '}']]`

_before alignment_
foobar(bar =1)= foo
baz(foo= 2) =bar
_after alignment_
foobar(bar =1) = foo
baz(foo= 2)    = bar
**Example** (`'char': '='`)

> `'not_enclosed_by': [';;']`

_before alignment_
;foo;bar= foo;(bar =1)
baz; =bar(foo= 2)
_after alignment_
;foo;bar= foo;(bar = 1)
baz;               = bar(foo= 2)
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="is_left_of_char"></a>
**`is_left_of_char: <list>`**

A list of string objects specifying characters which **must be** to the left of the alignment character in the same line to consider the alignment character valid. Those strings can consist of multiple characters in order to check for keywords. In case the list has multiple entries every single entry has to be left of the alignment character. It is intended to be used to define stricter limits when aligning at keywords.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': 'import'`)

> `'is_left_of_char': ['from']`

_before alignment_
# import math
from os import path
from sys   import exit
_after alignment_
# import math
from os  import path
from sys import exit
[[list of settings]](#list_of_settings)

------------------------------------------

<a name="not_left_of_char"></a>
**`not_left_of_char: <list>`**

A list of string objects specifying characters which **must not be** to the left of the alignment character in the same line to consider the alignment character valid. Those strings can consist of multiple characters in order to check for keywords. In case the list has multiple entries every single entry has to be left of the alignment character. It is intended to be used to define stricter limits when aligning at keywords.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': ':'`)

> `'not_left_of_char': ['[']`

_before alignment_
foo[0,:]   : bar
baz: [:, 3]
foobar: 2
_after alignment_
foo[0,:]   : bar
baz:    [:, 3]
foobar: 2
_**Note:** You might have expected all lines to get aligned but through_ `'not_left_of_char': 'as'` _in the third line the alignment character is invalid (see getp**as**s). As mentioned before you could consider adding mandatory spaces `'not_left_of_char': ' as '` _to avoid matches in substrings._

[[list of settings]](#list_of_settings)

------------------------------------------

<a name="is_right_of_char"></a>
**`is_right_of_char: <list>`**

A list of string objects specifying characters which **must be** to the right of the alignment character in the same line to consider the alignment character valid. Those strings can consist of multiple characters in order to check for keywords. In case the list has multiple entries every single entry has to be right of the alignment character. It is intended to be used to define stricter limits when aligning at keywords.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': 'intent'`)

> `'is_right_of_char': ['::']`

_before alignment_
integer,   intent(in)  :: cnt
real, intent(inout) ::  value
_after alignment_
integer, intent(in)  :: cnt
real,    intent(inout) ::  value
_**Note:** `::` would get aligned on the next keystroke if configured as alignment character._

[[list of settings]](#list_of_settings)

------------------------------------------

<a name="not_right_of_char"></a>
**`not_right_of_char: <list>`**

A list of string objects specifying characters which **must not be** to the right of the alignment character in the same line to consider the alignment character valid. Those strings can consist of multiple characters in order to check for keywords. In case the list has multiple entries every single entry has to be right of the alignment character. It is intended to be used to define stricter limits when aligning at keywords.

_Please note: This check is applied to matches of the [overall regex](#usage) thus it consumes a potential alignment character._

**Example** (`'char': 'import'`)

> `'not_right_of_char': ['as']`

_before alignment_
from datetime import time
from os import path
from sys import argv as arguments
_after alignment_
from datetime import time
from os       import path
from sys import argv as arguments
[[top]](#multialign) [[list of settings]](#list_of_settings)

------------------------------------------

## Installation

**Using the Package Control plugin:**

This is the easiest way and will automatically keep multiAlign up to date with the latest version.

- Install the [Package Control](https://packagecontrol.sublime.net.cn/installation) plugin (if not already installed).

- Open the Command Palette (`Ctrl+Shift+P`) in Sublime Text and select:

        Package Control: Install Package...

        multiAlign

**Using Git:**

- Go to your package directory through Sublime Text:

        (Windows/Linux): Preferences -> Browse Packages...

        (OS X):          Sublime Text -> Preferences -> Browse Packages...

- Clone the [multiAlign](git://github.com/shwk86/multiAlign.git) repository into your package directory.

        git clone git://github.com/shwk86/multiAlign.git

**Manual Download:**

- Browse to the [multiAlign](https://github.com/shwk86/multiAlign) plugin on GitHub.

- Download the repository as a [zip file](https://github.com/shwk86/multiAlign/archive/master.zip).

- Go to your package directory through Sublime Text:

        (Windows/Linux): Preferences -> Browse Packages...

        (OS X):          Sublime Text -> Preferences -> Browse Packages...

- Unzip the downloaded resposiory in your package directory.

- Remove the Git branch suffix in the directory name if you like to.

[[top]](#multialign)

------------------------------------------

## License

    MIT License

    Copyright (c) 2018 Jens Gorny

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.

[[top]](#multialign)