গতিশীল সমাপ্তি


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আমি আমার বাফারে যা পাই।

আমি কী ভুল করেছি বা ডকুমেন্টেশনে মিস করেছি?

নোট: আমি দেখেছি যে ছাড়া refresh=always, ফলাফলগুলি ফিল্টার করা হয়, ব্যতীত আমি কাস্টম ফিল্টার প্রয়োগ করতে আবার ফাংশনটিতে কল করতে চাই।

(কেবলমাত্র আমি জিভিএম 7.4-908 ব্যবহার করছি)


এটি একটি বাগের মতো মনে হচ্ছে। এটি আমার পক্ষে কাজ করে না (আমি ভিম 7.4.944 এ আছি)।
কার্ল ইংভে লেরভেগ

এটা কাজ করা উচিত? এটাই আমি জানি না।
লুক হার্মিটে

ডকুমেন্টেশনটি বোঝায় যে এটি কাজ করা উচিত।
কার্ল ইঙ্গভে লেরভেগ

উত্তর:


3

আরও তদন্তের পরে (এবং কিছু বিপরীত প্রকৌশল)।

সমাপ্তি কেন ডকুমেন্টেশন কঠোরভাবে অনুসরণ করে না তা আমি ব্যাখ্যা করতে পারি না। আমার মনে হয় ভিম_দেবকে জিজ্ঞাসা করতে হবে।

যাইহোক, মনে হচ্ছে এটি করার উপায়টি CursorMovedIযখনই কোনও চরিত্র everyোকানো হয় ততক্ষণে এটির পুনরায় শ্রোতার নিবন্ধকরণ অন্তর্ভুক্ত।

অসুবিধাটি তখন কখন থামবে তা জানা।

  • 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>

আপনি এই স্ক্রিনকাস্টে আমার টেম্পলেট এক্সপেন্ডার প্লাগইনের জন্য সি ++ স্নিপেট নির্বাচনের ক্ষেত্রে ফল প্রয়োগ (অপ্রত্যক্ষভাবে) পর্যবেক্ষণ করতে সক্ষম হবেন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.