किसी फाइल में सभी लाइनों से व्हाट्सएप को हटाने का सबसे सरल तरीका क्या है?


139

जब एक पंक्ति के अंत में व्हाट्सएप के साथ फ़ाइलों का सामना करने के लिए प्रोग्रामिंग करना या पाठ फ़ाइलों को खोलना बहुत आम है। vim के पास trailविकल्प में विकल्प सेट करके listcharsऔर फिर इसे चालू करके दिखाने का एक तरीका है list

हालाँकि, फ़ाइल के पूरे भाग में विश्व स्तर पर उस अनुगामी व्हाट्सएप को खत्म करने का सबसे आसान तरीका क्या है (आदर्श रूप से बिना प्लगइन के)?




यदि आपने vim-faq स्थापित किया है , तो आप वहां ऑफ़लाइन उत्तर प्राप्त कर सकते हैं: :h vim-faqऔर खोज करें /trailing। टैग को याद रखना कठिन है :h faq-12.1
होट्सचेक

जवाबों:


72

सभी अनुगामी व्हाट्सएप को पट्टी करने के लिए कीबाइंडिंग का उपयोग करें

चूंकि मेरे द्वारा संपादित किए जाने वाले कुछ पृष्ठों को वास्तव में अनुगामी व्हाट्सएप (जैसे मार्कडाउन) की आवश्यकता होती है और अन्य नहीं करते हैं, इसलिए मैंने एक कीबाइंडिंग स्थापित की है F5ताकि यह स्वचालित होने के बिना तुच्छ हो। ऐसा करने के लिए, नीचे दिए गए कोड (vim.wikia से) को जोड़ें या इसे अपने लिए कुछ भिन्नता दें .vimrc:

"Remove all trailing whitespace by pressing F5
nnoremap <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar><CR>
  • nnoremap <F5>F5सामान्य मोड में कुंजी के लिए एक गैर-मानचित्रण मैपिंग करता है
  • :let _s=@/@/चर में अंतिम खोज शब्द (मैक्रो से ) संग्रहीत करता है_s
  • <Bar>|अलग-अलग आदेशों के लिए एक पाइप प्रतीक के रूप में कार्य , हालांकि |इस संदर्भ में एक आदेश समाप्त होगा, इसलिए <Bar>इसके बजाय उपयोग किया जाना चाहिए।
  • :%s/\s\+$//eव्हॉट्सएप की खोज और इसे बफर में हर जगह हटा दिया जाता है (देखें इस अभिव्यक्ति के विस्तृत टूटने के लिए कारपेटसोकर का जवाब )
  • let @/=_sअपने अंतिम खोज शब्द को मैक्रो में पुनर्स्थापित करता है @/, ताकि अगली बार जब आप हिट करें तो यह उपलब्ध हो n
  • <CR> मैपिंग समाप्त करता है

... या अधिक चयनात्मक हो

यदि आपके पास ऐसे मामले हैं जिनमें आप सभी अनुगामी व्हाट्सएप को छीनना नहीं चाहते हैं, तो आप अधिक चयनात्मक होने के लिए एक पैटर्न का उपयोग कर सकते हैं। उदाहरण के लिए, निम्न कोड दिखाता है कि मैं व्हाट्सएप को कैसे छीनता हूं अगर यह अर्धविराम के बाद आता है (यहां इसे बांधा गया है F8)।

nnoremap <F8> :let _s=@/<Bar>:%s/;\s\+$/;/e<Bar>:let @/=_s<Bar><CR>

यह उपयोगी है अगर, मेरी तरह, आपके पास अर्धविराम- टर्म प्रोग्रामिंग प्रोग्रामिंग के बीच मार्कडाउन -जैसे हेरेडोस्क के साथ कुछ फाइलें हैं ।


6
:keeppatternsओवरराइडिंग को रोकने की कोशिश करें @/। और देख भी लेते हैं :keepjumps
बोह्र

@Bohr आप किस संस्करण का उपयोग कर रहे हैं? मैंने कोशिश की :help keeppatternऔर कुछ नहीं मिला।
क्रिस्टोफर बॉटम्स

@ChristopherBottoms कम से कम संस्करण 7.4.155
बोहर

@Bohr। धन्यवाद! पता लगाने के लिए आओ मैं अभी भी 7.4.0 का उपयोग कर रहा था। मैंने नवीनतम संस्करण स्थापित किया है और यह उपलब्ध है।
क्रिस्टोफर बॉटम्स 14

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

175

"सबसे सरल" तरीका सिर्फ उपयोग करना है :substitute:

:%s/\s\+$//e
  • :%s:substituteरेंज पर चलाने के लिए %, जो संपूर्ण बफर है।
  • \s टी सभी व्हाट्सएप पात्रों से मेल खाते हैं।
  • \+ उन्हें 1 या अधिक बार दोहराने के लिए।
  • $ पंक्ति के अंत में लंगर डालना।
  • eअगर वहाँ कोई मुकाबला नहीं है (यानी फ़ाइल रिक्त स्थान के अनुगामी के बिना पहले से ही है) झंडा एक त्रुटि नहीं देने के लिए।

हालांकि, यह शायद "सबसे अच्छा" तरीका नहीं है क्योंकि यह दो दुष्प्रभावों का कारण बनता है:

  1. यह कर्सर को अंतिम मैच में ले जाता है;
  2. यह इतिहास और खोज इतिहास में कमांड जोड़ता है;
  3. यह अंतिम खोज शब्द को रीसेट करता है।

आप इसे एक फंक्शन में बदलकर दोनों आइटम को ठीक कर सकते हैं:

fun! TrimWhitespace()
    let l:save = winsaveview()
    keeppatterns %s/\s\+$//e
    call winrestview(l:save)
endfun

और फिर इसका उपयोग करें जैसे:

:call TrimWhitespace()
  1. winsaveview()वर्तमान "दृश्य" है, जो कर्सर की स्थिति भी शामिल है, परतों, कूदता है, आदि की बचत होगी winrestview()अंत में बचाया चर से पुनर्स्थापित करेगा।
  2. :keeppatternsरोकता \s\+$खोज इतिहास में शामिल होने से पैटर्न।
  3. किसी कार्य को छोड़ने के बाद अंतिम रूप से खोजा गया शब्द स्वचालित रूप से पुनर्स्थापित हो जाता है, इसलिए हमें इसके लिए कुछ और करने की आवश्यकता नहीं है।

चूंकि यह हर :callसमय टाइप करने के लिए कुछ कष्टप्रद है , आप एक कमांड को परिभाषित कर सकते हैं:

command! TrimWhitespace call TrimWhitespace()

जिनका उपयोग बिना किया जा सकता है :call:

:TrimWitespace

और आप इसे एक कुंजी से बांध सकते हैं:

:noremap <Leader>w :call TrimWhitespace()<CR>

कुछ लोग डिस्क पर फ़ाइल लिखने से पहले इसे स्वचालित रूप से करना पसंद करते हैं, जैसे:

autocmd BufWritePre * :call TrimWhitespace()

मुझे यह पसंद नहीं है, क्योंकि कुछ प्रारूपों के लिए व्हाट्सएप (जैसे मार्कडाउन) की आवश्यकता होती है, और कुछ अन्य अवसरों पर भी आप अपने कोड में व्हाट्सएप को पीछे छोड़ना चाहते हैं (जैसे कि ईमेल को प्रारूपित करना, और --<Space>हस्ताक्षर की शुरुआत का संकेत देने के लिए मार्कर का उपयोग करना। )।


बेशर्म प्लग मोड: कुछ समय पहले मैंने एक बार में एक पूरे प्रोजेक्ट के लिए व्हाट्सएप को साफ करने के लिए थोड़ी पायथन स्क्रिप्ट लिखी थी ।


