LoinCloth is a shell program, built for project management and multi tasking.
You can create multiple workspaces, and scopes which each hold their own aliases.
You can create and load in .cloth scripts, to load in scope and aliases.
Mac os is not supported however binaries will be released, and pull requests for fixes on that platform are welcomed.
~/Projects/2026/March/LoinCloth (main) ~811.145µs
» !new w
[0] ~/Projects/2026/March/LoinCloth [*] (main) ~4.73µs
[1] ~/Projects/2026/March/LoinCloth [H]
»!new w creates a new space.
The [*] indicates to us the current workspace in which we are in, in our case we are at workspace with index 0.
The [H] indicates a workspace that is open in the same folder as our current workspace.
The ~4.73µs is the rough execution time the command took, including command parsing time.
The (main) is our current git branch, this will not display if there is no branch detected in the active workspace folder. Also, yes I am commiting to main, fight me.
Use !switch <index> to switch to our new workspace.
~/Projects/2026/March/LoinCloth (main) ~811.145µs
» !new w
[0] ~/Projects/2026/March/LoinCloth [*] (main) ~4.73µs
[1] ~/Projects/2026/March/LoinCloth [H]
» !switch 1
[0] ~/Projects/2026/March/LoinCloth [H]
[1] ~/Projects/2026/March/LoinCloth [*] (main) ~10.71µs
»You can see, we are now in workspace [1].
We will now see the [H] disappear in index [0] once we change directories.
[0] ~/Projects/2026/March/LoinCloth [H]
[1] ~/Projects/2026/March/LoinCloth [*] (main) ~10.71µs
» cd ..
[0] ~/Projects/2026/March/LoinCloth
[1] ~/Projects/2026/March [*] ~27.02µs
»We also have a typical ls command, which overrides your os ls, this was added because windows doesn't have one, and I had to make sure it was working for cross compatibility.
[0] ~/Projects/2026/March/LoinCloth [H]
[1] ~/Projects/2026/March/LoinCloth [*] (main) ~17.01µs
» ls
.git/ .gitignore LICENSE README.md
build_all.sh* builds/ command_lexer.go go.mod
go.sum main.go terminal_unix.go terminal_windows.go
test.cloth workspace_commands.go
[0] ~/Projects/2026/March/LoinCloth [H]
[1] ~/Projects/2026/March/LoinCloth [*] (main) ~105.981µs
»Anyways, we no longer need workspace [0], so let's use the !close command to close it.
[0] ~/Projects/2026/March/LoinCloth [H]
[1] ~/Projects/2026/March/LoinCloth [*] (main) ~805.365µs
» !close 0
~/Projects/2026/March/LoinCloth (main) ~6.32µs
»Scopes are used for saving temporary environment variables.
To start let's create a scope called "builder" like so:
~/Projects/2026/March/LoinCloth (main) ~844.463µs
» !new s builder
~/Projects/2026/March/LoinCloth (main) ~6.25µs
:builder»The prompt will now prefix with the series of scopes in order of which it overrides your env variables.
Note that these temp variables will also auto replace as arguments.
You can also stack scopes, do not worry about your scope names disappearing once you start typing, this is intentional design to prevent line noise.
~/Projects/2026/March/LoinCloth (main)
» !new s builder
~/Projects/2026/March/LoinCloth (main) ~8.84µs
» !new s r
~/Projects/2026/March/LoinCloth (main) ~10.22µs
:builder:r»Now, if you have any variables declared in r, which also exists in builder, the varaibles in r will have priority over builder.
You can now use the !set <key> <value> command like so:
~/Projects/2026/March/LoinCloth (main) ~10.22µs
» !set GOPROXY direct
~/Projects/2026/March/LoinCloth (main) ~5.95µs
» !set build "go build ."
~/Projects/2026/March/LoinCloth (main) ~8.51µs
» $build
~/Projects/2026/March/LoinCloth (main) ~33.449099ms
:builder:r»Note that the variables you declare only exist in each scope, once you drop them like in the example below, they will no longer exist. Variables, wether they are commands or not will be referenced using a $.
~/Projects/2026/March/LoinCloth (main) ~8.51µs
» $build
~/Projects/2026/March/LoinCloth (main) ~33.449099ms
» !drop r
~/Projects/2026/March/LoinCloth (main) ~6.83µs
» $build
exec: "build": executable file not found in $PATH
~/Projects/2026/March/LoinCloth (main) ~140.141µs
:builder»If you want each scope to always have a specific set of variables, consider writing a cloth file.
test.cloth:
!new s go-builder
!set run "go run ."
!set buid "go build ."
!set GOPROXY direct
!set update "go get -u"Now you can wear the cloth:
~/Projects/2026/March/LoinCloth (main) ~103.57µs
» !wear test.cloth
~/Projects/2026/March/LoinCloth (main) ~57.05µs
:go-builder»and run it's commands:
~/Projects/2026/March/LoinCloth (main) ~57.05µs
» $update github.com/loeredami/ungo@latest
~/Projects/2026/March/LoinCloth (main) ~314.921787ms
:go-builder»This ran go get -u github.com/loeredami/ungo@latest, with the GOPROXY set to direct.
!drop go-builder, to drop the builder commands and variables
Comments start and end with ##
example:
~/Projects/2026/March/LoinCloth (main) ~877.004µs
» echo Hello ## I am a comment, I will not be printed out. ## World
Hello World
~/Projects/2026/March/LoinCloth (main) ~557.296µs
»I really need custom syntax highlighting for this.
Need the output of one command as input for another?
No problem, just throw it in some {}!
~/Projects/2026/March/LoinCloth (main)
» echo {ls $HOME}
{ ls output ... }
~/Projects/2026/March/LoinCloth (main) ~780.915µs
»This example is useless, but it gets the point across.
Like a specific scope or workspace configuration? Write it to a file!
»!snapshot favorite-scope.cloth ## saves a scope to a wearable cloth file ##
»!snapshot-ws favorite-workspace.cloth ## saves a workspace to a wearable cloth file ##If you need another workspace with the configuration of another workspace use the clone command.
»!clone 0 ## clones the workspace at index 0 ##If you want to give a workspace a name to keep track of it, !switch to it, and use.
»!label "My Favourite Workspace" ## This text will now show up next to this workspace ##If you need to reload your default.cloth from your configuration folder just type:
»!reset ## Not to mix up with $reset, which references the default clear command on linux ##Ghost input appears as you are typing commands or known variables, press the right arrow key to accept them.
To add syntax highligting for .cloth files in vscode, download the source code, and copy the "cloth-syntax" folder into your vscode extensions folder. ~/.vscode/extensions
When launching into version Pre-Release 1.2 or newer, you will have created a "default.cloth", in your OS's user configuration folder.
Edit "/path/to/user/config/.loin/default.cloth", on linux this for example is:
~/.config/.loin/default.cloth
and for the sudo user /root/.config/.loin/default.cloth
In there you can type in some commands that should run every time you create an new shell, changes only apply when starting a new shell instance.
Here are some commands you can use:
!local <string field> <string> - Let's you replace a string.
!local prompt ">" changes the prompt field to be ">"
other strings:
sudo-promptscope-sign
!color <color field> <int> - Lets' you replace a color
!color input 32 - Set's your input text to Green.
color fields:
inputerrls-dirls-sym-linkls-execsudo-promptpromptidxcur-wscur-dircur-dir-indicgit-branchtimetime-prefixscopepathinput-stringinput-numinput-pathinput-varinput-braceghost
!disable-colors - Disables color rendering, good for very old machines.
!enable-colors - Enables color rendering, on by default.
!reset - Reloads your default.cloth, in your config folder, and resets your theme.