2012-12-14 30 views
20

Tôi muốn viết một ứng dụng dòng lệnh, một trình bao nếu bạn muốn, trong Ruby.Làm thế nào để viết một ứng dụng dòng lệnh Ruby hỗ trợ hoàn thành tab?

Tôi muốn người dùng có thể nhấn Tab tại các điểm nhất định và cung cấp hoàn thành các giá trị.

Làm cách nào để thực hiện việc này? Tôi phải sử dụng thư viện nào? Bạn có thể chỉ cho tôi một số ví dụ về mã không?

Trả lời

30

Ah, có vẻ như thư viện chuẩn là bạn của tôi sau tất cả. Những gì tôi đang tìm kiếm là thư viện Readline.

Đốc và các ví dụ ở đây: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/readline/rdoc/Readline.html

Đặc biệt, đây là một ví dụ điển hình từ trang đó để hiển thị như thế nào hoàn thành công trình:

require 'readline' 

LIST = [ 
    'search', 'download', 'open', 
    'help', 'history', 'quit', 
    'url', 'next', 'clear', 
    'prev', 'past' 
].sort 

comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) } 

Readline.completion_append_character = " " 
Readline.completion_proc = comp 

while line = Readline.readline('> ', true) 
    p line 
end 

LƯU Ý: Các proc chỉ nhận được những lời cuối cùng bước vào. Nếu bạn muốn toàn bộ dòng đánh máy cho đến nay (vì bạn muốn làm hoàn bối cảnh cụ thể), hãy thêm dòng sau vào code trên:

Readline.completer_word_break_characters = "" #Pass whole line to proc each time 

(Đây là theo mặc định thiết lập để một danh sách các nhân vật đại diện cho từ ranh giới và nguyên nhân chỉ từ cuối cùng được chuyển vào proc của bạn).

+2

Một điều cần lưu ý là readline sử dụng thư viện giống như thư viện cơ bản của hệ thống, có thể là tự do. Vì vậy, một số tính năng của lib ruby ​​readline sẽ không hoạt động hoặc sẽ gây ra sự cố. Tránh bất cứ điều gì mà các tài liệu nói là tùy chọn hoặc có thể không hoạt động. – davetron5000

9

Thư viện Readline tuyệt vời, tôi đã sử dụng nó nhiều lần. Nhưng, nếu bạn đang làm cho nó chỉ cho những niềm vui của nó, bạn cũng có thể cuộn hoàn thành của riêng bạn.

Dưới đây là một kịch bản hoàn thành đơn giản:

require 'io/console' # Ruby 1.9 
require 'abbrev' 

word = "" 

@completions = Abbrev.abbrev([ 
    "function", 
    "begin" 
]) 

while (char = $stdin.getch) != "\r" 
    word += char 
    word = "" if char == " " 
    if char == "\t" 
     if comp = @completions[word = word[0..-2]] 
     print comp[word.length..-1] 
     end 
    else 
     print char 
    end 
end 
puts 
+0

+1, cảm ơn, đây là một giải pháp tuyệt vời! – mydoghasworms

+0

Thay vì tự xác định '@ completions', tại sao không sử dụng Abbrev từ thư viện chuẩn? – iconoclast

+0

Cảm ơn lời khuyên! Đã cập nhật ví dụ để sử dụng thư viện Abbrev. –

-9

Vâng, tôi đề nghị bạn nên sử dụng Emacs để chạy dòng lệnh của Ruby ứng dụng của bạn. Ở Emacs, những người bạn SO của tôi gần đây đã giúp tôi giải quyết việc hoàn thành tab Tự động điền (herehere). Tự động hoàn tất có vẻ là công cụ hoàn thiện từ thông minh nhất cho đến nay.

+0

Dudes, cắt nó ra với downvoting đó. Không phát minh lại bánh xe là một gợi ý tốt. Câu trả lời này của tôi xứng đáng với một số tình yêu. –

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