Coder Social home page Coder Social logo

smug's Introduction

Smug - tmux session manager

Actions Status Go Report Card

Inspired by tmuxinator and tmuxp.

Smug automates your tmux workflow. You can create a single configuration file, and Smug will create all the required windows and panes from it.

gif

The configuration used in this GIF can be found here.

Installation

Download from the releases page

Download the latest version of Smug from the releases page and then run:

mkdir smug && tar -xzf smug_0.1.0_Darwin_x86_64.tar.gz -C ./smug && sudo mv smug/smug /usr/local/bin && rm -rf smug

Don't forget to replace smug_0.1.0_Darwin_x86_64.tar.gz with the archive that you've downloaded.

Git

Prerequisite Tools

Fetch from GitHub

The easiest way is to clone Smug from GitHub and install it using go-cli:

cd /tmp
git clone https://github.com/ivaaaan/smug.git
cd smug
go install

macOS

On macOS, you can install Smug using MacPorts or Homebrew.

Homebrew

brew install smug

MacPorts

sudo port selfupdate
sudo port install smug

Linux

Arch

There's AUR with smug.

git clone https://aur.archlinux.org/smug.git
cd smug
makepkg -si

Usage

smug <command> [<project>] [-f, --file <file>] [-w, --windows <window>]... [-a, --attach] [-d, --debug]

Options:

-f, --file A custom path to a config file
-w, --windows List of windows to start. If session exists, those windows will be attached to current session.
-a, --attach Force switch client for a session
-i, --inside-current-session Create all windows inside current session
-d, --debug Print all commands to ~/.config/smug/smug.log
--detach Detach session. The same as `-d` flag in the tmux

Custom settings

You can pass custom settings into your configuration file. Use ${variable_name} syntax in your config and then pass key-value args:

xyz@localhost:~$ smug start project variable_name=value

Examples

To create a new project, or edit an existing one in the $EDITOR:

xyz@localhost:~$ smug new project

xyz@localhost:~$ smug edit project

To start/stop a project and all windows, run:

xyz@localhost:~$ smug start project

xyz@localhost:~$ smug stop project

Also, smug has aliases to the most of the commands:

xyz@localhost:~$ smug project # the same as "smug start project"

xyz@localhost:~$ smug st project # the same as "smug stop project"

xyz@localhost:~$ smug p ses # the same as "smug print ses"

When you already have a running session, and you want only to create some windows from the configuration file, you can do something like this:

xyz@localhost:~$ smug start project:window1

xyz@localhost:~$ smug start project:window1,window2

xyz@localhost:~$ smug start project -w window1

xyz@localhost:~$ smug start project -w window1 -w window2

xyz@localhost:~$ smug stop project:window1

xyz@localhost:~$ smug stop project -w window1 -w window2

Also, you are not obliged to put your files in the ~/.config/smug directory. You can use a custom path in the -f flag:

xyz@localhost:~$ smug start -f ./project.yml

xyz@localhost:~$ smug stop -f ./project.yml

xyz@localhost:~$ smug start -f ./project.yml -w window1 -w window2

Configuration

Configuration files can stored in the ~/.config/smug directory in the YAML format, e.g ~/.config/smug/your_project.yml. You may also create a file named .smug.yml in the current working directory, which will be used by default.

Examples

Example 1

session: blog

root: ~/Developer/blog

before_start:
  - docker-compose -f my-microservices/docker-compose.yml up -d # my-microservices/docker-compose.yml is a relative to `root`

env:
  FOO: BAR

stop:
  - docker stop $(docker ps -q)

windows:
  - name: code
    root: blog # a relative path to root
    manual: true # you can start this window only manually, using the -w arg
    layout: main-vertical
    commands:
      - docker-compose start
    panes:
      - type: horizontal
        root: .
        commands:
          - docker-compose exec php /bin/sh
          - clear

  - name: infrastructure
    root: ~/Developer/blog/my-microservices
    layout: tiled
    panes:
      - type: horizontal
        root: .
        commands:
          - docker-compose up -d
          - docker-compose exec php /bin/sh
          - clear

Example 2

session: blog

root: ~/Code/blog

before_start:
  - docker-compose up -d

stop:
  - docker-compose stop

windows:
  - name: code
    layout: main-horizontal
    commands:
      - $EDITOR app/dependencies.php
    panes:
      - type: horizontal
        commands:
          - make run-tests
  - name: ssh
    commands:
      - ssh -i ~/keys/blog.pem [email protected]

smug's People

Contributors

