Tag Archives: Visual Studio Code

Filling Go Structs in VS Code

If you program in Go, then you work with structs all the time. There’s a handy little tool in VS Code that you can use to quickly populate an empty struct with all its fields instead of writing them by hand. With your cursor over the name of the struct, bring up the context menu by doing one of the following:

  • Clicking on the light bulb to the left
  • Pressing Ctrl+. (Windows/Linux)
  • Pressing Cmd+. (Max)
This context menu lets you fill a struct’s fields.

Then, click on the “Fill” option or press ENTER to accept it, and the struct’s fields will be added along with default values for each according to their type:

The struct’s fields have been added with default values.

This little productivity tool is great, especially when you’re mapping data across structs in different parts of your application.

Go To Line Number in Visual Studio Code

If you want to go to a specific line number in a file, there are a couple of ways to do that with Visual Studio Code, depending on whether you’re already in that file or not.

Same File

Go To Line in the same file.

If you’ve got a file already open and want to hop to a specific line number in it, just use the handy Go To Line shortcut – that is Ctrl+G (Windows/Linux) or Control+G (Mac). Then you just enter the line number in the prompt.

Different File

Going to a specific line in another file.

If you want to go to a specific line in another file, i.e. one you don’t already have open in front of you, there are a couple of things you can do.

The first is to open that file and use the same “Go To Line” in the previous section. There are several ways to open the file, but the quickest is probably to use the handy Ctrl+P (Windows/Linux) or Command+P (Mac) to search for the filename.

The second way is to enter the line number along with the filename in the same Ctrl+P/Command+P prompt! To do this, type the filename in full, followed by a colon (:), and then the line number. That will open the file at the specified line number.

Getting Started with Rust using VS Code

I’m not yet familiar with Rust, but now is as good a time as any other to start learning it. A couple of 2020 articles, “What is Rust and why is it so popular?” at the Stack Overflow Blog and “Why Discord is switching from Go to Rust” by Discord mention a few aspects that make Rust appealing to developers.

Usually, the first thing I do when starting to work with a new programming language is to figure out how to debug it. So in this article I’m going to show you how to get yourself set up to debug Rust using Visual Studio Code (VS Code), and then you can use that as a starting point and take your learning journey in any direction that is comfortable for you.

Installing Rust

The first thing you need is to install the Rust language itself and associated tools. Simply follow the Installation part of the Rust book to set up Rust for your operating system.

The cargo tool which comes with the Rust installation is vital as it is used for various things from building and running Rust source code to managing packages (“crates”, in the Rust ecosystem).

Setting Up VS Code for Rust

If you don’t already have VS Code, head to its website and download it.

Then, you’ll need to install two extensions, based on the IDE Integration Using rust-analyzer section of the Rust book, and the Debugging section of the Rust with Visual Studio Code documentation:

  • rust-analyzer gives you most of the IDE integration you need between Rust and VS Code (e.g. Intellisense)
  • Either the Microsoft C/C++ extension (if you’re on Windows) or CodeLLDB (for Linux/Mac) – this gives you the ability to actually debug Rust code
Add the rust-analyzer extension from the Extensions tab in VS Code for basic IDE support.

Creating a New Rust Project

Use cargo to create a new Rust project as follows:

$ cargo new rust1
     Created binary (application) `rust1` package

Then, open the newly created rust1 folder using either the terminal (as follows) or VS Code’s File -> Open Folder… menu option.

$ cd rust1
$ code .

Note that if you’re following the “Hello, World!” part of the Rust book and created a Rust program without cargo, you won’t be able to debug it.

Debugging Rust with VS Code

You’ll find a “Hello world” program in src/main.rs under the folder you created (in this case rust1). Ensure you have that open in VS Code and the press F5. When prompted, select LLDB as the debugger to use.

After pressing F5, select the LLDB debugger.

At that point you get an error because you don’t have a launch configuration yet:

“Cannot start debugging because no launch configuration has been provided.”

