1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 07:20:04 +08:00

chore(chinese): use bundle ChineseLinter

update to d819606eebc82dad34b2a9b7b1a861844380df84
This commit is contained in:
Eric Wong 2024-03-05 12:56:14 +08:00
parent 0559ad462d
commit 13f564b23a
20 changed files with 466 additions and 1 deletions

View File

@ -32,8 +32,8 @@ function! SpaceVim#layers#chinese#plugins() abort
\ ['yianwillis/vimcdoc' , {'merged' : 0}],
\ ['NamelessUzer/Vim-Natural-Language-Number-Translator' , {'merged' : 0}],
\ ['voldikss/vim-translator' , {'merged' : 0, 'on_cmd' : ['Translate', 'TranslateW', 'TranslateR', 'TranslateX']}],
\ ['wsdjeg/ChineseLinter.vim' , {'merged' : 0, 'on_cmd' : 'CheckChinese', 'on_ft' : ['markdown', 'text']}],
\ ]
call add(plugins, [g:_spacevim_root_dir . 'bundle/ChineseLinter.vim' , {'merged' : 0, 'on_cmd' : 'CheckChinese', 'on_ft' : ['markdown', 'text']}])
if SpaceVim#layers#isLoaded('ctrlp')
call add(plugins, ['vimcn/ctrlp.cnx', {'merged' : 0}])
endif

View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Fail on unset variables and command errors
set -ue -o pipefail
# Prevent commands misbehaving due to locale differences
export LC_ALL=C
pip install covimerage
git clone --depth=1 https://github.com/Shougo/dein.vim.git ~/.cache/vimfiles/repos/github.com/Shougo/dein.vim
if [[ ! -d "${DEPS}/_neovim" ]]; then
mkdir -p "${DEPS}/_neovim"
wget -q -O - https://github.com/neovim/neovim/releases/download/nightly/nvim-${TRAVIS_OS_NAME}64.tar.gz \
| tar xzf - --strip-components=1 -C "${DEPS}/_neovim"
fi
export PATH="${DEPS}/_neovim/bin:${PATH}"
echo "\$PATH: \"${PATH}\""
export VIM="${DEPS}/_neovim/share/nvim/runtime"
echo "\$VIM: \"${VIM}\""
nvim --version

View File

@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -ex
export PATH="${DEPS}/_neovim/bin:${PATH}"
echo "\$PATH: \"${PATH}\""
export VIM="${DEPS}/_neovim/share/nvim/runtime"
nvim --version
make test_coverage
covimerage -vv xml --omit 'build/*'
pip install codecov
codecov -X search gcov pycov -f coverage.xml
set +x

1
bundle/ChineseLinter.vim/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build/

View File

@ -0,0 +1,34 @@
language: python
dist: trusty
sudo: false
services:
- docker
git:
depth: 3
notifications:
slack:
on_success: never
on_failure: never
email:
on_success: never # default: change
on_failure: never # default: always
cache:
bundler: true
directories:
- $HOME/cache/
- $HOME/deps
env:
global:
- DEPS=$HOME/deps
- PATH=$DEPS/bin:$HOME/vim/bin:$PATH
jobs:
include:
- env: LINT=vader
install: .ci/install.sh
script: .ci/script.sh

View File

@ -0,0 +1,26 @@
test: build/vader | build
nvim -Nu test/vimrc -c 'Vader! test/**'
test_show: build/vader | build
nvim -Nu test/vimrc -c 'Vader test/**'
COVIMERAGE=$(shell command -v covimerage 2>/dev/null || echo build/covimerage/bin/covimerage)
test_coverage: $(COVIMERAGE) build/vader | build
$(COVIMERAGE) run nvim -Nu test/vimrc -c 'Vader! test/**'
build/covimerage:
virtualenv $@
build/covimerage/bin/covimerage: | build/covimerage
build/covimerage/bin/pip install covimerage
build/vader:
git clone --depth 1 https://github.com/junegunn/vader.vim.git $@
build:
mkdir -p $@
clean:
$(RM) -r build
.PHONY: clean test

View File

