Jump to content
Joshua Gardner

pasfmt out now!

Recommended Posts

image.thumb.png.d1a91539f1c44aa3d6ee5b0704e01200.png

We're excited to share the first public release of pasfmt, a free and open-source code formatter for Delphi.

It is a complete and opinionated formatting tool.

 

The latest release has support for:

  • Complete line wrapping (and unwrapping) for all Delphi structures
  • Configurable line length limit
  • Removing trailing whitespace
  • Change spacing around all tokens (e.g., operators and keywords)
  • Parallel file formatting with directory traversal
  • Removing repeated empty newlines
  • Line ending normalisation

 

To get started, either try our web demo, or download the executable (this one for Windows) and follow the getting started guide.

 

Additionally, there is an IDE plugin with support for:

  • In-editor formatting
  • Format-on-save
  • Cursor tracking

 

You may be wondering how this tool compares to the existing formatters (e.g., GExperts, JEDI, Formatter.exe). 

This tool goes a lot further than the alternatives by having a complete opinion on how every line should be wrapped or unwrapped; the original layout is (almost) ignored.

By ignoring most of the input format, it produces consistently styled code across a whole codebase.

 

We hope that you enjoy pasfmt, let us know what you think!

  • Like 6
  • Thanks 2

Share this post


Link to post

Haven't played around with it much yet. For my taste, turning it on or off via // pasfmt off is a bit to unobtrusive. I think it should stick a bit out more so you immediately see. Something like #[rustfmt::skip] somehow just catches your eye better. Maybe it could also be possible via {$DEFINE NO_FORMAT}? That would also give us syntax highlighting for these parts.

 

 

 

 

Share this post


Link to post

Multiline strings seem to be handled correctly. How about ignoring specific parts of the code? Is there a directive for that?

 

There is.  Looks great!

// pasfmt off
Edited by Attila Kovacs
  • Like 1

Share this post


Link to post
1 hour ago, Attila Kovacs said:

Multiline strings seem to be handled correctly. How about ignoring specific parts of the code? Is there a directive for that?

 

There is.  Looks great!


// pasfmt off

The handling for multiline strings and multiline comments is pretty minimal at the moment. It knows how to parse them and therefore can avoid mangling them (unlike some other Delphi formatters).

 

In a future release we would like to have the formatter rewrite the inside of multiline strings and comments such that they can be indented/deindented, and (in the case of comments) re-flowed.

  • Like 1

Share this post


Link to post
4 hours ago, Joshua Gardner said:

It is a complete and opinionated formatting tool. 

What does opinionated mean in this context?

Share this post


Link to post
5 hours ago, Joshua Gardner said:

Additionally, there is an IDE plugin with support for:

  • In-editor formatting
  • Format-on-save
  • Cursor tracking

Am I right in assuming that the plugin calls the executable to do the formatting?

Calling an executable is rather expensive (meaning: slow) in Windows, it would be really nice it you could also produce a DLL, that can be called from this plugin (and possibly other tools). 32 and 64 bits, if possible.

  • Like 1

Share this post


Link to post
5 hours ago, Sherlock said:

What does opinionated mean in this context?

In England, at least, I understand the word as "holding to one's own opinions and ideas too strongly"; "obstinate"; "unwilling to be corrected"; "inflexible".  In other words, not the most desirable qualities I need in a tool which will be adjusting and improving whatever I have carefully written.  But I accept that this may just be an accident of translation which is not intended for this context.

Share this post


Link to post
10 hours ago, dummzeuch said:

Am I right in assuming that the plugin calls the executable to do the formatting?

Calling an executable is rather expensive (meaning: slow) in Windows, it would be really nice it you could also produce a DLL, that can be called from this plugin (and possibly other tools). 32 and 64 bits, if possible.

You are right that the plugin calls the executable. I've addressed this comment over on the repository where an issue was raised.

https://github.com/integrated-application-development/pasfmt/issues/159#issuecomment-2672690523

Share this post


Link to post
17 hours ago, Joshua Gardner said:

We hope that you enjoy pasfmt, let us know what you think!

Great idea crumbled by rust.

There are other languages which would have been more appropriate to use for the implementation and would make contributions easier.
Sad.

And to expand on that:
When picking an implementation language, besides evaluating what solves the problem at hand, you also have to consider target community and who are going to deal with it down the line - especially for open source projects and that weighs higher than one's favorite language.
Rust has a toxic community, an ecosystem mess akin to npm and overall just a poorly designed language with unnecessary complexity driven up by hype. (I know this from first hand experience of having to deal with rust projects before and digging inside the rust compiler)

While some have drunk the rust kool-aid, I'd rather have seen Modern Object Pascal used or, if you want to be fancy, Zig.

There are good reasons why many prominent projects are abandoning rust.

Edited by Glenn Dufke
  • Like 3

Share this post


Link to post
13 hours ago, Sherlock said:

What does opinionated mean in this context? 

It is a fair enough question. In the context of a code formatter, it means that it has a strong opinion on what the code should look like. 

Predominantly, this manifests in having few or no configuration options and a highly consistent style.

