multiAlign
Sublime Text插件,用于逐步对多行中的多个对齐字符进行对齐
详细信息
安装量
- 总计 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
multiAlign
[功能] [用法] [配置] [可用设置] [安装] [许可证]
我已经尝试了一些Sublime Text(https://text.sublime.net.cn)现有的各种对齐插件,但是我对它们的性能并不满意。例如,我想在同一行中对多个字符进行对齐,并且能够使用更复杂的方式对行内注释和关键字进行对齐。最后,我决定从头开始编写自己的插件以实现我希望拥有的所有功能。由于实现非常灵活,并且可以轻松地根据用户的需求进行配置,所以我希望与所有对此感兴趣的人分享它。
我在Windows上为Sublime Text 3开发了此插件,但它也应该适用于Linux/OS X和Sublime Text 2。
功能
- 在不同缩进级别上持续地对多个光标周围的多个行中的多个对齐字符进行逐步对齐(因此我相信multiAlign的名字很合适:sweat_smile)。
- 可以在同一行中多次调用插件以对多个连续的行中的对齐字符进行对齐。
- 对齐字符可以在其左右留有特定的必须间隔数。
- 对齐字符可以有条件的前缀,这些前缀在对齐过程中被考虑。
- 对齐字符可以由多个字符组成(也可以对关键字进行对齐)。
- 对齐字符可以限制在特定的作用域中(编程语言)。
- 可以对齐字符设置为排除特定的作用域(编程语言)。
- 对齐字符可以设置在它们被认为是有效的对齐时的条件。
重要:对齐字符不匹配周围的空格,因此对关键字进行对齐可能会在代码的子字符串中产生匹配。请确保为关键字对齐字符定义严格的限制!
用法
请将一个或多个光标放在您想要对齐代码的位置,然后按
(Windows/Linux): (Ctrl+Alt+A)
(OS X): (Ctrl+Cmd+A)
请注意:
- 如果设置了多个光标,它们都将得到相同的对齐。
- 如果可以逐键对齐多个对齐字符,则每个按键将对齐第一行中未对齐的字符。
- 如果对齐字符位于行首,则其左侧的空格数量不会改变。
- 如果对齐字符位于行尾,则不会在其右侧添加空格。
以下是它是如何工作的
- 将包含所有对齐字符的总体正则表达式(总体正则式)进行编译。
- 使用此总体正则表达式,解析主要光标所在的行以获取可对齐的对齐字符的参考列表(主要对齐字符)。
- 对于所有光标,使用总体正则表达式解析光标行并与主要对齐字符进行比较。
- 为了被视为有效的对齐,对齐字符的顺序必须与主要行的顺序相同。
- 如果对齐字符无效,则其右侧的对齐字符也无效。
- 如果在光标行中检测到至少一个有效的对齐字符,则将检查上方和下方的行,直到至少满足一个条件。
- 缩进级别会变化(基于单个光标缩进级别)。
- 检测到空行(可以关闭 -参见配置)。
- 找不到有效的对齐字符。
- 到达文件开头或结尾。
- 识别所有可能对齐的对齐字符和行后,确定公共对齐位置(目标位置)。
- 对于每个主要对齐字符,检查所有可能对齐的行中对齐字符的位置。
- 如果对齐字符已正确对齐在所有已识别的行中,则检查下一个主要对齐字符。
- 如果在至少一行中,对齐未正确定位,则在所有已识别的行中对齐当前主要对齐字符。
配置
multiAlign附带一些基本对齐字符的默认配置,但用户可以通过单独的插件设置文件(multiAlign.sublime-settings
)或输入它们到通用的Sublime Text设置文件(Preferences.sublime-settings
)来覆盖这些设置。
重要性的顺序是
请参阅可用的设置以获取有关每个设置的更多信息。
默认设置
以下是多对齐插件中附带的一些默认设置。由于我目前正在使用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': ['[]']
}
]
}
插件设置文件
通过Sublime Text转到您的包目录
(Windows/Linux): Preferences -> Browse Packages... (OS X): Sublime Text -> Preferences -> Browse Packages...
转到
User
目录并创建或编辑multiAlign.sublime-settings
文件。使用您想要覆盖的设置的键
break_at_empty_lines
或align_chars
添加您自己的自定义配置。
{
"break_at_empty_lines": true,
"break_at_non_matching_lines": true,
"align_chars": [
{
"char": "=",
"alignment": "right",
"spaces_left": 1,
"spaces_right": 1
}
]
}
Sublime Text设置文件
通过Sublime Text打开通用的
Preferences.sublime-settings
文件(Windows/Linux): Preferences -> Settings... (OS X): Sublime Text -> Preferences -> Settings...
使用您想要覆盖的设置的键
mulitAlign_break_at_empty_lines
或mulitAlign_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
}
]
}
可用的设置
顶级设置
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>
字典对象的列表,指定单个对齐字符的配置。由于对齐字符的配置对插件正确工作至关重要,我将详细解释每个设置。
char: <str>
alignment: <str>
spaces_left: <int>
spaces_right: <int>
prefixes: <list>
is_in_scope: <list>
not_in_scope: <list>
is_enclosed_by: <list>
not_enclosed_by: <list>
is_left_of_char: <list>
not_left_of_char: <list>
is_right_of_char: <list>
not_right_of_char: <list>
除了基本的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
可以由多个字符组成,因此可能在关键字上进行对齐。由于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)