Core Library0.xHome

Choose documentation 3

latest

Current version

latest
English

Early release libtmux is released, and its APIs may still change between releases. This site's structure and URLs may change too.

Edit this page on GitHub

tmux client library for C#

Control tmux, connect to and create servers, navigate sessions, windows, and panes, send keys, watch for changes via control mode, capture pane contents.

Install

dotnet add package LibTmux

LibTmux 0.1.0 is pre-1.0 and can change between minor versions. Pin to a range:

<PackageReference Include="LibTmux" Version="[0.1.0,0.2)" />

At a glance

Server → Session → Window → Pane. Each level of the tmux hierarchy has its own entry in the C# API, with the tmux object it wraps.

TypeWraps
LibTmux.Server A tmux server
LibTmux.Session A session, ID $n
LibTmux.Window A window in a session, ID @n
LibTmux.Pane A pane in a window, ID %n

What it does

Start with C#

Example details
using System;
using System.Linq;
using System.Threading;
using System.Runtime.Versioning;
using LibTmux;
[assembly: UnsupportedOSPlatform("windows")]
if (OperatingSystem.IsWindows())
{
throw new PlatformNotSupportedException(
"This example requires tmux on Unix.");
}
using var deadline = new CancellationTokenSource(
TimeSpan.FromSeconds(30));
var token = deadline.Token;
var options = new ServerConnectionOptions
{
SocketName = "quickstart-" + Guid.NewGuid().ToString("N"),
ConfigurationFile = "/dev/null",
TmuxBinaryPath = Environment.GetEnvironmentVariable("LIBTMUX_TMUX")
?? "tmux",
};
var owned = await Server.CreateOwnedAsync(options, token);
Server server = owned.Value;
Session session = await server.CreateSessionAsync(
new NewSessionRequest { Name = "build", Command = "/bin/sh" },
token);
Window window = await session.CreateWindowAsync(
new NewWindowRequest { Name = "tests", Command = "/bin/sh" },
token);
Pane pane = (await window.GetPanesAsync(token))[0];
await pane.SendTextAsync(
"printf 'hello-from-%s\\n' libtmux",
enter: false, cancellationToken: token);
await pane.EnterAsync(token);
var lines = await TmuxWait.UntilAsync(
async cancellation => await pane.CaptureAsync(
cancellationToken: cancellation),
output => output.Any(line => line.TrimEnd() == "hello-from-libtmux"),
TimeSpan.FromSeconds(10),
TimeSpan.FromMilliseconds(20),
token);
Console.WriteLine("hello-from-libtmux");
using System;
using System.Linq;
using System.Threading;
using System.Runtime.Versioning;
using LibTmux;
[assembly: UnsupportedOSPlatform("windows")]
if (OperatingSystem.IsWindows())
{
throw new PlatformNotSupportedException(
"This example requires tmux on Unix.");
}
using var deadline = new CancellationTokenSource(
TimeSpan.FromSeconds(30));
var token = deadline.Token;
var options = new ServerConnectionOptions
{
SocketName = "quickstart-" + Guid.NewGuid().ToString("N"),
ConfigurationFile = "/dev/null",
TmuxBinaryPath = Environment.GetEnvironmentVariable("LIBTMUX_TMUX")
?? "tmux",
};
var owned = await Server.CreateOwnedAsync(options, token);
Server server = owned.Value;
try
{
Session session = await server.CreateSessionAsync(
new NewSessionRequest { Name = "build", Command = "/bin/sh" },
token);
Window window = await session.CreateWindowAsync(
new NewWindowRequest { Name = "tests", Command = "/bin/sh" },
token);
Pane pane = (await window.GetPanesAsync(token))[0];
await pane.SendTextAsync(
"printf 'hello-from-%s\\n' libtmux",
enter: false, cancellationToken: token);
await pane.EnterAsync(token);
var lines = await TmuxWait.UntilAsync(
async cancellation => await pane.CaptureAsync(
cancellationToken: cancellation),
output => output.Any(line => line.TrimEnd() == "hello-from-libtmux"),
TimeSpan.FromSeconds(10),
TimeSpan.FromMilliseconds(20),
token);
Console.WriteLine("hello-from-libtmux");
}
catch (Exception error)
{
throw new InvalidOperationException(
"tmux quickstart failed", error);
}
using System;
using System.Linq;
using System.Threading;
using System.Runtime.Versioning;
using LibTmux;
[assembly: UnsupportedOSPlatform("windows")]
if (OperatingSystem.IsWindows())
{
throw new PlatformNotSupportedException(
"This example requires tmux on Unix.");
}
using var deadline = new CancellationTokenSource(
TimeSpan.FromSeconds(30));
var token = deadline.Token;
var options = new ServerConnectionOptions
{
SocketName = "quickstart-" + Guid.NewGuid().ToString("N"),
ConfigurationFile = "/dev/null",
TmuxBinaryPath = Environment.GetEnvironmentVariable("LIBTMUX_TMUX")
?? "tmux",
};
await using var owned = await Server.CreateOwnedAsync(options, token);
Server server = owned.Value;
Session session = await server.CreateSessionAsync(
new NewSessionRequest { Name = "build", Command = "/bin/sh" },
token);
Window window = await session.CreateWindowAsync(
new NewWindowRequest { Name = "tests", Command = "/bin/sh" },
token);
Pane pane = (await window.GetPanesAsync(token))[0];
await pane.SendTextAsync(
"printf 'hello-from-%s\\n' libtmux",
enter: false, cancellationToken: token);
await pane.EnterAsync(token);
var lines = await TmuxWait.UntilAsync(
async cancellation => await pane.CaptureAsync(
cancellationToken: cancellation),
output => output.Any(line => line.TrimEnd() == "hello-from-libtmux"),
TimeSpan.FromSeconds(10),
TimeSpan.FromMilliseconds(20),
token);
Console.WriteLine("hello-from-libtmux");
using System;
using System.Linq;
using System.Threading;
using System.Runtime.Versioning;
using LibTmux;
[assembly: UnsupportedOSPlatform("windows")]
if (OperatingSystem.IsWindows())
{
throw new PlatformNotSupportedException(
"This example requires tmux on Unix.");
}
using var deadline = new CancellationTokenSource(
TimeSpan.FromSeconds(30));
var token = deadline.Token;
var options = new ServerConnectionOptions
{
SocketName = "quickstart-" + Guid.NewGuid().ToString("N"),
ConfigurationFile = "/dev/null",
TmuxBinaryPath = Environment.GetEnvironmentVariable("LIBTMUX_TMUX")
?? "tmux",
};
await using var owned = await Server.CreateOwnedAsync(options, token);
Server server = owned.Value;
try
{
Session session = await server.CreateSessionAsync(
new NewSessionRequest { Name = "build", Command = "/bin/sh" },
token);
Window window = await session.CreateWindowAsync(
new NewWindowRequest { Name = "tests", Command = "/bin/sh" },
token);
Pane pane = (await window.GetPanesAsync(token))[0];
await pane.SendTextAsync(
"printf 'hello-from-%s\\n' libtmux",
enter: false, cancellationToken: token);
await pane.EnterAsync(token);
var lines = await TmuxWait.UntilAsync(
async cancellation => await pane.CaptureAsync(
cancellationToken: cancellation),
output => output.Any(line => line.TrimEnd() == "hello-from-libtmux"),
TimeSpan.FromSeconds(10),
TimeSpan.FromMilliseconds(20),
token);
Console.WriteLine("hello-from-libtmux");
}
catch (Exception error)
{
throw new InvalidOperationException(
"tmux quickstart failed", error);
}
Run this example

