2013-05-01 4 views
10

में सभी चिह्नित लाइनों को यंकिंग करना अक्सर बार में लॉग फ़ाइलों की समीक्षा करते समय, मैं अंक का उपयोग करके दिलचस्प रेखाओं को हाइलाइट करूंगा। किसी बिंदु पर, मैं किसी भी रजिस्टर या किसी अन्य फ़ाइल में सभी रोचक लाइनों (या तो सभी चिह्नित लाइनों, या अंकों की एक सूची) की प्रतिलिपि बनाने में सक्षम होना चाहता हूं (यह वास्तव में कोई फर्क नहीं पड़ता; लक्ष्य है सारांश लिखने में सुविधा)। मैं ऐसा करने के लिए किसी भी तरह से निर्मित करने में सक्षम नहीं हूं; क्या यह विम में संभव है?विम

मुझे लगता है कि यह शायद एक काफी सरल कार्य है; शायद कुछ इस तरह लग रही है, लेकिन मेरी vimscript क्षमताओं बहुत कमजोर कर रहे हैं:

for cur_mark in list_of_marks 
    goto mark 
    yank current line and append to register 

क्या कभी किसी ने भी इसी तरह का है कि वे मेरे लिए इंगित कर सकते हैं कुछ भी लिखा गया है?

धन्यवाद

संपादित करें: मैं हमेशा की तरह https://github.com/mikeage/vim-yankmarks

उत्तर

5

माइकेज का एक अच्छा विचार था; यहां उनके फ़ंक्शन का एक और परिष्कृत संस्करण कमांड में बदल गया है:

":YankMarks [{marks}] [{register}] 
"     Yank all marked (with [a-z]/{marks} marks) lines into 
"     the default register/{register} (in the order of the 
"     marks). 
function! s:YankMarks(...) 
    let l:marks = 'abcdefghijklmnopqrstuvwxyz' 
    let l:register = '"' 
    if a:0 > 2 
     echohl ErrorMsg 
     echomsg 'Too many arguments' 
     echohl None 
     return 
    elseif a:0 == 2 
     let l:marks = a:1 
     let l:register = a:2 
    elseif a:0 == 1 
     if len(a:1) == 1 
      let l:register = a:1 
     else 
      let l:marks = a:1 
     endif 
    endif 

    let l:lines = '' 
    let l:yankedMarks = '' 
    for l:mark in split(l:marks, '\zs') 
     let l:lnum = line("'" . l:mark) 
     if l:lnum > 0 
      let l:yankedMarks .= l:mark 
      let l:lines .= getline(l:lnum) . "\n" 
     endif 
    endfor 

    call setreg(l:register, l:lines, 'V') 

    echomsg printf('Yanked %d line%s from mark%s %s', 
    \ len(l:yankedMarks), 
    \ len(l:yankedMarks) == 1 ? '' : 's', 
    \ len(l:yankedMarks) == 1 ? '' : 's', 
    \ l:yankedMarks 
    \) . (l:register ==# '"' ? '' : ' into register ' . l:register) 
endfunction 
command! -bar -nargs=* YankMarks call <SID>YankMarks(<f-args>) 
+1

बढ़िया! अब मुझे लोगों को अपने जवाब को कम करने और आपको श्रेय देने के लिए मनाने की ज़रूरत है :) – Mikeage

+2

@ माइकेज ओह नहीं, मुख्य क्रेडिट अभी भी आपके पास जाता है, क्योंकि मैं केवल कुछ बेहतर कार्यान्वयन प्रदान करता हूं। मैं सुझाव दूंगा कि लोग दोनों को ऊपर उठाएं :-) –

6

में स्वीकार समाधान तैनात, वहाँ कुछ चीजें हैं जो मदद के लिए पूछ की तुलना में अधिक प्रेरित कर रहे हैं। यहां मैं क्या आया था; प्रतिक्रिया स्वागत है।

:redir @a 
:silent marks XYZN 
:redir END 
"ap 

इस तरह :marks आदेश के उत्पादन में a रजिस्टर करने के लिए पुनः निर्देशित किया जाएगा:

