]> git.deb.at Git - pkg/abook.git/blob - abook_rl.c
workarounds for readline problems
[pkg/abook.git] / abook_rl.c
1 /*
2  * $Id$
3  *
4  * by JH <jheinonen@users.sourceforge.net>
5  *
6  * Copyright (C) Jaakko Heinonen
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include "abook.h"
13 #include "abook_rl.h"
14
15 #define KEYPAD_HACK 1 /* enable a keypad hack */
16 #define CBREAK_HACK 1 /* enable cbreak hack */
17
18 #ifdef HAVE_CONFIG_H
19 #       include "config.h"
20 #endif
21
22 #if defined(HAVE_READLINE_READLINE_H)
23 #       include <readline/readline.h>
24 #elif defined(HAVE_READLINE_H)
25 #       include <readline.h>
26 #endif
27
28 #if defined(HAVE_READLINE_HISTORY_H)
29 #       include <readline/history.h>
30 #elif defined(HAVE_HISTORY_H)
31 #       include <history.h>
32 #endif
33
34 #define RL_READLINE_NAME        "Abook"
35
36 static int rl_x, rl_y;
37 static WINDOW *rl_win;
38
39 static bool rl_cancelled;
40
41 static void
42 rl_refresh()
43 {
44         /*refresh();*/
45         wrefresh(rl_win);
46 }
47
48 static void
49 rline_update()
50 {       
51         int real_point = rl_point + rl_x;
52         
53         if(real_point > (COLS - 1))
54                 mvwaddnstr(rl_win, rl_y, rl_x,
55                         rl_line_buffer + (1 + real_point - COLS),
56                         COLS - rl_x - 1);
57         else
58                 mvwaddnstr(rl_win, rl_y, rl_x, rl_line_buffer, rl_end);
59
60         wclrtoeol(rl_win);
61         wmove(rl_win, rl_y, min(real_point, COLS - 1));
62
63         rl_refresh();
64 }
65
66 static void
67 rline_compdisp(char **matches, int n, int max_len)
68 {
69         /* dummy */
70 }
71
72 static int
73 rl_cancel(int dummy1, int dummy2)
74 {
75         rl_cancelled = TRUE;
76
77         rl_done = 1;
78
79         return 0;
80 }
81
82 static void
83 abook_rl_init(bool use_completion)
84 {
85         rl_readline_name = RL_READLINE_NAME;
86         
87         rl_already_prompted = 1;
88         rl_catch_sigwinch = 0;
89         
90         rl_redisplay_function = rline_update;
91         rl_completion_display_matches_hook = rline_compdisp;
92
93         rl_unbind_function_in_map(rl_clear_screen, rl_get_keymap());
94         rl_unbind_function_in_map(rl_reverse_search_history, rl_get_keymap());
95         rl_unbind_function_in_map(rl_re_read_init_file, rl_get_keymap());
96         
97         if(use_completion) {
98                 rl_bind_key('\t', rl_menu_complete);
99         } else {
100                 rl_unbind_function_in_map(rl_complete, rl_get_keymap());
101                 rl_unbind_function_in_map(rl_menu_complete, rl_get_keymap());
102         }
103
104         rl_bind_key('g' & 31, rl_cancel); /* C-g */
105
106         clear_history();
107
108         rl_cancelled = FALSE;
109 }       
110
111 char *
112 abook_readline(WINDOW *w, int y, int x, char *s, int limit, bool use_completion)
113 {
114         char *ret;
115
116         abook_rl_init(use_completion);
117
118         wmove(rl_win = w, rl_y = y, rl_x = x);
119         rl_refresh();
120
121         if(s && *s)
122                 add_history(s);
123         
124 #ifdef KEYPAD_HACK
125         keypad(w, FALSE);
126 #endif
127 #ifdef CBREAK_HACK
128         nocbreak();
129 #endif
130         ret = readline(NULL);
131 #ifdef CBREAK_HACK
132         cbreak();
133 #endif
134 #ifdef KEYPAD_HACK
135         keypad(w, TRUE);
136 #endif
137
138         if(rl_cancelled && ret) {
139                 free(ret);
140                 ret = NULL;
141         }
142
143         return ret;
144 }
145