Check-in [083aa4a165]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added scaffolding for VCS client interface.
Timelines: family | ancestors | descendants | both | feature/rewrite-multi-async
Files: files | file ages | folders
SHA1: 083aa4a1658418563c46936ed6c0f2b90bd39bbf
User & Date: tinus 2016-02-21 15:22:31
Context
2016-02-22
18:34
Added console running code to TVCSClient. check-in: 20d7dd8edd user: tinus tags: feature/rewrite-multi-async
2016-02-21
15:22
Added scaffolding for VCS client interface. check-in: 083aa4a165 user: tinus tags: feature/rewrite-multi-async
13:00
Register a module notifier for each file opened, and unregister it on destruction. check-in: 9368ecb481 user: tinus tags: feature/rewrite-multi-async
Changes

Changes to src/Delphi10/VCSInfo_XSeattle.dpr.

11
12
13
14
15
16
17
18


19
20
21
22
23
  using PChar or ShortString parameters. }

{$R *.dres}

uses
  System.SysUtils,
  System.Classes,
  VCSInfoWzrd in '..\VCSInfoWzrd.pas';



{$R *.res}

begin
end.







|
>
>





11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  using PChar or ShortString parameters. }

{$R *.dres}

uses
  System.SysUtils,
  System.Classes,
  vcsinfo.InfoWzrd in '..\vcsinfo.InfoWzrd.pas',
  vcsinfo.VCSClient in '..\vcsinfo.VCSClient.pas',
  vcsinfo.Fossil in '..\vcsinfo.Fossil.pas';

{$R *.res}

begin
end.

Changes to src/Delphi10/VCSInfo_XSeattle.dproj.

96
97
98
99
100
101
102


103
104
105
106
107

108
109
110
111
112
113
114
...
148
149
150
151
152
153
154
155




156
157






158
159
160





161
162
163
164
165
166
167
...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
        <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
        <DCC_DebugInformation>0</DCC_DebugInformation>
    </PropertyGroup>
    <ItemGroup>
        <DelphiCompile Include="$(MainSource)">
            <MainSource>MainSource</MainSource>
        </DelphiCompile>


        <DCCReference Include="..\VCSInfoWzrd.pas"/>
        <RcItem Include="..\Res\logo.bmp">
            <ResourceType>BITMAP</ResourceType>
            <ResourceId>BMP_LOGO</ResourceId>
        </RcItem>

        <BuildConfiguration Include="Release">
            <Key>Cfg_2</Key>
            <CfgParent>Base</CfgParent>
        </BuildConfiguration>
        <BuildConfiguration Include="Base">
            <Key>Base</Key>
        </BuildConfiguration>
................................................................................
                </DeployFile>
                <DeployFile LocalName="..\..\out\Win32\Debug\VCSInfo_XSeattle.dll" Configuration="Debug" Class="ProjectOutput">
                    <Platform Name="Win32">
                        <RemoteName>VCSInfo_XSeattle.dll</RemoteName>
                        <Overwrite>true</Overwrite>
                    </Platform>
                </DeployFile>
                <DeployClass Name="ProjectiOSDeviceResourceRules">




                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>






                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>





                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectOSXResource">
                    <Platform Name="OSX32">
                        <RemoteDir>Contents\Resources</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
................................................................................
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon36">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-ldpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="DependencyModule">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                        <Extensions>.dll;.bpl</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="OSX32">
                        <RemoteDir>Contents\MacOS</RemoteDir>
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                </DeployClass>
                <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>







>
>
|




>







 







|
>
>
>
>


>
>
>
>
>
>



>
>
>
>
>







 







|
<
<
<
<


<
<
<
<
<
<



<
<
<
<
<







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
525
526
527
528
529
530
531
532




533
534






535
536
537





