有方言意识的s-表达式缩进器

yasi的Python项目详细描述


yasi-又一个s表达式缩进器

简介

yasi是一个方言识别的s-表达式缩进器,它试图改进 多赖的压头 和vim的 内置压头。它可以处理 公共lisp clojure scheme newlisp 代码及其独特的语法。

它主要是一个批处理模式的压头,灵感来自Dorai's lispindent.lisp 它首先用 python 编写,然后翻译成 newlisp

它的缩进方式非常接近于lispindent.lisp和 尝试遵循这些风格 指导原则在合理的情况下。

对于使用其他任何编辑器的程序员来说,它应该是最有用的 而emacs则为类似lisp的表单和 开箱即用的S-表达式。

我做这个是因为没有足够好的工具 可以缩进我从教程中复制/粘贴并运行的代码 从Lisp开始。

安装

来自PYPI:

pip install --upgrade yasi

功能

yasi的 缩进在很大程度上依赖于给出它的正则表达式 与对应的lispindent.lisp相比的边。其功能包括:

  • 支持不同的主流语言 根据方言的正确缩进 语法/语义。例如, do 关键字是一个循环构造 在 common lisp 中,在 clojure 中执行顺序。关键词 在两种方言中应该是这样的:
;; In Common Lisp(do((j0(+j1)))(nil);Do forever.(formatt"~%Input ~D:"j)(let((item(read)))(if(nullitem)(return);Process items until NIL seen.(formatt"~&Output ~D: ~S"jitem))))
;; In Clojure(do(println "LOG: Computing...")(+ 11))
  • 能够修剪无关的空白和压缩代码
  • 对代码中可能出现的错误(如不匹配的括号)发出警告 和未闭合的字符串
  • 用户定义宏的正确缩进
  • 通过当前或中的配置文件支持其他关键字 主目录
  • 正确缩进 flets 标签 即使在Emacs中也不会出现
  • 从标准输入缩进
  • python版本可以输出初始和 缩进代码

命令行参数

usage: yasi [-h] [-nc] [-nb] [-nm] [--diff] [-nw] [-nr] [--no-output] [-c]
            [-ne] [-o OUTPUT_FILE] [--tab TAB_SIZE] [--dialect DIALECT] [-v]
            [-suffix BACKUP_SUFFIX] [-bd BACKUP_DIR] [-is INDENT_SIZE]
            [-di DEFAULT_INDENT] [-ic] [-uni]
            [files [files ...]]

Dialect-aware s-expression indenter

positional arguments:
  files                 List of files to be indented. Will indent from
                        standard input if no files are specified

optional arguments:
  -h, --help            show this help message and exit
  -nc, --no-compact, --nc
                        Do not compact the code, just indent
  -nb, --no-backup, --nb
                        Do not create a backup file even if --backup-dir is
                        specified
  -nm, --no-modify, --nm
                        Do not modify the file
  --diff, -diff         Prints unified diff of the initial and final result
  -nw, --no-warning, --nw
                        Do not display warnings
  -nr, --no-rc, --nr    Ignore any rc files in the current or home folder
  --no-output, -no-output
                        Suppress output of the indented code
  -c, --color, -color   Display diff text in color
  -ne, --no-exit, --ne  Instructs the program not to exit when a warning is
                        raised.
  -o OUTPUT_FILE        Path/name of output file
  --tab TAB_SIZE, -tab TAB_SIZE
                        Indent with tabs using the specified tabwidth. A tab
                        is assumed equal to 4 spaces by default when expanding
                        the tabs in the input file
  --dialect DIALECT, -dialect DIALECT
                        Use Scheme keywords
  -v, --version         Prints script version
  -suffix BACKUP_SUFFIX, --suffix BACKUP_SUFFIX
                        Backup file suffix
  -bd BACKUP_DIR, --backup-dir BACKUP_DIR, --bd BACKUP_DIR, -backup-dir BACKUP_DIR
                        The directory where the backup file is to be written
  -is INDENT_SIZE, --indent-size INDENT_SIZE, --is INDENT_SIZE
                        The number of spaces per indent
  -di DEFAULT_INDENT, --default-indent DEFAULT_INDENT, --di DEFAULT_INDENT
                        The indent level to be used in case a function's
                        argument is in the next line. Vim uses 2, the most
                        common being 1.
  -ic, --indent-comments, --ic
                        If true, comment lines will be indented possibly
                        messing with any deliberate comment layout
  -uni, --uniform, -uniform, --uni
                        Dictates whether the if-clause and else-clause of an
                        if-likeblock should have the same indent level.