1
यदि आप पिछली स्थिति में जाने के लिए कोई फ़ंक्शन नहीं बनाना चाहते हैं तो आप ​`​प्रतिस्थापन समाप्त होने के बाद सिर्फ दो बार दबा सकते हैं । यह इस तरह एक oneliner बनाने की संभावना को खोलता है:%s/\s\+$//e | exe "normal ``"
Nea Ovu Ovidiu गेब्रियल

1
@ NeariuOvidiuGabriel, निश्चित रूप से तब डबल बैकटिक ऑनलाइनर निष्पादित होने के बाद ही काम नहीं करेगा। ;)
वाइल्डकार्ड

समान: stackoverflow.com/a/1618401 । लेकिन मुझे मार्टिन का कोड ज्यादा पसंद है।
जॉन सीजे

11

सभी अनुगामी व्हाट्सएप (प्रत्येक पंक्ति के अंत में) को हटाने के लिए, आप कमांड का उपयोग कर सकते हैं:

:%s/ \+$//

टैब शामिल करने के लिए, \sस्थान के बजाय उपयोग करें ।


कमांड-लाइन से:

$ ex +'%s/\s\+$//e' -cwq file.c

वर्तमान निर्देशिका की सभी फाइलें (पुनरावर्ती उपयोग **/*.*):

$ ex +'bufdo!%s/\s\+$//e' -cxa *.*

अजगर का तरीका:

:py import vim
:pydo vim.current.buffer[linenr - 1] = vim.current.buffer[linenr - 1].strip()

या:

:py import vim
:py for i, l in enumerate(vim.current.buffer): vim.current.buffer[i] = l.rstrip()

का प्रयोग करें lstrip()छोड़ दिया पट्टी (अनुगामी), के लिए rstrip()सही पट्टी (अग्रणी) के लिए या strip()दोनों सिरों से दूर करने के लिए।


यहां उपयोगी कार्य है जो एक पंक्ति के अंत से शानदार सफेद स्थान को हटाता है जिसे आप अपने साथ जोड़ सकते हैं .vimrc:

" Removes superfluous white space from the end of a line
function! RemoveWhiteSpace()
   :%s/\s*$//g
    :'^
    "`.
endfunction

उसके लिए DeleteTrailingWhitespace प्लगइन भी है।


सफेद स्थानों पर प्रकाश डालना

यदि सभी अनुगामी रिक्त स्थान गए हैं, तो डबल-चेक करें:

  1. / $उन्हें खोजने के लिए टाइप करें। अगर कुछ हैं, तो विम उन्हें आपके लिए उजागर करेगा।

  2. उन्हें उजागर करने के लिए रंगों का उपयोग करें:

    :highlight ws ctermbg=red guibg=red
    :match ws /\s\+$/
    
  3. दृश्यमान वर्णों का उपयोग करें ( स्रोत ):

    :set encoding=utf-8
    :set listchars=trail:·
    :set list
    

यह भी देखें: अवांछित स्थानों को हाइलाइट करें

डिफ़ॉल्ट रूप से अनुगामी व्हाट्सएप को उजागर करने के लिए, आप अपने .vimrcअनुसरण को कॉन्फ़िगर कर सकते हैं:

highlight ws ctermbg=red guibg=red
match ws /\s\+$/
autocmd BufWinEnter * match ws / \+$/

डिफ़ॉल्ट रूप से सफेद रिक्त स्थान हटाना

यदि आप यह सुनिश्चित करना चाहते हैं कि फ़ाइल में सभी अनुगामी व्हाट्सएप स्वचालित रूप से सहेजने पर हटा दिए जाते हैं, तो आप निम्नलिखित को निम्न में जोड़ सकते हैं .vimrc:

autocmd BufWritePre *.c,*.php :%s/ \+$//ge

