Thanh at Pai

Trang Công Thành

Senior Bug Breeder

VIM Search and Replace

2024-06-14-#vim

Mặc dù dùng vim đã lâu, nhưng nhiều khi mình vẫn hay bị quên một số thứ mà không hay dùng thường xuyên. Có thể không có ích thường ngày, nhưng khi cần thì lại rất giá trị. Nên hôm nay dành chút thời gian ngày thứ 6 (Happy Friday 🥳) để viết lại không mỗi lần phải đi tìm mất công lắm.

Search without escape

Kể từ ngày biết cái này, mình dùng luôn cho mọi trường hợp. Đỡ bao nhiêu là thứ phải nhớ.

Bình thường, để search and replace, chúng ta sẽ dùng s/search/replace nhưng như thế này, mỗi lần tìm các từ khoá có chứa ký tự đặc biệt, mình sẽ phải escape các kí tự ấy thì nó mới match. Ví dụ muốn replace cái / thành | chẳng hạn: s/\//|. Damn! My eye 🫣

Để bớt muộn phiền phải nhớ cái nào phải escape, cái nào không, thì chỉ cần đổi / thành # là nuột ngay. Vẫn với ví dụ bên trên: s#/#|. Ok 👌

Non-greedy matching

Với trường hợp sử dụng regex để search and replace, đôi khi .* quá nà hung dữ, mình sẽ sử dụng .{-} để kết quả sẽ ngon hơn.

Ví dụ mình có object như này:

const thanhsblog = {
  "vimrticks": "non-greedy matching" // sửa vimrticks thành vimtricks
}

Nếu mình muốn tìm kết quả trong cái "" và sử dụng s#"\(.*\)"#"vimtricks" thì vim sẽ match tới tận cái " cuối cùng luôn. Thành ra \1 sẽ là cả dòng vimrticks...matching.

Thay vào đó, nếu sử dụng s#"\(.\{-\}\)"#"vimtricks" thì sẽ chỉ match tới đúng cụm "" đầu tiên thôi. 👌

Search and replace in quickfix list

Đôi khi, mình cần search and replace ở trong nhiều files thì phải làm thế nào? Hồi chưa biết, mình search kết quả bằng telescope rồi mở từng file để search and replace tất cả các kết quả trong file. Ôi quê là quê! Sau này, phát hiện ra là có thể sử dụng quickfix để làm điều ấy, cuộc đời mình sang một trang mới 🤣

Đầu tiên, sử dụng plugin gì tuỳ vào sở thích của các bạn để đưa các kết quả đã tìm vào quickfix. Mình sẽ dùng telescope. Với telescope, chỉ cần tìm kết quả bằng live grep, sau đó ấn ctrl-q để cho đống result vào quickfix.

Tiếp theo, sử dụng :cdo %s#search#replace.

Tiếp theo, à không, không còn bước tiếp theo nào nữa 🤣

gn and . repeat

Thỉnh thoảng mình muốn chỉ sửa một vài chỗ mà mình muốn chỉ sửa vài chỗ thôi, ngoài việc dùng /c ở cuối command search thì cách dùng gn khá là tiện.

Ví dụ mình có một đoạn code như này:

function ThanhsBlog() {
  return (
    <div class='flex items-center justify-center py-12'>
      <div class='mx-auto grid w-[350px] gap-6'>
        <div className='grid gap-2 text-center'>
          <h1 class='text-3xl font-bold'>Thanh's Blog</h1>
          <p class='text-muted-foreground text-balance'>VimTricks Search and Replace</p>
        </div>
      </div>
    </div>
  )
}

Đoạn này mình ăn trộm ở một cái html template nào đó, và giờ muốn đổi cái class thành className để dùng được với ReactJS. Nhưng do mình dở hơi, nên đã sửa sẵn 1 cái className rồi 🤣. Thôi kịch bản đã biên, giờ thì thử dùng gn xem sao.

Đầu tiên, dùng /class để tìm tất cả các từ class

Tiếp theo, sử dụng gnc để xoá từ đang được highlight đi, gõ tiếp từ muốn sửa vd: className.

Sử dụng, nN để đổi qua các kết quả trước và sau.

Đến từ muốn sửa, sử dụng . để lặp lại bước sửa class → className

Nói chung là cũng được 👌