Installation

Download

Grab the latest release from the releases page. Tape ships as a single archive — compiler, standard library, runtime DLLs, and examples included.

PlatformFile
Windows x64tape-2.0.23-win64.zip
Linux x86_64tape-2.0.23-linux.tar.gz
macOS x86_64tape-2.0.23-macos.tar.gz
macOS ARM64 (Apple Silicon)tape-2.0.23-macos-arm64.tar.gz

Windows

In a terminal (PowerShell or Windows Terminal), in your home folder:

powershell
# Extract into a folder named tape
mkdir tape
tar -xf Downloads\tape-2.0.23-win64.zip -C tape

# Put tape on your PATH (your user's; no administrator rights needed)
.\tape\tape.exe setup

Open a new terminal, so it reads the new PATH, and check:

powershell
tape --version

Then build and run the included demo, and your own programs, from any folder:

powershell
tape build tape\examples\widget_demo.tape -o widget_demo.exe
.\widget_demo.exe

tape build hello.tape -o hello.exe

tape finds its standard library next to itself.

Upgrading: extract the new version’s zip into the same tape folder (tar -xf Downloads\tape-<new version>-win64.zip -C tape). The folder stays on your PATH, so there is nothing else to do. To take tape off your PATH, before you delete its folder, run tape setup --remove (tape setup).

Linux

Debian and Ubuntu (apt)

Install from the tape apt repository (x86-64; Ubuntu 22.04+, Debian 12+). Apt verifies every package against the repository’s signing key, and apt upgrade keeps tape up to date.

bash
curl -fsSL https://apt.tapelang.org/tapelang.gpg | sudo tee /usr/share/keyrings/tapelang.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/tapelang.gpg] https://apt.tapelang.org stable main" \
  | sudo tee /etc/apt/sources.list.d/tapelang.list
sudo apt update && sudo apt install tape

# Build and run a program from anywhere
tape build /usr/lib/tape/examples/hello.tape -o hello
./hello

Tape installs into /usr/lib/tape (compiler, runtime libraries, standard library, examples) with tape on the PATH. Programs it builds find the runtime libraries there, or next to themselves when you ship them.

The repository is signed by the key tapelang.org apt repository <hello@puida.com> with fingerprint:

plaintext
3876 4583 261A AE3A 5300  7009 2C6A 9918 DA78 AFC9

Check the key you downloaded before trusting it:

bash
gpg --show-keys /usr/share/keyrings/tapelang.gpg

Other distributions (archive)

bash
# Extract into a folder and enter it
mkdir tape-2.0.23-linux
tar xzf tape-2.0.23-linux.tar.gz -C tape-2.0.23-linux
cd tape-2.0.23-linux
chmod +x tape

# Add to PATH and library path
export PATH=$PATH:$(pwd)
export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH

# Build and run the included demo
./tape build examples/widget_demo.tape -I stdlib -o widget_demo
chmod +x widget_demo && ./widget_demo

# Build your own program
./tape build hello.tape -I stdlib -o hello
chmod +x hello && ./hello

macOS

bash
# Extract into a folder and enter it
mkdir tape-2.0.23-macos
tar xzf tape-2.0.23-macos.tar.gz -C tape-2.0.23-macos
cd tape-2.0.23-macos
chmod +x tape

# Add to PATH and library path
export PATH=$PATH:$(pwd)
export DYLD_LIBRARY_PATH=$(pwd):$DYLD_LIBRARY_PATH

# Build and run the included demo
./tape build examples/widget_demo.tape -I stdlib -o widget_demo
chmod +x widget_demo && ./widget_demo

# Build your own program
./tape build hello.tape -I stdlib -o hello
chmod +x hello && ./hello

What’s in the archive

FileDescription
tape / tape.exeCompiler and build tool
tape-lsp / tape-lsp.exeLanguage server for editors (see Editor support)
tapert100.dll / .so / .dylibRuntime library (memory, I/O, args), used by tape run and by programs built with --runtime shared; other native programs have it compiled in
image100.dll / .so / .dylibImage codec library (BMP, PNG, JPEG, HUVA)
uwm100.dll / .so / .dylibWindow manager
audio100.dll / .so / .dylibAudio library (sound output: the audio module)
gamepad100.dll / .so / .dylibGamepad library (the gamepad module)
shell100.dll / .so / .dylibDesktop shell library (the secrets, notify, dialog, keystore, tray and launch modules)
stdlib/Standard library sources (io, fs, path, str, fmt, mem, math, os, time, color, collections, gfx, ui, widgets)
image/Image codec sources (PNG, BMP, JPEG, HUVA)
rt/Runtime source (platform bindings); tape build compiles rt/<platform>/tapert100.tape into programs
examples/Example programs (widget_demo, counter, canvas, etc.)
README.mdQuick start, requirements, and how to rebuild the runtime

