Auto indenter - again

Share your advanced PureBasic knowledge/code with the community.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Auto indenter - again

Post by Derek »

Code updated for 5.20+ (the IDE now support automatic indent)

Just two simple routines to indent or un-indent source code.

Did a search and couldn't find any recent ones.

Code: Select all

;INDENTER
;
;Configure as tool with Arguments set as "%FILE" "%TEMPFILE"
;Set shortcut to 'ctrl' 'shift' and 'I'
;Tick 'Wait until tool quits', 'Reload Source' and 'into current source'
;
;
cpp.b=CountProgramParameters()
If cpp<>2
  MessageRequester("Error","Wrong number of parameters.")
  End
EndIf

pps.s=ProgramParameter()
ppt.s=ProgramParameter()

If pps=""
  MessageRequester("Error","Source file has to be saved first.")
  End
EndIf

DataSection
  #plus=11
  Data.s "if ","for ","while ","repeat ","procedure ","select ","datasection "
  Data.s "macro ","compilerif ","compilerselect ","structure "
  
  #minus=12
  Data.s "endif ","next ","wend ","until ","endprocedure ","endselect ","enddatasection "
  Data.s "endmacro ","forever ","compilerendif ","compilerendselect ","endstructure "
  
  #temp=7
  Data.s "else ","elseif ","case ","compilerelse ","default ","compilercase ","compilerdefault "
EndDataSection

