কীভাবে আমার নিজের স্বয়ংসম্পূর্ণ ফাংশন তৈরি করবেন?


22

নির্দিষ্ট ফাইল টাইপের জন্য আমি কীভাবে আমার নিজের স্বয়ংক্রিয় সমাপ্তির তালিকা তৈরি করব?

উদাহরণস্বরূপ আমি ফন্টআউবিজে সিএসএস ক্লাসগুলির তালিকা থেকে সিএসএস এবং এইচটিএমএল স্বতঃপূরণ করতে চাই ।

উত্তর:


22

অভিধানের সমাপ্তি একটি সস্তা এবং অ-হস্তক্ষেপমূলক সমাধান হতে পারে:

  1. আপনার মেশিনে কোথাও fontawesome.txt সংরক্ষণ করুন,

  2. এটি রাখুন after/ftplugin/css.vim(ফাইলটি উপস্থিত না থাকলে এটি তৈরি করুন):

    setlocal complete+=k
    setlocal dictionary+=/path/to/fontawesome.txt
    setlocal iskeyword+=-
    
  3. একটি নতুন সেশন শুরু করুন বা :eউপরের ফাইলটি জোর করে উত্স হিসাবে সিএসএস বাফারে করুন,

  4. টিপুন <C-n>বা <C-p>সন্নিবেশ মোডে,

  5. উপভোগ করেন!

    অভিধান সমাপ্তি

রেফারেন্স:

:help ins-completion
:help 'complete'
:help 'dictionary'
:help 'iskeyword'

17

সম্পাদনা রোমেনেলের মন্তব্যে ধন্যবাদ আমি কীভাবে একটি ব্যবহারকারী-সংজ্ঞায়িত সমাপ্তি ফাংশন তৈরি করব তা দেখানোর জন্য আমার উত্তরটি সম্পাদনা করেছি। পূর্ববর্তী সংস্করণে আমি বুয়েল-ইন ওমনি-সমাপ্তিকে ওভাররাইড করছিলাম যা ভাল ছিল না কারণ ব্যবহারকারীর ডিফল্ট সমাপ্তিটি looseিলা হবে যা বেশ শক্তিশালী।


একটি প্রতিলিপি সমাধান

একটি সমাধান হ'ল ভিমস্ক্রিপ্ট এবং সত্য যে ভিম আপনাকে কাস্টমাইজড সমাপ্তির ফাংশন তৈরি করতে দেয় use

এই সমাধানটির সুবিধাটি হ'ল আপনার অতিরিক্ত প্লাগইনের দরকার নেই আপনি কেবল ব্যবহারকারী-সংজ্ঞায়িত সমাপ্তি ফাংশন তৈরি করতে পারবেন এবং বিল্ট-ইন সমাপ্তি বৈশিষ্ট্যটি ব্যবহার করতে পারেন।

আমি আপনার ফন্টে অসাধারণ ক্লাসের উদাহরণ ব্যবহার করব css:

ফাইলটি তৈরি করুন ~/.vim/autoload/csscomplete.vimএবং এতে নিম্নলিখিত লাইনগুলি রাখুন:

let s:matches=".fa-lg .fa-2x .fa-3x .fa-4x .fa-5x .fa-fw .fa-ul .fa-ul .fa-li .fa-li.fa-lg .fa-border .fa-pull-left .fa-pull-right .fa.fa-pull-left"

function! csscomplete#CompleteFA(findstart, base)
    if a:findstart
        " locate the start of the word
        let line = getline('.')
        let start = col('.') - 1
        while start > 0 && (line[start - 1] =~ '\a' || line[start - 1] =~ '.' || line[start - 1] =~ '-')
            let start -= 1
        endwhile
        return start
    else
        " find classes matching "a:base"
        let res = []
        for m in split(s:matches)
            if m =~ '^' . a:base
                call add(res, m)
            endif
        endfor
        return res
    endif
endfun

তারপরে ফাইলটি তৈরি করুন ~/.vim/after/ftplugin/css.vimএবং এটিতে নিম্নলিখিত লাইনটি দিন:

setlocal completefunc=csscomplete#CompleteFA

তারপরে আপনি এর সাথে আপনার ব্যবহারকারীর সংজ্ঞায়িত সমাপ্তির কার্যটি ট্রিগার করতে পারেন <C-x><C-u>। এটি সর্বশেষ টাইপ করা শব্দের সাথে মিল খুঁজে পাওয়ার চেষ্টা করবে।

স্ক্রিনশটটিতে আমি টাইপ করেছি .fa-lএবং তার সাথে ফাংশনটি ট্রিগার করেছিলাম <C-x><C-u>:

এখানে চিত্র বর্ণনা লিখুন


এটা কিভাবে কাজ করে?

প্রথমে এখানে কিছু প্রাসঙ্গিক ডকুমেন্টেশন বিষয় রয়েছে:

আপনি যদি কোনও নির্দিষ্ট ফাইল টাইপের জন্য একটি পছন্দসই সমাপ্তি তৈরি করতে চান তবে আপনাকে এটি ফাইলের মধ্যে রাখতে হবে $HOME/.vim/autoload/{FILETYPE}complete.vim

তারপরে এই ফাইলে আপনাকে আপনার সমাপ্তির ফাংশন তৈরি করতে হবে যা দুটিবার বলা হয়:

  • প্রথম কলটিতে তার প্রথম যুক্তিটি কার্সারের বর্তমান অবস্থান এবং ফাংশনটি শব্দটি সম্পূর্ণ করতে নির্ধারণ করবে। আমার ফাংশনে আমি শব্দটি সম্পন্ন করার জন্য 3 টি তুলনা ব্যবহার করেছি কারণ শ্রেণিটি বর্ণের সমন্বয়ে তৈরি করা যেতে পারে, .এবং - (আমি মনে করি এই মিলটি উন্নত করা সম্ভব তবে আমি সত্যিকার অর্থেই রেজিক্সের সাথে খারাপ)

  • দ্বিতীয় কলে দ্বিতীয় যুক্তি শব্দ মেলে এবং তারপর ফাংশন সম্ভব ক্লাস তালিকায় তুলনা মেলে 1 । এখানে আপনি দেখতে পাচ্ছেন যে আমি একটি অভিধানটি ফিরিয়ে দিচ্ছি যা সমাপ্তি মেনুটিকে জনপ্রিয় করবে তবে আপনি যখন ডকুমেন্টেশনটি পড়বেন তখন আপনি দেখতে পাবেন যে আপনি আরও বেশি জটিল অভিধান তৈরি করতে পারবেন আপনার ফাংশনের আচরণকে আরও কাস্টমাইজ করার জন্য।

আপনাকে এই ধরণের ফাইলের জন্য ভিমকেও বলতে হবে, আমার তৈরি এই সম্পূর্ণ ফাংশনটি ব্যবহার করুন "। এটি করার completefuncজন্য আপনাকে তৈরি করা ফাংশনের নামটি সেট করতে হবে (এখানে csscomplete#CompleteFA) এবং এই সেটিংটি অবশ্যই ফাইলে করা উচিত $HOME/.vim/after/ftplugin/{FILETYPE}.vim

1 আমার ফাংশনে s:matchesচলকটিতে সমস্ত সম্ভাব্য মিল রয়েছে। এখানে আমি কেবল পঠনযোগ্যতার জন্য কিছু পরামর্শ রেখেছি তবে আপনি ফন্টআউবাইজের দ্বারা প্রদত্ত সমস্ত ক্লাস রাখতে পারেন (রোমেনেলের তৈরি এই ফাইলটিতে আপনি সম্পূর্ণ তালিকা খুঁজে পেতে পারেন )।


আমি যদি ভিমস্ক্রিপ্ট পছন্দ না করি?