Verify

Create a file called hello.tape:

tape
@profile(t1);
import io from "io";

pub fn main() -> i32 {
    io.println("Hello, world!");
    return 0;
}

Build and run it:

bash
tape build hello.tape -I stdlib -o hello
./hello

You should see Hello, world! printed to the console.

Editor support

Install the Tape extension (puida.tape-language) from the VS Code Marketplace. It provides:

  • highlighting for every source region
  • diagnostics as you type, the same ones tape check reports
  • hover, go to definition, find all references, rename, completion, an outline, and folding

Diagnostics and navigation come from tape-lsp, the language server that ships with tape. It is next to tape in the release archives, and at /usr/bin/tape-lsp in the apt package. The extension finds it through the tape on your PATH. If tape is installed somewhere else, set tape.lsp.path to the full path of tape-lsp.

A project whose modules are imported by bare name from its own directories (what tape build -I <dir> is for) lists those directories in the tape.includePaths setting, absolute or relative to the workspace folder:

json
{
  "tape.includePaths": ["kernel/dev", "kernel/mem", "lib/font"]
}

Without it, tape-lsp looks for a module it cannot otherwise resolve in the workspace (the folder holding .git), by its file name.

tape-lsp uses the standard library installed with it. To use another one (a checkout of tape you are working on), set tape.stdlibPath, absolute or relative to the workspace folder; a folder without math.tape is not taken.

You can update tape while VS Code is open. On Windows the extension runs a copy of tape-lsp.exe from its own storage, so the installed file is never locked. The extension watches tape-lsp, and when it changes, the extension restarts the server on the new version (setting tape.lsp.restartOnUpdate).

Vim and Neovim

Tape Neovim support 1.0.1 provides .tape filetype detection, syntax highlighting for every source region, and optional LSP setup. It has its own releases, independent of the compiler version. The same plugin runs on Linux, Windows and macOS; no Tree-sitter or nvim-lspconfig is required.

Debian and Ubuntu

After adding the Tape APT repository above:

bash
sudo apt update
sudo apt install tape-nvim

The package installs into Neovim’s system-wide native package directory. Highlighting loads automatically; apt upgrade updates the plugin separately from Tape. It recommends tape for LSP, but highlighting does not require the compiler. Debian 12’s Neovim 0.7 can highlight; the LSP setup below requires Neovim 0.10 or newer.

Linux and macOS: archive installation

Download the platform-independent plugin, verify its checksum, and extract it into Neovim’s native package directory:

bash
curl -fLO https://releases.tapelang.org/tape-nvim-1.0.1-all.tar.gz
curl -fLO https://releases.tapelang.org/tape-nvim-1.0.1-all.tar.gz.sha256
# Linux:
sha256sum -c tape-nvim-1.0.1-all.tar.gz.sha256
# macOS: use shasum -a 256 -c tape-nvim-1.0.1-all.tar.gz.sha256 instead

mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/site/pack/tape/start/tape"
tar -xzf tape-nvim-1.0.1-all.tar.gz --strip-components=1 \
  -C "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/site/pack/tape/start/tape"

The same tar.gz works on Intel and Apple Silicon Macs. Install the matching Tape compiler release separately for tape-lsp. To update the plugin, close Neovim, remove the old plugin directory, and extract the new version.

Windows: archive installation

Run in PowerShell:

powershell
$url = 'https://releases.tapelang.org/tape-nvim-1.0.1-all.zip'
$zip = Join-Path $env:TEMP 'tape-nvim-1.0.1-all.zip'
Invoke-WebRequest $url -OutFile $zip
$sum = (Invoke-WebRequest "$url.sha256").Content.Trim().Split(' ')[0]
if ((Get-FileHash $zip -Algorithm SHA256).Hash.ToLowerInvariant() -ne $sum) {
    throw 'Neovim plugin checksum mismatch'
}
$unpack = Join-Path $env:TEMP 'tape-nvim-unpack'
Expand-Archive $zip -DestinationPath $unpack -Force
$start = Join-Path $env:LOCALAPPDATA 'nvim-data\site\pack\tape\start'
New-Item -ItemType Directory -Force $start | Out-Null
Copy-Item "$unpack\tape-nvim-1.0.1" "$start\tape" -Recurse

