terminal - tmux shows weirdly encoded history on OSX

07
2014-07
  • Reefersleep

    If I do the "history" command in tmux, I get a really weird result. Anyone got a hint on what to do to get normal output?

    The output looks like this:

      477  ◆┬▒⎺▒└☃◆ 
      478  c▒├ ◆┬▒⎺▒└☃◆
      479  ec▒⎺ ◆┬▒⎺▒└☃◆
      48▮  ┴☃└ ·/↓├└┤│↓c⎺┼° 
      481  ├└┤│
      482  ┌⎽
      483  cd ┐⎺▒┼⎽/
      484  ┌e☃┼ ┐⎺▒┼⎽ ⎼┤┼
      485  ┌⎽
      486  ┌e☃┼ ▮1_e─┤▒┌☃├☃e⎽↓c┌┘ ⎼┤┼
      487  cd ↓↓
      488  ┌e☃┼ ┐⎺▒┼⎽ ⎼┤┼
      489  cd ┐⎺▒┼⎽/
      49▮  ┌e☃┼ ┐⎺▒┼ ⎼┤┼
      491  ┴☃└ ▮1_e─┤▒┌☃├☃e⎽↓c┌┘ 
      492  ▒☃⎽├⎺⎼≤
      493  ┌e☃┼ ┐⎺▒┼ ⎼┤┼
      494  ├└┤│ ┌⎽
      495  ├⎺⎻
      496  ▒☃⎽├⎺⎼≤
      497  e│☃├
      498  e│☃├
      499  ▒☃⎽├⎺⎼≤
    S⎼e┼⎽↑M▒cB⎺⎺┐↑P⎼⎺↑2:· S⎺e⎼e┼$ 
    

    I'm guessing it has to do with encoding.

    I'm on a MacBook Pro in OSX Lion 10.7.5.

    I'm using the Terminal app which has (among others) UTF-8 encoding enabled and UFT-8 under "International - Character Encoding:".

    My shell is bash.

    My tmux as per tmux -V is tmux 1.9a.

    In my ~/.tmux.conf/, I have

    set-option -g          prefix ^Space
    bind-key ^Space        send-prefix
    unbind C-b
    set-option -g          status-fg white
    set-option -g          default-command "reattach-to-user-namespace -l bash"
    set -sg                escape-time 1
    set -g                 base-index 1
    setw -g                pane-base-index 1
    bind r                 source-file ~/.tmux.conf
    set-window-option -g   utf8 on
    set -g                 utf8
    set -g                 status-utf8 on
    

    My languagesetup is English, though I'm Danish and so is my keyboard layout :) This has only been a problem for me when languagesetup was not English - specifically, piping with my Danish pipe character | meant that bash would not recognise the command after the pipe if I wrote a space between it and the pipe, so I had to do e.g.

    echo $PATH |less

    rather than

    echo $PATH | less

    But as I said, I fixed this with languagesetup.

    I'm really eager to get going with tmux, so I hope somebody knows how to fix it! :)


    CAUSE:

    The weird output was because I had ^N (the output from the key combination of Ctrl + n) in my history. The weird output can be intentionally forced if I press Ctrl + n followed by enter in tmux. I filed a ticket at tmux's SourceForge page in case it was a bug: https://sourceforge.net/p/tmux/tickets/137/ So, no ^N, no weird output!

  • Answers
    Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

    Related Question

    terminal - Display escape characters in tmux
  • John

    I have a script on my mac that displays the battery level with some color output. The color is based on the battery leve. As the level goes to zero, the color goes from green to red:

    #!/bin/bash
    
    percent=`ioreg -l | grep -i capacity | tr '\n' ' | ' | awk '{printf("%d", $10/$5 * 100)}'`
    if [ $percent -gt 80 ] ; then
      echo -n $'\e[32m'"${percent}%"
    elif [ $percent -gt 65 ] ; then
      echo -n $'\e[1;33m'"${precent}%"
    elif [ $percent -gt 40 ] ; then
      echo -n $'\e[1;31m'"${percent}%"
    else
      echo -n $'\e[31m'"${percent}%"
    fi
    

    I have put this in my tmux config as:

    # status right options
    set -g status-right '#[fg=green][#[fg=blue]%Y-%m-%d #[fg=white]%H:%M#[default]  #($HOME/bin/battery)#[fg=green]]'
    

    However, it shows up in my terminal as:

    enter image description here

    My question is, how can I get tmux to display the escape character correctly?


  • Related Answers
  • Chris Johnsen

    This does not seem to be documented, but the output of #() shell-commands in status-left, status-right, window-status-format, and window-status-current-format is also processed for #[] color/attribute sequences.

    So, just output the #[] sequences instead of the escape sequences.

    #!/bin/bash
    percent=$(ioreg …)
    if   (( percent > 80 )); then color='#[nobright fg=green]'
    elif (( percent > 65 )); then color='#[bright fg=yellow]'
    elif (( percent > 40 )); then color='#[bright red]'
                             else color='#[nobright red]'
    fi
    echo "$color$percent%"
    

    It makes sense that full escape sequences are not interpreted for these status strings: there is not much point to doing (e.g.) cursor control since they are always rendered into (part of) a single line.


    I ended up browsing through the source code to find that #[] is interpreted strictly after all other # sequences (including #()). It looks like this has always been the case since #[] was introduced.