.NET SDK 10.0.303, .NET 8 and 10 runtimes, tmux on Linux/macOS

Save the program above as app/Program.cs in a new directory, along with the files below.

Cleanup is omitted; the private tmux server and its temporary files may remain. Select Cleanup to remove them when the program finishes. The program stops its private tmux server and removes any temporary files it created when it finishes. Error handling adds diagnostics; every version checks required results and deadlines.

app/Example.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisLevel>10-recommended</AnalysisLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<PackageReference Include="LibTmux" Version="[0.1.0]" />
</ItemGroup>
</Project>
app/global.json
{
"sdk": {
"version": "10.0.303",
"rollForward": "disable",
"allowPrerelease": false
},
"test": {
"runner": "Microsoft.Testing.Platform"
}
}

Setup and run

# Save the files above at their displayed relative paths.
cd app
dotnet restore Example.csproj
dotnet build Example.csproj -c Release --no-restore --warnaserror
export TMUX_TMPDIR=/tmp/libtmux-dotnet-dev
mkdir -p "$TMUX_TMPDIR"
unset TMUX TMUX_PANE
dotnet bin/Release/net8.0/Example.dll
dotnet bin/Release/net10.0/Example.dll

Expected output

hello-from-libtmux

Library revision: 472c2bcfbda6.

Typed API

What you get over the tmux CLI

Know where you're running

Inside tmux, find the pane your program runs in from TMUX and TMUX_PANE: LibTmux.Pane.FromEnvironmentAsync.

Testing

Run tests against an isolated tmux server: LibTmux.Testing.TemporaryServerScope.

Esc

Type to search.

Reference previewOpen reference