adamjt avatar blob42 avatar chandanand avatar herbygillot avatar ivaaaan avatar jordansgrant avatar kovetskiy avatar mipmip avatar windwp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

smug's Issues

No auto-attach on new session, extra window created.

Thanks for creating this! Per the title, I'm having trouble getting tmux to start/attach properly using smug. I'm running macOS 11.2, iTerm2 3.4.3, tmux 3.1c installed via Homebrew.

My config, intent is to start a session with a single window containing my Zettellkasten.

$ cat ~/.config/smug/zettel.yml
session: zettel

windows:
  - name: wiki
    commands:
      - vim +VimwikiIndex

Attempting to run it:

$ tmux ls
no server running on /private/tmp/tmux-501/default

$ smug start zettel
Starting a new session...
Cannot run "tmux kill-window -t zettel:0". Error exit status 1

$ smug start zettel:wiki
Starting a new session...

I'm returned to my shell prompt, and tmux does not open, but it was started!

$ tmux ls
zettel: 2 windows (created Mon Dec 21 17:15:45 2020)

Once I run tmux attach I see that 2 windows have been created. A blank shell which is the window I'm started in, and the wiki window.

image

image

Hope I've provided enough info to help, let me know if there is a debug/verbose mode I can try out, or anything else!

smug list displays all files in .config/smug as projects

Describe the bug
smug list displays any file in ~/.config/smug as project

> ls -1 .config/smug/
home.yml
smug.log
work.yml
# ~ 
> smug list
home
smug
work
# ~ 
> touch .config/smug/test
# ~ 
> smug list
home
smug
test
work

Expected behavior
smug list should only display smug projects

Smug version
v0.2.2

OS you're using
Gentoo

smug new <project> doesn't create a new configuration

Describe the bug
On smug new test -d no file is being created, smug.log is empty. So looks like bug

Screen.Recording.2024-03-26.at.5.07.38.PM.mov

Smug config
Nothing

Expected behavior
touch ~/.config/<name>.yaml

Output of cat ~/.config/smug/smug.log
Empty

Smug version
0.3.3

OS you're using
MacOS 14.4

Cannot open manual window with latest smug version

Describe the bug
I have a config defined with two windows. One is configured as manual: true. I open a session with smug start myconfig. This opens the first window successfully with the configured panes and commands.

Then I smug start myconfig:test2 which is the manual one. It fails to open.

Smug config

session: 'MyConfig'
windows:
  - name: test1
    commands: [ls]
    panes:
      - commands: [ls]
  - name: test2
    manual: true
    commands: [ls]
    panes:
      - commands: [ls]

Expected behavior
The test2 window should open successfully with the defined layout

Output of cat ~/.config/smug/smug.log

tmux has-session -t MyConfig:
tmux neww -Pd -t MyConfig: -c  -F #{window_id} -n test2
tmux send-keys -t @3 ls Enter
tmux split-window -Pd -t @3 -c  -F #{pane_id}
tmux select-layout -t @3 tiled
tmux send-keys -t @3.%6 ls Enter
tmux select-layout -t @3 even-horizontal
tmux kill-window -t MyConfig:smug_def
exit status 1 can't find window: smug_def

tmux kill-window -t MyConfig:test2

It seems smug_def window is not being created in this scenario, which is expected to exist.

Smug version

Smug - tmux session manager. Version 0.3.1

OS you're using
MacOS Monterey 12.4

Color handling

Describe the bug
Smug handles colors incorrectly:

e.g. background in fzf, background in vim, statusbar active window background, see in screenshot below marked by red rectangle (left is smug, right - just tmux):
image

for vim this issue resolves by :
image

Expected behavior
Show colors as expected

Output of cat ~/.config/smug/smug.log
Don't have one

Smug version
You can get it from the $ smug --help output
0.1.8
OS you're using
Void Linux.

example for main-vertical with 3 panes

I'm trying to get this layout, but I don't succeed. Can you help me with an example ?

|-----------------------|-----------------------|
|                       |                       |
|                       |         echo 2        |
|                       |                       |
|      echo 1           |-----------------------|
|                       |                       |
|                       |         echo 3        |
|                       |                       |
|-----------------------|-----------------------|

Splitting panes cause issue

Describe the bug
Can't split panes and getting error below for current master hash 7dbaa0f

Cannot run "tmux split-window -Pd -h -t test:first.0 -c /home/ctran/Projects -F #{pane_id}". Error exit status 1

Expected behavior
Should be able to create panes

Output of cat ~/.config/smug/smug.log
N/A

Smug version
7dbaa0f

