एक संख्या सूची के साथ तारांकन बुलेट बुलेट बिंदुओं की एक श्रृंखला को बदलें


16

कल्पना कीजिए कि मेरे पास निम्नलिखित पाठ है:

some random stuff
* asdf
* foo
* bar
some other random stuff

मैं संख्या के साथ तार की गोलियों को बदलना चाहता हूं, जैसे:

some random stuff
1. asdf
2. foo
3. bar
some other random stuff

यह विम में कैसे किया जा सकता है?


आप प्लगइन्स के लिए क्यों नहीं जाते हैं? इसी तरह का एक वेतन वृद्धि है।
गिथुब में सिविम

यह इतना अद्भुत और शांत है कि हर किसी ने अपने जवाबों की संख्या में वृद्धि की है, लेकिन चूंकि मार्कडाउन उन्हें आपके लिए नंबर देगा क्यों न केवल उन सभी को बनाएं 1.? तो :%s/^* /1. /कर लेती। जो बहुत कम काम की तरह लगता है।
चूजों

जवाबों:


14

आप निम्न आदेश आज़मा सकते हैं:

:let c=0 | g/^* /let c+=1 | s//\=c.'. '

पहले यह वैरिएबल c( let c=0) को इनिशियलाइज़ करता है , फिर यह ग्लोबल कमांड को निष्पादित करता है gजो पैटर्न ^*(लाइन की शुरुआत, इसके बाद एक तारांकन और एक स्थान) के लिए दिखता है ।

जब भी इस पैटर्न रखने वाली पंक्ति पाया जाता है, वैश्विक आदेश आदेश निष्पादित करता है:
let c+=1 | s//\=c.'. '
यह चर वृद्धि कर देता है c( let c+=1), तो ( |) यह विकल्प ( s) पिछले पैटर्न (खोजा गया //एक अभिव्यक्ति (के मूल्यांकन के साथ) \=):
चर की सामग्री को cश्रेणीबद्ध ( .) स्ट्रिंग के साथ'. '


यदि आप अपने बफर से सभी लाइनों को संशोधित नहीं करना चाहते हैं, लेकिन केवल एक विशिष्ट पैराग्राफ, आप वैश्विक कमांड के लिए एक सीमा पारित कर सकते हैं। उदाहरण के लिए, केवल उन पंक्तियों को संशोधित करने के लिए जिनकी संख्या 5 और 10 के बीच है:

:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '

यदि आपके पास कई समान सूचियों वाली फ़ाइल है, जिसे आप कनवर्ट करना चाहते हैं, उदाहरण के लिए कुछ इस तरह से:

some random stuff                 some random stuff                      
* foo                             1. foo                                 
* bar                             2. bar                                 
* baz                             3. baz                                 
some other random stuff           some other random stuff                
                           ==>                                                
some random stuff                 some random stuff                      
* foo                             1. foo                                 
* bar                             2. bar                                 
* baz                             3. baz                                 
* qux                             4. qux                                 
some other random stuff           some other random stuff                

आप इसे निम्न आदेश के साथ कर सकते हैं:

:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '

यह पिछली कमांड का केवल एक संस्करण है, जो cकिसी अन्य सूची में जाने पर चर को रीसेट करता है । यह पता लगाने के लिए कि क्या आप किसी अन्य सूची में हैं, चर dका उपयोग अंतिम पंक्ति की संख्या को संग्रहीत करने के लिए किया जाता है जहां एक प्रतिस्थापन बनाया गया था।
वैश्विक कमांड वर्तमान लाइन संख्या ( line('.')) की तुलना करता है d+1। यदि वे समान हैं, तो इसका मतलब है कि हम एक ही सूची में हैं क्योंकि इससे पहले cकि वेतन वृद्धि ( c+1) है, अन्यथा इसका मतलब है कि हम एक अलग सूची में हैं, इसलिए cरीसेट ( 1) है।

किसी फ़ंक्शन के अंदर, कमांड let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]को इस तरह से फिर से लिखा जा सकता है:

let c = line('.') == d+1 ? c+1 : 1
let d = line('.')

या इस तरह:

if line('.') == d+1
    let c = c+1
else
    let c = 1
endif
let d = line('.')

कुछ कीस्ट्रोक्स को बचाने के लिए, आप कस्टम कमांड को भी परिभाषित कर सकते हैं :NumberedLists, जो एक सीमा को स्वीकार करता है जिसका डिफ़ॉल्ट मान है 1,$( -range=%):

command! -range=% NumberedLists let [c,d]=[0,0] | <line1>,<line2>g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '

जब :NumberedListsनिष्पादित किया जाएगा, <line1>और <line2>आपके द्वारा उपयोग की जाने वाली सीमा के साथ स्वचालित रूप से बदल दिया जाएगा।

इसलिए, सभी सूचियों को बफर में बदलने के लिए, आप टाइप करेंगे: :NumberedLists

केवल रेखा 10 और 20 के बीच की सूची: :10,20NumberedLists

केवल दृश्य चयन: :'<,'>NumberedLists


अधिक जानकारी के लिए देखें:

:help :range
:help :global
:help :substitute
:help sub-replace-expression
:help list-identity    (section list unpack)
:help expr1
:help :command

9

यह केवल हाल ही में विम संस्करण के साथ काम करता है (जिसमें है :h v_g_CTRL-A):

  1. सूची गोलियों ( *) को ब्लॉक करें और उन्हें बदलें 0(कर्सर पहले पर है *) Ctrl-v j j r 0:।
  2. काउंटर के साथ पिछले ब्लॉक और वेतन वृद्धि का पुन : चयन करें:gv g Ctrl-a

