गतिशील पूर्णता


12

मैं एक पुराने पूर्ण कार्य को बढ़ाने की कोशिश कर रहा हूं। जैसे ही मैं नए वर्ण टाइप करता हूं, मुझे पॉपअप मेनू में प्रदर्शित विकल्पों को अपडेट करना पसंद है

मेरा पूरा काम है

function! lh#icomplete#ecm(findstart, base) abort
  if a:findstart
    let l = getline('.')
    let startcol = match(l[0:col('.')-1], '\v\S+$')
    if startcol == -1
      let startcol = col('.')-1
    endif
    " let g:debug+= ["findstart(".a:base.") -> ".(startcol)]
    return startcol
  else
    " let g:debug += ["matching(".a:base.")"]
    let words = ['un', 'deux', 'trois', 'trente-deux', 'unité']
    call filter(words, 'v:val =~ a:base')
    " return { 'words' : words}
    return { 'words' : words, 'refresh' : 'always'}
  endif
endfunction

जिसका मैं उपयोग करता हूं

:set completefunc=lh#icomplete#ecm
:inoremap µ <c-x><c-u><c-p>

प्रलेखन, तथ्य यह है मैं उपयोग की मेरी समझ से <c-p>, मैं में जाने तीसरा राज्य (| इन्स-पूर्ण-मेनू | के अनुसार), और जब मैं टाइप "किसी भी प्रिंट करने योग्य, गैर सफेद चरित्र" मैं करने के लिए सक्षम होना चाहिए "जोड़ें यह चरित्र और मैचों की संख्या को कम करता है। ”

जब मैं इन्सर्ट मोड में टाइप करता हूं , तो पूरा होने वाला मेनू उम्मीद के मुताबिक पॉप-अप हो जाता है। काश जब मैं टाइप करता हूं x(बस के बाद µ), मैं पूरा होने के मोड से बाहर हो uxजाता हूं और वही होता है जो मुझे अपने बफर में मिलता है।

मैंने गलत क्या किया या दस्तावेज में चूक हुई?

NB: मैंने देखा है कि इसके बिना refresh=always, परिणाम फ़िल्टर किए जाते हैं, सिवाय इसके कि मैं कस्टम फ़िल्टर लागू करने के लिए फ़ंक्शन को फिर से कॉल करना चाहूंगा।

(बस मामले में, मैं gvim का उपयोग कर रहा हूँ 7.4-908)


यह एक बग की तरह लगता है। यह मेरे लिए भी काम नहीं करता है (मैं Vim 7.4.944 पर हूँ)।
कार्ल यंगवे लर्वग

यह काम करना चाहिए? यही मैं नहीं जानता।
ल्यूक हरमिट

प्रलेखन से तात्पर्य यह लगता है कि उसे काम करना चाहिए।
कार्ल यंगवे लर्वग

जवाबों:


3

आगे की जांच के बाद (और कुछ रिवर्स इंजीनियरिंग)।

मैं समझा नहीं सकता कि पूर्णता दस्तावेज का सख्ती से पालन क्यों नहीं करती। मुझे लगता है कि मुझे vim_dev पर पूछना पड़ेगा।

वैसे भी, ऐसा लगता है कि ऐसा करने के लिए एक श्रोता को पंजीकृत CursorMovedIकरने में शामिल होना चाहिए जो हर बार एक चरित्र सम्मिलित होने पर फिर से पूरा हो जाएगा।

कठिनाई तो यह है कि कब रुकना है।

  • CompletionDone इसका कोई फायदा नहीं है क्योंकि यह हर कुंजी हिट के बाद चालू हो जाएगा।
  • InsertLeave एक अच्छी शुरुआत है, लेकिन यह सभी मामलों को कवर नहीं करता है, अर्थात
    • जब कोई ऐसा पात्र जिसके लिए अधिक मैच नहीं होता है, तो हमें रोकना होगा
    • जब एंड-यूज़र एक मेनू-आइटम का चयन करता है, तो हमें भी रोकना होगा।
      मुझे ओवरराइड करने के अलावा कोई रास्ता नहीं मिला है <cr>, और <c-y>

अन्य कठिनाइयों का पता लगाने में शामिल है जब अनंत छोरों और इतने पर से बचने के लिए कुछ भी नहीं बदला है।

किसी भी तरह से, यहां मेरा वर्तमान कोड है (जिसका उपयोग अन्य प्लगइन्स में किया जाएगा)। पिछले संस्करण यहाँ बनाए रखा जाएगा । यह काफी लंबा है, लेकिन यहाँ यह है:

