Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1 | " Vim script to work like "less" |
Christian Brabandt | e978b45 | 2023-08-13 10:33:05 +0200 | [diff] [blame] | 2 | " Maintainer: The Vim Project <https://github.com/vim/vim> |
Christian Brabandt | 79230f0 | 2024-02-15 22:14:01 +0100 | [diff] [blame] | 3 | " Last Change: 2024 Feb 15 |
Christian Brabandt | e978b45 | 2023-08-13 10:33:05 +0200 | [diff] [blame] | 4 | " Former Maintainer: Bram Moolenaar <Bram@vim.org> |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 5 | |
| 6 | " Avoid loading this file twice, allow the user to define his own script. |
| 7 | if exists("loaded_less") |
| 8 | finish |
| 9 | endif |
| 10 | let loaded_less = 1 |
| 11 | |
| 12 | " If not reading from stdin, skip files that can't be read. |
| 13 | " Exit if there is no file at all. |
| 14 | if argc() > 0 |
| 15 | let s:i = 0 |
| 16 | while 1 |
| 17 | if filereadable(argv(s:i)) |
| 18 | if s:i != 0 |
| 19 | sleep 3 |
| 20 | endif |
| 21 | break |
| 22 | endif |
| 23 | if isdirectory(argv(s:i)) |
| 24 | echomsg "Skipping directory " . argv(s:i) |
| 25 | elseif getftime(argv(s:i)) < 0 |
| 26 | echomsg "Skipping non-existing file " . argv(s:i) |
| 27 | else |
| 28 | echomsg "Skipping unreadable file " . argv(s:i) |
| 29 | endif |
| 30 | echo "\n" |
| 31 | let s:i = s:i + 1 |
| 32 | if s:i == argc() |
| 33 | quit |
| 34 | endif |
| 35 | next |
| 36 | endwhile |
| 37 | endif |
| 38 | |
Bram Moolenaar | 4072ba5 | 2020-12-23 13:56:35 +0100 | [diff] [blame] | 39 | " we don't want 'compatible' here |
| 40 | if &cp |
| 41 | set nocp |
| 42 | endif |
| 43 | |
| 44 | " enable syntax highlighting if not done already |
| 45 | if !get(g:, 'syntax_on', 0) |
| 46 | syntax enable |
| 47 | endif |
| 48 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 49 | set so=0 |
| 50 | set hlsearch |
| 51 | set incsearch |
| 52 | nohlsearch |
| 53 | " Don't remember file names and positions |
| 54 | set viminfo= |
| 55 | set nows |
| 56 | " Inhibit screen updates while searching |
| 57 | let s:lz = &lz |
| 58 | set lz |
| 59 | |
Bram Moolenaar | e392eb4 | 2015-11-19 20:38:09 +0100 | [diff] [blame] | 60 | " Allow the user to define a function, which can set options specifically for |
| 61 | " this script. |
| 62 | if exists('*LessInitFunc') |
| 63 | call LessInitFunc() |
| 64 | endif |
| 65 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 66 | " Used after each command: put cursor at end and display position |
| 67 | if &wrap |
| 68 | noremap <SID>L L0:redraw<CR>:file<CR> |
| 69 | au VimEnter * normal! L0 |
| 70 | else |
| 71 | noremap <SID>L Lg0:redraw<CR>:file<CR> |
| 72 | au VimEnter * normal! Lg0 |
| 73 | endif |
| 74 | |
| 75 | " When reading from stdin don't consider the file modified. |
| 76 | au VimEnter * set nomod |
| 77 | |
Bram Moolenaar | 388a5d4 | 2020-05-26 21:20:45 +0200 | [diff] [blame] | 78 | " Can't modify the text or write the file. |
| 79 | set nomodifiable readonly |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 80 | |
| 81 | " Give help |
| 82 | noremap h :call <SID>Help()<CR> |
| 83 | map H h |
| 84 | fun! s:Help() |
| 85 | echo "<Space> One page forward b One page backward" |
| 86 | echo "d Half a page forward u Half a page backward" |
| 87 | echo "<Enter> One line forward k One line backward" |
| 88 | echo "G End of file g Start of file" |
| 89 | echo "N% percentage in file" |
| 90 | echo "\n" |
| 91 | echo "/pattern Search for pattern ?pattern Search backward for pattern" |
| 92 | echo "n next pattern match N Previous pattern match" |
Bram Moolenaar | cd5c8f8 | 2017-04-09 20:11:58 +0200 | [diff] [blame] | 93 | if &foldmethod != "manual" |
| 94 | echo "\n" |
| 95 | echo "zR open all folds zm increase fold level" |
| 96 | endif |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 97 | echo "\n" |
| 98 | echo ":n<Enter> Next file :p<Enter> Previous file" |
| 99 | echo "\n" |
| 100 | echo "q Quit v Edit file" |
| 101 | let i = input("Hit Enter to continue") |
| 102 | endfun |
| 103 | |
| 104 | " Scroll one page forward |
| 105 | noremap <script> <Space> :call <SID>NextPage()<CR><SID>L |
| 106 | map <C-V> <Space> |
| 107 | map f <Space> |
| 108 | map <C-F> <Space> |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 109 | map <PageDown> <Space> |
| 110 | map <kPageDown> <Space> |
| 111 | map <S-Down> <Space> |
Bram Moolenaar | cd5c8f8 | 2017-04-09 20:11:58 +0200 | [diff] [blame] | 112 | " If 'foldmethod' was changed keep the "z" commands, e.g. "zR" to open all |
| 113 | " folds. |
| 114 | if &foldmethod == "manual" |
| 115 | map z <Space> |
| 116 | endif |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 117 | map <Esc><Space> <Space> |
| 118 | fun! s:NextPage() |
| 119 | if line(".") == line("$") |
| 120 | if argidx() + 1 >= argc() |
Bram Moolenaar | 1aeaf8c | 2012-05-18 13:46:39 +0200 | [diff] [blame] | 121 | " Don't quit at the end of the last file |
| 122 | return |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 123 | endif |
| 124 | next |
| 125 | 1 |
| 126 | else |
| 127 | exe "normal! \<C-F>" |
| 128 | endif |
| 129 | endfun |
| 130 | |
| 131 | " Re-read file and page forward "tail -f" |
| 132 | map F :e<CR>G<SID>L:sleep 1<CR>F |
| 133 | |
| 134 | " Scroll half a page forward |
| 135 | noremap <script> d <C-D><SID>L |
| 136 | map <C-D> d |
| 137 | |
| 138 | " Scroll one line forward |
| 139 | noremap <script> <CR> <C-E><SID>L |
| 140 | map <C-N> <CR> |
| 141 | map e <CR> |
| 142 | map <C-E> <CR> |
| 143 | map j <CR> |
| 144 | map <C-J> <CR> |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 145 | map <Down> <CR> |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 146 | |
| 147 | " Scroll one page backward |
| 148 | noremap <script> b <C-B><SID>L |
| 149 | map <C-B> b |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 150 | map <PageUp> b |
| 151 | map <kPageUp> b |
| 152 | map <S-Up> b |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 153 | map w b |
| 154 | map <Esc>v b |
| 155 | |
| 156 | " Scroll half a page backward |
| 157 | noremap <script> u <C-U><SID>L |
| 158 | noremap <script> <C-U> <C-U><SID>L |
| 159 | |
| 160 | " Scroll one line backward |
| 161 | noremap <script> k <C-Y><SID>L |
| 162 | map y k |
| 163 | map <C-Y> k |
| 164 | map <C-P> k |
| 165 | map <C-K> k |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 166 | map <Up> k |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 167 | |
| 168 | " Redraw |
| 169 | noremap <script> r <C-L><SID>L |
| 170 | noremap <script> <C-R> <C-L><SID>L |
| 171 | noremap <script> R <C-L><SID>L |
| 172 | |
| 173 | " Start of file |
| 174 | noremap <script> g gg<SID>L |
| 175 | map < g |
| 176 | map <Esc>< g |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 177 | map <Home> g |
| 178 | map <kHome> g |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 179 | |
| 180 | " End of file |
| 181 | noremap <script> G G<SID>L |
| 182 | map > G |
| 183 | map <Esc>> G |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 184 | map <End> G |
| 185 | map <kEnd> G |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 186 | |
| 187 | " Go to percentage |
| 188 | noremap <script> % %<SID>L |
| 189 | map p % |
| 190 | |
| 191 | " Search |
| 192 | noremap <script> / H$:call <SID>Forward()<CR>/ |
| 193 | if &wrap |
| 194 | noremap <script> ? H0:call <SID>Backward()<CR>? |
| 195 | else |
| 196 | noremap <script> ? Hg0:call <SID>Backward()<CR>? |
| 197 | endif |
| 198 | |
| 199 | fun! s:Forward() |
| 200 | " Searching forward |
| 201 | noremap <script> n H$nzt<SID>L |
| 202 | if &wrap |
| 203 | noremap <script> N H0Nzt<SID>L |
| 204 | else |
| 205 | noremap <script> N Hg0Nzt<SID>L |
| 206 | endif |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 207 | cnoremap <silent> <script> <CR> <CR>:cunmap <lt>CR><CR>zt<SID>L |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 208 | endfun |
| 209 | |
| 210 | fun! s:Backward() |
| 211 | " Searching backward |
| 212 | if &wrap |
| 213 | noremap <script> n H0nzt<SID>L |
| 214 | else |
| 215 | noremap <script> n Hg0nzt<SID>L |
| 216 | endif |
| 217 | noremap <script> N H$Nzt<SID>L |
Bram Moolenaar | c81e5e7 | 2007-05-05 18:24:42 +0000 | [diff] [blame] | 218 | cnoremap <silent> <script> <CR> <CR>:cunmap <lt>CR><CR>zt<SID>L |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 219 | endfun |
| 220 | |
| 221 | call s:Forward() |
Bram Moolenaar | e968e36 | 2014-05-13 20:23:24 +0200 | [diff] [blame] | 222 | cunmap <CR> |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 223 | |
| 224 | " Quitting |
| 225 | noremap q :q<CR> |
| 226 | |
| 227 | " Switch to editing (switch off less mode) |
| 228 | map v :silent call <SID>End()<CR> |
| 229 | fun! s:End() |
Christian Brabandt | 103f1df | 2024-02-15 21:44:05 +0100 | [diff] [blame] | 230 | set modifiable noreadonly |
Bram Moolenaar | 1423b9d | 2006-05-07 15:16:06 +0000 | [diff] [blame] | 231 | if exists('s:lz') |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 232 | let &lz = s:lz |
| 233 | endif |
Christian Brabandt | 103f1df | 2024-02-15 21:44:05 +0100 | [diff] [blame] | 234 | if !empty(maparg('h')) |
| 235 | unmap h |
| 236 | endif |
| 237 | if !empty(maparg('H')) |
| 238 | unmap H |
| 239 | endif |
| 240 | if !empty(maparg('<Space>')) |
| 241 | unmap <Space> |
| 242 | endif |
| 243 | if !empty(maparg('<C-V>')) |
| 244 | unmap <C-V> |
| 245 | endif |
| 246 | if !empty(maparg('f')) |
| 247 | unmap f |
| 248 | endif |
| 249 | if !empty(maparg('<C-F>')) |
| 250 | unmap <C-F> |
| 251 | endif |
| 252 | if !empty(maparg('z')) |
| 253 | unmap z |
| 254 | endif |
| 255 | if !empty(maparg('<Esc><Space>')) |
| 256 | unmap <Esc><Space> |
| 257 | endif |
| 258 | if !empty(maparg('F')) |
| 259 | unmap F |
| 260 | endif |
| 261 | if !empty(maparg('d')) |
| 262 | unmap d |
| 263 | endif |
| 264 | if !empty(maparg('<C-D>')) |
| 265 | unmap <C-D> |
| 266 | endif |
| 267 | if !empty(maparg('<CR>')) |
| 268 | unmap <CR> |
| 269 | endif |
| 270 | if !empty(maparg('<C-N>')) |
| 271 | unmap <C-N> |
| 272 | endif |
| 273 | if !empty(maparg('e')) |
| 274 | unmap e |
| 275 | endif |
| 276 | if !empty(maparg('<C-E>')) |
| 277 | unmap <C-E> |
| 278 | endif |
| 279 | if !empty(maparg('j')) |
| 280 | unmap j |
| 281 | endif |
| 282 | if !empty(maparg('<C-J>')) |
| 283 | unmap <C-J> |
| 284 | endif |
| 285 | if !empty(maparg('b')) |
| 286 | unmap b |
| 287 | endif |
| 288 | if !empty(maparg('<C-B>')) |
| 289 | unmap <C-B> |
| 290 | endif |
| 291 | if !empty(maparg('w')) |
| 292 | unmap w |
| 293 | endif |
| 294 | if !empty(maparg('<Esc>v')) |
| 295 | unmap <Esc>v |
| 296 | endif |
| 297 | if !empty(maparg('u')) |
| 298 | unmap u |
| 299 | endif |
| 300 | if !empty(maparg('<C-U>')) |
| 301 | unmap <C-U> |
| 302 | endif |
| 303 | if !empty(maparg('k')) |
| 304 | unmap k |
| 305 | endif |
| 306 | if !empty(maparg('y')) |
| 307 | unmap y |
| 308 | endif |
| 309 | if !empty(maparg('<C-Y>')) |
| 310 | unmap <C-Y> |
| 311 | endif |
| 312 | if !empty(maparg('<C-P>')) |
| 313 | unmap <C-P> |
| 314 | endif |
| 315 | if !empty(maparg('<C-K>')) |
| 316 | unmap <C-K> |
| 317 | endif |
| 318 | if !empty(maparg('r')) |
| 319 | unmap r |
| 320 | endif |
| 321 | if !empty(maparg('<C-R>')) |
| 322 | unmap <C-R> |
| 323 | endif |
| 324 | if !empty(maparg('R')) |
| 325 | unmap R |
| 326 | endif |
| 327 | if !empty(maparg('g')) |
| 328 | unmap g |
| 329 | endif |
| 330 | if !empty(maparg('<')) |
| 331 | unmap < |
| 332 | endif |
| 333 | if !empty(maparg('<Esc><')) |
| 334 | unmap <Esc>< |
| 335 | endif |
| 336 | if !empty(maparg('G')) |
| 337 | unmap G |
| 338 | endif |
| 339 | if !empty(maparg('>')) |
| 340 | unmap > |
| 341 | endif |
| 342 | if !empty(maparg('<Esc>>')) |
| 343 | unmap <Esc>> |
| 344 | endif |
| 345 | if !empty(maparg('%')) |
| 346 | unmap % |
| 347 | endif |
| 348 | if !empty(maparg('p')) |
| 349 | unmap p |
| 350 | endif |
| 351 | if !empty(maparg('n')) |
| 352 | unmap n |
| 353 | endif |
| 354 | if !empty(maparg('N')) |
| 355 | unmap N |
| 356 | endif |
| 357 | if !empty(maparg('q')) |
| 358 | unmap q |
| 359 | endif |
| 360 | if !empty(maparg('v')) |
| 361 | unmap v |
| 362 | endif |
| 363 | if !empty(maparg('/')) |
| 364 | unmap / |
| 365 | endif |
| 366 | if !empty(maparg('?')) |
| 367 | unmap ? |
| 368 | endif |
| 369 | if !empty(maparg('<Up>')) |
| 370 | unmap <Up> |
| 371 | endif |
| 372 | if !empty(maparg('<Down>')) |
| 373 | unmap <Down> |
| 374 | endif |
| 375 | if !empty(maparg('<PageDown>')) |
| 376 | unmap <PageDown> |
| 377 | endif |
| 378 | if !empty(maparg('<kPageDown>')) |
| 379 | unmap <kPageDown> |
| 380 | endif |
| 381 | if !empty(maparg('<PageUp>')) |
| 382 | unmap <PageUp> |
| 383 | endif |
| 384 | if !empty(maparg('<kPageUp>')) |
| 385 | unmap <kPageUp> |
| 386 | endif |
| 387 | if !empty(maparg('<S-Down>')) |
| 388 | unmap <S-Down> |
| 389 | endif |
| 390 | if !empty(maparg('<S-Up>')) |
| 391 | unmap <S-Up> |
| 392 | endif |
| 393 | if !empty(maparg('<Home>')) |
| 394 | unmap <Home> |
| 395 | endif |
| 396 | if !empty(maparg('<kHome>')) |
| 397 | unmap <kHome> |
| 398 | endif |
| 399 | if !empty(maparg('<End>')) |
| 400 | unmap <End> |
| 401 | endif |
| 402 | if !empty(maparg('<kEnd>')) |
| 403 | unmap <kEnd> |
| 404 | endif |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 405 | endfun |
| 406 | |
| 407 | " vim: sw=2 |