Skip to content

Instantly share code, notes, and snippets.

@tiye
Created January 15, 2012 13:38
Show Gist options
  • Save tiye/1615885 to your computer and use it in GitHub Desktop.
Save tiye/1615885 to your computer and use it in GitHub Desktop.
极简规则自动补全 Lisp 式括号
'''
想做对于 Lisp-like 的括号自动补全, 用 py 脚本处理
先做了测试看(虽然我没学会 clj 没的测), 默认读取 file 输出 new_file
现在的定义的规则如下(其中空行被排除)
每行代码开头添加 '('
每行代码结尾, 判断缩进个数比下一行多 n 个
当 (n >= 0), 在当前行末尾添加 (n+1) 个 ')'
每行代码结尾, 如果 '(' 数 a, ')' 数 b, 下一行多 c 个缩进
若 (a-b-c) 为正, 在该行末尾添加对应个 ')'
可以有多层的缩进, 对应手动添加一次括号 '('
Jan 16 重新构造代码, 增加单行括号数统计和补全
添加单行注释, 识别用下面这条正则, 不能处理行尾注释
r'^\s$|^\s*;'
用下面的正则大致尝试匹配单行中的单个值, 否则多余的括号会报错
r'\t+(\S)+\n'
$ cat file
curry0
curry1 (curry2
curry3
curry4
curry5
curry00
curry01
curry02
curry03
$ cat fi
(curry0
(curry1 (curry2
curry3)
curry4)
curry5)
(curry00
curry01
curry02
curry03)
$ cat fibo.0
defun fibonacci (N
; google
d
if (or (zerop N) (= N 1
1
+ (fibonacci (- N 1)) (fibonacci (- N 2
$ cat fibo
(defun fibonacci (N)
; google
d
(if (or (zerop N) (= N 1))
1)
(+ (fibonacci (- N 1)) (fibonacci (- N 2)))
'''
#!/usr/bin/python3
import sys
import re
def count_indents (line):
line = str (line)
count = 0
for char in line:
if char == '\t':
count += 1
line = line[1:]
else:
break
return count
def add_head (line, current_count, next_count):
if re.match (r'\t+(\S)+\n|^\t+\[.*\]$', line):
if current_count >= next_count:
return line
else:
line = line[:current_count] + '(' + line[current_count:]
return line
else:
line = line[:current_count] + '(' + line[current_count:]
return line
def add_back (line, current_count, next_count):
tabs = current_count - next_count
if tabs > 0:
line = line[:-1] + ')'*tabs + '\n'
return line
def complete_back (line, current_count, next_count):
tabs = next_count - current_count
pre_bracket = 0
after_bracket = 0
for char in line:
if char == '(':
pre_bracket += 1
if char == ')':
after_bracket += 1
num = pre_bracket - after_bracket - tabs
if num > 0:
line = line[:-1] + ')'*(num) + '\n'
return line
return line
file_name = sys.argv[1]
new_name = file_name[:-2]
texts = []
indents = []
comments = []
comment_index = []
index = 0
input_text = open (file_name, 'r')
for i in input_text:
line = str (i)
if re.match(r'^\s$|^\s*;', line):
comments.append (line)
comment_index.append (index)
else:
texts.append (line)
index += 1
indents.append (count_indents (line))
length = len (texts)
texts.append ('')
indents.append (0)
input_text.close ()
output_texts = ''
for i in range (length):
for j in range (len (comment_index)):
if comment_index[j] == i:
output_texts += comments[j]
texts[i] = add_head (texts[i], indents[i], indents[i+1])
texts[i] = add_back (texts[i], indents[i], indents[i+1])
texts[i] = complete_back (texts[i], indents[i], indents[i+1])
output_texts += texts[i]
output_text = open (new_name, 'w')
output_text.write (output_texts)
output_text.close ()
print ('Done:', new_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment