Have you ever written an IDE script?

I just never needed one until yesterday when I wanted to automate setting an attribute for each of a long list of classes in a project.

Tell all of us about a cool IDE script you’ve written.

A bunch of code assistant scripts aimed at people who write declares on macOS:

1 Like

We used to have a script to build a solution with demo and full product for macOS and Windows.

  1. Set app.demo constant to true
  2. Set name to “MyApp Demo”
  3. Build Mac
  4. Build Windows
  5. Set app.demo constant to false
  6. Set name to “MyApp”
  7. Build Mac
  8. Build Windows

With some error logic to stop as soon as a build failed.
That was convenient to build a release.

1 Like

I have a Script that compiles one App in two modes. The one code base creates both a CRM (Customer Relationship Manager - people who you sell to) and an SRM (Supplier Relationship Manager - people who sell to you).

The Script sets the application name, sets the App.isCRM and App.isSRM constants to True/False, sets the ‘Optimize Level’ to Moderate, compiles for Windows Intel, moves the new app out of the Build folder, then runs again as the alternate app with the opposing settings, moves this new app out of the Build folder too, then resets the constants back to their original state.

Ideally it would launch InnoSetup and build the Installer EXE, but that’s not the time consuming part.

Once in a while when I copy code from an older post on the forums, I end up with code that has curly quotes (“”) instead of straight quotes ("), which screws up code:

Var a As String = “Some Text”
vs
Var a As String = "Some Text"

So one of my first IDE scripts was to fix curly quotes:

// This script replaces curly quotation marks with
// straight quotation marks

Function Name () As String
  Return "Straighten Curly Quotes"
End Function

Function CanEdit (selection As String) As Boolean
  Var hasCurlyQuotes As Boolean
  If selection.indexof("“") > -1 Then
    hasCurlyQuotes = True
  End If
  If selection.indexof("”") > -1 Then
    hasCurlyQuotes = True
  End If
  
  Return hasCurlyQuotes
End Function

Function Edit (selection As String) As String
  
  selection = selection.ReplaceAll("“", Chr(34))
  selection = selection.ReplaceAll("”", Chr(34))
  
  Return selection
  
End Function

Here’s one… Selecting a method in the navigator and run this script to add a documentation comment to the top of the code editor:

// header maker
DoCommand("Copy")

Dim lines() As String
lines = split(clipboard, chr(13))
Dim sigline As String = lines(0)

Dim parts() As String
Dim p1 As Integer = instr(sigline, "(")
Dim name, paramstr As String
If p1 > 0 Then
  name = left(sigline, p1 - 1)

  Dim p2 As Integer = sigline.length
  while mid(sigline,p2,1)<>")"
	p2 = p2 - 1
  wend

  paramstr = mid(sigline, p1 + 1, p2 - p1 - 1)
End If

Dim scope As String = nthfield(name, " ", 1)
Dim mType As String = nthfield(name, " ", 2)
name = nthfield(name, " ", 3)

Dim params() As String = split(paramstr, ",")
For i As Integer = 0 To UBound(params)
  params(i) = trim(params(i))
Next

Dim returntype As String = nthfield(sigline, " ", countfields(sigline, " "))
If instr(returntype, ")") > 0 Or returntype = name Then 
  returntype = ""
End If

Redim lines(-1)
lines.append "//===================================="
lines.append "//"
lines.append "// Name: " + name
lines.append "// Params: "
For i As Integer = 0 To UBound(params)
lines.append "//    " + params(i)
Next
lines.append "// Returns: " + returntype
lines.append "//"
lines.append "//===================================="
lines.append ""
lines.append ""

Text = join(lines, endofline) + Text

so if the signature is:
CSR_ItemsSelected(obj as NSSavePanelGTO, items() as FolderItem)

it adds:

//====================================
//
// Name: CSR_ItemsSelected
// Params: 
//    obj as NSSavePanelGTO
//    items() as FolderItem
// Returns: 
//
//====================================
3 Likes

I was quite astonished when I counted my scripts that I have 20 of them:

  • The IDE Communicator script builds 4 apps in 3 different flavors.
  • I need to copy apps to get for instance the helper app into the right position.
  • I have some scripts which I can remove because of the internal plist editor.
  • Add files for Valentina.
  • AppWrapper
  • etc.

Developing IDE scripts sucks because there is no debugger. This means that they have to developed line by line. And when there is suddenly an error it means finding the bad script one by one because the error message doesn’t have the script name.

3 Likes

when I create a new methode, I use this script:

// Add a comment header to top of the current method.

Var projectFile As String = ProjectShellPath
Var header As String
Var s As String
Var info As String
Var ppte As String
Var sep As String = "- "  + EndOfLine
Var Nom As String = Location
Var idx As Integer
Var Nom02 As String
Var met As String

met = Text

Nom02 = Nom.Replace(“.”, “XX.”)

Var version As String
version = PropertyValue(“App.MajorVersion”) + “.” + _
PropertyValue(“App.MinorVersion”) + “.” + _
PropertyValue(“App.BugVersion”) + " (" + _
PropertyValue(“App.NonReleaseVersion”) + “)”
s = ItemAttribute( “Nom” )

