1 điểm bởi GN⁺ 2024-07-09 | 1 bình luận | Chia sẻ qua WhatsApp
  • Việc sửa văn bản trên dòng lệnh trông có vẻ là chức năng cơ bản, nhưng cách xử lý đầu vào khác nhau tùy chương trình, nên cùng một phím có thể hoạt động hoàn toàn khác nhau
  • Trải nghiệm nhập liệu trong terminal nhìn chung được chia thành bốn luồng: không có hệ thống nhập liệu, GNU readline, các thư viện thay thế như libedit, và hệ thống nhập liệu riêng
  • Trong các công cụ đơn giản như cat, nc, dash, phím mũi tên có thể hiện ra như ^[[D, nhưng các phím do terminal cung cấp như Ctrl+W, Ctrl+U, Ctrl+C, Ctrl+Z vẫn dùng được
  • Các công cụ dựa trên readline như bash, psql, irb, python3 cung cấp lịch sử, phím mũi tên, tìm kiếm Ctrl+R, di chuyển Ctrl+A/Ctrl+E; có thể dùng rlwrap để thêm trải nghiệm tương tự
  • Nếu phân biệt được hệ thống nhập liệu hiện tại, bạn có thể nhanh chóng đoán vì sao phím mũi tên hay Ctrl+R trông khác nhau, và khi cần dễ chọn cách xử lý như xem tài liệu hoặc dùng rlwrap

Trải nghiệm nhập liệu thay đổi theo từng chương trình

  • Cách nhập và sửa văn bản trong terminal khác nhau rất nhiều tùy chương trình
  • Các kiểu tiêu biểu được chia như sau
    • cat, nc, git commit --interactive không hỗ trợ phím mũi tên, nên bạn có thể thấy các chuỗi như ^[[D^[[D^[[C^[[C^
    • irb, python3 trên Linux cung cấp các chức năng chỉnh sửa cơ bản như lịch sử và phím mũi tên thông qua thư viện readline
    • Cũng có trường hợp như /usr/bin/python3 trên Mac: phím mũi tên hoạt động, nhưng tìm kiếm ngược Ctrl+left hoặc Ctrl+R thì không được hỗ trợ
    • fish, ipython3, micro, vim dùng hệ thống nhập liệu riêng

Chế độ 1: trạng thái cơ bản không có hệ thống nhập liệu

  • Nếu chương trình chỉ nhận văn bản bằng một lời gọi như fgets() và không cung cấp chức năng chỉnh sửa riêng, phím mũi tên có thể được in ra dưới dạng escape sequence thay vì lệnh chỉnh sửa
  • Ví dụ, trong dash, nhấn mũi tên trái sẽ in ^[[D ra terminal như sau
$ ls l-^[[D^[[D^[[D
  • Dù vậy, các chức năng điều khiển cơ bản do terminal cung cấp vẫn còn
    • Nhập văn bản
    • Backspace
    • Ctrl+W: xóa từ phía trước
    • Ctrl+U: xóa toàn bộ dòng
    • Ctrl+C: ngắt tiến trình
    • Ctrl+Z: tạm dừng tiến trình
  • Ngay cả trong môi trường này, dùng Ctrl+W cho phép xóa theo từng từ mà không cần nhấn backspace nhiều lần
  • Có thể kiểm tra các mã điều khiển mà terminal hỗ trợ bằng stty -a

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, được dùng trong nhiều công cụ tương tác
  • Các phím tắt readline thường dùng như sau
    • Ctrl+E hoặc End: di chuyển đến cuối dòng
    • Ctrl+A hoặc Home: di chuyển đến đầu dòng
    • Ctrl+left/right arrow: di chuyển tiến/lùi từng từ
    • Mũi tên lên: chuyển đến lệnh trước đó
    • Ctrl+R: tìm kiếm lịch sử
  • Cũng có thể dùng Ctrl+W, Ctrl+U của chế độ cơ bản, nhưng trong readline, Ctrl+U xóa từ con trỏ đến đầu dòng chứ không phải toàn bộ dòng
  • Tìm kiếm lịch sử bằng Ctrl+R trong bash là chức năng do readline cung cấp
  • psql, irb, python3 cũng là ví dụ về các chương trình dùng readline
  • Có thể xem danh sách đầy đủ các lệnh chỉnh sửa của readline trong hướng dẫn readline

Gắn rlwrap cho công cụ không có readline

  • Ngay cả chương trình không hỗ trợ readline như nc, nếu chạy bằng rlwrap nc thì có thể dùng như chương trình có hỗ trợ readline
  • rlwrap có thể cải thiện đáng kể khả năng sử dụng của các công cụ không có readline
  • Cũng có thể cấu hình tự động hoàn thành tùy chỉnh, nhưng đây không phải nội dung đã được dùng thử thực tế

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

  • Có vài lý do khiến một số công cụ không dùng readline
    • Các chương trình rất đơn giản như cat, nc có thể không muốn thêm một dependency tương đối lớn
    • readline không dùng LGPL mà dùng giấy phép GPL, nên có thể không phù hợp với giấy phép của chương trình
    • Nếu chỉ một phần của chương trình là tương tác và đầu vào gần như chỉ là một ký tự đơn như y hoặc n, việc hỗ trợ readline có thể có mức ưu tiên thấp
  • git có các chức năng tương tác như git add -p, nhưng khi cần nhập nội dung dài có ý nghĩa, nó thường mở trình soạn thảo văn bản
  • idris2 không dùng readline để giảm thiểu dependency, và đề xuất dùng rlwrap nếu cần các tính năng tương tác tốt hơn

Cách kiểm tra hiện có đang dùng readline hay không

  • Cách kiểm tra đơn giản nhất là thử nhấn Ctrl+R
  • Nếu thấy prompt sau, nhiều khả năng đang dùng readline
(reverse-i-search)`':
  • Các thư viện khác cũng có thể dùng cùng thuật ngữ nên đây không phải cách phân biệt chắc chắn, nhưng chưa biết hệ thống nào khác dùng cụm reverse-i-search cho tìm kiếm lịch sử

Phím tắt readline và Emacs

  • Có thể xem các phím tắt đi đến đầu dòng bằng Ctrl+A và cuối dòng bằng Ctrl+E là bắt nguồn từ Emacs
  • Trong Emacs, Ctrl+ACtrl+E cũng hoạt động giống readline
  • Ngược lại, Ctrl+W, Ctrl+U không hoạt động giống nhau trong Emacs và terminal
  • Có thể xem thêm lịch sử của dự án readline trong lịch sử dự án Readline

Chế độ 3: thư viện nhập liệu thay thế như libedit

  • /usr/bin/python3 trên Mac gần với trạng thái trung gian, chỉ hỗ trợ một số chức năng readline
  • Ví dụ, nếu nhấn Ctrl+left arrow, nó có thể in ra ;5D thay vì di chuyển theo từ
$ python3
>>> importt subprocess;5D
  • Trong bản cài Python mặc định của Mac OS, module Python readline thực ra dựa trên libedit
  • Điều này được cho là vì readline dùng giấy phép GPL
  • Có thể kiểm tra Python đó có dùng libedit hay không bằng lệnh sau
$ python3 -c "import readline; print(readline.__doc__)"
Importing this module enables command line editing using libedit readline.
  • Python cài trên Linux hoặc qua Homebrew thường dùng readline
  • Python 3.13 dự kiến sẽ loại bỏ dependency readline và dùng thư viện riêng, nên trong tương lai câu “Python dùng readline” có thể không phải lúc nào cũng đúng

Chế độ 4: hệ thống nhập liệu riêng

  • Một số chương trình dùng hệ thống chỉnh sửa văn bản riêng và đôi khi cung cấp nhiều tính năng đa dạng hơn readline
  • Ví dụ về các hệ thống nhập liệu riêng gồm
    • Hầu hết các trình soạn thảo văn bản trong terminal như nano, micro, vim, emacs
    • Shell như fish
    • Trình soạn thảo dòng zle của zsh
    • REPL như ipython
    • Công cụ như atuin
  • Trong các hệ thống này, bạn có thể thấy các chức năng sau
    • Tự động hoàn thành được điều chỉnh phù hợp hơn với công cụ
    • Quản lý lịch sử tốt hơn, bao gồm tô sáng cú pháp
    • Nhiều phím tắt bàn phím hơn

Hệ thống nhập liệu riêng lấy cảm hứng từ readline

  • Atuin là công cụ tìm kiếm lịch sử shell; phần triển khai nhập liệu là tự viết, nhưng lấy cảm hứng từ readline
  • Atuin tận dụng việc người dùng quen với key binding của readline, khiến các key binding đó hoạt động dù không trực tiếp dùng readline
  • prompt_toolkit mà IPython dùng cũng hỗ trợ nhiều tùy chọn, bao gồm key binding kiểu vi
  • Mặc định của prompt_toolkit là hỗ trợ key binding kiểu readline
  • Điều này tương tự việc nhiều chương trình hỗ trợ các key binding vim cơ bản như dùng j để đi xuống và k để đi lên
  • Ví dụ, Fastmail hỗ trợ j, k dù hầu hết phím tắt không liên quan nhiều đến vim
  • Hệ thống nhập liệu riêng lấy cảm hứng từ readline có thể không tương thích tinh tế với readline, nhưng với người dùng chỉ dùng vài phím tắt cơ bản thì có thể không phải vấn đề lớn
  • Các hệ thống riêng này thường có tự động hoàn thành tốt hơn so với chỉ dùng readline

Shell hỗ trợ chế độ vi

  • bash, zsh, fish đều hỗ trợ chế độ vi cho nhập văn bản
  • Trong một khảo sát không khoa học trên Mastodon, 12% trả lời rằng họ dùng chế độ vi
  • Bản thân readline cũng có chế độ vi, và hỗ trợ chế độ vi của bash hoạt động thông qua đó
  • Nhiều chương trình khác dùng readline cũng có thể có chế độ vi

Luồng chẩn đoán trạng thái nhập liệu

  • Nếu biết đang dùng hệ thống nhập liệu nào, bạn sẽ dễ dự đoán hành vi trên dòng lệnh hơn
  • Ở prompt nhập liệu, có thể đánh giá theo thứ tự sau
    • Nếu phím mũi tên không hoạt động, nhiều khả năng không có hệ thống nhập liệu; dù vậy vẫn có thể dùng Ctrl+W, Ctrl+U, và nếu cần có thể gắn rlwrap
    • Nếu Ctrl+R hiện reverse-i-search, nhiều khả năng là readline; có thể dùng các phím tắt readline quen thuộc và chức năng lịch sử cơ bản
    • Nếu Ctrl+R có hành vi khác, nhiều khả năng là thư viện nhập liệu riêng; nhìn chung nó có thể hoạt động tương tự readline, và nếu cần thì xem tài liệu
  • Vẫn còn những điểm phức tạp liên quan đến nhập liệu chưa được đề cập ở đây
    • Vấn đề liên quan đến ssh, tmux
    • Biến môi trường TERM
    • Khác biệt hỗ trợ sao chép/dán giữa các terminal như GNOME Terminal, iTerm, xterm
    • Unicode
    • Nhiều vấn đề khác liên quan đến nhập liệu

1 bình luận

 
GN⁺ 2024-07-09
Ý kiến trên Hacker News
  • Bài viết của Julia lúc nào cũng hay. Một phần còn thiếu là nếu dùng stty trong shell script, bạn có thể thay đổi nhiều hành vi của terminal, bao gồm cả cách xử lý input
    Một thử nghiệm trước đây tôi từng làm với shstty: https://gist.github.com/alganet/63f1dbc97b8fd35f7bb14ec30f79...
    Trong các terminal tương thích VT100 (mintty, xterm, Terminal.app, vscode, v.v.), có thể capture và diễn giải hầu hết tổ hợp phím, thậm chí cả gesture chuột (nhấn/kéo/thả) ngay trong shell
    Demo chạy bằng bash -c "$(curl -L https://git.io/fjToH)"; sau đó cứ bấm phím hoặc di chuyển chuột để thử. Thoát bằng Ctrl+W. zsh và ksh cũng được hỗ trợ, nhưng dash và các shell khác không có read -rn1 thì không
    Ngoài ra, nếu pipe một chương trình tương tác vào cat -v, như vi | cat -v, bạn có thể thấy các escape VT100 mà chương trình đó dùng; tôi đã học được rất nhiều khi quan sát vi làm thế nào

    • Nếu sau khi chạy lệnh mà terminal bị hỏng, không hiện output hoặc hiện ký tự lạ, có thể lệnh đó đã không dọn dẹp tty đúng cách. Đừng kill terminal; chỉ cần gõ stty sane là có thể khôi phục
    • Khi đọc phần đầu cuốn UNIX Programming Environment của Kernighan, với tinh thần tương tự, tôi đã nghĩ ra một cách kỳ quặc để khám phá hành vi I/O của terminal
      Mở 3 terminal và chạy lần lượt 1) man ascii, 2) nc -lvp 9001 | xxd -c1, 3) stty raw -echo; nc -nv 127.0.0.1 9001, rồi ở terminal số 3 tái hiện theo thứ tự toàn bộ cột “Hex” trong manpage
      Có thể quan sát thấy một số giá trị có thể tạo ra bằng nhiều cách, và một số phím khác gửi payload nhiều byte
    • Bài viết này về việc triển khai một trình soạn thảo văn bản trong terminal cũng giúp hiểu stty và raw mode: https://viewsourcecode.org/snaptoken/kilo/, https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode...
      Các tham số và ký hiệu stty trông như ma thuật thực ra đến từ các control sequence đã được định nghĩa từ rất lâu. Những chuẩn mơ hồ từ thập niên 1970 như ECMA-48 có rất nhiều thuật ngữ khó hiểu mà nay hầu như không còn dùng
      Ví dụ Select Graphic Rendition(SGR) đại khái giống như các thẻ HTML phiên bản thập niên 1970; để đặt màu foreground có thể viết kiểu ESC[38;2;R;G;BmTextESC[0m. ESC[ là CSI, m là SGR, 38 là màu foreground, 2 là không gian màu RGB, 0 là reset style
      Cấu trúc này hơi ngược đời vì tham số đứng trước lệnh. Cũng như trình duyệt, terminal có phạm vi và cách triển khai rất khác nhau, và đến nay vẫn vậy. Màu sắc được hỗ trợ khá tốt, nhưng các tính năng khác thì không. Chẳng hạn SGR<7> được gọi là chế độ “negative image”, nhưng chuẩn không giải thích chi tiết, nên có terminal hiển thị đảo màu, terminal khác xử lý theo cách khác, và đến nay vẫn gây vấn đề
    • Trước khi hút code từ Internet thẳng vào bash thì luôn phải kiểm tra. Demo này dường như đã làm hỏng kỳ lạ một số thiết lập không chuẩn của tôi, và tôi không định ghi chép chi tiết
    • Trên Sonoma thì hiện “The invoked shell does not support interactive features”
  • Hơn 20 năm trước, tôi đã xây dựng một state machine bên trên readline, để có thể dùng nó như một trình soạn thảo nhiều dòng thật sự, di chuyển lên xuống được, chứ không chỉ là một dòng bị wrap
    Video: https://github.com/colmmacc/jot/raw/master/jot-demo.mp4
    Kho CVS của client IM cho terminal Unix có tính năng này: https://c-hey.redbrick.dcu.ie/src/c-hey_cvs_latest/
    Khi di chuyển lên xuống giữa các dòng, nó theo dõi và vẽ lại con trỏ; khi kích thước terminal thay đổi thì nhận SIGWINCH rồi vẽ lại. Tôi muốn viết lại bằng Rust và phát hành thành một thư viện nhỏ, nhưng chưa có thời gian. Tôi luôn ngạc nhiên là dường như không ai làm thứ tương tự

    • Khá hay, tôi muốn mượn ý tưởng này. Một trường hợp cụ thể có vẻ có thể triển khai trong zsh chỉ bằng vài dòng
      Sau autoload -Uz zed, dùng zed để sửa một file tạm rồi truyền cho git commit -F, bạn có thể khởi động một trình soạn thảo inline có đầy đủ mọi tính năng của ZLE. Lưu bằng C-x C-w rồi commit, hoặc hủy bằng C-c
      Ưu điểm của cách triển khai cơ bản này là zed là một widget ZLE mới, nên có thể kiểm soát hoàn toàn keymap. Chế độ emacs hoặc vi hoạt động ngay và còn có thể tùy biến thêm
      Nếu tự viết widget ZLE, bạn có thể gọi nó trực tiếp ngay trong line editor, nên không cần bọc lệnh như trên nữa
      https://github.com/zsh-users/zsh/blob/master/Functions/Misc/...
    • Trước khi xem video tôi không nhận ra trải nghiệm soạn thảo kiểu này tốt hơn đến mức nào, và tôi đồng cảm với lợi thế không phải chuyển ngữ cảnh như chế độ tương tác của git commit. Hiệu ứng như “máy đánh chữ inline” cũng rất thú vị
    • Cửa sổ văn bản của rio khi ở hold mode trông cũng tương tự. Tuy nhiên thiết kế đơn giản hơn nhiều và hỗ trợ chuột tốt hơn: https://p9f.org/magic/man2html/1/rio
    • Tôi tò mò liệu phiên bản hiện tại của chương trình có ổn định không
  • Những phần bài viết còn bỏ sót gồm ký tự rộng, vấn đề cùng một phím bấm được biểu diễn bằng các chuỗi thoát ANSI khác nhau do khác biệt về chế độ bàn phím, khác biệt trạng thái TTY như echo cục bộ, và việc các lệnh gọi hệ thống thay đổi trạng thái TTY cũng hơi khác nhau tùy hệ điều hành
    Việc hỗ trợ giả lập terminal cũng mỗi nơi một kiểu. Ngày nay nhìn chung đều bắt chước xterm, nhưng ngay cả trong đó cũng không có bên nào đặt mục tiêu tương thích 100%
    Cũng thiếu sự đồng thuận về cách kiểm tra các tính năng mà terminal cung cấp. Có bên gửi chuỗi thoát ANSI rồi chờ phản hồi, có bên nhìn vào $TERM, có terminal tự nhận là xterm nhưng lại bỏ qua các chuỗi tính năng VT và đặt biến môi trường khác. Nói thật là còn lộn xộn hơn cả chuỗi user agent
    Tất cả những điều này là với giả định hệ thống POSIX; nếu trộn cả Windows vào thì mọi thứ thú vị gấp đôi

  • Nếu trong bash bạn đặt $EDITOR thành trình soạn thảo ưa thích, có thể dùng Ctrl-X Ctrl-E để gửi dòng hiện tại sang $EDITOR. Sau khi sửa lệnh, lưu và thoát thì lệnh sẽ được thực thi

    • Nếu là cao thủ Unix lâu năm dùng chế độ vi trong ksh thì chỉ cần nhấn v cũng được
    • Lệnh tích hợp fc cũng làm việc tương tự. Chỉ cần nhập fc, không cần chuỗi phím Ctrl
      Cũng có thể mở lệnh trước đó bằng một trình soạn thảo cụ thể thay vì $EDITOR mặc định. Ví dụ khi EDITOR=vi, để sửa lệnh ngay trước đó bằng ed thì dùng fc -e ed
      Cũng có cách tạo shell script nhanh từ lịch sử lệnh trong chế độ vi. Nếu lệnh mong muốn là mục thứ 15 trong lịch sử, có thể xử lý kiểu fc 15 rồi w1.sh, %d, wq
    • Trong fish là Alt-e
    • Tôi thích những phím tắt kiểu này, nhưng đến lúc thật sự cần thì lại không nhớ ra
    • Tôi đang dùng EDITOR=nvim trong Neovim cùng copilot.vim như kiểu tự động hoàn thành shell bằng AI. Khá ổn
      Thấy ở đây: https://twitter.com/arjie/status/1575201117595926530?s=46&t=...
  • Từ góc nhìn người mới dùng Linux, tôi tò mò vì sao chương trình chỉ đọc văn bản bằng thứ như fgets() mà vẫn tự nhiên có các chức năng như backspace, Ctrl+W, Ctrl+U
    Tài liệu fgets() nói rằng nó đọc cho đến khi gặp xuống dòng hoặc EOF; vậy có phải mặc định nó bị chặn cho đến khi người dùng nhập xuống dòng, và trước đó terminal cho phép chỉnh sửa bộ đệm dòng bằng backspace hoặc Ctrl+W/Ctrl+U hay không
    Nhưng không có gì bảo đảm chương trình nhất thiết đọc cả dòng, và cũng có thể truyền count là 2 để đọc theo từng ký tự. Khi đó nếu backspace xảy ra thì chắc không thể “hoàn tác” ký tự đã đọc rồi; vậy bên trong bộ đệm của fgets() có phép màu nào đó, hay trong trường hợp ấy chức năng chỉnh sửa dòng sẽ bị hỏng
    https://en.cppreference.com/w/c/io/fgets

    • zsh, bash, ksh, fish và hầu hết các chương trình UI terminal đặt terminal ở chế độ cooked để tự quản lý hành vi terminal. Trong chế độ cooked, terminal không đệm theo dòng mà đọc tất cả ký tự
      Việc trông như được đệm theo xuống dòng thực ra là do shell quản lý, nên nhà phát triển mới có thể thêm các chức năng thao tác bộ đệm văn bản như hoàn thành bằng Tab hoặc thêm sudo vào đầu dòng
    • Theo mặc định, terminal hoạt động ở chế độ canonical. Cho đến khi người dùng nhập xong một dòng hoàn chỉnh, không có nhập/xuất nào xảy ra
      Trước khi nhấn Enter, các ký tự trên màn hình chỉ nằm trong bộ nhớ của terminal, còn lời gọi hệ thống read của ứng dụng thì bị chặn trên file descriptor của terminal. Terminal không ghi dữ liệu cho đến khi dòng được hoàn tất
      Khi đó việc chỉnh sửa dòng đang nhập thường cũng do chính terminal cung cấp. Chữ hiện trên màn hình cũng là một tính năng terminal gọi là echo; backspace, delete, Ctrl+C cho SIGINT, Ctrl+D cho EOF cũng vậy
      Các trình chỉnh sửa dòng và trình soạn thảo văn bản tắt các tính năng này đi và đặt terminal ở chế độ raw. Mọi thứ nhập vào được gửi ngay cho ứng dụng để ứng dụng tự xử lý. Một ví dụ phổ biến là prompt mật khẩu chỉ tắt echo để ẩn ký tự
      Ký tự kết thúc dòng Unix truyền thống \n thực ra cũng là một tính năng terminal. Từ góc nhìn terminal, \n chỉ đưa con trỏ xuống một dòng, nên để quay về đầu dòng còn cần \r. Kết thúc dòng thật sự là \r\n, và terminal âm thầm đổi \n thành \r\n. Chức năng này cũng có thể bị vô hiệu hóa
    • Chức năng này do trình giả lập terminal ở chế độ “cooked” cung cấp: https://en.wikipedia.org/wiki/Terminal_mode
      Ở chế độ raw thì không hoạt động như vậy
    • Một trong những nhiệm vụ đầu tiên tôi nhận khi bắt đầu được trả tiền làm lập trình viên là port chương trình help của VMS sang SunOS. Chướng ngại đầu tiên là làm sao phản hồi theo từng phím bấm mà không chờ Enter/Return
      Sếp cố tình gần như không giúp gì, và vào năm 1986, khi không có web và gần như không có sách O’Reilly, tôi đã phải gần như tự mình tìm ra. Đến giờ tôi vẫn mãi biết ơn quyết định đó
  • Shell dash cũng hỗ trợ chế độ chỉnh sửa nếu được biên dịch với libedit. Các bản Debian có lẽ không làm vậy vì vấn đề dung lượng, nhưng nếu muốn những người bắt đầu với bash sau này đỡ phải học thêm thì nên hỗ trợ
    Chuẩn POSIX cũng chỉ định set -o vi là phần mở rộng tùy chọn. Nếu một shell tuyên bố tương thích POSIX triển khai chế độ chỉnh sửa này thì bắt buộc phải hỗ trợ set -o vi
    [set -o] vi: cho phép chỉnh sửa dòng lệnh shell bằng trình chỉnh sửa vi tích hợp. Khi bật chế độ vi, các chế độ chỉnh sửa dòng lệnh khác được cung cấp dưới dạng phần mở rộng triển khai phải bị vô hiệu hóa.”
    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...

    • dash của Debian được nhắm tới như một POSIX sh nhẹ để chạy shell script. Nó không nhắm đến việc làm login shell hay dùng tương tác, nên trong bối cảnh đó việc giữ dependency nhẹ là hợp lý
  • Tôi vẫn luôn nghĩ terminal là yếu tố duy nhất khiến Linux mãi bị kẹt ở thị phần dưới 5%
    Không chỉ việc nhập văn bản có vấn đề, mà toàn bộ trải nghiệm đều phức tạp. 95% dân số chỉ muốn lái drone, vậy mà lại bị đưa cho một buồng lái Concorde không có nhãn
    https://qph.cf2.quoracdn.net/main-qimg-2566f4c91b894e4169d77..., https://media.thedroningcompany.com/images/tincy/WQZpC56vqMp...

    • Nếu chỉ có các bản phân phối kiểu LFS, Gentoo, Arch thì nói vậy cũng đúng, nhưng khi còn Ubuntu, Mint, OpenSUSE, Fedora, Manjaro và vô số bản phân phối thân thiện với người dùng thì lập luận đó không thuyết phục lắm
      Việc phía sau Ubuntu có một buồng lái Concorde, và tôi có thể truy cập vào đó trên laptop Ubuntu dùng cho công việc của mình, ngược lại còn khiến tôi thấy biết ơn. Nếu không có mức độ kiểm soát đó thì chắc tôi sẽ không thích
      Trong khi đó laptop của mẹ tôi cũng chạy Ubuntu, laptop của bạn gái tôi chạy Manjaro, cả hai đều chỉ “lái drone” mà không hề đặt chân vào buồng lái Concorde, và vẫn dùng tốt. Tất nhiên, tôi dùng Arch
    • Kernel Linux không có terminal và một phần user space thì đa số mọi người đã dùng dưới dạng Android và Chromebook rồi
      Terminal là công cụ của lập trình viên và quản trị hệ thống. Chỉ là phần lớn người dùng GNU/Linux trên desktop là lập trình viên và quản trị hệ thống nên trông mới như vậy, mà những người này chỉ chiếm vài phần trăm dân số
    • Trong Gnome Terminal của Ubuntu hay Windows Terminal của Windows, có thể dùng Home để về đầu dòng, End để tới cuối dòng; những thứ dễ nhập thì có vẻ đều dễ tương tự nhau
      Nơi phải biết nhiều phím tắt kỳ quặc lại là terminal của macOS, nơi mọi thứ được làm kém trực quan nhất có thể
    • Điều tạo ra thị phần ít ỏi của Linux là thiếu cài sẵn. Windows thực ra cũng hầu như chẳng ai dùng cho đến khi Microsoft gần như ép buộc các gói OEM và cài sẵn từ thời 3.x
    • Ngược lại, việc trải nghiệm terminal của GNU/Linux tốt hơn Unix có thể là một trong những lý do nó áp đảo Unix. Đăng nhập vào một máy BSD cho cảm giác như du hành thời gian về thập niên 1980
  • Có lẽ đây là ý kiến không phổ biến, nhưng trong iTerm2 tôi đã đổi sang preset Natural text editing để khớp với các phím tắt chỉnh sửa truyền thống của macOS
    Vì trong ứng dụng terminal nó thường remap lại thành các control sequence, nên có lợi là gần như ở đâu cũng dùng được tính năng này mà không cần đổi ở nhiều nơi hay lo hỗ trợ readline
    Không hoàn hảo, nên đôi khi có những sequence tôi phải nhập thủ công lại bị remap, nhưng vì khớp với trí nhớ cơ bắp nên tôi dùng việc chỉnh sửa lệnh nhiều hơn hẳn
    https://pliszko.com/blog/post/2021-10-31-natural-text-editin...

    • Đây là một trong những thứ đầu tiên tôi cấu hình khi cài iTerm. Việc có thể dùng Cmd+phím mũi tên, Option+phím mũi tên, Cmd+Delete, Option+Delete một cách tự nhiên là rất quan trọng
      Tôi không muốn việc chỉnh sửa văn bản trong terminal hoạt động theo kiểu đặc biệt
  • Ba key binding readline cơ bản mà nếu mọi người biết thì cuộc sống sẽ dễ hơn là Ctrl+W, Ctrl+O, Ctrl+R
    Ctrl+W xóa từ cuối cùng như Julia đã nhắc trong bài viết
    Ctrl+O thực thi dòng được gọi ra từ lịch sử, rồi gọi tiếp dòng lịch sử kế tiếp. Nếu di chuyển tới lệnh đầu tiên trong lịch sử rồi nhấn Ctrl+O năm lần, bạn có thể chạy năm lệnh theo thứ tự
    Ctrl+R tìm ngược trong lịch sử khi bạn nhập chuỗi tìm kiếm. Nhấn Ctrl+R lần nữa để tới kết quả trước đó, Ctrl+S để di chuyển tiến theo thời gian. Thực thi bằng Enter hoặc Ctrl+O

    • Tôi luôn thắc mắc tại sao Ctrl+S lại được chọn. Vì theo kinh nghiệm, nó xung đột với tạm dừng XOFF vốn là mặc định gần như ở mọi nơi
      Nếu muốn dùng tổ hợp phím đó cho chức năng tìm kiếm tiến, bạn phải biết tại sao nó không chạy và có ý định tắt XOFF
    • Chức năng cuối cùng thì tôi luôn dùng Ctrl+Shift+R, giống như Shift+Tab trong GUI. Biết thêm Ctrl+S cũng tốt, nhưng vì trí nhớ cơ bắp nên chắc tôi sẽ không dùng được
  • Trong Windows Terminal, Ctrl+C luôn hoạt động đúng. Nếu đang chọn văn bản thì nó sao chép, còn nếu không chọn gì thì nó giết tiến trình đang chạy
    Các ứng dụng terminal trên Linux không dùng Ctrl+C để sao chép mà yêu cầu Ctrl+Shift+C. Khi dán, nhấn Ctrl+V cũng chèn vào ký tự kỳ lạ, trong khi mọi ứng dụng khác đều là Ctrl+V nên cứ bị trí nhớ cơ bắp làm hại
    Tôi tò mò liệu có ứng dụng terminal Linux nào hoạt động như Windows Terminal, không “đánh vào mu bàn tay” vì cái gọi là “sử dụng teletype không đúng cách” không

    • Tôi luôn thiết lập terminal để cứ chọn là sao chép. Không nhấn Ctrl+C. Ngay từ đầu, nếu không định sao chép thì chọn văn bản làm gì
    • Việc trong terminal, sao chép và kết thúc được tách thành Command-C và Ctrl-C là một trong những lý do lớn nhất khiến tôi vẫn ở lại với Mac
    • Việc sao chép trong và ngoài terminal được thực hiện bằng nút chuột giữa. Chọn văn bản rồi nhấp nút giữa tại vị trí muốn dán là xong
      Cách này dùng một bộ đệm Xorg riêng, nên sau khi sao chép thứ gì đó bằng Ctrl+C rồi chọn văn bản khác, Ctrl+V sẽ dán nội dung thứ nhất, còn nhấp chuột giữa sẽ dán nội dung thứ hai
      Trên Windows hay smartphone, đôi khi chỉ chọn một thứ gì đó rồi quên nhấn kiểu như Ctrl+C, rất bực
      Tôi nghĩ trong các terminal Linux chắc không có cái nào làm giống Windows Terminal. Vì chương trình đang chạy bên trong terminal có thể muốn tự xử lý Ctrl+C. Trình soạn thảo văn bản là một ví dụ, và terminal thậm chí không biết hiện đang chạy chương trình nào. Vì điều khiển tác vụ là việc của shell
    • Hầu hết các terminal Linux tử tế đều có thể cấu hình được. Ví dụ trong kitty, chỉ cần dùng map ctrl+c copy_or_interrupt
      https://sw.kovidgoyal.net/kitty/actions/#action-copy_or_inte...
    • Có vẻ WezTerm, vốn có thể cấu hình bằng Lua, cũng làm được. Vì tôi đang chạy một hàm Lua cụ thể bằng một key binding khác, nên khi ngồi trước laptop tôi định thử làm cho nó hoạt động