มีวิธีใช้การแทนที่แบบสอบถามจากโหมดเอาต์พุต grep / ack / ag หรือไม่?


31

ฉันรู้find-grep-diredแล้วทำเครื่องหมายไฟล์ที่เกี่ยวข้องแล้วกดQเพื่อเรียกใช้dired-do-query-replace-regexpไฟล์ที่ทำเครื่องหมาย น่าเสียดายที่ต้องรีสตาร์ท grep และไม่ต้องใช้ git-grep, ack หรือ ag และเปลี่ยนเป็นใช้find-grepซึ่งมีไวยากรณ์ที่แตกต่างกันสำหรับการค้นหา

ฉันรู้multi-occurและoccur-edit-modeด้วย แต่ต้องเริ่มต้นใหม่โดยใช้การค้นหาเกิดขึ้น ในที่สุดag-diredดูเหมือนจะตรงกับชื่อไฟล์ไม่ใช่เนื้อหาของไฟล์

วิธีการปัจจุบันของฉันคือการสร้างเอาต์พุต grep จากนั้นเรียกใช้แมโครที่เริ่มต้นในบัฟเฟอร์ grep และเข้าชมแต่ละรายการที่ตรงกันและเปลี่ยนแปลง ฉันต้องการใช้query-replaceโดยตรงกับชุดการแข่งขันที่พบ

สิ่งที่ฉันต้องการจะทำคือการอย่างใดอย่างหนึ่งได้อย่างรวดเร็วสร้างบัฟเฟอร์ dired จากการส่งออก grep ที่มีอยู่เพื่อที่ฉันสามารถทำเครื่องหมายไฟล์ที่เหมาะสมและโทรสอบถาม regexp กับพวกเขาหรือเปลี่ยนเอาท์พุท grep ลงในรายการของบัฟเฟอร์สำหรับmulti-occurเพื่อที่ฉันสามารถใช้occur-edit-modeเพื่อ แก้ไขให้ถูกต้องและรันquery-replaceบนบัฟเฟอร์นั้น

ฟังก์ชันนี้มีอยู่หรือมีเวิร์กโฟลว์อื่นที่สามารถแก้ไขปัญหานี้ได้หรือไม่

คำตอบ:


28

@Malabarba พูดถึงการใช้wgrepแพคเกจสำหรับการแก้ไขผลลัพธ์ grep / ack / ag

ฉันต้องการเขียนรายละเอียดวิธีใช้agแพคเกจและwgrep-agแพ็คเกจเพื่อให้ได้การแก้ไข 'ผลลัพธ์ ag'ged โดยใช้multiple-cursorsแพ็คเกจ

แพ็คเกจเหล่านี้มีให้บริการผ่าน Melpa คุณต้องติดตั้งagaka the_silver_searcherบนระบบของคุณ

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

  • ติดตั้งagบนระบบของคุณและแพ็คเกจ emacs ที่กล่าวถึงข้างต้น

  • agรองรับการค้นหาไฟล์ที่มีเนื้อหาที่ตรงกับ regex ที่คุณระบุ วิธีที่ง่ายที่สุดในการบอกagตำแหน่งของรูทโปรเจ็กต์เพื่อวาง.gitโฟลเดอร์ว่างไว้ที่นั่น M-x ag-project-regexpจากนั้นทำการค้นหาโดยใช้

  • บัฟเฟอร์ผลลัพธ์ของการค้นหา ag ไม่สามารถแก้ไขได้โดยค่าเริ่มต้น เพื่อให้สามารถแก้ไขได้ทำM-x wgrep-change-to-wgrep-modeหรือใช้wgrep-default C-c C-pผูกพัน

  • ตอนนี้หากคุณต้องการเปลี่ยน 'abcdef' เป็น 'ghijkl' ในไฟล์ทั้งหมดของคุณคุณจะต้องค้นหา 'abcdef' และบัฟเฟอร์ผลลัพธ์ ag จะแสดงบรรทัดทั้งหมดที่มีสตริงนั้น แล้วคุณทำที่บัฟเฟอร์ที่สามารถแก้ไขได้และเปลี่ยนสายเหล่านั้นด้วยตนเองและการเปลี่ยนแปลงเหล่านั้นจะสะท้อนให้เห็นในบัฟเฟอร์ไฟล์จริงในการทำหรือใช้ค่าเริ่มต้นที่มีผลผูกพันM-x wgrep-finish-edit C-c C-eคุณยังสามารถใช้query-replace-regexpเพื่อทำการค้นหาแทน

  • ฉันชอบที่จะใช้multiple-cursorsสำหรับการปรับโครงสร้างใหม่อย่างรวดเร็วเพื่อที่ฉันจะได้เห็นข้อเสนอแนะแบบเรียลไทม์ว่ามีการแก้ไขหลายรายการพร้อมกันที่ไหน เน้นสตริงที่คุณต้องการแทนที่ในบัฟเฟอร์ผลลัพธ์ ag และการโทรM-x mc/mark-all-like-thisแล้วแก้ไขออกไปอย่างน่าเกรงขามในขณะที่คุณเห็นสิ่งต่าง ๆ ที่ได้รับการแก้ไขในหลายจุดในเวลาเดียวกัน

  • เมื่อคุณพอใจกับการแก้ไขดังที่ได้กล่าวมาแล้วให้ทำC-c C-e"สะท้อน" การเปลี่ยนแปลงในบัฟเฟอร์จริง ยังไม่ได้บันทึกบัฟเฟอร์

  • เพื่อบันทึกบัฟเฟอร์ทั้งหมดฉันมักจะทำในครั้งเดียวโดยใช้การC-x s !ผูกemacs เริ่มต้น

