Skip to content

VS Code Tips for FORM Developers

Takahiro Ueda edited this page Sep 19, 2024 · 7 revisions

Since Visual Studio Code (VS Code) is used by many people, it would be helpful to introduce some useful configuration tips (i.e., workspace settings in .vscode/*.json) for VS Code here.

For simplicity, we assume a Linux environment, the local repository is cloned from your fork:

git clone [email protected]:YOUR_GITHUB_USER_NAME/form.git
cd form
git remote add upstream https://github.com/vermaseren/form.git

and the build directory (using out-of-source build) is build:

autoreconf -fiv
mkdir -p build
pushd build
../configure --enable-debug
echo '*' >.gitignore
popd

The following commands configure Git to ignore the workspace settings:

mkdir -p .vscode
echo '*' >.vscode/.gitignore

Basic Editor Settings

VS Code's auto-formatter is useful, so you may have it enabled globally. However, because the FORM source code is written in somewhat unique coding style, applying the formatter leads to massive changes that you do not desire. If this is the case, you need to turn it off in your workspace settings. Moreover, whitespaces and end-of-line settings should be adjusted for the FORM source code.

.vscode/settings.json:

{
    "editor.defaultFormatter": null,
    "editor.formatOnPaste": false,
    "editor.formatOnSave": false,
    "editor.formatOnType": false,
    "files.eol": "\n",
    "files.insertFinalNewline": true,
    "files.trimTrailingWhitespace": false
}

Folding

The FORM source code utilizes folding extensively with the fold markers #[ and #]. Unfortunately, as of April 2024, VS Code does not support folding based on custom markers. This is implemented, for example, by the following extension:

The configuration is as follows:

.vscode/settings.json:

{
    "editor.foldingStrategy": "auto",
    "editor.defaultFoldingRangeProvider": null,

    "[c]": {
        "editor.defaultFoldingRangeProvider": "zokugun.explicit-folding",
        "explicitFolding.rules": [
            {
                "begin": "#[",
                "end": "#]"
            },
            {
                "beginRegex": "#if(?:n?def)?",
                "middleRegex": "#el(?:se|if)",
                "endRegex": "#endif"
            }
        ]
    },

    "[cpp]": {
        "editor.defaultFoldingRangeProvider": "zokugun.explicit-folding",
        "explicitFolding.rules": [
            {
                "begin": "#[",
                "end": "#]"
            },
            {
                "beginRegex": "#if(?:n?def)?",
                "middleRegex": "#el(?:se|if)",
                "endRegex": "#endif"
            }
        ]
    },

    "[form]": {
        "editor.defaultFoldingRangeProvider": "zokugun.explicit-folding",
        "explicitFolding.rules": [
            {
                "begin": "#[",
                "end": "#]"
            }
        ]
    }
}

Whitespaces

Because the FORM source code contains intentional trailing whitespaces in some places, the following plugin to display them can be useful:

C/C++

At a minimum, the following extension is needed:

  • C/C++ (ms-vscode.cpptools)

However, to avoid seeing the pop-up message

Do you want to install the recommended 'C/C++ Extension Pack' extension from Microsoft for the C language?

every time you launch VS Code and open a C file for the first time after starting, you may install the following recommended extension:

Intellisense configuration is as follows. Note that some POSIX symbols require that _POSIX_C_SOURCE is properly defined (e.g., pthread_rwlock_t).

.vscode/c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "form",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "_POSIX_C_SOURCE=200809L"
            ]
        },
        {
            "name": "vorm",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "_POSIX_C_SOURCE=200809L",
                "DEBUGGING"
            ]
        },
        {
            "name": "tform",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "_POSIX_C_SOURCE=200809L",
                "WITHPTHREADS"
            ]
        },
        {
            "name": "tvorm",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "_POSIX_C_SOURCE=200809L",
                "WITHPTHREADS",
                "DEBUGGING"
            ]
        },
        {
            "name": "parform",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "_POSIX_C_SOURCE=200809L",
                "WITHMPI",
                "PF_WITHGETENV",
                "PF_WITHLOG"
            ]
        },
        {
            "name": "parvorm",
            "includePath": [
                "${workspaceFolder}/build",
                "${workspaceFolder}/build/sources"
            ],
            "defines": [
                "HAVE_CONFIG_H",
                "WITHMPI",
                "PF_WITHGETENV",
                "PF_WITHLOG",
                "DEBUGGING"
            ]
        }
    ],
    "version": 4
}

Debugging configuration with GDB, running test.frm, is as follows.

.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) vorm test.frm",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/sources/vorm",
            "args": [
                "test.frm"
            ],
            "cwd": "${workspaceFolder}",
            "environment": [],
            "stopAtEntry": false,
            "externalConsole": false,
            "MIMode": "gdb",
            "preLaunchTask": "make-vorm",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        },
        {
            "name": "(gdb) tvorm -w4 test.frm",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/sources/tvorm",
            "args": [
                "-w4",
                "test.frm"
            ],
            "cwd": "${workspaceFolder}",
            "environment": [],
            "stopAtEntry": false,
            "externalConsole": false,
            "MIMode": "gdb",
            "preLaunchTask": "make-tvorm",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

.vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "make-vorm",
            "type": "shell",
            "command": "make -j $(nproc) vorm",
            "options": {
                "cwd": "${workspaceFolder}/build/sources"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "make-tvorm",
            "type": "shell",
            "command": "make -j $(nproc) tvorm",
            "options": {
                "cwd": "${workspaceFolder}/build/sources"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

FORM

.vscode/settings.json:

{
    "files.associations": {
        "*.h": "c"
    }
}

Git

GitHub Actions

Autotools

Spell Checker

.vscode/settings.json:

{
    "cSpell.allowCompoundWords": true,
    "cSpell.maxNumberOfProblems": 1000,
    "cSpell.enableFiletypes": [
        "automake",
        "form",
        "github-actions-workflow",
        "m4",
        "ruby"
    ],
    "cSpell.words": [
        "ARGTOARG",
        "BHEAD",
        "boomlijst",
        "CBUF",
        "CDELETE",
        "CDOLLAR",
        "CDUBIOUS",
        "CEXPRESSION",
        "CFLAGS",
        "CFUNCTION",
        "CINDEX",
        "Civita",
        "CNUMBER",
        "compactify",
        "CPPFLAGS",
        "CSYMBOL",
        "CXXFLAGS",
        "daemonization",
        "DOLWILDARGS",
        "DROPGEXPRESSION",
        "DROPHGEXPRESSION",
        "DROPHLEXPRESSION",
        "ENDOFINPUT",
        "EXECUTINGIF",
        "FROMBRAC",
        "FUNTOFUN",
        "GRCC",
        "HAAKJE",
        "HIDEGEXPRESSION",
        "INDTOIND",
        "INDTOSUB",
        "INTOHIDEGEXPRESSION",
        "ISFACTORIZED",
        "ISGEPOSINC",
        "ISNOTZEROPOS",
        "ISUNMODIFIED",
        "ISZERO",
        "LDFLAGS",
        "LEVICIVITA",
        "LHSIDE",
        "lijst",
        "LPARENTHESIS",
        "Mathematica",
        "MAXNCPLG",
        "MCTS",
        "Moebius",
        "MPFR",
        "Mully",
        "NCOPY",
        "NOPARALLEL",
        "PFORTRANMODE",
        "RHSIDE",
        "SETTONUM",
        "SKIPGEXPRESSION",
        "SNUMBER",
        "stuffle",
        "SYMTONUM",
        "SYMTOSUB",
        "SYMTOSYM",
        "TDIVIDE",
        "TDOLLAR",
        "TDUBIOUS",
        "TENDOFIT",
        "Tentyukov",
        "TFORM",
        "TFUN",
        "TFUNCLOSE",
        "TFUNCTION",
        "TFUNOPEN",
        "TINDEX",
        "TMINUS",
        "TMULTIPLY",
        "TNUMBER",
        "TOBEFACTORED",
        "TOBEUNFACTORED",
        "TOLONG",
        "totalnumberofthreads",
        "TPLUS",
        "TPOWER",
        "TSYMBOL",
        "TVECTOR",
        "TYPEIF",
        "unfactorize",
        "UNHIDEGEXPRESSION",
        "UNHIDELEXPRESSION",
        "UWORD",
        "VARTYPEROOTOFUNITY",
        "VECTOMIN",
        "VECTOSUB",
        "VECTOVEC",
        "Vermaseren",
        "WCOPY",
        "WITHMPI"
    ]
}