Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert byte offset to char, to fix wrong highlight in non ascii text #95

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ Please set `g:grammarous#show_first_error` to `1`. It opens an information windo
Please set `g:grammarous#use_location_list` to `1`. It sets all grammatical errors to location list.
This variable is set to `0` by default to avoid conflicts of location list usage with other plugins.


## Automatic installation

This plugin attempts to install [LanguageTool](https://www.languagetool.org/) using `curl` or `wget` command at first time.
Expand Down
34 changes: 30 additions & 4 deletions autoload/grammarous.vim
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ let g:grammarous#hooks = get(g:, 'grammarous#hooks', {
let g:grammarous#languagetool_cmd = get(g:, 'grammarous#languagetool_cmd', '')
let g:grammarous#show_first_error = get(g:, 'grammarous#show_first_error', 0)
let g:grammarous#use_location_list = get(g:, 'grammarous#use_location_list', 0)
let g:grammarous#convert_char_to_byte = get(g:, 'grammarous#convert_char_to_byte', 1)

highlight default link GrammarousError SpellBad
highlight default link GrammarousInfoError ErrorMsg
Expand Down Expand Up @@ -180,6 +181,24 @@ function! s:set_errors_to_location_list() abort
endtry
endfunction

function! s:convert_char_to_byte(errs) abort
for e in a:errs
let line_from = getline(str2nr(e.fromy) + 1)
let line_to = getline(str2nr(e.toy) + 1)
let ch_from = strcharpart(line_from, str2nr(e.fromx), 1)
let e.errorlength = len(strcharpart(line_from, e.fromx, e.errorlength))
artur-shaik marked this conversation as resolved.
Show resolved Hide resolved
let e.fromx = len(strcharpart(line_from, 0, str2nr(e.fromx)))
let e.tox = len(strcharpart(line_to, 0, str2nr(e.tox)))
endfor
endfunction

function! s:shift_x(errs) abort
for e in a:errs
let e.fromx += 1
let e.tox += 1
endfor
endfunction

function! s:set_errors_from_xml_string(xml) abort
let b:grammarous_result = grammarous#get_errors_from_xml(s:XML.parse(substitute(a:xml, "\n", '', 'g')))
let parsed = s:last_parsed_options
Expand All @@ -194,6 +213,12 @@ function! s:set_errors_from_xml_string(xml) abort
return
endif

if g:grammarous#convert_char_to_byte
call s:convert_char_to_byte(b:grammarous_result)
else
call s:shift_x(b:grammarous_result)
endif

let len = len(b:grammarous_result)
echomsg printf('Detected %d grammatical error%s', len, len > 1 ? 's' : '')
call grammarous#highlight_errors_in_current_buffer(b:grammarous_result)
Expand Down Expand Up @@ -328,7 +353,7 @@ function! s:invoke_check(range_start, ...)
if g:grammarous#languagetool_cmd !=# ''
let cmd = printf('%s %s', g:grammarous#languagetool_cmd, cmdargs)
else
let cmd = printf('%s -jar %s %s', g:grammarous#java_cmd, substitute(jar, '\\\s\@!', '\\\\', 'g'), cmdargs)
let cmd = printf('%s -jar %s --line-by-line %s', g:grammarous#java_cmd, substitute(jar, '\\\s\@!', '\\\\', 'g'), cmdargs)
endif

if s:job_is_available
Expand Down Expand Up @@ -396,9 +421,9 @@ function! s:matcherrpos(...)
return matchaddpos('GrammarousError', [a:000], 999)
endfunction

function! s:highlight_error(from, to)
function! s:highlight_error(from, to, length)
if a:from[0] == a:to[0]
return s:matcherrpos(a:from[0], a:from[1], a:to[1] - a:from[1])
return s:matcherrpos(a:from[0], a:from[1], a:length)
endif

let ids = [s:matcherrpos(a:from[0], a:from[1], strlen(getline(a:from[0]))+1 - a:from[1])]
Expand All @@ -421,7 +446,8 @@ function! grammarous#highlight_errors_in_current_buffer(errs)
let e.id = s:highlight_error(
\ [str2nr(e.fromy)+1, str2nr(e.fromx)+1],
\ [str2nr(e.toy)+1, str2nr(e.tox)+1],
\ )
\ e.errorlength
\ )
endfor
else
for e in a:errs
Expand Down