Dim indent_plus.s(#plus)
Dim indent_minus.s(#minus)
Dim indent_temp.s(#temp)

For n=1 To #plus
  Read.s indent_plus(n)
Next
For n=1 To #minus
  Read.s indent_minus(n)
Next
For n=1 To #temp
  Read.s indent_temp(n)
Next

addspaces=0
#ind=2

RenameFile(pps,pps+".bak")
OpenFile(0,ppt)
CreateFile(1,pps)

While Not Eof(0)
  getline.s=ReadString(0)
  getline=Trim(getline)+" "
  toadd.s=Space(addspaces)
  
  flag=0
  For n=1 To #plus
    compare.s=indent_plus(n)
    If LCase(Left(getline,Len(compare)))=compare
      flag=1
    EndIf
  Next
  If flag
    addspaces+#ind
  EndIf
  
  flag=0
  For n=1 To #minus
    compare.s=indent_minus(n)
    If LCase(Left(getline,Len(compare)))=compare
      flag=1
    EndIf
  Next
  If flag
    addspaces-#ind
    If addspaces<0
      addspaces=0
    EndIf
    toadd=Space(addspaces)
  EndIf
  
  flag=0
  For n=1 To #temp
    compare.s=indent_temp(n)
    If LCase(Left(getline,Len(compare)))=compare
      flag=1
    EndIf
  Next
  If flag
    If Len(toadd)>0
      toadd=Left(toadd,Len(toadd)-#ind)
    EndIf
  EndIf
  
  
  getline=RTrim(toadd+getline)
  WriteStringN(1,getline)
Wend
CloseFile(0)
CloseFile(1)
CopyFile(pps,ppt)
and

Code: Select all

;UNINDENTER
;
;Configure as tool with Arguments set as "%FILE" "%TEMPFILE"
;Set shortcut to 'ctrl' 'shift' and 'U'
;Tick 'Wait until tool quits', 'Reload Source' and 'into current source'
;
cpp.b=CountProgramParameters()
If cpp<>2
  MessageRequester("Error","Wrong number of parameters.")
  End
EndIf

pps.s=ProgramParameter()
ppt.s=ProgramParameter()

If pps=""
  MessageRequester("Error","Source file has to be saved first.")
  End
EndIf

RenameFile(pps,pps+".bak")
OpenFile(0,ppt)
CreateFile(1,pps)

While Not Eof(0)
  getline.s=ReadString(0)
  getline=Trim(getline)
  WriteStringN(1,getline)
Wend
CloseFile(0)
CloseFile(1)
CopyFile(pps,ppt)
Doesn't take into account TABS, just adds spaces 2 at a time and also doesn't look any further than the first word on a line so for example

If a=1 : b=1 : EndIf

will miss the endif, solution, split the line into 3!

Anyway, try them if you like. :D
MikeB
Enthusiast
Enthusiast
Posts: 183
Joined: Sun Apr 27, 2003 8:39 pm
Location: Cornwall UK

Post by MikeB »

Great program, just what I needed to save a lot of messing about with downloaded progs! :D :D

There is one minor bug however, add "procedure." to the data section or the "procedure " will not pick up typed procedures. Don't forget to change the #plus to =12.

I also modified mine to put in TABs instead of spaces as that is what I use as I like bigger indents and tabs are quicker than multiple spaces.

Code: Select all

toadd.s = ""
If addspaces > 0
   For k = 1 To addspaces
      toadd.s = toadd + Chr(9)  ; add TABs
   Next
EndIf
instead of the "Space(addspaces)" bit.

I also included a "getline = replacestring(getline, Chr(9), "")" before the “getline = trim(getline)+" "” to remove any TABs that I might have already used.
Mike.
(I'm never going to catch up with the improvements to this program)
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Glad you liked it. I'm sure there are some other commands that should be indented so feel free to change whatever you like. :D
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

i fail to see why you would like to 'unindent' your source, but hey :-) i'm not *that* good :-)

anyway, codecaddy does some reformatting as well (and would be a lot better if fr34k would get rid of that annoying reload bug :-))
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Yeah, I see your point, it is a bit redundant. I was having reloading problems which is why I do a copy of the indented source to the tempfile as the last command, seems to fix the problem, at least with my program.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

reloading problems? as in: you try to reload your source from inside the ide, and the ide takes ages to reload? i can reproduce this clearly, and i know it's something inside the ide that causes it...

(in fact, it looks like the ide hangs, but it is actually reloading)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

I was getting an old copy of the source being reloaded even though I was renaming it and creating a new copy, then I started using the tempfile and was not getting the indented code reloaded.

In the end I had to create a new file which is indented and overwrite the tempfile with this before I could get it all to work.

But this is not the same problem as yours.
MikeB
Enthusiast
Enthusiast
Posts: 183
Joined: Sun Apr 27, 2003 8:39 pm
Location: Cornwall UK

Post by MikeB »

I don't know what the reloading problem is that you speak of, but I may have fixed it without knowing.

The way the files were handled seemed a bit strange to me so I changed it. In my version I set it to work on a file that is not already open, I used a filerequester to get the filename, then it deletes the “XXXXX.pb.bak” file, if it exists and renames the existing file as “XXXXX.pb.bak”.

Then it opens the “XXXXX.pb.bak” to read from and creates “XXXXX.pb” to write to. The main part runs and closes both files. Nothing then needs copying on completion.

Just load the original filename and away you go.
Mike.
(I'm never going to catch up with the improvements to this program)
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Yeah, but with the program the way I wrote it and installed as a tool you can just press 'ctrl' 'shift' and 'i' and it will indent the code on the screen without you having to select anything and it will be reloaded without any user assistance.

@MikeB, have you installed it as a tool or are you using it as a stand alone program?
MikeB
Enthusiast
Enthusiast
Posts: 183
Joined: Sun Apr 27, 2003 8:39 pm
Location: Cornwall UK

Post by MikeB »

It is used as a stand alone program in effect, but it is accessed from the tools menu, but as I said I use a filerequester to get the filename.

I changed it while adapting the program to insert TABs instead of double spaces, as in the past I have tried tools that work on open programs and had trouble with either destroying the original or never returning. It may have been something funny with earlier versions of PB? So I went for the way that just seems safer to me.

I know it's nice to auto-indent a loaded program and see it happen, but in theory I only do it the once on programs using spaces that I want converted to TABs. In that case I just run the program before loading (or save, close, run, reload). A minor inconvenience for one program and actually easier if doing several.
Mike.
(I'm never going to catch up with the improvements to this program)
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

Derek wrote:I was getting an old copy of the source being reloaded even though I was renaming it and creating a new copy, then I started using the tempfile and was not getting the indented code reloaded.

In the end I had to create a new file which is indented and overwrite the tempfile with this before I could get it all to work.

But this is not the same problem as yours.
euh, i'm a bit lost now, could you elaborate a little? or show me a small code sample?

codecaddy comes with source, so you can compare your approach with mine, perhaps i did something stupid, it's 3.94 though :-)

oh, and i do create numbered backups to avoid the 'loosing the old version of the code' problem
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
BillNee
User
User
Posts: 93
Joined: Thu Jan 29, 2004 6:01 am
Location: Homosassa, FL

auto-indent

Post by BillNee »

Hi Derek - a great program! Always wanted to get listings in better shape and your program does the job. Is it possible to indent the "case" in "select" like -
--select x
----case 1:do this
----case 2:do this
--endselect
or
--select x
----case 1
------do this
----case 2
------do this
--endselect
?
I also couldn't get next:return to indent even though "next" was the first word
--for x=1 to 5
----do this
--next:return

These are small items compared to what you've done. Really appreciate this tip
Bill Nee
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

@BillNee, glad you like it.

It should indent CASE and NEXT, I notice you have colons after both commands, the program actually looks for the keyword followed by a space, to stop it indenting variables.

If you change the line to 'next : return' or split it onto two lines then it should work, same with the case command.

Let me know if this helps or you have any other problems. :D
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

@Blueznl, make the following into a tool with the argument set as "%FILE"

Code: Select all

ppt.s=ProgramParameter()
RenameFile(ppt,ppt+".bak");rename file to backup
OpenFile(1,ppt+".bak");open backed up file
OpenFile(2,ppt);open new file with same name

While Not Eof(1);process files
a$=ReadString(1)
WriteStringN(2,"  "+a$)
Wend

CloseFile(1);closefiles
CloseFile(2);IDE should now reload file
Now load a sample program that you don't mind possibly losing some data from into PB. select the tool and it should indent everything, now add a line into the program but don't save it. Run the tool again and it now loads in an older copy, losing anything you have just entered.

I got around this by using the "%TEMPFILE" and then overwriting the tempfile afterwards so that there were no old copies lying around.

Hope this clears it up.
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Post by eJan »

Thanks Derek!
I have commented indenter line:

Code: Select all

;RenameFile(pps,pps+".bak")
Is there a solution to make indentation only (without modifying the source), closing it without msgbox to save changes?
Image
Last edited by eJan on Mon Jan 15, 2007 11:17 pm, edited 1 time in total.
Post Reply