1 " Copyright (c) 2024 Julian Mendoza
      2 "
      3 " MIT License
      4 "
      5 " Permission is hereby granted, free of charge, to any person obtaining a copy
      6 " of this software and associated documentation files (the "Software"), to deal
      7 " in the Software without restriction, including without limitation the rights
      8 " to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9 " copies of the Software, and to permit persons to whom the Software is
     10 " furnished to do so, subject to the following conditions:
     11 "
     12 " The above copyright notice and this permission notice shall be included in all
     13 " copies or substantial portions of the Software.
     14 "
     15 " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     18 " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20 " OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21 " SOFTWARE.
     22 
     23 ""
     24 " jmend's vimrc!
     25 "
     26 " Self Link: jmend.io/vimrc
     27 "
     28 " Installing Required Plugins:
     29 "   1. Install vim-plug: https://github.com/junegunn/vim-plug
     30 "   2. Run :PlugInstall
     31 "   3. Restart vim
     32 "
     33 " Self-Documentation:
     34 "   :Wtf commands ~ Show commands set in this vimrc
     35 "   :Wtf mappings ~ Show mappings set in this vimrc
     36 "   :Wtf <tab>    ~ Show other documentation available
     37 "                   (Mostly misc. stuff I find useful to remember)
     38 
     39 " Required here for vim9+
     40 set nocompatible
     41 
     42 " Command Prefix:
     43 "   <leader>      : used for global mappings
     44 "   <localleader> : used for buffer-local mappings
     45 let mapleader = '\'
     46 let maplocalleader = '\'
     47 
+  -    48 +-- 39 lines: System Dependencies:
  48 " System Dependencies: {{{
|    49 let g:jm_vimrc = {}
|    50 
|    51 " Will store documentation
|    52 " Accessible with the :Wtf command
|    53 let g:jm_vimrc.docs = {}
|    54 
|    55 " Map from defined commands to description
|    56 " See :Wtf commands
|    57 let g:jm_vimrc.docs.commands = {}
|    58 
|    59 " Map from defined mappings to description
|    60 " See :Wtf mappings
|    61 let g:jm_vimrc.docs.mappings = {}
|    62 
|    63 " A variety of dependencies on the system
|    64 let g:jm_vimrc.deps = #{
|    65       \   jshell: 'jshell',
|    66       \   curl:   'curl',
|    67       \   blaze:  'blaze',
|    68       \   javap:  'javap',
|    69       \   ag:     'ag',
|    70       \   fish:   'fish',
|    71       \   python: 'python3',
|    72       \ }
|    73 
|    74 " Whether this computer is a mac
|    75 let g:jm_vimrc.is_mac = system('uname -s') =~# 'Darwin'
|    76 
|    77 " Whether python is supported
|    78 let g:jm_vimrc.has_python = has('python3')
|    79 
|    80 " Some system dependencies
|    81 let g:jm_vimrc.deps.JavaClassnameList      = {-> systemlist('fish -c "classpath list-all-classes"')}
|    82 let g:jm_vimrc.deps.ClasspathJarList       = {-> systemlist('fish -c "jars list"')}
|    83 "let g:jm_vimrc.deps.google_java_executable = 'google-java-format --skip-javadoc-formatting'
|    84 let g:jm_vimrc.deps.google_java_executable = 'google-java-format'
|    85 let g:jm_vimrc.deps.buildozer   = 'fish -c buildozer'
|    86 " }}}
     87 
+  -    88 +-- 24 lines: Playground:
  88 " Playground: {{{
|    89 let s:pg_items = (g:jm_vimrc.is_mac)
|    90       \ ? #{
|    91       \     co: 'Files ~/Playground',
|    92       \     cj: 'Files ~/Playground/jdk/src/java.base/share/classes',
|    93       \     pg: 'Files ~/Playground',
|    94       \     n:  'Files ~/Playground/jmendio/n',
|    95       \     v:  'edit ~/.vimrc',
|    96       \   }
|    97       \ : #{
|    98       \     a:  'Files ~/code/abseil-cpp/absl',
|    99       \     co: 'Files ~/code',
|   100       \     cg: 'Files ~/code/guava/guava/src',
|   101       \     cj: 'Files ~/code/jdk/src/java.base/share/classes',
|   102       \     cv: 'Files ~/code/opencv/modules/core',
|   103       \     cp: 'Files ~/code/pandas',
|   104       \     n:  'Files ~/jmendio/n',
|   105       \     v:  'edit ~/.vimrc',
|   106       \   }
|   107 for [key, path] in items(s:pg_items)
|   108   execute printf('nnoremap <leader>e%s :%s<cr>', key, path)
|   109   let g:jm_vimrc.docs.mappings['\e' .. key] = 'Run :' .. path
|   110 endfor
|   111 " }}} Playground
    112 
+  -   113 +-- 85 lines: Plugins (vim-plug):
 113 " Plugins (vim-plug): {{{