header = "’ Copyright JLP 2023 " + EndOfLine
header = header +  "’ version: " + version + EndOfLine
header = header + EndOfLine
header = header + " ’ Méthode:  " + Nom + " ( ) "
header = header + EndOfLine
header = header + " ’ ************************************************************ " + EndOfLine

header = header + " ’ Description:  " + EndOfLine + EndOfLine

header = header + " ’ Méthode a copier:  " + EndOfLine
header = header + " ’ " + Nom02  + " (   )"

header = header + EndOfLine  + EndOfLine
header = header + " ’ ************************************************************ " + EndOfLine

header = header + “Var tx As String” + EndOfLine
header = header + “Var b As Boolean” + EndOfLine
header = header + “Var c34 As String  = Encodings.UTF8.Chr( 34 )” + EndOfLine + EndOfLine

header = header + EndOfLine
// header = header + Text
header = header + met

//  header = header + "name " + name

header = header + EndOfLine + EndOfLine
header = header + " Exception err "+ EndOfLine
header = header + " Break "+ EndOfLine
header = header + " // "

Text = header + EndOfLine
//

Xojo “to do”: Script editor with autocomplete and active linter. Most errors a linter will point out just at writing code time. It’s a kind of background compiler that generates no code, just the error list needing fixing and many times offers suggestions.

3 Likes

I have 12 Xojo projects I don’t build Universal. Long time ago when we moved from Motorola to Intel I didn’t build universal neither. Then I use an IDE script to set a constant in all my project with the actual date (the built date) and I build for INTEL, ARM and Windows.
I have another script to save all my projects.
I really miss a DoCommand(“CloseWindow”) saving YES/NO.

This is my “Archive” script. Unfortunately there’s no scripting command for “Collect Project Items” so I had to resort to a keyboard shortcut triggered via BetterTouchTool. The script saves some time and when coupled with my deployment utility that zips and uploads the collected archive folder it encourages me to be diligent about archiving.

Print "This script creates a dated archive folder next to the source file and copies the source into it,"+EndOfLine+ _
"then closes the source file, opens the copy, and offers to collect project items." +EndOfLine+_
"Ctl-Shift-C must be assigned to Collect Project Items in Xojo keyboard shortcuts and a BTT Named Trigger 'Xojo Collect' must send that to Xojo."

Var ProjFilePath As String = ProjectShellPath // Path to the Xojo project file

Dim Dirs() As String = ProjFilePath.split("/")  
Dim ProjFilename As String = Dirs(Dirs.LastRowIndex)

Dim ProjectName As String = ProjFilename.Replace(".xojo_binary_project","")

Dirs.RemoveAt(Dirs.LastRowIndex) // Remove the project file from the path
Dim ProjectFolderPath As String = String.FromArray(Dirs,"/") + "/"

Var result As String

Dim date As String
date = DoShellCommand("date +%F") // Should be YYYY-MM-DD
date = date.Left(10) // Seems shell appends CR or LF to the result

// Make archive directory
Dim ArchiveDir As String = Chr(34)+ProjectName.ReplaceAll("\ "," ") +" Archive "+date+Chr(34)
result = DoShellCommand( "cd " + ProjectFolderPath + " && mkdir " + ArchiveDir) 
If result = "" Then // mkdir succeeded
  
  // Copy project file into the directory and rename with date added
  Dim ArchiveProjectName As String = (ProjectName.ReplaceAll("\ "," ") +" "+date+".xojo_binary_project")
  Dim ArchiveCopyPath As String = ProjectFolderPath + ArchiveDir + "/" + Chr(34)+ArchiveProjectName+Chr(34)
  
  result = DoShellCommand("cp "+ProjectShellPath+" "+ArchiveCopyPath) // Source file, Dest directory/NewName
  
  If result = "" Then // Copy succeeded
    DoCommand("CloseWindow") // Don't leave the original source open - we don't want to Collect its items!!!
    
    // Open the archival copy
    Dim ArchiveLoadPath As String = ProjectFolderPath + ProjectName +"\ Archive\ "+date + "/"
    ArchiveLoadPath = ArchiveLoadPath + ProjectName +"\ "+date + ".xojo_binary_project"
    OpenFile(ArchiveLoadPath)
    
    // Automating Collect Project Items requires:
    // - A keyboard shortcut for Collect Project Items, defined in Xojo prefs
    // - A global "Named Trigger" in Better Touch Tool which sends the keyboard shortcut to Xojo
    
    result = DoShellCommand("open " + Chr(34)+"btt://trigger_named/?trigger_name=XojoCollect"+Chr(34))
    
    // Doing _anything_ after the menu shortcut for Collect Project Items is sent causes the collection to be aborted,
    // so closing the archive project window and subsequent compression and uploading of the archive must be done manually.
    
  Else
    Print "Error creating project file copy: " + result
  End
Else
  Print "Error creating archive directory: "+result
End

Two others I use fairly frequently - one just inserts a complete MessageDialog code block, and another inserts code to gather the SubexpressionStrings of a RegexMatch for debugging, since they’re not made visible in the debugger:

#If DebugBuild Then
  Dim subs() As String
  For i As Integer = 0 To rgm.SubExpressionCount-1
    subs.Add rgm.SubExpressionString(i)
  Next
#EndIf