Jump to content
Mark NZ

VSCode for a Delphi IDE

Recommended Posts

I've had a couple of requests for information on what settings etc I use to edit, compile Delphi from VSCode and I'm hoping others can add insights on what they use.
I don't have extensive experience with VSCode and moved to it last year for the following reasons, in priority order

 

  1. To work around a lot of problems we encounter with the Embarcadero IDE with our projects
  2. To have a consistent IDE between Linux C work and Windows Delphi
  3. To trial effectiveness of CoPilot after co-workers said how great it was.

 

Unfortunately I haven't done a clean VSCode setup and notes record from scratch so these aren't definitive notes.
I do some C coding on a Linux VM for a real time control app as well as Windows Delphi, hence C/C++ extensions

Extensions

I have following extensions installed
C/C++,  C/C++ Extension Pack, C/C++ GNU Global, C/C++ Themes, CMake, CMakeTools, 

CodeLLDB
Delphi LSP, Insert GUID, #region folding,

#region tree view
GitHub Copilot
GitHub Copilot Chat

Numbered Bookmarks

Pascal, Pascal Formatter

SVN

Todo Tree
WSL

XML

 

The following extensions are installed but disabled

#region tree view

Auto-align

Better Align

My notes say I installed the following but they aren't there now

Delphi Extension Pack which installs Pascal (still installed), Numbered Bookmarks (still installed), Delphi Keymap, Delphi Themes, 

CodeRunner, MakeFile,

 

Note on CoPilot, I'm a greybeard (although haven't had a beard for many years) and have been amazed at what it suggests, can do and some of the inferences it makes.  Sometimes it's mind boggling, eg coming up with a correct suggestion for something you're typing that's not related to anything else in the code nor anything else that you would think was commonplace.  You do need to check it carefully though, hallucinations, subtle and not subtle mistakes but well worth the time it can save.

Editor Tab colors

I use dark themes.  It can be difficult to see which tab item in the tab bar belongs to the currently visible file in the editor, especially when jumping to function definitions etc.
To add colorization open settings and search for colorcustomization
Under workbench: Color Customization click on Edit in settings.json
Example settings
1) black inactive tab header with active tab having medium blue background and light blue activeBorder and activeBorderTop

    "workbench.colorCustomizations": {

        "tab.activeBackground": "#0091ff56",
        "tab.activeBorder": "#00aaff",
        "tab.unfocusedActiveBorder": "#000000",
        "tab.activeBorderTop": "#00aaff" // Active Tab Top Highlighting
    }}

 

2) black tab headers with red activeBorder and activeBorderTop

    "workbench.colorCustomizations": {
        "tab.activeBackground": "#11ff001a",
        "tab.activeBorder": "#ff0000",
        "tab.unfocusedActiveBorder": "#000000",
        "tab.activeBorderTop": "#ff0000" // Active Tab Top Highlighting
    }

VSCode for Delphi Programming

Here’s Embarcadero’s page on setting up DelphiLSP with Visual Studio Code https://docwiki.embarcadero.com/RADStudio/Athens/en/Using_DelphiLSP_Code_Insight_with_Other_Editors 

 

Generation of a .delphilsp.json file from Delphi is controlled through Delphi Options, Editor->Language->Code Insight->Generate LSP Config 

Type LSP into VSCode settings to to Delphi LSP settings and set the location of the project delphilsp json file

 

Preferences / Settings