悬挂缩进

这是缩进的代码块与左边距不齐的地方。 Lispindent默认情况下会这样做,尽管它与 在Yasi实施。通过 获得效果–不紧凑 到剧本里去。下面是Lispindent和Yasi的悬挂凹痕 不同:

初始代码:

;; Comment(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(exit)

使用 调用文件上的yasi–不压缩

;; Comment(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(exit)

Lispindent是如何做到的(第一个块开头的空格数 定义文件中其余块的开始位置:

;; Comment(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(if(not(empty?macro-name))(push(listmacro-nameKEYWORD1)keyword-lst)nil)(exit)

定制

定制的方式与Lispindent中的类似- 关键字与决定下一行的数字相关联 缩进水平。

附加关键字定义在 主文件夹中的当前工作目录。如果有 两个目录中的配置文件当前工作目录中的配置文件 首选目录。

典型的配置文件如下:

{"scheme":{"do":2,"if":2},"lisp":{"do":2,"if":2},"clojure":{"do":2,"if":2},"newlisp":{"do":2,"if":2}}

数字如下所述(假设标准压痕尺寸为2 空间):

  • 0 -将关键字与零关联会将其转换为普通关键字 函数即删除关键字
(do-the-boogie(=1244)(print"if clause")(print"else clause"))
  • 1 -使函数的子窗体均匀缩进 按单位缩进大小(可以更改)
pip install --upgrade yasi
0
  • 2 -通过赋予第一个子窗体更大的 缩进比其他子窗体的缩进方式与标准相同 如果表达式缩进。第一个子窗体的 压痕尺寸与其余尺寸相同。
pip install --upgrade yasi
1
  • 3 -子窗体将均匀缩进两倍缩进 大小<LI>
pip install --upgrade yasi
2
  • 4 -按单位缩进,如1-关键字,但也按其局部缩进 功能
pip install --upgrade yasi
3

标准缩进(假设 letfn 只是另一个函数) 将是:

pip install --upgrade yasi
4

关于默认缩进

–默认缩进 出现在其子窗体通常为 从后面几行开始。就像在a cond 表达式中一样:

pip install --upgrade yasi
5

上述结果将是标准/预期缩进。然而 人们可能更希望子窗体开始于超过头部的两个空格 这样的表达式。

pip install --upgrade yasi
6

这是vim的默认缩进样式。这个选项使您能够 指定所需的数量,例如,要实现上述样式,可以 像这样传递参数:

pip install --upgrade yasi
7


Yasi不处理的内容

在某些方言中,有些语法似乎并不适用。 值得努力实施。例如 mzscheme gauche 对正则表达式使用 .// .[]

对Lispindent的修改

我对 lispindent.lisp 做了一些修改,并将其重命名为 lispindent2.lisp 。更改包括:

  • 为程序的某些部分添加了注释 理解
  • 它现在可以从命令行缩进文件而无需 将文件内容重定向到程序。T他最初的那个是纯粹的 仅用作从标准缩进的筛选脚本 输入.
  • lispindent2.lisp 更好地缩进clojure的向量和集合。 即压痕水平为1,但不影响Lisp的 scheme的缩进 。它使用文件的扩展名来确定 它正在查看clojure代码。例如
pip install --upgrade yasi
8
pip install --upgrade yasi
9
  • lispindent2.lisp 忽略多行注释中的任何代码,并且不会 受到评论中任何未关闭的括号的影响,如 原版。不幸的是,它的多行检测方法 注释相当幼稚,并在代码中引入了一个bug。参照 其问题如下。
  • lispindent2.lisp 默认使用行尾来写入文件。 它比通常在 烦人的方式在 vim

编辑器集成

Yasi从标准输入格式化代码的能力使它成为一个合适的 VIM中的 equalprg 设置的候选者。将此添加到 .vimrc 你很好去。

;; In Common Lisp(do((j0(+j1)))(nil);Do forever.(formatt"~%Input ~D:"j)(let((item(read)))(if(nullitem)(return);Process items until NIL seen.(formatt"~&Output ~D: ~S"jitem))))
0

然后,您可以通过在 = 符号,例如 =%

您还可以签出这些其他项目以进行适当的集成 不将其作为筛选脚本外部调用,例如:

  • vim插件:https://github.com/nkmathew/vim-newlisp-yasi" rel="nofollow">https://github.com/nkmathew/vim newlisp yasi
  • Sublime Text 2/3插件:https://github.com/nkmathew/sublime-yasi" rel="nofollow">https://github.com/nkmathew/sublime yasi

Lispindent2问题

我无意中添加了一个bug,试图阻止它评估 公共lisp中多行注释内的括号和符号 scheme中的空格。

它使用管道字符()跟踪注释是否仍然 在多行注释中,表示多行中奇数个管道 注释将产生错误的缩进,例如:

;; In Common Lisp(do((j0(+j1)))(nil);Do forever.(formatt"~%Input ~D:"j)(let((item(read)))(if(nullitem)(return);Process items until NIL seen.(formatt"~&Output ~D: ~S"jitem))))
1

我不认为这是个大问题,因为多行注释是 很少使用,常见的用例是注释掉代码区域 调试时。

lispindent2.lisp 使用 lisp reader函数从字符串中读取 从读取字符串中获取lisp形式和原子。

其缺点是当 字符串中的代码"格式不正确"。例如,如果它发现 用于在 common lisp 中考虑的运算符在打开后出现 括号,它将引发致命错误。这意味着任何 clojure 代码 尝试使用点运算符访问类方法的 由于错误而缩进。例如,此代码:

;; In Common Lisp(do((j0(+j1)))(nil);Do forever.(formatt"~%Input ~D:"j)(let((item(read)))(if(nullitem)(return);Process items until NIL seen.(formatt"~&Output ~D: ~S"jitem))))
2

lispindent2.lisp 使用忽略错误宏作为解决方法。 这样做意味着它不能在gnu common lisp中运行,因为它 没有宏。

lispindent2命令行选项

;; In Common Lisp(do((j0(+j1)))(nil);Do forever.(formatt"~%Input ~D:"j)(let((item(read)))(if(nullitem)(return);Process items until NIL seen.(formatt"~&Output ~D: ~S"jitem))))
3

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java InputStream对象在声明后关闭   java未定义名为“transactionManager”的bean重命名transactionManager   java“jar”命令何时会拒绝将类添加到java中。jar文件?   java JPA标准依赖WHERE子句   安卓中从SD卡读取文本文件时出现java错误   java直接启用类似位置的权限   使用@WebMvcTest和Mockito-BDDMockito对SpringBoot-RestController进行java测试   java JSESSIONID存储在哪里?   java jtextarea鼠标事件覆盖容器鼠标事件   java DRL无法解析动态加载的类   java是从一个方法返回多个对象的最简单方法   java自定义按钮/编辑框是否不可见?   java GUI如何在保存用户输入的同时在面板或框架之间切换   swing Java自定义JSlider不会更新   GridBagLayout中的java超过1个JPanel   java从ProjectReactor中的flux中采样除第一个元素外的所有元素   Java泛型和泛型类型   Java代码生成宽指令的jvm