2010-04-04 13 views
7

जब मैं उपयोग करता हूं:%! फ़िल्टर के माध्यम से फ़ाइल की सामग्री को चलाने के लिए और फ़िल्टर विफल रहता है (यह 0 से दूसरे कोड को वापस करता है) और stderr को एक त्रुटि संदेश प्रिंट करता है, मुझे अपनी फ़ाइल को इस त्रुटि संदेश से बदल दिया जाता है। फ़िल्टरिंग को छोड़ने के लिए विम को बताने का कोई तरीका है यदि फ़िल्टर एक स्टेटस कोड देता है जो एक त्रुटि इंगित करता है और/या आउटपुट को अनदेखा करता है तो फ़िल्टर प्रोग्राम stderr को लिखता है?विम फिल्टर और stdout/stderr

ऐसे मामले हैं जहां आप अपनी फ़ाइल फ़िल्टर के आउटपुट के साथ बदलना चाहते हैं लेकिन अक्सर यह व्यवहार गलत है। बेशक मैं सिर्फ एक कीप्रेस के साथ फ़िल्टरिंग पूर्ववत कर सकता हूं लेकिन यह इष्टतम नहीं है।

फ़िल्टरिंग करने के लिए कस्टम वीम स्क्रिप्ट लिखते समय भी मुझे एक ही समस्या है। मेरे पास एक स्क्रिप्ट है जो सिस्टम() के साथ फ़िल्टर प्रोग्राम को कॉल करती है और फ़ाइल को अपने आउटपुट के साथ बफर में बदल देती है लेकिन यह पता लगाने का एक तरीका प्रतीत नहीं होता है कि क्या सिस्टम() द्वारा लौटाई गई रेखाएं हैं जहां stdout या stderr को लिखा गया है । क्या उन्हें विम लिपि में अलग करने का कोई तरीका है?

उत्तर

3

आप stdout और stderr के बीच भेद करने अजगर का उपयोग कर सकते हैं:

python import vim, subprocess 
python b=vim.current.buffer 
python line=vim.current.range.start 
python p=subprocess.Popen(["command", "argument", ...], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) 
python returncode=p.poll() 
python if not returncode: b.append(("STDOUT:\n"+p.stdout.read()+"\nSTDERR:\n"+p.stderr.read()).split("\n"), line) 
+0

बेशक! प्रत्येक "असली" पटकथा भाषा के साथ यह कोई समस्या नहीं है। इसके बारे में नहीं सोचा था। यद्यपि यदि संभव हो तो मैं विम स्क्रिप्ट पसंद करूंगा क्योंकि मैं अपनी स्क्रिप्ट पर आवश्यकतानुसार अधिक निर्भरता नहीं लेना चाहता हूं। – ahe

+1

मुझे केवल एक और तरीका पता है: 'सिस्टम() 'का उपयोग करें, stderr को अस्थायी फ़ाइल (या'/dev/null') पर रीडायरेक्ट करें, कुछ चर के लिए stdout को सहेजें और यह निर्धारित करने के लिए' v: shell_error' का उपयोग करें कि कोई आदेश पहले विफल हुआ है या नहीं ओवरराइटिंग बफर। नोट, ''!' फिल्टर पिछले आदेश के साथ«! »को प्रतिस्थापित करता है और वर्तमान फ़ाइल नाम के साथ«% »'सिस्टम()' नहीं करता है। – ZyX

3

:!{cmd} खोल के साथ क्रियान्वित {cmd} और सेट v:shell_error

आप अपने फिल्टर कॉल करने के लिए मैपिंग स्थापित करने के लिए है, तो आप निम्नलिखित की तरह कुछ कर सकता है:

function! UndoIfShellError() 
    if v:shell_error 
     undo 
    endif 
endfuntion 

nmap <leader>filter :%!/path/to/filter<CR>:call UndoIfShellError()<CR> 
+0

अच्छी चाल :)। असल में मुझे एक त्रुटि संवेदनशील लटकन की उम्मीद थी:! {Cmd} वाक्यविन्यास जिसे मैंने अभी अनदेखा किया था। लेकिन अधिक से अधिक मुझे डर है कि ऐसा कोई वैकल्पिक वाक्यविन्यास मौजूद नहीं है। – ahe

1

एक वैकल्पिक फिल्टर आदेश यह डिस्क पर फ़ाइल को संशोधित करता है इस तरह के रूप में चलाने के लिए किया जाएगा।

उदाहरण के लिए, gofmt के लिए (www.golang.org) मैं जगह में इन मैपिंग है:

map <f9> :w<CR>:silent !gofmt -w=true %<CR>:e<CR> 
imap <f9> <ESC>:w<CR>:silent !gofmt -w=true %<CR>:e<CR> 

स्पष्टीकरण: : डब्ल्यू - फ़ाइल बचाने: मूक - दबाने से बचने के अंत % पर दर्ज - gofmt करने के लिए फ़ाइल गुजरता डब्ल्यू = सच - वापस फ़ाइल लिखने के लिए gofmt बताता है: ई - बताता vim संशोधित फिर से लोड करने फ़ाइल

0

यह मैं क्या कर समाप्त हो गया है:

function MakeItAFunction(line1, line2, args) 
    let l:results=system() " call filter via system or systemlist 
    if v:shell_error 
    "no changes were ever actually made! 
    echom "Error with etc etc" 
    echom results 
    endif 
    "process results if anything needed? 

    " delete lines but don't put in register: 
    execute a:line1.",".a:line2." normal \"_dd" 
    call append(a:line1-1, l:result) " add lines 
    call cursor(a:line1, 1) " back to starting place 
    " echom any messages 
endfunction 
command -range <command keys> MakeItAFunction(<line1>,<line2>,<q-args>) 
"           or <f-args>, etc. 

आप http://vim.wikia.com/wiki/Perl_compatible_regular_expressions

यह जटिल है पर मेरा पूरा कोड देख सकते हैं, लेकिन यह काम करता है और जब यह प्रयोग किया जाता है, यह काफी पारदर्शी और सुंदर है। उम्मीद है कि किसी भी तरह से मदद करता है!

संबंधित मुद्दे