विम में पूरी लाइन ऊपर और नीचे ले जाएँ


311

नोटपैड ++ में, मैं वर्तमान लाइन को ऊपर और नीचे स्थानांतरित करने के लिए Ctrl+ Shift+ Up/ Downका उपयोग कर सकता हूं । क्या विम में भी ऐसी ही आज्ञा है? मैंने अंतहीन गाइडों को देखा है, लेकिन कुछ भी नहीं पाया है।

यदि ऐसा नहीं है, तो मैं उस कुंजी संयोजन के लिए कार्रवाई को कैसे बांध सकता हूं?

संपादित करें: Mykola का उत्तर बफर के आरंभ और अंत में अलग-अलग सभी लाइनों के लिए काम करता है। पहली पंक्ति को ऊपर या नीचे की रेखा के नीचे ले जाने से लाइन हट जाती है, और नीचे की रेखा को ऊपर ले जाने पर यह शुरू में दो स्थानों को एक मोहरे की तरह उछाल देती है! क्या कोई भी किसी भी शोधन की पेशकश कर सकता है?


मेरे पास स्क्रिप्टिंग समाधान को लागू करने के अलावा कोई विकल्प नहीं था। मुझे आशा है कि यह आपकी आवश्यकताओं के लिए साफ और गोद लेने योग्य है।
मयकोला गोलुब्येव

31
भविष्य के बच्चों के लिए: vim.wikia.com/wiki/Moving_lines_up_or_down
बंदूकें

मुझे यकीन नहीं है कि आपको स्क्रिप्ट की आवश्यकता क्यों है, विकिया लेख उदाहरण काम करते हैं। मैंने एक सरलीकृत संस्करण के नीचे पोस्ट किया है, क्योंकि 3 अलग-अलग मानचित्रण मोड के साथ विकिया का उदाहरण कठिन हो सकता है (और वास्तव में आवश्यक नहीं है। यदि आप केवल ब्लॉक चयन मैपिंग का उपयोग करते हैं, तो आप बस चुनिंदा ब्लॉक (शिफ्ट वी) को याद कर सकते हैं और उपयोग कर सकते हैं। इन शॉर्टकट्स (नीचे मेरा उत्तर देखें)


इसके अलावा vi SE
cfi

जवाबों:


81

नौकरी करने के लिए अपने .vimrc में निम्नलिखित रखें

noremap <c-s-up> :call feedkeys( line('.')==1 ? '' : 'ddkP' )<CR>
noremap <c-s-down> ddp

रेखा का गायब होना विम बग जैसा दिखता है। मैंने इससे बचने के लिए हैक लगा दिया। संभवतः कुछ और सटीक समाधान है।

अपडेट करें

केवल विम संयोजनों का उपयोग करने के साथ कई अस्पष्टीकृत कठिनाइयाँ हैं। ये लाइन मिसिंग और एक्स्ट्रा लाइन जंपिंग हैं।

तो यहाँ स्क्रिप्टिंग समाधान है जिसे या तो .vimrc या ~ / .vim / plugin / swap_n.im के अंदर रखा जा सकता है।

function! s:swap_lines(n1, n2)
    let line1 = getline(a:n1)
    let line2 = getline(a:n2)
    call setline(a:n1, line2)
    call setline(a:n2, line1)
endfunction

function! s:swap_up()
    let n = line('.')
    if n == 1
        return
    endif

    call s:swap_lines(n, n - 1)
    exec n - 1
endfunction

function! s:swap_down()
    let n = line('.')
    if n == line('$')
        return
    endif

    call s:swap_lines(n, n + 1)
    exec n + 1
endfunction

noremap <silent> <c-s-up> :call <SID>swap_up()<CR>
noremap <silent> <c-s-down> :call <SID>swap_down()<CR>

1
बदलना पड़ा <cj> और <ck> के रूप में मेरे सेटअप के साथ एक संघर्ष हो रहा है, लेकिन शानदार जवाब! बहुत बहुत धन्यवाद
user4812

1
धन्यवाद, गिट रिबेस के लिए बहुत अच्छा को <cj> और <ck> से बांधना था। सीएस-अप / डाउन ने काम नहीं किया।
लारी होटारी

2
यदि कोई व्यक्ति एक अलग शॉर्टकट चाहता है: c नियंत्रण के लिए है, A ऊँचाई के लिए है, मैं उपयोग करता हूँ <A-up>जैसे कि ग्रहण में उपयोग किया जाता है।
जन

1
गायब लाइन एक विम बग नहीं है! यह ddkPदस्तावेज़ की अंतिम पंक्ति पर प्रदर्शन करने के कारण है । इसे 3-लाइन फ़ाइल पर अपने लिए आज़माएँ। इस तरह की समस्याओं से बचने के लिए, बहुत आसान :mमैपिंग का उपयोग करें जैसा कि विम विकी पर दिया गया है
सर्ज स्ट्रोबंड्ट

1
मैं करने के लिए पिछले लाइनों बदल <A-up>और <A-down>लेकिन जब मैं में दृश्य की दौड़ में शामिल vim में उन कुंजियों कोशिश tmux चयन गायब और कर्सर चाल लाइन अप; चयनित लाइनों को स्थानांतरित किए बिना।
कोनराड

574

अगर मैं एक लाइन को ऊपर से स्वैप करना चाहता हूं तो मैं आमतौर पर निम्नलिखित कार्य करता हूं

ddkP

व्याख्या

  • dd लाइन को हटा देगा और इसे डिफ़ॉल्ट रजिस्टर में जोड़ देगा।
  • k एक रेखा ऊपर ले जाएगा (j एक रेखा नीचे जाएगी)
  • P वर्तमान लाइन के ऊपर चिपकाएगा

5
और यह हमेशा उपलब्ध है, भी है। :-)
हेनो जूल

