From 64fb14c4a7b33db4a90a6cfc09095cba11814489 Mon Sep 17 00:00:00 2001 From: gryf Date: Mon, 25 Mar 2013 21:03:21 +0100 Subject: [PATCH] Added languageTool plugin --- .vimrc | 4 + GetLatest/GetLatestVimScripts.dat | 1 + bundle/languageTool/doc/LanguageTool.txt | 318 ++++++++++++++ bundle/languageTool/plugin/LanguageTool.vim | 459 ++++++++++++++++++++ 4 files changed, 782 insertions(+) create mode 100644 bundle/languageTool/doc/LanguageTool.txt create mode 100644 bundle/languageTool/plugin/LanguageTool.vim diff --git a/.vimrc b/.vimrc index 16039e9..101c82e 100644 --- a/.vimrc +++ b/.vimrc @@ -204,6 +204,10 @@ let g:NERDSpaceDelims=1 "Python indent{{{2 let g:python_version_2=1 "}}} +"LanguageTool {{{ +let g:languagetool_jar='/opt/LanguageTool/LanguageTool.jar' +"let g:languagetool_lang=pl +"}}} "}}} "KEYS: User defined keyboard shortcuts {{{ diff --git a/GetLatest/GetLatestVimScripts.dat b/GetLatest/GetLatestVimScripts.dat index 2a888a7..da0751f 100644 --- a/GetLatest/GetLatestVimScripts.dat +++ b/GetLatest/GetLatestVimScripts.dat @@ -5,6 +5,7 @@ ScriptID SourceID Filename 311 7645 grep.vim 2727 11120 jsbeautify.vim 2289 8922 loremipsum +3223 1 LanguageTool 2666 18811 Mark 2262 8944 occur.vim 152 3342 showmarks.vim diff --git a/bundle/languageTool/doc/LanguageTool.txt b/bundle/languageTool/doc/LanguageTool.txt new file mode 100644 index 0000000..5cb1e7c --- /dev/null +++ b/bundle/languageTool/doc/LanguageTool.txt @@ -0,0 +1,318 @@ +*LanguageTool.txt* A grammar checker in Vim for English, French, German, etc. +*LanguageTool* + +Author: Dominique Pellé +Last Change: 08 Feb 2013 + +For Vim version 7.0 and above + +============================================================================ + +1. Overview |languagetool-overview| +2. Screenshots & Demo |languagetool-screenshots| +3. Download |languagetool-download| +4. Installation |languagetool-installation| +5. Configuration |languagetool-configuration| +6. Features |languagetool-features| +7. Bugs |languagetool-bugs| +8. License |languagetool-license| + +============================================================================ + +1. Overview *languagetool-overview* + +This plugin integrates LanguageTool into Vim. LanguageTool is an Open Source +style and grammar checker for English, French, German, etc. See +http://www.languagetool.org/languages/ for a complete list of supported +languages. + +LanguageTool detects grammar mistakes that a spelling checker cannot detect +such as "it work" instead of "it works". Since version 1.8, LanguageTool +can also detect spelling mistakes using Hunspell dictionaries bundled with +LanguageTool for several languages or using morfologik for other languages. +Vim builtin spelling checker can also of course be used along with +LanguageTool. One advantage of the spelling checker of LanguageTool over +Vim spelling checker, is that it uses the native Hunspell dictionary directly, +so it works even with the latest Hunspell dictionaries containing features +not supported by Vim. For example, the latest French Hunspell dictionaries +from http://www.dicollect.org are not supported by Vim but they work well +with LanguageTool. On the other hand, the Vim native spelling checker is +faster and better integrated with Vim. + +See http://www.languagetool.org/ for more information about LanguageTool. + +============================================================================ + +2. Screenshots & Demo *languagetool-screenshots* + +If you don't have time to read help files, these screenshots will give you +an idea of what the LanguageTool plugin does: + + http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_en.png + http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_fr.png + +A screencast demo is also available at: + + http://shelr.tv/records/4fba8ef99660803e4f00001f + +============================================================================ + +3. Download *languagetool-download* + +You can download the latest version of this plugin from: + + http://www.vim.org/scripts/script.php?script_id=3223 + +LanguageTool can be downloaded from: + + http://www.languagetool.org/ + +============================================================================ + +4. Installation *languagetool-installation* + +4.1 Installing the plugin~ + +Unzip file LanguageTool.zip plugin from in your personal |vimfiles| directory +(~/.vim under Unix or %HOMEPATH%\vimfiles under Windows): > + + $ mkdir ~/.vim + $ cd ~/.vim + $ unzip /path-to/LanguageTool.zip + $ vim -c 'helptags ~/.vim/doc' + +The zip file contains the following files: > + + plugin/LanguageTool.vim + doc/LanguageTool.vim + +You have to enable plugins by adding these two lines in your |.vimrc| file: > + + set nocompatible + filetype plugin on + +4.2 Installing LanguageTool~ + +To use this plugin, you need to install the Java LanguageTool program. You +can choose to: + +* download stand-alone version of LanguageTool (LanguageTool-*.zip) from: + http://www.languagetool.org/ using the orange button labelled + "Download LanguageTool for stand-alone use". The standalone version of + Vim not only does grammar checking but also contains Hunspell dictionaries + for spell checking. +* or download a nightly build LanguageTool-.*-snapshot.zip from + http://www.languagetool.org/download/snapshots/. It contains a more + recent version than the stable version but it is not as well tested. +* or checkout and build the latest LanguageTool from sources in subversion. + +4.2.1 Download the stand-alone version of LanguageTool + +Download the stand-alone version of LanguageTool (LanguageTool-*.zip) +from http://www.languagetool.org/ and unzip it: > + + $ unzip LanguageTool-2.0.zip + +This should extract LanguageTool.jar among several other files. + +4.2.2 Build LanguageTool from sources in Subversion~ + +If you prefer to build LanguageTool yourself from sources, you first need +to install the pre-requisite packages. On Ubuntu, you need to install the +following packages: > + + $ sudo apt-get install openjdk-7-jdk mvn subversion + +Since version 2.1, LanguageTool is built with Maven. Prior to version 2.1, +it was built with ant. + +LanguageTool can then be downloaded and built with Maven as follows: > + + $ svn co https://languagetool.svn.sourceforge.net/svnroot/languagetool/trunk/languagetool + $ cd languagetool + $ mvn clean package + +After the build, the command line version of LanguageTool can be found in: > + + ./languagetool-standalone/target/LanguageTool-2.1-SNAPSHOT/LanguageTool-2.1-SNAPSHOT/languagetool-commandline.jar + +4.3 Configuring the location of LanguageTool.jar~ + +After installing LanguageTool, you must specify the location of the file +LanguageTool.jar in your $HOME/.vimrc file. Example: > + + let g:languagetool_jar='$HOME/languagetool/languagetool-standalone/target/LanguageTool-2.1-SNAPSHOT/LanguageTool-2.1-SNAPSHOT/languagetool-commandline.jar' + +Prior to LanguageTool-2.1, the command line version of LanguageTool +was called LanguageTool.jar. + +See section |languagetool-configuration| for more optional settings. + +============================================================================ + +5. Configuration *languagetool-configuration* + +LanguageTool plugin uses character encoding from the 'fenc' option or from +the 'enc' option if 'fenc' is empty. + +Several global variables can be set in your |vimrc| to configure the behavior +of the LanguageTool plugin. + +g:languagetool_jar *g:languagetool_jar* + + This variable specifies the location of the LanguageTool java grammar + checker program. + Default is: $HOME/languagetool/dist/LanguageTool.jar + +g:languagetool_lang + + The language code to use for the language tool checker. If undefined, + plugin tries to guess the language of the Vim spelling checker + 'spelllang' or v:lang. If neither works, plugin defaults to + English US (en-US). Starting with LanguageTool-1.8, regional variants + of some languages can be specified. For languages with variants + (currently English and German), it is necessary to specify the + variant in order for LanguageTool to signal spelling errors. + In other words, with :set spelllang=en LanguageTool only + signals grammar mistakes whereas with :set spellllang=en_us + LanguageTool signals spelling mistakes and grammar mistakes. + The valid language codes in LanguageTool-2.1 are: > + + ast Asturian + be Belarusian + br Breton + ca Catalan + cs Czech + da Danish + de German + de-AT German (Austria) + de-CH German (Switzerland) + de-DE German (Germany) + el Greek + en English + en-AU English (Australia) + en-CA English (Canada) + en-GB English (Great Britain) + en-NZ English (New Zealand) + en-US English (US) + en-ZA English (South Africa) + eo Esperanto + es Spanish + fr French + gl Galician + is Icelandic + it Italian + km Khmer + lt Lithuanian + ml Malayalam + nl Dutch + pl Polish + pt Portuguese + ro Romanian + ru Russian + sk Slovak + sl Slovenian + sv Swedish + tl Tagalog + uk Ukrainian + zh Chinese + +g:languagetool_disable_rules *g:languagetool_disable_rules* + + This variable specifies checker rules which are disabled. Each disabled + rule must be comma separated. + Default value set by plugin is: WHITESPACE_RULE,EN_QUOTES + +g:languagetool_win_height *g:languagetool_win_height* + + This variable specifies the height of the scratch window which contains + all grammatical mistakes with some explanations. You can use a negative + value to disable opening the scratch window. You can also make it empty '' + to let Vim pick a default size. + Default is: 14 + +You can also customize the following syntax highlighting groups: > + + LanguageToolGrammarError + LanguageToolSpellingError + LanguageToolCmd + LanguageToolLabel + LanguageToolErrorCount + +============================================================================ + +6. Features *languagetool-features* + +The LanguageTool plugin defines 2 commands |:LanguageToolCheck| and +|:LanguageToolClean|. + +:LanguageToolCheck *:LanguageToolCheck* + +Use the |:LanguageToolCheck| command to check the grammar in the current +buffer. This will highlight errors in the buffer. It will also open a new +scratch window with the list of grammar mistakes with further explanations +for each error. It also populates the location-list for the window. + +The |:LanguageToolCheck| command accepts a range. You can for example check +grammar between lines 100 and 200 in buffer with :100,200LanguageToolCheck, +check grammar in the visual selection with :<',>'LanguageToolCheck, etc. +The default range is 1,$ (whole buffer). + +:LanguageToolClear *:LanguageToolClear* + +Use the |:LanguageToolClear| command to clear highlighting of grammar +mistakes, close the scratch window containing the list of errors, clear +and close the location-list. + +The two commands are also available from the menu in gvim: > + + Plugin -> LanguageTool -> Check + -> Clear + +Using the error scratch window~ + +Pressing on an error in the error scratch buffer will jump to that +error. + +Using the Location-list~ + +The |location-list| is populated when running |:LanguageToolCheck|. So you can +use location-list Vim commands such as |:lopen| to open the location-list +window, |:lne| to jump to the next error, etc. + +The error scratch window may seem redundant with the location-list, but the +scratch window is more flexible to present errors in a nice way. If you do +not wish to popup the error scratch window, but use the location-list only, +you can disable it by setting |g:languagetool_win_height| to a negative value. + +============================================================================ + +7. Bugs *languagetool-bugs* + +Column number reported by LanguageTool indicating the location of the error +is sometimes incorrect. There is already an opened ticket about this bug: + + http://sourceforge.net/tracker/?func=detail&aid=3054895&group_id=110216&atid=655717 + +The script currently works around it by doing pattern matching with +information context but it's not a perfect workaround: it can cause +spurious highlighting of errors in rare cases. This bug is fixed in +LanguageTool-1.8. + +Please report bugs or suggestions to . +Alternatively, you can also discuss improvements to this plugin in Wiki +by clicking on the "Vim wiki" link at the top of the script page: + + http://www.vim.org/scripts/script.php?script_id=3223 + +============================================================================ + +8. License *languagetool-license* + +The VIM LICENSE applies to the LanguageTool.vim plugin (see |copyright| +except use "LanguageTool.vim" instead of "Vim"). + +LanguageTool is freely available under LGPL. + +============================================================================ +vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl: diff --git a/bundle/languageTool/plugin/LanguageTool.vim b/bundle/languageTool/plugin/LanguageTool.vim new file mode 100644 index 0000000..c6916d1 --- /dev/null +++ b/bundle/languageTool/plugin/LanguageTool.vim @@ -0,0 +1,459 @@ +" LanguageTool: Grammar checker in Vim for English, French, German, etc. +" Maintainer: Dominique Pellé +" Screenshots: http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_en.png +" http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_fr.png +" Last Change: 2013/02/08 +" Version: 1.25 +" +" Long Description: {{{1 +" +" This plugin integrates the LanguageTool grammar checker into Vim. +" Current version of LanguageTool can check grammar in many languages: +" ast, be, br, ca, da, de, el, en, eo, es, fr, gl, is, it, km, lt, ml, nl, +" pl, pt, ro, ru, sk, sl, sv, tl, uk, zh. See http://www.languagetool.org/ +" for more information about LanguageTool. +" +" The script defines 2 Ex commands: +" +" * Use :LanguageToolCheck to check grammar in current buffer. +" This will check for grammar mistakes in text of current buffer +" and highlight the errors. It also opens a new scratch window with the +" list of grammar errors with further explanations for each error. +" Pressing in scratch buffer will jump to that error. The +" location list for the buffer being checked is also populated. +" So you can use location commands such as :lopen to open the location +" list window, :lne to jump to the next error, etc. +" +" * Use :LanguageToolClear to remove highlighting of grammar mistakes, +" close the scratch window containing the list of errors, clear and +" close the location list. +" +" See screenshots of grammar checking in English and French at: +" http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_en.png +" http://dominique.pelle.free.fr/pic/LanguageToolVimPlugin_fr.png +" +" See also screencast demo at: +" http://shelr.tv/records/4fba8ef99660803e4f00001f +" +" See :help LanguageTool for more details +" +" Install Details: {{{1 +" +" Install the plugin with: +" +" $ mkdir ~/.vim +" $ cd ~/.vim +" $ unzip /path-to/LanguageTool.zip +" $ vim -c 'helptags ~/.vim/doc' +" +" You also need to install the Java LanguageTool program in order to use +" this plugin. There are 3 possibilities: +" +" 1/ Download the stand-alone latest version of LanguageTool file +" (LanguageTool-*.zip) from http://www.languagetool.org/ and +" Unzip it. This should extract LanguageTool.jar among several +" other files. +" +" 2/ Or download an unofficial nightly build available at: +" http://www.languagetool.org/download/snapshots/ +" +" 3/ Or download the latest LanguageTool from subversion and build +" it. This ensures that you get the latest version. On Ubuntu, you need +" to install the maven, openjdk-7-jdk and subversion packages as a +" prerequisite: +" +" $ sudo apt-get install openjdk-7-jdk maven subversion +" +" LanguageTool can then be downloaded and built as follows: +" +" $ svn co https://languagetool.svn.sourceforge.net/svnroot/languagetool/trunk/languagetool +" $ cd languagetool +" $ mvn package +" +" This should build the command line version of LanguageTool: +" +" ./languagetool-standalone/target/LanguageTool-2.1-SNAPSHOT/LanguageTool-2.1-SNAPSHOT/languagetool-commandline.jar +" +" You then need to set up g:languagetool_jar in your ~/.vimrc with +" the location of this languagetool-commandline.jar file (or +" LanguageTool.jar prior to version 2.1). For example: +" +" let g:languagetool_jar='$HOME/languagetool/languagetool-standalone/target/LanguageTool-2.1-SNAPSHOT/LanguageTool-2.1-SNAPSHOT/languagetool-commandline.jar' +" +" License: {{{1 +" +" The VIM LICENSE applies to LanguageTool.vim plugin +" (see ":help copyright" except use "LanguageTool.vim" instead of "Vim"). +" +" Plugin set up {{{1 +if &cp || exists("g:loaded_languagetool") + finish +endif +let g:loaded_languagetool = "1" + +" Guess language from 'a:lang' (either 'spelllang' or 'v:lang') +function s:FindLanguage(lang) "{{{1 + " This replaces things like en_gb en-GB as expected by LanguageTool, + " only for languages that support variants in LanguageTool. + let l:language = substitute(substitute(a:lang, + \ '\(\a\{2,3}\)\(_\a\a\)\?.*', + \ '\=tolower(submatch(1)) . toupper(submatch(2))', ''), + \ '_', '-', '') + + " All supported languages (with variants) from version LanguageTool-1.8. + let l:supportedLanguages = { + \ 'ast' : 1, + \ 'be' : 1, + \ 'br' : 1, + \ 'ca' : 1, + \ 'cs' : 1, + \ 'da' : 1, + \ 'de' : 1, + \ 'de-AT' : 1, + \ 'de-CH' : 1, + \ 'de-DE' : 1, + \ 'el' : 1, + \ 'en' : 1, + \ 'en-AU' : 1, + \ 'en-CA' : 1, + \ 'en-GB' : 1, + \ 'en-NZ' : 1, + \ 'en-US' : 1, + \ 'en-ZA' : 1, + \ 'eo' : 1, + \ 'es' : 1, + \ 'fr' : 1, + \ 'gl' : 1, + \ 'is' : 1, + \ 'it' : 1, + \ 'km' : 1, + \ 'lt' : 1, + \ 'ml' : 1, + \ 'nl' : 1, + \ 'pl' : 1, + \ 'pt' : 1, + \ 'ro' : 1, + \ 'ru' : 1, + \ 'sk' : 1, + \ 'sl' : 1, + \ 'sv' : 1, + \ 'tl' : 1, + \ 'uk' : 1, + \ 'zh' : 1 + \} + + if has_key(l:supportedLanguages, l:language) + return l:language + endif + + " Removing the region (if any) and trying again. + let l:language = substitute(l:language, '-.*', '', '') + return has_key(l:supportedLanguages, l:language) ? l:language : '' +endfunction + +" Return a regular expression used to highlight a grammatical error +" at line a:line in text. The error starts at character a:start in +" context a:context and its length in context is a:len. +function s:LanguageToolHighlightRegex(line, context, start, len) "{{{1 + let l:start_idx = byteidx(a:context, a:start) + let l:end_idx = byteidx(a:context, a:start + a:len) - 1 + let l:start_ctx_idx = byteidx(a:context, a:start + a:len) + let l:end_ctx_idx = byteidx(a:context, a:start + a:len + 5) - 1 + + " The substitute allows to match errors which span multiple lines. + " The part after \ze gives a bit of context to avoid spurious + " highlighting when the text of the error is present multiple + " times in the line. + return '\V' + \ . '\%' . a:line . 'l' + \ . substitute(escape(a:context[l:start_idx : l:end_idx], "'\\"), ' ', '\\_\\s', 'g') + \ . '\ze' + \ . substitute(escape(a:context[l:start_ctx_idx : l:end_ctx_idx], "'\\"), ' ', '\\_\\s', 'g') +endfunction + +" Unescape XML special characters in a:text. +function s:XmlUnescape(text) "{{{1 + " Change XML escape char such as " into " + " Substitution of & must be done last or else something + " like &quot; would get first transformed into " + " and then wrongly transformed into " (correct is ") + let l:escaped = substitute(a:text, '"', '"', 'g') + let l:escaped = substitute(l:escaped, ''', "'", 'g') + let l:escaped = substitute(l:escaped, '>', '>', 'g') + let l:escaped = substitute(l:escaped, '<', '<', 'g') + return substitute(l:escaped, '&', '\&', 'g') +endfunction + +" Parse a xml attribute such as: ruleId="FOO" in line a:line. +" where ruleId is the key a:key, and FOO is the returned value corresponding +" to that key. +function s:ParseKeyValue(key, line) "{{{1 + return s:XmlUnescape(matchstr(a:line, '\<' . a:key . '="\zs[^"]*\ze"')) +endfunction + +" Set up configuration. +" Returns 0 if success, < 0 in case of error. +function s:LanguageToolSetUp() "{{{1 + let s:languagetool_disable_rules = exists("g:languagetool_disable_rules") + \ ? g:languagetool_disable_rules + \ : 'WHITESPACE_RULE,EN_QUOTES' + let s:languagetool_win_height = exists("g:languagetool_win_height") + \ ? g:languagetool_win_height + \ : 14 + let s:languagetool_encoding = &fenc ? &fenc : &enc + + " Setting up language... + if exists("g:languagetool_lang") + let s:languagetool_lang = g:languagetool_lang + else + " Trying to guess language from 'spelllang' or 'v:lang'. + let s:languagetool_lang = s:FindLanguage(&spelllang) + if s:languagetool_lang == '' + let s:languagetool_lang = s:FindLanguage(v:lang) + if s:languagetool_lang == '' + echoerr 'Failed to guess language from spelllang=[' + \ . &spelllang . '] or from v:lang=[' . v:lang . ']. ' + \ . 'Defauling to English (en-US). ' + \ . 'See ":help LanguageTool" regarding setting g:languagetool_lang.' + let s:languagetool_lang = 'en-US' + endif + endif + endif + + let s:languagetool_jar = exists("g:languagetool_jar") + \ ? g:languagetool_jar + \ : $HOME . '/languagetool/dist/LanguageTool.jar' + + if !filereadable(s:languagetool_jar) + " Hmmm, can't find the jar file. Try again with expand() in case user + " set it up as: let g:languagetool_jar = '$HOME/LanguageTool.jar' + let l:languagetool_jar = expand(s:languagetool_jar) + if !filereadable(expand(l:languagetool_jar)) + echomsg "LanguageTool cannot be found at: " . s:languagetool_jar + echomsg "You need to install LanguageTool and/or set up g:languagetool_jar" + return -1 + endif + let s:languagetool_jar = l:languagetool_jar + endif + return 0 +endfunction + +" Jump to a grammar mistake (called when pressing +" on a particular error in scratch buffer). +function JumpToCurrentError() "{{{1 + let l:save_cursor = getpos('.') + norm! $ + if search('^Error:\s\+', 'beW') > 0 + let l:error_idx = expand('') + let l:error = s:errors[l:error_idx - 1] + let l:line = l:error['fromy'] + let l:col = l:error['fromx'] + let l:rule = l:error['ruleId'] + call setpos('.', l:save_cursor) + exe s:languagetool_text_win . 'wincmd w' + exe 'norm! ' . l:line . 'G0' + + " Finding the column is done using pattern matching with information + " in error context. + let l:context = l:error['replacements'][byteidx(l:error['replacements'], l:error['context']) + \ :byteidx(l:error['replacements'], l:error['context'] + l:error['contextoffset']) - 1] + let l:re = s:LanguageToolHighlightRegex(l:error['fromy'], l:error['replacements'], + \ l:error['context'], l:error['contextoffset']) + echon 'Jump to error ' . l:error_idx . '/' . len(s:errors) + \ . ' (' . l:rule . ') ...' . l:context . '... @ ' + \ . l:line . 'L ' . l:col . 'C' + call search(l:re) + norm! zz + else + call setpos('.', l:save_cursor) + endif +endfunction + +" This function performs grammar checking of text in the current buffer. +" It highlights grammar mistakes in current buffer and opens a scratch +" window with all errors found. It also populates the location-list of +" the window with all errors. +" a:line1 and a:line2 parameters are the first and last line number of +" the range of line to check. +" Returns 0 if success, < 0 in case of error. +function s:LanguageToolCheck(line1, line2) "{{{1 + let l:save_cursor = getpos('.') + if s:LanguageToolSetUp() < 0 + return -1 + endif + call s:LanguageToolClear() + + sil %y + botright new + let s:languagetool_error_buffer = bufnr('%') + let s:languagetool_error_win = winnr() + sil put! + + " LanguageTool somehow gives incorrect line/column numbers when + " reading from stdin so we need to use a temporary file to get + " correct results. + let l:tmpfilename = tempname() + + let l:range = a:line1 . ',' . a:line2 + silent exe l:range . 'w!' . l:tmpfilename + + let l:languagetool_cmd = 'java' + \ . ' -jar ' . s:languagetool_jar + \ . ' -c ' . s:languagetool_encoding + \ . ' -d ' . s:languagetool_disable_rules + \ . ' -l ' . s:languagetool_lang + \ . ' --api ' . l:tmpfilename + + sil exe '%!' . l:languagetool_cmd + call delete(l:tmpfilename) + + if v:shell_error + echoerr 'Command [' . l:languagetool_cmd . '] failed with error: ' + \ . v:shell_error + call s:LanguageToolClear() + return -1 + endif + + " Loop on all errors in XML output of LanguageTool and + " collect information about all errors in list s:errors + let s:errors = [] + while search('^ 0 + let l:l = getline('.') + " The fromx and tox given by LanguageTool are not reliable. + " They are even sometimes negative! + + let l:error= {} + for l:k in [ 'fromy', 'fromx', 'tox', 'toy', + \ 'ruleId', 'subId', 'msg', 'replacements', + \ 'context', 'contextoffset', 'errorlength', 'url' ] + let l:error[l:k] = s:ParseKeyValue(l:k, l:l) + endfor + + " Make line/column number start at 1 rather than 0. + " Make also line number absolute as in buffer. + let l:error['fromy'] += a:line1 + let l:error['fromx'] += 1 + let l:error['toy'] += a:line1 + let l:error['tox'] += 1 + + call add(s:errors, l:error) + endwhile + + if s:languagetool_win_height >= 0 + " Reformat the output of LanguageTool (XML is not human friendly) and + " set up syntax highlighting in the buffer which shows all errors. + sil %d + call append(0, '# ' . l:languagetool_cmd) + set bt=nofile + setlocal nospell + syn clear + syn match LanguageToolCmd '\%1l.*' + syn match LanguageToolLabel '^\(Pos\|Rule\|Context\|Message\|Correction\):' + syn match LanguageToolLabelMoreInfo '^More info:.*' contains=LanguageToolUrl + syn match LanguageToolErrorCount '^Error:\s\+\d\+.\d\+' + syn match LanguageToolUrl '^More info:\s*\zs.*' contained + let l:i = 0 + for l:error in s:errors + call append('$', 'Error: ' + \ . (l:i + 1) . '/' . len(s:errors) + \ . ' (' . l:error['ruleId'] . ':' . l:error['subId'] . ')' + \ . ' @ ' . l:error['fromy'] . 'L ' . l:error['fromx'] . 'C') + call append('$', 'Message: ' . l:error['msg']) + call append('$', 'Context: ' . l:error['context']) + + if l:error['ruleId'] =~ 'HUNSPELL_RULE\|HUNSPELL_NO_SUGGEST_RULE\|MORFOLOGIK_RULE_.*\|GERMAN_SPELLER_RULE' + exe "syn match LanguageToolSpellingError '" + \ . '\%' . line('$') . 'l\%9c' + \ . '.\{' . (4 + l:error['contextoffset']) . '}\zs' + \ . '.\{' . (l:error['errorlength']) . "}'" + else + exe "syn match LanguageToolGrammarError '" + \ . '\%' . line('$') . 'l\%9c' + \ . '.\{' . (4 + l:error['contextoffset']) . '}\zs' + \ . '.\{' . (l:error['errorlength']) . "}'" + endif + if !empty(l:error['replacements']) + call append('$', 'Correction: ' . l:error['replacements']) + endif + if !empty(l:error['url']) + call append('$', 'More info: ' . l:error['url']) + endif + call append('$', '') + let l:i += 1 + endfor + exe "norm! z" . s:languagetool_win_height . "\" + 0 + map :call JumpToCurrentError() + redraw + echon 'Press on error in scratch buffer to jump its location' + exe "norm! \\" + else + " Negative s:languagetool_win_height -> no scratch window. + bd! + unlet! s:languagetool_error_buffer + endif + let s:languagetool_text_win = winnr() + + " Also highlight errors in original buffer and populate location list. + setlocal errorformat=%f:%l:%c:%m + for l:error in s:errors + let l:re = s:LanguageToolHighlightRegex(l:error['fromy'], + \ l:error['context'], + \ l:error['contextoffset'], + \ l:error['errorlength']) + if l:error['ruleId'] =~ 'HUNSPELL_RULE\|HUNSPELL_NO_SUGGEST_RULE\|MORFOLOGIK_RULE_.*\|GERMAN_SPELLER_RULE' + exe "syn match LanguageToolSpellingError '" . l:re . "'" + laddexpr expand('%') . ':' + \ . l:error['fromy'] . ':' . l:error['fromx'] . ':' + \ . l:error['ruleId'] . ' ' . l:error['msg'] + else + exe "syn match LanguageToolGrammarError '" . l:re . "'" + laddexpr expand('%') . ':' + \ . l:error['fromy'] . ':' . l:error['fromx'] . ':' + \ . l:error['ruleId'] . ' ' . l:error['msg'] + endif + endfor + return 0 +endfunction + +" This function clears syntax highlighting created by LanguageTool plugin +" and removes the scratch window containing grammar errors. +function s:LanguageToolClear() "{{{1 + if exists('s:languagetool_error_buffer') + if bufexists(s:languagetool_error_buffer) + sil! exe "bd! " . s:languagetool_error_buffer + endif + endif + if exists('s:languagetool_text_win') + let l:win = winnr() + exe s:languagetool_text_win . 'wincmd w' + syn clear LanguageToolGrammarError + syn clear LanguageToolSpellingError + lexpr '' + lclose + exe l:win . 'wincmd w' + endif + unlet! s:languagetool_error_buffer + unlet! s:languagetool_error_win + unlet! s:languagetool_text_win +endfunction + +hi def link LanguageToolCmd Comment +hi def link LanguageToolLabel Label +hi def link LanguageToolLabelMoreInfo Label +hi def link LanguageToolGrammarError Error +hi def link LanguageToolSpellingError WarningMsg +hi def link LanguageToolErrorCount Title +hi def link LanguageToolUrl Underlined + +" Section: Menu items {{{1 +if has("gui_running") && has("menu") && &go =~ 'm' + amenu &Plugin.LanguageTool.Chec&k :LanguageToolCheck + amenu &Plugin.LanguageTool.Clea&r :LanguageToolClear +endif + +" Defines commands {{{1 +com! -nargs=0 LanguageToolClear :call s:LanguageToolClear() +com! -nargs=0 -range=% LanguageToolCheck :call s:LanguageToolCheck(, + \ ) +" vim: fdm=marker