2011-12-03 29 views
9

Có cách nào để kết hợp hai thao tác vào một keybinding (không nghĩ rằng sẽ làm việc với chức năng).Khóa liên kết phức tạp trong bash

Đây là những gì tôi muốn làm:

Tôi muốn một keybinding (nói Ctrl-X) để -

  1. chèn một số văn bản, sau đó
  2. gọi hoàn chỉnh hoặc menu-đầy đủ, sử dụng văn bản chèn vào làm cơ sở cho việc hoàn

tôi biết rằng tôi có thể (trong ~/.inputrc) chỉ định

  • Đầu vào văn bản với (C-X: "ls")
  • Execute lệnh readline (C-SPACE: menu-complete)

Nhưng tôi không chắc chắn làm thế nào để đưa những cùng

Trả lời

13

Bí quyết để làm điều này là gọi các chức năng giúp khôi phục khóa của bạn. Trong ví dụ của tôi, tôi sẽ sử dụng C-b để chèn văn bản và gọi để hoàn thành menu, thay vì C-x. Bạn sẽ phải hy sinh một khóa, trong ví dụ của tôi C-t

In.bashrc, hoặc một file bash được nguồn gốc

set_Cb_to_insert_text() { 
    bind '"\C-m": accept-line' 
    bind '"\C-b":"ls \C-t1"' 
    bind -x '"\C-t1":set_Cb_to_complete' 
} 
set_Cb_to_complete() { 
    bind '"\C-m":"\C-t2\C-t3"' 
    bind '"\C-b": menu-complete' 
    bind '"\C-t2": accept-line' 
    bind -x '"\C-t3":set_Cb_to_insert_text' 
} 
set_Cb_to_insert_text 

Cách hoạt động:

Với bind, bạn có thể gắn chìa khóa để làm một trong ba điều, nhưng không có sự kết hợp của chúng:

  • Thực hiện một lệnh readline: bind '"key": command'
  • Thực hiện một loạt các tổ hợp phím: bind '"key":"keystrokes"'
  • Thực thi lệnh shell: bind -x '"key": shell-command'

Vì vậy, nếu bạn muốn kết hợp ba điều này, bạn sẽ cần để ràng buộc họ từng đến một sự kết hợp riêng biệt của tổ hợp phím (trong ví dụ của tôi Ct {, , }) và ràng buộc một phím để thực hiện tất cả các tổ hợp phím này.

Trong ví dụ:

C-b chèn đầu tiên ls và 'ép' C-t , mà thực hiện set_Cb_to_complete, mà lần lượt rebinds C-b để menu-complete. Nó cũng rebinds Cm, vận chuyển trở lại, hoặc Nhập, bởi vì nó bây giờ cần làm hai việc: Chấp nhận dòng, và đặt lại Cb để chèn ls, bằng cách gọi set_Cb_to_insert_text chức năng, mà cũng reset Nhập để đó là sử dụng bình thường.

Lý do tôi nói rằng Ct phải được "hy sinh", là nếu bạn bấm Ct, readline sẽ chờ đợi để xem nếu bạn đang đi để bấm phím 1, hoặc 2, hoặc bất kỳ phím ràng buộc trình tự, trước khi thực hiện bất kỳ hành động nào. Nhưng khi bạn lần đầu tiên đặt C-t vào mục đích sử dụng này, bạn có thể sử dụng nó làm khóa ban đầu cho một số lượng lớn các tổ hợp phím để trang trải tất cả các thủ thuật đọc của bạn.

Lời khuyên: Khi bạn đang viết và kiểm tra, hãy liên kết khóa thay thế đến accept-line, vì đột nhiên có thứ gì đó phá vỡ chuỗi ở sai địa điểm và bạn bị mắc kẹt trong thiết bị đầu cuối mà không có cách thực hiện lệnh :)

+0

cảm ơn bạn rất nhiều vì ý tưởng, ví dụ và câu trả lời chi tiết (phức tạp, vâng, nhưng bạn đã làm việc trong khuôn khổ bash + readline và những hạn chế của chúng). Hơn một năm sau khi đăng bài, tôi chỉ có thể nhớ một cách mơ hồ những gì tôi đang cố gắng làm trong bức tranh lớn ... vì vậy tôi chỉ xác minh rằng ví dụ của bạn hoạt động nhưng sẽ đầu tư thêm thời gian để tái tạo những gì tôi đã cố gắng thực hiện trước đó - Cảm ơn! – nhed

4

Điều này có thể làm việc cho bạn:

"\ex": menu-complete 
"\ez": "ls \ex" 

Bao gồm các dòng này trong tệp ~/.inputrc của bạn.

Các dòng này đặt Alt-x thành menu-complete và Alt-z đến lsspacemenu-complete. Điều này sẽ cung cấp cho bạn tệp đầu tiên trong thư mục và sử dụng Alt-x để chuyển qua phần còn lại tại một thời điểm.

Xem here để biết thêm ví dụ về macro.

Thanh toán các lệnh readline bằng cách gọi bind -p hoặc bind -Pbind -s sẽ hiển thị các macro bạn đã có. Xem here cho lệnh liên kết, bạn cũng có thể tạo một macro tắt, xem here. Cuối cùng kiểm tra xem tập tin .inputrc đang được đọc chưa, tôi đã gặp sự cố vì biến môi trường được đặt thành /etc/Inputrc và phiên bản cá nhân của tôi chưa bao giờ được gọi.

BTW tránh xa Control-x vì nó đã được sử dụng cho nhiều lệnh readline.

+0

Điều này gần như không có thủ thuật nhưng yêu cầu 2 combo chính cho các cuộc gọi tiếp theo. Tôi đã có kiến ​​thức về cách kết buộc chèn văn bản và cách ràng buộc menu hoàn thành ... Nếu tôi "Alt-z" lần thứ hai tôi muốn hiển thị chỉ hiển thị 'ls ', nhưng thay vào đó tôi thấy' ls ls '... – nhed

+0

Điều này sẽ ngụ ý (và tôi có thể sai ở đây), rằng bạn muốn kết hợp cùng một phím để chuyển đổi hành động của nó. Khi đọc tài liệu của thư viện readline, các precepts chỉ có điều kiện có liên quan đến 'bash' tức là, emacs, ftp ... Có lẽ trong trường hợp này bạn có thể cần viết một hàm readline mới xem [here] (http: // cnswww .cns.cwru.edu/php/chet/readline/readline.html # SEC23). BTW Nhìn theo cách này ... Alt-x và Alt-z không phải là một triệu dặm (cũng không phải trên bàn phím của tôi) và một tổ hợp phím cho menu-complete có ích nói chung. – potong

+0

Trên thực tế, trên mac của tôi, keycombos bạn đề cập chỉ phản hồi Esc-x, Esc-z, và ở đó dấu "\ ex" dường như không thực sự làm bất cứ điều gì – nhed

Các vấn đề liên quan