1 điểm bởi GN⁺ 2024-07-09 | 1 bình luận | Chia sẻ qua WhatsApp

Vì sao việc nhập văn bản trong terminal lại phức tạp

  • Khi hỏi trên Mastodon về điều khiến mọi người thấy khó hiểu khi làm việc trong terminal, điểm nổi bật là “chỉnh sửa lệnh đã nhập”
  • Muốn chia sẻ lý do vì sao việc nhập văn bản trong terminal lại khó và một vài mẹo hữu ích

Thiếu tính nhất quán giữa các chương trình

  • Cách nhiều chương trình xử lý nhập văn bản không nhất quán
    • Một số chương trình (cat, nc, git commit --interactive v.v.) hoàn toàn không hỗ trợ phím mũi tên
    • Nhiều chương trình (irb, python3 v.v.) dùng thư viện readline để cung cấp các tính năng cơ bản
    • Một số chương trình chỉ hỗ trợ các tính năng tối thiểu
    • Một số chương trình có hệ thống nhập liệu được tùy biến hoàn toàn

Chế độ 1: trạng thái cơ bản

  • Trạng thái cơ bản trong đó chương trình chỉ đơn giản nhận đầu vào văn bản
    • Cung cấp các chức năng cơ bản như nhập văn bản, backspace, Ctrl+W, Ctrl+U v.v.
    • Có thể dùng lệnh stty -a để xem toàn bộ các mã Ctrl được hỗ trợ

Chế độ 2: công cụ dùng readline

  • readline là thư viện GNU giúp việc nhập văn bản thuận tiện hơn
    • Cung cấp các phím tắt hữu ích như Ctrl+E, Ctrl+A, Ctrl+left/right arrow, Ctrl+R v.v.
    • Nhiều chương trình như bash, psql, irb, python3 dùng readline

Mẹo: dùng rlwrap để có readline

  • Có thể dùng rlwrap để bổ sung các tính năng của readline cho những chương trình không hỗ trợ readline

Vì sao công cụ không dùng readline

  • Có thể vì chương trình rất đơn giản, vấn đề giấy phép, hoặc mức độ tương tác thấp

Cách kiểm tra có dùng readline hay không

  • Nếu nhấn Ctrl+R và thấy hiện reverse-i-search thì nhiều khả năng đang dùng readline

Nguồn gốc của key binding trong readline

  • Các key binding của readline bắt nguồn từ Emacs

Chế độ 3: thư viện nhập liệu khác (libedit v.v.)

  • /usr/bin/python3 trên Mac dùng libedit nên chỉ hỗ trợ một phần tính năng của readline

Chế độ 4: hệ thống nhập liệu tùy biến

  • Các trình soạn thảo văn bản như nano, micro, vim, emacs và các shell như fish có hệ thống nhập liệu tùy biến
  • Các hệ thống tùy biến này thường lấy cảm hứng từ readline

Nhiều shell hỗ trợ key binding kiểu vi

  • bash, zsh, fish v.v. hỗ trợ “vi mode” cho việc nhập văn bản

Hiểu ngữ cảnh sẽ hữu ích

  • Khi nhập văn bản ở dấu nhắc dòng lệnh, hiểu ngữ cảnh sẽ giúp mọi thứ dễ đoán hơn và bớt gây bối rối hơn

Những gì bài viết này không đề cập

  • Các vấn đề liên quan đến ssh, tmux, biến môi trường TERM, hỗ trợ copy/paste của các terminal khác nhau, Unicode v.v.

Tóm tắt của GN⁺

  • Giải thích vì sao việc nhập văn bản trong terminal lại phức tạp và vì sao thiếu tính nhất quán giữa nhiều chương trình
  • Đưa ra cách dùng các thư viện như readline để giúp việc nhập văn bản thuận tiện hơn
  • Cung cấp mẹo thêm tính năng readline bằng rlwrap
  • Nhấn mạnh rằng hiểu ngữ cảnh khi dùng terminal là điều quan trọng

1 bình luận

 
GN⁺ 2024-07-09
Ý kiến trên Hacker News
  • Các bài viết của Julia lúc nào cũng hay

    • Có thể dùng stty trong shell script để thay đổi cách terminal xử lý đầu vào
    • Chia sẻ một thử nghiệm có thể bắt và hiểu các tổ hợp phím và cử chỉ chuột trên terminal tương thích VT100
    • Có thể chạy demo bằng lệnh bash -c "$(curl -L https://git.io/fjToH)"
    • Có thể dùng vi | cat -v để xem các chuỗi escape VT100 của chương trình tương tác
  • Những nội dung còn thiếu trong bài

    • Ký tự rộng
    • Các chuỗi escape ANSI khác nhau tùy theo chế độ bàn phím
    • Nhiều trạng thái TTY khác nhau
    • Các system call thay đổi trạng thái TTY khác nhau theo từng OS
    • Sự khác biệt trong hỗ trợ mô phỏng terminal
    • Thiếu sự đồng thuận về cách kiểm tra tính năng của terminal
  • Trong bash, nếu đặt $EDITOR thì có thể dùng ctrl-x ctrl-e để gửi dòng hiện tại sang $EDITOR

  • Đã từng tạo một trình soạn thảo nhiều dòng bằng readline từ 20 năm trước

    • Bao gồm chức năng di chuyển con trỏ và vẽ lại khi kích thước terminal thay đổi
    • Muốn viết lại bằng Rust và phát hành thành một thư viện nhỏ
  • Câu hỏi về cách hoạt động của hàm fgets()

    • fgets() mặc định sẽ chặn cho đến khi người dùng nhập xuống dòng
    • Có thể chỉnh sửa bộ đệm dòng bằng các phím tắt Backspace, Ctrl+W, Ctrl+U
  • Có ý kiến cho rằng terminal là một trong những lý do làm giảm thị phần của Linux

    • Trải nghiệm sử dụng terminal khá phức tạp
  • Phản bác ý kiến cho rằng shell dash không hỗ trợ phím mũi tên

    • Nếu biên dịch với libedit thì có hỗ trợ chế độ chỉnh sửa
    • Tiêu chuẩn POSIX yêu cầu hỗ trợ set -o vi
  • Ba keybinding readline cơ bản mà ai biết cũng sẽ thấy hữu ích

    • Ctrl+W: xóa từ cuối cùng
    • Ctrl+O: thực thi dòng tiếp theo trong history
    • Ctrl+R: tìm kiếm ngược trong history
  • Phàn nàn về cách Ctrl-C và Ctrl-V hoạt động trong Windows Terminal

    • Ứng dụng terminal trên Linux không hoạt động giống Windows Terminal
  • Có ý kiến nói bài này gợi nhớ đến bài viết kinh điển của Linus