But that’s alright, because once you click “OK”, you’re offered the possibility to have a launch configuration generated for you, which you should gratefully accept:

“Cargo.toml has been detected in this workspace. Would you like to generate launch configurations for its targets?” Click “Yes”.

When you click “Yes”, a file with launch configurations is generated for you:

Launch configurations are generated for you.

See also my earlier article, “Working with VS Code Launch Configurations“, if you want to do more with these launch configurations in future.

Now you can switch back to main.rs and press F5 to debug the code. Click next to a line number to set a breakpoint if you want to stop anywhere. Try also hovering over parts of the code to get rich information about them.

Debugging Rust code: stopping at a breakpoint, and analysing the println macro.

Summary

If you prefer to debug Rust code in an IDE than do everything in the terminal, consider using VS Code. After installing both Rust and VS Code, all you need to do is install a couple of extensions, create a Rust project with cargo, and generate launch configurations for it. Then you can debug your Rust code and benefit from all the IDE comfort (e.g. Intellisense) you’re used to in other languages.

Getting Started with the Go Programming Language (GoLang) using VS Code

Go is a relatively young programming language, launched in 2009, with simplicity at its heart. Whereas it might not have all the bells and whistles you might expect from a modern programming language (see “From .NET to GoLang: Where Did Everything Go?” and “From .NET to GoLang: Here We Go Again” for my critique), it has some features that make it unique, such as its first-class concurrency model using channels and goroutines, based on Tony Hoare’s 1978 Communicating Sequential Processes (CSP).

You can set up Go and write your first program easily in a couple of minutes, but in order to program comfortably, I recommend using an Integrated Development Environment (IDE) that you can use to debug your code. You can use whatever you like, but I’ll show you how to use Visual Studio Code (VS Code) to write and debug Go code.

Download and Install Go

First, you need to download and install Go. This link has all the instructions you need for Linux, Mac and Windows, and they’re pretty straightforward, so I won’t bother repeating all of them here.

If you’re on Linux, though, do note that the first command is actually two commands combined with an && operator, so you need to add sudo before both of them. To make it super clear, you need to do the following steps on Linux:

  1. Download the latest Go package for Linux.
  2. Run the following to remove any previous Go installation (skip this if you’ve never installed Go before):
    • sudo rm -rf /usr/local/go
  3. cd into the directory where you downloaded the Go package.
  4. Run the following to extract the Go package and put it in the right folder:
    • sudo tar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz
    • Be sure to change the filename to the one you actually downloaded.
  5. Add the following to the end of ~/.profile:
    • export PATH=$PATH:/usr/local/go/bin
    • Restart your computer for the change to take effect.
  6. Run go version to ensure that the go command is now accessible in your terminal.

A Minimal Example

Create a new folder, and name it whatever you like (e.g. “hellogo”). In it, add a file called main.go, and add the following code in it:

package main

import "fmt"

func main() {
    fmt.Println("Hello Go!")
}

Using Go from the Command Line

You can run the above program in your favourite terminal by cd’ing into the directory where you added main.go, and running the following command:

go run main.go

The output, as you would expect, is:

Hello Go!

If you want to compile the code into an executable, you can run the following command:

go build main.go

This generates an executable named main. If you want to specify the name of the executable, you can add a -o switch and provide the name you want. For instance, the following command generates an executable named myapp:

go build -o myapp main.go

It’s important to note that the file being compiled must be at the end of the command, so the -o switch goes before it.

To run the executable:

  • On Windows, run: myapp
  • On Linux or Mac, run: ./myapp

Setting up VS Code for Go

If you don’t have it already, download and install Visual Studio Code. Use it to open the folder where main.go is. At this point, we need to install 3 things:

  1. The Go extension for Visual Studio Code
  2. The Delve debugger
  3. gopls, the Go language server

In my experience, VS Code automatically prompts you to install these when you open a .go file in it, so the easiest way is to just accept. In case it doesn’t, you can install the Go extension yourself from the Extensions tab on the left side of VS Code, and you can install the other two by following their respective instructions.

