From a9cd02088c8d2d1706edb8f7812982d7987e01bd Mon Sep 17 00:00:00 2001 From: Matt Rose Date: Dec 17 2019 02:37:42 +0000 Subject: add python3 support --- diff --git a/python3.patch b/python3.patch new file mode 100644 index 0000000..1490fb2 --- /dev/null +++ b/python3.patch @@ -0,0 +1,13476 @@ +diff -x .bzr -uNr terminator-1.91/.bzrignore python3/.bzrignore +--- terminator-1.91/.bzrignore 1969-12-31 19:00:00.000000000 -0500 ++++ python3/.bzrignore 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,7 @@ ++*.pyc ++terminatorlib/*.pyc ++.project ++.pydevproject ++terminatorlib/meliae ++_trial_temp ++terminatorc +diff -x .bzr -uNr terminator-1.91/debian/changelog python3/debian/changelog +--- terminator-1.91/debian/changelog 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/changelog 2019-10-21 22:58:46.937140000 -0400 +@@ -0,0 +1,368 @@ ++terminator (1.92) trusty; urgency=medium ++ ++ * Temporary upstream version for python3 port -- 1.92 ++ ++ -- Roman Kovtyukh Tue, 27 Aug 2019 07:43:00 +0100 ++ ++terminator (1.91) trusty; urgency=medium ++ ++ * New upstream release of 1.91 ++ ++ -- Steve Boddy Sun, 26 Feb 2017 17:17:00 +0100 ++ ++terminator (1.90) trusty; urgency=medium ++ ++ * Initial GTK3 version packaging ++ ++ -- Steve Boddy Thu, 27 Oct 2016 14:06:00 +0100 ++ ++terminator (0.98~ppa8) wily; urgency=medium ++ ++ * No-change upload for wily ++ ++ -- Bryce Harrington Mon, 21 Sep 2015 22:09:34 -0700 ++ ++terminator (0.98~ppa7) vivid; urgency=medium ++ ++ * No-change upload for vivid ++ ++ -- Bryce Harrington Mon, 21 Sep 2015 22:08:58 -0700 ++ ++terminator (0.98~ppa6) trusty; urgency=medium ++ ++ * copyright: Change upstream maintainer to Stephen Boddy ++ ++ -- Bryce Harrington Sun, 20 Sep 2015 14:21:38 -0700 ++ ++terminator (0.98) precise; urgency=medium ++ ++ * New upstream release of 0.98. Remaining changes: ++ + Add missing dependency on psutil to check for IBus running. ++ + Workaround debian compression of font files. ++ + Add terminator.wrapper to fix blurry/incorrect icons in task switchers. ++ * Sync up with Debian packaging ++ + Update homepage ++ + Revise copyright file ++ + Use canonical URIs for Vcs-* fields ++ + Update regular expression in watch ++ + Bump Standards-Version to 3.9.5 (no changes). ++ + Migrate from cdbs to dh. ++ + Add python-dbus to Depends. ++ + Bump Standards Version to 3.9.4. ++ + Bump debhelper version to 9. ++ + Bump compat level 5 to 9. ++ ++ -- Bryce Harrington Sat, 19 Sep 2015 18:41:57 -0700 ++ ++terminator (0.97~ppa3) saucy; urgency=low ++ ++ * No-change upload for saucy ++ ++ -- Chris Jones Tue, 30 Apr 2013 10:10:49 +0100 ++ ++terminator (0.97~ppa2) raring; urgency=low ++ ++ * No-change upload for raring ++ ++ -- Chris Jones Tue, 30 Apr 2013 10:09:08 +0100 ++ ++terminator (0.97~ppa1) quantal; urgency=low ++ ++ * No-change upload for quantal ++ ++ -- Chris Jones Tue, 30 Apr 2013 10:08:19 +0100 ++ ++terminator (0.97) precise; urgency=low ++ ++ * New upstream release of 0.97 ++ ++ -- Chris Jones Tue, 30 Apr 2013 08:54:00 +0100 ++ ++terminator (0.96ppa6) oneiric; urgency=low ++ ++ * No-change rebuild for oneiric PPA ++ ++ -- Chris Jones Wed, 28 Sep 2011 09:31:37 +0100 ++ ++terminator (0.96ppa5) lucid; urgency=low ++ ++ * No-change rebuild for lucid PPA ++ ++ -- Chris Jones Wed, 28 Sep 2011 09:31:09 +0100 ++ ++terminator (0.96ppa4) maverick; urgency=low ++ ++ * No-change rebuild for maverick PPA ++ ++ -- Chris Jones Wed, 28 Sep 2011 09:30:25 +0100 ++ ++terminator (0.96ppa3) natty; urgency=low ++ ++ * Update packaging to include remotinator ++ ++ -- Chris Jones Wed, 28 Sep 2011 09:24:02 +0100 ++ ++terminator (0.96ppa2) natty; urgency=low ++ ++ * No-change rebuild for natty ++ ++ -- Chris Jones Fri, 23 Sep 2011 22:02:58 +0100 ++ ++terminator (0.96ppa1) maverick; urgency=low ++ ++ * No-change rebuild for maverick ++ ++ -- Chris Jones Fri, 23 Sep 2011 22:02:02 +0100 ++ ++terminator (0.96) lucid; urgency=low ++ ++ * New upstream release of 0.96 ++ ++ -- Chris Jones Fri, 23 Sep 2011 21:44:38 +0100 ++ ++terminator (0.95ppa2) karmic; urgency=low ++ ++ * No-change rebuild for karmic ++ ++ -- Chris Jones Tue, 24 Aug 2010 22:24:59 +0100 ++ ++terminator (0.95ppa1) maverick; urgency=low ++ ++ * No-change rebuild for maverick ++ ++ -- Chris Jones Tue, 24 Aug 2010 22:24:20 +0100 ++ ++terminator (0.95) lucid; urgency=low ++ ++ * New upstream release of 0.95 ++ ++ -- Chris Jones Tue, 24 Aug 2010 21:42:51 +0100 ++ ++terminator (0.94) lucid; urgency=low ++ ++ * New upstream release of 0.94 ++ ++ -- Chris Jones Sun, 04 Jul 2010 18:48:52 +0100 ++ ++terminator (0.93ppa2) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Thu, 15 Apr 2010 21:16:00 +0100 ++ ++terminator (0.93ppa1) lucid; urgency=low ++ ++ * New upstream release of 0.93 ++ ++ -- Chris Jones Thu, 15 Apr 2010 21:15:18 +0100 ++ ++terminator (0.92ppa2) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Wed, 07 Apr 2010 22:42:51 +0100 ++ ++terminator (0.92ppa1) lucid; urgency=low ++ ++ * Nochange rebuild for lucid ++ ++ -- Chris Jones Wed, 07 Apr 2010 22:41:19 +0100 ++ ++terminator (0.92) lucid; urgency=low ++ ++ * New upstream release of 0.92 ++ ++ -- Chris Jones Wed, 07 Apr 2010 21:36:56 +0100 ++ ++terminator (0.91ppa4) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Wed, 31 Mar 2010 22:09:52 +0100 ++ ++terminator (0.91ppa3) lucid; urgency=low ++ ++ * Drop in one more fix ++ ++ -- Chris Jones Wed, 31 Mar 2010 22:09:16 +0100 ++ ++terminator (0.91ppa2) lucid; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Wed, 31 Mar 2010 10:58:13 +0100 ++ ++terminator (0.91ppa1) lucid; urgency=low ++ ++ * New upstream release of 0.91 ++ ++ -- Chris Jones Wed, 31 Mar 2010 10:55:33 +0100 ++ ++terminator (0.90ppa3) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Tue, 30 Mar 2010 23:56:37 +0100 ++ ++terminator (0.90ppa2) lucid; urgency=low ++ ++ * Fix a stupid release bug ++ ++ -- Chris Jones Tue, 30 Mar 2010 23:55:39 +0100 ++ ++terminator (0.90ppa1) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Tue, 30 Mar 2010 23:04:32 +0100 ++ ++terminator (0.90) lucid; urgency=low ++ ++ * Upstream release of 0.90 ++ ++ -- Chris Jones Tue, 30 Mar 2010 22:51:21 +0100 ++ ++terminator (0.90-beta3ppa1) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Mon, 15 Mar 2010 20:19:10 +0000 ++ ++terminator (0.90-beta3) lucid; urgency=low ++ ++ * Third upstream pre-release ++ ++ -- Chris Jones Mon, 15 Mar 2010 20:17:53 +0000 ++ ++terminator (0.90-beta2ppa1) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Tue, 09 Feb 2010 21:46:24 +0000 ++ ++terminator (0.90-beta2) lucid; urgency=low ++ ++ * Second upstream pre-release ++ ++ -- Chris Jones Tue, 09 Feb 2010 21:45:12 +0000 ++ ++terminator (0.90-beta1ppa1) karmic; urgency=low ++ ++ * Nochange rebuild for karmic ++ ++ -- Chris Jones Fri, 05 Feb 2010 00:23:39 +0000 ++ ++terminator (0.90-beta1) lucid; urgency=low ++ ++ * New upstream pre-release ++ ++ -- Chris Jones Tue, 05 Jan 2010 09:56:27 +0000 ++ ++terminator (0.14) karmic; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Thu, 03 Dec 2009 12:54:57 +0000 ++ ++terminator (0.13) karmic; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Fri, 29 May 2009 21:51:09 +0200 ++ ++terminator (0.12) intrepid; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Thu, 15 Jan 2009 00:20:34 +0000 ++ ++terminator (0.11) intrepid; urgency=low ++ ++ * New upstream release. ++ ++ -- Chris Jones Fri, 19 Sep 2008 18:28:54 +0100 ++ ++terminator (0.10) hardy; urgency=low ++ ++ * New upstream release. ++ ++ -- Chris Jones Wed, 27 Aug 2008 01:34:27 +0100 ++ ++terminator (0.9) hardy; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Mon, 07 Jul 2008 22:56:35 +0100 ++ ++terminator (0.9~rc3) hardy; urgency=low ++ ++ * Soyuz hates me. ++ ++ -- Chris Jones Sun, 06 Jul 2008 17:13:10 +0100 ++ ++terminator (0.9~rc2) hardy; urgency=low ++ ++ * Second and hopefully last release candidate for Terminator 0.9 ++ ++ -- Chris Jones Sun, 06 Jul 2008 15:40:02 +0100 ++ ++terminator (0.9~rc1-0) hardy; urgency=low ++ ++ * First release candidate for 0.9 ++ ++ -- Chris Jones Thu, 03 Jul 2008 23:19:09 +0100 ++ ++terminator (0.9~beta4-0) hardy; urgency=low ++ ++ * Improve the previous fix ++ ++ -- Chris Jones Fri, 20 Jun 2008 11:28:44 +0100 ++ ++terminator (0.9~beta3-0) hardy; urgency=low ++ ++ * New beta build to fix LP #241563 ++ ++ -- Chris Jones Fri, 20 Jun 2008 11:03:25 +0100 ++ ++terminator (0.9~beta2-0) hardy; urgency=low ++ ++ * Add some more debugging to spawn_child to track down bug 241563 ++ ++ -- Chris Jones Fri, 20 Jun 2008 09:39:38 +0100 ++ ++terminator (0.9~beta1-0.1) hardy; urgency=low ++ ++ * New beta snapshot ++ ++ -- Chris Jones Thu, 19 Jun 2008 11:38:11 +0100 ++ ++terminator (0.9~beta1-0) hardy; urgency=low ++ ++ * New upstream release. ++ ++ -- Nicolas Valcárcel Wed, 18 Jun 2008 11:24:22 -0500 ++ ++terminator (0.8.1-0ubuntu1) hardy; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Sun, 17 Feb 2008 01:45:37 +0000 ++ ++terminator (0.8-0ubuntu1) hardy; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Thu, 14 Feb 2008 00:19:33 +0000 ++ ++terminator (0.7.1-0ubuntu1) hardy; urgency=low ++ ++ * New upstream release ++ ++ -- Chris Jones Fri, 08 Feb 2008 00:34:27 +0000 ++ ++terminator (0.7-0ubuntu1) hardy; urgency=low ++ ++ * Packaging work for initial inclusion in Ubuntu. (LP: #180692) ++ ++ -- Chris Jones Wed, 02 Jan 2008 22:50:18 +0000 ++ +diff -x .bzr -uNr terminator-1.91/debian/compat python3/debian/compat +--- terminator-1.91/debian/compat 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/compat 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1 @@ ++9 +diff -x .bzr -uNr terminator-1.91/debian/control python3/debian/control +--- terminator-1.91/debian/control 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/control 2019-10-21 22:58:46.937140000 -0400 +@@ -0,0 +1,44 @@ ++Source: terminator ++Section: misc ++Priority: optional ++Maintainer: Nicolas Valcárcel Scerpella ++Uploaders: Rudy Godoy Guillén , ++ Python Applications Packaging Team , ++ Julián Moreno Patiño ++Build-Depends: debhelper (>=11~), ++ intltool, ++ dh-python, ++ python3-all, ++ python3-gi-cairo, ++ gir1.2-gtk-3.0, ++ gir1.2-vte-2.91, ++ python3-configobj ++X-Python-Version: >= 3.2 ++Standards-Version: 4.1.4 ++Vcs-Svn: svn://anonscm.debian.org/python-apps/packages/terminator/trunk/ ++Vcs-Browser: http://anonscm.debian.org/viewvc/python-apps/packages/terminator/trunk/ ++Homepage: http://gnometerminator.blogspot.com/p/introduction.html ++ ++Package: terminator ++Architecture: all ++Depends: gconf2, ++ gir1.2-gconf-2.0, ++ gir1.2-keybinder-3.0, ++ libdbus-1-3, ++ libgtk-3-0, ++ libnotify4, ++ gir1.2-vte-2.91, ++ python3-psutil, ++ python3-gi-cairo, ++ python3-configobj, ++ ${misc:Depends}, ++ ${python3:Depends} ++Provides: x-terminal-emulator ++Recommends: xdg-utils ++Description: multiple GNOME terminals in one window ++ Terminator is a little project to produce an efficient way of ++ filling a large area of screen space with terminals. ++ . ++ The user can have multiple terminals in one window and use ++ key bindings to switch between them. See the manpage for ++ details. +diff -x .bzr -uNr terminator-1.91/debian/copyright python3/debian/copyright +--- terminator-1.91/debian/copyright 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/copyright 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,48 @@ ++Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ ++Upstream-Name: terminator ++Upstream-Contact: Stephen Boddy ++Source: https://launchpad.net/terminator/+download ++ ++Files: * ++Copyright: Chris Jones and others ++ 2006-2011 Chris Jones ++ 2008 Thomas Hurst ++ 2010 Julien Nicoulaud ++ 2006-2010 Emmanuel Bretelle chantra@debuntu.org ++ 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa ++License: GPL-2.0 ++ ++Files: po/* ++Copyright: 2008-2011 Rosetta Contributors and Canonical Ltd ++ 2007 Nicolas Valcárcel ++ 2008 Cris Grada ++ 2010 Vytautas Bačiulis ++ 2008 Thomas Meire ++ 2009 Lucian Adrian Grijincu ++License: GPL-2.0 ++ ++Files: doc/terminator_config.5 ++Copyright: 2008 Nicolas Valcarcel ++License: GPL-2.0 ++ ++Files: debian/* ++Copyright: 2007 Chris Jones ++ 2008-2012 Nicolas Valcárcel Scerpella ++ 2012-2014 Julián Moreno Patiño ++License: GPL-2.0 ++ ++License: GPL-2.0 ++ This program is free software; you can redistribute it ++ and/or modify it under the terms of the GNU General Public ++ License as published by the Free Software Foundation, version ++ 2 of the License. ++ . ++ This program is distributed in the hope that it will be ++ useful, but WITHOUT ANY WARRANTY; without even the implied ++ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ++ PURPOSE. See the GNU General Public License for more ++ details. ++ . ++ On Debian systems, the full text of the GNU General Public ++ License version 2 can be found in the file ++ `/usr/share/common-licenses/GPL-2' +diff -x .bzr -uNr terminator-1.91/debian/docs python3/debian/docs +--- terminator-1.91/debian/docs 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/docs 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1 @@ ++README +diff -x .bzr -uNr terminator-1.91/debian/README.source python3/debian/README.source +--- terminator-1.91/debian/README.source 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/README.source 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,4 @@ ++This package uses CDBS simple patchsys. dpkg-source -x does produce source ++ready for building with dpkg-buildpackage. It does not procude source ready ++for editing. To edit or update a patch, use cdbs-edit-patch. ++See cdbs-edit-patch(1) manual page for details. +diff -x .bzr -uNr terminator-1.91/debian/rules python3/debian/rules +--- terminator-1.91/debian/rules 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/rules 2019-10-21 22:58:46.937140000 -0400 +@@ -0,0 +1,25 @@ ++#!/usr/bin/make -f ++# -*- makefile -*- ++#export DH_VERBOSE=1 ++ ++%: ++ dh $@ --with python3 --buildsystem=pybuild ++ ++override_dh_auto_install: ++ python3 setup.py \ ++ --without-icon-cache \ ++ install \ ++ --install-lib=usr/share/terminator/ \ ++ --install-data=usr/ \ ++ --install-scripts=usr/share/terminator/ \ ++ --root=$(CURDIR)/debian/terminator/ \ ++ --no-compile -O0 ++ ++override_dh_installchangelogs: ++ dh_installchangelogs ChangeLog ++ ++override_dh_clean: ++ rm -rf build/ ++ rm -f data/terminator.desktop ++ rm -f po/.intltool-merge-cache ++ find . -name '*.pyc' -delete +diff -x .bzr -uNr terminator-1.91/debian/source/format python3/debian/source/format +--- terminator-1.91/debian/source/format 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/source/format 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1 @@ ++3.0 (quilt) +diff -x .bzr -uNr terminator-1.91/debian/terminator.links python3/debian/terminator.links +--- terminator-1.91/debian/terminator.links 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/terminator.links 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1 @@ ++/usr/share/terminator/terminator /usr/bin/terminator +diff -x .bzr -uNr terminator-1.91/debian/terminator.postinst python3/debian/terminator.postinst +--- terminator-1.91/debian/terminator.postinst 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/terminator.postinst 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,17 @@ ++#!/bin/sh ++ ++set -e ++ ++if [ "$1" = "configure" ]; then ++ # Ensure the old alternative is removed ++ update-alternatives --remove terminator /usr/bin/terminator || true ++ update-alternatives --remove x-terminal-emulator /usr/bin/terminator ++ ++ # Add an alternative for x-terminal-emulator ++ update-alternatives --install /usr/bin/x-terminal-emulator \ ++ x-terminal-emulator /usr/bin/terminator.wrapper 50 \ ++ --slave /usr/share/man/man1/x-terminal-emulator.1.gz \ ++ x-terminal-emulator.1.gz /usr/share/man/man1/terminator.1.gz ++fi ++ ++#DEBHELPER# +diff -x .bzr -uNr terminator-1.91/debian/terminator.preinst python3/debian/terminator.preinst +--- terminator-1.91/debian/terminator.preinst 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/terminator.preinst 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,9 @@ ++#!/bin/sh ++ ++set -e ++ ++if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt 0.13+ds1; then ++ pycentral pkgremove terminator ++fi ++ ++#DEBHELPER# +diff -x .bzr -uNr terminator-1.91/debian/terminator.prerm python3/debian/terminator.prerm +--- terminator-1.91/debian/terminator.prerm 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/terminator.prerm 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,12 @@ ++#!/bin/sh ++ ++set -e ++ ++if [ "$1" = remove ]; then ++ update-alternatives --remove terminator /usr/bin/terminator || true ++ update-alternatives --remove x-terminal-emulator /usr/bin/terminator ++ update-alternatives --remove terminator.wrapper /usr/bin/terminator.wrapper || true ++ update-alternatives --remove x-terminal-emulator /usr/bin/terminator.wrapper ++fi ++ ++#DEBHELPER# +diff -x .bzr -uNr terminator-1.91/debian/watch python3/debian/watch +--- terminator-1.91/debian/watch 1969-12-31 19:00:00.000000000 -0500 ++++ python3/debian/watch 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,3 @@ ++version=3 ++opts=dversionmangle=s/\+ds\d+$// \ ++http://launchpad.net/terminator/+download .*/terminator[:?_|-](.+)\.tar\.gz +diff -x .bzr -uNr terminator-1.91/doc/terminator.1 python3/doc/terminator.1 +--- terminator-1.91/doc/terminator.1 2017-02-26 12:45:29.000000000 -0500 ++++ python3/doc/terminator.1 2019-08-19 19:25:15.963479000 -0400 +@@ -61,9 +61,6 @@ + .B \-r, \-\-role=ROLE + Set a custom WM_WINDOW_ROLE property on the window + .TP +-.B \-c, \-\-classname=CLASSNAME +-Set a custom name (WM_CLASS) property on the window +-.TP + .B \-l, \-\-layout=LAYOUT + Start Terminator with a specific layout. The argument here is the name + of a saved layout. +diff -x .bzr -uNr terminator-1.91/INSTALL python3/INSTALL +--- terminator-1.91/INSTALL 2017-02-26 12:45:29.000000000 -0500 ++++ python3/INSTALL 2019-10-21 22:58:46.937140000 -0400 +@@ -7,9 +7,9 @@ + If you don't have this option, please make sure you satisfy Terminator's + dependencies yourself: + +- * Python 2.5+, 2.6 recommended: ++ * Python 3.2+, 3.7 recommended: + Debian/Ubuntu: python +- FreeBSD: lang/python26 ++ FreeBSD: lang/python37 + + * Python VTE bindings: + Debian/Ubuntu: python-vte +diff -x .bzr -uNr terminator-1.91/MANIFEST.in python3/MANIFEST.in +--- terminator-1.91/MANIFEST.in 1969-12-31 19:00:00.000000000 -0500 ++++ python3/MANIFEST.in 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,7 @@ ++include AUTHORS ChangeLog COPYING INSTALL README remotinator setup.py terminator terminator.wrapper run_tests ++recursive-include data * ++recursive-include doc * ++recursive-include po * ++recursive-include terminatorlib *.py *.glade *.css ++recursive-include tests *.py ++ +diff -x .bzr -uNr terminator-1.91/PKG-INFO python3/PKG-INFO +--- terminator-1.91/PKG-INFO 2017-02-28 17:10:08.000000000 -0500 ++++ python3/PKG-INFO 1969-12-31 19:00:00.000000000 -0500 +@@ -1,10 +0,0 @@ +-Metadata-Version: 1.0 +-Name: terminator +-Version: 1.91 +-Summary: Terminator, the robot future of terminals +-Home-page: https://gnometerminator.blogspot.com/p/introduction.html +-Author: Chris Jones +-Author-email: cmsj@tenshu.net +-License: GNU GPL v2 +-Description: UNKNOWN +-Platform: UNKNOWN +diff -x .bzr -uNr terminator-1.91/po/af.po python3/po/af.po +--- terminator-1.91/po/af.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/af.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: af\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ar.po python3/po/ar.po +--- terminator-1.91/po/ar.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ar.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ar\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ast.po python3/po/ast.po +--- terminator-1.91/po/ast.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ast.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ast\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/az.po python3/po/az.po +--- terminator-1.91/po/az.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/az.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: az\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/be.po python3/po/be.po +--- terminator-1.91/po/be.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/be.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 +diff -x .bzr -uNr terminator-1.91/po/bg.po python3/po/bg.po +--- terminator-1.91/po/bg.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/bg.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: bg\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/bn.po python3/po/bn.po +--- terminator-1.91/po/bn.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/bn.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: bn\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/bs.po python3/po/bs.po +--- terminator-1.91/po/bs.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/bs.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: bs\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ca.po python3/po/ca.po +--- terminator-1.91/po/ca.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ca.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ca\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ca@valencia.po python3/po/ca@valencia.po +--- terminator-1.91/po/ca@valencia.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ca@valencia.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ca\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ckb.po python3/po/ckb.po +--- terminator-1.91/po/ckb.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ckb.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/cs.po python3/po/cs.po +--- terminator-1.91/po/cs.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/cs.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,44 +8,44 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:32+0000\n" +-"Last-Translator: Zdeněk Kopš \n" ++"PO-Revision-Date: 2017-06-09 21:25+0000\n" ++"Last-Translator: Petr Kubánek \n" + "Language-Team: Czech \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: cs\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "" ++msgstr "Otevřít nové okno" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "" ++msgstr "Otevřít nový panel" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +-msgstr "" ++msgstr "Rozdělit horizontálně" + + #: ../remotinator.py:41 + msgid "Split the current terminal vertically" +-msgstr "" ++msgstr "Rozdělit vertikálně" + + #: ../remotinator.py:42 + msgid "Get a list of all terminals" +-msgstr "" ++msgstr "Zobrazit seznam všech terminálů" + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "" ++msgstr "Získat UUID hlavního okna" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "" ++msgstr "Získat název hlavního okna" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +diff -x .bzr -uNr terminator-1.91/po/da.po python3/po/da.po +--- terminator-1.91/po/da.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/da.po 2019-08-19 19:25:15.963479000 -0400 +@@ -9,13 +9,13 @@ + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" + "PO-Revision-Date: 2015-08-05 12:32+0000\n" +-"Last-Translator: Aputsiaĸ Niels Janussen \n" ++"Last-Translator: Aputsiak Niels Janussen \n" + "Language-Team: Danish \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: da\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/de.po python3/po/de.po +--- terminator-1.91/po/de.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/de.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2017-02-21 03:11+0000\n" +-"Last-Translator: vulpecula \n" ++"PO-Revision-Date: 2017-04-14 08:55+0000\n" ++"Last-Translator: Stephan Woidowski \n" + "Language-Team: German \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-22 06:09+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: de\n" + + #. Command uuid req. Description +@@ -76,7 +76,7 @@ + + #: ../remotinator.py:66 + msgid "Terminal UUID for when not in env var TERMINATOR_UUID" +-msgstr "" ++msgstr "Terminal UUID falls nicht in ev var TERMINATOR_UUID" + + #: ../data/terminator.desktop.in.h:1 ../data/terminator.appdata.xml.in.h:1 + #: ../terminatorlib/plugins/activitywatch.py:84 +@@ -1203,6 +1203,11 @@ + "users. If you have any suggestions, please file wishlist bugs! (see left for " + "the Development link)" + msgstr "" ++"Das Ziel dieses Projekts ist es, ein nützliches Werkzeug zur Einrichtung von " ++"Terminals zu schaffen. Es ist von Programmen wie gnome-multi-term, " ++"quadkonsole, usw. inspiriert, wo der Hauptfokus auf das Arrangieren von " ++"Terminals in Gittern (Tabs sind die meist verbreitete Methode, die " ++"Terminator ebenfalls unterstützt." + + #: ../terminatorlib/preferences.glade.h:153 + msgid "The Manual" +diff -x .bzr -uNr terminator-1.91/po/el.po python3/po/el.po +--- terminator-1.91/po/el.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/el.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: el\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/en_AU.po python3/po/en_AU.po +--- terminator-1.91/po/en_AU.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/en_AU.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,46 +14,46 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "" ++msgstr "Open a new window" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "" ++msgstr "Open a new tab" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +-msgstr "" ++msgstr "Split the current terminal horizontally" + + #: ../remotinator.py:41 + msgid "Split the current terminal vertically" +-msgstr "" ++msgstr "Split the current terminal vertically" + + #: ../remotinator.py:42 + msgid "Get a list of all terminals" +-msgstr "" ++msgstr "Get a list of all terminals" + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "" ++msgstr "Get the UUID of a parent window" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "" ++msgstr "Get the title of a parent window" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +-msgstr "" ++msgstr "Get the UUID of a parent tab" + + #: ../remotinator.py:46 + msgid "Get the title of a parent tab" +-msgstr "" ++msgstr "Get the title of a parent tab" + + #: ../remotinator.py:63 + #, python-format +@@ -62,16 +62,21 @@ + "\n" + "%s" + msgstr "" ++"Run one of the following Terminator DBus commands:\n" ++"\n" ++"%s" + + #: ../remotinator.py:64 + msgid "" + "* These entries require either TERMINATOR_UUID environment var,\n" + " or the --uuid option must be used." + msgstr "" ++"* These entries require either TERMINATOR_UUID environment var,\n" ++" or the --uuid option must be used." + + #: ../remotinator.py:66 + msgid "Terminal UUID for when not in env var TERMINATOR_UUID" +-msgstr "" ++msgstr "Terminal UUID for when not in env var TERMINATOR_UUID" + + #: ../data/terminator.desktop.in.h:1 ../data/terminator.appdata.xml.in.h:1 + #: ../terminatorlib/plugins/activitywatch.py:84 +@@ -87,7 +92,7 @@ + #: ../data/terminator.appdata.xml.in.h:3 + #: ../terminatorlib/preferences.glade.h:149 + msgid "The robot future of terminals" +-msgstr "" ++msgstr "The robot future of terminals" + + #: ../data/terminator.appdata.xml.in.h:4 + msgid "" +@@ -96,6 +101,10 @@ + "terminals in grids (tabs is the most common default method, which Terminator " + "also supports)." + msgstr "" ++"A power-user tool for arranging terminals. It is inspired by programs such " ++"as gnome-multi-term, quadkonsole, etc. in that the main focus is arranging " ++"terminals in grids (tabs is the most common default method, which Terminator " ++"also supports)." + + #: ../data/terminator.appdata.xml.in.h:5 + msgid "" +@@ -104,50 +113,54 @@ + "out in different directions with useful features for sysadmins and other " + "users." + msgstr "" ++"Much of the behavior of Terminator is based on GNOME Terminal, and we are " ++"adding more features from that as time goes by, but we also want to extend " ++"out in different directions with useful features for sysadmins and other " ++"users." + + #: ../data/terminator.appdata.xml.in.h:6 + msgid "Some highlights:" +-msgstr "" ++msgstr "Some highlights:" + + #: ../data/terminator.appdata.xml.in.h:7 + msgid "Arrange terminals in a grid" +-msgstr "" ++msgstr "Arrange terminals in a grid" + + #: ../data/terminator.appdata.xml.in.h:8 + msgid "Tabs" +-msgstr "" ++msgstr "Tabs" + + #: ../data/terminator.appdata.xml.in.h:9 + msgid "Drag and drop re-ordering of terminals" +-msgstr "" ++msgstr "Drag and drop re-ordering of terminals" + + #: ../data/terminator.appdata.xml.in.h:10 + msgid "Lots of keyboard shortcuts" +-msgstr "" ++msgstr "Lots of keyboard shortcuts" + + #: ../data/terminator.appdata.xml.in.h:11 + msgid "Save multiple layouts and profiles via GUI preferences editor" +-msgstr "" ++msgstr "Save multiple layouts and profiles via GUI preferences editor" + + #: ../data/terminator.appdata.xml.in.h:12 + msgid "Simultaneous typing to arbitrary groups of terminals" +-msgstr "" ++msgstr "Simultaneous typing to arbitrary groups of terminals" + + #: ../data/terminator.appdata.xml.in.h:13 + msgid "And lots more..." +-msgstr "" ++msgstr "And lots more..." + + #: ../data/terminator.appdata.xml.in.h:14 + msgid "The main window showing the application in action" +-msgstr "" ++msgstr "The main window showing the application in action" + + #: ../data/terminator.appdata.xml.in.h:15 + msgid "Getting a little crazy with the terminals" +-msgstr "" ++msgstr "Getting a little crazy with the terminals" + + #: ../data/terminator.appdata.xml.in.h:16 + msgid "The preferences window where you can change the defaults" +-msgstr "" ++msgstr "The preferences window where you can change the defaults" + + #: ../terminatorlib/container.py:163 + msgid "Close?" +@@ -323,16 +336,16 @@ + + #: ../terminatorlib/layoutlauncher.glade.h:1 + msgid "Terminator Layout Launcher" +-msgstr "" ++msgstr "Terminator Layout Launcher" + + #: ../terminatorlib/layoutlauncher.glade.h:2 + #: ../terminatorlib/preferences.glade.h:135 + msgid "Layout" +-msgstr "" ++msgstr "Layout" + + #: ../terminatorlib/layoutlauncher.glade.h:3 + msgid "Launch" +-msgstr "" ++msgstr "Launch" + + #: ../terminatorlib/notebook.py:353 + msgid "tab" +@@ -348,7 +361,7 @@ + + #: ../terminatorlib/optionparse.py:52 + msgid "Maximize the window" +-msgstr "" ++msgstr "Maximize the window" + + #: ../terminatorlib/optionparse.py:54 + msgid "Make the window fill the screen" +@@ -404,11 +417,11 @@ + + #: ../terminatorlib/optionparse.py:89 + msgid "Launch with the given layout" +-msgstr "" ++msgstr "Launch with the given layout" + + #: ../terminatorlib/optionparse.py:91 + msgid "Select a layout from a list" +-msgstr "" ++msgstr "Select a layout from a list" + + #: ../terminatorlib/optionparse.py:93 + msgid "Use a different profile as the default" +@@ -440,25 +453,25 @@ + + #: ../terminatorlib/plugins/activitywatch.py:55 + msgid "Watch for _activity" +-msgstr "" ++msgstr "Watch for _activity" + + #: ../terminatorlib/plugins/activitywatch.py:84 + #, python-format + msgid "Activity in: %s" +-msgstr "" ++msgstr "Activity in: %s" + + #: ../terminatorlib/plugins/activitywatch.py:121 + msgid "Watch for _silence" +-msgstr "" ++msgstr "Watch for _silence" + + #: ../terminatorlib/plugins/activitywatch.py:163 + #, python-format + msgid "Silence in: %s" +-msgstr "" ++msgstr "Silence in: %s" + + #: ../terminatorlib/plugins/custom_commands.py:61 + msgid "_Custom Commands" +-msgstr "" ++msgstr "_Custom Commands" + + #. VERIFY FOR GTK3: is this ever false? + #: ../terminatorlib/plugins/custom_commands.py:67 +@@ -484,22 +497,22 @@ + + #: ../terminatorlib/plugins/custom_commands.py:152 + msgid "Enabled" +-msgstr "" ++msgstr "Enabled" + + #: ../terminatorlib/plugins/custom_commands.py:156 + #: ../terminatorlib/preferences.glade.h:137 + msgid "Name" +-msgstr "" ++msgstr "Name" + + #: ../terminatorlib/plugins/custom_commands.py:160 + #: ../terminatorlib/preferences.glade.h:103 + msgid "Command" +-msgstr "" ++msgstr "Command" + + #: ../terminatorlib/plugins/custom_commands.py:174 + #: ../terminatorlib/preferences.glade.h:37 + msgid "Top" +-msgstr "" ++msgstr "Top" + + #: ../terminatorlib/plugins/custom_commands.py:180 + msgid "Up" +@@ -559,23 +572,23 @@ + + #: ../terminatorlib/plugins/logger.py:34 + msgid "Start _Logger" +-msgstr "" ++msgstr "Start _Logger" + + #: ../terminatorlib/plugins/logger.py:37 + msgid "Stop _Logger" +-msgstr "" ++msgstr "Stop _Logger" + + #: ../terminatorlib/plugins/logger.py:67 + msgid "Save Log File As" +-msgstr "" ++msgstr "Save Log File As" + + #: ../terminatorlib/plugins/terminalshot.py:29 + msgid "Terminal _screenshot" +-msgstr "" ++msgstr "Terminal _screenshot" + + #: ../terminatorlib/plugins/terminalshot.py:38 + msgid "Save image" +-msgstr "" ++msgstr "Save image" + + #: ../terminatorlib/preferences.glade.h:1 + msgid "Automatic" +@@ -600,7 +613,7 @@ + + #: ../terminatorlib/preferences.glade.h:6 + msgid "Group" +-msgstr "" ++msgstr "Group" + + #: ../terminatorlib/preferences.glade.h:7 + msgid "None" +@@ -628,7 +641,7 @@ + + #: ../terminatorlib/preferences.glade.h:13 + msgid "Gray on black" +-msgstr "" ++msgstr "Gray on black" + + #: ../terminatorlib/preferences.glade.h:14 + msgid "Green on black" +@@ -648,11 +661,11 @@ + + #: ../terminatorlib/preferences.glade.h:18 + msgid "Solarized light" +-msgstr "" ++msgstr "Solarized light" + + #: ../terminatorlib/preferences.glade.h:19 + msgid "Solarized dark" +-msgstr "" ++msgstr "Solarized dark" + + #: ../terminatorlib/preferences.glade.h:20 + msgid "Gruvbox light" +@@ -676,7 +689,7 @@ + + #: ../terminatorlib/preferences.glade.h:25 + msgid "I-Beam" +-msgstr "" ++msgstr "I-Beam" + + #: ../terminatorlib/preferences.glade.h:26 + msgid "GNOME Default" +@@ -704,131 +717,131 @@ + + #: ../terminatorlib/preferences.glade.h:32 + msgid "Rxvt" +-msgstr "" ++msgstr "Rxvt" + + #: ../terminatorlib/preferences.glade.h:33 + msgid "Solarized" +-msgstr "" ++msgstr "Solarized" + + #: ../terminatorlib/preferences.glade.h:34 + msgid "On the left side" +-msgstr "" ++msgstr "On the left side" + + #: ../terminatorlib/preferences.glade.h:35 + msgid "On the right side" +-msgstr "" ++msgstr "On the right side" + + #: ../terminatorlib/preferences.glade.h:36 + msgid "Disabled" +-msgstr "" ++msgstr "Disabled" + + #: ../terminatorlib/preferences.glade.h:38 + msgid "Bottom" +-msgstr "" ++msgstr "Bottom" + + #: ../terminatorlib/preferences.glade.h:39 + msgid "Left" +-msgstr "" ++msgstr "Left" + + #: ../terminatorlib/preferences.glade.h:40 + msgid "Right" +-msgstr "" ++msgstr "Right" + + #: ../terminatorlib/preferences.glade.h:41 + msgid "Hidden" +-msgstr "" ++msgstr "Hidden" + + #: ../terminatorlib/preferences.glade.h:42 + msgid "Normal" +-msgstr "" ++msgstr "Normal" + + #: ../terminatorlib/preferences.glade.h:43 + msgid "Maximised" +-msgstr "" ++msgstr "Maximized" + + #: ../terminatorlib/preferences.glade.h:44 + msgid "Fullscreen" +-msgstr "" ++msgstr "Fullscreen" + + #: ../terminatorlib/preferences.glade.h:45 + msgid "Terminator Preferences" +-msgstr "" ++msgstr "Terminator Preferences" + + #: ../terminatorlib/preferences.glade.h:46 + msgid "Behavior" +-msgstr "" ++msgstr "Behavior" + + #: ../terminatorlib/preferences.glade.h:47 + msgid "Window state:" +-msgstr "" ++msgstr "Window state:" + + #: ../terminatorlib/preferences.glade.h:48 + msgid "Always on top" +-msgstr "" ++msgstr "Always on top" + + #: ../terminatorlib/preferences.glade.h:49 + msgid "Show on all workspaces" +-msgstr "" ++msgstr "Show on all workspaces" + + #: ../terminatorlib/preferences.glade.h:50 + msgid "Hide on lose focus" +-msgstr "" ++msgstr "Hide on lose focus" + + #: ../terminatorlib/preferences.glade.h:51 + msgid "Hide from taskbar" +-msgstr "" ++msgstr "Hide from taskbar" + + #: ../terminatorlib/preferences.glade.h:52 + msgid "Window geometry hints" +-msgstr "" ++msgstr "Window geometry hints" + + #: ../terminatorlib/preferences.glade.h:53 + msgid "DBus server" +-msgstr "" ++msgstr "DBus server" + + #: ../terminatorlib/preferences.glade.h:54 + msgid "Mouse focus:" +-msgstr "" ++msgstr "Mouse focus:" + + #: ../terminatorlib/preferences.glade.h:55 + msgid "Broadcast default:" +-msgstr "" ++msgstr "Broadcast default:" + + #: ../terminatorlib/preferences.glade.h:56 + msgid "PuTTY style paste" +-msgstr "" ++msgstr "PuTTY style paste" + + #: ../terminatorlib/preferences.glade.h:57 + msgid "Smart copy" +-msgstr "" ++msgstr "Smart copy" + + #: ../terminatorlib/preferences.glade.h:58 + msgid "Re-use profiles for new terminals" +-msgstr "" ++msgstr "Re-use profiles for new terminals" + + #: ../terminatorlib/preferences.glade.h:59 + msgid "Use custom URL handler" +-msgstr "" ++msgstr "Use custom URL handler" + + #: ../terminatorlib/preferences.glade.h:60 + msgid "Custom URL handler:" +-msgstr "" ++msgstr "Custom URL handler:" + + #: ../terminatorlib/preferences.glade.h:61 + msgid "Appearance" +-msgstr "" ++msgstr "Appearance" + + #: ../terminatorlib/preferences.glade.h:62 + msgid "Window borders" +-msgstr "" ++msgstr "Window borders" + + #: ../terminatorlib/preferences.glade.h:63 + msgid "Unfocused terminal font brightness:" +-msgstr "" ++msgstr "Unfocused terminal font brightness:" + + #: ../terminatorlib/preferences.glade.h:64 + msgid "Terminal separator size:" +-msgstr "" ++msgstr "Terminal separator size:" + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +@@ -836,19 +849,19 @@ + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +-msgstr "" ++msgstr "Tab position:" + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +-msgstr "" ++msgstr "Tabs homogeneous" + + #: ../terminatorlib/preferences.glade.h:68 + msgid "Tabs scroll buttons" +-msgstr "" ++msgstr "Tabs scroll buttons" + + #: ../terminatorlib/preferences.glade.h:69 + msgid "Terminal Titlebar" +-msgstr "" ++msgstr "Terminal Titlebar" + + #: ../terminatorlib/preferences.glade.h:70 + msgid "Font color:" +@@ -860,7 +873,7 @@ + + #: ../terminatorlib/preferences.glade.h:72 + msgid "Focused" +-msgstr "" ++msgstr "Focused" + + #: ../terminatorlib/preferences.glade.h:73 + msgid "Inactive" +@@ -868,7 +881,7 @@ + + #: ../terminatorlib/preferences.glade.h:74 + msgid "Receiving" +-msgstr "" ++msgstr "Receiving" + + #: ../terminatorlib/preferences.glade.h:75 + msgid "Hide size from title" +@@ -1786,3 +1799,6 @@ + #~ msgstr "" + #~ "This %s has several terminals open. Closing the %s will also close all " + #~ "terminals within it." ++ ++#~ msgid "default" ++#~ msgstr "default" +diff -x .bzr -uNr terminator-1.91/po/en_CA.po python3/po/en_CA.po +--- terminator-1.91/po/en_CA.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/en_CA.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/en_GB.po python3/po/en_GB.po +--- terminator-1.91/po/en_GB.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/en_GB.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2017-01-16 04:13+0000\n" +-"Last-Translator: Stephen Boddy \n" ++"PO-Revision-Date: 2017-08-30 11:23+0000\n" ++"Last-Translator: Marcin Sedlak \n" + "Language-Team: English (United Kingdom) \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-31 05:34+0000\n" ++"X-Generator: Launchpad (build 18446)\n" + "Language: \n" + + #. Command uuid req. Description +@@ -849,7 +849,7 @@ + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "Extra Styling (Theme dependant)" ++msgstr "Extra Styling (Theme dependent)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +diff -x .bzr -uNr terminator-1.91/po/eo.po python3/po/eo.po +--- terminator-1.91/po/eo.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/eo.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: eo\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/es.po python3/po/es.po +--- terminator-1.91/po/es.po 2017-02-28 17:07:22.000000000 -0500 ++++ python3/po/es.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2017-02-25 12:49+0000\n" +-"Last-Translator: Carlos Duque Guasch \n" ++"PO-Revision-Date: 2017-03-08 17:35+0000\n" ++"Last-Translator: dmouse \n" + "Language-Team: LANGUAGE \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=utf-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-27 05:52+0000\n" +-"X-Generator: Launchpad (build 18328)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +@@ -862,11 +862,11 @@ + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "Estilizado extra (depende del tema)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +-msgstr "Posición pestaña" ++msgstr "Posición de pestaña:" + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +diff -x .bzr -uNr terminator-1.91/po/et.po python3/po/et.po +--- terminator-1.91/po/et.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/et.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: et\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/eu.po python3/po/eu.po +--- terminator-1.91/po/eu.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/eu.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: eu\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/fa.po python3/po/fa.po +--- terminator-1.91/po/fa.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/fa.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: fa\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/fi.po python3/po/fi.po +--- terminator-1.91/po/fi.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/fi.po 2019-08-19 19:25:15.963479000 -0400 +@@ -16,8 +16,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: fi\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/fo.po python3/po/fo.po +--- terminator-1.91/po/fo.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/fo.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: fo\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/fr.po python3/po/fr.po +--- terminator-1.91/po/fr.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/fr.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-22 06:09+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: fr\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/fy.po python3/po/fy.po +--- terminator-1.91/po/fy.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/fy.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ga.po python3/po/ga.po +--- terminator-1.91/po/ga.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ga.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ga\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/gl.po python3/po/gl.po +--- terminator-1.91/po/gl.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/gl.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: gl\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/he.po python3/po/he.po +--- terminator-1.91/po/he.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/he.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: he\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/hi.po python3/po/hi.po +--- terminator-1.91/po/hi.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/hi.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: hi\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/hr.po python3/po/hr.po +--- terminator-1.91/po/hr.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/hr.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: hr\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/hu.po python3/po/hu.po +--- terminator-1.91/po/hu.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/hu.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: hu\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/hy.po python3/po/hy.po +--- terminator-1.91/po/hy.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/hy.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: hy\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ia.po python3/po/ia.po +--- terminator-1.91/po/ia.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ia.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 +diff -x .bzr -uNr terminator-1.91/po/id.po python3/po/id.po +--- terminator-1.91/po/id.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/id.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: id\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/is.po python3/po/is.po +--- terminator-1.91/po/is.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/is.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: is\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/it.po python3/po/it.po +--- terminator-1.91/po/it.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/it.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ro\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ja.po python3/po/ja.po +--- terminator-1.91/po/ja.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ja.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ja\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/jv.po python3/po/jv.po +--- terminator-1.91/po/jv.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/jv.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: jv\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ka.po python3/po/ka.po +--- terminator-1.91/po/ka.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ka.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ka\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/kk.po python3/po/kk.po +--- terminator-1.91/po/kk.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/kk.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: kk\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ko.po python3/po/ko.po +--- terminator-1.91/po/ko.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ko.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:40+0000\n" +-"Last-Translator: Seunghyo Chun \n" ++"PO-Revision-Date: 2017-04-18 08:11+0000\n" ++"Last-Translator: Seonghun Lim \n" + "Language-Team: Korean \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ko\n" + + #. Command uuid req. Description +@@ -87,7 +87,7 @@ + #: ../data/terminator.appdata.xml.in.h:3 + #: ../terminatorlib/preferences.glade.h:149 + msgid "The robot future of terminals" +-msgstr "" ++msgstr "터미널이 지배하는 미래 세상" + + #: ../data/terminator.appdata.xml.in.h:4 + msgid "" +@@ -111,7 +111,7 @@ + + #: ../data/terminator.appdata.xml.in.h:7 + msgid "Arrange terminals in a grid" +-msgstr "" ++msgstr "터미널들을 격자처럼 배열" + + #: ../data/terminator.appdata.xml.in.h:8 + msgid "Tabs" +@@ -119,19 +119,19 @@ + + #: ../data/terminator.appdata.xml.in.h:9 + msgid "Drag and drop re-ordering of terminals" +-msgstr "" ++msgstr "끌어놓기로 터미널 순서 조정" + + #: ../data/terminator.appdata.xml.in.h:10 + msgid "Lots of keyboard shortcuts" +-msgstr "" ++msgstr "수많은 키보드 바로가기" + + #: ../data/terminator.appdata.xml.in.h:11 + msgid "Save multiple layouts and profiles via GUI preferences editor" +-msgstr "" ++msgstr "GUI 설정 편집기로 여러 터미널 배치와 프로파일 저장" + + #: ../data/terminator.appdata.xml.in.h:12 + msgid "Simultaneous typing to arbitrary groups of terminals" +-msgstr "" ++msgstr "원하는 터미널들에 동시 키 입력" + + #: ../data/terminator.appdata.xml.in.h:13 + msgid "And lots more..." +@@ -165,13 +165,13 @@ + msgid "" + "This window has several terminals open. Closing the window will also close " + "all terminals within it." +-msgstr "" ++msgstr "이 창에는 터미널이 여러 개 열려 있습니다. 창을 닫으면 그 안의 모든 터미널이 닫히게 됩니다." + + #: ../terminatorlib/container.py:178 + msgid "" + "This tab has several terminals open. Closing the tab will also close all " + "terminals within it." +-msgstr "" ++msgstr "이 탭에는 터미널이 여러 개 열려 있습니다. 탭을 닫으면 그 안의 모든 터미널이 닫히게 됩니다." + + #: ../terminatorlib/container.py:198 + msgid "Do not show this message next time" +@@ -438,21 +438,21 @@ + + #: ../terminatorlib/plugins/activitywatch.py:55 + msgid "Watch for _activity" +-msgstr "" ++msgstr "활동 감시(_A)" + + #: ../terminatorlib/plugins/activitywatch.py:84 + #, python-format + msgid "Activity in: %s" +-msgstr "" ++msgstr "활동 탐지: %s" + + #: ../terminatorlib/plugins/activitywatch.py:121 + msgid "Watch for _silence" +-msgstr "" ++msgstr "정지 감시(_S)" + + #: ../terminatorlib/plugins/activitywatch.py:163 + #, python-format + msgid "Silence in: %s" +-msgstr "" ++msgstr "정지 탐지: %s" + + #: ../terminatorlib/plugins/custom_commands.py:61 + msgid "_Custom Commands" +@@ -473,16 +473,16 @@ + #: ../terminatorlib/plugins/logger.py:22 + #: ../terminatorlib/plugins/terminalshot.py:21 + msgid "_Cancel" +-msgstr "" ++msgstr "취소(_C)" + + #: ../terminatorlib/plugins/custom_commands.py:125 + #: ../terminatorlib/plugins/custom_commands.py:274 + msgid "_OK" +-msgstr "" ++msgstr "확인(_O)" + + #: ../terminatorlib/plugins/custom_commands.py:152 + msgid "Enabled" +-msgstr "사용함" ++msgstr "사용" + + #: ../terminatorlib/plugins/custom_commands.py:156 + #: ../terminatorlib/preferences.glade.h:137 +@@ -492,36 +492,36 @@ + #: ../terminatorlib/plugins/custom_commands.py:160 + #: ../terminatorlib/preferences.glade.h:103 + msgid "Command" +-msgstr "명령어" ++msgstr "명령" + + #: ../terminatorlib/plugins/custom_commands.py:174 + #: ../terminatorlib/preferences.glade.h:37 + msgid "Top" +-msgstr "상단" ++msgstr "처음으로" + + #: ../terminatorlib/plugins/custom_commands.py:180 + msgid "Up" +-msgstr "" ++msgstr "위로" + + #: ../terminatorlib/plugins/custom_commands.py:186 + msgid "Down" +-msgstr "" ++msgstr "아래로" + + #: ../terminatorlib/plugins/custom_commands.py:192 + msgid "Last" +-msgstr "" ++msgstr "끝으로" + + #: ../terminatorlib/plugins/custom_commands.py:198 + msgid "New" +-msgstr "" ++msgstr "신규" + + #: ../terminatorlib/plugins/custom_commands.py:203 + msgid "Edit" +-msgstr "" ++msgstr "편집" + + #: ../terminatorlib/plugins/custom_commands.py:209 + msgid "Delete" +-msgstr "" ++msgstr "삭제" + + #: ../terminatorlib/plugins/custom_commands.py:269 + msgid "New Command" +@@ -553,11 +553,11 @@ + #: ../terminatorlib/plugins/logger.py:23 + #: ../terminatorlib/plugins/terminalshot.py:22 + msgid "_Save" +-msgstr "" ++msgstr "저장(_S)" + + #: ../terminatorlib/plugins/logger.py:34 + msgid "Start _Logger" +-msgstr "로거 시자" ++msgstr "로거 시작" + + #: ../terminatorlib/plugins/logger.py:37 + msgid "Stop _Logger" +@@ -569,7 +569,7 @@ + + #: ../terminatorlib/plugins/terminalshot.py:29 + msgid "Terminal _screenshot" +-msgstr "" ++msgstr "터미널 스크린샷(_S)" + + #: ../terminatorlib/plugins/terminalshot.py:38 + msgid "Save image" +@@ -581,7 +581,7 @@ + + #: ../terminatorlib/preferences.glade.h:2 + msgid "Control-H" +-msgstr "" ++msgstr "Control-H" + + #: ../terminatorlib/preferences.glade.h:3 + msgid "ASCII DEL" +@@ -654,11 +654,11 @@ + + #: ../terminatorlib/preferences.glade.h:20 + msgid "Gruvbox light" +-msgstr "" ++msgstr "그루브박스 밝음" + + #: ../terminatorlib/preferences.glade.h:21 + msgid "Gruvbox dark" +-msgstr "" ++msgstr "그루브박스 어두움" + + #: ../terminatorlib/preferences.glade.h:22 + msgid "Custom" +@@ -666,7 +666,7 @@ + + #: ../terminatorlib/preferences.glade.h:23 + msgid "Block" +-msgstr "차단" ++msgstr "네모" + + #: ../terminatorlib/preferences.glade.h:24 + msgid "Underline" +@@ -738,7 +738,7 @@ + + #: ../terminatorlib/preferences.glade.h:42 + msgid "Normal" +-msgstr "표준" ++msgstr "기본" + + #: ../terminatorlib/preferences.glade.h:43 + msgid "Maximised" +@@ -754,11 +754,11 @@ + + #: ../terminatorlib/preferences.glade.h:46 + msgid "Behavior" +-msgstr "동작" ++msgstr "동작 방식" + + #: ../terminatorlib/preferences.glade.h:47 + msgid "Window state:" +-msgstr "" ++msgstr "창 상태:" + + #: ../terminatorlib/preferences.glade.h:48 + msgid "Always on top" +@@ -766,7 +766,7 @@ + + #: ../terminatorlib/preferences.glade.h:49 + msgid "Show on all workspaces" +-msgstr "모든 워크스페이스 보기" ++msgstr "모든 작업 공간 보기" + + #: ../terminatorlib/preferences.glade.h:50 + msgid "Hide on lose focus" +@@ -786,19 +786,19 @@ + + #: ../terminatorlib/preferences.glade.h:54 + msgid "Mouse focus:" +-msgstr "" ++msgstr "마우스 활성화:" + + #: ../terminatorlib/preferences.glade.h:55 + msgid "Broadcast default:" +-msgstr "" ++msgstr "동시 입력 기본:" + + #: ../terminatorlib/preferences.glade.h:56 + msgid "PuTTY style paste" +-msgstr "" ++msgstr "PuTTY 방식 붙여넣기" + + #: ../terminatorlib/preferences.glade.h:57 + msgid "Smart copy" +-msgstr "" ++msgstr "똑똑한 복사" + + #: ../terminatorlib/preferences.glade.h:58 + msgid "Re-use profiles for new terminals" +@@ -810,11 +810,11 @@ + + #: ../terminatorlib/preferences.glade.h:60 + msgid "Custom URL handler:" +-msgstr "" ++msgstr "사용자 URL 연결 프로그램:" + + #: ../terminatorlib/preferences.glade.h:61 + msgid "Appearance" +-msgstr "" ++msgstr "모양" + + #: ../terminatorlib/preferences.glade.h:62 + msgid "Window borders" +@@ -822,59 +822,59 @@ + + #: ../terminatorlib/preferences.glade.h:63 + msgid "Unfocused terminal font brightness:" +-msgstr "" ++msgstr "비활성 터미널 폰트 밝기:" + + #: ../terminatorlib/preferences.glade.h:64 + msgid "Terminal separator size:" +-msgstr "" ++msgstr "터미널 구분자 두께:" + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "추가 스타일 적용 (테마에 따라 다름)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +-msgstr "" ++msgstr "탭 위치:" + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +-msgstr "" ++msgstr "탭들을 균일하게" + + #: ../terminatorlib/preferences.glade.h:68 + msgid "Tabs scroll buttons" +-msgstr "" ++msgstr "탭 스크롤 버튼" + + #: ../terminatorlib/preferences.glade.h:69 + msgid "Terminal Titlebar" +-msgstr "" ++msgstr "터미널 제목" + + #: ../terminatorlib/preferences.glade.h:70 + msgid "Font color:" +-msgstr "" ++msgstr "글자색:" + + #: ../terminatorlib/preferences.glade.h:71 + msgid "Background:" +-msgstr "" ++msgstr "배경:" + + #: ../terminatorlib/preferences.glade.h:72 + msgid "Focused" +-msgstr "" ++msgstr "활성" + + #: ../terminatorlib/preferences.glade.h:73 + msgid "Inactive" +-msgstr "" ++msgstr "비활성" + + #: ../terminatorlib/preferences.glade.h:74 + msgid "Receiving" +-msgstr "" ++msgstr "수신 중" + + #: ../terminatorlib/preferences.glade.h:75 + msgid "Hide size from title" +-msgstr "" ++msgstr "제목에 크기 감추기" + + #: ../terminatorlib/preferences.glade.h:76 + msgid "_Use the system font" +-msgstr "" ++msgstr "시스템 글꼴 사용" + + #: ../terminatorlib/preferences.glade.h:77 + msgid "_Font:" +@@ -882,7 +882,7 @@ + + #: ../terminatorlib/preferences.glade.h:78 + msgid "Choose A Titlebar Font" +-msgstr "" ++msgstr "제목 글꼴 선택" + + #: ../terminatorlib/preferences.glade.h:79 + msgid "Global" +@@ -906,7 +906,7 @@ + + #: ../terminatorlib/preferences.glade.h:84 + msgid "Show titlebar" +-msgstr "타이틀바 보이기" ++msgstr "제목 보이기" + + #: ../terminatorlib/preferences.glade.h:85 + msgid "Copy on selection" +@@ -914,7 +914,7 @@ + + #: ../terminatorlib/preferences.glade.h:86 + msgid "Rewrap on resize" +-msgstr "" ++msgstr "크기 변경시 줄바꿈 조정" + + #: ../terminatorlib/preferences.glade.h:87 + msgid "Select-by-_word characters:" +@@ -926,19 +926,19 @@ + + #: ../terminatorlib/preferences.glade.h:89 + msgid "_Shape:" +-msgstr "" ++msgstr "모양:" + + #: ../terminatorlib/preferences.glade.h:90 + msgid "Color:" +-msgstr "" ++msgstr "색상:" + + #: ../terminatorlib/preferences.glade.h:91 + msgid "Blink" +-msgstr "" ++msgstr "깜박이기" + + #: ../terminatorlib/preferences.glade.h:92 + msgid "Foreground" +-msgstr "" ++msgstr "글자색" + + #: ../terminatorlib/preferences.glade.h:93 + msgid "Terminal bell" +@@ -946,11 +946,11 @@ + + #: ../terminatorlib/preferences.glade.h:94 + msgid "Titlebar icon" +-msgstr "타이틀바 아이콘" ++msgstr "제목 아이콘" + + #: ../terminatorlib/preferences.glade.h:95 + msgid "Visual flash" +-msgstr "화면 깜빡 거림" ++msgstr "화면 깜빡거림" + + #: ../terminatorlib/preferences.glade.h:96 + msgid "Audible beep" +@@ -958,7 +958,7 @@ + + #: ../terminatorlib/preferences.glade.h:97 + msgid "Window list flash" +-msgstr "창 목록 반짝임" ++msgstr "창 목록 깜빡거림" + + #: ../terminatorlib/preferences.glade.h:98 + msgid "General" +@@ -990,7 +990,7 @@ + + #: ../terminatorlib/preferences.glade.h:106 + msgid "Built-in sche_mes:" +-msgstr "내장 색상(_M):" ++msgstr "내장 색상표(_M):" + + #: ../terminatorlib/preferences.glade.h:107 + msgid "_Text color:" +@@ -1030,11 +1030,11 @@ + + #: ../terminatorlib/preferences.glade.h:116 + msgid "_Transparent background" +-msgstr "투명한 배경 효과" ++msgstr "투명 배경" + + #: ../terminatorlib/preferences.glade.h:117 + msgid "S_hade transparent background:" +-msgstr "" ++msgstr "투명 배경에 그림자:" + + #: ../terminatorlib/preferences.glade.h:118 + msgid "None" +@@ -1046,7 +1046,7 @@ + + #: ../terminatorlib/preferences.glade.h:120 + msgid "Background" +-msgstr "배경색" ++msgstr "배경" + + #: ../terminatorlib/preferences.glade.h:121 + msgid "_Scrollbar is:" +@@ -1096,7 +1096,7 @@ + + #: ../terminatorlib/preferences.glade.h:131 + msgid "Encoding:" +-msgstr "" ++msgstr "인코딩:" + + #: ../terminatorlib/preferences.glade.h:132 + msgid "_Reset Compatibility Options to Defaults" +@@ -1113,19 +1113,19 @@ + + #: ../terminatorlib/preferences.glade.h:136 + msgid "Type" +-msgstr "" ++msgstr "유형" + + #: ../terminatorlib/preferences.glade.h:138 + msgid "Profile:" +-msgstr "" ++msgstr "프로파일:" + + #: ../terminatorlib/preferences.glade.h:139 + msgid "Custom command:" +-msgstr "" ++msgstr "사용자 지정 명령:" + + #: ../terminatorlib/preferences.glade.h:140 + msgid "Working directory:" +-msgstr "" ++msgstr "작업 디렉터리:" + + #: ../terminatorlib/preferences.glade.h:141 + msgid "Layouts" +@@ -1133,11 +1133,11 @@ + + #: ../terminatorlib/preferences.glade.h:142 + msgid "Action" +-msgstr "" ++msgstr "동작" + + #: ../terminatorlib/preferences.glade.h:143 + msgid "Keybinding" +-msgstr "" ++msgstr "단축키" + + #: ../terminatorlib/preferences.glade.h:144 + msgid "Keybindings" +@@ -1145,7 +1145,7 @@ + + #: ../terminatorlib/preferences.glade.h:145 + msgid "Plugin" +-msgstr "" ++msgstr "플러그인" + + #: ../terminatorlib/preferences.glade.h:146 + msgid "This plugin has no configuration options" +@@ -1171,7 +1171,7 @@ + + #: ../terminatorlib/preferences.glade.h:153 + msgid "The Manual" +-msgstr "" ++msgstr "설명서" + + #: ../terminatorlib/preferences.glade.h:154 + msgid "" +@@ -1183,254 +1183,260 @@ + "Bugs / Enhancements\n" + "Translations" + msgstr "" ++"홈페이지\n" ++"블로그 / 뉴스\n" ++"개발\n" ++"버그 / 개선 사항\n" ++"번역" + + #: ../terminatorlib/preferences.glade.h:159 + msgid "About" +-msgstr "" ++msgstr "소개" + + #: ../terminatorlib/prefseditor.py:96 + msgid "Increase font size" +-msgstr "" ++msgstr "글꼴 크기 키우기" + + #: ../terminatorlib/prefseditor.py:97 + msgid "Decrease font size" +-msgstr "" ++msgstr "글꼴 크기 줄이기" + + #: ../terminatorlib/prefseditor.py:98 + msgid "Restore original font size" +-msgstr "" ++msgstr "원래 글꼴 크기로 돌아가기" + + #: ../terminatorlib/prefseditor.py:99 + msgid "Create a new tab" +-msgstr "" ++msgstr "새 탭 열기" + + #: ../terminatorlib/prefseditor.py:100 ../terminatorlib/prefseditor.py:102 + msgid "Focus the next terminal" +-msgstr "" ++msgstr "다음 터미널로" + + #: ../terminatorlib/prefseditor.py:101 ../terminatorlib/prefseditor.py:103 + msgid "Focus the previous terminal" +-msgstr "" ++msgstr "이전 터미널로" + + #: ../terminatorlib/prefseditor.py:104 + msgid "Focus the terminal above" +-msgstr "" ++msgstr "위쪽 터미널로" + + #: ../terminatorlib/prefseditor.py:105 + msgid "Focus the terminal below" +-msgstr "" ++msgstr "아래쪽 터미널로" + + #: ../terminatorlib/prefseditor.py:106 + msgid "Focus the terminal left" +-msgstr "" ++msgstr "왼쪽 터미널로" + + #: ../terminatorlib/prefseditor.py:107 + msgid "Focus the terminal right" +-msgstr "" ++msgstr "오른쪽 터미널로" + + #: ../terminatorlib/prefseditor.py:108 + msgid "Rotate terminals clockwise" +-msgstr "" ++msgstr "터미널들을 시계 방향으로 회전" + + #: ../terminatorlib/prefseditor.py:109 + msgid "Rotate terminals counter-clockwise" +-msgstr "" ++msgstr "터미널들을 시계 반대 방향으로 회전" + + #: ../terminatorlib/prefseditor.py:110 + msgid "Split horizontally" +-msgstr "" ++msgstr "상하로 나누기" + + #: ../terminatorlib/prefseditor.py:111 + msgid "Split vertically" +-msgstr "" ++msgstr "좌우로 나누기" + + #: ../terminatorlib/prefseditor.py:112 + msgid "Close terminal" +-msgstr "" ++msgstr "터미널 닫기" + + #: ../terminatorlib/prefseditor.py:113 + msgid "Copy selected text" +-msgstr "" ++msgstr "선택한 텍스트 복사" + + #: ../terminatorlib/prefseditor.py:114 + msgid "Paste clipboard" +-msgstr "" ++msgstr "클립보드 붙여넣기" + + #: ../terminatorlib/prefseditor.py:115 + msgid "Show/Hide the scrollbar" +-msgstr "" ++msgstr "스크롤바 보이기/감추기" + + #: ../terminatorlib/prefseditor.py:116 + msgid "Search terminal scrollback" +-msgstr "" ++msgstr "터미널 스크롤에서 검색" + + #: ../terminatorlib/prefseditor.py:117 + msgid "Scroll upwards one page" +-msgstr "" ++msgstr "위로 한 페이지 스크롤" + + #: ../terminatorlib/prefseditor.py:118 + msgid "Scroll downwards one page" +-msgstr "" ++msgstr "아래로 한 페이지 스크롤" + + #: ../terminatorlib/prefseditor.py:119 + msgid "Scroll upwards half a page" +-msgstr "" ++msgstr "위로 반 페이지 스크롤" + + #: ../terminatorlib/prefseditor.py:120 + msgid "Scroll downwards half a page" +-msgstr "" ++msgstr "아래로 반 페이지 스크롤" + + #: ../terminatorlib/prefseditor.py:121 + msgid "Scroll upwards one line" +-msgstr "" ++msgstr "위로 한 줄 스크롤" + + #: ../terminatorlib/prefseditor.py:122 + msgid "Scroll downwards one line" +-msgstr "" ++msgstr "아래로 한 줄 스크롤" + + #: ../terminatorlib/prefseditor.py:123 + msgid "Close window" +-msgstr "" ++msgstr "창 닫기" + + #: ../terminatorlib/prefseditor.py:124 + msgid "Resize the terminal up" +-msgstr "" ++msgstr "위로 터미널 크기 조정" + + #: ../terminatorlib/prefseditor.py:125 + msgid "Resize the terminal down" +-msgstr "" ++msgstr "아래로 터미널 크기 조정" + + #: ../terminatorlib/prefseditor.py:126 + msgid "Resize the terminal left" +-msgstr "" ++msgstr "왼쪽으로 터미널 크기 조정" + + #: ../terminatorlib/prefseditor.py:127 + msgid "Resize the terminal right" +-msgstr "" ++msgstr "오른쪽으로 터미널 크기 조정" + + #: ../terminatorlib/prefseditor.py:128 + msgid "Move the tab right" +-msgstr "" ++msgstr "탭을 오른쪽으로 이동" + + #: ../terminatorlib/prefseditor.py:129 + msgid "Move the tab left" +-msgstr "" ++msgstr "탭을 왼쪽으로 이동" + + #: ../terminatorlib/prefseditor.py:130 + msgid "Maximize terminal" +-msgstr "" ++msgstr "터미널 최대화" + + #: ../terminatorlib/prefseditor.py:131 + msgid "Zoom terminal" +-msgstr "" ++msgstr "터미널 확대" + + #: ../terminatorlib/prefseditor.py:132 + msgid "Switch to the next tab" +-msgstr "" ++msgstr "다음 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:133 + msgid "Switch to the previous tab" +-msgstr "" ++msgstr "이전 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:134 + msgid "Switch to the first tab" +-msgstr "" ++msgstr "첫 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:135 + msgid "Switch to the second tab" +-msgstr "" ++msgstr "두 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:136 + msgid "Switch to the third tab" +-msgstr "" ++msgstr "세 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:137 + msgid "Switch to the fourth tab" +-msgstr "" ++msgstr "네 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:138 + msgid "Switch to the fifth tab" +-msgstr "" ++msgstr "다섯 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:139 + msgid "Switch to the sixth tab" +-msgstr "" ++msgstr "여섯 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:140 + msgid "Switch to the seventh tab" +-msgstr "" ++msgstr "일곱 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:141 + msgid "Switch to the eighth tab" +-msgstr "" ++msgstr "여덟 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:142 + msgid "Switch to the ninth tab" +-msgstr "" ++msgstr "아홉 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:143 + msgid "Switch to the tenth tab" +-msgstr "" ++msgstr "열 번째 탭으로 이동" + + #: ../terminatorlib/prefseditor.py:144 + msgid "Toggle fullscreen" +-msgstr "" ++msgstr "전체화면 전환" + + #: ../terminatorlib/prefseditor.py:145 + msgid "Reset the terminal" +-msgstr "" ++msgstr "터미널 초기화" + + #: ../terminatorlib/prefseditor.py:146 + msgid "Reset and clear the terminal" +-msgstr "" ++msgstr "터미널 초기화 및 비우기" + + #: ../terminatorlib/prefseditor.py:147 + msgid "Toggle window visibility" +-msgstr "" ++msgstr "창 보이기 전환" + + #: ../terminatorlib/prefseditor.py:148 + msgid "Group all terminals" +-msgstr "" ++msgstr "모든 터미널을 그룹 지정" + + #: ../terminatorlib/prefseditor.py:149 + msgid "Group/Ungroup all terminals" +-msgstr "" ++msgstr "모든 터미널을 그룹 지정/해제" + + #: ../terminatorlib/prefseditor.py:150 + msgid "Ungroup all terminals" +-msgstr "" ++msgstr "모든 터미널을 그룹 해제" + + #: ../terminatorlib/prefseditor.py:151 + msgid "Group terminals in tab" +-msgstr "" ++msgstr "탭 내의 터미널들을 그룹 지정" + + #: ../terminatorlib/prefseditor.py:152 + msgid "Group/Ungroup terminals in tab" +-msgstr "" ++msgstr "탭 내의 터미널들을 그룹 지정/해제" + + #: ../terminatorlib/prefseditor.py:153 + msgid "Ungroup terminals in tab" +-msgstr "" ++msgstr "탭 내의 터미널들을 그룹 해제" + + #: ../terminatorlib/prefseditor.py:154 + msgid "Create a new window" +-msgstr "" ++msgstr "새 창 만들기" + + #: ../terminatorlib/prefseditor.py:155 + msgid "Spawn a new Terminator process" +-msgstr "" ++msgstr "새로운 터미네이터 프로세스 생성" + + #: ../terminatorlib/prefseditor.py:156 + msgid "Don't broadcast key presses" +-msgstr "" ++msgstr "동시 입력 하지 않기" + + #: ../terminatorlib/prefseditor.py:157 + msgid "Broadcast key presses to group" +-msgstr "" ++msgstr "그룹에 동시 입력" + + #: ../terminatorlib/prefseditor.py:158 + msgid "Broadcast key events to all" +-msgstr "" ++msgstr "전체에 동시 입력" + + #: ../terminatorlib/prefseditor.py:159 + msgid "Insert terminal number" +@@ -1442,31 +1448,31 @@ + + #: ../terminatorlib/prefseditor.py:161 + msgid "Edit window title" +-msgstr "" ++msgstr "창 제목 편집" + + #: ../terminatorlib/prefseditor.py:162 + msgid "Edit terminal title" +-msgstr "" ++msgstr "터미널 제목 편집" + + #: ../terminatorlib/prefseditor.py:163 + msgid "Edit tab title" +-msgstr "" ++msgstr "탭 제목 편집" + + #: ../terminatorlib/prefseditor.py:164 + msgid "Open layout launcher window" +-msgstr "" ++msgstr "레이아웃 런처 창 열기" + + #: ../terminatorlib/prefseditor.py:165 + msgid "Switch to next profile" +-msgstr "" ++msgstr "다음 프로파일로" + + #: ../terminatorlib/prefseditor.py:166 + msgid "Switch to previous profile" +-msgstr "" ++msgstr "이전 프로파일로" + + #: ../terminatorlib/prefseditor.py:167 + msgid "Open the manual" +-msgstr "" ++msgstr "설명서 열기" + + #: ../terminatorlib/prefseditor.py:1136 ../terminatorlib/prefseditor.py:1141 + msgid "New Profile" +@@ -1498,7 +1504,7 @@ + #. Wrap checkbox + #: ../terminatorlib/searchbar.py:85 + msgid "Wrap" +-msgstr "" ++msgstr "줄바꿈" + + #: ../terminatorlib/searchbar.py:144 + msgid "Searching scrollback" +@@ -1506,27 +1512,27 @@ + + #: ../terminatorlib/searchbar.py:162 ../terminatorlib/searchbar.py:188 + msgid "No more results" +-msgstr "결과가 더 없음" ++msgstr "결과 더 없음" + + #: ../terminatorlib/searchbar.py:203 + msgid "Found at row" +-msgstr "찾은 위치" ++msgstr "행 번호" + + #: ../terminatorlib/terminal_popup_menu.py:59 + msgid "_Send email to..." +-msgstr "이메일 보내기(_S)..." ++msgstr "이메일 전송(_S)..." + + #: ../terminatorlib/terminal_popup_menu.py:60 + msgid "_Copy email address" +-msgstr "이메일 주소 복사하기(_C)" ++msgstr "이메일 주소 복사(_C)" + + #: ../terminatorlib/terminal_popup_menu.py:62 + msgid "Ca_ll VoIP address" +-msgstr "VoIP 주소로 전화하기(_L)" ++msgstr "VoIP 주소로 전화(_L)" + + #: ../terminatorlib/terminal_popup_menu.py:63 + msgid "_Copy VoIP address" +-msgstr "VoIP 주소 복사하기(_C)" ++msgstr "VoIP 주소 복사(_C)" + + #: ../terminatorlib/terminal_popup_menu.py:84 + msgid "_Open link" +@@ -1534,15 +1540,15 @@ + + #: ../terminatorlib/terminal_popup_menu.py:86 + msgid "_Copy address" +-msgstr "주소 복사하기(_C)" ++msgstr "주소 복사(_C)" + + #: ../terminatorlib/terminal_popup_menu.py:102 + msgid "_Copy" +-msgstr "" ++msgstr "복사(_C)" + + #: ../terminatorlib/terminal_popup_menu.py:107 + msgid "_Paste" +-msgstr "" ++msgstr "붙여넣기(_P)" + + #: ../terminatorlib/terminal_popup_menu.py:114 + msgid "Split H_orizontally" +@@ -1562,7 +1568,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:147 + msgid "_Close" +-msgstr "" ++msgstr "닫기(_C)" + + #: ../terminatorlib/terminal_popup_menu.py:156 + msgid "_Zoom terminal" +@@ -1570,11 +1576,11 @@ + + #: ../terminatorlib/terminal_popup_menu.py:161 + msgid "Ma_ximize terminal" +-msgstr "" ++msgstr "터미널 최대화(_X)" + + #: ../terminatorlib/terminal_popup_menu.py:168 + msgid "_Restore all terminals" +-msgstr "모든 터미널 복원하기(_R)" ++msgstr "전체 터미널 복원(_R)" + + #: ../terminatorlib/terminal_popup_menu.py:175 + msgid "Grouping" +@@ -1602,11 +1608,11 @@ + + #: ../terminatorlib/terminal.py:433 + msgid "N_ew group..." +-msgstr "" ++msgstr "새 그룹(_E)" + + #: ../terminatorlib/terminal.py:439 + msgid "_None" +-msgstr "" ++msgstr "소속 없음" + + #: ../terminatorlib/terminal.py:459 + #, python-format +@@ -1615,11 +1621,11 @@ + + #: ../terminatorlib/terminal.py:464 + msgid "G_roup all in tab" +-msgstr "탭 안의 모두를 그룹으로 묶기(_G)" ++msgstr "탭 안의 모두를 그룹으로(_G)" + + #: ../terminatorlib/terminal.py:469 + msgid "Ungro_up all in tab" +-msgstr "" ++msgstr "탭 안의 모두를 그룹 해제(_U)" + + #: ../terminatorlib/terminal.py:474 + msgid "Remove all groups" +@@ -1632,31 +1638,31 @@ + + #: ../terminatorlib/terminal.py:491 + msgid "Broadcast _all" +-msgstr "" ++msgstr "전체에게 동시 입력(_A)" + + #: ../terminatorlib/terminal.py:492 + msgid "Broadcast _group" +-msgstr "" ++msgstr "그룹에 동시 입력(_G)" + + #: ../terminatorlib/terminal.py:493 + msgid "Broadcast _off" +-msgstr "" ++msgstr "동시 입력 끄기(_O)" + + #: ../terminatorlib/terminal.py:509 + msgid "_Split to this group" +-msgstr "" ++msgstr "나눌 때 이 그룹으로(_S)" + + #: ../terminatorlib/terminal.py:514 + msgid "Auto_clean groups" +-msgstr "" ++msgstr "빈 그룹 자동 제거(_C)" + + #: ../terminatorlib/terminal.py:521 + msgid "_Insert terminal number" +-msgstr "" ++msgstr "터미널 번호 붙여넣기(_I)" + + #: ../terminatorlib/terminal.py:525 + msgid "Insert _padded terminal number" +-msgstr "" ++msgstr "0으로 채운 터미널 번호 붙여넣기(_P)" + + #: ../terminatorlib/terminal.py:1394 + msgid "Unable to find a shell" +@@ -1672,103 +1678,103 @@ + + #: ../terminatorlib/terminal.py:1856 + msgid "Enter a new title for the Terminator window..." +-msgstr "터미네이터 윈도우 타이틀바의 새 이름을 입력하시요" ++msgstr "터미네이터 창의 새 제목을 입력하세요..." + + #: ../terminatorlib/titlebar.py:254 + msgid "Alpha" +-msgstr "" ++msgstr "비둘기" + + #: ../terminatorlib/titlebar.py:254 + msgid "Beta" +-msgstr "" ++msgstr "오리" + + #: ../terminatorlib/titlebar.py:254 + msgid "Gamma" +-msgstr "" ++msgstr "까치" + + #: ../terminatorlib/titlebar.py:254 + msgid "Delta" +-msgstr "" ++msgstr "독수리" + + #: ../terminatorlib/titlebar.py:254 + msgid "Epsilon" +-msgstr "" ++msgstr "갈매기" + + #: ../terminatorlib/titlebar.py:254 + msgid "Zeta" +-msgstr "" ++msgstr "메추라기" + + #: ../terminatorlib/titlebar.py:254 + msgid "Eta" +-msgstr "" ++msgstr "두루미" + + #: ../terminatorlib/titlebar.py:255 + msgid "Theta" +-msgstr "" ++msgstr "제비" + + #: ../terminatorlib/titlebar.py:255 + msgid "Iota" +-msgstr "" ++msgstr "까마귀" + + #: ../terminatorlib/titlebar.py:255 + msgid "Kappa" +-msgstr "" ++msgstr "뻐꾸기" + + #: ../terminatorlib/titlebar.py:255 + msgid "Lambda" +-msgstr "" ++msgstr "꿩" + + #: ../terminatorlib/titlebar.py:255 + msgid "Mu" +-msgstr "" ++msgstr "닭" + + #: ../terminatorlib/titlebar.py:255 + msgid "Nu" +-msgstr "" ++msgstr "고니" + + #: ../terminatorlib/titlebar.py:255 + msgid "Xi" +-msgstr "" ++msgstr "기러기" + + #: ../terminatorlib/titlebar.py:256 + msgid "Omicron" +-msgstr "" ++msgstr "논병아리" + + #: ../terminatorlib/titlebar.py:256 + msgid "Pi" +-msgstr "" ++msgstr "딱다구리" + + #: ../terminatorlib/titlebar.py:256 + msgid "Rho" +-msgstr "" ++msgstr "올빼미" + + #: ../terminatorlib/titlebar.py:256 + msgid "Sigma" +-msgstr "" ++msgstr "부엉이" + + #: ../terminatorlib/titlebar.py:256 + msgid "Tau" +-msgstr "" ++msgstr "느시" + + #: ../terminatorlib/titlebar.py:256 + msgid "Upsilon" +-msgstr "" ++msgstr "뜸부기" + + #: ../terminatorlib/titlebar.py:256 + msgid "Phi" +-msgstr "" ++msgstr "따오기" + + #: ../terminatorlib/titlebar.py:257 + msgid "Chi" +-msgstr "" ++msgstr "직박구리" + + #: ../terminatorlib/titlebar.py:257 + msgid "Psi" +-msgstr "" ++msgstr "지빠귀" + + #: ../terminatorlib/titlebar.py:257 + msgid "Omega" +-msgstr "" ++msgstr "곤줄박이" + + #: ../terminatorlib/window.py:276 + msgid "window" +diff -x .bzr -uNr terminator-1.91/po/ku.po python3/po/ku.po +--- terminator-1.91/po/ku.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ku.po 2019-08-19 19:25:15.963479000 -0400 +@@ -9,13 +9,13 @@ + "Report-Msgid-Bugs-To: FULL NAME \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" + "PO-Revision-Date: 2017-02-12 23:32+0000\n" +-"Last-Translator: Rokar \n" ++"Last-Translator: Rokar ✌ \n" + "Language-Team: Kurdish \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-13 06:00+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 +diff -x .bzr -uNr terminator-1.91/po/la.po python3/po/la.po +--- terminator-1.91/po/la.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/la.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: la\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/lt.po python3/po/lt.po +--- terminator-1.91/po/lt.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/lt.po 2019-08-19 19:25:15.963479000 -0400 +@@ -15,8 +15,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: lt\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/lv.po python3/po/lv.po +--- terminator-1.91/po/lv.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/lv.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: lv\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/mk.po python3/po/mk.po +--- terminator-1.91/po/mk.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/mk.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: mk\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ml.po python3/po/ml.po +--- terminator-1.91/po/ml.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ml.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ml\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/mr.po python3/po/mr.po +--- terminator-1.91/po/mr.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/mr.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: mr\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ms.po python3/po/ms.po +--- terminator-1.91/po/ms.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ms.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ms\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/nb.po python3/po/nb.po +--- terminator-1.91/po/nb.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/nb.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: nb\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/nl.po python3/po/nl.po +--- terminator-1.91/po/nl.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/nl.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/nn.po python3/po/nn.po +--- terminator-1.91/po/nn.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/nn.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: nn\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/oc.po python3/po/oc.po +--- terminator-1.91/po/oc.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/oc.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/pl.po python3/po/pl.po +--- terminator-1.91/po/pl.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/pl.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,24 +8,24 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2016-12-17 14:42+0000\n" +-"Last-Translator: m4sk1n \n" ++"PO-Revision-Date: 2017-08-30 11:34+0000\n" ++"Last-Translator: Marcin Sedlak \n" + "Language-Team: Polish \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-31 05:34+0000\n" ++"X-Generator: Launchpad (build 18446)\n" + "Language: pl\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "Otwiera nowe okno programu" ++msgstr "Otwórz nowe okno" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "Otwiera nową kartę" ++msgstr "Otwórz nową kartę" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +@@ -41,19 +41,19 @@ + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "" ++msgstr "Dziedziczenie UUID okna nadrzędnego" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "" ++msgstr "Dziedziczenie tytułu okna nadrzędnego" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +-msgstr "" ++msgstr "Dziedziczenie UUID karty nadrzędnej" + + #: ../remotinator.py:46 + msgid "Get the title of a parent tab" +-msgstr "" ++msgstr "Dziedziczenie tytułu karty nadrzędnej" + + #: ../remotinator.py:63 + #, python-format +@@ -829,7 +829,7 @@ + + #: ../terminatorlib/preferences.glade.h:63 + msgid "Unfocused terminal font brightness:" +-msgstr "" ++msgstr "Jasność czcionki nieaktywnego terminala" + + #: ../terminatorlib/preferences.glade.h:64 + msgid "Terminal separator size:" +@@ -837,7 +837,7 @@ + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "Dodatkowe stylowanie (zależne od motywu)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +@@ -865,7 +865,7 @@ + + #: ../terminatorlib/preferences.glade.h:72 + msgid "Focused" +-msgstr "" ++msgstr "Aktywny" + + #: ../terminatorlib/preferences.glade.h:73 + msgid "Inactive" +@@ -949,7 +949,7 @@ + + #: ../terminatorlib/preferences.glade.h:93 + msgid "Terminal bell" +-msgstr "Dzwonek termianala" ++msgstr "Dzwonek terminala" + + #: ../terminatorlib/preferences.glade.h:94 + msgid "Titlebar icon" +@@ -1245,11 +1245,11 @@ + + #: ../terminatorlib/prefseditor.py:108 + msgid "Rotate terminals clockwise" +-msgstr "" ++msgstr "Obróć terminale zgodnie z ruchem wskazówek zegara" + + #: ../terminatorlib/prefseditor.py:109 + msgid "Rotate terminals counter-clockwise" +-msgstr "" ++msgstr "Obróć terminale przeciwnie do ruchu wskazówek zegara" + + #: ../terminatorlib/prefseditor.py:110 + msgid "Split horizontally" +@@ -1309,19 +1309,19 @@ + + #: ../terminatorlib/prefseditor.py:124 + msgid "Resize the terminal up" +-msgstr "" ++msgstr "Zmień rozmiar terminala w górę" + + #: ../terminatorlib/prefseditor.py:125 + msgid "Resize the terminal down" +-msgstr "" ++msgstr "Zmień rozmiar terminala w dół" + + #: ../terminatorlib/prefseditor.py:126 + msgid "Resize the terminal left" +-msgstr "" ++msgstr "Zmień rozmiar terminala w lewo" + + #: ../terminatorlib/prefseditor.py:127 + msgid "Resize the terminal right" +-msgstr "" ++msgstr "Zmień rozmiar terminala w prawo" + + #: ../terminatorlib/prefseditor.py:128 + msgid "Move the tab right" +diff -x .bzr -uNr terminator-1.91/po/POTFILES.in python3/po/POTFILES.in +--- terminator-1.91/po/POTFILES.in 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/POTFILES.in 2019-08-19 19:25:15.963479000 -0400 +@@ -7,9 +7,6 @@ + data/terminator.desktop.in + data/terminator.appdata.xml.in + terminatorlib/borg.py +-terminatorlib/configobj/configobj.py +-terminatorlib/configobj/__init__.py +-terminatorlib/configobj/validate.py + terminatorlib/config.py + terminatorlib/container.py + terminatorlib/cwd.py +diff -x .bzr -uNr terminator-1.91/po/pt_BR.po python3/po/pt_BR.po +--- terminator-1.91/po/pt_BR.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/pt_BR.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:40+0000\n" +-"Last-Translator: Fábio Nogueira \n" ++"PO-Revision-Date: 2017-03-02 15:55+0000\n" ++"Last-Translator: raphael \n" + "Language-Team: Brazilian Portuguese \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: pt_BR\n" + + #. Command uuid req. Description +@@ -178,12 +178,16 @@ + "This window has several terminals open. Closing the window will also close " + "all terminals within it." + msgstr "" ++"Esta janela tem vários terminais abertos. Fechando a janela também irá " ++"fechar todos os terminais dentro dele." + + #: ../terminatorlib/container.py:178 + msgid "" + "This tab has several terminals open. Closing the tab will also close all " + "terminals within it." + msgstr "" ++"Esta guia tem vários terminais abertos. Fechando a guia também irá fechar " ++"todos os terminais dentro dela." + + #: ../terminatorlib/container.py:198 + msgid "Do not show this message next time" +@@ -489,12 +493,12 @@ + #: ../terminatorlib/plugins/logger.py:22 + #: ../terminatorlib/plugins/terminalshot.py:21 + msgid "_Cancel" +-msgstr "" ++msgstr "_Cancelar" + + #: ../terminatorlib/plugins/custom_commands.py:125 + #: ../terminatorlib/plugins/custom_commands.py:274 + msgid "_OK" +-msgstr "" ++msgstr "Certo" + + #: ../terminatorlib/plugins/custom_commands.py:152 + msgid "Enabled" +@@ -517,27 +521,27 @@ + + #: ../terminatorlib/plugins/custom_commands.py:180 + msgid "Up" +-msgstr "" ++msgstr "Acima" + + #: ../terminatorlib/plugins/custom_commands.py:186 + msgid "Down" +-msgstr "" ++msgstr "Abaixo" + + #: ../terminatorlib/plugins/custom_commands.py:192 + msgid "Last" +-msgstr "" ++msgstr "Último" + + #: ../terminatorlib/plugins/custom_commands.py:198 + msgid "New" +-msgstr "" ++msgstr "Novo" + + #: ../terminatorlib/plugins/custom_commands.py:203 + msgid "Edit" +-msgstr "" ++msgstr "Editar" + + #: ../terminatorlib/plugins/custom_commands.py:209 + msgid "Delete" +-msgstr "" ++msgstr "Deletar" + + #: ../terminatorlib/plugins/custom_commands.py:269 + msgid "New Command" +@@ -569,7 +573,7 @@ + #: ../terminatorlib/plugins/logger.py:23 + #: ../terminatorlib/plugins/terminalshot.py:22 + msgid "_Save" +-msgstr "" ++msgstr "_Salvar" + + #: ../terminatorlib/plugins/logger.py:34 + msgid "Start _Logger" +@@ -581,11 +585,11 @@ + + #: ../terminatorlib/plugins/logger.py:67 + msgid "Save Log File As" +-msgstr "Salvar Log Como Arquivo" ++msgstr "Salvar Arquivo de Log Como" + + #: ../terminatorlib/plugins/terminalshot.py:29 + msgid "Terminal _screenshot" +-msgstr "Terminal _imagem da tela" ++msgstr "Terminal _captura da tela" + + #: ../terminatorlib/plugins/terminalshot.py:38 + msgid "Save image" +@@ -662,7 +666,7 @@ + + #: ../terminatorlib/preferences.glade.h:18 + msgid "Solarized light" +-msgstr "Solarizado leve" ++msgstr "Solarizado claro" + + #: ../terminatorlib/preferences.glade.h:19 + msgid "Solarized dark" +@@ -670,15 +674,15 @@ + + #: ../terminatorlib/preferences.glade.h:20 + msgid "Gruvbox light" +-msgstr "" ++msgstr "Caixa de fundo iluminada" + + #: ../terminatorlib/preferences.glade.h:21 + msgid "Gruvbox dark" +-msgstr "" ++msgstr "Caixa de fundo escura" + + #: ../terminatorlib/preferences.glade.h:22 + msgid "Custom" +-msgstr "Personalizar" ++msgstr "Personalizado" + + #: ../terminatorlib/preferences.glade.h:23 + msgid "Block" +@@ -758,7 +762,7 @@ + + #: ../terminatorlib/preferences.glade.h:43 + msgid "Maximised" +-msgstr "Maximizar" ++msgstr "Maximizado" + + #: ../terminatorlib/preferences.glade.h:44 + msgid "Fullscreen" +@@ -846,7 +850,7 @@ + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "Estilização extra" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +@@ -930,7 +934,7 @@ + + #: ../terminatorlib/preferences.glade.h:86 + msgid "Rewrap on resize" +-msgstr "" ++msgstr "Organizar ao redimencionar" + + #: ../terminatorlib/preferences.glade.h:87 + msgid "Select-by-_word characters:" +@@ -954,7 +958,7 @@ + + #: ../terminatorlib/preferences.glade.h:92 + msgid "Foreground" +-msgstr "" ++msgstr "Primeiro plano" + + #: ../terminatorlib/preferences.glade.h:93 + msgid "Terminal bell" +@@ -1050,7 +1054,7 @@ + + #: ../terminatorlib/preferences.glade.h:117 + msgid "S_hade transparent background:" +-msgstr "" ++msgstr "S_ombrear fundo transparente" + + #: ../terminatorlib/preferences.glade.h:118 + msgid "None" +@@ -1114,7 +1118,7 @@ + + #: ../terminatorlib/preferences.glade.h:131 + msgid "Encoding:" +-msgstr "" ++msgstr "Codificação" + + #: ../terminatorlib/preferences.glade.h:132 + msgid "_Reset Compatibility Options to Defaults" +@@ -1211,6 +1215,13 @@ + "Bugs / Enhancements\n" + "Translations" + msgstr "" ++"Homepage" ++"\n" ++"Blog / News\n" ++"Development\n" ++"Bugs / Enhancements\n" ++"Translations" + + #: ../terminatorlib/preferences.glade.h:159 + msgid "About" +@@ -1338,11 +1349,11 @@ + + #: ../terminatorlib/prefseditor.py:128 + msgid "Move the tab right" +-msgstr "Mover aba para direita" ++msgstr "Mover aba para a direita" + + #: ../terminatorlib/prefseditor.py:129 + msgid "Move the tab left" +-msgstr "Mover aba para esqueda" ++msgstr "Mover aba para a esquerda" + + #: ../terminatorlib/prefseditor.py:130 + msgid "Maximize terminal" +@@ -1566,11 +1577,11 @@ + + #: ../terminatorlib/terminal_popup_menu.py:102 + msgid "_Copy" +-msgstr "" ++msgstr "_Copiar" + + #: ../terminatorlib/terminal_popup_menu.py:107 + msgid "_Paste" +-msgstr "" ++msgstr "_Colar" + + #: ../terminatorlib/terminal_popup_menu.py:114 + msgid "Split H_orizontally" +@@ -1590,7 +1601,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:147 + msgid "_Close" +-msgstr "" ++msgstr "_Fechar" + + #: ../terminatorlib/terminal_popup_menu.py:156 + msgid "_Zoom terminal" +diff -x .bzr -uNr terminator-1.91/po/pt.po python3/po/pt.po +--- terminator-1.91/po/pt.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/pt.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,24 +8,24 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:41+0000\n" +-"Last-Translator: Stephen Boddy \n" ++"PO-Revision-Date: 2017-03-05 23:10+0000\n" ++"Last-Translator: Sérgio Marques \n" + "Language-Team: Portuguese \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: pt_PT\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "Abrir uma nova janela" ++msgstr "Abrir nova janela" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "Abrir um novo separador" ++msgstr "Abrir novo separador" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +@@ -37,23 +37,23 @@ + + #: ../remotinator.py:42 + msgid "Get a list of all terminals" +-msgstr "Obter uma lista de todos os terminais" ++msgstr "Obter a lista de todos os terminais" + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "Obter o UUID da janela fonte" ++msgstr "Obter o UUID da janela superior" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "Obter o titulo de uma janela fonte" ++msgstr "Obter o título da janela superior" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +-msgstr "Obter o UUID de um separador fonte" ++msgstr "Obter o UUID do separador superior" + + #: ../remotinator.py:46 + msgid "Get the title of a parent tab" +-msgstr "Obter o titulo de um separador fonte" ++msgstr "Obter o título do separador superior" + + #: ../remotinator.py:63 + #, python-format +@@ -62,16 +62,21 @@ + "\n" + "%s" + msgstr "" ++"Execute um dos seguintes comandos DBus do Terminator:\n" ++"\n" ++"%s" + + #: ../remotinator.py:64 + msgid "" + "* These entries require either TERMINATOR_UUID environment var,\n" + " or the --uuid option must be used." + msgstr "" ++"* Estas entradas requerem a variável de ambiente TERMINATOR_UUID\n" ++" ou a utilização da opção --uuid." + + #: ../remotinator.py:66 + msgid "Terminal UUID for when not in env var TERMINATOR_UUID" +-msgstr "" ++msgstr "UUID do terminal se não existir a variável TERMINATOR_UUID" + + #: ../data/terminator.desktop.in.h:1 ../data/terminator.appdata.xml.in.h:1 + #: ../terminatorlib/plugins/activitywatch.py:84 +@@ -82,7 +87,7 @@ + + #: ../data/terminator.desktop.in.h:2 ../data/terminator.appdata.xml.in.h:2 + msgid "Multiple terminals in one window" +-msgstr "Terminais múltiplos numa janela" ++msgstr "Vários terminais por janela" + + #: ../data/terminator.appdata.xml.in.h:3 + #: ../terminatorlib/preferences.glade.h:149 +@@ -96,6 +101,10 @@ + "terminals in grids (tabs is the most common default method, which Terminator " + "also supports)." + msgstr "" ++"Uma ferramenta poderosíssima para arranjar terminais. Tem como inspiração " ++"programas como gnome-multi-term, quadkonsole e similares. O seu principal " ++"foco é o arranjo de terminais em grelha (o método mais usual são os " ++"separados, que também são suportados pelos Terminator)." + + #: ../data/terminator.appdata.xml.in.h:5 + msgid "" +@@ -104,6 +113,10 @@ + "out in different directions with useful features for sysadmins and other " + "users." + msgstr "" ++"Grande parte do comportamento baseia-se no terminal GNOME, mas adicionámos " ++"diversas funcionalidades com o passar do tempo e também pretendemos expandir " ++"a sua versatilidade, disponibilizando diversas opções para administradores " ++"de sistemas e outros utilizadores avançados." + + #: ../data/terminator.appdata.xml.in.h:6 + msgid "Some highlights:" +@@ -111,7 +124,7 @@ + + #: ../data/terminator.appdata.xml.in.h:7 + msgid "Arrange terminals in a grid" +-msgstr "Ordenar os terminais em grelha" ++msgstr "Disposição de terminais em grelha" + + #: ../data/terminator.appdata.xml.in.h:8 + msgid "Tabs" +@@ -128,12 +141,11 @@ + #: ../data/terminator.appdata.xml.in.h:11 + msgid "Save multiple layouts and profiles via GUI preferences editor" + msgstr "" +-"Guardar múltiplos layouts e perfis através da interface gráfica editor de " +-"preferências" ++"Guardar múltiplas disposições e perfis através do editor de preferências" + + #: ../data/terminator.appdata.xml.in.h:12 + msgid "Simultaneous typing to arbitrary groups of terminals" +-msgstr "Escrever para vários grupos de terminais simultaneamente" ++msgstr "Digitação para vários grupos de terminais em simultâneo" + + #: ../data/terminator.appdata.xml.in.h:13 + msgid "And lots more..." +@@ -141,15 +153,16 @@ + + #: ../data/terminator.appdata.xml.in.h:14 + msgid "The main window showing the application in action" +-msgstr "A janela principal que mostra a aplicação em acção" ++msgstr "A janela principal que mostra a aplicação em ação" + + #: ../data/terminator.appdata.xml.in.h:15 + msgid "Getting a little crazy with the terminals" +-msgstr "" ++msgstr "A loucura de diversos terminais" + + #: ../data/terminator.appdata.xml.in.h:16 + msgid "The preferences window where you can change the defaults" +-msgstr "A janela de preferências onde podes modificar os valores por omissão" ++msgstr "" ++"A janela de preferências na qual se pode alterar as definições padrão" + + #: ../terminatorlib/container.py:163 + msgid "Close?" +@@ -168,16 +181,20 @@ + "This window has several terminals open. Closing the window will also close " + "all terminals within it." + msgstr "" ++"Esta janela possui diversos terminais abertos. Se a fechar, todos os " ++"terminais serão fechados." + + #: ../terminatorlib/container.py:178 + msgid "" + "This tab has several terminals open. Closing the tab will also close all " + "terminals within it." + msgstr "" ++"Este separador possui diversos terminais abertos. Se o fechar, todos os " ++"terminais serão fechados." + + #: ../terminatorlib/container.py:198 + msgid "Do not show this message next time" +-msgstr "Não mostrar esta mensagem outra vez" ++msgstr "Não mostrar novamente a mensagem" + + #: ../terminatorlib/encoding.py:35 + msgid "Current Locale" +@@ -192,11 +209,11 @@ + #: ../terminatorlib/encoding.py:37 ../terminatorlib/encoding.py:69 + #: ../terminatorlib/encoding.py:81 ../terminatorlib/encoding.py:100 + msgid "Central European" +-msgstr "Europeu Central" ++msgstr "Europa Central" + + #: ../terminatorlib/encoding.py:38 + msgid "South European" +-msgstr "Europeu do Sul" ++msgstr "Europa do Sul" + + #: ../terminatorlib/encoding.py:39 ../terminatorlib/encoding.py:47 + #: ../terminatorlib/encoding.py:107 +@@ -222,7 +239,7 @@ + + #: ../terminatorlib/encoding.py:43 + msgid "Hebrew Visual" +-msgstr "Hebraico Visual" ++msgstr "Hebraico visual" + + #: ../terminatorlib/encoding.py:44 ../terminatorlib/encoding.py:72 + #: ../terminatorlib/encoding.py:89 ../terminatorlib/encoding.py:105 +@@ -296,7 +313,7 @@ + + #: ../terminatorlib/encoding.py:84 + msgid "Hindi" +-msgstr "Hindi" ++msgstr "Hindu" + + #: ../terminatorlib/encoding.py:85 + msgid "Persian" +@@ -330,11 +347,11 @@ + #: ../terminatorlib/layoutlauncher.glade.h:2 + #: ../terminatorlib/preferences.glade.h:135 + msgid "Layout" +-msgstr "" ++msgstr "Disposição" + + #: ../terminatorlib/layoutlauncher.glade.h:3 + msgid "Launch" +-msgstr "" ++msgstr "Iniciar" + + #: ../terminatorlib/notebook.py:353 + msgid "tab" +@@ -350,11 +367,11 @@ + + #: ../terminatorlib/optionparse.py:52 + msgid "Maximize the window" +-msgstr "" ++msgstr "Maximizar janela" + + #: ../terminatorlib/optionparse.py:54 + msgid "Make the window fill the screen" +-msgstr "Ajustar a janela ao ecrã" ++msgstr "Ajustar janela ao ecrã" + + #: ../terminatorlib/optionparse.py:56 + msgid "Disable window borders" +@@ -406,11 +423,11 @@ + + #: ../terminatorlib/optionparse.py:89 + msgid "Launch with the given layout" +-msgstr "" ++msgstr "Iniciar com a disposição indicada" + + #: ../terminatorlib/optionparse.py:91 + msgid "Select a layout from a list" +-msgstr "" ++msgstr "Selecione uma disposição da lista" + + #: ../terminatorlib/optionparse.py:93 + msgid "Use a different profile as the default" +@@ -426,11 +443,11 @@ + + #: ../terminatorlib/optionparse.py:99 + msgid "Comma separated list of classes to limit debugging to" +-msgstr "Classes separadas por vírgulas para limitar a depuração a" ++msgstr "Classes, separadas por vírgulas, para limitar a depuração a" + + #: ../terminatorlib/optionparse.py:101 + msgid "Comma separated list of methods to limit debugging to" +-msgstr "Métodos separados por vírgulas para limitar a depuração a" ++msgstr "Métodos, separados por vírgula,s para limitar a depuração a" + + #: ../terminatorlib/optionparse.py:103 + msgid "If Terminator is already running, just open a new tab" +@@ -442,25 +459,25 @@ + + #: ../terminatorlib/plugins/activitywatch.py:55 + msgid "Watch for _activity" +-msgstr "" ++msgstr "Monitorizar _atividade" + + #: ../terminatorlib/plugins/activitywatch.py:84 + #, python-format + msgid "Activity in: %s" +-msgstr "" ++msgstr "Atividade em: %s" + + #: ../terminatorlib/plugins/activitywatch.py:121 + msgid "Watch for _silence" +-msgstr "" ++msgstr "Monitorizar _silêncio" + + #: ../terminatorlib/plugins/activitywatch.py:163 + #, python-format + msgid "Silence in: %s" +-msgstr "" ++msgstr "Silêncio em: %s" + + #: ../terminatorlib/plugins/custom_commands.py:61 + msgid "_Custom Commands" +-msgstr "" ++msgstr "_Comandos personalizados" + + #. VERIFY FOR GTK3: is this ever false? + #: ../terminatorlib/plugins/custom_commands.py:67 +@@ -477,21 +494,21 @@ + #: ../terminatorlib/plugins/logger.py:22 + #: ../terminatorlib/plugins/terminalshot.py:21 + msgid "_Cancel" +-msgstr "" ++msgstr "_Cancelar" + + #: ../terminatorlib/plugins/custom_commands.py:125 + #: ../terminatorlib/plugins/custom_commands.py:274 + msgid "_OK" +-msgstr "" ++msgstr "_OK" + + #: ../terminatorlib/plugins/custom_commands.py:152 + msgid "Enabled" +-msgstr "" ++msgstr "Ativo" + + #: ../terminatorlib/plugins/custom_commands.py:156 + #: ../terminatorlib/preferences.glade.h:137 + msgid "Name" +-msgstr "" ++msgstr "Nome" + + #: ../terminatorlib/plugins/custom_commands.py:160 + #: ../terminatorlib/preferences.glade.h:103 +@@ -505,27 +522,27 @@ + + #: ../terminatorlib/plugins/custom_commands.py:180 + msgid "Up" +-msgstr "" ++msgstr "Subir" + + #: ../terminatorlib/plugins/custom_commands.py:186 + msgid "Down" +-msgstr "" ++msgstr "Descer" + + #: ../terminatorlib/plugins/custom_commands.py:192 + msgid "Last" +-msgstr "" ++msgstr "Último" + + #: ../terminatorlib/plugins/custom_commands.py:198 + msgid "New" +-msgstr "" ++msgstr "Novo" + + #: ../terminatorlib/plugins/custom_commands.py:203 + msgid "Edit" +-msgstr "" ++msgstr "Editar" + + #: ../terminatorlib/plugins/custom_commands.py:209 + msgid "Delete" +-msgstr "" ++msgstr "Apagar" + + #: ../terminatorlib/plugins/custom_commands.py:269 + msgid "New Command" +@@ -533,7 +550,7 @@ + + #: ../terminatorlib/plugins/custom_commands.py:280 + msgid "Enabled:" +-msgstr "Ativado:" ++msgstr "Ativo:" + + #: ../terminatorlib/plugins/custom_commands.py:286 + msgid "Name:" +@@ -546,7 +563,7 @@ + #: ../terminatorlib/plugins/custom_commands.py:315 + #: ../terminatorlib/plugins/custom_commands.py:425 + msgid "You need to define a name and command" +-msgstr "Precisa de definir o nome e o comando" ++msgstr "Tem que definir o nome e o comando" + + #: ../terminatorlib/plugins/custom_commands.py:332 + #: ../terminatorlib/plugins/custom_commands.py:444 +@@ -557,27 +574,27 @@ + #: ../terminatorlib/plugins/logger.py:23 + #: ../terminatorlib/plugins/terminalshot.py:22 + msgid "_Save" +-msgstr "" ++msgstr "_Guardar" + + #: ../terminatorlib/plugins/logger.py:34 + msgid "Start _Logger" +-msgstr "" ++msgstr "Iniciar _logger" + + #: ../terminatorlib/plugins/logger.py:37 + msgid "Stop _Logger" +-msgstr "" ++msgstr "Parar _logger" + + #: ../terminatorlib/plugins/logger.py:67 + msgid "Save Log File As" +-msgstr "" ++msgstr "Guardar ficheiro como" + + #: ../terminatorlib/plugins/terminalshot.py:29 + msgid "Terminal _screenshot" +-msgstr "" ++msgstr "_Captura de ecrã" + + #: ../terminatorlib/plugins/terminalshot.py:38 + msgid "Save image" +-msgstr "" ++msgstr "Guardar imagem" + + #: ../terminatorlib/preferences.glade.h:1 + msgid "Automatic" +@@ -589,11 +606,11 @@ + + #: ../terminatorlib/preferences.glade.h:3 + msgid "ASCII DEL" +-msgstr "DEL ASCII" ++msgstr "ASCII DEL" + + #: ../terminatorlib/preferences.glade.h:4 + msgid "Escape sequence" +-msgstr "Sequência de Escape" ++msgstr "Sequência de escape" + + #. FIXME: Why isn't this being done by Terminator() ? + #: ../terminatorlib/preferences.glade.h:5 ../terminatorlib/window.py:704 +@@ -602,7 +619,7 @@ + + #: ../terminatorlib/preferences.glade.h:6 + msgid "Group" +-msgstr "" ++msgstr "Agrupar" + + #: ../terminatorlib/preferences.glade.h:7 + msgid "None" +@@ -630,7 +647,7 @@ + + #: ../terminatorlib/preferences.glade.h:13 + msgid "Gray on black" +-msgstr "" ++msgstr "Cinzento sobre preto" + + #: ../terminatorlib/preferences.glade.h:14 + msgid "Green on black" +@@ -650,19 +667,19 @@ + + #: ../terminatorlib/preferences.glade.h:18 + msgid "Solarized light" +-msgstr "" ++msgstr "Solar claro" + + #: ../terminatorlib/preferences.glade.h:19 + msgid "Solarized dark" +-msgstr "" ++msgstr "Solar escuro" + + #: ../terminatorlib/preferences.glade.h:20 + msgid "Gruvbox light" +-msgstr "" ++msgstr "Gruvbox claro" + + #: ../terminatorlib/preferences.glade.h:21 + msgid "Gruvbox dark" +-msgstr "" ++msgstr "Gruvbox escuro" + + #: ../terminatorlib/preferences.glade.h:22 + msgid "Custom" +@@ -710,7 +727,7 @@ + + #: ../terminatorlib/preferences.glade.h:33 + msgid "Solarized" +-msgstr "" ++msgstr "Solar" + + #: ../terminatorlib/preferences.glade.h:34 + msgid "On the left side" +@@ -758,11 +775,11 @@ + + #: ../terminatorlib/preferences.glade.h:46 + msgid "Behavior" +-msgstr "" ++msgstr "Comportamento" + + #: ../terminatorlib/preferences.glade.h:47 + msgid "Window state:" +-msgstr "" ++msgstr "Estado da janela:" + + #: ../terminatorlib/preferences.glade.h:48 + msgid "Always on top" +@@ -790,19 +807,19 @@ + + #: ../terminatorlib/preferences.glade.h:54 + msgid "Mouse focus:" +-msgstr "" ++msgstr "Foco do rato:" + + #: ../terminatorlib/preferences.glade.h:55 + msgid "Broadcast default:" +-msgstr "" ++msgstr "Padrão de difusão:" + + #: ../terminatorlib/preferences.glade.h:56 + msgid "PuTTY style paste" +-msgstr "" ++msgstr "Estilo PuTTY" + + #: ../terminatorlib/preferences.glade.h:57 + msgid "Smart copy" +-msgstr "" ++msgstr "Cópia inteligente" + + #: ../terminatorlib/preferences.glade.h:58 + msgid "Re-use profiles for new terminals" +@@ -814,11 +831,11 @@ + + #: ../terminatorlib/preferences.glade.h:60 + msgid "Custom URL handler:" +-msgstr "" ++msgstr "Gestor personalizado:" + + #: ../terminatorlib/preferences.glade.h:61 + msgid "Appearance" +-msgstr "" ++msgstr "Aparência" + + #: ../terminatorlib/preferences.glade.h:62 + msgid "Window borders" +@@ -826,31 +843,31 @@ + + #: ../terminatorlib/preferences.glade.h:63 + msgid "Unfocused terminal font brightness:" +-msgstr "" ++msgstr "Brilho do tipo de letra em terminais não focados:" + + #: ../terminatorlib/preferences.glade.h:64 + msgid "Terminal separator size:" +-msgstr "" ++msgstr "Tamanho do separador:" + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "Estilização extra (conforme o tema)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +-msgstr "" ++msgstr "Posição do separador:" + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +-msgstr "" ++msgstr "Separadores homogéneos" + + #: ../terminatorlib/preferences.glade.h:68 + msgid "Tabs scroll buttons" +-msgstr "" ++msgstr "Botões de deslocação dos separadores" + + #: ../terminatorlib/preferences.glade.h:69 + msgid "Terminal Titlebar" +-msgstr "" ++msgstr "Barra de título do terminal" + + #: ../terminatorlib/preferences.glade.h:70 + msgid "Font color:" +@@ -858,7 +875,7 @@ + + #: ../terminatorlib/preferences.glade.h:71 + msgid "Background:" +-msgstr "" ++msgstr "Fundo:" + + #: ../terminatorlib/preferences.glade.h:72 + msgid "Focused" +@@ -866,19 +883,19 @@ + + #: ../terminatorlib/preferences.glade.h:73 + msgid "Inactive" +-msgstr "" ++msgstr "Inativo" + + #: ../terminatorlib/preferences.glade.h:74 + msgid "Receiving" +-msgstr "" ++msgstr "A receber" + + #: ../terminatorlib/preferences.glade.h:75 + msgid "Hide size from title" +-msgstr "" ++msgstr "Ocultar tamanho do título" + + #: ../terminatorlib/preferences.glade.h:76 + msgid "_Use the system font" +-msgstr "" ++msgstr "_Usar tipo de letra do sistema" + + #: ../terminatorlib/preferences.glade.h:77 + msgid "_Font:" +@@ -886,7 +903,7 @@ + + #: ../terminatorlib/preferences.glade.h:78 + msgid "Choose A Titlebar Font" +-msgstr "" ++msgstr "Escolha o tipo de letra para o título" + + #: ../terminatorlib/preferences.glade.h:79 + msgid "Global" +@@ -898,7 +915,7 @@ + + #: ../terminatorlib/preferences.glade.h:81 + msgid "_Use the system fixed width font" +-msgstr "_Utilizar tipo de letra de largura fixa do sistema" ++msgstr "_Usar tipo de letra de largura fixa do sistema" + + #: ../terminatorlib/preferences.glade.h:82 + msgid "Choose A Terminal Font" +@@ -918,11 +935,11 @@ + + #: ../terminatorlib/preferences.glade.h:86 + msgid "Rewrap on resize" +-msgstr "" ++msgstr "Moldar ao redimensionar" + + #: ../terminatorlib/preferences.glade.h:87 + msgid "Select-by-_word characters:" +-msgstr "Seleccionar _caracteres da palavra:" ++msgstr "Selecionar _caracteres da palavra:" + + #: ../terminatorlib/preferences.glade.h:88 + msgid "Cursor" +@@ -930,19 +947,19 @@ + + #: ../terminatorlib/preferences.glade.h:89 + msgid "_Shape:" +-msgstr "" ++msgstr "_Forma:" + + #: ../terminatorlib/preferences.glade.h:90 + msgid "Color:" +-msgstr "" ++msgstr "Cor:" + + #: ../terminatorlib/preferences.glade.h:91 + msgid "Blink" +-msgstr "" ++msgstr "Intermitente" + + #: ../terminatorlib/preferences.glade.h:92 + msgid "Foreground" +-msgstr "" ++msgstr "Principal" + + #: ../terminatorlib/preferences.glade.h:93 + msgid "Terminal bell" +@@ -974,7 +991,7 @@ + + #: ../terminatorlib/preferences.glade.h:100 + msgid "Ru_n a custom command instead of my shell" +-msgstr "_Executar um comando personalizado em vez da minha consola" ++msgstr "Executar um coma_ndo personalizado em vez da minha consola" + + #: ../terminatorlib/preferences.glade.h:101 + msgid "Custom co_mmand:" +@@ -982,7 +999,7 @@ + + #: ../terminatorlib/preferences.glade.h:102 + msgid "When command _exits:" +-msgstr "Ao sair do _comando" ++msgstr "Ao sair do _comando:" + + #: ../terminatorlib/preferences.glade.h:104 + msgid "Foreground and Background" +@@ -990,7 +1007,7 @@ + + #: ../terminatorlib/preferences.glade.h:105 + msgid "_Use colors from system theme" +-msgstr "_Utilizar cores do tema do sistema" ++msgstr "_Usar cores do tema do sistema" + + #: ../terminatorlib/preferences.glade.h:106 + msgid "Built-in sche_mes:" +@@ -1058,11 +1075,11 @@ + + #: ../terminatorlib/preferences.glade.h:122 + msgid "Scroll on _output" +-msgstr "Deslocar na _saída de" ++msgstr "Desl_ocar na saída de" + + #: ../terminatorlib/preferences.glade.h:123 + msgid "Scroll on _keystroke" +-msgstr "Deslocar ao premir o _teclado" ++msgstr "Deslocar ao premir a _tecla" + + #: ../terminatorlib/preferences.glade.h:124 + msgid "Infinite Scrollback" +@@ -1070,7 +1087,7 @@ + + #: ../terminatorlib/preferences.glade.h:125 + msgid "Scroll_back:" +-msgstr "Deslocamento para _trás:" ++msgstr "Deslocação para _trás:" + + #: ../terminatorlib/preferences.glade.h:126 + msgid "lines" +@@ -1078,7 +1095,7 @@ + + #: ../terminatorlib/preferences.glade.h:127 + msgid "Scrolling" +-msgstr "Deslocamento" ++msgstr "Deslocação" + + #: ../terminatorlib/preferences.glade.h:128 + msgid "" +@@ -1102,7 +1119,7 @@ + + #: ../terminatorlib/preferences.glade.h:131 + msgid "Encoding:" +-msgstr "" ++msgstr "Codificação:" + + #: ../terminatorlib/preferences.glade.h:132 + msgid "_Reset Compatibility Options to Defaults" +@@ -1119,11 +1136,11 @@ + + #: ../terminatorlib/preferences.glade.h:136 + msgid "Type" +-msgstr "" ++msgstr "Tipo" + + #: ../terminatorlib/preferences.glade.h:138 + msgid "Profile:" +-msgstr "" ++msgstr "Perfil:" + + #: ../terminatorlib/preferences.glade.h:139 + msgid "Custom command:" +@@ -1131,27 +1148,27 @@ + + #: ../terminatorlib/preferences.glade.h:140 + msgid "Working directory:" +-msgstr "" ++msgstr "Diretório de trabalho:" + + #: ../terminatorlib/preferences.glade.h:141 + msgid "Layouts" +-msgstr "Esquemas" ++msgstr "Disposições" + + #: ../terminatorlib/preferences.glade.h:142 + msgid "Action" +-msgstr "" ++msgstr "Ação" + + #: ../terminatorlib/preferences.glade.h:143 + msgid "Keybinding" +-msgstr "" ++msgstr "Associação de tecla" + + #: ../terminatorlib/preferences.glade.h:144 + msgid "Keybindings" +-msgstr "Teclas de atalho" ++msgstr "Associação de teclas" + + #: ../terminatorlib/preferences.glade.h:145 + msgid "Plugin" +-msgstr "" ++msgstr "Plugin" + + #: ../terminatorlib/preferences.glade.h:146 + msgid "This plugin has no configuration options" +@@ -1189,254 +1206,260 @@ + "Bugs / Enhancements\n" + "Translations" + msgstr "" ++"Página " ++"web\n" ++"Blog/Novidades\n" ++"Desenvolvimento\n" ++"Erros/Funcionalidades\n" ++"Tradução" + + #: ../terminatorlib/preferences.glade.h:159 + msgid "About" +-msgstr "" ++msgstr "Acerca" + + #: ../terminatorlib/prefseditor.py:96 + msgid "Increase font size" +-msgstr "" ++msgstr "Aumentar tamanho do tipo de letra" + + #: ../terminatorlib/prefseditor.py:97 + msgid "Decrease font size" +-msgstr "" ++msgstr "Diminuir tamanho do tipo de letra" + + #: ../terminatorlib/prefseditor.py:98 + msgid "Restore original font size" +-msgstr "" ++msgstr "restaurar tamanho padrão" + + #: ../terminatorlib/prefseditor.py:99 + msgid "Create a new tab" +-msgstr "" ++msgstr "Criar novo separador" + + #: ../terminatorlib/prefseditor.py:100 ../terminatorlib/prefseditor.py:102 + msgid "Focus the next terminal" +-msgstr "" ++msgstr "Focar o terminal seguinte" + + #: ../terminatorlib/prefseditor.py:101 ../terminatorlib/prefseditor.py:103 + msgid "Focus the previous terminal" +-msgstr "" ++msgstr "Focar o terminal anterior" + + #: ../terminatorlib/prefseditor.py:104 + msgid "Focus the terminal above" +-msgstr "" ++msgstr "Focar o terminal acima" + + #: ../terminatorlib/prefseditor.py:105 + msgid "Focus the terminal below" +-msgstr "" ++msgstr "Focar o terminal abaixo" + + #: ../terminatorlib/prefseditor.py:106 + msgid "Focus the terminal left" +-msgstr "" ++msgstr "Focar o terminal à esquerda" + + #: ../terminatorlib/prefseditor.py:107 + msgid "Focus the terminal right" +-msgstr "" ++msgstr "Focar o terminal à direita" + + #: ../terminatorlib/prefseditor.py:108 + msgid "Rotate terminals clockwise" +-msgstr "" ++msgstr "Rodar terminais para a direita" + + #: ../terminatorlib/prefseditor.py:109 + msgid "Rotate terminals counter-clockwise" +-msgstr "" ++msgstr "Rodar terminais para a esquerda" + + #: ../terminatorlib/prefseditor.py:110 + msgid "Split horizontally" +-msgstr "" ++msgstr "Dividir horizontalmente" + + #: ../terminatorlib/prefseditor.py:111 + msgid "Split vertically" +-msgstr "" ++msgstr "Dividir verticalmente" + + #: ../terminatorlib/prefseditor.py:112 + msgid "Close terminal" +-msgstr "" ++msgstr "Fechar terminal" + + #: ../terminatorlib/prefseditor.py:113 + msgid "Copy selected text" +-msgstr "" ++msgstr "Copiar texto selecionado" + + #: ../terminatorlib/prefseditor.py:114 + msgid "Paste clipboard" +-msgstr "" ++msgstr "Colar da área de transferência" + + #: ../terminatorlib/prefseditor.py:115 + msgid "Show/Hide the scrollbar" +-msgstr "" ++msgstr "Mostrar/ocultar barra de deslocação" + + #: ../terminatorlib/prefseditor.py:116 + msgid "Search terminal scrollback" +-msgstr "" ++msgstr "Pesquisar para trás" + + #: ../terminatorlib/prefseditor.py:117 + msgid "Scroll upwards one page" +-msgstr "" ++msgstr "Deslocar para uma página acima" + + #: ../terminatorlib/prefseditor.py:118 + msgid "Scroll downwards one page" +-msgstr "" ++msgstr "Deslocar para uma página abaixo" + + #: ../terminatorlib/prefseditor.py:119 + msgid "Scroll upwards half a page" +-msgstr "" ++msgstr "Deslocar para meia página acima" + + #: ../terminatorlib/prefseditor.py:120 + msgid "Scroll downwards half a page" +-msgstr "" ++msgstr "Deslocar para meia página abaixo" + + #: ../terminatorlib/prefseditor.py:121 + msgid "Scroll upwards one line" +-msgstr "" ++msgstr "Deslocar para uma linha acima" + + #: ../terminatorlib/prefseditor.py:122 + msgid "Scroll downwards one line" +-msgstr "" ++msgstr "Deslocar para uma linha abaixo" + + #: ../terminatorlib/prefseditor.py:123 + msgid "Close window" +-msgstr "" ++msgstr "Fechar janela" + + #: ../terminatorlib/prefseditor.py:124 + msgid "Resize the terminal up" +-msgstr "" ++msgstr "Redimensionar terminal para cima" + + #: ../terminatorlib/prefseditor.py:125 + msgid "Resize the terminal down" +-msgstr "" ++msgstr "Redimensionar terminal para baixo" + + #: ../terminatorlib/prefseditor.py:126 + msgid "Resize the terminal left" +-msgstr "" ++msgstr "Redimensionar terminal para a esquerda" + + #: ../terminatorlib/prefseditor.py:127 + msgid "Resize the terminal right" +-msgstr "" ++msgstr "Redimensionar terminal para a direita" + + #: ../terminatorlib/prefseditor.py:128 + msgid "Move the tab right" +-msgstr "" ++msgstr "Mover separador para a direita" + + #: ../terminatorlib/prefseditor.py:129 + msgid "Move the tab left" +-msgstr "" ++msgstr "Mover separador para a esquerda" + + #: ../terminatorlib/prefseditor.py:130 + msgid "Maximize terminal" +-msgstr "" ++msgstr "Maximizar terminal" + + #: ../terminatorlib/prefseditor.py:131 + msgid "Zoom terminal" +-msgstr "" ++msgstr "Ampliar terminal" + + #: ../terminatorlib/prefseditor.py:132 + msgid "Switch to the next tab" +-msgstr "" ++msgstr "Trocar para o separador seguinte" + + #: ../terminatorlib/prefseditor.py:133 + msgid "Switch to the previous tab" +-msgstr "" ++msgstr "Trocar para o separador anterior" + + #: ../terminatorlib/prefseditor.py:134 + msgid "Switch to the first tab" +-msgstr "" ++msgstr "Trocar para o primeiro separador" + + #: ../terminatorlib/prefseditor.py:135 + msgid "Switch to the second tab" +-msgstr "" ++msgstr "Trocar para o segundo separador" + + #: ../terminatorlib/prefseditor.py:136 + msgid "Switch to the third tab" +-msgstr "" ++msgstr "Trocar para o terceiro separador" + + #: ../terminatorlib/prefseditor.py:137 + msgid "Switch to the fourth tab" +-msgstr "" ++msgstr "Trocar para o quarto separador" + + #: ../terminatorlib/prefseditor.py:138 + msgid "Switch to the fifth tab" +-msgstr "" ++msgstr "Trocar para o quinto separador" + + #: ../terminatorlib/prefseditor.py:139 + msgid "Switch to the sixth tab" +-msgstr "" ++msgstr "Trocar para o sexto separador" + + #: ../terminatorlib/prefseditor.py:140 + msgid "Switch to the seventh tab" +-msgstr "" ++msgstr "Trocar para o sétimo separador" + + #: ../terminatorlib/prefseditor.py:141 + msgid "Switch to the eighth tab" +-msgstr "" ++msgstr "Trocar para o oitavo separador" + + #: ../terminatorlib/prefseditor.py:142 + msgid "Switch to the ninth tab" +-msgstr "" ++msgstr "Trocar para o nono separador" + + #: ../terminatorlib/prefseditor.py:143 + msgid "Switch to the tenth tab" +-msgstr "" ++msgstr "Trocar para o décimo separador" + + #: ../terminatorlib/prefseditor.py:144 + msgid "Toggle fullscreen" +-msgstr "" ++msgstr "Alternar ecrã completo" + + #: ../terminatorlib/prefseditor.py:145 + msgid "Reset the terminal" +-msgstr "" ++msgstr "Repor terminal" + + #: ../terminatorlib/prefseditor.py:146 + msgid "Reset and clear the terminal" +-msgstr "" ++msgstr "Repor e limpar o terminal" + + #: ../terminatorlib/prefseditor.py:147 + msgid "Toggle window visibility" +-msgstr "" ++msgstr "Alternar visibilidade da janela" + + #: ../terminatorlib/prefseditor.py:148 + msgid "Group all terminals" +-msgstr "" ++msgstr "Agrupar terminais" + + #: ../terminatorlib/prefseditor.py:149 + msgid "Group/Ungroup all terminals" +-msgstr "" ++msgstr "Agrupar/desagrupar terminais" + + #: ../terminatorlib/prefseditor.py:150 + msgid "Ungroup all terminals" +-msgstr "" ++msgstr "Deagrupar todos os terminais" + + #: ../terminatorlib/prefseditor.py:151 + msgid "Group terminals in tab" +-msgstr "" ++msgstr "Agrupar terminais para um separador" + + #: ../terminatorlib/prefseditor.py:152 + msgid "Group/Ungroup terminals in tab" +-msgstr "" ++msgstr "Agrupar/desagrupar terminais para um separador" + + #: ../terminatorlib/prefseditor.py:153 + msgid "Ungroup terminals in tab" +-msgstr "" ++msgstr "Desagrupar terminais do separador" + + #: ../terminatorlib/prefseditor.py:154 + msgid "Create a new window" +-msgstr "" ++msgstr "Criar nova janela" + + #: ../terminatorlib/prefseditor.py:155 + msgid "Spawn a new Terminator process" +-msgstr "" ++msgstr "Expandir novo processo terminator" + + #: ../terminatorlib/prefseditor.py:156 + msgid "Don't broadcast key presses" +-msgstr "" ++msgstr "Não difundir pressões de teclas" + + #: ../terminatorlib/prefseditor.py:157 + msgid "Broadcast key presses to group" +-msgstr "" ++msgstr "Difundir pressões de teclas para o grupo" + + #: ../terminatorlib/prefseditor.py:158 + msgid "Broadcast key events to all" +-msgstr "" ++msgstr "Difundir eventos de teclas para tudo" + + #: ../terminatorlib/prefseditor.py:159 + msgid "Insert terminal number" +@@ -1448,15 +1471,15 @@ + + #: ../terminatorlib/prefseditor.py:161 + msgid "Edit window title" +-msgstr "" ++msgstr "Editar título da janela" + + #: ../terminatorlib/prefseditor.py:162 + msgid "Edit terminal title" +-msgstr "" ++msgstr "Editar título do terminal" + + #: ../terminatorlib/prefseditor.py:163 + msgid "Edit tab title" +-msgstr "" ++msgstr "Editar título do separador" + + #: ../terminatorlib/prefseditor.py:164 + msgid "Open layout launcher window" +@@ -1464,15 +1487,15 @@ + + #: ../terminatorlib/prefseditor.py:165 + msgid "Switch to next profile" +-msgstr "" ++msgstr "Trocar para o perfil seguinte" + + #: ../terminatorlib/prefseditor.py:166 + msgid "Switch to previous profile" +-msgstr "" ++msgstr "Trocar para o perfil anterior" + + #: ../terminatorlib/prefseditor.py:167 + msgid "Open the manual" +-msgstr "" ++msgstr "Abrir o manual" + + #: ../terminatorlib/prefseditor.py:1136 ../terminatorlib/prefseditor.py:1141 + msgid "New Profile" +@@ -1504,11 +1527,11 @@ + #. Wrap checkbox + #: ../terminatorlib/searchbar.py:85 + msgid "Wrap" +-msgstr "" ++msgstr "Moldar" + + #: ../terminatorlib/searchbar.py:144 + msgid "Searching scrollback" +-msgstr "Pesquisando deslocamentos anteriores" ++msgstr "Pesquisar deslocações anteriores" + + #: ../terminatorlib/searchbar.py:162 ../terminatorlib/searchbar.py:188 + msgid "No more results" +@@ -1524,7 +1547,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:60 + msgid "_Copy email address" +-msgstr "_Copiar endereço eletrónico" ++msgstr "_Copiar endereço de e-mail" + + #: ../terminatorlib/terminal_popup_menu.py:62 + msgid "Ca_ll VoIP address" +@@ -1544,11 +1567,11 @@ + + #: ../terminatorlib/terminal_popup_menu.py:102 + msgid "_Copy" +-msgstr "" ++msgstr "_Copiar" + + #: ../terminatorlib/terminal_popup_menu.py:107 + msgid "_Paste" +-msgstr "" ++msgstr "Co_lar" + + #: ../terminatorlib/terminal_popup_menu.py:114 + msgid "Split H_orizontally" +@@ -1568,7 +1591,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:147 + msgid "_Close" +-msgstr "" ++msgstr "Fe_char" + + #: ../terminatorlib/terminal_popup_menu.py:156 + msgid "_Zoom terminal" +@@ -1576,7 +1599,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:161 + msgid "Ma_ximize terminal" +-msgstr "" ++msgstr "Ma_ximizar terminal" + + #: ../terminatorlib/terminal_popup_menu.py:168 + msgid "_Restore all terminals" +@@ -1596,7 +1619,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:254 + msgid "Default" +-msgstr "Omissão" ++msgstr "Padrão" + + #: ../terminatorlib/terminal_popup_menu.py:257 + msgid "User defined" +@@ -1608,11 +1631,11 @@ + + #: ../terminatorlib/terminal.py:433 + msgid "N_ew group..." +-msgstr "" ++msgstr "N_ovo grupo..." + + #: ../terminatorlib/terminal.py:439 + msgid "_None" +-msgstr "" ++msgstr "_Nenhum" + + #: ../terminatorlib/terminal.py:459 + #, python-format +@@ -1625,7 +1648,7 @@ + + #: ../terminatorlib/terminal.py:469 + msgid "Ungro_up all in tab" +-msgstr "" ++msgstr "Desagr_upar tudo no separador" + + #: ../terminatorlib/terminal.py:474 + msgid "Remove all groups" +@@ -1638,27 +1661,27 @@ + + #: ../terminatorlib/terminal.py:491 + msgid "Broadcast _all" +-msgstr "" ++msgstr "Difubdir tod_as" + + #: ../terminatorlib/terminal.py:492 + msgid "Broadcast _group" +-msgstr "" ++msgstr "Difundir _grupo" + + #: ../terminatorlib/terminal.py:493 + msgid "Broadcast _off" +-msgstr "" ++msgstr "Difusã_o desativada" + + #: ../terminatorlib/terminal.py:509 + msgid "_Split to this group" +-msgstr "" ++msgstr "_Separar este grupo" + + #: ../terminatorlib/terminal.py:514 + msgid "Auto_clean groups" +-msgstr "" ++msgstr "Limpar grupos automati_camente" + + #: ../terminatorlib/terminal.py:521 + msgid "_Insert terminal number" +-msgstr "" ++msgstr "_Inserir número do terminal" + + #: ../terminatorlib/terminal.py:525 + msgid "Insert _padded terminal number" +@@ -1678,103 +1701,103 @@ + + #: ../terminatorlib/terminal.py:1856 + msgid "Enter a new title for the Terminator window..." +-msgstr "Introduza o novo título para a janela Terminator..." ++msgstr "Digite o novo título para a janela Terminator..." + + #: ../terminatorlib/titlebar.py:254 + msgid "Alpha" +-msgstr "" ++msgstr "Alfa" + + #: ../terminatorlib/titlebar.py:254 + msgid "Beta" +-msgstr "" ++msgstr "Beta" + + #: ../terminatorlib/titlebar.py:254 + msgid "Gamma" +-msgstr "" ++msgstr "Gama" + + #: ../terminatorlib/titlebar.py:254 + msgid "Delta" +-msgstr "" ++msgstr "Delta" + + #: ../terminatorlib/titlebar.py:254 + msgid "Epsilon" +-msgstr "" ++msgstr "Ípsilon" + + #: ../terminatorlib/titlebar.py:254 + msgid "Zeta" +-msgstr "" ++msgstr "Zeta" + + #: ../terminatorlib/titlebar.py:254 + msgid "Eta" +-msgstr "" ++msgstr "Eta" + + #: ../terminatorlib/titlebar.py:255 + msgid "Theta" +-msgstr "" ++msgstr "Teta" + + #: ../terminatorlib/titlebar.py:255 + msgid "Iota" +-msgstr "" ++msgstr "Iota" + + #: ../terminatorlib/titlebar.py:255 + msgid "Kappa" +-msgstr "" ++msgstr "Capa" + + #: ../terminatorlib/titlebar.py:255 + msgid "Lambda" +-msgstr "" ++msgstr "Lambda" + + #: ../terminatorlib/titlebar.py:255 + msgid "Mu" +-msgstr "" ++msgstr "Mu" + + #: ../terminatorlib/titlebar.py:255 + msgid "Nu" +-msgstr "" ++msgstr "Nu" + + #: ../terminatorlib/titlebar.py:255 + msgid "Xi" +-msgstr "" ++msgstr "Xi" + + #: ../terminatorlib/titlebar.py:256 + msgid "Omicron" +-msgstr "" ++msgstr "Ómicron" + + #: ../terminatorlib/titlebar.py:256 + msgid "Pi" +-msgstr "" ++msgstr "Pi" + + #: ../terminatorlib/titlebar.py:256 + msgid "Rho" +-msgstr "" ++msgstr "Ró" + + #: ../terminatorlib/titlebar.py:256 + msgid "Sigma" +-msgstr "" ++msgstr "Sigma" + + #: ../terminatorlib/titlebar.py:256 + msgid "Tau" +-msgstr "" ++msgstr "Tau" + + #: ../terminatorlib/titlebar.py:256 + msgid "Upsilon" +-msgstr "" ++msgstr "Upsilon" + + #: ../terminatorlib/titlebar.py:256 + msgid "Phi" +-msgstr "" ++msgstr "Fi" + + #: ../terminatorlib/titlebar.py:257 + msgid "Chi" +-msgstr "" ++msgstr "Chi" + + #: ../terminatorlib/titlebar.py:257 + msgid "Psi" +-msgstr "" ++msgstr "Psi" + + #: ../terminatorlib/titlebar.py:257 + msgid "Omega" +-msgstr "" ++msgstr "Ómega" + + #: ../terminatorlib/window.py:276 + msgid "window" +diff -x .bzr -uNr terminator-1.91/po/ro.po python3/po/ro.po +--- terminator-1.91/po/ro.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ro.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ro\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ru.po python3/po/ru.po +--- terminator-1.91/po/ru.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ru.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,14 +8,14 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:41+0000\n" +-"Last-Translator: Stephen Boddy \n" ++"PO-Revision-Date: 2017-04-03 11:49+0000\n" ++"Last-Translator: Pavel Ivanov \n" + "Language-Team: Russian \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ru\n" + + #. Command uuid req. Description +@@ -92,7 +92,7 @@ + #: ../data/terminator.appdata.xml.in.h:3 + #: ../terminatorlib/preferences.glade.h:149 + msgid "The robot future of terminals" +-msgstr "" ++msgstr "Технологии будущего для терминалов" + + #: ../data/terminator.appdata.xml.in.h:4 + msgid "" +@@ -182,12 +182,16 @@ + "This window has several terminals open. Closing the window will also close " + "all terminals within it." + msgstr "" ++"Это окно имеет несколько запущенных терминалов. Закрытие окна повлечет за " ++"собой так же и их закрытие." + + #: ../terminatorlib/container.py:178 + msgid "" + "This tab has several terminals open. Closing the tab will also close all " + "terminals within it." + msgstr "" ++"Эта вкладка имеет несколько запущенных терминалов. Ее закрытие повлечет за " ++"собой так же и их закрытие." + + #: ../terminatorlib/container.py:198 + msgid "Do not show this message next time" +@@ -344,7 +348,7 @@ + #: ../terminatorlib/layoutlauncher.glade.h:2 + #: ../terminatorlib/preferences.glade.h:135 + msgid "Layout" +-msgstr "" ++msgstr "Компоновка" + + #: ../terminatorlib/layoutlauncher.glade.h:3 + msgid "Launch" +@@ -422,11 +426,11 @@ + + #: ../terminatorlib/optionparse.py:89 + msgid "Launch with the given layout" +-msgstr "" ++msgstr "Запуск с заданной компоновкой элементов" + + #: ../terminatorlib/optionparse.py:91 + msgid "Select a layout from a list" +-msgstr "" ++msgstr "Выбор компоновки из списка" + + #: ../terminatorlib/optionparse.py:93 + msgid "Use a different profile as the default" +@@ -494,7 +498,7 @@ + #: ../terminatorlib/plugins/logger.py:22 + #: ../terminatorlib/plugins/terminalshot.py:21 + msgid "_Cancel" +-msgstr "" ++msgstr "О_тменить" + + #: ../terminatorlib/plugins/custom_commands.py:125 + #: ../terminatorlib/plugins/custom_commands.py:274 +@@ -522,7 +526,7 @@ + + #: ../terminatorlib/plugins/custom_commands.py:180 + msgid "Up" +-msgstr "" ++msgstr "Выше" + + #: ../terminatorlib/plugins/custom_commands.py:186 + msgid "Down" +@@ -530,19 +534,19 @@ + + #: ../terminatorlib/plugins/custom_commands.py:192 + msgid "Last" +-msgstr "" ++msgstr "Последний" + + #: ../terminatorlib/plugins/custom_commands.py:198 + msgid "New" +-msgstr "" ++msgstr "Новый" + + #: ../terminatorlib/plugins/custom_commands.py:203 + msgid "Edit" +-msgstr "" ++msgstr "Редактировать" + + #: ../terminatorlib/plugins/custom_commands.py:209 + msgid "Delete" +-msgstr "" ++msgstr "Удалить" + + #: ../terminatorlib/plugins/custom_commands.py:269 + msgid "New Command" +@@ -574,7 +578,7 @@ + #: ../terminatorlib/plugins/logger.py:23 + #: ../terminatorlib/plugins/terminalshot.py:22 + msgid "_Save" +-msgstr "" ++msgstr "Сохранит_ь" + + #: ../terminatorlib/plugins/logger.py:34 + msgid "Start _Logger" +@@ -667,19 +671,19 @@ + + #: ../terminatorlib/preferences.glade.h:18 + msgid "Solarized light" +-msgstr "" ++msgstr "Solarized светлая" + + #: ../terminatorlib/preferences.glade.h:19 + msgid "Solarized dark" +-msgstr "" ++msgstr "Solarized тёмная" + + #: ../terminatorlib/preferences.glade.h:20 + msgid "Gruvbox light" +-msgstr "" ++msgstr "Gruvbox светлая" + + #: ../terminatorlib/preferences.glade.h:21 + msgid "Gruvbox dark" +-msgstr "" ++msgstr "Gruvbox темная" + + #: ../terminatorlib/preferences.glade.h:22 + msgid "Custom" +@@ -727,7 +731,7 @@ + + #: ../terminatorlib/preferences.glade.h:33 + msgid "Solarized" +-msgstr "" ++msgstr "Solarized" + + #: ../terminatorlib/preferences.glade.h:34 + msgid "On the left side" +@@ -807,7 +811,7 @@ + + #: ../terminatorlib/preferences.glade.h:54 + msgid "Mouse focus:" +-msgstr "" ++msgstr "Позиция мыши:" + + #: ../terminatorlib/preferences.glade.h:55 + msgid "Broadcast default:" +@@ -819,7 +823,7 @@ + + #: ../terminatorlib/preferences.glade.h:57 + msgid "Smart copy" +-msgstr "" ++msgstr "\"Умное\" копирование" + + #: ../terminatorlib/preferences.glade.h:58 + msgid "Re-use profiles for new terminals" +@@ -831,7 +835,7 @@ + + #: ../terminatorlib/preferences.glade.h:60 + msgid "Custom URL handler:" +-msgstr "" ++msgstr "Произвольный URL механизм:" + + #: ../terminatorlib/preferences.glade.h:61 + msgid "Appearance" +@@ -843,7 +847,7 @@ + + #: ../terminatorlib/preferences.glade.h:63 + msgid "Unfocused terminal font brightness:" +-msgstr "" ++msgstr "Яркость шрифта для терминала вне фокуса:" + + #: ../terminatorlib/preferences.glade.h:64 + msgid "Terminal separator size:" +@@ -851,7 +855,7 @@ + + #: ../terminatorlib/preferences.glade.h:65 + msgid "Extra Styling (Theme dependant)" +-msgstr "" ++msgstr "Экстра Дизайн (зависит от темы)" + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +@@ -859,15 +863,15 @@ + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +-msgstr "" ++msgstr "Идентичные вкладки" + + #: ../terminatorlib/preferences.glade.h:68 + msgid "Tabs scroll buttons" +-msgstr "" ++msgstr "Кнопки переключения вкладок" + + #: ../terminatorlib/preferences.glade.h:69 + msgid "Terminal Titlebar" +-msgstr "" ++msgstr "Название терминала" + + #: ../terminatorlib/preferences.glade.h:70 + msgid "Font color:" +@@ -935,7 +939,7 @@ + + #: ../terminatorlib/preferences.glade.h:86 + msgid "Rewrap on resize" +-msgstr "" ++msgstr "Перерисовать при масштабировании" + + #: ../terminatorlib/preferences.glade.h:87 + msgid "Select-by-_word characters:" +@@ -959,7 +963,7 @@ + + #: ../terminatorlib/preferences.glade.h:92 + msgid "Foreground" +-msgstr "" ++msgstr "Передний План" + + #: ../terminatorlib/preferences.glade.h:93 + msgid "Terminal bell" +@@ -1055,7 +1059,7 @@ + + #: ../terminatorlib/preferences.glade.h:117 + msgid "S_hade transparent background:" +-msgstr "" ++msgstr "Затенять прозрачный фон:" + + #: ../terminatorlib/preferences.glade.h:118 + msgid "None" +@@ -1119,7 +1123,7 @@ + + #: ../terminatorlib/preferences.glade.h:131 + msgid "Encoding:" +-msgstr "" ++msgstr "Кодировка:" + + #: ../terminatorlib/preferences.glade.h:132 + msgid "_Reset Compatibility Options to Defaults" +@@ -1191,6 +1195,17 @@ + "users. If you have any suggestions, please file wishlist bugs! (see left for " + "the Development link)" + msgstr "" ++"Задачей данного проекта является создание удобного инструмента для " ++"совмещения терминалов. Вдохновленный такими программами как gnome-multi-" ++"term, quadkonsole и подобных, он прежде всего нацелен собирать терминалы в " ++"сетки (которые в свою очередь могут разноситься по вкладкам, которые, кстати " ++"Terminator так же поддерживает).\n" ++"\n" ++"Большая часть функционала заимствована из GNOME Terminal и мы со временем " ++"добавляем больше разных плюшек оттуда. Но хотелось бы как-то еще расширить " ++"его возможности для сисадминов и прочих пользователей. Если у вас есть какие-" ++"либо предложения, пожалуйста озвучьте их на багтрекере (wishlist bugs)! (см. " ++"сайт разработчиков)" + + #: ../terminatorlib/preferences.glade.h:153 + msgid "The Manual" +@@ -1206,6 +1221,14 @@ + "Bugs / Enhancements\n" + "Translations" + msgstr "" ++"Главная" ++"\n" ++"Блог / Новости\n" ++"Разработка\n" ++"Баги / " ++"Совершенствование\n" ++"Переводы" + + #: ../terminatorlib/preferences.glade.h:159 + msgid "About" +@@ -1241,15 +1264,15 @@ + + #: ../terminatorlib/prefseditor.py:105 + msgid "Focus the terminal below" +-msgstr "" ++msgstr "Сделать активным терминал ниже" + + #: ../terminatorlib/prefseditor.py:106 + msgid "Focus the terminal left" +-msgstr "" ++msgstr "Сделать активным терминал слева" + + #: ../terminatorlib/prefseditor.py:107 + msgid "Focus the terminal right" +-msgstr "" ++msgstr "Сделать активным терминал справа" + + #: ../terminatorlib/prefseditor.py:108 + msgid "Rotate terminals clockwise" +@@ -1289,27 +1312,27 @@ + + #: ../terminatorlib/prefseditor.py:117 + msgid "Scroll upwards one page" +-msgstr "" ++msgstr "Прокрутить вверх на страницу" + + #: ../terminatorlib/prefseditor.py:118 + msgid "Scroll downwards one page" +-msgstr "" ++msgstr "Прокрутить вниз на страницу" + + #: ../terminatorlib/prefseditor.py:119 + msgid "Scroll upwards half a page" +-msgstr "" ++msgstr "Прокрутить вверх на полстраницы" + + #: ../terminatorlib/prefseditor.py:120 + msgid "Scroll downwards half a page" +-msgstr "" ++msgstr "Прокрутить вниз на полстраницы" + + #: ../terminatorlib/prefseditor.py:121 + msgid "Scroll upwards one line" +-msgstr "" ++msgstr "Прокрутить вверх на строку" + + #: ../terminatorlib/prefseditor.py:122 + msgid "Scroll downwards one line" +-msgstr "" ++msgstr "Прокрутить вниз на строку" + + #: ../terminatorlib/prefseditor.py:123 + msgid "Close window" +@@ -1317,19 +1340,19 @@ + + #: ../terminatorlib/prefseditor.py:124 + msgid "Resize the terminal up" +-msgstr "" ++msgstr "Изменить размер терминала сверху" + + #: ../terminatorlib/prefseditor.py:125 + msgid "Resize the terminal down" +-msgstr "" ++msgstr "Изменить размер терминала снизу" + + #: ../terminatorlib/prefseditor.py:126 + msgid "Resize the terminal left" +-msgstr "" ++msgstr "Изменить размер терминала слева" + + #: ../terminatorlib/prefseditor.py:127 + msgid "Resize the terminal right" +-msgstr "" ++msgstr "Изменить размер терминала справа" + + #: ../terminatorlib/prefseditor.py:128 + msgid "Move the tab right" +@@ -1409,7 +1432,7 @@ + + #: ../terminatorlib/prefseditor.py:147 + msgid "Toggle window visibility" +-msgstr "" ++msgstr "Показать/Скрыть окно" + + #: ../terminatorlib/prefseditor.py:148 + msgid "Group all terminals" +@@ -1417,7 +1440,7 @@ + + #: ../terminatorlib/prefseditor.py:149 + msgid "Group/Ungroup all terminals" +-msgstr "" ++msgstr "Группировать/разрознить все терминалы" + + #: ../terminatorlib/prefseditor.py:150 + msgid "Ungroup all terminals" +@@ -1429,7 +1452,7 @@ + + #: ../terminatorlib/prefseditor.py:152 + msgid "Group/Ungroup terminals in tab" +-msgstr "" ++msgstr "Группировать/разрознить терминалы во вкладке" + + #: ../terminatorlib/prefseditor.py:153 + msgid "Ungroup terminals in tab" +@@ -1441,19 +1464,19 @@ + + #: ../terminatorlib/prefseditor.py:155 + msgid "Spawn a new Terminator process" +-msgstr "" ++msgstr "Создать новый процесс Terminator'а" + + #: ../terminatorlib/prefseditor.py:156 + msgid "Don't broadcast key presses" +-msgstr "" ++msgstr "Не транслировать нажатия клавиш" + + #: ../terminatorlib/prefseditor.py:157 + msgid "Broadcast key presses to group" +-msgstr "" ++msgstr "Транслировать нажатия клавиш в группу терминалов" + + #: ../terminatorlib/prefseditor.py:158 + msgid "Broadcast key events to all" +-msgstr "" ++msgstr "Транслировать нажатия клавиш во все терминалы" + + #: ../terminatorlib/prefseditor.py:159 + msgid "Insert terminal number" +@@ -1469,11 +1492,11 @@ + + #: ../terminatorlib/prefseditor.py:162 + msgid "Edit terminal title" +-msgstr "" ++msgstr "Изменить наименование терминала" + + #: ../terminatorlib/prefseditor.py:163 + msgid "Edit tab title" +-msgstr "" ++msgstr "Изменить наименование вкладки" + + #: ../terminatorlib/prefseditor.py:164 + msgid "Open layout launcher window" +@@ -1561,11 +1584,11 @@ + + #: ../terminatorlib/terminal_popup_menu.py:102 + msgid "_Copy" +-msgstr "" ++msgstr "Копировать" + + #: ../terminatorlib/terminal_popup_menu.py:107 + msgid "_Paste" +-msgstr "" ++msgstr "Вст_авить" + + #: ../terminatorlib/terminal_popup_menu.py:114 + msgid "Split H_orizontally" +@@ -1585,7 +1608,7 @@ + + #: ../terminatorlib/terminal_popup_menu.py:147 + msgid "_Close" +-msgstr "" ++msgstr "За_крыть" + + #: ../terminatorlib/terminal_popup_menu.py:156 + msgid "_Zoom terminal" +@@ -1629,7 +1652,7 @@ + + #: ../terminatorlib/terminal.py:439 + msgid "_None" +-msgstr "" ++msgstr "_Ничего" + + #: ../terminatorlib/terminal.py:459 + #, python-format +@@ -1642,7 +1665,7 @@ + + #: ../terminatorlib/terminal.py:469 + msgid "Ungro_up all in tab" +-msgstr "" ++msgstr "Раз_рознить терминалы во вкладке" + + #: ../terminatorlib/terminal.py:474 + msgid "Remove all groups" +@@ -1655,27 +1678,27 @@ + + #: ../terminatorlib/terminal.py:491 + msgid "Broadcast _all" +-msgstr "" ++msgstr "Транслировать все_м" + + #: ../terminatorlib/terminal.py:492 + msgid "Broadcast _group" +-msgstr "" ++msgstr "Транслировать гру_ппе" + + #: ../terminatorlib/terminal.py:493 + msgid "Broadcast _off" +-msgstr "" ++msgstr "Откл_ючить трансляцию" + + #: ../terminatorlib/terminal.py:509 + msgid "_Split to this group" +-msgstr "" ++msgstr "Поделить на _эту группу" + + #: ../terminatorlib/terminal.py:514 + msgid "Auto_clean groups" +-msgstr "" ++msgstr "Автос_тирание у групп" + + #: ../terminatorlib/terminal.py:521 + msgid "_Insert terminal number" +-msgstr "" ++msgstr "_Добавить номер терминала" + + #: ../terminatorlib/terminal.py:525 + msgid "Insert _padded terminal number" +diff -x .bzr -uNr terminator-1.91/po/ru_RU.po python3/po/ru_RU.po +--- terminator-1.91/po/ru_RU.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ru_RU.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/si.po python3/po/si.po +--- terminator-1.91/po/si.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/si.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/sk.po python3/po/sk.po +--- terminator-1.91/po/sk.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/sk.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: sk\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/sl.po python3/po/sl.po +--- terminator-1.91/po/sl.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/sl.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: sl\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/sq.po python3/po/sq.po +--- terminator-1.91/po/sq.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/sq.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:01+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:12+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: sq\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/sr.po python3/po/sr.po +--- terminator-1.91/po/sr.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/sr.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:02+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: sr\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/su.po python3/po/su.po +--- terminator-1.91/po/su.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/su.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: su\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/sv.po python3/po/sv.po +--- terminator-1.91/po/sv.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/sv.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,52 +8,52 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:42+0000\n" +-"Last-Translator: Mikael Hiort af Ornäs \n" ++"PO-Revision-Date: 2017-05-11 09:52+0000\n" ++"Last-Translator: Jonatan Nyberg \n" + "Language-Team: Swedish \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: sv\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "" ++msgstr "Öppna ett nytt fönster" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "" ++msgstr "Öppna en ny flik" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +-msgstr "" ++msgstr "Dela den nuvarande terminalen horisontellt" + + #: ../remotinator.py:41 + msgid "Split the current terminal vertically" +-msgstr "" ++msgstr "Dela den nuvarande terminalen vertikalt" + + #: ../remotinator.py:42 + msgid "Get a list of all terminals" +-msgstr "" ++msgstr "Få en lista över alla terminaler" + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "" ++msgstr "Få UUID av ett överfönster" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "" ++msgstr "Få titeln på ett överfönster" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +-msgstr "" ++msgstr "Hämta UUID för en överflik" + + #: ../remotinator.py:46 + msgid "Get the title of a parent tab" +-msgstr "" ++msgstr "Hämta titeln på en överflik" + + #: ../remotinator.py:63 + #, python-format +@@ -62,6 +62,9 @@ + "\n" + "%s" + msgstr "" ++"Kör en av följande Terminator DBus-kommandon:\n" ++"\n" ++"%s" + + #: ../remotinator.py:64 + msgid "" +@@ -87,7 +90,7 @@ + #: ../data/terminator.appdata.xml.in.h:3 + #: ../terminatorlib/preferences.glade.h:149 + msgid "The robot future of terminals" +-msgstr "" ++msgstr "Robot-framtid för terminaler" + + #: ../data/terminator.appdata.xml.in.h:4 + msgid "" +@@ -96,6 +99,10 @@ + "terminals in grids (tabs is the most common default method, which Terminator " + "also supports)." + msgstr "" ++"Ett kraftverktyg för att ordna terminaler. Det är inspirerat av program som " ++"gnome-multi-term, quadkonsole, o.s.v. i det att huvudfokus är att ordna " ++"terminaler i rutnät (flikar är den vanligaste standardmetoden, vilka " ++"Terminator också stöder)." + + #: ../data/terminator.appdata.xml.in.h:5 + msgid "" +@@ -104,42 +111,46 @@ + "out in different directions with useful features for sysadmins and other " + "users." + msgstr "" ++"Mycket av beteendet hos Terminator bygger på GNOME Terminal, och vi lägger " ++"till fler funktioner från det medan tiden går, men vi vill också utöka i " ++"olika riktningar med användbara funktioner för sysadmins och andra användare." + + #: ../data/terminator.appdata.xml.in.h:6 + msgid "Some highlights:" +-msgstr "" ++msgstr "Några höjdpunkter:" + + #: ../data/terminator.appdata.xml.in.h:7 + msgid "Arrange terminals in a grid" +-msgstr "" ++msgstr "Arrangera terminaler i ett rutnät" + + #: ../data/terminator.appdata.xml.in.h:8 + msgid "Tabs" +-msgstr "" ++msgstr "Flikar" + + #: ../data/terminator.appdata.xml.in.h:9 + msgid "Drag and drop re-ordering of terminals" +-msgstr "" ++msgstr "Dra och släpp omordning av terminaler" + + #: ../data/terminator.appdata.xml.in.h:10 + msgid "Lots of keyboard shortcuts" +-msgstr "" ++msgstr "Massor av kortkommandon" + + #: ../data/terminator.appdata.xml.in.h:11 + msgid "Save multiple layouts and profiles via GUI preferences editor" + msgstr "" ++"Spara flera utformningar och profiler via GUI-inställningsredigeraren" + + #: ../data/terminator.appdata.xml.in.h:12 + msgid "Simultaneous typing to arbitrary groups of terminals" +-msgstr "" ++msgstr "Samtidigt skrivning till godtyckliga grupper av terminaler" + + #: ../data/terminator.appdata.xml.in.h:13 + msgid "And lots more..." +-msgstr "" ++msgstr "Och mycket mer..." + + #: ../data/terminator.appdata.xml.in.h:14 + msgid "The main window showing the application in action" +-msgstr "" ++msgstr "Huvudfönstret visar programmet i verkan" + + #: ../data/terminator.appdata.xml.in.h:15 + msgid "Getting a little crazy with the terminals" +@@ -328,11 +339,11 @@ + #: ../terminatorlib/layoutlauncher.glade.h:2 + #: ../terminatorlib/preferences.glade.h:135 + msgid "Layout" +-msgstr "" ++msgstr "Utformning" + + #: ../terminatorlib/layoutlauncher.glade.h:3 + msgid "Launch" +-msgstr "" ++msgstr "Starta" + + #: ../terminatorlib/notebook.py:353 + msgid "tab" +@@ -348,7 +359,7 @@ + + #: ../terminatorlib/optionparse.py:52 + msgid "Maximize the window" +-msgstr "" ++msgstr "Maximera fönstret" + + #: ../terminatorlib/optionparse.py:54 + msgid "Make the window fill the screen" +@@ -492,7 +503,7 @@ + #: ../terminatorlib/plugins/custom_commands.py:156 + #: ../terminatorlib/preferences.glade.h:137 + msgid "Name" +-msgstr "" ++msgstr "Namn" + + #: ../terminatorlib/plugins/custom_commands.py:160 + #: ../terminatorlib/preferences.glade.h:103 +@@ -578,7 +589,7 @@ + + #: ../terminatorlib/plugins/terminalshot.py:38 + msgid "Save image" +-msgstr "" ++msgstr "Spara bild" + + #: ../terminatorlib/preferences.glade.h:1 + msgid "Automatic" +@@ -603,7 +614,7 @@ + + #: ../terminatorlib/preferences.glade.h:6 + msgid "Group" +-msgstr "" ++msgstr "Grupp" + + #: ../terminatorlib/preferences.glade.h:7 + msgid "None" +@@ -631,7 +642,7 @@ + + #: ../terminatorlib/preferences.glade.h:13 + msgid "Gray on black" +-msgstr "" ++msgstr "Grått på svart" + + #: ../terminatorlib/preferences.glade.h:14 + msgid "Green on black" +@@ -759,7 +770,7 @@ + + #: ../terminatorlib/preferences.glade.h:46 + msgid "Behavior" +-msgstr "" ++msgstr "Beteende" + + #: ../terminatorlib/preferences.glade.h:47 + msgid "Window state:" +@@ -819,7 +830,7 @@ + + #: ../terminatorlib/preferences.glade.h:61 + msgid "Appearance" +-msgstr "" ++msgstr "Utseende" + + #: ../terminatorlib/preferences.glade.h:62 + msgid "Window borders" +@@ -839,7 +850,7 @@ + + #: ../terminatorlib/preferences.glade.h:66 + msgid "Tab position:" +-msgstr "" ++msgstr "Flikplacering:" + + #: ../terminatorlib/preferences.glade.h:67 + msgid "Tabs homogeneous" +@@ -859,7 +870,7 @@ + + #: ../terminatorlib/preferences.glade.h:71 + msgid "Background:" +-msgstr "" ++msgstr "Bakgrund:" + + #: ../terminatorlib/preferences.glade.h:72 + msgid "Focused" +@@ -867,7 +878,7 @@ + + #: ../terminatorlib/preferences.glade.h:73 + msgid "Inactive" +-msgstr "" ++msgstr "Inaktiv" + + #: ../terminatorlib/preferences.glade.h:74 + msgid "Receiving" +@@ -935,11 +946,11 @@ + + #: ../terminatorlib/preferences.glade.h:90 + msgid "Color:" +-msgstr "" ++msgstr "Färg:" + + #: ../terminatorlib/preferences.glade.h:91 + msgid "Blink" +-msgstr "" ++msgstr "Blinka" + + #: ../terminatorlib/preferences.glade.h:92 + msgid "Foreground" +@@ -1120,11 +1131,11 @@ + + #: ../terminatorlib/preferences.glade.h:136 + msgid "Type" +-msgstr "" ++msgstr "Typ" + + #: ../terminatorlib/preferences.glade.h:138 + msgid "Profile:" +-msgstr "" ++msgstr "Profil:" + + #: ../terminatorlib/preferences.glade.h:139 + msgid "Custom command:" +@@ -1132,7 +1143,7 @@ + + #: ../terminatorlib/preferences.glade.h:140 + msgid "Working directory:" +-msgstr "" ++msgstr "Arbetskatalog:" + + #: ../terminatorlib/preferences.glade.h:141 + msgid "Layouts" +@@ -1152,7 +1163,7 @@ + + #: ../terminatorlib/preferences.glade.h:145 + msgid "Plugin" +-msgstr "" ++msgstr "Insticksmodul" + + #: ../terminatorlib/preferences.glade.h:146 + msgid "This plugin has no configuration options" +@@ -1193,15 +1204,15 @@ + + #: ../terminatorlib/preferences.glade.h:159 + msgid "About" +-msgstr "" ++msgstr "Om" + + #: ../terminatorlib/prefseditor.py:96 + msgid "Increase font size" +-msgstr "" ++msgstr "Öka teckenstorlek" + + #: ../terminatorlib/prefseditor.py:97 + msgid "Decrease font size" +-msgstr "" ++msgstr "Minska teckenstorlek" + + #: ../terminatorlib/prefseditor.py:98 + msgid "Restore original font size" +@@ -1209,7 +1220,7 @@ + + #: ../terminatorlib/prefseditor.py:99 + msgid "Create a new tab" +-msgstr "" ++msgstr "Skapa en ny flik" + + #: ../terminatorlib/prefseditor.py:100 ../terminatorlib/prefseditor.py:102 + msgid "Focus the next terminal" +@@ -1257,11 +1268,11 @@ + + #: ../terminatorlib/prefseditor.py:113 + msgid "Copy selected text" +-msgstr "" ++msgstr "Kopiera markerad text" + + #: ../terminatorlib/prefseditor.py:114 + msgid "Paste clipboard" +-msgstr "" ++msgstr "Klistra in urklipp" + + #: ../terminatorlib/prefseditor.py:115 + msgid "Show/Hide the scrollbar" +@@ -1297,7 +1308,7 @@ + + #: ../terminatorlib/prefseditor.py:123 + msgid "Close window" +-msgstr "" ++msgstr "Stäng fönstret" + + #: ../terminatorlib/prefseditor.py:124 + msgid "Resize the terminal up" +@@ -1333,11 +1344,11 @@ + + #: ../terminatorlib/prefseditor.py:132 + msgid "Switch to the next tab" +-msgstr "" ++msgstr "Växla till nästa flik" + + #: ../terminatorlib/prefseditor.py:133 + msgid "Switch to the previous tab" +-msgstr "" ++msgstr "Växla till föregående flik" + + #: ../terminatorlib/prefseditor.py:134 + msgid "Switch to the first tab" +@@ -1381,7 +1392,7 @@ + + #: ../terminatorlib/prefseditor.py:144 + msgid "Toggle fullscreen" +-msgstr "" ++msgstr "Växla helskärmsläge" + + #: ../terminatorlib/prefseditor.py:145 + msgid "Reset the terminal" +@@ -1421,7 +1432,7 @@ + + #: ../terminatorlib/prefseditor.py:154 + msgid "Create a new window" +-msgstr "" ++msgstr "Skapa ett nytt fönster" + + #: ../terminatorlib/prefseditor.py:155 + msgid "Spawn a new Terminator process" +@@ -1473,7 +1484,7 @@ + + #: ../terminatorlib/prefseditor.py:167 + msgid "Open the manual" +-msgstr "" ++msgstr "Öppna handboken" + + #: ../terminatorlib/prefseditor.py:1136 ../terminatorlib/prefseditor.py:1141 + msgid "New Profile" +@@ -1683,19 +1694,19 @@ + + #: ../terminatorlib/titlebar.py:254 + msgid "Alpha" +-msgstr "" ++msgstr "Alfa" + + #: ../terminatorlib/titlebar.py:254 + msgid "Beta" +-msgstr "" ++msgstr "Beta" + + #: ../terminatorlib/titlebar.py:254 + msgid "Gamma" +-msgstr "" ++msgstr "Gamma" + + #: ../terminatorlib/titlebar.py:254 + msgid "Delta" +-msgstr "" ++msgstr "Delta" + + #: ../terminatorlib/titlebar.py:254 + msgid "Epsilon" +@@ -1743,7 +1754,7 @@ + + #: ../terminatorlib/titlebar.py:256 + msgid "Pi" +-msgstr "" ++msgstr "Pi" + + #: ../terminatorlib/titlebar.py:256 + msgid "Rho" +@@ -1751,7 +1762,7 @@ + + #: ../terminatorlib/titlebar.py:256 + msgid "Sigma" +-msgstr "" ++msgstr "Sigma" + + #: ../terminatorlib/titlebar.py:256 + msgid "Tau" +@@ -1775,7 +1786,7 @@ + + #: ../terminatorlib/titlebar.py:257 + msgid "Omega" +-msgstr "" ++msgstr "Omega" + + #: ../terminatorlib/window.py:276 + msgid "window" +diff -x .bzr -uNr terminator-1.91/po/ta.po python3/po/ta.po +--- terminator-1.91/po/ta.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ta.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ta\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/te.po python3/po/te.po +--- terminator-1.91/po/te.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/te.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: te\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/th.po python3/po/th.po +--- terminator-1.91/po/th.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/th.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: th\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/tr.po python3/po/tr.po +--- terminator-1.91/po/tr.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/tr.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: tr\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/tyv.po python3/po/tyv.po +--- terminator-1.91/po/tyv.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/tyv.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/ug.po python3/po/ug.po +--- terminator-1.91/po/ug.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ug.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 +diff -x .bzr -uNr terminator-1.91/po/uk.po python3/po/uk.po +--- terminator-1.91/po/uk.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/uk.po 2019-08-19 19:25:15.963479000 -0400 +@@ -8,52 +8,52 @@ + "Project-Id-Version: terminator\n" + "Report-Msgid-Bugs-To: \n" + "POT-Creation-Date: 2017-01-12 16:51+0100\n" +-"PO-Revision-Date: 2015-08-05 12:42+0000\n" +-"Last-Translator: Roman Koshkin \n" ++"PO-Revision-Date: 2017-06-15 12:47+0000\n" ++"Last-Translator: Rostyslav Gaitkulov \n" + "Language-Team: Ukrainian \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: uk\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 + msgid "Open a new window" +-msgstr "" ++msgstr "Відкрити нове вікно" + + #: ../remotinator.py:39 + msgid "Open a new tab" +-msgstr "" ++msgstr "Відкрити нову вкладку" + + #: ../remotinator.py:40 + msgid "Split the current terminal horizontally" +-msgstr "" ++msgstr "Розділити поточний термінал по горизонталі" + + #: ../remotinator.py:41 + msgid "Split the current terminal vertically" +-msgstr "" ++msgstr "Розділити поточний термінал по вертикалі" + + #: ../remotinator.py:42 + msgid "Get a list of all terminals" +-msgstr "" ++msgstr "Вивести список усіх терміналів" + + #: ../remotinator.py:43 + msgid "Get the UUID of a parent window" +-msgstr "" ++msgstr "Вивести UUID батьківського вікна" + + #: ../remotinator.py:44 + msgid "Get the title of a parent window" +-msgstr "" ++msgstr "Вивести заголовок батьківського вікна" + + #: ../remotinator.py:45 + msgid "Get the UUID of a parent tab" +-msgstr "" ++msgstr "Вивести UUID батьківської вкладки" + + #: ../remotinator.py:46 + msgid "Get the title of a parent tab" +-msgstr "" ++msgstr "Вивести заголовок батьківської вкладки" + + #: ../remotinator.py:63 + #, python-format +@@ -62,6 +62,9 @@ + "\n" + "%s" + msgstr "" ++"Виконати одну з наступних команд DBus:\n" ++"\n" ++"%s" + + #: ../remotinator.py:64 + msgid "" +diff -x .bzr -uNr terminator-1.91/po/ur.po python3/po/ur.po +--- terminator-1.91/po/ur.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/ur.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: ur\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/vi.po python3/po/vi.po +--- terminator-1.91/po/vi.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/vi.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: vi\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/wa.po python3/po/wa.po +--- terminator-1.91/po/wa.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/wa.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + + #. Command uuid req. Description + #: ../remotinator.py:38 +diff -x .bzr -uNr terminator-1.91/po/zh_CN.po python3/po/zh_CN.po +--- terminator-1.91/po/zh_CN.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/zh_CN.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/zh_HK.po python3/po/zh_HK.po +--- terminator-1.91/po/zh_HK.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/zh_HK.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: zh_HK\n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/po/zh_TW.po python3/po/zh_TW.po +--- terminator-1.91/po/zh_TW.po 2017-02-26 12:45:29.000000000 -0500 ++++ python3/po/zh_TW.po 2019-08-19 19:25:15.963479000 -0400 +@@ -14,8 +14,8 @@ + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"X-Launchpad-Export-Date: 2017-02-09 06:03+0000\n" +-"X-Generator: Launchpad (build 18326)\n" ++"X-Launchpad-Export-Date: 2017-08-02 06:13+0000\n" ++"X-Generator: Launchpad (build 18441)\n" + "Language: \n" + + #. Command uuid req. Description +diff -x .bzr -uNr terminator-1.91/RELEASING python3/RELEASING +--- terminator-1.91/RELEASING 1969-12-31 19:00:00.000000000 -0500 ++++ python3/RELEASING 2019-08-19 19:25:15.963479000 -0400 +@@ -0,0 +1,41 @@ ++Here are the steps to follow to create a new terminator release: ++ ++1. Ensure there are no local, uncommitted/unpushed modifications. ++ ++ $ bzr status ++ ++2. Verify the code passes checks and tests ++ ++ $ python setup.py test ++ $ python setup.py check ++ ++3. Update version number. Edit terminatorlib/version.py and set the ++ version number. Also edit terminator.spec and set it there. Edit ++ the debian/changelog to add new version. Update the Changelog ++ file if not already up-to-date. ++ ++4. Create the source distribution package ++ ++ $ python setup.py sdist ++ ++5. Sign the tarball ++ ++ $ gpg -u bryce@bryceharrington.org --armor --output ++ terminator-0.98.tar.gz.asc --detach-sig terminator-0.98.tar.gz ++ ++6. Upload to Launchpad ++ ++ + Create the appropriate Milestone ++ + Create a matching Release ++ + Upload the tarball and gpg signature to the Release ++ ++7. Tag the release in trunk ++ ++ $ bzr tag 0.98 ++ $ bzr push ++ ++8. Post announcements ++ ++ + Write a blog post ++ + Create an Announcement on the Launchpad page. ++ Include a link to the blog post URL +diff -x .bzr -uNr terminator-1.91/remotinator python3/remotinator +--- terminator-1.91/remotinator 2017-02-26 12:45:29.000000000 -0500 ++++ python3/remotinator 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # remotinator - send commands to Terminator via DBus + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -51,7 +51,7 @@ + + command_desc='' + for command in sorted(COMMANDS.keys()): +- command_desc += " %-*s %s %s\n" % (max([len(x) for x in COMMANDS.keys()]), ++ command_desc += " %-*s %s %s\n" % (max([len(x) for x in list(COMMANDS.keys())]), + command, + COMMANDS[command][0] and '*' or ' ', + COMMANDS[command][1]) +diff -x .bzr -uNr terminator-1.91/setup.py python3/setup.py +--- terminator-1.91/setup.py 2017-02-28 17:09:52.000000000 -0500 ++++ python3/setup.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + + from distutils.core import setup + from distutils.dist import Distribution +@@ -53,9 +53,9 @@ + try: + rc = subprocess.call(['msgfmt', '-o', mo, po]) + if rc != 0: +- raise Warning, "msgfmt returned %d" % rc +- except Exception, e: +- error("Building gettext files failed. Try setup.py --without-gettext [build|install]") ++ raise Warning("msgfmt returned %d" % rc) ++ except Exception as e: ++ error("Building gettext files failed. Ensure you have gettext installed. Alternatively, try setup.py --without-gettext [build|install]") + error("Error: %s" % str(e)) + sys.exit(1) + +@@ -63,14 +63,23 @@ + INTLTOOL_MERGE='intltool-merge' + desktop_in='data/terminator.desktop.in' + desktop_data='data/terminator.desktop' +- os.system ("C_ALL=C " + INTLTOOL_MERGE + " -d -u -c " + TOP_BUILDDIR + ++ rc = os.system ("C_ALL=C " + INTLTOOL_MERGE + " -d -u -c " + TOP_BUILDDIR + + "/po/.intltool-merge-cache " + TOP_BUILDDIR + "/po " + + desktop_in + " " + desktop_data) ++ if rc != 0: ++ # run the desktop_in through a command to strip the "_" characters ++ with open(desktop_in) as file_in, open(desktop_data, 'w') as file_data: ++ [file_data.write(line.lstrip('_')) for line in file_in] ++ + appdata_in='data/terminator.appdata.xml.in' + appdata_data='data/terminator.appdata.xml' +- os.system ("C_ALL=C " + INTLTOOL_MERGE + " -x -u -c " + TOP_BUILDDIR + ++ rc = os.system ("C_ALL=C " + INTLTOOL_MERGE + " -x -u -c " + TOP_BUILDDIR + + "/po/.intltool-merge-cache " + TOP_BUILDDIR + "/po " + + appdata_in + " " + appdata_data) ++ if rc != 0: ++ # run the appdata_in through a command to strip the "_" characters ++ with open(appdata_in) as file_in, open(appdata_data, 'w') as file_data: ++ [file_data.write(line.replace('<_','<').replace('= 2: ++ if OPTIONS.debug and OPTIONS.debug >= 2: + import terminatorlib.debugserver as debugserver + # pylint: disable-msg=W0611 + import threading +diff -x .bzr -uNr terminator-1.91/terminatorlib/borg.py python3/terminatorlib/borg.py +--- terminator-1.91/terminatorlib/borg.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/borg.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """borg.py - We are the borg. Resistance is futile. +@@ -9,14 +9,13 @@ + specific licencing terms. + """ + +-from util import dbg ++from .util import dbg + + # pylint: disable-msg=R0903 +-# pylint: disable-msg=R0921 + class Borg: + """Definition of a class that can never be duplicated. Correct usage is + thus: +- ++ + >>> from borg import Borg + >>> class foo(Borg): + ... # All attributes on a borg class *must* = None +@@ -29,13 +28,13 @@ + ... + >>> bar = foo() + >>> bar.prepare_attributes() +- ++ + The important thing to note is that all attributes of borg classes *must* be + declared as being None. If you attempt to use static class attributes you + will get unpredicted behaviour. Instead, prepare_attributes() must be called + which will then see the attributes in the shared state, and initialise them + if necessary.""" +- __shared_state = {} ++ __shared_state = {} + + def __init__(self, borgtype=None): + """Class initialiser. Overwrite our class dictionary with the shared +@@ -43,7 +42,7 @@ + type.""" + if borgtype is None: + raise TypeError('Borg::__init__: You must pass a borgtype') +- if not self.__shared_state.has_key(borgtype): ++ if borgtype not in self.__shared_state: + dbg('Borg::__init__: Preparing borg state for %s' % borgtype) + self.__shared_state[borgtype] = {} + self.__dict__ = self.__shared_state[borgtype] +diff -x .bzr -uNr terminator-1.91/terminatorlib/configobj/configobj.py python3/terminatorlib/configobj/configobj.py +--- terminator-1.91/terminatorlib/configobj/configobj.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/configobj/configobj.py 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2474 +0,0 @@ +-# configobj.py +-# A config file reader/writer that supports nested sections in config files. +-# Copyright (C) 2005-2010 Michael Foord, Nicola Larosa +-# E-mail: fuzzyman AT voidspace DOT org DOT uk +-# nico AT tekNico DOT net +- +-# ConfigObj 4 +-# http://www.voidspace.org.uk/python/configobj.html +- +-# Released subject to the BSD License +-# Please see http://www.voidspace.org.uk/python/license.shtml +- +-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml +-# For information about bugfixes, updates and support, please join the +-# ConfigObj mailing list: +-# http://lists.sourceforge.net/lists/listinfo/configobj-develop +-# Comments, suggestions and bug reports welcome. +- +-from __future__ import generators +- +-import os +-import re +-import sys +- +-from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE +- +- +-# imported lazily to avoid startup performance hit if it isn't used +-compiler = None +- +-# A dictionary mapping BOM to +-# the encoding to decode with, and what to set the +-# encoding attribute to. +-BOMS = { +- BOM_UTF8: ('utf_8', None), +- BOM_UTF16_BE: ('utf16_be', 'utf_16'), +- BOM_UTF16_LE: ('utf16_le', 'utf_16'), +- BOM_UTF16: ('utf_16', 'utf_16'), +- } +-# All legal variants of the BOM codecs. +-# TODO: the list of aliases is not meant to be exhaustive, is there a +-# better way ? +-BOM_LIST = { +- 'utf_16': 'utf_16', +- 'u16': 'utf_16', +- 'utf16': 'utf_16', +- 'utf-16': 'utf_16', +- 'utf16_be': 'utf16_be', +- 'utf_16_be': 'utf16_be', +- 'utf-16be': 'utf16_be', +- 'utf16_le': 'utf16_le', +- 'utf_16_le': 'utf16_le', +- 'utf-16le': 'utf16_le', +- 'utf_8': 'utf_8', +- 'u8': 'utf_8', +- 'utf': 'utf_8', +- 'utf8': 'utf_8', +- 'utf-8': 'utf_8', +- } +- +-# Map of encodings to the BOM to write. +-BOM_SET = { +- 'utf_8': BOM_UTF8, +- 'utf_16': BOM_UTF16, +- 'utf16_be': BOM_UTF16_BE, +- 'utf16_le': BOM_UTF16_LE, +- None: BOM_UTF8 +- } +- +- +-def match_utf8(encoding): +- return BOM_LIST.get(encoding.lower()) == 'utf_8' +- +- +-# Quote strings used for writing values +-squot = "'%s'" +-dquot = '"%s"' +-noquot = "%s" +-wspace_plus = ' \r\n\v\t\'"' +-tsquot = '"""%s"""' +-tdquot = "'''%s'''" +- +-# Sentinel for use in getattr calls to replace hasattr +-MISSING = object() +- +-__version__ = '4.7.2' +- +-try: +- any +-except NameError: +- def any(iterable): +- for entry in iterable: +- if entry: +- return True +- return False +- +- +-__all__ = ( +- '__version__', +- 'DEFAULT_INDENT_TYPE', +- 'DEFAULT_INTERPOLATION', +- 'ConfigObjError', +- 'NestingError', +- 'ParseError', +- 'DuplicateError', +- 'ConfigspecError', +- 'ConfigObj', +- 'SimpleVal', +- 'InterpolationError', +- 'InterpolationLoopError', +- 'MissingInterpolationOption', +- 'RepeatSectionError', +- 'ReloadError', +- 'UnreprError', +- 'UnknownType', +- 'flatten_errors', +- 'get_extra_values' +-) +- +-DEFAULT_INTERPOLATION = 'configparser' +-DEFAULT_INDENT_TYPE = ' ' +-MAX_INTERPOL_DEPTH = 10 +- +-OPTION_DEFAULTS = { +- 'interpolation': True, +- 'raise_errors': False, +- 'list_values': True, +- 'create_empty': False, +- 'file_error': False, +- 'configspec': None, +- 'stringify': True, +- # option may be set to one of ('', ' ', '\t') +- 'indent_type': None, +- 'encoding': None, +- 'default_encoding': None, +- 'unrepr': False, +- 'write_empty_values': False, +-} +- +- +- +-def getObj(s): +- global compiler +- if compiler is None: +- import compiler +- s = "a=" + s +- p = compiler.parse(s) +- return p.getChildren()[1].getChildren()[0].getChildren()[1] +- +- +-class UnknownType(Exception): +- pass +- +- +-class Builder(object): +- +- def build(self, o): +- m = getattr(self, 'build_' + o.__class__.__name__, None) +- if m is None: +- raise UnknownType(o.__class__.__name__) +- return m(o) +- +- def build_List(self, o): +- return map(self.build, o.getChildren()) +- +- def build_Const(self, o): +- return o.value +- +- def build_Dict(self, o): +- d = {} +- i = iter(map(self.build, o.getChildren())) +- for el in i: +- d[el] = i.next() +- return d +- +- def build_Tuple(self, o): +- return tuple(self.build_List(o)) +- +- def build_Name(self, o): +- if o.name == 'None': +- return None +- if o.name == 'True': +- return True +- if o.name == 'False': +- return False +- +- # An undefined Name +- raise UnknownType('Undefined Name') +- +- def build_Add(self, o): +- real, imag = map(self.build_Const, o.getChildren()) +- try: +- real = float(real) +- except TypeError: +- raise UnknownType('Add') +- if not isinstance(imag, complex) or imag.real != 0.0: +- raise UnknownType('Add') +- return real+imag +- +- def build_Getattr(self, o): +- parent = self.build(o.expr) +- return getattr(parent, o.attrname) +- +- def build_UnarySub(self, o): +- return -self.build_Const(o.getChildren()[0]) +- +- def build_UnaryAdd(self, o): +- return self.build_Const(o.getChildren()[0]) +- +- +-_builder = Builder() +- +- +-def unrepr(s): +- if not s: +- return s +- return _builder.build(getObj(s)) +- +- +- +-class ConfigObjError(SyntaxError): +- """ +- This is the base class for all errors that ConfigObj raises. +- It is a subclass of SyntaxError. +- """ +- def __init__(self, message='', line_number=None, line=''): +- self.line = line +- self.line_number = line_number +- SyntaxError.__init__(self, message) +- +- +-class NestingError(ConfigObjError): +- """ +- This error indicates a level of nesting that doesn't match. +- """ +- +- +-class ParseError(ConfigObjError): +- """ +- This error indicates that a line is badly written. +- It is neither a valid ``key = value`` line, +- nor a valid section marker line. +- """ +- +- +-class ReloadError(IOError): +- """ +- A 'reload' operation failed. +- This exception is a subclass of ``IOError``. +- """ +- def __init__(self): +- IOError.__init__(self, 'reload failed, filename is not set.') +- +- +-class DuplicateError(ConfigObjError): +- """ +- The keyword or section specified already exists. +- """ +- +- +-class ConfigspecError(ConfigObjError): +- """ +- An error occured whilst parsing a configspec. +- """ +- +- +-class InterpolationError(ConfigObjError): +- """Base class for the two interpolation errors.""" +- +- +-class InterpolationLoopError(InterpolationError): +- """Maximum interpolation depth exceeded in string interpolation.""" +- +- def __init__(self, option): +- InterpolationError.__init__( +- self, +- 'interpolation loop detected in value "%s".' % option) +- +- +-class RepeatSectionError(ConfigObjError): +- """ +- This error indicates additional sections in a section with a +- ``__many__`` (repeated) section. +- """ +- +- +-class MissingInterpolationOption(InterpolationError): +- """A value specified for interpolation was missing.""" +- def __init__(self, option): +- msg = 'missing option "%s" in interpolation.' % option +- InterpolationError.__init__(self, msg) +- +- +-class UnreprError(ConfigObjError): +- """An error parsing in unrepr mode.""" +- +- +- +-class InterpolationEngine(object): +- """ +- A helper class to help perform string interpolation. +- +- This class is an abstract base class; its descendants perform +- the actual work. +- """ +- +- # compiled regexp to use in self.interpolate() +- _KEYCRE = re.compile(r"%\(([^)]*)\)s") +- _cookie = '%' +- +- def __init__(self, section): +- # the Section instance that "owns" this engine +- self.section = section +- +- +- def interpolate(self, key, value): +- # short-cut +- if not self._cookie in value: +- return value +- +- def recursive_interpolate(key, value, section, backtrail): +- """The function that does the actual work. +- +- ``value``: the string we're trying to interpolate. +- ``section``: the section in which that string was found +- ``backtrail``: a dict to keep track of where we've been, +- to detect and prevent infinite recursion loops +- +- This is similar to a depth-first-search algorithm. +- """ +- # Have we been here already? +- if (key, section.name) in backtrail: +- # Yes - infinite loop detected +- raise InterpolationLoopError(key) +- # Place a marker on our backtrail so we won't come back here again +- backtrail[(key, section.name)] = 1 +- +- # Now start the actual work +- match = self._KEYCRE.search(value) +- while match: +- # The actual parsing of the match is implementation-dependent, +- # so delegate to our helper function +- k, v, s = self._parse_match(match) +- if k is None: +- # That's the signal that no further interpolation is needed +- replacement = v +- else: +- # Further interpolation may be needed to obtain final value +- replacement = recursive_interpolate(k, v, s, backtrail) +- # Replace the matched string with its final value +- start, end = match.span() +- value = ''.join((value[:start], replacement, value[end:])) +- new_search_start = start + len(replacement) +- # Pick up the next interpolation key, if any, for next time +- # through the while loop +- match = self._KEYCRE.search(value, new_search_start) +- +- # Now safe to come back here again; remove marker from backtrail +- del backtrail[(key, section.name)] +- +- return value +- +- # Back in interpolate(), all we have to do is kick off the recursive +- # function with appropriate starting values +- value = recursive_interpolate(key, value, self.section, {}) +- return value +- +- +- def _fetch(self, key): +- """Helper function to fetch values from owning section. +- +- Returns a 2-tuple: the value, and the section where it was found. +- """ +- # switch off interpolation before we try and fetch anything ! +- save_interp = self.section.main.interpolation +- self.section.main.interpolation = False +- +- # Start at section that "owns" this InterpolationEngine +- current_section = self.section +- while True: +- # try the current section first +- val = current_section.get(key) +- if val is not None and not isinstance(val, Section): +- break +- # try "DEFAULT" next +- val = current_section.get('DEFAULT', {}).get(key) +- if val is not None and not isinstance(val, Section): +- break +- # move up to parent and try again +- # top-level's parent is itself +- if current_section.parent is current_section: +- # reached top level, time to give up +- break +- current_section = current_section.parent +- +- # restore interpolation to previous value before returning +- self.section.main.interpolation = save_interp +- if val is None: +- raise MissingInterpolationOption(key) +- return val, current_section +- +- +- def _parse_match(self, match): +- """Implementation-dependent helper function. +- +- Will be passed a match object corresponding to the interpolation +- key we just found (e.g., "%(foo)s" or "$foo"). Should look up that +- key in the appropriate config file section (using the ``_fetch()`` +- helper function) and return a 3-tuple: (key, value, section) +- +- ``key`` is the name of the key we're looking for +- ``value`` is the value found for that key +- ``section`` is a reference to the section where it was found +- +- ``key`` and ``section`` should be None if no further +- interpolation should be performed on the resulting value +- (e.g., if we interpolated "$$" and returned "$"). +- """ +- raise NotImplementedError() +- +- +- +-class ConfigParserInterpolation(InterpolationEngine): +- """Behaves like ConfigParser.""" +- _cookie = '%' +- _KEYCRE = re.compile(r"%\(([^)]*)\)s") +- +- def _parse_match(self, match): +- key = match.group(1) +- value, section = self._fetch(key) +- return key, value, section +- +- +- +-class TemplateInterpolation(InterpolationEngine): +- """Behaves like string.Template.""" +- _cookie = '$' +- _delimiter = '$' +- _KEYCRE = re.compile(r""" +- \$(?: +- (?P\$) | # Two $ signs +- (?P[_a-z][_a-z0-9]*) | # $name format +- {(?P[^}]*)} # ${name} format +- ) +- """, re.IGNORECASE | re.VERBOSE) +- +- def _parse_match(self, match): +- # Valid name (in or out of braces): fetch value from section +- key = match.group('named') or match.group('braced') +- if key is not None: +- value, section = self._fetch(key) +- return key, value, section +- # Escaped delimiter (e.g., $$): return single delimiter +- if match.group('escaped') is not None: +- # Return None for key and section to indicate it's time to stop +- return None, self._delimiter, None +- # Anything else: ignore completely, just return it unchanged +- return None, match.group(), None +- +- +-interpolation_engines = { +- 'configparser': ConfigParserInterpolation, +- 'template': TemplateInterpolation, +-} +- +- +-def __newobj__(cls, *args): +- # Hack for pickle +- return cls.__new__(cls, *args) +- +-class Section(dict): +- """ +- A dictionary-like object that represents a section in a config file. +- +- It does string interpolation if the 'interpolation' attribute +- of the 'main' object is set to True. +- +- Interpolation is tried first from this object, then from the 'DEFAULT' +- section of this object, next from the parent and its 'DEFAULT' section, +- and so on until the main object is reached. +- +- A Section will behave like an ordered dictionary - following the +- order of the ``scalars`` and ``sections`` attributes. +- You can use this to change the order of members. +- +- Iteration follows the order: scalars, then sections. +- """ +- +- +- def __setstate__(self, state): +- dict.update(self, state[0]) +- self.__dict__.update(state[1]) +- +- def __reduce__(self): +- state = (dict(self), self.__dict__) +- return (__newobj__, (self.__class__,), state) +- +- +- def __init__(self, parent, depth, main, indict=None, name=None): +- """ +- * parent is the section above +- * depth is the depth level of this section +- * main is the main ConfigObj +- * indict is a dictionary to initialise the section with +- """ +- if indict is None: +- indict = {} +- dict.__init__(self) +- # used for nesting level *and* interpolation +- self.parent = parent +- # used for the interpolation attribute +- self.main = main +- # level of nesting depth of this Section +- self.depth = depth +- # purely for information +- self.name = name +- # +- self._initialise() +- # we do this explicitly so that __setitem__ is used properly +- # (rather than just passing to ``dict.__init__``) +- for entry, value in indict.iteritems(): +- self[entry] = value +- +- +- def _initialise(self): +- # the sequence of scalar values in this Section +- self.scalars = [] +- # the sequence of sections in this Section +- self.sections = [] +- # for comments :-) +- self.comments = {} +- self.inline_comments = {} +- # the configspec +- self.configspec = None +- # for defaults +- self.defaults = [] +- self.default_values = {} +- self.extra_values = [] +- self._created = False +- +- +- def _interpolate(self, key, value): +- try: +- # do we already have an interpolation engine? +- engine = self._interpolation_engine +- except AttributeError: +- # not yet: first time running _interpolate(), so pick the engine +- name = self.main.interpolation +- if name == True: # note that "if name:" would be incorrect here +- # backwards-compatibility: interpolation=True means use default +- name = DEFAULT_INTERPOLATION +- name = name.lower() # so that "Template", "template", etc. all work +- class_ = interpolation_engines.get(name, None) +- if class_ is None: +- # invalid value for self.main.interpolation +- self.main.interpolation = False +- return value +- else: +- # save reference to engine so we don't have to do this again +- engine = self._interpolation_engine = class_(self) +- # let the engine do the actual work +- return engine.interpolate(key, value) +- +- +- def __getitem__(self, key): +- """Fetch the item and do string interpolation.""" +- val = dict.__getitem__(self, key) +- if self.main.interpolation: +- if isinstance(val, basestring): +- return self._interpolate(key, val) +- if isinstance(val, list): +- def _check(entry): +- if isinstance(entry, basestring): +- return self._interpolate(key, entry) +- return entry +- new = [_check(entry) for entry in val] +- if new != val: +- return new +- return val +- +- +- def __setitem__(self, key, value, unrepr=False): +- """ +- Correctly set a value. +- +- Making dictionary values Section instances. +- (We have to special case 'Section' instances - which are also dicts) +- +- Keys must be strings. +- Values need only be strings (or lists of strings) if +- ``main.stringify`` is set. +- +- ``unrepr`` must be set when setting a value to a dictionary, without +- creating a new sub-section. +- """ +- if not isinstance(key, basestring): +- raise ValueError('The key "%s" is not a string.' % key) +- +- # add the comment +- if key not in self.comments: +- self.comments[key] = [] +- self.inline_comments[key] = '' +- # remove the entry from defaults +- if key in self.defaults: +- self.defaults.remove(key) +- # +- if isinstance(value, Section): +- if key not in self: +- self.sections.append(key) +- dict.__setitem__(self, key, value) +- elif isinstance(value, dict) and not unrepr: +- # First create the new depth level, +- # then create the section +- if key not in self: +- self.sections.append(key) +- new_depth = self.depth + 1 +- dict.__setitem__( +- self, +- key, +- Section( +- self, +- new_depth, +- self.main, +- indict=value, +- name=key)) +- else: +- if key not in self: +- self.scalars.append(key) +- if not self.main.stringify: +- if isinstance(value, basestring): +- pass +- elif isinstance(value, (list, tuple)): +- for entry in value: +- if not isinstance(entry, basestring): +- raise TypeError('Value is not a string "%s".' % entry) +- else: +- raise TypeError('Value is not a string "%s".' % value) +- dict.__setitem__(self, key, value) +- +- +- def __delitem__(self, key): +- """Remove items from the sequence when deleting.""" +- dict. __delitem__(self, key) +- if key in self.scalars: +- self.scalars.remove(key) +- else: +- self.sections.remove(key) +- del self.comments[key] +- del self.inline_comments[key] +- +- +- def get(self, key, default=None): +- """A version of ``get`` that doesn't bypass string interpolation.""" +- try: +- return self[key] +- except KeyError: +- return default +- +- +- def update(self, indict): +- """ +- A version of update that uses our ``__setitem__``. +- """ +- for entry in indict: +- self[entry] = indict[entry] +- +- +- def pop(self, key, default=MISSING): +- """ +- 'D.pop(k[,d]) -> v, remove specified key and return the corresponding value. +- If key is not found, d is returned if given, otherwise KeyError is raised' +- """ +- try: +- val = self[key] +- except KeyError: +- if default is MISSING: +- raise +- val = default +- else: +- del self[key] +- return val +- +- +- def popitem(self): +- """Pops the first (key,val)""" +- sequence = (self.scalars + self.sections) +- if not sequence: +- raise KeyError(": 'popitem(): dictionary is empty'") +- key = sequence[0] +- val = self[key] +- del self[key] +- return key, val +- +- +- def clear(self): +- """ +- A version of clear that also affects scalars/sections +- Also clears comments and configspec. +- +- Leaves other attributes alone : +- depth/main/parent are not affected +- """ +- dict.clear(self) +- self.scalars = [] +- self.sections = [] +- self.comments = {} +- self.inline_comments = {} +- self.configspec = None +- self.defaults = [] +- self.extra_values = [] +- +- +- def setdefault(self, key, default=None): +- """A version of setdefault that sets sequence if appropriate.""" +- try: +- return self[key] +- except KeyError: +- self[key] = default +- return self[key] +- +- +- def items(self): +- """D.items() -> list of D's (key, value) pairs, as 2-tuples""" +- return zip((self.scalars + self.sections), self.values()) +- +- +- def keys(self): +- """D.keys() -> list of D's keys""" +- return (self.scalars + self.sections) +- +- +- def values(self): +- """D.values() -> list of D's values""" +- return [self[key] for key in (self.scalars + self.sections)] +- +- +- def iteritems(self): +- """D.iteritems() -> an iterator over the (key, value) items of D""" +- return iter(self.items()) +- +- +- def iterkeys(self): +- """D.iterkeys() -> an iterator over the keys of D""" +- return iter((self.scalars + self.sections)) +- +- __iter__ = iterkeys +- +- +- def itervalues(self): +- """D.itervalues() -> an iterator over the values of D""" +- return iter(self.values()) +- +- +- def __repr__(self): +- """x.__repr__() <==> repr(x)""" +- def _getval(key): +- try: +- return self[key] +- except MissingInterpolationOption: +- return dict.__getitem__(self, key) +- return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) +- for key in (self.scalars + self.sections)]) +- +- __str__ = __repr__ +- __str__.__doc__ = "x.__str__() <==> str(x)" +- +- +- # Extra methods - not in a normal dictionary +- +- def dict(self): +- """ +- Return a deepcopy of self as a dictionary. +- +- All members that are ``Section`` instances are recursively turned to +- ordinary dictionaries - by calling their ``dict`` method. +- +- >>> n = a.dict() +- >>> n == a +- 1 +- >>> n is a +- 0 +- """ +- newdict = {} +- for entry in self: +- this_entry = self[entry] +- if isinstance(this_entry, Section): +- this_entry = this_entry.dict() +- elif isinstance(this_entry, list): +- # create a copy rather than a reference +- this_entry = list(this_entry) +- elif isinstance(this_entry, tuple): +- # create a copy rather than a reference +- this_entry = tuple(this_entry) +- newdict[entry] = this_entry +- return newdict +- +- +- def merge(self, indict): +- """ +- A recursive update - useful for merging config files. +- +- >>> a = '''[section1] +- ... option1 = True +- ... [[subsection]] +- ... more_options = False +- ... # end of file'''.splitlines() +- >>> b = '''# File is user.ini +- ... [section1] +- ... option1 = False +- ... # end of file'''.splitlines() +- >>> c1 = ConfigObj(b) +- >>> c2 = ConfigObj(a) +- >>> c2.merge(c1) +- >>> c2 +- ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}) +- """ +- for key, val in indict.items(): +- if (key in self and isinstance(self[key], dict) and +- isinstance(val, dict)): +- self[key].merge(val) +- else: +- self[key] = val +- +- +- def rename(self, oldkey, newkey): +- """ +- Change a keyname to another, without changing position in sequence. +- +- Implemented so that transformations can be made on keys, +- as well as on values. (used by encode and decode) +- +- Also renames comments. +- """ +- if oldkey in self.scalars: +- the_list = self.scalars +- elif oldkey in self.sections: +- the_list = self.sections +- else: +- raise KeyError('Key "%s" not found.' % oldkey) +- pos = the_list.index(oldkey) +- # +- val = self[oldkey] +- dict.__delitem__(self, oldkey) +- dict.__setitem__(self, newkey, val) +- the_list.remove(oldkey) +- the_list.insert(pos, newkey) +- comm = self.comments[oldkey] +- inline_comment = self.inline_comments[oldkey] +- del self.comments[oldkey] +- del self.inline_comments[oldkey] +- self.comments[newkey] = comm +- self.inline_comments[newkey] = inline_comment +- +- +- def walk(self, function, raise_errors=True, +- call_on_sections=False, **keywargs): +- """ +- Walk every member and call a function on the keyword and value. +- +- Return a dictionary of the return values +- +- If the function raises an exception, raise the errror +- unless ``raise_errors=False``, in which case set the return value to +- ``False``. +- +- Any unrecognised keyword arguments you pass to walk, will be pased on +- to the function you pass in. +- +- Note: if ``call_on_sections`` is ``True`` then - on encountering a +- subsection, *first* the function is called for the *whole* subsection, +- and then recurses into it's members. This means your function must be +- able to handle strings, dictionaries and lists. This allows you +- to change the key of subsections as well as for ordinary members. The +- return value when called on the whole subsection has to be discarded. +- +- See the encode and decode methods for examples, including functions. +- +- .. admonition:: caution +- +- You can use ``walk`` to transform the names of members of a section +- but you mustn't add or delete members. +- +- >>> config = '''[XXXXsection] +- ... XXXXkey = XXXXvalue'''.splitlines() +- >>> cfg = ConfigObj(config) +- >>> cfg +- ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}}) +- >>> def transform(section, key): +- ... val = section[key] +- ... newkey = key.replace('XXXX', 'CLIENT1') +- ... section.rename(key, newkey) +- ... if isinstance(val, (tuple, list, dict)): +- ... pass +- ... else: +- ... val = val.replace('XXXX', 'CLIENT1') +- ... section[newkey] = val +- >>> cfg.walk(transform, call_on_sections=True) +- {'CLIENT1section': {'CLIENT1key': None}} +- >>> cfg +- ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}}) +- """ +- out = {} +- # scalars first +- for i in range(len(self.scalars)): +- entry = self.scalars[i] +- try: +- val = function(self, entry, **keywargs) +- # bound again in case name has changed +- entry = self.scalars[i] +- out[entry] = val +- except Exception: +- if raise_errors: +- raise +- else: +- entry = self.scalars[i] +- out[entry] = False +- # then sections +- for i in range(len(self.sections)): +- entry = self.sections[i] +- if call_on_sections: +- try: +- function(self, entry, **keywargs) +- except Exception: +- if raise_errors: +- raise +- else: +- entry = self.sections[i] +- out[entry] = False +- # bound again in case name has changed +- entry = self.sections[i] +- # previous result is discarded +- out[entry] = self[entry].walk( +- function, +- raise_errors=raise_errors, +- call_on_sections=call_on_sections, +- **keywargs) +- return out +- +- +- def as_bool(self, key): +- """ +- Accepts a key as input. The corresponding value must be a string or +- the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to +- retain compatibility with Python 2.2. +- +- If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns +- ``True``. +- +- If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns +- ``False``. +- +- ``as_bool`` is not case sensitive. +- +- Any other input will raise a ``ValueError``. +- +- >>> a = ConfigObj() +- >>> a['a'] = 'fish' +- >>> a.as_bool('a') +- Traceback (most recent call last): +- ValueError: Value "fish" is neither True nor False +- >>> a['b'] = 'True' +- >>> a.as_bool('b') +- 1 +- >>> a['b'] = 'off' +- >>> a.as_bool('b') +- 0 +- """ +- val = self[key] +- if val == True: +- return True +- elif val == False: +- return False +- else: +- try: +- if not isinstance(val, basestring): +- # TODO: Why do we raise a KeyError here? +- raise KeyError() +- else: +- return self.main._bools[val.lower()] +- except KeyError: +- raise ValueError('Value "%s" is neither True nor False' % val) +- +- +- def as_int(self, key): +- """ +- A convenience method which coerces the specified value to an integer. +- +- If the value is an invalid literal for ``int``, a ``ValueError`` will +- be raised. +- +- >>> a = ConfigObj() +- >>> a['a'] = 'fish' +- >>> a.as_int('a') +- Traceback (most recent call last): +- ValueError: invalid literal for int() with base 10: 'fish' +- >>> a['b'] = '1' +- >>> a.as_int('b') +- 1 +- >>> a['b'] = '3.2' +- >>> a.as_int('b') +- Traceback (most recent call last): +- ValueError: invalid literal for int() with base 10: '3.2' +- """ +- return int(self[key]) +- +- +- def as_float(self, key): +- """ +- A convenience method which coerces the specified value to a float. +- +- If the value is an invalid literal for ``float``, a ``ValueError`` will +- be raised. +- +- >>> a = ConfigObj() +- >>> a['a'] = 'fish' +- >>> a.as_float('a') +- Traceback (most recent call last): +- ValueError: invalid literal for float(): fish +- >>> a['b'] = '1' +- >>> a.as_float('b') +- 1.0 +- >>> a['b'] = '3.2' +- >>> a.as_float('b') +- 3.2000000000000002 +- """ +- return float(self[key]) +- +- +- def as_list(self, key): +- """ +- A convenience method which fetches the specified value, guaranteeing +- that it is a list. +- +- >>> a = ConfigObj() +- >>> a['a'] = 1 +- >>> a.as_list('a') +- [1] +- >>> a['a'] = (1,) +- >>> a.as_list('a') +- [1] +- >>> a['a'] = [1] +- >>> a.as_list('a') +- [1] +- """ +- result = self[key] +- if isinstance(result, (tuple, list)): +- return list(result) +- return [result] +- +- +- def restore_default(self, key): +- """ +- Restore (and return) default value for the specified key. +- +- This method will only work for a ConfigObj that was created +- with a configspec and has been validated. +- +- If there is no default value for this key, ``KeyError`` is raised. +- """ +- default = self.default_values[key] +- dict.__setitem__(self, key, default) +- if key not in self.defaults: +- self.defaults.append(key) +- return default +- +- +- def restore_defaults(self): +- """ +- Recursively restore default values to all members +- that have them. +- +- This method will only work for a ConfigObj that was created +- with a configspec and has been validated. +- +- It doesn't delete or modify entries without default values. +- """ +- for key in self.default_values: +- self.restore_default(key) +- +- for section in self.sections: +- self[section].restore_defaults() +- +- +-class ConfigObj(Section): +- """An object to read, create, and write config files.""" +- +- _keyword = re.compile(r'''^ # line start +- (\s*) # indentation +- ( # keyword +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'"=].*?) # no quotes +- ) +- \s*=\s* # divider +- (.*) # value (including list values and comments) +- $ # line end +- ''', +- re.VERBOSE) +- +- _sectionmarker = re.compile(r'''^ +- (\s*) # 1: indentation +- ((?:\[\s*)+) # 2: section marker open +- ( # 3: section name open +- (?:"\s*\S.*?\s*")| # at least one non-space with double quotes +- (?:'\s*\S.*?\s*')| # at least one non-space with single quotes +- (?:[^'"\s].*?) # at least one non-space unquoted +- ) # section name close +- ((?:\s*\])+) # 4: section marker close +- \s*(\#.*)? # 5: optional comment +- $''', +- re.VERBOSE) +- +- # this regexp pulls list values out as a single string +- # or single values and comments +- # FIXME: this regex adds a '' to the end of comma terminated lists +- # workaround in ``_handle_value`` +- _valueexp = re.compile(r'''^ +- (?: +- (?: +- ( +- (?: +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\#][^,\#]*?) # unquoted +- ) +- \s*,\s* # comma +- )* # match all list items ending in a comma (if any) +- ) +- ( +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\#\s][^,]*?)| # unquoted +- (?:(? 1: +- msg = "Parsing failed with several errors.\nFirst error %s" % info +- error = ConfigObjError(msg) +- else: +- error = self._errors[0] +- # set the errors attribute; it's a list of tuples: +- # (error_type, message, line_number) +- error.errors = self._errors +- # set the config attribute +- error.config = self +- raise error +- # delete private attributes +- del self._errors +- +- if configspec is None: +- self.configspec = None +- else: +- self._handle_configspec(configspec) +- +- +- def _initialise(self, options=None): +- if options is None: +- options = OPTION_DEFAULTS +- +- # initialise a few variables +- self.filename = None +- self._errors = [] +- self.raise_errors = options['raise_errors'] +- self.interpolation = options['interpolation'] +- self.list_values = options['list_values'] +- self.create_empty = options['create_empty'] +- self.file_error = options['file_error'] +- self.stringify = options['stringify'] +- self.indent_type = options['indent_type'] +- self.encoding = options['encoding'] +- self.default_encoding = options['default_encoding'] +- self.BOM = False +- self.newlines = None +- self.write_empty_values = options['write_empty_values'] +- self.unrepr = options['unrepr'] +- +- self.initial_comment = [] +- self.final_comment = [] +- self.configspec = None +- +- if self._inspec: +- self.list_values = False +- +- # Clear section attributes as well +- Section._initialise(self) +- +- +- def __repr__(self): +- def _getval(key): +- try: +- return self[key] +- except MissingInterpolationOption: +- return dict.__getitem__(self, key) +- return ('ConfigObj({%s})' % +- ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) +- for key in (self.scalars + self.sections)])) +- +- +- def _handle_bom(self, infile): +- """ +- Handle any BOM, and decode if necessary. +- +- If an encoding is specified, that *must* be used - but the BOM should +- still be removed (and the BOM attribute set). +- +- (If the encoding is wrongly specified, then a BOM for an alternative +- encoding won't be discovered or removed.) +- +- If an encoding is not specified, UTF8 or UTF16 BOM will be detected and +- removed. The BOM attribute will be set. UTF16 will be decoded to +- unicode. +- +- NOTE: This method must not be called with an empty ``infile``. +- +- Specifying the *wrong* encoding is likely to cause a +- ``UnicodeDecodeError``. +- +- ``infile`` must always be returned as a list of lines, but may be +- passed in as a single string. +- """ +- if ((self.encoding is not None) and +- (self.encoding.lower() not in BOM_LIST)): +- # No need to check for a BOM +- # the encoding specified doesn't have one +- # just decode +- return self._decode(infile, self.encoding) +- +- if isinstance(infile, (list, tuple)): +- line = infile[0] +- else: +- line = infile +- if self.encoding is not None: +- # encoding explicitly supplied +- # And it could have an associated BOM +- # TODO: if encoding is just UTF16 - we ought to check for both +- # TODO: big endian and little endian versions. +- enc = BOM_LIST[self.encoding.lower()] +- if enc == 'utf_16': +- # For UTF16 we try big endian and little endian +- for BOM, (encoding, final_encoding) in BOMS.items(): +- if not final_encoding: +- # skip UTF8 +- continue +- if infile.startswith(BOM): +- ### BOM discovered +- ##self.BOM = True +- # Don't need to remove BOM +- return self._decode(infile, encoding) +- +- # If we get this far, will *probably* raise a DecodeError +- # As it doesn't appear to start with a BOM +- return self._decode(infile, self.encoding) +- +- # Must be UTF8 +- BOM = BOM_SET[enc] +- if not line.startswith(BOM): +- return self._decode(infile, self.encoding) +- +- newline = line[len(BOM):] +- +- # BOM removed +- if isinstance(infile, (list, tuple)): +- infile[0] = newline +- else: +- infile = newline +- self.BOM = True +- return self._decode(infile, self.encoding) +- +- # No encoding specified - so we need to check for UTF8/UTF16 +- for BOM, (encoding, final_encoding) in BOMS.items(): +- if not line.startswith(BOM): +- continue +- else: +- # BOM discovered +- self.encoding = final_encoding +- if not final_encoding: +- self.BOM = True +- # UTF8 +- # remove BOM +- newline = line[len(BOM):] +- if isinstance(infile, (list, tuple)): +- infile[0] = newline +- else: +- infile = newline +- # UTF8 - don't decode +- if isinstance(infile, basestring): +- return infile.splitlines(True) +- else: +- return infile +- # UTF16 - have to decode +- return self._decode(infile, encoding) +- +- # No BOM discovered and no encoding specified, just return +- if isinstance(infile, basestring): +- # infile read from a file will be a single string +- return infile.splitlines(True) +- return infile +- +- +- def _a_to_u(self, aString): +- """Decode ASCII strings to unicode if a self.encoding is specified.""" +- if self.encoding: +- return aString.decode('ascii') +- else: +- return aString +- +- +- def _decode(self, infile, encoding): +- """ +- Decode infile to unicode. Using the specified encoding. +- +- if is a string, it also needs converting to a list. +- """ +- if isinstance(infile, basestring): +- # can't be unicode +- # NOTE: Could raise a ``UnicodeDecodeError`` +- return infile.decode(encoding).splitlines(True) +- for i, line in enumerate(infile): +- if not isinstance(line, unicode): +- # NOTE: The isinstance test here handles mixed lists of unicode/string +- # NOTE: But the decode will break on any non-string values +- # NOTE: Or could raise a ``UnicodeDecodeError`` +- infile[i] = line.decode(encoding) +- return infile +- +- +- def _decode_element(self, line): +- """Decode element to unicode if necessary.""" +- if not self.encoding: +- return line +- if isinstance(line, str) and self.default_encoding: +- return line.decode(self.default_encoding) +- return line +- +- +- def _str(self, value): +- """ +- Used by ``stringify`` within validate, to turn non-string values +- into strings. +- """ +- if not isinstance(value, basestring): +- return str(value) +- else: +- return value +- +- +- def _parse(self, infile): +- """Actually parse the config file.""" +- temp_list_values = self.list_values +- if self.unrepr: +- self.list_values = False +- +- comment_list = [] +- done_start = False +- this_section = self +- maxline = len(infile) - 1 +- cur_index = -1 +- reset_comment = False +- +- while cur_index < maxline: +- if reset_comment: +- comment_list = [] +- cur_index += 1 +- line = infile[cur_index] +- sline = line.strip() +- # do we have anything on the line ? +- if not sline or sline.startswith('#'): +- reset_comment = False +- comment_list.append(line) +- continue +- +- if not done_start: +- # preserve initial comment +- self.initial_comment = comment_list +- comment_list = [] +- done_start = True +- +- reset_comment = True +- # first we check if it's a section marker +- mat = self._sectionmarker.match(line) +- if mat is not None: +- # is a section line +- (indent, sect_open, sect_name, sect_close, comment) = mat.groups() +- if indent and (self.indent_type is None): +- self.indent_type = indent +- cur_depth = sect_open.count('[') +- if cur_depth != sect_close.count(']'): +- self._handle_error("Cannot compute the section depth at line %s.", +- NestingError, infile, cur_index) +- continue +- +- if cur_depth < this_section.depth: +- # the new section is dropping back to a previous level +- try: +- parent = self._match_depth(this_section, +- cur_depth).parent +- except SyntaxError: +- self._handle_error("Cannot compute nesting level at line %s.", +- NestingError, infile, cur_index) +- continue +- elif cur_depth == this_section.depth: +- # the new section is a sibling of the current section +- parent = this_section.parent +- elif cur_depth == this_section.depth + 1: +- # the new section is a child the current section +- parent = this_section +- else: +- self._handle_error("Section too nested at line %s.", +- NestingError, infile, cur_index) +- +- sect_name = self._unquote(sect_name) +- if sect_name in parent: +- self._handle_error('Duplicate section name at line %s.', +- DuplicateError, infile, cur_index) +- continue +- +- # create the new section +- this_section = Section( +- parent, +- cur_depth, +- self, +- name=sect_name) +- parent[sect_name] = this_section +- parent.inline_comments[sect_name] = comment +- parent.comments[sect_name] = comment_list +- continue +- # +- # it's not a section marker, +- # so it should be a valid ``key = value`` line +- mat = self._keyword.match(line) +- if mat is None: +- # it neither matched as a keyword +- # or a section marker +- self._handle_error( +- 'Invalid line at line "%s".', +- ParseError, infile, cur_index) +- else: +- # is a keyword value +- # value will include any inline comment +- (indent, key, value) = mat.groups() +- if indent and (self.indent_type is None): +- self.indent_type = indent +- # check for a multiline value +- if value[:3] in ['"""', "'''"]: +- try: +- value, comment, cur_index = self._multiline( +- value, infile, cur_index, maxline) +- except SyntaxError: +- self._handle_error( +- 'Parse error in value at line %s.', +- ParseError, infile, cur_index) +- continue +- else: +- if self.unrepr: +- comment = '' +- try: +- value = unrepr(value) +- except Exception, e: +- if type(e) == UnknownType: +- msg = 'Unknown name or type in value at line %s.' +- else: +- msg = 'Parse error in value at line %s.' +- self._handle_error(msg, UnreprError, infile, +- cur_index) +- continue +- else: +- if self.unrepr: +- comment = '' +- try: +- value = unrepr(value) +- except Exception, e: +- if isinstance(e, UnknownType): +- msg = 'Unknown name or type in value at line %s.' +- else: +- msg = 'Parse error in value at line %s.' +- self._handle_error(msg, UnreprError, infile, +- cur_index) +- continue +- else: +- # extract comment and lists +- try: +- (value, comment) = self._handle_value(value) +- except SyntaxError: +- self._handle_error( +- 'Parse error in value at line %s.', +- ParseError, infile, cur_index) +- continue +- # +- key = self._unquote(key) +- if key in this_section: +- self._handle_error( +- 'Duplicate keyword name at line %s.', +- DuplicateError, infile, cur_index) +- continue +- # add the key. +- # we set unrepr because if we have got this far we will never +- # be creating a new section +- this_section.__setitem__(key, value, unrepr=True) +- this_section.inline_comments[key] = comment +- this_section.comments[key] = comment_list +- continue +- # +- if self.indent_type is None: +- # no indentation used, set the type accordingly +- self.indent_type = '' +- +- # preserve the final comment +- if not self and not self.initial_comment: +- self.initial_comment = comment_list +- elif not reset_comment: +- self.final_comment = comment_list +- self.list_values = temp_list_values +- +- +- def _match_depth(self, sect, depth): +- """ +- Given a section and a depth level, walk back through the sections +- parents to see if the depth level matches a previous section. +- +- Return a reference to the right section, +- or raise a SyntaxError. +- """ +- while depth < sect.depth: +- if sect is sect.parent: +- # we've reached the top level already +- raise SyntaxError() +- sect = sect.parent +- if sect.depth == depth: +- return sect +- # shouldn't get here +- raise SyntaxError() +- +- +- def _handle_error(self, text, ErrorClass, infile, cur_index): +- """ +- Handle an error according to the error settings. +- +- Either raise the error or store it. +- The error will have occured at ``cur_index`` +- """ +- line = infile[cur_index] +- cur_index += 1 +- message = text % cur_index +- error = ErrorClass(message, cur_index, line) +- if self.raise_errors: +- # raise the error - parsing stops here +- raise error +- # store the error +- # reraise when parsing has finished +- self._errors.append(error) +- +- +- def _unquote(self, value): +- """Return an unquoted version of a value""" +- if not value: +- # should only happen during parsing of lists +- raise SyntaxError +- if (value[0] == value[-1]) and (value[0] in ('"', "'")): +- value = value[1:-1] +- return value +- +- +- def _quote(self, value, multiline=True): +- """ +- Return a safely quoted version of a value. +- +- Raise a ConfigObjError if the value cannot be safely quoted. +- If multiline is ``True`` (default) then use triple quotes +- if necessary. +- +- * Don't quote values that don't need it. +- * Recursively quote members of a list and return a comma joined list. +- * Multiline is ``False`` for lists. +- * Obey list syntax for empty and single member lists. +- +- If ``list_values=False`` then the value is only quoted if it contains +- a ``\\n`` (is multiline) or '#'. +- +- If ``write_empty_values`` is set, and the value is an empty string, it +- won't be quoted. +- """ +- if multiline and self.write_empty_values and value == '': +- # Only if multiline is set, so that it is used for values not +- # keys, and not values that are part of a list +- return '' +- +- if multiline and isinstance(value, (list, tuple)): +- if not value: +- return ',' +- elif len(value) == 1: +- return self._quote(value[0], multiline=False) + ',' +- return ', '.join([self._quote(val, multiline=False) +- for val in value]) +- if not isinstance(value, basestring): +- if self.stringify: +- value = str(value) +- else: +- raise TypeError('Value "%s" is not a string.' % value) +- +- if not value: +- return '""' +- +- no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value +- need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value )) +- hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value) +- check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote +- +- if check_for_single: +- if not self.list_values: +- # we don't quote if ``list_values=False`` +- quot = noquot +- # for normal values either single or double quotes will do +- elif '\n' in value: +- # will only happen if multiline is off - e.g. '\n' in key +- raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) +- elif ((value[0] not in wspace_plus) and +- (value[-1] not in wspace_plus) and +- (',' not in value)): +- quot = noquot +- else: +- quot = self._get_single_quote(value) +- else: +- # if value has '\n' or "'" *and* '"', it will need triple quotes +- quot = self._get_triple_quote(value) +- +- if quot == noquot and '#' in value and self.list_values: +- quot = self._get_single_quote(value) +- +- return quot % value +- +- +- def _get_single_quote(self, value): +- if ("'" in value) and ('"' in value): +- raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) +- elif '"' in value: +- quot = squot +- else: +- quot = dquot +- return quot +- +- +- def _get_triple_quote(self, value): +- if (value.find('"""') != -1) and (value.find("'''") != -1): +- raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) +- if value.find('"""') == -1: +- quot = tdquot +- else: +- quot = tsquot +- return quot +- +- +- def _handle_value(self, value): +- """ +- Given a value string, unquote, remove comment, +- handle lists. (including empty and single member lists) +- """ +- if self._inspec: +- # Parsing a configspec so don't handle comments +- return (value, '') +- # do we look for lists in values ? +- if not self.list_values: +- mat = self._nolistvalue.match(value) +- if mat is None: +- raise SyntaxError() +- # NOTE: we don't unquote here +- return mat.groups() +- # +- mat = self._valueexp.match(value) +- if mat is None: +- # the value is badly constructed, probably badly quoted, +- # or an invalid list +- raise SyntaxError() +- (list_values, single, empty_list, comment) = mat.groups() +- if (list_values == '') and (single is None): +- # change this if you want to accept empty values +- raise SyntaxError() +- # NOTE: note there is no error handling from here if the regex +- # is wrong: then incorrect values will slip through +- if empty_list is not None: +- # the single comma - meaning an empty list +- return ([], comment) +- if single is not None: +- # handle empty values +- if list_values and not single: +- # FIXME: the '' is a workaround because our regex now matches +- # '' at the end of a list if it has a trailing comma +- single = None +- else: +- single = single or '""' +- single = self._unquote(single) +- if list_values == '': +- # not a list value +- return (single, comment) +- the_list = self._listvalueexp.findall(list_values) +- the_list = [self._unquote(val) for val in the_list] +- if single is not None: +- the_list += [single] +- return (the_list, comment) +- +- +- def _multiline(self, value, infile, cur_index, maxline): +- """Extract the value, where we are in a multiline situation.""" +- quot = value[:3] +- newvalue = value[3:] +- single_line = self._triple_quote[quot][0] +- multi_line = self._triple_quote[quot][1] +- mat = single_line.match(value) +- if mat is not None: +- retval = list(mat.groups()) +- retval.append(cur_index) +- return retval +- elif newvalue.find(quot) != -1: +- # somehow the triple quote is missing +- raise SyntaxError() +- # +- while cur_index < maxline: +- cur_index += 1 +- newvalue += '\n' +- line = infile[cur_index] +- if line.find(quot) == -1: +- newvalue += line +- else: +- # end of multiline, process it +- break +- else: +- # we've got to the end of the config, oops... +- raise SyntaxError() +- mat = multi_line.match(line) +- if mat is None: +- # a badly formed line +- raise SyntaxError() +- (value, comment) = mat.groups() +- return (newvalue + value, comment, cur_index) +- +- +- def _handle_configspec(self, configspec): +- """Parse the configspec.""" +- # FIXME: Should we check that the configspec was created with the +- # correct settings ? (i.e. ``list_values=False``) +- if not isinstance(configspec, ConfigObj): +- try: +- configspec = ConfigObj(configspec, +- raise_errors=True, +- file_error=True, +- _inspec=True) +- except ConfigObjError, e: +- # FIXME: Should these errors have a reference +- # to the already parsed ConfigObj ? +- raise ConfigspecError('Parsing configspec failed: %s' % e) +- except IOError, e: +- raise IOError('Reading configspec failed: %s' % e) +- +- self.configspec = configspec +- +- +- +- def _set_configspec(self, section, copy): +- """ +- Called by validate. Handles setting the configspec on subsections +- including sections to be validated by __many__ +- """ +- configspec = section.configspec +- many = configspec.get('__many__') +- if isinstance(many, dict): +- for entry in section.sections: +- if entry not in configspec: +- section[entry].configspec = many +- +- for entry in configspec.sections: +- if entry == '__many__': +- continue +- if entry not in section: +- section[entry] = {} +- section[entry]._created = True +- if copy: +- # copy comments +- section.comments[entry] = configspec.comments.get(entry, []) +- section.inline_comments[entry] = configspec.inline_comments.get(entry, '') +- +- # Could be a scalar when we expect a section +- if isinstance(section[entry], Section): +- section[entry].configspec = configspec[entry] +- +- +- def _write_line(self, indent_string, entry, this_entry, comment): +- """Write an individual line, for the write method""" +- # NOTE: the calls to self._quote here handles non-StringType values. +- if not self.unrepr: +- val = self._decode_element(self._quote(this_entry)) +- else: +- val = repr(this_entry) +- return '%s%s%s%s%s' % (indent_string, +- self._decode_element(self._quote(entry, multiline=False)), +- self._a_to_u(' = '), +- val, +- self._decode_element(comment)) +- +- +- def _write_marker(self, indent_string, depth, entry, comment): +- """Write a section marker line""" +- return '%s%s%s%s%s' % (indent_string, +- self._a_to_u('[' * depth), +- self._quote(self._decode_element(entry), multiline=False), +- self._a_to_u(']' * depth), +- self._decode_element(comment)) +- +- +- def _handle_comment(self, comment): +- """Deal with a comment.""" +- if not comment: +- return '' +- start = self.indent_type +- if not comment.startswith('#'): +- start += self._a_to_u(' # ') +- return (start + comment) +- +- +- # Public methods +- +- def write(self, outfile=None, section=None): +- """ +- Write the current ConfigObj as a file +- +- tekNico: FIXME: use StringIO instead of real files +- +- >>> filename = a.filename +- >>> a.filename = 'test.ini' +- >>> a.write() +- >>> a.filename = filename +- >>> a == ConfigObj('test.ini', raise_errors=True) +- 1 +- >>> import os +- >>> os.remove('test.ini') +- """ +- if self.indent_type is None: +- # this can be true if initialised from a dictionary +- self.indent_type = DEFAULT_INDENT_TYPE +- +- out = [] +- cs = self._a_to_u('#') +- csp = self._a_to_u('# ') +- if section is None: +- int_val = self.interpolation +- self.interpolation = False +- section = self +- for line in self.initial_comment: +- line = self._decode_element(line) +- stripped_line = line.strip() +- if stripped_line and not stripped_line.startswith(cs): +- line = csp + line +- out.append(line) +- +- indent_string = self.indent_type * section.depth +- +- # Do a little sorting for convenience +- section.scalars = sorted(section.scalars) +- section.sections = sorted(section.sections) +- if 'default' in section.scalars: +- # pop it and move to front +- section.scalars.remove('default') +- section.scalars.insert(0, 'default') +- if 'default' in section.sections: +- section.sections.remove('default') +- section.sections.insert(0, 'default') +- +- for entry in (section.scalars + section.sections): +- if entry in section.defaults: +- # don't write out default values +- continue +- for comment_line in section.comments[entry]: +- comment_line = self._decode_element(comment_line.lstrip()) +- if comment_line and not comment_line.startswith(cs): +- comment_line = csp + comment_line +- out.append(indent_string + comment_line) +- this_entry = section[entry] +- comment = self._handle_comment(section.inline_comments[entry]) +- +- if isinstance(this_entry, dict): +- # a section +- out.append(self._write_marker( +- indent_string, +- this_entry.depth, +- entry, +- comment)) +- out.extend(self.write(section=this_entry)) +- else: +- out.append(self._write_line( +- indent_string, +- entry, +- this_entry, +- comment)) +- +- if section is self: +- for line in self.final_comment: +- line = self._decode_element(line) +- stripped_line = line.strip() +- if stripped_line and not stripped_line.startswith(cs): +- line = csp + line +- out.append(line) +- self.interpolation = int_val +- +- if section is not self: +- return out +- +- if (self.filename is None) and (outfile is None): +- # output a list of lines +- # might need to encode +- # NOTE: This will *screw* UTF16, each line will start with the BOM +- if self.encoding: +- out = [l.encode(self.encoding) for l in out] +- if (self.BOM and ((self.encoding is None) or +- (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))): +- # Add the UTF8 BOM +- if not out: +- out.append('') +- out[0] = BOM_UTF8 + out[0] +- return out +- +- # Turn the list to a string, joined with correct newlines +- newline = self.newlines or os.linesep +- if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w' +- and sys.platform == 'win32' and newline == '\r\n'): +- # Windows specific hack to avoid writing '\r\r\n' +- newline = '\n' +- output = self._a_to_u(newline).join(out) +- if self.encoding: +- output = output.encode(self.encoding) +- if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)): +- # Add the UTF8 BOM +- output = BOM_UTF8 + output +- +- if not output.endswith(newline): +- output += newline +- if outfile is not None: +- outfile.write(output) +- else: +- h = open(self.filename, 'wb') +- h.write(output) +- h.close() +- +- +- def validate(self, validator, preserve_errors=False, copy=False, +- section=None): +- """ +- Test the ConfigObj against a configspec. +- +- It uses the ``validator`` object from *validate.py*. +- +- To run ``validate`` on the current ConfigObj, call: :: +- +- test = config.validate(validator) +- +- (Normally having previously passed in the configspec when the ConfigObj +- was created - you can dynamically assign a dictionary of checks to the +- ``configspec`` attribute of a section though). +- +- It returns ``True`` if everything passes, or a dictionary of +- pass/fails (True/False). If every member of a subsection passes, it +- will just have the value ``True``. (It also returns ``False`` if all +- members fail). +- +- In addition, it converts the values from strings to their native +- types if their checks pass (and ``stringify`` is set). +- +- If ``preserve_errors`` is ``True`` (``False`` is default) then instead +- of a marking a fail with a ``False``, it will preserve the actual +- exception object. This can contain info about the reason for failure. +- For example the ``VdtValueTooSmallError`` indicates that the value +- supplied was too small. If a value (or section) is missing it will +- still be marked as ``False``. +- +- You must have the validate module to use ``preserve_errors=True``. +- +- You can then use the ``flatten_errors`` function to turn your nested +- results dictionary into a flattened list of failures - useful for +- displaying meaningful error messages. +- """ +- if section is None: +- if self.configspec is None: +- raise ValueError('No configspec supplied.') +- if preserve_errors: +- # We do this once to remove a top level dependency on the validate module +- # Which makes importing configobj faster +- from validate import VdtMissingValue +- self._vdtMissingValue = VdtMissingValue +- +- section = self +- +- if copy: +- section.initial_comment = section.configspec.initial_comment +- section.final_comment = section.configspec.final_comment +- section.encoding = section.configspec.encoding +- section.BOM = section.configspec.BOM +- section.newlines = section.configspec.newlines +- section.indent_type = section.configspec.indent_type +- +- # +- # section.default_values.clear() #?? +- configspec = section.configspec +- self._set_configspec(section, copy) +- +- +- def validate_entry(entry, spec, val, missing, ret_true, ret_false): +- section.default_values.pop(entry, None) +- +- try: +- section.default_values[entry] = validator.get_default_value(configspec[entry]) +- except (KeyError, AttributeError, validator.baseErrorClass): +- # No default, bad default or validator has no 'get_default_value' +- # (e.g. SimpleVal) +- pass +- +- try: +- check = validator.check(spec, +- val, +- missing=missing +- ) +- except validator.baseErrorClass, e: +- if not preserve_errors or isinstance(e, self._vdtMissingValue): +- out[entry] = False +- else: +- # preserve the error +- out[entry] = e +- ret_false = False +- ret_true = False +- else: +- ret_false = False +- out[entry] = True +- if self.stringify or missing: +- # if we are doing type conversion +- # or the value is a supplied default +- if not self.stringify: +- if isinstance(check, (list, tuple)): +- # preserve lists +- check = [self._str(item) for item in check] +- elif missing and check is None: +- # convert the None from a default to a '' +- check = '' +- else: +- check = self._str(check) +- if (check != val) or missing: +- section[entry] = check +- if not copy and missing and entry not in section.defaults: +- section.defaults.append(entry) +- return ret_true, ret_false +- +- # +- out = {} +- ret_true = True +- ret_false = True +- +- unvalidated = [k for k in section.scalars if k not in configspec] +- incorrect_sections = [k for k in configspec.sections if k in section.scalars] +- incorrect_scalars = [k for k in configspec.scalars if k in section.sections] +- +- for entry in configspec.scalars: +- if entry in ('__many__', '___many___'): +- # reserved names +- continue +- if (not entry in section.scalars) or (entry in section.defaults): +- # missing entries +- # or entries from defaults +- missing = True +- val = None +- if copy and entry not in section.scalars: +- # copy comments +- section.comments[entry] = ( +- configspec.comments.get(entry, [])) +- section.inline_comments[entry] = ( +- configspec.inline_comments.get(entry, '')) +- # +- else: +- missing = False +- val = section[entry] +- +- ret_true, ret_false = validate_entry(entry, configspec[entry], val, +- missing, ret_true, ret_false) +- +- many = None +- if '__many__' in configspec.scalars: +- many = configspec['__many__'] +- elif '___many___' in configspec.scalars: +- many = configspec['___many___'] +- +- if many is not None: +- for entry in unvalidated: +- val = section[entry] +- ret_true, ret_false = validate_entry(entry, many, val, False, +- ret_true, ret_false) +- unvalidated = [] +- +- for entry in incorrect_scalars: +- ret_true = False +- if not preserve_errors: +- out[entry] = False +- else: +- ret_false = False +- msg = 'Value %r was provided as a section' % entry +- out[entry] = validator.baseErrorClass(msg) +- for entry in incorrect_sections: +- ret_true = False +- if not preserve_errors: +- out[entry] = False +- else: +- ret_false = False +- msg = 'Section %r was provided as a single value' % entry +- out[entry] = validator.baseErrorClass(msg) +- +- # Missing sections will have been created as empty ones when the +- # configspec was read. +- for entry in section.sections: +- # FIXME: this means DEFAULT is not copied in copy mode +- if section is self and entry == 'DEFAULT': +- continue +- if section[entry].configspec is None: +- unvalidated.append(entry) +- continue +- if copy: +- section.comments[entry] = configspec.comments.get(entry, []) +- section.inline_comments[entry] = configspec.inline_comments.get(entry, '') +- check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry]) +- out[entry] = check +- if check == False: +- ret_true = False +- elif check == True: +- ret_false = False +- else: +- ret_true = False +- +- section.extra_values = unvalidated +- if preserve_errors and not section._created: +- # If the section wasn't created (i.e. it wasn't missing) +- # then we can't return False, we need to preserve errors +- ret_false = False +- # +- if ret_false and preserve_errors and out: +- # If we are preserving errors, but all +- # the failures are from missing sections / values +- # then we can return False. Otherwise there is a +- # real failure that we need to preserve. +- ret_false = not any(out.values()) +- if ret_true: +- return True +- elif ret_false: +- return False +- return out +- +- +- def reset(self): +- """Clear ConfigObj instance and restore to 'freshly created' state.""" +- self.clear() +- self._initialise() +- # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload) +- # requires an empty dictionary +- self.configspec = None +- # Just to be sure ;-) +- self._original_configspec = None +- +- +- def reload(self): +- """ +- Reload a ConfigObj from file. +- +- This method raises a ``ReloadError`` if the ConfigObj doesn't have +- a filename attribute pointing to a file. +- """ +- if not isinstance(self.filename, basestring): +- raise ReloadError() +- +- filename = self.filename +- current_options = {} +- for entry in OPTION_DEFAULTS: +- if entry == 'configspec': +- continue +- current_options[entry] = getattr(self, entry) +- +- configspec = self._original_configspec +- current_options['configspec'] = configspec +- +- self.clear() +- self._initialise(current_options) +- self._load(filename, configspec) +- +- +- +-class SimpleVal(object): +- """ +- A simple validator. +- Can be used to check that all members expected are present. +- +- To use it, provide a configspec with all your members in (the value given +- will be ignored). Pass an instance of ``SimpleVal`` to the ``validate`` +- method of your ``ConfigObj``. ``validate`` will return ``True`` if all +- members are present, or a dictionary with True/False meaning +- present/missing. (Whole missing sections will be replaced with ``False``) +- """ +- +- def __init__(self): +- self.baseErrorClass = ConfigObjError +- +- def check(self, check, member, missing=False): +- """A dummy check method, always returns the value unchanged.""" +- if missing: +- raise self.baseErrorClass() +- return member +- +- +-def flatten_errors(cfg, res, levels=None, results=None): +- """ +- An example function that will turn a nested dictionary of results +- (as returned by ``ConfigObj.validate``) into a flat list. +- +- ``cfg`` is the ConfigObj instance being checked, ``res`` is the results +- dictionary returned by ``validate``. +- +- (This is a recursive function, so you shouldn't use the ``levels`` or +- ``results`` arguments - they are used by the function.) +- +- Returns a list of keys that failed. Each member of the list is a tuple:: +- +- ([list of sections...], key, result) +- +- If ``validate`` was called with ``preserve_errors=False`` (the default) +- then ``result`` will always be ``False``. +- +- *list of sections* is a flattened list of sections that the key was found +- in. +- +- If the section was missing (or a section was expected and a scalar provided +- - or vice-versa) then key will be ``None``. +- +- If the value (or section) was missing then ``result`` will be ``False``. +- +- If ``validate`` was called with ``preserve_errors=True`` and a value +- was present, but failed the check, then ``result`` will be the exception +- object returned. You can use this as a string that describes the failure. +- +- For example *The value "3" is of the wrong type*. +- """ +- if levels is None: +- # first time called +- levels = [] +- results = [] +- if res == True: +- return results +- if res == False or isinstance(res, Exception): +- results.append((levels[:], None, res)) +- if levels: +- levels.pop() +- return results +- for (key, val) in res.items(): +- if val == True: +- continue +- if isinstance(cfg.get(key), dict): +- # Go down one level +- levels.append(key) +- flatten_errors(cfg[key], val, levels, results) +- continue +- results.append((levels[:], key, val)) +- # +- # Go up one level +- if levels: +- levels.pop() +- # +- return results +- +- +-def get_extra_values(conf, _prepend=()): +- """ +- Find all the values and sections not in the configspec from a validated +- ConfigObj. +- +- ``get_extra_values`` returns a list of tuples where each tuple represents +- either an extra section, or an extra value. +- +- The tuples contain two values, a tuple representing the section the value +- is in and the name of the extra values. For extra values in the top level +- section the first member will be an empty tuple. For values in the 'foo' +- section the first member will be ``('foo',)``. For members in the 'bar' +- subsection of the 'foo' section the first member will be ``('foo', 'bar')``. +- +- NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't +- been validated it will return an empty list. +- """ +- out = [] +- +- out.extend([(_prepend, name) for name in conf.extra_values]) +- for name in conf.sections: +- if name not in conf.extra_values: +- out.extend(get_extra_values(conf[name], _prepend + (name,))) +- return out +- +- +-"""*A programming language is a medium of expression.* - Paul Graham""" +diff -x .bzr -uNr terminator-1.91/terminatorlib/configobj/validate.py python3/terminatorlib/configobj/validate.py +--- terminator-1.91/terminatorlib/configobj/validate.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/configobj/validate.py 1969-12-31 19:00:00.000000000 -0500 +@@ -1,1462 +0,0 @@ +-# validate.py +-# A Validator object +-# Copyright (C) 2005-2010 Michael Foord, Mark Andrews, Nicola Larosa +-# E-mail: fuzzyman AT voidspace DOT org DOT uk +-# mark AT la-la DOT com +-# nico AT tekNico DOT net +- +-# This software is licensed under the terms of the BSD license. +-# http://www.voidspace.org.uk/python/license.shtml +-# Basically you're free to copy, modify, distribute and relicense it, +-# So long as you keep a copy of the license with it. +- +-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml +-# For information about bugfixes, updates and support, please join the +-# ConfigObj mailing list: +-# http://lists.sourceforge.net/lists/listinfo/configobj-develop +-# Comments, suggestions and bug reports welcome. +- +-""" +- The Validator object is used to check that supplied values +- conform to a specification. +- +- The value can be supplied as a string - e.g. from a config file. +- In this case the check will also *convert* the value to +- the required type. This allows you to add validation +- as a transparent layer to access data stored as strings. +- The validation checks that the data is correct *and* +- converts it to the expected type. +- +- Some standard checks are provided for basic data types. +- Additional checks are easy to write. They can be +- provided when the ``Validator`` is instantiated or +- added afterwards. +- +- The standard functions work with the following basic data types : +- +- * integers +- * floats +- * booleans +- * strings +- * ip_addr +- +- plus lists of these datatypes +- +- Adding additional checks is done through coding simple functions. +- +- The full set of standard checks are : +- +- * 'integer': matches integer values (including negative) +- Takes optional 'min' and 'max' arguments : :: +- +- integer() +- integer(3, 9) # any value from 3 to 9 +- integer(min=0) # any positive value +- integer(max=9) +- +- * 'float': matches float values +- Has the same parameters as the integer check. +- +- * 'boolean': matches boolean values - ``True`` or ``False`` +- Acceptable string values for True are : +- true, on, yes, 1 +- Acceptable string values for False are : +- false, off, no, 0 +- +- Any other value raises an error. +- +- * 'ip_addr': matches an Internet Protocol address, v.4, represented +- by a dotted-quad string, i.e. '1.2.3.4'. +- +- * 'string': matches any string. +- Takes optional keyword args 'min' and 'max' +- to specify min and max lengths of the string. +- +- * 'list': matches any list. +- Takes optional keyword args 'min', and 'max' to specify min and +- max sizes of the list. (Always returns a list.) +- +- * 'tuple': matches any tuple. +- Takes optional keyword args 'min', and 'max' to specify min and +- max sizes of the tuple. (Always returns a tuple.) +- +- * 'int_list': Matches a list of integers. +- Takes the same arguments as list. +- +- * 'float_list': Matches a list of floats. +- Takes the same arguments as list. +- +- * 'bool_list': Matches a list of boolean values. +- Takes the same arguments as list. +- +- * 'ip_addr_list': Matches a list of IP addresses. +- Takes the same arguments as list. +- +- * 'string_list': Matches a list of strings. +- Takes the same arguments as list. +- +- * 'mixed_list': Matches a list with different types in +- specific positions. List size must match +- the number of arguments. +- +- Each position can be one of : +- 'integer', 'float', 'ip_addr', 'string', 'boolean' +- +- So to specify a list with two strings followed +- by two integers, you write the check as : :: +- +- mixed_list('string', 'string', 'integer', 'integer') +- +- * 'pass': This check matches everything ! It never fails +- and the value is unchanged. +- +- It is also the default if no check is specified. +- +- * 'option': This check matches any from a list of options. +- You specify this check with : :: +- +- option('option 1', 'option 2', 'option 3') +- +- You can supply a default value (returned if no value is supplied) +- using the default keyword argument. +- +- You specify a list argument for default using a list constructor syntax in +- the check : :: +- +- checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3')) +- +- A badly formatted set of arguments will raise a ``VdtParamError``. +-""" +- +-__version__ = '1.0.1' +- +- +-__all__ = ( +- '__version__', +- 'dottedQuadToNum', +- 'numToDottedQuad', +- 'ValidateError', +- 'VdtUnknownCheckError', +- 'VdtParamError', +- 'VdtTypeError', +- 'VdtValueError', +- 'VdtValueTooSmallError', +- 'VdtValueTooBigError', +- 'VdtValueTooShortError', +- 'VdtValueTooLongError', +- 'VdtMissingValue', +- 'Validator', +- 'is_integer', +- 'is_float', +- 'is_boolean', +- 'is_list', +- 'is_tuple', +- 'is_ip_addr', +- 'is_string', +- 'is_int_list', +- 'is_bool_list', +- 'is_float_list', +- 'is_string_list', +- 'is_ip_addr_list', +- 'is_mixed_list', +- 'is_option', +-) +- +- +-import re +- +- +-_list_arg = re.compile(r''' +- (?: +- ([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*list\( +- ( +- (?: +- \s* +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s\)][^,\)]*?) # unquoted +- ) +- \s*,\s* +- )* +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s\)][^,\)]*?) # unquoted +- )? # last one +- ) +- \) +- ) +-''', re.VERBOSE | re.DOTALL) # two groups +- +-_list_members = re.compile(r''' +- ( +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s=][^,=]*?) # unquoted +- ) +- (?: +- (?:\s*,\s*)|(?:\s*$) # comma +- ) +-''', re.VERBOSE | re.DOTALL) # one group +- +-_paramstring = r''' +- (?: +- ( +- (?: +- [a-zA-Z_][a-zA-Z0-9_]*\s*=\s*list\( +- (?: +- \s* +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s\)][^,\)]*?) # unquoted +- ) +- \s*,\s* +- )* +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s\)][^,\)]*?) # unquoted +- )? # last one +- \) +- )| +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s=][^,=]*?)| # unquoted +- (?: # keyword argument +- [a-zA-Z_][a-zA-Z0-9_]*\s*=\s* +- (?: +- (?:".*?")| # double quotes +- (?:'.*?')| # single quotes +- (?:[^'",\s=][^,=]*?) # unquoted +- ) +- ) +- ) +- ) +- (?: +- (?:\s*,\s*)|(?:\s*$) # comma +- ) +- ) +- ''' +- +-_matchstring = '^%s*' % _paramstring +- +-# Python pre 2.2.1 doesn't have bool +-try: +- bool +-except NameError: +- def bool(val): +- """Simple boolean equivalent function. """ +- if val: +- return 1 +- else: +- return 0 +- +- +-def dottedQuadToNum(ip): +- """ +- Convert decimal dotted quad string to long integer +- +- >>> int(dottedQuadToNum('1 ')) +- 1 +- >>> int(dottedQuadToNum(' 1.2')) +- 16777218 +- >>> int(dottedQuadToNum(' 1.2.3 ')) +- 16908291 +- >>> int(dottedQuadToNum('1.2.3.4')) +- 16909060 +- >>> dottedQuadToNum('1.2.3. 4') +- 16909060 +- >>> dottedQuadToNum('255.255.255.255') +- 4294967295L +- >>> dottedQuadToNum('255.255.255.256') +- Traceback (most recent call last): +- ValueError: Not a good dotted-quad IP: 255.255.255.256 +- """ +- +- # import here to avoid it when ip_addr values are not used +- import socket, struct +- +- try: +- return struct.unpack('!L', +- socket.inet_aton(ip.strip()))[0] +- except socket.error: +- # bug in inet_aton, corrected in Python 2.3 +- if ip.strip() == '255.255.255.255': +- return 0xFFFFFFFFL +- else: +- raise ValueError('Not a good dotted-quad IP: %s' % ip) +- return +- +- +-def numToDottedQuad(num): +- """ +- Convert long int to dotted quad string +- +- >>> numToDottedQuad(-1L) +- Traceback (most recent call last): +- ValueError: Not a good numeric IP: -1 +- >>> numToDottedQuad(1L) +- '0.0.0.1' +- >>> numToDottedQuad(16777218L) +- '1.0.0.2' +- >>> numToDottedQuad(16908291L) +- '1.2.0.3' +- >>> numToDottedQuad(16909060L) +- '1.2.3.4' +- >>> numToDottedQuad(4294967295L) +- '255.255.255.255' +- >>> numToDottedQuad(4294967296L) +- Traceback (most recent call last): +- ValueError: Not a good numeric IP: 4294967296 +- """ +- +- # import here to avoid it when ip_addr values are not used +- import socket, struct +- +- # no need to intercept here, 4294967295L is fine +- if num > 4294967295L or num < 0: +- raise ValueError('Not a good numeric IP: %s' % num) +- try: +- return socket.inet_ntoa( +- struct.pack('!L', long(num))) +- except (socket.error, struct.error, OverflowError): +- raise ValueError('Not a good numeric IP: %s' % num) +- +- +-class ValidateError(Exception): +- """ +- This error indicates that the check failed. +- It can be the base class for more specific errors. +- +- Any check function that fails ought to raise this error. +- (or a subclass) +- +- >>> raise ValidateError +- Traceback (most recent call last): +- ValidateError +- """ +- +- +-class VdtMissingValue(ValidateError): +- """No value was supplied to a check that needed one.""" +- +- +-class VdtUnknownCheckError(ValidateError): +- """An unknown check function was requested""" +- +- def __init__(self, value): +- """ +- >>> raise VdtUnknownCheckError('yoda') +- Traceback (most recent call last): +- VdtUnknownCheckError: the check "yoda" is unknown. +- """ +- ValidateError.__init__(self, 'the check "%s" is unknown.' % (value,)) +- +- +-class VdtParamError(SyntaxError): +- """An incorrect parameter was passed""" +- +- def __init__(self, name, value): +- """ +- >>> raise VdtParamError('yoda', 'jedi') +- Traceback (most recent call last): +- VdtParamError: passed an incorrect value "jedi" for parameter "yoda". +- """ +- SyntaxError.__init__(self, 'passed an incorrect value "%s" for parameter "%s".' % (value, name)) +- +- +-class VdtTypeError(ValidateError): +- """The value supplied was of the wrong type""" +- +- def __init__(self, value): +- """ +- >>> raise VdtTypeError('jedi') +- Traceback (most recent call last): +- VdtTypeError: the value "jedi" is of the wrong type. +- """ +- ValidateError.__init__(self, 'the value "%s" is of the wrong type.' % (value,)) +- +- +-class VdtValueError(ValidateError): +- """The value supplied was of the correct type, but was not an allowed value.""" +- +- def __init__(self, value): +- """ +- >>> raise VdtValueError('jedi') +- Traceback (most recent call last): +- VdtValueError: the value "jedi" is unacceptable. +- """ +- ValidateError.__init__(self, 'the value "%s" is unacceptable.' % (value,)) +- +- +-class VdtValueTooSmallError(VdtValueError): +- """The value supplied was of the correct type, but was too small.""" +- +- def __init__(self, value): +- """ +- >>> raise VdtValueTooSmallError('0') +- Traceback (most recent call last): +- VdtValueTooSmallError: the value "0" is too small. +- """ +- ValidateError.__init__(self, 'the value "%s" is too small.' % (value,)) +- +- +-class VdtValueTooBigError(VdtValueError): +- """The value supplied was of the correct type, but was too big.""" +- +- def __init__(self, value): +- """ +- >>> raise VdtValueTooBigError('1') +- Traceback (most recent call last): +- VdtValueTooBigError: the value "1" is too big. +- """ +- ValidateError.__init__(self, 'the value "%s" is too big.' % (value,)) +- +- +-class VdtValueTooShortError(VdtValueError): +- """The value supplied was of the correct type, but was too short.""" +- +- def __init__(self, value): +- """ +- >>> raise VdtValueTooShortError('jed') +- Traceback (most recent call last): +- VdtValueTooShortError: the value "jed" is too short. +- """ +- ValidateError.__init__( +- self, +- 'the value "%s" is too short.' % (value,)) +- +- +-class VdtValueTooLongError(VdtValueError): +- """The value supplied was of the correct type, but was too long.""" +- +- def __init__(self, value): +- """ +- >>> raise VdtValueTooLongError('jedie') +- Traceback (most recent call last): +- VdtValueTooLongError: the value "jedie" is too long. +- """ +- ValidateError.__init__(self, 'the value "%s" is too long.' % (value,)) +- +- +-class Validator(object): +- """ +- Validator is an object that allows you to register a set of 'checks'. +- These checks take input and test that it conforms to the check. +- +- This can also involve converting the value from a string into +- the correct datatype. +- +- The ``check`` method takes an input string which configures which +- check is to be used and applies that check to a supplied value. +- +- An example input string would be: +- 'int_range(param1, param2)' +- +- You would then provide something like: +- +- >>> def int_range_check(value, min, max): +- ... # turn min and max from strings to integers +- ... min = int(min) +- ... max = int(max) +- ... # check that value is of the correct type. +- ... # possible valid inputs are integers or strings +- ... # that represent integers +- ... if not isinstance(value, (int, long, basestring)): +- ... raise VdtTypeError(value) +- ... elif isinstance(value, basestring): +- ... # if we are given a string +- ... # attempt to convert to an integer +- ... try: +- ... value = int(value) +- ... except ValueError: +- ... raise VdtValueError(value) +- ... # check the value is between our constraints +- ... if not min <= value: +- ... raise VdtValueTooSmallError(value) +- ... if not value <= max: +- ... raise VdtValueTooBigError(value) +- ... return value +- ... +- >>> fdict = {'int_range': int_range_check} +- >>> vtr1 = Validator(fdict) +- >>> vtr1.check('int_range(20, 40)', '30') +- 30 +- >>> vtr1.check('int_range(20, 40)', '60') +- Traceback (most recent call last): +- VdtValueTooBigError: the value "60" is too big. +- +- New functions can be added with : :: +- +- >>> vtr2 = Validator() +- >>> vtr2.functions['int_range'] = int_range_check +- +- Or by passing in a dictionary of functions when Validator +- is instantiated. +- +- Your functions *can* use keyword arguments, +- but the first argument should always be 'value'. +- +- If the function doesn't take additional arguments, +- the parentheses are optional in the check. +- It can be written with either of : :: +- +- keyword = function_name +- keyword = function_name() +- +- The first program to utilise Validator() was Michael Foord's +- ConfigObj, an alternative to ConfigParser which supports lists and +- can validate a config file using a config schema. +- For more details on using Validator with ConfigObj see: +- http://www.voidspace.org.uk/python/configobj.html +- """ +- +- # this regex does the initial parsing of the checks +- _func_re = re.compile(r'(.+?)\((.*)\)', re.DOTALL) +- +- # this regex takes apart keyword arguments +- _key_arg = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$', re.DOTALL) +- +- +- # this regex finds keyword=list(....) type values +- _list_arg = _list_arg +- +- # this regex takes individual values out of lists - in one pass +- _list_members = _list_members +- +- # These regexes check a set of arguments for validity +- # and then pull the members out +- _paramfinder = re.compile(_paramstring, re.VERBOSE | re.DOTALL) +- _matchfinder = re.compile(_matchstring, re.VERBOSE | re.DOTALL) +- +- +- def __init__(self, functions=None): +- """ +- >>> vtri = Validator() +- """ +- self.functions = { +- '': self._pass, +- 'integer': is_integer, +- 'float': is_float, +- 'boolean': is_boolean, +- 'ip_addr': is_ip_addr, +- 'string': is_string, +- 'list': is_list, +- 'tuple': is_tuple, +- 'int_list': is_int_list, +- 'float_list': is_float_list, +- 'bool_list': is_bool_list, +- 'ip_addr_list': is_ip_addr_list, +- 'string_list': is_string_list, +- 'mixed_list': is_mixed_list, +- 'pass': self._pass, +- 'option': is_option, +- 'force_list': force_list, +- } +- if functions is not None: +- self.functions.update(functions) +- # tekNico: for use by ConfigObj +- self.baseErrorClass = ValidateError +- self._cache = {} +- +- +- def check(self, check, value, missing=False): +- """ +- Usage: check(check, value) +- +- Arguments: +- check: string representing check to apply (including arguments) +- value: object to be checked +- +- Returns value, converted to correct type if necessary +- +- If the check fails, raises a ``ValidateError`` subclass. +- +- >>> vtor.check('yoda', '') +- Traceback (most recent call last): +- VdtUnknownCheckError: the check "yoda" is unknown. +- >>> vtor.check('yoda()', '') +- Traceback (most recent call last): +- VdtUnknownCheckError: the check "yoda" is unknown. +- +- >>> vtor.check('string(default="")', '', missing=True) +- '' +- """ +- fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check) +- +- if missing: +- if default is None: +- # no information needed here - to be handled by caller +- raise VdtMissingValue() +- value = self._handle_none(default) +- +- if value is None: +- return None +- +- return self._check_value(value, fun_name, fun_args, fun_kwargs) +- +- +- def _handle_none(self, value): +- if value == 'None': +- value = None +- elif value in ("'None'", '"None"'): +- # Special case a quoted None +- value = self._unquote(value) +- return value +- +- +- def _parse_with_caching(self, check): +- if check in self._cache: +- fun_name, fun_args, fun_kwargs, default = self._cache[check] +- # We call list and dict below to work with *copies* of the data +- # rather than the original (which are mutable of course) +- fun_args = list(fun_args) +- fun_kwargs = dict(fun_kwargs) +- else: +- fun_name, fun_args, fun_kwargs, default = self._parse_check(check) +- fun_kwargs = dict([(str(key), value) for (key, value) in fun_kwargs.items()]) +- self._cache[check] = fun_name, list(fun_args), dict(fun_kwargs), default +- return fun_name, fun_args, fun_kwargs, default +- +- +- def _check_value(self, value, fun_name, fun_args, fun_kwargs): +- try: +- fun = self.functions[fun_name] +- except KeyError: +- raise VdtUnknownCheckError(fun_name) +- else: +- return fun(value, *fun_args, **fun_kwargs) +- +- +- def _parse_check(self, check): +- fun_match = self._func_re.match(check) +- if fun_match: +- fun_name = fun_match.group(1) +- arg_string = fun_match.group(2) +- arg_match = self._matchfinder.match(arg_string) +- if arg_match is None: +- # Bad syntax +- raise VdtParamError('Bad syntax in check "%s".' % check) +- fun_args = [] +- fun_kwargs = {} +- # pull out args of group 2 +- for arg in self._paramfinder.findall(arg_string): +- # args may need whitespace removing (before removing quotes) +- arg = arg.strip() +- listmatch = self._list_arg.match(arg) +- if listmatch: +- key, val = self._list_handle(listmatch) +- fun_kwargs[key] = val +- continue +- keymatch = self._key_arg.match(arg) +- if keymatch: +- val = keymatch.group(2) +- if not val in ("'None'", '"None"'): +- # Special case a quoted None +- val = self._unquote(val) +- fun_kwargs[keymatch.group(1)] = val +- continue +- +- fun_args.append(self._unquote(arg)) +- else: +- # allows for function names without (args) +- return check, (), {}, None +- +- # Default must be deleted if the value is specified too, +- # otherwise the check function will get a spurious "default" keyword arg +- try: +- default = fun_kwargs.pop('default', None) +- except AttributeError: +- # Python 2.2 compatibility +- default = None +- try: +- default = fun_kwargs['default'] +- del fun_kwargs['default'] +- except KeyError: +- pass +- +- return fun_name, fun_args, fun_kwargs, default +- +- +- def _unquote(self, val): +- """Unquote a value if necessary.""" +- if (len(val) >= 2) and (val[0] in ("'", '"')) and (val[0] == val[-1]): +- val = val[1:-1] +- return val +- +- +- def _list_handle(self, listmatch): +- """Take apart a ``keyword=list('val, 'val')`` type string.""" +- out = [] +- name = listmatch.group(1) +- args = listmatch.group(2) +- for arg in self._list_members.findall(args): +- out.append(self._unquote(arg)) +- return name, out +- +- +- def _pass(self, value): +- """ +- Dummy check that always passes +- +- >>> vtor.check('', 0) +- 0 +- >>> vtor.check('', '0') +- '0' +- """ +- return value +- +- +- def get_default_value(self, check): +- """ +- Given a check, return the default value for the check +- (converted to the right type). +- +- If the check doesn't specify a default value then a +- ``KeyError`` will be raised. +- """ +- fun_name, fun_args, fun_kwargs, default = self._parse_with_caching(check) +- if default is None: +- raise KeyError('Check "%s" has no default value.' % check) +- value = self._handle_none(default) +- if value is None: +- return value +- return self._check_value(value, fun_name, fun_args, fun_kwargs) +- +- +-def _is_num_param(names, values, to_float=False): +- """ +- Return numbers from inputs or raise VdtParamError. +- +- Lets ``None`` pass through. +- Pass in keyword argument ``to_float=True`` to +- use float for the conversion rather than int. +- +- >>> _is_num_param(('', ''), (0, 1.0)) +- [0, 1] +- >>> _is_num_param(('', ''), (0, 1.0), to_float=True) +- [0.0, 1.0] +- >>> _is_num_param(('a'), ('a')) +- Traceback (most recent call last): +- VdtParamError: passed an incorrect value "a" for parameter "a". +- """ +- fun = to_float and float or int +- out_params = [] +- for (name, val) in zip(names, values): +- if val is None: +- out_params.append(val) +- elif isinstance(val, (int, long, float, basestring)): +- try: +- out_params.append(fun(val)) +- except ValueError, e: +- raise VdtParamError(name, val) +- else: +- raise VdtParamError(name, val) +- return out_params +- +- +-# built in checks +-# you can override these by setting the appropriate name +-# in Validator.functions +-# note: if the params are specified wrongly in your input string, +-# you will also raise errors. +- +-def is_integer(value, min=None, max=None): +- """ +- A check that tests that a given value is an integer (int, or long) +- and optionally, between bounds. A negative value is accepted, while +- a float will fail. +- +- If the value is a string, then the conversion is done - if possible. +- Otherwise a VdtError is raised. +- +- >>> vtor.check('integer', '-1') +- -1 +- >>> vtor.check('integer', '0') +- 0 +- >>> vtor.check('integer', 9) +- 9 +- >>> vtor.check('integer', 'a') +- Traceback (most recent call last): +- VdtTypeError: the value "a" is of the wrong type. +- >>> vtor.check('integer', '2.2') +- Traceback (most recent call last): +- VdtTypeError: the value "2.2" is of the wrong type. +- >>> vtor.check('integer(10)', '20') +- 20 +- >>> vtor.check('integer(max=20)', '15') +- 15 +- >>> vtor.check('integer(10)', '9') +- Traceback (most recent call last): +- VdtValueTooSmallError: the value "9" is too small. +- >>> vtor.check('integer(10)', 9) +- Traceback (most recent call last): +- VdtValueTooSmallError: the value "9" is too small. +- >>> vtor.check('integer(max=20)', '35') +- Traceback (most recent call last): +- VdtValueTooBigError: the value "35" is too big. +- >>> vtor.check('integer(max=20)', 35) +- Traceback (most recent call last): +- VdtValueTooBigError: the value "35" is too big. +- >>> vtor.check('integer(0, 9)', False) +- 0 +- """ +- (min_val, max_val) = _is_num_param(('min', 'max'), (min, max)) +- if not isinstance(value, (int, long, basestring)): +- raise VdtTypeError(value) +- if isinstance(value, basestring): +- # if it's a string - does it represent an integer ? +- try: +- value = int(value) +- except ValueError: +- raise VdtTypeError(value) +- if (min_val is not None) and (value < min_val): +- raise VdtValueTooSmallError(value) +- if (max_val is not None) and (value > max_val): +- raise VdtValueTooBigError(value) +- return value +- +- +-def is_float(value, min=None, max=None): +- """ +- A check that tests that a given value is a float +- (an integer will be accepted), and optionally - that it is between bounds. +- +- If the value is a string, then the conversion is done - if possible. +- Otherwise a VdtError is raised. +- +- This can accept negative values. +- +- >>> vtor.check('float', '2') +- 2.0 +- +- From now on we multiply the value to avoid comparing decimals +- +- >>> vtor.check('float', '-6.8') * 10 +- -68.0 +- >>> vtor.check('float', '12.2') * 10 +- 122.0 +- >>> vtor.check('float', 8.4) * 10 +- 84.0 +- >>> vtor.check('float', 'a') +- Traceback (most recent call last): +- VdtTypeError: the value "a" is of the wrong type. +- >>> vtor.check('float(10.1)', '10.2') * 10 +- 102.0 +- >>> vtor.check('float(max=20.2)', '15.1') * 10 +- 151.0 +- >>> vtor.check('float(10.0)', '9.0') +- Traceback (most recent call last): +- VdtValueTooSmallError: the value "9.0" is too small. +- >>> vtor.check('float(max=20.0)', '35.0') +- Traceback (most recent call last): +- VdtValueTooBigError: the value "35.0" is too big. +- """ +- (min_val, max_val) = _is_num_param( +- ('min', 'max'), (min, max), to_float=True) +- if not isinstance(value, (int, long, float, basestring)): +- raise VdtTypeError(value) +- if not isinstance(value, float): +- # if it's a string - does it represent a float ? +- try: +- value = float(value) +- except ValueError: +- raise VdtTypeError(value) +- if (min_val is not None) and (value < min_val): +- raise VdtValueTooSmallError(value) +- if (max_val is not None) and (value > max_val): +- raise VdtValueTooBigError(value) +- return value +- +- +-bool_dict = { +- True: True, 'on': True, '1': True, 'true': True, 'yes': True, +- False: False, 'off': False, '0': False, 'false': False, 'no': False, +-} +- +- +-def is_boolean(value): +- """ +- Check if the value represents a boolean. +- +- >>> vtor.check('boolean', 0) +- 0 +- >>> vtor.check('boolean', False) +- 0 +- >>> vtor.check('boolean', '0') +- 0 +- >>> vtor.check('boolean', 'off') +- 0 +- >>> vtor.check('boolean', 'false') +- 0 +- >>> vtor.check('boolean', 'no') +- 0 +- >>> vtor.check('boolean', 'nO') +- 0 +- >>> vtor.check('boolean', 'NO') +- 0 +- >>> vtor.check('boolean', 1) +- 1 +- >>> vtor.check('boolean', True) +- 1 +- >>> vtor.check('boolean', '1') +- 1 +- >>> vtor.check('boolean', 'on') +- 1 +- >>> vtor.check('boolean', 'true') +- 1 +- >>> vtor.check('boolean', 'yes') +- 1 +- >>> vtor.check('boolean', 'Yes') +- 1 +- >>> vtor.check('boolean', 'YES') +- 1 +- >>> vtor.check('boolean', '') +- Traceback (most recent call last): +- VdtTypeError: the value "" is of the wrong type. +- >>> vtor.check('boolean', 'up') +- Traceback (most recent call last): +- VdtTypeError: the value "up" is of the wrong type. +- +- """ +- if isinstance(value, basestring): +- try: +- return bool_dict[value.lower()] +- except KeyError: +- raise VdtTypeError(value) +- # we do an equality test rather than an identity test +- # this ensures Python 2.2 compatibilty +- # and allows 0 and 1 to represent True and False +- if value == False: +- return False +- elif value == True: +- return True +- else: +- raise VdtTypeError(value) +- +- +-def is_ip_addr(value): +- """ +- Check that the supplied value is an Internet Protocol address, v.4, +- represented by a dotted-quad string, i.e. '1.2.3.4'. +- +- >>> vtor.check('ip_addr', '1 ') +- '1' +- >>> vtor.check('ip_addr', ' 1.2') +- '1.2' +- >>> vtor.check('ip_addr', ' 1.2.3 ') +- '1.2.3' +- >>> vtor.check('ip_addr', '1.2.3.4') +- '1.2.3.4' +- >>> vtor.check('ip_addr', '0.0.0.0') +- '0.0.0.0' +- >>> vtor.check('ip_addr', '255.255.255.255') +- '255.255.255.255' +- >>> vtor.check('ip_addr', '255.255.255.256') +- Traceback (most recent call last): +- VdtValueError: the value "255.255.255.256" is unacceptable. +- >>> vtor.check('ip_addr', '1.2.3.4.5') +- Traceback (most recent call last): +- VdtValueError: the value "1.2.3.4.5" is unacceptable. +- >>> vtor.check('ip_addr', 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- """ +- if not isinstance(value, basestring): +- raise VdtTypeError(value) +- value = value.strip() +- try: +- dottedQuadToNum(value) +- except ValueError: +- raise VdtValueError(value) +- return value +- +- +-def is_list(value, min=None, max=None): +- """ +- Check that the value is a list of values. +- +- You can optionally specify the minimum and maximum number of members. +- +- It does no check on list members. +- +- >>> vtor.check('list', ()) +- [] +- >>> vtor.check('list', []) +- [] +- >>> vtor.check('list', (1, 2)) +- [1, 2] +- >>> vtor.check('list', [1, 2]) +- [1, 2] +- >>> vtor.check('list(3)', (1, 2)) +- Traceback (most recent call last): +- VdtValueTooShortError: the value "(1, 2)" is too short. +- >>> vtor.check('list(max=5)', (1, 2, 3, 4, 5, 6)) +- Traceback (most recent call last): +- VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long. +- >>> vtor.check('list(min=3, max=5)', (1, 2, 3, 4)) +- [1, 2, 3, 4] +- >>> vtor.check('list', 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- >>> vtor.check('list', '12') +- Traceback (most recent call last): +- VdtTypeError: the value "12" is of the wrong type. +- """ +- (min_len, max_len) = _is_num_param(('min', 'max'), (min, max)) +- if isinstance(value, basestring): +- raise VdtTypeError(value) +- try: +- num_members = len(value) +- except TypeError: +- raise VdtTypeError(value) +- if min_len is not None and num_members < min_len: +- raise VdtValueTooShortError(value) +- if max_len is not None and num_members > max_len: +- raise VdtValueTooLongError(value) +- return list(value) +- +- +-def is_tuple(value, min=None, max=None): +- """ +- Check that the value is a tuple of values. +- +- You can optionally specify the minimum and maximum number of members. +- +- It does no check on members. +- +- >>> vtor.check('tuple', ()) +- () +- >>> vtor.check('tuple', []) +- () +- >>> vtor.check('tuple', (1, 2)) +- (1, 2) +- >>> vtor.check('tuple', [1, 2]) +- (1, 2) +- >>> vtor.check('tuple(3)', (1, 2)) +- Traceback (most recent call last): +- VdtValueTooShortError: the value "(1, 2)" is too short. +- >>> vtor.check('tuple(max=5)', (1, 2, 3, 4, 5, 6)) +- Traceback (most recent call last): +- VdtValueTooLongError: the value "(1, 2, 3, 4, 5, 6)" is too long. +- >>> vtor.check('tuple(min=3, max=5)', (1, 2, 3, 4)) +- (1, 2, 3, 4) +- >>> vtor.check('tuple', 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- >>> vtor.check('tuple', '12') +- Traceback (most recent call last): +- VdtTypeError: the value "12" is of the wrong type. +- """ +- return tuple(is_list(value, min, max)) +- +- +-def is_string(value, min=None, max=None): +- """ +- Check that the supplied value is a string. +- +- You can optionally specify the minimum and maximum number of members. +- +- >>> vtor.check('string', '0') +- '0' +- >>> vtor.check('string', 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- >>> vtor.check('string(2)', '12') +- '12' +- >>> vtor.check('string(2)', '1') +- Traceback (most recent call last): +- VdtValueTooShortError: the value "1" is too short. +- >>> vtor.check('string(min=2, max=3)', '123') +- '123' +- >>> vtor.check('string(min=2, max=3)', '1234') +- Traceback (most recent call last): +- VdtValueTooLongError: the value "1234" is too long. +- """ +- if not isinstance(value, basestring): +- raise VdtTypeError(value) +- (min_len, max_len) = _is_num_param(('min', 'max'), (min, max)) +- try: +- num_members = len(value) +- except TypeError: +- raise VdtTypeError(value) +- if min_len is not None and num_members < min_len: +- raise VdtValueTooShortError(value) +- if max_len is not None and num_members > max_len: +- raise VdtValueTooLongError(value) +- return value +- +- +-def is_int_list(value, min=None, max=None): +- """ +- Check that the value is a list of integers. +- +- You can optionally specify the minimum and maximum number of members. +- +- Each list member is checked that it is an integer. +- +- >>> vtor.check('int_list', ()) +- [] +- >>> vtor.check('int_list', []) +- [] +- >>> vtor.check('int_list', (1, 2)) +- [1, 2] +- >>> vtor.check('int_list', [1, 2]) +- [1, 2] +- >>> vtor.check('int_list', [1, 'a']) +- Traceback (most recent call last): +- VdtTypeError: the value "a" is of the wrong type. +- """ +- return [is_integer(mem) for mem in is_list(value, min, max)] +- +- +-def is_bool_list(value, min=None, max=None): +- """ +- Check that the value is a list of booleans. +- +- You can optionally specify the minimum and maximum number of members. +- +- Each list member is checked that it is a boolean. +- +- >>> vtor.check('bool_list', ()) +- [] +- >>> vtor.check('bool_list', []) +- [] +- >>> check_res = vtor.check('bool_list', (True, False)) +- >>> check_res == [True, False] +- 1 +- >>> check_res = vtor.check('bool_list', [True, False]) +- >>> check_res == [True, False] +- 1 +- >>> vtor.check('bool_list', [True, 'a']) +- Traceback (most recent call last): +- VdtTypeError: the value "a" is of the wrong type. +- """ +- return [is_boolean(mem) for mem in is_list(value, min, max)] +- +- +-def is_float_list(value, min=None, max=None): +- """ +- Check that the value is a list of floats. +- +- You can optionally specify the minimum and maximum number of members. +- +- Each list member is checked that it is a float. +- +- >>> vtor.check('float_list', ()) +- [] +- >>> vtor.check('float_list', []) +- [] +- >>> vtor.check('float_list', (1, 2.0)) +- [1.0, 2.0] +- >>> vtor.check('float_list', [1, 2.0]) +- [1.0, 2.0] +- >>> vtor.check('float_list', [1, 'a']) +- Traceback (most recent call last): +- VdtTypeError: the value "a" is of the wrong type. +- """ +- return [is_float(mem) for mem in is_list(value, min, max)] +- +- +-def is_string_list(value, min=None, max=None): +- """ +- Check that the value is a list of strings. +- +- You can optionally specify the minimum and maximum number of members. +- +- Each list member is checked that it is a string. +- +- >>> vtor.check('string_list', ()) +- [] +- >>> vtor.check('string_list', []) +- [] +- >>> vtor.check('string_list', ('a', 'b')) +- ['a', 'b'] +- >>> vtor.check('string_list', ['a', 1]) +- Traceback (most recent call last): +- VdtTypeError: the value "1" is of the wrong type. +- >>> vtor.check('string_list', 'hello') +- Traceback (most recent call last): +- VdtTypeError: the value "hello" is of the wrong type. +- """ +- if isinstance(value, basestring): +- raise VdtTypeError(value) +- return [is_string(mem) for mem in is_list(value, min, max)] +- +- +-def is_ip_addr_list(value, min=None, max=None): +- """ +- Check that the value is a list of IP addresses. +- +- You can optionally specify the minimum and maximum number of members. +- +- Each list member is checked that it is an IP address. +- +- >>> vtor.check('ip_addr_list', ()) +- [] +- >>> vtor.check('ip_addr_list', []) +- [] +- >>> vtor.check('ip_addr_list', ('1.2.3.4', '5.6.7.8')) +- ['1.2.3.4', '5.6.7.8'] +- >>> vtor.check('ip_addr_list', ['a']) +- Traceback (most recent call last): +- VdtValueError: the value "a" is unacceptable. +- """ +- return [is_ip_addr(mem) for mem in is_list(value, min, max)] +- +- +-def force_list(value, min=None, max=None): +- """ +- Check that a value is a list, coercing strings into +- a list with one member. Useful where users forget the +- trailing comma that turns a single value into a list. +- +- You can optionally specify the minimum and maximum number of members. +- A minumum of greater than one will fail if the user only supplies a +- string. +- +- >>> vtor.check('force_list', ()) +- [] +- >>> vtor.check('force_list', []) +- [] +- >>> vtor.check('force_list', 'hello') +- ['hello'] +- """ +- if not isinstance(value, (list, tuple)): +- value = [value] +- return is_list(value, min, max) +- +- +- +-fun_dict = { +- 'integer': is_integer, +- 'float': is_float, +- 'ip_addr': is_ip_addr, +- 'string': is_string, +- 'boolean': is_boolean, +-} +- +- +-def is_mixed_list(value, *args): +- """ +- Check that the value is a list. +- Allow specifying the type of each member. +- Work on lists of specific lengths. +- +- You specify each member as a positional argument specifying type +- +- Each type should be one of the following strings : +- 'integer', 'float', 'ip_addr', 'string', 'boolean' +- +- So you can specify a list of two strings, followed by +- two integers as : +- +- mixed_list('string', 'string', 'integer', 'integer') +- +- The length of the list must match the number of positional +- arguments you supply. +- +- >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')" +- >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True)) +- >>> check_res == [1, 2.0, '1.2.3.4', 'a', True] +- 1 +- >>> check_res = vtor.check(mix_str, ('1', '2.0', '1.2.3.4', 'a', 'True')) +- >>> check_res == [1, 2.0, '1.2.3.4', 'a', True] +- 1 +- >>> vtor.check(mix_str, ('b', 2.0, '1.2.3.4', 'a', True)) +- Traceback (most recent call last): +- VdtTypeError: the value "b" is of the wrong type. +- >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a')) +- Traceback (most recent call last): +- VdtValueTooShortError: the value "(1, 2.0, '1.2.3.4', 'a')" is too short. +- >>> vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', 1, 'b')) +- Traceback (most recent call last): +- VdtValueTooLongError: the value "(1, 2.0, '1.2.3.4', 'a', 1, 'b')" is too long. +- >>> vtor.check(mix_str, 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- +- This test requires an elaborate setup, because of a change in error string +- output from the interpreter between Python 2.2 and 2.3 . +- +- >>> res_seq = ( +- ... 'passed an incorrect value "', +- ... 'yoda', +- ... '" for parameter "mixed_list".', +- ... ) +- >>> res_str = "'".join(res_seq) +- >>> try: +- ... vtor.check('mixed_list("yoda")', ('a')) +- ... except VdtParamError, err: +- ... str(err) == res_str +- 1 +- """ +- try: +- length = len(value) +- except TypeError: +- raise VdtTypeError(value) +- if length < len(args): +- raise VdtValueTooShortError(value) +- elif length > len(args): +- raise VdtValueTooLongError(value) +- try: +- return [fun_dict[arg](val) for arg, val in zip(args, value)] +- except KeyError, e: +- raise VdtParamError('mixed_list', e) +- +- +-def is_option(value, *options): +- """ +- This check matches the value to any of a set of options. +- +- >>> vtor.check('option("yoda", "jedi")', 'yoda') +- 'yoda' +- >>> vtor.check('option("yoda", "jedi")', 'jed') +- Traceback (most recent call last): +- VdtValueError: the value "jed" is unacceptable. +- >>> vtor.check('option("yoda", "jedi")', 0) +- Traceback (most recent call last): +- VdtTypeError: the value "0" is of the wrong type. +- """ +- if not isinstance(value, basestring): +- raise VdtTypeError(value) +- if not value in options: +- raise VdtValueError(value) +- return value +- +- +-def _test(value, *args, **keywargs): +- """ +- A function that exists for test purposes. +- +- >>> checks = [ +- ... '3, 6, min=1, max=3, test=list(a, b, c)', +- ... '3', +- ... '3, 6', +- ... '3,', +- ... 'min=1, test="a b c"', +- ... 'min=5, test="a, b, c"', +- ... 'min=1, max=3, test="a, b, c"', +- ... 'min=-100, test=-99', +- ... 'min=1, max=3', +- ... '3, 6, test="36"', +- ... '3, 6, test="a, b, c"', +- ... '3, max=3, test=list("a", "b", "c")', +- ... '''3, max=3, test=list("'a'", 'b', "x=(c)")''', +- ... "test='x=fish(3)'", +- ... ] +- >>> v = Validator({'test': _test}) +- >>> for entry in checks: +- ... print v.check(('test(%s)' % entry), 3) +- (3, ('3', '6'), {'test': ['a', 'b', 'c'], 'max': '3', 'min': '1'}) +- (3, ('3',), {}) +- (3, ('3', '6'), {}) +- (3, ('3',), {}) +- (3, (), {'test': 'a b c', 'min': '1'}) +- (3, (), {'test': 'a, b, c', 'min': '5'}) +- (3, (), {'test': 'a, b, c', 'max': '3', 'min': '1'}) +- (3, (), {'test': '-99', 'min': '-100'}) +- (3, (), {'max': '3', 'min': '1'}) +- (3, ('3', '6'), {'test': '36'}) +- (3, ('3', '6'), {'test': 'a, b, c'}) +- (3, ('3',), {'test': ['a', 'b', 'c'], 'max': '3'}) +- (3, ('3',), {'test': ["'a'", 'b', 'x=(c)'], 'max': '3'}) +- (3, (), {'test': 'x=fish(3)'}) +- +- >>> v = Validator() +- >>> v.check('integer(default=6)', '3') +- 3 +- >>> v.check('integer(default=6)', None, True) +- 6 +- >>> v.get_default_value('integer(default=6)') +- 6 +- >>> v.get_default_value('float(default=6)') +- 6.0 +- >>> v.get_default_value('pass(default=None)') +- >>> v.get_default_value("string(default='None')") +- 'None' +- >>> v.get_default_value('pass') +- Traceback (most recent call last): +- KeyError: 'Check "pass" has no default value.' +- >>> v.get_default_value('pass(default=list(1, 2, 3, 4))') +- ['1', '2', '3', '4'] +- +- >>> v = Validator() +- >>> v.check("pass(default=None)", None, True) +- >>> v.check("pass(default='None')", None, True) +- 'None' +- >>> v.check('pass(default="None")', None, True) +- 'None' +- >>> v.check('pass(default=list(1, 2, 3, 4))', None, True) +- ['1', '2', '3', '4'] +- +- Bug test for unicode arguments +- >>> v = Validator() +- >>> v.check(u'string(min=4)', u'test') +- u'test' +- +- >>> v = Validator() +- >>> v.get_default_value(u'string(min=4, default="1234")') +- u'1234' +- >>> v.check(u'string(min=4, default="1234")', u'test') +- u'test' +- +- >>> v = Validator() +- >>> default = v.get_default_value('string(default=None)') +- >>> default == None +- 1 +- """ +- return (value, args, keywargs) +- +- +-def _test2(): +- """ +- >>> +- >>> v = Validator() +- >>> v.get_default_value('string(default="#ff00dd")') +- '#ff00dd' +- >>> v.get_default_value('integer(default=3) # comment') +- 3 +- """ +- +-def _test3(): +- r""" +- >>> vtor.check('string(default="")', '', missing=True) +- '' +- >>> vtor.check('string(default="\n")', '', missing=True) +- '\n' +- >>> print vtor.check('string(default="\n")', '', missing=True), +- +- >>> vtor.check('string()', '\n') +- '\n' +- >>> vtor.check('string(default="\n\n\n")', '', missing=True) +- '\n\n\n' +- >>> vtor.check('string()', 'random \n text goes here\n\n') +- 'random \n text goes here\n\n' +- >>> vtor.check('string(default=" \nrandom text\ngoes \n here\n\n ")', +- ... '', missing=True) +- ' \nrandom text\ngoes \n here\n\n ' +- >>> vtor.check("string(default='\n\n\n')", '', missing=True) +- '\n\n\n' +- >>> vtor.check("option('\n','a','b',default='\n')", '', missing=True) +- '\n' +- >>> vtor.check("string_list()", ['foo', '\n', 'bar']) +- ['foo', '\n', 'bar'] +- >>> vtor.check("string_list(default=list('\n'))", '', missing=True) +- ['\n'] +- """ +- +- +-if __name__ == '__main__': +- # run the code tests in doctest format +- import sys +- import doctest +- m = sys.modules.get('__main__') +- globs = m.__dict__.copy() +- globs.update({ +- 'vtor': Validator(), +- }) +- doctest.testmod(m, globs=globs) +diff -x .bzr -uNr terminator-1.91/terminatorlib/config.py python3/terminatorlib/config.py +--- terminator-1.91/terminatorlib/config.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/config.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # TerminatorConfig - layered config classes + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -74,10 +74,10 @@ + import platform + import os + from copy import copy +-from configobj.configobj import ConfigObj, flatten_errors +-from configobj.validate import Validator +-from borg import Borg +-from util import dbg, err, DEBUG, get_config_dir, dict_diff ++from configobj import ConfigObj, flatten_errors ++from validate import Validator ++from .borg import Borg ++from .util import dbg, err, DEBUG, get_config_dir, dict_diff + + from gi.repository import Gio + +@@ -298,7 +298,7 @@ + profile = options.profile + dbg('Config::set_profile: Changing profile to %s' % profile) + self.profile = profile +- if not self.base.profiles.has_key(profile): ++ if profile not in self.base.profiles: + dbg('Config::set_profile: %s does not exist, creating' % profile) + self.base.profiles[profile] = copy(DEFAULTS['profiles']['default']) + +@@ -313,7 +313,7 @@ + # remove a profile + err('Config::del_profile: Deleting in-use profile %s.' % profile) + self.set_profile('default') +- if self.base.profiles.has_key(profile): ++ if profile in self.base.profiles: + del(self.base.profiles[profile]) + options = self.options_get() + if options and options.profile == profile: +@@ -322,7 +322,7 @@ + + def rename_profile(self, profile, newname): + """Rename a profile""" +- if self.base.profiles.has_key(profile): ++ if profile in self.base.profiles: + self.base.profiles[newname] = self.base.profiles[profile] + del(self.base.profiles[profile]) + if profile == self.profile: +@@ -330,7 +330,7 @@ + + def list_profiles(self): + """List all configured profiles""" +- return(self.base.profiles.keys()) ++ return(list(self.base.profiles.keys())) + + def add_layout(self, name, layout): + """Add a new layout""" +@@ -342,18 +342,18 @@ + + def del_layout(self, layout): + """Delete a layout""" +- if self.base.layouts.has_key(layout): ++ if layout in self.base.layouts: + del(self.base.layouts[layout]) + + def rename_layout(self, layout, newname): + """Rename a layout""" +- if self.base.layouts.has_key(layout): ++ if layout in self.base.layouts: + self.base.layouts[newname] = self.base.layouts[layout] + del(self.base.layouts[layout]) + + def list_layouts(self): + """List all configured layouts""" +- return(self.base.layouts.keys()) ++ return(list(self.base.layouts.keys())) + + def connect_gsetting_callbacks(self): + """Get system settings and create callbacks for changes""" +@@ -416,7 +416,7 @@ + self.system_mono_font = None + # Need to trigger a reconfigure to change active terminals immediately + if "Terminator" not in globals(): +- from terminator import Terminator ++ from .terminator import Terminator + Terminator().reconfigure() + + def save(self): +@@ -490,7 +490,7 @@ + Borg.__init__(self, self.__class__.__name__) + + self.prepare_attributes() +- import optionparse ++ from . import optionparse + self.command_line_options = optionparse.options + self.load() + +@@ -585,7 +585,7 @@ + + configspec = ConfigObj(configspecdata) + if DEBUG == True: +- configspec.write(open('/tmp/terminator_configspec_debug.txt', 'w')) ++ configspec.write(open('/tmp/terminator_configspec_debug.txt', 'wb')) + return(configspec) + + def load(self): +@@ -604,7 +604,7 @@ + dbg('looking for config file: %s' % filename) + try: + configfile = open(filename, 'r') +- except Exception, ex: ++ except Exception as ex: + if not self.whined: + err('ConfigBase::load: Unable to open %s (%s)' % (filename, ex)) + self.whined = True +@@ -617,7 +617,7 @@ + parser = ConfigObj(configfile, configspec=configspec) + validator = Validator() + result = parser.validate(validator, preserve_errors=True) +- except Exception, ex: ++ except Exception as ex: + err('Unable to load configuration: %s' % ex) + return + +@@ -637,12 +637,12 @@ + if section_name == 'profiles': + for profile in parser[section_name]: + dbg('ConfigBase::load: Processing profile: %s' % profile) +- if not section.has_key(section_name): ++ if section_name not in section: + # FIXME: Should this be outside the loop? + section[profile] = copy(DEFAULTS['profiles']['default']) + section[profile].update(parser[section_name][profile]) + elif section_name == 'plugins': +- if not parser.has_key(section_name): ++ if section_name not in parser: + continue + for part in parser[section_name]: + dbg('ConfigBase::load: Processing %s: %s' % (section_name, +@@ -657,7 +657,7 @@ + continue + section[layout] = parser[section_name][layout] + elif section_name == 'keybindings': +- if not parser.has_key(section_name): ++ if section_name not in parser: + continue + for part in parser[section_name]: + dbg('ConfigBase::load: Processing %s: %s' % (section_name, +@@ -669,7 +669,7 @@ + else: + try: + section.update(parser[section_name]) +- except KeyError, ex: ++ except KeyError as ex: + dbg('ConfigBase::load: skipping missing section %s' % + section_name) + +@@ -711,21 +711,21 @@ + if not os.path.isdir(config_dir): + os.makedirs(config_dir) + try: +- parser.write(open(self.command_line_options.config, 'w')) +- except Exception, ex: ++ parser.write(open(self.command_line_options.config, 'wb')) ++ except Exception as ex: + err('ConfigBase::save: Unable to save config: %s' % ex) + + def get_item(self, key, profile='default', plugin=None, default=None): + """Look up a configuration item""" +- if not self.profiles.has_key(profile): ++ if profile not in self.profiles: + # Hitting this generally implies a bug + profile = 'default' + +- if self.global_config.has_key(key): ++ if key in self.global_config: + dbg('ConfigBase::get_item: %s found in globals: %s' % + (key, self.global_config[key])) + return(self.global_config[key]) +- elif self.profiles[profile].has_key(key): ++ elif key in self.profiles[profile]: + dbg('ConfigBase::get_item: %s found in profile %s: %s' % ( + key, profile, self.profiles[profile][key])) + return(self.profiles[profile][key]) +@@ -745,14 +745,14 @@ + dbg('ConfigBase::set_item: Setting %s=%s (profile=%s, plugin=%s)' % + (key, value, profile, plugin)) + +- if self.global_config.has_key(key): ++ if key in self.global_config: + self.global_config[key] = value +- elif self.profiles[profile].has_key(key): ++ elif key in self.profiles[profile]: + self.profiles[profile][key] = value + elif key == 'keybindings': + self.keybindings = value + elif plugin is not None: +- if not self.plugins.has_key(plugin): ++ if plugin not in self.plugins: + self.plugins[plugin] = {} + self.plugins[plugin][key] = value + else: +@@ -762,7 +762,7 @@ + + def get_plugin(self, plugin): + """Return a whole tree for a plugin""" +- if self.plugins.has_key(plugin): ++ if plugin in self.plugins: + return(self.plugins[plugin]) + + def set_plugin(self, plugin, tree): +@@ -797,7 +797,7 @@ + + def get_layout(self, layout): + """Return a layout""" +- if self.layouts.has_key(layout): ++ if layout in self.layouts: + return(self.layouts[layout]) + else: + err('layout does not exist: %s' % layout) +diff -x .bzr -uNr terminator-1.91/terminatorlib/container.py python3/terminatorlib/container.py +--- terminator-1.91/terminatorlib/container.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/container.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """container.py - classes necessary to contain Terminal widgets""" +@@ -6,13 +6,12 @@ + from gi.repository import GObject + from gi.repository import Gtk + +-from factory import Factory +-from config import Config +-from util import dbg, err +-from translation import _ +-from signalman import Signalman ++from .factory import Factory ++from .config import Config ++from .util import dbg, err ++from .translation import _ ++from .signalman import Signalman + +-# pylint: disable-msg=R0921 + class Container(object): + """Base class for Terminator Containers""" + +@@ -38,7 +37,7 @@ + dbg('Container:: skipping signal %s for %s, already exists' % ( + signal['name'], widget)) + else: +- dbg('Container:: registering signal for %s on %s' % ++ dbg('Container:: registering signal for %s on %s' % + (signal['name'], widget)) + try: + GObject.signal_new(signal['name'], +@@ -156,19 +155,19 @@ + + def construct_confirm_close(self, window, reqtype): + """Create a confirmation dialog for closing things""" +- ++ + # skip this dialog if applicable + if self.config['suppress_multiple_term_dialog']: + return Gtk.ResponseType.ACCEPT +- ++ + dialog = Gtk.Dialog(_('Close?'), window, Gtk.DialogFlags.MODAL) + dialog.set_resizable(False) +- ++ + dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) + c_all = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT) + c_all.get_children()[0].get_children()[0].get_children()[1].set_label( + _('Close _Terminals')) +- ++ + primary = Gtk.Label(label=_('Close multiple terminals?')) + primary.set_use_markup(True) + primary.set_alignment(0, 0.5) +@@ -182,15 +181,15 @@ + label_text = '' + secondary = Gtk.Label(label=label_text) + secondary.set_line_wrap(True) +- ++ + labels = Gtk.VBox() + labels.pack_start(primary, False, False, 6) + labels.pack_start(secondary, False, False, 6) +- ++ + image = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING, + Gtk.IconSize.DIALOG) + image.set_alignment(0.5, 0) +- ++ + box = Gtk.HBox() + box.pack_start(image, False, False, 6) + box.pack_start(labels, False, False, 6) +@@ -198,18 +197,18 @@ + + checkbox = Gtk.CheckButton(_("Do not show this message next time")) + dialog.vbox.pack_end(checkbox, True, True, 0) +- ++ + dialog.show_all() + + result = dialog.run() +- ++ + # set configuration + self.config.base.reload() + self.config['suppress_multiple_term_dialog'] = checkbox.get_active() + self.config.save() + + dialog.destroy() +- ++ + return(result) + + def propagate_title_change(self, widget, title): +@@ -264,13 +263,13 @@ + if hasattr(position, '__iter__'): + position = ':'.join([str(x) for x in position]) + layout['position'] = position +- ++ + if hasattr(self, 'ismaximised'): + layout['maximised'] = self.ismaximised +- ++ + if hasattr(self, 'isfullscreen'): + layout['fullscreen'] = self.isfullscreen +- ++ + if hasattr(self, 'ratio'): + layout['ratio'] = self.ratio + +@@ -283,7 +282,7 @@ + if mytype == 'Notebook': + labels = [] + last_active_term = [] +- for tabnum in xrange(0, self.get_n_pages()): ++ for tabnum in range(0, self.get_n_pages()): + page = self.get_nth_page(tabnum) + label = self.get_tab_label(page) + labels.append(label.get_custom_label()) +diff -x .bzr -uNr terminator-1.91/terminatorlib/cwd.py python3/terminatorlib/cwd.py +--- terminator-1.91/terminatorlib/cwd.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/cwd.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """cwd.py - function necessary to get the cwd for a given pid on various OSes +@@ -15,7 +15,7 @@ + import platform + import os + import pwd +-from util import dbg, err ++from .util import dbg, err + + try: + import psutil +@@ -46,7 +46,7 @@ + func = linux_get_pid_cwd + elif system == 'FreeBSD': + try: +- import freebsd ++ from . import freebsd + func = freebsd.get_process_cwd + dbg('Using FreeBSD get_pid_cwd') + except (OSError, NotImplementedError, ImportError): +@@ -66,7 +66,7 @@ + insert it into, e.g. /proc/%s/cwd""" + try: + cwd = os.path.realpath(path % pid) +- except Exception, ex: ++ except Exception as ex: + err('Unable to get cwd for PID %s: %s' % (pid, ex)) + cwd = '/' + +diff -x .bzr -uNr terminator-1.91/terminatorlib/debugserver.py python3/terminatorlib/debugserver.py +--- terminator-1.91/terminatorlib/debugserver.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/debugserver.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # + # Copyright (c) 2008, Thomas Hurst + # +@@ -10,7 +10,7 @@ + + import socket + import threading +-import SocketServer ++import socketserver + import code + import sys + import readline +@@ -22,7 +22,7 @@ + return + dbg(msg) + +-class PythonConsoleServer(SocketServer.BaseRequestHandler): ++class PythonConsoleServer(socketserver.BaseRequestHandler): + env = None + def setup(self): + dbg('debugserver: connect from %s' % str(self.client_address)) +@@ -165,7 +165,7 @@ + + def spawn(env): + PythonConsoleServer.env = env +- tcpserver = SocketServer.TCPServer(('127.0.0.1', 0), PythonConsoleServer) ++ tcpserver = socketserver.TCPServer(('127.0.0.1', 0), PythonConsoleServer) + dbg("debugserver: listening on %s" % str(tcpserver.server_address)) + debugserver = threading.Thread(target=tcpserver.serve_forever, name="DebugServer") + debugserver.setDaemon(True) +diff -x .bzr -uNr terminator-1.91/terminatorlib/editablelabel.py python3/terminatorlib/editablelabel.py +--- terminator-1.91/terminatorlib/editablelabel.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/editablelabel.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab + # + # Copyright (c) 2009, Emmanuel Bretelle +diff -x .bzr -uNr terminator-1.91/terminatorlib/encoding.py python3/terminatorlib/encoding.py +--- terminator-1.91/terminatorlib/encoding.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/encoding.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # TerminatorEncoding - charset encoding classes + # Copyright (C) 2006-2010 chantra@debuntu.org + # +@@ -23,7 +23,7 @@ + and src/encoding.c + """ + +-from translation import _ ++from .translation import _ + + #pylint: disable-msg=R0903 + class TerminatorEncoding: +diff -x .bzr -uNr terminator-1.91/terminatorlib/factory.py python3/terminatorlib/factory.py +--- terminator-1.91/terminatorlib/factory.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/factory.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """factory.py - Maker of objects +@@ -19,8 +19,8 @@ + + """ + +-from borg import Borg +-from util import dbg, err, inject_uuid ++from .borg import Borg ++from .util import dbg, err, inject_uuid + + # pylint: disable-msg=R0201 + # pylint: disable-msg=W0613 +@@ -33,7 +33,7 @@ + 'Notebook': 'notebook', + 'Container': 'container', + 'Window': 'window'} +- types_keys = types.keys() ++ types_keys = list(types.keys()) + instance_types = {} + instance_types_keys = [] + +@@ -97,26 +97,26 @@ + + def make_window(self, **kwargs): + """Make a Window""" +- import window ++ from . import window + return(window.Window(**kwargs)) + + def make_terminal(self, **kwargs): + """Make a Terminal""" +- import terminal ++ from . import terminal + return(terminal.Terminal()) + + def make_hpaned(self, **kwargs): + """Make an HPaned""" +- import paned ++ from . import paned + return(paned.HPaned()) + + def make_vpaned(self, **kwargs): + """Make a VPaned""" +- import paned ++ from . import paned + return(paned.VPaned()) + + def make_notebook(self, **kwargs): + """Make a Notebook""" +- import notebook ++ from . import notebook + return(notebook.Notebook(kwargs['window'])) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/freebsd.py python3/terminatorlib/freebsd.py +--- terminator-1.91/terminatorlib/freebsd.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/freebsd.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # + # Copyright (c) 2008, Thomas Hurst + # +@@ -50,11 +50,11 @@ + ver = c_uint(0) + + if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(uintlen), None, 0) < 0): +- raise OSError, "sysctlbyname returned < 0" ++ raise OSError("sysctlbyname returned < 0") + + # kern.proc.filedesc added for procstat(1) after these __FreeBSD_versions + if ver.value < 700104 and ver.value < 800019: +- raise NotImplementedError, "cwd detection requires a recent 7.0-STABLE or 8-CURRENT" ++ raise NotImplementedError("cwd detection requires a recent 7.0-STABLE or 8-CURRENT") + + + def get_process_cwd(pid): +@@ -72,7 +72,7 @@ + return None + + kifs = cast(buf, POINTER(kinfo_file)) +- for i in xrange(0, uintlen.value / sizeof(kinfo_file)): ++ for i in range(0, uintlen.value / sizeof(kinfo_file)): + kif = kifs[i] + if kif.kf_fd == -1: # KF_FD_TYPE_CWD + return kif.kf_path +@@ -80,12 +80,12 @@ + + if __name__ == '__main__': + import os, sys +- print " => %d cwd = %s" % (os.getpid(), get_process_cwd(os.getpid())) ++ print((" => %d cwd = %s" % (os.getpid(), get_process_cwd(os.getpid())))) + for pid in sys.argv: + try: + pid = int(pid) + except: + pass + else: +- print " => %d cwd = %s" % (pid, get_process_cwd(pid)) ++ print((" => %d cwd = %s" % (pid, get_process_cwd(pid)))) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/__init__.py python3/terminatorlib/__init__.py +--- terminator-1.91/terminatorlib/__init__.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/__init__.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator - multiple gnome terminals in one window + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +diff -x .bzr -uNr terminator-1.91/terminatorlib/ipc.py python3/terminatorlib/ipc.py +--- terminator-1.91/terminatorlib/ipc.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/ipc.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,17 +1,18 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """ipc.py - DBus server and API calls""" + ++import hashlib + from gi.repository import Gdk + import dbus.service + from dbus.exceptions import DBusException + import dbus.glib +-from borg import Borg +-from terminator import Terminator +-from config import Config +-from factory import Factory +-from util import dbg, enumerate_descendants ++from .borg import Borg ++from .terminator import Terminator ++from .config import Config ++from .factory import Factory ++from .util import dbg, enumerate_descendants + + CONFIG = Config() + if not CONFIG['dbus']: +@@ -23,7 +24,9 @@ + BUS_PATH = '/net/tenshu/Terminator2' + try: + # Try and include the X11 display name in the dbus bus name +- DISPLAY = hex(hash(Gdk.get_display().partition('.')[0])) ++ DISPLAY = Gdk.get_display().partition('.')[0] ++ # In Python 3, hash() uses a different seed on each run, so use hashlib ++ DISPLAY = hashlib.md5(DISPLAY.encode('utf-8')).hexdigest() + BUS_NAME = '%s%s' % (BUS_BASE, DISPLAY) + except: + BUS_NAME = BUS_BASE +@@ -185,7 +188,7 @@ + + def with_proxy(func): + """Decorator function to connect to the session dbus bus""" +- dbg('dbus client call: %s' % func.func_name) ++ dbg('dbus client call: %s' % func.__name__) + def _exec(*args, **argd): + bus = dbus.SessionBus() + proxy = bus.get_object(BUS_NAME, BUS_PATH) +@@ -205,45 +208,45 @@ + @with_proxy + def new_window(session, options): + """Call the dbus method to open a new window""" +- print session.new_window() ++ print((session.new_window())) + + @with_proxy + def new_tab(session, uuid, options): + """Call the dbus method to open a new tab in the first window""" +- print session.new_tab(uuid) ++ print((session.new_tab(uuid))) + + @with_proxy + def hsplit(session, uuid, options): + """Call the dbus method to horizontally split a terminal""" +- print session.hsplit(uuid) ++ print((session.hsplit(uuid))) + + @with_proxy + def vsplit(session, uuid, options): + """Call the dbus method to vertically split a terminal""" +- print session.vsplit(uuid) ++ print((session.vsplit(uuid))) + + @with_proxy + def get_terminals(session, options): + """Call the dbus method to return a list of all terminals""" +- print '\n'.join(session.get_terminals()) ++ print(('\n'.join(session.get_terminals()))) + + @with_proxy + def get_window(session, uuid, options): + """Call the dbus method to return the toplevel tab for a terminal""" +- print session.get_window(uuid) ++ print((session.get_window(uuid))) + + @with_proxy + def get_window_title(session, uuid, options): + """Call the dbus method to return the title of a tab""" +- print session.get_window_title(uuid) ++ print((session.get_window_title(uuid))) + + @with_proxy + def get_tab(session, uuid, options): + """Call the dbus method to return the toplevel tab for a terminal""" +- print session.get_tab(uuid) ++ print((session.get_tab(uuid))) + + @with_proxy + def get_tab_title(session, uuid, options): + """Call the dbus method to return the title of a tab""" +- print session.get_tab_title(uuid) ++ print((session.get_tab_title(uuid))) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/keybindings.py python3/terminatorlib/keybindings.py +--- terminator-1.91/terminatorlib/keybindings.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/keybindings.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator - multiple gnome terminals in one window + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -24,7 +24,7 @@ + + import re + from gi.repository import Gtk, Gdk +-from util import err ++from .util import err + + class KeymapError(Exception): + """Custom exception for errors in keybinding configurations""" +@@ -61,7 +61,7 @@ + """Parse bindings and mangle into an appropriate form""" + self._lookup = {} + self._masks = 0 +- for action, bindings in self.keys.items(): ++ for action, bindings in list(self.keys.items()): + if not isinstance(bindings, tuple): + bindings = (bindings,) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/layoutlauncher.py python3/terminatorlib/layoutlauncher.py +--- terminator-1.91/terminatorlib/layoutlauncher.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/layoutlauncher.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """layoutlauncher.py - class for the Layout Launcher window""" +@@ -7,11 +7,11 @@ + from gi.repository import Gtk + from gi.repository import GObject + +-from util import dbg, err, spawn_new_terminator +-import config +-from translation import _ +-from terminator import Terminator +-from plugin import PluginRegistry ++from .util import dbg, err, spawn_new_terminator ++from . import config ++from .translation import _ ++from .terminator import Terminator ++from .plugin import PluginRegistry + + class LayoutLauncher: + """Class implementing the various parts of the preferences editor""" +@@ -38,9 +38,9 @@ + librarypath = os.path.join(head, 'layoutlauncher.glade') + gladefile = open(librarypath, 'r') + gladedata = gladefile.read() +- except Exception, ex: +- print "Failed to find layoutlauncher.glade" +- print ex ++ except Exception as ex: ++ print("Failed to find layoutlauncher.glade") ++ print(ex) + return + + self.builder.add_from_string(gladedata) +@@ -72,7 +72,7 @@ + """Update the contents of the layout""" + self.layouttreestore.clear() + layouts = self.config.list_layouts() +- for layout in sorted(layouts, cmp=lambda x,y: cmp(x.lower(), y.lower())): ++ for layout in sorted(layouts, key=str.lower): + if layout != "default": + self.layouttreestore.append([layout]) + else: +@@ -100,9 +100,9 @@ + spawn_new_terminator(self.terminator.origcwd, ['-u', '-l', layout]) + + if __name__ == '__main__': +- import util ++ from . import util + util.DEBUG = True +- import terminal ++ from . import terminal + LAYOUTLAUNCHER = LayoutLauncher() + + Gtk.main() +diff -x .bzr -uNr terminator-1.91/terminatorlib/notebook.py python3/terminatorlib/notebook.py +--- terminator-1.91/terminatorlib/notebook.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/notebook.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """notebook.py - classes for the notebook widget""" +@@ -8,13 +8,13 @@ + from gi.repository import Gdk + from gi.repository import Gio + +-from terminator import Terminator +-from config import Config +-from factory import Factory +-from container import Container +-from editablelabel import EditableLabel +-from translation import _ +-from util import err, dbg, enumerate_descendants, make_uuid ++from .terminator import Terminator ++from .config import Config ++from .factory import Factory ++from .container import Container ++from .editablelabel import EditableLabel ++from .translation import _ ++from .util import err, dbg, enumerate_descendants, make_uuid + + class Notebook(Container, Gtk.Notebook): + """Class implementing a Gtk.Notebook container""" +@@ -65,7 +65,7 @@ + pos = getattr(Gtk.PositionType, self.config['tab_position'].upper()) + self.set_tab_pos(pos) + +- for tab in xrange(0, self.get_n_pages()): ++ for tab in range(0, self.get_n_pages()): + label = self.get_tab_label(self.get_nth_page(tab)) + label.update_angle() + +@@ -88,7 +88,7 @@ + if (order_a > order_b): + return 1 + +- if not layout.has_key('children'): ++ if 'children' not in layout: + err('layout specifies no children: %s' % layout) + return + +@@ -99,7 +99,7 @@ + return + + num = 0 +- keys = children.keys() ++ keys = list(children.keys()) + keys.sort(child_compare) + + for child_key in keys: +@@ -122,7 +122,7 @@ + # This page does not yet exist, so make it + self.newtab(children[child_key]) + page = self.get_nth_page(num) +- if layout.has_key('labels'): ++ if 'labels' in layout: + labeltext = layout['labels'][num] + if labeltext and labeltext != "None": + label = self.get_tab_label(page) +@@ -133,7 +133,7 @@ + self.last_active_term[page] = make_uuid(layout['last_active_term'][num]) + num = num + 1 + +- if layout.has_key('active_page'): ++ if 'active_page' in layout: + # Need to do it later, or layout changes result + GObject.idle_add(self.set_current_page, int(layout['active_page'])) + else: +@@ -233,7 +233,7 @@ + def get_children(self): + """Return an ordered list of our children""" + children = [] +- for page in xrange(0,self.get_n_pages()): ++ for page in range(0,self.get_n_pages()): + children.append(self.get_nth_page(page)) + return(children) + +@@ -278,13 +278,13 @@ + handler = handler[0] + self.connect_child(widget, signal, handler, *args) + +- if metadata and metadata.has_key('tabnum'): ++ if metadata and 'tabnum' in metadata: + tabpos = metadata['tabnum'] + else: + tabpos = -1 + + label = TabLabel(self.window.get_title(), self) +- if metadata and metadata.has_key('label'): ++ if metadata and 'label' in metadata: + dbg('creating TabLabel with text: %s' % metadata['label']) + label.set_custom_label(metadata['label']) + label.connect('close-clicked', self.closetab) +@@ -334,7 +334,7 @@ + err('TabLabel::closetab: called on non-Notebook: %s' % widget) + return + +- for i in xrange(0, nb.get_n_pages() + 1): ++ for i in range(0, nb.get_n_pages() + 1): + if label == nb.get_tab_label(nb.get_nth_page(i)): + tabnum = i + break +@@ -434,7 +434,7 @@ + del(self) + # Find the last terminal in the new parent and give it focus + terms = parent.get_visible_terminals() +- terms.keys()[-1].grab_focus() ++ list(terms.keys())[-1].grab_focus() + + def page_num_descendant(self, widget): + """Find the tabnum of the tab containing a widget at any level""" +@@ -464,7 +464,7 @@ + if self.terminator.doing_layout == True: + return + last_active_term = {} +- for tabnum in xrange(0, self.get_n_pages()): ++ for tabnum in range(0, self.get_n_pages()): + nth_page = self.get_nth_page(tabnum) + if nth_page in self.last_active_term: + last_active_term[nth_page] = self.last_active_term[nth_page] +@@ -501,7 +501,7 @@ + #print "event: %s" % event + child = self.get_nth_page(self.get_current_page()) + if child == None: +- print "Child = None, return false" ++ print("Child = None, return false") + return False + + event_widget = Gtk.get_event_widget(event) +@@ -509,7 +509,7 @@ + if event_widget == None or \ + event_widget == child or \ + event_widget.is_ancestor(child): +- print "event_widget is wrong one, return false" ++ print("event_widget is wrong one, return false") + return False + + # Not sure if we need these. I don't think wehave any action widgets +diff -x .bzr -uNr terminator-1.91/terminatorlib/optionparse.py python3/terminatorlib/optionparse.py +--- terminator-1.91/terminatorlib/optionparse.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/optionparse.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator.optionparse - Parse commandline options + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -20,11 +20,11 @@ + import os + + from optparse import OptionParser, SUPPRESS_HELP +-from util import dbg, err +-import util +-import config +-import version +-from translation import _ ++from .util import dbg, err ++from . import util ++from . import config ++from . import version ++from .translation import _ + + options = None + +@@ -79,8 +79,6 @@ + 'inside the terminal, and its arguments')) + parser.add_option('--working-directory', metavar='DIR', + dest='working_directory', help=_('Set the working directory')) +- parser.add_option('-c', '--classname', dest='classname', help=_('Set a \ +-custom name (WM_CLASS) property on the window')) + parser.add_option('-i', '--icon', dest='forcedicon', help=_('Set a custom \ + icon for the window (by file or name)')) + parser.add_option('-r', '--role', dest='role', +@@ -112,7 +110,7 @@ + parser.error('Additional unexpected arguments found: %s' % args) + + if options.version: +- print '%s %s' % (version.APP_NAME, version.APP_VERSION) ++ print(('%s %s' % (version.APP_NAME, version.APP_VERSION))) + sys.exit(0) + + if options.debug_classes or options.debug_methods: +diff -x .bzr -uNr terminator-1.91/terminatorlib/paned.py python3/terminatorlib/paned.py +--- terminator-1.91/terminatorlib/paned.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/paned.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """paned.py - a base Paned container class and the vertical/horizontal +@@ -7,12 +7,11 @@ + import time + from gi.repository import GObject, Gtk, Gdk + +-from util import dbg, err, enumerate_descendants +-from terminator import Terminator +-from factory import Factory +-from container import Container ++from .util import dbg, err, enumerate_descendants ++from .terminator import Terminator ++from .factory import Factory ++from .container import Container + +-# pylint: disable-msg=R0921 + # pylint: disable-msg=E1101 + class Paned(Container): + """Base class for Paned Containers""" +@@ -28,9 +27,9 @@ + self.terminator = Terminator() + self.maker = Factory() + Container.__init__(self) +- self.signals.append({'name': 'resize-term', ++ self.signals.append({'name': 'resize-term', + 'flags': GObject.SignalFlags.RUN_LAST, +- 'return_type': None, ++ 'return_type': None, + 'param_types': (GObject.TYPE_STRING,)}) + + +@@ -45,7 +44,7 @@ + container = VPaned() + else: + container = HPaned() +- ++ + self.get_toplevel().set_pos_by_ratio = True + + if not sibling: +@@ -71,7 +70,7 @@ + + self.show_all() + sibling.grab_focus() +- ++ + while Gtk.events_pending(): + Gtk.main_iteration_do(False) + self.get_toplevel().set_pos_by_ratio = False +@@ -123,7 +122,7 @@ + self.connect_child(widget, signal, handler, *args) + + if metadata and \ +- metadata.has_key('had_focus') and \ ++ 'had_focus' in metadata and \ + metadata['had_focus'] == True: + widget.grab_focus() + +@@ -141,7 +140,7 @@ + recurse_up=True + else: + recurse_up=False +- ++ + if event.get_state() & Gdk.ModifierType.SHIFT_MASK == Gdk.ModifierType.SHIFT_MASK: + recurse_down=True + else: +@@ -184,7 +183,7 @@ + highest_ancestor = highest_ancestor.get_parent() + + highest_ancestor.set_autoresize(False) +- ++ + # (1b) If Super modifier, redistribute higher sections too + if recurse_up: + grandfather=highest_ancestor.get_parent() +@@ -195,7 +194,7 @@ + highest_ancestor._do_redistribute(recurse_up, recurse_down) + + GObject.idle_add(highest_ancestor.set_autoresize, True) +- ++ + def _do_redistribute(self, recurse_up=False, recurse_down=False): + maker = Factory() + #2 Make a list of self + all children of same type +@@ -221,7 +220,7 @@ + (maker.isinstance(child, 'VPaned') or \ + maker.isinstance(child, 'HPaned')): + child.do_redistribute(False, True) +- ++ + #3 Get ancestor x/y => a, and handle size => hs + avail_pixels=self.get_length() + handle_size = self.get_handlesize() +@@ -357,7 +356,7 @@ + + def create_layout(self, layout): + """Apply layout configuration""" +- if not layout.has_key('children'): ++ if 'children' not in layout: + err('layout specifies no children: %s' % layout) + return + +@@ -376,14 +375,14 @@ + for child in children: + key = children[child]['order'] + child_order_map[key] = child +- map_keys = child_order_map.keys() ++ map_keys = list(child_order_map.keys()) + map_keys.sort() + for map_key in map_keys: + keys.append(child_order_map[map_key]) + except KeyError: + # We've failed to figure out the order. At least give the terminals + # in the wrong order +- keys = children.keys() ++ keys = list(children.keys()) + + num = 0 + for child_key in keys: +@@ -411,7 +410,7 @@ + self.get_child2().create_layout(children[keys[1]]) + + # Set the position with ratio. For some reason more reliable than by pos. +- if layout.has_key('ratio'): ++ if 'ratio' in layout: + self.ratio = float(layout['ratio']) + self.set_position_by_ratio() + +@@ -472,7 +471,7 @@ + self.set_position_by_ratio() + else: + self.set_position(self.get_position()) +- ++ + def position_by_ratio(self, total_size, handle_size, ratio): + non_separator_size = max(total_size - handle_size, 0) + ratio = min(max(ratio, 0.0), 1.0) +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugin.py python3/terminatorlib/plugin.py +--- terminator-1.91/terminatorlib/plugin.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugin.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """plugin.py - Base plugin system +@@ -25,10 +25,10 @@ + + import sys + import os +-import borg +-from config import Config +-from util import dbg, err, get_config_dir +-from terminator import Terminator ++from . import borg ++from .config import Config ++from .util import dbg, err, get_config_dir ++from .terminator import Terminator + + class Plugin(object): + """Definition of our base plugin class""" +@@ -95,7 +95,7 @@ + try: + module = __import__(plugin[:-3], None, None, ['']) + for item in getattr(module, 'AVAILABLE'): +- if item not in self.available_plugins.keys(): ++ if item not in list(self.available_plugins.keys()): + func = getattr(module, item) + self.available_plugins[item] = func + +@@ -104,7 +104,7 @@ + continue + if item not in self.instances: + self.instances[item] = func() +- except Exception, ex: ++ except Exception as ex: + err('PluginRegistry::load_plugins: Importing plugin %s \ + failed: %s' % (plugin, ex)) + +@@ -127,12 +127,12 @@ + def get_available_plugins(self): + """Return a list of all available plugins whether they are enabled or + disabled""" +- return(self.available_plugins.keys()) ++ return(list(self.available_plugins.keys())) + + def is_enabled(self, plugin): + """Return a boolean value indicating whether a plugin is enabled or + not""" +- return(self.instances.has_key(plugin)) ++ return(plugin in self.instances) + + def enable(self, plugin): + """Enable a plugin""" +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/activitywatch.py python3/terminatorlib/plugins/activitywatch.py +--- terminator-1.91/terminatorlib/plugins/activitywatch.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/activitywatch.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """activitywatch.py - Terminator Plugin to watch a terminal for activity""" +@@ -53,7 +53,7 @@ + def callback(self, menuitems, menu, terminal): + """Add our menu item to the menu""" + item = Gtk.CheckMenuItem.new_with_mnemonic(_('Watch for _activity')) +- item.set_active(self.watches.has_key(terminal)) ++ item.set_active(terminal in self.watches) + if item.get_active(): + item.connect("activate", self.unwatch, terminal) + else: +@@ -85,7 +85,7 @@ + terminal.get_window_title(), 'terminator') + + this_time = time.mktime(time.gmtime()) +- if not self.last_notifies.has_key(terminal): ++ if terminal not in self.last_notifies: + show_notify = True + else: + last_time = self.last_notifies[terminal] +@@ -119,7 +119,7 @@ + def callback(self, menuitems, menu, terminal): + """Add our menu item to the menu""" + item = Gtk.CheckMenuItem.new_with_mnemonic(_("Watch for _silence")) +- item.set_active(self.watches.has_key(terminal)) ++ item.set_active(terminal in self.watches) + if item.get_active(): + item.connect("activate", self.unwatch, terminal) + else: +@@ -153,7 +153,7 @@ + def check_times(self, terminal): + """Check if this terminal has gone silent""" + time_now = time.mktime(time.gmtime()) +- if not self.last_activities.has_key(terminal): ++ if terminal not in self.last_activities: + dbg('Terminal %s has no last activity' % terminal) + return True + +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/custom_commands.py python3/terminatorlib/plugins/custom_commands.py +--- terminator-1.91/terminatorlib/plugins/custom_commands.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/custom_commands.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """custom_commands.py - Terminator Plugin to add custom command menu entries""" +@@ -16,7 +16,7 @@ + from terminatorlib.translation import _ + from terminatorlib.util import get_config_dir, err, dbg, gerr + +-(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND) = range(0,3) ++(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND) = list(range(0,3)) + + # Every plugin you want Terminator to load *must* be listed in 'AVAILABLE' + AVAILABLE = ['CustomCommandsMenu'] +@@ -35,13 +35,13 @@ + noord_cmds = [] + for part in sections: + s = sections[part] +- if not (s.has_key("name") and s.has_key("command")): +- print "CustomCommandsMenu: Ignoring section %s" % s ++ if not ("name" in s and "command" in s): ++ print(("CustomCommandsMenu: Ignoring section %s" % s)) + continue + name = s["name"] + command = s["command"] + enabled = s["enabled"] and s["enabled"] or False +- if s.has_key("position"): ++ if "position" in s: + self.cmd_list[int(s["position"])] = {'enabled' : enabled, + 'name' : name, + 'command' : command +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/logger.py python3/terminatorlib/plugins/logger.py +--- terminator-1.91/terminatorlib/plugins/logger.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/logger.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + + # Plugin by Sinan Nalkaya + # See LICENSE of Terminator package. +@@ -30,7 +30,7 @@ + def callback(self, menuitems, menu, terminal): + """ Add save menu item to the menu""" + vte_terminal = terminal.get_vte() +- if not self.loggers.has_key(vte_terminal): ++ if vte_terminal not in self.loggers: + item = Gtk.MenuItem.new_with_mnemonic(_('Start _Logger')) + item.connect("activate", self.start_logger, terminal) + else: +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/maven.py python3/terminatorlib/plugins/maven.py +--- terminator-1.91/terminatorlib/plugins/maven.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/maven.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Copyright (c) 2010 Julien Nicoulaud + # + # This program is free software; you can redistribute it and/or modify +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/activitywatch.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/activitywatch.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/custom_commands.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/custom_commands.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/logger.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/logger.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/maven.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/maven.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/terminalshot.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/terminalshot.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/testplugin.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/testplugin.cpython-37.pyc differ +Binary files terminator-1.91/terminatorlib/plugins/__pycache__/url_handlers.cpython-37.pyc and python3/terminatorlib/plugins/__pycache__/url_handlers.cpython-37.pyc differ +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/terminalshot.py python3/terminatorlib/plugins/terminalshot.py +--- terminator-1.91/terminatorlib/plugins/terminalshot.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/terminalshot.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """terminalshot.py - Terminator Plugin to take 'screenshots' of individual +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/testplugin.py python3/terminatorlib/plugins/testplugin.py +--- terminator-1.91/terminatorlib/plugins/testplugin.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/testplugin.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + import terminatorlib.plugin as plugin + + # AVAILABLE must contain a list of all the classes that you want exposed +diff -x .bzr -uNr terminator-1.91/terminatorlib/plugins/url_handlers.py python3/terminatorlib/plugins/url_handlers.py +--- terminator-1.91/terminatorlib/plugins/url_handlers.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/plugins/url_handlers.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones &1 | grep "^Your code has been rated") ++ rating=$(echo $line | cut -f 7 -d ' ') ++ previous=$(echo $line | cut -f 10 -d ' ') ++ ++ if [ "$rating" != "10.00/10" ]; then ++ echo "$file rated $rating (previously $previous)" ++ fi ++done +diff -x .bzr -uNr terminator-1.91/terminatorlib/searchbar.py python3/terminatorlib/searchbar.py +--- terminator-1.91/terminatorlib/searchbar.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/searchbar.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,14 +1,14 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """searchbar.py - classes necessary to provide a terminal search bar""" + + from gi.repository import Gtk, Gdk + from gi.repository import GObject +-import re ++from gi.repository import GLib + +-from translation import _ +-from config import Config ++from .translation import _ ++from .config import Config + + # pylint: disable-msg=R0904 + class Searchbar(Gtk.HBox): +@@ -19,7 +19,6 @@ + } + + entry = None +- reslabel = None + next = None + prev = None + wrap = None +@@ -29,9 +28,6 @@ + + searchstring = None + searchre = None +- searchrow = None +- +- searchits = None + + def __init__(self): + """Class initialiser""" +@@ -52,10 +48,6 @@ + label = Gtk.Label(label=_('Search:')) + label.show() + +- # Result label +- self.reslabel = Gtk.Label(label='') +- self.reslabel.show() +- + # Close Button + close = Gtk.Button() + close.set_relief(Gtk.ReliefStyle.NONE) +@@ -89,7 +81,6 @@ + + self.pack_start(label, False, True, 0) + self.pack_start(self.entry, True, True, 0) +- self.pack_start(self.reslabel, False, True, 0) + self.pack_start(self.prev, False, False, 0) + self.pack_start(self.next, False, False, 0) + self.pack_start(self.wrap, False, False, 0) +@@ -99,10 +90,9 @@ + self.set_no_show_all(True) + + def wrap_toggled(self, toggled): +- if self.searchrow is None: +- self.prev.set_sensitive(False) +- self.next.set_sensitive(False) +- elif toggled: ++ toggled_state = toggled.get_active() ++ self.vte.search_set_wrap_around(toggled_state) ++ if toggled_state: + self.prev.set_sensitive(True) + self.next.set_sensitive(True) + +@@ -137,93 +127,38 @@ + return + + if searchtext != self.searchstring: +- self.searchrow = self.get_vte_buffer_range()[0] - 1 + self.searchstring = searchtext +- self.searchre = re.compile(searchtext) ++ self.searchre = GLib.Regex(searchtext, 0, 0) ++ self.vte.search_set_gregex(self.searchre, 0) + +- self.reslabel.set_text(_("Searching scrollback")) + self.next.set_sensitive(True) + self.prev.set_sensitive(True) + self.next_search(None) + + def next_search(self, widget): + """Search forwards and jump to the next result, if any""" +- startrow,endrow = self.get_vte_buffer_range() +- found = startrow <= self.searchrow and self.searchrow < endrow +- row = self.searchrow +- while True: +- row += 1 +- if row >= endrow: +- if found and self.wrap.get_active(): +- row = startrow - 1 +- else: +- self.prev.set_sensitive(found) +- self.next.set_sensitive(False) +- self.reslabel.set_text(_('No more results')) +- return +- buffer = self.vte.get_text_range(row, 0, row + 1, 0, self.search_character) +- +- buffer = buffer[0] +- buffer = buffer[:buffer.find('\n')] +- matches = self.searchre.search(buffer) +- if matches: +- self.searchrow = row +- self.prev.set_sensitive(True) +- self.search_hit(self.searchrow) +- return ++ found_result = self.vte.search_find_next() ++ if not self.wrap.get_active(): ++ self.next.set_sensitive(found_result) ++ else: ++ self.next.set_sensitive(True) ++ self.prev.set_sensitive(True) ++ return + + def prev_search(self, widget): + """Jump back to the previous search""" +- startrow,endrow = self.get_vte_buffer_range() +- found = startrow <= self.searchrow and self.searchrow < endrow +- row = self.searchrow +- while True: +- row -= 1 +- if row <= startrow: +- if found and self.wrap.get_active(): +- row = endrow +- else: +- self.next.set_sensitive(found) +- self.prev.set_sensitive(False) +- self.reslabel.set_text(_('No more results')) +- return +- buffer = self.vte.get_text_range(row, 0, row + 1, 0, self.search_character) +- +- buffer = buffer[0] +- buffer = buffer[:buffer.find('\n')] +- matches = self.searchre.search(buffer) +- if matches: +- self.searchrow = row +- self.next.set_sensitive(True) +- self.search_hit(self.searchrow) +- return +- +- def search_hit(self, row): +- """Update the UI for a search hit""" +- self.reslabel.set_text("%s %d" % (_('Found at row'), row)) +- self.get_parent().scrollbar_jump(row) +- self.next.show() +- self.prev.show() +- +- def search_character(self, widget, col, row): +- """We have to have a callback for each character""" +- return(True) +- +- def get_vte_buffer_range(self): +- """Get the range of a vte widget""" +- column, endrow = self.vte.get_cursor_position() +- if self.config['scrollback_infinite']: +- startrow = 0 ++ found_result = self.vte.search_find_previous() ++ if not self.wrap.get_active(): ++ self.prev.set_sensitive(found_result) + else: +- startrow = max(0, endrow - self.config['scrollback_lines']) +- return(startrow, endrow) ++ self.prev.set_sensitive(True) ++ self.next.set_sensitive(True) ++ return + + def end_search(self, widget=None): + """Trap and re-emit the end-search signal""" +- self.searchrow = 0 + self.searchstring = None + self.searchre = None +- self.reslabel.set_text('') + self.emit('end-search') + + def get_search_term(self): +diff -x .bzr -uNr terminator-1.91/terminatorlib/signalman.py python3/terminatorlib/signalman.py +--- terminator-1.91/terminatorlib/signalman.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/signalman.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,9 +1,9 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """Simple management of Gtk Widget signal handlers""" + +-from util import dbg, err ++from .util import dbg, err + + class Signalman(object): + """Class providing glib signal tracking and management""" +@@ -16,16 +16,16 @@ + + def __del__(self): + """Class destructor. This is only used to check for stray signals""" +- if len(self.cnxids.keys()) > 0: ++ if len(list(self.cnxids.keys())) > 0: + dbg('Remaining signals: %s' % self.cnxids) + + def new(self, widget, signal, handler, *args): + """Register a new signal on a widget""" +- if not self.cnxids.has_key(widget): ++ if widget not in self.cnxids: + dbg('creating new bucket for %s' % type(widget)) + self.cnxids[widget] = {} + +- if self.cnxids[widget].has_key(signal): ++ if signal in self.cnxids[widget]: + err('%s already has a handler for %s' % (id(widget), signal)) + + self.cnxids[widget][signal] = widget.connect(signal, handler, *args) +@@ -34,31 +34,31 @@ + + def remove_signal(self, widget, signal): + """Remove a signal handler""" +- if not self.cnxids.has_key(widget): ++ if widget not in self.cnxids: + dbg('%s is not registered' % widget) + return +- if not self.cnxids[widget].has_key(signal): ++ if signal not in self.cnxids[widget]: + dbg('%s not registered for %s' % (signal, type(widget))) + return + dbg('removing %s::%s' % (type(widget), signal)) + widget.disconnect(self.cnxids[widget][signal]) + del(self.cnxids[widget][signal]) +- if len(self.cnxids[widget].keys()) == 0: ++ if len(list(self.cnxids[widget].keys())) == 0: + dbg('no more signals for widget') + del(self.cnxids[widget]) + + def remove_widget(self, widget): + """Remove all signal handlers for a widget""" +- if not self.cnxids.has_key(widget): ++ if widget not in self.cnxids: + dbg('%s not registered' % widget) + return +- signals = self.cnxids[widget].keys() ++ signals = list(self.cnxids[widget].keys()) + for signal in signals: + self.remove_signal(widget, signal) + + def remove_all(self): + """Remove all signal handlers for all widgets""" +- widgets = self.cnxids.keys() ++ widgets = list(self.cnxids.keys()) + for widget in widgets: + self.remove_widget(widget) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/terminal_popup_menu.py python3/terminatorlib/terminal_popup_menu.py +--- terminator-1.91/terminatorlib/terminal_popup_menu.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/terminal_popup_menu.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,21 +1,19 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """terminal_popup_menu.py - classes necessary to provide a terminal context + menu""" + +-import string +- + from gi.repository import Gtk + +-from version import APP_NAME +-from translation import _ +-from encoding import TerminatorEncoding +-from terminator import Terminator +-from util import err, dbg +-from config import Config +-from prefseditor import PrefsEditor +-import plugin ++from .version import APP_NAME ++from .translation import _ ++from .encoding import TerminatorEncoding ++from .terminator import Terminator ++from .util import err, dbg ++from .config import Config ++from .prefseditor import PrefsEditor ++from . import plugin + + class TerminalPopupMenu(object): + """Class implementing the Terminal context menu""" +@@ -51,7 +49,7 @@ + + if url and url[0]: + dbg("URL matches id: %d" % url[1]) +- if not url[1] in terminal.matches.values(): ++ if not url[1] in list(terminal.matches.values()): + err("Unknown URL match id: %d" % url[1]) + dbg("Available matches: %s" % terminal.matches) + +@@ -63,7 +61,7 @@ + elif url[1] == terminal.matches['voip']: + nameopen = _('Ca_ll VoIP address') + namecopy = _('_Copy VoIP address') +- elif url[1] in terminal.matches.values(): ++ elif url[1] in list(terminal.matches.values()): + # This is a plugin match + for pluginname in terminal.matches: + if terminal.matches[pluginname] == url[1]: +@@ -191,7 +189,7 @@ + item.connect('activate', lambda x: PrefsEditor(self.terminal)) + menu.append(item) + +- profilelist = sorted(self.config.list_profiles(), key=string.lower) ++ profilelist = sorted(self.config.list_profiles(), key=str.lower) + + if len(profilelist) > 1: + item = Gtk.MenuItem.new_with_mnemonic(_('Profiles')) +@@ -228,7 +226,7 @@ + + for menuitem in menuitems: + menu.append(menuitem) +- except Exception, ex: ++ except Exception as ex: + err('TerminalPopupMenu::show: %s' % ex) + + menu.show_all() +@@ -246,7 +244,7 @@ + submenu = Gtk.Menu () + item.set_submenu (submenu) + encodings = TerminatorEncoding ().get_list () +- encodings.sort (lambda x, y: cmp (x[2].lower (), y[2].lower ())) ++ encodings.sort (key=lambda x: x[2].lower ()) + + current_encoding = terminal.vte.get_encoding () + group = None +diff -x .bzr -uNr terminator-1.91/terminatorlib/terminal.py python3/terminatorlib/terminal.py +--- terminator-1.91/terminatorlib/terminal.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/terminal.py 2019-10-21 22:59:38.279726026 -0400 +@@ -1,9 +1,9 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """terminal.py - classes necessary to provide Terminal widgets""" + +-from __future__ import division ++ + import os + import signal + import gi +@@ -11,20 +11,20 @@ + gi.require_version('Vte', '2.91') # vte-0.38 (gnome-3.14) + from gi.repository import Vte + import subprocess +-import urllib ++import urllib.request, urllib.parse, urllib.error + +-from util import dbg, err, spawn_new_terminator, make_uuid, manual_lookup, display_manager +-import util +-from config import Config +-from cwd import get_default_cwd +-from factory import Factory +-from terminator import Terminator +-from titlebar import Titlebar +-from terminal_popup_menu import TerminalPopupMenu +-from searchbar import Searchbar +-from translation import _ +-from signalman import Signalman +-import plugin ++from .util import dbg, err, spawn_new_terminator, make_uuid, manual_lookup, display_manager ++from . import util ++from .config import Config ++from .cwd import get_default_cwd ++from .factory import Factory ++from .terminator import Terminator ++from .titlebar import Titlebar ++from .terminal_popup_menu import TerminalPopupMenu ++from .searchbar import Searchbar ++from .translation import _ ++from .signalman import Signalman ++from . import plugin + from terminatorlib.layoutlauncher import LayoutLauncher + + # pylint: disable-msg=R0904 +@@ -63,7 +63,7 @@ + (GObject.TYPE_INT,)), + 'group-all': (GObject.SignalFlags.RUN_LAST, None, ()), + 'group-all-toggle': (GObject.SignalFlags.RUN_LAST, None, ()), +- 'move-tab': (GObject.SignalFlags.RUN_LAST, None, ++ 'move-tab': (GObject.SignalFlags.RUN_LAST, None, + (GObject.TYPE_STRING,)), + } + +@@ -72,7 +72,7 @@ + + MOUSEBUTTON_LEFT = 1 + MOUSEBUTTON_MIDDLE = 2 +- MOUSEBUTTON_RIGHT = 3 ++ MOUSEBUTTON_RIGHT = 3 + + terminator = None + vte = None +@@ -232,7 +232,7 @@ + try: + dbg('close: killing %d' % self.pid) + os.kill(self.pid, signal.SIGHUP) +- except Exception, ex: ++ except Exception as ex: + # We really don't want to care if this failed. Deep OS voodoo is + # not what we should be doing. + dbg('os.kill failed: %s' % ex) +@@ -269,7 +269,7 @@ + rboundry = "\\b" + + re = (lboundry + schemes + +- "//(" + user + "@)?[" + hostchars +".]+(:[0-9]+)?(" + ++ "//(" + user + "@)?[" + hostchars +".]+(:[0-9]+)?(" + + urlpath + ")?" + rboundry + "/?") + reg = GLib.Regex.new(re, self.regex_flags, 0) + self.matches['full_uri'] = self.vte.match_add_gregex(reg, 0) +@@ -278,13 +278,13 @@ + err ('Terminal::update_url_matches: Failed adding URL matches') + else: + re = (lboundry + +- '(callto:|h323:|sip:)' + "[" + userchars + "+][" + +- userchars + ".]*(:[0-9]+)?@?[" + pathchars + "]+" + ++ '(callto:|h323:|sip:)' + "[" + userchars + "+][" + ++ userchars + ".]*(:[0-9]+)?@?[" + pathchars + "]+" + + rboundry) + reg = GLib.Regex.new(re, self.regex_flags, 0) + self.matches['voip'] = self.vte.match_add_gregex(reg, 0) + re = (lboundry + +- "(www|ftp)[" + hostchars + "]*\.[" + hostchars + ++ "(www|ftp)[" + hostchars + "]*\.[" + hostchars + + ".]+(:[0-9]+)?(" + urlpath + ")?" + rboundry + "/?") + reg = GLib.Regex.new(re, self.regex_flags, 0) + self.matches['addr_only'] = self.vte.match_add_gregex(reg, 0) +@@ -314,10 +314,10 @@ + continue + reg = GLib.Regex.new(match, self.regex_flags, 0) + self.matches[name] = self.vte.match_add_gregex(reg, 0) +- dbg('added plugin URL handler for %s (%s) as %d' % ++ dbg('added plugin URL handler for %s (%s) as %d' % + (name, urlplugin.__class__.__name__, + self.matches[name])) +- except Exception, ex: ++ except Exception as ex: + err('Exception occurred adding plugin URL match: %s' % ex) + + def match_add(self, name, match): +@@ -351,19 +351,19 @@ + self.cnxids.new(self.vte, 'popup-menu', self.popup_menu) + + srcvtetargets = [("vte", Gtk.TargetFlags.SAME_APP, self.TARGET_TYPE_VTE)] +- dsttargets = [("vte", Gtk.TargetFlags.SAME_APP, self.TARGET_TYPE_VTE), +- ('text/x-moz-url', 0, self.TARGET_TYPE_MOZ), ++ dsttargets = [("vte", Gtk.TargetFlags.SAME_APP, self.TARGET_TYPE_VTE), ++ ('text/x-moz-url', 0, self.TARGET_TYPE_MOZ), + ('_NETSCAPE_URL', 0, 0)] + ''' + The following should work, but on my system it corrupts the returned + TargetEntry's in the newdstargets with binary crap, causing "Segmentation + fault (core dumped)" when the later drag_dest_set gets called. +- ++ + dsttargetlist = Gtk.TargetList.new([]) + dsttargetlist.add_text_targets(0) + dsttargetlist.add_uri_targets(0) + dsttargetlist.add_table(dsttargets) +- ++ + newdsttargets = Gtk.target_table_new_from_list(dsttargetlist) + ''' + # FIXME: Temporary workaround for the problems with the correct way of doing things +@@ -381,7 +381,7 @@ + dbg('Finalised drag targets: %s' % dsttargets) + + for (widget, mask) in [ +- (self.vte, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.BUTTON3_MASK), ++ (self.vte, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.BUTTON3_MASK), + (self.titlebar, Gdk.ModifierType.BUTTON1_MASK)]: + widget.drag_source_set(mask, srcvtetargets, Gdk.DragAction.MOVE) + +@@ -398,7 +398,7 @@ + self.cnxids.new(self.vte, 'drag-data-received', + self.on_drag_data_received, self) + +- self.cnxids.new(self.vte, 'selection-changed', ++ self.cnxids.new(self.vte, 'selection-changed', + lambda widget: self.maybe_copy_clipboard()) + + if self.composite_support: +@@ -495,9 +495,9 @@ + groupitems = [] + cnxs = [] + +- for key, value in {_('Broadcast _all'):'all', ++ for key, value in list({_('Broadcast _all'):'all', + _('Broadcast _group'):'group', +- _('Broadcast _off'):'off'}.items(): ++ _('Broadcast _off'):'off'}.items()): + item = Gtk.RadioMenuItem.new_with_mnemonic(groupitems, key) + groupitems = item.get_group() + dbg('Terminal::populate_group_menu: %s active: %s' % +@@ -568,7 +568,7 @@ + self.terminator.group_hoover() + + def create_group(self, _item): +- """Trigger the creation of a group via the titlebar (because popup ++ """Trigger the creation of a group via the titlebar (because popup + windows are really lame)""" + self.titlebar.create_group() + +@@ -588,7 +588,7 @@ + def set_groupsend(self, _widget, value): + """Set the groupsend mode""" + # FIXME: Can we think of a smarter way of doing this than poking? +- if value in self.terminator.groupsend_type.values(): ++ if value in list(self.terminator.groupsend_type.values()): + dbg('Terminal::set_groupsend: setting groupsend to %s' % value) + self.terminator.groupsend = value + +@@ -611,7 +611,7 @@ + if self.config['exit_action'] == 'restart': + self.cnxids.new(self.vte, 'child-exited', self.spawn_child, True) + elif self.config['exit_action'] in ('close', 'left'): +- self.cnxids.new(self.vte, 'child-exited', ++ self.cnxids.new(self.vte, 'child-exited', + lambda x, y: self.emit('close-term')) + + if self.custom_encoding != True: +@@ -714,20 +714,20 @@ + if len(colors) == 16: + # RGB values for indices 16..255 copied from vte source in order to dim them + shades = [0, 95, 135, 175, 215, 255] +- for r in xrange(0, 6): +- for g in xrange(0, 6): +- for b in xrange(0, 6): ++ for r in range(0, 6): ++ for g in range(0, 6): ++ for b in range(0, 6): + newcolor = Gdk.RGBA() + setattr(newcolor, "red", shades[r] / 255.0) + setattr(newcolor, "green", shades[g] / 255.0) + setattr(newcolor, "blue", shades[b] / 255.0) + self.palette_active.append(newcolor) +- for y in xrange(8, 248, 10): ++ for y in range(8, 248, 10): + newcolor = Gdk.RGBA() + setattr(newcolor, "red", y / 255.0) + setattr(newcolor, "green", y / 255.0) + setattr(newcolor, "blue", y / 255.0) +- self.palette_active.append(newcolor) ++ self.palette_active.append(newcolor) + self.palette_inactive = [] + for color in self.palette_active: + newcolor = Gdk.RGBA() +@@ -743,7 +743,7 @@ + self.palette_inactive) + profiles = self.config.base.profiles + terminal_box_style_context = self.terminalbox.get_style_context() +- for profile in profiles.keys(): ++ for profile in list(profiles.keys()): + munged_profile = "terminator-profile-%s" % ( + "".join([c if c.isalnum() else "-" for c in profile])) + if terminal_box_style_context.has_class(munged_profile): +@@ -799,7 +799,7 @@ + def set_cursor_color(self): + """Set the cursor color appropriately""" + if self.config['cursor_color_fg']: +- self.vte.set_color_cursor(None) ++ self.vte.set_color_cursor(None) + else: + cursor_color = Gdk.RGBA() + cursor_color.parse(self.config['cursor_color']) +@@ -842,6 +842,8 @@ + elif event.type == Gdk.EventType.BUTTON_PRESS: + # Single Click gives popup + dbg('on_group_button_press: group menu popup') ++ window = self.get_toplevel() ++ window.preventHide = True + self.create_popup_group_menu(widget, event) + return True + else: +@@ -868,7 +870,7 @@ + if mapping == "hide_window": + return(False) + +- if mapping and mapping not in ['close_window', ++ if mapping and mapping not in ['close_window', + 'full_screen']: + dbg('Terminal::on_keypress: lookup found: %r' % mapping) + # handle the case where user has re-bound copy to ctrl+ +@@ -926,8 +928,12 @@ + # try to pass it to vte widget first though + if event.get_state() & Gdk.ModifierType.CONTROL_MASK == 0: + if event.get_state() & Gdk.ModifierType.SHIFT_MASK == 0: ++ gtk_settings=Gtk.Settings().get_default() ++ primary_state = gtk_settings.get_property('gtk-enable-primary-paste') ++ gtk_settings.set_property('gtk-enable-primary-paste', False) + if not Vte.Terminal.do_button_press_event(self.vte, event): + middle_click[0](*middle_click[1]) ++ gtk_settings.set_property('gtk-enable-primary-paste', primary_state) + else: + middle_click[0](*middle_click[1]) + return(True) +@@ -945,7 +951,7 @@ + return(True) + + return(False) +- ++ + def on_mousewheel(self, widget, event): + """Handler for modifier + mouse wheel scroll events""" + SMOOTH_SCROLL_UP = event.direction == Gdk.ScrollDirection.SMOOTH and event.delta_y <= 0. +@@ -978,6 +984,8 @@ + + def popup_menu(self, widget, event=None): + """Display the context menu""" ++ window = self.get_toplevel() ++ window.preventHide = True + menu = TerminalPopupMenu(self) + menu.show(widget, event) + +@@ -1004,11 +1012,11 @@ + """Handle the start of a drag event""" + Gtk.drag_set_icon_pixbuf(drag_context, util.widget_pixbuf(self, 512), 0, 0) + +- def on_drag_data_get(self, _widget, _drag_context, selection_data, info, +- _time, data): ++ def on_drag_data_get(self, _widget, _drag_context, selection_data, info, ++ _time,data): + """I have no idea what this does, drag and drop is a mystery. sorry.""" + selection_data.set(Gdk.atom_intern('vte', False), info, +- str(data.terminator.terminals.index(self))) ++ str(data.terminator.terminals.index(self)).encode()) + + def on_drag_motion(self, widget, drag_context, x, y, _time, _data): + """*shrug*""" +@@ -1018,7 +1026,7 @@ + # copy text from another widget + return + srcwidget = Gtk.drag_get_source_widget(drag_context) +- if(isinstance(srcwidget, Gtk.EventBox) and ++ if(isinstance(srcwidget, Gtk.EventBox) and + srcwidget == self.titlebar) or widget == srcwidget: + # on self + return +@@ -1049,7 +1057,7 @@ + elif pos == "left": + coord = (topleft, topmiddle, bottommiddle, bottomleft) + elif pos == "bottom": +- coord = (bottomleft, bottomright, middleright , middleleft) ++ coord = (bottomleft, bottomright, middleright , middleleft) + + #here, we define some widget internal values + widget._draw_data = { 'color': color, 'coord' : coord } +@@ -1105,18 +1113,18 @@ + str='' + for fname in txt_lines[:-1]: + dbg('drag data fname: %s' % fname) +- fname = "'%s'" % urllib.unquote(fname[7:].replace("'", ++ fname = "'%s'" % urllib.parse.unquote(fname[7:].replace("'", + '\'\\\'\'')) + str += fname + ' ' + txt=str + for term in self.terminator.get_target_terms(self): + term.feed(txt) + return +- ++ + widgetsrc = data.terminator.terminals[int(selection_data.get_data())] + srcvte = Gtk.drag_get_source_widget(drag_context) + #check if computation requireds +- if (isinstance(srcvte, Gtk.EventBox) and ++ if (isinstance(srcvte, Gtk.EventBox) and + srcvte == self.titlebar) or srcvte == widget: + return + +@@ -1369,6 +1377,7 @@ + elif self.layout_command: + command = self.layout_command + elif debugserver is True: ++ # pylint: disable=unsubscriptable-object + details = self.terminator.debug_address + dbg('spawning debug session with: %s:%s' % (details[0], + details[1])) +@@ -1445,7 +1454,7 @@ + url = 'ftp://' + url + elif match == self.matches['addr_only']: + url = 'http://' + url +- elif match in self.matches.values(): ++ elif match in list(self.matches.values()): + # We have a match, but it's not a hard coded one, so it's a plugin + try: + registry = plugin.PluginRegistry() +@@ -1460,7 +1469,7 @@ + %s plugin' % urlplugin.handler_name) + url = newurl + break +- except Exception, ex: ++ except Exception as ex: + err('Exception occurred preparing URL: %s' % ex) + + return(url) +@@ -1621,20 +1630,20 @@ + def create_layout(self, layout): + """Apply our layout""" + dbg('Setting layout') +- if layout.has_key('command') and layout['command'] != '': ++ if 'command' in layout and layout['command'] != '': + self.layout_command = layout['command'] +- if layout.has_key('profile') and layout['profile'] != '': ++ if 'profile' in layout and layout['profile'] != '': + if layout['profile'] in self.config.list_profiles(): + self.set_profile(self, layout['profile']) +- if layout.has_key('group') and layout['group'] != '': ++ if 'group' in layout and layout['group'] != '': + # This doesn't need/use self.titlebar, but it's safer than sending + # None + self.really_create_group(self.titlebar, layout['group']) +- if layout.has_key('title') and layout['title'] != '': ++ if 'title' in layout and layout['title'] != '': + self.titlebar.set_custom_string(layout['title']) +- if layout.has_key('directory') and layout['directory'] != '': ++ if 'directory' in layout and layout['directory'] != '': + self.directory = layout['directory'] +- if layout.has_key('uuid') and layout['uuid'] != '': ++ if 'uuid' in layout and layout['uuid'] != '': + self.uuid = make_uuid(layout['uuid']) + + def scroll_by_page(self, pages): +@@ -1846,7 +1855,7 @@ + + def key_insert_number(self): + self.emit('enumerate', False) +- ++ + def key_insert_padded(self): + self.emit('enumerate', True) + +@@ -1859,13 +1868,14 @@ + dialog.set_default_response(Gtk.ResponseType.ACCEPT) + dialog.set_resizable(False) + dialog.set_border_width(8) +- ++ + label = Gtk.Label(label=_('Enter a new title for the Terminator window...')) + name = Gtk.Entry() + name.set_activates_default(True) + if window.title.text != self.vte.get_window_title(): + name.set_text(self.get_toplevel().title.text) +- ++ ++ + dialog.vbox.pack_start(label, False, False, 6) + dialog.vbox.pack_start(name, False, False, 6) + +diff -x .bzr -uNr terminator-1.91/terminatorlib/terminator.py python3/terminatorlib/terminator.py +--- terminator-1.91/terminatorlib/terminator.py 2017-02-28 17:07:22.000000000 -0500 ++++ python3/terminatorlib/terminator.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """terminator.py - class for the master Terminator singleton""" +@@ -10,14 +10,14 @@ + from gi.repository import Gtk, Gdk, Vte, GdkX11 + from gi.repository.GLib import GError + +-import borg +-from borg import Borg +-from config import Config +-from keybindings import Keybindings +-from util import dbg, err, enumerate_descendants +-from factory import Factory +-from cwd import get_pid_cwd +-from version import APP_NAME, APP_VERSION ++from . import borg ++from .borg import Borg ++from .config import Config ++from .keybindings import Keybindings ++from .util import dbg, err, enumerate_descendants ++from .factory import Factory ++from .cwd import get_pid_cwd ++from .version import APP_NAME, APP_VERSION + + def eventkey2gdkevent(eventkey): # FIXME FOR GTK3: is there a simpler way of casting from specific EventKey to generic (union) GdkEvent? + gdkevent = Gdk.Event.new(eventkey.type) +@@ -267,34 +267,34 @@ + count = count + 1 + if count == 1000: + err('hit maximum loop boundary. THIS IS VERY LIKELY A BUG') +- for obj in layout.keys(): ++ for obj in list(layout.keys()): + if layout[obj]['type'].lower() == 'window': + hierarchy[obj] = {} + hierarchy[obj]['type'] = 'Window' + hierarchy[obj]['children'] = {} + + # Copy any additional keys +- for objkey in layout[obj].keys(): +- if layout[obj][objkey] != '' and not hierarchy[obj].has_key(objkey): ++ for objkey in list(layout[obj].keys()): ++ if layout[obj][objkey] != '' and objkey not in hierarchy[obj]: + hierarchy[obj][objkey] = layout[obj][objkey] + + objects[obj] = hierarchy[obj] + del(layout[obj]) + else: + # Now examine children to see if their parents exist yet +- if not layout[obj].has_key('parent'): ++ if 'parent' not in layout[obj]: + err('Invalid object: %s' % obj) + del(layout[obj]) + continue +- if objects.has_key(layout[obj]['parent']): ++ if layout[obj]['parent'] in objects: + # Our parent has been created, add ourselves + childobj = {} + childobj['type'] = layout[obj]['type'] + childobj['children'] = {} + + # Copy over any additional object keys +- for objkey in layout[obj].keys(): +- if not childobj.has_key(objkey): ++ for objkey in list(layout[obj].keys()): ++ if objkey not in childobj: + childobj[objkey] = layout[obj][objkey] + + objects[layout[obj]['parent']]['children'][obj] = childobj +@@ -309,25 +309,25 @@ + raise(ValueError) + dbg('Creating a window') + window, terminal = self.new_window() +- if layout[windef].has_key('position'): ++ if 'position' in layout[windef]: + parts = layout[windef]['position'].split(':') + if len(parts) == 2: + window.move(int(parts[0]), int(parts[1])) +- if layout[windef].has_key('size'): ++ if 'size' in layout[windef]: + parts = layout[windef]['size'] + winx = int(parts[0]) + winy = int(parts[1]) + if winx > 1 and winy > 1: + window.resize(winx, winy) +- if layout[windef].has_key('title'): ++ if 'title' in layout[windef]: + window.title.force_title(layout[windef]['title']) +- if layout[windef].has_key('maximised'): ++ if 'maximised' in layout[windef]: + if layout[windef]['maximised'] == 'True': + window.ismaximised = True + else: + window.ismaximised = False + window.set_maximised(window.ismaximised) +- if layout[windef].has_key('fullscreen'): ++ if 'fullscreen' in layout[windef]: + if layout[windef]['fullscreen'] == 'True': + window.isfullscreen = True + else: +@@ -359,7 +359,7 @@ + # For windows with a notebook + notebook = window.get_toplevel().get_children()[0] + # Cycle through pages by number +- for page in xrange(0, notebook.get_n_pages()): ++ for page in range(0, notebook.get_n_pages()): + # Try and get the entry in the previously saved mapping + mapping = window_last_active_term_mapping[window] + page_last_active_term = mapping.get(notebook.get_nth_page(page), None) +@@ -474,7 +474,7 @@ + background-color: alpha(%s, %s); } + """ + profiles = self.config.base.profiles +- for profile in profiles.keys(): ++ for profile in list(profiles.keys()): + if profiles[profile]['use_theme_colors']: + # Create a dummy window/vte and realise it so it has correct + # values to read from +@@ -501,7 +501,7 @@ + css += template % (munged_profile, bgcolor, bgalpha) + + style_provider = Gtk.CssProvider() +- style_provider.load_from_data(css) ++ style_provider.load_from_data(css.encode('utf-8')) + self.style_providers.append(style_provider) + + # Attempt to load some theme specific stylistic tweaks for appearances +@@ -537,19 +537,19 @@ + + # Size the GtkPaned splitter handle size. + css = "" +- if self.config['handle_size'] in xrange(0, 21): ++ if self.config['handle_size'] in range(0, 21): + css += """ + .terminator-terminal-window GtkPaned, + .terminator-terminal-window paned { + -GtkPaned-handle-size: %s; } + """ % self.config['handle_size'] + style_provider = Gtk.CssProvider() +- style_provider.load_from_data(css) ++ style_provider.load_from_data(css.encode('utf-8')) + self.style_providers.append(style_provider) + + # Apply the providers, incrementing priority so they don't cancel out + # each other +- for idx in xrange(0, len(self.style_providers)): ++ for idx in range(0, len(self.style_providers)): + Gtk.StyleContext.add_provider_for_screen( + Gdk.Screen.get_default(), + self.style_providers[idx], +diff -x .bzr -uNr terminator-1.91/terminatorlib/titlebar.py python3/terminatorlib/titlebar.py +--- terminator-1.91/terminatorlib/titlebar.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/titlebar.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """titlebar.py - classes necessary to provide a terminal title bar""" +@@ -9,11 +9,11 @@ + import random + import itertools + +-from version import APP_NAME +-from util import dbg +-from terminator import Terminator +-from editablelabel import EditableLabel +-from translation import _ ++from .version import APP_NAME ++from .util import dbg ++from .terminator import Terminator ++from .editablelabel import EditableLabel ++from .translation import _ + + # pylint: disable-msg=R0904 + # pylint: disable-msg=W0613 +diff -x .bzr -uNr terminator-1.91/terminatorlib/translation.py python3/terminatorlib/translation.py +--- terminator-1.91/terminatorlib/translation.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/translation.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator - multiple gnome terminals in one window + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -17,8 +17,8 @@ + + """Terminator by Chris Jones """ + +-from version import APP_NAME +-from util import dbg ++from .version import APP_NAME ++from .util import dbg + + _ = None + +diff -x .bzr -uNr terminator-1.91/terminatorlib/util.py python3/terminatorlib/util.py +--- terminator-1.91/terminatorlib/util.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/util.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator.util - misc utility functions + # Copyright (C) 2006-2010 cmsj@tenshu.net + # +@@ -64,14 +64,14 @@ + if DEBUGMETHODS != [] and method not in DEBUGMETHODS: + return + try: +- print >> sys.stderr, "%s::%s: %s%s" % (classname, method, log, extra) ++ print(("%s::%s: %s%s" % (classname, method, log, extra)), file=sys.stderr) + except IOError: + pass + + def err(log = ""): + """Print an error message""" + try: +- print >> sys.stderr, log ++ print(log, file=sys.stderr) + except IOError: + pass + +@@ -279,7 +279,7 @@ + terminals""" + # FIXME: Does having to import this here mean we should move this function + # back to Container? +- from factory import Factory ++ from .factory import Factory + + containerstmp = [] + containers = [] +diff -x .bzr -uNr terminator-1.91/terminatorlib/version.py python3/terminatorlib/version.py +--- terminator-1.91/terminatorlib/version.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/terminatorlib/version.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # TerminatorVersion - version number + # Copyright (C) 2010 cmsj@tenshu.net + # +@@ -21,4 +21,4 @@ + """ + + APP_NAME = 'terminator' +-APP_VERSION = '1.91' ++APP_VERSION = '1.92' +diff -x .bzr -uNr terminator-1.91/terminatorlib/window.py python3/terminatorlib/window.py +--- terminator-1.91/terminatorlib/window.py 2017-02-28 17:07:22.000000000 -0500 ++++ python3/terminatorlib/window.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """window.py - class for the main Terminator window""" +@@ -10,13 +10,13 @@ + from gi.repository import GObject + from gi.repository import Gtk, Gdk, GdkX11 + +-from util import dbg, err, make_uuid, display_manager +-import util +-from translation import _ +-from version import APP_NAME +-from container import Container +-from factory import Factory +-from terminator import Terminator ++from .util import dbg, err, make_uuid, display_manager ++from . import util ++from .translation import _ ++from .version import APP_NAME ++from .container import Container ++from .factory import Factory ++from .terminator import Terminator + + if display_manager() == 'X11': + try: +@@ -42,6 +42,7 @@ + ignore_startup_show = None + set_pos_by_ratio = None + last_active_term = None ++ preventHide = None + + zoom_data = None + +@@ -75,6 +76,8 @@ + self.title = WindowTitle(self) + self.title.update() + ++ self.preventHide = False ++ + options = self.config.options_get() + if options: + if options.forcedtitle: +@@ -82,16 +85,13 @@ + + if options.role: + self.set_role(options.role) +- +-# if options.classname is not None: +-# self.set_wmclass(options.classname, self.wmclass_class) +- ++ + if options.forcedicon is not None: + icon_to_apply = options.forcedicon + + if options.geometry: + if not self.parse_geometry(options.geometry): +- err('Window::__init__: Unable to parse geometry: %s' % ++ err('Window::__init__: Unable to parse geometry: %s' % + options.geometry) + + self.apply_icon(icon_to_apply) +@@ -229,14 +229,20 @@ + terminal.on_window_focus_out() + + self.losefocus_time = time.time() +- if self.config['hide_on_lose_focus'] and self.get_property('visible'): +- self.position = self.get_position() +- self.hidefunc() ++ ++ if self.preventHide: ++ self.preventHide = False ++ else: ++ if self.config['hide_on_lose_focus'] and self.get_property('visible'): ++ self.position = self.get_position() ++ self.hidefunc() + + def on_focus_in(self, window, event): + """Focus has entered the window""" + self.set_urgency_hint(False) + if not self.terminator.doing_layout: ++ # self.uuid is injected in terminatorlib.factory ++ # pylint: disable=no-member + self.terminator.last_active_window = self.uuid + # FIXME: Cause the terminal titlebars to update here + +@@ -283,7 +289,7 @@ + def confirm_close(self, window, type): + """Display a confirmation dialog when the user is closing multiple + terminals in one window""" +- ++ + return(not (self.construct_confirm_close(window, type) == Gtk.ResponseType.ACCEPT)) + + def on_destroy_event(self, widget, data=None): +@@ -321,7 +327,7 @@ + # pylint: disable-msg=W0613 + def on_window_state_changed(self, window, event): + """Handle the state of the window changing""" +- self.isfullscreen = bool(event.new_window_state & ++ self.isfullscreen = bool(event.new_window_state & + Gdk.WindowState.FULLSCREEN) + self.ismaximised = bool(event.new_window_state & + Gdk.WindowState.MAXIMIZED) +@@ -380,7 +386,7 @@ + visual = screen.get_rgba_visual() + if visual: + self.set_visual(visual) +- ++ + def show(self, startup=False): + """Undo the startup show request if started in hidden mode""" + #Present is necessary to grab focus when window is hidden from taskbar. +@@ -462,7 +468,7 @@ + container = maker.make('VPaned') + else: + container = maker.make('HPaned') +- ++ + self.set_pos_by_ratio = True + + if not sibling: +@@ -486,7 +492,7 @@ + for term in order: + container.add(term) + container.show_all() +- ++ + while Gtk.events_pending(): + Gtk.main_iteration_do(False) + sibling.grab_focus() +@@ -513,7 +519,7 @@ + self.set_property('term_zoomed', True) + + if font_scale: +- widget.cnxids.new(widget, 'size-allocate', ++ widget.cnxids.new(widget, 'size-allocate', + widget.zoom_scale, self.zoom_data) + + widget.grab_focus() +@@ -651,7 +657,7 @@ + extra_height = win_height - total_font_height + + dbg('setting geometry hints: (ewidth:%s)(eheight:%s),\ +-(fwidth:%s)(fheight:%s)' % (extra_width, extra_height, ++(fwidth:%s)(fheight:%s)' % (extra_width, extra_height, + font_width, font_height)) + geometry = Gdk.Geometry() + geometry.base_width = extra_width +@@ -750,7 +756,7 @@ + if not maker.isinstance(notebook, 'Notebook'): + dbg('note in a notebook, refusing to ungroup tab') + return +- ++ + self.set_groups(None, self.get_visible_terminals()) + + def move_tab(self, widget, direction): +@@ -780,7 +786,7 @@ + else: + err('unknown direction: %s' % direction) + return +- ++ + notebook.reorder_child(child, page) + + def navigate_terminal(self, terminal, direction): +@@ -833,9 +839,9 @@ + for term in possibles: + rect = layout[term] + offsets[term] = util.get_nav_offset(edge, rect, direction) +- keys = offsets.values() ++ keys = list(offsets.values()) + keys.sort() +- winners = [k for k, v in offsets.iteritems() if v == keys[0]] ++ winners = [k for k, v in list(offsets.items()) if v == keys[0]] + next = terminals.index(winners[0]) + + if len(winners) > 1: +@@ -858,7 +864,7 @@ + + def create_layout(self, layout): + """Apply any config items from our layout""" +- if not layout.has_key('children'): ++ if 'children' not in layout: + err('layout describes no children: %s' % layout) + return + children = layout['children'] +@@ -867,7 +873,7 @@ + err('incorrect number of children for Window: %s' % layout) + return + +- child = children[children.keys()[0]] ++ child = children[list(children.keys())[0]] + terminal = self.get_children()[0] + dbg('Making a child of type: %s' % child['type']) + if child['type'] == 'VPaned': +@@ -888,10 +894,12 @@ + + self.get_children()[0].create_layout(child) + +- if layout.has_key('last_active_term') and layout['last_active_term'] not in ['', None]: ++ if 'last_active_term' in layout and layout['last_active_term'] not in ['', None]: + self.last_active_term = make_uuid(layout['last_active_term']) + +- if layout.has_key('last_active_window') and layout['last_active_window'] == 'True': ++ if 'last_active_window' in layout and layout['last_active_window'] == 'True': ++ # self.uuid is injected in terminatorlib.factory ++ # pylint: disable=no-member + self.terminator.last_active_window = self.uuid + + class WindowTitle(object): +Binary files terminator-1.91/terminatorlib/.window.py.swp and python3/terminatorlib/.window.py.swp differ +diff -x .bzr -uNr terminator-1.91/terminator.spec python3/terminator.spec +--- terminator-1.91/terminator.spec 1969-12-31 19:00:00.000000000 -0500 ++++ python3/terminator.spec 2019-10-21 22:58:46.937140000 -0400 +@@ -0,0 +1,126 @@ ++Name: terminator ++Version: 1.92 ++Release: 1%{?dist} ++Summary: Store and run multiple GNOME terminals in one window ++ ++Group: User Interface/Desktops ++License: GPLv2 ++URL: https://gnometerminator.blogspot.com/p/introduction.html ++Source: http://code.launchpad.net/terminator/gtk3/1.9/+download/terminator-%{version}.tar.gz ++ ++BuildArch: noarch ++BuildRequires: python-devel gettext desktop-file-utils intltool ++Requires: vte291 python-psutil python-gobject keybinder3 desktop-file-utils ++ ++%description ++Multiple GNOME terminals in one window. This is a project to produce ++an efficient way of filling a large area of screen space with ++terminals. This is done by splitting the window into a resizeable ++grid of terminals. As such, you can produce a very flexible ++arrangements of terminals for different tasks. ++ ++ ++%prep ++%setup -q ++sed -i '/#! \?\/usr.*/d' terminatorlib/*.py ++%patch -p1 ++ ++ ++%build ++%{__python} setup.py build ++ ++ ++%install ++rm -rf %{buildroot} ++%{__python} setup.py install -O1 --skip-build --root %{buildroot} ++%find_lang %{name} ++rm -f %{buildroot}/%{_datadir}/icons/hicolor/icon-theme.cache ++rm -f %{buildroot}/%{_datadir}/applications/%{name}.desktop ++desktop-file-install --dir=${RPM_BUILD_ROOT}%{_datadir}/applications data/%{name}.desktop ++ ++ ++%clean ++rm -rf %{buildroot} ++ ++ ++%files -f %{name}.lang ++%defattr(-,root,root) ++%doc README COPYING ChangeLog ++%{_mandir}/man1/%{name}.* ++%{_mandir}/man5/%{name}_config.* ++%{_bindir}/%{name} ++%{_bindir}/remotinator ++%{_bindir}/terminator.wrapper ++%{python_sitelib}/* ++%{_datadir}/applications/%{name}.desktop ++%{_datadir}/icons/hicolor/*/*/%{name}*.png ++%{_datadir}/icons/hicolor/*/*/%{name}*.svg ++%{_datadir}/icons/hicolor/16x16/status/terminal-bell.png ++%{_datadir}/pixmaps/%{name}.png ++%{_datadir}/icons/HighContrast/*/*/%{name}*.png ++%{_datadir}/icons/HighContrast/*/*/%{name}*.svg ++%{_datadir}/icons/HighContrast/16x16/status/terminal-bell.png ++%{_datadir}/appdata/terminator.appdata.xml ++ ++%post ++gtk-update-icon-cache -qf %{_datadir}/icons/hicolor &>/dev/null || : ++gtk-update-icon-cache -qf %{_datadir}/icons/HighContrast &>/dev/null || : ++ ++ ++%postun ++gtk-update-icon-cache -qf %{_datadir}/icons/hicolor &>/dev/null || : ++gtk-update-icon-cache -qf %{_datadir}/icons/HighContrast &>/dev/null || : ++ ++%changelog ++* Thu Nov 24 2016 Steve Boddy 1.90-1 ++- Update for gtk3 release using the specfile provided ++ by Matt Rose. ++ Note that this specfile is untested. ++ ++* Mon Aug 22 2011 Chris Jones 0.96-1 ++- Update for modern release to fix various build issues ++ by borrowing the specfile that Fedora uses ++ Note that this specfile is untested. ++ ++* Wed Mar 31 2010 Chris Jones 0.91-1 ++- Update to fix some stupid release bugs in 0.90. ++ Note that this specfile is untested. ++ ++* Tue Jan 05 2010 Chris Jones 0.90-1 ++- Attempt to update for 0.90 pre-release. ++ Note that this specfile is untested. ++ ++* Thu Jan 15 2009 Chris Jones 0.12-1 ++- Remove patch application since this isn't a fedora build. ++ Note that this specfile is untested. ++ ++* Mon Dec 08 2008 Ian Weller 0.11-3 ++- Patch version in terminatorlib/verison.py to the one we think it is ++- Fix License tag ++- Update post and postun scripts with one line ++ ++* Mon Dec 01 2008 Ian Weller 0.11-2 ++- Add BuildRequires: gettext ++- Fix installation of .desktop file ++- terminator-0.11-desktop.patch: ++ Remove useless things ++ Move to same category as gnome-terminal ++- Uses spaces instead of tabs in the specfile because I can't stand tabs ++ ++* Mon Dec 01 2008 Ian Weller 0.11-1 ++- Update upstream ++- Fix description to something useful ++- Fix group ++- Fix some specfile oddities ++- Complete/restandardize file list ++- Get rid of she-bangs in python_sitelib ++ ++* Sat Sep 13 2008 - Max Spevack 0.10 ++- New upstream release. ++- Tried to make sure the spec file matches guidelines on Fedora wiki. ++ ++* Fri Jul 08 2008 - chantra AatT rpm-based DdOoTt org 0.9.fc9.rb ++- New upstream release ++ ++* Sat May 17 2008 - chantra AatT rpm-based DdOoTt org 0.8.1.fc9.rb ++- Initial release for Fedora 9. +diff -x .bzr -uNr terminator-1.91/tests/testborg.py python3/tests/testborg.py +--- terminator-1.91/tests/testborg.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/tests/testborg.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """testborg.py - We are the borg. Resistance is futile. +diff -x .bzr -uNr terminator-1.91/tests/test_doctests.py python3/tests/test_doctests.py +--- terminator-1.91/tests/test_doctests.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/tests/test_doctests.py 2019-08-19 19:25:15.963479000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + """Load up the tests.""" + + import os +diff -x .bzr -uNr terminator-1.91/tests/testsignalman.py python3/tests/testsignalman.py +--- terminator-1.91/tests/testsignalman.py 2017-02-26 12:45:29.000000000 -0500 ++++ python3/tests/testsignalman.py 2019-10-21 22:58:46.937140000 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python2 ++#!/usr/bin/env python3 + # Terminator by Chris Jones + # GPL v2 only + """testsignalman.py - Test the signalman class +@@ -8,23 +8,23 @@ + >>> signalman.new(widget, 'test1', handler) + 1 + >>> signalman.cnxids[widget].keys() +-['test1'] ++dict_keys(['test1']) + >>> widget.signals.values() +-['test1'] ++dict_values(['test1']) + >>> signalman.remove_widget(widget) +->>> signalman.cnxids.has_key(widget) ++>>> widget in signalman.cnxids + False + >>> widget.signals.values() +-[] ++dict_values([]) + >>> signalman.new(widget, 'test2', handler) + 2 + >>> signalman.new(widget, 'test3', handler) + 3 + >>> signalman.remove_signal(widget, 'test2') + >>> signalman.cnxids[widget].keys() +-['test3'] ++dict_keys(['test3']) + >>> widget.signals.values() +-['test3'] ++dict_values(['test3']) + >>> signalman.remove_widget(widget) + >>> + +@@ -53,11 +53,11 @@ + del(self.signals[signalid]) + + def handler(): +- print "I am a test handler" ++ print("I am a test handler") + + if __name__ == '__main__': + import sys + import doctest + (failed, attempted) = doctest.testmod() +- print "%d/%d tests failed" % (failed, attempted) ++ print(("%d/%d tests failed" % (failed, attempted))) + sys.exit(failed) diff --git a/terminator.spec b/terminator.spec index 881c41c..7ef1fcd 100644 --- a/terminator.spec +++ b/terminator.spec @@ -1,6 +1,6 @@ Name: terminator Version: 1.91 -Release: 10%{?dist} +Release: 11%{?dist} Summary: Store and run multiple GNOME terminals in one window License: GPLv2 @@ -8,17 +8,17 @@ URL: http://gnometerminator.blogspot.com/p/introduction.html Source0: https://launchpad.net/terminator/gtk3/%{version}/+download/terminator-%{version}.tar.gz BuildArch: noarch -BuildRequires: python2-devel gettext desktop-file-utils intltool -Requires: vte291 python2-gobject keybinder3 desktop-file-utils +BuildRequires: python3-devel gettext desktop-file-utils intltool +Requires: vte291 python3-configobj python3-gobject keybinder3 desktop-file-utils %if 0%{?rhel} Requires: python-psutil %else -Requires: python2-psutil +Requires: python3-psutil %endif Patch0: 0000-terminator-fix-desktop-file.patch - +Patch1: python3.patch %description Multiple GNOME terminals in one window. This is a project to produce @@ -31,17 +31,17 @@ arrangements of terminals for different tasks. %prep %setup -q -n terminator-%{version} -sed -i '/#! \?\/usr.*/d' terminatorlib/*.py %patch0 -p0 +%patch1 -p1 %build -%{__python2} setup.py build +%{__python3} setup.py build %install rm -rf %{buildroot} -%{__python2} setup.py install -O1 --skip-build --root %{buildroot} +%{__python3} setup.py install -O1 --skip-build --root %{buildroot} %find_lang %{name} rm -f %{buildroot}/%{_datadir}/icons/hicolor/icon-theme.cache rm -f %{buildroot}/%{_datadir}/applications/%{name}.desktop @@ -51,12 +51,11 @@ desktop-file-install --dir=${RPM_BUILD_ROOT}%{_datadir}/applications data/%{name %files -f %{name}.lang %doc README COPYING ChangeLog -#%{_datadir}/doc/%{name}/* %{_mandir}/man1/%{name}.* %{_mandir}/man5/%{name}_config.* %{_bindir}/%{name}* %{_bindir}/remotinator -%{python2_sitelib}/* +%{python3_sitelib}/* %{_datadir}/%{name}/terminatorlib/themes/*/gtk-3.0/apps/*.css %{_datadir}/appdata/%{name}.appdata.xml %{_datadir}/applications/%{name}.desktop @@ -69,6 +68,9 @@ desktop-file-install --dir=${RPM_BUILD_ROOT}%{_datadir}/applications data/%{name %{_datadir}/pixmaps/%{name}.png %changelog +* Mon Dec 16 2019 Matt Rose - 1.91-11 +- Patched with python3 support, with thanks from Egmont Koblinger and Roman Kovtyukh + * Sat Jul 27 2019 Fedora Release Engineering - 1.91-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild