<commit_before>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>
" Email:      <EMAIL>
"

function! vimtex#cmd#init_options() " {{{1
endfunction

" }}}1
function! vimtex#cmd#init_script() " {{{1
endfunction

" }}}1
function! vimtex#cmd#init_buffer() " {{{1
  nnoremap <silent><buffer> <plug>(vimtex-cmd-delete)
        \ :call vimtex#cmd#delete()<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-change)
        \ :call vimtex#cmd#change()<cr>

  inoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ <c-r>=vimtex#cmd#create_insert()<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ :call vimtex#cmd#create_ask(0)<cr>

  xnoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ :<c-u>call vimtex#cmd#create_ask(1)<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-star)
        \ :call vimtex#cmd#toggle_star()<cr>
endfunction

" }}}1

function! vimtex#cmd#change() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  let l:old_name = l:cmd.name
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum

  " Get new command name
  call vimtex#echo#status(['Change command: ', ['VimtexWarning', l:old_name]])
  echohl VimtexMsg
  let l:new_name = input('> ')
  echohl None
  let l:new_name = substitute(l:new_name, '^\\', '', '')
  if empty(l:new_name) | return | endif

  " Update current position
  let l:save_pos = getpos('.')
  let l:save_pos[2] += strlen(l:new_name) - strlen(l:old_name) + 1

  " Perform the change
  let l:line = getline(l:lnum)
  call setline(l:lnum,
        \   strpart(l:line, 0, l:cnum)
        \ . l:new_name
        \ . strpart(l:line, l:cnum + strlen(l:old_name) - 1))

  " Restore cursor position and create repeat hook
  cal setpos('.', l:save_pos)
  silent! call repeat#set(
        \ "\<plug>(vimtex-cmd-change)" . l:new_name . '
', v:count)
endfunction

function! vimtex#cmd#delete() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  " Save current position
  let l:save_pos = getpos('.')
  let l:lnum_cur = l:save_pos[1]
  let l:cnum_cur = l:save_pos[2]

  " Remove closing bracket (if exactly one argument)
  if len(l:cmd.args) == 1
    let l:lnum = l:cmd.args[0].close.lnum
    let l:cnum = l:cmd.args[0].close.cnum
    let l:line = getline(l:lnum)
    call setline(l:lnum,
          \   strpart(l:line, 0, l:cnum - 1)
          \ . strpart(l:line, l:cnum))

    let l:cnum2 = l:cmd.args[0].open.cnum
  endif

  " Remove command (and possibly the opening bracket)
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum
  let l:cnum2 = get(l:, 'cnum2', l:cnum + strlen(l:cmd.name) - 1)
  let l:line = getline(l:lnum)
  call setline(l:lnum,
        \   strpart(l:line, 0, l:cnum - 1)
        \ . strpart(l:line, l:cnum2))

  " Restore appropriate cursor position
  if l:lnum_cur == l:lnum
    if l:cnum_cur > l:cnum2
      let l:save_pos[2] -= l:cnum2 - l:cnum + 1
    else
      let l:save_pos[2] -= l:cnum_cur - l:cnum
    endif
  endif
  cal setpos('.', l:save_pos)

  " Create repeat hook
  silent! call repeat#set("\<plug>(vimtex-cmd-delete)", v:count)
endfunction