একটি সম্ভাবনা হ'ল কমলিউম প্লাগইনটি ব্যবহার করুন যা সমাপ্তি মেনুতে খেলতে একটি এপিআই দেয়। আপনি পাইথন ফাংশন তৈরি করতে পারেন যা মিলবে কাজ করবে এবং ভিআইএম ইন্টারফেস পপুলেট করতে এপিআই ব্যবহার করবে। আরও বিশদ এখানে


2
সিএসএস এবং এইচটিএমএলের জন্য ডিফল্ট ওমনি সমাপ্তি ইতিমধ্যে বেশ কার্যকর এবং আপনার একবারে একটি মাত্র থাকতে পারে তাই আমি তার পরিবর্তে "ব্যবহারকারীর সংজ্ঞায়িত সমাপ্তি" ব্যবহারের পরামর্শ দেব। দেখুন :help i_ctrl-x_ctrl-u
রোমেনেল

@রোমেনাল: আপনি একেবারে ঠিক বলেছেন, আমি কীভাবে আমার উত্তরটি মানিয়ে নেব তা দেখব।
স্টাটক্স

5

কখনও কখনও আপনি এমন একটি কাস্টম স্বয়ংক্রিয়-সমাপ্তি চান যা কোনও অন্তর্নির্মিত বা ব্যবহারকারীর দ্বারা সংজ্ঞায়িত স্বতঃপূরণকে মোটেই বাধা দেয় না। স্ক্রিপ্ট বা প্লাগইনগুলির জন্য এটি বিশেষত দরকারী যা বিস্তৃত ফাইল টাইপের কাজ করার উদ্দেশ্যে।

এটি complete() ফাংশন এবং একটি সাধারণ মোড়কের সাহায্যে মোটামুটি সহজ করা যেতে পারে ; প্রক্রিয়াটির বেশিরভাগই বর্ণিত হিসাবে বর্ণিত :help complete-functions এবং স্ট্যাটক্সের উত্তরের মতো একই , আপনাকে নিজের ম্যাপিংগুলি সংজ্ঞায়িত করতে হবে এবং কোনও মান ফেরানোর complete()পরিবর্তে নিজেকে কল করতে হবে।

এখানে একটি প্রাথমিক উদাহরণ দেওয়া হয়েছে, মন্তব্যগুলিতে এটি কীভাবে কাজ করে তা ব্যাখ্যা করা উচিত।

" Map <C-x><C-m> for our custom completion
inoremap <C-x><C-m> <C-r>=MyComplete()<CR>

" Make subsequent <C-m> presses after <C-x><C-m> go to the next entry (just like
" other <C-x>* mappings)
inoremap <expr> <C-m> pumvisible() ?  "\<C-n>" : "\<C-m>"

" Complete function for addresses; we match the name & address
fun! MyComplete()
    " The data. In this example it's static, but you could read it from a file,
    " get it from a command, etc.
    let l:data = [
        \ ["Elmo the Elk", "daring@brave.com"],
        \ ["Eek the Cat", "doesnthurt@help.com"]
    \ ]

    " Locate the start of the word and store the text we want to match in l:base
    let l:line = getline('.')
    let l:start = col('.') - 1
    while l:start > 0 && l:line[l:start - 1] =~ '\a'
        let l:start -= 1
    endwhile
    let l:base = l:line[l:start : col('.')-1]

    " Record what matches − we pass this to complete() later
    let l:res = []

    " Find matches
    for m in l:data
        " Check if it matches what we're trying to complete; in this case we
        " want to match against the start of both the first and second list
        " entries (i.e. the name and email address)
        if l:m[0] !~? '^' . l:base && l:m[1] !~? '^' . l:base
            " Doesn't match
            continue
        endif

        " It matches! See :help complete() for the full docs on the key names
        " for this dict.
        call add(l:res, {
            \ 'icase': 1,
            \ 'word': l:m[0] . ' <' . l:m[1] . '>, ',
            \ 'abbr': l:m[0],
            \ 'menu': l:m[1],
            \ 'info': len(l:m) > 2 ? join(l:m[2:], "\n") : '',
        \ })
    endfor

    " Now call the complete() function
    call complete(l:start + 1, l:res)
    return ''
endfun
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.