นี่คือตัวอย่างการใช้งานที่มีหน้าจอตัวอย่าง:

มันแสดงให้เห็นกระบวนการของการเปลี่ยนทุกกรณีของbind-to-modi-mapการในของฉันbind-to-my-map~/.emacs.d/

เมื่อฉันค้นหาbind-to-modi-mapในโฟลเดอร์การตั้งค่า emacs ของฉันฉันได้ผลลัพธ์ ag'ged ด้านล่าง:ผลลัพธ์ ag ไม่มีการแก้ไข

บัฟเฟอร์นี้เป็นแบบอ่านอย่างเดียว

หลังจากนั้นM-x wgrep-change-to-wgrep-modeฉันไฮไลต์ให้-modi-mapเลือกอินสแตนซ์ทั้งหมดของการเลือกที่ใช้M-x mc/mark-all-like-thisและหลังจากแก้ไขการเลือกเหล่านั้น-my-mapแล้วจะมีลักษณะดังนี้: ผลลัพธ์ ag ปรับเปลี่ยนโดยใช้หลายเคอร์เซอร์

C-c C-eสีฟ้าแสดงไฮไลท์ซึ่งเส้นจะถูกแก้ไขเมื่อกด

เมื่อกดปุ่มC-c C-eคุณจะเห็นการเปลี่ยนแปลงที่ปรากฏในไฟล์จริงในภาพหน้าจอนี้: ผลลัพธ์ ag หลังจากเสร็จสิ้นการแก้ไข

C-x s !ฉันก็จะบันทึกไฟล์ทั้งหมดที่แก้ไขได้โดยใช้


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

13

สิ่งที่ฉันต้องการจะทำคือการสร้างบัฟเฟอร์ที่ล้าสมัยอย่างรวดเร็วจาก grep output ที่มีอยู่ [... ] หรือเปลี่ยนการส่งออก grep ไปยังรายการบัฟเฟอร์สำหรับ multi-เกิดขึ้น [... ]

