0
点赞
收藏
分享

微信扫一扫

Vim插件ale在windows下的安装配置与BUG解决

八怪不姓丑 2022-01-14 阅读 178

​​​​​​

文章目录

ALE介绍

ale是一个异步的检测插件,项目的介绍如下:

Github地址:Check syntax in Vim asynchronously and fix files, with Language Server Protocol (LSP) support

ALE安装

ale支持多种安装方式,详情参考项目github地址,这里以Vundle方式安装:

  1. 安装好Vundle插件
  2. .vimrc文件的Vundle插件列表里添加如下:
Plugin 'dense-analysis/ale'
  1. 打开vim然后运行命令:PluginInstall或者:BundleInstall等待完成即可。
  2. 相应语言的linter,可以查看github上的支持列表,装好相应的linter,加入环境变量即可。

Note:

  1. 由于Vundle插件后台还是在调用git进行代码克隆,如果失败请设置代理或者手动克隆项目到Vundle安装文件夹下,默认为~/.vim/bundle/
  2. linux下的家目录为~,windows下的家目录为%HOME_PATH%,如果在windows下可以使用\\(whindows风格,必须是双反斜杠,取消转义)或者/(linux风格)作为目录分割符。

ALE配置

详情参考项目github地址,在Vim中输入命令:h ale可以查看各种相关内容,大部分配置使用默认的就可以了,这里给出一些简单显示配置(以下所有设置都在.vimrc文件中写入,新修改的设置默认需要重启Vim才生效)。

自定义侧边提示符号

原始的ale侧边提示是这样:

--表示警告,>>表示错误,这样不是那么醒目,可以进行自定义设置:

" 自定义error和warning图标
let g:ale_sign_error = '✗'
let g:ale_sign_warning = '⚡'

重启打开Vim之后显示效果就变成这样了:

Note: 可以选择任何你喜欢的符号,出现乱码请检查Vim相关的编码设置以及字体是否支持该种符号。

自定义底部提示消息

默认的底部栏只显示出错消息:

可以设置添加更多的消息:

" 显示Linter名称,出错或警告等相关信息
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' 

增加了linter和相关消息类型提示,显示效果如下:

高亮显示设置

默认情况检查出现警告或者错误会在代码下高亮提示,如上面所示的~,如果不喜欢可以选择关闭。这个高亮显示是与linter和设置有关,有些linter设置并不支持高亮。

" 关闭高亮提示
let g:ale_set_highlights = 0

状态栏提示集成

ale提示可以集成在vim自带的状态栏或者第三方状态栏上比如airline上:
在vim自己的状态栏上显示设置如下:

"设置状态栏显示的内容,这里必须添加%{ALEGetStatusLine()到状态栏里
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")}\ %{ALEGetStatusLine()}
"设置ale显示内容
let g:ale_statusline_format = ['✗ %d', '⚡ %d', '✔ OK']

如果安装了airline,默认在airline中是显示ale内容的,可以手动关闭:

let g:airline#extensions#tabline#enabled = 0

如果希望airline状态栏的图标改变,可以进入airline的文件夹目录(默认为:~/.vim/bundle/vim-airline/autoload/airline/extensions/),找到ale.vim文件修改这几行:

" 错误图标默认为E
let error_symbol = get(g:, 'airline#extensions#ale#error_symbol', 'E:')
" 警告图标默认为W
let warning_symbol = get(g:, 'airline#extensions#ale#warning_symbol', 'W:')
" 等待图标默认为...
let checking_symbol = get(g:, 'airline#extensions#ale#checking_symbol', '...')

linter相关设置

默认实时检测代码,如果希望只在保存文件时才运行,可以进行如下设置:

" 文件内容发生变化时不进行检查
let g:ale_lint_on_text_changed = 'never'
" 打开文件时不进行检查
let g:ale_lint_on_enter = 0

插件默认会使能所有支持的linter,如果希望对某个语言单独设置相应的linter,可以做如下设置:

" 对verilog、c++、c、python单独设置linter
let g:ale_linters = { 'verilog': ['vlog'],
\   'c++': ['gcc'],
\   'c': ['gcc'],
\   'python': ['pylint'],
\}

