wavpack: Pass correct sample count to format_samples()
[cmus.git] / search_mode.c
blobd9b5501197388634f94393facdab754fb686c38c
1 /*
2 * Copyright 2004 Timo Hirvonen
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
20 #include "search_mode.h"
21 #include "cmdline.h"
22 #include "history.h"
23 #include "ui_curses.h"
24 #include "search.h"
25 #include "xmalloc.h"
26 #include "xstrjoin.h"
27 #include "misc.h"
28 #include "lib.h"
30 #include <ctype.h>
32 #if defined(__sun__)
33 #include <ncurses.h>
34 #else
35 #include <curses.h>
36 #endif
38 /* this is set in ui_curses.c */
39 enum search_direction search_direction = SEARCH_FORWARD;
41 /* current search string, this is set _only_ when user presses enter
42 * this string is used when 'n' or 'N' is pressed
43 * incremental search does not use this, it uses cmdline.line directly
45 char *search_str = NULL;
46 int search_restricted = 0;
48 static int search_found = 0;
49 static struct history search_history;
50 static char *search_history_filename;
51 static char *history_search_text = NULL;
53 static void update_search_line(const char *text, int restricted)
55 int len = strlen(text);
56 char ch = search_direction == SEARCH_FORWARD ? '/' : '?';
57 char *buf, *ptr;
59 buf = xnew(char, len + 2);
60 ptr = buf;
61 if (restricted)
62 *ptr++ = ch;
63 memcpy(ptr, text, len + 1);
64 cmdline_set_text(buf);
65 free(buf);
68 static int search_line_empty(void)
70 char ch;
72 if (cmdline.clen == 0)
73 return 1;
74 if (cmdline.clen > 1)
75 return 0;
76 ch = search_direction == SEARCH_FORWARD ? '/' : '?';
77 return cmdline.line[0] == ch;
80 static void parse_line(const char **text, int *restricted)
82 char ch = search_direction == SEARCH_FORWARD ? '/' : '?';
83 int r = 0;
85 if (cmdline.line[0] == ch) {
86 /* //WORDS or ??WORDS */
87 r = 1;
89 *text = cmdline.line + r;
90 *restricted = r;
93 static void reset_history_search(void)
95 history_reset_search(&search_history);
96 free(history_search_text);
97 history_search_text = NULL;
100 static void backspace(void)
102 if (cmdline.clen > 0) {
103 cmdline_backspace();
104 } else {
105 input_mode = NORMAL_MODE;
109 static void delete(void)
111 /* save old value */
112 int restricted = search_restricted;
113 const char *text;
115 cmdline_delete_ch();
116 parse_line(&text, &search_restricted);
117 if (text[0])
118 search_found = search(searchable, text, search_direction, 0);
120 /* restore old value */
121 search_restricted = restricted;
124 void search_mode_ch(uchar ch)
126 const char *text;
127 int restricted;
129 switch (ch) {
130 case 0x01: // ^A
131 cmdline_move_home();
132 break;
133 case 0x02: // ^B
134 cmdline_move_left();
135 break;
136 case 0x04: // ^D
137 delete();
138 break;
139 case 0x05: // ^E
140 cmdline_move_end();
141 break;
142 case 0x06: // ^F
143 cmdline_move_right();
144 break;
145 case 0x03: // ^C
146 case 0x07: // ^G
147 case 0x1B: // ESC
148 parse_line(&text, &restricted);
149 if (text[0]) {
150 history_add_line(&search_history, text);
151 cmdline_clear();
153 input_mode = NORMAL_MODE;
154 break;
155 case 0x0A:
156 parse_line(&text, &restricted);
157 if (text[0] == 0) {
158 /* cmdline is "/", "?", "//" or "??" */
159 if (search_str) {
160 /* use old search string */
161 search_restricted = restricted;
162 search_found = search_next(searchable, search_str, search_direction);
164 } else {
165 /* set new search string and add it to the history */
166 free(search_str);
167 search_str = xstrdup(text);
168 history_add_line(&search_history, text);
170 /* search not yet done if up or down arrow was pressed */
171 search_restricted = restricted;
172 search_found = search(searchable, search_str, search_direction, 0);
174 cmdline_clear();
175 if (!search_found)
176 search_not_found();
177 input_mode = NORMAL_MODE;
178 break;
179 case 0x0B:
180 cmdline_clear_end();
181 break;
182 case 0x15:
183 cmdline_backspace_to_bol();
184 break;
185 case 127:
186 backspace();
187 break;
188 default:
189 if (ch < 0x20) {
190 return;
191 } else {
192 /* start from beginning if this is first char */
193 int beginning = search_line_empty();
195 /* save old value
197 * don't set search_{str,restricted} here because
198 * search can be cancelled by pressing ESC
200 restricted = search_restricted;
202 cmdline_insert_ch(ch);
203 parse_line(&text, &search_restricted);
204 search_found = search(searchable, text, search_direction, beginning);
206 /* restore old value */
207 search_restricted = restricted;
209 break;
211 reset_history_search();
214 void search_mode_key(int key)
216 const char *text;
217 int restricted;
219 switch (key) {
220 case KEY_DC:
221 delete();
222 break;
223 case KEY_BACKSPACE:
224 backspace();
225 break;
226 case KEY_LEFT:
227 cmdline_move_left();
228 return;
229 case KEY_RIGHT:
230 cmdline_move_right();
231 return;
232 case KEY_HOME:
233 cmdline_move_home();
234 return;
235 case KEY_END:
236 cmdline_move_end();
237 return;
238 case KEY_UP:
239 parse_line(&text, &restricted);
240 if (history_search_text == NULL)
241 history_search_text = xstrdup(text);
242 text = history_search_forward(&search_history, history_search_text);
243 if (text)
244 update_search_line(text, restricted);
245 return;
246 case KEY_DOWN:
247 if (history_search_text) {
248 parse_line(&text, &restricted);
249 text = history_search_backward(&search_history, history_search_text);
250 if (text) {
251 update_search_line(text, restricted);
252 } else {
253 update_search_line(history_search_text, restricted);
256 return;
257 default:
258 return;
260 reset_history_search();
263 void search_mode_init(void)
265 search_history_filename = xstrjoin(cmus_config_dir, "/search-history");
266 history_load(&search_history, search_history_filename, 100);
269 void search_mode_exit(void)
271 history_save(&search_history);
272 free(search_history_filename);