पायथन फिलाटाइप का उपयोग करते समय मैं विम में मल्टी-लाइन स्ट्रिंग को कैसे सुधार सकता हूं?


23

मान लीजिए कि मैं विम में कुछ पायथन कोड संपादित कर रहा हूं जो थोड़ा सा दिखता है:

myobj.myfunc("Some string parameter that goes on and on and on and on and sometimes doesn't"
             "split very"
             "neatly over different lines so that"
             "it is formatted attractively")

मैं इसे पुन: स्वरूपित करना पसंद करूंगा ताकि यह textwidthमेरे द्वारा निर्धारित किए गए को फिर से परिभाषित करे :

myobj.myfunc("Some string parameter that goes on and on and "
             "on and on and sometimes doesn't split very "
             "neatly over different lines so that it is "
             "formatted attractively")

क्या इसे करने का कोई आसान तरीका है? यदि यह एक पारंपरिक पाठ पैराग्राफ था, gqipया समान उपयोगी होगा, लेकिन यह स्ट्रिंग को सीमांकित करने के लिए उपयोग किए जाने वाले उद्धरणों को संभाल नहीं पाएगा।

नोट : मैं विशेष रूप से यहां पायथन के बारे में पूछ रहा हूं, लेकिन आदर्श रूप से, यह उत्तर कई प्रकार की प्रोग्रामिंग भाषा के लिए प्रासंगिक होगा जो स्ट्रिंग निरंतरता की अनुमति देता है।


1
इसी तरह के सवाल यहाँ: vim.1045645.n5.nabble.com/…
एंड्रयू फेरियर

3
क्या आपने कोड को पुनर्लेखन के रूप में भी माना है """multi-line string"""?
200_सेबल

1
@ 200_success, यह एक महान टिप है, धन्यवाद। मैं पायथन की उस विशेषता के बारे में बिल्कुल नहीं जानता था। यह काम करने लगता है, ज्यादातर - हालांकि फ़ंक्शन के सभी मापदंडों को फिर से परिभाषित किया गया है, जो आदर्श नहीं है। मुझे लगता है कि मेरा प्रश्न अभी भी स्ट्रिंग के प्रकार के लिए मान्य है, हालांकि, और निश्चित रूप से अन्य लंग्स के लिए।
एंड्रयू फेरियर

2
ध्यान दें कि एक बहु-पंक्ति स्ट्रिंग में व्हॉट्सएप वर्ण जोड़े जाएंगे, जो कि स्ट्रिंग में व्हाट्सएप के मामलों में एक समस्या हो सकती है।
मैट बोहेम

बहुत ही संबंधित प्रश्न: vi.stackexchange.com/questions/2135/… ...
मार्टिन टूरनोइज

जवाबों:


6

ओह, यह एक कठिन है। मुझे लगता है कि सबसे अच्छा दृष्टिकोण संभवतः एक मैक्रो है, लेकिन अधिक संभावना एक प्लगइन है। यहां एक उदाहरण दिया गया है जिसे मैंने कोड़ा (मुझे एक बेहतर शौक की आवश्यकता है)। यह मेरे लिए काम कर रहा था, लेकिन ठीक से इंडेंट करने के लिए अजगर इंडेंटिंग प्लगइन की आवश्यकता होगी। कोशिश करके देखो।

function ReformatMultiLines()
  let brx = '^\s*"'
  let erx = '"\s*$'
  let fullrx = brx . '\(.\+\)' . erx
  let startLine = line(".")
  let endLine   = line(".")
  while getline(startLine) =~ fullrx
    let startLine -= 1
  endwhile
  if getline(endLine) =~ erx
    let endLine += 1
  endif
  while getline(endLine) =~ fullrx
    let endLine += 1
  endwhile
  if startLine != endLine
    exec endLine . ' s/' . brx . '//'
    exec startLine . ' s/' . erx . '//'
    exec startLine . ',' . endLine . ' s/' . fullrx . '/\1/'
    exec startLine . ',' . endLine . ' join'
  endif
  exec startLine
  let orig_tw = &tw
  if &tw == 0
    let &tw = &columns
    if &tw > 79
      let &tw = 79
    endif
  endif
  let &tw -= 3 " Adjust for missing quotes and space characters
  exec "normal A%-%\<Esc>gqq"
  let &tw = orig_tw
  let endLine = search("%-%$")
  exec endLine . ' s/%-%$//'
  if startLine == endLine
    return
  endif
  exec endLine
  exec 'normal I"'
  exec startLine
  exec 'normal A "'
  if endLine - startLine == 1
    return
  endif
  let startLine += 1
  while startLine != endLine
    exec startLine
    exec 'normal I"'
    exec 'normal A "'
    let startLine += 1
  endwhile
endfunction

तब आप इसका उपयोग :call ReformatMultiLines()और / या मैपिंग में उपयोग कर सकते थे।


6

