2009-03-27 28 views
21

Tiêu đề cụ thể hơn một chút so với mục tiêu thực tế của tôi:Sử dụng GNU Readline; làm thế nào tôi có thể thêm ncurses trong cùng một chương trình?

Tôi có chương trình dòng lệnh sử dụng GNU Readline, chủ yếu cho lịch sử lệnh (tức là lấy các lệnh trước bằng mũi tên lên) và một số thành phần khác. Ngay bây giờ, đầu ra của chương trình xuất hiện xen kẽ với đầu vào của người dùng, đôi khi là OK nhưng đầu ra không đồng bộ (nó đi qua kết nối mạng để đáp ứng với lệnh nhập) và đôi khi gây phiền nhiễu (ví dụ: nếu đường là đầu ra khi người dùng đang nhập đầu vào mới).

Tôi muốn thêm một tính năng vào chương trình này: một "cửa sổ" riêng biệt cho đầu ra. Tôi nghĩ về việc sử dụng ncurses cho việc này. Nhưng nó xuất hiện từ ncurses FAQ rằng hai thư viện không dễ sử dụng cùng nhau.

Tôi có thể xem xét sử dụng Editline hoặc tecla thay vì Readline, nhưng không rõ ràng nếu một trong hai cách đó giải quyết được sự cố của tôi. Tôi cũng sẽ xem xét sử dụng một cái gì đó khác hơn ncurses, bao gồm một thư viện cung cấp cả hai loại chức năng (cửa sổ chế độ văn bản và lịch sử lệnh), nhưng tôi không biết những gì có thể là tốt nhất.

Ồ, và hỗ trợ cho văn bản màu có thể nhận điểm thưởng. Tôi nghi ngờ tôi có thể làm điều đó với Readline, vì vậy có lẽ đó là một mối quan tâm riêng biệt, nhưng nếu một giải pháp cho vấn đề của tôi cũng làm cho nó dễ dàng để thêm một chút màu sắc cho đầu ra, rất nhiều càng tốt.

Tôi đang sử dụng Ubuntu Hardy (Linux 2.6).

+0

Bạn đã tìm thấy một giải pháp? –

+0

Tôi đã từ bỏ (và bị mắc kẹt với readline). –

Trả lời

6

Tôi đã thực hiện một số tìm kiếm và có vẻ như bạn đã hết may mắn.

Đối với các giải pháp thay thế ncurses, có SLang, NewtTurbo Vision. Tiếng lóng không chỉ đơn thuần là xử lý màn hình và do đó phức tạp hơn , nhưng có thể nó có thể được sử dụng cho mục đích của bạn ?. Newt sử dụng màn hình xử lý và đơn giản hơn nhiều, nhưng quá đơn giản và đơn luồng-mode cho mục đích của bạn tôi nghĩ.

Tầm nhìn Turbo là thư viện đồ họa chế độ văn bản từ Borland, được sử dụng bởi tất cả các công cụ của họ vào cuối những năm 80/đầu thập niên 90. Borland phát hành mã nguồn khi thị trường cho loại điều đó giảm đi, và có bây giờ là một cổng cho Linux (lưu ý bên, this project dường như đã viết triển khai tầm nhìn turbo riêng của nó). Cổng đó không chết (có là một số bản cập nhật cvs năm nay được biên soạn tốt (các bản phát hành cũ hơn không)), nhưng không có ví dụ TV nào tôi tìm thấy được cập nhật và tôi chỉ có một vài trong số chúng để biên dịch trước khi bỏ phần còn lại. Đây là một chút xấu hổ, vì TV là một môi trường đáng yêu để sử dụng. TV là btw C++ (và tôi cho rằng bạn đang sử dụng C?).