71
और ddpएक लाइन को नीचे ले जाने के लिए (डिलीट लाइन और करंट लाइन के नीचे पेस्ट करें)
bcoughlan

2
लाइनों के झुंड को स्थानांतरित करने के लिए, 4 को कहें, 4 ddऔर फिर 2 लाइन पर, :2जहां आप पेस्ट करना चाहते हैं , और कहें P
गुरु

2
@ गुरु 4ddइसके बजाय होना चाहिए 4 dd?
पैट्रिक मैकडॉनल्ड्स

3
और dd<number>jpलाइनों की वर्तमान संख्या <संख्या> +1 को नीचे ले जाने के लिए। और dd<number>kpलाइनों की वर्तमान लाइन <संख्या> को स्थानांतरित करने के लिए।
7

230

मान लें कि कर्सर उस पंक्ति पर है जिसे आप स्थानांतरित करना चाहते हैं।

ऊपर और नीचे :mचलना : चाल के लिए

:m +1 - 1 लाइन नीचे जाती है

:m -2 - 1 लाइनों को ऊपर ले जाएं

(ध्यान दें कि आप +1 को किसी भी संख्या से बदल सकते हैं, इस पर निर्भर करता है कि आप इसे कितनी लाइनों में ऊपर या नीचे ले जाना चाहते हैं, +2 इसे 2 पंक्तियों से नीचे ले जाएगा, -3 इसे 2 पंक्तियों तक ले जाएगा)

विशिष्ट लाइन में जाने के लिए

:set number - प्रदर्शन संख्या रेखाएं (यह देखना आसान है कि आप इसे कहां स्थानांतरित कर रहे हैं)

:m 3 - तीसरी पंक्ति के बाद लाइन को स्थानांतरित करें (अपनी पसंद की किसी भी पंक्ति को 3 बदलें)

कई पंक्तियों को आगे बढ़ाना:

V(यानी Shift- V) और VIM में कई लाइनों का चयन करने के लिए ऊपर और नीचे की ओर आएँ

एक बार चयनित हिट :और ऊपर कमांड चलाने, m +1आदि


14
मेरे लिए: एम -2 केवल एक लाइन को ऊपर ले जाता है।
हरमन इंग्लैड्ससन

2
मैं अपने vimrc में इस विधि को रखा, लेकिन फिर मैं '' का उपयोग कर कमांड को दोहराना नहीं कर सकते। क्या किसी को पता है कि क्यों है?
हरमन इंग्लैड्ससन

बहुत अच्छा! नोटपैड ++ में समाधान जितना आरामदायक नहीं है, लेकिन फिर भी - वास्तविक और काम कर रहा है।
आर्टुरस एम

हरमन, क्षमा करें, मेरी ओर से टाइपो / गलती, आप सही हैं: एम -2 इसे एक पंक्ति में ले जाएगा। मैंने इसे बदल दिया। बहुत देर से जवाब के लिए खेद है (.vimrc भाग के बारे में निश्चित नहीं) चीयर्स
सर्ग

