Out of the box Visual Studio Code is great but doesn’t do save+compile+debug very well.  The default debugging configuration just runs the debugger on existing code without saving or compiling first.

But the task system is GREAT and makes almost any possible automation pretty straightforward.  Here’s a quick example.  First set up any command line tasks you might need in your tasks.json file (Terminal > Configure Tasks > pick any task), eg:


{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello",
            "group": "build"
        },
        {
            "label": "Build cmake-debug",
            "type": "shell",
            "command": "clear && bash -i -c 'at dbd'",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "Build cmake-release",
            "type": "shell",
            "command": "clear && bash -i -c 'at dbr'",
            "group": "build",
            "problemMatcher": [
                "$msCompile"
            ]
        },
        {
            "label": "cmake",
            "type": "shell",
            "command": "clear && bash -i -c 'at dba'",
            "group": "build",
            "problemMatcher": [
                "$gcc"
            ]
        },
        {
            "label": "Go",
            "dependsOn": [
                "Build cmake-debug"
            ],
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}
That contains a few single-shot tasks, and another multi-task one called “Go”, where you can chain as many other tasks together as you need in the dependsOn array.  When you run Go, it will run the others in the specified order.  Here, you might note that I only needed one task in my chain (my one task does all the steps I need), but I want to future-proof by using a multi-task pattern.
From there, you can configure your … ermm.. configurations (Debug > Open Configurations).  That’s what code calls your debug task, and it’s more than a task as it figures out a lot about your compiler and debugger for you.  The configuration property we want here is called preLaunchTask, and we will specify our Go task so it runs right before the debugger starts up, eg:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/cmake-debug/at_server",
            "args": ["localhost","8000","localhost","etc"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Go"
        }
    ]
}

Some other things of note.

  • Performance of these automatic checks currently SUCKS and you need to turn them off:

    "npm.autoDetect": "off",
    "gulp.autoDetect": "off",
    "grunt.autoDetect": "off",
    "jake.autoDetect": "off",
"typescript.tsc.autoDetect": "off",
  • Bookmarks are essential, and I found that I like to have both of these popular extensions installed:
    • Bookmarks; go F2, set ctrl-F2
    • Numbered bookmarks; go c-1, set c-a-sh-1
  • There are lots more cool extensions, but be careful about bloat. Add, try, remove if not necessary.

This was going to be my naming standard for the foreseeable future.  But quicktype uses the same syntax for functionNames and variableNames, so we will go with that for code generated from quicktype.  Bye bye underscore, it’s been fun but I’m tired of typing_you_out_so_many_times.

So much lost time to such small things, but they can drive you mad if you don’t make a choice.  🙂

I spent this morning exploring available tech to address this goal:

Add a bigdata database to my application, to archive older data out of the realtime local model

This is for my stock app, which deals with realtime in-memory data during market hours, with a delayed-write to local storage.  At the end of the day, it can then archive most of the data collected during market hours.

Because I have not achieved “success” in life yet, at least enough to allow me to pursue my larger goals uninhibited, I have to be very careful about how I apply my limited resources.  To be more precise:

  • Follow patterns that are as simple as possible (but no less), and sustainable into the next decade.
  • For my projects, limit languages, libraries and tools to those that are
    • well maintained
    • solve difficult problems more elegantly than I could solve with a medium level of effort

The result of today’s philosophically-informed research:

  • The primary languages of my software projects should be Javascript and C++
  • All data should be defined by JSON schema that is used to generate code, via quicktype
  • Long-term libraries and tools include boost, jquery, bootstrap, accounting.js, moment.js, nlohmann::json, sqlite, postgres

Note that using quicktype with nlohmann::json is an elegant way to effectively get C++ reflection.  Once you serialize an object to JSON you can walk all its fields.  Then you can do things like automatically build SQL queries for your classes based on the JSON schema.  Beautiful.

PS. I avoided spotify-json, StaticJson/autojsoncxx, Google Prototype Buffers, Code Synthesis’s ODB, the sqlite JSON1 Extension, C++ reflection libraries like RTTR, lots of code from Stiffstream and Chilkat, etc. because while they are all brilliant and compelling, they bring extra weight.  The world keeps churning though, so keep searching.  Also, there are cases where my choices do not fit, most obviously being cross-platform mobile apps, which will have to be saved for another post… 🙂

When NPM gets bumped, you start with an empty module cache.  To restore it with optimal dependencies:

cd baseapp && rm -rf node_modules && npm -g install
cd dependentapp && rm -rf node_modules && npm -g install
cd thirdlevelapp && rm -rf node_modules && npm -g install