快捷键设置

设置一些常用的快捷键:

" sp前往上一个错误或警告,sn前往下一个错误或警告
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
" 开/关语法检查
nmap <Leader>s :ALEToggle<CR>
" 查看错误或警告的详细信息
nmap <Leader>d :ALEDetail<CR>

ALE的bug处理

Bug描述

在windows上使用某些linter检测相应代码(特别是HDL代码)会出现问题,主要表现为:

  1. 插件的确调用了相应的linter,产生了相应的输出文件。
    在这里插入图片描述
  2. 使用命令:ALEInfo查看运行日志,日志也提示了相应警告和错误。
  3. Vim界面上却没有显示任何报错信息。

Note: 这个问题在github上也有人提了issue,但是开发者目前并没有解决。

Bug分析

ale的基本工作原理是通过调用相应文件的linter输出错误信息,然后使用正则表达式进行捕获,再将捕获的信息显示到界面上。而导致这个bug的罪魁祸首是linux和windows文件路径的区别,linux的文件路径不会出现:这个符号,但是windows的路径会出现卷分隔符:。ale插件的部分linter正则表达式中并没有考虑这一情况,所以大多数linter输出信息里含有文件名的基本都会触发这个bug,我测试的lintervlogiverilogghdl等都有这个bug,但xvlog没有问题。

Bug解决

既然知道了Bug怎么来的了,解决方法也很简单,那就是进入ale相应的linter文件夹(默认为:~/.vim/bundle/ale/ale_linters/),修改相应linter原有的正则表达式。

vlog下的修改方法

打开目录下的vlog.vim,它的匹配函数写了两种,对应不同版本的vlog输出信息,区别就是文件名和错误码的位置不同而已,我的vlog输出是第一种:
我们可以很清楚的看到这个文件名的捕获是[a-zA-Z0-9\-\.\_\/ ]\+,这个意思是捕获的文件名包含至少一个大小写字母(a-zA-Z)、数字(0-9)、横线(-)、下划线(_)、点(.)、斜杠(/)、空格()。在windows下文件名除了?"、``/`、<>*|:,其他字符基本都是可以的,而路径中包含有:\这两种,那么最后就<>*?|/"这七种不能包含,其他字符基本都可以,我们可以采用[^<>|?"/*]取这七种之外的字符,也可以用个更简单的方法,直接使用.去匹配,匹配除换行以外其他所有的字符。
[a-zA-Z0-9\-\.\_\/ ]\+采用两种方式替换,如下:

" 使用.匹配
let l:pattern = '^\*\*\s\(\w*\): \(.\+\)(\(\d\+\)):\s\+\(.*\)'
" 使用[^<>|?*"/]匹配
let l:pattern = '^\*\*\s\(\w*\): \([^<>"|?/*]\+\)(\(\d\+\)):\s\+\(.*\)'

功能正常,测试结果如下:

Note: 这个匹配输出的前两个*,理论上应该使用\*,但是源码里写的是**原意应该是前面的字符出现0至多次,这里源码这样写也能通过,但是按道理应该有点问题的,所以我修改了,不知道有没有大佬知道,给我解答一下。

iverilog下的修改方法

在这里插入图片描述
这里的文件名匹配直接使用[^:],意思是除了:以外所有字符,显然直接把windows给忽略了,替换方法和上面一样:

" 使用[^<>|?/"*]匹配
let l:pattern = '^[^<>"|?/*]\+:\(\d\+\): \(warning\|error\|syntax error\)\(: \(.\+\)\)\?'
" 使用.匹配
let l:pattern = '^.\+:\(\d\+\): \(warning\|error\|syntax error\)\(: \(.\+\)\)\?'

功能正常,测试结果如下:

xvlog正常原因

那么问题来了,HDL的linter很多都触发了bug,xvlog为什么没有问题?

查看xvlog.vim发现它的匹配为.*,直接匹配任意任何数量的除换行符之外的其他所有字符,和.\+如出一辙。

参考资料

  1. Vim插件之ale
  2. ALE官方Wiki
  3. Linter running but errors not showing #3340

举报

相关推荐

0 条评论