जिसकी अनुशंसा नहीं की गई है, क्योंकि यह उपयोगकर्ता द्वारा सेव की जाने वाली हर फ़ाइल से व्हॉट्सएप को छीन लेगा (जहां व्हॉट्सएप वांछित हो सकता है)।


यह सभी देखें:


5

पर Exapnding क्रिस्टोफर बॉटम्स के जवाब एक सा : जोनाथन Palardy इस पर एक अच्छा लेख लिखा था । इसमें, वह एक फ़ंक्शन लिखता है Preserve(command), जो एक मनमाने ढंग से चलने के दौरान संपादक की स्थिति (मुख्य रूप से कर्सर की स्थिति और अंतिम खोज पैटर्न) को संरक्षित करता है:

function! Preserve(command)
  " Preparation: save window state
  let l:saved_winview = winsaveview()
  " Run the command:
  execute a:command
  " Clean up: restore previous window position
  call winrestview(l:saved_winview)
endfunction

यह बहुउद्देशीय होने का लाभ है, उदाहरण के लिए आप इसका उपयोग सभी अनुगामी व्हाट्सएप को बदलने के लिए कर सकते हैं (जैसा कि जोनाथन करते हैं)

nnoremap <F5> :call Preserve("%s/\\s\\+$//e")<CR>

आप इसे विज़ुअल मोड मैपिंग के लिए भी उपयोग कर सकते हैं ताकि नेत्रहीन चयनित लाइनों पर अनुगामी रिक्त स्थान को हटा सकें:

xnoremap <F5> :call Preserve("'<,'>s/\\s\\+$//e")<CR>

और आप इसे अन्य कॉल के लिए उपयोग कर सकते हैं, जैसे =अपनी जगह को बनाए रखते हुए पूरे दस्तावेज़ को प्रारूपित करना (अच्छी तरह से इस बार एक अलग कुंजी का उपयोग करें ताकि संघर्ष न करें):

nnoremap <F6> :call Preserve("normal gg=G")<CR>

सब और सब, मैं Preserve(command)एक अच्छा उपकरण होने के लिए समारोह पाया है।


2
जब आप एक फ़ंक्शन छोड़ते हैं तो अंतिम उपयोग किए गए खोज शब्द को स्वचालित रूप से संरक्षित किया जाना चाहिए; इसलिए के साथ छेड़छाड़ की @/आवश्यकता नहीं होनी चाहिए (इस मामले में, वैसे भी)।
मार्टिन टूरनोइज

3
winsaveview()और winrestview()बहुत बेहतर हैं।
डैश-टॉम-बैंग

बिलकुल सही! आपकी प्रतिक्रिया के आधार पर अपडेट किया गया।
एलेक्स

0

StripTrailingSpaces का दूसरा संस्करण

if !exists('*StripTrailingWhitespace')
    function! StripTrailingWhitespace() range
        if !&binary && &filetype != 'diff'
            call Preserve(":" . a:firstline . "," . a:lastline . "s/\\s\\+$//e")
        endif
    endfunction
endif

वास्तव में इस फंक्शन (यह एक) में एक बग है: कब्जे को "सीमा" विकल्प के कारण नहीं रखा जाता है। इसे हटा दिया जाता है यह बहुत अच्छी तरह से काम करता है, हालांकि मैं कुछ सहायता प्राप्त करने के लिए कोड साझा कर रहा हूं।

जैसा कि आप देख सकते हैं कि यह ऊपर दिए गए संरक्षित फ़ंक्शन का भी उपयोग करता है, लेकिन थोड़े अलग तरीके से।

यहां अंतर यह है कि मैं लाइनों की एक श्रृंखला या एक पैराग्राफ का चयन कर सकता हूं vipऔर फिर यह रेंज :'<,'>स्वचालित रूप से कमांड प्रॉम्प्ट पर दिखाई देगी।

यह विचार बेज हर्मोसो पोस्ट से आया है ।

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