OS you're using
Linux arch 5.10.13-arch1-1 #1 SMP PREEMPT Wed, 03 Feb 2021 23:44:07 +0000 x86_64 GNU/Linux

Detach the sessions

How i can detach the sessions?
in tmux if we want to make new sessions, we just need -d for making the new sessions without opening the sessions
tmux new -s mysessions -d
i tried to add -d in config files but won't close it

Add `create` and `edit` commands

We want to add an ability to create and edit configuration files within smug command.

smug <edit|create> <project> should open ~/.config/smug/project.yml in the $EDITOR

This is a simple task, and doesn't require any prior knowledge of the project. If you would like to contribute, reach me out, I'll be happy to assist with any questions.

-i flag opens new sessions

Describe the bug
Just found smug and really liking saving so may keystrokes setting up windows and panes! Thanks so much!

It's my understanding that if I use the -i flag, the new windows and panes should be opened in the current tmux session. However, smug seems to always open new sessions. Behavior appears to be the same with or without the flag.

Smug config

session: stream

root: ~/workspace/music/

windows:
  - name: player
    layout: main-horizontal
    commands:
      - cd player
      - ./start.sh
    panes:
      - type: horizontal
        commands:
          - cd stream-list
          - ./start.sh

Expected behavior
I would expect that when I pass the -i flag, any new windows from my smug config get created in the current session directly after the current window (as if I had created the new window manually)

Output of cat ~/.config/smug/smug.log

tmux has-session -t stream:
exit status 1
tmux new -Pd -s stream -n smug_def -c /home/codegoalie/workspace/music/
tmux neww -Pd -t stream: -c /home/codegoalie/workspace/music -F #{window_id} -n player
tmux send-keys -t @2 cd disney-stream-player Enter
tmux send-keys -t @2 ./start.sh Enter
tmux split-window -Pd -h -t @2 -c /home/codegoalie/workspace/music -F #{pane_id}
tmux send-keys -t @2.%3 cd stream-lister Enter
tmux send-keys -t @2.%3 ./start.sh Enter
tmux select-layout -t @2 main-horizontal

Smug version
v0.2.6

OS you're using
Linux 5.13.0-28-generic #31~20.04.1-Ubuntu SMP Wed Jan 19 14:08:10 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

update new version, is long time

Describe the bug
A clear and concise description of what the bug is.

Smug config

Expected behavior
A clear and concise description of what you expected to happen, or an image of what you want to see

Output of cat ~/.config/smug/smug.log
You should run smug with -d flag to output debug information

Smug version
You can get it from the $ smug --help output

OS you're using

features: swich new project

when i start this project, i want to new project
i just stop this project , and start new project

can you make new arugment
like

smug change

Add a flag for debugging

Would be nice to log all commands that smug runs.
We can achieve it by injecting log.Logger interface in the commander.go. By default, we can write everything into ~/.config/smug/smug.log

musl target in releases?

Hi,
just built smug under AlpineLinux and works pretty well.

Wonder if you'd add musl target to the builder.

Thanks.

Keys are sent to the wrong pane when multiple panes are configured

Describe the bug
Using the configuration below, keys for pane2 are sent to pane1.

session: debug

root: ~/

windows:
  - name: window
    commands:
      - echo "window"

    panes:
      - name: pane1 
        commands:
          - echo "pane 1"
      - name: pane2
        commands:
          - echo "pane 2"

Expected behavior
Commands are correctly sent to the pane for which they are specified.

It appears that when you split-window with a target-pane set to the window itself, this results in a shuffling of the numerical index tmux uses for panes. After pane2 is split, this pushes the original pane1 into debug:window.2, and it receives the send-keys meant for pane2.

It looks like tmux will assign a unique ID to each pane, but I am not sure how you might make use of that here.

tmux also gives each pane created in a server an identifier consisting of a ‘%’ and a number, starting from zero. A pane's identifier is unique for the life of the tmux server and is passed to the child process of the pane in the TMUX_PANE environment variable. It may be used alone to target a pane or the window containing it.

Thanks for your work on this tool!

Output of cat ~/.config/smug/smug.log

tmux has-session -t debug:
exit status 1
tmux new -Pd -s debug -n smug_def -c /home/micah/
tmux neww -Pd -t debug: -n window -c /home/micah
tmux send-keys -t debug:window echo "window" Enter
tmux select-layout -t debug:window even-horizontal
tmux split-window -Pd -t debug:window -c /home/micah
tmux send-keys -t debug:window.1 echo "pane 1" Enter
tmux split-window -Pd -t debug:window -c /home/micah
tmux send-keys -t debug:window.2 echo "pane 2" Enter
tmux kill-window -t debug:smug_def
tmux move-window -r -s debug: -t debug:
tmux attach -d -t debug:window

