ฉันสามารถเข้าร่วมบรรทัดด้วยเครื่องหมายจุลภาค (หรืออักขระอื่น) ได้หรือไม่


19

ฉันรู้ว่าฉันสามารถเข้าร่วมสายในเสียงเรียกเข้าด้วยJและหลายสายพันธุ์ของมัน ( gJ, ฯลฯ ); Jจะ"ลบเยื้องและใส่ได้ถึงสองช่องว่าง"

แต่มีวิธีที่ตรงไปตรงมาในการแทรกตัวละครอื่นแทนที่จะเป็นช่องว่างทั้งสองหรือไม่? เช่นเครื่องหมายจุลภาค ( ,) หรือเครื่องหมายจุลภาค & space ( ,)?

ได้รับ:

8
9
10
32

ฉันต้องการที่จะจบลงด้วย:

8, 9, 10, 32

หรือ:

8,9,10,32

คุณอาจต้องการgithub.com/sk1418/Join (ไม่ผ่านการทดสอบ)
VanLaser

คำตอบ:


5

ฉันเขียนปลั๊กอินเข้าร่วมสามารถทำสิ่งที่คุณต้องการและอีกมากมาย

ยกเว้นคุณสมบัติทั้งหมดที่มีในคำสั่ง build-in: join, Join สามารถ:

  • เข้าร่วมสายที่มีตัวคั่น (สตริง)
  • เข้าร่วมสายที่มีหรือไม่มีการตัดแต่งช่องว่างนำหน้า / ต่อท้าย
  • เข้าร่วมสายที่มีจำนวนลบ (เข้าร่วมย้อนหลัง)
  • เข้าร่วมสายกลับกัน
  • เข้าร่วมสายและให้เข้าร่วมสาย (โดยไม่ต้องลบสายเข้าร่วม)
  • เข้าร่วมสายกับการรวมกันของตัวเลือกข้างต้น

รายละเอียดและภาพหน้าจอเพิ่มเติม:

https://github.com/sk1418/Join


23

วิธีง่าย ๆ คือ: เพียงเลือกบรรทัดของคุณ (ทั้งหมดยกเว้นบรรทัดสุดท้าย) - หรือใช้%- และเรียกใช้:

:'<,'>s/\n/,/

หรือ

:'<,'>s/\n/, /

(แน่นอน'<,'>ส่วนที่ถูกแทรกหลังจาก:Vim เพื่อกำหนดเป้าหมายการเลือก)


(2) อัปเดต:

อาคารด้านบน (และความคิดเห็นของSato Katsura ) ต่อไปนี้คือการดำเนินการ "เข้าร่วมแบบโต้ตอบ" ที่เป็นไปได้โดยมีการนับซ้ำและการสนับสนุนซ้ำ ๆ เพิ่มเติม:

" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
    if (a:use_last_sep == 0) "interactive, ask for separator to use
        call inputsave()
        echohl Question
        let l:sep = input("Separator:", g:last_join_separator)
        echohl None
        call inputrestore()
        redraw!
        let g:last_join_separator = l:sep "update last separator value
    else "non-interactive (when repeating with '.')
        let l:sep = g:last_join_separator
    endif
    if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
        let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
    else " don't remove indentation or trailing spaces (act like 'gJ')
        let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
    endif
    if a:firstline < a:lastline "join given range
        execute a:firstline . ',' . (a:lastline - 1) . l:subst
        let l:count = a:lastline - a:firstline + 1 "default count for repeat
    else "or join only with next line
        execute l:subst
        let l:count = 1 "default count for repeat
    endif
    "make command repeatable
    "(with the tpope/vim-repeat plugin: optional, recommended)
    if (a:0 == 0)
        silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
    else
        silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
    endif
endfunction

noremap <silent> <Plug>(interactiveJoin)  :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin)       :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin)      :call <SID>interactiveJoin(1,'g')<CR>

และการทำแผนที่จริง:

"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)

นี่เป็น kinda (*) ที่ชอบJแต่เป็นแบบโต้ตอบ - มันจะพร้อมต์ให้กับสตริงตัวคั่น สตริงเริ่มต้นคือช่องว่าง - ตัวอย่างเช่นในการเข้าร่วมบรรทัดที่ไม่มีตัวคั่นกดBackspaceเมื่อได้รับแจ้งเพื่อลบอักขระช่องว่างเริ่มต้นและEnterเพื่อยอมรับตัวคั่นว่าง (ตอนนี้) นับเช่น3Jทำงานได้เช่นกัน หากtpope/vim-repeatติดตั้งปลั๊กอินให้ทำซ้ำด้วย '.' จะใช้งานได้การใช้ตัวคั่นล่าสุดซ้ำและ (หากไม่มีการเปลี่ยนแปลง - เช่น10.) การนับครั้งล่าสุดหรือช่วงของเส้นภาพ