2
कमांड कार्यों का उपयोग करते हुए आगे बढ़ना, यदि आप इसे नोटपैड ++ से जैसे बाइंडिंग में उपयोग करना चाहते हैं जैसा कि ओपी ने पूछा है, तो आपको निम्नलिखित में प्रवेश करने की आवश्यकता है ।vimrc:noremap <c-s-up> :m -2<CR> noremap <c-s-down> :m +1<CR>
kap

74

एक लाइन ऊपर ले जाएँ: ddkP

एक पंक्ति नीचे ले जाएँ: ddp


1
इस vimrc में होने से कमांड '' का उपयोग करते हुए दोहराता है।
हरमन इंग्लैड्ससन

@HermannIngjaldsson, मुझे लगता है कि आप एक फ़ंक्शन में कमांड लपेट सकते हैं यदि आप .दोहराने के लिए उपयोग करने में सक्षम होना चाहते थे ।
जेकोबिसिमोन

यस, .. और यदि आपको अधिक लाइनों को स्थानांतरित करने की आवश्यकता है, तो आप dd के बजाय V का उपयोग कर सकते हैं।
सेंसरियो

15

यह मेरे लिए काम किया:

http://vim.wikia.com/wiki/Moving_lines_up_or_down_in_a_file

BTW, यदि आप ALT + some_key का उपयोग करना चाहते हैं और आपका टर्मिनल (urxvt ऐसा करता है) अनुपालन करने से इनकार करता है, तो आपको अपने .vimrc में कुछ इस तरह दर्ज करना चाहिए:

" For moving lines (^] is a special character; use <M-k> and <M-j> if it works)
nnoremap ^]k mz:m-2<CR>`z==
inoremap ^]j <Esc>:m+<CR>==gi
inoremap ^]k <Esc>:m-2<CR>==gi
vnoremap ^]j :m'>+<CR>gv=`<my`>mzgv`yo`z
nnoremap ^]j mz:m+<CR>`z==
vnoremap ^]k :m'<-2<CR>gv=`>my`<mzgv`yo`z

जहाँ ^] एक एकल वर्ण है जो ALT कुंजी का प्रतिनिधित्व करता है। उस चरित्र को इनपुट करने के लिए, C+v, Escविम ( C+q, Escविंडोज पर) में उपयोग करें ।


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

1
आप Esc को <kbd> Cv <kbd /> <kbd> Esc </ kbd> (linux) के रूप में दर्ज क्यों नहीं करते हैं। विंडोज बोर्ड भर में <kbd> Cv <kbd /> <kbd> Cq <kbd /> द्वारा प्रतिस्थापित करता है, लेकिन इन्सर्ट / कमांड मोड में किसी विशेष कुंजी को दर्ज करने का एक ही तरीका है
sehe

@sehe: धन्यवाद, मुझे उस समय पता नहीं था। मैंने जवाब अपडेट कर दिया है।
emil.p.stanchev

1
@ राफेलरिनाल्डी, [niv]noremapसामान्य के लिए रिमैप हैं। <CR>है Carriage Return( Enterकुंजी)।
vp_arth

1
@vp_arth नहीं
जूल

13

निम्नलिखित को ~ / .vimrc फ़ाइल में जोड़ें (सुनिश्चित करें कि आपके पास n, m के लिए कोई मैपिंग नहीं है)

nmap n :m +1<CR>
nmap m :m -2<CR>

अब दबाने वाली nकुंजी एक रेखा को नीचे mले जाएगी और एक रेखा को ऊपर ले जाएगी।


12

कमांड मोड में कर्सर को उस रेखा पर रखें जिस पर आप नीचे जाना चाहते हैं, और फिर

ddp

स्पष्टीकरण: dd सामान्य रेखा p को वर्तमान रेखा हटाता है p इसे कर्सर स्थिति के बाद वापस लाता है, या संपूर्ण लाइनों के मामले में, एक पंक्ति नीचे।

कई डॉक्स में कमांड पी और पी के संबंध में कुछ भ्रम है। हकीकत में p, कर्सर से पहले और P पर कर्सर से चिपका है।


8

बस इस कोड को .vimrc (या .gvimrc) में जोड़ें

nnoremap <A-j> :m+<CR>==
nnoremap <A-k> :m-2<CR>==
inoremap <A-j> <Esc>:m+<CR>==gi
inoremap <A-k> <Esc>:m-2<CR>==gi
vnoremap <A-j> :m'>+<CR>gv=gv
vnoremap <A-k> :m-2<CR>gv=gv

