Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
For tmux configs: Merge deprecated/removed -fg, -bg, and -attr options into the -style option
#!/usr/bin/env python
# vim: set fileencoding=utf-8
#
# USAGE:
# Back up your tmux old config, run the script and redirect stdout to your conf
# file. Example:
#
# $ cp ~/.tmux.conf ~/.tmux.conf.orig
# $ python ./tmux-migrate-options.py ~/.tmux.conf.orig > ~/.tmux.conf
#
#
# PURPOSE:
# This script accepts the path to a tmux conf file to read, then combines the
# deprecated -fg, -bg, and -attr options into the new -style option, and
# prints the updated tmux conf to stdout. The deprecated options were flagged
# for removal in tmux v1.9, and then removed in tmux v2.9 years later.
#
# The script will place the new "-style" option at the location of the last
# matching prefix for that option family. This means if your config file had
# a triplet of "window-status-bg", "window-status-fg", and "window-status-attr"
# settings, they will be merged into one line at that location with the option
# "window-status-style bg=...,fg=...,<attr>", in that order.
#
# If your config file has duplicate settings for, say, -fg, they will all
# appear on the same -style option line, in the same order which should give
# the same effect as before.
#
# The parser used here is a naive regex which should be enough for most configs.
# There is *no effort* to handle tmux conditional lines or cases where you
# already have -style options as well as old -fg, -bg, -attr options.
# If you rely on those to set colors and styles, then you may want to avoid
# this script as it will break your config.
# ---
# ISC License (ISC)
#
# Copyright 2019 April | tbutts
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
from __future__ import print_function, unicode_literals
from io import open
import os
import re
import sys
if len(sys.argv) < 2:
sys.exit("[ERR] specify path to tmux config file")
tmux_conf = sys.argv[1]
with open(tmux_conf, mode='r', encoding='utf-8') as tmux_file:
content = tmux_file.readlines()
if not content:
sys.exit("[ERR] tmux config file appears to be empty")
OPTION_PREFIXES=[
"message-command-",
"message-",
"mode-",
"pane-active-border-",
"pane-border-",
"status-left-",
"status-right-",
"status-",
"window-active-",
"window-status-activity-",
"window-status-bell-",
"window-status-current-",
"window-status-last-",
"window-status-",
"window-",
]
SET_OPTION_RE=r"""
^\s*[^#]* # ignore comment lines
(?P<set_option>set\S*\s+-g) # set, setw, set-option, etc.
\s+
{prefix} # any of the above option strings
(?P<style>fg|bg|attr) # the style part name
\s+
(?P<value>\S+) # color value, attribute (bold/dim/none/etc)
"""
for opt in OPTION_PREFIXES:
option_matcher = re.compile(SET_OPTION_RE.format(prefix=opt), re.VERBOSE)
set_cmd = "" # track type of "set-option" command
line_no = 0 # track last line number of any matching set-option* command
settings = [] # track -fg, -bg, and -attr options
# Going line-by-line from content, attempt a string match with the current 'opt' option family.
# Use index-based iteration, so that 'content' can be modified while looping.
i = 0
while i < len(content):
match = option_matcher.search(content[i])
if match:
re_groups = match.groupdict()
set_cmd = re_groups["set_option"]
style = re_groups["style"]
value = re_groups["value"]
if style in ["fg", "bg"]:
settings.append("{}={}".format(style, value))
else:
# One of the -attr options (bold, dim, none, etc.)
settings.append(value)
line_no = i
content.pop(i)
else:
i += 1
if set_cmd:
style_replacement_line = "{} {} {}{}".format(
set_cmd,
opt+"style",
",".join(settings),
os.linesep)
content.insert(line_no, style_replacement_line)
# Print the updated config to stdout
if sys.version_info.major > 2:
print(''.join(content), end='')
else:
import codecs
codecs.getwriter('utf8')(sys.stdout).write(''.join(content))
@szybia

This comment has been minimized.

Copy link

szybia commented May 7, 2019

You are a hero.

@minch

This comment has been minimized.

Copy link

minch commented May 9, 2019

^

@kjivan

This comment has been minimized.

Copy link

kjivan commented May 15, 2019

Agreed. Hero!

@reliableGG

This comment has been minimized.

Copy link

reliableGG commented May 15, 2019

great Hero!

@ea2809

This comment has been minimized.

Copy link

ea2809 commented May 16, 2019

Thanks 🥇

@bedge

This comment has been minimized.

Copy link

bedge commented May 17, 2019

Nice!
Should be part of any release with config syntax changes :)

@ktsujichan

This comment has been minimized.

Copy link

ktsujichan commented May 20, 2019

Thanks 👍

@agoree407

This comment has been minimized.

Copy link

agoree407 commented May 24, 2019

Thank you so much for this.

@gerrard00

This comment has been minimized.

Copy link

gerrard00 commented Jun 9, 2019

Thanks so much for this!

@charlesdrews

This comment has been minimized.

Copy link

charlesdrews commented Jul 5, 2019

Thank you!!!

@thejasn

This comment has been minimized.

Copy link

thejasn commented Jul 17, 2019

thank you

@taira120

This comment has been minimized.

Copy link

taira120 commented Aug 19, 2019

thank you !!!!

@hallgrimur1471

This comment has been minimized.

Copy link

hallgrimur1471 commented Aug 29, 2019

Awesome, saved me some time, thank you very much!

@scmanjarrez

This comment has been minimized.

Copy link

scmanjarrez commented Oct 10, 2019

Thank you very much!

@mkohler

This comment has been minimized.

Copy link

mkohler commented Oct 20, 2019

Great! Thank you!

@aidanhmiles

This comment has been minimized.

Copy link

aidanhmiles commented Nov 30, 2019

This is amazing. Just brew upgraded tmux for the first time a long while and this saved my day

@geneidy

This comment has been minimized.

Copy link

geneidy commented Dec 6, 2019

<3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.