Đối với một thay thế cho readline, có libkinput, mà có lẽ làm việc cùng với kernel (nó nói nó có thể sử dụng terminfo ncurses'. Nhưng tôi không chắc chắn nếu điều đó có nghĩa là nó có thể cùng tồn tại cùng với việc sử dụng ncurses)?

Có thể một tùy chọn là chạy dòng readline "bên ngoài" cho chương trình ncurses bằng cách sử dụng rlwrap?

+0

tiếng lóng hóa ra là một ngôn ngữ trong chính nó. Ngoài ra, nó chỉ là giấy phép GPL2 cho phiên bản mới nhất. Tôi đã mong nó trở thành một thư viện. – matiu

+0

Lưu ý rằng Newt là một lớp trên SLang. Nó có thể dễ dàng hơn để sử dụng, nhưng nó chính xác là một lựa chọn khác. –

2

Tôi không chắc chắn bạn đã thử phiên bản nào. Tính đến hôm nay (2012/09/14) Nó rất đơn giản, Chúng ta chỉ cần móc hàm tùy chỉnh của chúng ta để làm theo các con trỏ hàm.

 
rl_getch_function 
rl_redisplay_function 
rl_completion_display_matches_hook 

Tôi đã làm điều gì đó hợp lý here.

+0

Bất kỳ ý tưởng nào về cách làm cho lịch sử hoạt động? – nccc

+1

OK, tôi đã phát hiện ra. Người ta phải hiển thị 'rl_display_prompt', sau đó' rl_line_buffer' và đặt con trỏ offset thành 'rl_point + strlen (rl_display_prompt)'. – nccc

5

này đã cho tôi đập đầu của tôi trong một vài giờ, vì vậy chỉ cần để cứu người Googling một số cơn đau:

Nếu bạn' sử dụng lại handler SIGWINCH của ncurses với KEY_RESIZE, hãy lưu ý rằng readline đặt mặc định là các biến môi trường LINESCOLUMNS. Chúng ghi đè lên bất kỳ phép tính kích thước động nào (thường là với ioctl()TIOCGWINSZ) mà nếu không, có nghĩa là bạn sẽ tiếp tục nhận được kích thước thiết bị đầu cuối ban đầu ngay cả sau khi thay đổi kích thước thiết bị đầu cuối.

Điều này có thể được ngăn chặn bằng cách đặt rl_change_environment thành 0 trước khi khởi tạo đường dây đọc.

Cập nhật:

Dưới đây là một số thông tin bổ sung Tôi lượm lặt từ các nguồn readline:

SIGWINCH xử lý mã readline của (được sử dụng nếu rl_catch_sigwinch là 1) không cập nhật LINESCOLUMNS, mà có vẻ như nó nên là đủ cho ncurses. Tuy nhiên, khi sử dụng giao diện readline thay thế (có ý nghĩa nhất khi kết hợp readline với ncurses), các bộ xử lý tín hiệu (bao gồm cả SIGWINCH) sẽ chỉ được cài đặt trong suốt thời gian của mỗi cuộc gọi rl_callback_read_char(). rl_callback_read_char() sẽ không được nhìn thấy bởi readline.

+1

Vui lòng xem xét [định dạng] (http://stackoverflow.com/help/formatting) câu trả lời của bạn. Các lệnh/mã khó đọc. – ryanyuyu

+1

@dotctor Cảm ơn bạn đã định dạng cho tôi! – Ulfalizer

9

Tôi đã kết hợp một chương trình ví dụ đơn giản trên GitHub: https://github.com/ulfalizer/readline-and-ncurses.

Nó hỗ trợ thay đổi kích thước đầu cuối liền mạch và hiệu quả và nhiều ký tự/kết hợp/ký tự rộng. Mã này có các bình luận hữu ích.

Ảnh chụp màn hình dưới đây:

Screenshot of program combining ncurses and readline

+0

Tuyệt vời! Giấy phép mã là gì? Tôi muốn tích hợp nó với một số tài liệu do MIT cấp phép nếu có thể. Cảm ơn! – cxw

+0

Rất vui được! Tôi có thể đặt nó dưới MIT nếu đó là rắc rối ít nhất. Tôi đã đi với ISC nếu không, và MIT trông tương tự. Tôi cũng có một phiên bản chạy ra một vòng lặp select() (hoặc epoll() trong trường hợp này) bằng cách này, cho https://github.com/ulfalizer/botniklas. Đã bị bỏ qua và chưa đẩy nó, nhưng tôi có thể làm một chi nhánh cho nó nếu bạn muốn được quan tâm. – Ulfalizer

+0

Phiên bản đó cài đặt một trình xử lý SIGWINCH (mặc dù sử dụng signalfd() thay vì một trình xử lý thông thường) và cho phép readline đọc trực tiếp từ stdin. Điều đó cũng xảy ra để khắc phục vấn đề với tìm kiếm và các ký tự nhiều byte. – Ulfalizer

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