1
Vim.wikia.com/wiki/… के अनुसार व्यापक विवरण के लिए वहाँ देखें।
सर्ज स्ट्रोबोबंड

एक मैक पर <A-something> काम नहीं करता है, मुझे पता नहीं क्यों। मैंने <Cj> <Ck> से बदल दिया है, और Ctrl कुंजी का उपयोग करके अच्छी तरह से काम करता है।
सेड्रिक निकोलस

5

वास्तव में आप इस भयानक प्लगइन की तलाश कर रहे हैं : https://github.com/vim-scripts/upAndDown


1
यह कई लाइनों का भी समर्थन करता है जो अच्छी है।
स्टुडेगेक

इसके लिए <S> कुंजी क्या है?
उस्मान मान

@UsamaMan शिफ्ट संशोधक
mazunki


3

मैंने अपने .vimrc फ़ाइल के अंत में निम्नलिखित डाला:

noremap H ddkkp
noremap N ddp

तो अब 'एच' और 'एन' वर्तमान लाइन को क्रमशः ऊपर और नीचे ले जाते हैं।


एच और एन वास्तव में उपयोगी कमांड हैं (एच स्क्रीन के ऊपर और शुरुआत में कर्सर ले जाता है, एन पिछले खोज परिणाम पर जाता है), इसलिए मैं अलग-अलग कुंजी का उपयोग करने की सलाह
दूंगा

समझा। मैंने भी उन्हें समेट लिया है। स्क्रीन के शीर्ष पर जाने के लिए मैं एक प्रेस करता हूं और फिर ऊपर। मेरी किताबों में हमेशा एक तरह का मतलब होता है। और पिछले परिणामों के माध्यम से खोजने के लिए मैं एफ दबाता हूं और फिर छोड़ दिया जाता है। F तो खोजने के लिए खड़ा है। लेकिन उन लोगों के लिए जो ऐसा नहीं है तो हाँ .. इसकी वैधता।
हरमन इंग्लैड्ससन

1

यहाँ मैकियाम के लिए एक सरल संस्करण है, विकिया लेख उदाहरणों का उपयोग करके ( बंदूक की टिप्पणी से सीएफ। लिंक )।

" Move selection up/down (add =gv to reindent after move)
:vmap <D-S-Up> :m-2<CR>gv
:vmap <D-S-Down> :m'>+<CR>gv

मैं केवल ब्लॉक चयन संस्करण का उपयोग कर रहा हूं, क्योंकि वर्तमान लाइन का चयन करने के लिए यह सब शिफ्ट-वी है, और कुछ और लाइनों का चयन करने के लिए वैकल्पिक रूप से कर्सर अप / डाउन करें।

ऊपर दिए गए शॉर्टकट्स के अनुसार, Cmd-Shift-Up / Down दबाने पर ब्लॉक सिलेक्शन अप / डाउन हो जाएगा। MacVim में "D" कमांड कुंजी है, विंडोज़ के लिए "C" (नियंत्रण), या "A" (Alt) (जैसे। <CAf> नियंत्रण Alt f होगा)।

विकिया लेख में इन पर "= जीवी" जोड़ा गया है, जो कि आसपास के पाठ के आधार पर, कदम के बाद ब्लॉक के इंडेंटेशन को समायोजित करने का प्रभाव है। यह भ्रामक है इसलिए मैंने इसे हटा दिया, और इसके बजाय चयन को जल्दी करने के लिए शॉर्टकट जोड़े।

" Indent selection left/right (Cmd Shift Left/Right is used for Tab switching)
:vmap <D-A-Left> <gv
:vmap <D-A-Right> >gv

मन, वही << और >> के साथ किया जा सकता है, लेकिन चयन खो जाएगा, इसलिए ऊपर दिए गए ये शॉर्टकट कई बार इंडेंट करने की अनुमति देते हैं और फिर भी चयन को बनाए रखने के कारण ब्लॉक को इधर-उधर कर देते हैं।

मेरे MacVim को Cmd-Shift-Left / Right के साथ Tabs स्विच करने के लिए कॉन्फ़िगर किया गया है, इसलिए मैंने Cmd-Alt-Left / दाएँ का उपयोग किया।

