Menu

automated code formatting?

2005-08-30
2013-05-23
  • Christoph Emonds

    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

     
    • Anthony Steele

      Anthony Steele - 2005-08-30

      You may be able to get the command line version to do fire on check in, maybe from a batch file.

       
    • Christoph Emonds

      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?

       
    • Anthony Steele

      Anthony Steele - 2005-09-14

      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.

       
    • Anthony Steele

      Anthony Steele - 2005-09-19

      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.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.