.local
, .cache
, and .config
are part of the FreeDesktop Base Directory Specification. They should not actually be hard-coded but instead use the environment variables (i.e. $XDG_DATA_HOME
, $XDG_CACHE_HOME
, and $XDG_CONFIG_HOME
). There are GLib and Python wrappers for the spec that may be helpful as well. Here's an example in Python:
>>> import xdg.BaseDirectory
>>> print xdg.BaseDirectory.xdg_data_home
/home/andrew/.local/share
>>> print xdg.BaseDirectory.xdg_config_home
/home/andrew/.config
>>> print xdg.BaseDirectory.xdg_cache_home
/home/andrew/.cache
.gnome
and .gnome2
are indeed deprecated and should not be used. These were used by libgnome's gnome-config module.
.gconf
does indeed contain the settings that gconf-editor
accesses as xml files. For instance, compare the output of the following commands:
gconftool -a /desktop/gnome/applications/browser
cat ~/.gconf/desktop/gnome/applications/browser/%gconf.xml
Ubuntu has changed since other answers to this question were written.
Keybindings have moved from gconf to dconf. Gconf stores its data in xml files and was accessed by gconf-editor
and gconf-tool2
. Dconf stores its data in a binary format and is accessed by dconf-editor
and gsettings
.
The number of places that keybindings are stored is reduced. There is now a centralized dconf path to store window manager keybindings (org.gnome.desktop.wm.keybindings
). There are mapping files in the directory /usr/share/gnome-control-center/keybindings/
that show how these are applied based on the window manager you are actually using (compiz or metacity).
A second set of non-window-manager related key bindings is stored in the dconf path org.gnome.settings-daemon.plugins.media-keys
There is a third set of keybindings related to power buttons that is stored in the dconf path org.gnome.settings-daemon.plugins.power
. There is currently a bug in the GUI that lets you configure keybindings. It doesn't know about these settings. I have a "sleep" button on my keyboard. If I want to reassign it to other functionality, I have to disable the setting in org.gnome.settings-daemon.plugins.power
manually. The GUI doesn't do it for me (although it assigns the new functionality just fine).
The other wrinkle is custom key bindings. These are stored in dconf using relocatable schema. Its done this way because there are an arbitrary number of them. A reasonable approach, but it makes listing or modifying them via the command line harder than it should be.
I also found out that the GUI that allows you to assign keybindings is limited in a way that annoys me. The GUI allows exactly ONE keybinding to be assigned to each action. In dconf, you can set an array of bindings for a single action. This is useful to me. For example, I like to have the "close-window" action assigned to the traditonal Alt-F4 as well as to an easier to hit single button on my keybord.
I have written a Perl script to dump all the keybindings to a csv file, or restore them from the csv file. For example to dump the keybindings you might use:
./keybindings.pl -e /tmp/keys.csv
and to restore them you might use:
./keybindings.pl -i /tmp/keys.csv
#!/usr/bin/perl
use strict;
my $action = '';
my $filename = '-';
for my $arg (@ARGV){
if ($arg eq "-e" or $arg eq "--export"){
$action = 'export';
} elsif ($arg eq "-i" or $arg eq "--import"){
$action = 'import';
} elsif ($arg eq "-h" or $arg eq "--help"){
print "Import and export keybindings\n";
print " -e, --export <filename>\n";
print " -i, --import <filename>\n";
print " -h, --help\n";
exit;
} elsif ($arg =~ /^\-/){
die "Unknown argument $arg";
} else {
$filename = $arg;
if (!$action){
if ( -e $filename){
$action='import';
} else {
$action='export';
}
}
}
}
$action='export' if (!$action);
if ($action eq 'export'){
&export();
} else {
&import();
}
sub export(){
my $gsettingsFolders = [
['org.gnome.desktop.wm.keybindings','.'],
['org.gnome.settings-daemon.plugins.power','button'],
['org.gnome.settings-daemon.plugins.media-keys','.'],
];
my $customBindings = [
];
$filename = ">$filename";
open (my $fh, $filename) || die "Can't open file $filename: $!";
for my $folder (@$gsettingsFolders){
my @keylist = split(/\n/, `gsettings list-recursively $folder->[0]`);
foreach my $line (@keylist){
if ($line =~ /^([^ ]+) ([^ ]+)(?: \@[a-z]+)? (.*)/){
my ($path, $name, $value) = ($1,$2,$3);
if ($name eq "custom-keybindings"){
$value =~ s/[\[\]\' ]//g;
my @c = split(/,/, $value);
$customBindings = \@c;
} elsif ($name =~ /$folder->[1]/){
if ($value =~ /^\[|\'/){
if ($value =~ /^\[\'(?:disabled)?\'\]$/){
$value = '[]';
}
print $fh "$path\t$name\t$value\n";
}
}
} else {
die "Could note parse $line";
}
}
}
for my $folder (@$customBindings){
my $gs = `gsettings list-recursively org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:$folder`;
my ($binding) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding binding (\'[^\n]+\')/g;
my ($command) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding command (\'[^\n]+\')/g;
my ($name) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding name (\'[^\n]+\')/g;
$command =~ s/\"/\\\"/g;
$command =~ s/^'(.*)'$/$1/g;
$command =~ s/\'/\'\\\'\'/g;
$command = "\'$command\'";
print $fh "custom\t$name\t$command\t$binding\n"
}
close($fh);
}
sub import(){
$filename = "<$filename";
open (my $fh, $filename) || die "Can't open file $filename: $!";
my $customcount=0;
while (my $line = <$fh>){
chomp $line;
if ($line){
my @v = split(/\t/, $line);
if (@v[0] eq 'custom'){
my ($custom, $name, $command, $binding) = @v;
print "Installing custom keybinding: $name\n";
print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ name \"$name\"`;
print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ command \"$command\"`;
print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ binding \"$binding\"`;
$customcount++;
} else {
my ($path, $name, $value) = @v;
print "Importing $path $name\n";
print `gsettings set \"$path\" \"$name\" \"$value\"`;
}
}
}
if ($customcount > 0){
my $customlist = "";
for (my $i=0; $i<$customcount; $i++){
$customlist .= "," if ($customlist);
$customlist .= "'/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$i/'";
}
$customlist = "[$customlist]";
print "Importing list of custom keybindings.\n";
print `gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings \"$customlist\"`;
}
close($fh);
}
This includes the fix by user2589537 to allow custom commands with quotes in them.
Best Answer
GNOME Terminal
itself doesn't provide such an option, so you have to manually operate on its database.Beginning with version 3.8 it uses
GSettings
, which in turn (at least on Linux systems) usesdconf
. It would probably be more elegant to go with thegsettings
tool. Unfortunately I couldn't figure out how to dump all the relevant data there, let alone restore them. So let's usedconf
.Based on this article, you can dump your settings using:
Reset (wipe out) the settings before loading a new one (probably not really required):
Load the saved settings:
Disclaimer: I haven't tested the restore steps. I recommend that before the reset/load operations you back up your entire dconf database, which is stored in the single file
~/.config/dconf/user
, using a simple standard filesystem copy operation (as opposed to some dconf command). In case of problem you can restore it just as easily (maybe from another terminal emulator or the Linux console).