writegood.vim (4435B)
1 " Based on https://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/ 2 3 function WriteGoodStyle() 4 " Highlight lines that exceed 120 columns 5 call matchadd('ColorColumn', '\%121v.', 100) 6 7 " Trailing spaces 8 call matchadd('Trailing', '\s\+$') 9 " Spaces before a tab 10 call matchadd('Trailing', ' \+\ze\t') 11 12 " Apply these rules to plain text and to comments. Is there a better way? 13 let l:contained='contained' 14 if &ft=='text' || &ft=='' 15 let l:contained='' 16 endif 17 18 " Duplicate words 19 exe 'syn match StyleDuplicate ' . l:contained . ' /\c\(\<\w\+\>\)\_s\+\<\1\>/' 20 21 " Weasel words 22 let l:nonweasel=['apply'] 23 let l:weasel=['many', 'various', 'very', 'fairly', 'several', 'extremely'] 24 let l:weasel+=['exceedingly', 'quite', 'remarkably', 'few', 'surprisingly'] 25 let l:weasel+=['mostly', 'largely', 'huge', 'tiny', 'are a number'] 26 let l:weasel+=['is a number', 'excellent', 'interestingly', 'significantly'] 27 let l:weasel+=['substantially', 'clearly', 'vast', 'relatively'] 28 let l:weasel+=['completely', 'obviously', 'note that', 'particular'] 29 let l:weasel+=['specific', 'manner', 'purposes', 'that is', 'which are'] 30 let l:weasel+=['that are', 'differently', 'formally', 'in other words'] 31 let l:weasel+=['almost', '\w\+ly'] 32 let l:abbrev=['etc.', 'e.g.', 'i.e.'] 33 let l:nonweasel='\(' . join(l:nonweasel, '\|') . '\)\@!' 34 let l:weasel='\(' . substitute(join(l:weasel, '\|'), ' ', '\\_s\\+', 'g') . '\)' 35 let l:abbrev='\(' . substitute(join(l:abbrev, '\|'), '\.', '\\.', 'g') . '\)' 36 exec 'syn match StylePassive ' . l:contained . ' /\c\<' . l:nonweasel . l:weasel. '\>\|\<' . l:abbrev .'/' 37 38 " Passive voice 39 let l:nontense=['red'] 40 let l:verb=['am', 'are', 'were', 'being', 'is', 'been', 'was', 'be'] 41 let l:tense=['\w\+ed', 'awoken', 'been', 'born', 'beat', 'become', 'begun'] 42 let l:tense+=['bent', 'beset', 'bet', 'bid', 'bidden', 'bound', 'bitten', 'bled'] 43 let l:tense+=['blown', 'broken', 'bred', 'brought', 'broadcast', 'built'] 44 let l:tense+=['burnt', 'burst', 'bought', 'cast', 'caught', 'chosen', 'clung'] 45 let l:tense+=['come', 'cost', 'crept', 'cut', 'dealt', 'dug', 'dived', 'done'] 46 let l:tense+=['drawn', 'dreamt', 'driven', 'drunk', 'eaten', 'fallen', 'fed'] 47 let l:tense+=['felt', 'fought', 'found', 'fit', 'fled', 'flung', 'flown'] 48 let l:tense+=['forbidden', 'forgotten', 'foregone', 'forgiven', 'forsaken'] 49 let l:tense+=['frozen', 'gotten', 'given', 'gone', 'ground', 'grown', 'hung'] 50 let l:tense+=['heard', 'hidden', 'hit', 'held', 'hurt', 'kept', 'knelt'] 51 let l:tense+=['knit', 'known', 'laid', 'led', 'leapt', 'learnt', 'left'] 52 let l:tense+=['lent', 'let', 'lain', 'lighted', 'lost', 'made', 'meant'] 53 let l:tense+=['met', 'misspelt', 'mistaken', 'mown', 'overcome', 'overdone'] 54 let l:tense+=['overtaken', 'overthrown', 'paid', 'pled', 'proven', 'put'] 55 let l:tense+=['quit', 'read', 'rid', 'ridden', 'rung', 'risen', 'run', 'sawn'] 56 let l:tense+=['said', 'seen', 'sought', 'sold', 'sent', 'set', 'sewn'] 57 let l:tense+=['shaken', 'shaven', 'shorn', 'shed', 'shone', 'shod', 'shot'] 58 let l:tense+=['shown', 'shrunk', 'shut', 'sung', 'sunk', 'sat', 'slept'] 59 let l:tense+=['slain', 'slid', 'slung', 'slit', 'smitten', 'sown', 'spoken'] 60 let l:tense+=['sped', 'spent', 'spilt', 'spun', 'spit', 'split', 'spread'] 61 let l:tense+=['sprung', 'stood', 'stolen', 'stuck', 'stung', 'stunk'] 62 let l:tense+=['stridden', 'struck', 'strung', 'striven', 'sworn', 'swept'] 63 let l:tense+=['swollen', 'swum', 'swung', 'taken', 'taught', 'torn', 'told'] 64 let l:tense+=['thought', 'thrived', 'thrown', 'thrust', 'trodden'] 65 let l:tense+=['understood', 'upheld', 'upset', 'woken', 'worn', 'woven'] 66 let l:tense+=['wed', 'wept', 'wound', 'won', 'withheld', 'withstood', 'wrung'] 67 let l:tense+=['written'] 68 let l:nontense='\(' . join(l:nontense, '\|') . '\)\@!' 69 let l:verb='\(' . join(l:verb, '\|') . '\)' 70 let l:tense='\(' . join(l:tense, '\|') . '\)' 71 exe 'syn match StylePassive ' . l:contained . ' /\c\<' . l:verb . '\>\_s\+\<' . l:nontense . l:tense . '\>/' 72 73 syn cluster Style contains=StyleDuplicate,StyleWeasel,StylePassive 74 syn cluster Spell add=@Style 75 76 hi def link StyleDuplicate StyleBad 77 hi def link StyleWeasel StyleBad 78 hi def link StylePassive StyleBad 79 hi def link StyleBad SpellBad 80 endfunction 81 82 augroup Style 83 au! 84 au FileType,Syntax,VimEnter,WinEnter,BufRead,BufNewFile * call WriteGoodStyle() 85 augroup End