Smug version
Smug - tmux session manager. Version v0.1.7

OS you're using
Pop!_OS 20.10

Feature: save current session

Print current session to stdout as yml. Print all windows and pane-layouts and per pane the current directory. Maybe even per pane every running command.

E.g.:

smug sess2yml [session-name]     Print current session to stdout as yml.
smug sess2yml this-session > ~/.config/smug/my-session.yml

Port CLI interface to github.com/urfave/cli/v2

If you implement this CLI library you loose a lot of overhead code for your commands and options. Beside this you get usage documentation and autocomplete without extra coding. If you like I can help.

config in the docs gif is not readable

I can't pause the gif it goes off too quickly :/

If it's important so maybe move it to a separate image?

Gif – what is Smug?
Config pic – sample config code

ps Awesome job with Smug @ivaaaan !! Cheers from Russia

Support passing args

I am excited to see another competitor to tmuxinator. I would love to drop it since its my only ruby dependency left in my dotfiles.

Wondering if there are plans to support passing in arguments to projects when invoking smug. This is the only feature of tmuxinator that I use that would make switching a little bit differerent. I have scripting around launching projects in tmux, if a tmuxinator/smug project would exist it would launch that, otherwise it launches a default project that gives me some standard windows. In tmuxinator it looks like this.

name: <%= @settings["name"].upcase().split(/[-_]/).join(' ') %>
root: <%= @settings["root"] %>

windows:
  - editor: nvim
  - console: clear

I could move this to a custom script instead of using smug/tmuxinator but it was kinda nice defining it and keeping it in tmuxinator.

arm64 build

Describe the bug
smug runs via emulation on Apple Silicon

Expected behavior
I'd like to package for all go-supported platforms

OS you're using
macOS 12.0.1

update new version, is long time

Describe the bug
A clear and concise description of what the bug is.

Smug config

Expected behavior
A clear and concise description of what you expected to happen, or an image of what you want to see

Output of cat ~/.config/smug/smug.log
You should run smug with -d flag to output debug information

Smug version
You can get it from the $ smug --help output

OS you're using

Name Conflict Resolution