function! Yankmark() 
    let save_cursor = getpos(".") 
    let n = 0 
    " I should really make this a parameter... 
    let marks_to_yank="abcdefghijklmnopqrstuvwxyz" 
    let nummarks = strlen(marks_to_yank) 
    " Clear the a register 
    let @a='' 
    while n < nummarks 
     let c = strpart(marks_to_yank, n, 1) 
     " Is the mark defined 
     if getpos("'".c)[2] != 0 
      " using g' instead of ' doesn't mess with the jumplist 
      exec "normal g'".c 
      normal "Ayy 
     endif 
     let n = n + 1 
    endwhile 
    call setpos('.', save_cursor) 
endfunction 
2

आप की तरह कुछ कर सकते हैं। ध्यान दें, कि यह केवल X, Y, Z और N अंकों (तर्क के रूप में), और यदि a रजिस्टर था, तो इसे हटा दिया जाएगा/ओवरराइट किया जाएगा।

यह भी ध्यान रखें, कि यह वांछित आउटपुट नहीं दे सकता है, लेकिन आप एक प्रारंभिक बिंदु देता है ...

+0

शानदार विचार! निश्चित रूप से इस तरह से अतिरिक्त "मेटाडाटा" है, लेकिन यह वास्तव में कई मामलों में सहायक हो सकता है। और यह – Mikeage

2

आप एक अपर-केस रजिस्टर नाम जब एक विशिष्ट रजिस्टर में yanking उपयोग करते हैं, विम जोड़ देंगे, रजिस्टर के मूल्य को ओवरराइट करने की बजाए यंक की गई सामग्री।

तो, उदाहरण के लिए:

  • "एकyy - a रजिस्टर करने के लिए वर्तमान पंक्ति झटका, अधिलेखन

  • [कदम]

  • "एकyy - रजिस्टर करने के लिए इस लाइन संलग्न a

  • [कदम]

  • "एकपी - पेस्ट सब yanked सामग्री

अधिक जानकारी के लिए

:help quotea देखें।

+0

के मुकाबले यह निश्चित रूप से सरल है कि मैंने अपने समाधान में – Mikeage

+0

@Mikeage से ऊपर किया है, मेरा मुद्दा यह है कि आपको किसी फ़ंक्शन की आवश्यकता नहीं है। जैसे ही आप जाते हैं, आप टेक्स्ट को हाथ से एक रजिस्टर में जमा कर सकते हैं। –

+0

आह, सच है। लेकिन पूरा क्यू प्रक्रिया को स्वचालित करने के लिए कैसे था। – Mikeage

3

इसे पूरा करने का एक अलग तरीका :global कमांड का उपयोग कर सकता है। वैश्विक आदेश फॉर्म :g/{pattern}/{cmd} लेता है। आदेश, {cmd}, {pattern} से मेल खाने वाली सभी लाइनों पर निष्पादित किया जाएगा।

:g/pattern/yank A 

संलग्न मिलान लाइन एक लॉग फ़ाइल के लिए:

संलग्न एक रजिस्टर करने के लिए एक पैटर्न मिलान लाइनों

:g/pattern/w >> file.log 
बेशक

यदि आप लाइन एक निशान आप इसे मिलान कर सकते हैं मिलान लगाना चाहते हैं आपके पैटर्न में निम्नलिखित पैटर्न चिह्न m के साथ एक पंक्ति से मेल खाता है।

:g/\%'m/w >> file.log 

ऐसा कुछ करने के लिए। (नोट: मैं बहुत जादू को चालू करने के \v उपयोग कर रहा हूँ)

:g/\v(%'a|%'b|%'m)/yank A 
बेशक

अगर एक पैटर्न आप हाथ से यह कर सकते हैं काम नहीं करेगा। लाइनों को चिह्नित करने के बजाय बस जैसे ही आप जाते हैं लाइनों का निर्माण करें। बस संलग्न करने के लिए एक अपरकेस रजिस्टर के लिए एक लाइन yank।

"Ayy 

या एक पंक्ति

:.w >> file.log 

की एक सीमा के साथ एक लिखने संलग्न करना और अधिक मदद की देख

:h :g 
:h :w_a 
:h /\%'m 
:h /\v 
2

मैं Mikeage से समाधान चाहते के लिए, हालांकि मैं शायद इस का समाधान होगा multiselect - Create multiple selections and operate प्लगइन के साथ। यह भी लाभ है कि आप अंक से बाहर नहीं निकलते हैं।

प्लगइन के साथ, आप <Leader>msa या :MSAdd के साथ लाइनों का चयन कर सकते हैं। अंत में, सभी लाइनों के साथ yank:

:let @a='' 
:MSExecCmd yank A