29

How to make Visual Studio Code (or Go Programming Language Extension) to run go fmt (or other tools/commands) on save? Even auto save?

Update: It is working now perfectly inside VSCode, at this time; just need to add some config files inside .vscode directory (I use these).

Update 2019: This question is old. The VSCode Go extension has all you need to develop in Go, now.

Last Update 2019 BTW It worth mentioning that right above the package declaration inside your test files appears a run package tests. If you click it, you can see your code coverage of your code. The covered and not-covered parts are highlighted in different colors.

Update 2020 And now, the Go Extension for VSCode, is under the supervision of Go Team!

enter image description here

Gama11
  • 31,714
  • 9
  • 78
  • 100
Kaveh Shahbazian
  • 13,088
  • 13
  • 80
  • 139

4 Answers4

46

Now, the feature has been implemented, you can enable format on save:

  1. Open Settings (Ctrl + ,)
  2. Search for editor.formatOnSave and set it to true

Your Go code will be formatted automatically on Ctrl + s

Pang
  • 9,564
  • 146
  • 81
  • 122
Yann C.
  • 1,315
  • 12
  • 17
  • 1
    I think this should even be the default setting if you newly install the Go extension. – Alper Aug 15 '19 at 14:12
  • Is there a way to change the formatting options? I have enabled the indent with space option but after the file is saved go fmt converts it back to tabs. – rd22 Jun 23 '20 at 09:24
  • 3
    Remember that if you have a different formatter (like Prettier) already set up in VS, this solution will need a final step: You need to change the "default formatter" in settings to "Go". – Farshid Apr 14 '21 at 19:59
  • For me this solution worked but I have to do ctrl+s even autosave is enabled. – Vineeth Peddi Feb 02 '22 at 05:55
  • I know it's an old question, but for future reference @rd22 the fact that this is not configurable actually solves the problem of "tabs vs spaces": just program with spaces as I do, but when you save it gofmt will convert it to a normalized format that everybody else uses. No need to worry about this anymore. I would just recommend configuring the size of your tabs to match the number of spaces you use for indenting. – VinGarcia Mar 22 '22 at 10:58
4

Its not possible at the moment but its being worked on https://github.com/Microsoft/vscode-go/issues/14

Jon
  • 38,814
  • 81
  • 233
  • 382
4

I'm not familiar with 'go fmt' specifically, but you can create a simple vscode extension to handle on save event and execute any arbitrary command passing the file path as an argument.

Here's a sample that just calls echo $filepath:

import * as vscode from 'vscode';
import {exec} from 'child_process';

export function activate(context: vscode.ExtensionContext) {

    vscode.window.showInformationMessage('Run command on save enabled.');

    var cmd = vscode.commands.registerCommand('extension.executeOnSave', () => {

        var onSave = vscode.workspace.onDidSaveTextDocument((e: vscode.TextDocument) => {

            // execute some child process on save
            var child = exec('echo ' + e.fileName);
            child.stdout.on('data', (data) => {
                vscode.window.showInformationMessage(data);
            });
        });
        context.subscriptions.push(onSave);
    });

    context.subscriptions.push(cmd);
}

And the package file:

{
    "name": "Custom onSave",
    "description": "Execute commands on save.",
    "version": "0.0.1",
    "publisher": "Emeraldwalk",
    "engines": {
        "vscode": "^0.10.1"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:extension.executeOnSave"
    ],
    "main": "./out/src/extension",
    "contributes": {
        "commands": [{
            "command": "extension.executeOnSave",
            "title": "Execute on Save"
        }]
    },
    "scripts": {
        "vscode:prepublish": "node ./node_modules/vscode/bin/compile",
        "compile": "node ./node_modules/vscode/bin/compile -watch -p ./"
    },
    "devDependencies": {
        "typescript": "^1.6.2",
        "vscode": "0.10.x"
    }
}

The extension is enabled via cmd+shift+p then typing "Execute on Save", but it could be reconfigured to start via another command including "*" which would cause it to load any time VSCode loads.

Once the extension is enabled, the event handler will fire whenever a file is saved (NOTE: this doesn't appear to work when file is first created or on Save as...)

This is just a minor modification of a yo code scaffolded extension as outlined here: https://code.visualstudio.com/docs/extensions/example-hello-world

Update

Here's a Visual Studio Code extension I wrote for running commands on file save. https://marketplace.visualstudio.com/items/emeraldwalk.RunOnSave.

bingles
  • 11,582
  • 10
  • 82
  • 93
  • `gofmt` takes a string (the content of the current file opened in editor) via `stdin` and gives a formatted Go code to us via `stdout` or some errors if any via `stderr`. So basically (best I wish for) I want to feed the changed content to `gofmt` and take the output and if there were no errors, save it to the file. I'll play around this to see what I can do in a meaningful timeframe (otherwise I'll fall back to LiteIDE for now). Thanks; – Kaveh Shahbazian Nov 21 '15 at 21:12
0

I was using CTRL+S for saving the file manually (this is habitual for me). However, I had a different binding in VS Code that would start with CTRL+S (e.g. swagger extension has a chord where pressing CTRL+S CTRL+W would generate the swagger annotation). This resulted in VS Code waiting for me to press the second chord (CTRL+W) and as such it ignored the save part altogether. I reconfigured all the keybinding chords which had CTRL+S as the first chord to a different combination. After this, pressing CTRL+S formatted my file with gofmt properly.

vhegde
  • 1
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30285852) – Bracken Nov 08 '21 at 14:26