VS Code asks whether you want to install the Go extension. Click “Install”.
You can also find the Go extension from the Extensions tab on the left. After installing it, VS Code helpfully asks you to install dlv (Delve) and gopls, which you also need.
When you accept to install Delve and gopls, you can see their progress and status in the Output window at the bottom of VS Code.

Debugging Go

Once you’ve installed all three items from the previous section, VS Code becomes a handy tool to write, run and debug Go code with ease. In fact, you get things like syntax highlighting, code completion, and the ability to debug your code.

Code completion for Go code.

To run/debug your code directly from VS Code, you can press F5, or do it via the “Run and Debug” tab (which looks like a Play button with a beetle) on the left side of VS Code. Doing this immediately gives us an error:

The error says: “go mod file not found in current directory or any parent directory”.

That’s because we missed a step. In the bottom part of VS Code, switch to the integrated terminal (“Terminal” tab) or, if you don’t have one, open a new one via the Terminal menu at the top of VS Code. Then, run the following command:

go mod init main

This creates a go.mod file:

Running go mod init main creates a go.mod file, initialising the main module.

You can now press F5 again to debug Go. You can set a breakpoint by clicking next to a line number; this will show the breakpoint as a red circle, and the code will stop when it reaches that point, allowing you to step through the code, inspect variables, and see other parts of the state of the program:

Hitting a breakpoint while debugging Go code.

There isn’t much to debug in this simple program, but at least this gives you what you need to be able to debug more interesting programs as you write them. Debugging is an entire topic in itself that’s out of scope for this article, but it’s an essential skill for a competent developer. You can learn more about it from:

One other tip: while you are in a debugging session, VS Code creates a temporary executable called __debug_bin. If you’re using source control, be sure to exclude it (e.g. add it to your .gitignore file when using Git).

Conclusion

Go is fairly straightforward to set up and use:

  • Download Go and follow the official instructions to set it up.
  • Use Go from the command-line if you need to (e.g. for Continuous Integration).
  • Set up the Go extension, Delve debugger and gopls language server in VS Code.
  • Press F5 to debug your Go programs in VS Code!

That’s all you need to keep Going!

Minimal Web Application with Flask and AlpineJS

I recently needed to develop a small application for personal use. Since I had a specific need to use Python, I decided to build the backend with Flask. For the frontend, I only needed (literally) a single page to visualise some data, so I resisted the urge to go with something like Angular or React, and instead decided to try this minimal Alpine.js thing I had heard about a few days earlier.

In this article, I’m going to show you how you can really quickly create a minimal web application (REST API, static files and web UI) like I did. This can be handy for putting a simple tool together in very little time, but please consider it as a quick and dirty thing rather than any kind of best practice. I’m new to both Flask and Alpine.js, so I’m certainly not going to be giving advice on how best to use them.

Getting Started with Flask

After creating a new folder for your project, create a file called main.py (or whatever you want, really). We can kick off our API development by using the Flask Quickstart example:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

The same page also explains how to run the application so that it can listen for connections and serve requests:

“To run the application, use the flask command or python -m flask. You need to tell the Flask where your application is with the --app option.”

— Flask Quickstart

This is nice and all, but I like to be able to debug my code from Visual Studio Code, and for that it’s necessary to create a launch.json file with the right settings. This can be done as illustrated by the following images and their captions. If you need to do anything more advanced, see “Working with VS Code Launch Configurations“.

First, select the Debug tab on the left, and click “create a launch.json” file.
From the list that appears, select “Flask”.
Change the default suggested filename of app.py to the one you’re using, e.g. main.py.

Once that is done, it generates a launch.json file with the following contents:

{
    // 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": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "main.py",
                "FLASK_DEBUG": "1"
            },
            "args": [
                "run",
                "--no-debugger",
                "--no-reload"
            ],
            "jinja": true,
            "justMyCode": true
        }
    ]
}