I don't like the LSP suggestion autocomplete happening when I press enter, for example by default when I type begin and hit enter it replaces it with BeginGlobalLoading
To prevent this I leave suggestions on but turn off ENTER as a completion shortcut ( TAB can still be used). Go to settings
File > Preferences > Settings > Text Editor > Suggestions > Accept Suggestions On Enter > Select on, off or smart. ("Controls whether suggestions should be accepted on Enter, in addition to Tab [...]"

Building via VSCode tasks

I suspect creating an extension to build by normal VSCode method would be not difficult to do but haven't had time to investigate.  Currently I build using tasks and it's a bit messy but is functional.

 

 

If you were only building a single DEBUG config using this method it would be simpler as you wouldn’t need to choose the config each time you build or run, we build different configs for different emulations.
I was hoping we could somehow easily preselect the emulator config we want to use at the start of a session and then just build/run each time (eg via <shift><ctrl>B) without having to select the config but haven't had time to look into that further.

We already had batch files setup for release building done outside of the IDE, ie Crbuild.bat, and use these for building via VSCode.

tasks.json needs to go in the .vscode folder, eg if I'm working on the TC7\TC7.dproj project then in TC7\.vscode folder, assuming TC7 is the workspace folder you have open.

<shit><ctrl>B will build or you can choose to run your desired task from Tasks: Run Task


Sample tasks.json from our wiki
 


/*
  Tasks definitions for compiling and running
  TC7 in VS Code.

  You can use this file for .vscode/tasks.json file in a workspace,
  or as "User level tasks" (indepedent of workspace).

  This tasks file allows to compile /run / compile+run the TC7 project using Wrist Bevel Emulator
  associated with the currently open file.

  Need to look at how to handle building using different emulators.
  One option could be to open a file in the emulator folder and then use ${fileDirname},
  can set cwd using the following
    "cwd": "${fileDirname}" 

  See https://go.microsoft.com/fwlink/?LinkId=733558
  for the documentation about the tasks.json format.
*/
{
    "version": "2.0.0",
    "inputs": [
        {        
            "id": "emulatorFolder",
            "type": "pickString",
            "description": "Select the emulator folder",
            "options": [
                "RELEASE",
                "DEBUG",
                "abs encoded 12 magnet twin sled PUG",
                "700 Towers",
                "725 K4100 wrist bevel",
                "wrist bevel x86",
                "K5100 wrist bevel and unloader" 
            ],
            "default": "K5100 wrist bevel and unloader" 
        }
    ],
    "tasks": [
        // Compile and then Run the TC7 project of the currently open editor file.
        // This is like F9 in Delphi.
        {
            "label": "(TC7) Compile And Run",
            /* We use VS code "dependsOn" feature to run 2 tasks in a sequence.
               This is better than using shell command with && which
               is not universally supported by PowerShell. */
            "dependsOn": [
                "(TC7) Compile",
                "(TC7) Run" 
            ],
            "dependsOrder": "sequence",
            "group": {
                "kind": "build",
             }
        },
        // (Re)build the TC7 project 
        {
            "label": "(TC7) (Re)Build",
            "type": "shell",
            /* Compile in debug mode using TC7 build tool (calls msbuild under the hood).
               */
               "command": "${workspaceFolder}\\crbuild.bat",
               "args": [
                   "-ProductVersion", "23.0",
//                   "-config", "DEBUG",
                   "-config", "${input:emulatorFolder}",
                   "-nolog",
                   "-target", "rebuild" 
//                   "-OutDir", "${workspaceFolder}\\Output\\EMUs\\${input:emulatorFolder}" 
               ],
               "options": {
                  "cwd": "${workspaceFolder}" 
//                "cwd": "${workspaceFolder}/Output/EMUs/${input:emulatorFolder}" 
},
            "group": {
                "kind": "build",
                "isDefault": false
            },
            "problemMatcher": {
                "fileLocation": "autoDetect",
                //["autoDetect", "${workspaceFolder}"],
                "pattern": [
                    {
                        /*
                        Match lines like
                          xxx.pas(123,456) Fatal: some message
                        Deliberately avoid matching summary line like
                          xxx.pas(2201) Fatal: There were 26 errors compiling module, stopping
                        Deliberately avoid
                          xxx.pas(648,15) Error: Found declaration: ...
                        because they only make sense when connected to previous error message, and VS Code reorders them.
                        Test: https://regex101.com/ (ECMAScript flavor)
                        */
                        "regexp": "^([^\\(]+)\\(([\\d+,]+)\\)\\s+(Fatal|Warning|Error|Note|Hint):\\s+((?!\\(10026\\) There were)(?!There were)(?!Found declaration: )(?!\\(5088\\)Found declaration: ).*)$",
                        "file": 1,
                        // location may be line or line+column.
                        "location": 2,
                        "severity": 3,
                        "message": 4
                    }
                    /* ,
                    {
                        // Match lines like
                        // Compiling xxx.pas
                        "regexp": "^(Compiling) ([^\\s]+)$",
                        "file": 2,
                        "message": 1,
                        "kind": "file" 
                    }
                    */
                ],
                /* We need non-empty owner to hide older problems on recompilation.
                See https://github.com/Microsoft/vscode/issues/50448,
                https://github.com/microsoft/vscode/issues/66982
                */
                "owner": "Kinetic Engineering" 
            }
        },
        // Compile the TC7 project 
        {
            "label": "(TC7) Compile",
            "type": "shell",
            /* Compile in debug mode using TC7 build tool (calls msbuild under the hood).
               */
               "command": "${workspaceFolder}\\crbuild.bat",
               "args": [
                   "-ProductVersion", "23.0",
//                   "-config", "DEBUG",
                   "-config", "${input:emulatorFolder}",
                   "-nolog",
                   "-target", "build" 
//                   "-OutDir", "${workspaceFolder}\\Output\\EMUs\\${input:emulatorFolder}" 
               ],
               "options": {
                  "cwd": "${workspaceFolder}" 
//                "cwd": "${workspaceFolder}/Output/EMUs/${input:emulatorFolder}" 
},
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "fileLocation": "autoDetect",
                //["autoDetect", "${workspaceFolder}"],
                "pattern": [
                    {
                        /*
                        Match lines like
                          xxx.pas(123,456) Fatal: some message
                        Deliberately avoid matching summary line like
                          xxx.pas(2201) Fatal: There were 26 errors compiling module, stopping
                        Deliberately avoid
                          xxx.pas(648,15) Error: Found declaration: ...
                        because they only make sense when connected to previous error message, and VS Code reorders them.
                        Test: https://regex101.com/ (ECMAScript flavor)
                        */
                        "regexp": "^([^\\(]+)\\(([\\d+,]+)\\)\\s+(Fatal|Warning|Error|Note|Hint):\\s+((?!\\(10026\\) There were)(?!There were)(?!Found declaration: )(?!\\(5088\\)Found declaration: ).*)$",
                        "file": 1,
                        // location may be line or line+column.
                        "location": 2,
                        "severity": 3,
                        "message": 4
                    }
                    /* ,
                    {
                        // Match lines like
                        // Compiling xxx.pas
                        "regexp": "^(Compiling) ([^\\s]+)$",
                        "file": 2,
                        "message": 1,
                        "kind": "file" 
                    }
                    */
                ],
                /* We need non-empty owner to hide older problems on recompilation.
                See https://github.com/Microsoft/vscode/issues/50448,
                https://github.com/microsoft/vscode/issues/66982
                */
                "owner": "Kinetic Engineering" 
            }
        },
        // Run the previously compiled TC7 project.
        // This is like <ctrl><shift><F9> in Delphi IDE.
        {
            "label": "(TC7) Run",
            "type": "shell",
            "command": "./TC7.exe",
            "args": [
                "/no_scale",
                "/t:0",
                "/l:105",
                "/portrait",
                "/no_polling_err",
                "/moveable_display",
                "/web_debug:..\\Web\\Resources\\" 
            ],
            "options": {
                "cwd": "${workspaceFolder}/Output/EMUs/${input:emulatorFolder}" 
            },
            "group": {
                "kind": "build" 
            }
        }
    ]
}

 

 

