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

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