Recent

Author Topic: How to taylor the output of "ptop" [partially SOLVED]  (Read 836 times)

maurizio.tomasi

  • New member
  • *
  • Posts: 5
How to taylor the output of "ptop" [partially SOLVED]
« on: October 21, 2020, 11:57:39 am »
Hi to everybody,

  I am trying to taylor "ptop" so that it can reformat my codes according to the following layout:


Code: Pascal  [Select][+][-]
  1. { -*- mode: opascal -*- }
  2.  
  3. {$mode objfpc}
  4.  
  5. Unit myunit;
  6.  
  7. Interface
  8.  
  9. Uses          { One unit per line, each indented }
  10.   math,
  11.   sysutils;
  12.  
  13. Type
  14.   TClass = Class; { Forward declaration }
  15.  
  16.   TRec = Record
  17.     a, b : Real;
  18.     c: TClass;
  19.   End;
  20.  
  21.   TClass = Class
  22.     rec: TRec;
  23.   End;
  24.  
  25. Implementation
  26.  
  27. End.
  28.  

However, this is the output of a plain call to ptop (i.e., using the default configuration):

Code: Pascal  [Select][+][-]
  1. { -*- mode: opascal -*- }
  2.  
  3. {$mode objfpc}
  4.  
  5. Unit myunit;
  6.  
  7. Interface
  8.  
  9. Uses math, sysutils; { All the uses are in one line }
  10.  
  11. Type
  12.   TClass = Class;
  13.  
  14.     TRec = Record { Is it a bug? This should not be indented wrt TClass }
  15.       a, b : Real;
  16.       c: TClass;
  17.     End;
  18.  
  19.     TClass = Class
  20.       rec: TRec;
  21.     End;
  22.  
  23.     Implementation
  24.  
  25.   End.
  26.  

The output is nearly perfect, but there are two things that I want to change:

  • I would like to put a newline after "uses" and indent the class list. The best would be to put every unit name in its own line.
  • The code is wrongly indented after the forward declaration of the class;

