]> git.deb.at Git - pkg/abook.git/blob - abook_rl.c
multibyte update
[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 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 #ifdef HANDLE_MULTIBYTE
35 #       include <wchar.h>
36 #       include <mbswidth.h>
37 #endif
38
39 #define RL_READLINE_NAME        "Abook"
40
41 static int rl_x, rl_y;
42 static WINDOW *rl_win;
43
44 static bool rl_cancelled;
45
46 static void
47 rl_refresh()
48 {
49         /*refresh();*/
50         wrefresh(rl_win);
51 }
52
53 #ifdef HANDLE_MULTIBYTE
54 static int
55 rline_calc_point()
56 {
57         return (int)mbsnwidth(rl_line_buffer, rl_point, 0);
58 }
59 #endif
60
61 static void
62 rline_update()
63 {       
64 #ifdef HANDLE_MULTIBYTE
65         int real_point = rline_calc_point() + rl_x;
66 #else
67         int real_point = rl_point + rl_x;
68 #endif
69         
70         if(real_point > (COLS - 1))
71                 mvwaddnstr(rl_win, rl_y, rl_x,
72                         rl_line_buffer + (1 + real_point - COLS),
73                         COLS - rl_x - 1);
74         else
75                 mvwaddnstr(rl_win, rl_y, rl_x, rl_line_buffer, rl_end);
76
77         wclrtoeol(rl_win);
78         wmove(rl_win, rl_y, min(real_point, COLS - 1));
79
80         rl_refresh();
81 }
82
83 static void
84 rline_compdisp(char **matches, int n, int max_len)
85 {
86         /* dummy */
87 }
88
89 static int
90 rl_cancel(int dummy1, int dummy2)
91 {
92         rl_cancelled = TRUE;
93
94         rl_done = 1;
95
96         return 0;
97 }
98
99 static void
100 abook_rl_init(bool use_completion)
101 {
102         rl_readline_name = RL_READLINE_NAME;
103         
104         rl_already_prompted = 1;
105         rl_catch_sigwinch = 0;
106         
107         rl_redisplay_function = rline_update;
108         rl_completion_display_matches_hook = rline_compdisp;
109
110         rl_unbind_function_in_map(rl_clear_screen, rl_get_keymap());
111         rl_unbind_function_in_map(rl_reverse_search_history, rl_get_keymap());
112         rl_unbind_function_in_map(rl_re_read_init_file, rl_get_keymap());
113         
114         if(use_completion) {
115                 rl_bind_key('\t', rl_menu_complete);
116         } else {
117                 rl_unbind_function_in_map(rl_complete, rl_get_keymap());
118                 rl_unbind_function_in_map(rl_menu_complete, rl_get_keymap());
119         }
120
121         rl_bind_key('g' & 31, rl_cancel); /* C-g */
122
123         clear_history();
124
125         rl_cancelled = FALSE;
126 }       
127
128 char *
129 abook_readline(WINDOW *w, int y, int x, char *s, int limit, bool use_completion)
130 {
131         char *ret;
132
133         abook_rl_init(use_completion);
134
135         wmove(rl_win = w, rl_y = y, rl_x = x);
136         rl_refresh();
137
138         if(s && *s)
139                 add_history(s);
140         
141 #ifdef KEYPAD_HACK
142         keypad(w, FALSE);
143 #endif
144 #ifdef CBREAK_HACK
145         nocbreak();
146 #endif
147         ret = readline(NULL);
148 #ifdef CBREAK_HACK
149         cbreak();
150 #endif
151 #ifdef KEYPAD_HACK
152         keypad(w, TRUE);
153 #endif
154
155         if(rl_cancelled && ret) {
156                 free(ret);
157                 ret = NULL;
158         }
159
160         return ret;
161 }
162