对一个vim 函数的详细注释。
2013-12-09 15:24
543 查看
对我而言, 这是一个复杂的函数, 虽然详细注释, 但还是有些难懂, 注释也是参考原作者的。
我只是简单的整理了一下。将注释添加到了函数中,方便阅读理解。
函数功能, 能够自动对齐赋值运算符的位置。 查找,替换是核心目的。(调试通过)
function! AlignAssignments ()
"Patterns needed to locate assignment operators...
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ASSIGN_OP 中的模式匹配任何标准的赋值运算符:=、+=、-=、*=,等等,
"但是注意不要匹配其他包含 = 的运算符,比如 == 和 =~。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let ASSIGN_OP = '[-+*/%|&]\?=\@<!=[=~]\@!'
echo "ASSIGN_OP = " ASSIGN_OP
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ASSIGN_LINE 中的模式只在行的起始部分(^)开始匹配,首先匹配最小字符数(.\{-}),
"然后匹配任何空白(\s*),最后匹配赋值运算符。
"注意,最初的 “最小字符数” 子模式和运算符子模式都在捕捉圆括号内进行了指定:\(...\)。
"这两个正则表达式组件捕获的子字符串稍后将通过调用内置 submatch() 函数来提取;
"具体来讲,通过调用 submatch(1) 来提取运算符前面的所有内容,
"然后调用 submatch(2) 来提取运算符本身。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let ASSIGN_LINE = '^\(.\{-}\)\s*\(' . ASSIGN_OP . '\)'
echo "ASSIGN_LINE =" ASSIGN_LINE
"Locate block of code to be considered (same indentation, no blanks)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"直接计算行范围。实现方法,
"它首先调用内置 matchstr() 函数来确定出现在当前行(getline('.'))起始部分的前导空白('^\s*')。
"随后在 indent_pat 中构建一个新的正则表达式,精确匹配任何非空行的起始处的相同序列的空白(即拖尾 '\S')。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let indent_pat = '^' . matchstr(getline('.'), '^\s*') . '\S'
echo "indent_pat = " indent_pat
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"内置 search() 函数向上搜索(使用标记 'bnW')并定位位于游标上方的第一个不具有相同缩进的行。
"向此行号加 1 将得出感兴趣的范围的起始行号,也就是说,具有相同缩进的第一个相邻行就作为第一行
"内置 search() 函数向下搜索('nW')来判断 lastline:具有相同缩进的最后一个相邻行。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let firstline = search('^\%('. indent_pat . '\)\@!','bnW') + 1
let lastline = search('^\%('. indent_pat . '\)\@!', 'nW') - 1
echo "firstline =" firstline
echo "lastline = " lastline
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"搜索可能会到达文件的末尾,并且没有找到具有不同缩进的行,这种情况下 search() 将返回 -1。
"要正确地处理这种情况, if 语句需要显式地将 lastline 设置为文件末端的行号
"即设置为由 line('$') 返回的行号
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if lastline < 0
let lastline = line('$')
endif
"Find the column at which the operators should be aligned...
let max_align_col = 0
let max_op_width = 0
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"for 循环功能: 获取赋值运算符应当对齐的列。
"实现方法:
"遍历所选范围内的行列表(由 getline(firstline, lastline) 取回的行)
"并检查每个行是否包含赋值运算符(运算符的前面可能包含空格):
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
for linetext in getline(firstline, lastline)
"Does this line have an assignment in it?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"如果该行中没有运算符,那么内置 match() 函数将无法找到匹配,因此将返回 -1。
"对于这种情况,循环将直接跳到下一行。
"如果存在 运算符,那么 match() 将返回在其中显示运算符的(正)指数。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let left_width = match(linetext, '\s*' . ASSIGN_OP)
"If so, track the maximal assignment column and operator width...
if left_width >= 0
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用内置 max() 函数判断这个最近的列位置是否比此前找到的运算符更靠右,
"从而跟踪所需的最大列位置来对齐范围内的所有赋值运算符:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let max_align_col = max([max_align_col, left_width])
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用内置 matchstr() 函数检索实际的运算符,
"然后使用内置 strlen() 函数判断行的长度("=" 的长度为 1,'+='、'-=' 的长度为 2,等等)。
"max_op_width 变量随后被用来跟踪所需的最大宽度,以对范围内的各种运算符执行对齐:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let op_width = strlen(matchstr(linetext, ASSIGN_OP))
let max_op_width = max([max_op_width, op_width+1])
endif
endfor
"Code needed to reformat lines so as to align operators...
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"vim 的printf 函数, 类似于c/perl 的sprintf 函数, 返回一个字符串
"这个内嵌的 printf() 将把运算符左侧的所有内容(submatch(1))靠左对齐(使用 %-*s 占位符)
"并将结果放到字符宽度为 max_align_col 的字段中。
"随后将运算符本身(submatch(2))右对齐(使用%*s)到第二个字段,其字符宽度为 max_op_width。
"参考 :help printf(),了解 - 和 * 选项如何修改
"这里使用的两个 %s 格式说明符(specifier)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let FORMATTER = '\=printf("%-*s%*s", max_align_col, submatch(1), max_op_width, submatch(2))'
" Reformat lines with operators aligned in the appropriate column...
for linenum in range(firstline, lastline)
let oldline = getline(linenum)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"substitute() 中 "\=expr"。
"前导 \= 要求对随后的表达式求值并使用结果作为替换文本。
"注意,这类似于 Insert 模式下的 <C-R>= 机制,
"这种奇妙的行为只针对内置 substitute() 函数的替换字符串(或在标准 :s/.../.../ Vim 命令中)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let newline = substitute(oldline, ASSIGN_LINE, FORMATTER, "")
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"与当前编辑的文本缓冲区进行交互(通过 getline() 和 setline())
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
call setline(linenum, newline)
endfor
endfunction
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"创建一个键映射来调用 AlignAssignments()
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
nmap <silent> ;= :call AlignAssignments()<CR>
我只是简单的整理了一下。将注释添加到了函数中,方便阅读理解。
函数功能, 能够自动对齐赋值运算符的位置。 查找,替换是核心目的。(调试通过)
function! AlignAssignments ()
"Patterns needed to locate assignment operators...
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ASSIGN_OP 中的模式匹配任何标准的赋值运算符:=、+=、-=、*=,等等,
"但是注意不要匹配其他包含 = 的运算符,比如 == 和 =~。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let ASSIGN_OP = '[-+*/%|&]\?=\@<!=[=~]\@!'
echo "ASSIGN_OP = " ASSIGN_OP
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ASSIGN_LINE 中的模式只在行的起始部分(^)开始匹配,首先匹配最小字符数(.\{-}),
"然后匹配任何空白(\s*),最后匹配赋值运算符。
"注意,最初的 “最小字符数” 子模式和运算符子模式都在捕捉圆括号内进行了指定:\(...\)。
"这两个正则表达式组件捕获的子字符串稍后将通过调用内置 submatch() 函数来提取;
"具体来讲,通过调用 submatch(1) 来提取运算符前面的所有内容,
"然后调用 submatch(2) 来提取运算符本身。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let ASSIGN_LINE = '^\(.\{-}\)\s*\(' . ASSIGN_OP . '\)'
echo "ASSIGN_LINE =" ASSIGN_LINE
"Locate block of code to be considered (same indentation, no blanks)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"直接计算行范围。实现方法,
"它首先调用内置 matchstr() 函数来确定出现在当前行(getline('.'))起始部分的前导空白('^\s*')。
"随后在 indent_pat 中构建一个新的正则表达式,精确匹配任何非空行的起始处的相同序列的空白(即拖尾 '\S')。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let indent_pat = '^' . matchstr(getline('.'), '^\s*') . '\S'
echo "indent_pat = " indent_pat
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"内置 search() 函数向上搜索(使用标记 'bnW')并定位位于游标上方的第一个不具有相同缩进的行。
"向此行号加 1 将得出感兴趣的范围的起始行号,也就是说,具有相同缩进的第一个相邻行就作为第一行
"内置 search() 函数向下搜索('nW')来判断 lastline:具有相同缩进的最后一个相邻行。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let firstline = search('^\%('. indent_pat . '\)\@!','bnW') + 1
let lastline = search('^\%('. indent_pat . '\)\@!', 'nW') - 1
echo "firstline =" firstline
echo "lastline = " lastline
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"搜索可能会到达文件的末尾,并且没有找到具有不同缩进的行,这种情况下 search() 将返回 -1。
"要正确地处理这种情况, if 语句需要显式地将 lastline 设置为文件末端的行号
"即设置为由 line('$') 返回的行号
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if lastline < 0
let lastline = line('$')
endif
"Find the column at which the operators should be aligned...
let max_align_col = 0
let max_op_width = 0
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"for 循环功能: 获取赋值运算符应当对齐的列。
"实现方法:
"遍历所选范围内的行列表(由 getline(firstline, lastline) 取回的行)
"并检查每个行是否包含赋值运算符(运算符的前面可能包含空格):
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
for linetext in getline(firstline, lastline)
"Does this line have an assignment in it?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"如果该行中没有运算符,那么内置 match() 函数将无法找到匹配,因此将返回 -1。
"对于这种情况,循环将直接跳到下一行。
"如果存在 运算符,那么 match() 将返回在其中显示运算符的(正)指数。
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let left_width = match(linetext, '\s*' . ASSIGN_OP)
"If so, track the maximal assignment column and operator width...
if left_width >= 0
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用内置 max() 函数判断这个最近的列位置是否比此前找到的运算符更靠右,
"从而跟踪所需的最大列位置来对齐范围内的所有赋值运算符:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let max_align_col = max([max_align_col, left_width])
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"使用内置 matchstr() 函数检索实际的运算符,
"然后使用内置 strlen() 函数判断行的长度("=" 的长度为 1,'+='、'-=' 的长度为 2,等等)。
"max_op_width 变量随后被用来跟踪所需的最大宽度,以对范围内的各种运算符执行对齐:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let op_width = strlen(matchstr(linetext, ASSIGN_OP))
let max_op_width = max([max_op_width, op_width+1])
endif
endfor
"Code needed to reformat lines so as to align operators...
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"vim 的printf 函数, 类似于c/perl 的sprintf 函数, 返回一个字符串
"这个内嵌的 printf() 将把运算符左侧的所有内容(submatch(1))靠左对齐(使用 %-*s 占位符)
"并将结果放到字符宽度为 max_align_col 的字段中。
"随后将运算符本身(submatch(2))右对齐(使用%*s)到第二个字段,其字符宽度为 max_op_width。
"参考 :help printf(),了解 - 和 * 选项如何修改
"这里使用的两个 %s 格式说明符(specifier)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let FORMATTER = '\=printf("%-*s%*s", max_align_col, submatch(1), max_op_width, submatch(2))'
" Reformat lines with operators aligned in the appropriate column...
for linenum in range(firstline, lastline)
let oldline = getline(linenum)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"substitute() 中 "\=expr"。
"前导 \= 要求对随后的表达式求值并使用结果作为替换文本。
"注意,这类似于 Insert 模式下的 <C-R>= 机制,
"这种奇妙的行为只针对内置 substitute() 函数的替换字符串(或在标准 :s/.../.../ Vim 命令中)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let newline = substitute(oldline, ASSIGN_LINE, FORMATTER, "")
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"与当前编辑的文本缓冲区进行交互(通过 getline() 和 setline())
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
call setline(linenum, newline)
endfor
endfunction
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"创建一个键映射来调用 AlignAssignments()
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
nmap <silent> ;= :call AlignAssignments()<CR>
相关文章推荐
- (转)发布一个Java写的俄罗斯方块源码 算法简单(300行) 注释详细
- 发现一个比较详细的vim介绍
- IntelliJ IDEA 里 查看一个函数注释的方法是 ctrl+q
- 利用JML开发的一个小例子,附详细注释
- 一个包含详细注释的扫描器C源代码(转)
- linux中一个简单的TCP套接字程序(1)(内含详细注释)
- 一个包含详细注释的扫描器C源代码
- 一个包含详细注释的扫描器C源代码
- 我的vim配置文件(带详细中文注释)
- 马的移动(BFS) 详细注释 一个具有情怀的题目
- cvgoodFeaturesToTrack函数详细注释
- 使用TCP协议实现一个可以上传文件的客户端源代码(附详细注释)
- 一个包含详细注释的扫描器C源代码
- Golang 如何将一个函数作为另一个函数的输入值,清晰透彻的注释让你理解该如何阅读抽象的代码
- 一个包含详细注释的扫描器C源代码
- 今天突然想到的一个关于代码注释和函数的想法
- 一个包含详细注释的扫描器C源代码(转) [z]
- 量子编程详解之一: QP-nano代码大餐之状态机函数详细注释
- (2)int A[nSize],其中隐藏着若干0,其余非0整数,写一个函数int Func(int* A, int nSize),使A把0移至后面,非0整数移至数组前面并保持有序,返回值为原数据中第一个元素为0的下标。(尽可能不使用辅助空间且考虑效率及异常问题,注释规范且给出设计思路)
- icvGetRTMatrix函数详细注释