|   114 call plug#begin('~/.vim/bundle')
|   115 
|   116 "" Plugins:
|   117 Plug 'morhetz/gruvbox'
|   118 Plug 'tpope/vim-surround'
|   119 Plug 'scrooloose/nerdtree'
|   120 Plug 'godlygeek/tabular'
|   121 if g:jm_vimrc.has_python
|   122   Plug 'SirVer/ultisnips'
|   123   Plug 'Valloric/YouCompleteMe'
|   124 endif
|   125 Plug 'honza/vim-snippets'
|   126 Plug 'junegunn/fzf', {'do': {-> fzf#install()}}
|   127 Plug 'junegunn/fzf.vim'
|   128 Plug 'junegunn/vim-easy-align'
|   129 Plug 'tpope/vim-fugitive'
|   130 Plug 'moll/vim-bbye'
|   131 Plug 'scrooloose/nerdcommenter' " \c<Space> \cc
|   132 Plug 'jiangmiao/auto-pairs'
|   133 Plug 'tpope/vim-repeat'
|   134 Plug 'triglav/vim-visual-increment'
|   135 Plug 'tmhedberg/SimpylFold'
|   136 Plug 'majutsushi/tagbar'
|   137 Plug 'pangloss/vim-javascript'
|   138 Plug 'nelstrom/vim-markdown-folding'
|   139 Plug 'justinmk/vim-syntax-extra'
|   140 Plug 'jpalardy/vim-slime'
|   141 Plug 'itchyny/lightline.vim'
|   142 Plug 'ap/vim-buftabline'
|   143 Plug 'airblade/vim-gitgutter'
|   144 Plug 'google/vim-maktaba'
|   145 Plug 'google/vim-codefmt'
|   146 Plug 'google/vim-glaive'
|   147 Plug 'frazrepo/vim-rainbow'
|   148 Plug 'AndrewRadev/splitjoin.vim' " gS gJ
|   149 Plug 'shiracamus/vim-syntax-x86-objdump-d'
|   150 Plug 'romainl/vim-devdocs'
|   151 if isdirectory('$OCAML_OCP_INDENT')
|   152   Plug $OCAML_OCP_INDENT
|   153 endif
|   154 if exists("$BASIS")
|   155   Plug $BASIS, { 'rtp': 'vim' }
|   156 else
|   157   Plug 'jmend736/basis', { 'rtp': 'vim' }
|   158 endif
|   159 
|   160 "" Old Plugins:
|   161 " Plug 'vim-scripts/DrawIt'
|   162 " Plug 'cohama/lexima.vim'
|   163 " Plug 'mattn/emmet-vim'
|   164 " Plug 'sheerun/vim-polyglot'
|   165 " Plug 'fatih/vim-go'
|   166 " Plug 'davidhalter/jedi-vim'
|   167 " Plug 'ervandew/supertab'
|   168 " Plug 'w0rp/ale'
|   169 " Plug 'neoclide/coc.nvim', {'branch': 'release'}
|   170 " http://eclim.org
|   171 " Plug 'bazelbuild/vim-ft-bzl'
|   172 " -> https://github.com/bazelbuild/vim-ft-bzl/commit/941fb142f604c254029c2a0852ea7578f08de91a
|   173 
|   174 "" Plugins to check out:
|   175 " Plug 'liuchengxu/vista.vim'
|   176 " Plug 'natebosch/vim-lsc'
|   177 " Plug 'chrisbra/NrrwRgn'
|   178 " Plug 'justinmk/vim-sneak'
|   179 " Plug 'romainl/vim-qf'
|   180 " Plug 'romainl/vim-qlist'
|   181 " Plug 'mbbill/undotree'
|   182 " Plug 'wellle/targets.vim'
|   183 call plug#end()
|   184 
|   185 if !exists('g:loaded_plug')
|   186   echoerr "ERROR: vim-plug is REQUIRED https://github.com/junegunn/vim-plug"
|   187   finish
|   188 endif
|   189 
|   190 
|   191 call glaive#Install()
|   192 
|   193 Glaive codefmt
|   194       \ google_java_executable=`g:jm_vimrc.deps.google_java_executable`
|   195       \ clang_format_style='Google'
|   196 
|   197 " }}} Plugins (Vundle)
    198 
+  -   199 +-- 92 lines: General Options:
 199 " General Options: {{{
|   200 filetype plugin indent on
|   201 
|   202 set t_Co=256        " Number of colors
|   203 set t_ut=           " Use current background color for clearing
|   204 
|   205 set scrolloff=0     " Minimal number of screen lines to keep above/below cursor
|   206 
|   207 set shell=/bin/bash " Sets the shell to use
|   208 
|   209 set hidden          " Whether to allow modified buffers to be hidden
|   210 
|   211 set tabstop=2       " Number of spaces that a read <Tab> counts for
|   212 set softtabstop=2   " Number of spaces an inserted <Tab> counts for
|   213 set shiftwidth=2    " Sets what >> and << ops do
|   214 set expandtab       " Replace tabs with spaces when editing
|   215 set smarttab        " More reasonable tab actions
|   216 
|   217 set autoindent      " Copy indent from current line when starting a new line
|   218 set smartindent     " Adds indents after {, or 'cinwords'
|   219 
|   220                     " Reasonable backspace functionality
|   221 set backspace=indent,eol,start
|   222 
|   223 set list            " Replace certain characters visually
|   224 set listchars=tab:\>\ ,trail:·,extends:,precedes:|   225 
|   226 set number           " Show line number at cursor,
|   227 set numberwidth=4    " with a column width of 3,
|   228 set relativenumber   " and numbers relative to cursor elsewhere
|   229 set noruler          " Show line/col number (hidden by lightline)
|   230 set showcmd          " Show currently entered command below status
|   231                      " Define status line (hidden by lightline)
|   232 set statusline=%f\ %=L:%l/%L\ %c\ (%p%%)
|   233 
|   234 set wildmenu         " Tab completion for : command
|   235 set wildmode=longest,list,full
|   236 
|   237 set hlsearch         " Highlight search results
|   238 set incsearch        " Highlight while searching
|   239 set foldopen-=search " Whether to open folds when searching
|   240                      " Also see :ToggleFoldOpenSearch
|   241 
|   242 " Ignore case, unless you use uppercase characters
|   243 set ignorecase
|   244 set smartcase
|   245 
|   246 " Other
|   247 set fileencodings=utf-8
|   248 set tags=tags
|   249 set tags+=/usr/include/**/tags
|   250 set printoptions=number:y,duplex:long,paper:letter
|   251 if g:jm_vimrc.is_mac
|   252   set clipboard=unnamed
|   253 else
|   254   set clipboard=unnamedplus
|   255 endif
|   256 set errorbells
|   257 set laststatus=2
|   258 set cursorline
|   259 set sessionoptions=
|   260       \blank,
|   261       \curdir,
|   262       \folds,
|   263       \help,
|   264       \localoptions,
|   265       \options,
|   266       \tabpages,
|   267       \winsize,
|   268       \terminal
|   269 
|   270 set directory=~/.swaps//
|   271 
|   272 " Some mathematical digraphs
|   273 digraphs el 8712 " Element in
|   274 digraphs in 8712 " Element in
|   275 digraphs ni 8713 " element not in
|   276 digraphs es 8709 " Empty Set
|   277 digraphs ss 8834 " Subset
|   278 digraphs se 8838 " Subset equals
|   279 digraphs ns 8836 " Not subset
|   280 digraphs nS 8840 " Not subset equals
|   281 digraphs nn 8745 " Intersection
|   282 digraphs uu 8746 " Union
|   283 digraphs un 8746 " Union
|   284 digraphs co 8728 " Composition
|   285 
|   286 " Themes
|   287 colorscheme gruvbox
|   288 syntax enable
|   289 set bg=dark
|   290 " }}} General Settings
    291 
+  -   292 +-- 67 lines: Plugin Settings:
 292 " Plugin Settings: {{{
|   293 
|   294 let g:lightline = {
|   295       \   'active': {
|   296       \     'left': [['mode', 'paste'], ['filename', 'modified']],
|   297       \     'right': [['winlayout', 'winid_bufnr', 'lineinfo'], ['percent', 'foldlevel'], ['readonly']]
|   298       \   },
|   299       \   'inactive': {
|   300       \     'left': [['filename', 'modified']],
|   301       \     'right': [['winlayout', 'winid_bufnr', 'lineinfo'], ['readonly']]
|   302       \   },
|   303       \   'component_type': {
|   304       \     'readonly': 'error',
|   305       \   },
|   306       \   'component': {
|   307       \     'winid_bufnr': '[%{winnr()}/%{win_getid()}(%{Layout()[win_getid()]})]{%{bufnr()}}',
|   308       \     'foldlevel': '%{(&foldenable) ? &foldlevel : "-"}f',
|   309       \   },
|   310       \ }
|   311 
|   312 let $FZF_DEFAULT_COMMAND = 'ag -l'
|   313 
|   314 "let g:lsc_server_commands = {}
|   315 "let g:lsc_enable_autocomplete = v:true
|   316 "let g:lsc_auto_map = v:true
|   317 
|   318 let g:ycm_auto_trigger = 1
|   319 let g:ycm_disable_signature_help = 1
|   320 let g:ycm_key_list_select_completion = ['<C-n>', '<Down>']
|   321 let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
|   322 
|   323 let g:slime_target = "tmux"
|   324 
|   325 " Will disable indent-based markdown code blocks
|   326 let g:bss_markdown_fix = 1
|   327 
|   328 let g:bss_java_fix = 1
|   329 
|   330 let g:vim_markdown_new_list_item_indent = 0
|   331 let g:vim_markdown_folding_disabled = 1
|   332 let g:markdown_fold_style = 'nested'
|   333 
|   334 let g:NERDCompactSexyComs = v:true
|   335 let g:NERDCommentEmptyLines = v:true
|   336 let g:NERDDefaultAlign = 'left'
|   337 
|   338 let g:tagbar_sort = v:false
|   339 
|   340 " Use ordinal numbers (2) rather than bufnum (1)
|   341 let g:buftabline_numbers = 2
|   342 let g:buftabline_indicators = v:true
|   343 let g:buftabline_separators = v:false
|   344 
|   345 let g:netre_liststyle=3
|   346 
|   347 let g:tex_flavor='latex'
|   348 
|   349 let g:UltiSnipsExpandTrigger="<tab>"
|   350 let g:UltiSnipsJumpForwardTrigger="<c-j>"
|   351 let g:UltiSnipsJumpBackwardTrigger="<c-z>"
|   352 let g:UltiSnipsEditSplit="vertical"
|   353 
|   354 let g:gitgutter_sign_added = '··'
|   355 let g:gitgutter_sign_modified = '··'
|   356 let g:gitgutter_sign_removed = '·'
|   357 let g:gitgutter_sign_modified_removed = '·'
|   358 " }}} Plugin Settings
    359 
+  -   360 +--133 lines: Keymappings:
 360 " Keymappings: {{{
|   361 "   To understand keys see :h key-notation
|   362 
|   363 " Moves around a line more closely to what is expected (at least by me) when
|   364 " the line is wrapped.
|   365 "nnoremap j gj
|   366 "nnoremap k gk
|   367 "vnoremap j gj
|   368 "vnoremap k gk
|   369 
|   370 " Moving around between windows quickly
|   371 let g:jm_vimrc.docs.mappings['<C-[hjkl]>'] =
|   372       \ 'Move between windows by holding CTRL'
|   373 noremap <C-j> <C-W>j
|   374 noremap <C-k> <C-W>k
|   375 noremap <C-h> <C-W>h
|   376 noremap <C-l> <C-W>l
|   377 
|   378 let g:jm_vimrc.docs.mappings['<C-[←↑↓→]>'] =
|   379       \ 'Move visual selection'
|   380 vnoremap <C-Up> koko
|   381 vnoremap <C-Down> jojo
|   382 vnoremap <C-Left> hoho
|   383 vnoremap <C-Right> lolo
|   384 
|   385 let g:jm_vimrc.docs.mappings['[['] =
|   386       \ 'Enable [[,][,]],[] to operate on non-col-1-{}'
|   387 " From :h object-motions
|   388 nnoremap [[ ?{<CR>w99[{
|   389 nnoremap ][ /}<CR>b99]}
|   390 nnoremap ]] j0[[%/{<CR>
|   391 nnoremap [] k$][%?}<CR>
|   392 
|   393 let g:jm_vimrc.docs.mappings['\q'] =
|   394       \ 'Delete current buffer without changing window layout'
|   395 nnoremap <leader>q :Bdelete<cr>
|   396 
|   397 let g:jm_vimrc.docs.mappings["\\'"] =
|   398       \ 'Open NERDTree (file explorer)'
|   399 nnoremap <leader>' :NERDTreeToggle<cr>
|   400 
|   401 let g:jm_vimrc.docs.mappings['\"'] =
|   402       \ 'Open NERDTree (file explorer) to current file'
|   403 nnoremap <leader>" :NERDTreeFind<cr>
|   404 
|   405 let g:jm_vimrc.docs.mappings['\<Tab>'] =
|   406       \ 'Open Tagbar'
|   407 nnoremap <leader><tab> :TagbarToggle<cr>
|   408 
|   409 let g:jm_vimrc.docs.mappings['<F10>'] =
|   410       \ 'Toggle paste'
|   411 set pastetoggle=<F10>
|   412 
|   413 let g:jm_vimrc.docs.mappings['<F9>'] =
|   414       \ 'Toggle virtualedit=all'
|   415 nnoremap <F9> :let &ve = <C-r>=empty(&ve) ? '"all"' : '""'<cr><cr>
|   416 
|   417 let g:jm_vimrc.docs.mappings['<C-r><C-f>'] =
|   418       \ '[modes:ic] Insert file name root'
|   419 inoremap <C-r><C-f> <C-r>=expand('%:p:t:r')<cr>
|   420 cnoremap <C-r><C-f> <C-r>=expand('%:p:t:r')<cr>
|   421 
|   422 let g:jm_vimrc.docs.mappings['<C-r><C-t>'] =
|   423       \ '[modes:ic] Insert file name root'
|   424 inoremap <C-r><C-t> <C-r>=bss#blaze#BlazeTarget()<cr>
|   425 cnoremap <C-r><C-t> <C-r>=bss#blaze#BlazeTarget()<cr>
|   426 
|   427 let g:jm_vimrc.docs.mappings['<C-p>'] =
|   428       \ 'Fuzzy-search PWD'
|   429 nnoremap <C-p> :Files<cr>
|   430 
|   431 let g:jm_vimrc.docs.mappings['\w'] =
|   432       \ 'Clear search highlights (:nohlsearch)'
|   433 nnoremap <silent> <leader>w :nohlsearch<Bar>:echo<cr>
|   434 
|   435 let g:jm_vimrc.docs.mappings['<F11>'] =
|   436       \ 'Ensure non-syntax toplevel text is spell-checked'
|   437 noremap <F11> :syntax spell toplevel<cr>
|   438 let g:jm_vimrc.docs.mappings['<F12>'] =
|   439       \ 'Toggle spell checking'
|   440 noremap <F12> :setlocal spell! spelllang=en_us<cr>
|   441 
|   442 let g:jm_vimrc.docs.mappings['<Space>l'] =
|   443       \ 'Open Git ("Change [L]ist")'
|   444 nnoremap <leader>l :Git<cr>
|   445 
|   446 let g:jm_vimrc.docs.mappings['<C-w><C-z>'] =
|   447       \ 'Set window height to 10 and fix the height'
|   448 nnoremap <C-w><C-z> :FixHeight 10<cr>
|   449 nnoremap <C-w>z :FixHeight 10<cr>
|   450 
|   451 let g:jm_vimrc.docs.mappings['K'] =
|   452       \ 'Do grep for word under cursor'
|   453 nnoremap K :grep! "\b<C-R><C-W>\b"<CR>:cw<CR>
|   454 
|   455 let g:jm_vimrc.docs.mappings['\\'] =
|   456       \ 'Show :tags'
|   457 nnoremap <leader><leader> :tags<cr>
|   458 
|   459 let g:jm_vimrc.docs.mappings['\s'] =
|   460       \ 'Refresh UltSnips snippets'
|   461 nnoremap <leader>s :call UltiSnips#RefreshSnippets()<cr>
|   462 
|   463 let g:jm_vimrc.docs.mappings['\<Space>'] =
|   464       \ 'Toggle foldcolumn'
|   465 nnoremap <leader><space> :let &l:foldcolumn = (&l:foldcolumn) ? 0 : 3<cr>
|   466 
|   467 let g:jm_vimrc.docs.mappings['\a'] =
|   468       \ 'Trigger EasyAlign (See :Wtf ea)'
|   469 xmap <leader>a <Plug>(EasyAlign)
|   470 nmap <leader>a <Plug>(EasyAlign)
|   471 
|   472 let g:jm_vimrc.docs.mappings["C-W !"] =
|   473       \ 'Toggle buflisted'
|   474 nnoremap <C-W>l :set buflisted!<cr>
|   475 
|   476 let g:jm_vimrc.docs.mappings['\a[:(]'] =
|   477       \ 'Extra/overriden EasyAlign items'
|   478 let g:easy_align_delimiters = bss#extra#EasyAlignDelimiters()
|   479 
|   480 let g:jm_vimrc.docs.mappings['\[0-9]'] =
|   481       \ 'Switch to buffer (from buftabline)'
|   482 nmap <leader>1 <Plug>BufTabLine.Go(1)
|   483 nmap <leader>2 <Plug>BufTabLine.Go(2)
|   484 nmap <leader>3 <Plug>BufTabLine.Go(3)
|   485 nmap <leader>4 <Plug>BufTabLine.Go(4)
|   486 nmap <leader>5 <Plug>BufTabLine.Go(5)
|   487 nmap <leader>6 <Plug>BufTabLine.Go(6)
|   488 nmap <leader>7 <Plug>BufTabLine.Go(7)
|   489 nmap <leader>8 <Plug>BufTabLine.Go(8)
|   490 nmap <leader>9 <Plug>BufTabLine.Go(9)
|   491 nmap <leader>0 <Plug>BufTabLine.Go(10)
|   492 " }}} Keymappings
    493 
+  -   494 +--155 lines: Commands:
 494 " Commands: {{{
|   495 " Note -bar allows these to be followed by | to chain commands (ie. for autocmds)
|   496 
|   497 " Command :Term ~ Nicer :term API
|   498 " :Term ~ Runs 'shell'
|   499 " :Term [command]... ~ Runs the command in 'shell'
|   500 "
|   501 " This command will reuse the last window, unless it's no longer being used
|   502 " for the terminal buffer. Also, this hides the buffer, in case you leave a
|   503 " terminal window running and don't want to accidentally get stuck in it.
|   504 if !exists('g:jm_term')
|   505   let g:jm_term = bss#view#TermView()
|   506 endif
|   507 let g:jm_vimrc.docs.commands['Term'] =
|   508       \ 'Run a terminal command in a reused window'
|   509 command! -nargs=* -complete=shellcmd Term
|   510       \ eval g:jm_term.Run(<q-args>)
|   511 
|   512 let g:jm_vimrc.docs.commands['ReplaceR'] =
|   513       \ 'Locally set \r to run :Term with the specified command'
|   514 command! -nargs=+ ReplaceR
|   515       \ nnoremap <buffer> <localleader>r :Term <args><cr>
|   516 
|   517 let g:jm_vimrc.docs.commands['ReplaceRTarget'] =
|   518       \ 'Set \r to bazel target of the current file'
|   519 command! -bar ReplaceRTarget
|   520       \ execute 'ReplaceR' BlazeGuessCommand()
|   521 
|   522 let g:jm_vimrc.docs.commands['StopAllJobs'] =
|   523       \ 'Stop all running jobs'
|   524 command! -bar StopAllJobs eval job_info()->map('job_stop(v:val)')
|   525 
|   526 let g:jm_vimrc.docs.commands['SetupClasspath'] =
|   527       \ 'Set classpath to jm_vimrc.deps.ClasspathJarList()'
|   528 command! -bar SetupClasspath
|   529       \ let $CLASSPATH = join(g:jm_vimrc.deps.ClasspathJarList(), ':')
|   530 
|   531 let g:jm_vimrc.docs.commands['SetupTargetClasspath'] =
|   532       \ 'Set classpath to blaze target included jars'
|   533 command! -bar SetupTargetClasspath
|   534       \ let $CLASSPATH = s:TargetClasspath()
|   535 
|   536 let g:jm_vimrc.docs.commands['SetupCV'] =
|   537       \ 'Setup $LDFLAGS, $CFLAGS and &path for OpenCV development'
|   538 command! -bar SetupCV
|   539       \ let $LDFLAGS = '-lopencv_core -lopencv_imgcodecs -lopencv_imgproc' |
|   540       \ let $CFLAGS = '-I/usr/include/opencv4' |
|   541       \ let &path ..= ',/usr/include/opencv4,/usr/include/c++/10/'
|   542 
|   543 let g:jm_vimrc.docs.commands['FixHeight'] =
|   544       \ 'Resize window and fix its height'
|   545 command! -nargs=1 FixHeight
|   546       \ resize <args> | set winfixheight
|   547 
|   548 let g:jm_vimrc.docs.commands['SetupTermRainbow'] =
|   549       \ 'Add Rainbow-coloring to terminals'
|   550 command! -bar SetupTermRainbow
|   551       \ autocmd TerminalOpen * RainbowLoad
|   552 
|   553 let g:jm_vimrc.docs.commands['SetupAutoread'] =
|   554       \ 'Enable autoread and add checktime autocmd'
|   555 command! -bar SetupAutoread
|   556       \ set autoread | autocmd FocusGained,BufEnter * checktime
|   557 
|   558 let g:jm_vimrc.docs.commands['RemoveTrailingWhitespace'] =
|   559       \ 'Removes all trailing whitespace from the selected lines'
|   560 command! -range=% RemoveTrailingWhitespace
|   561       \ <line1>,<line2>s/\s\+$//
|   562 
|   563 let g:jm_vimrc.docs.commands['SetupMatchHex'] =
|   564       \ 'Match hex numbers'
|   565 command! -bar SetupMatchHex
|   566       \ match GruvboxAqua /\<0x0*\zs[1-9a-f]\x*\>/
|   567 
|   568 let g:jm_vimrc.docs.commands['SetupMatchNum'] =
|   569       \ 'Match decimal numbers'
|   570 command! -bar SetupMatchNum
|   571       \ match GruvboxAqua /\<\(0x\)\?0*\zs[1-9a-f]\x*\>/
|   572 
|   573 let g:jm_vimrc.docs.commands['Dis'] =
|   574       \ 'Setup terminal for viewing objdump output ($ objdump -d ... | vim +Dis -)'
|   575 command! -bar Dis
|   576       \ setlocal ft=dis buftype=nofile
|   577 
|   578 let g:jm_vimrc.docs.commands['ToggleFoldOpenSearch'] =
|   579       \ 'Toggle search on foldopen option'
|   580 command! ToggleFoldOpenSearch
|   581       \ if stridx(&foldopen, "search") == -1 |
|   582       \   set foldopen+=search |
|   583       \   echo "ENABLED foldopen search" |
|   584       \ else |
|   585       \   set foldopen-=search |
|   586       \   echo "DISABLED foldopen search" |
|   587       \ endif
|   588 
|   589 let g:jm_vimrc.docs.commands['SetupMath'] =
|   590       \ 'Set up abbreviations for math symbols'
|   591 command! SetupMath
|   592       \ execute 'iabbrev nn ∩' |
|   593       \ execute 'iabbrev uu ∪' |
|   594       \ execute 'iabbrev in ∈' |
|   595       \ execute 'iabbrev ni ∉' |
|   596       \ execute 'iabbrev ss ⊂' |
|   597       \ execute 'iabbrev se ⊆' |
|   598       \ execute 'iabbrev ns ⊄' |
|   599       \ execute 'iabbrev AN ∧' |
|   600       \ execute 'iabbrev OR ∨' |
|   601       \ execute 'iabbrev es ∅' |
|   602       \ execute 'iabbrev => ⇒' |
|   603       \ execute 'iabbrev == ⇔' |
|   604       \ execute 'iabbrev != ≠' |
|   605       \ execute 'iabbrev co ∘' |
|   606       \ execute 'iabbrev FA ∀' |
|   607       \ execute 'iabbrev TE ∃'
|   608 
|   609 let g:jm_vimrc.docs.commands['PyHelp'] =
|   610       \ 'Look-up help for python expression (: PyHelp <pkg> <cls>)'
|   611 command! -nargs=+ -bang PyHelp
|   612       \ call py3eval((<bang>0) ? printf('help(%s)', <q-args>) : printf('help(__import__("%s").%s)', <f-args>))
|   613 
|   614 let g:jm_vimrc.docs.commands['MakeOrSetup'] =
|   615       \ 'Run blaze, make, or create a Makefile with included commands (using ; as separator)'
|   616 command! -nargs=+ MakeOrSetup call s:MakeOrSetup(<q-args>)
|   617 function! s:MakeOrSetup(cmds) abort
|   618   if filereadable('WORKSPACE')
|   619     execute 'Term blaze build' BlazeTarget()
|   620   elseif filereadable('Makefile')
|   621     Term make
|   622   else
|   623     let l:cmds = substitute(a:cmds, '%', expand('%'), 'g')
|   624     let l:lines = split(l:cmds, ';')->map('trim(v:val)')
|   625     let l:cursor = bss#cursor#SaveWithBuf()
|   626     try
|   627       redir > Makefile
|   628       silent echo '.PHONY: all'
|   629       silent echo 'all:'
|   630       for l:cmd in l:lines
|   631         silent echo ' ' .. l:cmd
|   632       endfor
|   633       redir END
|   634       silent edit Makefile
|   635       Term make
|   636     finally
|   637       call l:cursor.Restore()
|   638     endtry
|   639   endif
|   640 endfunction
|   641 
|   642 " The Silver Searcher
|   643 if executable('ag')
|   644     " Use ag over grep
|   645     set grepprg=ag\ --nogroup\ --nocolor\ --ignore=tags\ --vimgrep
|   646     set grepformat^=%f:%l:%c:%m
|   647 endif
|   648 " }}} Commands
    649 
+  -   650 +--230 lines: FT-Specific Settings:
 650 " FT-Specific Settings: {{{
|   651 
|   652 " Autocommands are split into filetype `augroup`s, each is separated by
|   653 " filetype. This solves the problem of sourcing the vimrc multiple times
|   654 " causing multiple duplicated autocommands to be set. An augroup is only run
|   655 " once**.
|   656 "
|   657 " These keymappings depend on the filetype, when :filetype on is enabled (as
|   658 " it is earlier in this config), when vim first loads a buffer, it will
|   659 " automatically detect the filetype and set the 'filetype' option (buffer)
|   660 " locally. After this happens, any `FileType` type autocommands are triggered
|   661 "
|   662 " NOTES:
|   663 " ** An augroup doesn't provide this functionality by itself. When you
|   664 " redefine it, it will 'add onto' the original one, in order to clear one, you
|   665 " can add `autocommand!` or `au!` to it (or another with the same name). This
|   666 " is used to make sure that only one version of the autocommand hooks is set
|   667 " per buffer.
|   668 augroup ft_latex
|   669     autocmd!
|   670     autocmd FileType tex setlocal nocursorline
|   671     autocmd FileType tex setlocal tabstop=4 shiftwidth=4
|   672     autocmd FileType tex nnoremap <buffer> <localleader>r
|   673           \ :execute 'Term fish -c "mkt ' .. expand('%') .. '"'<cr>
|   674 augroup END
|   675 
|   676 augroup ft_c
|   677     autocmd!
|   678     autocmd FileType c setlocal tabstop=2 shiftwidth=2
|   679     autocmd FileType c setlocal foldmethod=syntax
|   680     autocmd FileType c nnoremap <buffer> <localleader>r
|   681           \ :Term make<CR>
|   682     autocmd FileType c nnoremap <buffer> <localleader>R
|   683           \ :MakeOrSetup gcc -Wall -O3 -o a.out %; ./a.out; rm a.out<cr>
|   684 augroup END
|   685 
|   686 
|   687 augroup ft_cc
|   688     autocmd!
|   689     autocmd FileType cpp setlocal tabstop=2 shiftwidth=2
|   690     autocmd FileType cpp setlocal foldmethod=syntax
|   691     autocmd FileType cpp nnoremap <buffer> <localleader>t
|   692           \ :term <C-r>=BlazeGuessCommand()<CR>
|   693     autocmd FileType cpp nnoremap <buffer> <localleader>r
|   694           \ :MakeOrSetup
|   695           \   clang++-12 -std=c++17 $(CFLAGS) -o build % $(LDFLAGS);
|   696           \   ./build<CR>
|   697     autocmd FileType cpp nnoremap <buffer> <space>f
|   698           \ :FormatCode<CR>
|   699     autocmd FileType cpp
|   700           \ if exists('g:jm_setup_cpp_cv') |
|   701           \   SetupCV |
|   702           \ endif
|   703     autocmd FileType cpp
|   704           \ if expand('%:p') =~ '/home/jmend/pg' |
|   705           \   silent ReplaceRTarget |
|   706           \ endif
|   707 augroup END
|   708 
|   709 augroup ft_gdb
|   710     autocmd!
|   711     autocmd FileType gdb nnoremap <buffer> <localleader>r
|   712           \ :execute 'Term gdb -q -x' expand('%')<cr>
|   713 augroup END
|   714 
|   715 augroup ft_python
|   716     autocmd!
|   717     autocmd FileType python command! RunPython
|   718           \ execute "Term" g:jm_vimrc.deps.python expand('%')
|   719     autocmd FileType python command! RunPythonTests
|   720           \ execute "Term" g:jm_vimrc.deps.python "-m pytest" expand('%')
|   721     autocmd FileType python command! RunPythonTypechecks
|   722           \ execute "Term" g:jm_vimrc.deps.python "-m mypy --ignore-missing-imports --follow-imports=skip " expand("%")
|   723     autocmd FileType python command! RunPythonMPL
|   724           \ StopAllJobs | eval timer_start(0, {-> execute('RunPython')})
|   725     autocmd FileType python nnoremap <buffer> <localleader>r
|   726           \ :RunPython<cr>
|   727     autocmd FileType python nnoremap <buffer> <localleader>R
|   728           \ :RunPythonTests<cr>
|   729     autocmd FileType python nnoremap <buffer> <localleader>t
|   730           \ :RunPythonTypechecks<cr>
|   731     autocmd FileType python nnoremap <buffer> <space>f
|   732           \ :FormatCode<CR>
|   733 augroup END
|   734 
|   735 augroup ft_scheme
|   736     autocmd!
|   737     autocmd FileType scheme setlocal colorcolumn=79
|   738     autocmd FileType scheme let g:lisp_rainbow = v:true
|   739     autocmd FileType scheme nnoremap <buffer> <localleader>r
|   740           \ :w<CR> :Term mit-scheme --load % <CR>
|   741 augroup END
|   742 
|   743 augroup ft_java
|   744     autocmd!
|   745     autocmd FileType java
|   746           \ setlocal tabstop=2 softtabstop=2 tabstop=2 smarttab
|   747     autocmd FileType java nnoremap <space>f :FormatCode<cr>
|   748     autocmd FileType java vnoremap <space>f :FormatLines<cr>
|   749     if filereadable('Makefile')
|   750       autocmd FileType java nnoremap <silent> <buffer> <localleader>r
|   751             \ :Term make<cr>
|   752     elseif filereadable('WORKSPACE')
|   753       autocmd FileType java nnoremap <silent> <buffer> <localleader>r
|   754             \ :execute "Term blaze run " .. join(<SID>BlazeTargets(expand("%")), " ")<cr>
|   755     elseif filereadable('gradlew')
|   756       autocmd FileType java nnoremap <silent> <buffer> <localleader>r
|   757             \ :Term ./gradlew test -i --rerun<cr>
|   758     endif
|   759     autocmd FileType java nnoremap <silent> <buffer> <localleader>R
|   760           \ :Term ./gradlew run<cr>
|   761     autocmd FileType java let b:surround_99 = "{@code \r}"
|   762 augroup END
|   763 
|   764 augroup ft_jar
|   765   autocmd!
|   766   autocmd FileType jar
|   767         \ call zip#Browse(expand("<amatch>"))
|   768 augroup END
|   769 
|   770 augroup ft_class
|   771   autocmd!
|   772   autocmd BufReadCmd *.class
|   773         \ call bss#java#javap#Browse(expand("<amatch>"))
|   774 augroup END
|   775 
|   776 
|   777 
|   778 augroup ft_javascript
|   779     autocmd!
|   780     autocmd FileType javascript
|   781           \ setlocal tabstop=2 softtabstop=2 tabstop=2 smarttab
|   782     autocmd FileType javascript nnoremap <buffer> <localleader>r
|   783           \ :execute "Term node " .. expand('%')<cr>
|   784     autocmd FileType javascript nnoremap <buffer> <localleader>R
|   785           \ :Term webpack<CR>
|   786     autocmd FileType javascript nnoremap <buffer> <space>f
|   787           \ :FormatCode<CR>
|   788 augroup END
|   789 
|   790 augroup ft_markdown
|   791     autocmd!
|   792     autocmd FileType markdown set textwidth=72 smartindent autoindent
|   793     autocmd FileType markdown set cinwords+=:
|   794 
|   795     autocmd FileType markdown nnoremap <buffer> ]h :<c-u>call search('\v^#+ ', 'Wz')<cr>
|   796     autocmd FileType markdown nnoremap <buffer> [h :<c-u>call search('\v^#+ ', 'bWz')<cr>
|   797     "autocmd FileType markdown nnoremap <buffer> <leader>r
|   798                 "\ :Term pandoc %:p -s --highlight-style kate --pdf-engine=xelatex -o gen/%:t:r.pdf<cr>
|   799 
|   800     autocmd FileType markdown command! SetupR nnoremap <buffer> <localleader>r
|   801           \ :call execute(printf(
|   802           \     "Term pandoc %s -s --highlight-style kate --pdf-engine=xelatex -o %s.pdf",
|   803           \     expand('%:p'),
|   804           \     expand('%:t:r'),
|   805           \   ))<cr>
|   806 
|   807     autocmd FileType markdown command! JmMdQuotesAsComments match GruvboxFg3 /^\s*>.*/
|   808 
|   809     if !exists('g:bss_markdown_fix') || !g:bss_markdown_fix
|   810       " Disable indent-based code blocks, this enables arbitrarily deep
|   811       " indentation of lists
|   812       autocmd FileType markdown syntax clear markdownCodeBlock
|   813       autocmd FileType markdown syntax region markdownCodeBlock matchgroup=markdownCodeDelimiter start="^\s*\z(`\{3,\}\).*$" end="^\s*\z1\ze\s*$" keepend
|   814       autocmd FileType markdown syntax region markdownCodeBlock matchgroup=markdownCodeDelimiter start="^\s*\z(\~\{3,\}\).*$" end="^\s*\z1\ze\s*$" keepend
|   815 
|   816       " Fix up the colors
|   817       autocmd FileType markdown highlight link markdownH1 GruvboxRedBold
|   818       autocmd FileType markdown highlight link markdownH2 GruvboxBlueBold
|   819       autocmd FileType markdown highlight link markdownH3 GruvboxGreenBold
|   820       autocmd FileType markdown highlight link markdownH4 GruvboxPurpleBold
|   821 
|   822       " Ensure bold/italics are highlighted
|   823       autocmd FileType markdown highlight link markdownBold GruvboxFg4
|   824       autocmd FileType markdown highlight link markdownBoldDelimiter GruvboxFg4
|   825       autocmd FileType markdown highlight link markdownItalic GruvboxFg2
|   826       autocmd FileType markdown highlight link markdownItalicDelimiter GruvboxFg2
|   827     endif
|   828 augroup END
|   829 
|   830 augroup ft_vim
|   831     autocmd!
|   832     autocmd FileType vim setlocal foldmethod=marker shiftwidth=2
|   833     autocmd FileType vim nnoremap <buffer> <localleader>r
|   834           \ :source %<cr>
|   835     autocmd FileType vim nnoremap K :help <C-r><C-w><CR>
|   836 augroup END
|   837 
|   838 augroup ft_fish
|   839     autocmd!
|   840     autocmd FileType fish setlocal tabstop=4 shiftwidth=4 smartindent
|   841     autocmd FileType fish nnoremap <buffer> <space>f
|   842           \ :0,$!fish_indent<cr>
|   843     autocmd FileType fish setlocal omnifunc=bss#fish#Complete
|   844 augroup END
|   845 
|   846 augroup ft_make
|   847     autocmd!
|   848     autocmd FileType make nnoremap <buffer> <localleader>r
|   849           \ :Term make<cr>
|   850 augroup END
|   851 
|   852 augroup ft_ocaml
|   853     autocmd!
|   854     autocmd FileType ocaml
|   855           \ setlocal tabstop=2 softtabstop=2 tabstop=2 smarttab
|   856     autocmd FileType ocaml nnoremap <space>f :FormatCode<cr>
|   857     autocmd FileType ocaml vnoremap <space>f :FormatLines<cr>
|   858     if filereadable('Makefile')
|   859       autocmd FileType ocaml nnoremap <silent> <buffer> <localleader>r
|   860             \ :Term make<cr>
|   861     elseif filereadable('dune-project')
|   862       autocmd FileType ocaml nnoremap <silent> <buffer> <localleader>r
|   863             \ :Term dune build<cr>
|   864     else
|   865       autocmd FileType ocaml nnoremap <silent> <buffer> <localleader>r
|   866             \ :execute 'Term ocaml' expand("%")<cr>
|   867     endif
|   868     if isdirectory('/usr/bin/ocaml')
|   869       autocmd FileType ocaml set path+=/usr/lib/ocaml
|   870     endif
|   871 augroup END
|   872 
|   873 " Use quickfix window when using :make
|   874 augroup cfg_quickfix_fix
|   875     autocmd QuickFixCmdPost [^l]* nested cwindow
|   876     autocmd QuickFixCmdPost    l* nested lwindow
|   877 augroup end
|   878 
|   879 " }}} FT-Specific Settings
    880 
+  -   881 +--521 lines: Misc:
 881 " Misc: {{{
|   882 
|   883 " :FindImport {Classname}
|   884 "   Attempt to find and a Java import statement for the {Classname}
|   885 "     1. Try the `g:jm_vimrc.java_import_cache`
|   886 "     2. Search the CWD using `ag` for an `import .*\.{ClassName};`
|   887 "     3. Finally, search `g:jm_vimrc.deps.JavaClassnameList()`
|   888 "   Alternatively, for C++ do only:
|   889 "     1. Try the `g:jm_vimrc.cc_import_cache`
|+ |-  890 +--- 90 lines:
 890 " {{{
||  891 let g:jm_vimrc.docs.commands['FindImport'] =
||  892       \ 'Given a name, find the corresponding import and add an import statment'
||  893 nnoremap <space>t :call <SID>FindImport(expand('<cword>'))<CR>
||  894 command -nargs=1 FindImport call <SID>FindImport(<q-args>)
||  895 function! s:FindImport(word) abort
||  896 
||  897   if &filetype ==# 'cpp'
||  898     let l:res = g:jm_vimrc.cc_import_cache
||  899           \->copy()
||  900           \->filter({incl, names -> index(names, a:word) != -1})
||  901           \->keys()
||  902           \->map({k, incl -> printf("#include %s", incl)})
||  903     if len(l:res) == 0
||  904       echo "FindImport: `" .. a:word .. "` not found!"
||  905     elseif len(l:res) > 1
||  906       call maktaba#ui#selector#Create(l:res)
||  907             \.WithMappings({'<cr>': [function("s:AddImportCpp")->get("name"), 'Close', 'Add import']})
||  908             \.Show()
||  909     else
||  910       call s:AddImportCpp(l:res[0])
||  911     endif
||  912     return
||  913   endif
||  914 
||  915   if &filetype !=# 'java'
||  916     throw 'ERROR(InvalidFiletype)'
||  917     return
||  918   endif
||  919 
||  920   " First try the g:jm_vimrc.java_import_cache
||  921   if (has_key(g:jm_vimrc.java_import_cache, a:word))
||  922     call s:AddImport(printf('import %s;', get(g:jm_vimrc.java_import_cache, a:word)))
||  923     return
||  924   endif
||  925 
||  926   " Next find an import statement in the current directory
||  927   let l:results = printf(
||  928           \ '%s --nofilename --nobreak %s',
||  929           \ g:jm_vimrc.deps.ag,
||  930           \ shellescape(printf('import .+\b%s\b;', a:word)))
||  931           \->systemlist()
||  932           \->sort()
||  933           \->uniq()
||  934 
||  935   " Finally, fallback to classname list
||  936   if empty(l:results)
||  937     let l:results = g:jm_vimrc.deps.JavaClassnameList()
||  938           \->filter('v:val =~# a:word')
||  939           \->map('"import " .. v:val .. ";"')
||  940   endif
||  941 
||  942   if len(l:results) == 1
||  943     call s:AddImport(l:results[0])
||  944   elseif len(l:results) > 1
||  945     call maktaba#ui#selector#Create(l:results)
||  946           \.WithMappings({'<cr>': [function("s:AddImport")->get("name"), 'Close', 'Add import']})
||  947           \.Show()
||  948   endif
||  949 endfunction
||  950 
||  951 function! s:AddImport(import) abort
||  952     let l:result = search(a:import, 'nw')
||  953     if l:result == 0
||  954       let l:start = search('^import', 'nw')
||  955       if l:start == 0
||  956         let l:start = search('^package', 'nw')
||  957         call append(l:start, [""])
||  958         let l:start += 1
||  959       endif
||  960       call append(l:start, [a:import])
||  961       "execute '1,1FormatLines'
||  962       echom "Adding: " .. a:import
||  963     else
||  964       echom "Already Present: " .. a:import
||  965     endif
||  966 endfunction
||  967 
||  968 function! s:AddImportCpp(import) abort
||  969     let l:result = search(a:import, 'nw')
||  970     if l:result == 0
||  971       let l:start = search('^#include', 'nw')
||  972       call append(l:start, [a:import])
||  973       "execute '1,1FormatLines'
||  974       echom "Adding: " .. a:import
||  975     else
||  976       echom "Already Present: " .. a:import
||  977     endif
||  978 endfunction
||  979 " }}}
|   980 
|   981 " :Javap {qualified-classname}
|   982 "   Run `javap` against the provided classname
|+ |-  983 +--- 40 lines:
 983 " {{{
||  984 let g:jm_vimrc.docs.commands['Javap'] =
||  985       \ 'Execute Javap and show output with highlighting'
||  986 command! -nargs=? -complete=customlist,<SID>JavapComplete -bang
||  987         \ Javap call <SID>Javap(<q-args>, "<bang>" ==# '!')
||  988 function! s:Javap(arg, search) abort
||  989   if empty($CLASSPATH)
||  990     SetupClasspath
||  991   endif
||  992 
||  993   " Note: Vim Syntax highlighting doesn't like `\->substitute(...)`
||  994   let l:cls = empty(a:arg) ? @" : a:arg
||  995   let l:cls = substitute(l:cls, '\(;\|<.\+>\)', '', 'ga')
||  996 
||  997   if a:search
||  998     let l:results = s:JavapComplete(l:cls, v:none, v:none)
||  999     if len(l:results) == 1
|| 1000       let l:cls = l:results[0]
|| 1001     else
|| 1002       call maktaba#ui#selector#Create(l:results)
|| 1003             \.WithMappings({'<cr>': [function("s:JavapOpen")->get("name"), 'Close', 'Open window']})
|| 1004             \.Show()
|| 1005       return
|| 1006     endif
|| 1007   endif
|| 1008 
|| 1009   eval g:jm_term
|| 1010         \.Run(join([g:jm_vimrc.deps.javap, l:cls], ' '))
|| 1011         \.Exec('set ft=java')
|| 1012 endfunction
|| 1013 
|| 1014 function! s:JavapComplete(arg_lead, cmd_line, cursor_pos) abort
|| 1015   return g:jm_vimrc.deps.JavaClassnameList()
|| 1016         \->filter('v:val =~# a:arg_lead')
|| 1017 endfunction
|| 1018 
|| 1019 function! s:JavapOpen(cls) abort
|| 1020   execute 'Javap ' .. a:cls
|| 1021 endfunction
|| 1022 " }}}
|  1023 
|  1024 " :MavenSearch {query}
|  1025 " :M {query}
|  1026 "   Run a maven query, and show results in a selector window
|+ |- 1027 +--- 62 lines:
1027 " {{{
|| 1028 let g:jm_vimrc.docs.commands['MavenSearch'] =
|| 1029       \ 'Search maven, then either add a dependecy or download the jar'
|| 1030 command! -nargs=1 MavenSearch call <SID>MavenSearch(<q-args>)
|| 1031 command! -nargs=1 M MavenSearch <args>
|| 1032 function! s:MavenSearch(query) abort
|| 1033   const l:query_url = printf(
|| 1034         \ 'https://search.maven.org/solrsearch/select?q=%s&rows=10&wt=json',
|| 1035         \ a:query)
|| 1036 
|| 1037   const l:query_cmd = join([
|| 1038         \   g:jm_vimrc.deps.curl,
|| 1039         \   '-s',
|| 1040         \   printf('"%s"', l:query_url),
|| 1041         \ ])
|| 1042 
|| 1043   let l:msg = system(l:query_cmd)
|| 1044   let l:resp = json_decode(l:msg).response
|| 1045 
|| 1046   if l:resp.numFound == 0
|| 1047     echom "None found!"
|| 1048     return
|| 1049   endif
|| 1050   let l:docs = l:resp.docs
|| 1051   const l:mappings = {
|| 1052         \   '<cr>': [function("s:MInsert")->get("name"), 'Close', 'Insert below'],
|| 1053         \   'D': [function("s:MDownload")->get("name"), 'Close', 'Insert below'],
|| 1054         \ }
|| 1055   call maktaba#ui#selector#Create(map(l:docs, 'v:val.id .. ":" ..  v:val.latestVersion'))
|| 1056         \.WithMappings(l:mappings)
|| 1057         \.Show()
|| 1058 endfunction
|| 1059 
|| 1060 function! s:MInsert(msg) abort
|| 1061   let l:spaces = getline('.')->matchstr('^\s*')
|| 1062   call append(line('.'), printf("%simplementation '%s'", l:spaces, a:msg))
|| 1063 endfunction
|| 1064 
|| 1065 function! s:MDownload(msg) abort
|| 1066   let [l:package, l:name, l:version] = split(a:msg, ':')
|| 1067   let l:url_package = substitute(l:package, '\.', '/', 'g')
|| 1068   let l:url = printf('https://repo1.maven.org/maven2/%s/%s/%s/',
|| 1069         \  l:url_package,
|| 1070         \  l:name,
|| 1071         \  l:version)
|| 1072   let l:file = printf('%s-%s.jar', l:name, l:version)
|| 1073   let l:file_url = l:url .. l:file
|| 1074   echom l:url .. l:file
|| 1075 
|| 1076   const l:cmd = join([
|| 1077         \   g:jm_vimrc.deps.curl,
|| 1078         \   '-o',
|| 1079         \   shellescape(l:file),
|| 1080         \   '-s',
|| 1081         \   shellescape(l:file_url),
|| 1082         \ ])
|| 1083   silent call system(l:cmd)
|| 1084   if v:shell_error
|| 1085     echom 'ERROR: Could not download! ' .. l:file_url
|| 1086   endif
|| 1087 endfunction
|| 1088 " }}}
|  1089 
|  1090 " Bazel/Blaze helper functions
|  1091 "
|  1092 "   s:BlazeTargets({fname})
|  1093 "     Return the targets that depend on {fname} directly
|  1094 "
|  1095 "   BlazeTarget()
|  1096 "     Returns the first target for the current file
|  1097 "
|  1098 "   s:TargetClasspath()
|  1099 "     Returns the classpath for BlazeTarget()
|  1100 "
|  1101 "   s:CompleteTargets({arg_lead}, {cmd_line}, {cursor_pos})
|  1102 "     A -complete=customlist compatible function that simply filters the
|  1103 "     commandline against all targets
|  1104 "
|+ |- 1105 +--- 69 lines:
1105 " {{{
|| 1106 function! s:BlazeTargets(fname) abort
|| 1107   let l:query = printf(
|| 1108         \   'same_pkg_direct_rdeps(%s)',
|| 1109         \   fnamemodify(a:fname, ":p:."),
|| 1110         \ )
|| 1111 
|| 1112   let l:command = printf(
|| 1113         \   "%s query '%s'",
|| 1114         \   g:jm_vimrc.deps.blaze,
|| 1115         \   l:query,
|| 1116         \ )
|| 1117   return filter(systemlist(l:command), 'v:val =~# "^//"')
|| 1118 endfunction
|| 1119 
|| 1120 function! BlazeGuessCommand(show = v:false) abort
|| 1121   let l:fname = expand('%:p')
|| 1122 
|| 1123   let l:target = BlazeTarget()
|| 1124   if l:target ==# "???"
|| 1125     echom "Can't find blaze target!"
|| 1126     return "false"
|| 1127   endif
|| 1128 
|| 1129   let l:action = 'build'
|| 1130   if l:fname =~# '\v(_test.cc|Test.java)$' || l:target =~# '\v(_test|Test)$'
|| 1131     let l:action = 'test'
|| 1132   elseif l:fname =~# '\v(main.cc|_bin.cc|Bin.java)$' || l:target =~# '\v(_bin|Bin|main|Main)$'
|| 1133     let l:action = 'run'
|| 1134   elseif l:fname =~# '\v(_bench.cc)$' || l:target =~# '\v(_bench)$'
|| 1135     let l:action = 'run -c opt'
|| 1136   endif
|| 1137 
|| 1138   let l:command = printf(
|| 1139         \   "%s %s %s",
|| 1140         \   g:jm_vimrc.deps.blaze,
|| 1141         \   l:action,
|| 1142         \   l:target,
|| 1143         \ )
|| 1144   if a:show
|| 1145     echom 'Using:' l:command
|| 1146   endif
|| 1147   return l:command
|| 1148 endfunction
|| 1149 
|| 1150 function! BlazeTarget() abort
|| 1151   return get(s:BlazeTargets(expand('%:p')), 0, "???")
|| 1152 endfunction
|| 1153 
|| 1154 function! s:TargetClasspath() abort
|| 1155   let l:target = BlazeTarget()
|| 1156   if l:target ==# "???"
|| 1157     echom "Can't find blaze target!"
|| 1158     return ""
|| 1159   endif
|| 1160 
|| 1161   let l:lines = systemlist(printf('blaze print_action "%s"', l:target))
|| 1162   let l:jars = filter(l:lines, {_, v -> v =~# '^\s\+\(outputjar\|classpath\): "[^"]*"'})
|| 1163         \->map({_, v -> matchlist(v, '"\([^"]*\)"')[1]})
|| 1164   return join(l:jars, ':')
|| 1165 endfunction
|| 1166 
|| 1167 function! s:CompleteTargets(arg_lead, cmd_line, cursor_pos) abort
|| 1168   if a:arg_lead =~ '^//.*'
|| 1169     return systemlist(printf('%s query ... 2>&1', g:jm_vimrc.deps.blaze))
|| 1170           \->filter('v:val =~# "' .. a:arg_lead .. '"')
|| 1171   endif
|| 1172 endfunction
|| 1173 " }}}
|  1174 
|  1175 " :Touch {path}...
|  1176 "   Like `$ touch`, but also create directories if necessary
|+ |- 1177 +--- 16 lines:
1177 " {{{
|| 1178 let g:jm_vimrc.docs.commands['Touch'] =
|| 1179       \ 'Create files and directories'
|| 1180 command! -nargs=* Touch call s:Touch([<f-args>])
|| 1181 function! s:Touch(paths) abort
|| 1182   for l:path in a:paths
|| 1183     let l:dir = fnamemodify(l:path, ':h')
|| 1184     if l:dir !=# '.' && !isdirectory(l:dir)
|| 1185       call system('mkdir -p ' .. shellescape(l:dir))
|| 1186     endif
|| 1187     if !filereadable(l:path)
|| 1188       call system('touch ' .. shellescape(l:path))
|| 1189     endif
|| 1190   endfor
|| 1191 endfunction
|| 1192 " }}}
|  1193 
|  1194 " :CurrentHLGroup
|  1195 "   Print the highlight Group under cursor
|+ |- 1196 +---  8 lines:
1196 " {{{
|| 1197 let g:jm_vimrc.docs.commands['CurrentHLGroup'] =
|| 1198       \ 'Echo name of the highlight group under the cursor'
|| 1199 command! CurrentHLGroup echo s:SyntaxItem()
|| 1200 function! s:SyntaxItem()
|| 1201   return synIDattr(synID(line("."), col("."), 1), "name")
|| 1202 endfunction
|| 1203 " }}}
|  1204 
|  1205 " AsyncExec(fn)
|  1206 "   Call fn() async
|  1207 "
|  1208 " AsyncExec(...)
|  1209 "   Join string arguments and exec async
|+ |- 1210 +---  9 lines:
1210 " {{{
|| 1211 function! s:Async(Fn)
|| 1212   eval timer_start(0, a:Fn)
|| 1213 endfunction
|| 1214 
|| 1215 function! s:AsyncExec(...)
|| 1216   eval s:Async({-> execute(join(map(a:000, function('string'))))})
|| 1217 endfunction
|| 1218 " }}}
|  1219 
|  1220 " ConcealK
|  1221 "   Define conceal rules: eg. ConcealK lambda:λ
|+ |- 1222 +--- 17 lines:
1222 " {{{
|| 1223 let g:jm_vimrc.docs.commands['ConcealK'] =
|| 1224       \ 'Define conceal rules: eg. ConcealK lambda:λ'
|| 1225 command! -complete=expression -nargs=1 ConcealK call <SID>ConcealK(<q-args>)
|| 1226 function! s:ConcealK(repl_str) abort
|| 1227   let l:repl = {}
|| 1228   let l:i = 0
|| 1229   for [l:keyword, l:replacement] in split(a:repl_str, ' ')->map('v:val->split(":")')
|| 1230     let l:i += 1
|| 1231     execute 'syntax keyword'
|| 1232           \ printf('ConcealK%03d', l:i) l:keyword
|| 1233           \ 'conceal' printf('cchar=%s', l:replacement)
|| 1234   endfor
|| 1235   setlocal conceallevel=1
|| 1236   setlocal concealcursor=ni
|| 1237 endfunction
|| 1238 " }}}
|  1239 
|  1240 " ReadExecute
|  1241 "   Execute then read the output of that vim command
|+ |- 1242 +---  5 lines:
1242 " {{{
|| 1243 let g:jm_vimrc.docs.commands['ReadExecute'] =
|| 1244       \ 'Execute then read the output of that vim command'
|| 1245 command! -nargs=* -complete=command ExecuteRead eval append(line('.'), execute(<q-args>)->split("\n"))
|| 1246 " }}}
|  1247 
|  1248 " Bdz
|  1249 "   Run buildozer on current target (or :__pkg__ if none exists)
|+ |- 1250 +---  9 lines:
1250 " {{{
|| 1251 let g:jm_vimrc.docs.commands['Bdz'] =
|| 1252       \ 'Run buildozer on current target (or :__pkg__ if none exists)'
|| 1253 command! -nargs=* Bdz echom
|| 1254       \ system(printf("fish -c \"buildozer '%s' %s\"",
|| 1255       \   join([<f-args>], ' '),
|| 1256       \   BlazeTarget() != '???' ? BlazeTarget() : ':__pkg__'
|| 1257       \ ))
|| 1258 " }}}
|  1259 
|  1260 " JemFormat
|  1261 "   Format lines between "format:`cmd`" to "format: END"
|+ |- 1262 +--- 38 lines:
1262 " {{{
|| 1263 let g:jm_vimrc.docs.commands['JemFormat'] =
|| 1264       \ 'Format lines between "format:`cmd`" to "format: END"'
|| 1265 command! -nargs=* -complete=customlist,<SID>JemFormatComplete JemFormat eval s:JemFormat[<q-args>]()
|| 1266 let s:JemFormat = {
|| 1267       \   ''     : {-> s:JemFormat.format()},
|| 1268       \   'help' : {-> bss#PP(s:JemFormat, v:true)},
|| 1269       \ }
|| 1270 function! s:JemFormatComplete(arglead, cmdline, curpos) abort
|| 1271   return keys(s:JemFormat)->filter({k, v -> !stridx(v, a:arglead)})
|| 1272 endfunction
|| 1273 
|| 1274 function! s:JemFormat.format() abort dict
|| 1275   let command = self.find()
|| 1276   if !empty(command)
|| 1277     silent execute command
|| 1278   endif
|| 1279 endfunction
|| 1280 
|| 1281 function! s:JemFormat.find() abort dict
|| 1282   let [_, num, col; _] = getcurpos()
|| 1283   let start_pat   = '\v.*for' .. 'mat: `([^`]+)`.*'
|| 1284   let end_pat     = '\v.*for' .. 'mat: END.*'
|| 1285   let start_lines = matchbufline(bufnr(), start_pat, 1, num)
|| 1286   let start_line  = bss#Last(start_lines)
|| 1287   let end_line    = start_line
|| 1288         \->bss#Get('lnum')
|| 1289         \->bss#Apply({l -> matchbufline(bufnr(), end_pat, l, '$')})
|| 1290         \->bss#Apply('bss#Last')
|| 1291         \->bss#Or('$')
|| 1292   if start_line is v:none
|| 1293     return ''
|| 1294   endif
|| 1295   let range   = [start_line.lnum + 1, end_line.lnum - 1]->join(',')
|| 1296   let command = substitute(start_line.text, start_pat, '\1', '')
|| 1297   return join([range, command], ' ')
|| 1298 endfunction
|| 1299 " }}}
|  1300 
|  1301 " AppendMarkdownBlock <fname>
|  1302 "   Append the current buffer's lines to the file <fname>.
|  1303 "   Adds an empty line if the last line in <fname> is non-empty.
|  1304 "
|  1305 " SetupAppendMarkdownBlock <fname>
|  1306 "   Setup \r nmap in the current buffer
|  1307 " 
|+ |- 1308 +--- 50 lines:
1308 " {{{
|| 1309 command! -nargs=1 -complete=file SetupAppendMarkdownBlock
|| 1310       \ nnoremap <buffer> \r :AppendMarkdownBlock <args><cr>
|| 1311 command! -nargs=1 -complete=file -range=% AppendMarkdownBlock
|| 1312       \ eval AppendMarkdownBlock(<q-args>, <line1>, <line2>)
|| 1313 command! -nargs=1 -complete=file AppendMarkdownBlockDebug
|| 1314       \ eval AppendMarkdownBlock(<q-args>, 0, '$', v:true)
|| 1315 
|| 1316 function! AppendMarkdownBlock(fname, begin=0, end='$', debug=v:false) abort
|| 1317   let lines = getline(a:begin, a:end)->s:Markdown_lines2codeblock()
|| 1318   if !a:debug
|| 1319     call s:AppendMarkdownBlock_write(a:fname, lines)
|| 1320   else
|| 1321     call s:AppendMarkdownBlock_dump(a:fname, lines)
|| 1322   endif
|| 1323 endfunction
|| 1324 
|| 1325 ""
|| 1326 " Convert a list of lines to a list of codeblock lines.
|| 1327 "
|| 1328 function! s:Markdown_lines2codeblock(lines) abort
|| 1329   let prefix = '```'
|| 1330   let suffix = prefix
|| 1331   return [prefix] + a:lines + [suffix]
|| 1332 endfunction
|| 1333 
|| 1334 
|| 1335 ""
|| 1336 " Add a block to a markdown file.
|| 1337 "
|| 1338 function! s:AppendMarkdownBlock_write(fname, lines) abort
|| 1339   let prefix = (readfile(a:fname)->bss#Last()->empty())
|| 1340         \ ? [] : [""]
|| 1341   call writefile(prefix + a:lines, a:fname, 'a')
|| 1342   echom "Wrote file" a:fname
|| 1343 endfunction
|| 1344 
|| 1345 ""
|| 1346 " Dump debug information.
|| 1347 "
|| 1348 function! s:AppendMarkdownBlock_dump(fname, lines) abort
|| 1349   " Dump debug output
|| 1350   echo 'fname:' a:fname
|| 1351   echo 'lines:'
|| 1352   echo
|| 1353   for l in a:lines
|| 1354     echo '  ' .. l
|| 1355   endfor
|| 1356 endfunction
|| 1357 " }}}
|  1358 
|  1359 " SetupSlimeTarget
|  1360 "   Wrapper for setting the g:slime_target
|+ |- 1361 +--- 17 lines:
1361 " {{{
|| 1362 command! -nargs=? -complete=customlist,s:SetupSlimeTarget_Complete SetupSlimeTarget call s:SetupSlimeTarget(<q-args>)
|| 1363 let s:SlimeTargets = [
|| 1364       \   'tmux',
|| 1365       \   'vimterminal',
|| 1366       \ ]
|| 1367 function! s:SetupSlimeTarget(arg) abort
|| 1368   if empty(a:arg)
|| 1369     echom printf('Current slime target: %s', g:slime_target)
|| 1370   else
|| 1371     let g:slime_target = a:arg
|| 1372   endif
|| 1373 endfunction
|| 1374 function! s:SetupSlimeTarget_Complete(arg, ...) abort
|| 1375   return s:SlimeTargets->filter('stridx(v:val, a:arg) == 0')
|| 1376 endfunction
|| 1377 " }}}
|  1378 
|  1379 function! Layout() abort
|  1380   let layout = winlayout()
|  1381   return s:InvertLayout(layout)
|  1382 endfunction
|  1383 function! s:InvertLayout(l, path=[]) abort
|  1384   if len(a:l) != 2
|  1385     throw "ERROR(InvalidArguments): s:InvertLayout expects only 2-element lists"
|  1386   endif
|  1387   let [kind, val] = a:l
|  1388   if kind ==# 'leaf'
|  1389     return {val: join(a:path, '')}
|  1390   elseif kind ==# 'col'
|  1391     return val
|  1392           \->map('s:InvertLayout(v:val, a:path + ["|"])')
|  1393           \->reduce({a, b -> extend(a, b)})
|  1394   elseif kind ==# 'row'
|  1395     return val
|  1396           \->map('s:InvertLayout(v:val, a:path + ["-"])')
|  1397           \->reduce({a, b -> extend(a, b)})
|  1398   endif
|  1399 endfunction
|  1400 
|  1401 " }}} Misc
   1402 
+  -  1403 +--  5 lines: Notes
1403 " Notes {{{
|  1404 let s:Wtf = bss#wtf#Initialize()
|  1405 call bss#wtf#AddDict(['mappings', 'm'], g:jm_vimrc.docs.mappings)
|  1406 call bss#wtf#AddDict(['commands', 'c'], g:jm_vimrc.docs.commands)
|  1407 " }}} Notes
   1408 
   1409 " Defines the import cache used for Java import search, if an attempt to
   1410 " resolve the import for a key in this map, the value specified will be
   1411 " imported before trying any other method to find the import.
+  -  1412 +--143 lines: Java Import Cache:
1412 " Java Import Cache: {{{
|  1413 let g:jm_vimrc.java_import_cache = #{
|  1414       \   Map                        : 'java.util.Map',
|  1415       \   Set                        : 'java.util.Set',
|  1416       \   Stream                     : 'java.util.stream.Stream',
|  1417       \   Collectors                 : 'java.util.stream.Collectors',
|  1418       \   counting                   : 'static java.util.stream.Collectors.counting',
|  1419       \   averagingDouble            : 'static java.util.stream.Collectors.averagingDouble',
|  1420       \   averagingInt               : 'static java.util.stream.Collectors.averagingInt',
|  1421       \   averagingLong              : 'static java.util.stream.Collectors.averagingLong',
|  1422       \   collectingAndThen          : 'static java.util.stream.Collectors.collectingAndThen',
|  1423       \   filtering                  : 'static java.util.stream.Collectors.filtering',
|  1424       \   flatMapping                : 'static java.util.stream.Collectors.flatMapping',
|  1425       \   groupingBy                 : 'static java.util.stream.Collectors.groupingBy',
|  1426       \   joining                    : 'static java.util.stream.Collectors.joining',
|  1427       \   mapping                    : 'static java.util.stream.Collectors.mapping',
|  1428       \   maxBy                      : 'static java.util.stream.Collectors.maxBy',
|  1429       \   minBy                      : 'static java.util.stream.Collectors.minBy',
|  1430       \   partitioningBy             : 'static java.util.stream.Collectors.partitioningBy',
|  1431       \   reducing                   : 'static java.util.stream.Collectors.reducing',
|  1432       \   summarizingDouble          : 'static java.util.stream.Collectors.summarizingDouble',
|  1433       \   summarizingInt             : 'static java.util.stream.Collectors.summarizingInt',
|  1434       \   summarizingLong            : 'static java.util.stream.Collectors.summarizingLong',
|  1435       \   summingDouble              : 'static java.util.stream.Collectors.summingDouble',
|  1436       \   summingInt                 : 'static java.util.stream.Collectors.summingInt',
|  1437       \   summingLong                : 'static java.util.stream.Collectors.summingLong',
|  1438       \   toCollection               : 'static java.util.stream.Collectors.toCollection',
|  1439       \   toConcurrentMap            : 'static java.util.stream.Collectors.toConcurrentMap',
|  1440       \   toList                     : 'static java.util.stream.Collectors.toList',
|  1441       \   toMap                      : 'static java.util.stream.Collectors.toMap',
|  1442       \   toSet                      : 'static java.util.stream.Collectors.toSet',
|  1443       \   toUnmodifiableList         : 'static java.util.stream.Collectors.toUnmodifiableList',
|  1444       \   toUnmodifiableMap          : 'static java.util.stream.Collectors.toUnmodifiableMap',
|  1445       \   toUnmodifiableSet          : 'static java.util.stream.Collectors.toUnmodifiableSet',
|  1446       \   Collector                  : 'java.util.stream.Collector',
|  1447       \   List                       : 'java.util.List',
|  1448       \   ArrayList                  : 'java.util.ArrayList',
|  1449       \   LinkedList                 : 'java.util.LinkedList',
|  1450       \   Iterator                   : 'java.util.Iterator',
|  1451       \   Optional                   : 'java.util.Optional',
|  1452       \   HashSet                    : 'java.util.HashSet',
|  1453       \   HashMap                    : 'java.util.HashMap',
|  1454       \   TreeMap                    : 'java.util.TreeMap',
|  1455       \   TreeSet                    : 'java.util.TreeSet',
|  1456       \   Arrays                     : 'java.util.Arrays',
|  1457       \   Collection                 : 'java.util.Collection',
|  1458       \   OrderedMap                 : 'java.util.OrderedMap',
|  1459       \   NavigableMap               : 'java.util.NavigableMap',
|  1460       \   Consumer                   : 'java.util.function.Consumer',
|  1461       \   Predicate                  : 'java.util.function.Predicate',
|  1462       \   Function                   : 'java.util.function.Function',
|  1463       \   Supplier                   : 'java.util.function.Supplier',
|  1464       \   ImmutableList              : 'com.google.common.collect.ImmutableList',
|  1465       \   Lists                      : 'com.google.common.collect.Lists',
|  1466       \   ImmutableSet               : 'com.google.common.collect.ImmutableSet',
|  1467       \   Streams                    : 'com.google.common.collect.Streams',
|  1468       \   Table                      : 'com.google.common.collect.Table',
|  1469       \   Tables                     : 'com.google.common.collect.Tables',
|  1470       \   ImmutableTable             : 'com.google.common.collect.ImmutableTable',
|  1471       \   toImmutableList            : 'static com.google.common.collect.ImmutableList.toImmutableList',
|  1472       \   toImmutableSet             : 'static com.google.common.collect.ImmutableSet.toImmutableSet',
|  1473       \   ImmutableMap               : 'com.google.common.collect.ImmutableMap',
|  1474       \   Provider                   : 'javax.inject.Provider',
|  1475       \   Inject                     : 'javax.inject.Inject',
|  1476       \   Qualifier                  : 'javax.inject.Qualifier',
|  1477       \   Singleton                  : 'javax.inject.Singleton',
|  1478       \   Binds                      : 'dagger.Binds',
|  1479       \   Module                     : 'dagger.Module',
|  1480       \   Component                  : 'dagger.Component',
|  1481       \   Provides                   : 'dagger.Provides',
|  1482       \   Multibinds                 : 'dagger.multibindings.Multibinds',
|  1483       \   IntoSet                    : 'dagger.multibindings.IntoSet',
|  1484       \   IntoMap                    : 'dagger.multibindings.IntoMap',
|  1485       \   IntKey                     : 'dagger.multibindings.IntKey',
|  1486       \   LongKey                    : 'dagger.multibindings.LongKey',
|  1487       \   StringKey                  : 'dagger.multibindings.StringKey',
|  1488       \   ClassKey                   : 'dagger.multibindings.ClassKey',
|  1489       \   ElementsIntoSet            : 'dagger.multibindings.ElementsIntoSet',
|  1490       \   MapKey                     : 'dagger.MapKey',
|  1491       \   Path                       : 'java.nio.file.Path',
|  1492       \   Files                      : 'java.nio.file.Files',
|  1493       \   ClassReader                : 'org.objectweb.asm.ClassReader',
|  1494       \   ClassWriter                : 'org.objectweb.asm.ClassWriter',
|  1495       \   ClassVisitor               : 'org.objectweb.asm.ClassVisitor',
|  1496       \   Opcodes                    : 'org.objectweb.asm.Opcodes',
|  1497       \   FieldVisitor               : 'org.objectweb.asm.FieldVisitor',
|  1498       \   MethodVisitor              : 'org.objectweb.asm.MethodVisitor',
|  1499       \   TypePath                   : 'org.objectweb.asm.TypePath',
|  1500       \   Modifier                   : 'java.lang.reflect.Modifier',
|  1501       \   Executable                 : 'java.lang.reflect.Executable',
|  1502       \   Field                      : 'java.lang.reflect.Field',
|  1503       \   Method                     : 'java.lang.reflect.Method',
|  1504       \   Type                       : 'java.lang.reflect.Type',
|  1505       \   AnnotatedElement           : 'java.lang.reflect.AnnotatedElement',
|  1506       \   Executor                   : 'java.util.concurrent.Executor',
|  1507       \   Future                     : 'java.util.concurrent.Future',
|  1508       \   ExecutorService            : 'java.util.concurrent.ExecutorService',
|  1509       \   Executors                  : 'java.util.concurrent.Executors',
|  1510       \   TimeUnit                   : 'java.util.concurrent.TimeUnit',
|  1511       \   ThreadPoolExecutor         : 'java.util.concurrent.ThreadPoolExecutor',
|  1512       \   AtomicInteger              : 'java.util.concurrent.atomic.AtomicInteger',
|  1513       \   AtomicLong                 : 'java.util.concurrent.atomic.AtomicLong',
|  1514       \   LongAdder                  : 'java.util.concurrent.atomic.LongAdder',
|  1515       \   Stats                      : 'com.google.common.math.Stats',
|  1516       \   Stopwatch                  : 'com.google.common.base.Stopwatch',
|  1517       \   StatsAccumulator           : 'com.google.common.math.StatsAccumulator',
|  1518       \   ConcurrentHashMap          : 'java.util.concurrent.ConcurrentHashMap',
|  1519       \   assertThat                 : 'static com.google.common.truth.Truth.assertThat',
|  1520       \   assertWithMessage          : 'static com.google.common.truth.Truth.assertWithMessage',
|  1521       \   AuxCounters                : 'org.openjdk.jmh.annotations.AuxCounters',
|  1522       \   Benchmark                  : 'org.openjdk.jmh.annotations.Benchmark',
|  1523       \   BenchmarkMode              : 'org.openjdk.jmh.annotations.BenchmarkMode',
|  1524       \   CompilerControl            : 'org.openjdk.jmh.annotations.CompilerControl',
|  1525       \   Fork                       : 'org.openjdk.jmh.annotations.Fork',
|  1526       \   Group                      : 'org.openjdk.jmh.annotations.Group',
|  1527       \   GroupThreads               : 'org.openjdk.jmh.annotations.GroupThreads',
|  1528       \   Level                      : 'org.openjdk.jmh.annotations.Level',
|  1529       \   Measurement                : 'org.openjdk.jmh.annotations.Measurement',
|  1530       \   Mode                       : 'org.openjdk.jmh.annotations.Mode',
|  1531       \   OperationsPerInvocation    : 'org.openjdk.jmh.annotations.OperationsPerInvocation',
|  1532       \   OutputTimeUnit             : 'org.openjdk.jmh.annotations.OutputTimeUnit',
|  1533       \   Param                      : 'org.openjdk.jmh.annotations.Param',
|  1534       \   Scope                      : 'org.openjdk.jmh.annotations.Scope',
|  1535       \   Setup                      : 'org.openjdk.jmh.annotations.Setup',
|  1536       \   State                      : 'org.openjdk.jmh.annotations.State',
|  1537       \   TearDown                   : 'org.openjdk.jmh.annotations.TearDown',
|  1538       \   Threads                    : 'org.openjdk.jmh.annotations.Threads',
|  1539       \   Timeout                    : 'org.openjdk.jmh.annotations.Timeout',
|  1540       \   Warmup                     : 'org.openjdk.jmh.annotations.Warmup',
|  1541       \   BenchmarkParams            : 'org.openjdk.jmh.infra.BenchmarkParams',
|  1542       \   Blackhole                  : 'org.openjdk.jmh.infra.Blackhole',
|  1543       \   Control                    : 'org.openjdk.jmh.infra.Control',
|  1544       \   IterationParams            : 'org.openjdk.jmh.infra.IterationParams',
|  1545       \   ThreadParams               : 'org.openjdk.jmh.infra.ThreadParams',
|  1546       \   Runner                     : 'org.openjdk.jmh.runner.Runner',
|  1547       \   RunnerException            : 'org.openjdk.jmh.runner.RunnerException',
|  1548       \   CommandLineOptionException : 'org.openjdk.jmh.runner.options.CommandLineOptionException',
|  1549       \   CommandLineOptions         : 'org.openjdk.jmh.runner.options.CommandLineOptions',
|  1550       \   Options                    : 'org.openjdk.jmh.runner.options.Options',
|  1551       \   OptionsBuilder             : 'org.openjdk.jmh.runner.options.OptionsBuilder',
|  1552       \   ResultFormatType           : 'org.openjdk.jmh.results.format.ResultFormatType',
|  1553       \ }
|  1554 " }}} Java Import Cache
   1555 
   1556 
+  -  1557 +--193 lines: C++ Import Cache:
1557 " C++ Import Cache: {{{
|  1558 let g:jm_vimrc.cc_import_cache = {
|  1559       \   '"absl/flags/flag.h"': ['ABSL_FLAG', 'GetFlag'],
|  1560       \   '"absl/flags/declare.h"': ['ABSL_DECLARE_FLAG'],
|  1561       \   '"absl/flags/parse.h"': ['ParseCommandLine'],
|  1562       \   '"absl/flags/usage.h"': ['ProgramUsageMessage', 'SetProgramUsageMessage'],
|  1563       \   '"absl/strings/str_join.h"': ['StrJoin'],
|  1564       \   '"absl/strings/str_cat.h"': ['StrCat'],
|  1565       \   '"absl/strings/str_replace.h"': ['StrReplaceAll'],
|  1566       \   '"absl/strings/str_split.h"': ['StrSplit'],
|  1567       \   '"absl/status/status.h"': ['Status'],
|  1568       \   '"absl/status/statusor.h"': ['StatusOr'],
|  1569       \   '<opencv2/core.hpp>': [
|  1570       \     'Mat',
|  1571       \     'Mat_',
|  1572       \     'Mat1b', 'Mat2b', 'Mat3b', 'Mat4b',
|  1573       \     'Mat1i', 'Mat2i', 'Mat3i', 'Mat4i',
|  1574       \     'Mat1f', 'Mat2f', 'Mat3f', 'Mat4f',
|  1575       \     'Mat1d', 'Mat2d', 'Mat3d', 'Mat4d',
|  1576       \     'Matx',
|  1577       \     'Matx22f', 'Matx33f', 'Matx44f',
|  1578       \     'Matx21f', 'Matx31f', 'Matx41f',
|  1579       \     'Matx22d', 'Matx33d', 'Matx44d',
|  1580       \     'Matx21d', 'Matx31d', 'Matx41d',
|  1581       \     'Vec',
|  1582       \     'Vec1b', 'Vec2b', 'Vec3b', 'Vec4b', 'Vec6b',
|  1583       \     'Vec1i', 'Vec2i', 'Vec3i', 'Vec4i', 'Vec6i',
|  1584       \     'Vec1f', 'Vec2f', 'Vec3f', 'Vec4f', 'Vec6f',
|  1585       \     'Vec1d', 'Vec2d', 'Vec3d', 'Vec4d', 'Vec6d',
|  1586       \     'Scalar_', 'Scalar',
|  1587       \     'Point_', 'Point2i', 'Point2l', 'Point2f', 'Point2d',
|  1588       \     'Point3_', 'Point3i', 'Point3l', 'Point3f', 'Point3d',
|  1589       \     'abs',
|  1590       \     'exp', 'log',
|  1591       \     'pow', 'sqrt',
|  1592       \   ],
|  1593       \   '<opencv2/imgcodecs.hpp>': ['imread', 'imwrite'],
|  1594       \   '<opencv2/imgproc.hpp>': ['circle'],
|  1595       \   '<utility>': [
|  1596       \     'forward', 'declval',
|  1597       \     'move', 'swap', 'exchange',
|  1598       \     'integer_sequence', 'make_integer_sequence',
|  1599       \     'index_sequence', 'make_index_sequence',
|  1600       \     'pair', 'make_pair',
|  1601       \   ],
|  1602       \   '<memory>': ['unique_ptr', 'make_unique'],
|  1603       \   '<vector>': ['vector'],
|  1604       \   '<tuple>': [
|  1605       \     'tuple',
|  1606       \     'tuple_size',
|  1607       \     'tuple_element',
|  1608       \     'get',
|  1609       \   ],
|  1610       \   '<type_traits>': [
|  1611       \     'enable_if', 'conditional',
|  1612       \     'enable_if_t', 'conditional_t',
|  1613       \     'integral_constant', 'bool_constant',
|  1614       \     'true_type', 'false_type',
|  1615       \     'conjunction', 'disjunction', 'negation',
|  1616       \     'conjunction_v', 'disjunction_v', 'negation_v',
|  1617       \     'is_same', 'is_base_of', 'is_convertible',
|  1618       \     'is_same_v', 'is_base_of_v', 'is_convertible_v',
|  1619       \   ],
|  1620       \   '<array>': ['array'],
|  1621       \   '<valarray>': ['valarray'],
|  1622       \   '<cstddef>': [
|  1623       \     'size_t', 'ptrdiff_t', 'nullptr_t',
|  1624       \   ],
|  1625       \   '<future>': [
|  1626       \     'future', 'promise', 'async', 'launch',
|  1627       \   ],
|  1628       \   '<thread>': [
|  1629       \     'thread', 'this_thread', 'yield', 'get_id', 'sleep_for',
|  1630       \   ],
|  1631       \   '<cstdint>': [
|  1632       \     'int8_t', 'int16_t', 'int32_t', 'int64_t',
|  1633       \     'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
|  1634       \   ],
|  1635       \   '<cmath>': [
|  1636       \     'abs',
|  1637       \     'exp', 'log', 'log2', 'log10',
|  1638       \     'pow', 'sqrt', 'hypot',
|  1639       \     'sin', 'cos', 'tan',
|  1640       \     'asin', 'acos', 'atan',
|  1641       \     'sinh', 'cosh', 'tanh',
|  1642       \     'asinh', 'acosh', 'atanh',
|  1643       \     'ceil', 'floor', 'trunc', 'round',
|  1644       \   ],
|  1645       \   '<string>': [
|  1646       \     'string',
|  1647       \     'to_string',
|  1648       \     'stoi', 'stol', 'stoul', 'stoll', 'stoull',
|  1649       \     'stof', 'stod', 'stold',
|  1650       \   ],
|  1651       \   '<map>': ['map'],
|  1652       \   '<unordered_map>': ['unordered_map'],
|  1653       \   '<set>': ['set'],
|  1654       \   '<iostream>': [
|  1655       \     'cout', 'cin', 'cerr',
|  1656       \     'endl',
|  1657       \   ],
|  1658       \   '<ios>': [
|  1659       \     'internal', 'left', 'right',
|  1660       \     'boolalpha', 'showbase', 'showpos',
|  1661       \     'dec', 'hex', 'oct',
|  1662       \     'fixed', 'scientific', 'default',
|  1663       \   ],
|  1664       \   '<format>': ['format'],
|  1665       \   '<iomanip>': [
|  1666       \     'setw',
|  1667       \     'quoted',
|  1668       \   ],
|  1669       \   '<unordered_set>': ['unordered_set'],
|  1670       \   '<optional>': ['optional'],
|  1671       \   '<complex>': ['complex'],
|  1672       \   '<initializer_list>': ['initializer_list'],
|  1673       \   '<numeric>': [
|  1674       \     'iota',
|  1675       \     'accumulate',
|  1676       \     'reduce',
|  1677       \     'inner_product',
|  1678       \     'adjacent_difference',
|  1679       \     'partial_sum',
|  1680       \   ],
|  1681       \   '<cstdlib>': [
|  1682       \     'system',
|  1683       \     'exit',
|  1684       \     'getenv',
|  1685       \     'malloc',
|  1686       \     'free',
|  1687       \     'aligned_malloc',
|  1688       \   ],
|  1689       \   '<random>': [
|  1690       \     'random_device',
|  1691       \     'mt19937',
|  1692       \     'mt19937_64',
|  1693       \     'uniform_real_distribution',
|  1694       \     'uniform_int_distribution',
|  1695       \     'normal_distribution',
|  1696       \   ],
|  1697       \   '<functional>': [
|  1698       \     'function',
|  1699       \     'plus', 'minus', 'multiplies', 'divides',
|  1700       \     'equal_to', 'not_equal_to',
|  1701       \     'greater', 'less', 'greater_equal', 'less_equal',
|  1702       \     'logical_and', 'logical_or', 'logical_not',
|  1703       \     'bit_end', 'bit_or', 'bit_xor', 'bit_not',
|  1704       \   ],
|  1705       \   '<algorithm>': [
|  1706       \
|  1707       \     'all_of', 'any_of', 'none_of',
|  1708       \     'for_each', 'for_each_n',
|  1709       \     'count', 'count_if',
|  1710       \     'mismatch',
|  1711       \     'find', 'find_if', 'find_if_not',
|  1712       \     'find_end', 'find_first_of', 'adjacent_find',
|  1713       \     'search', 'search_n',
|  1714       \
|  1715       \     'copy', 'copy_backward', 'move', 'move_backward', 'copy_n',
|  1716       \     'fill', 'fill_n', 'transform', 'generate', 'generate_n',
|  1717       \     'remove', 'remove_if', 'remove_copy', 'remove_copy_if',
|  1718       \     'replace', 'replace_if', 'replace_copy', 'replace_copy_if',
|  1719       \     'swap', 'swap_ranges', 'swap_iter',
|  1720       \     'reverse', 'reverse_copy', 'rotate',
|  1721       \     'rotate_copy',
|  1722       \     'shuffle',
|  1723       \     'max', 'min', 'max_element', 'min_element', 'minmax',
|  1724       \   ],
|  1725       \   '"absl/algorithm/container.h"': [
|  1726       \
|  1727       \     'c_all_of', 'c_any_of', 'c_none_of',
|  1728       \     'c_for_each', 'c_for_each_n',
|  1729       \     'c_count', 'c_count_if',
|  1730       \     'c_mismatch',
|  1731       \     'c_find', 'c_find_if', 'c_find_if_not',
|  1732       \     'c_find_end', 'c_find_first_of', 'c_adjacent_find',
|  1733       \     'c_search', 'c_search_n',
|  1734       \
|  1735       \     'c_copy', 'c_copy_backward', 'c_move', 'c_move_backward', 'c_copy_n',
|  1736       \     'c_fill', 'c_fill_n', 'c_transform', 'c_generate', 'c_generate_n',
|  1737       \     'c_remove', 'c_remove_if', 'c_remove_copy', 'c_remove_copy_if',
|  1738       \     'c_replace', 'c_replace_if', 'c_replace_copy', 'c_replace_copy_if',
|  1739       \     'c_swap', 'c_swap_ranges', 'c_swap_iter',
|  1740       \     'c_reverse', 'c_reverse_copy', 'c_rotate',
|  1741       \     'c_rotate_copy',
|  1742       \     'c_shuffle',
|  1743       \   ],
|  1744       \   '<iterator>': [
|  1745       \     'istream_iterator',
|  1746       \     'ostream_iterator',
|  1747       \   ],
|  1748       \ }
|  1749 " }}} C++ Import Cache