... और बस :)


(आप प्रत्येक संख्या के बाद एक बिंदु है चाहते हैं, के लिए 1 कदम बदलने के लिए: Ctrl-v j j s 0 . Esc)


9

नेत्रहीन रूप से लाइनों का चयन करें और इस प्रतिस्थापन कमांड को निष्पादित करें:

:'<,'>s/*/\=line('.') - line("'<") + 1 . '.'

देखें :help sub-replace-expression, :help line()और :help '<

लाइनों का चयन करने से बचने के लिए, ऑफसेट के साथ पीछे और आगे की खोजों का उपयोग इस तरह प्रतिस्थापन रेंज को निर्दिष्ट करने के लिए किया जा सकता है:

:?^[^*]?+1,/^[^*]/-1s/*/\=line('.') - search('^[^[:digit:]]', 'bn') . '.'

देख :help cmdline-ranges


2

दूसरा रास्ता:

:let n = 1 | g/^* /s//\=printf('%d. ', n)/g | let n = n + 1

0

आप कस्टम ऑपरेटरों को भी परिभाषित कर सकते हैं

आप उन्हें मुख्य दृश्यों के लिए मैप कर सकते हैं '*और '#। निशान *और #मौजूद नहीं है, इसलिए आप किसी भी डिफ़ॉल्ट कार्यक्षमता को ओवरराइड नहीं करेंगे। 'उपसर्ग के रूप में चुनने का कारण कुछ प्रकार के निंदकों को प्राप्त करना है। आप कुछ पंक्तियों के सामने एक संकेत / चिह्न जोड़ रहे हैं। और आमतौर पर एक निशान पर जाने के लिए आप उपसर्ग का उपयोग करते हैं '

fu! s:op_list_bullet(...) abort range

    if a:0
        let [lnum1, lnum2] = [line("'["), line("']")]
    else
        let [lnum1, lnum2] = [line("'<"), line("'>")]
    endif

    if !empty(matchstr(getline(lnum1), '^\s*\d\s*\.'))
        let pattern     = '\d\s*\.\s\?'
        let replacement = '* '

    elseif count(['-', '*'], matchstr(getline(lnum1), '\S'))
        let pattern     = '\v\S\s*'
        let replacement = ''

    else
        let pattern     = '\v\ze\S'
        let replacement = '* '
    endif

    let cmd = 'keepj keepp %s,%s s/%s/%s'

    sil exe printf(cmd, lnum1, lnum2, pattern, replacement)
endfu

fu! s:op_list_digit(...) abort range
    let l:c = 0

    if a:0
        let [lnum1, lnum2] = [line("'["), line("']")]
    else
        let [lnum1, lnum2] = [a:firstline, a:lastline]
    endif

    if count(['-', '*'], matchstr(getline(lnum1), '\S'))
        let pattern     = '\S\s*'
        let replacement = '\=l:c.". "'

    elseif !empty(matchstr(getline(lnum1), '^\s*\d\s*\.'))
        let pattern     = '\d\s*\.\s\?'
        let replacement = ''

    else
        let pattern     = '\v^\s*\zs\ze\S'
        let replacement = '\=l:c.". "'
    endif

    let cmd = 'keepj keepp %s,%s g/%s/let l:c = line(".") == line("'']")+1 ?
                                                \ l:c+1 : 1 |
                                                \ keepj keepp s/%s/%s'

    sil exe printf(cmd, lnum1, lnum2, pattern, pattern, replacement)
endfu

nno <silent> '*     :<C-U>set opfunc=<SID>op_list_bullet<CR>g@
nno <silent> '**    :<C-U>set opfunc=<SID>op_list_bullet
                    \<Bar>exe 'norm! ' . v:count1 . 'g@_'<CR>
xno <silent> '*     :call <SID>op_list_bullet()<CR>

nno <silent> '#     :<C-U>set opfunc=<SID>op_list_digit<CR>g@
nno <silent> '##    :<C-U>set opfunc=<SID>op_list_digit
                    \<Bar>exe 'norm! ' . v:count1 . 'g@_'<CR>
xno <silent> '#     :call <SID>op_list_digit()<CR>

यह विजुअल मोड से भी काम करता है।
पूर्व कमांड स्क्रिप्टिंग के लिए अच्छे हैं, लेकिन एक इंटरैक्टिव उपयोग के लिए, एक सामान्य ऑपरेटर शायद बेहतर है, क्योंकि आप इसे किसी भी गति या पाठ-वस्तु के साथ जोड़ सकते हैं।

उदाहरण के लिए, आप हिट करके वर्तमान पैराग्राफ के अंदर तारांकन या माइनस संकेतों के साथ उपसर्ग किए गए सूची को टॉगल कर सकते हैं '*ip। यहां, '*एक ऑपरेटर है और ipवह टेक्स्ट-ऑब्जेक्ट है जिस पर वह काम करता है।

और अगली 10 पंक्तियों की संख्याओं को मारकर संख्याओं के साथ उपसर्ग करने वाली सूची के लिए एक ही काम करें '#10j। यहां, '#एक अन्य ऑपरेटर है और 10jएक गति है जो उन लाइनों को कवर करता है जिस पर ऑपरेटर काम करता है।

कस्टम ऑपरेटर का उपयोग करने का दूसरा लाभ यह है कि आप अपने अंतिम संस्करण को डॉट कमांड के साथ दोहरा सकते हैं।

यहाँ छवि विवरण दर्ज करें

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