]> git.ayabusa.dev Git - dot_files.git/commitdiff
hop
authorayabusa <leon.roullin@epita.fr>
Wed, 24 Dec 2025 13:48:39 +0000 (14:48 +0100)
committerayabusa <leon.roullin@epita.fr>
Wed, 24 Dec 2025 13:48:39 +0000 (14:48 +0100)
vim/.vimrc [new file with mode: 0644]
vim/plugin/auto-pairs.vim [new file with mode: 0644]

diff --git a/vim/.vimrc b/vim/.vimrc
new file mode 100644 (file)
index 0000000..149b4ce
--- /dev/null
@@ -0,0 +1,20 @@
+" Disable compatibility with vi which can cause unexpected issues.
+set nocompatible
+
+" Enable type file detection. Vim will be able to try to detect the type of file in use.
+filetype on
+
+" Enable plugins and load plugin for the detected file type.
+filetype plugin on
+
+" Load an indent file for the detected file type.
+filetype indent on
+
+" Turn syntax highlighting on.
+syntax on
+
+" Add numbers to each line on the left-hand side.
+set number
+
+" Enable mouse for selection n all
+set mouse+=a
diff --git a/vim/plugin/auto-pairs.vim b/vim/plugin/auto-pairs.vim
new file mode 100644 (file)
index 0000000..af5eb32
--- /dev/null
@@ -0,0 +1,673 @@
+" Insert or delete brackets, parens, quotes in pairs.
+" Maintainer:  JiangMiao <jiangfriend@gmail.com>
+" Contributor: camthompson
+" Last Change:  2019-02-02
+" Version: 2.0.0
+" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
+" Repository: https://github.com/jiangmiao/auto-pairs
+" License: MIT
+
+if exists('g:AutoPairsLoaded') || &cp
+  finish
+end
+let g:AutoPairsLoaded = 1
+
+if !exists('g:AutoPairs')
+  let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '```':'```', '"""':'"""', "'''":"'''", "`":"`"}
+end
+
+" default pairs base on filetype
+func! AutoPairsDefaultPairs()
+  if exists('b:autopairs_defaultpairs')
+    return b:autopairs_defaultpairs
+  end
+  let r = copy(g:AutoPairs)
+  let allPairs = {
+        \ 'vim': {'\v^\s*\zs"': ''},
+        \ 'rust': {'\w\zs<': '>', '&\zs''': ''},
+        \ 'php': {'<?': '?>//k]', '<?php': '?>//k]'}
+        \ }
+  for [filetype, pairs] in items(allPairs)
+    if &filetype == filetype
+      for [open, close] in items(pairs)
+        let r[open] = close
+      endfor
+    end
+  endfor
+  let b:autopairs_defaultpairs = r
+  return r
+endf
+
+if !exists('g:AutoPairsMapBS')
+  let g:AutoPairsMapBS = 1
+end
+
+" Map <C-h> as the same BS
+if !exists('g:AutoPairsMapCh')
+  let g:AutoPairsMapCh = 1
+end
+
+if !exists('g:AutoPairsMapCR')
+  let g:AutoPairsMapCR = 1
+end
+
+if !exists('g:AutoPairsWildClosedPair')
+  let g:AutoPairsWildClosedPair = ''
+end
+
+if !exists('g:AutoPairsMapSpace')
+  let g:AutoPairsMapSpace = 1
+end
+
+if !exists('g:AutoPairsCenterLine')
+  let g:AutoPairsCenterLine = 1
+end
+
+if !exists('g:AutoPairsShortcutToggle')
+  let g:AutoPairsShortcutToggle = '<M-p>'
+end
+
+if !exists('g:AutoPairsShortcutFastWrap')
+  let g:AutoPairsShortcutFastWrap = '<M-e>'
+end
+
+if !exists('g:AutoPairsMoveCharacter')
+  let g:AutoPairsMoveCharacter = "()[]{}\"'"
+end
+
+if !exists('g:AutoPairsShortcutJump')
+  let g:AutoPairsShortcutJump = '<M-n>'
+endif
+
+" Fly mode will for closed pair to jump to closed pair instead of insert.
+" also support AutoPairsBackInsert to insert pairs where jumped.
+if !exists('g:AutoPairsFlyMode')
+  let g:AutoPairsFlyMode = 0
+endif
+
+" When skipping the closed pair, look at the current and
+" next line as well.
+if !exists('g:AutoPairsMultilineClose')
+  let g:AutoPairsMultilineClose = 1
+endif
+
+" Work with Fly Mode, insert pair where jumped
+if !exists('g:AutoPairsShortcutBackInsert')
+  let g:AutoPairsShortcutBackInsert = '<M-b>'
+endif
+
+if !exists('g:AutoPairsSmartQuotes')
+  let g:AutoPairsSmartQuotes = 1
+endif
+
+" 7.4.849 support <C-G>U to avoid breaking '.'
+" Issue talk: https://github.com/jiangmiao/auto-pairs/issues/3
+" Vim note: https://github.com/vim/vim/releases/tag/v7.4.849
+if v:version > 704 || v:version == 704 && has("patch849")
+  let s:Go = "\<C-G>U"
+else
+  let s:Go = ""
+endif
+
+let s:Left = s:Go."\<LEFT>"
+let s:Right = s:Go."\<RIGHT>"
+
+
+
+
+" unicode len
+func! s:ulen(s)
+  return len(split(a:s, '\zs'))
+endf
+
+func! s:left(s)
+  return repeat(s:Left, s:ulen(a:s))
+endf
+
+func! s:right(s)
+  return repeat(s:Right, s:ulen(a:s))
+endf
+
+func! s:delete(s)
+  return repeat("\<DEL>", s:ulen(a:s))
+endf
+
+func! s:backspace(s)
+  return repeat("\<BS>", s:ulen(a:s))
+endf
+
+func! s:getline()
+  let line = getline('.')
+  let pos = col('.') - 1
+  let before = strpart(line, 0, pos)
+  let after = strpart(line, pos)
+  let afterline = after
+  if g:AutoPairsMultilineClose
+    let n = line('$')
+    let i = line('.')+1
+    while i <= n
+      let line = getline(i)
+      let after = after.' '.line
+      if !(line =~ '\v^\s*$')
+        break
+      end
+      let i = i+1
+    endwhile
+  end
+  return [before, after, afterline]
+endf
+
+" split text to two part
+" returns [orig, text_before_open, open]
+func! s:matchend(text, open)
+    let m = matchstr(a:text, '\V'.a:open.'\v$')
+    if m == ""
+      return []
+    end
+    return [a:text, strpart(a:text, 0, len(a:text)-len(m)), m]
+endf
+
+" returns [orig, close, text_after_close]
+func! s:matchbegin(text, close)
+    let m = matchstr(a:text, '^\V'.a:close)
+    if m == ""
+      return []
+    end
+    return [a:text, m, strpart(a:text, len(m), len(a:text)-len(m))]
+endf
+
+" add or delete pairs base on g:AutoPairs
+" AutoPairsDefine(addPairs:dict[, removeOpenPairList:list])
+"
+" eg:
+"   au FileType html let b:AutoPairs = AutoPairsDefine({'<!--' : '-->'}, ['{'])
+"   add <!-- --> pair and remove '{' for html file
+func! AutoPairsDefine(pairs, ...)
+  let r = AutoPairsDefaultPairs()
+  if a:0 > 0
+    for open in a:1
+      unlet r[open]
+    endfor
+  end
+  for [open, close] in items(a:pairs)
+    let r[open] = close
+  endfor
+  return r
+endf
+
+func! AutoPairsInsert(key)
+  if !b:autopairs_enabled
+    return a:key
+  end
+
+  let b:autopairs_saved_pair = [a:key, getpos('.')]
+
+  let [before, after, afterline] = s:getline()
+
+  " Ignore auto close if prev character is \
+  if before[-1:-1] == '\'
+    return a:key
+  end
+
+  " check open pairs
+  for [open, close, opt] in b:AutoPairsList
+    let ms = s:matchend(before.a:key, open)
+    let m = matchstr(afterline, '^\v\s*\zs\V'.close)
+    if len(ms) > 0
+      " process the open pair
+      
+      " remove inserted pair
+      " eg: if the pairs include < > and  <!-- --> 
+      " when <!-- is detected the inserted pair < > should be clean up 
+      let target = ms[1]
+      let openPair = ms[2]
+      if len(openPair) == 1 && m == openPair
+        break
+      end
+      let bs = ''
+      let del = ''
+      while len(before) > len(target)
+        let found = 0
+        " delete pair
+        for [o, c, opt] in b:AutoPairsList
+          let os = s:matchend(before, o)
+          if len(os) && len(os[1]) < len(target)
+            " any text before openPair should not be deleted
+            continue
+          end
+          let cs = s:matchbegin(afterline, c)
+          if len(os) && len(cs)
+            let found = 1
+            let before = os[1]
+            let afterline = cs[2]
+            let bs = bs.s:backspace(os[2])
+            let del = del.s:delete(cs[1])
+            break
+          end
+        endfor
+        if !found
+          " delete charactor
+          let ms = s:matchend(before, '\v.')
+          if len(ms)
+            let before = ms[1]
+            let bs = bs.s:backspace(ms[2])
+          end
+        end
+      endwhile
+      return bs.del.openPair.close.s:left(close)
+    end
+  endfor
+
+  " check close pairs
+  for [open, close, opt] in b:AutoPairsList
+    if close == ''
+      continue
+    end
+    if a:key == g:AutoPairsWildClosedPair || opt['mapclose'] && opt['key'] == a:key
+      " the close pair is in the same line
+      let m = matchstr(afterline, '^\v\s*\V'.close)
+      if m != ''
+        if before =~ '\V'.open.'\v\s*$' && m[0] =~ '\v\s'
+          " remove the space we inserted if the text in pairs is blank
+          return "\<DEL>".s:right(m[1:])
+        else
+          return s:right(m)
+        end
+      end
+      let m = matchstr(after, '^\v\s*\zs\V'.close)
+      if m != ''
+        if a:key == g:AutoPairsWildClosedPair || opt['multiline']
+          if b:autopairs_return_pos == line('.') && getline('.') =~ '\v^\s*$'
+            normal! ddk$
+          end
+          call search(m, 'We')
+          return "\<Right>"
+        else
+          break
+        end
+      end
+    end
+  endfor
+
+
+  " Fly Mode, and the key is closed-pairs, search closed-pair and jump
+  if g:AutoPairsFlyMode &&  a:key =~ '\v[\}\]\)]'
+    if search(a:key, 'We')
+      return "\<Right>"
+    endif
+  endif
+
+  return a:key
+endf
+
+func! AutoPairsDelete()
+  if !b:autopairs_enabled
+    return "\<BS>"
+  end
+
+  let [before, after, ig] = s:getline()
+  for [open, close, opt] in b:AutoPairsList
+    let b = matchstr(before, '\V'.open.'\v\s?$')
+    let a = matchstr(after, '^\v\s*\V'.close)
+    if b != '' && a != ''
+      if b[-1:-1] == ' '
+        if a[0] == ' '
+          return "\<BS>\<DELETE>"
+        else
+          return "\<BS>"
+        end
+      end
+      return s:backspace(b).s:delete(a)
+    end
+  endfor
+
+  return "\<BS>"
+  " delete the pair foo[]| <BS> to foo
+  for [open, close, opt] in b:AutoPairsList
+    let m = s:matchend(before, '\V'.open.'\v\s*'.'\V'.close.'\v$')
+    if len(m) > 0
+      return s:backspace(m[2])
+    end
+  endfor
+  return "\<BS>"
+endf
+
+
+" Fast wrap the word in brackets
+func! AutoPairsFastWrap()
+  let c = @"
+  normal! x
+  let [before, after, ig] = s:getline()
+  if after[0] =~ '\v[\{\[\(\<]'
+    normal! %
+    normal! p
+  else
+    for [open, close, opt] in b:AutoPairsList
+      if close == ''
+        continue
+      end
+      if after =~ '^\s*\V'.open
+        call search(close, 'We')
+        normal! p
+        let @" = c
+        return ""
+      end
+    endfor
+    if after[1:1] =~ '\v\w'
+      normal! e
+      normal! p
+    else
+      normal! p
+    end
+  end
+  let @" = c
+  return ""
+endf
+
+func! AutoPairsJump()
+  call search('["\]'')}]','W')
+endf
+
+func! AutoPairsMoveCharacter(key)
+  let c = getline(".")[col(".")-1]
+  let escaped_key = substitute(a:key, "'", "''", 'g')
+  return "\<DEL>\<ESC>:call search("."'".escaped_key."'".")\<CR>a".c."\<LEFT>"
+endf
+
+func! AutoPairsBackInsert()
+  let pair = b:autopairs_saved_pair[0]
+  let pos  = b:autopairs_saved_pair[1]
+  call setpos('.', pos)
+  return pair
+endf
+
+func! AutoPairsReturn()
+  if b:autopairs_enabled == 0
+    return ''
+  end
+  let b:autopairs_return_pos = 0
+  let before = getline(line('.')-1)
+  let [ig, ig, afterline] = s:getline()
+  let cmd = ''
+  for [open, close, opt] in b:AutoPairsList
+    if close == ''
+      continue
+    end
+
+    if before =~ '\V'.open.'\v\s*$' && afterline =~ '^\s*\V'.close
+      let b:autopairs_return_pos = line('.')
+      if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
+        " Recenter before adding new line to avoid replacing line content
+        let cmd = "zz"
+      end
+
+      " If equalprg has been set, then avoid call =
+      " https://github.com/jiangmiao/auto-pairs/issues/24
+      if &equalprg != ''
+        return "\<ESC>".cmd."O"
+      endif
+
+      " conflict with javascript and coffee
+      " javascript   need   indent new line
+      " coffeescript forbid indent new line
+      if &filetype == 'coffeescript' || &filetype == 'coffee'
+        return "\<ESC>".cmd."k==o"
+      else
+        return "\<ESC>".cmd."=ko"
+      endif
+    end
+  endfor
+  return ''
+endf
+
+func! AutoPairsSpace()
+  if !b:autopairs_enabled
+    return "\<SPACE>"
+  end
+
+  let [before, after, ig] = s:getline()
+
+  for [open, close, opt] in b:AutoPairsList
+    if close == ''
+      continue
+    end
+    if before =~ '\V'.open.'\v$' && after =~ '^\V'.close
+      if close =~ '\v^[''"`]$'
+        return "\<SPACE>"
+      else
+        return "\<SPACE>\<SPACE>".s:Left
+      end
+    end
+  endfor
+  return "\<SPACE>"
+endf
+
+func! AutoPairsMap(key)
+  " | is special key which separate map command from text
+  let key = a:key
+  if key == '|'
+    let key = '<BAR>'
+  end
+  let escaped_key = substitute(key, "'", "''", 'g')
+  " use expr will cause search() doesn't work
+  execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
+endf
+
+func! AutoPairsToggle()
+  if b:autopairs_enabled
+    let b:autopairs_enabled = 0
+    echo 'AutoPairs Disabled.'
+  else
+    let b:autopairs_enabled = 1
+    echo 'AutoPairs Enabled.'
+  end
+  return ''
+endf
+
+func! s:sortByLength(i1, i2)
+  return len(a:i2[0])-len(a:i1[0])
+endf
+
+func! AutoPairsInit()
+  let b:autopairs_loaded  = 1
+  if !exists('b:autopairs_enabled')
+    let b:autopairs_enabled = 1
+  end
+
+  if !exists('b:AutoPairs')
+    let b:AutoPairs = AutoPairsDefaultPairs()
+  end
+
+  if !exists('b:AutoPairsMoveCharacter')
+    let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
+  end
+
+  let b:autopairs_return_pos = 0
+  let b:autopairs_saved_pair = [0, 0]
+  let b:AutoPairsList = []
+
+  " buffer level map pairs keys
+  " n - do not map the first charactor of closed pair to close key
+  " m - close key jumps through multi line
+  " s - close key jumps only in the same line
+  for [open, close] in items(b:AutoPairs)
+    let o = open[-1:-1]
+    let c = close[0]
+    let opt = {'mapclose': 1, 'multiline':1}
+    let opt['key'] = c
+    if o == c
+      let opt['multiline'] = 0
+    end
+    let m = matchlist(close, '\v(.*)//(.*)$')
+    if len(m) > 0 
+      if m[2] =~ 'n'
+        let opt['mapclose'] = 0
+      end
+      if m[2] =~ 'm'
+        let opt['multiline'] = 1
+      end
+      if m[2] =~ 's'
+        let opt['multiline'] = 0
+      end
+      let ks = matchlist(m[2], '\vk(.)')
+      if len(ks) > 0
+        let opt['key'] = ks[1]
+        let c = opt['key']
+      end
+      let close = m[1]
+    end
+    call AutoPairsMap(o)
+    if o != c && c != '' && opt['mapclose']
+      call AutoPairsMap(c)
+    end
+    let b:AutoPairsList += [[open, close, opt]]
+  endfor
+
+  " sort pairs by length, longer pair should have higher priority
+  let b:AutoPairsList = sort(b:AutoPairsList, "s:sortByLength")
+
+  for item in b:AutoPairsList
+    let [open, close, opt] = item
+    if open == "'" && open == close
+      let item[0] = '\v(^|\W)\zs'''
+    end
+  endfor
+
+
+  for key in split(b:AutoPairsMoveCharacter, '\s*')
+    let escaped_key = substitute(key, "'", "''", 'g')
+    execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
+  endfor
+
+  " Still use <buffer> level mapping for <BS> <SPACE>
+  if g:AutoPairsMapBS
+    " Use <C-R> instead of <expr> for issue #14 sometimes press BS output strange words
+    execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
+  end
+
+  if g:AutoPairsMapCh
+    execute 'inoremap <buffer> <silent> <C-h> <C-R>=AutoPairsDelete()<CR>'
+  endif
+
+  if g:AutoPairsMapSpace
+    " Try to respect abbreviations on a <SPACE>
+    let do_abbrev = ""
+    if v:version == 703 && has("patch489") || v:version > 703
+      let do_abbrev = "<C-]>"
+    endif
+    execute 'inoremap <buffer> <silent> <SPACE> '.do_abbrev.'<C-R>=AutoPairsSpace()<CR>'
+  end
+
+  if g:AutoPairsShortcutFastWrap != ''
+    execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
+  end
+
+  if g:AutoPairsShortcutBackInsert != ''
+    execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutBackInsert.' <C-R>=AutoPairsBackInsert()<CR>'
+  end
+
+  if g:AutoPairsShortcutToggle != ''
+    " use <expr> to ensure showing the status when toggle
+    execute 'inoremap <buffer> <silent> <expr> '.g:AutoPairsShortcutToggle.' AutoPairsToggle()'
+    execute 'noremap <buffer> <silent> '.g:AutoPairsShortcutToggle.' :call AutoPairsToggle()<CR>'
+  end
+
+  if g:AutoPairsShortcutJump != ''
+    execute 'inoremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' <ESC>:call AutoPairsJump()<CR>a'
+    execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
+  end
+
+  if &keymap != ''
+    let l:imsearch = &imsearch
+    let l:iminsert = &iminsert
+    let l:imdisable = &imdisable
+    execute 'setlocal keymap=' . &keymap
+    execute 'setlocal imsearch=' . l:imsearch
+    execute 'setlocal iminsert=' . l:iminsert
+    if l:imdisable
+      execute 'setlocal imdisable'
+    else
+      execute 'setlocal noimdisable'
+    end
+  end
+
+endf
+
+func! s:ExpandMap(map)
+  let map = a:map
+  let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
+  let map = substitute(map, '\(<Plug>([^)]*)\)', '\=maparg(submatch(1), "i")', 'g')
+  return map
+endf
+
+func! AutoPairsTryInit()
+  if exists('b:autopairs_loaded')
+    return
+  end
+
+  " for auto-pairs starts with 'a', so the priority is higher than supertab and vim-endwise
+  "
+  " vim-endwise doesn't support <Plug>AutoPairsReturn
+  " when use <Plug>AutoPairsReturn will cause <Plug> isn't expanded
+  "
+  " supertab doesn't support <SID>AutoPairsReturn
+  " when use <SID>AutoPairsReturn  will cause Duplicated <CR>
+  "
+  " and when load after vim-endwise will cause unexpected endwise inserted.
+  " so always load AutoPairs at last
+
+  " Buffer level keys mapping
+  " comptible with other plugin
+  if g:AutoPairsMapCR
+    if v:version == 703 && has('patch32') || v:version > 703
+      " VIM 7.3 supports advancer maparg which could get <expr> info
+      " then auto-pairs could remap <CR> in any case.
+      let info = maparg('<CR>', 'i', 0, 1)
+      if empty(info)
+        let old_cr = '<CR>'
+        let is_expr = 0
+      else
+        let old_cr = info['rhs']
+        let old_cr = s:ExpandMap(old_cr)
+        let old_cr = substitute(old_cr, '<SID>', '<SNR>' . info['sid'] . '_', 'g')
+        let is_expr = info['expr']
+        let wrapper_name = '<SID>AutoPairsOldCRWrapper73'
+      endif
+    else
+      " VIM version less than 7.3
+      " the mapping's <expr> info is lost, so guess it is expr or not, it's
+      " not accurate.
+      let old_cr = maparg('<CR>', 'i')
+      if old_cr == ''
+        let old_cr = '<CR>'
+        let is_expr = 0
+      else
+        let old_cr = s:ExpandMap(old_cr)
+        " old_cr contain (, I guess the old cr is in expr mode
+        let is_expr = old_cr =~ '\V(' && toupper(old_cr) !~ '\V<C-R>'
+
+        " The old_cr start with " it must be in expr mode
+        let is_expr = is_expr || old_cr =~ '\v^"'
+        let wrapper_name = '<SID>AutoPairsOldCRWrapper'
+      end
+    end
+
+    if old_cr !~ 'AutoPairsReturn'
+      if is_expr
+        " remap <expr> to `name` to avoid mix expr and non-expr mode
+        execute 'inoremap <buffer> <expr> <script> '. wrapper_name . ' ' . old_cr
+        let old_cr = wrapper_name
+      end
+      " Always silent mapping
+      execute 'inoremap <script> <buffer> <silent> <CR> '.old_cr.'<SID>AutoPairsReturn'
+    end
+  endif
+  call AutoPairsInit()
+endf
+
+" Always silent the command
+inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
+imap <script> <Plug>AutoPairsReturn <SID>AutoPairsReturn
+
+
+au BufEnter * :call AutoPairsTryInit()