1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 ****************************************************************
24 #include <sys/types.h>
31 #define INPUTLINE (flayer->l_height - 1)
33 extern struct layer
*flayer
;
34 extern struct win
*fore
;
40 /********************************************************************
44 static int matchword
__P((char *, int, int, int));
45 static void searchend
__P((char *, int, char *));
46 static void backsearchend
__P((char *, int, char *));
52 struct markdata
*markdata
;
55 markdata
= (struct markdata
*)flayer
->l_data
;
56 if (markdata
->isdir
> 0)
57 searchend(0, 0, NULL
);
58 else if (markdata
->isdir
< 0)
59 backsearchend(0, 0, NULL
);
61 LMsg(0, "No previous pattern");
64 Input((dir
> 0 ? "/" : "?"), sizeof(markdata
->isstr
)-1, INP_COOKED
,
65 (dir
> 0 ? searchend
: backsearchend
), NULL
, 0);
69 searchend(buf
, len
, data
)
72 char *data
; /* dummy */
75 struct markdata
*markdata
;
78 markdata
= (struct markdata
*)flayer
->l_data
;
79 p
= markdata
->md_window
;
82 strcpy(markdata
->isstr
, buf
);
83 sx
= markdata
->cx
+ 1;
84 ex
= flayer
->l_width
- 1;
85 for (y
= markdata
->cy
; y
< p
->w_histheight
+ flayer
->l_height
; y
++, sx
= 0)
87 if ((x
= matchword(markdata
->isstr
, y
, sx
, ex
)) >= 0)
90 if (y
>= p
->w_histheight
+ flayer
->l_height
)
92 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
93 LMsg(0, "Pattern not found");
100 backsearchend(buf
, len
, data
)
103 char *data
; /* dummy */
105 int sx
, ex
, x
= -1, y
;
106 struct markdata
*markdata
;
108 markdata
= (struct markdata
*)flayer
->l_data
;
109 markdata
->isdir
= -1;
111 strcpy(markdata
->isstr
, buf
);
112 ex
= markdata
->cx
- 1;
113 for (y
= markdata
->cy
; y
>= 0; y
--, ex
= flayer
->l_width
- 1)
116 while ((sx
= matchword(markdata
->isstr
, y
, sx
, ex
)) >= 0)
123 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
124 LMsg(0, "Pattern not found");
131 matchword(pattern
, y
, sx
, ex
)
135 unsigned char *ip
, *ipe
, *cp
, *pp
;
138 /* *sigh* to make WIN work */
139 fore
= ((struct markdata
*)flayer
->l_data
)->md_window
;
143 ipe
= ml
->image
+ flayer
->l_width
;
144 for (;sx
<= ex
; sx
++)
147 pp
= (unsigned char *)pattern
;
151 if (!search_ic
|| ((*cp
^ *pp
) & 0xdf) || (*cp
| 0x20) < 'a' || (*cp
| 0x20) > 'z')
165 /********************************************************************
166 * Emacs style ISearch
169 static char *isprompts
[] = {
170 "I-search backward: ", "failing I-search backward: ",
171 "I-search: ", "failing I-search: "
175 static int is_redo
__P((struct markdata
*));
176 static void is_process
__P((char *, int, char *));
177 static int is_bm
__P((char *, int, int, int, int));
181 is_bm(str
, l
, p
, end
, dir
)
188 int w
= flayer
->l_width
;
190 /* *sigh* to make WIN work */
191 fore
= ((struct markdata
*)flayer
->l_next
->l_data
)->md_window
;
192 debug2("is_bm: searching for %s len %d\n", str
, l
);
193 debug3("start at %d end %d dir %d\n", p
, end
, dir
);
194 if (p
< 0 || p
+ l
> end
)
200 for (i
= 0; i
< 256; i
++)
202 for (i
= 0; i
< l
- 1; i
++, str
+= dir
)
204 q
= *(unsigned char *)str
;
205 tab
[q
] = (l
- 1 - i
) * dir
;
206 if (search_ic
&& (q
| 0x20) >= 'a' && ((q
| 0x20) <= 'z'))
207 tab
[q
^ 0x20] = (l
- 1 - i
) * dir
;
211 debug1("first char to match: %c\n", *str
);
212 while (p
>= 0 && p
< end
)
215 s
= (unsigned char *)str
;
218 c
= (WIN(q
/ w
))->image
[q
% w
];
220 p
+= tab
[(int)(unsigned char) c
];
222 if (!search_ic
|| ((c
^ *s
) & 0xdf) || (c
| 0x20) < 'a' || (c
| 0x20) > 'z')
227 return q
+ (dir
> 0 ? 1 : -l
);
236 is_process(p
, n
, data
) /* i-search */
239 char *data
; /* dummy */
242 struct markdata
*markdata
;
247 markdata
= (struct markdata
*)flayer
->l_next
->l_data
;
249 pos
= markdata
->cx
+ markdata
->cy
* flayer
->l_width
;
250 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
254 case '\007': /* CTRL-G */
255 pos
= markdata
->isstartpos
;
257 case '\033': /* ESC */
260 case '\013': /* CTRL-K */
261 case '\027': /* CTRL-W */
262 markdata
->isistrl
= 1;
266 if (markdata
->isistrl
== 0)
269 pos
= is_redo(markdata
);
272 case '\023': /* CTRL-S */
273 case '\022': /* CTRL-R */
274 if (markdata
->isistrl
>= (int)sizeof(markdata
->isistr
))
276 dir
= (*p
== '\023') ? 1 : -1;
278 if (markdata
->isdir
== dir
&& markdata
->isistrl
== 0)
280 strcpy(markdata
->isistr
, markdata
->isstr
);
281 markdata
->isistrl
= markdata
->isstrl
= strlen(markdata
->isstr
);
284 markdata
->isdir
= dir
;
285 markdata
->isistr
[markdata
->isistrl
++] = *p
;
288 if (*p
< ' ' || markdata
->isistrl
>= (int)sizeof(markdata
->isistr
)
289 || markdata
->isstrl
>= (int)sizeof(markdata
->isstr
) - 1)
291 markdata
->isstr
[markdata
->isstrl
++] = *p
;
292 markdata
->isistr
[markdata
->isistrl
++] = *p
;
293 markdata
->isstr
[markdata
->isstrl
] = 0;
294 debug2("New char: %c - left %d\n", *p
, (int)sizeof(markdata
->isistr
) - markdata
->isistrl
);
296 if (*p
&& *p
!= '\b')
297 pos
= is_bm(markdata
->isstr
, markdata
->isstrl
, pos
, flayer
->l_width
* (markdata
->md_window
->w_histheight
+ flayer
->l_height
), markdata
->isdir
);
300 x
= pos
% flayer
->l_width
;
301 y
= pos
/ flayer
->l_width
;
304 LayRedisplayLine(INPUTLINE
, 0, flayer
->l_width
- 1, 0);
306 if (W2D(markdata
->cy
) == INPUTLINE
)
307 revto_line(markdata
->cx
, markdata
->cy
, INPUTLINE
> 0 ? INPUTLINE
- 1 : 1);
311 inp_setprompt(isprompts
[markdata
->isdir
+ (pos
< 0) + 1], markdata
->isstrl
? markdata
->isstr
: "");
312 flayer
->l_x
= markdata
->cx
;
313 flayer
->l_y
= W2D(markdata
->cy
);
314 LGotoPos(flayer
, flayer
->l_x
, flayer
->l_y
);
317 /* we are about to finish, keep cursor position */
318 flayer
->l_next
->l_x
= markdata
->cx
;
319 flayer
->l_next
->l_y
= W2D(markdata
->cy
);
325 struct markdata
*markdata
;
327 int i
, pos
, npos
, dir
;
330 npos
= pos
= markdata
->isstartpos
;
331 dir
= markdata
->isstartdir
;
332 markdata
->isstrl
= 0;
333 for (i
= 0; i
< markdata
->isistrl
; i
++)
335 c
= markdata
->isistr
[i
];
336 if (c
== '\022') /* ^R */
338 else if (c
== '\023') /* ^S */
341 markdata
->isstr
[markdata
->isstrl
++] = c
;
344 npos
= is_bm(markdata
->isstr
, markdata
->isstrl
, pos
, flayer
->l_width
* (markdata
->md_window
->w_histheight
+ flayer
->l_height
), dir
);
349 markdata
->isstr
[markdata
->isstrl
] = 0;
350 markdata
->isdir
= dir
;
358 struct markdata
*markdata
;
360 markdata
= (struct markdata
*)flayer
->l_data
;
361 markdata
->isdir
= markdata
->isstartdir
= dir
;
362 markdata
->isstartpos
= markdata
->cx
+ markdata
->cy
* flayer
->l_width
;
363 markdata
->isistrl
= markdata
->isstrl
= 0;
364 if (W2D(markdata
->cy
) == INPUTLINE
)
365 revto_line(markdata
->cx
, markdata
->cy
, INPUTLINE
> 0 ? INPUTLINE
- 1 : 1);
366 Input(isprompts
[dir
+ 1], sizeof(markdata
->isstr
) - 1, INP_RAW
,
367 is_process
, NULL
, 0);
368 LGotoPos(flayer
, markdata
->cx
, W2D(markdata
->cy
));
369 flayer
->l_x
= markdata
->cx
;
370 flayer
->l_y
= W2D(markdata
->cy
);
373 #endif /* COPY_PASTE */