Recent

Author Topic: SynEdit.SearchReplaceEx Example  (Read 9143 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
SynEdit.SearchReplaceEx Example
« on: March 30, 2018, 10:49:36 pm »
I'm struggling with what shd be the most basic use of SearchReplaceEx().  I would like to break out the operations Find, Find Next, Replace, into separate buttons.  I want "In selected only" to be assumed if there is a selection made in the SynEdit.  I'm assuming since there is no ReplaceNext that the "Replace" will just work on the next occurrence to be replaced.  In any case...

Would it be possible to get a SynEdit expert to look at the attached app and correct my code so that the app works, and can be used as a working example of how to use SynEdit.SearchReplaceEx() correctly? (Then post the corrected code here for all to see).   I've searched the web and forums and could not find such an example.

Thanks in advance.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit.SearchReplaceEx Example
« Reply #1 on: March 31, 2018, 12:32:34 am »
There are a few hints here http://wiki.lazarus.freepascal.org/Editor_Macros_PascalScript#Caller:_TSynEdit
But you probably know most of them.

I haven't  tested anything, just looked it over.

first:
   SearchReplaceEx(....., AStart: TPoint)
This is NOT the range, it is a point in the text.
So you always start in the last line of text.

And because you explicitly define the start point, ssoFindContinue does not work (it continues according to the current selection, which should be the last found item, OR iirc the caret if no selection exists).
Generally ssoFindContinue does not work with SearchReplaceEx

You really just want SearchReplace.
And that searches from the current caret (or deals with continue), depending on search direction to begin or end of file (or the boundary of selection)

Note that SynEdit does not support continue mixed with selection only. Because the first search moved the selection, and it does not remember the old selection. If the new selection is set to the found item, then you search that new selection (probably from its END to its END) so you find nothing.

----------
So
- use SearchReplace,
- drop srch_rng,
- and do not do continue and select-only together
And that probably should sort most of it.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: SynEdit.SearchReplaceEx Example
« Reply #2 on: March 31, 2018, 03:38:08 am »
let me see if I can make your example work. I'll be back in a couple of hours.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Re: SynEdit.SearchReplaceEx Example
« Reply #3 on: March 31, 2018, 03:44:28 am »
Thank you Martin_fr, good points.  Looking forward to the mods made by taazz.  This will be a good resource for the community.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: SynEdit.SearchReplaceEx Example
« Reply #4 on: March 31, 2018, 08:59:50 pm »
If you submit the final example to the bugtracker (with permission to use), I can add it to the example folder.

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Re: SynEdit.SearchReplaceEx Example
« Reply #5 on: April 01, 2018, 12:36:05 am »
taazz, as you have probably noticed, there is a checkbox missing... one for "Confirm Replace".  Error of omission on my part.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: SynEdit.SearchReplaceEx Example
« Reply #6 on: April 01, 2018, 12:50:50 am »
taazz, as you have probably noticed, there is a checkbox missing... one for "Confirm Replace".  Error of omission on my part.
I assume that its always on, its the safer option any way. I added a check box to start searching  from top or from current position when pressing findfirst/replacefirst which is (IMHO) a lot more important. I'm working on the selection portion of the search at the moment when finish I'll apply the changes to the replace procedure as well and attach it in a new post. It will take a bit of time though it needs a bit of a fine touch.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: SynEdit.SearchReplaceEx Example
« Reply #7 on: April 01, 2018, 08:20:28 am »
sorry for the delay. Here is the code for the form.I only played around with the  find event not the replace. The selection think was a bit to unbalanced so I simplified the logic behind it, no restart from the top or preserve the last found selection. But it stops if the next found item is outside the original selection block, although as it is now it jumps at the top.

I assume that this is enough to get you started. If there are any problems post and I'll try to address them.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Types, FileUtil, SynEdit, SynEditTypes, Forms, Controls,
  9.   Graphics, Dialogs, StdCtrls, ExtCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     btnFindFirst: TButton;
  17.     btnFindNext: TButton;
  18.     btnReplaceAll: TButton;
  19.     btnReplaceFirst: TButton;
  20.     btnReplaceNext: TButton;
  21.     edtFind: TEdit;
  22.     edtRplc: TEdit;
  23.     rgDirection: TRadioGroup;
  24.     SynEdit1: TSynEdit;
  25.     xbxMatchCase: TCheckBox;
  26.     xbxFromTop :TCheckBox;
  27.     xbxWhole: TCheckBox;
  28.     procedure btnFindFirstClick(Sender: TObject);
  29.     procedure btnReplaceFirstClick(Sender: TObject);
  30.   private
  31.     FSrch_rng: TPoint;
  32.     FSearchOpts:TSynSearchOptions;
  33.     FInBlock : TRect;
  34.   public
  35.     constructor Create(TheOwner :TComponent); override;
  36.   end;
  37.  
  38. var
  39.   Form1: TForm1;
  40.  
  41. implementation
  42.  
  43. {$R *.lfm}
  44. const
  45.   cEmptyRect : TRect = (Left:0;Top:0;Right:0;Bottom:0);
  46. { TForm1 }
  47.  
  48. //function EqualPoints(const aPnt1, aPnt2:TPoint):Boolean;
  49. //begin
  50. //  Result := (aPnt1.x = aPnt2.x) and (aPnt1.Y = aPnt2.Y);
  51. //end;
  52. //
  53. Function RectInRect(const aOuterRect, aInnerRect:TRect):Boolean;
  54. begin
  55.   Result := (aInnerRect.Left   >= aOuterRect.Left) and (aInnerRect.Left   <= aOuterRect.Right)  and
  56.             (aInnerRect.Right  >= aOuterRect.Left) and (aInnerRect.Right  <= aOuterRect.Right)  and
  57.             (aInnerRect.Top    >= aOuterRect.Top)  and (aInnerRect.Top    <= aOuterRect.Bottom) and
  58.             (aInnerRect.Bottom >= aOuterRect.Top)  and (aInnerRect.Bottom <= aOuterRect.Bottom);
  59. end;
  60. //
  61. function RectIsEmpty(const aRect:TRect):Boolean;
  62. begin
  63.   Result :=  (aRect.Left  = 0) and (aRect.Top    = 0)
  64.          and (aRect.Right = 0) and (aRect.Bottom = 0);
  65. end;
  66.  
  67. function ToRect(const aTopLeft, aBottomRight:TPoint):TRect; overload;
  68. begin
  69.   Result.TopLeft     := aTopLeft;
  70.   Result.BottomRight := aBottomRight;
  71. end;
  72.  
  73. function ToRect(const aTop, aLeft, aBottom, aRight : LongInt):TRect; overload;
  74. begin
  75.   Result.Top    := aTop;
  76.   Result.Left   := aLeft;
  77.   Result.Bottom := aBottom;
  78.   Result.Right  := aRight;
  79. end;
  80.  
  81.  
  82. procedure TForm1.btnFindFirstClick(Sender: TObject);
  83. var
  84.   vMatches    :Integer;
  85.   vOutOfBlock :Boolean;
  86.   function Search :LongInt;
  87.   begin
  88.     Result := SynEdit1.SearchReplaceEx(edtFind.Text, '', FSearchOpts, FSrch_rng);
  89.     if  (Result > 0) then begin
  90.       if (not RectIsEmpty(FInBlock)) and (not RectInRect(FInBlock,ToRect(SynEdit1.BlockBegin, SynEdit1.BlockEnd))) then begin
  91.         vOutOfBlock := True;
  92.         Result := 0;
  93.       end;
  94.     end;
  95.   end;
  96.  
  97. begin
  98.   vOutOfBlock := False;
  99.   if (Sender = btnFindNext) then begin
  100.     if SynEdit1.SelAvail then
  101.       FSrch_rng := SynEdit1.BlockEnd
  102.     else
  103.       FSrch_rng := SynEdit1.CaretXY;
  104.   end else begin
  105.     if xbxFromTop.Checked then
  106.       FSrch_rng := Point(1,1)
  107.     else
  108.       FSrch_rng := SynEdit1.CaretXY;
  109.     FSearchOpts := [];
  110.     if (SynEdit1.SelAvail) then begin
  111.       FInBlock.TopLeft     := SynEdit1.BlockBegin;
  112.       FInBlock.BottomRight := SynEdit1.BlockEnd;
  113.     end else
  114.       FInBlock := cEmptyRect;
  115.   end;
  116.  
  117.   if (SynEdit1.SelAvail) and (Sender = btnFindFirst) then begin
  118.     Include(FSearchOpts, ssoSelectedOnly);
  119.   end;
  120.  
  121.   if xbxFromTop.Checked then
  122.     FSearchOpts := FSearchOpts + [ssoEntireScope]
  123.   else begin
  124.     FSearchOpts := FSearchOpts - [ssoEntireScope];
  125.   end;
  126.  
  127.   if rgDirection.ItemIndex = 1 then
  128.     Include(FSearchOpts, ssoBackwards);
  129.  
  130.   if xbxWhole.Checked then
  131.     Include(FSearchOpts, ssoWholeWord);
  132.  
  133.   if xbxMatchCase.Checked then
  134.     Include(FSearchOpts, ssoMatchCase);
  135.  
  136.   if Sender = btnFindNext then begin
  137.     Exclude(FSearchOpts, ssoEntireScope);
  138.     Exclude(FSearchOpts, ssoSelectedOnly);
  139.     Include(FSearchOpts, ssoFindContinue);
  140.   end;
  141.  
  142.   vMatches := Search;
  143.  
  144.   if vMatches > 0 then begin
  145.     btnFindNext.Enabled := True;
  146.   end else begin
  147.     btnFindNext.Enabled := False;
  148.     FInBlock := cEmptyRect; //start a new find.
  149.     if vOutOfBlock then begin
  150.       SynEdit1.CaretXY := FInBlock.BottomRight;
  151.       SynEdit1.EnsureCursorPosVisible;
  152.     end;
  153.     ShowMessage(edtFind.Text + ' not found');
  154.   end;
  155. end;
  156.  
  157. procedure TForm1.btnReplaceFirstClick(Sender: TObject);
  158. var
  159.   vMatches: Integer;
  160.  
  161.   function Search:LongInt;
  162.   begin
  163.     Result := SynEdit1.SearchReplaceEx(edtFind.Text, '', FSearchOpts, FSrch_rng);
  164.     if  (Result > 0) then begin
  165.       if (not RectIsEmpty(FInBlock)) and (not RectInRect(FInBlock, ToRect(SynEdit1.BlockBegin, SynEdit1.BlockEnd))) then
  166.         Result := 0;
  167.     end;
  168.   end;
  169.  
  170. begin
  171.   if (Sender = btnReplaceNext) then begin
  172.     if SynEdit1.SelAvail then
  173.       FSrch_rng := SynEdit1.BlockEnd
  174.     else
  175.       FSrch_rng := SynEdit1.CaretXY;
  176.   end else begin
  177.     if xbxFromTop.Checked then
  178.       FSrch_rng := Point(1,1)
  179.     else
  180.       FSrch_rng := SynEdit1.CaretXY;
  181.     FSearchOpts := [];
  182.   end;
  183.  
  184.   if rgDirection.ItemIndex = 1 then
  185.     Include(FSearchOpts, ssoBackwards);
  186.  
  187.   if xbxWhole.Checked then
  188.     Include(FSearchOpts, ssoWholeWord);
  189.  
  190.   if xbxMatchCase.Checked then
  191.     Include(FSearchOpts, ssoMatchCase);
  192.  
  193.   if xbxFromTop.Checked then
  194.     FSearchOpts := FSearchOpts + [ssoEntireScope]
  195.   else begin
  196.     FSearchOpts := FSearchOpts - [ssoEntireScope];
  197.   end;
  198.  
  199.   if SynEdit1.SelAvail and (sender = btnReplaceFirst) then begin
  200.     Include(FSearchOpts, ssoSelectedOnly);
  201.     FInBlock.TopLeft     := SynEdit1.BlockBegin;
  202.     FInBlock.BottomRight := SynEdit1.BlockEnd;
  203.   end;
  204.  
  205.    Include(FSearchOpts, ssoPrompt);
  206.  
  207.   if Sender = btnReplaceAll then
  208.     Include(FSearchOpts, ssoReplaceAll)
  209.   else
  210.     Include(FSearchOpts, ssoReplace);
  211.  
  212.   vMatches := SynEdit1.SearchReplaceEx(edtFind.Text, edtRplc.Text, FSearchOpts, fsrch_rng);
  213.   if vMatches > 0 then
  214.     begin
  215.       ShowMessage(IntToStr(vMatches) + ' Replaced');
  216.     end;
  217. end;
  218.  
  219. constructor TForm1.Create(TheOwner :TComponent);
  220. begin
  221.   inherited Create(TheOwner);
  222.   FInBlock := cEmptyRect;
  223. end;
  224.  
  225. {TSynSearchOption =
  226.   ( ssoMatchCase, ssoWholeWord,
  227.     ssoBackwards,
  228.     ssoEntireScope, ssoSelectedOnly,
  229.     ssoReplace, ssoReplaceAll,
  230.     ssoPrompt,
  231.     ssoSearchInReplacement,    // continue search-replace in replacement (with ssoReplaceAll) // replace recursive
  232.     ssoRegExpr, ssoRegExprMultiLine,
  233.     ssoFindContinue}
  234.  
  235. end.
  236.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: SynEdit.SearchReplaceEx Example
« Reply #8 on: April 01, 2018, 02:48:17 pm »
sorry forgot the lfm file
Code: [Select]
object Form1: TForm1
  Left = 478
  Height = 482
  Top = 167
  Width = 783
  Caption = 'Form1'
  ClientHeight = 482
  ClientWidth = 783
  LCLVersion = '1.8.2.0'
  inline SynEdit1: TSynEdit
    Left = 0
    Height = 482
    Top = 0
    Width = 320
    Align = alLeft
    Font.Height = -13
    Font.Name = 'Courier New'
    Font.Pitch = fpFixed
    Font.Quality = fqNonAntialiased
    ParentColor = False
    ParentFont = False
    TabOrder = 0
    Gutter.Width = 65
    Gutter.MouseActions = <>
    RightGutter.Width = 0
    RightGutter.MouseActions = <>
    Keystrokes = <   
      item
        Command = ecUp
        ShortCut = 38
      end   
      item
        Command = ecSelUp
        ShortCut = 8230
      end   
      item
        Command = ecScrollUp
        ShortCut = 16422
      end   
      item
        Command = ecDown
        ShortCut = 40
      end   
      item
        Command = ecSelDown
        ShortCut = 8232
      end   
      item
        Command = ecScrollDown
        ShortCut = 16424
      end   
      item
        Command = ecLeft
        ShortCut = 37
      end   
      item
        Command = ecSelLeft
        ShortCut = 8229
      end   
      item
        Command = ecWordLeft
        ShortCut = 16421
      end   
      item
        Command = ecSelWordLeft
        ShortCut = 24613
      end   
      item
        Command = ecRight
        ShortCut = 39
      end   
      item
        Command = ecSelRight
        ShortCut = 8231
      end   
      item
        Command = ecWordRight
        ShortCut = 16423
      end   
      item
        Command = ecSelWordRight
        ShortCut = 24615
      end   
      item
        Command = ecPageDown
        ShortCut = 34
      end   
      item
        Command = ecSelPageDown
        ShortCut = 8226
      end   
      item
        Command = ecPageBottom
        ShortCut = 16418
      end   
      item
        Command = ecSelPageBottom
        ShortCut = 24610
      end   
      item
        Command = ecPageUp
        ShortCut = 33
      end   
      item
        Command = ecSelPageUp
        ShortCut = 8225
      end   
      item
        Command = ecPageTop
        ShortCut = 16417
      end   
      item
        Command = ecSelPageTop
        ShortCut = 24609
      end   
      item
        Command = ecLineStart
        ShortCut = 36
      end   
      item
        Command = ecSelLineStart
        ShortCut = 8228
      end   
      item
        Command = ecEditorTop
        ShortCut = 16420
      end   
      item
        Command = ecSelEditorTop
        ShortCut = 24612
      end   
      item
        Command = ecLineEnd
        ShortCut = 35
      end   
      item
        Command = ecSelLineEnd
        ShortCut = 8227
      end   
      item
        Command = ecEditorBottom
        ShortCut = 16419
      end   
      item
        Command = ecSelEditorBottom
        ShortCut = 24611
      end   
      item
        Command = ecToggleMode
        ShortCut = 45
      end   
      item
        Command = ecCopy
        ShortCut = 16429
      end   
      item
        Command = ecPaste
        ShortCut = 8237
      end   
      item
        Command = ecDeleteChar
        ShortCut = 46
      end   
      item
        Command = ecCut
        ShortCut = 8238
      end   
      item
        Command = ecDeleteLastChar
        ShortCut = 8
      end   
      item
        Command = ecDeleteLastChar
        ShortCut = 8200
      end   
      item
        Command = ecDeleteLastWord
        ShortCut = 16392
      end   
      item
        Command = ecUndo
        ShortCut = 32776
      end   
      item
        Command = ecRedo
        ShortCut = 40968
      end   
      item
        Command = ecLineBreak
        ShortCut = 13
      end   
      item
        Command = ecSelectAll
        ShortCut = 16449
      end   
      item
        Command = ecCopy
        ShortCut = 16451
      end   
      item
        Command = ecBlockIndent
        ShortCut = 24649
      end   
      item
        Command = ecLineBreak
        ShortCut = 16461
      end   
      item
        Command = ecInsertLine
        ShortCut = 16462
      end   
      item
        Command = ecDeleteWord
        ShortCut = 16468
      end   
      item
        Command = ecBlockUnindent
        ShortCut = 24661
      end   
      item
        Command = ecPaste
        ShortCut = 16470
      end   
      item
        Command = ecCut
        ShortCut = 16472
      end   
      item
        Command = ecDeleteLine
        ShortCut = 16473
      end   
      item
        Command = ecDeleteEOL
        ShortCut = 24665
      end   
      item
        Command = ecUndo
        ShortCut = 16474
      end   
      item
        Command = ecRedo
        ShortCut = 24666
      end   
      item
        Command = ecGotoMarker0
        ShortCut = 16432
      end   
      item
        Command = ecGotoMarker1
        ShortCut = 16433
      end   
      item
        Command = ecGotoMarker2
        ShortCut = 16434
      end   
      item
        Command = ecGotoMarker3
        ShortCut = 16435
      end   
      item
        Command = ecGotoMarker4
        ShortCut = 16436
      end   
      item
        Command = ecGotoMarker5
        ShortCut = 16437
      end   
      item
        Command = ecGotoMarker6
        ShortCut = 16438
      end   
      item
        Command = ecGotoMarker7
        ShortCut = 16439
      end   
      item
        Command = ecGotoMarker8
        ShortCut = 16440
      end   
      item
        Command = ecGotoMarker9
        ShortCut = 16441
      end   
      item
        Command = ecSetMarker0
        ShortCut = 24624
      end   
      item
        Command = ecSetMarker1
        ShortCut = 24625
      end   
      item
        Command = ecSetMarker2
        ShortCut = 24626
      end   
      item
        Command = ecSetMarker3
        ShortCut = 24627
      end   
      item
        Command = ecSetMarker4
        ShortCut = 24628
      end   
      item
        Command = ecSetMarker5
        ShortCut = 24629
      end   
      item
        Command = ecSetMarker6
        ShortCut = 24630
      end   
      item
        Command = ecSetMarker7
        ShortCut = 24631
      end   
      item
        Command = ecSetMarker8
        ShortCut = 24632
      end   
      item
        Command = ecSetMarker9
        ShortCut = 24633
      end   
      item
        Command = EcFoldLevel1
        ShortCut = 41009
      end   
      item
        Command = EcFoldLevel2
        ShortCut = 41010
      end   
      item
        Command = EcFoldLevel3
        ShortCut = 41011
      end   
      item
        Command = EcFoldLevel4
        ShortCut = 41012
      end   
      item
        Command = EcFoldLevel5
        ShortCut = 41013
      end   
      item
        Command = EcFoldLevel6
        ShortCut = 41014
      end   
      item
        Command = EcFoldLevel7
        ShortCut = 41015
      end   
      item
        Command = EcFoldLevel8
        ShortCut = 41016
      end   
      item
        Command = EcFoldLevel9
        ShortCut = 41017
      end   
      item
        Command = EcFoldLevel0
        ShortCut = 41008
      end   
      item
        Command = EcFoldCurrent
        ShortCut = 41005
      end   
      item
        Command = EcUnFoldCurrent
        ShortCut = 41003
      end   
      item
        Command = EcToggleMarkupWord
        ShortCut = 32845
      end   
      item
        Command = ecNormalSelect
        ShortCut = 24654
      end   
      item
        Command = ecColumnSelect
        ShortCut = 24643
      end   
      item
        Command = ecLineSelect
        ShortCut = 24652
      end   
      item
        Command = ecTab
        ShortCut = 9
      end   
      item
        Command = ecShiftTab
        ShortCut = 8201
      end   
      item
        Command = ecMatchBracket
        ShortCut = 24642
      end   
      item
        Command = ecColSelUp
        ShortCut = 40998
      end   
      item
        Command = ecColSelDown
        ShortCut = 41000
      end   
      item
        Command = ecColSelLeft
        ShortCut = 40997
      end   
      item
        Command = ecColSelRight
        ShortCut = 40999
      end   
      item
        Command = ecColSelPageDown
        ShortCut = 40994
      end   
      item
        Command = ecColSelPageBottom
        ShortCut = 57378
      end   
      item
        Command = ecColSelPageUp
        ShortCut = 40993
      end   
      item
        Command = ecColSelPageTop
        ShortCut = 57377
      end   
      item
        Command = ecColSelLineStart
        ShortCut = 40996
      end   
      item
        Command = ecColSelLineEnd
        ShortCut = 40995
      end   
      item
        Command = ecColSelEditorTop
        ShortCut = 57380
      end   
      item
        Command = ecColSelEditorBottom
        ShortCut = 57379
      end>
    MouseActions = <>
    MouseTextActions = <>
    MouseSelActions = <>
    Lines.Strings = (
      'spontaneous'
      'discriminate'
      'competition'
      'responsibility'
      'literature'
      'manufacturer'
      'organisation'
      'implication'
      'superintendent'
      'photocopy'
      'available'
      'constellation'
      'anniversary'
      'technology'
      'reputation'
      'redundancy'
      'personality'
      'fashionable'
      'environmental'
      'constitutional'
      'hypothesize'
      'nationalism'
      'electronics'
      'achievement'
      'ambiguous'
      'characteristic'
      'embarrassment'
      'accessible'
      'artificial'
      'deteriorate'
      'systematic'
      'nationalist'
      'prosecution'
      'contradiction'
      'distributor'
      'favorable'
      'intervention'
      'temporary'
      'development'
      'possibility'
      'remunerate'
      'intermediate'
      'minority'
      'publication'
      'policeman'
      'declaration'
      'apparatus'
      'economy'
      'conversation'
      'beneficiary'
      'interactive'
      'correspondence'
      'astonishing'
      'calculation'
      'application'
      'nomination'
      'generation'
      'intensify'
      'complication'
      'acceptable'
      'affinity'
      'comfortable'
      'mechanical'
      'notorious'
      'ordinary'
      'deprivation'
      'machinery'
      'lifestyle'
      'multimedia'
      'catalogue'
      'resignation'
      'radiation sickness'
      'association'
      'requirement'
      'economics'
      'excavation'
      'community'
      'respectable'
      'communication'
      'philosophy'
      'identity'
      'disappointment'
      'hypothesis'
      'disposition'
      'understanding'
      'computer virus'
      'ambiguity'
      'uncertainty'
      'legislature'
      'beautiful'
      'curriculum'
      'inhabitant'
      'exhibition'
      'literacy'
      'cooperation'
      'population'
      'intelligence'
      'consciousness'
      'economic'
      'inhibition'
      'confrontation'
      'incapable'
      'celebration'
      'operational'
      'salesperson'
      'analysis'
      'comprehensive'
      'continuation'
      'indication'
      'supplementary'
      'investigation'
      'security'
      'authority'
      'hilarious'
      'miserable'
      'executive'
      'charismatic'
      'cemetery'
      'firefighter'
      'resolution'
      'constitution'
      'executrix'
      'television'
      'monopoly'
      'stimulation'
      'preparation'
      'photocopy'
      'diplomatic'
      'acquisition'
      'eliminate'
      'unfortunate'
      'fastidious'
      'exploration'
      'empirical'
      'conspiracy'
      'entertainment'
      'dictionary'
      'representative'
      'rehabilitation'
      'timetable'
      'consideration'
      'integration'
      'circulation'
      'environment'
      'unanimous'
      'discovery'
      'presidential'
      'engagement'
      'simplicity'
      'responsible'
      'conventional'
      'cooperative'
      'reconcile'
      'democratic'
      'accumulation'
      'economist'
      'introduction'
      'examination'
      'epicalyx'
      'refrigerator'
      'consolidate'
      'ideology'
      'nonremittal'
      'negotiation'
      'acquaintance'
      'academy'
      'education'
      'gregarious'
      'spokesperson'
      'regulation'
      'demonstration'
      'extraterrestrial'
      'strikebreaker'
      'preoccupation'
      'consultation'
      'anticipation'
      'evolution'
      'federation'
      'deficiency'
      'satisfaction'
      'entitlement'
      'delivery'
      'invisible'
      'motivation'
      'temperature'
      'innovation'
      'litigation'
      'advertising'
      'econobox'
      'original'
      'emergency'
      'vegetation'
      'management'
      'combination'
      'experiment'
      'vegetable'
      'photocopy'
      'presentation'
      'hospitality'
      'facility'
    )
    VisibleSpecialChars = [vscSpace, vscTabAtLast]
    SelectedColor.BackPriority = 50
    SelectedColor.ForePriority = 50
    SelectedColor.FramePriority = 50
    SelectedColor.BoldPriority = 50
    SelectedColor.ItalicPriority = 50
    SelectedColor.UnderlinePriority = 50
    SelectedColor.StrikeOutPriority = 50
    BracketHighlightStyle = sbhsBoth
    BracketMatchColor.Background = clNone
    BracketMatchColor.Foreground = clNone
    BracketMatchColor.Style = [fsBold]
    FoldedCodeColor.Background = clNone
    FoldedCodeColor.Foreground = clGray
    FoldedCodeColor.FrameColor = clGray
    MouseLinkColor.Background = clNone
    MouseLinkColor.Foreground = clBlue
    LineHighlightColor.Background = clNone
    LineHighlightColor.Foreground = clNone
    inline SynLeftGutterPartList1: TSynGutterPartList
      object SynGutterMarks1: TSynGutterMarks
        Width = 24
        MouseActions = <>
      end
      object SynGutterLineNumber1: TSynGutterLineNumber
        Width = 25
        MouseActions = <>
        MarkupInfo.Background = clBtnFace
        MarkupInfo.Foreground = clNone
        DigitCount = 2
        ShowOnlyLineNumbersMultiplesOf = 1
        ZeroStart = False
        LeadingZeros = False
      end
      object SynGutterChanges1: TSynGutterChanges
        Width = 4
        MouseActions = <>
        ModifiedColor = 59900
        SavedColor = clGreen
      end
      object SynGutterSeparator1: TSynGutterSeparator
        Width = 2
        MouseActions = <>
        MarkupInfo.Background = clWhite
        MarkupInfo.Foreground = clGray
      end
      object SynGutterCodeFolding1: TSynGutterCodeFolding
        MouseActions = <>
        MarkupInfo.Background = clNone
        MarkupInfo.Foreground = clGray
        MouseActionsExpanded = <>
        MouseActionsCollapsed = <>
      end
    end
  end
  object btnFindFirst: TButton
    Left = 432
    Height = 25
    Top = 109
    Width = 75
    Caption = 'FIND'
    Default = True
    OnClick = btnFindFirstClick
    TabOrder = 1
  end
  object edtFind: TEdit
    Left = 336
    Height = 23
    Top = 109
    Width = 88
    TabOrder = 2
    Text = 'Photocopy'
  end
  object btnFindNext: TButton
    Left = 515
    Height = 25
    Top = 109
    Width = 75
    Caption = 'Find Next'
    OnClick = btnFindFirstClick
    TabOrder = 3
  end
  object btnReplaceFirst: TButton
    Left = 432
    Height = 25
    Top = 181
    Width = 75
    Caption = 'Replace'
    OnClick = btnReplaceFirstClick
    TabOrder = 4
  end
  object btnReplaceNext: TButton
    Left = 515
    Height = 25
    Top = 182
    Width = 75
    Caption = 'Rplc Next'
    OnClick = btnReplaceFirstClick
    TabOrder = 5
  end
  object edtRplc: TEdit
    Left = 336
    Height = 23
    Top = 181
    Width = 88
    TabOrder = 6
    Text = 'FaxMachine'
  end
  object btnReplaceAll: TButton
    Left = 602
    Height = 25
    Top = 182
    Width = 75
    Caption = 'Replace All'
    OnClick = btnReplaceFirstClick
    TabOrder = 7
  end
  object rgDirection: TRadioGroup
    Left = 328
    Height = 49
    Top = 16
    Width = 185
    AutoFill = True
    Caption = 'Direction'
    ChildSizing.LeftRightSpacing = 6
    ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
    ChildSizing.EnlargeVertical = crsHomogenousChildResize
    ChildSizing.ShrinkHorizontal = crsScaleChilds
    ChildSizing.ShrinkVertical = crsScaleChilds
    ChildSizing.Layout = cclLeftToRightThenTopToBottom
    ChildSizing.ControlsPerLine = 2
    ClientHeight = 29
    ClientWidth = 181
    Columns = 2
    ItemIndex = 0
    Items.Strings = (
      'Down'
      'Up'
    )
    TabOrder = 8
  end
  object xbxWhole: TCheckBox
    Left = 528
    Height = 19
    Top = 19
    Width = 115
    Caption = 'Whole words only'
    TabOrder = 9
  end
  object xbxMatchCase: TCheckBox
    Left = 528
    Height = 19
    Top = 43
    Width = 82
    Caption = 'Match Case'
    TabOrder = 10
  end
  object xbxFromTop: TCheckBox
    Left = 652
    Height = 19
    Top = 19
    Width = 125
    Caption = 'From the Beggining'
    TabOrder = 11
  end
end
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

RedOctober

  • Sr. Member
  • ****
  • Posts: 452
Re: SynEdit.SearchReplaceEx Example
« Reply #9 on: May 02, 2018, 11:56:10 pm »
I finally got the whole SearchReplace function working.  It turns out I was trying to "do too much" for the SearchReplaceEx.  It does everything by itself.  The tricky part is figuring out how to tell it what you want.  I am posting this code to the community in case anyone else needs a working "Find Replace" example for TSynEdit.

Usage:  Call the form and set the "Search Component" to the TSynEdit you want searched.

Code: Pascal  [Select][+][-]
  1. unit f_find_rplc;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls, CheckLst, EditBtn,
  9.   SynEdit, SynEditTypes, LCLType, ExtCtrls, Buttons;
  10.  
  11. type
  12.  
  13.   { TfrmFindRplc }
  14.  
  15.   TfrmFindRplc = class(TForm)
  16.     btnFindFst: TButton;
  17.     btnFindNxt: TButton;
  18.     btnRplcFst1: TButton;
  19.     btnRplcNxt: TButton;
  20.     btnRplcFst: TButton;
  21.     btnRplcAll: TButton;
  22.     edtFind: TEdit;
  23.     edtRplc: TEdit;
  24.     imglst: TImageList;
  25.     Label1: TLabel;
  26.     Label2: TLabel;
  27.     sbar: TStatusBar;
  28.     sbtnDir: TSpeedButton;
  29.     xbxMatchCase: TCheckBox;
  30.     xbxRplc: TCheckBox;
  31.     xbxWhole: TCheckBox;
  32.     xbxSelectionOnly: TCheckBox;
  33.     procedure btnCancelClick(Sender: TObject);
  34.     procedure btnFindFstClick(Sender: TObject);
  35.     procedure btnRplcFst1Click(Sender: TObject);
  36.     procedure btnRplcFstClick(Sender: TObject);
  37.     procedure edtFindChange(Sender: TObject);
  38.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  39.     procedure FormCreate(Sender: TObject);
  40.     procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  41.     procedure sbtnDirClick(Sender: TObject);
  42.     procedure xbxRplcClick(Sender: TObject);
  43.   private
  44.     is_blk: Boolean;
  45.     mode: String;
  46.     srch_cmp: TSynEdit;
  47.     ts0_result: UInt64;
  48.     start_at, fnd_cnt: UInt64;
  49.     start_pnt: TPoint;
  50.     sql_instance_id: Integer;
  51.     srch_for, rplc_wth: String;
  52.     srch_ops: TSynSearchOptions;
  53.     srch_dir: Integer;
  54.     procedure DoFindRplc(Sender: TObject);
  55.     procedure LoadDefaults;
  56.  
  57.   public
  58.     procedure SetSrchCmp(const Asrch_cmp: TSynEdit; const Asql_instance_id: Integer);
  59.   end;
  60.  
  61. var
  62.   frmFindRplc: TfrmFindRplc;
  63.  
  64.  
  65. implementation
  66.  
  67. {$R *.lfm}
  68.  
  69. { TfrmFindRplc }
  70.  
  71. procedure TfrmFindRplc.FormCreate(Sender: TObject);
  72. begin
  73.   LoadDefaults;
  74. end;
  75.  
  76. procedure TfrmFindRplc.LoadDefaults;
  77. begin
  78.   srch_dir := 0;
  79.   sbtnDir.Glyph := nil;
  80.   imglst.GetBitmap(srch_dir, sbtnDir.Glyph);
  81. end;
  82.  
  83. procedure TfrmFindRplc.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  84. begin
  85.   CloseAction := caHide;
  86. end;
  87.  
  88. procedure TfrmFindRplc.btnCancelClick(Sender: TObject);
  89. begin
  90.   Close;
  91. end;
  92.  
  93. procedure TfrmFindRplc.btnFindFstClick(Sender: TObject);
  94. begin
  95.   DoFindRplc(Sender);
  96. end;
  97.  
  98. procedure TfrmFindRplc.btnRplcFst1Click(Sender: TObject);
  99. begin
  100.   Close;
  101. end;
  102.  
  103. procedure TfrmFindRplc.btnRplcFstClick(Sender: TObject);
  104. begin
  105.   DoFindRplc(Sender);
  106. end;
  107.  
  108. procedure TfrmFindRplc.edtFindChange(Sender: TObject);
  109. begin
  110.   xbxRplc.Checked := False;
  111.   xbxRplcClick(Sender);
  112. end;
  113.  
  114. procedure TfrmFindRplc.DoFindRplc(Sender: TObject);
  115. begin
  116.   if (Length(edtFind.Text) = 0) then
  117.     Exit;
  118.  
  119.   srch_for := edtFind.Text;
  120.   rplc_wth := '';
  121.   srch_ops := [];
  122.  
  123.   start_pnt := srch_cmp.LogicalCaretXY;
  124.  
  125.   if (srch_dir = 1) then
  126.     Include(srch_ops, ssoBackwards);
  127.  
  128.   if Sender = btnFindFst then
  129.     Include(srch_ops, ssoEntireScope);
  130.  
  131.   if Sender = btnFindNxt then
  132.     Include(srch_ops, ssoFindContinue);
  133.  
  134.   if Sender = btnRplcFst then
  135.     Include(srch_ops, ssoReplace);
  136.  
  137.   if Sender = btnRplcNxt then
  138.     begin
  139.       Include(srch_ops, ssoReplace);
  140.       Include(srch_ops, ssoFindContinue);
  141.     end;
  142.  
  143.   if Sender = btnRplcAll then
  144.     Include(srch_ops, ssoReplaceAll);
  145.  
  146.   if xbxRplc.Checked then
  147.     rplc_wth := edtRplc.Text;
  148.  
  149.   if xbxSelectionOnly.Checked then
  150.     Include(srch_ops, ssoSelectedOnly);
  151.  
  152.   if xbxWhole.Checked then
  153.     Include(srch_ops, ssoWholeWord);
  154.  
  155.   if xbxMatchCase.Checked then
  156.     Include(srch_ops, ssoMatchCase);
  157.  
  158.   fnd_cnt := srch_cmp.SearchReplaceEx(srch_for, rplc_wth, srch_ops, start_pnt);
  159.   if fnd_cnt > 0 then
  160.     begin
  161.       sbar.Panels[0].Text := ' Start: ' + IntToStr(start_pnt.x) + '.' + IntToStr(start_pnt.y);
  162.       sbar.Panels[1].Text := ' Cursor: ' + IntToStr(srch_cmp.LogicalCaretXY.x) + '.' + IntToStr(srch_cmp.LogicalCaretXY.y);
  163.       sbar.Panels[2].Text := ' Found: ' + IntToStr(fnd_cnt);
  164.     end
  165.   else
  166.     begin
  167.       ShowMessage('Search term: "' + srch_for + '" not found.');
  168.     end;
  169. end;
  170.  
  171. procedure TfrmFindRplc.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  172. begin
  173.   if Key = VK_ESCAPE then
  174.     Close;
  175. end;
  176.  
  177. procedure TfrmFindRplc.sbtnDirClick(Sender: TObject);
  178. begin
  179.   if srch_dir = 0 then
  180.     srch_dir := 1
  181.   else
  182.     srch_dir := 0;
  183.  
  184.   sbtnDir.Glyph := nil;
  185.   imglst.GetBitmap(srch_dir, sbtnDir.Glyph);
  186.  
  187. end;
  188.  
  189. procedure TfrmFindRplc.xbxRplcClick(Sender: TObject);
  190. begin
  191.   edtRplc.Enabled := xbxRplc.Checked;
  192.   btnRplcFst.Enabled := xbxRplc.Checked;
  193.   btnRplcAll.Enabled := xbxRplc.Checked;
  194. end;
  195.  
  196. procedure TfrmFindRplc.SetSrchCmp(const Asrch_cmp: TSynEdit; const Asql_instance_id: Integer);
  197. begin
  198.   srch_cmp := Asrch_cmp;
  199.   sql_instance_id := Asql_instance_id;
  200. end;
  201.  
  202. end.
  203.  
  204.  

 

TinyPortal © 2005-2018