gue*_*tli 5 python macros pycharm python-black
我们还没有准备好用black自动格式化整个源代码。
但有时我想black -S
通过 PyCharm 在一个区域上执行。
有一个在文档提示如何运行black
(或者black -S
对整个文件(我喜欢))。但 ...
如何仅在选定区域运行黑色?
可以通过将 Python Black 实现为外部工具来在 PyCharm IDE 中的代码区域上使用Python Black。目前黑色有两个主要选项来选择要格式化的代码
[SRC]...
-c, --code TEXT
。以下实现展示了如何使用第二个选项来执行此操作。原因是,将黑色应用于整个模块可能会改变行数,从而使通过选择开始和结束行号来选择代码区域的工作变得更加复杂。
可以实现第一个选项,但需要在 Black 格式化整个模块后将初始代码区域映射到最终代码区域。
让我们以以下代码为例,该代码存在许多明显的 PEP-8 违规(缺少空格和空行):
"""
long multi-line
comment
"""
def foo(token:int=None)->None:
a=token+1
class bar:
foo:int=None
def the_simple_test():
"""the_simple_test"""
pass
Run Code Online (Sandbox Code Playgroud)
使用 Black作为 IDE 中的外部工具可以通过单击File
>
Tools
>
External Tools
或Add
图标进行配置Edit
。
感兴趣的是从 PyCharm IDE传递正确的宏 -(参见第 3 点“带有宏的参数”)到调用 Black 并执行必要处理的自定义脚本。也就是说你需要宏
FilePath - File Path
SelectionStartLine - Selected text start line number
SelectionEndLine - Select text end line number
PyInterpreterDirectory - The directory containing the Python interpreter selected for the project
但有时我想通过 PyCharm 在某个区域上执行 black -S。
您想要作为参数传递的任何其他Black CLI 选项最好放置在参数列表的末尾。
由于您可能在特定的 venv 上安装了 Black,因此该示例也使用了该PyInterpreterDirectory
宏。
屏幕截图说明了上述内容:
您需要实现一个脚本来调用 Black 并与 IDE 交互。以下是一个工作示例。需要注意的是:
import os
import pathlib
import tempfile
import subprocess
import sys
def region_to_str(file_path: pathlib.Path, start_line: int, end_line: int) -> str:
file = open(file_path)
str_build = list()
for line_number, line in enumerate(file, start=1):
if line_number > end_line:
break
elif line_number < start_line:
continue
else:
str_build.append(line)
return "".join(str_build)
def black_to_clipboard(py_interpeter, black_cli_options, code_region_str):
py_interpreter_path = pathlib.Path(py_interpeter) / "python.exe" # OS specific, .exe for Windows.
proc = subprocess.Popen([py_interpreter_path, "-m", "black", *black_cli_options,
"-c", code_region_str], stdout=subprocess.PIPE)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
# By default Black outputs binary, decodes to default Python module utf-8 encoding.
result = outs.decode('utf-8').replace('\r','') # OS specific, remove \r from \n\r Windows new-line.
tmp_dir_name = tempfile.gettempdir()
tmp_file = tempfile.gettempdir() + "\\__run_black_tmp.txt" # OS specific, escaped path separator.
with open(tmp_file, mode='w+', encoding='utf-8', errors='strict') as out_file:
out_file.write(result + '\n')
command = 'clip < ' + str(tmp_file) # OS specific, send result to clipboard for copy-paste.
os.system(command)
def main(argv: list[str] = sys.argv[1:]) -> int:
"""External tool script to run black on a code region.
Args:
argv[0] (str): Path to module containing code region.
argv[1] (str): Code region start line.
argv[2] (str): Code region end line.
argv[3] (str): Path to venv /Scripts directory.
argv[4:] (str): Black CLI options.
"""
# print(argv)
lines_as_str = region_to_str(argv[0], int(argv[1]), int(argv[2]))
black_to_clipboard(argv[3], argv[4:], lines_as_str)
if __name__ == "__main__":
main(sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)
最困难的部分已经完成。让我们使用新功能。
通常在编辑器中选择您想要作为代码区域的行。必须强调这一点,因为前一个宏SelectionStartLine
和SelectionEndLine
宏需要选择才能起作用。(参见下一个屏幕截图)。
运行之前实现的外部工具。这可以通过右键单击编辑器并选择 来完成External Tools
>
the_name_of_your_external_tool
。
只需粘贴(屏幕截图显示运行外部工具并按 后的结果Ctrl + v)。步骤 2中的实现将 Black 的输出复制到操作系统的剪贴板,这似乎是更好的解决方案,因为通过这种方式您可以在编辑器中更改文件,因此Undo
Ctrl + z也可以工作。通过在编辑器外部以编程方式覆盖文件来更改文件将不太无缝,并且可能需要在编辑器内刷新它。
您可以录制前面步骤的宏,并将其与键盘快捷键关联,以便通过一次按键即可实现上述功能(类似于复制粘贴Ctrl + c+ Ctrl + v)。
结束注释。
如果您需要调试步骤 2 中的功能,也可以使用与外部工具配置相同的宏来配置运行配置。
使用剪贴板时需要注意的是,字符编码可以跨层更改。我决定直接从临时文件中使用clip
和读取它,这是为了避免在命令行上将代码字符串传递给 Black,因为默认情况下 CMD Windows 编码不是 UTF-8。(对于 Linux 用户,这应该更简单,但可能取决于您的系统设置。)
一个重要的注意事项是,您可以选择一个代码区域,而无需更广泛的缩进级别上下文。这意味着,例如,如果您在一个类中只选择 2 个方法,它们将被传递给 Black 并使用模块级函数的缩进级别进行格式化。如果您仔细选择具有适当范围的代码区域,这应该不是问题。通过传递第 1 步SelectionStartColumn - Select text start column number
中的附加宏并在第 2 步脚本中的每行前面添加一定数量的空格,也可以轻松解决此问题。(理想情况下,此类功能将由 Black 作为 CLI 选项来实现。)在任何情况下,如果需要,使用将区域置于适当的缩进级别是非常容易的。Tab
问题的主要主题是如何将 Black 与 PyCharm IDE 集成到代码区域,因此演示第二个选项应该足以解决问题,因为第一个选项在大多数情况下只会增加实现特定的复杂性。(答案已经足够长了。实现第一个选项的具体细节将为 Black 项目提供一个很好的功能/拉取请求。)
归档时间: |
|
查看次数: |
197 次 |
最近记录: |