You can now press F5 to start the application in debug mode. The integrated terminal informs you that the application is running at http://localhost:5000/, so you can open a browser window to see that it’s working. By running it in this way, you can also add breakpoints and debug your Python code as needed.

The Flask “Hello World” is definitely working.

A Simple REST API

To build a reasonable example, we need to return some data from our API. We can do this quite easily by returning a list of dictionary objects from a function annotated with the route “/products”:

@app.route("/products")
def get_products():
    return [
        {
            "name": "Rope",
            "description": "Used to climb heights or swing across chasms.",
            "price": 15
        },
        {
            "name": "Whip",
            "description": "An old and trusty friend.",
            "price": 20
        },
        {
            "name": "Notebook",
            "description": "Contains lots of valuable information!",
            "price": 80
        }
    ]

After restarting the application and visiting http://localhost:5000/products, we can see that the list gets translated quite nicely to JSON:

The response of the /products endpoint.

Serving a Static Webpage

It is now time to build a simple user interface. Before we do that though, we need to figure out how to serve static files so that we can return an HTML file and then use Alpine.js to dynamically populate it using the API.

It turns out that this is quite simple: Flask automatically serves any files you put under the static folder. So let’s create a static folder and add an index.html file with some minimal HTML in it:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>My Products</title>
<body>

<h1>My Products</h1>

</body>
</html>

We can now see this page if we visit http://localhost:5000/static/index.html in a browser:

The HTML page is served from the static folder.

It works, but it’s not great. I’d like this to come up by default when I visit http://localhost:5000/, instead of having such a long URL. Fortunately, this is easy to achieve. All we need to do is replace our “Hello world” code in the default endpoint with the following:

from flask import Flask, send_from_directory

app = Flask(__name__)

@app.route('/')
def serve_index():
    return send_from_directory('static', 'index.html')

Displaying the Products

Now that we have an API and an easily accessible webpage, we can display the data after retrieving it from the API. We can now add Alpine.js to our website by adding a <script> tag, and then build out a table that retrieves data from the API:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>My Products</title>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<style>
    body {
        font-family: sans-serif;
    }

    table, th, td {
        border: solid 1px #555;
        border-collapse: collapse;
    }
</style>
<body>

<h1>My Products</h1>

<div
    x-data="{ products: [] }"
    x-init="products = await (await fetch('/products')).json()"
>
    <table>
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
        </tr>
        <template x-for="product in products">
            <tr>
                <td x-text="product.name"></td>
                <td x-text="product.description"></td>
                <td x-text="product.price"></td>
            </tr>
        </template>
    </table>
</div>

</body>
</html>

In the above HTML, the main thing to look at is the stuff inside the <div>. Outside of that, the new things are just the <script> tag that imports Alpine.js, and a little CSS to make the webpage look almost bearable.

The <div> tag’s attributes set up the data model that the table is based on. Using this x-data attribute, we’re saying that we have an array called “products”. The x-init attribute is where we use the Fetch API to retrieve data from the /products endpoint and assign the result to the “products” array.

Once this data is retrieved, all that’s left to do is display it. In the <table>, we use an x-for attribute in a <template> to loop over the “products” array. Then, we bind the content of each cell (<td> element) to the properties of each product using the x-text attribute, effectively displaying them.

The result is simple but effective:

Indiana Jones would be proud of this inventory.

Conclusion

As you can see, it’s pretty quick and easy to put something simple together and then build whatever you need on top of that. For instance, you might want to filter the data you display, apply conditional highlighting, or add other functionality.

Honestly, I’m not quite sure how far you can take Alpine.js. For instance, it doesn’t seem possible to create reusable components, which somewhat limits its usefulness. And I don’t yet know how to avoid having heaps of JavaScript within HTML attributes. I’ve only started using this a few days ago, after all.

But it’s great to be able to use something like this to create simple tools without having to incur the learning curves of things like Angular, React or Vue.