function! MyAutoScroll()
let s:SusLines=winheight(winnr()) * 0.3
if winheight(winnr())-winline()>=s:SusLines
return
else
let thisline=winline()
let inbetween=winheight(winnr())-thisline
while inbetween <= s:SusLines
exec "normal! \<c-e>"
let inbetween=inbetween+1
endwhile
endif
endfunction
autocmd! CursorMoved,CursorMovedI * call MyAutoScroll()
这是通常的滚屏代码, 仅有一点改进。
let s:SusLines=winheight(winnr()) * 0.3,让光标所在行与窗口底部保持30%(当前窗口行数的30%)。
但是这个代码有个很头疼的问题,就是由于vim的原因(回退到命令模式时,光标会前进一个字符),那么在我们滚屏时,如果有tab或空格,就会导致有些行末多出一个空白字符(空格或TAB, 一般是TAB)。
那么解决这个问题方法是使用vim中的字符串替换:
nnoremap <silent> <F2> :%s/\s\+$//<CR>
按F2就可以删除当前文件中所有的行末空白字符。
但是对我来说,按F2也挺麻烦的。
就把它放到我的保存键中了,原本S键只映射为:w
function RemoveSpace()
try
exec "%s/\\s\\+$//"
catch
echo "No space!"
endtry
endfunction
map <silent> S :call RemoveSpace()<CR>:w<CR>
注意不要简单地
map <silent> S :%s/\s\+$//<CR>:w<CR>
因为字符串替换时,如果文件所有行末都没有空白字符的话,会抛出异常。导致后面的保存(:w)无法执行。
所以必须捕获异常。
本来是想把删除行末空白符的命令放到滚屏函数中的,既然每次滚屏时,可能多出空白符,那么就删掉就好了。
但是这个思路出现一些问题,如果是全局替换的话,替换后光标会跳转到行末有空白符的那行,而不在当前行了,而且会把新一行正常缩进的TAB也删掉。局部替换的话,不太好把握范围。
但是每次保存时去除所有行尾空白符,也是比较合适的。所以先这样吧。
大家看效果的话,可以用下面的,来显示行尾空白符。
highlight WhitespaceEOL ctermfg=red ctermbg=red
match WhitespaceEOL /\s\+$/