" ## Smart completion {{{2
" Function: lh#icomplete#new(startcol, matches, hook) {{{3
function! lh#icomplete#new(startcol, matches, hook) abort
  silent! unlet b:complete_data
  let augroup = 'IComplete'.bufnr('%').'Done'
  let b:complete_data = lh#on#exit()
        \.restore('&completefunc')
        \.restore('&complete')
        \.restore('&omnifunc')
        \.register('au! '.augroup)
        \.register('call self.logger.log("finalized! (".getline(".").")")')
  set complete=
  let b:complete_data.startcol        = a:startcol
  let b:complete_data.all_matches     = map(copy(a:matches), 'type(v:val)==type({}) ? v:val : {"word": v:val}')
  let b:complete_data.matches         = {'words': [], 'refresh': 'always'}
  let b:complete_data.hook            = a:hook
  let b:complete_data.cursor_pos      = []
  let b:complete_data.last_content    = [line('.'), getline('.')]
  let b:complete_data.no_more_matches = 0
  let b:complete_data.logger          = s:logger.reset()

  " keybindings {{{4
  call b:complete_data
        \.restore_buffer_mapping('<cr>', 'i')
        \.restore_buffer_mapping('<c-y>', 'i')
        \.restore_buffer_mapping('<esc>', 'i')
        \.restore_buffer_mapping('<tab>', 'i')
  inoremap <buffer> <silent> <cr>  <c-y><c-\><c-n>:call b:complete_data.conclude()<cr>
  inoremap <buffer> <silent> <c-y> <c-y><c-\><c-n>:call b:complete_data.conclude()<cr>
  " Unlike usual <tab> behaviour, this time, <tab> inserts the next match
  inoremap <buffer> <silent> <tab> <down><c-y><c-\><c-n>:call b:complete_data.conclude()<cr>
  " <c-o><Nop> doesn't work as expected...
  " To stay in INSERT-mode:
  " inoremap <silent> <esc> <c-e><c-o>:<cr>
  " To return into NORMAL-mode:
  inoremap <buffer> <silent> <esc> <c-e><esc>
  " TODO: see to have <Left>, <Right>, <Home>, <End> abort

  " Group {{{4
  exe 'augroup '.augroup
    au!
    " Emulate InsertCharPost
    " au CompleteDone <buffer> call b:complete_data.logger.log("Completion done")
    au InsertLeave  <buffer> call b:complete_data.finalize()
    au CursorMovedI <buffer> call b:complete_data.cursor_moved()
  augroup END

  function! s:cursor_moved() abort dict "{{{4
    if self.no_more_matches
      call self.finalize()
      return
    endif
    if !self.has_text_changed_since_last_move()
      call s:logger.log(lh#fmt#printf("cursor %1 just moved (text hasn't changed)", string(getpos('.'))))
      return
    endif
    call s:logger.log(lh#fmt#printf('cursor moved %1 and text has changed -> relaunch completion', string(getpos('.'))))
    call feedkeys( "\<C-X>\<C-O>\<C-P>\<Down>", 'n' )
  endfunction
  let b:complete_data.cursor_moved = function('s:cursor_moved')

  function! s:has_text_changed_since_last_move() abort dict "{{{4
    let l = line('.')
    let line = getline('.')
    try
      if l != self.last_content[0]  " moved vertically
        let self.no_more_matches = 1
        call s:logger.log("Vertical move => stop")
        return 0
        " We shall leave complete mode now!
      endif
      call s:logger.log(lh#fmt#printf("line was: %1, and becomes: %2; has_changed?%3", self.last_content[1], line, line != self.last_content[1]))
      return line != self.last_content[1] " text changed
    finally
      let self.last_content = [l, line]
    endtry
  endfunction
  let b:complete_data.has_text_changed_since_last_move = function('s:has_text_changed_since_last_move')

  function! s:complete(findstart, base) abort dict "{{{4
    call s:logger.log(lh#fmt#printf('findstart?%1 -> %2', a:findstart, a:base))
    if a:findstart
      if self.no_more_matches
        call s:logger.log("no more matches -> -3")
        return -3
        call self.finalize()
      endif
      if self.cursor_pos == getcurpos()
        call s:logger.log("cursor hasn't moved -> -2")
        return -2
      endif
      let self.cursor_pos = getcurpos()
      return self.startcol
    else
      return self.get_completions(a:base)
    endif
  endfunction
  let b:complete_data.complete = function('s:complete')

  function! s:get_completions(base) abort dict "{{{4
    let matching = filter(copy(self.all_matches), 'v:val.word =~ join(split(a:base, ".\\zs"), ".*")')
    let self.matches.words = matching
    call s:logger.log(lh#fmt#printf("'%1' matches: %2", a:base, string(self.matches)))
    if empty(self.matches.words)
      call s:logger.log("No more matches...")
      let self.no_more_matches = 1
    endif
    return self.matches
  endfunction
  let b:complete_data.get_completions = function('s:get_completions')

  function! s:conclude() abort dict " {{{4
    let selection = getline('.')[self.startcol : col('.')-1]
    call s:logger.log("Successful selection of <".selection.">")
    if !empty(self.hook)
      call lh#function#execute(self.hook, selection)
    endif
    " call self.hook()
    call self.finalize()
  endfunction
  let b:complete_data.conclude = function('s:conclude')

  " Register {{{4
  " call b:complete_data
        " \.restore('b:complete_data')
  " set completefunc=lh#icomplete#func
  set omnifunc=lh#icomplete#func
endfunction

" Function: lh#icomplete#new_on(pattern, matches, hook) {{{3
function! lh#icomplete#new_on(pattern, matches, hook) abort
  let l = getline('.')
  let startcol = match(l[0:col('.')-1], '\v'.a:pattern.'+$')
  if startcol == -1
    let startcol = col('.')-1
  endif
  call lh#icomplete#new(startcol, a:matches, a:hook)
endfunction

" Function: lh#icomplete#func(startcol, base) {{{3
function! lh#icomplete#func(findstart, base) abort
  return b:complete_data.complete(a:findstart, a:base)
endfunction

जिसका उपयोग किया जा सकता है:

let entries = [
  \ {'word': 'un', 'menu': 1},
  \ {'word': 'deux', 'menu': 2},
  \ {'word': 'trois', 'menu': 3},
  \ {'word': 'trentre-deux', 'menu': 32},
  \ 'unité'
  \ ]
inoremap <silent> <buffer> µ <c-o>:call lh#icomplete#new_on('\w', entries, 'lh#common#warning_msg("nominal: ".v:val)')<cr><c-x><c-O><c-p><down>

आप इस स्क्रेंस्ट पर मेरे टेम्पलेट विस्तारक प्लगइन के लिए C ++ स्निपेट चयन के लिए लागू परिणाम (परोक्ष रूप से) का निरीक्षण करने में सक्षम होना चाहिए ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.