यहाँ MacVim के लिए टैब स्विचिंग (बाकी ऊपर के साथ .gvimrc में डालें):

:macm Window.Select\ Previous\ Tab key=<D-S-Left>
:macm Window.Select\ Next\ Tab key=<D-S-Right>

1

vim plugin unimpaired.vim [e और] e


2
यह ओवरकिल की तरह लगता है, मुझे नहीं लगता कि आपको वास्तव में इसके लिए एक पूर्ण प्लगइन की आवश्यकता है। एक vimrc में 2 पंक्तियाँ वही करती हैं जो ओपी चाहता है
डैनियल ग्रैज़र

1

जब आप कमांड :help moveको हिट करते हैं vim, तो यहां परिणाम है:

:[range]m[ove] {address} *:m* *:mo* *:move* *E134* Move the lines given by [range] to below the line given by {address}.

उदा: वर्तमान रेखा को एक पंक्ति नीचे ले जाएँ => :m+1

जैसे: संख्या .० => के साथ पंक्ति के नीचे १०० नंबर के साथ लाइन ले जाएँ :100 m 80

जैसे: संख्या 200 => वाली रेखा के नीचे 100 नंबर के साथ लाइन को स्थानांतरित करें :100 m 200

जैसे: २०० => की रेखा के नीचे [१००, १२०] के साथ संख्या के साथ लाइनों को स्थानांतरित करें :100,120 m 200


1

यहाँ एक समाधान है जो मेरी मशीन पर काम करता है : मैकबुक प्रो VIM 8.1 चल रहा है

ये कमांड आपके बफर के ऊपर या नीचे आपकी लाइनों को नहीं हटाएंगे।

ऑल्ट-जे और ऑल्ट-के आउटपुट वास्तविक प्रतीकों का उपयोग करना, उनके कुंजी-कोड के लिए मेरे वातावरण में ठीक से मैपिंग नहीं करने के लिए एक समाधान है।

इसे पुराने .vimrc में फेंक दें और देखें कि क्या आपके लिए काम करता है।

" Maps Alt-J and Alt-K to macros for moving lines up and down
" Works for modes: Normal, Insert and Visual
nnoremap ∆ :m .+1<CR>==
nnoremap ˚ :m .-2<CR>==
inoremap ∆ <Esc>:m .+1<CR>==gi
inoremap ˚ <Esc>:m .-2<CR>==gi
vnoremap ∆ :m '>+1<CR>gv=gv
vnoremap ˚ :m '<-2<CR>gv=gv


0

: m। + 1 या: m.-2 यदि आप एक पंक्ति को आगे बढ़ा रहे हैं, तो आप करेंगे। यहाँ कई लाइनों को स्थानांतरित करने के लिए मेरी स्क्रिप्ट है। दृश्य मोड में, Alt-up / Alt-down, दृश्य चयन युक्त लाइनों को एक पंक्ति से ऊपर / नीचे ले जाएगा। सम्मिलित मोड या सामान्य मोड में, यदि कोई गिनती उपसर्ग नहीं दी गई है, तो Alt-up / Alt-down वर्तमान रेखा को स्थानांतरित करेगा। यदि कोई गिनती उपसर्ग है, तो Alt-up / Alt-down उस लाइन को चालू करने वाली कई लाइनों को एक पंक्ति से ऊपर / नीचे ले जाएगा।

function! MoveLines(offset) range
    let l:col = virtcol('.')
    let l:offset = str2nr(a:offset)
    exe 'silent! :' . a:firstline . ',' . a:lastline . 'm'
        \ . (l:offset > 0 ? a:lastline + l:offset : a:firstline + l:offset)
    exe 'normal ' . l:col . '|'
endf

imap <silent> <M-up> <C-O>:call MoveLines('-2')<CR>
imap <silent> <M-down> <C-O>:call MoveLines('+1')<CR>
nmap <silent> <M-up> :call MoveLines('-2')<CR>
nmap <silent> <M-down> :call MoveLines('+1')<CR>
vmap <silent> <M-up> :call MoveLines('-2')<CR>gv
vmap <silent> <M-down> :call MoveLines('+1')<CR>gv

0

यदि आप एक विशिष्ट खोज से मेल खाने वाली कई लाइनों पर ऐसा करना चाहते हैं:

  • यूपी: :g/Your query/ normal ddp या:g/Your query/ m -1
  • नीचे :g/Your query/ normal ddpया:g/Your query/ m +1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.