function! vimtex#cmd#create_insert() " {{{1
  if mode() !=# 'i' | return | endif

  let l:re = '\v%(^|\A)\zs\w+\ze%(\A|$)'
  let l:c0 = col('.') - 1

  let [l:l1, l:c1] = searchpos(l:re, 'bcn', line('.'))
  let l:c1 -= 1
  let l:line = getline(l:l1)
  let l:match = matchstr(l:line, l:re, l:c1)
  let l:c2 = l:c1 + strlen(l:match)

  if l:c0 > l:c2
    call vimtex#echo#status(['vimtex: ',
          \ ['VimtexWarning', 'Could not create command']])
    return ''
  endif

  let l:strpart1 = strpart(l:line, 0, l:c1)
  let l:strpart2 = '\' . strpart(l:match, 0, l:c0 - l:c1) . '{'
  let l:strpart3 = strpart(l:line, l:c0)
  call setline(l:l1, l:strpart1 . l:strpart2 . l:strpart3)

  call setpos('.', [0, l:l1, l:c2+3, 0])
  return ''
endfunction

" }}}1
function! vimtex#cmd#create_ask(visualmode) " {{{1
  call vimtex#echo#status(['Command command: ',
        \ ['VimtexWarning', '(empty to cancel)']])
  echohl VimtexMsg
  let l:cmd = input('> ')
  echohl None
  let l:cmd = substitute(l:cmd, '^\\', '', '')
  if empty(l:cmd) | return | endif

  if a:visualmode
    let l:pos_start = getpos("'<")
    let l:pos_end = getpos("'>")

    normal! `<
    execute 'normal! i\' . l:cmd . '{'
    normal! `>
    execute 'normal! ' . (strlen(l:cmd) + 2) . 'la}'

    let l:pos_end[2] += 1
    if l:pos_end[1] == l:pos_start[1]
      let l:pos_end[2] += strlen(l:cmd) + 2
    endif

    call setpos('.', l:pos_end)
  else
    let l:pos = getpos('.')
    let l:save_reg = getreg('"')
    let l:pos[2] += strlen(l:cmd) + 2
    execute 'normal! ciw\' . l:cmd . '{"}'
    silent! call repeat#set(
          \ "\<plug>(vimtex-cmd-create-ask)" . l:cmd . '
', v:count)
    call setreg('"', l:save_reg)
    call setpos('.', l:pos)
  endif
endfunction

" }}}1
function! vimtex#cmd#toggle_star() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  let l:old_name = l:cmd.name
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum

  " Set new command name
  if match(l:old_name, '\*$') == -1<commit_msg>Fixed #699: Disable indentkeys during cmd#create_ask<commit_after>" vimtex - LaTeX plugin for Vim
"
" Maintainer: <NAME>g
" Email:      <EMAIL>
"

function! vimtex#cmd#init_options() " {{{1
endfunction

" }}}1
function! vimtex#cmd#init_script() " {{{1
endfunction

" }}}1
function! vimtex#cmd#init_buffer() " {{{1
  nnoremap <silent><buffer> <plug>(vimtex-cmd-delete)
        \ :call vimtex#cmd#delete()<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-change)
        \ :call vimtex#cmd#change()<cr>

  inoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ <c-r>=vimtex#cmd#create_insert()<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ :call vimtex#cmd#create_ask(0)<cr>

  xnoremap <silent><buffer> <plug>(vimtex-cmd-create)
        \ :<c-u>call vimtex#cmd#create_ask(1)<cr>

  nnoremap <silent><buffer> <plug>(vimtex-cmd-toggle-star)
        \ :call vimtex#cmd#toggle_star()<cr>
endfunction

" }}}1

function! vimtex#cmd#change() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  let l:old_name = l:cmd.name
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum

  " Get new command name
  call vimtex#echo#status(['Change command: ', ['VimtexWarning', l:old_name]])
  echohl VimtexMsg
  let l:new_name = input('> ')
  echohl None
  let l:new_name = substitute(l:new_name, '^\\', '', '')
  if empty(l:new_name) | return | endif

  " Update current position
  let l:save_pos = getpos('.')
  let l:save_pos[2] += strlen(l:new_name) - strlen(l:old_name) + 1

  " Perform the change
  let l:line = getline(l:lnum)
  call setline(l:lnum,
        \   strpart(l:line, 0, l:cnum)
        \ . l:new_name
        \ . strpart(l:line, l:cnum + strlen(l:old_name) - 1))

  " Restore cursor position and create repeat hook
  cal setpos('.', l:save_pos)
  silent! call repeat#set(
        \ "\<plug>(vimtex-cmd-change)" . l:new_name . '
', v:count)
endfunction

function! vimtex#cmd#delete() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  " Save current position
  let l:save_pos = getpos('.')
  let l:lnum_cur = l:save_pos[1]
  let l:cnum_cur = l:save_pos[2]

  " Remove closing bracket (if exactly one argument)
  if len(l:cmd.args) == 1
    let l:lnum = l:cmd.args[0].close.lnum
    let l:cnum = l:cmd.args[0].close.cnum
    let l:line = getline(l:lnum)
    call setline(l:lnum,
          \   strpart(l:line, 0, l:cnum - 1)
          \ . strpart(l:line, l:cnum))

    let l:cnum2 = l:cmd.args[0].open.cnum
  endif

  " Remove command (and possibly the opening bracket)
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum
  let l:cnum2 = get(l:, 'cnum2', l:cnum + strlen(l:cmd.name) - 1)
  let l:line = getline(l:lnum)
  call setline(l:lnum,
        \   strpart(l:line, 0, l:cnum - 1)
        \ . strpart(l:line, l:cnum2))

  " Restore appropriate cursor position
  if l:lnum_cur == l:lnum
    if l:cnum_cur > l:cnum2
      let l:save_pos[2] -= l:cnum2 - l:cnum + 1
    else
      let l:save_pos[2] -= l:cnum_cur - l:cnum
    endif
  endif
  cal setpos('.', l:save_pos)

  " Create repeat hook
  silent! call repeat#set("\<plug>(vimtex-cmd-delete)", v:count)
endfunction

function! vimtex#cmd#create_insert() " {{{1
  if mode() !=# 'i' | return | endif

  let l:re = '\v%(^|\A)\zs\w+\ze%(\A|$)'
  let l:c0 = col('.') - 1

  let [l:l1, l:c1] = searchpos(l:re, 'bcn', line('.'))
  let l:c1 -= 1
  let l:line = getline(l:l1)
  let l:match = matchstr(l:line, l:re, l:c1)
  let l:c2 = l:c1 + strlen(l:match)

  if l:c0 > l:c2
    call vimtex#echo#status(['vimtex: ',
          \ ['VimtexWarning', 'Could not create command']])
    return ''
  endif

  let l:strpart1 = strpart(l:line, 0, l:c1)
  let l:strpart2 = '\' . strpart(l:match, 0, l:c0 - l:c1) . '{'
  let l:strpart3 = strpart(l:line, l:c0)
  call setline(l:l1, l:strpart1 . l:strpart2 . l:strpart3)

  call setpos('.', [0, l:l1, l:c2+3, 0])
  return ''
endfunction

" }}}1
function! vimtex#cmd#create_ask(visualmode) " {{{1
  call vimtex#echo#status(['Command command: ',
        \ ['VimtexWarning', '(empty to cancel)']])
  echohl VimtexMsg
  let l:cmd = input('> ')
  echohl None
  let l:cmd = substitute(l:cmd, '^\\', '', '')
  if empty(l:cmd) | return | endif

  " Avoid autoindent (disable indentkeys)
  let l:save_indentkeys = &l:indentkeys
  setlocal indentkeys=

  if a:visualmode
    let l:pos_start = getpos("'<")
    let l:pos_end = getpos("'>")

    normal! `<
    execute 'normal! i\' . l:cmd . '{'
    normal! `>
    execute 'normal! ' . (strlen(l:cmd) + 2) . 'la}'

    let l:pos_end[2] += 1
    if l:pos_end[1] == l:pos_start[1]
      let l:pos_end[2] += strlen(l:cmd) + 2
    endif

    call setpos('.', l:pos_end)
  else
    let l:pos = getpos('.')
    let l:save_reg = getreg('"')
    let l:pos[2] += strlen(l:cmd) + 2
    execute 'normal! ciw\' . l:cmd . '{"}'
    silent! call repeat#set(
          \ "\<plug>(vimtex-cmd-create-ask)" . l:cmd . '
', v:count)
    call setreg('"', l:save_reg)
    call setpos('.', l:pos)
  endif

  " Restore indentkeys setting
  let &l:indentkeys = l:save_indentkeys
endfunction

" }}}1
function! vimtex#cmd#toggle_star() " {{{1
  let l:cmd = vimtex#cmd#get_current()
  if empty(l:cmd) | return | endif

  let l:old_name = l:cmd.name
  let l:lnum = l:cmd.pos_start.lnum
  let l:cnum = l:cmd.pos_start.cnum

  " Set new command name
  if match(l:old_name, '\*$') == -1
{'fraction_non_alphanumeric': 0.1823329558323896, 'fraction_numerical': 0.015194412986032465, 'mean_word_length': 3.292021061158364, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5074122', 'n_tokens_mistral': 4585, 'n_tokens_neox': 4436, 'n_words': 913}