Describe the bug
If there are two or more smug config with name prefixed from one of them, and then the prefix of the name itself is running last (as it uses $(smug config)

To get the situation here:

  • Running a smug config will give you a list, with prefixer to come later from prefixed name.
    image
  • Executing whole batch using for VAR in $(smug config) will execute everything except the last one, due to prefixing issue. On the picture it's yohane-irc vs yohane which is shadowed by yohane-irc upon doing smug start yohane until the yohane-irc window got stopped.

However:

  • If I decide to smug config | sort, or at least sorting the naming order from smug config output, which happens to give different output from just smug config. Things works normally.
  • Execution order changed from yohane to yohane-irc instead vice versa. No naming conflict like what happened above.

Smug config
smug config does not matter

Expected behavior

  • Both yohane-irc and yohane should be executed alongside in any order of execution.

Output of cat ~/.config/smug/smug.log
output log does not matter.

Smug version
0.2.7

OS you're using
Linux

Allow tmux-style short commands

I'd love support for short commands, like tmux does.

In cases where there's no ambiguity, it would be very handy to be able to use "n" for "new", "e" for "edit", "l" or "ls" for "list", etc.

Of course, cases like "s" would be ambiguous (start/stop), so would need to be used in it's fuller form, the same way tmux does.

Empty name cause smug to not behave correctly

Describe the bug
When having name set to empty string smug messed up all the windows. I'm able to do this with tmuxinator but smug isn't working correctly. When not setting a name for a window it puts all splitted panes into the first window.

Expected behavior
Setting empty string for name should not make splitted panes to be in the first window.

Output of cat ~/.config/smug/smug.log
None

Smug version
v0.1.6

OS you're using
Linux arch 5.10.13-arch1-1 #1 SMP PREEMPT Wed, 03 Feb 2021 23:44:07 +0000 x86_64 GNU/Linux

smug new <project> does not open $EDITOR

Describe the bug
smug new <project> does not open $EDITOR

Expected behavior
smug new <project> should open a ~/.config/smug/project.yml in the $EDITOR

Smug version
v.0.1.8

NixOS Package update

Current version available on NixOS packages is 0.2.7, could do with an update.

Need an example for multipanes

Good day to you!
Thank you for your work!

Describe the bug
I can create multiple panes in window, but I can't figure out how to place them in geometric order as I want.

example:
I have config for window:
image

And I want to place main pane at left side, and others at right.

but now it gives me this:
image

Expected behavior
I'm asking about:

How I can split specific pane in config file?
(like nested splitting)

Output of cat ~/.config/smug/smug.log

Smug version
0.1.7

OS you're using

Void Linux

Request for `-L` option

Tmux has the -L option to specify the socket name (and -S to specify the socket path). This is very useful to group sessions in different sockets (isolated tmux servers).

It would be nice to have this option in smug.

Other tmux managers allow users to set the socket name in the yaml files which I haven't used, but could also be useful.

I have the intention of creating a PR for this, but I would have to learn at least some basic Go to do this 😅

What do you think @ivaaaan? Do you see value in this? Should I create a PR or is it easy for you to do?

Thank you!

Dynamic session

Any chance you could support a dynamic session, where session could evaluate a command to execute or session name could be passed in from the command line?

I have a use case where I create a session for each code base I'm working on, each with the same layout. I can then easily flip between vim/tests/etc... If I use smug, I must define my session ahead of time, which doesn't allow me to reuse a common layout, since they would all share the same session name.

Thanks in advance!

Error with 6 panels

Describe the bug
When I create a session with 5 panels, it's ok, but with 6 I have this message: "Oops, an error occurred! Rolling back..."

Smug config

session: infra

root: ~/dev/ops/infra

windows:
  - name: server
    layout: tiled
    commands:
      - date
    panes:
      - commands:
        - date
      - commands:
        - date
      - commands:
        - date
      - commands:
        - date
      - commands:
        - date

Expected behavior
I would like create 8 panels.

Output of cat ~/.config/smug/smug.log

tmux has-session -t infra:
exit status 1
tmux new -Pd -s infra -n smug_def -c /home/kosssi/dev/ops/infra
tmux neww -Pd -t infra: -c /home/kosssi/dev/ops/infra -F #{window_id} -n server
tmux split-window -Pd -t @1 -c /home/kosssi/dev/ops/infra -F #{pane_id}
tmux send-keys -t @1.%2 date Enter
tmux split-window -Pd -t @1 -c /home/kosssi/dev/ops/infra -F #{pane_id}
tmux send-keys -t @1.%3 date Enter
tmux split-window -Pd -t @1 -c /home/kosssi/dev/ops/infra -F #{pane_id}
tmux send-keys -t @1.%4 date Enter
tmux split-window -Pd -t @1 -c /home/kosssi/dev/ops/infra -F #{pane_id}
tmux send-keys -t @1.%5 date Enter
tmux split-window -Pd -t @1 -c /home/kosssi/dev/ops/infra -F #{pane_id}
exit status 1
tmux kill-session -t infra

Smug version

$ tmux -V
tmux 3.0a
$ smug --version
Smug - tmux session manager. Version v0.2

OS you're using
Ubuntu 20.04 LTS

Allow to group projects into directories

I want to allow users to group their configs into directories, e.g:

smug
├── my-awesome-project
│   ├── app.yml
│   └── backend.yml

Now command smug start my-awesome-project should create multiple tmux sessions, and attach to the last one created.
Config option always_attach: true on the config root level may be added

Support smug - donate to Ukrainian Army 🇺🇦

Hello!

I'm the author of the smug, and I need your help. I’m fundraising money for a new car for the territorial defense forces, where my uncle is fighting from the first day of the war. I've already raised $3000 out of $5000.
I would appreciate any help (donate or repost), it would be the best way to support the project.

How to donate:

Paypal: [email protected]
Wise: [email protected]
BTC: bc1qmyphjt8ep4l2fvx4yppf9vmq0uhmcaefl03xe0
ETH: 0x0b96192951184a4b0df16ee947bbf0a60367bc85
USDT: 0x0b96192951184a4b0df16ee947bbf0a60367bc85

Thanks,
Ivan

Feature: smug stop within session

It might be useful to look up the current tmux session, and allow users to run smug stop without a session name within a smug managed session, by using tmux display-message -p '#S'1 and looking to see if it matches an expected session name.

[feature request] ready-command

[feature request] ready-command

ready-command:
- do-this-then-that-later

This would allow to have the command echoed to the prompt but NOT yet executed.

Running smug list fails when no tmux is running

Describe the bug
When running smug list outside a tmux session, while no instance of tmux is running, it returns Cannot run "tmux display-message -p #S". Error exit status 1. Same goes for smug print
This issue does not occur when running smug list -d, then everything works flawlessly

Expected behavior
Print the names of the configs

Smug version
0.29

OS you're using
Mac OS Monterey 12.4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.