For an update, close Neovim and remove the old tape plugin directory before copying the new version. The ZIP uses Unix line endings on every platform.

Enable LSP

Highlighting requires no Lua setup. For diagnostics, hover, completion and go-to-definition, install Tape (including tape-lsp) and add this to your Neovim init.lua:

lua
vim.cmd('filetype plugin on')
vim.cmd('syntax enable')
require('tape').setup({
  -- Optional: directories you pass as tape build -I, relative to the project.
  include_paths = {},
})

-- setup() above does this from plugin 1.0.1 on (keymaps = false and completion =
-- false turn it off). With plugin 1.0.0 or your own client setup: gd is Vim's text
-- search unless you map it, and completion runs as you type only if you enable it.
vim.api.nvim_create_autocmd('LspAttach', {
  callback = function(ev)
    local client = vim.lsp.get_client_by_id(ev.data.client_id)
    if client.name ~= 'tape' then return end
    vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { buffer = ev.buf })
    if vim.fn.has('nvim-0.11') == 1 then
      vim.opt_local.completeopt = { 'menuone', 'noselect', 'popup' }
      vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
    end
  end,
})

The plugin finds tape-lsp beside tape on PATH, then on PATH directly.

  • K shows the hover: the declaration, its type and its doc comment.
  • gd or Ctrl-] goes to the definition: of a type, a method, a field, a variant or a local, in this file, another module or the standard library. A type name goes to its declaration wherever a type is written (b: gpu.Buffer, *T, ?T, []T, as T, @sizeof(T), s is Shape.Circle); a type alias goes to its type A = ... line. gy (vim.lsp.buf.type_definition()) goes to the type of what is under the cursor: an alias’s to the type it names.
  • grr (vim.lsp.buf.references(), Neovim 0.11’s default mapping) lists the references of the name under the cursor in the project’s files, open or not; grn (vim.lsp.buf.rename()) renames it in all of them. A rename is refused, with the reason, for a name of the standard library, a keyword, or a new name that would clash with one already declared there.
  • Ctrl-X, Ctrl-O in insert mode completes on any Neovim 0.10 or newer (Neovim sets omnifunc by itself). With vim.lsp.completion.enable on 0.11 it also runs as you type, after ., @ and a literal’s {, and after the " and each / of an import’s path.

Completion comes from the type checker and works while the line is unfinished: after player. the fields and methods of player’s type, whether it is a local, a field chain, a call’s result or self, and only what is pub of another module’s; Color. the variants; without a . the locals and parameters in scope first, then functions, types and modules, keywords last; in Point { the fields not given yet; after :, -> and as the types. In an import’s path (import os from "o) it offers the modules the path can name, found the way tape finds an import: a bare name in your include paths and the standard library, then next to the file. A folder next to the file completes to lib/, and after the / to the modules and folders in it; after "m#, style when m has a #style region.

With a Tape file open, :lua vim.print(vim.lsp.get_clients({ bufnr = 0 })) should show a tape client. Pass cmd = { '/path/to/tape-lsp' } to setup() for an explicit server path and home = '/path/to/tape-install' if its stdlib is elsewhere. Restart Neovim after updating Tape; keep the server and stdlib versions matched.

Archives and their checksums are listed on releases.tapelang.org. The plugin README also covers Vim and local lazy.nvim installation.

Other LSP clients

Other editors that speak the Language Server Protocol can run tape-lsp too. It talks over stdio. The include paths go in the initialize request’s initializationOptions, as {"includePaths": ["/abs/dir", "relative/to/root"]}, and another standard library as "stdlibPath": "<dir>" (absolute or relative to the root).

tape-lsp finds the standard library next to itself (stdlib/ beside the executable). To run it from a different directory, give it the directory of the tape installation:

  • on the command line: tape-lsp --home <dir>
  • in the initialize request: "initializationOptions": {"home": "<dir>"}

If both are given, --home wins. Without either, tape-lsp uses its own directory. The VS Code extension uses --home for its copy on Windows. An editor that copies the server to avoid locking it can do the same.

Last modified: