devops-works / binenv

One binary to rule them all. Manage all those pesky binaries (kubectl, helm, terraform, ...) easily.
MIT License
367 stars 44 forks source link

Bash window title #171

Open jgournet opened 2 years ago

jgournet commented 2 years ago

Hi there,

It's really low priority, as it's cosmetic and highly dependent on configuration, but just wanted to mention: I'm using "Konsole", and by default, the bash window title is "folder : software_running"

When launching any application installed via binenv, I get: "folder : software_version" => is there a way to change binenv so it would reflect the software running ?

leucos commented 2 years ago

I think this is terminal+shell dependent and it is not actionable on the binenv side.

leucos commented 2 years ago

Ok I get it. We probably can get away by unsafe-changing argv[0], something like:

func SetProcessName(name string) error {
    argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
    argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]

    n := copy(argv0, name)
    if n < len(argv0) {
            argv0[n] = 0
    }

    return nil
}

Will check this.

leucos commented 2 years ago

After taking a third look at this, the above solution won't work, since it has to be made in the binary itself, something we of course do not control.

The only way I see is to change binaries layout, and instead of having binaries in the distribution name like this:

$ ls -la ~/.binenv/binaries/terraform/
-rwxr-x---   0.13.1*
-rwxr-x---   0.13.5*
...

we could use another directory level using version, and a properly name binary inside like so:


$ ls -la ~/.binenv/binaries/terraform/
drwxr-x---   0.13.1/
drwxr-x---   0.13.5/
$ ls -la ~/.binenv/binaries/terraform/0.13.1/
-rwxr-x---   terraform*
...

However it is not easy to transition the current installations to a new directory layout.
lmorg commented 2 years ago

There is an ANSI escape code for changing the terminal emulators window title:

package ansititle

import (
    "bytes"
    "errors"
    "os"

    "golang.org/x/crypto/ssh/terminal"
)

func Write(title []byte) error {
    fd := os.Stdout.Fd()
    if !terminal.IsTerminal(int(fd)) {
        return errors.New("not a TTY")
    }

    _, err := os.Stdout.Write(formatTitle(title))
    return err
}

func formatTitle(title []byte) []byte {
    if len(title) == 0 {
        return nil
    }
    title = sanatise(title)
    ansi := make([]byte, len(title)+5)

    copy(ansi[0:4], []byte{27, ']', '0', ';'})
    copy(ansi[4:len(title)+4], title)
    ansi[len(ansi)-1] = 7

    return ansi
}

func sanatise(b []byte) []byte {
    b = bytes.ReplaceAll(b, []byte{'\r'}, nil)
    // replace all control characters with space
    for i := range b {
        if b[i] < 32 || b[i] == 127 {
            b[i] = 32
        }
    }

    return b
}

(adapted from: https://github.com/lmorg/murex/tree/master/utils/ansititle)

The issue is while some terminal emulators seems to honour this, Konsole by default does not. That's up to the user to change in their tab settings (I've not found a way to force change that myself). image

However you can query what the tab title format is with this command:

qdbus $KONSOLE_DBUS_SERVICE $KONSOLE_DBUS_SESSION org.kde.konsole.Session.tabTitleFormat $KONSOLE_DBUS_WINDOW
leucos commented 2 weeks ago

@jgournet thanks fo the report but, as you can see, I have very little time for the project right now. Since this is not critical, I'd rather set it aside for now if that's ok.

If someone wants to handle this, I'd be glad to review PRs.