first i'd like to thank you for your done work. We really appreciate your code formatting tool.
We are migrating from SourceSafe to Subversion and would like to automatically code format all files before check in. Is it possible to run code format for a file, everytime it get saved in Delphi? I haven't found such an option in the IDE Plugin but maybe you know a work around?
Another idea was trying to make subversion call the code formatter before check in, but as with the IDE plugin I haven't found a way to do this.
Greetings
Christoph Emonds
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I thought of such an approach. The problem is, that we would like to use an IDE plugin for subversion, so we won't call the subversion command line client. In the IDE plugin (sourceConnexion from EPocalipse) there is no way to trigger a batch file or something similar before checkin.
I had a look at the source code of the code format plugin to see how much work it would be, to add a feature like auto format at save, but because of lack of knowledge for the opentools api I couldn't estimate the work this feature would require. Do you have an idea, how much time it would need to implement such feature?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Right, the prototype BeforeSave detection is below. It works on occasion, but the problem is that it crashes and burns terribly if you do a compile followed by a save. If someone can get me past this hurdle, I can replace the ShowMessage stub with a format of the file.
procedure Register;
var
lcServices: IOTAServices;
begin
lcServices := (BorlandIDEServices as IOTAServices);
miIdeNotifierIndex := lcServices.AddNotifier(TJCFIdeNotifier.Create);
mbRegistered := True;
end;
function FileIsFormatted(const psFileName: string): boolean;
var
lsExt: string;
begin
lsExt := ExtractFileExt(psFileName);
Result := (lsExt = '.pas');
end;
{ TJCFIdeNotifier }
constructor TJCFIdeNotifier.Create;
begin
inherited;
destructor TJCFIdeNotifier.Destroy;
begin
inherited;
Dec(miNotifierCount);
end;
procedure TJCFIdeNotifier.AfterCompile(Succeeded: boolean);
begin
end;
procedure TJCFIdeNotifier.AfterSave;
begin
end;
procedure TJCFIdeNotifier.BeforeCompile(const Project: IOTAProject;
var Cancel: boolean);
begin
end;
procedure TJCFIdeNotifier.BeforeSave;
begin
end;
procedure TJCFIdeNotifier.Destroyed;
begin
end;
procedure TJCFIdeNotifier.AddNotifiers(const FileName: string);
var
lcModule: IOTAModule;
lcEditor: IOTAEditor;
lcEditorNotifier: TJcfEditorNotifier;
liEditorNotifierResult: integer;
liLoop: integer;
begin
{ Get the IOTAModule associated to this File }
lcModule := (BorlandIDEServices as IOTAModuleServices).FindModule(FileName);
if lcModule <> nil then
begin
{ Loop over the number of associated Files }
for liLoop := 0 to lcModule.GetModuleFileCount - 1 do
begin
{ Get the FileEditor }
lcEditor := lcModule.GetModuleFileEditor(liLoop);
{ Add an editor notifier }
lcEditorNotifier := TJcfEditorNotifier.Create(FileName);
liEditorNotifierResult := lcEditor.AddNotifier(lcEditorNotifier);
if liEditorNotifierResult < 0 then
lcEditorNotifier.Free;
end;
end;
end;
procedure TJCFIdeNotifier.RemoveNotifiers(const psFileName: string);
begin
// fall out of scope
end;
procedure TJCFIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: boolean);
begin
case NotifyCode of
ofnFileOpened:
begin
if FileIsFormatted(FileName) then
AddNotifiers(FileName);
end;
ofnFileClosing:
RemoveNotifiers(FileName);
end;
end;
procedure TJCFIdeNotifier.Modified;
begin
end;
{ TJcfEditorNotifier }
constructor TJcfEditorNotifier.Create(const psFileName: string);
begin
inherited Create;
fsFileName := psFileName;
end;
procedure TJcfEditorNotifier.AfterSave;
begin
end;
procedure TJcfEditorNotifier.BeforeSave;
begin
// dummy
ShowMessage('BeforeSave ' + FileName);
end;
procedure TJcfEditorNotifier.Destroyed;
begin
end;
procedure TJcfEditorNotifier.Modified;
begin
end;
procedure TJcfEditorNotifier.ViewActivated(const View: IOTAEditView);
begin
end;
procedure TJcfEditorNotifier.ViewNotification(const View: IOTAEditView;
Operation: TOperation);
begin
end;
function TJcfEditorNotifier.GetFileName: string;
begin
Result := fsFileName;
end;
initialization
finalization
if mbRegistered then
begin
(BorlandIDEServices as IOTAServices).RemoveNotifier(miIdeNotifierIndex);
end;
end.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
first i'd like to thank you for your done work. We really appreciate your code formatting tool.
We are migrating from SourceSafe to Subversion and would like to automatically code format all files before check in. Is it possible to run code format for a file, everytime it get saved in Delphi? I haven't found such an option in the IDE Plugin but maybe you know a work around?
Another idea was trying to make subversion call the code formatter before check in, but as with the IDE plugin I haven't found a way to do this.
Greetings
Christoph Emonds
You may be able to get the command line version to do fire on check in, maybe from a batch file.
I thought of such an approach. The problem is, that we would like to use an IDE plugin for subversion, so we won't call the subversion command line client. In the IDE plugin (sourceConnexion from EPocalipse) there is no way to trigger a batch file or something similar before checkin.
I had a look at the source code of the code format plugin to see how much work it would be, to add a feature like auto format at save, but because of lack of knowledge for the opentools api I couldn't estimate the work this feature would require. Do you have an idea, how much time it would need to implement such feature?
There's some coe here that seems relevant:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10338003.html
I am poking at it, might get something going this weekend.
Right, the prototype BeforeSave detection is below. It works on occasion, but the problem is that it crashes and burns terribly if you do a compile followed by a save. If someone can get me past this hurdle, I can replace the ShowMessage stub with a format of the file.
unit EdNotify;
{
capture whenever a unit is saved
after Stefaan's comments in
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10338003.html
}
interface
uses
Classes,
Contnrs,
ToolsAPI;
type
IJcfEditorNotifier = interface
['{94534926-8ACB-4A07-AC67-6A62217F3EB3}']
function GetFileName: string;
property FileName: string read GetFileName;
end;
TJCFIdeNotifier = class(TInterfacedObject, IOTAIDENotifier)
private
// the callbacks
procedure AfterSave;
procedure BeforeSave;
procedure Destroyed;
procedure Modified;
procedure FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: boolean);
procedure BeforeCompile(const Project: IOTAProject; var Cancel: boolean); overload;
procedure AfterCompile(Succeeded: boolean); overload;
// worker procs
procedure AddNotifiers(const FileName: string);
procedure RemoveNotifiers(const psFileName: string);
public
constructor Create;
destructor Destroy; override;
end;
TJcfEditorNotifier = class(TInterfacedObject, IOTAEditorNotifier, IOTANotifier, IJcfEditorNotifier)
private
fsFileName: string;
// the callbacks
procedure AfterSave;
procedure BeforeSave;
procedure Destroyed;
procedure Modified;
procedure ViewNotification(const View: IOTAEditView; Operation: TOperation);
procedure ViewActivated(const View: IOTAEditView);
function GetFileName: string;
public
constructor Create(const psFileName: string);
property FileName: string read GetFileName;
end;
procedure Register;
implementation
uses
Dialogs,
SysUtils;
var
miIdeNotifierIndex: integer;
mbRegistered: boolean = False;
miNotifierCount: integer = 0;
miMaxNotifierCount: integer = 0;
procedure Register;
var
lcServices: IOTAServices;
begin
lcServices := (BorlandIDEServices as IOTAServices);
miIdeNotifierIndex := lcServices.AddNotifier(TJCFIdeNotifier.Create);
mbRegistered := True;
end;
function FileIsFormatted(const psFileName: string): boolean;
var
lsExt: string;
begin
lsExt := ExtractFileExt(psFileName);
Result := (lsExt = '.pas');
end;
{ TJCFIdeNotifier }
constructor TJCFIdeNotifier.Create;
begin
inherited;
Inc(miNotifierCount);
Inc(miMaxNotifierCount);
end;
destructor TJCFIdeNotifier.Destroy;
begin
inherited;
Dec(miNotifierCount);
end;
procedure TJCFIdeNotifier.AfterCompile(Succeeded: boolean);
begin
end;
procedure TJCFIdeNotifier.AfterSave;
begin
end;
procedure TJCFIdeNotifier.BeforeCompile(const Project: IOTAProject;
var Cancel: boolean);
begin
end;
procedure TJCFIdeNotifier.BeforeSave;
begin
end;
procedure TJCFIdeNotifier.Destroyed;
begin
end;
procedure TJCFIdeNotifier.AddNotifiers(const FileName: string);
var
lcModule: IOTAModule;
lcEditor: IOTAEditor;
lcEditorNotifier: TJcfEditorNotifier;
liEditorNotifierResult: integer;
liLoop: integer;
begin
{ Get the IOTAModule associated to this File }
lcModule := (BorlandIDEServices as IOTAModuleServices).FindModule(FileName);
if lcModule <> nil then
begin
{ Loop over the number of associated Files }
for liLoop := 0 to lcModule.GetModuleFileCount - 1 do
begin
{ Get the FileEditor }
lcEditor := lcModule.GetModuleFileEditor(liLoop);
{ Add an editor notifier }
lcEditorNotifier := TJcfEditorNotifier.Create(FileName);
liEditorNotifierResult := lcEditor.AddNotifier(lcEditorNotifier);
if liEditorNotifierResult < 0 then
lcEditorNotifier.Free;
end;
end;
end;
procedure TJCFIdeNotifier.RemoveNotifiers(const psFileName: string);
begin
// fall out of scope
end;
procedure TJCFIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: boolean);
begin
case NotifyCode of
ofnFileOpened:
begin
if FileIsFormatted(FileName) then
AddNotifiers(FileName);
end;
ofnFileClosing:
RemoveNotifiers(FileName);
end;
end;
procedure TJCFIdeNotifier.Modified;
begin
end;
{ TJcfEditorNotifier }
constructor TJcfEditorNotifier.Create(const psFileName: string);
begin
inherited Create;
fsFileName := psFileName;
end;
procedure TJcfEditorNotifier.AfterSave;
begin
end;
procedure TJcfEditorNotifier.BeforeSave;
begin
// dummy
ShowMessage('BeforeSave ' + FileName);
end;
procedure TJcfEditorNotifier.Destroyed;
begin
end;
procedure TJcfEditorNotifier.Modified;
begin
end;
procedure TJcfEditorNotifier.ViewActivated(const View: IOTAEditView);
begin
end;
procedure TJcfEditorNotifier.ViewNotification(const View: IOTAEditView;
Operation: TOperation);
begin
end;
function TJcfEditorNotifier.GetFileName: string;
begin
Result := fsFileName;
end;
initialization
finalization
if mbRegistered then
begin
(BorlandIDEServices as IOTAServices).RemoveNotifier(miIdeNotifierIndex);
end;
end.