คุณไม่จำเป็นต้องแปลงบัฟเฟอร์ผลลัพธ์ grep เป็นอะไรเลยมีโหมดเฉพาะสำหรับการแก้ไขเอาต์พุต grep (และสะท้อนการเปลี่ยนแปลงในไฟล์ของหลักสูตร)

  1. ติดตั้งwgrepแพคเกจจาก Melpa
  2. (require 'wgrep) ในไฟล์ init ของคุณ
  3. หลังจากทำการค้นหา grep กดC-c C-pและแก้ไขทันที!
  4. บันทึกการแก้ไขของคุณด้วย C-c C-e

มันใช้ได้กับ ack และ ag ด้วยเช่นกัน


2
นั่นคือสิ่งที่ฉันทำ (กับ ag.el) เมื่อรวมกับการปรับเปลี่ยนหลายส่วนแบบเรียบง่ายด้วยแว่นขยายแบบมัลติสโคปนั้นเป็นเรื่องง่ายมาก
Tom Regner

4

ฟังก์ชั่นนี้มีอยู่ภายในprojectile ( projectile-replace) มันจะใช้ ag / ack / git grep / grep หากมี (ตามลำดับ) เพื่อค้นหาสิ่งที่เกิดขึ้นและtags-query-replaceเพื่อดำเนินการค้นหาแทนที่


ที่ทนทุกข์ทรมานจากปัญหาเดียวกันกับ find-grep-dired ไม่ได้ใช้เอาต์พุต grep ที่มีอยู่ มีปัญหาคล้ายกับ projectile-multi-เกิดขึ้น ฉันต้องการเริ่มการค้นหาแทนที่หลังจากดูรายการการจับคู่และไม่เปลี่ยนวิธีการค้นหาพื้นฐาน มันเป็นเวิร์กโฟลว์ทางเลือกแม้ว่า
dgtized

สิ่งที่คุณกำลังอธิบายฟังดูเหมือนสามารถทำได้อย่างง่ายดายด้วยการสร้างมาโครที่รวดเร็วมากเพื่อแทนที่ข้อความและการโทรซ้ำ ๆM-g n C-x e(เช่นใช้next-errorเพื่อเลื่อนดูเหตุการณ์ที่เกิดขึ้น)
shosti

1

นี่คืออีกวิธีหนึ่งโดยใช้Icicles

ใน Emacs คุณ*grep*บัฟเฟอร์ส่งออกตีสำเนา `(ที่สำเนา backquote) ซึ่งในเฉยชาโหมดที่ถูกผูกไว้ในบัฟเฟอร์คำสั่ง*grep* icicle-compilation-searchสิ่งนี้จะช่วยให้คุณนำทางไปยังรายการค้นหายอดนิยม (จำนวนgrepครั้ง) ที่คุณเลือกในลำดับใดก็ได้

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

เมื่อนำทางในการค้นหายอดนิยมคุณสามารถแทนที่รายการใดก็ได้ที่ต้องการไม่ว่าจะเป็น Hit ทั้งหมด (บรรทัด) หรือเพียงแค่ส่วนที่ตรงกับอินพุต minibuffer ปัจจุบันของคุณ

ดูIcicles ค้นหา - คอมไพล์หรือ Grep บทนำเพื่อIciclesค้นหาคือที่นี่และข้อมูลเกี่ยวกับการเปลี่ยนระหว่างการแข่งขันIciclesค้นหาที่นี่


0

ฉันใช้ประโยชน์นี้ฉันเขียน xah_find.el

ฉันเขียนเพราะ:

  • อิลิสบริสุทธิ์ ไม่ต้องกังวลเกี่ยวกับ grep ในการส่งผ่าน Windows หรือ Unicode ระหว่าง emacs ไปยังระบบปฏิบัติการ emacs ปัญหา grep
  • หากคุณเป็นผู้ใช้ Unicode ขนาดใหญ่เครื่องมือ unix จะมีข้อบกพร่องบางอย่าง ปัญหา linux uniq
  • ฉันจะค้นหา / แทนที่ทุกสัปดาห์ในไฟล์ 5k ฉันใช้ dired-do-query-replace-regexp เป็นเวลาหลายปี ฉันพบว่าลักษณะการโต้ตอบเป็นจริงเวลาของฉัน zapped แต่ฉันต้องตรวจสอบผลลัพธ์ของการเปลี่ยนแปลง ดังนั้นวิธีการแก้ปัญหาของฉันคือตอนนี้ทำงานเป็นชุด แต่มีรายงานที่ดีที่ฉันสามารถสแกนผลการค้นหา / แทนที่ทั้งหมดพร้อมตัวเลือกในการเขียนไปยังไฟล์

การใช้ elisp นี้อาจช้ากว่าการเรียกใช้ยูนิกซ์ grep ใน emacs 5 ถึง 10 เท่า แต่ก็ใช้ได้สำหรับฉัน

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