আপনি maparg()
ফাংশন ব্যবহার করতে পারে।
ব্যবহারকারী <C-c>
সাধারণ মোডে কিছু ম্যাপ করেছেন কিনা তা পরীক্ষা করতে আপনি লিখবেন:
if !empty(maparg('<C-c>', 'n'))
{rhs}
ভেরিয়েবলটিতে স্টোর সংরক্ষণ করতে যদি ব্যবহারকারী কোনও কিছু ম্যাপ করেন তবে আপনি লিখবেন:
let rhs_save = maparg('<C-c>', 'n')
আপনি যদি ম্যাপিং সম্পর্কিত আরও তথ্য চান তবে:
- এটা কি নীরব (
<silent>
যুক্তি)?
- এটি কি বর্তমান বাফারের (
<buffer>
যুক্তি) স্থানীয় ?
- হয়
{rhs}
একটি অভিব্যক্তি (মূল্যায়ন <expr>
যুক্তি)?
- এটি
{rhs}
( nnoremap
বনাম nmap
) পুনর্নির্মাণ না ?
- যদি ব্যবহারকারীটির সাথে আর একটি ম্যাপিং থাকে যা দিয়ে শুরু হয়
<C-c>
, তবে কি ভিম আরও অক্ষর টাইপ হওয়ার জন্য অপেক্ষা করবেন ( <nowait>
যুক্তি)?
- ...
তারপরে, আপনি একটি তৃতীয় এবং চতুর্থ যুক্তি দিতে পারেন: 0
এবং 1
।
0
কারণ আপনি কোনও ম্যাপিংয়ের সন্ধান করছেন এবং কোনও সংক্ষেপণ নয়, এবং 1
আপনি সর্বাধিক তথ্য সহ একটি অভিধান চান যা কেবল {rhs}
মান হিসাবে নয়:
let map_save = maparg('<C-c>', 'n', 0, 1)
ধরে নিই যে ব্যবহারকারী তার ম্যাপিংয়ে কোনও বিশেষ যুক্তি ব্যবহার করেনি এবং এটি {rhs}
পুনরুদ্ধার করতে এটি পুনরায় তৈরি করতে পারে না, আপনি কেবল লিখতে পারেন:
let rhs_save = maparg('<C-c>', 'n')
" do some stuff which changes the mapping
exe 'nnoremap <C-c> ' . rhs_save
বা নিশ্চিত হয়ে এবং সম্ভাব্য সমস্ত যুক্তি পুনরুদ্ধার করতে:
let map_save = maparg('<C-c>', 'n', 0, 1)
" do some stuff which changes the mapping
exe (map_save.noremap ? 'nnoremap' : 'nmap') .
\ (map_save.buffer ? ' <buffer> ' : '') .
\ (map_save.expr ? ' <expr> ' : '') .
\ (map_save.nowait ? ' <nowait> ' : '') .
\ (map_save.silent ? ' <silent> ' : '') .
\ ' <C-c> ' .
\ map_save.rhs
সম্পাদনা: দুঃখিত, আমি ঠিক বুঝতে পেরেছি যদি ব্যবহারকারী {rhs}
ম্যাপিংয়ের মধ্যে কোনও স্ক্রিপ্ট-লোকাল ফাংশন কল করে তবে এটি প্রত্যাশা অনুযায়ী কাজ করবে না ।
মনে করুন যে ব্যবহারকারীর তার ভিতরে নিম্নলিখিত ম্যাপিং রয়েছে vimrc
:
nnoremap <C-c> :<C-U>call <SID>FuncA()<CR>
function! s:FuncA()
echo 'hello world!'
endfunction
যখন সে আঘাত করে <C-c>
, এটি বার্তাটি প্রদর্শন করে hello world!
।
এবং আপনার প্লাগইনে, আপনি সমস্ত তথ্য সহ একটি অভিধান সংরক্ষণ করেন, তারপরে অস্থায়ীভাবে তার ম্যাপিংটি এভাবে পরিবর্তন করুন:
let map_save = maparg('<C-c>', 'n', 0, 1)
nnoremap <C-c> :<C-U>call <SID>FuncB()<CR>
function! s:FuncB()
echo 'bye all!'
endfunction
এখন, এটি প্রদর্শিত হবে bye all!
। আপনার প্লাগইনটি কিছু কাজ করে এবং এটি শেষ হয়ে গেলে এটি পূর্ববর্তী কমান্ডের সাহায্যে ম্যাপিং পুনরুদ্ধার করার চেষ্টা করে।
এটি সম্ভবত এমন বার্তায় ব্যর্থ হবে:
E117: Unknown function: <SNR>61_FuncA
61
আপনার ম্যাপিং কমান্ডটি কার্যকর করা হবে এমন স্ক্রিপ্টটির কেবলমাত্র শনাক্তকারী। এটি অন্য কোনও নম্বর হতে পারে। আপনার প্লাগইন 42th ব্যবহারকারীর সিস্টেমে sourced ফাইল হয়, তাহলে এটি হতে হবে 42
।
একটি স্ক্রিপ্টের অভ্যন্তরে, যখন কোনও ম্যাপিং কমান্ড কার্যকর করা হয়, তখন ভিম স্বয়ংক্রিয়ভাবে স্বরলিপিটি <SID>
বিশেষ কী কোডে অনুবাদ করে <SNR>
, এর পরে একটি নম্বর স্ক্রিপ্টের জন্য অনন্য এবং একটি আন্ডারস্কোর হয়। এটি করতে হবে, কারণ যখন ব্যবহারকারী হিট করবে <C-c>
, তখন ম্যাপিংটি স্ক্রিপ্টের বাইরে কার্যকর করা হবে এবং এভাবে কোন স্ক্রিপ্ট FuncA()
সংজ্ঞায়িত হবে তা তা জানতে পারবে না ।
সমস্যাটি হ'ল আসল ম্যাপিংটি আপনার প্লাগইনের চেয়ে আলাদা স্ক্রিপ্টে উত্সাহিত হয়েছিল, সুতরাং এখানে স্বয়ংক্রিয় অনুবাদটি ভুল। এটি আপনার স্ক্রিপ্টের সনাক্তকারী ব্যবহার করে, যখন এটি ব্যবহারকারীর সনাক্তকারী ব্যবহার করে vimrc
।
তবে আপনি নিজেই অনুবাদটি করতে পারতেন। অভিধান map_save
একটি কী বলা রয়েছে 'sid'
যার মান সঠিক আইডেন্টিফায়ার।
সুতরাং, পূর্ববর্তী পুনরুদ্ধার কমান্ডটি আরও শক্তিশালী করার জন্য আপনি এর map_save.rhs
সাথে প্রতিস্থাপন করতে পারেন :
substitute(map_save.rhs, '<SID>', '<SNR>' . map_save.sid . '_', 'g')
যদি {rhs}
মূল ম্যাপিং থাকে তবে <SID>
এটি সঠিকভাবে অনুবাদ করা উচিত। অন্যথায়, কিছুই পরিবর্তন করা উচিত।
এবং আপনি যদি কোডটি কিছুটা ছোট করতে চান তবে আপনি 4 টি লাইন প্রতিস্থাপন করতে পারেন যা বিশেষ যুক্তিগুলির যত্ন করে:
join(map(['buffer', 'expr', 'nowait', 'silent'], 'map_save[v:val] ? "<" . v:val . ">": ""'))
map()
ফাংশন তালিকা থেকে প্রতিটি আইটেমের রূপান্তর করা উচিত ['buffer', 'expr', 'nowait', 'silent']
সংশ্লিষ্ট ম্যাপিং আর্গুমেন্ট মধ্যে কিন্তু তার মূল ভিতরে শুধুমাত্র যদি map_save
অ শূন্য। এবং join()
সমস্ত আইটেম একটি স্ট্রিং মধ্যে যোগদান করা উচিত।
সুতরাং, ম্যাপিং সংরক্ষণ এবং পুনরুদ্ধারের আরও শক্তিশালী উপায় হতে পারে:
let map_save = maparg('<C-c>', 'n', 0, 1)
" do some stuff which changes the mapping
exe (map_save.noremap ? 'nnoremap' : 'nmap') .
\ join(map(['buffer', 'expr', 'nowait', 'silent'], 'map_save[v:val] ? "<" . v:val . ">": ""')) .
\ map_save.lhs . ' ' .
\ substitute(map_save.rhs, '<SID>', '<SNR>' . map_save.sid . '_', 'g')
Edit2:
আমি আপনার মতো একই সমস্যার মুখোমুখি হচ্ছি, কীভাবে কোনও অঙ্কন প্লাগইনে কোনও ম্যাপিং সংরক্ষণ এবং পুনরুদ্ধার করবেন। এবং আমি মনে করি যে আমি 2 টি সমস্যা পেয়েছি যা প্রাথমিক উত্তরটি আমি লেখার সময় দেখিনি, সে সম্পর্কে দুঃখিত sorry
প্রথম ইস্যু, ধরুন যে ব্যবহারকারী <C-c>
একটি গ্লোবাল ম্যাপিং ব্যবহার করে তবে একটি বাফার-লোকাল ম্যাপিংয়েও ব্যবহার করে। উদাহরণ:
nnoremap <C-c> :echo 'global mapping'<CR>
nnoremap <buffer> <C-c> :echo 'local mapping'<CR>
এই ক্ষেত্রে, maparg()
স্থানীয় ম্যাপিংকে অগ্রাধিকার দেবে:
:echo maparg('<C-c>', 'n', 0, 1)
---> {'silent': 0, 'noremap': 1, 'lhs': '<C-C>', 'mode': 'n', 'nowait': 0, 'expr': 0, 'sid': 7, 'rhs': ':echo ''local mapping''<CR>', 'buffer': 1}
যা নিশ্চিত :h maparg()
:
The mappings local to the current buffer are checked first,
then the global mappings.
তবে আপনি বাফার-লোকাল ম্যাপিংয়ে আগ্রহী নন, সম্ভবত আপনি বিশ্বব্যাপী এটি চান।
বিশ্বব্যাপী ম্যাপিং সম্পর্কে আমি নির্ভরযোগ্যতার সাথে তথ্য পাওয়ার একমাত্র উপায়টি হ'ল একই কী ব্যবহার করে সাময়িকভাবে কোনও সম্ভাব্য, ছায়াযুক্ত, বাফার-লোকাল ম্যাপিংকে আনম্যাপ করার চেষ্টা করা।
এটি 4 টি ধাপে করা যেতে পারে:
- কীটি ব্যবহার করে একটি (সম্ভাব্য) বাফার-লোকাল ম্যাপিং সংরক্ষণ করুন
<C-c>
:silent! nunmap <buffer> <C-c>
একটি (সম্ভাব্য) বাফার-লোকাল ম্যাপিং মুছতে এক্সিকিউট করুন
- গ্লোবাল ম্যাপিং সংরক্ষণ করুন (
maparg('<C-c>', 'n', 0, 1)
)
- বাফার-লোকাল ম্যাপিং পুনরুদ্ধার করুন
দ্বিতীয় সংখ্যাটি নিম্নরূপ। মনে করুন যে ব্যবহারকারী কোনও মানচিত্র তৈরি করেনি <C-c>
, তবে এর ফলাফল maparg()
একটি খালি অভিধান হবে। এবং এই ক্ষেত্রে, পুনরুদ্ধার প্রক্রিয়াটি ম্যাপিং ( :nnoremap
) স্থাপনের সাথে অন্তর্ভুক্ত নয়, তবে ম্যাপিং ( ) এর ধ্বংসের ক্ষেত্রে :nunmap
।
এই 2 টি নতুন সমস্যা সমাধানের চেষ্টা করার জন্য, আপনি ম্যাপিংগুলি সংরক্ষণ করতে এই ফাংশনটি চেষ্টা করতে পারেন:
fu! Save_mappings(keys, mode, global) abort
let mappings = {}
if a:global
for l:key in a:keys
let buf_local_map = maparg(l:key, a:mode, 0, 1)
sil! exe a:mode.'unmap <buffer> '.l:key
let map_info = maparg(l:key, a:mode, 0, 1)
let mappings[l:key] = !empty(map_info)
\ ? map_info
\ : {
\ 'unmapped' : 1,
\ 'buffer' : 0,
\ 'lhs' : l:key,
\ 'mode' : a:mode,
\ }
call Restore_mappings({l:key : buf_local_map})
endfor
else
for l:key in a:keys
let map_info = maparg(l:key, a:mode, 0, 1)
let mappings[l:key] = !empty(map_info)
\ ? map_info
\ : {
\ 'unmapped' : 1,
\ 'buffer' : 1,
\ 'lhs' : l:key,
\ 'mode' : a:mode,
\ }
endfor
endif
return mappings
endfu
... এবং এগুলি তাদের পুনরুদ্ধার করার জন্য:
fu! Restore_mappings(mappings) abort
for mapping in values(a:mappings)
if !has_key(mapping, 'unmapped') && !empty(mapping)
exe mapping.mode
\ . (mapping.noremap ? 'noremap ' : 'map ')
\ . (mapping.buffer ? ' <buffer> ' : '')
\ . (mapping.expr ? ' <expr> ' : '')
\ . (mapping.nowait ? ' <nowait> ' : '')
\ . (mapping.silent ? ' <silent> ' : '')
\ . mapping.lhs
\ . ' '
\ . substitute(mapping.rhs, '<SID>', '<SNR>'.mapping.sid.'_', 'g')
elseif has_key(mapping, 'unmapped')
sil! exe mapping.mode.'unmap '
\ .(mapping.buffer ? ' <buffer> ' : '')
\ . mapping.lhs
endif
endfor
endfu
Save_mappings()
ফাংশন ম্যাপিং সংরক্ষণ করতে ব্যবহার করা যেতে পারে।
এটি 3 টি যুক্তি প্রত্যাশা করে:
- কীগুলির একটি তালিকা; উদাহরণ:
['<C-a>', '<C-b>', '<C-c>']
- একটি মোড; উদাহরণ:
n
সাধারণ মোডের x
জন্য বা ভিজ্যুয়াল মোডের জন্য
- একটি বুলিয়ান পতাকা; যদি এটি হয় তবে এর
1
অর্থ হ'ল আপনি বিশ্বব্যাপী ম্যাপিংগুলিতে আগ্রহী, এবং যদি এটি 0
স্থানীয় ক্ষেত্রে থাকে
এটি দিয়ে, আপনি বিশ্বব্যাপী কীগুলি ব্যবহার করে ম্যাপিং বাঁচাতে পারে C-a
, C-b
এবং C-c
, স্বাভাবিক মোডে, একটি অভিধান ভিতরে:
let your_saved_mappings = Save_mappings(['<C-a>', '<C-b>', '<C-c>'], 'n', 1)
এরপরে, আপনি যখন ম্যাপিংগুলি পুনরুদ্ধার করতে চান, আপনি কল করতে পারেন Restore_mappings()
, সমস্ত তথ্য সম্বলিত অভিধানটি একটি আর্গুমেন্ট হিসাবে পাস করে:
call Restore_mappings(your_saved_mappings)
বাফার-লোকাল ম্যাপিংগুলি সংরক্ষণ / পুনরুদ্ধার করার সময় একটি তৃতীয় সমস্যা হতে পারে। কারণ, আমরা যখন ম্যাপিংগুলি সংরক্ষণ করেছি এবং সেই মুহুর্তের মধ্যে যখন আমরা সেগুলি পুনরুদ্ধার করার চেষ্টা করব তখনকার বর্তমান বাফারটি পরিবর্তিত হতে পারে।
এই ক্ষেত্রে, Save_mappings()
বর্তমান বাফারের সংখ্যা সংরক্ষণ করে ফাংশনটি উন্নত হতে পারে ( bufnr('%')
)।
এবং তারপরে, Restore_mappings()
ডান বাফারে বাফার-লোকাল ম্যাপিংগুলি পুনরুদ্ধার করতে এই তথ্যটি ব্যবহার করবে। আমরা সম্ভবত :bufdo
কমান্ডটি ব্যবহার করতে পারতাম , একটি গণনা দিয়ে পূর্বের উপসর্গটি ব্যবহার করতে পারি (পূর্বে সংরক্ষিত বাফার সংখ্যার সাথে মিল রেখে) এবং ম্যাপিং কমান্ডের সাথে এটি প্রত্যয় দিয়েছি ।
হতে পারে এরকম কিছু:
:{original buffer number}bufdo {mapping command}
bufexists()
ফাংশনটি ব্যবহার করে বাফারটি এখনও বিদ্যমান আছে কিনা তা আমাদের প্রথমে পরীক্ষা করে দেখতে হবে, কারণ এর মধ্যে এটি মুছে ফেলা হতে পারে।