आप 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
उस स्क्रिप्ट की पहचानकर्ता है जिसमें आपकी मैपिंग कमांड निष्पादित की जाएगी। यह कोई अन्य संख्या हो सकती है। यदि आपका प्लगइन उपयोगकर्ता के सिस्टम पर 42 वाँ फ़ाइल है, तो यह होगा 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 मुद्दों को पाया है जो प्रारंभिक उत्तर उस समय नहीं देखा था जब मैंने इसे लिखा था, इसके बारे में क्षमा करें।
पहला मुद्दा, मान लीजिए कि उपयोगकर्ता <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)
बफर-स्थानीय मैपिंग को सहेजते / बहाल करते समय एक 3 समस्या हो सकती है। क्योंकि, उन क्षणों के बीच जब हमने मैपिंग को सहेजा है, और जिस क्षण हम उन्हें पुनर्स्थापित करने का प्रयास करते हैं, वर्तमान बफर बदल सकता है।
इस स्थिति में, हो Save_mappings()
सकता है कि वर्तमान बफर ( bufnr('%')
) की संख्या को बचाकर फ़ंक्शन को बेहतर बनाया जा सके ।
और फिर, Restore_mappings()
इस जानकारी का उपयोग सही बफर में बफर-स्थानीय मैपिंग को पुनर्स्थापित करने के लिए करेंगे। हम संभवतः :bufdo
कमांड का उपयोग कर सकते हैं , उत्तरार्द्ध को एक गिनती के साथ उपसर्ग कर सकते हैं (पहले सहेजे गए बफर नंबर से मेल खाते हुए), और इसे मैपिंग कमांड के साथ प्रत्यय दें।
शायद कुछ इस तरह:
:{original buffer number}bufdo {mapping command}
हमें पहले चेक करना होगा कि क्या बफर अभी भी मौजूद है, bufexists()
फ़ंक्शन का उपयोग करते हुए , क्योंकि इस बीच इसे हटाया जा सकता था।