A sample crbuild.bat is as follows

@echo off

set BUILD_TARGET_TYPE="rebuild" 
set BUILD_CONFIG=Release
set OUTPUT_TO_LOG=Y
set OUTPUT_FOLDER_PARAM=

rem Set the default Delphi version to compile with, 22.0 => Delphi 11.x, 23.0 => Delphi 12.1
set ProductVersion=22.0

:argsloop
IF NOT [%1]==[] (
  IF /i [%1]==[-config] (
    SET BUILD_CONFIG=%2
    shift
  )
  IF /i [%1]==[-ProductVersion] (
    SET ProductVersion=%2
    shift
  )
  IF /i [%1]==[-Target] (
    SET BUILD_TARGET_TYPE=%2
    shift
  )
  IF /i [%1]==[-nolog] (
    SET OUTPUT_TO_LOG=N
  )
  SHIFT
  GOTO :argsloop
)

set BUILD_TYPE=DEBUG
set BUILD_CONFIG_UNQUOTED=%BUILD_CONFIG:"=%
if /i ["%BUILD_CONFIG_UNQUOTED:~0,7%"]==["RELEASE"] (
  set BUILD_TYPE=RELEASE
)

set DELPHI_VARS_PATH="C:\Program Files (x86)\Embarcadero\Studio\%ProductVersion%\bin\rsvars.bat" 
call %DELPHI_VARS_PATH%

rem build using msbuild 
set MSBUILD_CMD=msbuild TC7.dproj /t:%BUILD_TARGET_TYPE% /p:config=%BUILD_CONFIG%

echo Running %MSBUILD_CMD%

if /i "%OUTPUT_TO_LOG%"=="Y" (
  %MSBUILD_CMD% 2>&1>>".\Output\crbuild.log" 
) else (
  %MSBUILD_CMD%
)

Debugging

Not working yet, would like to get it working for simple debugging and have only spent a little bit of time on it.  Whether it's overly usable for inspecting values/classes etc though will be interesting - but then we have a lot of problems with Delphi debugging inspection etc of things not working. 
Have tried using lldb setup via the following VSCode launch.json setting file but lldb won't run the exe (eg running lldb from command line).  WinDBG will run the exe but have only briefly tried it
 

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Delphi TC7 L102 Maxphotonics",
      "type": "lldb",
      "request": "launch",
      "program": "${workspaceFolder}/Output/emus/L102 Maxphotonics/TC7.exe",
      "args": ["/no_scale /t:0 /l:105 /portrait /no_polling_err /moveable_display /web_debug:..\\Web\\Resources\\"],
      "cwd": "${workspaceFolder}/Output/emus/L102 Maxphotonics",
      "stopOnEntry": false,
      "preLaunchTask": "Echo vars"
    }
  ]
}
  • Thanks 3

Share this post


Link to post
1 hour ago, omnibrain said:

Does anyone know what happened to OmniPascal?

Not much since 2022. Sadly I just now got interested in the subject. So I'm putting my hopes on @Mark NZs efforts.

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

×