538
539
540
541
542
543
544
        <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
        <DCC_DebugInformation>0</DCC_DebugInformation>
    </PropertyGroup>
    <ItemGroup>
        <DelphiCompile Include="$(MainSource)">
            <MainSource>MainSource</MainSource>
        </DelphiCompile>
        <DCCReference Include="..\vcsinfo.InfoWzrd.pas"/>
        <DCCReference Include="..\vcsinfo.VCSClient.pas"/>
        <DCCReference Include="..\vcsinfo.Fossil.pas"/>
        <RcItem Include="..\Res\logo.bmp">
            <ResourceType>BITMAP</ResourceType>
            <ResourceId>BMP_LOGO</ResourceId>
        </RcItem>
        <None Include="..\..\todo.md"/>
        <BuildConfiguration Include="Release">
            <Key>Cfg_2</Key>
            <CfgParent>Base</CfgParent>
        </BuildConfiguration>
        <BuildConfiguration Include="Base">
            <Key>Base</Key>
        </BuildConfiguration>
................................................................................
                </DeployFile>
                <DeployFile LocalName="..\..\out\Win32\Debug\VCSInfo_XSeattle.dll" Configuration="Debug" Class="ProjectOutput">
                    <Platform Name="Win32">
                        <RemoteName>VCSInfo_XSeattle.dll</RemoteName>
                        <Overwrite>true</Overwrite>
                    </Platform>
                </DeployFile>
                <DeployClass Name="DependencyModule">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                        <Extensions>.dll;.bpl</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="OSX32">
                        <RemoteDir>Contents\MacOS</RemoteDir>
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectOSXResource">
                    <Platform Name="OSX32">
                        <RemoteDir>Contents\Resources</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
................................................................................
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon36">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-ldpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectiOSDeviceResourceRules">




                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>






                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>





                    </Platform>
                </DeployClass>
                <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>

Added src/vcsinfo.Fossil.pas.







































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
unit vcsinfo.Fossil;

interface
uses
  vcsinfo.VCSClient;

type
  TVCSFossil = class(TVCSClient)
  strict protected
    class function IsRepo(const APath: string; out ARootPath: string): boolean; override;
  strict protected
    function  GetExecutable: string; override;
    function  GetUIExecutable: string; override;
    function  GetTitle: string; override;
  public
    constructor Create(const APath: string);
    destructor  Destroy; override;

    function  GetBranches: TArray<string>; override;

    function  GetIncoming: integer; override;
    function  GetOutgoing: integer; override;

    function  GetPendingFiles: integer; override;
    function  GetUntrackedFiles: Integer; override;
    function  GetStatus: TArray<string>; override;

    procedure ShowRepositoryUI; override;
    procedure ShowRemoteUI; override;
    procedure ShowStatusUI; override;
    function  SwitchToBranchUI(const BranchName: string): boolean; override;

    procedure ProcessRename(const OldName, NewName: string); override;
  end;

implementation

{ TVCSFossil }

constructor TVCSFossil.Create(const APath: string);
begin
  inherited;

end;

destructor TVCSFossil.Destroy;
begin

  inherited;
end;

function TVCSFossil.GetBranches: TArray<string>;
begin
  {$MESSAGE WARN 'TODO: fossil branch list; put the current one first'}
end;

function TVCSFossil.GetExecutable: string;
begin
  Result := 'fossil.exe';
end;

function TVCSFossil.GetIncoming: integer;
begin
  {$MESSAGE WARN 'TODO: if remote-url is off, then 0; otherwise -1'}
  Result := -1;
end;

function TVCSFossil.GetOutgoing: integer;
begin
  {$MESSAGE WARN 'TODO: if remote-url is off, or autosync is on, then 0; otherwise -1'}
  Result := -1;
end;

function TVCSFossil.GetPendingFiles: integer;
begin
  {$MESSAGE WARN 'TODO: fossil changes'}
end;

function TVCSFossil.GetStatus: TArray<string>;
begin
  {$MESSAGE WARN 'TODO: fossil status'}
end;

function TVCSFossil.GetTitle: string;
begin
  {$MESSAGE WARN 'TODO: fossil sqlite3 "SELECT value FROM config WHERE name=‘project-name’"'}
end;

function TVCSFossil.GetUIExecutable: string;
begin
  Result := '';
end;

function TVCSFossil.GetUntrackedFiles: Integer;
begin
  {$MESSAGE WARN 'TODO: fossil extras'}
end;

procedure TVCSFossil.ShowRemoteUI;
begin
  {$MESSAGE WARN 'TODO: fossil sync -autourl; show results'}
end;