I read the ptop documentation (https://wiki.freepascal.org/PTop), but it seems that there is no simple way to break the list of "uses" in many lines, because this would require to interpret commas in a context-dependent way. So I would be happy with just a newline after uses and proper indentation of the list of units. I tweaked the file produced by ptop -g my_ptop.cfg and modified the uses= line in this way:

Code: [Select]
uses=blinbefore,crafter,dindonkey,spaft,inbytab,capital
[uses]=proc,func,var,label,const,type

To my understanding, this should tell ptop to deintent after a uses whenever it finds the keywords procedure, function, etc.

However, here is the result of running ptop -c my_ptop.cfg:

Code: Pascal  [Select][+][-]
  1. { -*- mode: opascal -*- }
  2.  
  3. {$mode objfpc}
  4.  
  5. Unit myunit;
  6.  
  7. Interface
  8.  
  9. Uses
  10.   math, sysutils;
  11.  
  12.   Type { <--- Why is not deintending here? }
  13.     TClass = Class;
  14.  
  15.       TRec = Record
  16.         a, b : Real;
  17.       End;
  18.  
  19.       TClass = Class
  20.         rec: TRec;
  21.       End;
  22.  
  23.       Implementation
  24.  
  25.     End.
  26.  

The newline after Uses shows that the new configuration file is working indeed, but there is no de-indent. Clearly, I have misunderstood the documentation of ptop.

So, here are my questions:

  • Is there a bug in ptop when it encounters forward class declarations?
  • How can I tell ptop to deindent Uses lists after the semicolon?

Thanks a lot!
« Last Edit: October 24, 2020, 07:01:16 am by maurizio.tomasi »

jamie

  • Hero Member
  • *****
  • Posts: 3797
Re: How to taylor the output of "ptop"
« Reply #1 on: October 21, 2020, 01:06:31 pm »
I didn't look close at your code but the name "TCLASS" is already used in the system.

Please pick another name otherwise youl have other issues one day .
The only true wisdom is knowing you know nothing

maurizio.tomasi

  • New member
  • *
  • Posts: 5
Re: How to taylor the output of "ptop"
« Reply #2 on: October 21, 2020, 02:52:57 pm »
Hi Jamie, thanks for your comment. Of course, the code I posted was meant only to highlight the problem. My real code is obviously longer and significantly different from the example above.

jamie

  • Hero Member
  • *****
  • Posts: 3797
Re: How to taylor the output of "ptop"
« Reply #3 on: October 21, 2020, 11:59:59 pm »
you must be talking about the editor behavior ?

have you looked in the settings for the editor and JEDI code formatter ?
The only true wisdom is knowing you know nothing

maurizio.tomasi

  • New member
  • *
  • Posts: 5
Re: How to taylor the output of "ptop"
« Reply #4 on: October 22, 2020, 09:26:03 am »
Hi Jamie, no, I am talking about the command-line tool ptop provided by FreePascal (https://wiki.freepascal.org/PTop). I am an Emacs user, and I would like to have ptop run whenever I save my files with C-x C-s.

I did not try JEDI because I understand it's bundled with the Lazarus GUI, while I was looking for a stand-alone solution. Following your answer, I found that somebody wrapped JEDI in a standalone command-line interface (https://github.com/git-bee/jcf-cli), which would be ok! However, the site warns that JEDI won't run if the code is not compilable (https://github.com/git-bee/jcf-cli#the-problem-with-jcf), which is a deal-breaker for me as I save my code quite often. (ptop does not seem to have this limitation.)

maurizio.tomasi

  • New member
  • *
  • Posts: 5
Re: How to taylor the output of "ptop" [SOLVED, at least partially]
« Reply #5 on: October 24, 2020, 07:01:00 am »
I was finally able to tell ptop to unindent at the end of the uses clause. It was a matter of specifying uses in the list of de-indents for the semicolon:

Code: [Select]
semicolon=crsupp,dindonkey,crafter
[semicolon]=if,then,else,while,with,for,colon,equals,uses

while I was mistakenly trying to specify it in the [uses] clause directly. Here is my full ptop.cfg file, if anyone is interested:

Code: [Select]
end=crbefore,dindonkey,dindent,crafter,lower
[end]=if,then,else,while,with,for,record,try,finally,except,class,object,private,public,protected,published,casevar,colon,equals
begin=crbefore,dindonkey,inbytab,crafter
[begin]=var,label,const,type
if=spaft,gobsym,inbytab,lower
then=,lower
else=crbefore,dindonkey,inbytab,lower
[else]=if,then,else
proc=dindonkey,spaft,lower
[proc]=var,label,const,type
var=blinbefore,dindonkey,spaft,inbytab,lower
[var]=var,label,const,type
of=crsupp,spbef,spaft,lower
while=spaft,gobsym,inbytab,crafter,lower
do=crsupp,spbef,lower
case=spaft,gobsym,inbytab,crafter,lower
with=spaft,gobsym,inbytab,crafter,lower
for=spaft,gobsym,inbytab,crafter,lower
repeat=inbytab,crafter,lower
until=crbefore,dindonkey,dindent,spaft,gobsym,crafter,lower
[until]=if,then,else,while,with,for,colon,equals
func=dindonkey,spaft,lower
[func]=var,label,const,type
label=blinbefore,spaft,inbytab,lower
const=blinbefore,dindonkey,spaft,inbytab,lower
[const]=var,label,const,type
type=blinbefore,dindonkey,spaft,inbytab,lower
[type]=var,label,const,type
record=inbyindent,crafter,lower
[record]=end
string=
prog=blinbefore,spaft,lower
asm=lower
try=crbefore,inbytab,crafter,lower
finally=crbefore,dindent,inbytab,crafter,lower
[finally]=try
except=crbefore,dindent,inbytab,crafter,lower
[except]=try
raise=lower
class=inbyindent,lower
object=inbyindent,lower
constructor=lower
destructor=lower
inherited=lower
property=lower
private=crbefore,dindonkey,spaft,inbytab,lower
[private]=end,private,public,protected,published
public=crbefore,dindonkey,spaft,inbytab,lower
[public]=end,private,public,protected,published
protected=crbefore,dindonkey,spaft,inbytab,lower
[protected]=end,private,public,protected,published
published=crbefore,dindonkey,spaft,inbytab,lower
[published]=end,private,public,protected,published
initialization=lower
finalization=lower
inline=lower
library=blinbefore,spaft,lower
interface=blinbefore,crafter,lower
implementation=blinbefore,dindonkey,crafter,lower
[implementation]=end,var,label,const,type,property
read=lower
write=lower
unit=blinbefore,spaft,lower
and=lower
arr=lower
div=lower
down=lower
file=lower
goto=lower
in=lower
mod=lower
not=lower
nil=lower
or=lower
set=lower
to=lower
virtual=lower
uses=blinbefore,crafter,spaft,inbytab,lower
casevar=spaft,gobsym,inbytab,crafter
ofobject=
becomes=spbef,spaft,gobsym
notequal=
lessorequal=
greaterorequal=
delphicomment=crafter
dopencomment=
dclosecomment=
opencomment=crsupp
closecomment=crsupp
semicolon=crsupp,dindonkey,crafter
[semicolon]=if,then,else,while,with,for,colon,equals,uses
colon=inbytab
equals=spbef,spaft,inbytab
openparen=gobsym
closeparen=
period=crsupp
endoffile=
other=

There is still the problem of forward declarations, but I think I can live with it.

Note: I changed a bit the configuration file to output all keywords in lowercase, so that Emacs' opascal-mode can highlight them correctly. (Don't know why this mode enforces exact case matches when Pascal is case-insensitive. Oh, well.)

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8901
  • FPC developer.
Re: How to taylor the output of "ptop" [partially SOLVED]
« Reply #6 on: October 24, 2020, 01:46:43 pm »
The tool dates from Turbo Pascal times, when it was custom to uppercase all keywords.

maurizio.tomasi

  • New member
  • *
  • Posts: 5
Re: How to taylor the output of "ptop" [partially SOLVED]
« Reply #7 on: October 26, 2020, 05:04:55 am »
The tool dates from Turbo Pascal times, when it was custom to uppercase all keywords.

This rule was forced in Wirth's languages Modula-2 and Oberon, which required keywords to be typeset all in uppercase. However, I've used Turbo Pascal through versions 3.0, 4.0, 5.5, 6.0, 7.0, and I've never seen uppercase keywords in the examples or source code bundled with the compiler. (Even Knuth used all-lowercase word in the source code of the TeX typesetting system.) As far as I remember, only Duntemann's "Complete Turbo Pascal" followed this rule.

(Besides, ptop's default is to capitalize keywords, not to make them all uppercase.)

 

TinyPortal © 2005-2018