Other formatters like prettier, biome, and google-java-format call themselves opinionated.

  • Like 1
  • Thanks 1

Share this post


Link to post
Just now, Joshua Gardner said:

Other formatters like prettier, biome, and google-java-format call themselves opinionated.

As well as python's black.

 

Quote

Black is a PEP 8 compliant opinionated formatter

 

Edited by pyscripter

Share this post


Link to post

Looks great - as always: spring4d source for the real test and it seems to stumble at a few places where it then goes into "line breaks go to 11" mode - here for example:

 

image.thumb.png.3341ce4f0e3da6175116cb35f1f27b95.png

 

or

 

image.thumb.png.8aeb5e62a826a369220f172a4e2655ee.png

Share this post


Link to post

Talking about capitalization, the Delphi Style Guide: is quite clear about:

  • using "Pascal casing" (e.g. MyData) across the board (variables, parameters etc..)
  • fields starting with a capital F.
  • avoiding prefixes such as lData for local variables or aFileName for parameters.

 

The Delphi RTL mostly complies with the above recommendations, but much of the Delphi code around does not.  There is also a lot of variation regarding the use of prefixes in control names inside Forms.

 

Spring4D in particular uses camelCasing for parameters and local variables, small f for fields and uses Pascal casing for function/procedure names and properties.

 

@Stefan Glienke Is this just a matter of taste?

 

I can see some advantages in the following convention (a hybrid of the DSG and the spring4d conventions):

  • Properties/function/procedure names use Pascal casing - Inside the class use the field name instead of the corresponding property name.
  • Function/procedure parameters use camelCasing
  • Fields start with F
  • Local variables follow Pascal casing
  • Global variables (just avoid using).

In this way you could immediately tell if any variable is a parameter, a local variable or a field without littering the code with ugly prefixes and the like (except for the now established F for fields).  And if you follow the rule about properties and avoid with statements, then you would almost always refer to properties using the dot notation.

 

I am not actually using this currently, trying to stick to the Delphi Style Guide.

 

Any thoughts?  What is you preferred convention and why?

 

@Joshua Gardner Does the "opinionated" pasfmt take a view on capitalization?

Edited by pyscripter

Share this post


Link to post
48 minutes ago, pyscripter said:

I can see some advantages in the following convention (a hybrid of the DSG and the spring4d conventions):

I follow that except I also use camelCase for local variables. 

 

An opinionated formatter that doesn't allow me to configure to my taste is unfortunately not going to cut it. I also do weird things like align assigments in constructors

 

constructor TMyClass.Create(x : integer; y : integer; const theName : string);
begin
  Fx 	:= x;
  Fy 	:= y;
  FName	:= theName;
end;

and for constants

const
	cMyConst      = 'test';
	cAnotherConst = 'foobar';

 

No formatter I have tried can cope with that. 

Share this post


Link to post
34 minutes ago, Vincent Parrett said:

No formatter I have tried can cope with that. 

None of them have a: "Don't touch my assignment alignments" option? 🙂

 

  • Haha 1

Share this post


Link to post
Just now, Dave Nottage said:

None of them have a: "Don't touch my assignment alignments" option? 🙂

Sadly not. I don't want to be littering my code with //formatting off/on etc. So I format by hand and it is what it is.

 

  • Like 2

Share this post


Link to post
19 minutes ago, pyscripter said:

@Joshua Gardner Does the "opinionated" pasfmt take a view on capitalization? 

A good question! At this point in time, we strive to not modify any tokens, for safety.

We have tentative plans to implement keyword lowercasing in the future.

For identifiers, we feel strongly that the identifier should match its declaration, however, this tool doesn't have any semantic information to be able to enforce this.

Our other tools sonar-delphi in conjunction with delphilint are much better suited to that task.

Share this post


Link to post
47 minutes ago, Vincent Parrett said:

I don't want to be littering my code with //formatting off/on etc.

What you want in a formatter is a simple DSL where you can express your desired formatting style and the formatter uses this as the basis..
I'm glad you asked...

Share this post


Link to post
37 minutes ago, Glenn Dufke said:

What you want in a formatter is a simple DSL where you can express your desired formatting style and the formatter uses this as the basis..
I'm glad you asked...

While not aligned with the goals of this project, that's an interesting concept.

Can't say I'm aware of any well-known formatting tools that operate in such a way, though.

Edited by Jonah Jeleniewski

Share this post


Link to post
Just now, Jonah Jeleniewski said:

While not aligned with the goals of this project, that's an interesting concept.

Can't say I'm aware of any well-known formatting tools that operates in such a way, though.

Well, it's an interesting concept because I created one in my formatter engine which is multi language and support mixed source documents among other cool features.
- And it is high performance without using rust 🙃

Share this post


Link to post
Just now, Glenn Dufke said:

Well, it's an interesting concept because I created one in my formatter engine which is multi language and support mixed source documents among other cool features.
- And it is high performance without using rust 🙃

Sounds cool.
You should write a blog post on how you architected your tool. Differing philosophies aside, I'd be interested to read it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×