source: trunk/src/netlabs/macros/locate.e@ 3877

Last change on this file since 3877 was 3877, checked in by Andreas Schnellbacher, 5 years ago
  • Changed a comment.
  • Property svn:keywords set to Date Revision Author HeadURL Id
File size: 71.2 KB
Line 
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
74compile if not defined( SMALL) -- If compiled separately
75 EA_comment 'This defines macros for saerch operations.'
76
77define
78 INCLUDING_FILE = 'LOCATE.E'
79
80 include 'stdconst.e'
81const
82 tryinclude 'mycnf.e'
83const
84 compile if not defined( NLS_LANGUAGE)
85 NLS_LANGUAGE = 'ENGLISH'
86 compile endif
87 include NLS_LANGUAGE'.e'
88compile endif
89
90; ---------------------------------------------------------------------------
91const
92compile if not defined( LOCATE_CIRCLE_STYLE)
93 --LOCATE_CIRCLE_STYLE = 1 -- changed by aschn
94 LOCATE_CIRCLE_STYLE = 5 -- (1) filled oval
95compile endif
96compile if not defined( LOCATE_CIRCLE_COLOR1)
97 --LOCATE_CIRCLE_COLOR1 = 16777220 -- changed by aschn
98 LOCATE_CIRCLE_COLOR1 = 16777231 -- (16777220) complementary
99compile endif
100compile 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
104compile endif
105compile if not defined( HIGHLIGHT_COLOR)
106 HIGHLIGHT_COLOR = 14 -- This must be set to enable circle colors
107compile endif
108
109; ---------------------------------------------------------------------------
110defmodify -- 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
125defproc 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
217defproc 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
474defproc 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; ---------------------------------------------------------------------------
534defproc GetLastSearchArgs
535 KeyPath = '\NEPMD\Var\Search\LastSearchArgs'
536 LastSearchArgs = QueryConfigKey( KeyPath)
537 --dprintf( 'GetLastSearchArgs: LastSearchArgs = 'LastSearchArgs)
538 return LastSearchArgs
539
540; ---------------------------------------------------------------------------
541defproc GetLastChangeArgs
542 KeyPath = '\NEPMD\Var\Search\LastChangeArgs'
543 LastChangeArgs = QueryConfigKey( KeyPath)
544 return LastChangeArgs
545
546; ---------------------------------------------------------------------------
547defproc GetLastSearchDialogOptions
548 KeyPath = '\NEPMD\Var\Search\LastSearchDialogOptions'
549 LastSearchDialogOptions = QueryConfigKey( KeyPath)
550 --dprintf( 'GetLastSearchDialogOptions: LastSearchDialogOptions = 'LastSearchDialogOptions)
551 return LastSearchDialogOptions
552
553; ---------------------------------------------------------------------------
554defproc 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; ---------------------------------------------------------------------------
562defproc SetLastChangeArgs
563 KeyPath = '\NEPMD\Var\Search\LastChangeArgs'
564 LastChangeArgs = arg( 1)
565 call WriteConfigKey( KeyPath, LastChangeArgs)
566 return
567
568; ---------------------------------------------------------------------------
569defproc 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; ---------------------------------------------------------------------------
577defproc GetAddSearchChangeOptions
578 KeyPath = '\NEPMD\Var\Search\AddSearchChangeOptions'
579 AddSearchChangeOptions = QueryConfigKey( KeyPath)
580 return AddSearchChangeOptions
581
582; ---------------------------------------------------------------------------
583defproc 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'.
600defc 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; ---------------------------------------------------------------------------
805defc 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>
1059defproc 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.
1096defc HighlightMatch
1097 call Highlight_Match( arg( 1))
1098
1099; ---------------------------------------------------------------------------
1100defc 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.
1121defproc 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*/
1249defc 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.
1271defc 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 '-'.
1315defproc 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.
1353defc 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 '-').
1377defc 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; ---------------------------------------------------------------------------
1395defc FindNext
1396 'SearchDirection +'
1397 'RepeatFind'
1398
1399; ---------------------------------------------------------------------------
1400defc FindPrev
1401 'SearchDirection -'
1402 'RepeatFind'
1403
1404; ---------------------------------------------------------------------------
1405defc ChangeFindNext
1406 'SearchDirection +'
1407 'RepeatChange'
1408 if not rc then
1409 'RepeatFind'
1410 endif
1411
1412; ---------------------------------------------------------------------------
1413defc ChangeFindPrev
1414 'SearchDirection -'
1415 'RepeatChange'
1416 if not rc then
1417 'RepeatFind'
1418 endif
1419
1420; ---------------------------------------------------------------------------
1421defc 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; ---------------------------------------------------------------------------
1511defc 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; ---------------------------------------------------------------------------
1607defc FindNextAllFiles
1608 'SearchDirection F'
1609 'RepeatFindAllFiles'
1610
1611; ---------------------------------------------------------------------------
1612defc FindPrevAllFiles
1613 'SearchDirection R'
1614 'RepeatFindAllFiles'
1615
1616; ---------------------------------------------------------------------------
1617defc 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.
1637defc 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.
1662defc 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.
1692defproc 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; ---------------------------------------------------------------------------
1742defc 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; ---------------------------------------------------------------------------
1751defc 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; ---------------------------------------------------------------------------
1798defc 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; ---------------------------------------------------------------------------
1816const
1817compile if not defined( MATCH_MAX_LINES)
1818 MATCH_MAX_LINES = 200
1819compile endif
1820compile if not defined( MATCH_MAX_LOOPS)
1821 MATCH_MAX_LOOPS = 20
1822compile endif
1823
1824defproc 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; ---------------------------------------------------------------------------
1874defc 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).
1900defproc 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.
2045defproc 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.
2073defc 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
Note: See TracBrowser for help on using the repository browser.