]> git.wincent.com - pinnacle.git/blob - autoload/pinnacle.vim
add pinnacle#underline()
[pinnacle.git] / autoload / pinnacle.vim
1 ""
2 " @plugin Pinnacle Highlight group manipulation for Vim
3 "
4 " # Intro
5 "
6 " Pinnacle provides functions for manipulating |:highlight| groups.
7 "
8 "
9 " # Installation
10 "
11 " To install Pinnacle, use your plug-in management system of choice.
12 "
13 " If you don't have a "plug-in management system of choice", I recommend
14 " Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
15 " robustness. Assuming that you have Pathogen installed and configured, and that
16 " you want to install vim-docvim into `~/.vim/bundle`, you can do so with:
17 "
18 " ```
19 " git clone https://github.com/wincent/pinnacle.git ~/.vim/bundle/pinnacle
20 " ```
21 "
22 " Alternatively, if you use a Git submodule for each Vim plug-in, you could do
23 " the following after `cd`-ing into the top-level of your Git superproject:
24 "
25 " ```
26 " git submodule add https://github.com/wincent/pinnacle.git ~/vim/bundle/pinnacle
27 " git submodule init
28 " ```
29 "
30 " To generate help tags under Pathogen, you can do so from inside Vim with:
31 "
32 " ```
33 " :call pathogen#helptags()
34 " ```
35 "
36 "
37 " # Website
38 "
39 " The official Pinnacle source code repo is at:
40 "
41 "   http://git.wincent.com/pinnacle.git
42 "
43 " Mirrors exist at:
44 "
45 "   - https://github.com/wincent/pinnacle
46 "   - https://gitlab.com/wincent/pinnacle
47 "   - https://bitbucket.org/ghurrell/pinnacle
48 "
49 " Official releases are listed at:
50 "
51 "   http://www.vim.org/scripts/script.php?script_id=5360
52 "
53 "
54 " # License
55 "
56 " Copyright (c) 2016-present Greg Hurrell
57 "
58 " Permission is hereby granted, free of charge, to any person obtaining
59 " a copy of this software and associated documentation files (the
60 " "Software"), to deal in the Software without restriction, including
61 " without limitation the rights to use, copy, modify, merge, publish,
62 " distribute, sublicense, and/or sell copies of the Software, and to
63 " permit persons to whom the Software is furnished to do so, subject to
64 " the following conditions:
65 "
66 " The above copyright notice and this permission notice shall be
67 " included in all copies or substantial portions of the Software.
68 "
69 " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
70 " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
71 " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
72 " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
73 " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
74 " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
75 " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76 "
77 "
78 " # Development
79 "
80 " ## Contributing patches
81 "
82 " Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
83 " at: https://github.com/wincent/pinnacle/pulls
84 "
85 " ## Cutting a new release
86 "
87 " At the moment the release process is manual:
88 "
89 " - Perform final sanity checks and manual testing
90 " - Update the |pinnacle-history| section of the documentation
91 " - Verify clean work tree:
92 "
93 " ```
94 " git status
95 " ```
96 "
97 " - Tag the release:
98 "
99 " ```
100 " git tag -s -m "$VERSION release" $VERSION
101 " ```
102 "
103 " - Publish the code:
104 "
105 " ```
106 " git push origin master --follow-tags
107 " git push github master --follow-tags
108 " ```
109 "
110 " - Produce the release archive:
111 "
112 " ```
113 " git archive -o vim-docvim-$VERSION.zip HEAD -- .
114 " ```
115 "
116 " - Upload to http://www.vim.org/scripts/script.php?script_id=5360
117 "
118 "
119 " # Authors
120 "
121 " Pinnacle is written and maintained by Greg Hurrell <greg@hurrell.net>.
122 "
123 "
124 " # History
125 "
126 " ## 0.1 (30 March 2016)
127 "
128 " - Initial release.
129
130 " Replaces newlines with spaces.
131 function! pinnacle#sub_newlines(string) abort
132   return tr(a:string, "\r\n", '  ')
133 endfunction
134
135 " Runs a command and returns the captured output as a single line.
136 "
137 " Useful when we don't want to let long lines on narrow windows produce unwanted
138 " embedded newlines.
139 function! pinnacle#capture_line(command) abort
140   redir => l:capture
141   execute a:command
142   redir END
143
144   return pinnacle#sub_newlines(l:capture)
145 endfunction
146
147 " Gets the current value of a highlight group.
148 function! pinnacle#capture_highlight(group) abort
149   return pinnacle#capture_line('0verbose silent highlight ' . a:group)
150 endfunction
151
152 " Extracts a highlight string from a group, recursively traversing linked
153 " groups, and returns a string suitable for passing to `:highlight`.
154 function! pinnacle#extract_highlight(group) abort
155   let l:group = pinnacle#capture_highlight(a:group)
156
157   " Traverse links back to authoritative group.
158   while l:group =~# 'links to'
159     let l:index = stridx(l:group, 'links to') + len('links to')
160     let l:linked = strpart(l:group, l:index + 1)
161     let l:group = pinnacle#capture_highlight(l:linked)
162   endwhile
163
164   " Extract the highlighting details (the bit after "xxx")
165   let l:matches = matchlist(l:group, '\<xxx\>\s\+\(.*\)')
166   let l:original = l:matches[1]
167   return l:original
168 endfunction
169
170 " Returns an italicized copy of `group` suitable for passing to `:highlight`.
171 function! pinnacle#italicize(group) abort
172   return pinnacle#decorate('italic', a:group)
173 endfunction
174
175 " Returns a bold copy of `group` suitable for passing to `:highlight`.
176 function! pinnacle#embolden(group) abort
177   return pinnacle#decorate('bold', a:group)
178 endfunction
179
180 " Returns an underlined copy of `group` suitable for passing to `:highlight`.
181 function! pinnacle#underline(group) abort
182   return pinnacle#decorate('undercurl', a:group)
183 endfunction
184
185 " Returns a copy of `group` decorated with `style` (eg. "bold", "italic" etc)
186 " suitable for passing to `:highlight`.
187 function! pinnacle#decorate(style, group) abort
188   let l:original = pinnacle#extract_highlight(a:group)
189
190   for l:lhs in ['gui', 'term', 'cterm']
191     " Check for existing setting.
192     let l:matches = matchlist(
193       \   l:original,
194       \   '^\([^ ]\+ \)\?' .
195       \   '\(' . l:lhs . '=[^ ]\+\)' .
196       \   '\( .\+\)\?$'
197       \ )
198     if l:matches == []
199       " No setting, add one with just a:style in it
200       let l:original .= ' ' . l:lhs . '=' . a:style
201     else
202       " Existing setting; check whether a:style is already in it.
203       let l:start = l:matches[1]
204       let l:value = l:matches[2]
205       let l:end = l:matches[3]
206       if l:value =~# '.*' . a:style . '.*'
207         continue
208       else
209         let l:original = l:start . l:value . ',' . a:style . l:end
210       endif
211     endif
212   endfor
213
214   return pinnacle#sub_newlines(l:original)
215 endfunction