2183 lines
99 KiB
Diff
2183 lines
99 KiB
Diff
From 2056b6f2fcc6f0fd5a190f68c4310129535a7bf5 Mon Sep 17 00:00:00 2001
|
|
From: Patrick Monnerat <patrick@monnerat.net>
|
|
Date: Mon, 27 May 2019 18:16:18 +0200
|
|
Subject: [PATCH] snippets plugin: change code for Python 2 & 3 compatibility
|
|
|
|
---
|
|
plugins/snippets/snippets/Completion.py | 23 +-
|
|
plugins/snippets/snippets/Document.py | 151 ++---
|
|
plugins/snippets/snippets/Exporter.py | 4 +-
|
|
plugins/snippets/snippets/Helper.py | 32 +-
|
|
plugins/snippets/snippets/Importer.py | 2 +-
|
|
plugins/snippets/snippets/LanguageManager.py | 3 +-
|
|
plugins/snippets/snippets/Library.py | 43 +-
|
|
plugins/snippets/snippets/Manager.py | 76 ++-
|
|
plugins/snippets/snippets/Parser.py | 2 +-
|
|
plugins/snippets/snippets/Placeholder.py | 85 ++-
|
|
plugins/snippets/snippets/Snippet.py | 46 +-
|
|
plugins/snippets/snippets/WindowHelper.py | 4 +-
|
|
plugins/snippets/snippets/__init__.py | 19 +-
|
|
plugins/snippets/snippets/snippets.ui | 679 +++++++------------
|
|
14 files changed, 528 insertions(+), 641 deletions(-)
|
|
|
|
diff --git a/plugins/snippets/snippets/Completion.py b/plugins/snippets/snippets/Completion.py
|
|
index a860d21..ad0ad75 100644
|
|
--- a/plugins/snippets/snippets/Completion.py
|
|
+++ b/plugins/snippets/snippets/Completion.py
|
|
@@ -1,14 +1,14 @@
|
|
from gi.repository import GObject, Gtk, GtkSource, Pluma
|
|
|
|
-from Library import Library
|
|
-from LanguageManager import get_language_manager
|
|
-from Snippet import Snippet
|
|
+from .Library import Library
|
|
+from .LanguageManager import get_language_manager
|
|
+from .Snippet import Snippet
|
|
|
|
class Proposal(GObject.Object, GtkSource.CompletionProposal):
|
|
__gtype_name__ = "PlumaSnippetsProposal"
|
|
|
|
def __init__(self, snippet):
|
|
- GObject.Object.__init__(self)
|
|
+ super(Proposal, self).__init__()
|
|
self._snippet = Snippet(snippet)
|
|
|
|
def snippet(self):
|
|
@@ -25,7 +25,7 @@ class Provider(GObject.Object, GtkSource.CompletionProvider):
|
|
__gtype_name__ = "PlumaSnippetsProvider"
|
|
|
|
def __init__(self, name, language_id, handler):
|
|
- GObject.Object.__init__(self)
|
|
+ super(Provider, self).__init__()
|
|
|
|
self.name = name
|
|
self.info_widget = None
|
|
@@ -38,7 +38,10 @@ class Provider(GObject.Object, GtkSource.CompletionProvider):
|
|
theme = Gtk.IconTheme.get_default()
|
|
f, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU)
|
|
|
|
- self.icon = theme.load_icon(Gtk.STOCK_JUSTIFY_LEFT, w, 0)
|
|
+ try:
|
|
+ self.icon = theme.load_icon("format-justify-left", w, 0)
|
|
+ except:
|
|
+ self.icon = None
|
|
|
|
def __del__(self):
|
|
if self.mark:
|
|
@@ -89,9 +92,9 @@ class Provider(GObject.Object, GtkSource.CompletionProvider):
|
|
|
|
# Filter based on the current word
|
|
if word:
|
|
- proposals = filter(lambda x: x['tag'].startswith(word), proposals)
|
|
+ proposals = (x for x in proposals if x['tag'].startswith(word))
|
|
|
|
- return map(lambda x: Proposal(x), proposals)
|
|
+ return [Proposal(x) for x in proposals]
|
|
|
|
def do_populate(self, context):
|
|
proposals = self.get_proposals(self.get_word(context))
|
|
@@ -113,6 +116,10 @@ class Provider(GObject.Object, GtkSource.CompletionProvider):
|
|
|
|
sw = Gtk.ScrolledWindow()
|
|
sw.add(view)
|
|
+ sw.show_all()
|
|
+
|
|
+ # Fixed size
|
|
+ sw.set_size_request(300, 200)
|
|
|
|
self.info_view = view
|
|
self.info_widget = sw
|
|
diff --git a/plugins/snippets/snippets/Document.py b/plugins/snippets/snippets/Document.py
|
|
index f1cc065..f40186b 100644
|
|
--- a/plugins/snippets/snippets/Document.py
|
|
+++ b/plugins/snippets/snippets/Document.py
|
|
@@ -18,12 +18,12 @@
|
|
import os
|
|
import re
|
|
|
|
-from gi.repository import GLib, Gio, Gdk, Gtk, GtkSource, Pluma
|
|
+from gi.repository import GLib, Gio, Gdk, Gtk, Pluma
|
|
|
|
-from Library import Library
|
|
-from Snippet import Snippet
|
|
-from Placeholder import *
|
|
-import Completion
|
|
+from .Library import Library
|
|
+from .Snippet import Snippet
|
|
+from .Placeholder import *
|
|
+from . import Completion
|
|
|
|
class DynamicSnippet(dict):
|
|
def __init__(self, text):
|
|
@@ -31,9 +31,7 @@ class DynamicSnippet(dict):
|
|
self.valid = True
|
|
|
|
class Document:
|
|
- TAB_KEY_VAL = (Gdk.KEY_Tab, \
|
|
- Gdk.KEY_ISO_Left_Tab)
|
|
- SPACE_KEY_VAL = (Gdk.KEY_space,)
|
|
+ TAB_KEY_VAL = ('Tab', 'ISO_Left_Tab')
|
|
|
|
def __init__(self, instance, view):
|
|
self.view = None
|
|
@@ -109,7 +107,7 @@ class Document:
|
|
self.deactivate_snippet(snippet, True)
|
|
|
|
completion = self.view.get_completion()
|
|
- if completion:
|
|
+ if completion and self.provider in completion.get_providers():
|
|
completion.remove_provider(self.provider)
|
|
|
|
self.view = view
|
|
@@ -182,8 +180,6 @@ class Document:
|
|
snippets = Library().from_accelerator(accelerator, \
|
|
self.language_id)
|
|
|
|
- snippets_debug('Accel!')
|
|
-
|
|
if len(snippets) == 0:
|
|
return False
|
|
elif len(snippets) == 1:
|
|
@@ -193,6 +189,7 @@ class Document:
|
|
provider = Completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated)
|
|
provider.set_proposals(snippets)
|
|
|
|
+ cm = self.view.get_completion()
|
|
cm.show([provider], cm.create_context(None))
|
|
|
|
return True
|
|
@@ -266,7 +263,6 @@ class Document:
|
|
|
|
# Find the nearest placeholder
|
|
if nearest(piter, begin, end, found):
|
|
- foundIndex = index
|
|
found = placeholder
|
|
|
|
# Find the current placeholder
|
|
@@ -276,7 +272,7 @@ class Document:
|
|
currentIndex = index
|
|
current = placeholder
|
|
|
|
- if current and current != found and \
|
|
+ if current and found and current != found and \
|
|
(current.begin_iter().compare(found.begin_iter()) == 0 or \
|
|
current.end_iter().compare(found.begin_iter()) == 0) and \
|
|
self.active_placeholder and \
|
|
@@ -363,57 +359,60 @@ class Document:
|
|
|
|
def env_get_current_word(self, buf):
|
|
start, end = buffer_word_boundary(buf)
|
|
-
|
|
return buf.get_text(start, end, False)
|
|
|
|
def env_get_current_line(self, buf):
|
|
start, end = buffer_line_boundary(buf)
|
|
-
|
|
return buf.get_text(start, end, False)
|
|
|
|
def env_get_current_line_number(self, buf):
|
|
start, end = buffer_line_boundary(buf)
|
|
return str(start.get_line() + 1)
|
|
|
|
- def env_get_document_uri(self, buf):
|
|
- location = buf.get_location()
|
|
-
|
|
+ def location_uri_for_env(self, location):
|
|
if location:
|
|
return location.get_uri()
|
|
- else:
|
|
- return ''
|
|
-
|
|
- def env_get_document_name(self, buf):
|
|
- location = buf.get_location()
|
|
+ return ''
|
|
|
|
+ def location_name_for_env(self, location):
|
|
if location:
|
|
return location.get_basename()
|
|
- else:
|
|
- return ''
|
|
-
|
|
- def env_get_document_scheme(self, buf):
|
|
- location = buf.get_location()
|
|
+ return ''
|
|
|
|
+ def location_scheme_for_env(self, location):
|
|
if location:
|
|
return location.get_uri_scheme()
|
|
- else:
|
|
- return ''
|
|
-
|
|
- def env_get_document_path(self, buf):
|
|
- location = buf.get_location()
|
|
+ return ''
|
|
|
|
+ def location_path_for_env(self, location):
|
|
if location:
|
|
return location.get_path()
|
|
- else:
|
|
- return ''
|
|
-
|
|
- def env_get_document_dir(self, buf):
|
|
- location = buf.get_location()
|
|
+ return ''
|
|
|
|
+ def location_dir_for_env(self, location):
|
|
if location:
|
|
- return location.get_parent().get_path() or ''
|
|
- else:
|
|
- return ''
|
|
+ parent = location.get_parent()
|
|
+
|
|
+ if parent and parent.has_uri_scheme('file'):
|
|
+ return parent.get_path() or ''
|
|
+
|
|
+ return ''
|
|
+
|
|
+ def env_add_for_location(self, environ, location, prefix):
|
|
+ parts = {
|
|
+ 'URI': self.location_uri_for_env,
|
|
+ 'NAME': self.location_name_for_env,
|
|
+ 'SCHEME': self.location_scheme_for_env,
|
|
+ 'PATH': self.location_path_for_env,
|
|
+ 'DIR': self.location_dir_for_env,
|
|
+ }
|
|
+
|
|
+ for k in parts:
|
|
+ v = parts[k](location)
|
|
+ key = prefix + '_' + k
|
|
+ environ[key] = str(v)
|
|
+
|
|
+ return environ
|
|
|
|
def env_get_document_type(self, buf):
|
|
typ = buf.get_mime_type()
|
|
@@ -451,25 +450,30 @@ class Document:
|
|
|
|
return ' '.join(documents_path)
|
|
|
|
- def update_environment(self):
|
|
+ def get_environment(self):
|
|
buf = self.view.get_buffer()
|
|
+ environ = {}
|
|
+
|
|
+ for k in os.environ:
|
|
+ # Get the original environment
|
|
+ v = os.environ[k]
|
|
+ environ[k] = v
|
|
|
|
- variables = {'PLUMA_SELECTED_TEXT': self.env_get_selected_text,
|
|
+ variables = {
|
|
+ 'PLUMA_SELECTED_TEXT': self.env_get_selected_text,
|
|
'PLUMA_CURRENT_WORD': self.env_get_current_word,
|
|
'PLUMA_CURRENT_LINE': self.env_get_current_line,
|
|
'PLUMA_CURRENT_LINE_NUMBER': self.env_get_current_line_number,
|
|
- 'PLUMA_CURRENT_DOCUMENT_URI': self.env_get_document_uri,
|
|
- 'PLUMA_CURRENT_DOCUMENT_NAME': self.env_get_document_name,
|
|
- 'PLUMA_CURRENT_DOCUMENT_SCHEME': self.env_get_document_scheme,
|
|
- 'PLUMA_CURRENT_DOCUMENT_PATH': self.env_get_document_path,
|
|
- 'PLUMA_CURRENT_DOCUMENT_DIR': self.env_get_document_dir,
|
|
'PLUMA_CURRENT_DOCUMENT_TYPE': self.env_get_document_type,
|
|
'PLUMA_DOCUMENTS_URI': self.env_get_documents_uri,
|
|
'PLUMA_DOCUMENTS_PATH': self.env_get_documents_path,
|
|
}
|
|
|
|
for var in variables:
|
|
- os.environ[var] = variables[var](buf)
|
|
+ environ[var] = variables[var](buf)
|
|
+
|
|
+ self.env_add_for_location(environ, buf.get_location(), 'PLUMA_CURRENT_DOCUMENT')
|
|
+ return environ
|
|
|
|
def uses_current_word(self, snippet):
|
|
matches = re.findall('(\\\\*)\\$PLUMA_CURRENT_WORD', snippet['text'])
|
|
@@ -489,12 +493,19 @@ class Document:
|
|
|
|
return False
|
|
|
|
- def apply_snippet(self, snippet, start = None, end = None):
|
|
+ def apply_snippet(self, snippet, start = None, end = None, environ = {}):
|
|
if not snippet.valid:
|
|
return False
|
|
|
|
+ # Set environmental variables
|
|
+ env = self.get_environment()
|
|
+
|
|
+ if environ:
|
|
+ for k in environ:
|
|
+ env[k] = environ[k]
|
|
+
|
|
buf = self.view.get_buffer()
|
|
- s = Snippet(snippet)
|
|
+ s = Snippet(snippet, env)
|
|
|
|
if not start:
|
|
start = buf.get_iter_at_mark(buf.get_insert())
|
|
@@ -513,9 +524,6 @@ class Document:
|
|
# it will be removed
|
|
start, end = buffer_line_boundary(buf)
|
|
|
|
- # Set environmental variables
|
|
- self.update_environment()
|
|
-
|
|
# You know, we could be in an end placeholder
|
|
(current, next) = self.next_placeholder()
|
|
if current and current.__class__ == PlaceholderEnd:
|
|
@@ -527,8 +535,6 @@ class Document:
|
|
buf.delete(start, end)
|
|
|
|
# Insert the snippet
|
|
- holders = len(self.placeholders)
|
|
-
|
|
if len(self.active_snippets) == 0:
|
|
self.first_snippet_inserted()
|
|
|
|
@@ -536,7 +542,7 @@ class Document:
|
|
self.active_snippets.append(sn)
|
|
|
|
# Put cursor at first tab placeholder
|
|
- keys = filter(lambda x: x > 0, sn.placeholders.keys())
|
|
+ keys = [x for x in sn.placeholders.keys() if x > 0]
|
|
|
|
if len(keys) == 0:
|
|
if 0 in sn.placeholders:
|
|
@@ -637,7 +643,6 @@ class Document:
|
|
return True
|
|
|
|
def deactivate_snippet(self, snippet, force = False):
|
|
- buf = self.view.get_buffer()
|
|
remove = []
|
|
ordered_remove = []
|
|
|
|
@@ -792,10 +797,11 @@ class Document:
|
|
library = Library()
|
|
|
|
state = event.get_state()
|
|
+ keyname = Gdk.keyval_name(event.keyval)
|
|
|
|
if not (state & Gdk.ModifierType.CONTROL_MASK) and \
|
|
not (state & Gdk.ModifierType.MOD1_MASK) and \
|
|
- event.keyval in self.TAB_KEY_VAL:
|
|
+ keyname in self.TAB_KEY_VAL:
|
|
if not state & Gdk.ModifierType.SHIFT_MASK:
|
|
return self.run_snippet()
|
|
else:
|
|
@@ -868,20 +874,9 @@ class Document:
|
|
pathname = ''
|
|
dirname = ''
|
|
ruri = ''
|
|
+ environ = {'PLUMA_DROP_DOCUMENT_TYPE': mime}
|
|
|
|
- if Pluma.utils_uri_has_file_scheme(uri):
|
|
- pathname = gfile.get_path()
|
|
- dirname = gfile.get_parent().get_path()
|
|
-
|
|
- name = os.path.basename(uri)
|
|
- scheme = gfile.get_uri_scheme()
|
|
-
|
|
- os.environ['PLUMA_DROP_DOCUMENT_URI'] = uri
|
|
- os.environ['PLUMA_DROP_DOCUMENT_NAME'] = name
|
|
- os.environ['PLUMA_DROP_DOCUMENT_SCHEME'] = scheme
|
|
- os.environ['PLUMA_DROP_DOCUMENT_PATH'] = pathname
|
|
- os.environ['PLUMA_DROP_DOCUMENT_DIR'] = dirname
|
|
- os.environ['PLUMA_DROP_DOCUMENT_TYPE'] = mime
|
|
+ self.env_add_for_location(environ, gfile, 'PLUMA_DROP_DOCUMENT')
|
|
|
|
buf = self.view.get_buffer()
|
|
location = buf.get_location()
|
|
@@ -890,7 +885,7 @@ class Document:
|
|
|
|
relpath = self.relative_path(ruri, uri, mime)
|
|
|
|
- os.environ['PLUMA_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
|
|
+ environ['PLUMA_DROP_DOCUMENT_RELATIVE_PATH'] = relpath
|
|
|
|
mark = buf.get_mark('gtk_drag_target')
|
|
|
|
@@ -898,7 +893,7 @@ class Document:
|
|
mark = buf.get_insert()
|
|
|
|
piter = buf.get_iter_at_mark(mark)
|
|
- self.apply_snippet(snippet, piter, piter)
|
|
+ self.apply_snippet(snippet, piter, piter, environ)
|
|
|
|
def in_bounds(self, x, y):
|
|
rect = self.view.get_visible_rect()
|
|
@@ -907,6 +902,9 @@ class Document:
|
|
return not (x < rect.x or x > rect.x + rect.width or y < rect.y or y > rect.y + rect.height)
|
|
|
|
def on_drag_data_received(self, view, context, x, y, data, info, timestamp):
|
|
+ if not self.view.get_editable():
|
|
+ return
|
|
+
|
|
uris = drop_get_uris(data)
|
|
if not uris:
|
|
return
|
|
@@ -944,6 +942,9 @@ class Document:
|
|
return self.view.drag_dest_find_target(context, lst)
|
|
|
|
def on_proposal_activated(self, proposal, piter):
|
|
+ if not self.view.get_editable():
|
|
+ return False
|
|
+
|
|
buf = self.view.get_buffer()
|
|
bounds = buf.get_selection_bounds()
|
|
|
|
@@ -1048,8 +1049,6 @@ class Document:
|
|
if isinstance(placeholder, PlaceholderEnd):
|
|
return
|
|
|
|
- buf = self.view.get_buffer()
|
|
-
|
|
col = self.view.get_style_context().get_color(Gtk.StateFlags.INSENSITIVE)
|
|
col.alpha = 0.5
|
|
Gdk.cairo_set_source_rgba(ctx, col)
|
|
diff --git a/plugins/snippets/snippets/Exporter.py b/plugins/snippets/snippets/Exporter.py
|
|
index 850c3a4..713077f 100644
|
|
--- a/plugins/snippets/snippets/Exporter.py
|
|
+++ b/plugins/snippets/snippets/Exporter.py
|
|
@@ -3,9 +3,9 @@ import tempfile
|
|
import sys
|
|
import shutil
|
|
|
|
-from Library import *
|
|
+from .Library import *
|
|
import xml.etree.ElementTree as et
|
|
-from Helper import *
|
|
+from .Helper import *
|
|
|
|
class Exporter:
|
|
def __init__(self, filename, snippets):
|
|
diff --git a/plugins/snippets/snippets/Helper.py b/plugins/snippets/snippets/Helper.py
|
|
index 6d440d0..c1f1c35 100644
|
|
--- a/plugins/snippets/snippets/Helper.py
|
|
+++ b/plugins/snippets/snippets/Helper.py
|
|
@@ -15,10 +15,10 @@
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
-import string
|
|
from xml.sax import saxutils
|
|
-from xml.etree.ElementTree import *
|
|
+import xml.etree.ElementTree as et
|
|
import re
|
|
+import codecs
|
|
|
|
from gi.repository import Gtk
|
|
|
|
@@ -93,7 +93,7 @@ def write_xml(node, f, cdata_nodes=()):
|
|
assert node is not None
|
|
|
|
if not hasattr(f, "write"):
|
|
- f = open(f, "wb")
|
|
+ f = codecs.open(f, "wb", encoding="utf-8")
|
|
|
|
# Encoding
|
|
f.write("<?xml version='1.0' encoding='utf-8'?>\n")
|
|
@@ -107,27 +107,27 @@ def _write_node(node, file, cdata_nodes=(), indent=0):
|
|
# write XML to file
|
|
tag = node.tag
|
|
|
|
- if node is Comment:
|
|
- _write_indent(file, "<!-- %s -->\n" % saxutils.escape(node.text.encode('utf-8')), indent)
|
|
- elif node is ProcessingInstruction:
|
|
- _write_indent(file, "<?%s?>\n" % saxutils.escape(node.text.encode('utf-8')), indent)
|
|
+ if node is et.Comment:
|
|
+ _write_indent(file, "<!-- %s -->\n" % saxutils.escape(node.text), indent)
|
|
+ elif node is et.ProcessingInstruction:
|
|
+ _write_indent(file, "<?%s?>\n" % saxutils.escape(node.text), indent)
|
|
else:
|
|
items = node.items()
|
|
|
|
if items or node.text or len(node):
|
|
- _write_indent(file, "<" + tag.encode('utf-8'), indent)
|
|
+ _write_indent(file, "<" + tag, indent)
|
|
|
|
if items:
|
|
items.sort() # lexical order
|
|
for k, v in items:
|
|
- file.write(" %s=%s" % (k.encode('utf-8'), saxutils.quoteattr(v.encode('utf-8'))))
|
|
+ file.write(" %s=%s" % (k, saxutils.quoteattr(v)))
|
|
if node.text or len(node):
|
|
file.write(">")
|
|
if node.text and node.text.strip() != "":
|
|
if tag in cdata_nodes:
|
|
file.write(_cdata(node.text))
|
|
else:
|
|
- file.write(saxutils.escape(node.text.encode('utf-8')))
|
|
+ file.write(saxutils.escape(node.text))
|
|
else:
|
|
file.write("\n")
|
|
|
|
@@ -135,19 +135,17 @@ def _write_node(node, file, cdata_nodes=(), indent=0):
|
|
_write_node(n, file, cdata_nodes, indent + 1)
|
|
|
|
if not len(node):
|
|
- file.write("</" + tag.encode('utf-8') + ">\n")
|
|
+ file.write("</" + tag + ">\n")
|
|
else:
|
|
- _write_indent(file, "</" + tag.encode('utf-8') + ">\n", \
|
|
- indent)
|
|
+ _write_indent(file, "</" + tag + ">\n", indent)
|
|
else:
|
|
file.write(" />\n")
|
|
|
|
if node.tail and node.tail.strip() != "":
|
|
- file.write(saxutils.escape(node.tail.encode('utf-8')))
|
|
+ file.write(saxutils.escape(node.tail))
|
|
|
|
-def _cdata(text, replace=string.replace):
|
|
- text = text.encode('utf-8')
|
|
- return '<![CDATA[' + replace(text, ']]>', ']]]]><![CDATA[>') + ']]>'
|
|
+def _cdata(text):
|
|
+ return '<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>'
|
|
|
|
def buffer_word_boundary(buf):
|
|
iter = buf.get_iter_at_mark(buf.get_insert())
|
|
diff --git a/plugins/snippets/snippets/Importer.py b/plugins/snippets/snippets/Importer.py
|
|
index c1d211e..83c520c 100644
|
|
--- a/plugins/snippets/snippets/Importer.py
|
|
+++ b/plugins/snippets/snippets/Importer.py
|
|
@@ -3,7 +3,7 @@ import tempfile
|
|
import sys
|
|
import shutil
|
|
|
|
-from Library import *
|
|
+from .Library import *
|
|
|
|
class Importer:
|
|
def __init__(self, filename):
|
|
diff --git a/plugins/snippets/snippets/LanguageManager.py b/plugins/snippets/snippets/LanguageManager.py
|
|
index e738333..d962dcf 100644
|
|
--- a/plugins/snippets/snippets/LanguageManager.py
|
|
+++ b/plugins/snippets/snippets/LanguageManager.py
|
|
@@ -1,7 +1,7 @@
|
|
import os
|
|
from gi.repository import GtkSource
|
|
|
|
-from Library import Library
|
|
+from .Library import Library
|
|
|
|
global manager
|
|
manager = None
|
|
@@ -19,4 +19,5 @@ def get_language_manager():
|
|
manager.set_search_path(dirs + manager.get_search_path())
|
|
|
|
return manager
|
|
+
|
|
# ex:ts=4:et:
|
|
diff --git a/plugins/snippets/snippets/Library.py b/plugins/snippets/snippets/Library.py
|
|
index f152082..d8ae219 100644
|
|
--- a/plugins/snippets/snippets/Library.py
|
|
+++ b/plugins/snippets/snippets/Library.py
|
|
@@ -20,11 +20,12 @@ import weakref
|
|
import sys
|
|
import tempfile
|
|
import re
|
|
+import codecs
|
|
|
|
from gi.repository import Gdk, Gtk
|
|
|
|
import xml.etree.ElementTree as et
|
|
-from Helper import *
|
|
+from .Helper import *
|
|
|
|
class NamespacedId:
|
|
def __init__(self, namespace, id):
|
|
@@ -453,28 +454,38 @@ class SnippetsSystemFile:
|
|
lambda node: elements.append((node, True)), \
|
|
lambda node: elements.append((node, False)))
|
|
|
|
- parser = et.XMLTreeBuilder(target=builder)
|
|
+ self.ok = True
|
|
+ parser = et.XMLParser(target=builder)
|
|
self.insnippet = False
|
|
|
|
try:
|
|
- f = open(self.path, "r")
|
|
+ f = codecs.open(self.path, "r", encoding='utf-8')
|
|
+ except IOError:
|
|
+ self.ok = False
|
|
+ return
|
|
|
|
- while True:
|
|
+ while self.ok:
|
|
+ try:
|
|
data = f.read(readsize)
|
|
+ except IOError:
|
|
+ self.ok = False
|
|
+ break
|
|
|
|
- if not data:
|
|
- break
|
|
+ if not data:
|
|
+ break
|
|
|
|
+ try:
|
|
parser.feed(data)
|
|
+ except Exception:
|
|
+ self.ok = False
|
|
+ break
|
|
|
|
- for element in elements:
|
|
- yield element
|
|
+ for element in elements:
|
|
+ yield element
|
|
|
|
- del elements[:]
|
|
+ del elements[:]
|
|
|
|
- f.close()
|
|
- except IOError:
|
|
- self.ok = False
|
|
+ f.close()
|
|
|
|
def load(self):
|
|
if not self.ok:
|
|
@@ -531,6 +542,8 @@ class SnippetsUserFile(SnippetsSystemFile):
|
|
SnippetsSystemFile.__init__(self, path)
|
|
self.tainted = False
|
|
self.need_id = False
|
|
+ self.modifier = False
|
|
+ self.root = None
|
|
|
|
def _set_root(self, element):
|
|
SnippetsSystemFile._set_root(self, element)
|
|
@@ -611,7 +624,7 @@ class SnippetsUserFile(SnippetsSystemFile):
|
|
|
|
try:
|
|
if not os.path.isdir(path):
|
|
- os.makedirs(path, 0755)
|
|
+ os.makedirs(path, 0o755)
|
|
except OSError:
|
|
# TODO: this is bad...
|
|
sys.stderr.write("Error in making dirs\n")
|
|
@@ -929,8 +942,8 @@ class Library(Singleton):
|
|
def valid_accelerator(self, keyval, mod):
|
|
mod &= Gtk.accelerator_get_default_mod_mask()
|
|
|
|
- return (mod and (Gdk.keyval_to_unicode(keyval) or \
|
|
- keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1)))
|
|
+ return mod and (Gdk.keyval_to_unicode(keyval) or \
|
|
+ re.match('^F(?:1[012]?|[2-9])$', Gdk.keyval_name(keyval)))
|
|
|
|
def valid_tab_trigger(self, trigger):
|
|
if not trigger:
|
|
diff --git a/plugins/snippets/snippets/Manager.py b/plugins/snippets/snippets/Manager.py
|
|
index 9760fa7..71ada38 100644
|
|
--- a/plugins/snippets/snippets/Manager.py
|
|
+++ b/plugins/snippets/snippets/Manager.py
|
|
@@ -21,13 +21,13 @@ import shutil
|
|
|
|
from gi.repository import GObject, Gio, Gdk, Gtk, GtkSource, Pluma
|
|
|
|
-from Snippet import Snippet
|
|
-from Helper import *
|
|
-from Library import *
|
|
-from Importer import *
|
|
-from Exporter import *
|
|
-from Document import Document
|
|
-from LanguageManager import get_language_manager
|
|
+from .Snippet import Snippet
|
|
+from .Helper import *
|
|
+from .Library import *
|
|
+from .Importer import *
|
|
+from .Exporter import *
|
|
+from .Document import Document
|
|
+from .LanguageManager import get_language_manager
|
|
|
|
class Manager:
|
|
NAME_COLUMN = 0
|
|
@@ -42,7 +42,7 @@ class Manager:
|
|
dragging = False
|
|
dnd_target_list = [Gtk.TargetEntry.new('text/uri-list', 0, TARGET_URI)]
|
|
|
|
- def __init__(self, datadir):
|
|
+ def __init__(self, datadir, window=None):
|
|
self.datadir = datadir
|
|
self.snippet = None
|
|
self.dlg = None
|
|
@@ -52,7 +52,7 @@ class Manager:
|
|
self.default_size = None
|
|
|
|
self.key_press_id = 0
|
|
- self.run()
|
|
+ self.run(window)
|
|
|
|
def get_language_snippets(self, path, name = None):
|
|
library = Library()
|
|
@@ -159,9 +159,9 @@ class Manager:
|
|
snippet = model.get_value(iter, self.SNIPPET_COLUMN)
|
|
|
|
if snippet and not snippet.valid:
|
|
- cell.set_property('stock-id', Gtk.STOCK_DIALOG_ERROR)
|
|
+ cell.set_property('icon-name', 'dialog-error')
|
|
else:
|
|
- cell.set_property('stock-id', None)
|
|
+ cell.set_property('icon-name', None)
|
|
|
|
cell.set_property('xalign', 1.0)
|
|
|
|
@@ -300,9 +300,6 @@ class Manager:
|
|
self.build_tree_view()
|
|
self.build_model()
|
|
|
|
- image = self['image_remove']
|
|
- image.set_from_stock(Gtk.STOCK_REMOVE, Gtk.IconSize.SMALL_TOOLBAR)
|
|
-
|
|
source_view = self['source_view_snippet']
|
|
manager = get_language_manager()
|
|
lang = manager.get_language('snippets')
|
|
@@ -391,15 +388,15 @@ class Manager:
|
|
|
|
if not (override ^ remove) or system:
|
|
button_remove.set_sensitive(False)
|
|
- image_remove.set_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.BUTTON)
|
|
+ image_remove.set_from_icon_name("edit-delete", Gtk.IconSize.BUTTON)
|
|
else:
|
|
button_remove.set_sensitive(True)
|
|
|
|
if override:
|
|
- image_remove.set_from_stock(Gtk.STOCK_UNDO, Gtk.IconSize.BUTTON)
|
|
+ image_remove.set_from_icon_name("edit-undo", Gtk.IconSize.BUTTON)
|
|
tooltip = _('Revert selected snippet')
|
|
else:
|
|
- image_remove.set_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.BUTTON)
|
|
+ image_remove.set_from_icon_name("edit-delete", Gtk.IconSize.BUTTON)
|
|
tooltip = _('Delete selected snippet')
|
|
|
|
button_remove.set_tooltip_text(tooltip)
|
|
@@ -427,12 +424,14 @@ class Manager:
|
|
|
|
return self.snippet_changed(piter)
|
|
|
|
- def run(self):
|
|
+ def run(self, window=None):
|
|
if not self.dlg:
|
|
self.build()
|
|
+ self.dlg.set_transient_for(window)
|
|
self.dlg.show()
|
|
else:
|
|
self.build_model()
|
|
+ self.dlg.set_transient_for(window)
|
|
self.dlg.present()
|
|
|
|
def snippet_from_iter(self, model, piter):
|
|
@@ -611,7 +610,7 @@ class Manager:
|
|
self.default_size = [alloc.width, alloc.height]
|
|
|
|
if resp == Gtk.ResponseType.HELP:
|
|
- Pluma.help_display(self, 'pluma', 'pluma-snippets-plugin')
|
|
+ Pluma.help_display(self.dlg, 'pluma', 'pluma-snippets-plugin')
|
|
return
|
|
|
|
self.dlg.destroy()
|
|
@@ -668,7 +667,7 @@ class Manager:
|
|
|
|
if text and not Library().valid_tab_trigger(text):
|
|
img = self['image_tab_trigger']
|
|
- img.set_from_stock(Gtk.STOCK_DIALOG_ERROR, Gtk.IconSize.BUTTON)
|
|
+ img.set_from_icon_name("dialog-error", Gtk.IconSize.BUTTON)
|
|
img.show()
|
|
|
|
#self['hbox_tab_trigger'].set_spacing(3)
|
|
@@ -790,10 +789,11 @@ class Manager:
|
|
self.import_snippets(f)
|
|
|
|
def on_button_import_snippets_clicked(self, button):
|
|
- dlg = Gtk.FileChooserDialog(parent=self.dlg, title=_("Import snippets"),
|
|
- action=Gtk.FileChooserAction.OPEN,
|
|
- buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
|
- Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
|
|
+ dlg = Gtk.FileChooserDialog(title=_("Import snippets"),
|
|
+ parent=self.dlg,
|
|
+ action=Gtk.FileChooserAction.OPEN)
|
|
+ self._add_button(dlg, _('_Cancel'), Gtk.ResponseType.CANCEL, "process-stop")
|
|
+ self._add_button(dlg, _("_Open"), Gtk.ResponseType.OK, "document-open")
|
|
|
|
dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar', '*.xml')))
|
|
dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
|
|
@@ -875,10 +875,11 @@ class Manager:
|
|
return False
|
|
|
|
if not filename:
|
|
- dlg = Gtk.FileChooserDialog(parent=self.dlg, title=_('Export snippets'),
|
|
- action=Gtk.FileChooserAction.SAVE,
|
|
- buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
|
- Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
|
|
+ dlg = Gtk.FileChooserDialog(title=_('Export snippets'),
|
|
+ parent=self.dlg,
|
|
+ action=Gtk.FileChooserAction.SAVE)
|
|
+ self._add_button(dlg, _('_Cancel'), Gtk.ResponseType.CANCEL, "process-stop")
|
|
+ self._add_button(dlg, _("_Save"), Gtk.ResponseType.OK, "document-save")
|
|
|
|
dlg._export_snippets = export_snippets
|
|
dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
|
|
@@ -913,10 +914,11 @@ class Manager:
|
|
else:
|
|
systemsnippets.append(snippet)
|
|
|
|
- dlg = Gtk.FileChooserDialog(parent=self.dlg, title=_('Export snippets'),
|
|
- action=Gtk.FileChooserAction.SAVE,
|
|
- buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
|
- Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
|
|
+ dlg = Gtk.FileChooserDialog(title=_('Export snippets'),
|
|
+ parent=self.dlg,
|
|
+ action=Gtk.FileChooserAction.SAVE)
|
|
+ self._add_button(dlg, _('_Cancel'), Gtk.ResponseType.CANCEL, "process-stop")
|
|
+ self._add_button(dlg, _("_Save"), Gtk.ResponseType.OK, "document-save")
|
|
|
|
dlg._export_snippets = snippets
|
|
|
|
@@ -1145,4 +1147,14 @@ class Manager:
|
|
context.finish(True, False, timestamp)
|
|
|
|
entry.stop_emission('drag_data_received')
|
|
+
|
|
+ @staticmethod
|
|
+ def _add_button(dialog, label, response, icon=None):
|
|
+ button = dialog.add_button(label, response)
|
|
+ if icon:
|
|
+ image = Gtk.Image.new_from_icon_name(icon, Gtk.IconSize.BUTTON)
|
|
+ button.set_image(image)
|
|
+ button.set_property("always-show-image", True)
|
|
+ return button
|
|
+
|
|
# ex:ts=4:et:
|
|
diff --git a/plugins/snippets/snippets/Parser.py b/plugins/snippets/snippets/Parser.py
|
|
index 280ce0c..f200043 100644
|
|
--- a/plugins/snippets/snippets/Parser.py
|
|
+++ b/plugins/snippets/snippets/Parser.py
|
|
@@ -18,7 +18,7 @@
|
|
import os
|
|
import re
|
|
import sys
|
|
-from SubstitutionParser import SubstitutionParser
|
|
+from .SubstitutionParser import SubstitutionParser
|
|
|
|
class Token:
|
|
def __init__(self, klass, data):
|
|
diff --git a/plugins/snippets/snippets/Placeholder.py b/plugins/snippets/snippets/Placeholder.py
|
|
index 9edf099..050fda6 100644
|
|
--- a/plugins/snippets/snippets/Placeholder.py
|
|
+++ b/plugins/snippets/snippets/Placeholder.py
|
|
@@ -24,12 +24,12 @@ import locale
|
|
import subprocess
|
|
from gi.repository import GObject, GLib, Gtk
|
|
|
|
-from SubstitutionParser import SubstitutionParser
|
|
-from Helper import *
|
|
+from .SubstitutionParser import SubstitutionParser
|
|
+from .Helper import *
|
|
|
|
# These are places in a view where the cursor can go and do things
|
|
class Placeholder:
|
|
- def __init__(self, view, tabstop, defaults, begin):
|
|
+ def __init__(self, view, tabstop, environ, defaults, begin):
|
|
self.ok = True
|
|
self.done = False
|
|
self.buf = view.get_buffer()
|
|
@@ -38,6 +38,7 @@ class Placeholder:
|
|
self.mirrors = []
|
|
self.leave_mirrors = []
|
|
self.tabstop = tabstop
|
|
+ self.environ = environ
|
|
self.set_default(defaults)
|
|
self.prev_contents = self.default
|
|
self.set_mark_gravity()
|
|
@@ -49,6 +50,9 @@ class Placeholder:
|
|
|
|
self.end = None
|
|
|
|
+ def get_environ(self):
|
|
+ return self.environ
|
|
+
|
|
def __str__(self):
|
|
return '%s (%s)' % (str(self.__class__), str(self.default))
|
|
|
|
@@ -81,10 +85,12 @@ class Placeholder:
|
|
return s
|
|
|
|
def re_environment(self, m):
|
|
- if m.group(1) or not m.group(2) in os.environ:
|
|
+ env = self.get_environ()
|
|
+
|
|
+ if m.group(1) or not m.group(2) in env:
|
|
return '$' + m.group(2)
|
|
else:
|
|
- return self.format_environment(os.environ[m.group(2)])
|
|
+ return self.format_environment(env[m.group(2)])
|
|
|
|
def expand_environment(self, text):
|
|
if not text:
|
|
@@ -214,8 +220,8 @@ class Placeholder:
|
|
|
|
# This is an placeholder which inserts a mirror of another Placeholder
|
|
class PlaceholderMirror(Placeholder):
|
|
- def __init__(self, view, tabstop, begin):
|
|
- Placeholder.__init__(self, view, -1, None, begin)
|
|
+ def __init__(self, view, tabstop, environ, begin):
|
|
+ Placeholder.__init__(self, view, -1, environ, None, begin)
|
|
self.mirror_stop = tabstop
|
|
|
|
def update(self, mirror):
|
|
@@ -237,8 +243,8 @@ class PlaceholderMirror(Placeholder):
|
|
|
|
# This placeholder indicates the end of a snippet
|
|
class PlaceholderEnd(Placeholder):
|
|
- def __init__(self, view, begin, default):
|
|
- Placeholder.__init__(self, view, 0, default, begin)
|
|
+ def __init__(self, view, environ, begin, default):
|
|
+ Placeholder.__init__(self, view, 0, environ, default, begin)
|
|
|
|
def run_last(self, placeholders):
|
|
Placeholder.run_last(self, placeholders)
|
|
@@ -264,8 +270,8 @@ class PlaceholderEnd(Placeholder):
|
|
|
|
# This placeholder is used to expand a command with embedded mirrors
|
|
class PlaceholderExpand(Placeholder):
|
|
- def __init__(self, view, tabstop, begin, s):
|
|
- Placeholder.__init__(self, view, tabstop, None, begin)
|
|
+ def __init__(self, view, tabstop, environ, begin, s):
|
|
+ Placeholder.__init__(self, view, tabstop, environ, None, begin)
|
|
|
|
self.mirror_text = {0: ''}
|
|
self.timeout_id = None
|
|
@@ -359,8 +365,6 @@ class PlaceholderExpand(Placeholder):
|
|
return ret
|
|
|
|
def update(self, mirror):
|
|
- text = None
|
|
-
|
|
if mirror:
|
|
self.mirror_text[mirror.tabstop] = mirror.get_text()
|
|
|
|
@@ -379,8 +383,8 @@ class PlaceholderExpand(Placeholder):
|
|
|
|
# The shell placeholder executes commands in a subshell
|
|
class PlaceholderShell(PlaceholderExpand):
|
|
- def __init__(self, view, tabstop, begin, s):
|
|
- PlaceholderExpand.__init__(self, view, tabstop, begin, s)
|
|
+ def __init__(self, view, tabstop, environ, begin, s):
|
|
+ PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
|
|
|
|
self.shell = None
|
|
self.remove_me = False
|
|
@@ -412,7 +416,7 @@ class PlaceholderShell(PlaceholderExpand):
|
|
self.close_shell()
|
|
self.remove_timeout()
|
|
|
|
- self.set_text(str.join('', self.shell_output).rstrip('\n'))
|
|
+ self.set_text(''.join(self.shell_output).rstrip('\n'))
|
|
|
|
if self.default == None:
|
|
self.default = self.get_text()
|
|
@@ -423,19 +427,24 @@ class PlaceholderShell(PlaceholderExpand):
|
|
|
|
def process_cb(self, source, condition):
|
|
if condition & GObject.IO_IN:
|
|
- line = source.readline()
|
|
+ while True:
|
|
+ line = source.readline()
|
|
|
|
- if len(line) > 0:
|
|
- try:
|
|
- line = unicode(line, 'utf-8')
|
|
- except:
|
|
- line = unicode(line, locale.getdefaultlocale()[1],
|
|
- 'replace')
|
|
+ if len(line) <= 0:
|
|
+ break
|
|
|
|
- self.shell_output += line
|
|
- self.install_timeout()
|
|
+ if isinstance(line, bytes):
|
|
+ try:
|
|
+ line = line.decode('utf-8')
|
|
+ except UnicodeDecodeError:
|
|
+ line = line.decode(locale.getdefaultlocale()[1],
|
|
+ errors='replace')
|
|
|
|
- return True
|
|
+ self.shell_output += line
|
|
+ self.install_timeout()
|
|
+
|
|
+ if not (condition & GObject.IO_HUP):
|
|
+ return True
|
|
|
|
self.process_close()
|
|
return False
|
|
@@ -456,7 +465,7 @@ class PlaceholderShell(PlaceholderExpand):
|
|
popen_args = {
|
|
'cwd' : None,
|
|
'shell': True,
|
|
- 'env' : os.environ,
|
|
+ 'env': self.get_environ(),
|
|
'stdout': subprocess.PIPE
|
|
}
|
|
|
|
@@ -491,8 +500,8 @@ class TimeoutError(Exception):
|
|
|
|
# The python placeholder evaluates commands in python
|
|
class PlaceholderEval(PlaceholderExpand):
|
|
- def __init__(self, view, tabstop, refs, begin, s, namespace):
|
|
- PlaceholderExpand.__init__(self, view, tabstop, begin, s)
|
|
+ def __init__(self, view, tabstop, environ, refs, begin, s, namespace):
|
|
+ PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s)
|
|
|
|
self.fdread = 0
|
|
self.remove_me = False
|
|
@@ -529,7 +538,7 @@ class PlaceholderEval(PlaceholderExpand):
|
|
return hasattr(signal, 'SIGALRM')
|
|
|
|
def timeout_cb(self, signum = 0, frame = 0):
|
|
- raise TimeoutError, "Operation timed out (>2 seconds)"
|
|
+ raise TimeoutError("Operation timed out (>2 seconds)")
|
|
|
|
def install_timeout(self):
|
|
if not self.timeout_supported():
|
|
@@ -568,7 +577,7 @@ class PlaceholderEval(PlaceholderExpand):
|
|
del self.namespace['process_snippet']
|
|
|
|
try:
|
|
- exec text in self.namespace
|
|
+ exec(text, self.namespace)
|
|
except:
|
|
traceback.print_exc()
|
|
|
|
@@ -593,7 +602,7 @@ class PlaceholderEval(PlaceholderExpand):
|
|
'time, execution aborted.') % self.command)
|
|
|
|
return False
|
|
- except Exception, detail:
|
|
+ except Exception as detail:
|
|
self.remove_timeout()
|
|
|
|
message_dialog(None, Gtk.MessageType.ERROR,
|
|
@@ -612,8 +621,8 @@ class PlaceholderEval(PlaceholderExpand):
|
|
|
|
# Regular expression placeholder
|
|
class PlaceholderRegex(PlaceholderExpand):
|
|
- def __init__(self, view, tabstop, begin, inp, pattern, substitution, modifiers):
|
|
- PlaceholderExpand.__init__(self, view, tabstop, begin, '')
|
|
+ def __init__(self, view, tabstop, environ, begin, inp, pattern, substitution, modifiers):
|
|
+ PlaceholderExpand.__init__(self, view, tabstop, environ, begin, '')
|
|
|
|
self.instant_update = True
|
|
self.inp = inp
|
|
@@ -652,10 +661,12 @@ class PlaceholderRegex(PlaceholderExpand):
|
|
return re.escape(s)
|
|
|
|
def get_input(self):
|
|
+ env = self.get_environ()
|
|
+
|
|
if isinstance(self.inp, int):
|
|
return self.mirror_text[self.inp]
|
|
- elif self.inp in os.environ:
|
|
- return os.environ[self.inp]
|
|
+ elif self.inp in env:
|
|
+ return env[self.inp]
|
|
else:
|
|
return ''
|
|
|
|
@@ -672,7 +683,7 @@ class PlaceholderRegex(PlaceholderExpand):
|
|
# Try to compile pattern
|
|
try:
|
|
regex = re.compile(pattern, self.modifiers)
|
|
- except re.error, message:
|
|
+ except re.error as message:
|
|
sys.stderr.write('Could not compile regular expression: %s\n%s\n' % (pattern, message))
|
|
return False
|
|
|
|
diff --git a/plugins/snippets/snippets/Snippet.py b/plugins/snippets/snippets/Snippet.py
|
|
index 192b036..91e6380 100644
|
|
--- a/plugins/snippets/snippets/Snippet.py
|
|
+++ b/plugins/snippets/snippets/Snippet.py
|
|
@@ -16,11 +16,12 @@
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
import os
|
|
+import six
|
|
from gi.repository import Gio, Gtk
|
|
|
|
-from Placeholder import *
|
|
-from Parser import Parser, Token
|
|
-from Helper import *
|
|
+from .Placeholder import *
|
|
+from .Parser import Parser, Token
|
|
+from .Helper import *
|
|
|
|
class EvalUtilities:
|
|
def __init__(self, view=None):
|
|
@@ -87,8 +88,8 @@ class EvalUtilities:
|
|
for col in range(0, len(items[row]) - 1):
|
|
item = items[row][col]
|
|
|
|
- result += item + ("\t" * ((maxlen[col] - \
|
|
- self._real_len(item, tablen)) / tablen))
|
|
+ result += item + ("\t" * int(((maxlen[col] - \
|
|
+ self._real_len(item, tablen)) / tablen)))
|
|
|
|
result += items[row][len(items[row]) - 1]
|
|
|
|
@@ -98,8 +99,9 @@ class EvalUtilities:
|
|
return result
|
|
|
|
class Snippet:
|
|
- def __init__(self, data):
|
|
+ def __init__(self, data, environ = {}):
|
|
self.data = data
|
|
+ self.environ = environ
|
|
|
|
def __getitem__(self, prop):
|
|
return self.data[prop]
|
|
@@ -132,7 +134,7 @@ class Snippet:
|
|
if not detail:
|
|
return nm
|
|
else:
|
|
- return nm + ' (<b>' + markup_escape(str.join(', ', detail)) + \
|
|
+ return nm + ' (<b>' + markup_escape(", ".join(detail)) + \
|
|
'</b>)'
|
|
|
|
def _add_placeholder(self, placeholder):
|
|
@@ -149,14 +151,17 @@ class Snippet:
|
|
|
|
def _insert_text(self, text):
|
|
# Insert text keeping indentation in mind
|
|
- indented = unicode.join('\n' + unicode(self._indent), spaces_instead_of_tabs(self._view, text).split('\n'))
|
|
+ indented = (six.u('\n') + self._indent).join(spaces_instead_of_tabs(self._view, text).split('\n'))
|
|
self._view.get_buffer().insert(self._insert_iter(), indented)
|
|
|
|
def _insert_iter(self):
|
|
return self._view.get_buffer().get_iter_at_mark(self._insert_mark)
|
|
|
|
def _create_environment(self, data):
|
|
- val = ((data in os.environ) and os.environ[data]) or ''
|
|
+ if data in self.environ:
|
|
+ val = self.environ[data]
|
|
+ else:
|
|
+ val = ''
|
|
|
|
# Get all the current indentation
|
|
all_indent = compute_indentation(self._view, self._insert_iter())
|
|
@@ -165,7 +170,7 @@ class Snippet:
|
|
indent = all_indent[len(self._indent):]
|
|
|
|
# Keep indentation
|
|
- return unicode.join('\n' + unicode(indent), val.split('\n'))
|
|
+ return (six.u('\n') + indent).join(val.split('\n'))
|
|
|
|
def _create_placeholder(self, data):
|
|
tabstop = data['tabstop']
|
|
@@ -173,25 +178,25 @@ class Snippet:
|
|
|
|
if tabstop == 0:
|
|
# End placeholder
|
|
- return PlaceholderEnd(self._view, begin, data['default'])
|
|
+ return PlaceholderEnd(self._view, self.environ, begin, data['default'])
|
|
elif tabstop in self.placeholders:
|
|
# Mirror placeholder
|
|
- return PlaceholderMirror(self._view, tabstop, begin)
|
|
+ return PlaceholderMirror(self._view, tabstop, self.environ, begin)
|
|
else:
|
|
# Default placeholder
|
|
- return Placeholder(self._view, tabstop, data['default'], begin)
|
|
+ return Placeholder(self._view, tabstop, self.environ, data['default'], begin)
|
|
|
|
def _create_shell(self, data):
|
|
begin = self._insert_iter()
|
|
- return PlaceholderShell(self._view, data['tabstop'], begin, data['contents'])
|
|
+ return PlaceholderShell(self._view, data['tabstop'], self.environ, begin, data['contents'])
|
|
|
|
def _create_eval(self, data):
|
|
begin = self._insert_iter()
|
|
- return PlaceholderEval(self._view, data['tabstop'], data['dependencies'], begin, data['contents'], self._utils.namespace)
|
|
+ return PlaceholderEval(self._view, data['tabstop'], self.environ, data['dependencies'], begin, data['contents'], self._utils.namespace)
|
|
|
|
def _create_regex(self, data):
|
|
begin = self._insert_iter()
|
|
- return PlaceholderRegex(self._view, data['tabstop'], begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
|
|
+ return PlaceholderRegex(self._view, data['tabstop'], self.environ, begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
|
|
|
|
def _create_text(self, data):
|
|
return data
|
|
@@ -239,11 +244,11 @@ class Snippet:
|
|
'eval': self._create_eval,
|
|
'regex': self._create_regex,
|
|
'text': self._create_text}[token.klass](token.data)
|
|
- except:
|
|
+ except KeyError:
|
|
sys.stderr.write('Token class not supported: %s\n' % token.klass)
|
|
continue
|
|
|
|
- if isinstance(val, basestring):
|
|
+ if isinstance(val, six.string_types):
|
|
# Insert text
|
|
self._insert_text(val)
|
|
else:
|
|
@@ -252,7 +257,7 @@ class Snippet:
|
|
|
|
# Create end placeholder if there isn't one yet
|
|
if 0 not in self.placeholders:
|
|
- self.placeholders[0] = PlaceholderEnd(self._view, self.end_iter(), None)
|
|
+ self.placeholders[0] = PlaceholderEnd(self._view, self.environ, self.end_iter(), None)
|
|
self.plugin_data.ordered_placeholders.append(self.placeholders[0])
|
|
|
|
# Make sure run_last is ran for all placeholders and remove any
|
|
@@ -317,8 +322,7 @@ class Snippet:
|
|
# So now all of the snippet is in the buffer, we have all our
|
|
# placeholders right here, what's next, put all marks in the
|
|
# plugin_data.marks
|
|
- k = self.placeholders.keys()
|
|
- k.sort(reverse=True)
|
|
+ k = sorted(self.placeholders.keys(), reverse=True)
|
|
|
|
plugin_data.placeholders.insert(last_index, self.placeholders[0])
|
|
last_iter = self.placeholders[0].end_iter()
|
|
diff --git a/plugins/snippets/snippets/WindowHelper.py b/plugins/snippets/snippets/WindowHelper.py
|
|
index 296ff03..44ac558 100644
|
|
--- a/plugins/snippets/snippets/WindowHelper.py
|
|
+++ b/plugins/snippets/snippets/WindowHelper.py
|
|
@@ -21,8 +21,8 @@ import gettext
|
|
|
|
from gi.repository import GObject, Gtk, Pluma
|
|
|
|
-from Document import Document
|
|
-from Library import Library
|
|
+from .Document import Document
|
|
+from .Library import Library
|
|
|
|
class WindowHelper:
|
|
def __init__(self, plugin):
|
|
diff --git a/plugins/snippets/snippets/__init__.py b/plugins/snippets/snippets/__init__.py
|
|
index 8642406..ada586c 100644
|
|
--- a/plugins/snippets/snippets/__init__.py
|
|
+++ b/plugins/snippets/snippets/__init__.py
|
|
@@ -18,9 +18,9 @@
|
|
import os
|
|
from gi.repository import GObject, GLib, Gtk, Peas, Pluma
|
|
|
|
-from WindowHelper import WindowHelper
|
|
-from Library import Library
|
|
-from Manager import Manager
|
|
+from .WindowHelper import WindowHelper
|
|
+from .Library import Library
|
|
+from .Manager import Manager
|
|
|
|
class SnippetsPlugin(GObject.Object, Peas.Activatable):
|
|
__gtype_name__ = "SnippetsPlugin"
|
|
@@ -53,7 +53,7 @@ class SnippetsPlugin(GObject.Object, Peas.Activatable):
|
|
library = Library()
|
|
library.add_accelerator_callback(self.accelerator_activated)
|
|
|
|
- snippetsdir = os.path.join(GLib.get_user_config_dir(), '/pluma/snippets')
|
|
+ snippetsdir = os.path.join(GLib.get_user_config_dir(), 'pluma/snippets')
|
|
library.set_dirs(snippetsdir, self.system_dirs())
|
|
|
|
self._helper = WindowHelper(self)
|
|
@@ -72,15 +72,12 @@ class SnippetsPlugin(GObject.Object, Peas.Activatable):
|
|
self._helper.update()
|
|
|
|
def create_configure_dialog(self):
|
|
- if not self.dlg:
|
|
- self.dlg = Manager(self.plugin_info.get_data_dir())
|
|
- else:
|
|
- self.dlg.run()
|
|
-
|
|
window = Pluma.App.get_default().get_active_window()
|
|
|
|
- if window:
|
|
- self.dlg.dlg.set_transient_for(window)
|
|
+ if not self.dlg:
|
|
+ self.dlg = Manager(self.plugin_info.get_data_dir(), window)
|
|
+ else:
|
|
+ self.dlg.run(window)
|
|
|
|
return self.dlg.dlg
|
|
|
|
diff --git a/plugins/snippets/snippets/snippets.ui b/plugins/snippets/snippets/snippets.ui
|
|
index 6fcaf85..833aa02 100644
|
|
--- a/plugins/snippets/snippets/snippets.ui
|
|
+++ b/plugins/snippets/snippets/snippets.ui
|
|
@@ -1,8 +1,11 @@
|
|
-<?xml version="1.0"?>
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
+<!-- Generated with glade 3.22.1 -->
|
|
<!--*- mode: xml -*-->
|
|
<interface>
|
|
+ <requires lib="gtk+" version="3.0"/>
|
|
<object class="GtkListStore" id="model1">
|
|
<columns>
|
|
+ <!-- column-name gchararray -->
|
|
<column type="gchararray"/>
|
|
</columns>
|
|
<data>
|
|
@@ -32,303 +35,249 @@
|
|
</row>
|
|
</data>
|
|
</object>
|
|
- <object class="PlumaDocument" id="source_buffer">
|
|
- <property name="highlight-matching-brackets">True</property>
|
|
- </object>
|
|
<object class="GtkDialog" id="dialog_snippets">
|
|
+ <property name="can_focus">False</property>
|
|
<property name="title" translatable="yes">Snippets Manager</property>
|
|
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
|
|
- <property name="window_position">GTK_WIN_POS_NONE</property>
|
|
- <property name="modal">False</property>
|
|
<property name="default_width">750</property>
|
|
<property name="default_height">500</property>
|
|
- <property name="resizable">True</property>
|
|
<property name="destroy_with_parent">True</property>
|
|
- <property name="decorated">True</property>
|
|
+ <property name="type_hint">dialog</property>
|
|
<property name="skip_taskbar_hint">True</property>
|
|
- <property name="skip_pager_hint">False</property>
|
|
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
|
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
|
- <property name="focus_on_map">True</property>
|
|
- <property name="urgency_hint">False</property>
|
|
- <signal handler="on_dialog_snippets_response" last_modification_time="Mon, 19 Dec 2005 11:20:00 GMT" name="response"/>
|
|
- <signal handler="on_dialog_snippets_destroy" last_modification_time="Sun, 22 Jun 2008 13:22:00 GMT" name="destroy"/>
|
|
+ <signal name="destroy" handler="on_dialog_snippets_destroy" swapped="no"/>
|
|
+ <signal name="response" handler="on_dialog_snippets_response" swapped="no"/>
|
|
+ <child>
|
|
+ <placeholder/>
|
|
+ </child>
|
|
<child internal-child="vbox">
|
|
- <object class="GtkVBox" id="dialog-vbox1">
|
|
+ <object class="GtkBox" id="dialog-vbox1">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="orientation">vertical</property>
|
|
<child internal-child="action_area">
|
|
- <object class="GtkHButtonBox" id="dialog-action_area1">
|
|
+ <object class="GtkButtonBox" id="dialog-action_area1">
|
|
<property name="visible">True</property>
|
|
- <property name="layout_style">GTK_BUTTONBOX_END</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="layout_style">end</property>
|
|
<child>
|
|
- <object class="GtkButton" id="closebutton1">
|
|
+ <object class="GtkButton" id="button1">
|
|
+ <property name="label">gtk-help</property>
|
|
<property name="visible">True</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="label">gtk-close</property>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
<property name="use_stock">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
</object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkButton" id="button1">
|
|
+ <object class="GtkButton" id="closebutton1">
|
|
+ <property name="label">gtk-close</property>
|
|
<property name="visible">True</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="label">gtk-help</property>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
<property name="use_stock">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
</object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="pack_type">end</property>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
<property name="expand">False</property>
|
|
<property name="fill">True</property>
|
|
- <property name="pack_type">GTK_PACK_END</property>
|
|
+ <property name="pack_type">end</property>
|
|
+ <property name="position">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkHPaned" id="hpaned_paned">
|
|
- <property name="border_width">6</property>
|
|
+ <object class="GtkPaned">
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
<property name="position">275</property>
|
|
<child>
|
|
- <object class="GtkVBox" id="vbox_selection">
|
|
- <property name="width_request">230</property>
|
|
+ <object class="GtkGrid" id="grid_selection">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">6</property>
|
|
- <child>
|
|
- <object class="GtkLabel" id="label1">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes">_Snippets:</property>
|
|
- <property name="use_underline">True</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="mnemonic_widget">tree_view_snippets</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- </packing>
|
|
- </child>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="vexpand">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <property name="row_spacing">6</property>
|
|
<child>
|
|
<object class="GtkScrolledWindow" id="scrolled_window_snippets">
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
|
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
|
- <property name="shadow_type">GTK_SHADOW_IN</property>
|
|
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="vexpand">True</property>
|
|
+ <property name="shadow_type">in</property>
|
|
<child>
|
|
<object class="GtkTreeView" id="tree_view_snippets">
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
<property name="headers_visible">False</property>
|
|
- <property name="rules_hint">False</property>
|
|
- <property name="reorderable">False</property>
|
|
- <property name="enable_search">True</property>
|
|
- <property name="fixed_height_mode">False</property>
|
|
- <property name="hover_selection">False</property>
|
|
- <property name="hover_expand">False</property>
|
|
- <signal handler="on_tree_view_snippets_row_expanded" last_modification_time="Tue, 03 Jan 2006 22:06:02 GMT" name="row_expanded"/>
|
|
- <signal handler="on_tree_view_snippets_key_press" last_modification_time="Tue, 03 Jan 2006 22:07:00 GMT" name="key_press_event"/>
|
|
+ <signal name="key-press-event" handler="on_tree_view_snippets_key_press" swapped="no"/>
|
|
+ <signal name="row-expanded" handler="on_tree_view_snippets_row_expanded" swapped="no"/>
|
|
+ <child internal-child="selection">
|
|
+ <object class="GtkTreeSelection"/>
|
|
+ </child>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkHBox" id="hbox_buttons">
|
|
+ <object class="GtkLabel" id="label1">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">6</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes">_Snippets:</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ <property name="mnemonic_widget">tree_view_snippets</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkGrid" id="grid_buttons">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="column_spacing">6</property>
|
|
<child>
|
|
<object class="GtkButton" id="button_new_snippet">
|
|
<property name="visible">True</property>
|
|
- <property name="tooltip-text" translatable="yes">Create new snippet</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
- <signal handler="on_button_new_snippet_clicked" last_modification_time="Tue, 20 Dec 2005 19:50:58 GMT" name="clicked"/>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Create new snippet</property>
|
|
+ <signal name="clicked" handler="on_button_new_snippet_clicked" swapped="no"/>
|
|
<child>
|
|
<object class="GtkImage" id="image1">
|
|
<property name="visible">True</property>
|
|
- <property name="stock">gtk-new</property>
|
|
- <property name="icon_size">4</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="icon_name">document-new</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
<object class="GtkButton" id="button_import_snippets">
|
|
<property name="visible">True</property>
|
|
- <property name="tooltip-text" translatable="yes">Import snippets</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
- <signal handler="on_button_import_snippets_clicked" last_modification_time="Tue, 10 Jul 2007 18:37:11 GMT" name="clicked"/>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Import snippets</property>
|
|
+ <signal name="clicked" handler="on_button_import_snippets_clicked" swapped="no"/>
|
|
<child>
|
|
<object class="GtkImage" id="image5">
|
|
<property name="visible">True</property>
|
|
- <property name="stock">gtk-open</property>
|
|
- <property name="icon_size">4</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="icon_name">document-open</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
<object class="GtkButton" id="button_export_snippets">
|
|
<property name="visible">True</property>
|
|
- <property name="tooltip-text" translatable="yes">Export selected snippets</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
- <signal handler="on_button_export_snippets_clicked" last_modification_time="Tue, 10 Jul 2007 18:37:25 GMT" name="clicked"/>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Export selected snippets</property>
|
|
+ <signal name="clicked" handler="on_button_export_snippets_clicked" swapped="no"/>
|
|
<child>
|
|
<object class="GtkImage" id="image4">
|
|
<property name="visible">True</property>
|
|
- <property name="stock">gtk-save</property>
|
|
- <property name="icon_size">4</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="icon_name">document-save</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">2</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
<object class="GtkButton" id="button_remove_snippet">
|
|
<property name="visible">True</property>
|
|
<property name="sensitive">False</property>
|
|
- <property name="tooltip-text" translatable="yes">Delete selected snippet</property>
|
|
- <property name="can_default">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="relief">GTK_RELIEF_NORMAL</property>
|
|
- <property name="focus_on_click">True</property>
|
|
- <signal handler="on_button_remove_snippet_clicked" last_modification_time="Mon, 19 Dec 2005 13:15:14 GMT" name="clicked"/>
|
|
+ <property name="can_default">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="tooltip_text" translatable="yes">Delete selected snippet</property>
|
|
+ <property name="halign">end</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <signal name="clicked" handler="on_button_remove_snippet_clicked" swapped="no"/>
|
|
<child>
|
|
<object class="GtkImage" id="image_remove">
|
|
<property name="visible">True</property>
|
|
- <property name="stock">gtk-delete</property>
|
|
- <property name="icon_size">4</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="icon_name">edit-delete</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- <property name="pack_type">GTK_PACK_END</property>
|
|
+ <property name="left_attach">3</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">2</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="shrink">False</property>
|
|
<property name="resize">False</property>
|
|
+ <property name="shrink">True</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkVBox" id="vbox_snippet">
|
|
+ <object class="GtkGrid" id="grid_snippet">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">12</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="vexpand">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <property name="row_spacing">12</property>
|
|
<child>
|
|
- <object class="GtkVBox" id="vbox2">
|
|
+ <object class="GtkGrid">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">6</property>
|
|
- <child>
|
|
- <object class="GtkLabel" id="label4">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes">_Edit:</property>
|
|
- <property name="use_underline">True</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- </packing>
|
|
- </child>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="vexpand">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <property name="row_spacing">6</property>
|
|
<child>
|
|
<object class="GtkScrolledWindow" id="scrolled_window_snippet">
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
|
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
|
- <property name="shadow_type">GTK_SHADOW_IN</property>
|
|
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="vexpand">True</property>
|
|
+ <property name="shadow_type">in</property>
|
|
<child>
|
|
<object class="PlumaView" id="source_view_snippet">
|
|
<property name="buffer">source_buffer</property>
|
|
@@ -346,302 +295,198 @@
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="label4">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="label" translatable="yes">_Edit:</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkVBox" id="vbox1">
|
|
+ <object class="GtkGrid">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">6</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <property name="row_spacing">6</property>
|
|
<child>
|
|
<object class="GtkLabel" id="label3">
|
|
<property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="hexpand">True</property>
|
|
<property name="label" translatable="yes">Activation</property>
|
|
- <property name="use_underline">False</property>
|
|
<property name="use_markup">True</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
<attributes>
|
|
- <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
|
|
+ <attribute name="weight" value="bold"/>
|
|
</attributes>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkHBox" id="hbox1">
|
|
+ <object class="GtkGrid">
|
|
<property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="margin_left">12</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="row_spacing">6</property>
|
|
+ <property name="column_spacing">6</property>
|
|
<child>
|
|
- <object class="GtkLabel" id="label2">
|
|
+ <object class="GtkComboBox" id="combo_drop_targets">
|
|
<property name="visible">True</property>
|
|
- <property name="label" translatable="yes"> </property>
|
|
- <property name="use_underline">False</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="model">model1</property>
|
|
+ <property name="has_entry">True</property>
|
|
+ <property name="entry_text_column">0</property>
|
|
+ <child internal-child="entry">
|
|
+ <object class="GtkEntry">
|
|
+ <property name="can_focus">True</property>
|
|
+ </object>
|
|
+ </child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">2</property>
|
|
+ <property name="width">2</property>
|
|
</packing>
|
|
</child>
|
|
<child>
|
|
- <object class="GtkTable" id="table1">
|
|
+ <object class="GtkLabel" id="label_drop_targets">
|
|
<property name="visible">True</property>
|
|
- <property name="n_rows">3</property>
|
|
- <property name="n_columns">2</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="row_spacing">6</property>
|
|
- <property name="column_spacing">6</property>
|
|
- <child>
|
|
- <object class="GtkLabel" id="label_tab_trigger">
|
|
- <property name="visible">True</property>
|
|
- <property comments=""tab" here means the tab key, not the notebook tab!" name="label" translatable="yes">_Tab trigger:</property>
|
|
- <property name="use_underline">True</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="mnemonic_widget">entry_tab_trigger</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">0</property>
|
|
- <property name="right_attach">1</property>
|
|
- <property name="top_attach">0</property>
|
|
- <property name="bottom_attach">1</property>
|
|
- <property name="x_options">fill</property>
|
|
- <property name="y_options"/>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkHBox" id="hbox_tab_trigger">
|
|
- <property name="visible">True</property>
|
|
- <child>
|
|
- <object class="GtkEntry" id="entry_tab_trigger">
|
|
- <property name="visible">True</property>
|
|
- <property name="sensitive">False</property>
|
|
- <property name="tooltip-text" translatable="yes">Single word the snippet is activated with after pressing Tab</property>
|
|
- <property name="can_focus">True</property>
|
|
- <property name="editable">True</property>
|
|
- <property name="visibility">True</property>
|
|
- <property name="max_length">0</property>
|
|
- <property name="text" translatable="yes"/>
|
|
- <property name="has_frame">True</property>
|
|
- <property name="invisible_char">*</property>
|
|
- <property name="activates_default">False</property>
|
|
- <signal handler="on_entry_tab_trigger_focus_out" last_modification_time="Wed, 04 Jan 2006 14:07:29 GMT" name="focus_out_event"/>
|
|
- <signal handler="on_entry_tab_trigger_changed" last_modification_time="Fri, 28 Apr 2006 16:50:34 GMT" name="changed"/>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="expand">True</property>
|
|
- <property name="position">0</property>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkImage" id="image_tab_trigger">
|
|
- <property name="visible">False</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="expand">False</property>
|
|
- <property name="position">1</property>
|
|
- <property name="padding">3</property>
|
|
- </packing>
|
|
- </child>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">1</property>
|
|
- <property name="right_attach">2</property>
|
|
- <property name="top_attach">0</property>
|
|
- <property name="bottom_attach">1</property>
|
|
- <property name="y_options"/>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkEntry" id="entry_accelerator">
|
|
- <property name="visible">True</property>
|
|
- <property name="sensitive">False</property>
|
|
- <property name="tooltip-text" translatable="yes">Shortcut key with which the snippet is activated</property>
|
|
- <property name="can_focus">True</property>
|
|
- <property name="editable">False</property>
|
|
- <property name="visibility">True</property>
|
|
- <property name="max_length">0</property>
|
|
- <property name="text" translatable="yes"/>
|
|
- <property name="has_frame">True</property>
|
|
- <property name="invisible_char">*</property>
|
|
- <property name="activates_default">False</property>
|
|
- <signal handler="on_entry_accelerator_focus_out" last_modification_time="Wed, 04 Jan 2006 14:07:20 GMT" name="focus_out_event"/>
|
|
- <signal handler="on_entry_accelerator_key_press" last_modification_time="Wed, 04 Jan 2006 14:07:23 GMT" name="key_press_event"/>
|
|
- <signal handler="on_entry_accelerator_focus_in" last_modification_time="Wed, 04 Jan 2006 14:09:06 GMT" name="focus_in_event"/>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">1</property>
|
|
- <property name="right_attach">2</property>
|
|
- <property name="top_attach">1</property>
|
|
- <property name="bottom_attach">2</property>
|
|
- <property name="y_options"/>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkLabel" id="label_accelerator">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes">S_hortcut key:</property>
|
|
- <property name="use_underline">True</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="mnemonic_widget">entry_accelerator</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">0</property>
|
|
- <property name="right_attach">1</property>
|
|
- <property name="top_attach">1</property>
|
|
- <property name="bottom_attach">2</property>
|
|
- <property name="x_options">fill</property>
|
|
- <property name="y_options"/>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkLabel" id="label_drop_targets">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes">_Drop targets:</property>
|
|
- <property name="use_underline">True</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="mnemonic_widget">entry_accelerator</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">0</property>
|
|
- <property name="right_attach">1</property>
|
|
- <property name="top_attach">2</property>
|
|
- <property name="bottom_attach">3</property>
|
|
- <property name="x_options">fill</property>
|
|
- <property name="y_options"/>
|
|
- </packing>
|
|
- </child>
|
|
- <child>
|
|
- <object class="GtkComboBox" id="combo_drop_targets">
|
|
- <property name="visible">True</property>
|
|
- <property name="add_tearoffs">False</property>
|
|
- <property name="has_frame">True</property>
|
|
- <property name="has_entry">True</property>
|
|
- <property name="focus_on_click">True</property>
|
|
- <property name="model">model1</property>
|
|
- <child>
|
|
- <object class="GtkCellRendererText" id="renderer1"/>
|
|
- <attributes>
|
|
- <attribute name="text">0</attribute>
|
|
- </attributes>
|
|
- </child>
|
|
- </object>
|
|
- <packing>
|
|
- <property name="left_attach">1</property>
|
|
- <property name="right_attach">2</property>
|
|
- <property name="top_attach">2</property>
|
|
- <property name="bottom_attach">3</property>
|
|
- <property name="x_options">fill</property>
|
|
- <property name="y_options">fill</property>
|
|
- </packing>
|
|
- </child>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes">_Drop targets:</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">2</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkEntry" id="entry_accelerator">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="sensitive">False</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="tooltip_text" translatable="yes">Shortcut key with which the snippet is activated</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="editable">False</property>
|
|
+ <property name="invisible_char">*</property>
|
|
+ <signal name="focus-in-event" handler="on_entry_accelerator_focus_in" swapped="no"/>
|
|
+ <signal name="focus-out-event" handler="on_entry_accelerator_focus_out" swapped="no"/>
|
|
+ <signal name="key-press-event" handler="on_entry_accelerator_key_press" swapped="no"/>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">1</property>
|
|
+ <property name="width">2</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="label_accelerator">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes">S_hortcut key:</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="label_tab_trigger">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="label" translatable="yes" comments=""tab" here means the tab key, not the notebook tab!">_Tab trigger:</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkImage" id="image_tab_trigger">
|
|
+ <property name="can_focus">False</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">2</property>
|
|
+ <property name="top_attach">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkEntry" id="entry_tab_trigger">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="sensitive">False</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="tooltip_text" translatable="yes">Single word the snippet is activated with after pressing Tab</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <property name="invisible_char">*</property>
|
|
+ <signal name="changed" handler="on_entry_tab_trigger_changed" swapped="no"/>
|
|
+ <signal name="focus-out-event" handler="on_entry_tab_trigger_focus_out" swapped="no"/>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">0</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="shrink">True</property>
|
|
<property name="resize">True</property>
|
|
+ <property name="shrink">True</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
<packing>
|
|
- <property name="padding">0</property>
|
|
<property name="expand">True</property>
|
|
<property name="fill">True</property>
|
|
+ <property name="position">1</property>
|
|
</packing>
|
|
</child>
|
|
</object>
|
|
</child>
|
|
<action-widgets>
|
|
- <action-widget response="-7">closebutton1</action-widget>
|
|
<action-widget response="-11">button1</action-widget>
|
|
+ <action-widget response="-7">closebutton1</action-widget>
|
|
</action-widgets>
|
|
</object>
|
|
+ <object class="PlumaDocument" id="source_buffer">
|
|
+ <property name="highlight-matching-brackets">True</property>
|
|
+ </object>
|
|
</interface>
|
|
--
|
|
2.21.0
|
|
|