1 | /****************************** Module Header *******************************
|
---|
2 | *
|
---|
3 | * Module Name: locate.e
|
---|
4 | *
|
---|
5 | * Copyright (c) Netlabs EPM Distribution Project 2002
|
---|
6 | *
|
---|
7 | * $Id: locate.e 3877 2020-02-23 20:22:15Z aschn $
|
---|
8 | *
|
---|
9 | * ===========================================================================
|
---|
10 | *
|
---|
11 | * This file is part of the Netlabs EPM Distribution package and is free
|
---|
12 | * software. You can redistribute it and/or modify it under the terms of the
|
---|
13 | * GNU General Public License as published by the Free Software
|
---|
14 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
15 | * Netlabs EPM Distribution. This library is distributed in the hope that it
|
---|
16 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
---|
17 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
18 | * General Public License for more details.
|
---|
19 | *
|
---|
20 | ****************************************************************************/
|
---|
21 |
|
---|
22 | ; Undocumented:
|
---|
23 | ; display -8 ==> messages go only to the msg line, not to the msg box.
|
---|
24 | ; display 8 ==> reenables messages from a previous display -8
|
---|
25 | ; The rest is documented in epmtech.inf.
|
---|
26 |
|
---|
27 |
|
---|
28 | ; 'xcom l', 'xcom c' and repeatfind:
|
---|
29 | ;
|
---|
30 | ; o 'xcom l <delim><SearchString><delim><SearchOptions>' or
|
---|
31 | ; 'xcom c <delim><SearchString><delim><ChangeString><delim><SearchOptions>'
|
---|
32 | ; can be specified without <delim><SearchOptions>. Then the internal
|
---|
33 | ; default options are used: +FAE.
|
---|
34 | ;
|
---|
35 | ; o Doubled or exclusive options may be specified. The last option wins.
|
---|
36 | ;
|
---|
37 | ; o 'xcom l' and 'xcom c' store their command line in the same internal var.
|
---|
38 | ; It can be queried with getsearch and be set with setsearch. That var is
|
---|
39 | ; empty on EPM's start.
|
---|
40 | ;
|
---|
41 | ; o repeatfind uses the previous search line of 'xcom l' or 'xcom c', but
|
---|
42 | ; always executes 'xcom l'. It can't be used for repeated change.
|
---|
43 |
|
---|
44 |
|
---|
45 | ; Bugs in the original defs, now workarounded:
|
---|
46 | ;
|
---|
47 | ; o Bugs of 'xcom l', 'xcom c' and repeatfind:
|
---|
48 | ; - 'xcom l' and 'xcom c' don't move the cursor, repeatfind does.
|
---|
49 | ; - With option R (reversed search), it also finds the search string at
|
---|
50 | ; the cursor.
|
---|
51 | ; - For search within a mark (option M), the search is restarted from
|
---|
52 | ; the mark begin when the end was reached.
|
---|
53 | ; - For search within a char mark, the entire lines where the mark starts
|
---|
54 | ; and ends are searched, not only the marked area.
|
---|
55 | ; Note that a workaround was added for 'locate'. It does not fully work
|
---|
56 | ; with 'change'. A workaround for 'change all' doesn't seem to be
|
---|
57 | ; possible.
|
---|
58 | ;
|
---|
59 | ; o Bugs of the original 'Locate' = 'l' and 'Change' = 'c' commands:
|
---|
60 | ; - The bugs of 'xcom l', 'xcom c' and repeatfind, except that the
|
---|
61 | ; cursor is moved after 'l' or 'c'.
|
---|
62 | ; - The cursor position after a 'c' was wrong: It was moved by the length
|
---|
63 | ; of the search string, not of the replace string.
|
---|
64 | ;
|
---|
65 | ; o The above bugs are fixed/workarounded by the current 'Locate' = 'l'
|
---|
66 | ; and 'Change' = 'c' commands.
|
---|
67 | ;
|
---|
68 | ; o Without pre- and postprocessing, 'xcom l', 'xcom c' and repeatfind
|
---|
69 | ; should only be used for forward find (locate) searches and not for
|
---|
70 | ; replace (change).
|
---|
71 |
|
---|
72 | ; ---------------------------------------------------------------------------
|
---|
73 |
|
---|
74 | compile if not defined( SMALL) -- If compiled separately
|
---|
75 | EA_comment 'This defines macros for saerch operations.'
|
---|
76 |
|
---|
77 | define
|
---|
78 | INCLUDING_FILE = 'LOCATE.E'
|
---|
79 |
|
---|
80 | include 'stdconst.e'
|
---|
81 | const
|
---|
82 | tryinclude 'mycnf.e'
|
---|
83 | const
|
---|
84 | compile if not defined( NLS_LANGUAGE)
|
---|
85 | NLS_LANGUAGE = 'ENGLISH'
|
---|
86 | compile endif
|
---|
87 | include NLS_LANGUAGE'.e'
|
---|
88 | compile endif
|
---|
89 |
|
---|
90 | ; ---------------------------------------------------------------------------
|
---|
91 | const
|
---|
92 | compile if not defined( LOCATE_CIRCLE_STYLE)
|
---|
93 | --LOCATE_CIRCLE_STYLE = 1 -- changed by aschn
|
---|
94 | LOCATE_CIRCLE_STYLE = 5 -- (1) filled oval
|
---|
95 | compile endif
|
---|
96 | compile if not defined( LOCATE_CIRCLE_COLOR1)
|
---|
97 | --LOCATE_CIRCLE_COLOR1 = 16777220 -- changed by aschn
|
---|
98 | LOCATE_CIRCLE_COLOR1 = 16777231 -- (16777220) complementary
|
---|
99 | compile endif
|
---|
100 | compile if not defined( LOCATE_CIRCLE_COLOR2)
|
---|
101 | -- for styles 2 and 4 only
|
---|
102 | --LOCATE_CIRCLE_COLOR2 = 16777218 -- changed by aschn
|
---|
103 | LOCATE_CIRCLE_COLOR2 = 16777216 -- (16777218) complementary
|
---|
104 | compile endif
|
---|
105 | compile if not defined( HIGHLIGHT_COLOR)
|
---|
106 | HIGHLIGHT_COLOR = 14 -- This must be set to enable circle colors
|
---|
107 | compile endif
|
---|
108 |
|
---|
109 | ; ---------------------------------------------------------------------------
|
---|
110 | defmodify -- This stops the modification dialog for grep output "files" -- JBS
|
---|
111 | if leftstr( .filename, 17) = '.Output from grep' then
|
---|
112 | .modify = 0
|
---|
113 | .autosave = 0
|
---|
114 | endif
|
---|
115 |
|
---|
116 | ; ---------------------------------------------------------------------------
|
---|
117 | ; Preprocessor 1 for Locate and Change. It's called before the search and
|
---|
118 | ; o makes the search options uppercase.
|
---|
119 | ; o removes the M option from the default search options when the current
|
---|
120 | ; file is not marked.
|
---|
121 | ; o combines the default search options with the user search options.
|
---|
122 | ; o removes doubled and exclusive options. (For xcom l, the last option
|
---|
123 | ; wins.)
|
---|
124 | ; Returns: SearchOptions
|
---|
125 | defproc ProcessSearchOptions( UserOptions)
|
---|
126 | universal default_search_options
|
---|
127 | universal searchoptions
|
---|
128 |
|
---|
129 | -- Set DefaultOptions to uppercase
|
---|
130 | DefaultOptions = upcase( default_search_options)
|
---|
131 |
|
---|
132 | -- Switch to All if Mark is default and no text marked, but don't disable
|
---|
133 | -- 'M' from UserOptions to make it work as expected.
|
---|
134 | if not FileIsMarked() then
|
---|
135 | -- Remove 'M' from DefaultOptions
|
---|
136 | do forever
|
---|
137 | pv = verify( DefaultOptions, 'M', 'M') -- 2nd arg is charlist to find
|
---|
138 | if pv = 0 then
|
---|
139 | leave
|
---|
140 | endif
|
---|
141 | DefaultOptions = delstr( DefaultOptions, pv, 1)
|
---|
142 | enddo
|
---|
143 | endif
|
---|
144 |
|
---|
145 | -- Remove 'T', 'B' and 'U' from DefaultOptions if the new option 'U' is
|
---|
146 | -- used. This new option can be added to tell the locate command to remove
|
---|
147 | -- 'T' and 'B'. E.g. the 'All' cmd doesn't work with B' or 'T'.
|
---|
148 | if pos( 'U', upcase( UserOptions)) then -- if 'U' is used
|
---|
149 | -- Remove 'U' from UserOptions
|
---|
150 | do forever
|
---|
151 | pv = verify( upcase( UserOptions), 'U', 'M')
|
---|
152 | if pv = 0 then
|
---|
153 | leave
|
---|
154 | endif
|
---|
155 | UserOptions = delstr( UserOptions, pv, 1)
|
---|
156 | enddo
|
---|
157 | -- Remove 'T' and 'B' from DefaultOptions
|
---|
158 | do forever
|
---|
159 | pv = verify( DefaultOptions, 'TB', 'M')
|
---|
160 | if pv = 0 then
|
---|
161 | leave
|
---|
162 | endif
|
---|
163 | DefaultOptions = delstr( DefaultOptions, pv, 1)
|
---|
164 | enddo
|
---|
165 | endif
|
---|
166 |
|
---|
167 | -- Build SearchOptions. The last option wins.
|
---|
168 | -- Insert default_search_options just before supplied options (if any)
|
---|
169 | -- so the supplied options will take precedence.
|
---|
170 | SearchOptions = upcase( DefaultOptions''UserOptions)
|
---|
171 |
|
---|
172 | -- Append 'N' to give a message how many changes, if 'Q' not specified
|
---|
173 | -- and if all should be changed.
|
---|
174 | if pos( '*', SearchOptions) & -- if e.g. called from SearchDlg
|
---|
175 | not pos( 'Q', SearchOptions) then
|
---|
176 | SearchOptions = SearchOptions'N'
|
---|
177 | endif
|
---|
178 |
|
---|
179 | -- Normalize options string and filter out multiple and excluding options
|
---|
180 | OptionsList = '+- FR BT AM EC GXW ^ * K N D' -- for every word in this list: every char excludes each other
|
---|
181 | -- Other options: '^ * K N D'
|
---|
182 | rest = OptionsList
|
---|
183 | SavedSearchOptions = SearchOptions
|
---|
184 | SearchOptions = ''
|
---|
185 | do w = 1 to words( OptionsList)
|
---|
186 | -- Find CurSearchOption
|
---|
187 | wrd = word( OptionsList, w)
|
---|
188 | restopt = wrd
|
---|
189 | CurSearchOption = ''
|
---|
190 | CurSearchOptionPos = 0
|
---|
191 | do n = 1 to length( restopt)
|
---|
192 | parse value restopt with nextopt 2 restopt -- parse 1 char of restopt
|
---|
193 | -- The last option out of wrd in SavedSearchOptions wins
|
---|
194 | lp = lastpos( nextopt, SavedSearchOptions)
|
---|
195 | if lp > 0 & lp > CurSearchOptionPos then
|
---|
196 | CurSearchOption = nextopt
|
---|
197 | CurSearchOptionPos = lp
|
---|
198 | endif
|
---|
199 | enddo
|
---|
200 | -- Append to SearchOptions
|
---|
201 | SearchOptions = SearchOptions''CurSearchOption
|
---|
202 | enddo
|
---|
203 |
|
---|
204 | return SearchOptions
|
---|
205 |
|
---|
206 | ; ---------------------------------------------------------------------------
|
---|
207 | ; Preprocessor 2 for Locate and Change. It's called before the search and
|
---|
208 | ; o determines if a find-next is executed (when search options, search
|
---|
209 | ; string and file id haven't changed).
|
---|
210 | ; o removes T and B options when a find-next is executed. (Also the Search
|
---|
211 | ; dialog doesn't switch automatically from Top or Bottom to Cursor then.)
|
---|
212 | ; o corrects the cursor position before a search action, when required as a
|
---|
213 | ; workaround for 'xcom l' bugs to avoid finding false strings.
|
---|
214 | ; Returns: SearchOptions
|
---|
215 | ; or -1 if a search can't be processed, due to the cursor position
|
---|
216 | ; and the search direction
|
---|
217 | defproc ProsessSearchPos( SearchOptions, LastSearchOptions,
|
---|
218 | SearchString, LastSearchString,
|
---|
219 | fid, SearchMode, var fFindNext)
|
---|
220 | universal lastsearchpos
|
---|
221 | --dprintf( ' ProcessSearchPos: SearchOptions = 'SearchOptions', LastSearchOptions = 'LastSearchOptions)
|
---|
222 |
|
---|
223 | parse value lastsearchpos with LastLine LastCol LastFid LastSearchLen LastSearchMode LastSearchRc
|
---|
224 | fForeward = lastpos( 'F', SearchOptions) > lastpos( 'R', SearchOptions)
|
---|
225 | fDownward = lastpos( '+', SearchOptions) > lastpos( '-', SearchOptions)
|
---|
226 |
|
---|
227 | fCursorPosChanged = 1
|
---|
228 | do once = 1 to 1
|
---|
229 | if LastLine <> .line then
|
---|
230 | leave
|
---|
231 | elseif LastCol <> .col then
|
---|
232 | leave
|
---|
233 | endif
|
---|
234 | fCursorPosChanged = 0
|
---|
235 | enddo
|
---|
236 |
|
---|
237 | fOnlyDirectionChanged = 0
|
---|
238 | do once = 1 to 1
|
---|
239 | -- Remove FR+-D from LastOpts and NextOpts for comparison
|
---|
240 | -- with LastSearchOptions and SearchOptions
|
---|
241 | LastOpts = LastSearchOptions
|
---|
242 | do forever
|
---|
243 | pv = verify( LastOpts, 'FR+-D', 'M')
|
---|
244 | if pv = 0 then
|
---|
245 | leave
|
---|
246 | endif
|
---|
247 | LastOpts = delstr( LastOpts, pv, 1)
|
---|
248 | enddo
|
---|
249 | NextOpts = SearchOptions
|
---|
250 | do forever
|
---|
251 | pv = verify( NextOpts, 'FR+-D', 'M')
|
---|
252 | if pv = 0 then
|
---|
253 | leave
|
---|
254 | endif
|
---|
255 | NextOpts = delstr( NextOpts, pv, 1)
|
---|
256 | enddo
|
---|
257 |
|
---|
258 | if fid <> LastFid then
|
---|
259 | leave
|
---|
260 | elseif LastSearchString <> SearchString then
|
---|
261 | leave
|
---|
262 | elseif LastSearchOptions <> SearchOptions then
|
---|
263 | if LastOpts = NextOpts then
|
---|
264 | -- This will set fFindNext = 1 and then fMoveCursor = 1
|
---|
265 | fOnlyDirectionChanged = 1
|
---|
266 | else
|
---|
267 | leave
|
---|
268 | endif
|
---|
269 | endif
|
---|
270 | enddo
|
---|
271 |
|
---|
272 | OptsTBRemoved = SearchOptions
|
---|
273 | do forever
|
---|
274 | pv = verify( OptsTBRemoved, 'TB', 'M')
|
---|
275 | if pv = 0 then
|
---|
276 | leave
|
---|
277 | endif
|
---|
278 | OptsTBRemoved = delstr( OptsTBRemoved, pv, 1)
|
---|
279 | enddo
|
---|
280 | LastOptsTBRemoved = LastSearchOptions
|
---|
281 | do forever
|
---|
282 | pv = verify( LastOptsTBRemoved, 'TB', 'M')
|
---|
283 | if pv = 0 then
|
---|
284 | leave
|
---|
285 | endif
|
---|
286 | LastOptsTBRemoved = delstr( LastOptsTBRemoved, pv, 1)
|
---|
287 | enddo
|
---|
288 |
|
---|
289 | fFindNext = 0
|
---|
290 | do once = 1 to 1
|
---|
291 | if fid <> LastFid then
|
---|
292 | leave
|
---|
293 | elseif LastSearchRc <> 0 then
|
---|
294 | leave
|
---|
295 | elseif fCursorPosChanged then
|
---|
296 | leave
|
---|
297 | elseif LastSearchString <> SearchString then
|
---|
298 | leave
|
---|
299 | elseif OptsTBRemoved <> LastOptsTBRemoved & not fOnlyDirectionChanged then
|
---|
300 | leave
|
---|
301 | else
|
---|
302 | fFindNext = 1
|
---|
303 | endif
|
---|
304 | enddo
|
---|
305 |
|
---|
306 | do once = 1 to 1
|
---|
307 | -- Disable further search if the previous search
|
---|
308 | -- with the same fid, SearchString, SearchOptions and SearchPos wasn't
|
---|
309 | -- successfull. This is required for T and B to prevent looping after a
|
---|
310 | -- single search stop at the end.
|
---|
311 | if fid <> LastFid then
|
---|
312 | leave
|
---|
313 | elseif LastSearchString <> SearchString then
|
---|
314 | leave
|
---|
315 | elseif fCursorPosChanged then
|
---|
316 | leave
|
---|
317 | elseif LastSearchRc = 0 then
|
---|
318 | leave
|
---|
319 | elseif fOnlyDirectionChanged then
|
---|
320 | leave
|
---|
321 | --elseif OptsTBRemoved <> LastOptsTBRemoved then
|
---|
322 | elseif SearchOptions <> LastSearchOptions then
|
---|
323 | leave
|
---|
324 | else
|
---|
325 | return -1 -- -1 means: don't search
|
---|
326 | endif
|
---|
327 | enddo
|
---|
328 |
|
---|
329 | -- FindNext: Remove 'T' and 'B' for the search execution (not from LastSearchArgs)
|
---|
330 | FilteredSearchOptions = SearchOptions
|
---|
331 | if fFindNext then
|
---|
332 | --dprintf( ' ProcessSearchPos: Removing T and B')
|
---|
333 | FilteredSearchOptions = OptsTBRemoved
|
---|
334 | endif
|
---|
335 |
|
---|
336 | -- FindNext or backward: Move cursor first to not find the just found string again
|
---|
337 | fMoveCursor = 0
|
---|
338 | do once = 1 to 1
|
---|
339 |
|
---|
340 | -- Change should process the string at cursor. The cursor pos may result
|
---|
341 | -- from a previous locate.
|
---|
342 | -- If there is no string to change at the cursor, it processes the next
|
---|
343 | -- string. For that no cursor move is required.
|
---|
344 | if LastSearchMode = 'l' & SearchMode = 'c' then
|
---|
345 | --dprintf( ' ProcessSearchPos: Search mode: l -> c ==> leave')
|
---|
346 | leave
|
---|
347 |
|
---|
348 | -- If the cursor was moved manually after the last search, don't move it
|
---|
349 | -- before the next search.
|
---|
350 | elseif fCursorPosChanged then
|
---|
351 | leave
|
---|
352 |
|
---|
353 | -- FindNext requires to move the cursor first, before the next search.
|
---|
354 | -- Reverse search requires to move the cursor first, before the next search.
|
---|
355 | -- Bug in xcom l: reverse search finds also string right of cursor
|
---|
356 | -- Move cursor to not find the just found string again
|
---|
357 | elseif not fFindNext & fForeward then
|
---|
358 | leave
|
---|
359 | endif
|
---|
360 |
|
---|
361 | fMoveCursor = 1
|
---|
362 | enddo
|
---|
363 | --dprintf( ' ProcessSearchPos: fCursorPosChanged = 'fCursorPosChanged', fOnlyDirectionChanged = 'fOnlyDirectionChanged', fMoveCursor = 'fMoveCursor', fFindNext = 'fFindNext)
|
---|
364 |
|
---|
365 | fSearch = 1
|
---|
366 | -- Move cursor to not find the string at cursor (again)
|
---|
367 | if fMoveCursor then
|
---|
368 | if LastSearchLen = '' then
|
---|
369 | LastSearchLen = 0
|
---|
370 | endif
|
---|
371 | if fForeward then -- must be a FindNext
|
---|
372 | -- Foreward
|
---|
373 | if fOnlyDirectionChanged & fFindNext & LastSearchRc <> 0 then
|
---|
374 | next = .col
|
---|
375 | else
|
---|
376 | -- Foreward: move amount of LastSearchLen right
|
---|
377 | next = .col + LastSearchLen
|
---|
378 | endif
|
---|
379 | if next >= length( textline( .line)) + 1 then
|
---|
380 | if fDownward then
|
---|
381 | if .line < .last then
|
---|
382 | down
|
---|
383 | .col = 1
|
---|
384 | else
|
---|
385 | fSearch = 0 -- can't move down at the bottom
|
---|
386 | endif
|
---|
387 | else
|
---|
388 | if .line > 1 then
|
---|
389 | up
|
---|
390 | .col = 1
|
---|
391 | else
|
---|
392 | fSearch = 0 -- can't move up at the top
|
---|
393 | endif
|
---|
394 | endif
|
---|
395 | else
|
---|
396 | .col = next
|
---|
397 | endif
|
---|
398 | else
|
---|
399 | -- Backward: move 1 char left
|
---|
400 | next = .col - 1
|
---|
401 | if next < 1 then
|
---|
402 | if fDownward then
|
---|
403 | if .line < .last then
|
---|
404 | down
|
---|
405 | end_line
|
---|
406 | else
|
---|
407 | fSearch = 0 -- can't move down at the bottom
|
---|
408 | endif
|
---|
409 | else
|
---|
410 | if .line > 1 then
|
---|
411 | up
|
---|
412 | end_line
|
---|
413 | else
|
---|
414 | fSearch = 0 -- can't move up at the top
|
---|
415 | endif
|
---|
416 | endif
|
---|
417 | else
|
---|
418 | .col = next
|
---|
419 | endif
|
---|
420 | endif
|
---|
421 | endif
|
---|
422 |
|
---|
423 | -- Check if cursor is after or before the mark
|
---|
424 | getmark markfirstline, marklastline, markfirstcol, marklastcol, markfid
|
---|
425 | if pos( 'M', upcase( SearchOptions)) then
|
---|
426 | if fDownward then
|
---|
427 | if not pos( 'T', upcase( SearchOptions)) then
|
---|
428 | if .line > marklastline then
|
---|
429 | fSearch = 0
|
---|
430 | endif
|
---|
431 | endif
|
---|
432 | else
|
---|
433 | if not pos( 'B', upcase( SearchOptions)) then
|
---|
434 | if .line < markfirstline then
|
---|
435 | fSearch = 0
|
---|
436 | endif
|
---|
437 | endif
|
---|
438 | endif
|
---|
439 | if fForeward then
|
---|
440 | if not pos( 'T', upcase( SearchOptions)) then
|
---|
441 | if .line = marklastline then
|
---|
442 | if .col > marklastcol then
|
---|
443 | fSearch = 0
|
---|
444 | endif
|
---|
445 | endif
|
---|
446 | endif
|
---|
447 | else
|
---|
448 | if not pos( 'B', upcase( SearchOptions)) then
|
---|
449 | if .line = markfirstline then
|
---|
450 | if .col < markfirstcol then
|
---|
451 | fSearch = 0
|
---|
452 | endif
|
---|
453 | endif
|
---|
454 | endif
|
---|
455 | endif
|
---|
456 | endif
|
---|
457 |
|
---|
458 | if not fSearch then
|
---|
459 | return -1
|
---|
460 | else
|
---|
461 | return FilteredSearchOptions
|
---|
462 | endif
|
---|
463 |
|
---|
464 | ; ---------------------------------------------------------------------------
|
---|
465 | ; Preprocessor 3 for Locate and Change. It's called after a successfull
|
---|
466 | ; search within a mark and
|
---|
467 | ; o recognizes if a search within a mark is restarted (and should rather be
|
---|
468 | ; stopped)
|
---|
469 | ; o checks if found string is completely within the mark (required for
|
---|
470 | ; char mark only)
|
---|
471 | ; Returns: rc = -273 if search has restarted
|
---|
472 | ; -280 if found string is not completely within the mark
|
---|
473 | ; 0 otherwise
|
---|
474 | defproc ProsessSearchMark( SearchOptions, LastSearchOptions,
|
---|
475 | SearchString, LastSearchString,
|
---|
476 | fFindNext)
|
---|
477 | universal lastsearchpos
|
---|
478 |
|
---|
479 | -- Search in mark: disable search restart when at end
|
---|
480 | -- Bug in any mark search: At the end of the mark the search loops to
|
---|
481 | -- the begin of the mark. Mark search won't stop at the mark end.
|
---|
482 | parse value lastsearchpos with LastLine LastCol LastFid LastSearchLen LastSearchMode LastSearchRc
|
---|
483 | fForeward = lastpos( 'F', SearchOptions) > lastpos( 'R', SearchOptions)
|
---|
484 | fDownward = lastpos( '+', SearchOptions) > lastpos( '-', SearchOptions)
|
---|
485 |
|
---|
486 | fRestarted = 0
|
---|
487 | if fFindNext then
|
---|
488 | if fDownward then
|
---|
489 | if .line < LastLine then
|
---|
490 | fRestarted = 1
|
---|
491 | endif
|
---|
492 | else
|
---|
493 | if .line > LastLine then
|
---|
494 | fRestarted = 1
|
---|
495 | endif
|
---|
496 | endif
|
---|
497 | if .line = LastLine then
|
---|
498 | if fForeward then
|
---|
499 | if .col < LastCol then
|
---|
500 | fRestarted = 1
|
---|
501 | endif
|
---|
502 | else
|
---|
503 | if .col > LastCol then
|
---|
504 | fRestarted = 1
|
---|
505 | endif
|
---|
506 | endif
|
---|
507 | endif
|
---|
508 | endif
|
---|
509 |
|
---|
510 | -- Search in char mark: repeat search if found string is not full in mark
|
---|
511 | -- Bug for char mark search: The first and last marked lines were completely
|
---|
512 | -- searched, like for a line mark.
|
---|
513 | fRepeat = 0
|
---|
514 | markt = marktype()
|
---|
515 | if markt = 'CHAR' then
|
---|
516 | SearchStringLen = getpminfo( EPMINFO_LSLENGTH)
|
---|
517 | if not InMark( .line, .col, SearchStringLen) then
|
---|
518 | fRepeat = 1
|
---|
519 | endif
|
---|
520 | endif
|
---|
521 |
|
---|
522 | if fRestarted then
|
---|
523 | return -273 -- String not found
|
---|
524 | elseif fRepeat then
|
---|
525 | return -280 -- Text not marked
|
---|
526 | else
|
---|
527 | return 0
|
---|
528 | endif
|
---|
529 |
|
---|
530 | ; ---------------------------------------------------------------------------
|
---|
531 | ; LastSearchArgs and LastChangeArgs are no longer universals. To make them
|
---|
532 | ; global across all EPM windows, they are saved in NEPMD.INI only.
|
---|
533 | ; ---------------------------------------------------------------------------
|
---|
534 | defproc GetLastSearchArgs
|
---|
535 | KeyPath = '\NEPMD\Var\Search\LastSearchArgs'
|
---|
536 | LastSearchArgs = QueryConfigKey( KeyPath)
|
---|
537 | --dprintf( 'GetLastSearchArgs: LastSearchArgs = 'LastSearchArgs)
|
---|
538 | return LastSearchArgs
|
---|
539 |
|
---|
540 | ; ---------------------------------------------------------------------------
|
---|
541 | defproc GetLastChangeArgs
|
---|
542 | KeyPath = '\NEPMD\Var\Search\LastChangeArgs'
|
---|
543 | LastChangeArgs = QueryConfigKey( KeyPath)
|
---|
544 | return LastChangeArgs
|
---|
545 |
|
---|
546 | ; ---------------------------------------------------------------------------
|
---|
547 | defproc GetLastSearchDialogOptions
|
---|
548 | KeyPath = '\NEPMD\Var\Search\LastSearchDialogOptions'
|
---|
549 | LastSearchDialogOptions = QueryConfigKey( KeyPath)
|
---|
550 | --dprintf( 'GetLastSearchDialogOptions: LastSearchDialogOptions = 'LastSearchDialogOptions)
|
---|
551 | return LastSearchDialogOptions
|
---|
552 |
|
---|
553 | ; ---------------------------------------------------------------------------
|
---|
554 | defproc SetLastSearchArgs
|
---|
555 | KeyPath = '\NEPMD\Var\Search\LastSearchArgs'
|
---|
556 | LastSearchArgs = arg( 1)
|
---|
557 | call WriteConfigKey( KeyPath, LastSearchArgs)
|
---|
558 | --dprintf( 'SetLastSearchArgs: LastSearchArgs = 'LastSearchArgs)
|
---|
559 | return
|
---|
560 |
|
---|
561 | ; ---------------------------------------------------------------------------
|
---|
562 | defproc SetLastChangeArgs
|
---|
563 | KeyPath = '\NEPMD\Var\Search\LastChangeArgs'
|
---|
564 | LastChangeArgs = arg( 1)
|
---|
565 | call WriteConfigKey( KeyPath, LastChangeArgs)
|
---|
566 | return
|
---|
567 |
|
---|
568 | ; ---------------------------------------------------------------------------
|
---|
569 | defproc SetLastSearchDialogOptions
|
---|
570 | KeyPath = '\NEPMD\Var\Search\LastSearchDialogOptions'
|
---|
571 | LastSearchDialogOptions = arg( 1)
|
---|
572 | call WriteConfigKey( KeyPath, LastSearchDialogOptions)
|
---|
573 | --dprintf( 'SetLastSearchDialogOptions: LastSearchDialogOptions = 'LastSearchDialogOptions)
|
---|
574 | return
|
---|
575 |
|
---|
576 | ; ---------------------------------------------------------------------------
|
---|
577 | defproc GetAddSearchChangeOptions
|
---|
578 | KeyPath = '\NEPMD\Var\Search\AddSearchChangeOptions'
|
---|
579 | AddSearchChangeOptions = QueryConfigKey( KeyPath)
|
---|
580 | return AddSearchChangeOptions
|
---|
581 |
|
---|
582 | ; ---------------------------------------------------------------------------
|
---|
583 | defproc SetAddSearchChangeOptions
|
---|
584 | KeyPath = '\NEPMD\Var\Search\AddSearchChangeOptions'
|
---|
585 | AddSearchChangeOptions = arg( 1)
|
---|
586 | call WriteConfigKey( KeyPath, AddSearchChangeOptions)
|
---|
587 | return
|
---|
588 |
|
---|
589 | ; ---------------------------------------------------------------------------
|
---|
590 | ; Syntax: locate !<SearchString>[!<UserOptions>]
|
---|
591 | ; The first char will be taken as delimitter, in this case '!'.
|
---|
592 | ;
|
---|
593 | ; New: Without args, a FindNext will be executed.
|
---|
594 | ;
|
---|
595 | ; Added a new search option: 'U'. This will replace any occurance of
|
---|
596 | ; 'T' and 'B' in default_search_options for this locate command.
|
---|
597 | ;
|
---|
598 | ; Note: this DEFC also gets executed by the slash ('/') command and by the
|
---|
599 | ; search dialog. The search dialog adds option 'D'.
|
---|
600 | defc RepeatFind, L, Locate
|
---|
601 | universal default_search_options
|
---|
602 | universal lastsearchpos
|
---|
603 |
|
---|
604 | sayerror 0 -- delete previous message from messageline
|
---|
605 | LastSearchArgs = GetLastSearchArgs()
|
---|
606 | LastChangeArgs = GetLastChangeArgs()
|
---|
607 | LastSearchDialogOptions = GetLastSearchDialogOptions()
|
---|
608 |
|
---|
609 | args = strip( arg( 1), 'L')
|
---|
610 | --dprintf( overlay( ' Locate ', copies( '-', 60), 4))
|
---|
611 |
|
---|
612 | -- Filter out 'D' arg from search dialog for RepeatFind
|
---|
613 | fDialogRepeat = 0
|
---|
614 | if args = \1\1\1\1'D' then
|
---|
615 | fDialogRepeat = 1
|
---|
616 | args = ''
|
---|
617 | endif
|
---|
618 |
|
---|
619 | -- Handle RepeatFind
|
---|
620 | if args = '' then -- If no args, query args
|
---|
621 | SearchArgs = LastSearchArgs
|
---|
622 |
|
---|
623 | tmpdelim = substr( SearchArgs, 1, 1) -- get 1st delimiter
|
---|
624 | parse value SearchArgs with (tmpdelim)SearchString(tmpdelim)SearchOptions
|
---|
625 | next = SearchOptions
|
---|
626 |
|
---|
627 | -- Ensure that option D is removed if not coming from the search dialog
|
---|
628 | if not fDialogRepeat then
|
---|
629 | do forever
|
---|
630 | Dpos = pos( 'D', next)
|
---|
631 | if Dpos = 0 then
|
---|
632 | leave
|
---|
633 | endif
|
---|
634 | next = delstr( next, Dpos, 1)
|
---|
635 | enddo
|
---|
636 | endif
|
---|
637 | -- Ensure that last options from the dialog are used, not from elsewhere
|
---|
638 | if fDialogRepeat then
|
---|
639 | next = LastSearchDialogOptions
|
---|
640 | endif
|
---|
641 |
|
---|
642 | -- Rebuild SearchArgs
|
---|
643 | SearchOptions = next
|
---|
644 | SearchArgs = tmpdelim''SearchString''tmpdelim''SearchOptions
|
---|
645 |
|
---|
646 | args = SearchArgs
|
---|
647 | -- Process the parsing of args again to recognize a possible change of
|
---|
648 | -- default_search_options in the meantime.
|
---|
649 | endif
|
---|
650 |
|
---|
651 | delim = substr( args, 1, 1) -- get 1st delimiter
|
---|
652 | parse value args with (delim)SearchString(delim)UserOptions
|
---|
653 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
654 |
|
---|
655 | AddSearchChangeOptions = GetAddSearchChangeOptions()
|
---|
656 | if AddSearchChangeOptions <> '' then
|
---|
657 | -- Append options for a direction change. The last option wins.
|
---|
658 | UserOptions = UserOptions''AddSearchChangeOptions
|
---|
659 | --dprintf( 'Appending AddSearchChangeOptions = 'AddSearchChangeOptions)
|
---|
660 | -- Reset after appliance
|
---|
661 | SetAddSearchChangeOptions( '')
|
---|
662 | endif
|
---|
663 |
|
---|
664 | tmpdelim = substr( LastSearchArgs, 1, 1) -- get 1st delimiter
|
---|
665 | parse value LastSearchArgs with (tmpdelim)LastSearchString(tmpdelim)LastSearchOptions
|
---|
666 |
|
---|
667 | -- The current SearchString is compared with that of LastChangeArgs.
|
---|
668 | -- If another string was specified, then LastChangeArgs is reset to ''.
|
---|
669 | tmpdelim = substr( LastChangeArgs, 1, 1) -- get 1st delimiter
|
---|
670 | parse value LastChangeArgs with (tmpdelim)cSearchString(tmpdelim)cReplaceString(tmpdelim)cSearchOptions
|
---|
671 |
|
---|
672 | getfileid fid
|
---|
673 |
|
---|
674 | -- Prepend default options and normalize search options
|
---|
675 | SearchOptions = ProcessSearchOptions( UserOptions)
|
---|
676 |
|
---|
677 | -- Build list of search args with options, last option wins.
|
---|
678 | -- Save the universal var here. Later ProsessSearchPos changes
|
---|
679 | -- SearchOptions if required.
|
---|
680 | SearchArgs = delim''SearchString''delim''SearchOptions
|
---|
681 | --dprintf( '--- SearchArgs = 'SearchArgs', arg( 1) = 'arg( 1)', fDialogRepeat = 'fDialogRepeat)
|
---|
682 | --dprintf( 'LastSearchArgs = 'LastSearchArgs', LastSearchDialogOptions = 'LastSearchDialogOptions)
|
---|
683 |
|
---|
684 | parse value lastsearchpos with LastLine LastCol LastFid LastSearchLen LastSearchMode LastSearchRc
|
---|
685 |
|
---|
686 | SearchMode = 'l'
|
---|
687 |
|
---|
688 | --dprintf( 'Before ProsessSearchPos: SearchOptions = 'SearchOptions', LastSearchOptions = 'LastSearchOptions)
|
---|
689 | -- Maybe move cursor and remove T and B search options for a FindNext
|
---|
690 | fFindNext = 0
|
---|
691 | FilteredSearchOptions = ProsessSearchPos( SearchOptions, LastSearchOptions,
|
---|
692 | SearchString, LastSearchString,
|
---|
693 | fid, SearchMode,
|
---|
694 | fFindNext) -- fFindNext is set
|
---|
695 | --dprintf( 'After ProsessSearchPos: FilteredSearchOptions = 'FilteredSearchOptions', LastSearchOptions = 'LastSearchOptions)
|
---|
696 | fSearch = 1
|
---|
697 | if FilteredSearchOptions = -1 then
|
---|
698 | -- Omit search at the top or at the bottom
|
---|
699 | fSearch = 0
|
---|
700 | else
|
---|
701 | -- SearchOptions may be changed by ProcessSearchPos
|
---|
702 | SearchArgs = delim''SearchString''delim''SearchOptions
|
---|
703 | FilteredSearchArgs = delim''SearchString''delim''FilteredSearchOptions
|
---|
704 | endif
|
---|
705 |
|
---|
706 | -- Save last and cur args
|
---|
707 | call SetLastSearchArgs( SearchArgs)
|
---|
708 | if pos( 'D', SearchOptions) then
|
---|
709 | call SetLastSearchDialogOptions( SearchOptions)
|
---|
710 | endif
|
---|
711 |
|
---|
712 | if SearchString = cSearchString then
|
---|
713 | -- Reset the SearchOptions in LastChangeArgs for the next Change while
|
---|
714 | -- keeping the previous ReplaceString.
|
---|
715 | --dprintf( 'Change LastChangeArgs to use the options from Locate')
|
---|
716 | ChangeArgs = delim''cSearchString''delim''cReplaceString''delim''SearchOptions
|
---|
717 | call SetLastChangeArgs( ChangeArgs)
|
---|
718 | else
|
---|
719 | -- Reset LastChangeArgs when a new search string was specified.
|
---|
720 | call SetLastChangeArgs( '')
|
---|
721 | endif
|
---|
722 |
|
---|
723 | -- Pos from before the search
|
---|
724 | call pSave_Pos( savedpos)
|
---|
725 | fRestorePos = 1
|
---|
726 |
|
---|
727 | lrc = -273 -- String not found
|
---|
728 | if fSearch then
|
---|
729 | display -8 -- suppress writing to MsgBox
|
---|
730 | 'xcom l 'FilteredSearchArgs
|
---|
731 | lrc = rc
|
---|
732 | call pSave_Pos( lpos)
|
---|
733 | display 8
|
---|
734 | endif
|
---|
735 | SetAddSearchChangeOptions( '')
|
---|
736 |
|
---|
737 | fRepeat = 0
|
---|
738 | if fSearch & lrc = 0 & pos( 'M', SearchOptions) > 0 then
|
---|
739 | -- Check if found string is fully marked (if not: rc = -280) and
|
---|
740 | -- if Search is not looping within the mark (if: rc = -273)
|
---|
741 | SearchMarkRc = ProsessSearchMark( FilteredSearchOptions, LastSearchOptions,
|
---|
742 | SearchString, LastSearchString,
|
---|
743 | fFindNext)
|
---|
744 | if SearchMarkRc = -273 then -- String not found
|
---|
745 | lrc = SearchMarkRc
|
---|
746 | fRepeat = 0
|
---|
747 | fRestorePos = 1
|
---|
748 | fSearch = 0
|
---|
749 | elseif SearchMarkRc = -280 then -- Text not marked
|
---|
750 | lrc = SearchMarkRc
|
---|
751 | fRepeat = 1
|
---|
752 | endif
|
---|
753 | endif
|
---|
754 |
|
---|
755 | if not fRepeat then
|
---|
756 | -- Give error message if search was omitted
|
---|
757 | if not fSearch then
|
---|
758 | display -8 -- suppress writing to MsgBox
|
---|
759 | sayerror sayerrortext( lrc) -- The same as: 'SayError -273'
|
---|
760 | display 8
|
---|
761 | endif
|
---|
762 |
|
---|
763 | -- Highlight it and maybe scroll to cursor pos
|
---|
764 | if lrc = 0 then
|
---|
765 | fRestorePos = 0
|
---|
766 | -- Cursor position here must be that from before the search (savedpos)
|
---|
767 | call ScrollAfterLocate( savedpos, lpos)
|
---|
768 | -- SearchLen will be queried by getpminfo( EPMINFO_LSLENGTH)
|
---|
769 | call Highlight_Match()
|
---|
770 | endif
|
---|
771 |
|
---|
772 | if fRestorePos then
|
---|
773 | call pRestore_Pos( savedpos)
|
---|
774 | .line = .line -- maybe scroll to ensure that cursor is visible
|
---|
775 | 'HighlightCursor'
|
---|
776 | endif
|
---|
777 | endif
|
---|
778 |
|
---|
779 | -- Save last searched pos, file, len, search mode and rc
|
---|
780 | -- For a repeated search, the start pos. will be moved by len to avoid
|
---|
781 | -- finding the same string multiple times.
|
---|
782 | -- GetPmInfo queries the length right, also for the grep or egrep search.
|
---|
783 | len = getpminfo( EPMINFO_LSLENGTH)
|
---|
784 | --dprintf( 'len = 'len', linelen = 'length( textline( .line))', xcom l 'SearchArgs)
|
---|
785 | if (len = 0 | len = '') & (lrc = 0 | fRepeat) then
|
---|
786 | len = length( SearchString)
|
---|
787 | endif
|
---|
788 | thissearchpos = .line .col fid len SearchMode lrc
|
---|
789 | --dprintf( 'thissearchpos = 'thissearchpos', lastsearchpos = 'lastsearchpos)
|
---|
790 | lastsearchpos = thissearchpos
|
---|
791 |
|
---|
792 | rc = lrc -- does hightlight_match change rc?
|
---|
793 |
|
---|
794 | if fRepeat then
|
---|
795 | -- Replace the centered scroll pos of 'xcom l'.
|
---|
796 | -- Cursor position here must be that from before the search (savedpos)
|
---|
797 | call ScrollAfterLocate( savedpos, lpos)
|
---|
798 |
|
---|
799 | -- The position must be advanced before the next search.
|
---|
800 | -- RepeatFind does that by checking lastsearchpos in ProsessSearchPos.
|
---|
801 | 'RepeatFind'
|
---|
802 | endif
|
---|
803 |
|
---|
804 | ; ---------------------------------------------------------------------------
|
---|
805 | defc RepeatChange, C, Change
|
---|
806 | universal default_search_options
|
---|
807 | universal lastsearchpos
|
---|
808 | universal stay -- if 1, then restore pos even after a successful change
|
---|
809 |
|
---|
810 | sayerror 0 -- delete previous message from messageline
|
---|
811 | LastSearchArgs = GetLastSearchArgs()
|
---|
812 | LastChangeArgs = GetLastChangeArgs()
|
---|
813 | LastSearchDialogOptions = GetLastSearchDialogOptions()
|
---|
814 |
|
---|
815 | args = strip( arg( 1), 'L')
|
---|
816 | --dprintf( overlay( ' Change ', copies( '-', 60), 4))
|
---|
817 |
|
---|
818 | -- Filter out 'D' arg from search dialog for RepeatChange
|
---|
819 | fDialogRepeat = 0
|
---|
820 | if args = \1\1\1\1'D' then
|
---|
821 | fDialogRepeat = 1
|
---|
822 | args = ''
|
---|
823 | endif
|
---|
824 |
|
---|
825 | -- Handle RepeatChange
|
---|
826 | if args = '' then -- If no args, query lastchangeargs
|
---|
827 | ChangeArgs = LastChangeArgs
|
---|
828 |
|
---|
829 | tmpdelim = substr( ChangeArgs, 1, 1) -- get 1st delimiter
|
---|
830 | parse value ChangeArgs with (tmpdelim)SearchString(tmpdelim)ReplaceString(tmpdelim)SearchOptions
|
---|
831 | next = SearchOptions
|
---|
832 |
|
---|
833 | -- Ensure that option D is removed if not coming from the search dialog
|
---|
834 | if not fDialogRepeat then
|
---|
835 | do forever
|
---|
836 | Dpos = pos( 'D', next)
|
---|
837 | if Dpos = 0 then
|
---|
838 | leave
|
---|
839 | endif
|
---|
840 | next = delstr( next, Dpos, 1)
|
---|
841 | enddo
|
---|
842 | endif
|
---|
843 | -- Ensure that last options from the dialog are used, not from elsewhere
|
---|
844 | if fDialogRepeat then
|
---|
845 | next = LastSearchDialogOptions
|
---|
846 | endif
|
---|
847 |
|
---|
848 | -- Rebuild LastChangeArgs
|
---|
849 | SearchOptions = next
|
---|
850 | ChangeArgs = tmpdelim''SearchString''tmpdelim''ReplaceString''tmpdelim''SearchOptions
|
---|
851 |
|
---|
852 | args = ChangeArgs
|
---|
853 | -- Process the parsing of args again to recognize a possible change of
|
---|
854 | -- default_search_options in the meantime.
|
---|
855 | endif
|
---|
856 |
|
---|
857 | delim = substr( args, 1, 1) -- get 1st delimiter
|
---|
858 | p2 = pos( delim, args, 2) -- check 2nd delimiter of 2 or 3
|
---|
859 | if not p2 then
|
---|
860 | sayerror NO_REP__MSG -- 'No replacement string specified' (Rather the missing delimiter is checked.)
|
---|
861 | -- A defc must use "return myrc" or use "rc = myrc" to set the
|
---|
862 | -- global var rc. When "return" is used only, rc would be set to empty.
|
---|
863 | -- Another option is to omit return for a defc. Then rc will be kept as well.
|
---|
864 | -- A defproc may return its own rcx, without overriding the global rc.
|
---|
865 | rc = -257 -- Invalid number of parameters
|
---|
866 | return rc
|
---|
867 | endif
|
---|
868 | parse value args with (delim)SearchString(delim)ReplaceString(delim)UserOptions
|
---|
869 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
870 |
|
---|
871 | AddSearchChangeOptions = GetAddSearchChangeOptions()
|
---|
872 | if AddSearchChangeOptions <> '' then
|
---|
873 | -- Append options for a direction change. The last option wins.
|
---|
874 | UserOptions = UserOptions''AddSearchChangeOptions
|
---|
875 | --dprintf( 'Appending AddSearchChangeOptions = 'AddSearchChangeOptions)
|
---|
876 | -- Reset after appliance
|
---|
877 | SetAddSearchChangeOptions( '')
|
---|
878 | endif
|
---|
879 |
|
---|
880 | tmpdelim = substr( LastSearchArgs, 1, 1) -- get 1st delimiter
|
---|
881 | parse value LastSearchArgs with (tmpdelim)LastSearchString(tmpdelim)LastSearchOptions
|
---|
882 |
|
---|
883 | -- If LastChangeArgs was reset by the last search ...
|
---|
884 | if LastChangeArgs = '' then
|
---|
885 | -- ... get args from last search, not from last change
|
---|
886 | LastChangeArgs = delim''LastSearchString''delim''ReplaceString''delim''LastSearchOptions
|
---|
887 | endif
|
---|
888 | tmpdelim = substr( LastChangeArgs, 1, 1) -- get 1st delimiter
|
---|
889 | parse value LastChangeArgs with (tmpdelim)LastSearchString(tmpdelim)LastReplaceString(tmpdelim)LastSearchOptions
|
---|
890 |
|
---|
891 | getfileid fid
|
---|
892 |
|
---|
893 | -- Prepend default options and normalize search options
|
---|
894 | SearchOptions = ProcessSearchOptions( UserOptions)
|
---|
895 |
|
---|
896 | -- Build list of change args with options, last option wins.
|
---|
897 | -- Save the universal var here. Later ProsessSearchPos changes
|
---|
898 | -- SearchOptions if required.
|
---|
899 | ChangeArgs = delim''SearchString''delim''ReplaceString''delim''SearchOptions
|
---|
900 | -- Set LastSearchArgs as well, to use first Ctrl+F and then Ctrl+C for to
|
---|
901 | -- operate on the same SearchString. Even a ChangeNext should synchronize it.
|
---|
902 | SearchArgs = delim''SearchString''delim''SearchOptions
|
---|
903 | --dprintf( '--- ChangeArgs = 'ChangeArgs', arg( 1) = 'arg( 1)', fDialogRepeat = 'fDialogRepeat)
|
---|
904 | --dprintf( '--- SearchArgs = 'SearchArgs', arg( 1) = 'arg( 1))
|
---|
905 | --dprintf( 'LastChangeArgs = 'LastChangeArgs', LastSearchArgs = 'LastSearchArgs', LastSearchDialogOptions = 'LastSearchDialogOptions)
|
---|
906 |
|
---|
907 | -- Save last args
|
---|
908 | call SetLastChangeArgs( ChangeArgs)
|
---|
909 | call SetLastSearchArgs( SearchArgs)
|
---|
910 | if pos( 'D', SearchOptions) then
|
---|
911 | call SetLastSearchDialogOptions( SearchOptions)
|
---|
912 | endif
|
---|
913 |
|
---|
914 | SearchMode = 'c'
|
---|
915 |
|
---|
916 | --dprintf( 'Before ProsessSearchPos: SearchOptions = 'SearchOptions', LastSearchOptions = 'LastSearchOptions)
|
---|
917 | -- Maybe move cursor and remove T and B search options for a FindNext
|
---|
918 | fFindNext = 0
|
---|
919 | FilteredSearchOptions = ProsessSearchPos( SearchOptions, LastSearchOptions,
|
---|
920 | SearchString, LastSearchString,
|
---|
921 | fid, SearchMode,
|
---|
922 | fFindNext) -- fFindNext is set
|
---|
923 | --dprintf( 'After ProsessSearchPos: FilteredSearchOptions = 'FilteredSearchOptions', LastSearchOptions = 'LastSearchOptions)
|
---|
924 |
|
---|
925 | fSearch = 1
|
---|
926 | if FilteredSearchOptions = -1 then -- never true for 'change'
|
---|
927 | -- Omit search at the top or at the bottom
|
---|
928 | fSearch = 0
|
---|
929 | else
|
---|
930 | -- SearchOptions may be changed by ProsessSearchPos
|
---|
931 | FilteredChangeArgs = delim''SearchString''delim''ReplaceString''delim''FilteredSearchOptions
|
---|
932 | endif
|
---|
933 |
|
---|
934 | -- Pos from before the search
|
---|
935 | call pSave_Pos( savedpos)
|
---|
936 | fRestorePos = 1
|
---|
937 |
|
---|
938 | OldLineLen = 0
|
---|
939 | NewLineLen = 0
|
---|
940 | if fSearch then
|
---|
941 | if pos( 'G', SearchOptions) > 0 | pos( 'X', SearchOptions) > 0 then
|
---|
942 | -- For grep and egrep searches only:
|
---|
943 | -- Also build SearchArgs for finding the same line where Change will process
|
---|
944 | -- next. This allows for querying the line length before the change and
|
---|
945 | -- for calculating the change length.
|
---|
946 | TmpSearchArgs = delim''SearchString''delim''FilteredSearchOptions
|
---|
947 | display -8
|
---|
948 | 'xcom l 'TmpSearchArgs
|
---|
949 | if rc = 0 then
|
---|
950 | OldLineLen = length( textline( .line))
|
---|
951 | --dprintf( 'OldLineLen = 'OldLineLen', .line = '.line)
|
---|
952 | endif
|
---|
953 | call pRestore_Pos( savedpos)
|
---|
954 | display 8
|
---|
955 | endif
|
---|
956 | endif
|
---|
957 |
|
---|
958 | lrc = -273 -- String not found
|
---|
959 | if fSearch then
|
---|
960 | call NextCmdAltersText()
|
---|
961 | display -8
|
---|
962 | 'xcom c 'FilteredChangeArgs
|
---|
963 | lrc = rc
|
---|
964 | NewLineLen = length( textline( .line))
|
---|
965 | call pSave_Pos( lpos)
|
---|
966 | display 8
|
---|
967 | endif
|
---|
968 | SetAddSearchChangeOptions( '')
|
---|
969 |
|
---|
970 | fRepeat = 0
|
---|
971 | if fSearch & lrc = 0 & pos( 'M', SearchOptions) > 0 then
|
---|
972 | -- Check if found string is fully marked (if not: rc = -280) and
|
---|
973 | -- if Search is not looping within the mark (if: rc = -273)
|
---|
974 | SearchMarkRc = ProsessSearchMark( SearchOptions, LastSearchOptions,
|
---|
975 | SearchString, LastSearchString,
|
---|
976 | fFindNext)
|
---|
977 | if SearchMarkRc = -273 then -- String not found
|
---|
978 | lrc = SearchMarkRc
|
---|
979 | fRepeat = 0
|
---|
980 | fRestorePos = 1
|
---|
981 | fSearch = 0
|
---|
982 | elseif SearchMarkRc = -280 then -- Text not marked
|
---|
983 | lrc = SearchMarkRc
|
---|
984 | fRepeat = 1
|
---|
985 | endif
|
---|
986 | endif
|
---|
987 |
|
---|
988 | -- Save last searched pos, file, len, search mode and rc
|
---|
989 | -- For a repeated search, the start pos. will be moved by len to avoid
|
---|
990 | -- finding the same string multiple times.
|
---|
991 | -- GetPmInfo queries the length right, also for the grep or egrep search.
|
---|
992 | -- SearchLen can be queried for a Search action by getpminfo( EPMINFO_LSLENGTH).
|
---|
993 | -- But getpminfo( EPMINFO_LSLENGTH) gives the value for the search string,
|
---|
994 | -- not for the change string.
|
---|
995 | -- While for a non-grep search the length of the replacement string
|
---|
996 | -- is known, it has to be calculated with the line length from before
|
---|
997 | -- the change for a grep search.
|
---|
998 | if pos( 'G', SearchOptions) > 0 | pos( 'X', SearchOptions) > 0 then
|
---|
999 | OldLen = getpminfo( EPMINFO_LSLENGTH)
|
---|
1000 | if OldLen = '' then
|
---|
1001 | OldLen = 0
|
---|
1002 | endif
|
---|
1003 | NewLen = OldLen - OldLineLen + NewLineLen
|
---|
1004 | --dprintf( 'NewLen = 'NewLen)
|
---|
1005 | ReplaceLen = NewLen
|
---|
1006 | else
|
---|
1007 | ReplaceLen = length( ReplaceString)
|
---|
1008 | endif
|
---|
1009 | thissearchpos = .line .col fid ReplaceLen SearchMode lrc
|
---|
1010 | --dprintf( 'thissearchpos = 'thissearchpos', lastsearchpos = 'lastsearchpos)
|
---|
1011 | lastsearchpos = thissearchpos
|
---|
1012 |
|
---|
1013 | if not fRepeat then
|
---|
1014 | -- Give error message if search was omitted
|
---|
1015 | if not fSearch then
|
---|
1016 | display -8 -- suppress writing to MsgBox
|
---|
1017 | sayerror sayerrortext( lrc) -- The same as: 'SayError -273'
|
---|
1018 | display 8
|
---|
1019 | endif
|
---|
1020 |
|
---|
1021 | -- Highlight it and maybe scroll to cursor pos
|
---|
1022 | if lrc = 0 then
|
---|
1023 | fRestorePos = 0
|
---|
1024 | -- Cursor position here must be that from before the search (savedpos)
|
---|
1025 | call ScrollAfterLocate( savedpos, lpos)
|
---|
1026 |
|
---|
1027 | --call highlight_match() -- gives wrong value
|
---|
1028 | call Highlight_Match( .line .col ReplaceLen)
|
---|
1029 |
|
---|
1030 | -- Restore pos after change command if stay = 1
|
---|
1031 | if stay then
|
---|
1032 | call pRestore_Pos( savedpos)
|
---|
1033 | endif
|
---|
1034 | endif
|
---|
1035 |
|
---|
1036 | if fRestorePos then
|
---|
1037 | call pRestore_Pos( savedpos)
|
---|
1038 | .line = .line -- maybe scroll to ensure that cursor is visible
|
---|
1039 | 'HighlightCursor'
|
---|
1040 | endif
|
---|
1041 | endif
|
---|
1042 |
|
---|
1043 | rc = lrc -- does hightlight_match change rc?
|
---|
1044 |
|
---|
1045 | if fRepeat then
|
---|
1046 | -- Replace the centered scroll pos of 'xcom c'.
|
---|
1047 | -- Cursor position here must be that from before the search (savedpos)
|
---|
1048 | call ScrollAfterLocate( savedpos, lpos)
|
---|
1049 |
|
---|
1050 | -- The position must be advanced before the next search.
|
---|
1051 | -- RepeatFind does that by checking lastsearchpos in ProsessSearchPos.
|
---|
1052 | 'RepeatFind'
|
---|
1053 | endif
|
---|
1054 |
|
---|
1055 | ; ---------------------------------------------------------------------------
|
---|
1056 | ; Highlight a "hit" after a Locate command or Repeat_find operation.
|
---|
1057 | ; Never used its previous arg( 1) = search_len in 6.03b.
|
---|
1058 | ; New: optional arg( 1) = <line> <col> <len>
|
---|
1059 | defproc Highlight_Match
|
---|
1060 |
|
---|
1061 | if rc then -- if not found; rc was set from last 'c'|'l'|repeat_find
|
---|
1062 | return
|
---|
1063 | endif
|
---|
1064 | savedrc = rc
|
---|
1065 |
|
---|
1066 | parse arg args
|
---|
1067 | if args <> '' then
|
---|
1068 | parse arg line col len
|
---|
1069 | if col = '' then
|
---|
1070 | -- This must be the previously used syntax: arg( 1) = search_len
|
---|
1071 | args = ''
|
---|
1072 | endif
|
---|
1073 | endif
|
---|
1074 | if args = '' then
|
---|
1075 | line = .line
|
---|
1076 | col = getpminfo( EPMINFO_SEARCHPOS)
|
---|
1077 | len = getpminfo( EPMINFO_LSLENGTH)
|
---|
1078 | endif
|
---|
1079 | if col = 0 then
|
---|
1080 | col = .col
|
---|
1081 | endif
|
---|
1082 |
|
---|
1083 | -- Draw a circle around the found string
|
---|
1084 | circleit LOCATE_CIRCLE_STYLE,
|
---|
1085 | line,
|
---|
1086 | col,
|
---|
1087 | col + len - 1,
|
---|
1088 | LOCATE_CIRCLE_COLOR1,
|
---|
1089 | LOCATE_CIRCLE_COLOR2
|
---|
1090 |
|
---|
1091 | rc = savedrc
|
---|
1092 | return
|
---|
1093 |
|
---|
1094 | ; ---------------------------------------------------------------------------
|
---|
1095 | ; Callable with 'postme'. Required for GlobalFind.
|
---|
1096 | defc HighlightMatch
|
---|
1097 | call Highlight_Match( arg( 1))
|
---|
1098 |
|
---|
1099 | ; ---------------------------------------------------------------------------
|
---|
1100 | defc CircleIt
|
---|
1101 | parse arg line startcol endcol
|
---|
1102 | circleit LOCATE_CIRCLE_STYLE, line, startcol, endcol,
|
---|
1103 | LOCATE_CIRCLE_COLOR1, LOCATE_CIRCLE_COLOR2
|
---|
1104 |
|
---|
1105 | ; ---------------------------------------------------------------------------
|
---|
1106 | ; Syntax: ScrollAfterLocate( savedpos [, lpos] [, UpDown] [, ScrollSpace])
|
---|
1107 | ; savedpos = pos before the search
|
---|
1108 | ; lpos = pos after the search, at the found string (optional)
|
---|
1109 | ; ScrollToTopBot = 'T' or 'B' (optional)
|
---|
1110 | ; ScrollSpace = space or window line values as 'top bot' (optional)
|
---|
1111 | ; Negative values are handled as vertical space,
|
---|
1112 | ; positive values are handled as window height line number,
|
---|
1113 | ; where the topmost visible line is 1 and the bottommost
|
---|
1114 | ; visible line is .windowheight.
|
---|
1115 | ; Example: '26 -4' means:
|
---|
1116 | ; topmost window line to scroll to = 26
|
---|
1117 | ; (the vertical space between 1 and 25 can be used for the search dialog)
|
---|
1118 | ; bottom minimum space = 4 lines
|
---|
1119 | ; If possible, vertical window scrolling is avoided. Then the loacate
|
---|
1120 | ; pos must be within the specified scroll area.
|
---|
1121 | defproc ScrollAfterLocate
|
---|
1122 | savedpos = arg( 1)
|
---|
1123 | if savedpos = '' then
|
---|
1124 | sayerror 'Error in ScrollAfterLoacate call: 'sayerrortext( -268)'. savedpos is missing.'
|
---|
1125 | return -268
|
---|
1126 | else
|
---|
1127 | parse value savedpos with svline svcol svcx svcy .
|
---|
1128 | endif
|
---|
1129 |
|
---|
1130 | lpos = arg( 2)
|
---|
1131 | if lpos = '' then
|
---|
1132 | lline = .line
|
---|
1133 | lcol = .col
|
---|
1134 | lcx = .cursorx
|
---|
1135 | lcy = .cursory
|
---|
1136 | else
|
---|
1137 | parse value lpos with lline lcol lcx lcy .
|
---|
1138 | endif
|
---|
1139 |
|
---|
1140 | ScrollToTopBot = upcase( arg( 3))
|
---|
1141 | if ScrollToTopBot = 'T' then
|
---|
1142 | -- Assist: inverted arg to sroll to the bottom after a downward search
|
---|
1143 | fDownward = 1
|
---|
1144 | elseif ScrollToTopBot = 'B' then
|
---|
1145 | -- Assist: inverted arg to sroll to the top after an upward search
|
---|
1146 | fDownward = 0
|
---|
1147 | else
|
---|
1148 | -- Get search direction from previous search options
|
---|
1149 | getsearch CurSearch
|
---|
1150 | parse value CurSearch with 'xcom' SearchMode rest
|
---|
1151 | rest = strip( rest)
|
---|
1152 | delim = leftstr( rest, 1)
|
---|
1153 | if SearchMode = 'c' then
|
---|
1154 | parse value rest with (delim)SeachString(delim)ReplaceString(delim)SearchOptions
|
---|
1155 | else
|
---|
1156 | parse value rest with (delim)SeachString(delim)SearchOptions
|
---|
1157 | endif
|
---|
1158 | fDownward = lastpos( '+', SearchOptions) >= lastpos( '-', SearchOptions)
|
---|
1159 | endif
|
---|
1160 |
|
---|
1161 | ScrollSpace = arg( 4)
|
---|
1162 | if ScrollSpace = '' then
|
---|
1163 | ScrollSpace = QueryConfigKey( '\NEPMD\User\CursorPos\ScrollAfterLocate')
|
---|
1164 | endif
|
---|
1165 |
|
---|
1166 | topline = svline - svcy + 1
|
---|
1167 | botline = svline - svcy + .windowheight
|
---|
1168 | leftcol = svcol - svcx + 1
|
---|
1169 | rightcol = svcol - svcx + .windowwidth
|
---|
1170 |
|
---|
1171 | topheight = word( ScrollSpace, 1)
|
---|
1172 | botheight = word( ScrollSpace, 2)
|
---|
1173 | if not IsNum( topheight) then
|
---|
1174 | topheight = 4
|
---|
1175 | elseif topheight < 0 then
|
---|
1176 | -- Minus: topheight is vspace in lines from top, set absolute value + 1
|
---|
1177 | topheight = -1 * topheight + 1
|
---|
1178 | endif
|
---|
1179 | if not IsNum( botheight) then
|
---|
1180 | botheight = .windowheight - 4
|
---|
1181 | elseif botheight < 0 then
|
---|
1182 | -- Minus: botheight is vspace in lines from bottom, calc with absolute value
|
---|
1183 | botheight = .windowheight + botheight
|
---|
1184 | endif
|
---|
1185 | -- Ensure that area is at least 1 line height
|
---|
1186 | if botheight - topheight < 0 then
|
---|
1187 | topheight = .windowheight % 2
|
---|
1188 | botheight = topheight
|
---|
1189 | endif
|
---|
1190 |
|
---|
1191 | fInScrollArea = 0
|
---|
1192 | x = lcol
|
---|
1193 | y = lline
|
---|
1194 | if y < topline + topheight then
|
---|
1195 | elseif y > botline - .windowheight + botheight then
|
---|
1196 | elseif x < leftcol then
|
---|
1197 | elseif x > rightcol then
|
---|
1198 | else
|
---|
1199 | fInScrollArea = 1
|
---|
1200 | endif
|
---|
1201 |
|
---|
1202 | -- Minimize scrolling for ScrollSpace = '0 0'
|
---|
1203 | if topheight = 0 & botheight = 0 then
|
---|
1204 | fInArea = OnScreen()
|
---|
1205 | -- Minimize scrolling if line number hasn't changed
|
---|
1206 | elseif lline = svline then
|
---|
1207 | fInArea = OnScreen()
|
---|
1208 | else
|
---|
1209 | fInArea = fInScrollArea
|
---|
1210 | endif
|
---|
1211 |
|
---|
1212 | if fInArea then
|
---|
1213 | call pRestore_Pos( savedpos)
|
---|
1214 | -- Set line to lline without scrolling
|
---|
1215 | .cursory = svcy + lline - svline
|
---|
1216 | .col = lcol
|
---|
1217 | else
|
---|
1218 | -- Reposition cursor
|
---|
1219 | call pRestore_Pos( lpos)
|
---|
1220 | oldline = .line
|
---|
1221 |
|
---|
1222 | if fDownward then
|
---|
1223 | .cursory = topheight
|
---|
1224 | else
|
---|
1225 | .cursory = botheight
|
---|
1226 | endif
|
---|
1227 |
|
---|
1228 | .line = oldline
|
---|
1229 | endif
|
---|
1230 |
|
---|
1231 | ; ---------------------------------------------------------------------------
|
---|
1232 | ; Can also be called with C or F as arg to repeat last change or find.
|
---|
1233 | /*
|
---|
1234 | ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
---|
1235 | ³ what's it called: searchdlg syntax: searchdlg [next] ³
|
---|
1236 | ³ ³
|
---|
1237 | ³ what does it do : ask EPM.EXE to pop up its internal search & replace dlg. ³
|
---|
1238 | ³ This is done by posting a EPM_POPCHANGEDLG message to the³
|
---|
1239 | ³ EPM Book window. ³
|
---|
1240 | ³ if the [next] param = 'F' a find next will take place ³
|
---|
1241 | ³ if the [next] param = 'C' a change next will take place ³
|
---|
1242 | ³ ³
|
---|
1243 | ³ (All EPM_EDIT_xxx messages are defined in the ETOOLKT ³
|
---|
1244 | ³ PACKAGE available on PCTOOLS.) ³
|
---|
1245 | ³ ³
|
---|
1246 | ³ who and when : Jerry C. 2/27/89 ³
|
---|
1247 | ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
---|
1248 | */
|
---|
1249 | defc SearchDlg
|
---|
1250 | universal default_search_options
|
---|
1251 |
|
---|
1252 | parse value upcase( arg( 1)) with uparg .
|
---|
1253 |
|
---|
1254 | if uparg = 'C' then
|
---|
1255 | 'RepeatChange '\1\1\1\1'D'
|
---|
1256 | elseif uparg = 'F' then
|
---|
1257 | 'RepeatFind '\1\1\1\1'D'
|
---|
1258 |
|
---|
1259 | else
|
---|
1260 | -- The application will free the buffer allocated by this macro
|
---|
1261 | call windowmessage( 0,
|
---|
1262 | getpminfo( APP_HANDLE),
|
---|
1263 | 5128, -- EPM_POPCHANGEDLG
|
---|
1264 | 0,
|
---|
1265 | Put_In_Buffer( default_search_options))
|
---|
1266 | 'PostMe PostSearchDlgOptions' -- PostMe required
|
---|
1267 | endif
|
---|
1268 |
|
---|
1269 | ; ---------------------------------------------------------------------------
|
---|
1270 | ; This must be posted, otherwise the handles are 0 after startup.
|
---|
1271 | defc PostSearchDlgOptions
|
---|
1272 | universal default_search_options
|
---|
1273 | universal searchoptions -- Set by ProcessSearchOptions
|
---|
1274 |
|
---|
1275 | hWndParent = WindowFromId( 5300)
|
---|
1276 |
|
---|
1277 | -- Handle default options T or B. The dialog won't check them on opening.
|
---|
1278 | -- searchoptions is empty on the first search. Therefore add
|
---|
1279 | -- default_search_options. After the first search, it is integrated.
|
---|
1280 | UpCurSearchOpt = upcase( default_search_options)''upcase( searchoptions)
|
---|
1281 | fTopIsDefault = (pos( 'T', UpCurSearchOpt) > 0)
|
---|
1282 | fBottomIsDefault = (pos( 'B', UpCurSearchOpt) > 0)
|
---|
1283 | if fTopIsDefault then
|
---|
1284 | SetCheckValue( hWndParent, 5318, 1) -- Start at: Top
|
---|
1285 | endif
|
---|
1286 | if fBottomIsDefault then
|
---|
1287 | SetCheckValue( hWndParent, 5319, 1) -- Start at: Bottom
|
---|
1288 | endif
|
---|
1289 |
|
---|
1290 | -- If file is marked, activate search in mark
|
---|
1291 | -- and from top, if B or T is not already set.
|
---|
1292 | if FileIsMarked() then
|
---|
1293 | SetCheckValue( hWndParent, 5303, 1) -- Options: Marked area
|
---|
1294 | if not fTopIsDefault & not fBottomIsDefault then
|
---|
1295 | SetCheckValue( hWndParent, 5318, 1) -- Start at: Top
|
---|
1296 | endif
|
---|
1297 | else
|
---|
1298 | SetCheckValue( hWndParent, 5303, 0) -- Options: Marked area
|
---|
1299 | if not fTopIsDefault & not fBottomIsDefault then
|
---|
1300 | SetCheckValue( hWndParent, 5317, 1) -- Start at: Cursor
|
---|
1301 | endif
|
---|
1302 | endif
|
---|
1303 |
|
---|
1304 | -- Set font
|
---|
1305 | KeyPath = '\NEPMD\User\Fonts\Text'
|
---|
1306 | TextFont = QueryConfigKey( KeyPath, '12.System VIO')
|
---|
1307 | SetWindowFont( hWndParent, 5301, TextFont) -- Search entry field
|
---|
1308 | SetWindowFont( hWndParent, 5310, TextFont) -- Replace entry field
|
---|
1309 |
|
---|
1310 | -- Set focus
|
---|
1311 | SetFocus( WindowFromId( hWndParent, 5301)) -- Search entry field
|
---|
1312 |
|
---|
1313 | ; ---------------------------------------------------------------------------
|
---|
1314 | ; Returns '+' or '-'.
|
---|
1315 | defproc GetSearchDirection
|
---|
1316 | universal default_search_options
|
---|
1317 | ret = '+'
|
---|
1318 |
|
---|
1319 | args = GetLastSearchArgs()
|
---|
1320 | delim = substr( args, 1, 1) -- get 1st delimiter
|
---|
1321 | parse value args with (delim)SearchString(delim)UserOptions
|
---|
1322 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
1323 |
|
---|
1324 | -- Analyze only last search options, not last change options
|
---|
1325 | Minuspos = lastpos( '-', default_search_options''UserOptions)
|
---|
1326 | Pluspos = lastpos( '+', default_search_options''UserOptions)
|
---|
1327 |
|
---|
1328 | if MinusPos > PlusPos then
|
---|
1329 | ret = '-'
|
---|
1330 | endif
|
---|
1331 | return ret
|
---|
1332 |
|
---|
1333 | ; ---------------------------------------------------------------------------
|
---|
1334 | ; From EPMSMP\REVERSE.E
|
---|
1335 | ; Search options for specifying the direction:
|
---|
1336 | ; F start searching from the start of line
|
---|
1337 | ; R start searching from the end of line
|
---|
1338 | ; + start searching from the start of text
|
---|
1339 | ; - start searching from the end of text
|
---|
1340 | ; The relevant options are + and -, F or R is set automatically.
|
---|
1341 | ;
|
---|
1342 | ; Original by Larry Margolis:
|
---|
1343 | ; Repeat the previous Locate, but in the reverse direction.
|
---|
1344 | ; E.g., if you search for a string that you know exists, but
|
---|
1345 | ; it's not found before the end of the file, press Ctrl+minus
|
---|
1346 | ; to repeat the search for the same string looking from the
|
---|
1347 | ; cursor position to the beginning of the file.
|
---|
1348 | ; Changed:
|
---|
1349 | ; Toggles the search direction (options +F or -R) without any
|
---|
1350 | ; following locate action.
|
---|
1351 | ; Doesn't produce an error msg anymore if oldsearch = empty.
|
---|
1352 | ; This has no effect on the settings of the Search dialog.
|
---|
1353 | defc ToggleSearchDirection
|
---|
1354 | universal default_search_options
|
---|
1355 |
|
---|
1356 | args = GetLastSearchArgs()
|
---|
1357 | delim = substr( args, 1, 1) -- get 1st delimiter
|
---|
1358 | parse value args with (delim)SearchString(delim)UserOptions
|
---|
1359 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
1360 |
|
---|
1361 | -- Analyze only last search options, not last change options
|
---|
1362 | Minuspos = lastpos( '-', default_search_options''UserOptions)
|
---|
1363 | Pluspos = lastpos( '+', default_search_options''UserOptions)
|
---|
1364 |
|
---|
1365 | -- Append +F or -R
|
---|
1366 | if Minuspos > Pluspos then -- in searchoptions: the last option wins
|
---|
1367 | 'SearchDirection +'
|
---|
1368 | 'SayHint Changed search direction to: forward.'
|
---|
1369 | else
|
---|
1370 | 'SearchDirection -'
|
---|
1371 | 'SayHint Changed search direction to: backward.'
|
---|
1372 | endif
|
---|
1373 |
|
---|
1374 | ; ---------------------------------------------------------------------------
|
---|
1375 | ; Set SearchDirection to foreward (arg = 'F' or '+') or backward (arg = 'R'
|
---|
1376 | ; or '-').
|
---|
1377 | defc SearchDirection
|
---|
1378 | -- Options will be normalized by ProcessSearchOptions. Therefore it's
|
---|
1379 | -- possible to simply append options. (The last option wins.)
|
---|
1380 | AddSearchChangeOptions = ''
|
---|
1381 | Direction = upcase( arg( 1))
|
---|
1382 | if Direction = '' then
|
---|
1383 | -- nop
|
---|
1384 | elseif Direction = '+' | Direction = 'F' then
|
---|
1385 | AddSearchChangeOptions = '+F'
|
---|
1386 | elseif Direction = '-' | Direction = 'R' then
|
---|
1387 | AddSearchChangeOptions = '-R'
|
---|
1388 | endif
|
---|
1389 | if AddSearchChangeOptions <> '' then
|
---|
1390 | SetAddSearchChangeOptions( AddSearchChangeOptions)
|
---|
1391 | endif
|
---|
1392 | return
|
---|
1393 |
|
---|
1394 | ; ---------------------------------------------------------------------------
|
---|
1395 | defc FindNext
|
---|
1396 | 'SearchDirection +'
|
---|
1397 | 'RepeatFind'
|
---|
1398 |
|
---|
1399 | ; ---------------------------------------------------------------------------
|
---|
1400 | defc FindPrev
|
---|
1401 | 'SearchDirection -'
|
---|
1402 | 'RepeatFind'
|
---|
1403 |
|
---|
1404 | ; ---------------------------------------------------------------------------
|
---|
1405 | defc ChangeFindNext
|
---|
1406 | 'SearchDirection +'
|
---|
1407 | 'RepeatChange'
|
---|
1408 | if not rc then
|
---|
1409 | 'RepeatFind'
|
---|
1410 | endif
|
---|
1411 |
|
---|
1412 | ; ---------------------------------------------------------------------------
|
---|
1413 | defc ChangeFindPrev
|
---|
1414 | 'SearchDirection -'
|
---|
1415 | 'RepeatChange'
|
---|
1416 | if not rc then
|
---|
1417 | 'RepeatFind'
|
---|
1418 | endif
|
---|
1419 |
|
---|
1420 | ; ---------------------------------------------------------------------------
|
---|
1421 | defc RepeatFindAllFiles, RingFind
|
---|
1422 |
|
---|
1423 | LastSearchArgs = GetLastSearchArgs()
|
---|
1424 | delim = substr( LastSearchArgs, 1, 1) -- get 1st delimiter
|
---|
1425 | parse value LastSearchArgs with (delim)SearchString(delim)UserOptions
|
---|
1426 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
1427 |
|
---|
1428 | -- Get current search direction
|
---|
1429 | Minuspos = lastpos( '-', UserOptions)
|
---|
1430 | Pluspos = lastpos( '+', UserOptions)
|
---|
1431 | if Minuspos > Pluspos then
|
---|
1432 | fForward = 0
|
---|
1433 | else
|
---|
1434 | fForward = 1
|
---|
1435 | endif
|
---|
1436 |
|
---|
1437 | -- Always search in entire files, not in mark
|
---|
1438 | if pos( 'M', UserOptions) > 0 | pos( 'A', UserOptions) = 0 then
|
---|
1439 | -- Remove 'M' from UserOptions
|
---|
1440 | do forever
|
---|
1441 | pv = verify( upcase( UserOptions), 'M', 'M')
|
---|
1442 | if pv = 0 then
|
---|
1443 | leave
|
---|
1444 | endif
|
---|
1445 | UserOptions = delstr( UserOptions, pv, 1)
|
---|
1446 | enddo
|
---|
1447 | -- Append 'A'
|
---|
1448 | UserOptions = UserOptions'A'
|
---|
1449 | call SetLastSearchArgs( delim''SearchString''delim''UserOptions)
|
---|
1450 | endif
|
---|
1451 |
|
---|
1452 | -- Get LastSearchArgs from ini, remove 'T' and 'B' options
|
---|
1453 | 'RepeatFind'
|
---|
1454 |
|
---|
1455 | if rc = 0 then
|
---|
1456 | -- Next occurrence found in current file
|
---|
1457 | return
|
---|
1458 | endif
|
---|
1459 |
|
---|
1460 | -- Not found in current file: search in other files
|
---|
1461 | getfileid fid
|
---|
1462 | startfid = fid
|
---|
1463 | do forever
|
---|
1464 |
|
---|
1465 | -- Next file
|
---|
1466 | if fForward = 1 then
|
---|
1467 | nextfile
|
---|
1468 | else
|
---|
1469 | prevfile
|
---|
1470 | endif
|
---|
1471 | getfileid fid
|
---|
1472 | activatefile fid
|
---|
1473 |
|
---|
1474 | call pSave_Pos( savedpos)
|
---|
1475 | -- Start from top of file
|
---|
1476 | if fForward = 1 then
|
---|
1477 | top
|
---|
1478 | .col = 1
|
---|
1479 | else
|
---|
1480 | bottom
|
---|
1481 | endline
|
---|
1482 | endif
|
---|
1483 |
|
---|
1484 | -- Get LastSearchArgs from ini, remove 'T' and 'B' options
|
---|
1485 | 'RepeatFind'
|
---|
1486 |
|
---|
1487 | if rc = 0 then
|
---|
1488 | -- Found
|
---|
1489 | 'HookAdd fileswitchedonce postme postme HighlightMatch' -- additionally required to highlight after file switching
|
---|
1490 | if fid = startfid then
|
---|
1491 | 'SayHint String only found in this file.'
|
---|
1492 | else
|
---|
1493 | sayerror 0 -- flush the message
|
---|
1494 | endif
|
---|
1495 | leave
|
---|
1496 | else
|
---|
1497 | -- Not found
|
---|
1498 | call pRestore_Pos( savedpos)
|
---|
1499 | if fid = startfid then
|
---|
1500 | 'SayError String not found in any file of the ring.'
|
---|
1501 | leave
|
---|
1502 | else
|
---|
1503 | -- Search next file
|
---|
1504 | endif
|
---|
1505 | endif
|
---|
1506 |
|
---|
1507 | enddo
|
---|
1508 | activatefile fid
|
---|
1509 |
|
---|
1510 | ; ---------------------------------------------------------------------------
|
---|
1511 | defc RepeatChangeAllFiles, RingChange
|
---|
1512 | universal stay
|
---|
1513 |
|
---|
1514 | LastChangeArgs = GetLastChangeArgs()
|
---|
1515 | delim = substr( LastChangeArgs, 1, 1) -- get 1st delimiter
|
---|
1516 | parse value LastChangeArgs with (delim)SearchString(delim)ReplaceString(delim)UserOptions
|
---|
1517 | UserOptions = strip( UserOptions, 'T', delim)
|
---|
1518 | SavedOptions = UserOptions
|
---|
1519 |
|
---|
1520 | -- Get current search direction
|
---|
1521 | Minuspos = lastpos( '-', UserOptions)
|
---|
1522 | Pluspos = lastpos( '+', UserOptions)
|
---|
1523 | if Minuspos > Pluspos then
|
---|
1524 | fForward = 0
|
---|
1525 | else
|
---|
1526 | fForward = 1
|
---|
1527 | endif
|
---|
1528 |
|
---|
1529 | -- Always search in entire files, not in mark
|
---|
1530 | if pos( 'M', UserOptions) > 0 | pos( 'A', UserOptions) = 0 then
|
---|
1531 | -- Remove 'M' from UserOptions
|
---|
1532 | do forever
|
---|
1533 | pv = verify( upcase( UserOptions), 'M', 'M')
|
---|
1534 | if pv = 0 then
|
---|
1535 | leave
|
---|
1536 | endif
|
---|
1537 | UserOptions = delstr( UserOptions, pv, 1)
|
---|
1538 | enddo
|
---|
1539 | -- Append 'A'
|
---|
1540 | UserOptions = UserOptions'A'
|
---|
1541 | endif
|
---|
1542 |
|
---|
1543 | -- Replace all occurrences, not only next
|
---|
1544 | if pos( '*', UserOptions) = 0 then
|
---|
1545 | -- Append '*'
|
---|
1546 | UserOptions = UserOptions'*'
|
---|
1547 | endif
|
---|
1548 |
|
---|
1549 | -- Write LastChangeArgs to ini
|
---|
1550 | if UserOptions <> SavedOptions then
|
---|
1551 | call SetLastChangeArgs( delim''SearchString''delim''ReplaceString''delim''UserOptions)
|
---|
1552 | endif
|
---|
1553 |
|
---|
1554 | getfileid fid
|
---|
1555 | startfid = fid
|
---|
1556 | ChangeCount = 0
|
---|
1557 | do forever
|
---|
1558 |
|
---|
1559 | call pSave_Pos( savedpos)
|
---|
1560 | -- Start from top of file
|
---|
1561 | if fForward = 1 then
|
---|
1562 | top
|
---|
1563 | .col = 1
|
---|
1564 | else
|
---|
1565 | bottom
|
---|
1566 | endline
|
---|
1567 | endif
|
---|
1568 |
|
---|
1569 | -- Get LastChangeArgs from ini, remove 'T' and 'B' options
|
---|
1570 | 'RepeatChange'
|
---|
1571 |
|
---|
1572 | if rc = 0 then
|
---|
1573 | -- Found
|
---|
1574 | ChangeCount = ChangeCount + 1
|
---|
1575 | if stay then
|
---|
1576 | call pRestore_Pos( savedpos)
|
---|
1577 | endif
|
---|
1578 | elseif rc = -257 then -- Invalid number of parameters
|
---|
1579 | return rc
|
---|
1580 | else
|
---|
1581 | -- Not found
|
---|
1582 | call pRestore_Pos( savedpos)
|
---|
1583 | endif
|
---|
1584 |
|
---|
1585 | -- Next file
|
---|
1586 | if fForward = 1 then
|
---|
1587 | nextfile
|
---|
1588 | else
|
---|
1589 | prevfile
|
---|
1590 | endif
|
---|
1591 |
|
---|
1592 | getfileid fid
|
---|
1593 | if fid = startfid then
|
---|
1594 | leave
|
---|
1595 | endif
|
---|
1596 |
|
---|
1597 | enddo
|
---|
1598 |
|
---|
1599 | if ChangeCount = 1 then
|
---|
1600 | files = 'file.'
|
---|
1601 | else
|
---|
1602 | files = 'files.'
|
---|
1603 | endif
|
---|
1604 | 'SayHint String changed in' ChangeCount files
|
---|
1605 |
|
---|
1606 | ; ---------------------------------------------------------------------------
|
---|
1607 | defc FindNextAllFiles
|
---|
1608 | 'SearchDirection F'
|
---|
1609 | 'RepeatFindAllFiles'
|
---|
1610 |
|
---|
1611 | ; ---------------------------------------------------------------------------
|
---|
1612 | defc FindPrevAllFiles
|
---|
1613 | 'SearchDirection R'
|
---|
1614 | 'RepeatFindAllFiles'
|
---|
1615 |
|
---|
1616 | ; ---------------------------------------------------------------------------
|
---|
1617 | defc FindMark
|
---|
1618 | if FileIsMarked() then
|
---|
1619 | -- Get active mark coordinates and fileid
|
---|
1620 | getmark FirstLine, LastLine, FirstCol, LastCol, MarkFileid
|
---|
1621 | if LastLine <> FirstLine then
|
---|
1622 | -- Take up to one line
|
---|
1623 | LastLine = FirstLine
|
---|
1624 | endline
|
---|
1625 | LastCol = .col
|
---|
1626 | endif
|
---|
1627 | SearchString = substr( textline( FirstLine ), FirstCol, LastCol - FirstCol + 1)
|
---|
1628 | if SearchString <> '' then
|
---|
1629 | 'l '\1''SearchString
|
---|
1630 | endif
|
---|
1631 | else
|
---|
1632 | sayerror -280 -- Text not marked
|
---|
1633 | endif
|
---|
1634 |
|
---|
1635 | ; ---------------------------------------------------------------------------
|
---|
1636 | ; Find word under cursor -- if arg( 1) > 0: -- under pointer.
|
---|
1637 | defc FindWord
|
---|
1638 | -- If arg( 1) specified and > 0: Set cursor to pos of pointer.
|
---|
1639 | if arg( 1) then
|
---|
1640 | 'MH_GoToLastClick'
|
---|
1641 | endif
|
---|
1642 | lrc = 1
|
---|
1643 | StartLine = .line
|
---|
1644 | StartCol = .col
|
---|
1645 | call pEnd_Word()
|
---|
1646 | LastCol = .col
|
---|
1647 | call pBegin_Word()
|
---|
1648 | FirstCol = .col
|
---|
1649 | -- Start search after current word
|
---|
1650 | .col = LastCol + 1
|
---|
1651 | SearchString = substr( textline( StartLine), FirstCol, LastCol - FirstCol + 1)
|
---|
1652 | if SearchString <> '' then
|
---|
1653 | 'l '\1''SearchString
|
---|
1654 | lrc = rc
|
---|
1655 | endif
|
---|
1656 | if lrc <> 0 then
|
---|
1657 | .col = StartCol
|
---|
1658 | endif
|
---|
1659 |
|
---|
1660 | ; ---------------------------------------------------------------------------
|
---|
1661 | ; Find identifier under cursor -- if arg( 1) > 0: -- under pointer.
|
---|
1662 | defc FindToken
|
---|
1663 | -- If arg( 1) specified and > 0: Set cursor to pos of pointer.
|
---|
1664 | if arg( 1) then
|
---|
1665 | 'MH_GoToLastClick'
|
---|
1666 | endif
|
---|
1667 | lrc = 1
|
---|
1668 | call pSave_Pos( savedpos)
|
---|
1669 | if Find_Token( startcol, endcol) then
|
---|
1670 | -- find_token returns first and last col of the found string. Therefore
|
---|
1671 | -- search shall start from 1 col behind.
|
---|
1672 | .col = endcol + 1
|
---|
1673 | -- The standard cmd 'locate' won't set standard rc. The standard 'locate'
|
---|
1674 | -- always returns rc = ''.
|
---|
1675 | -- Standard commands that don't change rc (are there more?):
|
---|
1676 | -- 'locate', 'edit'
|
---|
1677 | -- This is fixed in NEPMD.
|
---|
1678 | -- The standard commands 'quit', 'save', 'name',... do change rc.
|
---|
1679 | -- Therefore 'locate' now calls the proc locate, that sets rc correctly.
|
---|
1680 | -- rc is the rc from 'xcom locate'.
|
---|
1681 | -- (rc is a universal var, that doesn't need the universal definition.)
|
---|
1682 | 'l '\1''substr( textline( .line), startcol, (endcol - startcol) + 1)
|
---|
1683 | lrc = rc
|
---|
1684 | endif
|
---|
1685 | --sayerror 'defc findword: lrc = 'lrc
|
---|
1686 | if lrc <> 0 then -- if not found
|
---|
1687 | call pRestore_Pos( savedpos)
|
---|
1688 | endif
|
---|
1689 |
|
---|
1690 | ; ---------------------------------------------------------------------------
|
---|
1691 | ; Find a token around the cursor.
|
---|
1692 | defproc Find_Token( var startcol, var endcol)
|
---|
1693 | if arg( 3) = '' then
|
---|
1694 | token_separators = ' ~`!%^&*()-+=][{}|\:;?/><,''"'\t
|
---|
1695 | else
|
---|
1696 | token_separators = arg( 3)
|
---|
1697 | endif
|
---|
1698 | if arg( 4) = '' then
|
---|
1699 | diads = '-> ++ -- << >> <= >= && || += -= *= /= %= ª= &= |= :: /* */'
|
---|
1700 | else
|
---|
1701 | diads = arg( 4)
|
---|
1702 | endif
|
---|
1703 | trailing_token_separators = '.:,;!?'
|
---|
1704 | getline line
|
---|
1705 | len = length( line)
|
---|
1706 | if .col > len | pos( substr( line, .col, 1), ' '\t) then
|
---|
1707 | -- Past end of line, or over whitespace
|
---|
1708 | return
|
---|
1709 | endif
|
---|
1710 | endcol = verify( line, token_separators, 'M', .col)
|
---|
1711 | if endcol = .col then
|
---|
1712 | -- On an operator
|
---|
1713 | startcol = endcol
|
---|
1714 | if wordpos( substr( line, startcol, 2), diads) then
|
---|
1715 | -- On first character
|
---|
1716 | endcol = endcol + 1
|
---|
1717 | elseif .col > 1 then
|
---|
1718 | if wordpos( substr( line, endcol-1, 2), diads) then
|
---|
1719 | -- On last character
|
---|
1720 | startcol = startcol - 1
|
---|
1721 | endif
|
---|
1722 | endif
|
---|
1723 | return 2
|
---|
1724 | endif
|
---|
1725 | if endcol then
|
---|
1726 | endcol = endcol - 1
|
---|
1727 | else
|
---|
1728 | endcol = len
|
---|
1729 | endif
|
---|
1730 | if pos( substr( line, endcol, 1), trailing_token_separators) then
|
---|
1731 | endcol = endcol - 1
|
---|
1732 | endif
|
---|
1733 | startcol = verify( reverse( line), token_separators, 'M', len - .col + 1)
|
---|
1734 | if startcol then
|
---|
1735 | startcol = len - startcol + 2
|
---|
1736 | else
|
---|
1737 | startcol = 1
|
---|
1738 | endif
|
---|
1739 | return 1
|
---|
1740 |
|
---|
1741 | ; ---------------------------------------------------------------------------
|
---|
1742 | defc ShowSearch
|
---|
1743 | getsearch CurSearch
|
---|
1744 |
|
---|
1745 | Next = 'Last search = ['cursearch'], last search args = ['GetLastSearchArgs()']' ||
|
---|
1746 | ', last change args = ['GetLastChangeArgs()']'
|
---|
1747 | 'SayHint' Next
|
---|
1748 | dprintf( Next)
|
---|
1749 |
|
---|
1750 | ; ---------------------------------------------------------------------------
|
---|
1751 | defc SetScrollAfterLocate
|
---|
1752 | KeyPath = '\NEPMD\User\CursorPos\ScrollAfterLocate'
|
---|
1753 | DefaultValue = '26 -4'
|
---|
1754 | -- if executed with a num as arg
|
---|
1755 | parse value arg( 1) with topval botval
|
---|
1756 | if IsNum( topval) & IsNum( botval) then
|
---|
1757 | call WriteConfigKey( KeyPath, arg( 1))
|
---|
1758 | if isadefproc( 'MenuText_scrollafterlocate') then
|
---|
1759 | MenuText_scrollafterlocate()
|
---|
1760 | endif
|
---|
1761 | return
|
---|
1762 | endif
|
---|
1763 | -- else open entrybox
|
---|
1764 | Title = 'Configure line position on screen after locate'
|
---|
1765 | Text = 'Enter number of lines from top and from bottom (negative values for vspace).'
|
---|
1766 | IniValue = QueryConfigKey( KeyPath)
|
---|
1767 | If IniValue = 0 | IniValue = '' then
|
---|
1768 | DefaultButton = 3
|
---|
1769 | elseif IniValue < 0 then
|
---|
1770 | DefaultButton = 2
|
---|
1771 | else
|
---|
1772 | DefaultButton = 1
|
---|
1773 | endif
|
---|
1774 | -- strip + or -
|
---|
1775 | IniValue = strip( IniValue)
|
---|
1776 | parse value EntryBox( Title,
|
---|
1777 | '/'OK__MSG'/~Reset/'CANCEL__MSG, -- max. 4 buttons
|
---|
1778 | IniValue,
|
---|
1779 | '',
|
---|
1780 | 260,
|
---|
1781 | atoi( DefaultButton) ||
|
---|
1782 | atoi( 0000) || -- help id
|
---|
1783 | GethWndC( APP_HANDLE) ||
|
---|
1784 | Text) with Button 2 NewValue \0
|
---|
1785 | -- strip + or -
|
---|
1786 | NewValue = strip( NewValue)
|
---|
1787 | if Button = \1 then
|
---|
1788 | 'SetScrollAfterLocate' NewValue
|
---|
1789 | return
|
---|
1790 | elseif Button = \2 then
|
---|
1791 | 'SetScrollAfterLocate 'DefaultValue
|
---|
1792 | return
|
---|
1793 | elseif Button = \3 then
|
---|
1794 | return
|
---|
1795 | endif
|
---|
1796 |
|
---|
1797 | ; ---------------------------------------------------------------------------
|
---|
1798 | defc GotoLineDlg
|
---|
1799 | Title = 'Go to line'
|
---|
1800 | Text = 'Enter line number and optionally a column number:'
|
---|
1801 | --Text = Text''copies( ' ', max( 100 - length(Text), 0))
|
---|
1802 | Entry = ''
|
---|
1803 | parse value EntryBox( Title,
|
---|
1804 | '',
|
---|
1805 | Entry,
|
---|
1806 | 0,
|
---|
1807 | 240,
|
---|
1808 | atoi(1) || atoi(0) || atol(0) ||
|
---|
1809 | Text) with button 2 NewLine \0
|
---|
1810 | NewLine = strip( NewLine)
|
---|
1811 | if button = \1 & NewLine <> '' then
|
---|
1812 | 'GoTo' NewLine
|
---|
1813 | endif
|
---|
1814 |
|
---|
1815 | ; ---------------------------------------------------------------------------
|
---|
1816 | const
|
---|
1817 | compile if not defined( MATCH_MAX_LINES)
|
---|
1818 | MATCH_MAX_LINES = 200
|
---|
1819 | compile endif
|
---|
1820 | compile if not defined( MATCH_MAX_LOOPS)
|
---|
1821 | MATCH_MAX_LOOPS = 20
|
---|
1822 | compile endif
|
---|
1823 |
|
---|
1824 | defproc Match( ThisStr)
|
---|
1825 | universal lastassistpos
|
---|
1826 |
|
---|
1827 | lrc = 1
|
---|
1828 | display -3 -- turn off non-critical error messages and screen updates
|
---|
1829 | -- Note: SayHint uses temp. 'display -8' to disable message box saving.
|
---|
1830 | -- That results in 'display -11'.
|
---|
1831 | call pSave_Pos( ScreenPos)
|
---|
1832 | sayerror 0
|
---|
1833 |
|
---|
1834 | do once = 1 to 1
|
---|
1835 | VerboseLevel = 0 -- No message, no pointer change
|
---|
1836 | fHighlight = 0 -- Match itself decides to highlight or report only
|
---|
1837 | fUseArray = 0 -- Building an MLC array causes stuttering cursor move
|
---|
1838 | lrc = pAssist( VerboseLevel, fHighlight, MATCH_MAX_LINES, MATCH_MAX_LOOPS, fUseArray)
|
---|
1839 |
|
---|
1840 | -- Can't use getpminfo( EPMINFO_LSLENGTH) here.
|
---|
1841 | parse value lastassistpos with HighlightLine HighlightCol HighlightLen
|
---|
1842 | if HighlightLen = 0 then
|
---|
1843 | HighlightLen = length( ThisStr)
|
---|
1844 | endif
|
---|
1845 | MatchLineStr = textline( .line)
|
---|
1846 | MatchLine = .line
|
---|
1847 | MatchCol = .col
|
---|
1848 | MatchLen = HighlightLen
|
---|
1849 |
|
---|
1850 | call pRestore_Pos( ScreenPos)
|
---|
1851 | display 3 -- turn on non-critical error messages and screen updates
|
---|
1852 | if lrc then
|
---|
1853 | leave
|
---|
1854 | endif
|
---|
1855 |
|
---|
1856 | if OnScreen( MatchLine, MatchCol) then
|
---|
1857 | -- Highlight it
|
---|
1858 | EndCol = MatchCol + MatchLen - 1
|
---|
1859 | 'CircleIt' MatchLine MatchCol EndCol
|
---|
1860 | else
|
---|
1861 | -- This character not on screen, so tell user in message area where it is
|
---|
1862 | ReportLineStr = leftstr( MatchLineStr, MatchCol + MatchLen - 1)
|
---|
1863 | if (length( ReportLineStr) > 20) then
|
---|
1864 | ReportLineStr = leftstr( ReportLineStr, 20) "..."
|
---|
1865 | endif
|
---|
1866 | 'SayHint Line' MatchLine', column' MatchCol':' ReportLineStr
|
---|
1867 | endif
|
---|
1868 | enddo
|
---|
1869 | rc = lrc
|
---|
1870 |
|
---|
1871 | return
|
---|
1872 |
|
---|
1873 | ; ---------------------------------------------------------------------------
|
---|
1874 | defc Match
|
---|
1875 | call Match( arg( 1))
|
---|
1876 |
|
---|
1877 | ; ---------------------------------------------------------------------------
|
---|
1878 | ; Syntax: rcx = SearchReplaceLine( SearchStr, ReplaceStr, ReplaceTimes
|
---|
1879 | ; [, SearchOpt [, Line , [StartCol [, EndCol]]]])
|
---|
1880 | ; Returns:
|
---|
1881 | ; rcx = 0 line changed
|
---|
1882 | ; rcx = 1 line not changed
|
---|
1883 | ; Default values for the optional args:
|
---|
1884 | ; SearchOpt = ''
|
---|
1885 | ; Line = current line
|
---|
1886 | ; StartCol = current column
|
---|
1887 | ; EndCol = line end
|
---|
1888 | ; o If '' is specified as SearchStr, the entire string from StartCol to
|
---|
1889 | ; EndCol is replaced.
|
---|
1890 | ; o Replaces a search mask on one line only.
|
---|
1891 | ; o Found SearchStr is replaced ReplaceTimes times.
|
---|
1892 | ; o If ReplaceTimes is empty or 0, all occurrences between StartCol and
|
---|
1893 | ; EndCol are replaced.
|
---|
1894 | ; o If StartCol is empty, the current .col is used.
|
---|
1895 | ; o If EndCol is empty or -1, the rest of the line is searched.
|
---|
1896 | ; o Any output is suppressed. Cursor and scroll pos. and previous search
|
---|
1897 | ; args are restored after processing.
|
---|
1898 | ; o This can be used instead of the replaceline statement to preserve
|
---|
1899 | ; attributes (e.g. bookmarks).
|
---|
1900 | defproc SearchReplaceLine( SearchStr, ReplaceStr, ReplaceTimes)
|
---|
1901 | if ReplaceTimes = '' then
|
---|
1902 | ReplaceTimes = 0
|
---|
1903 | endif
|
---|
1904 | SearchOpt = arg( 4)
|
---|
1905 | Line = arg( 5)
|
---|
1906 | if Line = '' then
|
---|
1907 | Line = .line
|
---|
1908 | endif
|
---|
1909 |
|
---|
1910 | -- Ensure that Line exists
|
---|
1911 | LastLine = .last
|
---|
1912 | if Line > LastLine then
|
---|
1913 | do l = 1 to Line - LastLine
|
---|
1914 | insertline '', .last + 1
|
---|
1915 | enddo
|
---|
1916 | endif
|
---|
1917 |
|
---|
1918 | StartCol = arg( 6)
|
---|
1919 | if StartCol = '' then
|
---|
1920 | StartCol = .col
|
---|
1921 | endif
|
---|
1922 | EndCol = arg( 7)
|
---|
1923 | if EndCol = '' then
|
---|
1924 | EndCol = -1 -- -1 means: search until end of line
|
---|
1925 | endif
|
---|
1926 | rcx = 1
|
---|
1927 |
|
---|
1928 | fGrep = 0
|
---|
1929 | if pos( 'g', lowcase( SearchOpt)) | pos( 'x', lowcase( SearchOpt)) then
|
---|
1930 | fGrep = 1
|
---|
1931 | endif
|
---|
1932 |
|
---|
1933 | pSave_Pos( savepos)
|
---|
1934 | getsearch savesearch
|
---|
1935 |
|
---|
1936 | if SearchStr = '' then
|
---|
1937 | LineStr = textline( Line)
|
---|
1938 | if EndCol = -1 | EndCol >= 1599 then
|
---|
1939 | SearchStr = substr( LineStr, StartCol)
|
---|
1940 | else
|
---|
1941 | SearchStr = substr( LineStr, StartCol, Max( 0, EndCol - StartCol + 1))
|
---|
1942 | endif
|
---|
1943 | endif
|
---|
1944 |
|
---|
1945 | -- Handle empty SearchStr: Insert a '*' to make xcom l and xcom c work
|
---|
1946 | if SearchStr = '' then
|
---|
1947 | fInsertToggled = 0
|
---|
1948 | if insertstate() then
|
---|
1949 | inserttoggle
|
---|
1950 | fInsertToggled = 1
|
---|
1951 | endif
|
---|
1952 |
|
---|
1953 | .col = StartCol
|
---|
1954 | .lineg = Line
|
---|
1955 | SearchStr = '*'
|
---|
1956 | TypeChars( SearchStr)
|
---|
1957 |
|
---|
1958 | if fInsertToggled then
|
---|
1959 | inserttoggle
|
---|
1960 | endif
|
---|
1961 | endif
|
---|
1962 | --dprintf( 'SearchReplaceLine: SearchStr = ['SearchStr']')
|
---|
1963 |
|
---|
1964 | .col = StartCol
|
---|
1965 | .lineg = Line
|
---|
1966 | ProcessCount = 0
|
---|
1967 | do forever
|
---|
1968 | ProcessCount = ProcessCount + 1
|
---|
1969 | -- Check processing number
|
---|
1970 | if ReplaceTimes > 0 then
|
---|
1971 | if ProcessCount > ReplaceTimes then
|
---|
1972 | leave
|
---|
1973 | endif
|
---|
1974 | endif
|
---|
1975 |
|
---|
1976 | display -14
|
---|
1977 | -- Search
|
---|
1978 | 'xcom l '\1''SearchStr''\1''SearchOpt
|
---|
1979 | display 14
|
---|
1980 |
|
---|
1981 | -- Check rc
|
---|
1982 | lrc = rc
|
---|
1983 | if lrc then
|
---|
1984 | leave
|
---|
1985 | endif
|
---|
1986 | -- Check pos.
|
---|
1987 | if .line <> Line then
|
---|
1988 | leave
|
---|
1989 | endif
|
---|
1990 | if EndCol > -1 then
|
---|
1991 | if .col > EndCol then
|
---|
1992 | leave
|
---|
1993 | endif
|
---|
1994 | endif
|
---|
1995 |
|
---|
1996 | -- Get line length before replace
|
---|
1997 | if fGrep then
|
---|
1998 | LineStr = textline( .line)
|
---|
1999 | LineLen = length( LineStr)
|
---|
2000 | endif
|
---|
2001 |
|
---|
2002 | display -14
|
---|
2003 | -- Replace
|
---|
2004 | 'xcom c '\1''SearchStr''\1''ReplaceStr''\1''SearchOpt
|
---|
2005 | display 14
|
---|
2006 |
|
---|
2007 | -- Check rc
|
---|
2008 | crc = rc
|
---|
2009 | if crc then
|
---|
2010 | leave
|
---|
2011 | endif
|
---|
2012 |
|
---|
2013 | rcx = 0 -- line changed
|
---|
2014 |
|
---|
2015 | -- Move cursor after replace, adapt EndCol
|
---|
2016 | if fGrep then
|
---|
2017 | NewLineStr = textline( .line)
|
---|
2018 | NewLineLen = length( NewLineStr)
|
---|
2019 | DiffLen = NewLineLen - LineLen
|
---|
2020 | else
|
---|
2021 | DiffLen = length( ReplaceStr) - length( SearchStr)
|
---|
2022 | endif
|
---|
2023 | .col = .col + DiffLen
|
---|
2024 | if EndCol > -1 then
|
---|
2025 | EndCol = EndCol + DiffLen
|
---|
2026 | endif
|
---|
2027 |
|
---|
2028 | -- Check pos.
|
---|
2029 | if EndCol > -1 then
|
---|
2030 | if .col > EndCol then
|
---|
2031 | leave
|
---|
2032 | endif
|
---|
2033 | endif
|
---|
2034 | enddo
|
---|
2035 |
|
---|
2036 | setsearch savesearch
|
---|
2037 | pRestore_Pos( savepos)
|
---|
2038 |
|
---|
2039 | return rcx
|
---|
2040 |
|
---|
2041 | ; ---------------------------------------------------------------------------
|
---|
2042 | ; Syntax: pReplaceLine( ReplaceStr [, LineNum [, FileId]])
|
---|
2043 | ; o This can be used instead of the replaceline statement to preserve
|
---|
2044 | ; attributes (e.g. bookmarks). It has the same args.
|
---|
2045 | defproc pReplaceLine( ReplaceStr)
|
---|
2046 | LineNum = arg( 2)
|
---|
2047 | if LineNum = '' then
|
---|
2048 | LineNum = .line
|
---|
2049 | endif
|
---|
2050 |
|
---|
2051 | getfileid StartFid
|
---|
2052 | fSwitchFile = 0
|
---|
2053 | ReplaceFid = arg( 3)
|
---|
2054 | if ReplaceFid = '' then
|
---|
2055 | -- nop
|
---|
2056 | elseif ReplaceFid <> StartFid then
|
---|
2057 | fSwitchFile = 1
|
---|
2058 | endif
|
---|
2059 |
|
---|
2060 | if fSwitchFile then
|
---|
2061 | activatefile ReplaceFid
|
---|
2062 | endif
|
---|
2063 |
|
---|
2064 | --dprintf( 'ReplaceStr = ['ReplaceStr'], LineNum = 'LineNum)
|
---|
2065 | rcx = SearchReplaceLine( '', ReplaceStr, 1, '', LineNum, 1)
|
---|
2066 | if fSwitchFile then
|
---|
2067 | activatefile StartFid
|
---|
2068 | endif
|
---|
2069 | return
|
---|
2070 |
|
---|
2071 | ; ---------------------------------------------------------------------------
|
---|
2072 | ; This is used by Alt+1.
|
---|
2073 | defc FindStringInCode
|
---|
2074 | searchwrd = arg( 1)
|
---|
2075 | Mode = GetMode()
|
---|
2076 |
|
---|
2077 | -- First try word search
|
---|
2078 | 'l '\1''searchwrd''\1'wt+fac'
|
---|
2079 |
|
---|
2080 | -- If nothing found, try normal search
|
---|
2081 | if rc then
|
---|
2082 | 'l '\1''searchwrd''\1't+fac'
|
---|
2083 | endif
|
---|
2084 |
|
---|
2085 | do forever
|
---|
2086 | -- Check for strings and comments
|
---|
2087 | if InsideCommentLiteral( Mode) then
|
---|
2088 | repeatfind
|
---|
2089 | endif
|
---|
2090 |
|
---|
2091 | leave
|
---|
2092 | enddo
|
---|
2093 |
|
---|