(*) มันไม่ตรงเช่นJแม้ว่า: ในขณะที่มันจะลบเยื้องก็จะไม่ตรวจสอบ.!?(ตอนจบของวลี) เพื่อแทรก 2 คันแทนหนึ่งหรือใส่เป็นพื้นที่เฉพาะในกรณีที่มันหายไป (มันยากที่จะทำสิ่งที่ชอบ สิ่งนี้เนื่องจากสตริงตัวคั่นสามารถเป็นอะไรก็ได้ในขณะนี้) นอกจากนี้ยังจะลบช่องว่างต่อท้าย (ดูสมเหตุสมผล)

ฉันคิดว่านี่อาจเป็นวิธีที่ดีในการ จำกัด จำนวนผู้ให้บริการพื้นที่จดหมาย :)

ในทางเทคนิคแล้วJมันไม่ได้เป็นโอเปอเรเตอร์ แต่ใกล้เคียงกับหนึ่งตัวอย่างเช่นคุณไม่สามารถทำได้Jawเพื่อเข้าร่วม "คำ"

(ยินดีต้อนรับคำแนะนำ)

ป้อนคำอธิบายรูปภาพที่นี่


2
ยังดีกว่า: :'<,'>-1s/\n/, /สำหรับบรรทัดที่ทำเครื่องหมายไว้หรือ:1,$-1s/\n/, /สำหรับไฟล์ทั้งหมด
Sato Katsura

แน่นอนว่ามันดียิ่งขึ้น :)
VanLaser

@SatoKatsura คุณสามารถอธิบายได้-1หรือไม่
alxndr

1
@alxndr - ใช้เพื่อข้ามบรรทัดสุดท้ายในช่วง / file: เช่นในตัวอย่าง OP คุณไม่ต้องการคอมม่าหลังจาก 32 และคุณไม่ต้องการเข้าร่วมกับบรรทัดถัดไปหากมีอยู่ . คุณยังสามารถใช้'<,'>-s/\n/, /หรือ1,$-s/\n/, /เป็นเป็นเช่นเดียวกับ- -1
VanLaser

1
ถ้าl:sepเป็น&แล้วการเปลี่ยนของคุณจะทำงานไม่ถูกต้องเนื่องจาก&เป็นเวทมนตร์ในการเปลี่ยน อาจดีกว่าที่จะใช้\=เพื่อใช้สตริงตัวอักษร - let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- แทนที่จะพยายามจัดการกับการหลบหนี
jamessan

3

นี่คือตัวอย่างการใช้คำสั่งภายนอก:

:%!paste -sd,

โดย%!แทนที่บัฟเฟอร์ปัจจุบัน (เนื้อหาของไฟล์) ด้วยคำสั่ง: paste -sd,(พารามิเตอร์-sถูกใช้เพื่อรวมหลายบรรทัดและ-dตั้งค่าอักขระตัวคั่นเป็น,)


3

ในกรณีที่มีคนไม่ชอบพิมพ์ Regex และจดจำคำสั่ง Plugin Ex เพิ่มเติม:

ผนวกบล็อกแบบเห็นภาพ

ผนวกบล็อกที่มองเห็นได้ในโหมด Visual Block ( <C-v>) และสามารถทำบล็อกA ppend (และบล็อกฉัน nsert สำหรับการเติม) (อ้างอิง: :help v_b_A, :help v_b_I)

และหากการเคลื่อนไหวครั้งสุดท้ายในโหมดบล็อกภาพคือ$การผนวกจะทำในตอนท้ายของการเลือกทั้งหมด; มิฉะนั้นจะมีการแทรกช่องว่างก่อนข้อความที่คุณต่อท้าย (ลองนึกภาพการจัดแนวปิด)ที่ส่วนท้ายของการโทรด้วยวิธีการต่างๆในรหัส)

ด้วยข้อความตัวอย่างด้านล่างและเคอร์เซอร์บน8:

8
9
10
12

<C-v>}$A,<C-c>. หลังจากกลับไปที่โหมดปกติเราจะเห็นว่า,ต่อท้ายทุกบรรทัดที่เลือก (ลองโดยไม่ต้อง$)

แล้วทำgvอีกครั้งเลือกพื้นที่และหรือJ gJเรามีส่วนท้าย,: 8,9,10,12,และ$xเราเสร็จแล้ว

ใช้การแทรกสำหรับการไม่มีการต่อท้าย ,

ลองยกเลิกข้อความของเรา (ไม่ว่าจะuu..uเป็นแฟนซีหรือ:ea 1d<cr>:lat 1ลอง) และลองแทรกภาพ:

j<C-v>}I, <C-c>และจากนั้นเราสามารถเข้าร่วมบรรทัดโดยgJไม่มีช่องว่าง