यदि यह एक नियमित घटना है, तो आप एक प्लगइन की तलाश में या @Sukima के फ़ंक्शन का उपयोग करना सबसे अच्छा होगा। अगर मैं इसे उड़ने पर कर रहा था, तो यहाँ मैं क्या करूँगा:

  1. ओपनिंग परन के बाद और क्लोजिंग पेरेन से पहले एक नईलाइन जोड़ें ताकि स्ट्रिंग्स अलग-अलग लाइनों पर हों।

    myobj.myfunc(
                 "Some string parameter that goes on and on and on and on and sometimes doesn't"
                 "split very"
                 "neatly over different lines so that"
                 "it is formatted attractively"
    )
    
  2. स्ट्रिंग के साथ लाइनों का चयन करें और आसपास के उद्धरण हटाएं: :norm ^x$x

  3. पाठ्यपुस्तक को कम करना (गुम उद्धरणों को ध्यान में रखना) :set tw-=2
  4. फिर से चुनें और प्रारूप: gvgq
  5. तयशुदा बनावट: :set tw+=2
  6. फिर से उद्धरण जोड़ें gv:norm I"<Esc>A":। इसके बजाय <Esc>आप भागने की कुंजी के बाद ctrl-v लिखकर शाब्दिक बच निकालना चाहते हैं। चूंकि मैं भागने के लिए jj का नक्शा बनाता हूं, मैं आमतौर पर यहां jj टाइप करता हूं।
  7. वैकल्पिक रूप से J का उपयोग पहले दो / अंतिम दो लाइनों में फिर से शामिल होने के लिए करें। जब मेरे पास इस तरह से अजगर में एक बहुत लंबी स्ट्रिंग है, तो मैं आमतौर पर इसे अगली पंक्ति पर शुरू करना पसंद करता हूं और केवल पिछली पंक्ति की तुलना में एक स्तर अधिक इंडेंट करता हूं। यह स्ट्रिंग के लिए अधिक क्षैतिज स्थान देता है और बस मुझे अधिक प्राकृतिक लगता है। वैकल्पिक रूप से, आप स्ट्रिंग को ऊपर दिए गए किसी चर में सहेज सकते हैं। इसे एक स्थिर स्ट्रिंग मानकर, आप इसे एक वैश्विक वैरिएबल पर भी सहेज सकते हैं ताकि यह बहुत कम इंडेंटेशन स्तर पर हो और कम लाइनों पर फिट हो सके। ध्यान दें कि आप एक ही लाइन पर क्लोजिंग पेरेन को फिर से जोड़ रहे हैं, आप संभवतः 2 के बजाय 3 से घटाना / बढ़ाना चाहते हैं।

1
धन्यवाद। मैं सिर्फ यह कोशिश की, लेकिन :set tw-=2परिणाम में E487: Argument must be positive: tw-=2। वाक्य रचना गलत है?
एंड्रयू फेरियर

1
के साथ पाठ्यपुस्तक के वर्तमान मूल्य की जाँच करें :set tw?। मेरा अनुमान है कि आपके पास टेक्स्ट सेट है। 0. इन चरणों का मानना ​​है कि टेक्स्टवर्क उन अक्षरों की संख्या के रूप में शुरू होता है जिन्हें आप प्रति पंक्ति चाहते हैं।
मैट बोहम

आपके उदाहरण में आप संभवतः s/2/3/समापन उद्धरण से पहले एक स्थान जोड़ना और जोड़ना चाहते हैं , आपके लंबे स्ट्रिंग में शब्दों के बीच उचित अंतर नहीं होगा।
cdosborn

1

पार्सिंग और स्वरूपण कोड कठिन है, विशेष रूप से गतिशील भाषाओं जैसे कि पायथन के लिए।

विम्सस्क्रिप्ट में पायथन को पार्स करने की कोशिश करने के बजाय, मैं आपको सलाह देता हूं कि आप एक बाहरी फॉर्मैटर जैसे कि yapf का उपयोग कर सकते हैं । यहाँ मेरे जवाब के साथ आप इसे लिखने के साथ स्वचालित रूप से लिख सकते हैं:

augroup write_cmd
    autocmd BufWritePre *.py call s:write_cmd('yapf')
augroup end

s:write_cmd()समारोह अन्य जवाब में है - मैं इसे यहाँ नहीं जोड़ेगा तो मैं दो स्थानों पर इसे अद्यतन करने अगर मैं एक बग मिल नहीं होगा :-)

तुम भी सेट कर सकते हैं formatprgकरने के लिए yapfऔर मैन्युअल रूप से स्वरूपित gq


नमस्ते। सहायक उत्तर, लेकिन मैं नीच हूं क्योंकि मुझे नहीं लगता कि यह इस सवाल का जवाब देता है: यह प्रश्न विशेष रूप से बहुस्तरीय तारों के सुधार के बारे में पूछ रहा है, जो yapfऐसा नहीं करता है। फिर भी मैं मानता हूं कि यह एक उपयोगी उपकरण की तरह दिखता है।
एंड्रयू फेरियर

@AndrewFerrier मेला काफी; मैं शपथ ले सकता था जब मैंने इसे दूसरे दिन परीक्षण किया था, तब मैंने इसे सुधारित तार देखा था, लेकिन इसे अब या तो काम करने के लिए नहीं मिला: - / अनुमान है कि मैं भ्रमित था।
मार्टिन टूरनोइज

0

निम्नलिखित कार्यों और इसी मैपिंग ने मेरे लिए इस समस्या को हल किया:

function! BreakMultlineString(quote)
let c = 100
while c == 100
    normal 100|
    let c = virtcol('.')
    if c == 100
        execute "normal ," . a:quote
    endif
endwhile
endfunction

function! JoinMultilineString()
    let c = "'"
    while c == "'" || c == '"'
        normal gj^
        let c = matchstr(getline('.'), '\%' . col('.') . 'c.')
        normal k
        if c == "'" || c == '"'
            normal ,j
        endif
    endwhile
endfunction

" break lines
nnoremap <Leader>" 100\|Bi"<CR>"<Esc>
nnoremap <Leader><Leader>" :call BreakMultlineString('"')<CR>
nnoremap <Leader>' 100\|Bi'<CR>'<Esc>
nnoremap <Leader><Leader>' :call BreakMultlineString("'")<CR>

" join lines
nmap <Leader>j Jds'ds"x
nnoremap <Leader>J :call JoinMultilineString()<CR>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.