Mercurial > vim
annotate runtime/autoload/dist/man.vim @ 32837:050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Commit: https://github.com/vim/vim/commit/8cfe52e6fbf44032cd40d1561e93644786b15ee7
Author: goweol <goweol@gmail.com>
Date: Fri Aug 18 06:13:29 2023 +0900
man.vim: Recognise hyphenated-at-eol cross-references (https://github.com/vim/vim/issues/12609)
Manual pages requested for output may undergo formatting
arranged by some roff-descendant program. Lines longer
than MANWIDTH or COLUMNS or real-estate width of a device
(with support for horizontal scrolling considered) can be
divided at either blank characters and/or at groups of word
characters (syllables) according to supported hyphenation
rules (although page authors are free to disable hyphenation
or prevent particular words from being hyphenated).
Groff?s manual describes it as follows:
5.1.2 Hyphenation
Since the odds are not great for finding a set of words, for
every output line, which fit nicely on a line without
inserting excessive amounts of space between words, gtroff
hyphenates words so that it can justify lines without
inserting too much space between words. It uses an internal
hyphenation algorithm (a simplified version of the algorithm
used within TeX) to indicate which words can be hyphenated
and how to do so. When a word is hyphenated, the first part
of the word is added to the current filled line being output
(with an attached hyphen), and the other portion is added to
the next line to be filled.
It would be expedient for autoload/dist/man.vim (along with
syntax/man.vim?s highlighting and ftplugin/man.vim?s Ctrl-],
\K mappings) to allow for hyphenation of cross-references
to manual pages.
For example,
# Launch Vim [v9.0; patched: 1-1378, 1499] as follows:
MANWIDTH=80 vim --not-a-term +MANPAGER '+Man man' '+/conv(1)' '+norm B'
# Press Ctrl-] with cursor on _m_: "... use man?
# conv(1) directly."_______________________[^]
#
# (Man v2.11.2)
# Launch Vim as follows:
MANWIDTH=80 vim --not-a-term +MANPAGER '+Man git' '+/config(1)' '+norm B'
# Press Ctrl-] with cursor on _g_: "... in git-
# config(1) for a more ..."_______________[^]
#
# (Git v2.39.2)
Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 17 Aug 2023 23:15:07 +0200 |
parents | f0854888250f |
children | 4ae88f9389b4 |
rev | line source |
---|---|
29236 | 1 " Vim filetype plugin autoload file |
2 " Language: man | |
3 " Maintainer: Jason Franklin <vim@justemail.net> | |
4 " Maintainer: SungHyun Nam <goweol@gmail.com> | |
5 " Autoload Split: Bram Moolenaar | |
32836
f0854888250f
man.vim: Uniformly place cursor at the same column with `Ctrl-t` (#12608)
Christian Brabandt <cb@256bit.org>
parents:
29236
diff
changeset
|
6 " Last Change: 2023 Jun 28 |
29236 | 7 |
8 let s:cpo_save = &cpo | |
9 set cpo-=C | |
10 | |
11 let s:man_tag_depth = 0 | |
12 | |
13 let s:man_sect_arg = "" | |
14 let s:man_find_arg = "-w" | |
15 try | |
16 if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5" | |
17 let s:man_sect_arg = "-s" | |
18 let s:man_find_arg = "-l" | |
19 endif | |
20 catch /E145:/ | |
21 " Ignore the error in restricted mode | |
22 endtry | |
23 | |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
24 func s:ParseIntoPageAndSection() |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
25 " Accommodate a reference that terminates in a hyphen. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
26 " |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
27 " See init_charset_table() at |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
28 " https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/input.cpp?h=1.22.4#n6794 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
29 " |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
30 " See can_break_after() at |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
31 " https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/charinfo.h?h=1.22.4#n140 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
32 " |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
33 " Assumptions and limitations: |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
34 " 1) Manual-page references (in consequence of command-related filenames) |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
35 " do not contain non-ASCII HYPHENs (0x2010), any terminating HYPHEN |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
36 " must have been introduced to mark division of a word at the end of |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
37 " a line and can be discarded; whereas similar references may contain |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
38 " ASCII HYPHEN-MINUSes (0x002d) and any terminating HYPHEN-MINUS forms |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
39 " a compound word in addition to marking word division. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
40 " 2) Well-formed manual-page references always have a section suffix, e.g. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
41 " "git-commit(1)", therefore suspended hyphenated compounds are not |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
42 " determined, e.g. [V] (With cursor at _git-merge-_ below...) |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
43 " ".................... git-merge- and git-merge-base. (See git-cherry- |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
44 " pick(1) and git-cherry(1).)" (... look up "git-merge-pick(1)".) |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
45 " |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
46 " Note that EM DASH (0x2014), a third stooge from init_charset_table(), |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
47 " neither connects nor divides parts of a word. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
48 let str = expand("<cWORD>") |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
49 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
50 if str =~ '\%u2010$' " HYPHEN (-1). |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
51 let str = strpart(str, 0, strridx(str, "\u2010")) |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
52 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
53 " Append the leftmost WORD (or an empty string) from the line below. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
54 let str .= get(split(get(getbufline(bufnr('%'), line('.') + 1), 0, '')), 0, '') |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
55 elseif str =~ '-$' " HYPHEN-MINUS. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
56 " Append the leftmost WORD (or an empty string) from the line below. |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
57 let str .= get(split(get(getbufline(bufnr('%'), line('.') + 1), 0, '')), 0, '') |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
58 endif |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
59 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
60 " According to man(1), section name formats vary (MANSECT): |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
61 " 1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 9 6 7 |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
62 let parts = matchlist(str, '\(\k\+\)(\(\k\+\))') |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
63 return (len(parts) > 2) |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
64 \ ? {'page': parts[1], 'section': parts[2]} |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
65 \ : {'page': matchstr(str, '\k\+'), 'section': ''} |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
66 endfunc |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
67 |
29236 | 68 func dist#man#PreGetPage(cnt) |
69 if a:cnt == 0 | |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
70 let what = s:ParseIntoPageAndSection() |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
71 let sect = what.section |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
72 let page = what.page |
29236 | 73 else |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
74 let what = s:ParseIntoPageAndSection() |
29236 | 75 let sect = a:cnt |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
76 let page = what.page |
29236 | 77 endif |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
78 |
29236 | 79 call dist#man#GetPage('', sect, page) |
80 endfunc | |
81 | |
82 func s:GetCmdArg(sect, page) | |
83 if empty(a:sect) | |
84 return shellescape(a:page) | |
85 endif | |
86 | |
87 return s:man_sect_arg . ' ' . shellescape(a:sect) . ' ' . shellescape(a:page) | |
88 endfunc | |
89 | |
90 func s:FindPage(sect, page) | |
91 let l:cmd = printf('man %s %s', s:man_find_arg, s:GetCmdArg(a:sect, a:page)) | |
92 call system(l:cmd) | |
93 | |
94 if v:shell_error | |
95 return 0 | |
96 endif | |
97 | |
98 return 1 | |
99 endfunc | |
100 | |
101 func dist#man#GetPage(cmdmods, ...) | |
102 if a:0 >= 2 | |
103 let sect = a:1 | |
104 let page = a:2 | |
105 elseif a:0 >= 1 | |
106 let sect = "" | |
107 let page = a:1 | |
108 else | |
109 return | |
110 endif | |
111 | |
32837
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
112 " To support: nmap K :Man <cWORD><CR> |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
113 if page ==? '<cword>' |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
114 let what = s:ParseIntoPageAndSection() |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
115 let sect = what.section |
050794aa4ef2
man.vim: Recognise hyphenated-at-eol cross-references (#12609)
Christian Brabandt <cb@256bit.org>
parents:
32836
diff
changeset
|
116 let page = what.page |
29236 | 117 endif |
118 | |
119 if !exists('g:ft_man_no_sect_fallback') || (g:ft_man_no_sect_fallback == 0) | |
120 if sect != "" && s:FindPage(sect, page) == 0 | |
121 let sect = "" | |
122 endif | |
123 endif | |
124 if s:FindPage(sect, page) == 0 | |
125 let msg = 'man.vim: no manual entry for "' . page . '"' | |
126 if !empty(sect) | |
127 let msg .= ' in section ' . sect | |
128 endif | |
129 echomsg msg | |
130 return | |
131 endif | |
132 exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%") | |
133 exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".") | |
134 exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".") | |
135 let s:man_tag_depth = s:man_tag_depth + 1 | |
136 | |
137 let open_cmd = 'edit' | |
138 | |
139 " Use an existing "man" window if it exists, otherwise open a new one. | |
140 if &filetype != "man" | |
141 let thiswin = winnr() | |
142 exe "norm! \<C-W>b" | |
143 if winnr() > 1 | |
144 exe "norm! " . thiswin . "\<C-W>w" | |
145 while 1 | |
146 if &filetype == "man" | |
147 break | |
148 endif | |
149 exe "norm! \<C-W>w" | |
150 if thiswin == winnr() | |
151 break | |
152 endif | |
153 endwhile | |
154 endif | |
155 if &filetype != "man" | |
156 if exists("g:ft_man_open_mode") | |
157 if g:ft_man_open_mode == 'vert' | |
158 let open_cmd = 'vsplit' | |
159 elseif g:ft_man_open_mode == 'tab' | |
160 let open_cmd = 'tabedit' | |
161 else | |
162 let open_cmd = 'split' | |
163 endif | |
164 else | |
165 let open_cmd = a:cmdmods . ' split' | |
166 endif | |
167 endif | |
168 endif | |
169 | |
170 silent execute open_cmd . " $HOME/" . page . '.' . sect . '~' | |
171 | |
172 " Avoid warning for editing the dummy file twice | |
173 setl buftype=nofile noswapfile | |
174 | |
175 setl fdc=0 ma nofen nonu nornu | |
176 %delete _ | |
177 let unsetwidth = 0 | |
178 if empty($MANWIDTH) | |
179 let $MANWIDTH = winwidth(0) | |
180 let unsetwidth = 1 | |
181 endif | |
182 | |
183 " Ensure Vim is not recursively invoked (man-db does this) when doing ctrl-[ | |
184 " on a man page reference by unsetting MANPAGER. | |
185 " Some versions of env(1) do not support the '-u' option, and in such case | |
186 " we set MANPAGER=cat. | |
187 if !exists('s:env_has_u') | |
188 call system('env -u x true') | |
189 let s:env_has_u = (v:shell_error == 0) | |
190 endif | |
191 let env_cmd = s:env_has_u ? 'env -u MANPAGER' : 'env MANPAGER=cat' | |
192 let env_cmd .= ' GROFF_NO_SGR=1' | |
193 let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b' | |
194 silent exec "r !" . man_cmd | |
195 | |
196 if unsetwidth | |
197 let $MANWIDTH = '' | |
198 endif | |
199 " Remove blank lines from top and bottom. | |
200 while line('$') > 1 && getline(1) =~ '^\s*$' | |
201 1delete _ | |
202 endwhile | |
203 while line('$') > 1 && getline('$') =~ '^\s*$' | |
204 $delete _ | |
205 endwhile | |
206 1 | |
207 setl ft=man nomod | |
208 setl bufhidden=hide | |
209 setl nobuflisted | |
210 setl noma | |
211 endfunc | |
212 | |
213 func dist#man#PopPage() | |
214 if s:man_tag_depth > 0 | |
215 let s:man_tag_depth = s:man_tag_depth - 1 | |
216 exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth | |
217 exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth | |
218 exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth | |
32836
f0854888250f
man.vim: Uniformly place cursor at the same column with `Ctrl-t` (#12608)
Christian Brabandt <cb@256bit.org>
parents:
29236
diff
changeset
|
219 |
29236 | 220 exec s:man_tag_buf."b" |
32836
f0854888250f
man.vim: Uniformly place cursor at the same column with `Ctrl-t` (#12608)
Christian Brabandt <cb@256bit.org>
parents:
29236
diff
changeset
|
221 call cursor(s:man_tag_lin, s:man_tag_col) |
f0854888250f
man.vim: Uniformly place cursor at the same column with `Ctrl-t` (#12608)
Christian Brabandt <cb@256bit.org>
parents:
29236
diff
changeset
|
222 |
29236 | 223 exec "unlet s:man_tag_buf_".s:man_tag_depth |
224 exec "unlet s:man_tag_lin_".s:man_tag_depth | |
225 exec "unlet s:man_tag_col_".s:man_tag_depth | |
226 unlet s:man_tag_buf s:man_tag_lin s:man_tag_col | |
227 endif | |
228 endfunc | |
229 | |
230 let &cpo = s:cpo_save | |
231 unlet s:cpo_save | |
232 | |
233 " vim: set sw=2 ts=8 noet: |