รอเดี๋ยวเดี๋ยวก่อนมีบางอย่างหายไป วิธีการเลือก "อาร์เรย์" ทั้งหมดอีกครั้ง? ครั้งนี้เราไม่ได้เลือกบรรทัดแรก ... ดังนั้นจึงgvไม่ช่วย

- หรืออาจช่วยได้gvokคือเลือกใหม่ ( gv), oเปิดมุม pposite kขึ้นไป

PS ฉันพิ้งกี้ไม่ได้อย่างรวดเร็วและถูกต้องมากพอที่จะพิมพ์/\สำหรับ/\nดังนั้นฉันเช่นการรวมกลุ่มตัวในการดำเนินงานและการเคลื่อนไหวที่จะหลีกเลี่ยงการใช้ Regex อย่างไรก็ตามหากฉันทำสิ่งนี้บ่อยครั้งมากพอการใช้การจับคู่อาจเป็นแผนที่ที่ไปยังปลั๊กอินควรจะดีกว่า


1

วิธีที่ง่ายกว่ามากโดยไม่มีปลั๊กอินหรือคำสั่งภายนอกเพื่อทำการแมปใหม่ ( J) จากพื้นที่หนึ่งไปยังอักขระใดก็ได้ที่คุณต้องการ ตัวอย่างเช่นหากต้องการเข้าร่วมกับเครื่องหมายจุลภาคและช่องว่าง:

:nmap J :s/\n/, /^M

สำหรับอักขระขึ้นบรรทัดใหม่ที่ท้าย ( ^M) กดCtrl-Vจากนั้นกลับ / Enter เดียวกันจะไปถ้าคุณต้องการที่จะแทนที่ด้วยแท็บ ( ^I) พิมพ์แล้วCtrl-ITab

:nmap J :s/\n/^I/^M

สิ่งนี้กำลังทำคือการแทนที่ขึ้นบรรทัดใหม่ด้วยแท็บบนบรรทัดปัจจุบันและทำการแมปลักษณะการทำงานนั้นซ้ำกับอักขระ J

สิ่งนี้ยังทำงานร่วมกับชุดค่าผสมเช่นเดียวกับใน4Jการเข้าร่วม 4 บรรทัดถัดไป


0

คุณสามารถบันทึกแมโครเพื่อเข้าร่วมบรรทัดด้วยเครื่องหมายจุลภาค สิ่งนี้มีประโยชน์หากเป็นงานที่หายากหรือเป็นงานครั้งเดียวและคุณจำไม่ได้ว่าจะเขียนคำสั่งทดแทนและนิพจน์ทั่วไปเพื่อทำงานได้อย่างไร แต่คุณจะจำวิธีบันทึกและเรียกใช้แมโครได้

ในการเข้าร่วมสายด้วยเครื่องหมายจุลภาคพิมพ์ในการบันทึกแมโครในการลงทะเบียนqjgJi,Escq จากนั้นคุณสามารถเรียกใช้แมโครด้วยj @jคุณสามารถเรียกใช้แมโครอีกครั้งด้วย@@ซึ่งจะช่วยในการพิมพ์เมื่อเรียกใช้หลายครั้งในแถวคุณสามารถกดค้างไว้@จนกว่าคุณจะเข้าใกล้จุดสิ้นสุดของบรรทัดที่คุณต้องการเข้าร่วม นอกจากนี้คุณยังสามารถใช้คำนำหน้าเป็นตัวเลข@jหรือ@@เปิดซ้ำจำนวนครั้ง การทำเช่นนี้จะทำให้ช่องว่างนำหน้าและต่อท้ายเหมือนเดิมดังนั้นจะมีช่องว่างก่อนหรือหลังเครื่องหมายจุลภาคหากข้อความต้นฉบับของคุณมีช่องว่างอยู่

ในการเข้าร่วมกับเครื่องหมายจุลภาคและเว้นวรรคให้แทรกSpaceระหว่าง,และEscเมื่อบันทึกแมโคร

นอกจากนี้คุณยังสามารถใช้JแทนgJเมื่อบันทึกแมโครซึ่งโดยปกติจะรวมบรรทัดด้วยเครื่องหมายจุลภาคและเว้นวรรค อย่างไรก็ตามหากบรรทัดปัจจุบันมีช่องว่างต่อท้ายคอมมาจะปรากฏหลังช่องว่างโดยไม่มีช่องว่างตามหลัง นอกจากนี้ยังไม่รวมพื้นที่ที่ถ้าบรรทัดถัดไปเริ่มต้นด้วย)และมันทำให้สองช่องว่างหลังเครื่องหมายจุลภาคถ้าjoinspacesมีการตั้งค่าและปลายสายในปัจจุบันมี., หรือ! คำเตือนเหล่านี้จะอธิบายภายใต้?:help J

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.