procedure TVCSFossil.ShowRepositoryUI;
begin
  {$MESSAGE WARN 'TODO: fossil ui'}
end;

procedure TVCSFossil.ProcessRename(const OldName, NewName: string);
begin
  {$MESSAGE WARN 'TODO: fossil rename --soft "OldName" "NewName"'}
end;

procedure TVCSFossil.ShowStatusUI;
begin
  {$MESSAGE WARN 'TODO: fossil gdiff'}
end;

function TVCSFossil.SwitchToBranchUI(const BranchName: string): boolean;
begin
  // TODO: see old VCSInfoMenuWzrd: try fossil checkout first, then dialog with
  //    discard (fossil checkout --force), shelve (fossil stash), merge (fossil update), or cancel
  {$MESSAGE WARN 'TODO: see old VCSInfoMenuWzrd'}
end;

class function TVCSFossil.IsRepo(const APath: string; out ARootPath: string): boolean;
begin
  {$MESSAGE WARN 'TODO: fossil info; extract line for local-root'}
end;

end.

Name change from src/VCSInfoWzrd.pas to src/vcsinfo.InfoWzrd.pas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
unit VCSInfoWzrd;

interface
uses
  Vcl.Graphics,
  ToolsAPI,
  VCSInfoView;

type
  TVCSInfoStatusWizard = class(TNotifierObject, IOTAWizard)
  private
    FLogo: TBitmap;
    FView: TVCSInfoView;
  public
    constructor Create;
    destructor Destroy; override;

    { IOTAWizard }
    function GetIDString: string;
    function GetName: string;