@ -0,0 +1,48 @@
# ChineseLinter.vim
> 中文文档语言规范检查工具
[![Build Status](https://travis-ci.org/wsdjeg/ChineseLinter.vim.svg?branch=master)](https://travis-ci.org/wsdjeg/ChineseLinter.vim)
[![codecov](https://codecov.io/gh/wsdjeg/ChineseLinter.vim/branch/master/graph/badge.svg)](https://codecov.io/gh/wsdjeg/ChineseLinter.vim)
## 使用说明
在编辑中文文档时,使用如下命令即可检查,错误信息将被展示在 `local list` 窗口。
```vim
:CheckChinese
```
## 错误代码
| 代码 | 描述 |
| ------ | ------------------------------- |
| `E001` | 中文字符后存在英文标点 |
| `E002` | 中英文之间没有空格 |
| `E003` | 中文与数字之间没有空格 |
| `E004` | 中文标点两侧存在空格 |
| `E005` | 行尾含有空格 |
| `E006` | 数字和单位之间存在空格 |
| `E007` | 数字使用了全角字符 |
| `E008` | 汉字之间存在空格 |
| `E009` | 中文标点重复 |
| `E010` | 英文标点符号两侧的空格数量不对 |
| `E011` | 中英文之间空格数量多于 1 个 |
| `E012` | 中文和数字之间空格数量多于 1 个 |
| `E013` | 英文和数字之间没有空格 |
| `E014` | 英文和数字之间空格数量多于 1 个 |
| `E015` | 英文标点重复 |
| `E016` | 连续的空行数量大于 2 行 |
| `E017` | 数字之间存在空格 |
## 配置
如果需要忽略某些错误,可以将错误代码加入选项:`g:chinese_linter_disabled_nr`
```vim
let g:chinese_linter_disabled_nr = ['E002', 'E005']
```
## 参考指南:
- [中文文案排版指北(简体中文版)](https://github.com/mzlogin/chinese-copywriting-guidelines)

View File

@ -0,0 +1,5 @@
{
"name": "ChineseLinter",
"description": "The Linter for Chinese",
"author": "wsdjeg"
}

View File

@ -0,0 +1,215 @@
scriptencoding utf-8
""
" 指定需要忽略的错误、警告的编号,默认没有禁止。
" >
" let g:chinese_linter_disabled_nr = ['E001']
" <
"
" 目前支持的检查包括:
" >
" E001 | 中文字符后存在英文标点
" E002 | 中英文之间没有空格
" E003 | 中文和数字之间没有空格
" E004 | 中文标点两侧存在空格
" E005 | 行尾含有空格
" E006 | 数字和单位之间存在空格
" E007 | 数字使用了全角字符
" E008 | 汉字之间存在空格
" E009 | 中文标点重复
" E010 | 英文标点符号两侧的空格数量不对
" E011 | 中英文之间空格数量多于 1 个
" E012 | 中文和数字之间空格数量多于 1 个
" E013 | 英文和数字之间没有空格
" E014 | 英文和数字之间空格数量多于 1 个
" E015 | 英文标点重复
" E016 | 连续的空行数量大于 2 行
" E017 | 数字之间存在空格
" <
let g:chinese_linter_disabled_nr = get(g:,'chinese_linter_disabled_nr', [])
""
" This setting will open the |location-list| or |quickfix| list (depending on
" whether it is operating on a file) when adding entries. A value of 2 will
" preserve the cursor position when the |location-list| or |quickfix| window is
" opened. Defaults to 2.
let g:chinese_linter_open_list = 2
" 中文标点符号(更全)
" let s:CHINESE_PUNCTUATION = '[\u2014\u2015\u2018\u2019\u201c\u201d\u2026\u3001\u3002\u3008\u3009\u300a\u300b\u300c\u300d\u300e\u300f\u3010\u3011\u3014\u3015\ufe43\ufe44\ufe4f\uff01\uff08\uff09\uff0c\uff1a\uff1b\uff1f\uff5e\uffe5]'
" [\u2010-\u201f] == [‐‑‒–—―‖‗‘’‚‛“”„‟]
" [\u2026] == […]
" [\uff01-\uff0f] == []
" [\uff1a-\uff1f] == []
" [\uff3b-\uff40] == [_]
" [\uff5b-\uff5e] == []
let s:CHINESE_PUNCTUATION = '[\u2010-\u201f\u2026\uff01-\uff0f\uff1a-\uff1f\uff3b-\uff40\uff5b-\uff5e]'
" 英文标点
let s:punctuation_en = '[,:;?!-]'
" 中文标点符号
" let s:punctuation_cn = '[‘’“”、。《》『』!"'(),/:;<=>?[]{}]' 与下面这行代码等价
let s:punctuation_cn = '[\u2018\u2019\u201c\u201d\u3001\u3002\u300a\u300b\u300e\u300f\uff01\uff02\uff07\uff08\uff09\uff0c\uff0f\uff1a\uff1b\uff1c\uff1d\uff1e\uff1f\uff3b\uff3d\uff5b\uff5d]'
" 中文汉字
let s:chars_cn = '[\u4e00-\u9fff]'
" 数字
let s:numbers = '[0-9]'
" 全角数字
let s:numbers_cn = '[\uff10-\uff19]'
" 英文字母
let s:chars_en = '[a-zA-Z]'
" 单位
" TODO: 需要添加更多的单位,单位见以下链接
" https://unicode-table.com/cn/blocks/cjk-compatibility/
" https://unicode-table.com/cn/#2031
" https://unicode-table.com/cn/#2100
let s:symbol = '[%‰‱\u3371-\u33df\u2100-\u2109]'
" 空白符号
let s:blank = '\(\s\|[\u3000]\)'
let s:ERRORS = {
\ 'E001' : [
\ ['中文字符后存在英文标点' , s:chars_cn . s:blank . '*' . s:punctuation_en],
\ ],
\ 'E002' : [
\ ['中文与英文之间没有空格' , s:chars_cn . s:chars_en],
\ ['英文与中文之间没有空格' , s:chars_en . s:chars_cn],
\ ],
\ 'E003' : [
\ ['中文与数字之间没有空格' , s:chars_cn . s:numbers],
\ ['数字与中文之间没有空格' , s:numbers . s:chars_cn],
\ ],
\ 'E004' : [
\ ['中文标点前存在空格' , s:blank . '\+\ze' . s:CHINESE_PUNCTUATION],
\ ['中文标点后存在空格' , s:CHINESE_PUNCTUATION . '\zs' . s:blank . '\+'],
\ ],
\ 'E005' : [
\ ['行尾有空格' , s:blank . '\+$'],
\ ],
\ 'E006' : [
\ ['数字和单位之间有空格' , s:numbers . '\zs' . s:blank . '\+\ze' . s:symbol],
\ ],
\ 'E007' : [
\ ['数字使用了全角数字' , s:numbers_cn . '\+'],
\ ],
\ 'E008' : [
\ ['汉字之间存在空格' , s:chars_cn . '\zs' . s:blank . '\+\ze' . s:chars_cn],
\ ],
\ 'E009' : [
\ ['中文标点符号重复' , '\(' . s:punctuation_cn . '\)\1\+'],
\ ['连续多个中文标点符号' , '[、,:;。!?]\{2,}'],
\ ],
\ 'E010' : [
\ ['英文标点前侧存在空格' , s:blank . '\+\ze' . s:punctuation_en],
\ ['英文标点符号后侧的空格数量多于 1 个' , s:punctuation_en . '\zs' . s:blank . '\{2,}'],
\ ['英文标点与英文之间没有空格' , '[,:;?!]' . s:chars_en],
\ ['英文标点与中文之间没有空格' , '[,:;?!]' . s:chars_cn],
\ ['英文标点与数字之间没有空格' , '[,:;?!]' . s:numbers],
\ ],
\ 'E011' : [
\ ['中文与英文之间空格数量多于 1 个' , '\%#=2' . s:chars_cn . '\zs' . s:blank . '\{2,}\ze' . s:chars_en],
\ ['英文与中文之间空格数量多于 1 个' , '\%#=2' . s:chars_en . '\zs' . s:blank . '\{2,}\ze' . s:chars_cn],
\ ],
\ 'E012' : [
\ ['中文与数字之间空格数量多于 1 个' , '\%#=2' . s:chars_cn . '\zs' . s:blank . '\{2,}\ze' . s:numbers],
\ ['数字与中文之间空格数量多于 1 个' , '\%#=2' . s:numbers . '\zs' . s:blank . '\{2,}\ze' . s:chars_cn],
\ ],
\ 'E013' : [
\ ['英文与数字之间没有空格' , s:chars_en . s:numbers],
\ ['数字与英文之间没有空格' , s:numbers . s:chars_en],
\ ],
\ 'E014' : [
\ ['英文与数字之间空格数量多于 1 个' , s:chars_en . '\zs' . s:blank . '\{2,}\ze' . s:numbers],
\ ['数字与英文之间空格数量多于 1 个' , s:numbers . '\zs' . s:blank . '\{2,}\ze' . s:chars_en],
\ ],
\ 'E015' : [
\ ['英文标点符号重复' , '\(' . s:punctuation_en . s:blank . '*\)\1\+'],
\ ['连续多个英文标点符号' , '\(' . '[,:;?!-]' . s:blank . '*\)\{2,}'],
\ ],
\ 'E016' : [
\ ['连续的空行数量大于 2 行' , '^\(' . s:blank . '*\n\)\{3,}'],
\ ],
\ 'E017' : [
\ ['数字之间存在空格' , s:numbers . '\zs' . s:blank . '\+\ze' . s:numbers],
\ ],
\ }
function! s:getNotIgnoreErrors()
let s:notIgnoreErrorList = []
for l:errors_nr in keys(s:ERRORS)
if index(g:chinese_linter_disabled_nr, l:errors_nr) == -1
call add(s:notIgnoreErrorList, l:errors_nr)
endif
endfor
endfunction
function! ChineseLinter#check(...) abort
call s:getNotIgnoreErrors()
let s:file = getline(1, '$')
let s:bufnr = bufnr('%')
let s:linenr = 0
let s:colnr = 0
let s:qf = []
for l:line in s:file
let s:linenr += 1
call s:parser(l:line)
endfor
if !empty(s:qf)
call s:update_qf(s:qf)
if g:chinese_linter_open_list == 1
rightbelow copen
elseif g:chinese_linter_open_list ==2
rightbelow copen
wincmd p
endif
else
call setqflist([])
cclose
doautocmd WinEnter
endif
unlet s:linenr
unlet s:colnr
endfunction
function! s:parser(line) abort
for l:errors_nr in s:notIgnoreErrorList
call s:find_error(l:errors_nr, a:line)
endfor
endfunction
function! s:find_error(errors_nr, line) abort
let l:errorList = s:ERRORS[a:errors_nr]
for l:error in l:errorList
let s:colnr = matchend(a:line, l:error[1])
if s:colnr != -1
call s:add_to_qf(a:errors_nr, l:error[0])
endif
endfor
endfunction
function! s:add_to_qf(errors_nr, errors_text) abort
let l:error_item = {
\ 'bufnr': s:bufnr,
\ 'lnum' : s:linenr,
\ 'col' : s:colnr,
\ 'vcol' : 0,
\ 'text' : a:errors_nr . ' ' . a:errors_text,
\ 'nr' : a:errors_nr,
\ 'type' : 'E',
\ }
call add(s:qf, l:error_item)
endfunction
" TODO 加入语法分析
function! s:update_qf(listOfDicts) abort
call setqflist(a:listOfDicts)
endfunction

View File

@ -0,0 +1,9 @@
coverage:
range: 30..60
round: down
precision: 2
comment:
layout: "header, diff, changes, uncovered"
behavior: default # update if exists else create new
codecov:
branch: master

View File

@ -0,0 +1,26 @@
*ChineseLinter.txt* The Linter for Chinese
wsdjeg *ChineseLinter*
==============================================================================
CONTENTS *ChineseLinter-contents*
1. Configuration......................................|ChineseLinter-config|
2. Commands.........................................|ChineseLinter-commands|
==============================================================================
CONFIGURATION *ChineseLinter-config*
*g:chinese_linter_open_list*
This setting will open the |location-list| or |quickfix| list (depending on
whether it is operating on a file) when adding entries. A value of 2 will
preserve the cursor position when the |location-list| or |quickfix| window is
opened. Defaults to 2.
==============================================================================
COMMANDS *ChineseLinter-commands*
:CheckChinese *:CheckChinese*
Start checking the document, and the results will be shown in the local
list.
vim:tw=78:ts=8:ft=help:norl:

View File

@ -0,0 +1,4 @@
""
" Start checking the document, and the results will be shown in the local
" list.
command! -nargs=? CheckChinese call ChineseLinter#check(<q-args>)

View File

@ -0,0 +1,12 @@
Given markdown:
你好,中文
Execute (test clear errors):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 7
AssertEqual getqflist()[0].text[:3], 'E001'
wincmd p
call setline(1, '你好,中文')
CheckChinese
AssertEqual len(getqflist()), 0

View File

@ -0,0 +1,7 @@
Given markdown:
你好,中文
Execute (test error E001):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 7
AssertEqual getqflist()[0].text[:3], 'E001'

View File

@ -0,0 +1,8 @@
Given markdown:
你好hello
Execute (test error E002):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 7
AssertEqual getqflist()[0].text[:3], 'E002'

View File

@ -0,0 +1,7 @@
Given markdown:
你好123
Execute (test error E001):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 7
AssertEqual getqflist()[0].text[:3], 'E003'

View File

@ -0,0 +1,7 @@
Given markdown:
你好中文
Execute (test error E005):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 13
AssertEqual getqflist()[0].text[:3], 'E005'

View File

@ -0,0 +1,7 @@
Given markdown:
你好, 中文
Execute (test error E001):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 10
AssertEqual getqflist()[0].text[:3], 'E004'

View File

@ -0,0 +1,7 @@
Given markdown:
100 %
Execute (test error E006):
CheckChinese
AssertEqual getqflist()[0].lnum, 1
AssertEqual getqflist()[0].col, 5
AssertEqual getqflist()[0].text[:3], 'E006'

View File

@ -0,0 +1,7 @@
filetype off
set rtp+=build/vader
set rtp+=.
set rtp+=after
filetype plugin indent on
syntax enable
exe 'set nocompatible'