]> git.sur5r.net Git - i3/i3/commitdiff
Add script to migrate a v3 config to v4 (tree). Please test this!
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 6 Jul 2011 11:56:58 +0000 (13:56 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 6 Jul 2011 11:56:58 +0000 (13:56 +0200)
Run ./i3-migrate-config-to-v4.pl < ~/.i3/config > /tmp/i3.config
and see if /tmp/i3.config is fine (especially check the comments
starting with XXX, they are inserted by the script).

i3-migrate-config-to-v4.pl [new file with mode: 0755]
testcases/t/71-config-migrate.t [new file with mode: 0644]

diff --git a/i3-migrate-config-to-v4.pl b/i3-migrate-config-to-v4.pl
new file mode 100755 (executable)
index 0000000..ecffa8d
--- /dev/null
@@ -0,0 +1,317 @@
+#!/usr/bin/env perl
+# vim:ts=4:sw=4:expandtab
+#
+# script to migrate an old config file (i3 < 4.0) to the new format (>= 4.0)
+# this script only uses modules which come with perl 5.10
+#
+# reads an i3 v3 config from stdin and spits out a v4 config on stdout
+# exit codes:
+#     0 = the input was a v3 config
+#     1 = the input was already a v4 config
+#         (the config is printed to stdout nevertheless)
+#
+# © 2011 Michael Stapelberg and contributors, see LICENSE
+
+use strict;
+use warnings;
+use Getopt::Long;
+use v5.10;
+
+# is this a version 3 config file? disables auto-detection
+my $v3 = 0;
+my $result = GetOptions('v3' => \$v3);
+
+# reads stdin
+sub slurp {
+    local $/;
+    <>;
+}
+
+my @unchanged = qw(
+    font
+    set
+    mode
+    exec
+    assign
+    floating_modifier
+    focus_follows_mouse
+    ipc-socket
+    ipc_socket
+    client.focused
+    client.focused_inactive
+    client.unfocused
+    client.urgent
+);
+
+my %workspace_names;
+my $workspace_bar = 1;
+
+my $input = slurp();
+my @lines = split /\n/, $input;
+
+# remove whitespaces in the beginning of lines
+@lines = map { s/^[ \t]*//g; $_ } @lines;
+
+# Try to auto-detect if this is a v3 config file.
+sub need_to_convert {
+    # If the user passed --v3, we need to convert in any case
+    return 1 if $v3;
+
+    for my $line (@lines) {
+        # only v4 configfiles can use bindcode or workspace_layout
+        return 0 if $line =~ /^bindcode/ || $line =~ /^workspace_layout/;
+
+        # have a look at bindings
+        next unless $line =~ /^bind/;
+
+        my ($statement, $key, $command) = ($line =~ /([a-zA-Z_-]+)[ \t]+([^ \t]+)[ \t]+(.*)/);
+        return 0 if $command =~ /^layout/ ||
+                    $command =~ /^floating/ ||
+                    $command =~ /^workspace/ ||
+                    $command =~ /^focus (left|right|up|down)/ ||
+                    $command =~ /^border (normal|1pixel|borderless)/;
+    }
+
+    return 1;
+}
+
+if (!need_to_convert()) {
+    # If this is already a v4 config file, we will spit out the lines
+    # and exit with return code 1
+    print $input;
+    exit 1;
+}
+
+for my $line (@lines) {
+    # directly use comments and empty lines
+    if ($line =~ /^#/ || $line =~ /^$/) {
+        print "$line\n";
+        next;
+    }
+
+    my ($statement, $parameters) = ($line =~ /([a-zA-Z._-]+)(.*)/);
+
+    # directly use lines which have not changed between 3.x and 4.x
+    if (!defined($statement) || (lc $statement ~~ @unchanged)) {
+        print "$line\n";
+        next;
+    }
+
+    # new_container changed only the statement name to workspace_layout
+    if ($statement eq 'new_container') {
+        # TODO: new_container stack-limit
+        print "workspace_layout$parameters\n";
+        next;
+    }
+
+    # workspace_bar is gone, you should use i3bar now
+    if ($statement eq 'workspace_bar') {
+        $workspace_bar = ($parameters =~ /[ \t+](yes|true|on|enable|active)/);
+        print "# XXX: REMOVED workspace_bar line. There is no internal workspace bar in v4.\n";
+        next;
+    }
+
+    # new_window changed the parameters from bb to borderless etc.
+    if ($statement eq 'new_window') {
+        if ($parameters =~ /bb/) {
+            print "new_window borderless\n";
+        } elsif ($parameters =~ /bp/) {
+            print "new_window 1pixel\n";
+        } elsif ($parameters =~ /bn/) {
+            print "new_window normal\n";
+        } else {
+            print "# XXX: Invalid parameter for new_window, not touching line:\n";
+            print "$line\n";
+        }
+        next;
+    }
+
+    # bar colors are obsolete, need to be configured in i3bar
+    if ($statement =~ /^bar\./) {
+        print "# XXX: REMOVED $statement, configure i3bar instead.\n";
+        next;
+    }
+
+    # one form of this is still ok (workspace assignments), the other (named workspaces) isn’t
+    if ($statement eq 'workspace') {
+        my ($number, $params) = ($parameters =~ /[ \t]+([0-9]+) (.+)/);
+        if ($params =~ /^output/) {
+            print "$line\n";
+            next;
+        } else {
+            print "# XXX: workspace name will end up in the bindings, see below\n";
+            $workspace_names{$number} = $params;
+            next;
+        }
+    }
+
+    if ($statement eq 'bind' || $statement eq 'bindsym') {
+        convert_command($line);
+        next;
+    }
+
+    print "# XXX: migration script could not handle line: $line\n";
+}
+
+#
+# Converts a command (after bind/bindsym)
+#
+sub convert_command {
+    my ($line) = @_;
+
+    my @unchanged_cmds = qw(
+        exec
+        mode
+        mark
+        kill
+        restart
+        reload
+        exit
+        stack-limit
+    );
+
+    my ($statement, $key, $command) = ($line =~ /([a-zA-Z_-]+)[ \t]+([^ \t]+)[ \t]+(.*)/);
+
+    # turn 'bind' to 'bindcode'
+    $statement = 'bindcode' if $statement eq 'bind';
+
+    # check if it’s one of the unchanged commands
+    my ($cmd) = ($command =~ /([a-zA-Z_-]+)/);
+    if ($cmd ~~ @unchanged_cmds) {
+        print "$statement $key $command\n";
+        return;
+    }
+
+    # simple replacements
+    my @replace = (
+        qr/^s/ => 'layout stacking',
+        qr/^d/ => 'layout default',
+        qr/^T/ => 'layout tabbed',
+        qr/^f($|[^go])/ => 'fullscreen',
+        qr/^fg/ => 'fullscreen global',
+        qr/^t/ => 'focus mode_toggle',
+        qr/^h/ => 'focus left',
+        qr/^j($|[^u])/ => 'focus down',
+        qr/^k/ => 'focus up',
+        qr/^l/ => 'focus right',
+        qr/^mh/ => 'move left',
+        qr/^mj/ => 'move down',
+        qr/^mk/ => 'move up',
+        qr/^ml/ => 'move right',
+        qr/^bn/ => 'border normal',
+        qr/^bp/ => 'border 1pixel',
+        qr/^bb/ => 'border borderless',
+        qr/^pw/ => 'workspace prev',
+        qr/^nw/ => 'workspace next',
+    );
+
+    my $replaced = 0;
+    for (my $c = 0; $c < @replace; $c += 2) {
+        if ($command =~ $replace[$c]) {
+            $command = $replace[$c+1];
+            $replaced = 1;
+            last;
+        }
+    }
+
+    # goto command is now obsolete due to criteria + focus command
+    if ($command =~ /^goto/) {
+        my ($mark) = ($command =~ /^goto (.*)/);
+        print qq|$statement $key [con_mark="$mark"] focus\n|;
+        return;
+    }
+
+    # the jump command is also obsolete due to criteria + focus
+    if ($command =~ /^jump/) {
+        my ($params) = ($command =~ /^jump (.*)/);
+        if ($params =~ /^"/) {
+            # jump ["]window class[/window title]["]
+            ($params) = ($params =~ /^"([^"]+)"/);
+
+            # check if a window title was specified
+            if ($params =~ m,/,) {
+                my ($class, $title) = ($params =~ m,([^/]+)/(.+),);
+                print qq|$statement $key [class="$class" title="$title"] focus\n|;
+            } else {
+                print qq|$statement $key [class="$params"] focus\n|;
+            }
+            return;
+        } else {
+            # jump <workspace> [ column row ]
+            print "# XXX: jump workspace is obsolete in 4.x: $line\n";
+            return;
+        }
+    }
+
+    if (!$replaced && $command =~ /^focus/) {
+        my ($what) = ($command =~ /^focus (.*)/);
+        $what =~ s/[ \t]//g;
+        if ($what eq 'ft') {
+            $what = 'mode_toggle';
+        } elsif ($what eq 'floating' || $what eq 'tiling') {
+            # those are unchanged
+        } else {
+            print "# XXX: focus <number> is obsolete in 4.x: $line\n";
+            return;
+        }
+        print qq|$statement $key focus $what\n|;
+        return;
+    }
+
+    # the parameters of the resize command have changed
+    if ($command =~ /^resize/) {
+        # OLD: resize <left|right|top|bottom> [+|-]<pixels>\n")
+        # NEW: resize <grow|shrink> <direction> [<px> px] [or <ppt> ppt]
+        my ($direction, $sign, $px) = ($command =~ /^resize (left|right|top|bottom) ([+-])([0-9]+)/);
+        my $cmd = 'resize ';
+        $cmd .= ($sign eq '+' ? 'grow' : 'shrink') . ' ';
+        $cmd .= "$direction ";
+        $cmd .= "$px px";
+        print qq|$statement $key $cmd\n|;
+        return;
+    }
+
+    # switch workspace
+    if ($command =~ /^[0-9]+/) {
+        my ($number) = ($command =~ /^([0-9]+)/);
+        if (exists $workspace_names{$number}) {
+            print qq|$statement $key workspace $workspace_names{$number}\n|;
+            return;
+        } else {
+            print qq|$statement $key workspace $number\n|;
+            return;
+        }
+    }
+
+    # move to workspace
+    if ($command =~ /^m[0-9]+/) {
+        my ($number) = ($command =~ /^m([0-9]+)/);
+        if (exists $workspace_names{$number}) {
+            print qq|$statement $key move workspace $workspace_names{$number}\n|;
+            return;
+        } else {
+            print qq|$statement $key move workspace $number\n|;
+            return;
+        }
+    }
+
+    # With Container-commands are now obsolete due to different abstraction
+    if ($command =~ /^wc/) {
+        print "# XXX: 'with container' commands are obsolete in 4.x: $line\n";
+        return;
+    }
+
+    if ($replaced) {
+        print "$statement $key $command\n";
+    } else {
+        print "# XXX: migration script could not handle command: $line\n";
+    }
+}
+
+
+# add an i3bar invocation automatically if no 'workspace_bar no' was found
+if ($workspace_bar) {
+    print "\n";
+    print "# XXX: Automatically added a call to i3bar to provide a workspace bar\n";
+    print "exec i3status | i3bar -d\n";
+}
diff --git a/testcases/t/71-config-migrate.t b/testcases/t/71-config-migrate.t
new file mode 100644 (file)
index 0000000..9903d54
--- /dev/null
@@ -0,0 +1,325 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+# !NO_I3_INSTANCE! will prevent complete-run.pl from starting i3
+#
+# Tests if i3-migrate-config-to-v4.pl correctly migrates all config file
+# directives and commands
+#
+use i3test;
+use Cwd qw(abs_path);
+use Proc::Background;
+use File::Temp qw(tempfile tempdir);
+use POSIX qw(getuid);
+use Data::Dumper;
+use v5.10;
+
+# reads in a whole file
+sub slurp {
+    open my $fh, '<', shift;
+    local $/;
+    <$fh>;
+}
+
+sub migrate_config {
+    my ($config) = @_;
+
+    my ($fh, $tmpfile) = tempfile();
+    print $fh $config;
+    close($fh);
+
+    my $cmd = "sh -c 'exec " . abs_path("../i3-migrate-config-to-v4.pl") . " --v3 <$tmpfile'";
+    return [ split /\n/, qx($cmd) ];
+}
+
+sub line_exists {
+    my ($lines, $pattern) = @_;
+
+    for my $line (@$lines) {
+        return 1 if $line =~ $pattern;
+    }
+
+    return 0
+}
+
+#####################################################################
+# check that some directives remain untouched
+#####################################################################
+
+my $input = <<EOT;
+    font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+EOT
+
+my $output = migrate_config($input);
+ok(line_exists($output, qr|font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1|), 'font directive unchanged');
+
+$input = <<EOT;
+    floating_Modifier Mod1
+    focus_follows_mouse true
+    ipc-socket /tmp/i3-ipc.sock
+    ipc_socket /tmp/i3-ipc.sock
+    exec /usr/bin/i3
+    set stuff Mod1
+    assign "XTerm" → 3
+    assign "XTerm" → ~5
+    client.focused #2F343A #900000 #FFFFFF
+    client.focused_inactive #FF0000 #FF0000 #FF0000
+    client.unfocused #00FF00 #00FF00 #00FF00
+    client.urgent #0000FF #0000FF #0000FF
+EOT
+
+$output = migrate_config($input);
+ok(line_exists($output, qr|^floating_Modifier Mod1$|), 'floating_modifier unchanged');
+ok(line_exists($output, qr|^focus_follows_mouse true$|), 'focus_follows_mouse unchanged');
+ok(line_exists($output, qr|^ipc-socket /tmp/i3-ipc.sock$|), 'ipc-socket unchanged');
+ok(line_exists($output, qr|^ipc_socket /tmp/i3-ipc.sock$|), 'ipc_socket unchanged');
+ok(line_exists($output, qr|^exec /usr/bin/i3|), 'exec unchanged');
+ok(line_exists($output, qr|^set stuff Mod1|), 'set unchanged');
+ok(line_exists($output, qr|^assign "XTerm" → 3|), 'assign unchanged');
+ok(line_exists($output, qr|^assign "XTerm" → ~5|), 'assign unchanged');
+ok(line_exists($output, qr|^client\.focused #2F343A #900000 #FFFFFF$|), 'client.focused unchanged');
+ok(line_exists($output, qr|^client\.focused_inactive #FF0000 #FF0000 #FF0000$|), 'client.focused_inactive unchanged');
+ok(line_exists($output, qr|^client\.unfocused #00FF00 #00FF00 #00FF00$|), 'client.unfocused unchanged');
+ok(line_exists($output, qr|^client\.urgent #0000FF #0000FF #0000FF$|), 'client.urgent unchanged');
+
+#####################################################################
+# check whether the bar colors get removed properly
+#####################################################################
+
+$input = <<EOT;
+    bar.focused #FFFF00 #FFFF00 #FFFF00
+    bar.unfocused #FFFF00 #FFFF00 #FFFF00
+    bar.urgent #FFFF00 #FFFF00 #FFFF00
+EOT
+
+$output = migrate_config($input);
+ok(!line_exists($output, qr|^bar\.|), 'no bar. lines');
+ok(line_exists($output, qr|^#.*REMOVED bar|), 'note bar. removed');
+
+
+#####################################################################
+# check whether the other directives get converted correctly
+#####################################################################
+
+$input = <<EOT;
+    new_container stacking
+    workspace_bar no
+    new_window bb
+EOT
+
+$output = migrate_config($input);
+ok(line_exists($output, qr|^workspace_layout stacking$|), 'new_container changed');
+ok(line_exists($output, qr|REMOVED workspace_bar|), 'workspace_bar removed');
+ok(!line_exists($output, qr|^workspace_bar|), 'no workspace_bar in the output');
+ok(line_exists($output, qr|^new_window borderless$|), 'new_window changed');
+
+#####################################################################
+# check whether new_window's parameters get changed correctly
+#####################################################################
+
+$output = migrate_config('new_window bb');
+ok(line_exists($output, qr|^new_window borderless$|), 'new_window bb changed');
+
+$output = migrate_config('new_window bn');
+ok(line_exists($output, qr|^new_window normal$|), 'new_window bn changed');
+
+$output = migrate_config('new_window bp');
+ok(line_exists($output, qr|^new_window 1pixel$|), 'new_window bp changed');
+
+#####################################################################
+# check that some commands remain untouched
+#####################################################################
+
+$input = <<EOT;
+    bindsym Mod1+s exec /usr/bin/urxvt
+    bindsym Mod1+s mark foo
+    bindsym Mod1+s restart
+    bindsym Mod1+s reload
+    bindsym Mod1+s exit
+    bindsym Mod1+s stack-limit cols 2
+    bindsym Mod1+s stack-limit rows 3
+    bind Mod1+c exec /usr/bin/urxvt
+    mode "asdf" {
+        bind 36 mode default
+    }
+EOT
+
+$output = migrate_config($input);
+ok(line_exists($output, qr|^bindsym Mod1\+s exec /usr/bin/urxvt$|), 'exec unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s mark foo$|), 'mark unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s restart$|), 'restart unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s reload$|), 'reload unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s exit$|), 'exit unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s stack-limit cols 2$|), 'stack-limit unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+s stack-limit rows 3$|), 'stack-limit unchanged');
+ok(line_exists($output, qr|^bindcode Mod1\+c exec /usr/bin/urxvt$|), 'bind changed to bindcode');
+ok(line_exists($output, qr|^mode "asdf" {$|), 'mode asdf unchanged');
+ok(line_exists($output, qr|^bindcode 36 mode default$|), 'mode default unchanged');
+ok(line_exists($output, qr|^}$|), 'closing mode bracket still there');
+
+#####################################################################
+# check the simple command replacements
+#####################################################################
+
+$input = <<EOT;
+    bindsym Mod1+s s
+    bindsym Mod1+s d
+    bindsym Mod1+s T
+
+    bindsym Mod1+s f
+    bindsym Mod1+s fg
+
+    bindsym Mod1+s t
+
+    bindsym Mod1+s h
+    bindsym Mod1+s j
+    bindsym Mod1+s k
+    bindsym Mod1+s l
+
+    bindsym Mod1+s mh
+    bindsym Mod1+s mj
+    bindsym Mod1+s mk
+    bindsym Mod1+s ml
+
+    bindsym Mod1+s bn
+    bindsym Mod1+s bp
+    bindsym Mod1+s bb
+
+    bindsym Mod1+j wch
+    bindsym Mod1+j wcml
+
+    bindsym Mod1+k kill
+
+    bindsym Mod1+n nw
+    bindsym Mod1+p pw
+EOT
+
+$output = migrate_config($input);
+ok(line_exists($output, qr|^bindsym Mod1\+s layout stacking$|), 's replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s layout default$|), 'd replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s layout tabbed$|), 'T replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s fullscreen$|), 'f replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s fullscreen global$|), 'fg replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s focus mode_toggle$|), 't replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s focus left$|), 'h replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s focus down$|), 'j replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s focus up$|), 'k replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s focus right$|), 'l replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s move left$|), 'mh replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s move down$|), 'mj replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s move up$|), 'mk replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s move right$|), 'ml replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s border normal$|), 'bn replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s border 1pixel$|), 'bp replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+s border borderless$|), 'bb replaced');
+ok(line_exists($output, qr|^#.*with container.*obsolete.*wch$|), 'with container removed');
+ok(line_exists($output, qr|^#.*with container.*obsolete.*wcml$|), 'with container removed');
+ok(line_exists($output, qr|^bindsym Mod1\+k kill$|), 'kill unchanged');
+ok(line_exists($output, qr|^bindsym Mod1\+n workspace next$|), 'nw replaced');
+ok(line_exists($output, qr|^bindsym Mod1\+p workspace prev$|), 'pw replaced');
+
+#####################################################################
+# check more advanced replacements
+#####################################################################
+
+$input = <<EOT;
+    bindsym Mod1+s goto foo
+EOT
+
+$output = migrate_config($input);
+ok(line_exists($output, qr|^bindsym Mod1\+s \[con_mark="foo"\] focus$|), 'goto replaced');
+
+#####################################################################
+# check whether focus's parameters get changed correctly
+#####################################################################
+
+$output = migrate_config('bindsym Mod1+f focus 3');
+ok(line_exists($output, qr|^#.*focus.*obsolete.*focus 3$|), 'focus [number] gone');
+
+$output = migrate_config('bindsym Mod1+f focus floating');
+ok(line_exists($output, qr|^bindsym Mod1\+f focus floating$|), 'focus floating unchanged');
+
+$output = migrate_config('bindsym Mod1+f focus tiling');
+ok(line_exists($output, qr|^bindsym Mod1\+f focus tiling$|), 'focus tiling unchanged');
+
+$output = migrate_config('bindsym Mod1+f focus ft');
+ok(line_exists($output, qr|^bindsym Mod1\+f focus mode_toggle$|), 'focus ft changed');
+
+#####################################################################
+# check whether resize's parameters get changed correctly
+#####################################################################
+
+$output = migrate_config('bindsym Mod1+f resize left +10');
+ok(line_exists($output, qr|^bindsym Mod1\+f resize grow left 10 px$|), 'resize left changed');
+
+$output = migrate_config('bindsym Mod1+f resize top -20');
+ok(line_exists($output, qr|^bindsym Mod1\+f resize shrink top 20 px$|), 'resize top changed');
+
+$output = migrate_config('bindsym Mod1+f resize right -20');
+ok(line_exists($output, qr|^bindsym Mod1\+f resize shrink right 20 px$|), 'resize right changed');
+
+$output = migrate_config('bindsym Mod1+f resize bottom +23');
+ok(line_exists($output, qr|^bindsym Mod1\+f resize grow bottom 23 px$|), 'resize bottom changed');
+
+#####################################################################
+# check whether jump's parameters get changed correctly
+#####################################################################
+
+$output = migrate_config('bindsym Mod1+f jump 3');
+ok(line_exists($output, qr|^#.*obsolete.*jump 3$|), 'jump to workspace removed');
+
+$output = migrate_config('bindsym Mod1+f jump 3 4 5');
+ok(line_exists($output, qr|^#.*obsolete.*jump 3 4 5$|), 'jump to workspace + col/row removed');
+
+$output = migrate_config('bindsym Mod1+f jump "XTerm"');
+ok(line_exists($output, qr|^bindsym Mod1\+f \[class="XTerm"\] focus$|), 'jump changed');
+
+$output = migrate_config('bindsym Mod1+f jump "XTerm/irssi"');
+ok(line_exists($output, qr|^bindsym Mod1\+f \[class="XTerm" title="irssi"\] focus$|), 'jump changed');
+
+#####################################################################
+# check whether workspace commands are handled correctly
+#####################################################################
+
+$output = migrate_config('workspace 3 output VGA-1');
+ok(line_exists($output, qr|^workspace 3 output VGA-1$|), 'workspace assignment unchanged');
+
+$output = migrate_config('workspace 3 work');
+ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
+ok(line_exists($output, qr|#.*workspace name.*bindings|), 'note present');
+
+$input = <<EOT;
+    workspace 3 work
+    bindsym Mod1+3 3
+EOT
+$output = migrate_config($input);
+ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
+ok(line_exists($output, qr|^bindsym Mod1\+3 workspace work|), 'named workspace in bindings');
+
+$output = migrate_config('bindsym Mod1+3 3');
+ok(line_exists($output, qr|^bindsym Mod1\+3 workspace 3|), 'workspace changed');
+
+$output = migrate_config('bindsym Mod1+3 m3');
+ok(line_exists($output, qr|^bindsym Mod1\+3 move workspace 3|), 'move workspace changed');
+
+$input = <<EOT;
+    workspace 3 work
+    bindsym Mod1+3 m3
+EOT
+$output = migrate_config($input);
+ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
+ok(line_exists($output, qr|^bindsym Mod1\+3 move workspace work|), 'move to named workspace in bindings');
+
+#####################################################################
+# check whether an i3bar call is added if the workspace bar bar was enabled
+#####################################################################
+
+$output = migrate_config('');
+ok(line_exists($output, qr|i3bar|), 'i3bar added');
+
+$output = migrate_config('workspace_bar enable');
+ok(line_exists($output, qr|i3bar|), 'i3bar added');
+
+$output = migrate_config('workspace_bar no');
+ok(!line_exists($output, qr|i3bar|), 'no i3bar added');
+
+done_testing();