วิธีค้นหาและแทนที่ Vim โดยไม่ต้องพิมพ์คำต้นฉบับ?


53

ฉันต้องการเพิ่มประสิทธิภาพเวิร์กโฟลว์ "ค้นหาและแทนที่" ใน Vim มันเป็นสิ่งที่ฉันทำบ่อยๆเพราะฉันมั่นใจว่าพวกคุณส่วนใหญ่ก็เช่นกัน โดยปกติบางสิ่งบางอย่างตามแนว - คัดลอกบล็อกและเปลี่ยนชื่อของตัวแปรในไม่กี่แห่ง ฉันรู้ว่าฉันรู้ว่าอาจเป็นสาเหตุของการสะท้อน "ทำไมคุณคัดลอกและวางรหัส" แต่อย่าไปลงที่ถนนนั้น ... มีกรณีการใช้งานที่ถูกต้องมากมาย :)

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

เวิร์กโฟลว์ปัจจุบันของฉันใช้การเคลื่อนไหว / ดึง / เลือก / ค้นหา / วางเพื่อย้ายไปรอบ ๆ ไฟล์และแทนที่ทีละไฟล์ มันไม่ดี แต่มีประโยชน์ในการหลีกเลี่ยงการพิมพ์ชื่อตัวแปรแบบเต็ม ฉันอาจต้องพิมพ์ตัวอักษรสองสามตัวแรกด้วย/หรือใช้คำสั่งการเคลื่อนไหวอื่น (เช่นfx) ขึ้นอยู่กับสิ่งที่อยู่รอบ ๆ แล้วกดveเพื่อเลือกคำทั้งหมด ฉันไม่สนใจว่าฉันต้องทำซ้ำทุกครั้ง ฉันไม่เคยทำการค้นหาแบบเต็มโดยไม่ยืนยันการเปลี่ยนแปลงแต่ละครั้ง แต่มันจะดีกว่าถ้าฉันสามารถทำซ้ำการดำเนินการแทนด้วยการกดแป้นเดียว (ซึ่งฉันไม่สามารถทำได้ด้วยวิธีนี้) แต่ละทดแทนมักจะเป็นสิ่งที่ต้องการnจากนั้นveแล้วp(หรือแย่"0p)

มีวิธีที่เร็วกว่านี้ไหม


1
.ทำซ้ำ "command block" สุดท้าย (ไม่แน่ใจในคำศัพท์ที่แน่นอนตัวอย่างเช่น: ย้าย + action + text สำหรับ exemple: cwtoto<Esc>(เปลี่ยนจากเคอร์เซอร์เป็นจุดสิ้นสุดของคำด้วย "toto") c/foo<enter>bar<Esc>(เปลี่ยนจากเคอร์เซอร์เป็นก่อน " foo "และแทนที่ด้วย" bar ") จากนั้นคุณสามารถย้าย (ด้วยเคอร์เซอร์ hjkl หรือตัวเลข + hjkl (ทำ n ครั้ง), G (ไปที่จุดสิ้นสุดของไฟล์) / บางสิ่ง (ไปก่อน" บางสิ่งบางอย่าง "), ฯลฯ ) และจากนั้นกด.ที่จะทำซ้ำเดียวกัน 'คำสั่งบล็อก'
โอลิเวีย Dulac

ฉันจะใช้มันไม่น้อย! อย่างไรก็ตามมันจะไม่ทำงานหากคุณต้องการดึงคำออกแล้วแทนที่คำอื่นด้วยคำนั้นในหลาย ๆ ที่ n ve "0pนั่นคือกรณีการใช้งานหลักของฉันมีปัญหากับและจะไปอะไรเช่น ซึ่งน่าเสียดายที่ไม่สามารถทำซ้ำได้ด้วย.
Joel

5
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
รวย

@ Joel คุณยังสามารถบันทึกแมโครได้ (qa แล้วทุกสิ่งที่คุณต้องการจากนั้น q: สร้างแมโคร a) จากนั้นใช้: @a เพื่อเล่นซ้ำ (และตามปกติคือ 134 @ a เพื่อทำ 134 ครั้ง) มาโครสามารถปรับแต่งได้ตามต้องการ (ตัวอย่าง: ค้นหาบางสิ่งย้ายไปยังสถานที่ที่เหมาะสมจากนั้นเปลี่ยนคำในนั้นจากนั้นย้ายไปยังตำแหน่งที่เหมาะสมเพื่อให้สามารถเรียกได้อีกครั้งในตำแหน่งที่ดีขึ้น)
Olivier Dulac

1
ฉันได้เรียนรู้เทคนิค VIM ที่มีประโยชน์จากคำถามนี้มากกว่าคำถามอื่น ๆ ในเว็บไซต์ ขอขอบคุณ!
dotancohen

คำตอบ:


81

จริง ๆ แล้วฉันมีเวิร์กโฟลว์ที่คล้ายคลึงกับคุณ (คัดลอกและวางบล็อกที่คล้ายกันจากนั้นใช้:sเพื่อเปลี่ยนชื่อตัวแปร) โดยเฉพาะอย่างยิ่งเมื่อฉันเขียนบรรทัดจำนวนมากที่คล้ายกันยกเว้นตัวแปรที่พวกเขาใช้ แต่มีสองสามอย่างที่ฉันทำคุณอาจพบว่ามีประโยชน์

สิ่งที่เป็นกลุ่มทั่วไป

  1. สิ่งแรกที่จะช่วยให้คุณมีการตระหนักว่า:s//foo/gจะเติมคำค้นหาสิ่งที่คุณใช้ครั้งสุดท้ายและแทนที่ด้วยfoo เพียงอย่างเดียวสามารถประหยัดเวลาได้มาก แต่เมื่อคุณรวมเข้ากับคำสั่งดอกจัน (ค้นหาคำที่อยู่ใต้เคอร์เซอร์ปัจจุบัน) จะช่วยประหยัดเวลาได้มาก ตัวอย่างเช่นหากต้องการเปลี่ยนทั้งหมดfooเป็นspamแทนที่จะทำ

    :%s/foo/spam/g
    

    ซึ่งต้องการให้คุณพิมพ์ทั้ง foo และสแปม (ซึ่งอาจเป็นตัวแปรที่มีความยาว) คุณสามารถนำทางไปที่ foo และทำ:

    *:%s//spam/g
    

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

    (หมายเหตุด้าน: คำสั่งดอกจันจะเพิ่มขอบเขตของคำนั่นคือ\<และ\>รอบคำใต้เคอร์เซอร์หากคุณไม่ต้องการให้ใช้g*แทน)

  2. มันจะดีกว่ามากถ้าฉันสามารถทำซ้ำการดำเนินการแทนด้วยการกดแป้นเดียว

    คุณสามารถใช้@:เพื่อทำซ้ำคำสั่งทดแทนล่าสุด นั่นเป็นสิ่งที่ดีถ้าคุณต้องการทำ:sคำสั่งบนบรรทัดจำนวนมาก แต่ไม่ใช่ทุกคำสั่งดังนั้น:%sจะไม่ทำงาน :%s///gcตัวเลือกหนึ่งคือธงยืนยันคือ สิ่งนี้จะช่วยให้คุณพิมพ์yหรือnในแต่ละเหตุการณ์เพื่อตัดสินใจว่าคุณต้องการแทนที่หรือไม่

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

    nnoremap & :&&<cr>
    
  3. หากคุณต้องการเปลี่ยนทุกสิ่งที่เกิดขึ้นในบล็อก แต่ไม่ใช่ทุกคู่ที่ตรงกันในไฟล์คุณสามารถใช้การเลือกบล็อกที่มองเห็นได้ซึ่งจะเติม

    :'<,'>
    

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

    หากคุณทำคำสั่งทดแทนอื่นคุณไม่จำเป็นต้องเลือกบรรทัดเดียวกันอีกครั้งเพราะ:'<,'> จะยังคงทำงานในบรรทัดเดียวกัน อย่างไรก็ตามมันสะดวกกว่าในการพิมพ์

    gv:s
    

    ค่อนข้างมากกว่า

    :'<,'>s
    

ปลั๊กอิน / แมปที่ฉันชอบ

  1. ฉันมีการแม็พต่อไปนี้ในของฉัน.vimrcซึ่งขยายวิธีเครื่องหมายดอกจันเพื่อให้ฉันต้องพิมพ์ชื่อใหม่ที่ต้องการ:

    "(R)eplace all
    nnoremap <leader>r yiw:%s/\<<C-r>"\>//g<left><left>
    

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

    nnoremap <leader>r yiw:%s/\<<C-r>"\>//gc<left><left><left>
    

    เพื่อให้ตัวเลือกการยืนยัน

    แก้ไข : ทำตามทั้งคำตอบของมวลชนและความคิดเห็นของ rcorreคุณสามารถเขียนสิ่งนี้เป็น

    nnoremap <leader>r :%s/\<<C-r><C-w>\>//g<left><left>
    

    ซึ่งมีข้อได้เปรียบในการรักษาชื่อของคุณไว้เหมือนเดิม

  2. หากคุณเปลี่ยนชื่อกลุ่มของตัวแปรที่คล้ายกันในเวลาเดียวกันตัวอย่างเช่นการเปลี่ยนแปลง

    fooSuffix
    PrefixFoo
    foo1
    SHOUTINGFOO
    

    ไปยัง

    barSuffix
    PrefixBar
    bar1
    SHOUTINGBAR
    

    มันอาจเป็นความเจ็บปวดที่จะทดแทนพวกมันทีละคน นี่คือที่tpope / vim-abolishมีประโยชน์ คุณสามารถแทนที่สิ่งเหล่านี้ทั้งหมดในคำสั่งเดียวด้วย:

    :%S/foo/bar/g
    

    และดูแลการใช้อักษรตัวพิมพ์ใหญ่สำหรับคุณ

สิ่งเหล่านี้จะช่วยคุณได้มาก แต่แจ้งให้เราทราบหากมีวิธีการใดที่คุณไม่ชอบหรือรู้สึกว่าขาด ฉันยินดีที่จะพูดคุยเกี่ยวกับวิธีการเพิ่มเติม :)


อ่านหนังสือที่แนะนำ:


โอ้ฉันเพิ่งเรียนรู้หลายสิ่งที่นี่ ดี! วิธีอื่นที่คุณสามารถทำได้คือ<leader>rc(หรือcr) เพื่อเพิ่มสิ่งนั้น/cในตอนท้าย นอกจากนี้ฉันได้set gdefaultตั้งค่าเพราะฉันแทบจะไม่เคยต้องการที่จะแทนที่ผลลัพธ์เดียวดังนั้นมันจะเป็นเช่นนั้น yiw:%s/\<<C-r>"\>//<left><left>
Wayne Werner

2
ช่างเป็นคำตอบที่ยอดเยี่ยมมาก!
Scott Lundberg

2
หากคุณใช้ctrl+r-ctrl+wในการทำแผนที่ (ตามที่แนะนำโดย @Mass) มันควรจะทำงานเหมือนเดิม แต่จะไม่ยุ่งกับการลงทะเบียน
yank

1
สิ่งหนึ่งที่ควรจดจำเมื่อทำงานกับกลุ่มข้อความที่คุณไฮไลต์ (ก่อนที่จะตัด / ดึง ฯลฯ ) คือคุณสามารถป้อน gv ในโหมดปกติเพื่อเน้นสีข้อความที่ไฮไลต์ใหม่ได้อีกครั้ง

1
ฉันได้เขียนปลั๊กอินgithub.com/hauleth/sad.vimที่ทำงานคล้ายกับวิธีที่ 2 hovewer ช่วยให้คุณสามารถใช้.เพื่อดำเนินการทดแทนเพิ่มเติม
Hauleth

20

c_CTRL-Rครอบครัวของแผนที่สามารถปรับปรุงเวิร์กโฟลว์ของคุณค่อนข้างบิต:

  1. คุณไม่จำเป็นต้องพิมพ์ชื่อตัวแปรเมื่อใช้:s/เพียงใช้CTRL-R CTRL-Wเพื่อแทรกคำใต้เคอร์เซอร์ลงในบรรทัดคำสั่ง (คำเตือน: นี่ไม่ได้หนีอักขระพิเศษเช่นเดียวกับ*)

  2. หลังจากที่มีการเปลี่ยนแปลงขนาดเล็กที่ใช้คุณสามารถค้นหาคำเก่าใช้ce / CTRL-R -จากนั้นใช้.เพื่อทำการเปลี่ยนแปลงซ้ำ

  3. หากคุณต้องการเปลี่ยนแปลงรูปแบบการค้นหาCTRL-R /จะทำการค้นหาที่มีอยู่ลงในบรรทัดคำสั่ง

  4. ในที่สุดคุณสามารถใส่เนื้อหาของการลงทะเบียนใด ๆ ที่ใช้ CTRL-R {register}


จุดดี! ฉันมักจะลืมเกี่ยวกับ Ctrl R. ฉันจะดูว่าฉันสามารถทำงานได้ด้วยหรือไม่
Joel

2
มูลค่าการกล่าวขวัญโดยเฉพาะCtrl-R /? ฉันใช้:sคำสั่งนี้บ่อยครั้งหากฉันต้องการใช้คำค้นหาที่เกือบจะเหมือนกัน แต่ไม่เหมือนกับคำก่อน ๆ
รวย

12

ยังมีวิธีอีกสองสามอย่างที่ (ยังทำให้ฉันประหลาดใจ!) ยังไม่ได้กล่าวถึง

การใช้gnคำสั่ง

gnทำงานเหมือนnคำสั่งยกเว้นว่านอกเหนือไปจากการกระโดดไปที่การแข่งขันมันเข้าสู่โหมดภาพด้วยการแข่งขันทั้งหมดที่เลือก

ดังนั้นหากต้องการเปลี่ยนคำ (หรืออะไรก็ตามที่คุณสามารถจับคู่กับนิพจน์ปกติ!) ก่อนอื่นให้ค้นหา1แล้วกดcgnตามด้วยข้อความที่คุณต้องการแทนที่การจับคู่ด้วยและEscเพื่อกลับสู่โหมดปกติ

(คุณพูดถึงว่าบางครั้งข้อความทดแทนที่คุณต้องการใช้จะถูกเก็บไว้ใน"0yank register - โปรดทราบว่าคุณสามารถป้อนได้อย่างรวดเร็วโดยไม่ต้องพิมพ์อีกครั้งโดยกดCtrl+R0ในโหมดแทรก)

จากนั้นคุณสามารถข้ามไปยังแมตช์ถัดไปและทำซ้ำการเปลี่ยนแปลงด้วยการ.กดแป้นเดียว!

หากมีสถานที่ใดที่คุณไม่ต้องการทำการแทนที่เพียงกดunเพื่อยกเลิกการเปลี่ยนแปลงและข้ามไปยังการแข่งขันถัดไป

1: อย่างรวดเร็วโดยใช้คำแนะนำอื่น ๆ ในหน้านี้เช่น*, Ctrl+RCtrl+Wฯลฯ ดูเพิ่มเติมความคิดเห็นปีเตอร์ Rincker ของสำหรับคำแนะนำเพิ่มเติมเกี่ยวกับวิธีการแรกเติมการค้นหาของคุณ

ใช้โหมดเลือก

(ฉันเรียนรู้สิ่งนี้จากการโพสต์ของromainl ใน subreddit กลุ่มฉันไม่รู้ว่าเขาคิดค้นมันเองหรือเพิ่งจะผ่านมันไป)

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

คุณสามารถใช้การแมปทั้งสามนี้เพื่อทำการค้นหา / แทนที่อย่างรวดเร็วซึ่งคุณสามารถเปลี่ยนไฟล์กลางได้หากจำเป็น:

nnoremap § *``gn<C-g>
inoremap § <C-o>gn<C-g>
snoremap <expr> . @.

การแมปโหมดปกติ : เข้าสู่โหมดเลือกด้วยคำที่ใกล้ที่สุดที่เคอร์เซอร์เลือกไว้

จากนั้นคุณสามารถพิมพ์การแทนที่คำที่เลือกและ ( โดยไม่ต้องกดEsc) ใช้:

แทรกการแมปโหมด : ข้ามไปยังการแข่งขันถัดไปและเข้าสู่โหมดการเลือก

จากนั้นคุณสามารถพิมพ์การเปลี่ยนใหม่หรือกด.เพื่อใช้:

เลือกการแมปโหมด : ป้อนข้อความที่แทรกล่าสุดอีกครั้งโดยหลักแล้วจะแทรกการแทรกครั้งล่าสุดซ้ำ


ฉันได้พูดถึงgnวิธีการในตอนท้ายของคำตอบของฉันvi.stackexchange.com/a/13696/488เมื่อวานนี้สำหรับสิ่งที่คุ้มค่า! คำตอบของคุณมีการจัดรูปแบบที่ดีกว่ามาก
TankorSmash

1
@TankorSmash คุณก็ทำได้! โปรดทราบว่าฉันพลาดอย่างไร โปรดทราบว่าวิธีการจริงที่ฉันใช้นั้นแตกต่างจากของคุณแม้ว่า (ฉันจะเรียกใช้เพียงgnครั้งเดียว) และเป็นวิธีเฉพาะ (แทนที่จะเป็นแค่gnคำสั่ง) ที่ฉันรู้สึกประหลาดใจที่ยังไม่ได้กล่าวถึง
รวย

ฉันจะแนะนำให้มีบางชนิดของ"ดาวภาพ"gnปลั๊กอินที่จะใช้กับ ให้ตัวเลือกการค้นหาเพิ่มเติมแก่คุณ การทำแผนที่ดาวของชายผู้น่าสงสาร: xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>. ตอน Vimcasts ที่เกี่ยวข้อง: ปฏิบัติการค้นหาการแข่งขันโดยใช้ gn
Peter Rincker

1
ฉันได้สร้าง plugin sad.vimที่ช่วยในการไหลเช่นนี้
Hauleth

7

ปลั๊กอินhttps://github.com/terryma/vim-multiple-cursorsดูแลปัญหานี้เป็นส่วนใหญ่

กระบวนการทำงานของฉันมักจะเป็นดังนี้:

  1. เลื่อนเคอร์เซอร์ไปที่คำเพื่อแทนที่
  2. กดค้างไว้ctrl-nจนกว่าจะเลือกทุกอย่าง
  3. กดcและเริ่มพิมพ์การแทนที่

สิ่งอำนวยความสะดวกที่นี่คือคุณสามารถทำการดำเนินการที่ซับซ้อนมากกว่าเพียงแค่ค้นหา - เปลี่ยนแม้ว่าฉันจะพบว่าถ้าคุณใช้เวลามากเกินไปปลั๊กอินเริ่มแสดงข้อบกพร่องบางอย่าง


4

อีกวิธีในการทำสิ่งต่าง ๆ ที่ยังไม่ได้กล่าวถึง: คุณสามารถใช้หน้าต่างบรรทัดคำสั่ง (เปิดq:ในโหมดปกติ - ดู:help q:ข้อมูลเพิ่มเติม) ซึ่งคุณสามารถเข้าถึงคุณสมบัติการเติมข้อความอัตโนมัติของ Vim ได้อย่างสมบูรณ์ ( i_CTRL-N/ i_CTRL-Pและi_CTRL-Xลำดับต่างๆอยู่ท่ามกลางพวกเขา)

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

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


1
นอกจากนี้คุณยังสามารถเปิดหน้าต่างบรรทัดคำสั่งเมื่อคุณผ่านการป้อน:substituteคำสั่งของคุณไปแล้วครึ่งหนึ่งโดยกด<ctrl-f>
Rich

2

การแก้ปัญหานี้ค่อนข้างจะอยู่ระหว่างคำตอบอื่น ๆ

สมมติว่าคุณมีเส้นที่เหมือนกัน 6 บรรทัดและคุณต้องการแทนที่ 'apple' ในกึ่งกลางสอง:

I have apples for days
I have apples for days
I have apples for days
I have apples for days
I have apples for days
I have apples for days

สิ่งที่ฉันทำคือ:

  1. ฉันไปที่จุดเริ่มต้นของข้อความที่ฉันต้องการแทนที่ 'แอปเปิ้ล'
  2. กดvปุ่มเพื่อเข้าสู่โหมดภาพ
  3. ลงไปที่คำสุดท้ายที่ฉันต้องการแทนที่ในกรณีนี้ไม่กี่บรรทัดดังนั้น 2j
  4. :s/<C-R><C-W>/ซึ่งใช้การเลือกที่มองเห็นเป็นช่วงสำหรับ:sแล้วแทรกคำใต้เคอร์เซอร์
  5. ฉันตี<C-F>ที่ทำให้คุณเข้าสู่โหมดที่คุณสามารถแก้ไขคำสั่งของคุณราวกับว่ามันเป็นบัฟเฟอร์ ดังนั้นคุณสามารถใช้ความสมบูรณ์ใด ๆ หรือปลั๊กอินที่คุณต้องการเลือกคำแทนที่และคุณเสร็จแล้ว

ทั้งหมดในหนึ่งบรรทัดการไหลของสิ่งนี้จะเป็น/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>แต่นั่นดูแย่กว่าที่เป็นอยู่

ในกรณีของคุณคุณสามารถผนวก/cกับคำสั่งที่จะข้ามคนที่คุณไม่ต้องการถ้าช่วงของคุณมีบางอย่างที่คุณต้องการที่จะข้าม::s:s/<C-R><C-W/orange/c

อีกวิธีหนึ่ง (และอาจมากกว่านั้น) คุณสามารถค้นหาทั้งคำที่คุณต้องการแทนที่เปลี่ยนcมันแล้วgnและ.ทำการค้นหาซ้ำและใช้การเปลี่ยนแปลงเดิมอีกครั้ง ดูเหมือนว่า/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.จะทำซ้ำในสามจากนั้นข้ามอินสแตนซ์จากนั้นทำซ้ำเป็นครั้งสุดท้าย


วิธีที่คุณอธิบายในตอนท้ายไม่ได้ผลสำหรับฉัน (ใน Vim 7.4 ที่เรียกใช้ด้วยvim -Nu NONE) .มันก็ดังขึ้นเมื่อกดครั้งแรก ความคิดใด ๆ ที่เป็นสาเหตุ? ไม่ว่าในกรณีใดมันจะง่ายกว่าที่จะใช้ciwแทนviwและnแทนที่จะgnทำการเปลี่ยนแปลงด้วยวิธีนี้
รวย

2

สิ่งนี้ไม่เกี่ยวข้องกับคำถามทั้งหมด แต่ก็ยังควรช่วยเลือกคำที่จะแทนที่

การค้นหาที่เพิ่มขึ้น ( set incsearch) ช่วยให้คุณพิมพ์คำนำหน้าของคำที่คุณต้องการค้นหาและเสียงเรียกเข้าจะข้ามไปที่การเกิดขึ้นครั้งแรกของคำนำหน้าโดยอัตโนมัติขณะที่คุณพิมพ์มากขึ้น การค้นหาจะได้รับการยืนยันหากคุณกด Enter และทิ้งไว้บน Esc (ในกรณีหลังเคอร์เซอร์จะกระโดดกลับไปที่เดิมก่อนการค้นหาจะเริ่มต้น)

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

ดังนั้นถ้าฉันต้องการแทนที่someOddVariableNameด้วยevenOdderVariableNameฉัน

  1. พิมพ์/someOddVและมาถึงที่เกิดขึ้นของsomeOddVariableName;
  2. กดค้างไว้<C-L>จนกระทั่งsomeOddVariableNameปรากฏในบรรทัดการค้นหาอย่างสมบูรณ์;
  3. กด Enter เพื่อยืนยันการค้นหา
  4. :%s//evenOdderVariableName/gหรือสิ่งใดแทนที่คำสั่งที่คุณต้องการ; คุณอาจต้องการทำตามคำตอบอื่น ๆ ที่นี่

2

คุณสามารถใส่ชื่อตัวแปรในบัฟเฟอร์แรก ( ywคัดลอกคำ) แล้วคัดลอกวางมันโดยการกดปุ่ม:%s<C-r>"


2

หากคุณต้องการแทนที่ตัวแปรภายในบล็อก (วาง) ใหม่ฉันมีสองข้อเสนอแนะ:

แทนที่อัตโนมัติ

  • maไปที่บรรทัดแรกของบล็อกใหม่ตี aนี้จะทำเครื่องหมายสถานที่และตั้งชื่อมัน

  • mbไปที่บรรทัดสุดท้ายของบล็อกใหม่ตี ตอนนี้คุณมีสองสถานที่ตั้งชื่อ

  • ตอนนี้แทนที่ระหว่าง:'a,'bs/oldVarName/newVarName/gสองบรรทัดเช่นดังนั้น:

  • นั่นคือขอบเขตของการแทนที่อยู่ระหว่างเครื่องหมายทั้งสองของคุณ

คู่มือวิธี

  • ไปที่บรรทัดแรกของบล็อกใหม่

  • ใช้เพื่อค้นหาตัวอย่างแรกของ/oldVarNameoldVarName

  • เปลี่ยนเป็นดังนี้: cwnewVarName<Esc>ซึ่งจะเปลี่ยนคำเป็นnewVarNameและกดปุ่มหลบหนี

  • ใช้ไปอินสแตนซ์ต่อไปของnoldVarName

  • ใช้.เพื่อทำซ้ำการเปลี่ยนแปลงครั้งล่าสุด (เช่นทำซ้ำcw)


2

คำตอบอื่น ๆ อีกมากมายที่นี่ครอบคลุมวิธีที่สร้างขึ้นเพื่อปรับปรุงเวิร์กโฟลว์ค้นหาและแทนที่ แต่ฉันต้องการพูดถึงabolish.vimปลั๊กอินของ Tim Pope มันทำให้การแทนที่ในกรณีที่คุณต้องการที่จะครอบคลุมช่วงกว้างของกรณีโดยปกติเกิดจากการเปลี่ยนแปลงในกรณีหรือเพราะคุณจำเป็นต้องจัดการกับทั้งคำเอกพจน์และพหูพจน์ของคำ

:S/child{,ren}/adult{,s}/gได้อย่างถูกต้องแปลงchildไปadult, ChildrenไปAdultsและจะCHILDADULT

หากคุณกำลังจัดการกับคำที่ใส่อูฐไว้คุณต้องใส่ตัวพิมพ์ใหญ่ที่คุณต้องการในคำที่เป็นต้นฉบับและคำที่ใช้แทนที่

%:S/wordWrap/textBreak/gได้อย่างถูกต้องจัดการทั้งและwordWrapwordwrap


0

ตามที่คนอื่น ๆ ชี้ไปแล้วหากคุณวางเคอร์เซอร์ไว้บนคำคุณสามารถใช้คำสั่งตระกูล Ctrl + r ได้เนื่องจากการกด Ctrl + r Ctrl + w น่าจะเหมาะสมที่สุดที่จะใช้

อย่างไรก็ตามวิธีการนั้นใช้สำหรับการแทรกหนึ่งคำ (เพียงใต้เคอร์เซอร์) แต่จะเกิดอะไรขึ้นถ้ามีข้อความหลายส่วนในบัฟเฟอร์ที่เราต้องการใช้ ในขณะที่คุณไม่สามารถเลื่อนเคอร์เซอร์ขณะอยู่ในบรรทัดคำสั่ง วิธีที่ดีที่สุดในการทำเช่นนี้คือการคัดลอกส่วนของข้อความที่คุณจะต้องลงทะเบียนต่าง ๆ ซึ่งคุณสามารถทำได้โดยนำหน้า "{reg_letter} (เครื่องหมายคำพูดและจดหมายจากการลงทะเบียน) ไปยังผู้ดำเนินการคัดลอกวิธีนี้จะเป็นไปได้ แทรกคำต่าง ๆ ในบรรทัดคำสั่งในภายหลังด้วย Ctrl + r {reg_letter} นี่มันค่อนข้างงุ่มง่าม แต่ใช้ได้

แต่กลับไปที่ความคิดก่อนหน้ามันจะดีถ้าเราจะย้ายตำแหน่งเคอร์เซอร์ไปที่บัฟเฟอร์ในขณะที่เขียนรูปแบบ ด้วยวิธีนี้เราสามารถ "เลือก" ข้อความจากตำแหน่งที่แตกต่างด้วย Ctrl + r Ctrl + w ดังนั้นฉันจึงสร้างปลั๊กอินที่ทำเช่นนั้น: EXtend.vim ปลั๊กอินยังมีคุณสมบัติอื่น ๆ อีกมากมายที่จะทำการดำเนินการทดแทน

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