Home > Delphi, Quartex Pascal > Quartex pascal, foundation stone laid

Quartex pascal, foundation stone laid

January 15, 2014 Leave a comment Go to comments

Managed to get a couple of hours work done on QPAS (quartex pascal) today, and finally I have reached the part where all the different sub-systems come together. Writing an IDE is not the same as writing  a notepad clone or simple text editor. The concept of project item types (for instance, how do you define a unit versus a textfile? Should a file ending with .res open up in a text-editor or a hex-dump?), storage mechanisms, source templates, search paths – the list goes on. Point is, it has to be abstract enough to be flexible, but rigid enough to take a punch and provide logical structure.

Meanwhile in Tønsberg, Norway

Meanwhile in Tønsberg, Norway

Today I got the time to glue the project-element templates (unit, program unit etc.) into the actual creation of a unit. I also got rid of all the initial hardcoded stuff. So when QPAS starts-up it reads all the information from files. Adding a new project type with different sub-elements (php, C#, javascript etc) is more or less a matter of writing some .inifiles which defines what the editor should do, provide a default source template (optional), and voila — the IDE has no clue about the difference between a unit and a textfile is, but it will handle both differently based on definitions now user-adaptable.

Getting there

Getting there

So in short: Yes, the IDE can be adapted for other languages (finally we can put those synEdit syntax highlighters to good use)!

But those are just the default “low level IDE stuff”, I will also need to add support for pre-defined projects. You know when you create a new delphi project, it basically just copies an already existing project from disk? This will be the next part.

Application services

In order to make this scriptable I had to add some overhead. First, everything is neatly isolated in a core class which provides access to all the sub-systems. It was very tempting to just litter the code with functions (like “getTemplateList”) rather than coding full manager classes, but I’m in no hurry – and I have a full daytime job besides. So I decided to take my time.

Here is an example from the IDE:

function TfrmMainForm.getBufferForUnit(aIdentifier:String;
         var aData:String):Boolean;
var
  mOpen:TObjectList;
  x:  Integer;
  mExt: String;
  mName:  String;
  mFound: TQTFileSourceRefList;
  mText:  TStringlist;
  mData:  TStream;
  mRef:   String;
  mAccess:  TIDEAccessManager;
begin
  (* Initialize to negative *)
  result:=False;
  mOpen:=NIL;
  setLength(aData,0);

  (* Make sure we can do this *)
  if not (csDestroying in ComponentState)
  and not (csLoading in ComponentState)
  and not application.Terminated then
  begin
    (* Request access to IDE API *)
    if getIDEAccess(mAccess) then
    begin
      mExt:=ExtractFileExt(aIdentifier);

      (* Get buffer from open tab *)
      if getOpenTabsForProject(mAccess.ProjectManager.ActiveProject,mOpen) then
      begin
        try
          for x:=0 to mOpen.Count-1 do
          begin
            (* NOTE: replace with byterage->compare later! *)
            if SameText(mopen[x].Item.Identifier,aIdentifier) then
            begin
              if (mOpen[x].Frame is TframePascal) then
              begin
                aData:=TframePascal(mOpen[x].Frame).editor.Text;
                break;
              end;
            end;
          end;
          result:=length(aData)>0;
        finally
          mOpen.Free;
        end;
      end;

      if not result then
      begin
        if length(mExt)=0 then
        mName:=aIdentifier + '.pas' else
        mName:=aIdentifier;

        if mAccess.FileSourceManager.LocateFileByName(mName,mFound) then
        begin
          try
            if mFound.Count>0 then
            begin
              mtext:=TStringlist.Create;
              try
                (* Get unit candidates, sort by priority to the project *)
                mRef:=mAccess.FileSourceManager.SortByPriority(mFound,mAccess.ProjectManager.ActiveProject).Items[0];
                WriteMessageF('using package unit [%s]',[mRef]);
                try
                  if mAccess.FileSourceManager.ObtainStreamFromRef(mRef,mData) then
                  begin
                    try
                      (* Note: Replace with streamToStr before alpha *)
                      mtext.LoadFromStream(mData);
                      aData:=mtext.Text;
                      result:=true;
                    finally
                      mData.Free;
                    end;
                  end;
                except
                  on e: exception do
                  TIDEExceptionHandler.HandleIOException(e,ehLogMessage);
                end;
              finally
                mtext.Free;
              end;
            end;
          finally
            mFound.Free;
          end;
        end;
      end;
    end;
  end;
end;

Now to get rid of the “.pas” harcoded string (query the project.template subsystem) and rename the editor frame to something more useful. Or just go bananaz and compile with packages and isolate different editors in DLL plugins (ala eclipse).

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: