1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include <sys/types.h>
36 #define INPUTLINE (flayer->l_height - 1)
38 extern struct layer
*flayer
;
39 extern struct win
*fore
;
45 /********************************************************************
49 static int matchword
__P((char *, int, int, int));
50 static void searchend
__P((char *, int, char *));
51 static void backsearchend
__P((char *, int, char *));
57 struct markdata
*markdata
;
60 markdata
= (struct markdata
*)flayer
->l_data
;
61 if (markdata
->isdir
> 0)
62 searchend(0, 0, NULL
);
63 else if (markdata
->isdir
< 0)
64 backsearchend(0, 0, NULL
);
66 LMsg(0, "No previous pattern");
69 Input((dir
> 0 ? "/" : "?"), sizeof(markdata
->isstr
)-1, INP_COOKED
,
70 (dir
> 0 ? searchend
: backsearchend
), NULL
, 0);
74 searchend(buf
, len
, data
)
77 char *data
; /* dummy */
80 struct markdata
*markdata
;
83 markdata
= (struct markdata
*)flayer
->l_data
;
84 p
= markdata
->md_window
;
87 strcpy(markdata
->isstr
, buf
);
88 sx
= markdata
->cx
+ 1;
89 ex
= flayer
->l_width
- 1;
90 for (y
= markdata
->cy
; y
< p
->w_histheight
+ flayer
->l_height
; y
++, sx
= 0)
92 if ((x
= matchword(markdata
->isstr
, y
, sx
, ex
)) >= 0)
95 if (y
>= p
->w_histheight
+ flayer
->l_height
)
97 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
98 LMsg(0, "Pattern not found");
105 backsearchend(buf
, len
, data
)
108 char *data
; /* dummy */
110 int sx
, ex
, x
= -1, y
;
111 struct markdata
*markdata
;
113 markdata
= (struct markdata
*)flayer
->l_data
;
114 markdata
->isdir
= -1;
116 strcpy(markdata
->isstr
, buf
);
117 ex
= markdata
->cx
- 1;
118 for (y
= markdata
->cy
; y
>= 0; y
--, ex
= flayer
->l_width
- 1)
121 while ((sx
= matchword(markdata
->isstr
, y
, sx
, ex
)) >= 0)
128 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
129 LMsg(0, "Pattern not found");
136 matchword(pattern
, y
, sx
, ex
)
140 unsigned char *ip
, *ipe
, *cp
, *pp
;
143 /* *sigh* to make WIN work */
144 fore
= ((struct markdata
*)flayer
->l_data
)->md_window
;
148 ipe
= ml
->image
+ flayer
->l_width
;
149 for (;sx
<= ex
; sx
++)
152 pp
= (unsigned char *)pattern
;
156 if (!search_ic
|| ((*cp
^ *pp
) & 0xdf) || (*cp
| 0x20) < 'a' || (*cp
| 0x20) > 'z')
170 /********************************************************************
171 * Emacs style ISearch
174 static char *isprompts
[] = {
175 "I-search backward: ", "failing I-search backward: ",
176 "I-search: ", "failing I-search: "
180 static int is_redo
__P((struct markdata
*));
181 static void is_process
__P((char *, int, char *));
182 static int is_bm
__P((char *, int, int, int, int));
186 is_bm(str
, l
, p
, end
, dir
)
193 int w
= flayer
->l_width
;
195 /* *sigh* to make WIN work */
196 fore
= ((struct markdata
*)flayer
->l_next
->l_data
)->md_window
;
197 debug2("is_bm: searching for %s len %d\n", str
, l
);
198 debug3("start at %d end %d dir %d\n", p
, end
, dir
);
199 if (p
< 0 || p
+ l
> end
)
205 for (i
= 0; i
< 256; i
++)
207 for (i
= 0; i
< l
- 1; i
++, str
+= dir
)
209 q
= *(unsigned char *)str
;
210 tab
[q
] = (l
- 1 - i
) * dir
;
211 if (search_ic
&& (q
| 0x20) >= 'a' && ((q
| 0x20) <= 'z'))
212 tab
[q
^ 0x20] = (l
- 1 - i
) * dir
;
216 debug1("first char to match: %c\n", *str
);
217 while (p
>= 0 && p
< end
)
220 s
= (unsigned char *)str
;
223 c
= (WIN(q
/ w
))->image
[q
% w
];
225 p
+= tab
[(int)(unsigned char) c
];
227 if (!search_ic
|| ((c
^ *s
) & 0xdf) || (c
| 0x20) < 'a' || (c
| 0x20) > 'z')
232 return q
+ (dir
> 0 ? 1 : -l
);
241 is_process(p
, n
, data
) /* i-search */
244 char *data
; /* dummy */
247 struct markdata
*markdata
;
252 markdata
= (struct markdata
*)flayer
->l_next
->l_data
;
254 pos
= markdata
->cx
+ markdata
->cy
* flayer
->l_width
;
255 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
259 case '\007': /* CTRL-G */
260 pos
= markdata
->isstartpos
;
262 case '\033': /* ESC */
265 case '\013': /* CTRL-K */
266 case '\027': /* CTRL-W */
267 markdata
->isistrl
= 1;
271 if (markdata
->isistrl
== 0)
274 pos
= is_redo(markdata
);
277 case '\023': /* CTRL-S */
278 case '\022': /* CTRL-R */
279 if (markdata
->isistrl
>= (int)sizeof(markdata
->isistr
))
281 dir
= (*p
== '\023') ? 1 : -1;
283 if (markdata
->isdir
== dir
&& markdata
->isistrl
== 0)
285 strcpy(markdata
->isistr
, markdata
->isstr
);
286 markdata
->isistrl
= markdata
->isstrl
= strlen(markdata
->isstr
);
289 markdata
->isdir
= dir
;
290 markdata
->isistr
[markdata
->isistrl
++] = *p
;
293 if (*p
< ' ' || markdata
->isistrl
>= (int)sizeof(markdata
->isistr
)
294 || markdata
->isstrl
>= (int)sizeof(markdata
->isstr
) - 1)
296 markdata
->isstr
[markdata
->isstrl
++] = *p
;
297 markdata
->isistr
[markdata
->isistrl
++] = *p
;
298 markdata
->isstr
[markdata
->isstrl
] = 0;
299 debug2("New char: %c - left %d\n", *p
, (int)sizeof(markdata
->isistr
) - markdata
->isistrl
);
301 if (*p
&& *p
!= '\b')
302 pos
= is_bm(markdata
->isstr
, markdata
->isstrl
, pos
, flayer
->l_width
* (markdata
->md_window
->w_histheight
+ flayer
->l_height
), markdata
->isdir
);
305 x
= pos
% flayer
->l_width
;
306 y
= pos
/ flayer
->l_width
;
309 LayRedisplayLine(INPUTLINE
, 0, flayer
->l_width
- 1, 0);
311 if (W2D(markdata
->cy
) == INPUTLINE
)
312 revto_line(markdata
->cx
, markdata
->cy
, INPUTLINE
> 0 ? INPUTLINE
- 1 : 1);
316 inp_setprompt(isprompts
[markdata
->isdir
+ (pos
< 0) + 1], markdata
->isstrl
? markdata
->isstr
: "");
317 flayer
->l_x
= markdata
->cx
;
318 flayer
->l_y
= W2D(markdata
->cy
);
319 LGotoPos(flayer
, flayer
->l_x
, flayer
->l_y
);
322 /* we are about to finish, keep cursor position */
323 flayer
->l_next
->l_x
= markdata
->cx
;
324 flayer
->l_next
->l_y
= W2D(markdata
->cy
);
330 struct markdata
*markdata
;
332 int i
, pos
, npos
, dir
;
335 npos
= pos
= markdata
->isstartpos
;
336 dir
= markdata
->isstartdir
;
337 markdata
->isstrl
= 0;
338 for (i
= 0; i
< markdata
->isistrl
; i
++)
340 c
= markdata
->isistr
[i
];
341 if (c
== '\022') /* ^R */
343 else if (c
== '\023') /* ^S */
346 markdata
->isstr
[markdata
->isstrl
++] = c
;
349 npos
= is_bm(markdata
->isstr
, markdata
->isstrl
, pos
, flayer
->l_width
* (markdata
->md_window
->w_histheight
+ flayer
->l_height
), dir
);
354 markdata
->isstr
[markdata
->isstrl
] = 0;
355 markdata
->isdir
= dir
;
363 struct markdata
*markdata
;
365 markdata
= (struct markdata
*)flayer
->l_data
;
366 markdata
->isdir
= markdata
->isstartdir
= dir
;
367 markdata
->isstartpos
= markdata
->cx
+ markdata
->cy
* flayer
->l_width
;
368 markdata
->isistrl
= markdata
->isstrl
= 0;
369 if (W2D(markdata
->cy
) == INPUTLINE
)
370 revto_line(markdata
->cx
, markdata
->cy
, INPUTLINE
> 0 ? INPUTLINE
- 1 : 1);
371 Input(isprompts
[dir
+ 1], sizeof(markdata
->isstr
) - 1, INP_RAW
,
372 is_process
, NULL
, 0);
373 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
374 flayer
->l_x
= markdata
->cx
;
375 flayer
->l_y
= W2D(markdata
->cy
);
378 #endif /* COPY_PASTE */