................................................................................
  FLogo.LoadFromResourceName(HInstance, 'BMP_LOGO');
  SplashScreenServices.AddPluginBitmap(rsWizardName, FLogo.Handle,
                                        False, 'Freeware');
  (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(rsWizardName, rsWizardName, FLogo.Handle,
                                                            False, 'Freeware');
  // TODO: set up cache (Model)
  // TODO: set up UI, including timer and notifiers (View)
  FView := TVCSInfoView.Create;
  (BorlandIDEServices as IOTAServices).AddNotifier(FView);
  // TODO: set up thread queue (Controller)
end;

destructor TVCSInfoStatusWizard.Destroy;
begin
  // TODO: destroy all the objects we own
|





|





|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
unit vcsinfo.InfoWzrd;

interface
uses
  Vcl.Graphics,
  ToolsAPI,
  vcsinfo.View;

type
  TVCSInfoStatusWizard = class(TNotifierObject, IOTAWizard)
  private
    FLogo: TBitmap;
    FView: TNotifiers;
  public
    constructor Create;
    destructor Destroy; override;

    { IOTAWizard }
    function GetIDString: string;
    function GetName: string;
................................................................................
  FLogo.LoadFromResourceName(HInstance, 'BMP_LOGO');
  SplashScreenServices.AddPluginBitmap(rsWizardName, FLogo.Handle,
                                        False, 'Freeware');
  (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(rsWizardName, rsWizardName, FLogo.Handle,
                                                            False, 'Freeware');
  // TODO: set up cache (Model)
  // TODO: set up UI, including timer and notifiers (View)
  FView := TNotifiers.Create;
  (BorlandIDEServices as IOTAServices).AddNotifier(FView);
  // TODO: set up thread queue (Controller)
end;

destructor TVCSInfoStatusWizard.Destroy;
begin
  // TODO: destroy all the objects we own

Name change from src/RepoCache.pas to src/vcsinfo.RepoCache.pas.

1
2
3
4
5

6
7
8
9
10
11
12
unit RepoCache;

interface
uses
  System.Generics.Collections;


type
  TRepoInfo = class
  private
    FVCSClient: TVCSClient;
    FRoot: string;
    FLastCheckRepo: TDateTime;




|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
unit RepoCache;

interface
uses
  System.Generics.Collections,
  vcsinfo.VCSClient;

type
  TRepoInfo = class
  private
    FVCSClient: TVCSClient;
    FRoot: string;
    FLastCheckRepo: TDateTime;

Added src/vcsinfo.VCSClient.pas.



























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
unit vcsinfo.VCSClient;

interface
uses
  System.SysUtils, System.Generics.Collections;

type
  EVCSException = class(Exception);

type
  TVCSClient = class;
  TVCSClientClass = class of TVCSClient;

  TVCSClient = class
  public
    class function CreateForPath(const APath: string): TVCSClient;
    class function IsRepo(const APath: string; out ARootPath: string): boolean; virtual; abstract;
    class procedure RegisterVCSClass(const VCSClass: TVCSClientClass);
  strict private
    class var FRegisteredVCSes: TList<TVCSClientClass>;
  strict protected
    FRoot: string;

    function  GetExecutable: string; virtual; abstract;
    function  GetUIExecutable: string; virtual; abstract;
    function  GetTitle: string; virtual;
    function  GetCurrentBranch: string; virtual;
  public
    constructor Create(const APath: string);
    destructor  Destroy; override;

    function  GetBranches: TArray<string>; virtual; abstract;

    function  GetIncoming: integer; virtual; abstract;
    function  GetOutgoing: integer; virtual; abstract;

    function  GetPendingFiles: integer; virtual; abstract;
    function  GetUntrackedFiles: Integer; virtual; abstract;
    function  GetStatus: TArray<string>; virtual; abstract;

    procedure ShowRepositoryUI; virtual; abstract;
    procedure ShowRemoteUI; virtual; abstract;
    procedure ShowStatusUI; virtual; abstract;
    function  SwitchToBranchUI(const BranchName: string): boolean; virtual; abstract;

    procedure ProcessRename(const OldName, NewName: string); virtual; abstract;

    property Executable: string   read GetExecutable;
    property UIExecutable: string read GetUIExecutable;
    property Root: string         read FRoot;
    property Title: string        read GetTitle;

    property CurrentBranch: string  read GetCurrentBranch;
  end;


implementation

{ TVCSClient }

constructor TVCSClient.Create(const APath: string);
begin

end;

destructor TVCSClient.Destroy;
begin

  inherited;
end;


function TVCSClient.GetCurrentBranch: string;
var
  Branches: TArray<string>;
begin
  // ASSUMPTION: the first branch is the current one
  Branches := GetBranches;
  if Length(Branches) > 0 then
    Result := Branches[0]
  else
    Result := '';
end;

function TVCSClient.GetTitle: string;
begin
  Result := ExtractFileName(ExcludeTrailingPathDelimiter(FRoot));
end;

class function TVCSClient.CreateForPath(const APath: string): TVCSClient;
var
  VCSClass: TVCSClientClass;
  RootPath: string;
begin
  for VCSClass in FRegisteredVCSes do begin
    if VCSClass.IsRepo(APath, RootPath) then begin
      Result := VCSClass.Create(APath);
      Exit;
    end;
  end;
  Result := nil;
end;

class procedure TVCSClient.RegisterVCSClass(const VCSClass: TVCSClientClass);
begin
  FRegisteredVCSes.Add(VCSClass);
end;

end.

Name change from src/VCSInfoView.pas to src/vcsinfo.View.pas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
unit VCSInfoView;

interface
uses
  ToolsAPI, System.Classes, System.Generics.Collections;

type
  TVCSInfoView = class(TNotifierObject,
                        IOTAIDENotifier, IOTAIDENotifier50, IOTAIDENotifier80,
                        IOTAModuleNotifier, IOTAModuleNotifier80, IOTAModuleNotifier90)
  private
    FModules: TDictionary<IOTAModule,Integer>;
  public
    constructor Create;
    destructor Destroy; override;
................................................................................

implementation
uses
  System.SysUtils;

{ TVCSInfoView }

constructor TVCSInfoView.Create;
begin
  inherited;
  FModules := TDictionary<IOTAModule,Integer>.Create;
end;

destructor TVCSInfoView.Destroy;
var
  Module: IOTAModule;
begin
  for Module in FModules.Keys do begin
    Module.RemoveNotifier(FModules.Items[Module]);
  end;
  FModules.Free;
  inherited;
end;

procedure TVCSInfoView.LogMessage(const Text: string; const Args: array of const);
begin
  LogMessage(Format(Text, Args));
end;

procedure TVCSInfoView.LogMessage(const Text: string);
const
  RFC3339: TFormatSettings = (DateSeparator: '-'; TimeSeparator: ':';
                              ShortDateFormat: 'yyyy-MM-dd'; LongDateFormat: 'yyyy-MM-dd';
                              ShortTimeFormat: 'hh:nn:ss'; LongTimeFormat: 'hh:nn:ss.zzz');
var
  Messages: IOTAMessageServices;
  Group: IOTAMessageGroup;
................................................................................
  for Line in Text.Replace(#13#10, #10).Split([#10, #13]) do begin
    Messages.AddTitleMessage(TimeStamp + #9 + Line, Group);
    if TimeStamp[1] <> #9 then
      TimeStamp := StringOfChar(#9, 2);
  end;
end {TVCSInfoView.LogMessage};

procedure TVCSInfoView.AfterCompile(Succeeded, IsCodeInsight: Boolean);
begin
end;

procedure TVCSInfoView.AfterCompile(const Project: IOTAProject; Succeeded, IsCodeInsight: Boolean);
begin
  if not IsCodeInsight then begin
    {$MESSAGE WARN 'TODO: update workdir status'}
  end;
end;

procedure TVCSInfoView.AfterCompile(Succeeded: Boolean);
begin
end;

procedure TVCSInfoView.AfterRename(const OldFileName, NewFileName: string);
begin
  {$MESSAGE HINT 'TODO: rename in VCS as well'}
  LogMessage('Renamed "%s" to "%s"', [OldFilename, NewFileName]);
end;

function TVCSInfoView.AllowSave: Boolean;
begin
  Result := True;
  {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in two seconds'}
  LogMessage('AllowSave: %d', [Ord(Result)]);

end;

procedure TVCSInfoView.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
begin
end;

procedure TVCSInfoView.BeforeCompile(const Project: IOTAProject; IsCodeInsight: Boolean;
  var Cancel: Boolean);
begin
end;

procedure TVCSInfoView.BeforeRename(const OldFileName, NewFileName: string);
begin
end;

function TVCSInfoView.CheckOverwrite: Boolean;
begin
  Result := True;
end;

procedure TVCSInfoView.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string;
  var Cancel: Boolean);
var
  NewModule: IOTAModule;
  Index: Integer;
begin
  case NotifyCode of
    ofnFileOpened: begin
................................................................................
    ofnActiveProjectChanged: begin
      {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in a second'}
      LogMessage('Active project changed: "%s"', [FileName]);
    end;
  end;
end;

function TVCSInfoView.GetOverwriteFileName(Index: Integer): string;
begin
  Result := '';
end;

function TVCSInfoView.GetOverwriteFileNameCount: Integer;
begin
  Result := 0;
end;

procedure TVCSInfoView.ModuleRenamed(const NewName: string);
begin
end;

procedure TVCSInfoView.SetSaveFileName(const FileName: string);
begin
end;


end.
|






|







 







|





|










|




|







 







|



|


|



|



|





|




>


|



|




|



|




|







 







|




|




|



|





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
unit vcsinfo.View;

interface
uses
  ToolsAPI, System.Classes, System.Generics.Collections;

type
  TNotifiers = class(TNotifierObject,
                        IOTAIDENotifier, IOTAIDENotifier50, IOTAIDENotifier80,
                        IOTAModuleNotifier, IOTAModuleNotifier80, IOTAModuleNotifier90)
  private
    FModules: TDictionary<IOTAModule,Integer>;
  public
    constructor Create;
    destructor Destroy; override;
................................................................................

implementation
uses
  System.SysUtils;

{ TVCSInfoView }

constructor TNotifiers.Create;
begin
  inherited;
  FModules := TDictionary<IOTAModule,Integer>.Create;
end;

destructor TNotifiers.Destroy;
var
  Module: IOTAModule;
begin
  for Module in FModules.Keys do begin
    Module.RemoveNotifier(FModules.Items[Module]);
  end;
  FModules.Free;
  inherited;
end;

procedure TNotifiers.LogMessage(const Text: string; const Args: array of const);
begin
  LogMessage(Format(Text, Args));
end;

procedure TNotifiers.LogMessage(const Text: string);
const
  RFC3339: TFormatSettings = (DateSeparator: '-'; TimeSeparator: ':';
                              ShortDateFormat: 'yyyy-MM-dd'; LongDateFormat: 'yyyy-MM-dd';
                              ShortTimeFormat: 'hh:nn:ss'; LongTimeFormat: 'hh:nn:ss.zzz');
var
  Messages: IOTAMessageServices;
  Group: IOTAMessageGroup;
................................................................................
  for Line in Text.Replace(#13#10, #10).Split([#10, #13]) do begin
    Messages.AddTitleMessage(TimeStamp + #9 + Line, Group);
    if TimeStamp[1] <> #9 then
      TimeStamp := StringOfChar(#9, 2);
  end;
end {TVCSInfoView.LogMessage};

procedure TNotifiers.AfterCompile(Succeeded, IsCodeInsight: Boolean);
begin
end;

procedure TNotifiers.AfterCompile(const Project: IOTAProject; Succeeded, IsCodeInsight: Boolean);
begin
  if not IsCodeInsight then begin
    {$MESSAGE WARN 'TODO: update project’s workdir status'}
  end;
end;

procedure TNotifiers.AfterCompile(Succeeded: Boolean);
begin
end;

procedure TNotifiers.AfterRename(const OldFileName, NewFileName: string);
begin
  {$MESSAGE HINT 'TODO: rename in VCS as well'}
  LogMessage('Renamed "%s" to "%s"', [OldFilename, NewFileName]);
end;

function TNotifiers.AllowSave: Boolean;
begin
  Result := True;
  {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in two seconds'}
  LogMessage('AllowSave: %d', [Ord(Result)]);
  (BorlandIDEServices as IOTAModuleServices).CurrentModule.FileName;
end;

procedure TNotifiers.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
begin
end;

procedure TNotifiers.BeforeCompile(const Project: IOTAProject; IsCodeInsight: Boolean;
  var Cancel: Boolean);
begin
end;

procedure TNotifiers.BeforeRename(const OldFileName, NewFileName: string);
begin
end;

function TNotifiers.CheckOverwrite: Boolean;
begin
  Result := True;
end;

procedure TNotifiers.FileNotification(NotifyCode: TOTAFileNotification; const FileName: string;
  var Cancel: Boolean);
var
  NewModule: IOTAModule;
  Index: Integer;
begin
  case NotifyCode of
    ofnFileOpened: begin
................................................................................
    ofnActiveProjectChanged: begin
      {$MESSAGE WARN 'TODO: (re)schedule to refresh the working dir in a second'}
      LogMessage('Active project changed: "%s"', [FileName]);
    end;
  end;
end;

function TNotifiers.GetOverwriteFileName(Index: Integer): string;
begin
  Result := '';
end;

function TNotifiers.GetOverwriteFileNameCount: Integer;
begin
  Result := 0;
end;

procedure TNotifiers.ModuleRenamed(const NewName: string);
begin
end;

procedure TNotifiers.SetSaveFileName(const FileName: string);
begin
end;


end.

Changes to todo.md.

106
107
108
109
110
111
112



113
114
115
116
117
118
119
* Overview of current status _(nice to have)_
  - `hg -y --summary --remote`
  - `fossil info` or `fossil status`
* Repo title _(nice to have)_
  - `hg -yq root`
  - `fossil sqlite3 "SELECT value FROM config WHERE name='project-name'"`
	(or `fossil info`, then extract the line starting with `project-name:`)




____________________________________________________________________________________________________

    TRepoInfo = class
    private
      FVCSClient: TVCSClient;
      FRoot: string;







>
>
>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
* Overview of current status _(nice to have)_
  - `hg -y --summary --remote`
  - `fossil info` or `fossil status`
* Repo title _(nice to have)_
  - `hg -yq root`
  - `fossil sqlite3 "SELECT value FROM config WHERE name='project-name'"`
	(or `fossil info`, then extract the line starting with `project-name:`)
* Process rename
  - `hg -yq rename --after SOURCE DEST`
  - `fossil rename --soft OLDNAME NEWNAME`

____________________________________________________________________________________________________

    TRepoInfo = class
    private
      FVCSClient: TVCSClient;
      FRoot: string;