Removed python extensions
This commit is contained in:
parent
b5aa03547f
commit
5d9508d509
12
configure.ac
12
configure.ac
|
@ -385,21 +385,9 @@ plugin-loaders/python/bindings/Makefile
|
|||
plugins/Makefile
|
||||
plugins/changecase/Makefile
|
||||
plugins/docinfo/Makefile
|
||||
plugins/externaltools/data/Makefile
|
||||
plugins/externaltools/Makefile
|
||||
plugins/externaltools/scripts/Makefile
|
||||
plugins/externaltools/tools/Makefile
|
||||
plugins/filebrowser/Makefile
|
||||
plugins/filebrowser/org.x.editor.plugins.filebrowser.gschema.xml
|
||||
plugins/modelines/Makefile
|
||||
plugins/pythonconsole/Makefile
|
||||
plugins/pythonconsole/pythonconsole/Makefile
|
||||
plugins/quickopen/Makefile
|
||||
plugins/quickopen/quickopen/Makefile
|
||||
plugins/snippets/data/lang/Makefile
|
||||
plugins/snippets/data/Makefile
|
||||
plugins/snippets/Makefile
|
||||
plugins/snippets/snippets/Makefile
|
||||
plugins/sort/Makefile
|
||||
plugins/spell/Makefile
|
||||
plugins/spell/org.x.editor.plugins.spell.gschema.xml
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
DIST_SUBDIRS = \
|
||||
DIST_SUBDIRS = \
|
||||
changecase \
|
||||
docinfo \
|
||||
externaltools \
|
||||
filebrowser \
|
||||
filebrowser \
|
||||
modelines \
|
||||
pythonconsole \
|
||||
quickopen \
|
||||
snippets \
|
||||
sort \
|
||||
spell \
|
||||
taglist \
|
||||
|
@ -16,7 +12,6 @@ DIST_SUBDIRS = \
|
|||
SUBDIRS = \
|
||||
changecase \
|
||||
docinfo \
|
||||
externaltools \
|
||||
filebrowser \
|
||||
modelines \
|
||||
sort \
|
||||
|
@ -24,10 +19,6 @@ SUBDIRS = \
|
|||
time \
|
||||
trailsave
|
||||
|
||||
if ENABLE_PYTHON
|
||||
SUBDIRS += pythonconsole snippets quickopen
|
||||
endif
|
||||
|
||||
if ENABLE_ENCHANT
|
||||
SUBDIRS += spell
|
||||
endif
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
# External Tools plugin
|
||||
SUBDIRS = tools data scripts
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = externaltools.xedit-plugin.desktop.in
|
||||
%.xedit-plugin: %.xedit-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
|
||||
|
||||
plugin_DATA = $(plugin_in_files:.xedit-plugin.desktop.in=.xedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,46 +0,0 @@
|
|||
TOOL_MERGE=$(top_srcdir)/plugins/externaltools/scripts/xedit-tool-merge.pl
|
||||
|
||||
tools_in_files = \
|
||||
build.tool.in \
|
||||
open-terminal-here.tool.in \
|
||||
remove-trailing-spaces.tool.in \
|
||||
run-command.tool.in \
|
||||
search-recursive.tool.in \
|
||||
switch-c.tool.in
|
||||
|
||||
install_tools_in_files = $(tools_in_files)
|
||||
|
||||
desktop_in_files = $(install_tools_in_files:.tool.in=.desktop.in)
|
||||
desktop_files = $(install_tools_in_files:.tool.in=.desktop)
|
||||
|
||||
tools_SCRIPTS = $(install_tools_in_files:.tool.in=)
|
||||
toolsdir = $(XEDIT_PLUGINS_DATA_DIR)/externaltools/tools
|
||||
|
||||
all_tools_in_files = \
|
||||
$(tools_in_files)
|
||||
|
||||
all_desktop_in_files = $(all_tools_in_files:.tool.in=.desktop.in)
|
||||
all_desktop_files = $(all_tools_in_files:.tool.in=.desktop)
|
||||
all_tools_files = $(all_tools_in_files:.tool.in=)
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
# Tools are generated by merging a script file (.tool.in) with a data file
|
||||
# (.desktop), which happens to be translated using intltool.
|
||||
$(tools_SCRIPTS): %: %.tool.in %.desktop $(TOOL_MERGE)
|
||||
perl $(TOOL_MERGE) -o $@ $< $(word 2,$^)
|
||||
chmod 755 $@
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(all_desktop_in_files) \
|
||||
$(all_tools_in_files)
|
||||
|
||||
CLEANFILES = \
|
||||
$(all_desktop_files) \
|
||||
$(all_tools_files)
|
||||
|
||||
DISTCLEANFILES = \
|
||||
$(all_desktop_files) \
|
||||
$(all_tools_files)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,9 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Build
|
||||
_Comment=Run "make" in the document directory
|
||||
Input=nothing
|
||||
Output=output-panel
|
||||
Shortcut=<Control>F8
|
||||
Applicability=local
|
||||
Save-files=nothing
|
||||
Languages=
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
EHOME=`echo $HOME | sed "s/#/\#/"`
|
||||
DIR=$XEDIT_CURRENT_DOCUMENT_DIR
|
||||
while test "$DIR" != "/"; do
|
||||
for m in GNUmakefile makefile Makefile; do
|
||||
if [ -f "${DIR}/${m}" ]; then
|
||||
echo "Using ${m} from ${DIR}" | sed "s#$EHOME#~#" > /dev/stderr
|
||||
make -C "${DIR}"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
DIR=`dirname "${DIR}"`
|
||||
done
|
||||
echo "No Makefile found!" > /dev/stderr
|
|
@ -1,8 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Open terminal here
|
||||
_Comment=Open a terminal in the document location
|
||||
Input=nothing
|
||||
Output=output-panel
|
||||
Applicability=local
|
||||
Save-files=nothing
|
||||
Languages=
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
xterminal --working-directory=$XEDIT_CURRENT_DOCUMENT_DIR &
|
|
@ -1,9 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Remove trailing spaces
|
||||
_Comment=Remove useless trailing spaces in your file
|
||||
Input=document
|
||||
Output=replace-document
|
||||
Shortcut=<Alt>F12
|
||||
Applicability=all
|
||||
Save-files=nothing
|
||||
Languages=
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
sed 's/[[:blank:]]*$//'
|
|
@ -1,8 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Run command
|
||||
_Comment=Execute a custom command and put its output in a new document
|
||||
Input=nothing
|
||||
Output=new-document
|
||||
Applicability=all
|
||||
Save-files=nothing
|
||||
Languages=
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
exec `zenity --entry --title="Run command" --text="Command to run"`
|
|
@ -1,9 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Search
|
||||
Shortcut=<Primary><Shift>f
|
||||
Languages=
|
||||
Applicability=local
|
||||
Input=document
|
||||
Output=output-panel
|
||||
Save-files=nothing
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright © 2011 Perberos
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# 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 Lesser
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
SEARCHTEXT=`zenity --entry --title="Search text on files" --text="Text to search"`
|
||||
|
||||
if [ ! "${#SEARCHTEXT}" = 0 ]; then
|
||||
|
||||
OIFS=$IFS; IFS=$'\n' # Backup and set new IFS
|
||||
|
||||
for LINE in `grep -nHIirF -- "$SEARCHTEXT" ./`; do
|
||||
primer_indice=`expr index "$LINE" :`
|
||||
tmp=${LINE:$primer_indice}
|
||||
segundo_indice=`expr index "$tmp" :`
|
||||
linea_codigo=${tmp:$segundo_indice}
|
||||
|
||||
# lugar donde está la palabra
|
||||
posicion=`expr index "$tmp" "$SEARCHTEXT"`
|
||||
|
||||
linea_archivo=${LINE:0:$primer_indice + $segundo_indice - 1}
|
||||
|
||||
echo "${linea_archivo}: ${linea_codigo}"
|
||||
done
|
||||
|
||||
IFS=$OIFS # Restore IFS
|
||||
fi
|
|
@ -1,7 +0,0 @@
|
|||
[Xedit Tool]
|
||||
_Name=Switch onto a file .c and .h
|
||||
Shortcut=<Shift><Alt>s
|
||||
Applicability=all
|
||||
Output=nothing
|
||||
Input=nothing
|
||||
Save-files=nothing
|
|
@ -1,25 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright © 2011 Perberos
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# 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 Lesser
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
import os
|
||||
|
||||
name = os.environ["XEDIT_CURRENT_DOCUMENT_NAME"]
|
||||
|
||||
if name.endswith('.c'):
|
||||
os.system("xedit %s.h" % ".".join(name.split('.')[:-1]))
|
||||
if name.endswith('.h'):
|
||||
os.system("xedit %s.c" % ".".join(name.split('.')[:-1]))
|
|
@ -1,9 +0,0 @@
|
|||
[Xedit Plugin]
|
||||
Loader=python
|
||||
Module=externaltools
|
||||
IAge=2
|
||||
_Name=External Tools
|
||||
_Description=Execute external commands and shell scripts.
|
||||
Authors=Steve Frécinaux <steve@istique.net>
|
||||
Copyright=Copyright © 2005 Steve Frécinaux
|
||||
Website=http://www.mate-desktop.org
|
|
@ -1,4 +0,0 @@
|
|||
EXTRA_DIST = xedit-tool-merge.pl
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# xedit-tool-merge.pl
|
||||
# This file is part of xedit
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux <code@istique.net>
|
||||
#
|
||||
# xedit 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# xedit 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with xedit; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA
|
||||
|
||||
# This script merges a script file with a desktop file containing
|
||||
# metadata about the external tool. This is required in order to
|
||||
# have translatable tools (bug #342042) since intltool can't extract
|
||||
# string directly from tool files (a tool file being the combination
|
||||
# of a script file and a metadata section).
|
||||
#
|
||||
# The desktop file is embedded in a comment of the script file, under
|
||||
# the assumption that any scripting language supports # as a comment
|
||||
# mark (this is likely to be true since the shebang uses #!). The
|
||||
# section is placed at the top of the tool file, after the shebang and
|
||||
# modelines if present.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
sub usage {
|
||||
print <<EOF;
|
||||
Usage: ${0} [OPTION]... [SCRIPT] [DESKTOP]
|
||||
Merges a script file with a desktop file, embedding it in a comment.
|
||||
|
||||
-o, --output=FILE Specify the output file name. [default: stdout]
|
||||
EOF
|
||||
exit;
|
||||
}
|
||||
|
||||
my $output = "";
|
||||
my $help;
|
||||
|
||||
GetOptions ("help|h" => \$help, "output|o=s" => \$output) or &usage;
|
||||
usage if $help or @ARGV lt 2;
|
||||
|
||||
open INFILE, "<", $ARGV[0];
|
||||
open DFILE, "<", $ARGV[1];
|
||||
open STDOUT, ">", $output if $output;
|
||||
|
||||
# Put shebang and various modelines at the top of the generated file.
|
||||
$_ = <INFILE>;
|
||||
print and $_ = <INFILE> if /^#!/;
|
||||
print and $_ = <INFILE> if /-\*-/;
|
||||
print and $_ = <INFILE> if /(ex|vi|vim):/;
|
||||
|
||||
# Put a blank line before the info block if there is one in INFILE.
|
||||
print and $_ = <INFILE> if /^\s*$/;
|
||||
seek INFILE, -length, 1;
|
||||
|
||||
# Embed the desktop file...
|
||||
print "# $_" while <DFILE>;
|
||||
print "\n";
|
||||
|
||||
# ...and write the remaining part of the script.
|
||||
print while <INFILE>;
|
||||
|
||||
close INFILE;
|
||||
close DFILE;
|
||||
close STDOUT;
|
|
@ -1,23 +0,0 @@
|
|||
# Python snippets plugin
|
||||
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)/externaltools
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
capture.py \
|
||||
library.py \
|
||||
functions.py \
|
||||
manager.py \
|
||||
outputpanel.py \
|
||||
filelookup.py \
|
||||
linkparsing.py
|
||||
|
||||
uidir = $(XEDIT_PLUGINS_DATA_DIR)/externaltools/ui
|
||||
ui_DATA = tools.ui \
|
||||
outputpanel.ui
|
||||
|
||||
EXTRA_DIST = $(ui_DATA)
|
||||
|
||||
CLEANFILES = *.bak *.gladep
|
||||
DISTCLEANFILES = *.bak *.gladep
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,281 +0,0 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('ExternalToolsPlugin', 'ExternalToolsWindowHelper',
|
||||
'Manager', 'OutputPanel', 'Capture', 'UniqueById')
|
||||
|
||||
import xedit
|
||||
import gtk
|
||||
from manager import Manager
|
||||
from library import ToolLibrary
|
||||
from outputpanel import OutputPanel
|
||||
from capture import Capture
|
||||
from functions import *
|
||||
|
||||
class ToolMenu(object):
|
||||
ACTION_HANDLER_DATA_KEY = "ExternalToolActionHandlerData"
|
||||
ACTION_ITEM_DATA_KEY = "ExternalToolActionItemData"
|
||||
|
||||
def __init__(self, library, window, menupath):
|
||||
super(ToolMenu, self).__init__()
|
||||
self._library = library
|
||||
self._window = window
|
||||
self._menupath = menupath
|
||||
|
||||
self._merge_id = 0
|
||||
self._action_group = gtk.ActionGroup("ExternalToolsPluginToolActions")
|
||||
self._signals = []
|
||||
|
||||
self.update()
|
||||
|
||||
def deactivate(self):
|
||||
self.remove()
|
||||
|
||||
def remove(self):
|
||||
if self._merge_id != 0:
|
||||
self._window.get_ui_manager().remove_ui(self._merge_id)
|
||||
self._window.get_ui_manager().remove_action_group(self._action_group)
|
||||
self._merge_id = 0
|
||||
|
||||
for action in self._action_group.list_actions():
|
||||
handler = action.get_data(self.ACTION_HANDLER_DATA_KEY)
|
||||
|
||||
if handler is not None:
|
||||
action.disconnect(handler)
|
||||
|
||||
action.set_data(self.ACTION_ITEM_DATA_KEY, None)
|
||||
action.set_data(self.ACTION_HANDLER_DATA_KEY, None)
|
||||
|
||||
self._action_group.remove_action(action)
|
||||
|
||||
accelmap = gtk.accel_map_get()
|
||||
|
||||
for s in self._signals:
|
||||
accelmap.disconnect(s)
|
||||
|
||||
self._signals = []
|
||||
|
||||
def _insert_directory(self, directory, path):
|
||||
manager = self._window.get_ui_manager()
|
||||
|
||||
for item in directory.subdirs:
|
||||
action_name = 'ExternalToolDirectory%X' % id(item)
|
||||
action = gtk.Action(action_name, item.name.replace('_', '__'), None, None)
|
||||
self._action_group.add_action(action)
|
||||
|
||||
manager.add_ui(self._merge_id, path,
|
||||
action_name, action_name,
|
||||
gtk.UI_MANAGER_MENU, False)
|
||||
|
||||
self._insert_directory(item, path + '/' + action_name)
|
||||
|
||||
for item in directory.tools:
|
||||
action_name = 'ExternalToolTool%X' % id(item)
|
||||
action = gtk.Action(action_name, item.name.replace('_', '__'), item.comment, None)
|
||||
handler = action.connect("activate", capture_menu_action, self._window, item)
|
||||
|
||||
action.set_data(self.ACTION_ITEM_DATA_KEY, item)
|
||||
action.set_data(self.ACTION_HANDLER_DATA_KEY, handler)
|
||||
|
||||
# Make sure to replace accel
|
||||
accelpath = '<Actions>/ExternalToolsPluginToolActions/%s' % (action_name, )
|
||||
|
||||
if item.shortcut:
|
||||
key, mod = gtk.accelerator_parse(item.shortcut)
|
||||
gtk.accel_map_change_entry(accelpath, key, mod, True)
|
||||
|
||||
self._signals.append(gtk.accel_map_get().connect('changed::%s' % (accelpath,), self.on_accelmap_changed, item))
|
||||
|
||||
self._action_group.add_action_with_accel(action, item.shortcut)
|
||||
|
||||
manager.add_ui(self._merge_id, path,
|
||||
action_name, action_name,
|
||||
gtk.UI_MANAGER_MENUITEM, False)
|
||||
|
||||
def on_accelmap_changed(self, accelmap, path, key, mod, tool):
|
||||
tool.shortcut = gtk.accelerator_name(key, mod)
|
||||
tool.save()
|
||||
|
||||
self._window.get_data("ExternalToolsPluginWindowData").update_manager(tool)
|
||||
|
||||
def update(self):
|
||||
self.remove()
|
||||
self._merge_id = self._window.get_ui_manager().new_merge_id()
|
||||
self._insert_directory(self._library.tree, self._menupath)
|
||||
self._window.get_ui_manager().insert_action_group(self._action_group, -1)
|
||||
self.filter(self._window.get_active_document())
|
||||
|
||||
def filter_language(self, language, item):
|
||||
if not item.languages:
|
||||
return True
|
||||
|
||||
if not language and 'plain' in item.languages:
|
||||
return True
|
||||
|
||||
if language and (language.get_id() in item.languages):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def filter(self, document):
|
||||
if document is None:
|
||||
return
|
||||
|
||||
titled = document.get_uri() is not None
|
||||
remote = not document.is_local()
|
||||
|
||||
states = {
|
||||
'all' : True,
|
||||
'local': titled and not remote,
|
||||
'remote': titled and remote,
|
||||
'titled': titled,
|
||||
'untitled': not titled,
|
||||
}
|
||||
|
||||
language = document.get_language()
|
||||
|
||||
for action in self._action_group.list_actions():
|
||||
item = action.get_data(self.ACTION_ITEM_DATA_KEY)
|
||||
|
||||
if item is not None:
|
||||
action.set_visible(states[item.applicability] and self.filter_language(language, item))
|
||||
|
||||
class ExternalToolsWindowHelper(object):
|
||||
def __init__(self, plugin, window):
|
||||
super(ExternalToolsWindowHelper, self).__init__()
|
||||
|
||||
self._window = window
|
||||
self._plugin = plugin
|
||||
self._library = ToolLibrary()
|
||||
|
||||
manager = window.get_ui_manager()
|
||||
|
||||
self._action_group = gtk.ActionGroup('ExternalToolsPluginActions')
|
||||
self._action_group.set_translation_domain('xedit')
|
||||
self._action_group.add_actions([('ExternalToolManager',
|
||||
None,
|
||||
_('Manage _External Tools...'),
|
||||
None,
|
||||
_("Opens the External Tools Manager"),
|
||||
lambda action: plugin.open_dialog()),
|
||||
('ExternalTools',
|
||||
None,
|
||||
_('External _Tools'),
|
||||
None,
|
||||
_("External tools"),
|
||||
None)])
|
||||
manager.insert_action_group(self._action_group, -1)
|
||||
|
||||
ui_string = """
|
||||
<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu name="ToolsMenu" action="Tools">
|
||||
<placeholder name="ToolsOps_4">
|
||||
<separator/>
|
||||
<menu name="ExternalToolsMenu" action="ExternalTools">
|
||||
<placeholder name="ExternalToolPlaceholder"/>
|
||||
</menu>
|
||||
<separator/>
|
||||
</placeholder>
|
||||
<placeholder name="ToolsOps_5">
|
||||
<menuitem name="ExternalToolManager" action="ExternalToolManager"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>"""
|
||||
|
||||
self._merge_id = manager.add_ui_from_string(ui_string)
|
||||
|
||||
self.menu = ToolMenu(self._library, self._window,
|
||||
"/MenuBar/ToolsMenu/ToolsOps_4/ExternalToolsMenu/ExternalToolPlaceholder")
|
||||
manager.ensure_update()
|
||||
|
||||
# Create output console
|
||||
self._output_buffer = OutputPanel(self._plugin.get_data_dir(), window)
|
||||
bottom = window.get_bottom_panel()
|
||||
bottom.add_item(self._output_buffer.panel,
|
||||
_("Shell Output"),
|
||||
gtk.STOCK_EXECUTE)
|
||||
|
||||
def update_ui(self):
|
||||
self.menu.filter(self._window.get_active_document())
|
||||
self._window.get_ui_manager().ensure_update()
|
||||
|
||||
def deactivate(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
self.menu.deactivate()
|
||||
manager.remove_ui(self._merge_id)
|
||||
manager.remove_action_group(self._action_group)
|
||||
manager.ensure_update()
|
||||
|
||||
bottom = self._window.get_bottom_panel()
|
||||
bottom.remove_item(self._output_buffer.panel)
|
||||
|
||||
def update_manager(self, tool):
|
||||
self._plugin.update_manager(tool)
|
||||
|
||||
class ExternalToolsPlugin(xedit.Plugin):
|
||||
WINDOW_DATA_KEY = "ExternalToolsPluginWindowData"
|
||||
|
||||
def __init__(self):
|
||||
super(ExternalToolsPlugin, self).__init__()
|
||||
|
||||
self._manager = None
|
||||
self._manager_default_size = None
|
||||
|
||||
ToolLibrary().set_locations(os.path.join(self.get_data_dir(), 'tools'))
|
||||
|
||||
def activate(self, window):
|
||||
helper = ExternalToolsWindowHelper(self, window)
|
||||
window.set_data(self.WINDOW_DATA_KEY, helper)
|
||||
|
||||
def deactivate(self, window):
|
||||
window.get_data(self.WINDOW_DATA_KEY).deactivate()
|
||||
window.set_data(self.WINDOW_DATA_KEY, None)
|
||||
|
||||
def update_ui(self, window):
|
||||
window.get_data(self.WINDOW_DATA_KEY).update_ui()
|
||||
|
||||
def create_configure_dialog(self):
|
||||
return self.open_dialog()
|
||||
|
||||
def open_dialog(self):
|
||||
if not self._manager:
|
||||
self._manager = Manager(self.get_data_dir())
|
||||
|
||||
if self._manager_default_size:
|
||||
self._manager.dialog.set_default_size(*self._manager_default_size)
|
||||
|
||||
self._manager.dialog.connect('destroy', self.on_manager_destroy)
|
||||
|
||||
window = xedit.app_get_default().get_active_window()
|
||||
self._manager.run(window)
|
||||
|
||||
return self._manager.dialog
|
||||
|
||||
def update_manager(self, tool):
|
||||
if not self._manager:
|
||||
return
|
||||
|
||||
self._manager.tool_changed(tool, True)
|
||||
|
||||
def on_manager_destroy(self, dialog):
|
||||
self._manager_default_size = [dialog.allocation.width, dialog.allocation.height]
|
||||
self._manager = None
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,214 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('Capture', )
|
||||
|
||||
import os, sys, signal
|
||||
import locale
|
||||
import subprocess
|
||||
import gobject
|
||||
import fcntl
|
||||
import glib
|
||||
|
||||
class Capture(gobject.GObject):
|
||||
CAPTURE_STDOUT = 0x01
|
||||
CAPTURE_STDERR = 0x02
|
||||
CAPTURE_BOTH = 0x03
|
||||
CAPTURE_NEEDS_SHELL = 0x04
|
||||
|
||||
WRITE_BUFFER_SIZE = 0x4000
|
||||
|
||||
__gsignals__ = {
|
||||
'stdout-line' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
|
||||
'stderr-line' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
|
||||
'begin-execute': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, tuple()),
|
||||
'end-execute' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,))
|
||||
}
|
||||
|
||||
def __init__(self, command, cwd = None, env = {}):
|
||||
gobject.GObject.__init__(self)
|
||||
self.pipe = None
|
||||
self.env = env
|
||||
self.cwd = cwd
|
||||
self.flags = self.CAPTURE_BOTH | self.CAPTURE_NEEDS_SHELL
|
||||
self.command = command
|
||||
self.input_text = None
|
||||
|
||||
def set_env(self, **values):
|
||||
self.env.update(**values)
|
||||
|
||||
def set_command(self, command):
|
||||
self.command = command
|
||||
|
||||
def set_flags(self, flags):
|
||||
self.flags = flags
|
||||
|
||||
def set_input(self, text):
|
||||
self.input_text = text
|
||||
|
||||
def set_cwd(self, cwd):
|
||||
self.cwd = cwd
|
||||
|
||||
def execute(self):
|
||||
if self.command is None:
|
||||
return
|
||||
|
||||
# Initialize pipe
|
||||
popen_args = {
|
||||
'cwd' : self.cwd,
|
||||
'shell': self.flags & self.CAPTURE_NEEDS_SHELL,
|
||||
'env' : self.env
|
||||
}
|
||||
|
||||
if self.input_text is not None:
|
||||
popen_args['stdin'] = subprocess.PIPE
|
||||
if self.flags & self.CAPTURE_STDOUT:
|
||||
popen_args['stdout'] = subprocess.PIPE
|
||||
if self.flags & self.CAPTURE_STDERR:
|
||||
popen_args['stderr'] = subprocess.PIPE
|
||||
|
||||
self.tried_killing = False
|
||||
self.idle_write_id = 0
|
||||
self.read_buffer = ''
|
||||
|
||||
try:
|
||||
self.pipe = subprocess.Popen(self.command, **popen_args)
|
||||
except OSError, e:
|
||||
self.pipe = None
|
||||
self.emit('stderr-line', _('Could not execute command: %s') % (e, ))
|
||||
return
|
||||
|
||||
# Signal
|
||||
self.emit('begin-execute')
|
||||
|
||||
if self.flags & self.CAPTURE_STDOUT:
|
||||
# Set non blocking
|
||||
flags = fcntl.fcntl(self.pipe.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK
|
||||
fcntl.fcntl(self.pipe.stdout.fileno(), fcntl.F_SETFL, flags)
|
||||
|
||||
gobject.io_add_watch(self.pipe.stdout,
|
||||
gobject.IO_IN | gobject.IO_HUP,
|
||||
self.on_output)
|
||||
|
||||
if self.flags & self.CAPTURE_STDERR:
|
||||
# Set non blocking
|
||||
flags = fcntl.fcntl(self.pipe.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK
|
||||
fcntl.fcntl(self.pipe.stderr.fileno(), fcntl.F_SETFL, flags)
|
||||
|
||||
gobject.io_add_watch(self.pipe.stderr,
|
||||
gobject.IO_IN | gobject.IO_HUP,
|
||||
self.on_output)
|
||||
|
||||
# IO
|
||||
if self.input_text is not None:
|
||||
# Write async, in chunks of something
|
||||
self.write_buffer = str(self.input_text)
|
||||
|
||||
if self.idle_write_chunk():
|
||||
self.idle_write_id = gobject.idle_add(self.idle_write_chunk)
|
||||
|
||||
# Wait for the process to complete
|
||||
gobject.child_watch_add(self.pipe.pid, self.on_child_end)
|
||||
|
||||
def idle_write_chunk(self):
|
||||
if not self.pipe:
|
||||
self.idle_write_id = 0
|
||||
return False
|
||||
|
||||
try:
|
||||
l = len(self.write_buffer)
|
||||
m = min(l, self.WRITE_BUFFER_SIZE)
|
||||
|
||||
self.pipe.stdin.write(self.write_buffer[:m])
|
||||
|
||||
if m == l:
|
||||
self.write_buffer = ''
|
||||
self.pipe.stdin.close()
|
||||
|
||||
self.idle_write_id = 0
|
||||
|
||||
return False
|
||||
else:
|
||||
self.write_buffer = self.write_buffer[m:]
|
||||
return True
|
||||
except IOError:
|
||||
self.pipe.stdin.close()
|
||||
self.idle_write_id = 0
|
||||
|
||||
return False
|
||||
|
||||
def on_output(self, source, condition):
|
||||
if condition & (glib.IO_IN | glib.IO_PRI):
|
||||
line = source.read()
|
||||
|
||||
if len(line) > 0:
|
||||
try:
|
||||
line = unicode(line, 'utf-8')
|
||||
except:
|
||||
line = unicode(line,
|
||||
locale.getdefaultlocale()[1],
|
||||
'replace')
|
||||
|
||||
self.read_buffer += line
|
||||
lines = self.read_buffer.splitlines(True)
|
||||
|
||||
if not lines[-1].endswith("\n"):
|
||||
self.read_buffer = lines[-1]
|
||||
lines = lines[0:-1]
|
||||
else:
|
||||
self.read_buffer = ''
|
||||
|
||||
for line in lines:
|
||||
if not self.pipe or source == self.pipe.stdout:
|
||||
self.emit('stdout-line', line)
|
||||
else:
|
||||
self.emit('stderr-line', line)
|
||||
|
||||
if condition & ~(glib.IO_IN | glib.IO_PRI):
|
||||
if self.read_buffer:
|
||||
if source == self.pipe.stdout:
|
||||
self.emit('stdout-line', self.read_buffer)
|
||||
else:
|
||||
self.emit('stderr-line', self.read_buffer)
|
||||
|
||||
self.read_buffer = ''
|
||||
|
||||
self.pipe = None
|
||||
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def stop(self, error_code = -1):
|
||||
if self.pipe is not None:
|
||||
if self.idle_write_id:
|
||||
gobject.source_remove(self.idle_write_id)
|
||||
self.idle_write_id = 0
|
||||
|
||||
if not self.tried_killing:
|
||||
os.kill(self.pipe.pid, signal.SIGTERM)
|
||||
self.tried_killing = True
|
||||
else:
|
||||
os.kill(self.pipe.pid, signal.SIGKILL)
|
||||
|
||||
def on_child_end(self, pid, error_code):
|
||||
# In an idle, so it is emitted after all the std*-line signals
|
||||
# have been intercepted
|
||||
gobject.idle_add(self.emit, 'end-execute', error_code)
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,145 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2009-2010 Per Arneng <per.arneng@anyplanet.com>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import gio
|
||||
import xedit
|
||||
|
||||
class FileLookup:
|
||||
"""
|
||||
This class is responsible for looking up files given a part or the whole
|
||||
path of a real file. The lookup is delegated to providers wich use different
|
||||
methods of trying to find the real file.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.providers = []
|
||||
self.providers.append(AbsoluteFileLookupProvider())
|
||||
self.providers.append(CwdFileLookupProvider())
|
||||
self.providers.append(OpenDocumentRelPathFileLookupProvider())
|
||||
self.providers.append(OpenDocumentFileLookupProvider())
|
||||
|
||||
def lookup(self, path):
|
||||
"""
|
||||
Tries to find a file specified by the path parameter. It delegates to
|
||||
different lookup providers and the first match is returned. If no file
|
||||
was found then None is returned.
|
||||
|
||||
path -- the path to find
|
||||
"""
|
||||
found_file = None
|
||||
for provider in self.providers:
|
||||
found_file = provider.lookup(path)
|
||||
if found_file is not None:
|
||||
break
|
||||
|
||||
return found_file
|
||||
|
||||
|
||||
class FileLookupProvider:
|
||||
"""
|
||||
The base class of all file lookup providers.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
"""
|
||||
This method must be implemented by subclasses. Implementors will be
|
||||
given a path and will try to find a matching file. If no file is found
|
||||
then None is returned.
|
||||
"""
|
||||
raise NotImplementedError("need to implement a lookup method")
|
||||
|
||||
|
||||
class AbsoluteFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
This file tries to see if the path given is an absolute path and that the
|
||||
path references a file.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if os.path.isabs(path) and os.path.isfile(path):
|
||||
return gio.File(path)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class CwdFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
This lookup provider tries to find a file specified by the path relative to
|
||||
the current working directory.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
try:
|
||||
cwd = os.getcwd()
|
||||
except OSError:
|
||||
cwd = os.getenv('HOME')
|
||||
|
||||
real_path = os.path.join(cwd, path)
|
||||
|
||||
if os.path.isfile(real_path):
|
||||
return gio.File(real_path)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class OpenDocumentRelPathFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
Tries to see if the path is relative to any directories where the
|
||||
currently open documents reside in. Example: If you have a document opened
|
||||
'/tmp/Makefile' and a lookup is made for 'src/test2.c' then this class
|
||||
will try to find '/tmp/src/test2.c'.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if path.startswith('/'):
|
||||
return None
|
||||
|
||||
for doc in xedit.app_get_default().get_documents():
|
||||
if doc.is_local():
|
||||
location = doc.get_location()
|
||||
if location:
|
||||
rel_path = location.get_parent().get_path()
|
||||
joined_path = os.path.join(rel_path, path)
|
||||
if os.path.isfile(joined_path):
|
||||
return gio.File(joined_path)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class OpenDocumentFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
Makes a guess that the if the path that was looked for matches the end
|
||||
of the path of a currently open document then that document is the one
|
||||
that is looked for. Example: If a document is opened called '/tmp/t.c'
|
||||
and a lookup is made for 't.c' or 'tmp/t.c' then both will match since
|
||||
the open document ends with the path that is searched for.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if path.startswith('/'):
|
||||
return None
|
||||
|
||||
for doc in xedit.app_get_default().get_documents():
|
||||
if doc.is_local():
|
||||
location = doc.get_location()
|
||||
if location and location.get_uri().endswith(path):
|
||||
return location
|
||||
return None
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,303 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import gio
|
||||
import xedit
|
||||
#import gtksourceview
|
||||
from outputpanel import OutputPanel
|
||||
from capture import *
|
||||
|
||||
def default(val, d):
|
||||
if val is not None:
|
||||
return val
|
||||
else:
|
||||
return d
|
||||
|
||||
def current_word(document):
|
||||
piter = document.get_iter_at_mark(document.get_insert())
|
||||
start = piter.copy()
|
||||
|
||||
if not piter.starts_word() and (piter.inside_word() or piter.ends_word()):
|
||||
start.backward_word_start()
|
||||
|
||||
if not piter.ends_word() and piter.inside_word():
|
||||
piter.forward_word_end()
|
||||
|
||||
return (start, piter)
|
||||
|
||||
# ==== Capture related functions ====
|
||||
def run_external_tool(window, node):
|
||||
# Configure capture environment
|
||||
try:
|
||||
cwd = os.getcwd()
|
||||
except OSError:
|
||||
cwd = os.getenv('HOME');
|
||||
|
||||
capture = Capture(node.command, cwd)
|
||||
capture.env = os.environ.copy()
|
||||
capture.set_env(XEDIT_CWD = cwd)
|
||||
|
||||
view = window.get_active_view()
|
||||
if view is not None:
|
||||
# Environment vars relative to current document
|
||||
document = view.get_buffer()
|
||||
uri = document.get_uri()
|
||||
|
||||
# Current line number
|
||||
piter = document.get_iter_at_mark(document.get_insert())
|
||||
capture.set_env(XEDIT_CURRENT_LINE_NUMBER=str(piter.get_line() + 1))
|
||||
|
||||
# Current line text
|
||||
piter.set_line_offset(0)
|
||||
end = piter.copy()
|
||||
|
||||
if not end.ends_line():
|
||||
end.forward_to_line_end()
|
||||
|
||||
capture.set_env(XEDIT_CURRENT_LINE=piter.get_text(end))
|
||||
|
||||
# Selected text (only if input is not selection)
|
||||
if node.input != 'selection' and node.input != 'selection-document':
|
||||
bounds = document.get_selection_bounds()
|
||||
|
||||
if bounds:
|
||||
capture.set_env(XEDIT_SELECTED_TEXT=bounds[0].get_text(bounds[1]))
|
||||
|
||||
bounds = current_word(document)
|
||||
capture.set_env(XEDIT_CURRENT_WORD=bounds[0].get_text(bounds[1]))
|
||||
|
||||
capture.set_env(XEDIT_CURRENT_DOCUMENT_TYPE=document.get_mime_type())
|
||||
|
||||
if uri is not None:
|
||||
gfile = gio.File(uri)
|
||||
scheme = gfile.get_uri_scheme()
|
||||
name = os.path.basename(uri)
|
||||
capture.set_env(XEDIT_CURRENT_DOCUMENT_URI = uri,
|
||||
XEDIT_CURRENT_DOCUMENT_NAME = name,
|
||||
XEDIT_CURRENT_DOCUMENT_SCHEME = scheme)
|
||||
if xedit.utils.uri_has_file_scheme(uri):
|
||||
path = gfile.get_path()
|
||||
cwd = os.path.dirname(path)
|
||||
capture.set_cwd(cwd)
|
||||
capture.set_env(XEDIT_CURRENT_DOCUMENT_PATH = path,
|
||||
XEDIT_CURRENT_DOCUMENT_DIR = cwd)
|
||||
|
||||
documents_uri = [doc.get_uri()
|
||||
for doc in window.get_documents()
|
||||
if doc.get_uri() is not None]
|
||||
documents_path = [gio.File(uri).get_path()
|
||||
for uri in documents_uri
|
||||
if xedit.utils.uri_has_file_scheme(uri)]
|
||||
capture.set_env(XEDIT_DOCUMENTS_URI = ' '.join(documents_uri),
|
||||
XEDIT_DOCUMENTS_PATH = ' '.join(documents_path))
|
||||
|
||||
flags = capture.CAPTURE_BOTH
|
||||
|
||||
if not node.has_hash_bang():
|
||||
flags |= capture.CAPTURE_NEEDS_SHELL
|
||||
|
||||
capture.set_flags(flags)
|
||||
|
||||
# Get input text
|
||||
input_type = node.input
|
||||
output_type = node.output
|
||||
|
||||
# Get the panel
|
||||
panel = window.get_data("ExternalToolsPluginWindowData")._output_buffer
|
||||
panel.clear()
|
||||
|
||||
if output_type == 'output-panel':
|
||||
panel.show()
|
||||
|
||||
# Assign the error output to the output panel
|
||||
panel.set_process(capture)
|
||||
|
||||
if input_type != 'nothing' and view is not None:
|
||||
if input_type == 'document':
|
||||
start, end = document.get_bounds()
|
||||
elif input_type == 'selection' or input_type == 'selection-document':
|
||||
try:
|
||||
start, end = document.get_selection_bounds()
|
||||
|
||||
print start, end
|
||||
except ValueError:
|
||||
if input_type == 'selection-document':
|
||||
start, end = document.get_bounds()
|
||||
|
||||
if output_type == 'replace-selection':
|
||||
document.select_range(start, end)
|
||||
else:
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
|
||||
elif input_type == 'line':
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
if not start.starts_line():
|
||||
start.set_line_offset(0)
|
||||
if not end.ends_line():
|
||||
end.forward_to_line_end()
|
||||
elif input_type == 'word':
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
if not start.inside_word():
|
||||
panel.write(_('You must be inside a word to run this command'),
|
||||
panel.command_tag)
|
||||
return
|
||||
if not start.starts_word():
|
||||
start.backward_word_start()
|
||||
if not end.ends_word():
|
||||
end.forward_word_end()
|
||||
|
||||
input_text = document.get_text(start, end)
|
||||
capture.set_input(input_text)
|
||||
|
||||
# Assign the standard output to the chosen "file"
|
||||
if output_type == 'new-document':
|
||||
tab = window.create_tab(True)
|
||||
view = tab.get_view()
|
||||
document = tab.get_document()
|
||||
pos = document.get_start_iter()
|
||||
capture.connect('stdout-line', capture_stdout_line_document, document, pos)
|
||||
document.begin_user_action()
|
||||
view.set_editable(False)
|
||||
view.set_cursor_visible(False)
|
||||
elif output_type != 'output-panel' and output_type != 'nothing' and view is not None:
|
||||
document.begin_user_action()
|
||||
view.set_editable(False)
|
||||
view.set_cursor_visible(False)
|
||||
|
||||
if output_type == 'insert':
|
||||
pos = document.get_iter_at_mark(document.get_mark('insert'))
|
||||
elif output_type == 'replace-selection':
|
||||
document.delete_selection(False, False)
|
||||
pos = document.get_iter_at_mark(document.get_mark('insert'))
|
||||
elif output_type == 'replace-document':
|
||||
document.set_text('')
|
||||
pos = document.get_end_iter()
|
||||
else:
|
||||
pos = document.get_end_iter()
|
||||
capture.connect('stdout-line', capture_stdout_line_document, document, pos)
|
||||
elif output_type != 'nothing':
|
||||
capture.connect('stdout-line', capture_stdout_line_panel, panel)
|
||||
document.begin_user_action()
|
||||
|
||||
capture.connect('stderr-line', capture_stderr_line_panel, panel)
|
||||
capture.connect('begin-execute', capture_begin_execute_panel, panel, view, node.name)
|
||||
capture.connect('end-execute', capture_end_execute_panel, panel, view, output_type)
|
||||
|
||||
# Run the command
|
||||
capture.execute()
|
||||
|
||||
if output_type != 'nothing':
|
||||
document.end_user_action()
|
||||
|
||||
class MultipleDocumentsSaver:
|
||||
def __init__(self, window, docs, node):
|
||||
self._window = window
|
||||
self._node = node
|
||||
self._error = False
|
||||
|
||||
self._counter = len(docs)
|
||||
self._signal_ids = {}
|
||||
self._counter = 0
|
||||
|
||||
signals = {}
|
||||
|
||||
for doc in docs:
|
||||
signals[doc] = doc.connect('saving', self.on_document_saving)
|
||||
xedit.commands.save_document(window, doc)
|
||||
doc.disconnect(signals[doc])
|
||||
|
||||
def on_document_saving(self, doc, size, total_size):
|
||||
self._counter += 1
|
||||
self._signal_ids[doc] = doc.connect('saved', self.on_document_saved)
|
||||
|
||||
def on_document_saved(self, doc, error):
|
||||
if error:
|
||||
self._error = True
|
||||
|
||||
doc.disconnect(self._signal_ids[doc])
|
||||
del self._signal_ids[doc]
|
||||
|
||||
self._counter -= 1
|
||||
|
||||
if self._counter == 0 and not self._error:
|
||||
run_external_tool(self._window, self._node)
|
||||
|
||||
def capture_menu_action(action, window, node):
|
||||
if node.save_files == 'document' and window.get_active_document():
|
||||
MultipleDocumentsSaver(window, [window.get_active_document()], node)
|
||||
return
|
||||
elif node.save_files == 'all':
|
||||
MultipleDocumentsSaver(window, window.get_documents(), node)
|
||||
return
|
||||
|
||||
run_external_tool(window, node)
|
||||
|
||||
def capture_stderr_line_panel(capture, line, panel):
|
||||
if not panel.visible():
|
||||
panel.show()
|
||||
|
||||
panel.write(line, panel.error_tag)
|
||||
|
||||
def capture_begin_execute_panel(capture, panel, view, label):
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gdk.Cursor(gdk.WATCH))
|
||||
|
||||
panel['stop'].set_sensitive(True)
|
||||
panel.clear()
|
||||
panel.write(_("Running tool:"), panel.italic_tag);
|
||||
panel.write(" %s\n\n" % label, panel.bold_tag);
|
||||
|
||||
def capture_end_execute_panel(capture, exit_code, panel, view, output_type):
|
||||
panel['stop'].set_sensitive(False)
|
||||
|
||||
if output_type in ('new-document','replace-document'):
|
||||
doc = view.get_buffer()
|
||||
start = doc.get_start_iter()
|
||||
end = start.copy()
|
||||
end.forward_chars(300)
|
||||
|
||||
mtype = gio.content_type_guess(data=doc.get_text(start, end))
|
||||
lmanager = xedit.get_language_manager()
|
||||
|
||||
language = lmanager.guess_language(doc.get_uri(), mtype)
|
||||
|
||||
if language is not None:
|
||||
doc.set_language(language)
|
||||
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gdk.Cursor(gdk.XTERM))
|
||||
view.set_cursor_visible(True)
|
||||
view.set_editable(True)
|
||||
|
||||
if exit_code == 0:
|
||||
panel.write("\n" + _("Done.") + "\n", panel.italic_tag)
|
||||
else:
|
||||
panel.write("\n" + _("Exited") + ":", panel.italic_tag)
|
||||
panel.write(" %d\n" % exit_code, panel.bold_tag)
|
||||
|
||||
def capture_stdout_line_panel(capture, line, panel):
|
||||
panel.write(line)
|
||||
|
||||
def capture_stdout_line_document(capture, line, document, pos):
|
||||
document.insert(pos, line)
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,493 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2006 Steve Frécinaux <code@istique.net>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import re
|
||||
import locale
|
||||
import platform
|
||||
|
||||
class Singleton(object):
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls._instance:
|
||||
cls._instance = super(Singleton, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
cls._instance.__init_once__()
|
||||
|
||||
return cls._instance
|
||||
|
||||
class ToolLibrary(Singleton):
|
||||
def __init_once__(self):
|
||||
self.locations = []
|
||||
|
||||
def set_locations(self, datadir):
|
||||
self.locations = []
|
||||
|
||||
if platform.platform() != 'Windows':
|
||||
for d in self.get_xdg_data_dirs():
|
||||
self.locations.append(os.path.join(d, 'xedit', 'plugins', 'externaltools', 'tools'))
|
||||
|
||||
self.locations.append(datadir)
|
||||
|
||||
# self.locations[0] is where we save the custom scripts
|
||||
if platform.platform() == 'Windows':
|
||||
toolsdir = os.path.expanduser('~/xedit/tools')
|
||||
else:
|
||||
userdir = os.getenv('MATE22_USER_DIR')
|
||||
if userdir:
|
||||
toolsdir = os.path.join(userdir, 'xedit/tools')
|
||||
else:
|
||||
toolsdir = os.path.expanduser('~/.config/xedit/tools')
|
||||
|
||||
self.locations.insert(0, toolsdir);
|
||||
|
||||
if not os.path.isdir(self.locations[0]):
|
||||
os.makedirs(self.locations[0])
|
||||
self.tree = ToolDirectory(self, '')
|
||||
self.import_old_xml_store()
|
||||
else:
|
||||
self.tree = ToolDirectory(self, '')
|
||||
|
||||
# cf. http://standards.freedesktop.org/basedir-spec/latest/
|
||||
def get_xdg_data_dirs(self):
|
||||
dirs = os.getenv('XDG_DATA_DIRS')
|
||||
if dirs:
|
||||
dirs = dirs.split(os.pathsep)
|
||||
else:
|
||||
dirs = ('/usr/local/share', '/usr/share')
|
||||
return dirs
|
||||
|
||||
# This function is meant to be ran only once, when the tools directory is
|
||||
# created. It imports eventual tools that have been saved in the old XML
|
||||
# storage file.
|
||||
def import_old_xml_store(self):
|
||||
import xml.etree.ElementTree as et
|
||||
userdir = os.getenv('MATE22_USER_DIR')
|
||||
if userdir:
|
||||
filename = os.path.join(userdir, 'xedit/xedit-tools.xml')
|
||||
else:
|
||||
filename = os.path.expanduser('~/.config/xedit/xedit-tools.xml')
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return
|
||||
|
||||
print "External tools: importing old tools into the new store..."
|
||||
|
||||
xtree = et.parse(filename)
|
||||
xroot = xtree.getroot()
|
||||
|
||||
for xtool in xroot:
|
||||
for i in self.tree.tools:
|
||||
if i.name == xtool.get('label'):
|
||||
tool = i
|
||||
break
|
||||
else:
|
||||
tool = Tool(self.tree)
|
||||
tool.name = xtool.get('label')
|
||||
tool.autoset_filename()
|
||||
self.tree.tools.append(tool)
|
||||
tool.comment = xtool.get('description')
|
||||
tool.shortcut = xtool.get('accelerator')
|
||||
tool.applicability = xtool.get('applicability')
|
||||
tool.output = xtool.get('output')
|
||||
tool.input = xtool.get('input')
|
||||
|
||||
tool.save_with_script(xtool.text)
|
||||
|
||||
def get_full_path(self, path, mode='r', system = True, local = True):
|
||||
assert (system or local)
|
||||
if path is None:
|
||||
return None
|
||||
if mode == 'r':
|
||||
if system and local:
|
||||
locations = self.locations
|
||||
elif local and not system:
|
||||
locations = [self.locations[0]]
|
||||
elif system and not local:
|
||||
locations = self.locations[1:]
|
||||
else:
|
||||
raise ValueError("system and local can't be both set to False")
|
||||
|
||||
for i in locations:
|
||||
p = os.path.join(i, path)
|
||||
if os.path.lexists(p):
|
||||
return p
|
||||
return None
|
||||
else:
|
||||
path = os.path.join(self.locations[0], path)
|
||||
dirname = os.path.dirname(path)
|
||||
if not os.path.isdir(dirname):
|
||||
os.mkdir(dirname)
|
||||
return path
|
||||
|
||||
class ToolDirectory(object):
|
||||
def __init__(self, parent, dirname):
|
||||
super(ToolDirectory, self).__init__()
|
||||
self.subdirs = list()
|
||||
self.tools = list()
|
||||
if isinstance(parent, ToolDirectory):
|
||||
self.parent = parent
|
||||
self.library = parent.library
|
||||
else:
|
||||
self.parent = None
|
||||
self.library = parent
|
||||
self.dirname = dirname
|
||||
self._load()
|
||||
|
||||
def listdir(self):
|
||||
elements = dict()
|
||||
for l in self.library.locations:
|
||||
d = os.path.join(l, self.dirname)
|
||||
if not os.path.isdir(d):
|
||||
continue
|
||||
for i in os.listdir(d):
|
||||
elements[i] = None
|
||||
keys = elements.keys()
|
||||
keys.sort()
|
||||
return keys
|
||||
|
||||
def _load(self):
|
||||
for p in self.listdir():
|
||||
path = os.path.join(self.dirname, p)
|
||||
full_path = self.library.get_full_path(path)
|
||||
if os.path.isdir(full_path):
|
||||
self.subdirs.append(ToolDirectory(self, p))
|
||||
elif os.path.isfile(full_path) and os.access(full_path, os.X_OK):
|
||||
self.tools.append(Tool(self, p))
|
||||
|
||||
def get_path(self):
|
||||
if self.parent is None:
|
||||
return self.dirname
|
||||
else:
|
||||
return os.path.join(self.parent.get_path(), self.dirname)
|
||||
path = property(get_path)
|
||||
|
||||
def get_name(self):
|
||||
return os.path.basename(self.dirname)
|
||||
name = property(get_name)
|
||||
|
||||
def delete_tool(self, tool):
|
||||
# Only remove it if it lays in $HOME
|
||||
if tool in self.tools:
|
||||
path = tool.get_path()
|
||||
if path is not None:
|
||||
filename = os.path.join(self.library.locations[0], path)
|
||||
if os.path.isfile(filename):
|
||||
os.unlink(filename)
|
||||
self.tools.remove(tool)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def revert_tool(self, tool):
|
||||
# Only remove it if it lays in $HOME
|
||||
filename = os.path.join(self.library.locations[0], tool.get_path())
|
||||
if tool in self.tools and os.path.isfile(filename):
|
||||
os.unlink(filename)
|
||||
tool._load()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class Tool(object):
|
||||
RE_KEY = re.compile('^([a-zA-Z_][a-zA-Z0-9_.\-]*)(\[([a-zA-Z_@]+)\])?$')
|
||||
|
||||
def __init__(self, parent, filename = None):
|
||||
super(Tool, self).__init__()
|
||||
self.parent = parent
|
||||
self.library = parent.library
|
||||
self.filename = filename
|
||||
self.changed = False
|
||||
self._properties = dict()
|
||||
self._transform = {
|
||||
'Languages': [self._to_list, self._from_list]
|
||||
}
|
||||
self._load()
|
||||
|
||||
def _to_list(self, value):
|
||||
if value.strip() == '':
|
||||
return []
|
||||
else:
|
||||
return map(lambda x: x.strip(), value.split(','))
|
||||
|
||||
def _from_list(self, value):
|
||||
return ','.join(value)
|
||||
|
||||
def _parse_value(self, key, value):
|
||||
if key in self._transform:
|
||||
return self._transform[key][0](value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def _load(self):
|
||||
if self.filename is None:
|
||||
return
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return
|
||||
|
||||
fp = file(filename, 'r', 1)
|
||||
in_block = False
|
||||
lang = locale.getlocale(locale.LC_MESSAGES)[0]
|
||||
|
||||
for line in fp:
|
||||
if not in_block:
|
||||
in_block = line.startswith('# [Xedit Tool]')
|
||||
continue
|
||||
if line.startswith('##') or line.startswith('# #'): continue
|
||||
if not line.startswith('# '): break
|
||||
|
||||
try:
|
||||
(key, value) = [i.strip() for i in line[2:].split('=', 1)]
|
||||
m = self.RE_KEY.match(key)
|
||||
if m.group(3) is None:
|
||||
self._properties[m.group(1)] = self._parse_value(m.group(1), value)
|
||||
elif lang is not None and lang.startswith(m.group(3)):
|
||||
self._properties[m.group(1)] = self._parse_value(m.group(1), value)
|
||||
except ValueError:
|
||||
break
|
||||
fp.close()
|
||||
self.changed = False
|
||||
|
||||
def _set_property_if_changed(self, key, value):
|
||||
if value != self._properties.get(key):
|
||||
self._properties[key] = value
|
||||
|
||||
self.changed = True
|
||||
|
||||
def is_global(self):
|
||||
return self.library.get_full_path(self.get_path(), local=False) is not None
|
||||
|
||||
def is_local(self):
|
||||
return self.library.get_full_path(self.get_path(), system=False) is not None
|
||||
|
||||
def is_global(self):
|
||||
return self.library.get_full_path(self.get_path(), local=False) is not None
|
||||
|
||||
def get_path(self):
|
||||
if self.filename is not None:
|
||||
return os.path.join(self.parent.get_path(), self.filename)
|
||||
else:
|
||||
return None
|
||||
path = property(get_path)
|
||||
|
||||
# This command is the one that is meant to be ran
|
||||
# (later, could have an Exec key or something)
|
||||
def get_command(self):
|
||||
return self.library.get_full_path(self.get_path())
|
||||
command = property(get_command)
|
||||
|
||||
def get_applicability(self):
|
||||
applicability = self._properties.get('Applicability')
|
||||
if applicability: return applicability
|
||||
return 'all'
|
||||
def set_applicability(self, value):
|
||||
self._set_property_if_changed('Applicability', value)
|
||||
applicability = property(get_applicability, set_applicability)
|
||||
|
||||
def get_name(self):
|
||||
name = self._properties.get('Name')
|
||||
if name: return name
|
||||
return os.path.basename(self.filename)
|
||||
def set_name(self, value):
|
||||
self._set_property_if_changed('Name', value)
|
||||
name = property(get_name, set_name)
|
||||
|
||||
def get_shortcut(self):
|
||||
shortcut = self._properties.get('Shortcut')
|
||||
if shortcut: return shortcut
|
||||
return None
|
||||
def set_shortcut(self, value):
|
||||
self._set_property_if_changed('Shortcut', value)
|
||||
shortcut = property(get_shortcut, set_shortcut)
|
||||
|
||||
def get_comment(self):
|
||||
comment = self._properties.get('Comment')
|
||||
if comment: return comment
|
||||
return self.filename
|
||||
def set_comment(self, value):
|
||||
self._set_property_if_changed('Comment', value)
|
||||
comment = property(get_comment, set_comment)
|
||||
|
||||
def get_input(self):
|
||||
input = self._properties.get('Input')
|
||||
if input: return input
|
||||
return 'nothing'
|
||||
def set_input(self, value):
|
||||
self._set_property_if_changed('Input', value)
|
||||
input = property(get_input, set_input)
|
||||
|
||||
def get_output(self):
|
||||
output = self._properties.get('Output')
|
||||
if output: return output
|
||||
return 'output-panel'
|
||||
def set_output(self, value):
|
||||
self._set_property_if_changed('Output', value)
|
||||
output = property(get_output, set_output)
|
||||
|
||||
def get_save_files(self):
|
||||
save_files = self._properties.get('Save-files')
|
||||
if save_files: return save_files
|
||||
return 'nothing'
|
||||
def set_save_files(self, value):
|
||||
self._set_property_if_changed('Save-files', value)
|
||||
save_files = property(get_save_files, set_save_files)
|
||||
|
||||
def get_languages(self):
|
||||
languages = self._properties.get('Languages')
|
||||
if languages: return languages
|
||||
return []
|
||||
def set_languages(self, value):
|
||||
self._set_property_if_changed('Languages', value)
|
||||
languages = property(get_languages, set_languages)
|
||||
|
||||
def has_hash_bang(self):
|
||||
if self.filename is None:
|
||||
return True
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return True
|
||||
|
||||
fp = open(filename, 'r', 1)
|
||||
for line in fp:
|
||||
if line.strip() == '':
|
||||
continue
|
||||
|
||||
return line.startswith('#!')
|
||||
|
||||
# There is no property for this one because this function is quite
|
||||
# expensive to perform
|
||||
def get_script(self):
|
||||
if self.filename is None:
|
||||
return ["#!/bin/sh\n"]
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return ["#!/bin/sh\n"]
|
||||
|
||||
fp = open(filename, 'r', 1)
|
||||
lines = list()
|
||||
|
||||
# before entering the data block
|
||||
for line in fp:
|
||||
if line.startswith('# [Xedit Tool]'):
|
||||
break
|
||||
lines.append(line)
|
||||
# in the block:
|
||||
for line in fp:
|
||||
if line.startswith('##'): continue
|
||||
if not (line.startswith('# ') and '=' in line):
|
||||
# after the block: strip one emtpy line (if present)
|
||||
if line.strip() != '':
|
||||
lines.append(line)
|
||||
break
|
||||
# after the block
|
||||
for line in fp:
|
||||
lines.append(line)
|
||||
fp.close()
|
||||
return lines
|
||||
|
||||
def _dump_properties(self):
|
||||
lines = ['# [Xedit Tool]']
|
||||
for item in self._properties.iteritems():
|
||||
if item[0] in self._transform:
|
||||
lines.append('# %s=%s' % (item[0], self._transform[item[0]][1](item[1])))
|
||||
elif item[1] is not None:
|
||||
lines.append('# %s=%s' % item)
|
||||
return '\n'.join(lines) + '\n'
|
||||
|
||||
def save_with_script(self, script):
|
||||
filename = self.library.get_full_path(self.filename, 'w')
|
||||
|
||||
fp = open(filename, 'w', 1)
|
||||
|
||||
# Make sure to first print header (shebang, modeline), then
|
||||
# properties, and then actual content
|
||||
header = []
|
||||
content = []
|
||||
inheader = True
|
||||
|
||||
# Parse
|
||||
for line in script:
|
||||
line = line.rstrip("\n")
|
||||
|
||||
if not inheader:
|
||||
content.append(line)
|
||||
elif line.startswith('#!'):
|
||||
# Shebang (should be always present)
|
||||
header.append(line)
|
||||
elif line.strip().startswith('#') and ('-*-' in line or 'ex:' in line or 'vi:' in line or 'vim:' in line):
|
||||
header.append(line)
|
||||
else:
|
||||
content.append(line)
|
||||
inheader = False
|
||||
|
||||
# Write out header
|
||||
for line in header:
|
||||
fp.write(line + "\n")
|
||||
|
||||
fp.write(self._dump_properties())
|
||||
fp.write("\n")
|
||||
|
||||
for line in content:
|
||||
fp.write(line + "\n")
|
||||
|
||||
fp.close()
|
||||
os.chmod(filename, 0750)
|
||||
self.changed = False
|
||||
|
||||
def save(self):
|
||||
if self.changed:
|
||||
self.save_with_script(self.get_script())
|
||||
|
||||
def autoset_filename(self):
|
||||
if self.filename is not None:
|
||||
return
|
||||
dirname = self.parent.path
|
||||
if dirname != '':
|
||||
dirname += os.path.sep
|
||||
|
||||
basename = self.name.lower().replace(' ', '-').replace('/', '-')
|
||||
|
||||
if self.library.get_full_path(dirname + basename):
|
||||
i = 2
|
||||
while self.library.get_full_path(dirname + "%s-%d" % (basename, i)):
|
||||
i += 1
|
||||
basename = "%s-%d" % (basename, i)
|
||||
self.filename = basename
|
||||
|
||||
if __name__ == '__main__':
|
||||
library = ToolLibrary()
|
||||
|
||||
def print_tool(t, indent):
|
||||
print indent * " " + "%s: %s" % (t.filename, t.name)
|
||||
|
||||
def print_dir(d, indent):
|
||||
print indent * " " + d.dirname + '/'
|
||||
for i in d.subdirs:
|
||||
print_dir(i, indent+1)
|
||||
for i in d.tools:
|
||||
print_tool(i, indent+1)
|
||||
|
||||
print_dir(library.tree, 0)
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,231 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2009-2010 Per Arneng <per.arneng@anyplanet.com>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
|
||||
class Link:
|
||||
"""
|
||||
This class represents a file link from within a string given by the
|
||||
output of some software tool. A link contains a reference to a file, the
|
||||
line number within the file and the boundaries within the given output
|
||||
string that should be marked as a link.
|
||||
"""
|
||||
|
||||
def __init__(self, path, line_nr, start, end):
|
||||
"""
|
||||
path -- the path of the file (that could be extracted)
|
||||
line_nr -- the line nr of the specified file
|
||||
start -- the index within the string that the link starts at
|
||||
end -- the index within the string where the link ends at
|
||||
"""
|
||||
self.path = path
|
||||
self.line_nr = int(line_nr)
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
def __repr__(self):
|
||||
return "%s[%s](%s:%s)" % (self.path, self.line_nr,
|
||||
self.start, self.end)
|
||||
|
||||
class LinkParser:
|
||||
"""
|
||||
Parses a text using different parsing providers with the goal of finding one
|
||||
or more file links within the text. A typical example could be the output
|
||||
from a compiler that specifies an error in a specific file. The path of the
|
||||
file, the line nr and some more info is then returned so that it can be used
|
||||
to be able to navigate from the error output in to the specific file.
|
||||
|
||||
The actual work of parsing the text is done by instances of classes that
|
||||
inherits from AbstractLinkParser or by regular expressions. To add a new
|
||||
parser just create a class that inherits from AbstractLinkParser and then
|
||||
register in this class cunstructor using the method add_parser. If you want
|
||||
to add a regular expression then just call add_regexp in this class
|
||||
constructor and provide your regexp string as argument.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._providers = []
|
||||
self.add_regexp(REGEXP_STANDARD)
|
||||
self.add_regexp(REGEXP_PYTHON)
|
||||
self.add_regexp(REGEXP_VALAC)
|
||||
self.add_regexp(REGEXP_BASH)
|
||||
self.add_regexp(REGEXP_RUBY)
|
||||
self.add_regexp(REGEXP_PERL)
|
||||
self.add_regexp(REGEXP_MCS)
|
||||
|
||||
def add_parser(self, parser):
|
||||
self._providers.append(parser)
|
||||
|
||||
def add_regexp(self, regexp):
|
||||
"""
|
||||
Adds a regular expression string that should match a link using
|
||||
re.MULTILINE and re.VERBOSE regexp. The area marked as a link should
|
||||
be captured by a group named lnk. The path of the link should be
|
||||
captured by a group named pth. The line number should be captured by
|
||||
a group named ln. To read more about this look at the documentation
|
||||
for the RegexpLinkParser constructor.
|
||||
"""
|
||||
self.add_parser(RegexpLinkParser(regexp))
|
||||
|
||||
def parse(self, text):
|
||||
"""
|
||||
Parses the given text and returns a list of links that are parsed from
|
||||
the text. This method delegates to parser providers that can parse
|
||||
output from different kinds of formats. If no links are found then an
|
||||
empty list is returned.
|
||||
|
||||
text -- the text to scan for file links. 'text' can not be None.
|
||||
"""
|
||||
if text is None:
|
||||
raise ValueError("text can not be None")
|
||||
|
||||
links = []
|
||||
|
||||
for provider in self._providers:
|
||||
links.extend(provider.parse(text))
|
||||
|
||||
return links
|
||||
|
||||
class AbstractLinkParser(object):
|
||||
"""The "abstract" base class for link parses"""
|
||||
|
||||
def parse(self, text):
|
||||
"""
|
||||
This method should be implemented by subclasses. It takes a text as
|
||||
argument (never None) and then returns a list of Link objects. If no
|
||||
links are found then an empty list is expected. The Link class is
|
||||
defined in this module. If you do not override this method then a
|
||||
NotImplementedError will be thrown.
|
||||
|
||||
text -- the text to parse. This argument is never None.
|
||||
"""
|
||||
raise NotImplementedError("need to implement a parse method")
|
||||
|
||||
class RegexpLinkParser(AbstractLinkParser):
|
||||
"""
|
||||
A class that represents parsers that only use one single regular expression.
|
||||
It can be used by subclasses or by itself. See the constructor documentation
|
||||
for details about the rules surrouning the regexp.
|
||||
"""
|
||||
|
||||
def __init__(self, regex):
|
||||
"""
|
||||
Creates a new RegexpLinkParser based on the given regular expression.
|
||||
The regular expression is multiline and verbose (se python docs on
|
||||
compilation flags). The regular expression should contain three named
|
||||
capturing groups 'lnk', 'pth' and 'ln'. 'lnk' represents the area wich
|
||||
should be marked as a link in the text. 'pth' is the path that should
|
||||
be looked for and 'ln' is the line number in that file.
|
||||
"""
|
||||
self.re = re.compile(regex, re.MULTILINE | re.VERBOSE)
|
||||
|
||||
def parse(self, text):
|
||||
links = []
|
||||
for m in re.finditer(self.re, text):
|
||||
path = m.group("pth")
|
||||
line_nr = m.group("ln")
|
||||
start = m.start("lnk")
|
||||
end = m.end("lnk")
|
||||
link = Link(path, line_nr, start, end)
|
||||
links.append(link)
|
||||
|
||||
return links
|
||||
|
||||
# gcc 'test.c:13: warning: ...'
|
||||
# javac 'Test.java:13: ...'
|
||||
# ruby 'test.rb:5: ...'
|
||||
# scalac 'Test.scala:5: ...'
|
||||
# 6g (go) 'test.go:9: ...'
|
||||
REGEXP_STANDARD = r"""
|
||||
^
|
||||
(?P<lnk>
|
||||
(?P<pth> .*[a-z0-9] )
|
||||
\:
|
||||
(?P<ln> \d+)
|
||||
)
|
||||
\:\s"""
|
||||
|
||||
# python ' File "test.py", line 13'
|
||||
REGEXP_PYTHON = r"""
|
||||
^\s\sFile\s
|
||||
(?P<lnk>
|
||||
\"
|
||||
(?P<pth> [^\"]+ )
|
||||
\",\sline\s
|
||||
(?P<ln> \d+ )
|
||||
),"""
|
||||
|
||||
# python 'test.sh: line 5:'
|
||||
REGEXP_BASH = r"""
|
||||
^(?P<lnk>
|
||||
(?P<pth> .* )
|
||||
\:\sline\s
|
||||
(?P<ln> \d+ )
|
||||
)\:"""
|
||||
|
||||
# valac 'Test.vala:13.1-13.3: ...'
|
||||
REGEXP_VALAC = r"""
|
||||
^(?P<lnk>
|
||||
(?P<pth>
|
||||
.*vala
|
||||
)
|
||||
\:
|
||||
(?P<ln>
|
||||
\d+
|
||||
)
|
||||
\.\d+-\d+\.\d+
|
||||
)\: """
|
||||
|
||||
#ruby
|
||||
#test.rb:5: ...
|
||||
# from test.rb:3:in `each'
|
||||
# fist line parsed by REGEXP_STANDARD
|
||||
REGEXP_RUBY = r"""
|
||||
^\s+from\s
|
||||
(?P<lnk>
|
||||
(?P<pth>
|
||||
.*
|
||||
)
|
||||
\:
|
||||
(?P<ln>
|
||||
\d+
|
||||
)
|
||||
)"""
|
||||
|
||||
# perl 'syntax error at test.pl line 88, near "$fake_var'
|
||||
REGEXP_PERL = r"""
|
||||
\sat\s
|
||||
(?P<lnk>
|
||||
(?P<pth> .* )
|
||||
\sline\s
|
||||
(?P<ln> \d+ )
|
||||
)"""
|
||||
|
||||
# mcs (C#) 'Test.cs(12,7): error CS0103: The name `fakeMethod'
|
||||
REGEXP_MCS = r"""
|
||||
^
|
||||
(?P<lnk>
|
||||
(?P<pth> .*\.[cC][sS] )
|
||||
\(
|
||||
(?P<ln> \d+ )
|
||||
,\d+\)
|
||||
)
|
||||
\:\s
|
||||
"""
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,948 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('Manager', )
|
||||
|
||||
import xedit
|
||||
import gtk
|
||||
import gtksourceview2 as gsv
|
||||
import os.path
|
||||
from library import *
|
||||
from functions import *
|
||||
import hashlib
|
||||
from xml.sax import saxutils
|
||||
import gobject
|
||||
|
||||
class LanguagesPopup(gtk.Window):
|
||||
COLUMN_NAME = 0
|
||||
COLUMN_ID = 1
|
||||
COLUMN_ENABLED = 2
|
||||
|
||||
def __init__(self, languages):
|
||||
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
|
||||
|
||||
self.set_default_size(200, 200)
|
||||
self.props.can_focus = True
|
||||
|
||||
self.build()
|
||||
self.init_languages(languages)
|
||||
|
||||
self.show()
|
||||
self.map()
|
||||
|
||||
self.grab_add()
|
||||
|
||||
gtk.gdk.keyboard_grab(self.window, False, 0L)
|
||||
gtk.gdk.pointer_grab(self.window, False, gtk.gdk.BUTTON_PRESS_MASK |
|
||||
gtk.gdk.BUTTON_RELEASE_MASK |
|
||||
gtk.gdk.POINTER_MOTION_MASK |
|
||||
gtk.gdk.ENTER_NOTIFY_MASK |
|
||||
gtk.gdk.LEAVE_NOTIFY_MASK |
|
||||
gtk.gdk.PROXIMITY_IN_MASK |
|
||||
gtk.gdk.PROXIMITY_OUT_MASK, None, None, 0L)
|
||||
|
||||
self.view.get_selection().select_path((0,))
|
||||
|
||||
def build(self):
|
||||
self.model = gtk.ListStore(str, str, bool)
|
||||
|
||||
self.sw = gtk.ScrolledWindow()
|
||||
self.sw.show()
|
||||
|
||||
self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
self.sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
|
||||
self.view = gtk.TreeView(self.model)
|
||||
self.view.show()
|
||||
|
||||
self.view.set_headers_visible(False)
|
||||
|
||||
column = gtk.TreeViewColumn()
|
||||
|
||||
renderer = gtk.CellRendererToggle()
|
||||
column.pack_start(renderer, False)
|
||||
column.set_attributes(renderer, active=self.COLUMN_ENABLED)
|
||||
|
||||
renderer.connect('toggled', self.on_language_toggled)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, text=self.COLUMN_NAME)
|
||||
|
||||
self.view.append_column(column)
|
||||
self.view.set_row_separator_func(self.on_separator)
|
||||
|
||||
self.sw.add(self.view)
|
||||
|
||||
self.add(self.sw)
|
||||
|
||||
def enabled_languages(self, model, path, piter, ret):
|
||||
enabled = model.get_value(piter, self.COLUMN_ENABLED)
|
||||
|
||||
if path == (0,) and enabled:
|
||||
return True
|
||||
|
||||
if enabled:
|
||||
ret.append(model.get_value(piter, self.COLUMN_ID))
|
||||
|
||||
return False
|
||||
|
||||
def languages(self):
|
||||
ret = []
|
||||
|
||||
self.model.foreach(self.enabled_languages, ret)
|
||||
return ret
|
||||
|
||||
def on_separator(self, model, piter):
|
||||
val = model.get_value(piter, self.COLUMN_NAME)
|
||||
return val == '-'
|
||||
|
||||
def init_languages(self, languages):
|
||||
manager = gsv.LanguageManager()
|
||||
langs = xedit.language_manager_list_languages_sorted(manager, True)
|
||||
|
||||
self.model.append([_('All languages'), None, not languages])
|
||||
self.model.append(['-', None, False])
|
||||
self.model.append([_('Plain Text'), 'plain', 'plain' in languages])
|
||||
self.model.append(['-', None, False])
|
||||
|
||||
for lang in langs:
|
||||
self.model.append([lang.get_name(), lang.get_id(), lang.get_id() in languages])
|
||||
|
||||
def correct_all(self, model, path, piter, enabled):
|
||||
if path == (0,):
|
||||
return False
|
||||
|
||||
model.set_value(piter, self.COLUMN_ENABLED, enabled)
|
||||
|
||||
def on_language_toggled(self, renderer, path):
|
||||
piter = self.model.get_iter(path)
|
||||
|
||||
enabled = self.model.get_value(piter, self.COLUMN_ENABLED)
|
||||
self.model.set_value(piter, self.COLUMN_ENABLED, not enabled)
|
||||
|
||||
if path == '0':
|
||||
self.model.foreach(self.correct_all, False)
|
||||
else:
|
||||
self.model.set_value(self.model.get_iter_first(), self.COLUMN_ENABLED, False)
|
||||
|
||||
def do_key_press_event(self, event):
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
self.destroy()
|
||||
return True
|
||||
else:
|
||||
event.window = self.view.get_bin_window()
|
||||
return self.view.event(event)
|
||||
|
||||
def do_key_release_event(self, event):
|
||||
event.window = self.view.get_bin_window()
|
||||
return self.view.event(event)
|
||||
|
||||
def in_window(self, event, window=None):
|
||||
if not window:
|
||||
window = self.window
|
||||
|
||||
geometry = window.get_geometry()
|
||||
origin = window.get_origin()
|
||||
|
||||
return event.x_root >= origin[0] and \
|
||||
event.x_root <= origin[0] + geometry[2] and \
|
||||
event.y_root >= origin[1] and \
|
||||
event.y_root <= origin[1] + geometry[3]
|
||||
|
||||
def do_destroy(self):
|
||||
gtk.gdk.keyboard_ungrab(0L)
|
||||
gtk.gdk.pointer_ungrab(0L)
|
||||
|
||||
return gtk.Window.do_destroy(self)
|
||||
|
||||
def setup_event(self, event, window):
|
||||
fr = event.window.get_origin()
|
||||
to = window.get_origin()
|
||||
|
||||
event.window = window
|
||||
event.x += fr[0] - to[0]
|
||||
event.y += fr[1] - to[1]
|
||||
|
||||
def resolve_widgets(self, root):
|
||||
res = [root]
|
||||
|
||||
if isinstance(root, gtk.Container):
|
||||
root.forall(lambda x, y: res.extend(self.resolve_widgets(x)), None)
|
||||
|
||||
return res
|
||||
|
||||
def resolve_windows(self, window):
|
||||
if not window:
|
||||
return []
|
||||
|
||||
res = [window]
|
||||
res.extend(window.get_children())
|
||||
|
||||
return res
|
||||
|
||||
def propagate_mouse_event(self, event):
|
||||
allwidgets = self.resolve_widgets(self.get_child())
|
||||
allwidgets.reverse()
|
||||
|
||||
orig = [event.x, event.y]
|
||||
|
||||
for widget in allwidgets:
|
||||
windows = self.resolve_windows(widget.window)
|
||||
windows.reverse()
|
||||
|
||||
for window in windows:
|
||||
if not (window.get_events() & event.type):
|
||||
continue
|
||||
|
||||
if self.in_window(event, window):
|
||||
self.setup_event(event, window)
|
||||
|
||||
if widget.event(event):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def do_button_press_event(self, event):
|
||||
if not self.in_window(event):
|
||||
self.destroy()
|
||||
else:
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_button_release_event(self, event):
|
||||
if not self.in_window(event):
|
||||
self.destroy()
|
||||
else:
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_scroll_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_motion_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_enter_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_leave_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_proximity_in_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_proximity_out_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
gobject.type_register(LanguagesPopup)
|
||||
|
||||
class Manager:
|
||||
TOOL_COLUMN = 0 # For Tree
|
||||
NAME_COLUMN = 1 # For Combo
|
||||
|
||||
def __init__(self, datadir):
|
||||
self.datadir = datadir
|
||||
self.dialog = None
|
||||
self._languages = {}
|
||||
self._tool_rows = {}
|
||||
|
||||
self.build()
|
||||
|
||||
def build(self):
|
||||
callbacks = {
|
||||
'on_new_tool_button_clicked' : self.on_new_tool_button_clicked,
|
||||
'on_remove_tool_button_clicked' : self.on_remove_tool_button_clicked,
|
||||
'on_tool_manager_dialog_response' : self.on_tool_manager_dialog_response,
|
||||
'on_tool_manager_dialog_focus_out': self.on_tool_manager_dialog_focus_out,
|
||||
'on_accelerator_key_press' : self.on_accelerator_key_press,
|
||||
'on_accelerator_focus_in' : self.on_accelerator_focus_in,
|
||||
'on_accelerator_focus_out' : self.on_accelerator_focus_out,
|
||||
'on_languages_button_clicked' : self.on_languages_button_clicked
|
||||
}
|
||||
|
||||
# Load the "main-window" widget from the ui file.
|
||||
self.ui = gtk.Builder()
|
||||
self.ui.add_from_file(os.path.join(self.datadir, 'ui', 'tools.ui'))
|
||||
self.ui.connect_signals(callbacks)
|
||||
self.dialog = self.ui.get_object('tool-manager-dialog')
|
||||
|
||||
self.view = self.ui.get_object('view')
|
||||
|
||||
self.__init_tools_model()
|
||||
self.__init_tools_view()
|
||||
|
||||
for name in ['input', 'output', 'applicability', 'save-files']:
|
||||
self.__init_combobox(name)
|
||||
|
||||
self.do_update()
|
||||
|
||||
def expand_from_doc(self, doc):
|
||||
row = None
|
||||
|
||||
if doc:
|
||||
if doc.get_language():
|
||||
lid = doc.get_language().get_id()
|
||||
|
||||
if lid in self._languages:
|
||||
row = self._languages[lid]
|
||||
elif 'plain' in self._languages:
|
||||
row = self._languages['plain']
|
||||
|
||||
if not row and None in self._languages:
|
||||
row = self._languages[None]
|
||||
|
||||
if not row:
|
||||
return
|
||||
|
||||
self.view.expand_row(row.get_path(), False)
|
||||
self.view.get_selection().select_path(row.get_path())
|
||||
|
||||
def run(self, window):
|
||||
if self.dialog == None:
|
||||
self.build()
|
||||
|
||||
# Open up language
|
||||
self.expand_from_doc(window.get_active_document())
|
||||
|
||||
self.dialog.set_transient_for(window)
|
||||
window.get_group().add_window(self.dialog)
|
||||
self.dialog.present()
|
||||
|
||||
def add_accelerator(self, item):
|
||||
if not item.shortcut:
|
||||
return
|
||||
|
||||
if item.shortcut in self.accelerators:
|
||||
if not item in self.accelerators[item.shortcut]:
|
||||
self.accelerators[item.shortcut].append(item)
|
||||
else:
|
||||
self.accelerators[item.shortcut] = [item]
|
||||
|
||||
def remove_accelerator(self, item, shortcut=None):
|
||||
if not shortcut:
|
||||
shortcut = item.shortcut
|
||||
|
||||
if not shortcut in self.accelerators:
|
||||
return
|
||||
|
||||
self.accelerators[shortcut].remove(item)
|
||||
|
||||
if not self.accelerators[shortcut]:
|
||||
del self.accelerators[shortcut]
|
||||
|
||||
def add_tool_to_language(self, tool, language):
|
||||
if isinstance(language, gsv.Language):
|
||||
lid = language.get_id()
|
||||
else:
|
||||
lid = language
|
||||
|
||||
if not lid in self._languages:
|
||||
piter = self.model.append(None, [language])
|
||||
|
||||
parent = gtk.TreeRowReference(self.model, self.model.get_path(piter))
|
||||
self._languages[lid] = parent
|
||||
else:
|
||||
parent = self._languages[lid]
|
||||
|
||||
piter = self.model.get_iter(parent.get_path())
|
||||
child = self.model.append(piter, [tool])
|
||||
|
||||
if not tool in self._tool_rows:
|
||||
self._tool_rows[tool] = []
|
||||
|
||||
self._tool_rows[tool].append(gtk.TreeRowReference(self.model, self.model.get_path(child)))
|
||||
return child
|
||||
|
||||
def add_tool(self, tool):
|
||||
manager = gsv.LanguageManager()
|
||||
ret = None
|
||||
|
||||
for lang in tool.languages:
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if l:
|
||||
ret = self.add_tool_to_language(tool, l)
|
||||
elif lang == 'plain':
|
||||
ret = self.add_tool_to_language(tool, 'plain')
|
||||
|
||||
if not ret:
|
||||
ret = self.add_tool_to_language(tool, None)
|
||||
|
||||
self.add_accelerator(tool)
|
||||
return ret
|
||||
|
||||
def __init_tools_model(self):
|
||||
self.tools = ToolLibrary()
|
||||
self.current_node = None
|
||||
self.script_hash = None
|
||||
self.accelerators = dict()
|
||||
|
||||
self.model = gtk.TreeStore(object)
|
||||
self.view.set_model(self.model)
|
||||
|
||||
for tool in self.tools.tree.tools:
|
||||
self.add_tool(tool)
|
||||
|
||||
self.model.set_default_sort_func(self.sort_tools)
|
||||
self.model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
|
||||
|
||||
def sort_tools(self, model, iter1, iter2):
|
||||
# For languages, sort All before everything else, otherwise alphabetical
|
||||
t1 = model.get_value(iter1, self.TOOL_COLUMN)
|
||||
t2 = model.get_value(iter2, self.TOOL_COLUMN)
|
||||
|
||||
if model.iter_parent(iter1) == None:
|
||||
if t1 == None:
|
||||
return -1
|
||||
|
||||
if t2 == None:
|
||||
return 1
|
||||
|
||||
def lang_name(lang):
|
||||
if isinstance(lang, gsv.Language):
|
||||
return lang.get_name()
|
||||
else:
|
||||
return _('Plain Text')
|
||||
|
||||
n1 = lang_name(t1)
|
||||
n2 = lang_name(t2)
|
||||
else:
|
||||
n1 = t1.name
|
||||
n2 = t2.name
|
||||
|
||||
return cmp(n1.lower(), n2.lower())
|
||||
|
||||
def __init_tools_view(self):
|
||||
# Tools column
|
||||
column = gtk.TreeViewColumn('Tools')
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, False)
|
||||
renderer.set_property('editable', True)
|
||||
self.view.append_column(column)
|
||||
|
||||
column.set_cell_data_func(renderer, self.get_cell_data_cb)
|
||||
|
||||
renderer.connect('edited', self.on_view_label_cell_edited)
|
||||
renderer.connect('editing-started', self.on_view_label_cell_editing_started)
|
||||
|
||||
self.selection_changed_id = self.view.get_selection().connect('changed', self.on_view_selection_changed, None)
|
||||
|
||||
def __init_combobox(self, name):
|
||||
combo = self[name]
|
||||
combo.set_active(0)
|
||||
|
||||
# Convenience function to get an object from its name
|
||||
def __getitem__(self, key):
|
||||
return self.ui.get_object(key)
|
||||
|
||||
def set_active_by_name(self, combo_name, option_name):
|
||||
combo = self[combo_name]
|
||||
model = combo.get_model()
|
||||
piter = model.get_iter_first()
|
||||
while piter is not None:
|
||||
if model.get_value(piter, self.NAME_COLUMN) == option_name:
|
||||
combo.set_active_iter(piter)
|
||||
return True
|
||||
piter = model.iter_next(piter)
|
||||
return False
|
||||
|
||||
def get_selected_tool(self):
|
||||
model, piter = self.view.get_selection().get_selected()
|
||||
|
||||
if piter is not None:
|
||||
tool = model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if not isinstance(tool, Tool):
|
||||
tool = None
|
||||
|
||||
return piter, tool
|
||||
else:
|
||||
return None, None
|
||||
|
||||
def compute_hash(self, string):
|
||||
return hashlib.md5(string).hexdigest()
|
||||
|
||||
def save_current_tool(self):
|
||||
if self.current_node is None:
|
||||
return
|
||||
|
||||
if self.current_node.filename is None:
|
||||
self.current_node.autoset_filename()
|
||||
|
||||
def combo_value(o, name):
|
||||
combo = o[name]
|
||||
return combo.get_model().get_value(combo.get_active_iter(), self.NAME_COLUMN)
|
||||
|
||||
self.current_node.input = combo_value(self, 'input')
|
||||
self.current_node.output = combo_value(self, 'output')
|
||||
self.current_node.applicability = combo_value(self, 'applicability')
|
||||
self.current_node.save_files = combo_value(self, 'save-files')
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
script = buf.get_text(*buf.get_bounds())
|
||||
h = self.compute_hash(script)
|
||||
if h != self.script_hash:
|
||||
# script has changed -> save it
|
||||
self.current_node.save_with_script([line + "\n" for line in script.splitlines()])
|
||||
self.script_hash = h
|
||||
else:
|
||||
self.current_node.save()
|
||||
|
||||
self.update_remove_revert()
|
||||
|
||||
def clear_fields(self):
|
||||
self['accelerator'].set_text('')
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
buf.begin_not_undoable_action()
|
||||
buf.set_text('')
|
||||
buf.end_not_undoable_action()
|
||||
|
||||
for nm in ('input', 'output', 'applicability', 'save-files'):
|
||||
self[nm].set_active(0)
|
||||
|
||||
self['languages_label'].set_text(_('All Languages'))
|
||||
|
||||
def fill_languages_button(self):
|
||||
if not self.current_node or not self.current_node.languages:
|
||||
self['languages_label'].set_text(_('All Languages'))
|
||||
else:
|
||||
manager = gsv.LanguageManager()
|
||||
langs = []
|
||||
|
||||
for lang in self.current_node.languages:
|
||||
if lang == 'plain':
|
||||
langs.append(_('Plain Text'))
|
||||
else:
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if l:
|
||||
langs.append(l.get_name())
|
||||
|
||||
self['languages_label'].set_text(', '.join(langs))
|
||||
|
||||
def fill_fields(self):
|
||||
node = self.current_node
|
||||
self['accelerator'].set_text(default(node.shortcut, ''))
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
script = default(''.join(node.get_script()), '')
|
||||
|
||||
buf.begin_not_undoable_action()
|
||||
buf.set_text(script)
|
||||
buf.end_not_undoable_action()
|
||||
|
||||
self.script_hash = self.compute_hash(script)
|
||||
contenttype = gio.content_type_guess(data=script)
|
||||
lmanager = xedit.get_language_manager()
|
||||
language = lmanager.guess_language(content_type=contenttype)
|
||||
|
||||
if language is not None:
|
||||
buf.set_language(language)
|
||||
buf.set_highlight_syntax(True)
|
||||
else:
|
||||
buf.set_highlight_syntax(False)
|
||||
|
||||
for nm in ('input', 'output', 'applicability', 'save-files'):
|
||||
model = self[nm].get_model()
|
||||
piter = model.get_iter_first()
|
||||
|
||||
self.set_active_by_name(nm,
|
||||
default(node.__getattribute__(nm.replace('-', '_')),
|
||||
model.get_value(piter, self.NAME_COLUMN)))
|
||||
|
||||
self.fill_languages_button()
|
||||
|
||||
def update_remove_revert(self):
|
||||
piter, node = self.get_selected_tool()
|
||||
|
||||
removable = node is not None and node.is_local()
|
||||
|
||||
self['remove-tool-button'].set_sensitive(removable)
|
||||
self['revert-tool-button'].set_sensitive(removable)
|
||||
|
||||
if node is not None and node.is_global():
|
||||
self['remove-tool-button'].hide()
|
||||
self['revert-tool-button'].show()
|
||||
else:
|
||||
self['remove-tool-button'].show()
|
||||
self['revert-tool-button'].hide()
|
||||
|
||||
def do_update(self):
|
||||
self.update_remove_revert()
|
||||
|
||||
piter, node = self.get_selected_tool()
|
||||
self.current_node = node
|
||||
|
||||
if node is not None:
|
||||
self.fill_fields()
|
||||
self['tool-table'].set_sensitive(True)
|
||||
else:
|
||||
self.clear_fields()
|
||||
self['tool-table'].set_sensitive(False)
|
||||
|
||||
def language_id_from_iter(self, piter):
|
||||
if not piter:
|
||||
return None
|
||||
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(tool, Tool):
|
||||
piter = self.model.iter_parent(piter)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(tool, gsv.Language):
|
||||
return tool.get_id()
|
||||
elif tool:
|
||||
return 'plain'
|
||||
|
||||
return None
|
||||
|
||||
def selected_language_id(self):
|
||||
# Find current language if there is any
|
||||
model, piter = self.view.get_selection().get_selected()
|
||||
|
||||
return self.language_id_from_iter(piter)
|
||||
|
||||
def on_new_tool_button_clicked(self, button):
|
||||
self.save_current_tool()
|
||||
|
||||
# block handlers while inserting a new item
|
||||
self.view.get_selection().handler_block(self.selection_changed_id)
|
||||
|
||||
self.current_node = Tool(self.tools.tree);
|
||||
self.current_node.name = _('New tool')
|
||||
self.tools.tree.tools.append(self.current_node)
|
||||
|
||||
lang = self.selected_language_id()
|
||||
|
||||
if lang:
|
||||
self.current_node.languages = [lang]
|
||||
|
||||
piter = self.add_tool(self.current_node)
|
||||
|
||||
self.view.set_cursor(self.model.get_path(piter), self.view.get_column(self.TOOL_COLUMN), True)
|
||||
self.fill_fields()
|
||||
|
||||
self['tool-table'].set_sensitive(True)
|
||||
self.view.get_selection().handler_unblock(self.selection_changed_id)
|
||||
|
||||
def tool_changed(self, tool, refresh=False):
|
||||
for row in self._tool_rows[tool]:
|
||||
self.model.row_changed(row.get_path(), self.model.get_iter(row.get_path()))
|
||||
|
||||
if refresh and tool == self.current_node:
|
||||
self.fill_fields()
|
||||
|
||||
self.update_remove_revert()
|
||||
|
||||
def on_remove_tool_button_clicked(self, button):
|
||||
piter, node = self.get_selected_tool()
|
||||
|
||||
if not node:
|
||||
return
|
||||
|
||||
if node.is_global():
|
||||
shortcut = node.shortcut
|
||||
|
||||
if node.parent.revert_tool(node):
|
||||
self.remove_accelerator(node, shortcut)
|
||||
self.add_accelerator(node)
|
||||
|
||||
self['revert-tool-button'].set_sensitive(False)
|
||||
self.fill_fields()
|
||||
|
||||
self.tool_changed(node)
|
||||
else:
|
||||
parent = self.model.iter_parent(piter)
|
||||
language = self.language_id_from_iter(parent)
|
||||
|
||||
self.model.remove(piter)
|
||||
|
||||
if language in node.languages:
|
||||
node.languages.remove(language)
|
||||
|
||||
self._tool_rows[node] = filter(lambda x: x.valid(), self._tool_rows[node])
|
||||
|
||||
if not self._tool_rows[node]:
|
||||
del self._tool_rows[node]
|
||||
|
||||
if node.parent.delete_tool(node):
|
||||
self.remove_accelerator(node)
|
||||
self.current_node = None
|
||||
self.script_hash = None
|
||||
|
||||
if self.model.iter_is_valid(piter):
|
||||
self.view.set_cursor(self.model.get_path(piter), self.view.get_column(self.TOOL_COLUMN), False)
|
||||
|
||||
self.view.grab_focus()
|
||||
|
||||
path = self._languages[language].get_path()
|
||||
parent = self.model.get_iter(path)
|
||||
|
||||
if not self.model.iter_has_child(parent):
|
||||
self.model.remove(parent)
|
||||
del self._languages[language]
|
||||
|
||||
def on_view_label_cell_edited(self, cell, path, new_text):
|
||||
if new_text != '':
|
||||
piter = self.model.get_iter(path)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
tool.name = new_text
|
||||
|
||||
self.save_current_tool()
|
||||
self.tool_changed(tool)
|
||||
|
||||
def on_view_label_cell_editing_started(self, renderer, editable, path):
|
||||
piter = self.model.get_iter(path)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(editable, gtk.Entry):
|
||||
editable.set_text(tool.name)
|
||||
editable.grab_focus()
|
||||
|
||||
def on_view_selection_changed(self, selection, userdata):
|
||||
self.save_current_tool()
|
||||
self.do_update()
|
||||
|
||||
def accelerator_collision(self, name, node):
|
||||
if not name in self.accelerators:
|
||||
return []
|
||||
|
||||
ret = []
|
||||
|
||||
for other in self.accelerators[name]:
|
||||
if not other.languages or not node.languages:
|
||||
ret.append(other)
|
||||
continue
|
||||
|
||||
for lang in other.languages:
|
||||
if lang in node.languages:
|
||||
ret.append(other)
|
||||
continue
|
||||
|
||||
return ret
|
||||
|
||||
def set_accelerator(self, keyval, mod):
|
||||
# Check whether accelerator already exists
|
||||
self.remove_accelerator(self.current_node)
|
||||
|
||||
name = gtk.accelerator_name(keyval, mod)
|
||||
|
||||
if name == '':
|
||||
self.current_node.shorcut = None
|
||||
self.save_current_tool()
|
||||
return True
|
||||
|
||||
col = self.accelerator_collision(name, self.current_node)
|
||||
|
||||
if col:
|
||||
dialog = gtk.MessageDialog(self.dialog,
|
||||
gtk.DIALOG_MODAL,
|
||||
gtk.MESSAGE_ERROR,
|
||||
gtk.BUTTONS_OK,
|
||||
_('This accelerator is already bound to %s') % (', '.join(map(lambda x: x.name, col)),))
|
||||
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
self.add_accelerator(self.current_node)
|
||||
return False
|
||||
|
||||
self.current_node.shortcut = name
|
||||
self.add_accelerator(self.current_node)
|
||||
self.save_current_tool()
|
||||
|
||||
return True
|
||||
|
||||
def on_accelerator_key_press(self, entry, event):
|
||||
mask = event.state & gtk.accelerator_get_default_mod_mask()
|
||||
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
return True
|
||||
elif event.keyval == gtk.keysyms.Delete \
|
||||
or event.keyval == gtk.keysyms.BackSpace:
|
||||
entry.set_text('')
|
||||
self.remove_accelerator(self.current_node)
|
||||
self.current_node.shortcut = None
|
||||
self['commands'].grab_focus()
|
||||
return True
|
||||
elif event.keyval in range(gtk.keysyms.F1, gtk.keysyms.F12 + 1):
|
||||
# New accelerator
|
||||
if self.set_accelerator(event.keyval, mask):
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
|
||||
# Capture all `normal characters`
|
||||
return True
|
||||
elif gtk.gdk.keyval_to_unicode(event.keyval):
|
||||
if mask:
|
||||
# New accelerator
|
||||
if self.set_accelerator(event.keyval, mask):
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
# Capture all `normal characters`
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def on_accelerator_focus_in(self, entry, event):
|
||||
if self.current_node is None:
|
||||
return
|
||||
if self.current_node.shortcut:
|
||||
entry.set_text(_('Type a new accelerator, or press Backspace to clear'))
|
||||
else:
|
||||
entry.set_text(_('Type a new accelerator'))
|
||||
|
||||
def on_accelerator_focus_out(self, entry, event):
|
||||
if self.current_node is not None:
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self.tool_changed(self.current_node)
|
||||
|
||||
def on_tool_manager_dialog_response(self, dialog, response):
|
||||
if response == gtk.RESPONSE_HELP:
|
||||
xedit.help_display(self.dialog, 'xedit', 'xedit-external-tools-plugin')
|
||||
return
|
||||
|
||||
self.on_tool_manager_dialog_focus_out(dialog, None)
|
||||
|
||||
self.dialog.destroy()
|
||||
self.dialog = None
|
||||
self.tools = None
|
||||
|
||||
def on_tool_manager_dialog_focus_out(self, dialog, event):
|
||||
self.save_current_tool()
|
||||
|
||||
for window in xedit.app_get_default().get_windows():
|
||||
helper = window.get_data("ExternalToolsPluginWindowData")
|
||||
helper.menu.update()
|
||||
|
||||
def get_cell_data_cb(self, column, cell, model, piter):
|
||||
tool = model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if tool == None or not isinstance(tool, Tool):
|
||||
if tool == None:
|
||||
label = _('All Languages')
|
||||
elif not isinstance(tool, gsv.Language):
|
||||
label = _('Plain Text')
|
||||
else:
|
||||
label = tool.get_name()
|
||||
|
||||
markup = saxutils.escape(label)
|
||||
editable = False
|
||||
else:
|
||||
escaped = saxutils.escape(tool.name)
|
||||
|
||||
if tool.shortcut:
|
||||
markup = '%s (<b>%s</b>)' % (escaped, saxutils.escape(tool.shortcut))
|
||||
else:
|
||||
markup = escaped
|
||||
|
||||
editable = True
|
||||
|
||||
cell.set_properties(markup=markup, editable=editable)
|
||||
|
||||
def tool_in_language(self, tool, lang):
|
||||
if not lang in self._languages:
|
||||
return False
|
||||
|
||||
ref = self._languages[lang]
|
||||
parent = ref.get_path()
|
||||
|
||||
for row in self._tool_rows[tool]:
|
||||
path = row.get_path()
|
||||
|
||||
if path[0] == parent[0]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def update_languages(self, popup):
|
||||
self.current_node.languages = popup.languages()
|
||||
self.fill_languages_button()
|
||||
|
||||
piter, node = self.get_selected_tool()
|
||||
ret = None
|
||||
|
||||
if node:
|
||||
ref = gtk.TreeRowReference(self.model, self.model.get_path(piter))
|
||||
|
||||
# Update languages, make sure to inhibit selection change stuff
|
||||
self.view.get_selection().handler_block(self.selection_changed_id)
|
||||
|
||||
# Remove all rows that are no longer
|
||||
for row in list(self._tool_rows[self.current_node]):
|
||||
piter = self.model.get_iter(row.get_path())
|
||||
language = self.language_id_from_iter(piter)
|
||||
|
||||
if (not language and not self.current_node.languages) or \
|
||||
(language in self.current_node.languages):
|
||||
continue
|
||||
|
||||
# Remove from language
|
||||
self.model.remove(piter)
|
||||
self._tool_rows[self.current_node].remove(row)
|
||||
|
||||
# If language is empty, remove it
|
||||
parent = self.model.get_iter(self._languages[language].get_path())
|
||||
|
||||
if not self.model.iter_has_child(parent):
|
||||
self.model.remove(parent)
|
||||
del self._languages[language]
|
||||
|
||||
# Now, add for any that are new
|
||||
manager = gsv.LanguageManager()
|
||||
|
||||
for lang in self.current_node.languages:
|
||||
if not self.tool_in_language(self.current_node, lang):
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if not l:
|
||||
l = 'plain'
|
||||
|
||||
self.add_tool_to_language(self.current_node, l)
|
||||
|
||||
if not self.current_node.languages and not self.tool_in_language(self.current_node, None):
|
||||
self.add_tool_to_language(self.current_node, None)
|
||||
|
||||
# Check if we can still keep the current
|
||||
if not ref or not ref.valid():
|
||||
# Change selection to first language
|
||||
path = self._tool_rows[self.current_node][0].get_path()
|
||||
piter = self.model.get_iter(path)
|
||||
parent = self.model.iter_parent(piter)
|
||||
|
||||
# Expand parent, select child and scroll to it
|
||||
self.view.expand_row(self.model.get_path(parent), False)
|
||||
self.view.get_selection().select_path(path)
|
||||
self.view.set_cursor(path, self.view.get_column(self.TOOL_COLUMN), False)
|
||||
|
||||
self.view.get_selection().handler_unblock(self.selection_changed_id)
|
||||
|
||||
def on_languages_button_clicked(self, button):
|
||||
popup = LanguagesPopup(self.current_node.languages)
|
||||
popup.set_transient_for(self.dialog)
|
||||
|
||||
origin = button.window.get_origin()
|
||||
popup.move(origin[0], origin[1] - popup.allocation.height)
|
||||
|
||||
popup.connect('destroy', self.update_languages)
|
||||
|
||||
# ex:et:ts=4:
|
|
@ -1,224 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Xedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
# Copyright (C) 2010 Per Arneng <per.arneng@anyplanet.com>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('OutputPanel', 'UniqueById')
|
||||
|
||||
import gtk, xedit
|
||||
import pango
|
||||
import gobject
|
||||
import os
|
||||
from weakref import WeakKeyDictionary
|
||||
from capture import *
|
||||
from gtk import gdk
|
||||
import re
|
||||
import gio
|
||||
import linkparsing
|
||||
import filelookup
|
||||
|
||||
class UniqueById:
|
||||
__shared_state = WeakKeyDictionary()
|
||||
|
||||
def __init__(self, i):
|
||||
if i in self.__class__.__shared_state:
|
||||
self.__dict__ = self.__class__.__shared_state[i]
|
||||
return True
|
||||
else:
|
||||
self.__class__.__shared_state[i] = self.__dict__
|
||||
return False
|
||||
|
||||
def states(self):
|
||||
return self.__class__.__shared_state
|
||||
|
||||
class OutputPanel(UniqueById):
|
||||
def __init__(self, datadir, window):
|
||||
if UniqueById.__init__(self, window):
|
||||
return
|
||||
|
||||
callbacks = {
|
||||
'on_stop_clicked' : self.on_stop_clicked,
|
||||
'on_view_visibility_notify_event': self.on_view_visibility_notify_event,
|
||||
'on_view_motion_notify_event': self.on_view_motion_notify_event,
|
||||
'on_view_button_press_event': self.on_view_button_press_event
|
||||
}
|
||||
|
||||
self.window = window
|
||||
self.ui = gtk.Builder()
|
||||
self.ui.add_from_file(os.path.join(datadir, 'ui', 'outputpanel.ui'))
|
||||
self.ui.connect_signals(callbacks)
|
||||
|
||||
self.panel = self["output-panel"]
|
||||
self['view'].modify_font(pango.FontDescription('Monospace'))
|
||||
|
||||
buffer = self['view'].get_buffer()
|
||||
|
||||
self.normal_tag = buffer.create_tag('normal')
|
||||
|
||||
self.error_tag = buffer.create_tag('error')
|
||||
self.error_tag.set_property('foreground', 'red')
|
||||
|
||||
self.italic_tag = buffer.create_tag('italic')
|
||||
self.italic_tag.set_property('style', pango.STYLE_OBLIQUE)
|
||||
|
||||
self.bold_tag = buffer.create_tag('bold')
|
||||
self.bold_tag.set_property('weight', pango.WEIGHT_BOLD)
|
||||
|
||||
self.invalid_link_tag = buffer.create_tag('invalid_link')
|
||||
|
||||
self.link_tag = buffer.create_tag('link')
|
||||
self.link_tag.set_property('underline', pango.UNDERLINE_SINGLE)
|
||||
|
||||
self.link_cursor = gdk.Cursor(gdk.HAND2)
|
||||
self.normal_cursor = gdk.Cursor(gdk.XTERM)
|
||||
|
||||
self.process = None
|
||||
|
||||
self.links = []
|
||||
|
||||
self.link_parser = linkparsing.LinkParser()
|
||||
self.file_lookup = filelookup.FileLookup()
|
||||
|
||||
def set_process(self, process):
|
||||
self.process = process
|
||||
|
||||
def __getitem__(self, key):
|
||||
# Convenience function to get an object from its name
|
||||
return self.ui.get_object(key)
|
||||
|
||||
def on_stop_clicked(self, widget, *args):
|
||||
if self.process is not None:
|
||||
self.write("\n" + _('Stopped.') + "\n",
|
||||
self.italic_tag)
|
||||
self.process.stop(-1)
|
||||
|
||||
def scroll_to_end(self):
|
||||
iter = self['view'].get_buffer().get_end_iter()
|
||||
self['view'].scroll_to_iter(iter, 0.0)
|
||||
return False # don't requeue this handler
|
||||
|
||||
def clear(self):
|
||||
self['view'].get_buffer().set_text("")
|
||||
self.links = []
|
||||
|
||||
def visible(self):
|
||||
panel = self.window.get_bottom_panel()
|
||||
return panel.props.visible and panel.item_is_active(self.panel)
|
||||
|
||||
def write(self, text, tag = None):
|
||||
buffer = self['view'].get_buffer()
|
||||
|
||||
end_iter = buffer.get_end_iter()
|
||||
insert = buffer.create_mark(None, end_iter, True)
|
||||
|
||||
if tag is None:
|
||||
buffer.insert(end_iter, text)
|
||||
else:
|
||||
buffer.insert_with_tags(end_iter, text, tag)
|
||||
|
||||
# find all links and apply the appropriate tag for them
|
||||
links = self.link_parser.parse(text)
|
||||
for lnk in links:
|
||||
|
||||
insert_iter = buffer.get_iter_at_mark(insert)
|
||||
lnk.start = insert_iter.get_offset() + lnk.start
|
||||
lnk.end = insert_iter.get_offset() + lnk.end
|
||||
|
||||
start_iter = buffer.get_iter_at_offset(lnk.start)
|
||||
end_iter = buffer.get_iter_at_offset(lnk.end)
|
||||
|
||||
tag = None
|
||||
|
||||
# if the link points to an existing file then it is a valid link
|
||||
if self.file_lookup.lookup(lnk.path) is not None:
|
||||
self.links.append(lnk)
|
||||
tag = self.link_tag
|
||||
else:
|
||||
tag = self.invalid_link_tag
|
||||
|
||||
buffer.apply_tag(tag, start_iter, end_iter)
|
||||
|
||||
buffer.delete_mark(insert)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
|
||||
def show(self):
|
||||
panel = self.window.get_bottom_panel()
|
||||
panel.show()
|
||||
panel.activate_item(self.panel)
|
||||
|
||||
def update_cursor_style(self, view, x, y):
|
||||
if self.get_link_at_location(view, x, y) is not None:
|
||||
cursor = self.link_cursor
|
||||
else:
|
||||
cursor = self.normal_cursor
|
||||
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(cursor)
|
||||
|
||||
def on_view_motion_notify_event(self, view, event):
|
||||
if event.window == view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
self.update_cursor_style(view, int(event.x), int(event.y))
|
||||
|
||||
return False
|
||||
|
||||
def on_view_visibility_notify_event(self, view, event):
|
||||
if event.window == view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
x, y, m = event.window.get_pointer()
|
||||
self.update_cursor_style(view, x, y)
|
||||
|
||||
return False
|
||||
|
||||
def idle_grab_focus(self):
|
||||
self.window.get_active_view().grab_focus()
|
||||
return False
|
||||
|
||||
def get_link_at_location(self, view, x, y):
|
||||
"""
|
||||
Get the link under a specified x,y coordinate. If no link exists then
|
||||
None is returned.
|
||||
"""
|
||||
|
||||
# get the offset within the buffer from the x,y coordinates
|
||||
buff_x, buff_y = view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT,
|
||||
x, y)
|
||||
iter_at_xy = view.get_iter_at_location(buff_x, buff_y)
|
||||
offset = iter_at_xy.get_offset()
|
||||
|
||||
# find the first link that contains the offset
|
||||
for lnk in self.links:
|
||||
if offset >= lnk.start and offset <= lnk.end:
|
||||
return lnk
|
||||
|
||||
# no link was found at x,y
|
||||
return None
|
||||
|
||||
def on_view_button_press_event(self, view, event):
|
||||
if event.button != 1 or event.type != gdk.BUTTON_PRESS or \
|
||||
event.window != view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
return False
|
||||
|
||||
link = self.get_link_at_location(view, int(event.x), int(event.y))
|
||||
if link is None:
|
||||
return False
|
||||
|
||||
gfile = self.file_lookup.lookup(link.path)
|
||||
|
||||
if gfile:
|
||||
xedit.commands.load_uri(self.window, gfile.get_uri(), None,
|
||||
link.line_nr)
|
||||
gobject.idle_add(self.idle_grab_focus)
|
||||
|
||||
# ex:ts=4:et:
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Generated with glade3
|
||||
Version: 2.91.3
|
||||
Date: Sat Nov 18 13:58:59 2006
|
||||
User: sf
|
||||
Host: antea
|
||||
-->
|
||||
<interface>
|
||||
<object class="GtkHBox" id="output-panel">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">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>
|
||||
<child>
|
||||
<object class="GtkTextView" id="view">
|
||||
<property name="visible">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
<property name="accepts_tab">False</property>
|
||||
<signal name="button_press_event" handler="on_view_button_press_event"/>
|
||||
<signal name="motion_notify_event" handler="on_view_motion_notify_event"/>
|
||||
<signal name="visibility_notify_event" handler="on_view_visibility_notify_event"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVButtonBox" id="vbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="stop">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="label">gtk-stop</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal handler="on_stop_clicked" name="clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
|
@ -1,605 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="model_save_files">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current document</col>
|
||||
<col id="1">document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents</col>
|
||||
<col id="1">all</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_input">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current document</col>
|
||||
<col id="1">document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current selection</col>
|
||||
<col id="1">selection</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current selection (default to document)</col>
|
||||
<col id="1">selection-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current line</col>
|
||||
<col id="1">line</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current word</col>
|
||||
<col id="1">word</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_output">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Display in bottom pane</col>
|
||||
<col id="1">output-panel</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Create new document</col>
|
||||
<col id="1">new-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Append to current document</col>
|
||||
<col id="1">append-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Replace current document</col>
|
||||
<col id="1">replace-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Replace current selection</col>
|
||||
<col id="1">replace-selection</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Insert at cursor position</col>
|
||||
<col id="1">insert</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_applicability">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents</col>
|
||||
<col id="1">all</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents except untitled ones</col>
|
||||
<col id="1">titled</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Local files only</col>
|
||||
<col id="1">local</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Remote files only</col>
|
||||
<col id="1">remote</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Untitled documents only</col>
|
||||
<col id="1">untitled</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="XeditDocument" id="commands_buffer">
|
||||
<property name="highlight-matching-brackets">True</property>
|
||||
</object>
|
||||
<object class="GtkDialog" id="tool-manager-dialog">
|
||||
<property name="title" translatable="yes">External Tools Manager</property>
|
||||
<property name="default_width">750</property>
|
||||
<property name="default_height">500</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<signal name="focus_out_event" handler="on_tool_manager_dialog_focus_out"/>
|
||||
<signal name="response" handler="on_tool_manager_dialog_response"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="tool-manager-dialog-vbox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkHPaned" id="paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="position">275</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label20">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Tools:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">view</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolled_window1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="reorderable">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="new-tool-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_new_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="new-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="revert-tool-button">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_remove_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="revert-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-revert-to-saved</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="remove-tool-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_remove_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="remove-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="label" translatable="yes">_Edit:</property>
|
||||
<property name="mnemonic_widget">commands</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox7">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label22">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"> </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTable" id="tool-table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="accelerator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="key_press_event" handler="on_accelerator_key_press"/>
|
||||
<signal name="focus_out_event" handler="on_accelerator_focus_out"/>
|
||||
<signal name="focus_in_event" handler="on_accelerator_focus_in"/>
|
||||
</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="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="applicability">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_applicability</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="applicability_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="languages_event_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="visible-window">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="languages_button">
|
||||
<property name="visible">True</property>
|
||||
<signal name="clicked" handler="on_languages_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkLabel" id="languages_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">All Languages</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="output">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_output</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="output_renderer"/>
|
||||
<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">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="input">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_input</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="input_renderer"/>
|
||||
<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">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="save-files">
|
||||
<property name="model">model_save_files</property>
|
||||
<property name="visible">True</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">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label23">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Applicability:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">applicability</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Output:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">output</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Input:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">input</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Save:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">save-files</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Shortcut Key:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">accelerator</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="XeditView" id="commands">
|
||||
<property name="buffer">commands_buffer</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="auto-indent">True</property>
|
||||
<property name="insert-spaces-instead-of-tabs">False</property>
|
||||
<property name="smart-home-end">GTK_SOURCE_SMART_HOME_END_AFTER</property>
|
||||
<property name="tab-width">2</property>
|
||||
<property name="highlight-current-line">True</property>
|
||||
<property name="show-right-margin">False</property>
|
||||
<property name="show-line-numbers">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button2">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-11">button1</action-widget>
|
||||
<action-widget response="-7">button2</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -1,15 +0,0 @@
|
|||
# Python Console Plugin
|
||||
SUBDIRS = pythonconsole
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = pythonconsole.xedit-plugin.desktop.in
|
||||
%.xedit-plugin: %.xedit-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
|
||||
|
||||
plugin_DATA = $(plugin_in_files:.xedit-plugin.desktop.in=.xedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,10 +0,0 @@
|
|||
[Xedit Plugin]
|
||||
Loader=python
|
||||
Module=pythonconsole
|
||||
IAge=2
|
||||
_Name=Python Console
|
||||
_Description=Interactive Python console standing in the bottom panel
|
||||
Icon=mate-mime-text-x-python
|
||||
Authors=Steve Frécinaux <steve@istique.net>
|
||||
Copyright=Copyright © 2006 Steve Frécinaux
|
||||
Website=http://www.mate-desktop.org
|
|
@ -1,17 +0,0 @@
|
|||
# Python console plugin
|
||||
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)/pythonconsole
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
console.py \
|
||||
config.py
|
||||
|
||||
uidir = $(XEDIT_PLUGINS_DATA_DIR)/pythonconsole/ui
|
||||
ui_DATA = config.ui
|
||||
|
||||
EXTRA_DIST = $(ui_DATA)
|
||||
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,78 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# __init__.py -- plugin object
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux
|
||||
#
|
||||
# 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; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from xedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import gtk
|
||||
import xedit
|
||||
|
||||
from console import PythonConsole
|
||||
from config import PythonConsoleConfigDialog
|
||||
from config import PythonConsoleConfig
|
||||
|
||||
PYTHON_ICON = 'mate-mime-text-x-python'
|
||||
|
||||
class PythonConsolePlugin(xedit.Plugin):
|
||||
def __init__(self):
|
||||
xedit.Plugin.__init__(self)
|
||||
self.dlg = None
|
||||
|
||||
def activate(self, window):
|
||||
console = PythonConsole(namespace = {'__builtins__' : __builtins__,
|
||||
'xedit' : xedit,
|
||||
'window' : window})
|
||||
console.eval('print "You can access the main window through ' \
|
||||
'\'window\' :\\n%s" % window', False)
|
||||
bottom = window.get_bottom_panel()
|
||||
image = gtk.Image()
|
||||
image.set_from_icon_name(PYTHON_ICON, gtk.ICON_SIZE_MENU)
|
||||
bottom.add_item(console, _('Python Console'), image)
|
||||
window.set_data('PythonConsolePluginInfo', console)
|
||||
|
||||
def deactivate(self, window):
|
||||
console = window.get_data("PythonConsolePluginInfo")
|
||||
console.stop()
|
||||
window.set_data("PythonConsolePluginInfo", None)
|
||||
bottom = window.get_bottom_panel()
|
||||
bottom.remove_item(console)
|
||||
|
||||
def create_configure_dialog(self):
|
||||
|
||||
if not self.dlg:
|
||||
self.dlg = PythonConsoleConfigDialog(self.get_data_dir())
|
||||
|
||||
dialog = self.dlg.dialog()
|
||||
window = xedit.app_get_default().get_active_window()
|
||||
if window:
|
||||
dialog.set_transient_for(window)
|
||||
|
||||
return dialog
|
||||
|
||||
# Here we dynamically insert create_configure_dialog based on if configuration
|
||||
# is enabled. This has to be done like this because xedit checks if a plugin
|
||||
# is configurable solely on the fact that it has this member defined or not
|
||||
if PythonConsoleConfig.enabled():
|
||||
PythonConsolePlugin.create_configure_dialog = create_configure_dialog
|
||||
|
||||
# ex:et:ts=4:
|
|
@ -1,134 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# config.py -- Config dialog
|
||||
#
|
||||
# Copyright (C) 2008 - B. Clausius
|
||||
#
|
||||
# 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; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from xedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import os
|
||||
import gtk
|
||||
|
||||
__all__ = ('PythonConsoleConfig', 'PythonConsoleConfigDialog')
|
||||
|
||||
MATECONF_KEY_BASE = '/apps/xedit/plugins/pythonconsole'
|
||||
MATECONF_KEY_COMMAND_COLOR = MATECONF_KEY_BASE + '/command-color'
|
||||
MATECONF_KEY_ERROR_COLOR = MATECONF_KEY_BASE + '/error-color'
|
||||
|
||||
DEFAULT_COMMAND_COLOR = '#314e6c' # Blue Shadow
|
||||
DEFAULT_ERROR_COLOR = '#990000' # Accent Red Dark
|
||||
|
||||
class PythonConsoleConfig(object):
|
||||
try:
|
||||
import mateconf
|
||||
except ImportError:
|
||||
mateconf = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def enabled():
|
||||
return PythonConsoleConfig.mateconf != None
|
||||
|
||||
@staticmethod
|
||||
def add_handler(handler):
|
||||
if PythonConsoleConfig.mateconf:
|
||||
PythonConsoleConfig.mateconf.client_get_default().notify_add(MATECONF_KEY_BASE, handler)
|
||||
|
||||
color_command = property(
|
||||
lambda self: self.mateconf_get_str(MATECONF_KEY_COMMAND_COLOR, DEFAULT_COMMAND_COLOR),
|
||||
lambda self, value: self.mateconf_set_str(MATECONF_KEY_COMMAND_COLOR, value))
|
||||
|
||||
color_error = property(
|
||||
lambda self: self.mateconf_get_str(MATECONF_KEY_ERROR_COLOR, DEFAULT_ERROR_COLOR),
|
||||
lambda self, value: self.mateconf_set_str(MATECONF_KEY_ERROR_COLOR, value))
|
||||
|
||||
@staticmethod
|
||||
def mateconf_get_str(key, default=''):
|
||||
if not PythonConsoleConfig.mateconf:
|
||||
return default
|
||||
|
||||
val = PythonConsoleConfig.mateconf.client_get_default().get(key)
|
||||
if val is not None and val.type == mateconf.VALUE_STRING:
|
||||
return val.get_string()
|
||||
else:
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
def mateconf_set_str(key, value):
|
||||
if not PythonConsoleConfig.mateconf:
|
||||
return
|
||||
|
||||
v = PythonConsoleConfig.mateconf.Value(mateconf.VALUE_STRING)
|
||||
v.set_string(value)
|
||||
PythonConsoleConfig.mateconf.client_get_default().set(key, v)
|
||||
|
||||
class PythonConsoleConfigDialog(object):
|
||||
|
||||
def __init__(self, datadir):
|
||||
object.__init__(self)
|
||||
self._dialog = None
|
||||
self._ui_path = os.path.join(datadir, 'ui', 'config.ui')
|
||||
self.config = PythonConsoleConfig()
|
||||
|
||||
def dialog(self):
|
||||
if self._dialog is None:
|
||||
self._ui = gtk.Builder()
|
||||
self._ui.add_from_file(self._ui_path)
|
||||
|
||||
self.set_colorbutton_color(self._ui.get_object('colorbutton-command'),
|
||||
self.config.color_command)
|
||||
self.set_colorbutton_color(self._ui.get_object('colorbutton-error'),
|
||||
self.config.color_error)
|
||||
|
||||
self._ui.connect_signals(self)
|
||||
|
||||
self._dialog = self._ui.get_object('dialog-config')
|
||||
self._dialog.show_all()
|
||||
else:
|
||||
self._dialog.present()
|
||||
|
||||
return self._dialog
|
||||
|
||||
@staticmethod
|
||||
def set_colorbutton_color(colorbutton, value):
|
||||
try:
|
||||
color = gtk.gdk.color_parse(value)
|
||||
except ValueError:
|
||||
pass # Default color in config.ui used
|
||||
else:
|
||||
colorbutton.set_color(color)
|
||||
|
||||
def on_dialog_config_response(self, dialog, response_id):
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_dialog_config_destroy(self, dialog):
|
||||
self._dialog = None
|
||||
self._ui = None
|
||||
|
||||
def on_colorbutton_command_color_set(self, colorbutton):
|
||||
self.config.color_command = colorbutton.get_color().to_string()
|
||||
|
||||
def on_colorbutton_error_color_set(self, colorbutton):
|
||||
self.config.color_error = colorbutton.get_color().to_string()
|
||||
|
||||
# ex:et:ts=4:
|
|
@ -1,106 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.14"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="dialog-config">
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="destroy" handler="on_dialog_config_destroy"/>
|
||||
<signal name="response" handler="on_dialog_config_response"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label-command">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">C_ommand color:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">colorbutton-command</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label-error">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Error color:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">colorbutton-error</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="colorbutton-command">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="color">#31314e4e6c6c</property>
|
||||
<signal name="color_set" handler="on_colorbutton_command_color_set"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="colorbutton-error">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="color">#999900000000</property>
|
||||
<signal name="color_set" handler="on_colorbutton_error_color_set"/>
|
||||
</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>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -1,370 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# pythonconsole.py -- Console widget
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux
|
||||
#
|
||||
# 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; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from xedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import string
|
||||
import sys
|
||||
import re
|
||||
import traceback
|
||||
import gobject
|
||||
import gtk
|
||||
import pango
|
||||
|
||||
from config import PythonConsoleConfig
|
||||
|
||||
__all__ = ('PythonConsole', 'OutFile')
|
||||
|
||||
class PythonConsole(gtk.ScrolledWindow):
|
||||
|
||||
__gsignals__ = {
|
||||
'grab-focus' : 'override',
|
||||
}
|
||||
|
||||
def __init__(self, namespace = {}):
|
||||
gtk.ScrolledWindow.__init__(self)
|
||||
|
||||
self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
|
||||
self.set_shadow_type(gtk.SHADOW_IN)
|
||||
self.view = gtk.TextView()
|
||||
self.view.modify_font(pango.FontDescription('Monospace'))
|
||||
self.view.set_editable(True)
|
||||
self.view.set_wrap_mode(gtk.WRAP_WORD_CHAR)
|
||||
self.add(self.view)
|
||||
self.view.show()
|
||||
|
||||
buffer = self.view.get_buffer()
|
||||
self.normal = buffer.create_tag("normal")
|
||||
self.error = buffer.create_tag("error")
|
||||
self.command = buffer.create_tag("command")
|
||||
|
||||
PythonConsoleConfig.add_handler(self.apply_preferences)
|
||||
self.apply_preferences()
|
||||
|
||||
self.__spaces_pattern = re.compile(r'^\s+')
|
||||
self.namespace = namespace
|
||||
|
||||
self.block_command = False
|
||||
|
||||
# Init first line
|
||||
buffer.create_mark("input-line", buffer.get_end_iter(), True)
|
||||
buffer.insert(buffer.get_end_iter(), ">>> ")
|
||||
buffer.create_mark("input", buffer.get_end_iter(), True)
|
||||
|
||||
# Init history
|
||||
self.history = ['']
|
||||
self.history_pos = 0
|
||||
self.current_command = ''
|
||||
self.namespace['__history__'] = self.history
|
||||
|
||||
# Set up hooks for standard output.
|
||||
self.stdout = OutFile(self, sys.stdout.fileno(), self.normal)
|
||||
self.stderr = OutFile(self, sys.stderr.fileno(), self.error)
|
||||
|
||||
# Signals
|
||||
self.view.connect("key-press-event", self.__key_press_event_cb)
|
||||
buffer.connect("mark-set", self.__mark_set_cb)
|
||||
|
||||
def do_grab_focus(self):
|
||||
self.view.grab_focus()
|
||||
|
||||
def apply_preferences(self, *args):
|
||||
config = PythonConsoleConfig()
|
||||
self.error.set_property("foreground", config.color_error)
|
||||
self.command.set_property("foreground", config.color_command)
|
||||
|
||||
def stop(self):
|
||||
self.namespace = None
|
||||
|
||||
def __key_press_event_cb(self, view, event):
|
||||
modifier_mask = gtk.accelerator_get_default_mod_mask()
|
||||
event_state = event.state & modifier_mask
|
||||
|
||||
if event.keyval == gtk.keysyms.d and event_state == gtk.gdk.CONTROL_MASK:
|
||||
self.destroy()
|
||||
|
||||
elif event.keyval == gtk.keysyms.Return and event_state == gtk.gdk.CONTROL_MASK:
|
||||
# Get the command
|
||||
buffer = view.get_buffer()
|
||||
inp_mark = buffer.get_mark("input")
|
||||
inp = buffer.get_iter_at_mark(inp_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
line = buffer.get_text(inp, cur)
|
||||
self.current_command = self.current_command + line + "\n"
|
||||
self.history_add(line)
|
||||
|
||||
# Prepare the new line
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.insert(cur, "\n... ")
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(inp_mark, cur)
|
||||
|
||||
# Keep indentation of precendent line
|
||||
spaces = re.match(self.__spaces_pattern, line)
|
||||
if spaces is not None:
|
||||
buffer.insert(cur, line[spaces.start() : spaces.end()])
|
||||
cur = buffer.get_end_iter()
|
||||
|
||||
buffer.place_cursor(cur)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.Return:
|
||||
# Get the marks
|
||||
buffer = view.get_buffer()
|
||||
lin_mark = buffer.get_mark("input-line")
|
||||
inp_mark = buffer.get_mark("input")
|
||||
|
||||
# Get the command line
|
||||
inp = buffer.get_iter_at_mark(inp_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
line = buffer.get_text(inp, cur)
|
||||
self.current_command = self.current_command + line + "\n"
|
||||
self.history_add(line)
|
||||
|
||||
# Make the line blue
|
||||
lin = buffer.get_iter_at_mark(lin_mark)
|
||||
buffer.apply_tag(self.command, lin, cur)
|
||||
buffer.insert(cur, "\n")
|
||||
|
||||
cur_strip = self.current_command.rstrip()
|
||||
|
||||
if cur_strip.endswith(":") \
|
||||
or (self.current_command[-2:] != "\n\n" and self.block_command):
|
||||
# Unfinished block command
|
||||
self.block_command = True
|
||||
com_mark = "... "
|
||||
elif cur_strip.endswith("\\"):
|
||||
com_mark = "... "
|
||||
else:
|
||||
# Eval the command
|
||||
self.__run(self.current_command)
|
||||
self.current_command = ''
|
||||
self.block_command = False
|
||||
com_mark = ">>> "
|
||||
|
||||
# Prepare the new line
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(lin_mark, cur)
|
||||
buffer.insert(cur, com_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(inp_mark, cur)
|
||||
buffer.place_cursor(cur)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Down or event.keyval == gtk.keysyms.Down:
|
||||
# Next entry from history
|
||||
view.emit_stop_by_name("key_press_event")
|
||||
self.history_down()
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Up or event.keyval == gtk.keysyms.Up:
|
||||
# Previous entry from history
|
||||
view.emit_stop_by_name("key_press_event")
|
||||
self.history_up()
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Left or event.keyval == gtk.keysyms.Left or \
|
||||
event.keyval == gtk.keysyms.BackSpace:
|
||||
buffer = view.get_buffer()
|
||||
inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
cur = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
if inp.compare(cur) == 0:
|
||||
if not event_state:
|
||||
buffer.place_cursor(inp)
|
||||
return True
|
||||
return False
|
||||
|
||||
# For the console we enable smart/home end behavior incoditionally
|
||||
# since it is useful when editing python
|
||||
|
||||
elif (event.keyval == gtk.keysyms.KP_Home or event.keyval == gtk.keysyms.Home) and \
|
||||
event_state == event_state & (gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK):
|
||||
# Go to the begin of the command instead of the begin of the line
|
||||
buffer = view.get_buffer()
|
||||
iter = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
ins = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
|
||||
while iter.get_char().isspace():
|
||||
iter.forward_char()
|
||||
|
||||
if iter.equal(ins):
|
||||
iter = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
|
||||
if event_state & gtk.gdk.SHIFT_MASK:
|
||||
buffer.move_mark_by_name("insert", iter)
|
||||
else:
|
||||
buffer.place_cursor(iter)
|
||||
return True
|
||||
|
||||
elif (event.keyval == gtk.keysyms.KP_End or event.keyval == gtk.keysyms.End) and \
|
||||
event_state == event_state & (gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK):
|
||||
|
||||
buffer = view.get_buffer()
|
||||
iter = buffer.get_end_iter()
|
||||
ins = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
|
||||
iter.backward_char()
|
||||
|
||||
while iter.get_char().isspace():
|
||||
iter.backward_char()
|
||||
|
||||
iter.forward_char()
|
||||
|
||||
if iter.equal(ins):
|
||||
iter = buffer.get_end_iter()
|
||||
|
||||
if event_state & gtk.gdk.SHIFT_MASK:
|
||||
buffer.move_mark_by_name("insert", iter)
|
||||
else:
|
||||
buffer.place_cursor(iter)
|
||||
return True
|
||||
|
||||
def __mark_set_cb(self, buffer, iter, name):
|
||||
input = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
pos = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
self.view.set_editable(pos.compare(input) != -1)
|
||||
|
||||
def get_command_line(self):
|
||||
buffer = self.view.get_buffer()
|
||||
inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
cur = buffer.get_end_iter()
|
||||
return buffer.get_text(inp, cur)
|
||||
|
||||
def set_command_line(self, command):
|
||||
buffer = self.view.get_buffer()
|
||||
mark = buffer.get_mark("input")
|
||||
inp = buffer.get_iter_at_mark(mark)
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.delete(inp, cur)
|
||||
buffer.insert(inp, command)
|
||||
self.view.grab_focus()
|
||||
|
||||
def history_add(self, line):
|
||||
if line.strip() != '':
|
||||
self.history_pos = len(self.history)
|
||||
self.history[self.history_pos - 1] = line
|
||||
self.history.append('')
|
||||
|
||||
def history_up(self):
|
||||
if self.history_pos > 0:
|
||||
self.history[self.history_pos] = self.get_command_line()
|
||||
self.history_pos = self.history_pos - 1
|
||||
self.set_command_line(self.history[self.history_pos])
|
||||
|
||||
def history_down(self):
|
||||
if self.history_pos < len(self.history) - 1:
|
||||
self.history[self.history_pos] = self.get_command_line()
|
||||
self.history_pos = self.history_pos + 1
|
||||
self.set_command_line(self.history[self.history_pos])
|
||||
|
||||
def scroll_to_end(self):
|
||||
iter = self.view.get_buffer().get_end_iter()
|
||||
self.view.scroll_to_iter(iter, 0.0)
|
||||
return False
|
||||
|
||||
def write(self, text, tag = None):
|
||||
buffer = self.view.get_buffer()
|
||||
if tag is None:
|
||||
buffer.insert(buffer.get_end_iter(), text)
|
||||
else:
|
||||
buffer.insert_with_tags(buffer.get_end_iter(), text, tag)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
|
||||
def eval(self, command, display_command = False):
|
||||
buffer = self.view.get_buffer()
|
||||
lin = buffer.get_mark("input-line")
|
||||
buffer.delete(buffer.get_iter_at_mark(lin),
|
||||
buffer.get_end_iter())
|
||||
|
||||
if isinstance(command, list) or isinstance(command, tuple):
|
||||
for c in command:
|
||||
if display_command:
|
||||
self.write(">>> " + c + "\n", self.command)
|
||||
self.__run(c)
|
||||
else:
|
||||
if display_command:
|
||||
self.write(">>> " + c + "\n", self.command)
|
||||
self.__run(command)
|
||||
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark_by_name("input-line", cur)
|
||||
buffer.insert(cur, ">>> ")
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark_by_name("input", cur)
|
||||
self.view.scroll_to_iter(buffer.get_end_iter(), 0.0)
|
||||
|
||||
def __run(self, command):
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
|
||||
# eval and exec are broken in how they deal with utf8-encoded
|
||||
# strings so we have to explicitly decode the command before
|
||||
# passing it along
|
||||
command = command.decode('utf8')
|
||||
|
||||
try:
|
||||
try:
|
||||
r = eval(command, self.namespace, self.namespace)
|
||||
if r is not None:
|
||||
print `r`
|
||||
except SyntaxError:
|
||||
exec command in self.namespace
|
||||
except:
|
||||
if hasattr(sys, 'last_type') and sys.last_type == SystemExit:
|
||||
self.destroy()
|
||||
else:
|
||||
traceback.print_exc()
|
||||
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
#gtk.ScrolledWindow.destroy(self)
|
||||
|
||||
class OutFile:
|
||||
"""A fake output file object. It sends output to a TK test widget,
|
||||
and if asked for a file number, returns one set on instance creation"""
|
||||
def __init__(self, console, fn, tag):
|
||||
self.fn = fn
|
||||
self.console = console
|
||||
self.tag = tag
|
||||
def close(self): pass
|
||||
def flush(self): pass
|
||||
def fileno(self): return self.fn
|
||||
def isatty(self): return 0
|
||||
def read(self, a): return ''
|
||||
def readline(self): return ''
|
||||
def readlines(self): return []
|
||||
def write(self, s): self.console.write(s, self.tag)
|
||||
def writelines(self, l): self.console.write(l, self.tag)
|
||||
def seek(self, a): raise IOError, (29, 'Illegal seek')
|
||||
def tell(self): raise IOError, (29, 'Illegal seek')
|
||||
truncate = tell
|
||||
|
||||
# ex:et:ts=4:
|
|
@ -1,15 +0,0 @@
|
|||
# Quick Open Plugin
|
||||
SUBDIRS = quickopen
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = quickopen.xedit-plugin.desktop.in
|
||||
%.xedit-plugin: %.xedit-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
|
||||
|
||||
plugin_DATA = $(plugin_in_files:.xedit-plugin.desktop.in=.xedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,10 +0,0 @@
|
|||
[Xedit Plugin]
|
||||
Loader=python
|
||||
Module=quickopen
|
||||
IAge=2
|
||||
_Name=Quick Open
|
||||
_Description=Quickly open files
|
||||
Icon=gtk-open
|
||||
Authors=Jesse van den Kieboom <jessevdk@gnome.org>
|
||||
Copyright=Copyright © 2009 Jesse van den Kieboom
|
||||
Website=http://www.mate-desktop.org
|
|
@ -1,13 +0,0 @@
|
|||
# Quick Open Plugin
|
||||
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)/quickopen
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
popup.py \
|
||||
virtualdirs.py \
|
||||
windowhelper.py
|
||||
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,46 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
import xedit
|
||||
from windowhelper import WindowHelper
|
||||
|
||||
class QuickOpenPlugin(xedit.Plugin):
|
||||
def __init__(self):
|
||||
xedit.Plugin.__init__(self)
|
||||
|
||||
self._popup_size = (450, 300)
|
||||
self._helpers = {}
|
||||
|
||||
def activate(self, window):
|
||||
self._helpers[window] = WindowHelper(window, self)
|
||||
|
||||
def deactivate(self, window):
|
||||
self._helpers[window].deactivate()
|
||||
del self._helpers[window]
|
||||
|
||||
def update_ui(self, window):
|
||||
self._helpers[window].update_ui()
|
||||
|
||||
def get_popup_size(self):
|
||||
return self._popup_size
|
||||
|
||||
def set_popup_size(self, size):
|
||||
self._popup_size = size
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,534 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
import gobject
|
||||
import os
|
||||
import gio
|
||||
import pango
|
||||
import glib
|
||||
import fnmatch
|
||||
import xedit
|
||||
import xml.sax.saxutils
|
||||
from virtualdirs import VirtualDirectory
|
||||
|
||||
class Popup(gtk.Dialog):
|
||||
def __init__(self, window, paths, handler):
|
||||
gtk.Dialog.__init__(self,
|
||||
title=_('Quick Open'),
|
||||
parent=window,
|
||||
flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR | gtk.DIALOG_MODAL)
|
||||
|
||||
self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
|
||||
self._open_button = self.add_button(gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)
|
||||
|
||||
self._handler = handler
|
||||
self._build_ui()
|
||||
|
||||
self._dirs = []
|
||||
self._cache = {}
|
||||
self._theme = None
|
||||
self._cursor = None
|
||||
self._shift_start = None
|
||||
|
||||
accel_group = gtk.AccelGroup()
|
||||
accel_group.connect_group(gtk.keysyms.l, gtk.gdk.CONTROL_MASK, 0, self.on_focus_entry)
|
||||
|
||||
self.add_accel_group(accel_group)
|
||||
|
||||
unique = []
|
||||
|
||||
for path in paths:
|
||||
if not path.get_uri() in unique:
|
||||
self._dirs.append(path)
|
||||
unique.append(path.get_uri())
|
||||
|
||||
def _build_ui(self):
|
||||
vbox = self.get_content_area()
|
||||
vbox.set_spacing(3)
|
||||
|
||||
self._entry = gtk.Entry()
|
||||
|
||||
self._entry.connect('changed', self.on_changed)
|
||||
self._entry.connect('key-press-event', self.on_key_press_event)
|
||||
|
||||
sw = gtk.ScrolledWindow(None, None)
|
||||
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
sw.set_shadow_type(gtk.SHADOW_OUT)
|
||||
|
||||
tv = gtk.TreeView()
|
||||
tv.set_headers_visible(False)
|
||||
|
||||
self._store = gtk.ListStore(gio.Icon, str, object, int)
|
||||
tv.set_model(self._store)
|
||||
|
||||
self._treeview = tv
|
||||
tv.connect('row-activated', self.on_row_activated)
|
||||
|
||||
renderer = gtk.CellRendererPixbuf()
|
||||
column = gtk.TreeViewColumn()
|
||||
column.pack_start(renderer, False)
|
||||
column.set_attributes(renderer, gicon=0)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, markup=1)
|
||||
|
||||
column.set_cell_data_func(renderer, self.on_cell_data_cb)
|
||||
|
||||
tv.append_column(column)
|
||||
sw.add(tv)
|
||||
|
||||
selection = tv.get_selection()
|
||||
selection.connect('changed', self.on_selection_changed)
|
||||
selection.set_mode(gtk.SELECTION_MULTIPLE)
|
||||
|
||||
vbox.pack_start(self._entry, False, False, 0)
|
||||
vbox.pack_start(sw, True, True, 0)
|
||||
|
||||
lbl = gtk.Label()
|
||||
lbl.set_alignment(0, 0.5)
|
||||
lbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
|
||||
self._info_label = lbl
|
||||
|
||||
vbox.pack_start(lbl, False, False, 0)
|
||||
|
||||
# Initial selection
|
||||
self.on_selection_changed(tv.get_selection())
|
||||
vbox.show_all()
|
||||
|
||||
def on_cell_data_cb(self, column, cell, model, piter):
|
||||
path = model.get_path(piter)
|
||||
|
||||
if self._cursor and path == self._cursor.get_path():
|
||||
style = self._treeview.get_style()
|
||||
bg = style.bg[gtk.STATE_PRELIGHT]
|
||||
|
||||
cell.set_property('cell-background-gdk', bg)
|
||||
cell.set_property('style', pango.STYLE_ITALIC)
|
||||
else:
|
||||
cell.set_property('cell-background-set', False)
|
||||
cell.set_property('style-set', False)
|
||||
|
||||
def _icon_from_stock(self, stock):
|
||||
theme = gtk.icon_theme_get_default()
|
||||
size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
|
||||
pixbuf = theme.load_icon(stock, size[0], gtk.ICON_LOOKUP_USE_BUILTIN)
|
||||
|
||||
return pixbuf
|
||||
|
||||
def _list_dir(self, gfile):
|
||||
entries = []
|
||||
|
||||
try:
|
||||
entries = gfile.enumerate_children("standard::*")
|
||||
except glib.GError:
|
||||
pass
|
||||
|
||||
children = []
|
||||
|
||||
for entry in entries:
|
||||
if isinstance(gfile, VirtualDirectory):
|
||||
child, entry = entry
|
||||
else:
|
||||
child = gfile.get_child(entry.get_name())
|
||||
|
||||
children.append((child, entry.get_name(), entry.get_file_type(), entry.get_icon()))
|
||||
|
||||
return children
|
||||
|
||||
def _compare_entries(self, a, b, lpart):
|
||||
if lpart in a:
|
||||
if lpart in b:
|
||||
return cmp(a.index(lpart), b.index(lpart))
|
||||
else:
|
||||
return -1
|
||||
elif lpart in b:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def _match_glob(self, s, glob):
|
||||
if glob:
|
||||
glob += '*'
|
||||
|
||||
return fnmatch.fnmatch(s, glob)
|
||||
|
||||
def do_search_dir(self, parts, d):
|
||||
if not parts or not d:
|
||||
return []
|
||||
|
||||
if not d in self._cache:
|
||||
entries = self._list_dir(d)
|
||||
entries.sort(lambda x, y: cmp(x[1].lower(), y[1].lower()))
|
||||
|
||||
self._cache[d] = entries
|
||||
else:
|
||||
entries = self._cache[d]
|
||||
|
||||
found = []
|
||||
newdirs = []
|
||||
|
||||
lpart = parts[0].lower()
|
||||
|
||||
for entry in entries:
|
||||
if not entry:
|
||||
continue
|
||||
|
||||
lentry = entry[1].lower()
|
||||
|
||||
if not lpart or lpart in lentry or self._match_glob(lentry, lpart):
|
||||
if entry[2] == gio.FILE_TYPE_DIRECTORY:
|
||||
if len(parts) > 1:
|
||||
newdirs.append(entry[0])
|
||||
else:
|
||||
found.append(entry)
|
||||
elif entry[2] == gio.FILE_TYPE_REGULAR and \
|
||||
(not lpart or len(parts) == 1):
|
||||
found.append(entry)
|
||||
|
||||
found.sort(lambda a, b: self._compare_entries(a[1].lower(), b[1].lower(), lpart))
|
||||
|
||||
if lpart == '..':
|
||||
newdirs.append(d.get_parent())
|
||||
|
||||
for dd in newdirs:
|
||||
found.extend(self.do_search_dir(parts[1:], dd))
|
||||
|
||||
return found
|
||||
|
||||
def _replace_insensitive(self, s, find, rep):
|
||||
out = ''
|
||||
l = s.lower()
|
||||
find = find.lower()
|
||||
last = 0
|
||||
|
||||
if len(find) == 0:
|
||||
return xml.sax.saxutils.escape(s)
|
||||
|
||||
while True:
|
||||
m = l.find(find, last)
|
||||
|
||||
if m == -1:
|
||||
break
|
||||
else:
|
||||
out += xml.sax.saxutils.escape(s[last:m]) + rep % (xml.sax.saxutils.escape(s[m:m + len(find)]),)
|
||||
last = m + len(find)
|
||||
|
||||
return out + xml.sax.saxutils.escape(s[last:])
|
||||
|
||||
|
||||
def make_markup(self, parts, path):
|
||||
out = []
|
||||
|
||||
for i in range(0, len(parts)):
|
||||
out.append(self._replace_insensitive(path[i], parts[i], "<b>%s</b>"))
|
||||
|
||||
return os.sep.join(out)
|
||||
|
||||
def _get_icon(self, f):
|
||||
query = f.query_info(gio.FILE_ATTRIBUTE_STANDARD_ICON)
|
||||
|
||||
if not query:
|
||||
return None
|
||||
else:
|
||||
return query.get_icon()
|
||||
|
||||
def _make_parts(self, parent, child, pp):
|
||||
parts = []
|
||||
|
||||
# We went from parent, to child, using pp
|
||||
idx = len(pp) - 1
|
||||
|
||||
while idx >= 0:
|
||||
if pp[idx] == '..':
|
||||
parts.insert(0, '..')
|
||||
else:
|
||||
parts.insert(0, child.get_basename())
|
||||
child = child.get_parent()
|
||||
|
||||
idx -= 1
|
||||
|
||||
return parts
|
||||
|
||||
def normalize_relative(self, parts):
|
||||
if not parts:
|
||||
return []
|
||||
|
||||
out = self.normalize_relative(parts[:-1])
|
||||
|
||||
if parts[-1] == '..':
|
||||
if not out or (out[-1] == '..') or len(out) == 1:
|
||||
out.append('..')
|
||||
else:
|
||||
del out[-1]
|
||||
else:
|
||||
out.append(parts[-1])
|
||||
|
||||
return out
|
||||
|
||||
def _append_to_store(self, item):
|
||||
if not item in self._stored_items:
|
||||
self._store.append(item)
|
||||
self._stored_items[item] = True
|
||||
|
||||
def _clear_store(self):
|
||||
self._store.clear()
|
||||
self._stored_items = {}
|
||||
|
||||
def _show_virtuals(self):
|
||||
for d in self._dirs:
|
||||
if isinstance(d, VirtualDirectory):
|
||||
for entry in d.enumerate_children("standard::*"):
|
||||
self._append_to_store((entry[1].get_icon(), xml.sax.saxutils.escape(entry[1].get_name()), entry[0], entry[1].get_file_type()))
|
||||
|
||||
def _remove_cursor(self):
|
||||
if self._cursor:
|
||||
path = self._cursor.get_path()
|
||||
self._cursor = None
|
||||
|
||||
self._store.row_changed(path, self._store.get_iter(path))
|
||||
|
||||
def do_search(self):
|
||||
self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
|
||||
self._remove_cursor()
|
||||
|
||||
text = self._entry.get_text().strip()
|
||||
self._clear_store()
|
||||
|
||||
if text == '':
|
||||
self._show_virtuals()
|
||||
else:
|
||||
parts = self.normalize_relative(text.split(os.sep))
|
||||
files = []
|
||||
|
||||
for d in self._dirs:
|
||||
for entry in self.do_search_dir(parts, d):
|
||||
pathparts = self._make_parts(d, entry[0], parts)
|
||||
self._append_to_store((entry[3], self.make_markup(parts, pathparts), entry[0], entry[2]))
|
||||
|
||||
piter = self._store.get_iter_first()
|
||||
|
||||
if piter:
|
||||
self._treeview.get_selection().select_path(self._store.get_path(piter))
|
||||
|
||||
self.window.set_cursor(None)
|
||||
|
||||
def do_show(self):
|
||||
gtk.Window.do_show(self)
|
||||
|
||||
self._entry.grab_focus()
|
||||
self._entry.set_text("")
|
||||
|
||||
self.do_search()
|
||||
|
||||
def on_changed(self, editable):
|
||||
self.do_search()
|
||||
self.on_selection_changed(self._treeview.get_selection())
|
||||
|
||||
def _shift_extend(self, towhere):
|
||||
selection = self._treeview.get_selection()
|
||||
|
||||
if not self._shift_start:
|
||||
model, rows = selection.get_selected_rows()
|
||||
start = rows[0]
|
||||
|
||||
self._shift_start = gtk.TreeRowReference(self._store, start)
|
||||
else:
|
||||
start = self._shift_start.get_path()
|
||||
|
||||
selection.unselect_all()
|
||||
selection.select_range(start, towhere)
|
||||
|
||||
def _select_index(self, idx, hasctrl, hasshift):
|
||||
path = (idx,)
|
||||
|
||||
if not (hasctrl or hasshift):
|
||||
self._treeview.get_selection().unselect_all()
|
||||
|
||||
if hasshift:
|
||||
self._shift_extend(path)
|
||||
else:
|
||||
self._shift_start = None
|
||||
|
||||
if not hasctrl:
|
||||
self._treeview.get_selection().select_path(path)
|
||||
|
||||
self._treeview.scroll_to_cell(path, None, True, 0.5, 0)
|
||||
self._remove_cursor()
|
||||
|
||||
if hasctrl or hasshift:
|
||||
self._cursor = gtk.TreeRowReference(self._store, path)
|
||||
|
||||
piter = self._store.get_iter(path)
|
||||
self._store.row_changed(path, piter)
|
||||
|
||||
def _move_selection(self, howmany, hasctrl, hasshift):
|
||||
num = self._store.iter_n_children(None)
|
||||
|
||||
if num == 0:
|
||||
return True
|
||||
|
||||
# Test for cursor
|
||||
path = None
|
||||
|
||||
if self._cursor:
|
||||
path = self._cursor.get_path()
|
||||
else:
|
||||
model, rows = self._treeview.get_selection().get_selected_rows()
|
||||
|
||||
if len(rows) == 1:
|
||||
path = rows[0]
|
||||
|
||||
if not path:
|
||||
if howmany > 0:
|
||||
self._select_index(0, hasctrl, hasshift)
|
||||
else:
|
||||
self._select_index(num - 1, hasctrl, hasshift)
|
||||
else:
|
||||
idx = path[0]
|
||||
|
||||
if idx + howmany < 0:
|
||||
self._select_index(0, hasctrl, hasshift)
|
||||
elif idx + howmany >= num:
|
||||
self._select_index(num - 1, hasctrl, hasshift)
|
||||
else:
|
||||
self._select_index(idx + howmany, hasctrl, hasshift)
|
||||
|
||||
return True
|
||||
|
||||
def _direct_file(self):
|
||||
uri = self._entry.get_text()
|
||||
gfile = None
|
||||
|
||||
if xedit.utils.uri_is_valid(uri):
|
||||
gfile = gio.File(uri)
|
||||
elif os.path.isabs(uri):
|
||||
f = gio.File(uri)
|
||||
|
||||
if f.query_exists():
|
||||
gfile = f
|
||||
|
||||
return gfile
|
||||
|
||||
def _activate(self):
|
||||
model, rows = self._treeview.get_selection().get_selected_rows()
|
||||
ret = True
|
||||
|
||||
for row in rows:
|
||||
s = model.get_iter(row)
|
||||
info = model.get(s, 2, 3)
|
||||
|
||||
if info[1] != gio.FILE_TYPE_DIRECTORY:
|
||||
ret = ret and self._handler(info[0])
|
||||
else:
|
||||
text = self._entry.get_text()
|
||||
|
||||
for i in range(len(text) - 1, -1, -1):
|
||||
if text[i] == os.sep:
|
||||
break
|
||||
|
||||
self._entry.set_text(os.path.join(text[:i], os.path.basename(info[0].get_uri())) + os.sep)
|
||||
self._entry.set_position(-1)
|
||||
self._entry.grab_focus()
|
||||
return True
|
||||
|
||||
if rows and ret:
|
||||
self.destroy()
|
||||
|
||||
if not rows:
|
||||
gfile = self._direct_file()
|
||||
|
||||
if gfile and self._handler(gfile):
|
||||
self.destroy()
|
||||
else:
|
||||
ret = False
|
||||
else:
|
||||
ret = False
|
||||
|
||||
return ret
|
||||
|
||||
def toggle_cursor(self):
|
||||
if not self._cursor:
|
||||
return
|
||||
|
||||
path = self._cursor.get_path()
|
||||
selection = self._treeview.get_selection()
|
||||
|
||||
if selection.path_is_selected(path):
|
||||
selection.unselect_path(path)
|
||||
else:
|
||||
selection.select_path(path)
|
||||
|
||||
def on_key_press_event(self, widget, event):
|
||||
move_mapping = {
|
||||
gtk.keysyms.Down: 1,
|
||||
gtk.keysyms.Up: -1,
|
||||
gtk.keysyms.Page_Down: 5,
|
||||
gtk.keysyms.Page_Up: -5
|
||||
}
|
||||
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
self.destroy()
|
||||
return True
|
||||
elif event.keyval in move_mapping:
|
||||
return self._move_selection(move_mapping[event.keyval], event.state & gtk.gdk.CONTROL_MASK, event.state & gtk.gdk.SHIFT_MASK)
|
||||
elif event.keyval in [gtk.keysyms.Return, gtk.keysyms.KP_Enter, gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab]:
|
||||
return self._activate()
|
||||
elif event.keyval == gtk.keysyms.space and event.state & gtk.gdk.CONTROL_MASK:
|
||||
self.toggle_cursor()
|
||||
|
||||
return False
|
||||
|
||||
def on_row_activated(self, view, path, column):
|
||||
self._activate()
|
||||
|
||||
def do_response(self, response):
|
||||
if response != gtk.RESPONSE_ACCEPT or not self._activate():
|
||||
self.destroy()
|
||||
|
||||
def on_selection_changed(self, selection):
|
||||
model, rows = selection.get_selected_rows()
|
||||
|
||||
gfile = None
|
||||
fname = None
|
||||
|
||||
if not rows:
|
||||
gfile = self._direct_file()
|
||||
elif len(rows) == 1:
|
||||
gfile = model.get(model.get_iter(rows[0]), 2)[0]
|
||||
else:
|
||||
fname = ''
|
||||
|
||||
if gfile:
|
||||
if gfile.is_native():
|
||||
fname = xml.sax.saxutils.escape(gfile.get_path())
|
||||
else:
|
||||
fname = xml.sax.saxutils.escape(gfile.get_uri())
|
||||
|
||||
self._open_button.set_sensitive(fname != None)
|
||||
self._info_label.set_markup(fname or '')
|
||||
|
||||
def on_focus_entry(self, group, accel, keyval, modifier):
|
||||
self._entry.grab_focus()
|
||||
|
||||
gobject.type_register(Popup)
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,87 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
import gtk
|
||||
import gio
|
||||
|
||||
class VirtualDirectory:
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
self._children = []
|
||||
|
||||
def get_uri(self):
|
||||
return 'virtual://' + self._name
|
||||
|
||||
def get_parent(self):
|
||||
return None
|
||||
|
||||
def enumerate_children(self, attr):
|
||||
return self._children
|
||||
|
||||
def append(self, child):
|
||||
if not child.is_native():
|
||||
return
|
||||
|
||||
try:
|
||||
info = child.query_info("standard::*")
|
||||
|
||||
if info:
|
||||
self._children.append((child, info))
|
||||
except:
|
||||
pass
|
||||
|
||||
class RecentDocumentsDirectory(VirtualDirectory):
|
||||
def __init__(self, maxitems=10, screen=None):
|
||||
VirtualDirectory.__init__(self, 'recent')
|
||||
|
||||
self._maxitems = maxitems
|
||||
self.fill(screen)
|
||||
|
||||
def fill(self, screen):
|
||||
if screen:
|
||||
manager = gtk.recent_manager_get_for_screen(screen)
|
||||
else:
|
||||
manager = gtk.recent_manager_get_default()
|
||||
|
||||
items = manager.get_items()
|
||||
items.sort(lambda a, b: cmp(b.get_visited(), a.get_visited()))
|
||||
|
||||
added = 0
|
||||
|
||||
for item in items:
|
||||
if item.has_group('xedit'):
|
||||
self.append(gio.File(item.get_uri()))
|
||||
added += 1
|
||||
|
||||
if added >= self._maxitems:
|
||||
break
|
||||
|
||||
class CurrentDocumentsDirectory(VirtualDirectory):
|
||||
def __init__(self, window):
|
||||
VirtualDirectory.__init__(self, 'documents')
|
||||
|
||||
self.fill(window)
|
||||
|
||||
def fill(self, window):
|
||||
for doc in window.get_documents():
|
||||
location = doc.get_location()
|
||||
if location:
|
||||
self.append(location)
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,197 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
import xedit
|
||||
import gtk
|
||||
from popup import Popup
|
||||
import os
|
||||
import xedit.commands
|
||||
import gio
|
||||
import glib
|
||||
from virtualdirs import RecentDocumentsDirectory
|
||||
from virtualdirs import CurrentDocumentsDirectory
|
||||
|
||||
ui_str = """<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu name="FileMenu" action="File">
|
||||
<placeholder name="FileOps_2">
|
||||
<menuitem name="QuickOpen" action="QuickOpen"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
class WindowHelper:
|
||||
def __init__(self, window, plugin):
|
||||
self._window = window
|
||||
self._plugin = plugin
|
||||
|
||||
self._popup = None
|
||||
self._install_menu()
|
||||
|
||||
def deactivate(self):
|
||||
self._uninstall_menu()
|
||||
self._window = None
|
||||
self._plugin = None
|
||||
|
||||
def update_ui(self):
|
||||
pass
|
||||
|
||||
def _uninstall_menu(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
|
||||
manager.remove_ui(self._ui_id)
|
||||
manager.remove_action_group(self._action_group)
|
||||
|
||||
manager.ensure_update()
|
||||
|
||||
def _install_menu(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
self._action_group = gtk.ActionGroup("XeditQuickOpenPluginActions")
|
||||
self._action_group.add_actions([
|
||||
("QuickOpen", gtk.STOCK_OPEN, _("Quick open"),
|
||||
'<Ctrl><Alt>O', _("Quickly open documents"),
|
||||
self.on_quick_open_activate)
|
||||
])
|
||||
|
||||
manager.insert_action_group(self._action_group, -1)
|
||||
self._ui_id = manager.add_ui_from_string(ui_str)
|
||||
|
||||
def _create_popup(self):
|
||||
paths = []
|
||||
|
||||
# Open documents
|
||||
paths.append(CurrentDocumentsDirectory(self._window))
|
||||
|
||||
doc = self._window.get_active_document()
|
||||
|
||||
# Current document directory
|
||||
if doc and doc.is_local():
|
||||
gfile = doc.get_location()
|
||||
paths.append(gfile.get_parent())
|
||||
|
||||
# File browser root directory
|
||||
bus = self._window.get_message_bus()
|
||||
|
||||
try:
|
||||
msg = bus.send_sync('/plugins/filebrowser', 'get_root')
|
||||
|
||||
if msg:
|
||||
uri = msg.get_value('uri')
|
||||
|
||||
if uri:
|
||||
gfile = gio.File(uri)
|
||||
|
||||
if gfile.is_native():
|
||||
paths.append(gfile)
|
||||
|
||||
except StandardError:
|
||||
pass
|
||||
|
||||
# Recent documents
|
||||
paths.append(RecentDocumentsDirectory(screen=self._window.get_screen()))
|
||||
|
||||
# Local bookmarks
|
||||
for path in self._local_bookmarks():
|
||||
paths.append(path)
|
||||
|
||||
# Desktop directory
|
||||
desktopdir = self._desktop_dir()
|
||||
|
||||
if desktopdir:
|
||||
paths.append(gio.File(desktopdir))
|
||||
|
||||
# Home directory
|
||||
paths.append(gio.File(os.path.expanduser('~')))
|
||||
|
||||
self._popup = Popup(self._window, paths, self.on_activated)
|
||||
|
||||
self._popup.set_default_size(*self._plugin.get_popup_size())
|
||||
self._popup.set_transient_for(self._window)
|
||||
self._popup.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
|
||||
self._window.get_group().add_window(self._popup)
|
||||
|
||||
self._popup.connect('destroy', self.on_popup_destroy)
|
||||
|
||||
def _local_bookmarks(self):
|
||||
filename = os.path.expanduser('~/.gtk-bookmarks')
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return []
|
||||
|
||||
paths = []
|
||||
|
||||
for line in file(filename, 'r').xreadlines():
|
||||
uri = line.strip().split(" ")[0]
|
||||
f = gio.File(uri)
|
||||
|
||||
if f.is_native():
|
||||
try:
|
||||
info = f.query_info("standard::type")
|
||||
|
||||
if info and info.get_file_type() == gio.FILE_TYPE_DIRECTORY:
|
||||
paths.append(f)
|
||||
except glib.GError:
|
||||
pass
|
||||
|
||||
return paths
|
||||
|
||||
def _desktop_dir(self):
|
||||
config = os.getenv('XDG_CONFIG_HOME')
|
||||
|
||||
if not config:
|
||||
config = os.path.expanduser('~/.config')
|
||||
|
||||
config = os.path.join(config, 'user-dirs.dirs')
|
||||
desktopdir = None
|
||||
|
||||
if os.path.isfile(config):
|
||||
for line in file(config, 'r').xreadlines():
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith('XDG_DESKTOP_DIR'):
|
||||
parts = line.split('=', 1)
|
||||
desktopdir = os.path.expandvars(parts[1].strip('"').strip("'"))
|
||||
break
|
||||
|
||||
if not desktopdir:
|
||||
desktopdir = os.path.expanduser('~/Desktop')
|
||||
|
||||
return desktopdir
|
||||
|
||||
# Callbacks
|
||||
def on_quick_open_activate(self, action):
|
||||
if not self._popup:
|
||||
self._create_popup()
|
||||
|
||||
self._popup.show()
|
||||
|
||||
def on_popup_destroy(self, popup):
|
||||
alloc = popup.get_allocation()
|
||||
self._plugin.set_popup_size((alloc.width, alloc.height))
|
||||
|
||||
self._popup = None
|
||||
|
||||
def on_activated(self, gfile):
|
||||
xedit.commands.load_uri(self._window, gfile.get_uri(), None, -1)
|
||||
return True
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,15 +0,0 @@
|
|||
# Python snippets plugin
|
||||
SUBDIRS = snippets data
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = snippets.xedit-plugin.desktop.in
|
||||
%.xedit-plugin: %.xedit-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
|
||||
|
||||
plugin_DATA = $(plugin_in_files:.xedit-plugin.desktop.in=.xedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,33 +0,0 @@
|
|||
# Python snippets plugin
|
||||
SUBDIRS = lang
|
||||
|
||||
snippets_DATA = \
|
||||
css.xml \
|
||||
c.xml \
|
||||
cpp.xml \
|
||||
chdr.xml \
|
||||
docbook.xml \
|
||||
fortran.xml \
|
||||
global.xml \
|
||||
haskell.xml \
|
||||
html.xml \
|
||||
idl.xml \
|
||||
javascript.xml \
|
||||
java.xml \
|
||||
latex.xml \
|
||||
mallard.xml \
|
||||
perl.xml \
|
||||
php.xml \
|
||||
python.xml \
|
||||
ruby.xml \
|
||||
sh.xml \
|
||||
snippets.xml \
|
||||
tcl.xml \
|
||||
xml.xml \
|
||||
xslt.xml
|
||||
|
||||
snippetsdir = $(XEDIT_PLUGINS_DATA_DIR)/snippets
|
||||
|
||||
EXTRA_DIST = $(snippets_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,283 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="C">
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
{
|
||||
$0
|
||||
} while ($1);]]></text>
|
||||
<tag>do</tag>
|
||||
<description>do .. while</description>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (${1:i} = ${2:0}; ${1:i} < ${3:count}; ${1:i} += ${4:1})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>for</tag>
|
||||
<description>for loop</description>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>while</tag>
|
||||
<description>while loop</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>if</tag>
|
||||
<description>if</description>
|
||||
</snippet>
|
||||
<snippet id="elif">
|
||||
<text><![CDATA[else if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>elif</tag>
|
||||
<description>else if</description>
|
||||
</snippet>
|
||||
<snippet id="else">
|
||||
<text><![CDATA[else
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>else</tag>
|
||||
<description>else</description>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}.h>
|
||||
$0]]></text>
|
||||
<tag>Inc</tag>
|
||||
<description>#include <..></description>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}.h"
|
||||
$0]]></text>
|
||||
<tag>inc</tag>
|
||||
<description>#include ".."</description>
|
||||
</snippet>
|
||||
<snippet id="main">
|
||||
<text><![CDATA[int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
$0
|
||||
return 0;
|
||||
}]]></text>
|
||||
<tag>main</tag>
|
||||
<description>main</description>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<tag>struct</tag>
|
||||
<description>struct</description>
|
||||
</snippet>
|
||||
<snippet id="endif">
|
||||
<text><![CDATA[#endif
|
||||
$0]]></text>
|
||||
<description>#endif</description>
|
||||
<accelerator><![CDATA[<Control><Alt>period]]></accelerator>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="gobject">
|
||||
<text><![CDATA[#include "$1.h"
|
||||
$<
|
||||
global camel_str,low_str, type_str, is_str, up_str
|
||||
components = $1.split('-')
|
||||
low_str = '_'.join(components).lower()
|
||||
up_str = '_'.join(components).upper()
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:]).upper()
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:]).upper()
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
>
|
||||
|
||||
#define $<[1]: return up_str >_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), $<[1]: return type_str >, $<[1]: return camel_str >Private))
|
||||
|
||||
struct _$<[1]: return camel_str >Private
|
||||
{
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE ($<[1]: return camel_str >, $<[1]: return low_str >, ${2:G_TYPE_OBJECT})
|
||||
|
||||
static void
|
||||
$<[1]: return low_str>_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS ($<[1]: return low_str >_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str >_class_init ($<[1]: return camel_str >Class *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = $<[1]: return low_str >_finalize;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof ($<[1]: return camel_str >Private));
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str >_init ($<[1]: return camel_str> *self)
|
||||
{
|
||||
self->priv = $<[1]: return up_str >_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
$<[1]: return camel_str > *
|
||||
$<[1]: return low_str >_new ()
|
||||
{
|
||||
return g_object_new ($<[1]: return type_str >, NULL);
|
||||
}]]></text>
|
||||
<tag>gobject</tag>
|
||||
<description>GObject template</description>
|
||||
</snippet>
|
||||
<snippet id="ginterface">
|
||||
<text><![CDATA[#include "$1.h"
|
||||
$<
|
||||
global camel_str,low_str,up_str
|
||||
components = $1.split('-')
|
||||
low_str = '_'.join(components).lower()
|
||||
up_str = '_'.join(components).upper()
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
>
|
||||
/* Default implementation */
|
||||
static const gchar *
|
||||
$<[1]: return low_str>_example_method_default ($<[1]: return camel_str > *self)
|
||||
{
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str>_init ($<[1]: return camel_str >Iface *iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
iface->example_method = $<[1]: return low_str>_example_method_default;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is an method example for an interface
|
||||
*/
|
||||
const gchar *
|
||||
$<[1]: return low_str>_example_method ($<[1]: return camel_str > *self)
|
||||
{
|
||||
g_return_val_if_fail ($<[1]: return up_str> (self), NULL);
|
||||
return $<[1]: return up_str>_GET_INTERFACE (self)->example_method (self);
|
||||
}
|
||||
|
||||
GType
|
||||
$<[1]: return low_str>_get_type ()
|
||||
{
|
||||
static GType $<[1]: return low_str>_type_id = 0;
|
||||
|
||||
if (!$<[1]: return low_str>_type_id)
|
||||
{
|
||||
static const GTypeInfo g_define_type_info =
|
||||
{
|
||||
sizeof ($<[1]: return camel_str >Iface),
|
||||
(GBaseInitFunc) $<[1]: return low_str>_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
$<[1]: return low_str>_type_id =
|
||||
g_type_register_static (G_TYPE_INTERFACE,
|
||||
"$<[1]: return camel_str>",
|
||||
&g_define_type_info,
|
||||
0);
|
||||
}
|
||||
|
||||
return $<[1]: return low_str>_type_id;
|
||||
}]]></text>
|
||||
<tag>ginterface</tag>
|
||||
<description>GObject interface</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,241 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="chdr">
|
||||
<snippet id="once">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
$0
|
||||
|
||||
#endif /* __$1_H__ */
|
||||
]]></text>
|
||||
<description>Header Include-Guard</description>
|
||||
<tag>once</tag>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}"
|
||||
$0]]></text>
|
||||
<description>#include ".."</description>
|
||||
<tag>inc</tag>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}>
|
||||
$0]]></text>
|
||||
<description>#include <..></description>
|
||||
<tag>Inc</tag>
|
||||
</snippet>
|
||||
<snippet id="namespace">
|
||||
<text><![CDATA[namespace ${1:ns}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<description>namespace ..</description>
|
||||
<tag>namespace</tag>
|
||||
</snippet>
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="class">
|
||||
<text><![CDATA[class ${1:name}
|
||||
{
|
||||
public:
|
||||
${1:name} (${2:arguments});
|
||||
virtual ~${1:name} ();
|
||||
|
||||
private:
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<description>class ..</description>
|
||||
<tag>class</tag>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<tag>struct</tag>
|
||||
<description>struct</description>
|
||||
</snippet>
|
||||
<snippet id="template">
|
||||
<text><![CDATA[template <typename ${1:_InputIter}>]]></text>
|
||||
<description>template <typename ..></description>
|
||||
<tag>template</tag>
|
||||
</snippet>
|
||||
<snippet id="gobject">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
#include <${2:glib-object.h}>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
$<
|
||||
global camel_str
|
||||
components = $1.split('_')
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:])
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:])
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
|
||||
items = [ \
|
||||
['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \
|
||||
['#define ' + $1 + '(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + '))'], \
|
||||
['#define ' + $1 + '_CONST(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + ' const))'], \
|
||||
['#define ' + $1 + '_CLASS(klass)', '(G_TYPE_CHECK_CLASS_CAST ((klass), ' + type_str + ', ' + camel_str + 'Class))'], \
|
||||
['#define ' + is_str + '(obj)', '(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ' + type_str + '))'], \
|
||||
['#define ' + is_str + '_CLASS(klass)', '(G_TYPE_CHECK_CLASS_TYPE ((klass), ' + type_str + '))'], \
|
||||
['#define ' + $1 + '_GET_CLASS(obj)', '(G_TYPE_INSTANCE_GET_CLASS ((obj), ' + type_str + ', ' + camel_str + 'Class))']
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
$<[1]:
|
||||
items = [ \
|
||||
['typedef struct _' + camel_str, camel_str + ';'], \
|
||||
['typedef struct _' + camel_str + 'Class', camel_str + 'Class;'], \
|
||||
['typedef struct _' + camel_str + 'Private', camel_str + 'Private;'] \
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
struct _$<[1]: return camel_str > {
|
||||
${7:GObject} parent;
|
||||
|
||||
$<[1]: return camel_str >Private *priv;
|
||||
};
|
||||
|
||||
struct _$<[1]: return camel_str >Class {
|
||||
$7Class parent_class;
|
||||
};
|
||||
|
||||
GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST;
|
||||
$<[1]: return camel_str > *$< return $1.lower()>_new (void);
|
||||
|
||||
$0
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __$1_H__ */]]></text>
|
||||
<tag>gobject</tag>
|
||||
<description>GObject template</description>
|
||||
</snippet>
|
||||
<snippet id="ginterface">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
#include <${2:glib-object.h}>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
$<
|
||||
global camel_str
|
||||
components = $1.split('_')
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:])
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:])
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
|
||||
items = [ \
|
||||
['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \
|
||||
['#define ' + $1 + '(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + '))'], \
|
||||
['#define ' + is_str + '(obj)', '(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ' + type_str + '))'], \
|
||||
['#define ' + $1 + '_GET_INTERFACE(obj)', '(G_TYPE_INSTANCE_GET_INTERFACE ((obj), ' + type_str + ', ' + camel_str + 'Iface))']
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
$<[1]:
|
||||
items = [ \
|
||||
['typedef struct _' + camel_str, camel_str + ';'], \
|
||||
['typedef struct _' + camel_str + 'Iface', camel_str + 'Iface;'], \
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
struct _$<[1]: return camel_str >Iface
|
||||
{
|
||||
${7:GTypeInterface} parent;
|
||||
|
||||
const gchar * (*example_method) ($<[1]: return camel_str > *self);
|
||||
};
|
||||
|
||||
GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST;
|
||||
|
||||
const gchar *$< return $1.lower()>_example_method ($<[1]: return camel_str > *self);
|
||||
$0
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __$1_H__ */]]></text>
|
||||
<tag>ginterface</tag>
|
||||
<description>GObject interface</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,183 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="cpp">
|
||||
<snippet id="main">
|
||||
<text><![CDATA[int main (int argc, char const* argv[])
|
||||
{
|
||||
$0
|
||||
return 0;
|
||||
}]]></text>
|
||||
<description>main</description>
|
||||
<tag>main</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (${1:unsigned int} ${2:i} = ${3:0}; ${2:i} < ${4:count}; ${2:i} += ${5:1})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<description>for loop</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="beginend">
|
||||
<text><![CDATA[${1:v}.begin(), ${1:v}.end()]]></text>
|
||||
<description>$1.begin</description>
|
||||
<tag>beginend</tag>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
{
|
||||
$0
|
||||
} while ($1 );]]></text>
|
||||
<description>do .. while</description>
|
||||
<tag>do</tag>
|
||||
</snippet>
|
||||
<snippet id="endif">
|
||||
<text><![CDATA[#endif
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Control><Alt>period]]></accelerator>
|
||||
<description>#endif</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<description>if ..</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}"
|
||||
$0]]></text>
|
||||
<description>#include ".."</description>
|
||||
<tag>inc</tag>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}>
|
||||
$0]]></text>
|
||||
<description>#include <..></description>
|
||||
<tag>Inc</tag>
|
||||
</snippet>
|
||||
<snippet id="namespace">
|
||||
<text><![CDATA[namespace ${1:ns}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<description>namespace ..</description>
|
||||
<tag>namespace</tag>
|
||||
</snippet>
|
||||
<snippet id="readfile">
|
||||
<text><![CDATA[std::vector<uint8_t> v;
|
||||
if (FILE* fp = fopen (${1:"filename"}, "r"))
|
||||
{
|
||||
uint8_t buf[1024];
|
||||
while (size_t len = fread (buf, 1, sizeof (buf), fp))
|
||||
v.insert (v.end(), buf, buf + len);
|
||||
fclose(fp);
|
||||
}
|
||||
$0]]></text>
|
||||
<description>Read File Into Vector</description>
|
||||
<tag>readfile</tag>
|
||||
</snippet>
|
||||
<snippet id="map">
|
||||
<text><![CDATA[std::map<${1:key}, ${2:value}> ${3:map};
|
||||
$0]]></text>
|
||||
<description>std::map</description>
|
||||
<tag>map</tag>
|
||||
</snippet>
|
||||
<snippet id="vector">
|
||||
<text><![CDATA[std::vector<${1:char}> ${2:v};
|
||||
$0]]></text>
|
||||
<description>std::vector</description>
|
||||
<tag>vector</tag>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<description>struct ..</description>
|
||||
<tag>struct</tag>
|
||||
</snippet>
|
||||
<snippet id="template">
|
||||
<text><![CDATA[template <typename ${1:_InputIter}>]]></text>
|
||||
<description>template <typename ..></description>
|
||||
<tag>template</tag>
|
||||
</snippet>
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$XEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ($1)
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>while</tag>
|
||||
<description>while</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,557 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="CSS">
|
||||
<snippet id="background">
|
||||
<text><![CDATA[background-attachment: ${1:scroll/fixed};
|
||||
$0]]></text>
|
||||
<description>background-attachment: scroll/fixed</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-1">
|
||||
<text><![CDATA[background-color: #${1:DDD};
|
||||
$0]]></text>
|
||||
<description>background-color: color-hex</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-2">
|
||||
<text><![CDATA[background-color: ${1:red};
|
||||
$0]]></text>
|
||||
<description>background-color: color-name</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-3">
|
||||
<text><![CDATA[background-color: rgb(${1:255},${2:255},${3:255});
|
||||
$0]]></text>
|
||||
<description>background-color: color-rgb</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-4">
|
||||
<text><![CDATA[background: #${1:DDD} url($2) ${3:repeat/repeat-x/repeat-y/no-repeat} ${4:scroll/fixed} ${5:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos};
|
||||
$0]]></text>
|
||||
<description>background: color image repeat attachment position</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-5">
|
||||
<text><![CDATA[background-color: transparent;
|
||||
$0]]></text>
|
||||
<description>background-color: transparent</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-6">
|
||||
<text><![CDATA[background-image: none;
|
||||
$0]]></text>
|
||||
<description>background-image: none</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-7">
|
||||
<text><![CDATA[background-image: url($1);
|
||||
$0]]></text>
|
||||
<description>background-image: url</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-8">
|
||||
<text><![CDATA[background-position: ${1:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos};
|
||||
$0]]></text>
|
||||
<description>background-position: position</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-9">
|
||||
<text><![CDATA[background-repeat: ${1:repeat/repeat-x/repeat-y/no-repeat};
|
||||
$0]]></text>
|
||||
<description>background-repeat: r/r-x/r-y/n-r</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="border">
|
||||
<text><![CDATA[border-bottom-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom-color: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-1">
|
||||
<text><![CDATA[border-bottom: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-2">
|
||||
<text><![CDATA[border-bottom-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-bottom-style: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-3">
|
||||
<text><![CDATA[border-bottom-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom-width: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-4">
|
||||
<text><![CDATA[border-color: ${1:999};
|
||||
$0]]></text>
|
||||
<description>border-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-5">
|
||||
<text><![CDATA[border-right-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-left-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-6">
|
||||
<text><![CDATA[border-left: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-left: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-7">
|
||||
<text><![CDATA[border-left-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-left-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-8">
|
||||
<text><![CDATA[border-left-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-left-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-9">
|
||||
<text><![CDATA[border-right-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-right-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-10">
|
||||
<text><![CDATA[border-right: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-right: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-11">
|
||||
<text><![CDATA[border-right-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-right-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-12">
|
||||
<text><![CDATA[border-right-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-right-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-13">
|
||||
<text><![CDATA[border: ${1:1px} ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-14">
|
||||
<text><![CDATA[border-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-15">
|
||||
<text><![CDATA[border-top-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-top-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-16">
|
||||
<text><![CDATA[border-top: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-top: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-17">
|
||||
<text><![CDATA[border-top-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-top-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-18">
|
||||
<text><![CDATA[border-top-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-top-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-19">
|
||||
<text><![CDATA[border-color: ${1:1px};
|
||||
$0]]></text>
|
||||
<description>border-width: width</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="clear">
|
||||
<text><![CDATA[clear: ${1:left/right/both/none};
|
||||
$0]]></text>
|
||||
<description>clear: value</description>
|
||||
<tag>clear</tag>
|
||||
</snippet>
|
||||
<snippet id="color">
|
||||
<text><![CDATA[color: #${1:DDD};
|
||||
$0]]></text>
|
||||
<description>color: color-hex</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="color-1">
|
||||
<text><![CDATA[color: ${1:red};
|
||||
$0]]></text>
|
||||
<description>color: color-name</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="color-2">
|
||||
<text><![CDATA[color: rgb(${1:255},${2:255},${3:255});
|
||||
$0]]></text>
|
||||
<description>color: color-rgb</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="cursor">
|
||||
<text><![CDATA[cursor: {$1:default/auto/crosshair/pointer/move/*-resize/text/wait/help};
|
||||
$0]]></text>
|
||||
<description>cursor: type</description>
|
||||
<tag>cursor</tag>
|
||||
</snippet>
|
||||
<snippet id="clear-1">
|
||||
<text><![CDATA[cursor: url($1);
|
||||
$0]]></text>
|
||||
<description>cursor: url</description>
|
||||
<tag>clear</tag>
|
||||
</snippet>
|
||||
<snippet id="direction">
|
||||
<text><![CDATA[direction: ${1:ltr|rtl};
|
||||
$0]]></text>
|
||||
<description>direction: ltr|rtl</description>
|
||||
<tag>direction</tag>
|
||||
</snippet>
|
||||
<snippet id="display">
|
||||
<text><![CDATA[display: block;
|
||||
$0]]></text>
|
||||
<description>display: block</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-1">
|
||||
<text><![CDATA[display: ${1:none/inline/block/list-item/run-in/compact/marker};
|
||||
$0]]></text>
|
||||
<description>display: common-types</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-2">
|
||||
<text><![CDATA[display: inline;
|
||||
$0]]></text>
|
||||
<description>display: inline</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-3">
|
||||
<text><![CDATA[display: ${1:table/inline-table/table-row-group/table-header-group/table-footer-group/table-row/table-column-group/table-column/table-cell/table-caption};
|
||||
$0]]></text>
|
||||
<description>display: table-types</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="float">
|
||||
<text><![CDATA[float: ${1:left/right/none};
|
||||
$0]]></text>
|
||||
<description>float: left/right/none</description>
|
||||
<tag>float</tag>
|
||||
</snippet>
|
||||
<snippet id="font">
|
||||
<text><![CDATA[font-family: ${1:Arial, "MS Trebuchet"}, ${2:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font-family: family</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-1">
|
||||
<text><![CDATA[font: ${1:75%} ${2:"Lucida Grande", "Trebuchet MS", Verdana,} ${3:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font: size font</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-2">
|
||||
<text><![CDATA[font-size: ${1:100%};
|
||||
$0]]></text>
|
||||
<description>font-size: size</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-3">
|
||||
<text><![CDATA[font-style: ${1:normal/italic/oblique};
|
||||
$0]]></text>
|
||||
<description>font-style: normal/italic/oblique</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-4">
|
||||
<text><![CDATA[font: ${1:normal/italic/oblique} ${2:normal/small-caps} ${3:normal/bold} ${4:1em/1.5em} ${5:Arial}, ${6:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font: style variant weight size/line-height font-family</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-5">
|
||||
<text><![CDATA[font-variant: ${1:normal/small-caps};
|
||||
$0]]></text>
|
||||
<description>font-variant: normal/small-caps</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-6">
|
||||
<text><![CDATA[font-weight: ${1:normal/bold};
|
||||
$0]]></text>
|
||||
<description>font-weight: weight</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="letter">
|
||||
<text><![CDATA[letter-spacing: $1em;
|
||||
$0]]></text>
|
||||
<description>letter-spacing: length-em</description>
|
||||
<tag>letter</tag>
|
||||
</snippet>
|
||||
<snippet id="letter-1">
|
||||
<text><![CDATA[letter-spacing: $1px;
|
||||
$0]]></text>
|
||||
<description>letter-spacing: length-px</description>
|
||||
<tag>letter</tag>
|
||||
</snippet>
|
||||
<snippet id="list">
|
||||
<text><![CDATA[list-style-image: url($1);
|
||||
$0]]></text>
|
||||
<description>list-style-image: url</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-1">
|
||||
<text><![CDATA[list-style-position: ${1:inside/outside};
|
||||
$0]]></text>
|
||||
<description>list-style-position: pos</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-2">
|
||||
<text><![CDATA[list-style-type: ${1:cjk-ideographic/hiragana/katakana/hiragana-iroha/katakana-iroha};
|
||||
$0]]></text>
|
||||
<description>list-style-type: asian</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-3">
|
||||
<text><![CDATA[list-style-type: ${1:none/disc/circle/square};
|
||||
$0]]></text>
|
||||
<description>list-style-type: marker</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-4">
|
||||
<text><![CDATA[list-style-type: ${1:decimal/decimal-leading-zero/zero};
|
||||
$0]]></text>
|
||||
<description>list-style-type: numeric</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-5">
|
||||
<text><![CDATA[list-style-type: ${1:hebrew/armenian/georgian};
|
||||
$0]]></text>
|
||||
<description>list-style-type: other</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-6">
|
||||
<text><![CDATA[list-style: ${1:none/disc/circle/square/decimal/zero} ${2:inside/outside} url($3);
|
||||
$0]]></text>
|
||||
<description>list-style: type position image</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-7">
|
||||
<text><![CDATA[list-style-type: ${1:lower-roman/uppert-roman/lower-alpha/upper-alpha/lower-greek/lower-latin/upper-latin};
|
||||
$0]]></text>
|
||||
<description>list-style-type: roman-alpha-greek</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="margin">
|
||||
<text><![CDATA[margin: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin: all</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-1">
|
||||
<text><![CDATA[margin-bottom: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-bottom: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-2">
|
||||
<text><![CDATA[margin-left: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-left: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-3">
|
||||
<text><![CDATA[margin-right: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-right: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-4">
|
||||
<text><![CDATA[margin-top: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-top: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-5">
|
||||
<text><![CDATA[margin: ${1:20px} ${2:0px} ${3:40px} ${4:0px};
|
||||
$0]]></text>
|
||||
<description>margin: T R B L</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-6">
|
||||
<text><![CDATA[margin: ${1:20px} ${2:0px};
|
||||
$0]]></text>
|
||||
<description>margin: V H</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="marker">
|
||||
<text><![CDATA[marker-offset: auto;
|
||||
$0]]></text>
|
||||
<description>marker-offset: auto</description>
|
||||
<tag>marker</tag>
|
||||
</snippet>
|
||||
<snippet id="marker-1">
|
||||
<text><![CDATA[marker-offset: ${1:10px};
|
||||
$0]]></text>
|
||||
<description>marker-offset: length</description>
|
||||
<tag>marker</tag>
|
||||
</snippet>
|
||||
<snippet id="overflow">
|
||||
<text><![CDATA[overflow: ${1:visible/hidden/scroll/auto};
|
||||
$0]]></text>
|
||||
<description>overflow: type</description>
|
||||
<tag>overflow</tag>
|
||||
</snippet>
|
||||
<snippet id="padding">
|
||||
<text><![CDATA[padding: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding: all</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-7">
|
||||
<text><![CDATA[padding-bottom: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-bottom: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-8">
|
||||
<text><![CDATA[padding-left: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-left: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-9">
|
||||
<text><![CDATA[padding-right: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-right: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-10">
|
||||
<text><![CDATA[padding-top: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-top: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="padding-1">
|
||||
<text><![CDATA[padding: ${1:20px} ${2:0px} ${3:40px} ${4:0px};
|
||||
$0]]></text>
|
||||
<description>padding: T R B L</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="padding-2">
|
||||
<text><![CDATA[padding: ${1:20px} ${2:0px};
|
||||
$0]]></text>
|
||||
<description>padding: V H</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="position">
|
||||
<text><![CDATA[position: ${1:static/relative/absolute/fixed};
|
||||
$0]]></text>
|
||||
<description>position: type</description>
|
||||
<tag>position</tag>
|
||||
</snippet>
|
||||
<snippet id="{">
|
||||
<text><![CDATA[{
|
||||
/* $1 */
|
||||
$0
|
||||
]]></text>
|
||||
<description>properties { }</description>
|
||||
<tag>{</tag>
|
||||
</snippet>
|
||||
<snippet id="text">
|
||||
<text><![CDATA[text-align: ${1:left/right/center/justify};
|
||||
$0]]></text>
|
||||
<description>text-align: left/center/right</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-1">
|
||||
<text><![CDATA[text-decoration: ${1:none/underline/overline/line-through/blink};
|
||||
$0]]></text>
|
||||
<description>text-decoration: none/underline/overline/line-through/blink</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-2">
|
||||
<text><![CDATA[text-indent: ${1:10p}x;
|
||||
$0]]></text>
|
||||
<description>text-indent: length</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-3">
|
||||
<text><![CDATA[text-shadow: #${1:DDD} ${2:10px} ${3:10px} ${4:2px};
|
||||
$0]]></text>
|
||||
<description>text-shadow: color-hex x y blur</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-4">
|
||||
<text><![CDATA[text-shadow: rgb(${1:255},${2:255},${3:255}) ${4:10px} ${5:10px} ${6:2px};
|
||||
$0]]></text>
|
||||
<description>text-shadow: color-rgb x y blur</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-5">
|
||||
<text><![CDATA[text-shadow: none;
|
||||
$0]]></text>
|
||||
<description>text-shadow: none</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-6">
|
||||
<text><![CDATA[text-transform: ${1:capitalize/uppercase/lowercase};
|
||||
$0]]></text>
|
||||
<description>text-transform: capitalize/upper/lower</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-7">
|
||||
<text><![CDATA[text-transform: none;
|
||||
$0]]></text>
|
||||
<description>text-transform: none</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="vertical">
|
||||
<text><![CDATA[vertical-align: ${1:baseline/sub/super/top/text-top/middle/bottom/text-bottom/length/%};
|
||||
$0]]></text>
|
||||
<description>vertical-align: type</description>
|
||||
<tag>vertical</tag>
|
||||
</snippet>
|
||||
<snippet id="visibility">
|
||||
<text><![CDATA[visibility: ${1:visible/hidden/collapse};
|
||||
$0]]></text>
|
||||
<description>visibility: type</description>
|
||||
<tag>visibility</tag>
|
||||
</snippet>
|
||||
<snippet id="white">
|
||||
<text><![CDATA[white-space: ${1:normal/pre/nowrap};
|
||||
$0]]></text>
|
||||
<description>white-space: normal/pre/nowrap</description>
|
||||
<tag>white</tag>
|
||||
</snippet>
|
||||
<snippet id="word">
|
||||
<text><![CDATA[word-spacing: ${1:10px};
|
||||
$0]]></text>
|
||||
<description>word-spacing: length</description>
|
||||
<tag>word</tag>
|
||||
</snippet>
|
||||
<snippet id="word-1">
|
||||
<text><![CDATA[word-spacing: normal;
|
||||
$0]]></text>
|
||||
<description>word-spacing: normal</description>
|
||||
<tag>word</tag>
|
||||
</snippet>
|
||||
<snippet id="z">
|
||||
<text><![CDATA[z-index: $1;
|
||||
$0]]></text>
|
||||
<description>z-index: index</description>
|
||||
<tag>z</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,118 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="docbook">
|
||||
<!-- useful snippets from xml set -->
|
||||
<snippet id="<">
|
||||
<text><![CDATA[<${1}>$0</${1}>]]></text>
|
||||
<description>XML tag</description>
|
||||
<tag><</tag>
|
||||
</snippet>
|
||||
<snippet id="menuchoice">
|
||||
<text><![CDATA[<menuchoice><guimenu>$1</guimenu><guimenuitem>$2</guimenuitem></menuchoice>
|
||||
]]></text>
|
||||
<tag>menu</tag>
|
||||
<description>menuchoice</description>
|
||||
<accelerator />
|
||||
</snippet>
|
||||
<snippet id="keycombo">
|
||||
<text><![CDATA[<keycombo><keycap>${1:Ctrl}</keycap><keycap>${2}</keycap></keycombo>]]></text>
|
||||
<tag>key</tag>
|
||||
<description>keycombo</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="sect">
|
||||
<text><![CDATA[<sect${1} id="${2}">
|
||||
<title>${3}</title>
|
||||
</sect${1}>]]></text>
|
||||
<tag>sect</tag>
|
||||
<description>sect*</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="app">
|
||||
<text><![CDATA[<application>&app;</application>]]></text>
|
||||
<tag>app</tag>
|
||||
<description>app entity</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="appwrap">
|
||||
<text><![CDATA[<application>$XEDIT_SELECTED_TEXT</application>]]></text>
|
||||
<tag>application</tag>
|
||||
<description>application tag</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="enclose">
|
||||
<text><![CDATA[<${1}>$XEDIT_SELECTED_TEXT</${1}>]]></text>
|
||||
<tag>enclose</tag>
|
||||
<description>enclose selected text</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="itemizedlist">
|
||||
<text><![CDATA[<itemizedlist>
|
||||
<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>
|
||||
</itemizedlist>]]></text>
|
||||
<tag>ul</tag>
|
||||
<description>itemized list</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="orderedlist">
|
||||
<text><![CDATA[<orderedlist>
|
||||
<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>
|
||||
</orderedlist>]]></text>
|
||||
<tag>ol</tag>
|
||||
<description>ordered list</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="listitem">
|
||||
<text><![CDATA[<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>]]></text>
|
||||
<tag>li</tag>
|
||||
<description>list item</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="variablelist">
|
||||
<text><![CDATA[<variablelist>
|
||||
$1
|
||||
</variablelist>]]></text>
|
||||
<tag>vl</tag>
|
||||
<description>variablelist</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="varlistentry">
|
||||
<text><![CDATA[<varlistentry><term>${1}</term>
|
||||
<listitem>
|
||||
<para>${2}</para>
|
||||
</listitem>
|
||||
</varlistentry>]]></text>
|
||||
<tag>vli</tag>
|
||||
<description>variablelist entry</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="closepara">
|
||||
<text><![CDATA[</para>]]></text>
|
||||
<tag>/</tag>
|
||||
<description>para close</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="openpara">
|
||||
<text><![CDATA[<para>]]></text>
|
||||
<tag>p</tag>
|
||||
<description>para open</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="http">
|
||||
<text><![CDATA[<ulink type="http" url="$1">$2</ulink>]]></text>
|
||||
<tag>http</tag>
|
||||
<description>ulink http</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="yelp">
|
||||
<text><![CDATA[<ulink type="help" url="$1">$2</ulink>]]></text>
|
||||
<tag>help</tag>
|
||||
<description>ulink mate help</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,164 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<snippets language="fortran">
|
||||
<snippet id="c">
|
||||
<text><![CDATA[character(len=${1:10}) :: $0]]></text>
|
||||
<tag>c</tag>
|
||||
<description>character</description>
|
||||
</snippet>
|
||||
<snippet id="cl">
|
||||
<text><![CDATA[close(${1:unit}, status='${2:keep}')]]></text>
|
||||
<tag>cl</tag>
|
||||
<description>close</description>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do ${1:i}=$2, $3, ${4:1}
|
||||
${0:source}
|
||||
end do]]></text>
|
||||
<tag>do</tag>
|
||||
<description>do ... end do</description>
|
||||
</snippet>
|
||||
<snippet id="func">
|
||||
<text><![CDATA[function ${1:name}( ${2:parameter} )
|
||||
${3:integer/real ::} $1
|
||||
${4:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
|
||||
$1 = !result
|
||||
end function]]></text>
|
||||
<tag>func</tag>
|
||||
<description>function</description>
|
||||
</snippet>
|
||||
<snippet id="ifel">
|
||||
<text><![CDATA[if( $1 ) then
|
||||
${2:source}
|
||||
else
|
||||
${0:source}
|
||||
end if]]></text>
|
||||
<tag>ifel</tag>
|
||||
<description>if ... else ... end if</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if( $1 ) then
|
||||
${0:source}
|
||||
end if]]></text>
|
||||
<tag>if</tag>
|
||||
<description>if ... end if</description>
|
||||
</snippet>
|
||||
<snippet id="i">
|
||||
<text><![CDATA[integer(kind=${1:4}) :: $0]]></text>
|
||||
<tag>i</tag>
|
||||
<description>integer</description>
|
||||
</snippet>
|
||||
<snippet id="ida">
|
||||
<text><![CDATA[integer(kind=${1:4}), dimension(${2::}), allocatable :: $0]]></text>
|
||||
<tag>ida</tag>
|
||||
<description>integerdimalloc</description>
|
||||
</snippet>
|
||||
<snippet id="id">
|
||||
<text><![CDATA[integer(kind=${1:4}), dimension(${2::}) :: $0]]></text>
|
||||
<tag>id</tag>
|
||||
<description>integerdim</description>
|
||||
</snippet>
|
||||
<snippet id="l">
|
||||
<text><![CDATA[logical(kind=${1:1}) :: $0]]></text>
|
||||
<tag>l</tag>
|
||||
<description>logical</description>
|
||||
</snippet>
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:name}
|
||||
implicit none
|
||||
${2:integer/real ::} $3
|
||||
|
||||
${4:contains}
|
||||
|
||||
${0:source}
|
||||
end module]]></text>
|
||||
<tag>mod</tag>
|
||||
<description>module</description>
|
||||
</snippet>
|
||||
<snippet id="op">
|
||||
<text><![CDATA[open(${1:unit}, file='${2:name}', status='${3:new}')]]></text>
|
||||
<tag>op</tag>
|
||||
<description>open</description>
|
||||
</snippet>
|
||||
<snippet id="prog">
|
||||
<text><![CDATA[program ${1:name}
|
||||
implicit none
|
||||
|
||||
${0:source}
|
||||
end program]]></text>
|
||||
<tag>prog</tag>
|
||||
<description>program</description>
|
||||
</snippet>
|
||||
<snippet id="re">
|
||||
<text><![CDATA[read(unit=${1:*},fmt=${2:*}) $0]]></text>
|
||||
<tag>re</tag>
|
||||
<description>read</description>
|
||||
</snippet>
|
||||
<snippet id="r">
|
||||
<text><![CDATA[real(kind=${1:8}) :: $0]]></text>
|
||||
<tag>r</tag>
|
||||
<description>real</description>
|
||||
</snippet>
|
||||
<snippet id="rda">
|
||||
<text><![CDATA[real(kind=${1:8}), dimension(${2::}), allocatable :: $0]]></text>
|
||||
<tag>rda</tag>
|
||||
<description>realdimalloc</description>
|
||||
</snippet>
|
||||
<snippet id="rd">
|
||||
<text><![CDATA[real(kind=${1:8}), dimension(${2::}) :: $0]]></text>
|
||||
<tag>rd</tag>
|
||||
<description>realdim</description>
|
||||
</snippet>
|
||||
<snippet id="rec">
|
||||
<text><![CDATA[recursive function ${1:name}( ${2:parameter} ) result( ${3:res} )
|
||||
${4:integer/real ::} $3
|
||||
${5:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
|
||||
$3 = !result
|
||||
end function]]></text>
|
||||
<tag>rec</tag>
|
||||
<description>recursivfunc</description>
|
||||
</snippet>
|
||||
<snippet id="sel">
|
||||
<text><![CDATA[select case( $1 )
|
||||
case( $2 )
|
||||
${3:source}
|
||||
case default
|
||||
${0:source}
|
||||
end select]]></text>
|
||||
<tag>sel</tag>
|
||||
<description>select</description>
|
||||
</snippet>
|
||||
<snippet id="sub">
|
||||
<text><![CDATA[subroutine ${1:name}( ${2:parameter} )
|
||||
${3:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
end subroutine]]></text>
|
||||
<tag>sub</tag>
|
||||
<description>subroutine</description>
|
||||
</snippet>
|
||||
<snippet id="t">
|
||||
<text><![CDATA[type :: ${1:name}
|
||||
${2:integer/real ::} $0
|
||||
end type $1]]></text>
|
||||
<tag>t</tag>
|
||||
<description>type</description>
|
||||
</snippet>
|
||||
<snippet id="dow">
|
||||
<text><![CDATA[do while( ${1} )
|
||||
${0:source}
|
||||
end do]]></text>
|
||||
<tag>dow</tag>
|
||||
<description>while</description>
|
||||
</snippet>
|
||||
<snippet id="wr">
|
||||
<text><![CDATA[write(unit=${1:*},fmt=${2:*}) "$3", $0]]></text>
|
||||
<tag>wr</tag>
|
||||
<description>write</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets/>
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Haskell">
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:Main} where
|
||||
$0]]></text>
|
||||
<description>module</description>
|
||||
<tag>mod</tag>
|
||||
</snippet>
|
||||
<snippet id="\">
|
||||
<text><![CDATA[\\${1:t} -> ${1:t}]]></text>
|
||||
<description>\t -> t</description>
|
||||
<tag>\</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,246 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="HTML">
|
||||
<snippet id="doctype">
|
||||
<text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
]]></text>
|
||||
<description>HTML — 4.01 Strict</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-1">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Frameset</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-2">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Strict</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-3">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Transitional</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-4">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.1</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-5">
|
||||
<text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
]]></text>
|
||||
<description>HTML — 4.0 Transitional</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="author">
|
||||
<text><![CDATA[<meta name="author" content="${1:author}" />
|
||||
$0]]></text>
|
||||
<tag>author</tag>
|
||||
<description>Author</description>
|
||||
</snippet>
|
||||
<snippet id="date">
|
||||
<text><![CDATA[<meta name="date" content="$<1: import time; return time.strftime("%Y-%m-%d") >" />
|
||||
$0]]></text>
|
||||
<tag>date</tag>
|
||||
<description>Date</description>
|
||||
</snippet>
|
||||
<snippet id="ref">
|
||||
<text><![CDATA[<a href="${1:http://somesite.com/}">${2:$XEDIT_SELECTED_TEXT}</a>
|
||||
]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>l]]></accelerator>
|
||||
<description>Wrap Selection as Link</description>
|
||||
<tag>ref</tag>
|
||||
</snippet>
|
||||
<snippet id="open/close">
|
||||
<text><![CDATA[<${1:p}>$XEDIT_SELECTED_TEXT</${1}>]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>w]]></accelerator>
|
||||
<description>Wrap Selection in Open/Close Tag</description>
|
||||
</snippet>
|
||||
<snippet id="mailto">
|
||||
<text><![CDATA[<a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a> $0]]></text>
|
||||
<description>Mail Anchor</description>
|
||||
<tag>mailto</tag>
|
||||
</snippet>
|
||||
<snippet id="base">
|
||||
<text><![CDATA[<base href="$1" ${2}/>$0]]></text>
|
||||
<description>Base</description>
|
||||
<tag>base</tag>
|
||||
</snippet>
|
||||
<snippet id="body">
|
||||
<text><![CDATA[<body id="${1:ID} " onload="$2"}>
|
||||
$0
|
||||
</body>]]></text>
|
||||
<description>Body</description>
|
||||
<tag>body</tag>
|
||||
</snippet>
|
||||
<snippet id="br">
|
||||
<text><![CDATA[<br />
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Shift><Control>space]]></accelerator>
|
||||
<description>Br</description>
|
||||
</snippet>
|
||||
<snippet id="button">
|
||||
<text><![CDATA[<button type="button" name="${1:name}" value="${2:caption}" onclick="$3" />$4
|
||||
]]></text>
|
||||
<tag>button</tag>
|
||||
<description>Button</description>
|
||||
</snippet>
|
||||
<snippet id="div">
|
||||
<text><![CDATA[<div ${1}>
|
||||
${0:$XEDIT_SELECTED_TEXT}
|
||||
</div>]]></text>
|
||||
<description>Div</description>
|
||||
<tag>div</tag>
|
||||
</snippet>
|
||||
<snippet id="file">
|
||||
<text><![CDATA[<input type="file" name="${1:name}" size="$2" accept="$3" />$0
|
||||
]]></text>
|
||||
<tag>file</tag>
|
||||
<description>File</description>
|
||||
</snippet>
|
||||
<snippet id="form">
|
||||
<text><![CDATA[<form action="${1}" method="${2:get}">
|
||||
$0
|
||||
|
||||
<p><input type="submit" value="${3:Continue →}" /></p>
|
||||
</form>]]></text>
|
||||
<description>Form</description>
|
||||
<tag>form</tag>
|
||||
</snippet>
|
||||
<snippet id="h">
|
||||
<text><![CDATA[<h${1:1} id="${2}">${3:$XEDIT_SELECTED_TEXT}</h${1}>
|
||||
$0]]></text>
|
||||
<description>Heading</description>
|
||||
<tag>h</tag>
|
||||
</snippet>
|
||||
<snippet id="head">
|
||||
<text><![CDATA[<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<title>${1:Page Title}</title>
|
||||
$0
|
||||
</head>]]></text>
|
||||
<description>Head</description>
|
||||
<tag>head</tag>
|
||||
</snippet>
|
||||
<snippet id="image">
|
||||
<text><![CDATA[<img src="${1:path/to/file}" alt="${2:description}" title="${3:description}" width="$4" height="$5" />$0]]></text>
|
||||
<tag>img</tag>
|
||||
<description>Image</description>
|
||||
</snippet>
|
||||
<snippet id="input">
|
||||
<text><![CDATA[<input type="${1:[button,checkbox,file,hidden,image,password,radio,reset,submit,text]}" name="${2:some_name}" value="$3" id="${5}" />]]></text>
|
||||
<description>Input</description>
|
||||
<tag>input</tag>
|
||||
</snippet>
|
||||
<snippet id="li">
|
||||
<text><![CDATA[<li>$1</li>$0]]></text>
|
||||
<tag>li</tag>
|
||||
<description>List Element</description>
|
||||
</snippet>
|
||||
<snippet id="link">
|
||||
<text><![CDATA[<link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" title="${4:no title}" charset="${5:utf-8}" />]]></text>
|
||||
<description>Link</description>
|
||||
<tag>link</tag>
|
||||
</snippet>
|
||||
<snippet id="meta">
|
||||
<text><![CDATA[<meta name="${1:name}" content="${2:content}" />]]></text>
|
||||
<description>Meta</description>
|
||||
<tag>meta</tag>
|
||||
</snippet>
|
||||
<snippet id="nbsp">
|
||||
<text><![CDATA[ ]]></text>
|
||||
<accelerator><![CDATA[<Control><Alt>space]]></accelerator>
|
||||
<description>Non-Breaking Space</description>
|
||||
</snippet>
|
||||
<snippet id="noscript">
|
||||
<text><![CDATA[<noscript>$1</noscript>$0]]></text>
|
||||
<tag>noscript</tag>
|
||||
<description>Noscript</description>
|
||||
</snippet>
|
||||
<snippet id="option">
|
||||
<text><![CDATA[<option value="${1:value}">$2</option>$0]]></text>
|
||||
<tag>option</tag>
|
||||
<description>Option</description>
|
||||
</snippet>
|
||||
<snippet id="script">
|
||||
<text><![CDATA[<script type="text/javascript" language="javascript" charset="utf-8">
|
||||
// <![CDATA[
|
||||
$0
|
||||
// ]]]]><![CDATA[>
|
||||
</script>]]></text>
|
||||
<description>Script</description>
|
||||
<tag>script</tag>
|
||||
</snippet>
|
||||
<snippet id="scriptsrc">
|
||||
<text><![CDATA[<script src="$1" type="text/javascript" language="${2:javascript}" charset="${3:utf-8}" />]]></text>
|
||||
<description>Script With External Source</description>
|
||||
<tag>scriptsrc</tag>
|
||||
</snippet>
|
||||
<snippet id="select">
|
||||
<text><![CDATA[<select name="${1:name}">
|
||||
<option value="${2:value}">$3</option>
|
||||
$4
|
||||
</select>$0
|
||||
]]></text>
|
||||
<tag>select</tag>
|
||||
<description>Select</description>
|
||||
</snippet>
|
||||
<snippet id="span">
|
||||
<text><![CDATA[<span ${1}>$2</span>$0]]></text>
|
||||
<tag>span</tag>
|
||||
<description>Span</description>
|
||||
</snippet>
|
||||
<snippet id="style">
|
||||
<text><![CDATA[<style type="text/css" media="screen">
|
||||
/* <![CDATA[ */
|
||||
$0
|
||||
/* ]]]]><![CDATA[> */
|
||||
</style>
|
||||
]]></text>
|
||||
<description>Style</description>
|
||||
<tag>style</tag>
|
||||
</snippet>
|
||||
<snippet id="table">
|
||||
<text><![CDATA[<table border="${1:0}" cellspacing="${2:0}" cellpadding="${3:0}">
|
||||
<tr><th>${4:Header}</th></tr>
|
||||
<tr><td>${5:Data}</td></tr>
|
||||
$0
|
||||
</table>]]></text>
|
||||
<description>Table</description>
|
||||
<tag>table</tag>
|
||||
</snippet>
|
||||
<snippet id="textarea">
|
||||
<text><![CDATA[<textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">$0</textarea>]]></text>
|
||||
<description>Text Area</description>
|
||||
<tag>textarea</tag>
|
||||
</snippet>
|
||||
<snippet id="title">
|
||||
<text><![CDATA[<title>${1:Page Title}</title>]]></text>
|
||||
<description>Title</description>
|
||||
<tag>title</tag>
|
||||
</snippet>
|
||||
<snippet id="tr">
|
||||
<text><![CDATA[<tr><td>$1</td></tr>
|
||||
$0]]></text>
|
||||
<tag>tr</tag>
|
||||
<description>Table Row</description>
|
||||
</snippet>
|
||||
<snippet id="ul">
|
||||
<text><![CDATA[<ul>
|
||||
<li>$1</li>
|
||||
$2
|
||||
</ul>
|
||||
$0]]></text>
|
||||
<tag>ul</tag>
|
||||
<description>Unordered List</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="IDL">
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>mod</tag>
|
||||
<description>Module</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[interface ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>if</tag>
|
||||
<description>Interface</description>
|
||||
</snippet>
|
||||
<snippet id="str">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>str</tag>
|
||||
<description>Struct</description>
|
||||
</snippet>
|
||||
<snippet id="exc">
|
||||
<text><![CDATA[exception ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>exc</tag>
|
||||
<description>Exception</description>
|
||||
</snippet>
|
||||
<snippet id="seq">
|
||||
<text><![CDATA[sequence<${1:type}> ]]></text>
|
||||
<tag>seq</tag>
|
||||
<description>Sequence</description>
|
||||
</snippet>
|
||||
<snippet id="tseq">
|
||||
<text><![CDATA[typedef sequence<${1:type}> ${0:newtype};]]></text>
|
||||
<tag>tseq</tag>
|
||||
<description>Typedef Sequence</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,91 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Java">
|
||||
<snippet id="cd">
|
||||
<text><![CDATA[private static final ${1:String} ${2:var} = "$0";]]></text>
|
||||
<description>const def</description>
|
||||
<tag>cd</tag>
|
||||
</snippet>
|
||||
<snippet id="ife">
|
||||
<text><![CDATA[if ($1) { // $2
|
||||
|
||||
$0
|
||||
|
||||
} else { // $3
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
]]></text>
|
||||
<description>if .. else</description>
|
||||
<tag>ife</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if ($1) { // $2
|
||||
$0
|
||||
}]]></text>
|
||||
<description>if</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="log">
|
||||
<text><![CDATA[/** Logger for this class and subclasses. */
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
]]></text>
|
||||
<description>logger</description>
|
||||
<tag>log</tag>
|
||||
</snippet>
|
||||
<snippet id="tcf">
|
||||
<text><![CDATA[try {
|
||||
$2
|
||||
} catch (${1:Exception} e) {
|
||||
$3
|
||||
} finally {
|
||||
$4
|
||||
}
|
||||
$0]]></text>
|
||||
<description>try .. catch .. finally</description>
|
||||
<tag>tcf</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ($1) { // $2
|
||||
$0
|
||||
}]]></text>
|
||||
<description>while statement</description>
|
||||
<tag>while</tag>
|
||||
</snippet>
|
||||
<snippet id="main">
|
||||
<text><![CDATA[public static void main(String[] args) {
|
||||
${1:System.exit(0)};
|
||||
}]]></text>
|
||||
<description>main</description>
|
||||
<tag>main</tag>
|
||||
</snippet>
|
||||
<snippet id="sout">
|
||||
<text><![CDATA[System.out.println("${1}");
|
||||
$0
|
||||
]]></text>
|
||||
<description>System.out.println</description>
|
||||
<tag>sout</tag>
|
||||
</snippet>
|
||||
<snippet id="try/catch">
|
||||
<text><![CDATA[try {
|
||||
$XEDIT_SELECTED_TEXT
|
||||
}
|
||||
catch (Exception e) {
|
||||
${1:e.printStackTrace();}
|
||||
}
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>t]]></accelerator>
|
||||
<description>Wrap Selection in Try/Catch</description>
|
||||
</snippet>
|
||||
<snippet id="tc">
|
||||
<text><![CDATA[try {
|
||||
$2
|
||||
} catch (${1:Exception} e) {
|
||||
$3
|
||||
}
|
||||
$0]]></text>
|
||||
<tag>tc</tag>
|
||||
<description>try .. catch</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="JavaScript">
|
||||
<snippet id="fun">
|
||||
<text><![CDATA[function ${1:function_name} (${2:first_argument})
|
||||
{
|
||||
${0:# body...}
|
||||
}]]></text>
|
||||
<description>function</description>
|
||||
<tag>fun</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,9 +0,0 @@
|
|||
# Python snippets plugin
|
||||
lang_DATA = \
|
||||
snippets.lang
|
||||
|
||||
langdir = $(XEDIT_PLUGINS_DATA_DIR)/snippets/lang
|
||||
|
||||
EXTRA_DIST = $(lang_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,162 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
|
||||
Author: Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
Copyright (C) 2007-2008 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301 USA.
|
||||
|
||||
-->
|
||||
<language id="snippets" name="Snippets" hidden="true" version="2.0">
|
||||
<styles>
|
||||
<style id="placeholder-bounds" name="Placeholder begin and end" map-to="def:function"/>
|
||||
<style id="default-value" name="Default Value" map-to="def:string"/>
|
||||
<style id="single-placeholder" name="Single Placeholder" map-to="def:decimal"/>
|
||||
<style id="shell-placeholder" name="Shell Placeholder" map-to="def:preprocessor"/>
|
||||
<style id="python-placeholder" name="Python Placeholder" map-to="def:preprocessor"/>
|
||||
<style id="regex-placeholder" name="Regular Expression Placeholder" map-to="def:preprocessor"/>
|
||||
<style id="tabstop" name="Tabstop" map-to="def:decimal"/>
|
||||
<style id="placeholder-ref" name="Placeholder Reference" map-to="def:decimal"/>
|
||||
<style id="placeholder-def" name="Placeholder Default" map-to="def:string"/>
|
||||
<style id="escape" name="Escape" map-to="def:special-char"/>
|
||||
<style id="environmental-var" name="Environmental Variable" map-to="def:string"/>
|
||||
<style id="seperator" name="Seperator" map-to="def:shebang"/>
|
||||
<style id="regex-pattern" name="Regular Expression Pattern" map-to="def:string"/>
|
||||
<style id="replace-pattern" name="Regular Expression Replace Pattern" map-to="def:string"/>
|
||||
<style id="modifier" name="Modifier" map-to="def:keyword"/>
|
||||
</styles>
|
||||
|
||||
<definitions>
|
||||
<define-regex id="number">[0-9]+</define-regex>
|
||||
<define-regex id="tabstop">\s*((\%{number})(:))</define-regex>
|
||||
<define-regex id="number-list" extended="true">\s*(\[(\%{number}(,\%{number})*)\](:))</define-regex>
|
||||
<define-regex id="environment">\$[A-Z_]+</define-regex>
|
||||
<define-regex id="regex-pattern">((?:\\[/]|\\}|[^/}])+)</define-regex>
|
||||
|
||||
<context id="escape" style-ref="escape">
|
||||
<match>\\\$</match>
|
||||
</context>
|
||||
<context id="single-placeholder" style-ref="single-placeholder">
|
||||
<match>\$\%{number}|\${\%{number}}</match>
|
||||
</context>
|
||||
<context id="simple-placeholder-def" style-ref="default-value">
|
||||
<start>\${\%{tabstop}</start>
|
||||
<end>}</end>
|
||||
<include>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="start"/>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="end"/>
|
||||
<context sub-pattern="2" where="start" style-ref="tabstop"/>
|
||||
<context sub-pattern="3" where="start" style-ref="seperator"/>
|
||||
<context>
|
||||
<match>\\}</match>
|
||||
</context>
|
||||
<context ref="escape"/>
|
||||
<context ref="environmental-variable"/>
|
||||
</include>
|
||||
</context>
|
||||
<context id="simple-placeholder">
|
||||
<include>
|
||||
<context ref="single-placeholder"/>
|
||||
<context ref="simple-placeholder-def"/>
|
||||
</include>
|
||||
</context>
|
||||
<context id="shell-placeholder-contents">
|
||||
<include>
|
||||
<context ref="escape"/>
|
||||
<context ref="environmental-variable"/>
|
||||
<context ref="single-placeholder"/>
|
||||
</include>
|
||||
</context>
|
||||
<context id="shell-placeholder">
|
||||
<include>
|
||||
<context style-ref="shell-placeholder">
|
||||
<start>\$\(\%{tabstop}?</start>
|
||||
<end>\)</end>
|
||||
<include>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="start"/>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="end"/>
|
||||
<context sub-pattern="2" where="start" style-ref="tabstop"/>
|
||||
<context sub-pattern="3" where="start" style-ref="seperator"/>
|
||||
<context ref="shell-placeholder-contents"/>
|
||||
<context>
|
||||
<match>\\\)</match>
|
||||
</context>
|
||||
</include>
|
||||
</context>
|
||||
<context style-ref="shell-placeholder">
|
||||
<start>`\%{tabstop}?</start>
|
||||
<end>`</end>
|
||||
<include>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="start"/>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="end"/>
|
||||
<context sub-pattern="2" where="start" style-ref="tabstop"/>
|
||||
<context sub-pattern="3" where="start" style-ref="seperator"/>
|
||||
<context ref="shell-placeholder-contents"/>
|
||||
<context>
|
||||
<match>\\`</match>
|
||||
</context>
|
||||
</include>
|
||||
</context>
|
||||
</include>
|
||||
</context>
|
||||
<context id="python-placeholder">
|
||||
<start>\$<\%{tabstop}?\%{number-list}?</start>
|
||||
<end>></end>
|
||||
<include>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="start"/>
|
||||
<context sub-pattern="0" style-ref="placeholder-bounds" where="end"/>
|
||||
<context sub-pattern="2" where="start" style-ref="tabstop"/>
|
||||
<context sub-pattern="3" where="start" style-ref="seperator"/>
|
||||
<context sub-pattern="5" where="start" style-ref="tabstop"/>
|
||||
<context sub-pattern="7" where="start" style-ref="seperator"/>
|
||||
<context>
|
||||
<match>\\></match>
|
||||
</context>
|
||||
<context ref="escape"/>
|
||||
<context ref="environmental-variable"/>
|
||||
<context ref="single-placeholder"/>
|
||||
<context ref="python:python"/>
|
||||
</include>
|
||||
</context>
|
||||
<context id="regex-placeholder" style-ref="regex-placeholder">
|
||||
<match>(\${)\%{tabstop}?(?:\s*(?:(\%{number})|(\%{environment})))/\%{regex-pattern}/\%{regex-pattern}(?:[/]([a-zA-Z]*))?(})</match>
|
||||
<include>
|
||||
<context sub-pattern="1" style-ref="placeholder-bounds"/>
|
||||
<context sub-pattern="10" style-ref="placeholder-bounds"/>
|
||||
<context sub-pattern="3" style-ref="tabstop"/>
|
||||
<context sub-pattern="4" style-ref="seperator"/>
|
||||
<context sub-pattern="5" style-ref="tabstop"/>
|
||||
<context sub-pattern="6" style-ref="environmental-var"/>
|
||||
<context sub-pattern="7" style-ref="regex-pattern"/>
|
||||
<context sub-pattern="8" style-ref="replace-pattern"/>
|
||||
<context sub-pattern="9" style-ref="modifier"/>
|
||||
</include>
|
||||
</context>
|
||||
<context id="environmental-variable" style-ref="environmental-var">
|
||||
<match>\%{environment}</match>
|
||||
</context>
|
||||
<context id="snippets">
|
||||
<include>
|
||||
<context ref="escape"/>
|
||||
<context ref="regex-placeholder"/>
|
||||
<context ref="simple-placeholder"/>
|
||||
<context ref="shell-placeholder"/>
|
||||
<context ref="python-placeholder"/>
|
||||
<context ref="environmental-variable"/>
|
||||
</include>
|
||||
</context>
|
||||
</definitions>
|
||||
</language>
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="LaTeX">
|
||||
<snippet id="command">
|
||||
<text><![CDATA[{\\${1:bf} $XEDIT_SELECTED_TEXT}]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>w]]></accelerator>
|
||||
<description>Wrap Selection in Command</description>
|
||||
</snippet>
|
||||
<snippet id="$">
|
||||
<text><![CDATA[\[
|
||||
$1
|
||||
\]]]></text>
|
||||
<description>Displaymath</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="itd">
|
||||
<text><![CDATA[\item[${1:description}] ${0:item}]]></text>
|
||||
<description>\item[description]</description>
|
||||
<tag>itd</tag>
|
||||
</snippet>
|
||||
<snippet id="sec">
|
||||
<text><![CDATA[\section{${1:section name}}\label{${2:label}}
|
||||
]]></text>
|
||||
<description>Section</description>
|
||||
<tag>sec</tag>
|
||||
</snippet>
|
||||
<snippet id="sub">
|
||||
<text><![CDATA[\subsection{${1:subsection name}}\label{${2:label}}
|
||||
]]></text>
|
||||
<description>Sub Section</description>
|
||||
<tag>sub</tag>
|
||||
</snippet>
|
||||
<snippet id="ssub">
|
||||
<text><![CDATA[\subsubsection{${1:subsubsection name}}\label{${2:label}}
|
||||
]]></text>
|
||||
<description>Sub Sub Section</description>
|
||||
<tag>ssub</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,207 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<snippets language="mallard">
|
||||
<snippet>
|
||||
<text><![CDATA[<app>${1:Application's name}</app>$0]]></text>
|
||||
<tag>app</tag>
|
||||
<description>app</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<![CDATA[$0]]]]><![CDATA[>]]></text>
|
||||
<tag>cdata</tag>
|
||||
<description>cdata</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<cite>${1:Joe Example}</cite>]]></text>
|
||||
<tag>cite</tag>
|
||||
<description>cite</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<cite date="$1">${2:Joe Example}</cite>]]></text>
|
||||
<tag>cited</tag>
|
||||
<description>cite</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<desc>${1:Description}</desc>]]></text>
|
||||
<tag>desc</tag>
|
||||
<description>desc</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<em>$1</em>]]></text>
|
||||
<tag>em</tag>
|
||||
<description>em</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<figure>
|
||||
<title>${1:Title}</title>
|
||||
<desc>${2:Short description}</desc>
|
||||
<media type="${3:image}" mime="${5:image/png}" src="${4:figures/image.png}" >
|
||||
</media>
|
||||
</figure>]]></text>
|
||||
<tag>figure</tag>
|
||||
<description>figure</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<file>${0:filename}</file>]]></text>
|
||||
<tag>file</tag>
|
||||
<description>file</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<gui>$1</gui>$2]]></text>
|
||||
<tag>g</tag>
|
||||
<description>gui</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<guiseq><gui>$1</gui><gui>$2</gui></guiseq>]]></text>
|
||||
<tag>q</tag>
|
||||
<description>guiseq</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<link href="http://$1/"<$2></link>]]></text>
|
||||
<tag>http</tag>
|
||||
<description>http</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<item><p>$0</p></item>]]></text>
|
||||
<tag>item</tag>
|
||||
<description>item</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<key>$1</key>]]></text>
|
||||
<tag>key</tag>
|
||||
<description>key</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<keyseq><key>$1</key><key>$2</key></keyseq>]]></text>
|
||||
<tag>keys</tag>
|
||||
<description>keystroke</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<link type="${1:guide}" xref="${2:index}"/>]]></text>
|
||||
<tag>link</tag>
|
||||
<description>link</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<list>
|
||||
<title>${2:Title}</title>
|
||||
<item><p>${3}</p></item>
|
||||
<item><p>${4}</p></item>
|
||||
</list>]]></text>
|
||||
<tag>list</tag>
|
||||
<description>list</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<listing>
|
||||
<title>${1:Title}</title>
|
||||
<desc>${2:Short description}</desc>
|
||||
<code><![CDATA[
|
||||
$0
|
||||
]]]]><![CDATA[></code>
|
||||
</listing>]]></text>
|
||||
<tag>listing</tag>
|
||||
<description>listing</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<note style="${1:advanced|bug|important|tip|warning}">
|
||||
<p>
|
||||
$0
|
||||
</p>
|
||||
</note>]]></text>
|
||||
<tag>note</tag>
|
||||
<description>note</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<list type="numbered">
|
||||
<item><p>$1</p></item>
|
||||
<item><p>$2</p></item>
|
||||
<item><p>$3</p></item>
|
||||
</list> ]]></text>
|
||||
<tag>num</tag>
|
||||
<description>numbered list</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<page xmlns="http://projectmallard.org/1.0/"
|
||||
type="${1:topic}" style="${2:task}"
|
||||
id="${3:id}">
|
||||
|
||||
<info>
|
||||
<desc>${4:Short description}</desc>
|
||||
<revision pkgversion="${5:program_version}" version="${6:document_version}" date="$<7: import datetime as d; return d.date.isoformat(d.date.today())>" status="${8:incomplete}"/>
|
||||
<credit type="author">
|
||||
<name>$<9:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return 'Joe Example' ></name>
|
||||
<email>$<10:
|
||||
import os
|
||||
return os.getenv('EMAIL', 'joe@example.com') ></email>
|
||||
</credit>
|
||||
</info>
|
||||
|
||||
$0
|
||||
|
||||
</page>]]></text>
|
||||
<tag>page</tag>
|
||||
<description>page</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[</p>]]></text>
|
||||
<tag>/</tag>
|
||||
<description>p close</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<p>]]></text>
|
||||
<tag>p</tag>
|
||||
<description>p open</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<quote>
|
||||
<p>$0</p>
|
||||
</quote>]]></text>
|
||||
<tag>quote</tag>
|
||||
<description>quote</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<section id="${1}">
|
||||
<title>${2:Section Title}</title>
|
||||
<p>$0</p>
|
||||
</section>]]></text>
|
||||
<tag>section</tag>
|
||||
<description>section</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<steps>
|
||||
<item><p>$0</p></item>
|
||||
</steps>]]></text>
|
||||
<tag>steps</tag>
|
||||
<description>steps</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<terms>
|
||||
<title>$1</title>
|
||||
<item><p>$2</p></item>
|
||||
</terms>]]></text>
|
||||
<tag>terms</tag>
|
||||
<description>terms</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<note style="tip">
|
||||
<p>$1</p>
|
||||
</note> ]]></text>
|
||||
<tag>tip</tag>
|
||||
<description>tip note</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<title>$1</title>]]></text>
|
||||
<tag>title</tag>
|
||||
<description>title</description>
|
||||
</snippet>
|
||||
<snippet>
|
||||
<text><![CDATA[<note style="warning>
|
||||
<p>$1</p>
|
||||
</note> ]]></text>
|
||||
<tag>warn</tag>
|
||||
<description>warning note</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,126 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Perl">
|
||||
<snippet id="perl">
|
||||
<text><![CDATA[#!/usr/bin/perl
|
||||
$0]]></text>
|
||||
<tag>perl</tag>
|
||||
<description>#!/usr/bin/perl</description>
|
||||
</snippet>
|
||||
<snippet id="ife">
|
||||
<text><![CDATA[if ($1) {
|
||||
${2:# body...}
|
||||
} else {
|
||||
${3:# else...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Conditional if..else</description>
|
||||
<tag>ife</tag>
|
||||
</snippet>
|
||||
<snippet id="ifee">
|
||||
<text><![CDATA[if ($1) {
|
||||
${2:# body...}
|
||||
} elsif ($3) {
|
||||
${4:# elsif...}
|
||||
} else {
|
||||
${5:# else...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Conditional if..elsif..else</description>
|
||||
<tag>ifee</tag>
|
||||
</snippet>
|
||||
<snippet id="xunless">
|
||||
<text><![CDATA[${1:expression} unless ${2:condition};
|
||||
]]></text>
|
||||
<description>Conditional one-line</description>
|
||||
<tag>xunless</tag>
|
||||
</snippet>
|
||||
<snippet id="xif">
|
||||
<text><![CDATA[${1:expression} if ${2:condition};
|
||||
]]></text>
|
||||
<description>Conditional one-line</description>
|
||||
<tag>xif</tag>
|
||||
</snippet>
|
||||
<snippet id="eval">
|
||||
<text><![CDATA[eval {
|
||||
${1:# do something risky...}
|
||||
};
|
||||
if ($@) {
|
||||
${2:# handle failure...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Try/Except</description>
|
||||
<tag>eval</tag>
|
||||
</snippet>
|
||||
<snippet id="fore">
|
||||
<text><![CDATA[foreach ${1:my $${2:x} }(@${3:array}) {
|
||||
${4:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Loop</description>
|
||||
<tag>fore</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (my $${1:var} = 0; $$1 < ${2:expression}; $$1++) {
|
||||
${3:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Loop</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="sub">
|
||||
<text><![CDATA[sub ${1:function_name} {
|
||||
${2:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Function</description>
|
||||
<tag>sub</tag>
|
||||
</snippet>
|
||||
<snippet id="hashpointer">
|
||||
<text><![CDATA[ => ]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>l]]></accelerator>
|
||||
<description>hash pointer</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if ($1) {
|
||||
${2:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Conditional</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="xfore">
|
||||
<text><![CDATA[${1:expression} foreach @${2:array};
|
||||
]]></text>
|
||||
<description>Loop one-line</description>
|
||||
<tag>xfore</tag>
|
||||
</snippet>
|
||||
<snippet id="xwhile">
|
||||
<text><![CDATA[${1:expression} while ${2:condition};
|
||||
]]></text>
|
||||
<description>Loop one-line</description>
|
||||
<tag>xwhile</tag>
|
||||
</snippet>
|
||||
<snippet id="slurp">
|
||||
<text><![CDATA[my $${1:var};
|
||||
{ local $/ = undef; local *FILE; open FILE, "<${2:file}"; $$1 = <FILE>; close FILE }
|
||||
]]></text>
|
||||
<description>Read File</description>
|
||||
<tag>slurp</tag>
|
||||
</snippet>
|
||||
<snippet id="unless">
|
||||
<text><![CDATA[unless ($1) {
|
||||
${2:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Conditional</description>
|
||||
<tag>unless</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ($1) {
|
||||
${2:# body...}
|
||||
}
|
||||
]]></text>
|
||||
<description>Loop</description>
|
||||
<tag>while</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,224 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="PHP">
|
||||
<snippet id="class">
|
||||
<text><![CDATA[#doc
|
||||
# classname: ${1:ClassName}
|
||||
# scope: ${2:PUBLIC}
|
||||
#
|
||||
#/doc
|
||||
|
||||
class ${1:ClassName} ${3:extends AnotherClass}
|
||||
{
|
||||
# internal variables
|
||||
|
||||
# Constructor
|
||||
function __construct (${4:argument})
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}
|
||||
###
|
||||
|
||||
}
|
||||
###]]></text>
|
||||
<description>class ..</description>
|
||||
<tag>class</tag>
|
||||
</snippet>
|
||||
<snippet id="$">
|
||||
<text><![CDATA[\$_COOKIE['${1:variable}']]]></text>
|
||||
<description>COOKIE['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
} while (${1:$a <= 10});]]></text>
|
||||
<description>do .. while ..</description>
|
||||
<tag>do</tag>
|
||||
</snippet>
|
||||
<snippet id="elseif">
|
||||
<text><![CDATA[elseif (${1:condition})
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}]]></text>
|
||||
<description>elseif ..</description>
|
||||
<tag>elseif</tag>
|
||||
</snippet>
|
||||
<snippet id="else">
|
||||
<text><![CDATA[else
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}]]></text>
|
||||
<description>else ..</description>
|
||||
<tag>else</tag>
|
||||
</snippet>
|
||||
<snippet id="$-1">
|
||||
<text><![CDATA[\$_ENV['${1:variable}']]]></text>
|
||||
<description>ENV['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-2">
|
||||
<text><![CDATA[\$_FILES['${1:variable}']]]></text>
|
||||
<description>FILES['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="foreach">
|
||||
<text><![CDATA[foreach ($${1:variable} as $${2:key} => $${3:value})
|
||||
{
|
||||
# code...
|
||||
$0:
|
||||
}]]></text>
|
||||
<description>foreach ..</description>
|
||||
<tag>foreach</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for ($${1:i} = ${2:0}; $${1:i} < $3; $${1:i}++)
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}]]></text>
|
||||
<description>for ..</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="function">
|
||||
<text><![CDATA[${1:public }function ${2:FunctionName}($3)
|
||||
{
|
||||
${0:# code...}
|
||||
}]]></text>
|
||||
<description>function ..</description>
|
||||
<tag>function</tag>
|
||||
</snippet>
|
||||
<snippet id="$-3">
|
||||
<text><![CDATA[\$_GET['${1:variable}']]]></text>
|
||||
<description>GET['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="globals">
|
||||
<text><![CDATA[\$GLOBALS['${1:variable}']${2: =} ${3:something} ${4:;}]]></text>
|
||||
<description>$GLOBALS['..']</description>
|
||||
<tag>globals</tag>
|
||||
</snippet>
|
||||
<snippet id="if?">
|
||||
<text><![CDATA[$${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};]]></text>
|
||||
<description>$.. =</description>
|
||||
<tag>iff</tag>
|
||||
</snippet>
|
||||
<snippet id="ifelse">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
${2:# code...}
|
||||
}
|
||||
else
|
||||
{
|
||||
${3:# code...}
|
||||
}
|
||||
$0]]></text>
|
||||
<description>if .. else ..</description>
|
||||
<tag>ifelse</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}]]></text>
|
||||
<description>if ..</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="incl1">
|
||||
<text><![CDATA[include_once('${1:file}');$0]]></text>
|
||||
<description>include_once</description>
|
||||
<tag>inclo</tag>
|
||||
</snippet>
|
||||
<snippet id="incl">
|
||||
<text><![CDATA[include('${1:file}');$0]]></text>
|
||||
<description>include</description>
|
||||
<tag>incl</tag>
|
||||
</snippet>
|
||||
<snippet id="array">
|
||||
<text><![CDATA[$${1:arrayName} = array('$2'${3:,});]]></text>
|
||||
<description>$.. = array</description>
|
||||
<tag>array</tag>
|
||||
</snippet>
|
||||
<snippet id="php">
|
||||
<text><![CDATA[<?php
|
||||
|
||||
$0
|
||||
|
||||
?>]]></text>
|
||||
<description><?php .. ?></description>
|
||||
<tag>php</tag>
|
||||
</snippet>
|
||||
<snippet id="$-4">
|
||||
<text><![CDATA[\$_POST['${1:variable}']]]></text>
|
||||
<description>POST['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="print">
|
||||
<text><![CDATA[print "${1:string}"${2: . };]]></text>
|
||||
<description>print ".."</description>
|
||||
<tag>print</tag>
|
||||
</snippet>
|
||||
<snippet id="$-5">
|
||||
<text><![CDATA[\$_REQUEST['${1:variable}']]]></text>
|
||||
<description>REQUEST['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="req1">
|
||||
<text><![CDATA[require_once('${1:file}');]]></text>
|
||||
<description>require_once</description>
|
||||
<tag>reqo</tag>
|
||||
</snippet>
|
||||
<snippet id="req">
|
||||
<text><![CDATA[require('${1:file}');]]></text>
|
||||
<description>require</description>
|
||||
<tag>req</tag>
|
||||
</snippet>
|
||||
<snippet id="$-6">
|
||||
<text><![CDATA[\$_SERVER['${1:variable}']]]></text>
|
||||
<description>SERVER['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-7">
|
||||
<text><![CDATA[\$_SESSION['${1:variable}']]]></text>
|
||||
<description>SESSION['..']</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="case">
|
||||
<text><![CDATA[case '${1:variable}':
|
||||
# code...
|
||||
$0
|
||||
break;]]></text>
|
||||
<description>case ..</description>
|
||||
<tag>case</tag>
|
||||
</snippet>
|
||||
<snippet id="switch">
|
||||
<text><![CDATA[switch (${1:variable})
|
||||
{
|
||||
case '${2:value}':
|
||||
${3:# code...}
|
||||
break;
|
||||
|
||||
$0
|
||||
|
||||
default:
|
||||
${4:# code...}
|
||||
break;
|
||||
}]]></text>
|
||||
<description>switch ..</description>
|
||||
<tag>switch</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while (${1:$a <= 10})
|
||||
{
|
||||
# code...
|
||||
$0
|
||||
}]]></text>
|
||||
<description>while ..</description>
|
||||
<tag>while</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Python">
|
||||
<snippet id="py">
|
||||
<text><![CDATA[#!/usr/bin/env python
|
||||
#-*- coding:utf-8 -*-
|
||||
|
||||
$0]]></text>
|
||||
<description>#!/usr/bin/env python</description>
|
||||
<tag>py</tag>
|
||||
</snippet>
|
||||
<snippet id="def">
|
||||
<text><![CDATA[def ${1:fname}(${2:self}):
|
||||
${3:pass}]]></text>
|
||||
<description>New Function</description>
|
||||
<tag>def</tag>
|
||||
</snippet>
|
||||
<snippet id="doc">
|
||||
<text><![CDATA["""
|
||||
$1
|
||||
"""
|
||||
$0]]></text>
|
||||
<description>doc string</description>
|
||||
<tag>doc</tag>
|
||||
</snippet>
|
||||
<snippet id="get">
|
||||
<text><![CDATA[def get$1(self): return self._$1]]></text>
|
||||
<description>New Get Method</description>
|
||||
<tag>get</tag>
|
||||
</snippet>
|
||||
<snippet id="class">
|
||||
<text><![CDATA[class ${1:ClassName} (${2:object}):
|
||||
|
||||
def __init__(self${3:,}):
|
||||
${4:pass}
|
||||
|
||||
$0]]></text>
|
||||
<description>New Class</description>
|
||||
<tag>class</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for ${1:i} in ${2:xrange}(${3:count}):
|
||||
$0]]></text>
|
||||
<description>for loop</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="from">
|
||||
<text><![CDATA[from $1 import $2
|
||||
$0]]></text>
|
||||
<description>from</description>
|
||||
<tag>from</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if ${1:condition}:
|
||||
$0]]></text>
|
||||
<description>if</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="elif">
|
||||
<text><![CDATA[elif ${1:condition}:
|
||||
$0]]></text>
|
||||
<description>elif</description>
|
||||
<tag>elif</tag>
|
||||
</snippet>
|
||||
<snippet id="else">
|
||||
<text><![CDATA[else:
|
||||
$0]]></text>
|
||||
<description>else</description>
|
||||
<tag>else</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ${1:condition}:
|
||||
$0]]></text>
|
||||
<tag>while</tag>
|
||||
<description>while loop</description>
|
||||
</snippet>
|
||||
<snippet id="insert">
|
||||
<text><![CDATA["${1:$XEDIT_SELECTED_TEXT}"]]></text>
|
||||
<accelerator><![CDATA[<Control>2]]></accelerator>
|
||||
<description>Inside String: Insert "…"</description>
|
||||
</snippet>
|
||||
<snippet id="insert-1">
|
||||
<text><![CDATA['${1:$XEDIT_SELECTED_TEXT}']]></text>
|
||||
<accelerator><![CDATA[<Control>apostrophe]]></accelerator>
|
||||
<description>Inside String: Insert '…'</description>
|
||||
</snippet>
|
||||
<snippet id=".">
|
||||
<text><![CDATA[self.]]></text>
|
||||
<description>self</description>
|
||||
<tag>.</tag>
|
||||
</snippet>
|
||||
<snippet id="set">
|
||||
<text><![CDATA[def set$1(self, ${2:newValue}): self._$1 = $2]]></text>
|
||||
<description>New Set Method</description>
|
||||
<tag>set</tag>
|
||||
</snippet>
|
||||
<snippet id="try">
|
||||
<text><![CDATA[try:
|
||||
$1
|
||||
except ${2:Error}:
|
||||
$0]]></text>
|
||||
<tag>try</tag>
|
||||
<description>Try... Except</description>
|
||||
</snippet>
|
||||
<snippet id="main">
|
||||
<text><![CDATA[if __name__ == '__main__':
|
||||
${1:sys.exit(main())}
|
||||
|
||||
$0]]></text>
|
||||
<description>main</description>
|
||||
<tag>main</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,166 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Ruby">
|
||||
<snippet id="forin">
|
||||
<text><![CDATA[for ${1:element} in ${2:collection}
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>for .. in .. end</description>
|
||||
<tag>forin</tag>
|
||||
</snippet>
|
||||
<snippet id="inject">
|
||||
<text><![CDATA[inject(${1:object}) { |${2:injection}, ${3:element}| $0 }]]></text>
|
||||
<description>inject object</description>
|
||||
<tag>inject</tag>
|
||||
</snippet>
|
||||
<snippet id="reject">
|
||||
<text><![CDATA[reject { |${1:element}| ${1:element}.$0 }]]></text>
|
||||
<description>reject element</description>
|
||||
<tag>reject</tag>
|
||||
</snippet>
|
||||
<snippet id="select">
|
||||
<text><![CDATA[select { |${1:element}| ${1:element}.$0 }]]></text>
|
||||
<description>select element</description>
|
||||
<tag>select</tag>
|
||||
</snippet>
|
||||
<snippet id="ife">
|
||||
<text><![CDATA[if ${1:condition}
|
||||
$2
|
||||
else
|
||||
$3
|
||||
end]]></text>
|
||||
<description>if .. else .. end</description>
|
||||
<tag>ife</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if ${1:condition}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>if .. end</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="case">
|
||||
<text><![CDATA[case ${1:object}
|
||||
when ${2:condition}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>case .. end</description>
|
||||
<tag>case</tag>
|
||||
</snippet>
|
||||
<snippet id="begin">
|
||||
<text><![CDATA[begin
|
||||
$1
|
||||
rescue ${2:Exception} => ${3:e}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>begin .. rescue .. end</description>
|
||||
<tag>begin</tag>
|
||||
</snippet>
|
||||
<snippet id="class">
|
||||
<text><![CDATA[class ${1:class_name}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>class .. end</description>
|
||||
<tag>class</tag>
|
||||
</snippet>
|
||||
<snippet id="collecto">
|
||||
<text><![CDATA[collect do |${1:element}|
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>collect element do</description>
|
||||
<tag>collecto</tag>
|
||||
</snippet>
|
||||
<snippet id="collect">
|
||||
<text><![CDATA[collect { |${1:element}| ${1:element}.$0 }]]></text>
|
||||
<description>collect element</description>
|
||||
<tag>collect</tag>
|
||||
</snippet>
|
||||
<snippet id="def">
|
||||
<text><![CDATA[def ${1:method_name}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>def .. end</description>
|
||||
<tag>def</tag>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
$0
|
||||
end]]></text>
|
||||
<description>do .. end</description>
|
||||
<tag>do</tag>
|
||||
</snippet>
|
||||
<snippet id="doo">
|
||||
<text><![CDATA[do |${1:object}|
|
||||
$0
|
||||
end]]></text>
|
||||
<description>do |object| .. end</description>
|
||||
<tag>doo</tag>
|
||||
</snippet>
|
||||
<snippet id="eacho">
|
||||
<text><![CDATA[each do |${1:element}|
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>each element do</description>
|
||||
<tag>eacho</tag>
|
||||
</snippet>
|
||||
<snippet id="each">
|
||||
<text><![CDATA[each { |${1:element}| ${1:element}.$0 }]]></text>
|
||||
<description>each element</description>
|
||||
<tag>each</tag>
|
||||
</snippet>
|
||||
<snippet id="each_with_indexo">
|
||||
<text><![CDATA[each_with_index do |${1:element}, ${2:idx}|
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>each_with_index do</description>
|
||||
<tag>eachwithindexo</tag>
|
||||
</snippet>
|
||||
<snippet id="each_with_index">
|
||||
<text><![CDATA[each_with_index { |${1:element}, ${2:idx}| ${1:element}.$0 }]]></text>
|
||||
<description>each_with_index</description>
|
||||
<tag>eachwithindex</tag>
|
||||
</snippet>
|
||||
<snippet id=":">
|
||||
<text><![CDATA[:${1:key} => ${2:"value"}${3:, }]]></text>
|
||||
<description>hash pair</description>
|
||||
<tag>:</tag>
|
||||
</snippet>
|
||||
<snippet id="hashpointer">
|
||||
<text><![CDATA[ => ]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>l]]></accelerator>
|
||||
<description>hash pointer</description>
|
||||
</snippet>
|
||||
<snippet id="injecto">
|
||||
<text><![CDATA[inject(${1:object}) do |${2:injection}, ${3:element}|
|
||||
$0
|
||||
end]]></text>
|
||||
<description>inject object do</description>
|
||||
<tag>injecto</tag>
|
||||
</snippet>
|
||||
<snippet id="rejecto">
|
||||
<text><![CDATA[reject do |${1:element}|
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>reject element do</description>
|
||||
<tag>rejecto</tag>
|
||||
</snippet>
|
||||
<snippet id="selecto">
|
||||
<text><![CDATA[select do |${1:element}|
|
||||
${1:element}.$0
|
||||
end]]></text>
|
||||
<description>select element do</description>
|
||||
<tag>selecto</tag>
|
||||
</snippet>
|
||||
<snippet id="unless">
|
||||
<text><![CDATA[unless ${1:condition}
|
||||
$0
|
||||
end]]></text>
|
||||
<description>unless</description>
|
||||
<tag>unless</tag>
|
||||
</snippet>
|
||||
<snippet id="when">
|
||||
<text><![CDATA[when ${1:condition}
|
||||
$0]]></text>
|
||||
<description>when</description>
|
||||
<tag>when</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="sh">
|
||||
<snippet id="elif">
|
||||
<text><![CDATA[elif [[ ${1:condition} ]]; then
|
||||
$0]]></text>
|
||||
<description>elif ..</description>
|
||||
<tag>elif</tag>
|
||||
</snippet>
|
||||
<snippet id="case">
|
||||
<text><![CDATA[case ${1:choice} in
|
||||
${2:first})
|
||||
$3
|
||||
;;
|
||||
*)
|
||||
$4
|
||||
;;
|
||||
esac]]></text>
|
||||
<description>case ..</description>
|
||||
<tag>case</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (( ${1:i = 0}; ${2:i < 10}; ${3:i++} )); do
|
||||
$0
|
||||
done]]></text>
|
||||
<description>for .. done</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if [[ ${1:condition} ]]; then
|
||||
$0
|
||||
fi]]></text>
|
||||
<description>if .. then</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="sh">
|
||||
<text><![CDATA[#!/bin/sh
|
||||
$0]]></text>
|
||||
<description>#!/bin/sh</description>
|
||||
<tag>sh</tag>
|
||||
</snippet>
|
||||
<snippet id="bash">
|
||||
<text><![CDATA[#!/bin/bash
|
||||
$0]]></text>
|
||||
<description>#!/bin/bash</description>
|
||||
<tag>bash</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,98 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="snippets">
|
||||
<snippet id="simple">
|
||||
<text><![CDATA[\${${1:n:default}}]]></text>
|
||||
<description>Simple Placeholder</description>
|
||||
<tag>simple</tag>
|
||||
</snippet>
|
||||
<snippet id="simple-fallback">
|
||||
<text><![CDATA[\${${1:n:}[${2:default1,default2}]}]]></text>
|
||||
<description>Simple Fallback Placeholder</description>
|
||||
<tag>simplef</tag>
|
||||
</snippet>
|
||||
<snippet id="shell">
|
||||
<text><![CDATA[\$(${1:n:} ${2:shell code})]]></text>
|
||||
<description>Shell Placeholder</description>
|
||||
<tag>shell</tag>
|
||||
</snippet>
|
||||
<snippet id="python">
|
||||
<text><![CDATA[\$<${1:n:} ${2:[refs]:} return 'python code' >]]></text>
|
||||
<description>Python Placeholder</description>
|
||||
<tag>python</tag>
|
||||
</snippet>
|
||||
<snippet id="regex">
|
||||
<text><![CDATA[\${${1:n:} ${2:input}/${3:regex-pattern}/${4:replacement}/${5:modifiers}}]]></text>
|
||||
<description>Regular Expression Placeholder</description>
|
||||
<tag>regex</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_DOCUMENT_PATH">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_DOCUMENT_PATH]]></text>
|
||||
<description>Xedit Current Document Path Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_DOCUMENT_NAME">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_DOCUMENT_NAME]]></text>
|
||||
<description>Xedit Current Document Name Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_DOCUMENT_URI">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_DOCUMENT_URI]]></text>
|
||||
<description>Xedit Current Document Uri Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_DOCUMENT_SCHEME">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_DOCUMENT_SCHEME]]></text>
|
||||
<description>Xedit Current Document Scheme Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_DOCUMENT_TYPE">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_DOCUMENT_TYPE]]></text>
|
||||
<description>Xedit Current Document Type Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-DOCUMENTS_URI">
|
||||
<text><![CDATA[\$XEDIT_DOCUMENTS_URI]]></text>
|
||||
<description>Xedit Documents Uri Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-DOCUMENTS_PATH">
|
||||
<text><![CDATA[\$XEDIT_DOCUMENTS_PATH]]></text>
|
||||
<description>Xedit Documents Path Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-SELECTED_TEXT">
|
||||
<text><![CDATA[\$XEDIT_SELECTED_TEXT]]></text>
|
||||
<description>Xedit Selected Text Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_WORD">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_WORD]]></text>
|
||||
<description>Xedit Current Word Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_LINE">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_LINE]]></text>
|
||||
<description>Xedit Current Line Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-CURRENT_LINE_NUMBER">
|
||||
<text><![CDATA[\$XEDIT_CURRENT_LINE_NUMBER]]></text>
|
||||
<description>Xedit Current Line Number Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-DROP_FILENAME">
|
||||
<text><![CDATA[\$XEDIT_DROP_FILENAME]]></text>
|
||||
<description>Xedit Drop Filename Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-DROP_REL_FILENAME">
|
||||
<text><![CDATA[\$XEDIT_DROP_REL_FILENAME]]></text>
|
||||
<description>Xedit Drop Relative Filename Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
<snippet id="$-DROP_MIME_TYPE">
|
||||
<text><![CDATA[\$XEDIT_DROP_MIME_TYPE]]></text>
|
||||
<description>Xedit Drop Mime Type Variable</description>
|
||||
<tag>$</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,55 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Tcl">
|
||||
<snippet id="foreach">
|
||||
<text><![CDATA[foreach ${1:var} ${2:$list} {
|
||||
${3}
|
||||
}
|
||||
]]></text>
|
||||
<description>foreach...</description>
|
||||
<tag>foreach</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for {${1:set i 0}} {${2:$i < $n}} {${3:incr i}} {
|
||||
${4}
|
||||
}
|
||||
]]></text>
|
||||
<description>for...</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if {${1:condition}} {
|
||||
${2}
|
||||
}
|
||||
]]></text>
|
||||
<description>if...</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="proc">
|
||||
<text><![CDATA[proc ${1:name} {${2:args}} \
|
||||
{
|
||||
${3}
|
||||
}
|
||||
]]></text>
|
||||
<description>proc...</description>
|
||||
<tag>proc</tag>
|
||||
</snippet>
|
||||
<snippet id="switch">
|
||||
<text><![CDATA[switch ${1:-exact} -- ${2:$var} {
|
||||
${3:match} {
|
||||
${4}
|
||||
}
|
||||
default {${5}}
|
||||
}
|
||||
]]></text>
|
||||
<description>switch...</description>
|
||||
<tag>switch</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while {${1:condition}} {
|
||||
${2}
|
||||
}
|
||||
]]></text>
|
||||
<description>while...</description>
|
||||
<tag>while</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="XML">
|
||||
<snippet id=""">
|
||||
<text><![CDATA[<${1:name} ${2:attr}="${3:value}">$0</${1}>]]></text>
|
||||
<description>Long Attribute Tag</description>
|
||||
<tag>"</tag>
|
||||
</snippet>
|
||||
<snippet id="<">
|
||||
<text><![CDATA[<${1:name}>$0</${1}>
|
||||
|
||||
]]></text>
|
||||
<description>Long Tag</description>
|
||||
<tag><</tag>
|
||||
</snippet>
|
||||
<snippet id=">">
|
||||
<text><![CDATA[<${1:name} />]]></text>
|
||||
<description>Short Tag</description>
|
||||
<tag>></tag>
|
||||
</snippet>
|
||||
<snippet id="cdata">
|
||||
<text><![CDATA[<![CDATA[$0]]]]><![CDATA[>]]></text>
|
||||
<tag>cdata</tag>
|
||||
<description>CDATA</description>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,143 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="xslt">
|
||||
<snippet id="stylesheet">
|
||||
<text><![CDATA[<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
$0
|
||||
</xsl:stylesheet>
|
||||
]]></text>
|
||||
<description>StyleSheet</description>
|
||||
<tag>stylesheet</tag>
|
||||
</snippet>
|
||||
<snippet id="include">
|
||||
<text><![CDATA[<xsl:include href="$1"/>
|
||||
]]></text>
|
||||
<description>Include</description>
|
||||
<tag>inc</tag>
|
||||
</snippet>
|
||||
<snippet id="import">
|
||||
<text><![CDATA[<xsl:import href="$1"/>
|
||||
]]></text>
|
||||
<description>Import</description>
|
||||
<tag>imp</tag>
|
||||
</snippet>
|
||||
<snippet id="param">
|
||||
<text><![CDATA[<xsl:param name="$1"/>
|
||||
]]></text>
|
||||
<description>Parameter</description>
|
||||
<tag>param</tag>
|
||||
</snippet>
|
||||
<snippet id="template">
|
||||
<text><![CDATA[<xsl:template ${1:[match,name]}="$2" ${3:mode=""}>
|
||||
$0
|
||||
</xsl:template>
|
||||
]]></text>
|
||||
<description>Template</description>
|
||||
<tag>templ</tag>
|
||||
</snippet>
|
||||
<snippet id="variable-1">
|
||||
<text><![CDATA[<xsl:variable name="$1">
|
||||
$0
|
||||
</xsl:variable>
|
||||
]]></text>
|
||||
<description>Variable</description>
|
||||
<tag>var</tag>
|
||||
</snippet>
|
||||
<snippet id="variable-2">
|
||||
<text><![CDATA[<xsl:variable name="$1" select="$2"/>
|
||||
$0]]></text>
|
||||
<description>Variable with Select Attribute</description>
|
||||
<tag>var</tag>
|
||||
</snippet>
|
||||
<snippet id="choose">
|
||||
<text><![CDATA[<xsl:choose>
|
||||
<xsl:when test="$1">
|
||||
$2
|
||||
</xsl:when>
|
||||
$3
|
||||
</xsl:choose>
|
||||
]]></text>
|
||||
<description>Choose</description>
|
||||
<tag>choose</tag>
|
||||
</snippet>
|
||||
<snippet id="when">
|
||||
<text><![CDATA[<xsl:when test="$1">
|
||||
$2
|
||||
</xsl:when>
|
||||
$0]]></text>
|
||||
<description>When</description>
|
||||
<tag>when</tag>
|
||||
</snippet>
|
||||
<snippet id="otherwise">
|
||||
<text><![CDATA[<xsl:otherwise>
|
||||
$1
|
||||
</xsl:otherwise>
|
||||
$0]]></text>
|
||||
<description>Otherwise</description>
|
||||
<tag>otherwise</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[<xsl:if test="$1">
|
||||
$2
|
||||
</xsl:if>
|
||||
$0]]></text>
|
||||
<description>If</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="value-of">
|
||||
<text><![CDATA[<xsl:value-of select="$1"/>
|
||||
]]></text>
|
||||
<description>Value of</description>
|
||||
<tag>val</tag>
|
||||
</snippet>
|
||||
<snippet id="element">
|
||||
<text><![CDATA[<xsl:element name="$1">
|
||||
</xsl:element>
|
||||
$0]]></text>
|
||||
<description>Element</description>
|
||||
<tag>elem</tag>
|
||||
</snippet>
|
||||
<snippet id="attribute">
|
||||
<text><![CDATA[<xsl:attribute name="$1">$2</xsl:attribute>
|
||||
$0]]></text>
|
||||
<description>Attribute</description>
|
||||
<tag>attr</tag>
|
||||
</snippet>
|
||||
<snippet id="text">
|
||||
<text><![CDATA[<xsl:text>${1:$XEDIT_SELECTED_TEXT}</xsl:text>
|
||||
]]></text>
|
||||
<description>Text</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="comment">
|
||||
<text><![CDATA[<xsl:comment>${1:$XEDIT_SELECTED_TEXT}</xsl:comment>
|
||||
]]></text>
|
||||
<description>Comment</description>
|
||||
<tag>comment</tag>
|
||||
</snippet>
|
||||
<snippet id="call-template">
|
||||
<text><![CDATA[<xsl:call-template name="$1"/>
|
||||
]]></text>
|
||||
<description>Call Template</description>
|
||||
<tag>call</tag>
|
||||
</snippet>
|
||||
<snippet id="apply-templates">
|
||||
<text><![CDATA[<xsl:apply-templates mode="$1" select="$2"/>
|
||||
$0]]></text>
|
||||
<description>Apply Templates</description>
|
||||
<tag>applyt</tag>
|
||||
</snippet>
|
||||
<snippet id="apply-imports">
|
||||
<text><![CDATA[<xsl:apply-imports/>
|
||||
]]></text>
|
||||
<description>Apply Imports</description>
|
||||
<tag>applyimp</tag>
|
||||
</snippet>
|
||||
<snippet id="with-param">
|
||||
<text><![CDATA[<xsl:with-param name="$1">
|
||||
$2
|
||||
</xsl:with-param>
|
||||
$0]]></text>
|
||||
<description>With Param</description>
|
||||
<tag>with</tag>
|
||||
</snippet>
|
||||
</snippets>
|
|
@ -1,9 +0,0 @@
|
|||
[Xedit Plugin]
|
||||
Loader=python
|
||||
Module=snippets
|
||||
IAge=2
|
||||
_Name=Snippets
|
||||
_Description=Insert often-used pieces of text in a fast way
|
||||
Authors=Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
Copyright=Copyright © 2005 Jesse van den Kieboom
|
||||
Website=http://www.mate-desktop.org
|
|
@ -1,165 +0,0 @@
|
|||
import gtksourceview2 as gsv
|
||||
import gobject
|
||||
import xedit
|
||||
import gtk
|
||||
|
||||
from Library import Library
|
||||
from LanguageManager import get_language_manager
|
||||
from Snippet import Snippet
|
||||
|
||||
class Proposal(gobject.GObject, gsv.CompletionProposal):
|
||||
def __init__(self, snippet):
|
||||
gobject.GObject.__init__(self)
|
||||
self._snippet = Snippet(snippet)
|
||||
|
||||
def snippet(self):
|
||||
return self._snippet.data
|
||||
|
||||
# Interface implementation
|
||||
def do_get_markup(self):
|
||||
return self._snippet.display()
|
||||
|
||||
def do_get_info(self):
|
||||
return self._snippet.data['text']
|
||||
|
||||
class Provider(gobject.GObject, gsv.CompletionProvider):
|
||||
def __init__(self, name, language_id, handler):
|
||||
gobject.GObject.__init__(self)
|
||||
|
||||
self.name = name
|
||||
self.info_widget = None
|
||||
self.proposals = []
|
||||
self.language_id = language_id
|
||||
self.handler = handler
|
||||
self.info_widget = None
|
||||
self.mark = None
|
||||
|
||||
theme = gtk.icon_theme_get_default()
|
||||
w, h = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
|
||||
|
||||
self.icon = theme.load_icon(gtk.STOCK_JUSTIFY_LEFT, w, 0)
|
||||
|
||||
def __del__(self):
|
||||
if self.mark:
|
||||
self.mark.get_buffer().delete_mark(self.mark)
|
||||
|
||||
def set_proposals(self, proposals):
|
||||
self.proposals = proposals
|
||||
|
||||
def mark_position(self, it):
|
||||
if not self.mark:
|
||||
self.mark = it.get_buffer().create_mark(None, it, True)
|
||||
else:
|
||||
self.mark.get_buffer().move_mark(self.mark, it)
|
||||
|
||||
def get_word(self, context):
|
||||
it = context.get_iter()
|
||||
|
||||
if it.starts_word() or it.starts_line() or not it.ends_word():
|
||||
return None
|
||||
|
||||
start = it.copy()
|
||||
|
||||
if start.backward_word_start():
|
||||
self.mark_position(start)
|
||||
return start.get_text(it)
|
||||
else:
|
||||
return None
|
||||
|
||||
def do_get_start_iter(self, context, proposal):
|
||||
if not self.mark or self.mark.get_deleted():
|
||||
return None
|
||||
|
||||
return self.mark.get_buffer().get_iter_at_mark(self.mark)
|
||||
|
||||
def do_match(self, context):
|
||||
return True
|
||||
|
||||
def get_proposals(self, word):
|
||||
if self.proposals:
|
||||
proposals = self.proposals
|
||||
else:
|
||||
proposals = Library().get_snippets(None)
|
||||
|
||||
if self.language_id:
|
||||
proposals += Library().get_snippets(self.language_id)
|
||||
|
||||
# Filter based on the current word
|
||||
if word:
|
||||
proposals = filter(lambda x: x['tag'].startswith(word), proposals)
|
||||
|
||||
return map(lambda x: Proposal(x), proposals)
|
||||
|
||||
def do_populate(self, context):
|
||||
proposals = self.get_proposals(self.get_word(context))
|
||||
context.add_proposals(self, proposals, True)
|
||||
|
||||
def do_get_name(self):
|
||||
return self.name
|
||||
|
||||
def do_activate_proposal(self, proposal, piter):
|
||||
return self.handler(proposal, piter)
|
||||
|
||||
def do_get_info_widget(self, proposal):
|
||||
if not self.info_widget:
|
||||
view = xedit.View(xedit.Document())
|
||||
manager = get_language_manager()
|
||||
|
||||
lang = manager.get_language('snippets')
|
||||
view.get_buffer().set_language(lang)
|
||||
|
||||
sw = gtk.ScrolledWindow()
|
||||
sw.add(view)
|
||||
|
||||
self.info_view = view
|
||||
self.info_widget = sw
|
||||
|
||||
return self.info_widget
|
||||
|
||||
def do_update_info(self, proposal, info):
|
||||
buf = self.info_view.get_buffer()
|
||||
|
||||
buf.set_text(proposal.get_info())
|
||||
buf.move_mark(buf.get_insert(), buf.get_start_iter())
|
||||
buf.move_mark(buf.get_selection_bound(), buf.get_start_iter())
|
||||
self.info_view.scroll_to_iter(buf.get_start_iter(), False)
|
||||
|
||||
info.set_sizing(-1, -1, False, False)
|
||||
info.process_resize()
|
||||
|
||||
def do_get_icon(self):
|
||||
return self.icon
|
||||
|
||||
def do_get_activation(self):
|
||||
return gsv.COMPLETION_ACTIVATION_USER_REQUESTED
|
||||
|
||||
class Defaults(gobject.GObject, gsv.CompletionProvider):
|
||||
def __init__(self, handler):
|
||||
gobject.GObject.__init__(self)
|
||||
|
||||
self.handler = handler
|
||||
self.proposals = []
|
||||
|
||||
def set_defaults(self, defaults):
|
||||
self.proposals = []
|
||||
|
||||
for d in defaults:
|
||||
self.proposals.append(gsv.CompletionItem(d))
|
||||
|
||||
def do_get_name(self):
|
||||
return ""
|
||||
|
||||
def do_activate_proposal(self, proposal, piter):
|
||||
return self.handler(proposal, piter)
|
||||
|
||||
def do_populate(self, context):
|
||||
context.add_proposals(self, self.proposals, True)
|
||||
|
||||
def do_get_activation(self):
|
||||
return gsv.COMPLETION_ACTIVATION_NONE
|
||||
|
||||
gobject.type_register(Proposal)
|
||||
gobject.type_register(Provider)
|
||||
gobject.type_register(Defaults)
|
||||
|
||||
# ex:ts=8:et:
|
File diff suppressed because it is too large
Load Diff
|
@ -1,98 +0,0 @@
|
|||
import os
|
||||
import tempfile
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
from snippets.Library import *
|
||||
import xml.etree.ElementTree as et
|
||||
from Helper import *
|
||||
|
||||
class Exporter:
|
||||
def __init__(self, filename, snippets):
|
||||
self.filename = filename
|
||||
self.set_snippets(snippets)
|
||||
|
||||
def set_snippets(self, snippets):
|
||||
self.snippets = {}
|
||||
|
||||
for snippet in snippets:
|
||||
lang = snippet.language()
|
||||
|
||||
if lang in self.snippets:
|
||||
self.snippets[lang].append(snippet)
|
||||
else:
|
||||
self.snippets[lang] = [snippet]
|
||||
|
||||
def export_xml(self, dirname, language, snippets):
|
||||
# Create the root snippets node
|
||||
root = et.Element('snippets')
|
||||
|
||||
# Create filename based on language
|
||||
if language:
|
||||
filename = os.path.join(dirname, language + '.xml')
|
||||
|
||||
# Set the language attribute
|
||||
root.attrib['language'] = language
|
||||
else:
|
||||
filename = os.path.join(dirname, 'global.xml')
|
||||
|
||||
# Add all snippets to the root node
|
||||
for snippet in snippets:
|
||||
root.append(snippet.to_xml())
|
||||
|
||||
# Write xml
|
||||
write_xml(root, filename, ('text', 'accelerator'))
|
||||
|
||||
def export_archive(self, cmd):
|
||||
dirname = tempfile.mkdtemp()
|
||||
|
||||
# Save current working directory and change to temporary directory
|
||||
curdir = os.getcwd()
|
||||
|
||||
try:
|
||||
os.chdir(dirname)
|
||||
|
||||
# Write snippet xml files
|
||||
for language, snippets in self.snippets.items():
|
||||
self.export_xml(dirname, language , snippets)
|
||||
|
||||
# Archive files
|
||||
status = os.system('%s "%s" *.xml' % (cmd, self.filename))
|
||||
finally:
|
||||
os.chdir(curdir)
|
||||
|
||||
if status != 0:
|
||||
return _('The archive "%s" could not be created' % self.filename)
|
||||
|
||||
# Remove the temporary directory
|
||||
shutil.rmtree(dirname)
|
||||
|
||||
def export_targz(self):
|
||||
self.export_archive('tar -c --gzip -f')
|
||||
|
||||
def export_tarbz2(self):
|
||||
self.export_archive('tar -c --bzip2 -f')
|
||||
|
||||
def export_tar(self):
|
||||
self.export_archive('tar -cf')
|
||||
|
||||
def run(self):
|
||||
dirname = os.path.dirname(self.filename)
|
||||
if not os.path.exists(dirname):
|
||||
return _('Target directory "%s" does not exist') % dirname
|
||||
|
||||
if not os.path.isdir(dirname):
|
||||
return _('Target directory "%s" is not a valid directory') % dirname
|
||||
|
||||
(root, ext) = os.path.splitext(self.filename)
|
||||
|
||||
actions = {'.tar.gz': self.export_targz,
|
||||
'.tar.bz2': self.export_tarbz2,
|
||||
'.tar': self.export_tar}
|
||||
|
||||
for k, v in actions.items():
|
||||
if self.filename.endswith(k):
|
||||
return v()
|
||||
|
||||
return self.export_targz()
|
||||
# ex:ts=8:et:
|
|
@ -1,182 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# 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 re
|
||||
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
|
||||
def message_dialog(par, typ, msg):
|
||||
d = gtk.MessageDialog(par, gtk.DIALOG_MODAL, typ, gtk.BUTTONS_OK, msg)
|
||||
d.set_property('use-markup', True)
|
||||
|
||||
d.run()
|
||||
d.destroy()
|
||||
|
||||
def compute_indentation(view, piter):
|
||||
line = piter.get_line()
|
||||
start = view.get_buffer().get_iter_at_line(line)
|
||||
end = start.copy()
|
||||
|
||||
ch = end.get_char()
|
||||
|
||||
while (ch.isspace() and ch != '\r' and ch != '\n' and \
|
||||
end.compare(piter) < 0):
|
||||
if not end.forward_char():
|
||||
break;
|
||||
|
||||
ch = end.get_char()
|
||||
|
||||
if start.equal(end):
|
||||
return ''
|
||||
|
||||
return start.get_slice(end)
|
||||
|
||||
def markup_escape(text):
|
||||
return saxutils.escape(text)
|
||||
|
||||
def spaces_instead_of_tabs(view, text):
|
||||
if not view.get_insert_spaces_instead_of_tabs():
|
||||
return text
|
||||
|
||||
return text.replace("\t", view.get_tab_width() * ' ')
|
||||
|
||||
def insert_with_indent(view, piter, text, indentfirst = True, context = None):
|
||||
text = spaces_instead_of_tabs(view, text)
|
||||
lines = text.split('\n')
|
||||
|
||||
view.get_buffer().set_data('XeditSnippetsPluginContext', context)
|
||||
|
||||
if len(lines) == 1:
|
||||
view.get_buffer().insert(piter, text)
|
||||
else:
|
||||
# Compute indentation
|
||||
indent = compute_indentation(view, piter)
|
||||
text = ''
|
||||
|
||||
for i in range(0, len(lines)):
|
||||
if indentfirst or i > 0:
|
||||
text += indent + lines[i] + '\n'
|
||||
else:
|
||||
text += lines[i] + '\n'
|
||||
|
||||
view.get_buffer().insert(piter, text[:-1])
|
||||
|
||||
view.get_buffer().set_data('XeditSnippetsPluginContext', None)
|
||||
|
||||
def get_buffer_context(buf):
|
||||
return buf.get_data('XeditSnippetsPluginContext')
|
||||
|
||||
def snippets_debug(*s):
|
||||
return
|
||||
|
||||
def write_xml(node, f, cdata_nodes=()):
|
||||
assert node is not None
|
||||
|
||||
if not hasattr(f, "write"):
|
||||
f = open(f, "wb")
|
||||
|
||||
# Encoding
|
||||
f.write("<?xml version='1.0' encoding='utf-8'?>\n")
|
||||
|
||||
_write_node(node, f, cdata_nodes)
|
||||
|
||||
def _write_indent(file, text, indent):
|
||||
file.write(' ' * indent + text)
|
||||
|
||||
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)
|
||||
else:
|
||||
items = node.items()
|
||||
|
||||
if items or node.text or len(node):
|
||||
_write_indent(file, "<" + tag.encode('utf-8'), 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'))))
|
||||
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')))
|
||||
else:
|
||||
file.write("\n")
|
||||
|
||||
for n in node:
|
||||
_write_node(n, file, cdata_nodes, indent + 1)
|
||||
|
||||
if not len(node):
|
||||
file.write("</" + tag.encode('utf-8') + ">\n")
|
||||
else:
|
||||
_write_indent(file, "</" + tag.encode('utf-8') + ">\n", \
|
||||
indent)
|
||||
else:
|
||||
file.write(" />\n")
|
||||
|
||||
if node.tail and node.tail.strip() != "":
|
||||
file.write(saxutils.escape(node.tail.encode('utf-8')))
|
||||
|
||||
def _cdata(text, replace=string.replace):
|
||||
text = text.encode('utf-8')
|
||||
return '<![CDATA[' + replace(text, ']]>', ']]]]><![CDATA[>') + ']]>'
|
||||
|
||||
def buffer_word_boundary(buf):
|
||||
iter = buf.get_iter_at_mark(buf.get_insert())
|
||||
start = iter.copy()
|
||||
|
||||
if not iter.starts_word() and (iter.inside_word() or iter.ends_word()):
|
||||
start.backward_word_start()
|
||||
|
||||
if not iter.ends_word() and iter.inside_word():
|
||||
iter.forward_word_end()
|
||||
|
||||
return (start, iter)
|
||||
|
||||
def buffer_line_boundary(buf):
|
||||
iter = buf.get_iter_at_mark(buf.get_insert())
|
||||
start = iter.copy()
|
||||
start.set_line_offset(0)
|
||||
|
||||
if not iter.ends_line():
|
||||
iter.forward_to_line_end()
|
||||
|
||||
return (start, iter)
|
||||
|
||||
def drop_get_uris(selection):
|
||||
lines = re.split('\\s*[\\n\\r]+\\s*', selection.data.strip())
|
||||
result = []
|
||||
|
||||
for line in lines:
|
||||
if not line.startswith('#'):
|
||||
result.append(line)
|
||||
|
||||
return result
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,100 +0,0 @@
|
|||
import os
|
||||
import tempfile
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
from snippets.Library import *
|
||||
|
||||
class Importer:
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
|
||||
def import_destination(self, filename):
|
||||
userdir = Library().userdir
|
||||
|
||||
filename = os.path.basename(filename)
|
||||
(root, ext) = os.path.splitext(filename)
|
||||
|
||||
filename = os.path.join(userdir, root + ext)
|
||||
i = 1
|
||||
|
||||
while os.path.exists(filename):
|
||||
filename = os.path.join(userdir, root + '_' + str(i) + ext)
|
||||
i += 1
|
||||
|
||||
return filename
|
||||
|
||||
def import_file(self, filename):
|
||||
if not os.path.exists(filename):
|
||||
return _('File "%s" does not exist') % filename
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return _('File "%s" is not a valid snippets file') % filename
|
||||
|
||||
# Find destination for file to copy to
|
||||
dest = self.import_destination(filename)
|
||||
|
||||
# Copy file
|
||||
shutil.copy(filename, dest)
|
||||
|
||||
# Add library
|
||||
if not Library().add_user_library(dest):
|
||||
return _('Imported file "%s" is not a valid snippets file') % os.path.basename(dest)
|
||||
|
||||
def import_xml(self):
|
||||
return self.import_file(self.filename)
|
||||
|
||||
def import_archive(self, cmd):
|
||||
dirname = tempfile.mkdtemp()
|
||||
status = os.system('cd %s; %s "%s"' % (dirname, cmd, self.filename))
|
||||
|
||||
if status != 0:
|
||||
return _('The archive "%s" could not be extracted' % self.filename)
|
||||
|
||||
errors = []
|
||||
|
||||
# Now import all the files from the archive
|
||||
for f in os.listdir(dirname):
|
||||
f = os.path.join(dirname, f)
|
||||
|
||||
if os.path.isfile(f):
|
||||
if self.import_file(f):
|
||||
errors.append(os.path.basename(f))
|
||||
else:
|
||||
sys.stderr.write('Skipping %s, not a valid snippets file' % os.path.basename(f))
|
||||
|
||||
# Remove the temporary directory
|
||||
shutil.rmtree(dirname)
|
||||
|
||||
if len(errors) > 0:
|
||||
return _('The following files could not be imported: %s') % ', '.join(errors)
|
||||
|
||||
def import_targz(self):
|
||||
self.import_archive('tar -x --gzip -f')
|
||||
|
||||
def import_tarbz2(self):
|
||||
self.import_archive('tar -x --bzip2 -f')
|
||||
|
||||
def import_tar(self):
|
||||
self.import_archive('tar -xf')
|
||||
|
||||
def run(self):
|
||||
if not os.path.exists(self.filename):
|
||||
return _('File "%s" does not exist') % self.filename
|
||||
|
||||
if not os.path.isfile(self.filename):
|
||||
return _('File "%s" is not a valid snippets archive') % self.filename
|
||||
|
||||
(root, ext) = os.path.splitext(self.filename)
|
||||
|
||||
actions = {'.tar.gz': self.import_targz,
|
||||
'.tar.bz2': self.import_tarbz2,
|
||||
'.xml': self.import_xml,
|
||||
'.tar': self.import_tar}
|
||||
|
||||
for k, v in actions.items():
|
||||
if self.filename.endswith(k):
|
||||
return v()
|
||||
|
||||
return _('File "%s" is not a valid snippets archive') % self.filename
|
||||
# ex:ts=8:et:
|
|
@ -1,21 +0,0 @@
|
|||
import gtksourceview2 as gsv
|
||||
import os
|
||||
|
||||
from Library import Library
|
||||
|
||||
global manager
|
||||
manager = None
|
||||
|
||||
def get_language_manager():
|
||||
global manager
|
||||
|
||||
if not manager:
|
||||
dirs = []
|
||||
|
||||
for d in Library().systemdirs:
|
||||
dirs.append(os.path.join(d, 'lang'))
|
||||
|
||||
manager = gsv.LanguageManager()
|
||||
manager.set_search_path(dirs + manager.get_search_path())
|
||||
|
||||
return manager
|
|
@ -1,993 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import weakref
|
||||
import sys
|
||||
import tempfile
|
||||
import re
|
||||
|
||||
import gtk
|
||||
|
||||
import xml.etree.ElementTree as et
|
||||
from Helper import *
|
||||
|
||||
class NamespacedId:
|
||||
def __init__(self, namespace, id):
|
||||
if not id:
|
||||
self.id = None
|
||||
else:
|
||||
if namespace:
|
||||
self.id = namespace + '-'
|
||||
else:
|
||||
self.id = 'global-'
|
||||
|
||||
self.id += id
|
||||
|
||||
class SnippetData:
|
||||
PROPS = {'tag': '', 'text': '', 'description': 'New snippet',
|
||||
'accelerator': '', 'drop-targets': ''}
|
||||
|
||||
def __init__(self, node, library):
|
||||
self.priv_id = node.attrib.get('id')
|
||||
|
||||
self.set_library(library)
|
||||
self.valid = False
|
||||
self.set_node(node)
|
||||
|
||||
def can_modify(self):
|
||||
return (self.library and (isinstance(self.library(), SnippetsUserFile)))
|
||||
|
||||
def set_library(self, library):
|
||||
if library:
|
||||
self.library = weakref.ref(library)
|
||||
else:
|
||||
self.library = None
|
||||
|
||||
self.id = NamespacedId(self.language(), self.priv_id).id
|
||||
|
||||
def set_node(self, node):
|
||||
if self.can_modify():
|
||||
self.node = node
|
||||
else:
|
||||
self.node = None
|
||||
|
||||
self.init_snippet_data(node)
|
||||
|
||||
def init_snippet_data(self, node):
|
||||
if node == None:
|
||||
return
|
||||
|
||||
self.override = node.attrib.get('override')
|
||||
|
||||
self.properties = {}
|
||||
props = SnippetData.PROPS.copy()
|
||||
|
||||
# Store all properties present
|
||||
for child in node:
|
||||
if child.tag in props:
|
||||
del props[child.tag]
|
||||
|
||||
# Normalize accelerator
|
||||
if child.tag == 'accelerator' and child.text != None:
|
||||
keyval, mod = gtk.accelerator_parse(child.text)
|
||||
|
||||
if gtk.accelerator_valid(keyval, mod):
|
||||
child.text = gtk.accelerator_name(keyval, mod)
|
||||
else:
|
||||
child.text = ''
|
||||
|
||||
if self.can_modify():
|
||||
self.properties[child.tag] = child
|
||||
else:
|
||||
self.properties[child.tag] = child.text or ''
|
||||
|
||||
# Create all the props that were not found so we stay consistent
|
||||
for prop in props:
|
||||
if self.can_modify():
|
||||
child = et.SubElement(node, prop)
|
||||
|
||||
child.text = props[prop]
|
||||
self.properties[prop] = child
|
||||
else:
|
||||
self.properties[prop] = props[prop]
|
||||
|
||||
self.check_validation()
|
||||
|
||||
def check_validation(self):
|
||||
if not self['tag'] and not self['accelerator'] and not self['drop-targets']:
|
||||
return False
|
||||
|
||||
library = Library()
|
||||
keyval, mod = gtk.accelerator_parse(self['accelerator'])
|
||||
|
||||
self.valid = library.valid_tab_trigger(self['tag']) and \
|
||||
(not self['accelerator'] or library.valid_accelerator(keyval, mod))
|
||||
|
||||
def _format_prop(self, prop, value):
|
||||
if prop == 'drop-targets' and value != '':
|
||||
return re.split('\\s*[,;]\\s*', value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def __getitem__(self, prop):
|
||||
if prop in self.properties:
|
||||
if self.can_modify():
|
||||
return self._format_prop(prop, self.properties[prop].text or '')
|
||||
else:
|
||||
return self._format_prop(prop, self.properties[prop] or '')
|
||||
|
||||
return self._format_prop(prop, '')
|
||||
|
||||
def __setitem__(self, prop, value):
|
||||
if not prop in self.properties:
|
||||
return
|
||||
|
||||
if isinstance(value, list):
|
||||
value = ','.join(value)
|
||||
|
||||
if not self.can_modify() and self.properties[prop] != value:
|
||||
# ohoh, this is not can_modify, but it needs to be changed...
|
||||
# make sure it is transfered to the changes file and set all the
|
||||
# fields.
|
||||
# This snippet data container will effectively become the container
|
||||
# for the newly created node, but transparently to whoever uses
|
||||
# it
|
||||
self._override()
|
||||
|
||||
if self.can_modify() and self.properties[prop].text != value:
|
||||
if self.library():
|
||||
self.library().tainted = True
|
||||
|
||||
oldvalue = self.properties[prop].text
|
||||
self.properties[prop].text = value
|
||||
|
||||
if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets':
|
||||
container = Library().container(self.language())
|
||||
container.prop_changed(self, prop, oldvalue)
|
||||
|
||||
self.check_validation()
|
||||
|
||||
def language(self):
|
||||
if self.library and self.library():
|
||||
return self.library().language
|
||||
else:
|
||||
return None
|
||||
|
||||
def is_override(self):
|
||||
return self.override and Library().overridden[self.override]
|
||||
|
||||
def to_xml(self):
|
||||
return self._create_xml()
|
||||
|
||||
def _create_xml(self, parent=None, update=False, attrib={}):
|
||||
# Create a new node
|
||||
if parent != None:
|
||||
element = et.SubElement(parent, 'snippet', attrib)
|
||||
else:
|
||||
element = et.Element('snippet')
|
||||
|
||||
# Create all the properties
|
||||
for p in self.properties:
|
||||
prop = et.SubElement(element, p)
|
||||
prop.text = self[p]
|
||||
|
||||
if update:
|
||||
self.properties[p] = prop
|
||||
|
||||
return element
|
||||
|
||||
def _override(self):
|
||||
# Find the user file
|
||||
target = Library().get_user_library(self.language())
|
||||
|
||||
# Create a new node there with override
|
||||
element = self._create_xml(target.root, True, {'override': self.id})
|
||||
|
||||
# Create an override snippet data, feed it element so that it stores
|
||||
# all the values and then set the node to None so that it only contains
|
||||
# the values in .properties
|
||||
override = SnippetData(element, self.library())
|
||||
override.set_node(None)
|
||||
override.id = self.id
|
||||
|
||||
# Set our node to the new element
|
||||
self.node = element
|
||||
|
||||
# Set the override to our id
|
||||
self.override = self.id
|
||||
self.id = None
|
||||
|
||||
# Set the new library
|
||||
self.set_library(target)
|
||||
|
||||
# The library is tainted because we added this snippet
|
||||
target.tainted = True
|
||||
|
||||
# Add the override
|
||||
Library().overridden[self.override] = override
|
||||
|
||||
def revert(self, snippet):
|
||||
userlib = self.library()
|
||||
self.set_library(snippet.library())
|
||||
|
||||
userlib.remove(self.node)
|
||||
|
||||
self.set_node(None)
|
||||
|
||||
# Copy the properties
|
||||
self.properties = snippet.properties
|
||||
|
||||
# Set the id
|
||||
self.id = snippet.id
|
||||
|
||||
# Reset the override flag
|
||||
self.override = None
|
||||
|
||||
class SnippetsTreeBuilder(et.TreeBuilder):
|
||||
def __init__(self, start=None, end=None):
|
||||
et.TreeBuilder.__init__(self)
|
||||
self.set_start(start)
|
||||
self.set_end(end)
|
||||
|
||||
def set_start(self, start):
|
||||
self._start_cb = start
|
||||
|
||||
def set_end(self, end):
|
||||
self._end_cb = end
|
||||
|
||||
def start(self, tag, attrs):
|
||||
result = et.TreeBuilder.start(self, tag, attrs)
|
||||
|
||||
if self._start_cb:
|
||||
self._start_cb(result)
|
||||
|
||||
return result
|
||||
|
||||
def end(self, tag):
|
||||
result = et.TreeBuilder.end(self, tag)
|
||||
|
||||
if self._end_cb:
|
||||
self._end_cb(result)
|
||||
|
||||
return result
|
||||
|
||||
class LanguageContainer:
|
||||
def __init__(self, language):
|
||||
self.language = language
|
||||
self.snippets = []
|
||||
self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}}
|
||||
self.accel_group = gtk.AccelGroup()
|
||||
self._refs = 0
|
||||
|
||||
def _add_prop(self, snippet, prop, value=0):
|
||||
if value == 0:
|
||||
value = snippet[prop]
|
||||
|
||||
if not value or value == '':
|
||||
return
|
||||
|
||||
snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language))
|
||||
|
||||
if prop == 'accelerator':
|
||||
keyval, mod = gtk.accelerator_parse(value)
|
||||
self.accel_group.connect_group(keyval, mod, 0, \
|
||||
Library().accelerator_activated)
|
||||
|
||||
snippets = self.snippets_by_prop[prop]
|
||||
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
|
||||
for val in value:
|
||||
if val in snippets:
|
||||
snippets[val].append(snippet)
|
||||
else:
|
||||
snippets[val] = [snippet]
|
||||
|
||||
def _remove_prop(self, snippet, prop, value=0):
|
||||
if value == 0:
|
||||
value = snippet[prop]
|
||||
|
||||
if not value or value == '':
|
||||
return
|
||||
|
||||
snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language))
|
||||
|
||||
if prop == 'accelerator':
|
||||
keyval, mod = gtk.accelerator_parse(value)
|
||||
self.accel_group.disconnect_key(keyval, mod)
|
||||
|
||||
snippets = self.snippets_by_prop[prop]
|
||||
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
|
||||
for val in value:
|
||||
try:
|
||||
snippets[val].remove(snippet)
|
||||
except:
|
||||
True
|
||||
|
||||
def append(self, snippet):
|
||||
tag = snippet['tag']
|
||||
accelerator = snippet['accelerator']
|
||||
|
||||
self.snippets.append(snippet)
|
||||
|
||||
self._add_prop(snippet, 'tag')
|
||||
self._add_prop(snippet, 'accelerator')
|
||||
self._add_prop(snippet, 'drop-targets')
|
||||
|
||||
return snippet
|
||||
|
||||
def remove(self, snippet):
|
||||
try:
|
||||
self.snippets.remove(snippet)
|
||||
except:
|
||||
True
|
||||
|
||||
self._remove_prop(snippet, 'tag')
|
||||
self._remove_prop(snippet, 'accelerator')
|
||||
self._remove_prop(snippet, 'drop-targets')
|
||||
|
||||
def prop_changed(self, snippet, prop, oldvalue):
|
||||
snippets_debug('PROP CHANGED (', prop, ')', oldvalue)
|
||||
|
||||
self._remove_prop(snippet, prop, oldvalue)
|
||||
self._add_prop(snippet, prop)
|
||||
|
||||
def from_prop(self, prop, value):
|
||||
snippets = self.snippets_by_prop[prop]
|
||||
|
||||
if prop == 'drop-targets':
|
||||
s = []
|
||||
|
||||
# FIXME: change this to use
|
||||
# matevfs.mime_type_get_equivalence when it comes
|
||||
# available
|
||||
for key, val in snippets.items():
|
||||
if not value.startswith(key):
|
||||
continue
|
||||
|
||||
for snippet in snippets[key]:
|
||||
if not snippet in s:
|
||||
s.append(snippet)
|
||||
|
||||
return s
|
||||
else:
|
||||
if value in snippets:
|
||||
return snippets[value]
|
||||
else:
|
||||
return []
|
||||
|
||||
def ref(self):
|
||||
self._refs += 1
|
||||
|
||||
return True
|
||||
|
||||
def unref(self):
|
||||
if self._refs > 0:
|
||||
self._refs -= 1
|
||||
|
||||
return self._refs != 0
|
||||
|
||||
class SnippetsSystemFile:
|
||||
def __init__(self, path=None):
|
||||
self.path = path
|
||||
self.loaded = False
|
||||
self.language = None
|
||||
self.ok = True
|
||||
self.need_id = True
|
||||
|
||||
def load_error(self, message):
|
||||
sys.stderr.write("An error occurred loading " + self.path + ":\n")
|
||||
sys.stderr.write(message + "\nSnippets in this file will not be " \
|
||||
"available, please correct or remove the file.\n")
|
||||
|
||||
def _add_snippet(self, element):
|
||||
if not self.need_id or element.attrib.get('id'):
|
||||
self.loading_elements.append(element)
|
||||
|
||||
def set_language(self, element):
|
||||
self.language = element.attrib.get('language')
|
||||
|
||||
if self.language:
|
||||
self.language = self.language.lower()
|
||||
|
||||
def _set_root(self, element):
|
||||
self.set_language(element)
|
||||
|
||||
def _preprocess_element(self, element):
|
||||
if not self.loaded:
|
||||
if not element.tag == "snippets":
|
||||
self.load_error("Root element should be `snippets' instead " \
|
||||
"of `%s'" % element.tag)
|
||||
return False
|
||||
else:
|
||||
self._set_root(element)
|
||||
self.loaded = True
|
||||
elif element.tag != 'snippet' and not self.insnippet:
|
||||
self.load_error("Element should be `snippet' instead of `%s'" \
|
||||
% element.tag)
|
||||
return False
|
||||
else:
|
||||
self.insnippet = True
|
||||
|
||||
return True
|
||||
|
||||
def _process_element(self, element):
|
||||
if element.tag == 'snippet':
|
||||
self._add_snippet(element)
|
||||
self.insnippet = False
|
||||
|
||||
return True
|
||||
|
||||
def ensure(self):
|
||||
if not self.ok or self.loaded:
|
||||
return
|
||||
|
||||
self.load()
|
||||
|
||||
def parse_xml(self, readsize=16384):
|
||||
if not self.path:
|
||||
return
|
||||
|
||||
elements = []
|
||||
|
||||
builder = SnippetsTreeBuilder( \
|
||||
lambda node: elements.append((node, True)), \
|
||||
lambda node: elements.append((node, False)))
|
||||
|
||||
parser = et.XMLTreeBuilder(target=builder)
|
||||
self.insnippet = False
|
||||
|
||||
try:
|
||||
f = open(self.path, "r")
|
||||
|
||||
while True:
|
||||
data = f.read(readsize)
|
||||
|
||||
if not data:
|
||||
break
|
||||
|
||||
parser.feed(data)
|
||||
|
||||
for element in elements:
|
||||
yield element
|
||||
|
||||
del elements[:]
|
||||
|
||||
f.close()
|
||||
except IOError:
|
||||
self.ok = False
|
||||
|
||||
def load(self):
|
||||
if not self.ok:
|
||||
return
|
||||
|
||||
snippets_debug("Loading library (" + str(self.language) + "): " + \
|
||||
self.path)
|
||||
|
||||
self.loaded = False
|
||||
self.ok = False
|
||||
self.loading_elements = []
|
||||
|
||||
for element in self.parse_xml():
|
||||
if element[1]:
|
||||
if not self._preprocess_element(element[0]):
|
||||
del self.loading_elements[:]
|
||||
return
|
||||
else:
|
||||
if not self._process_element(element[0]):
|
||||
del self.loading_elements[:]
|
||||
return
|
||||
|
||||
for element in self.loading_elements:
|
||||
snippet = Library().add_snippet(self, element)
|
||||
|
||||
del self.loading_elements[:]
|
||||
self.ok = True
|
||||
|
||||
# This function will get the language for a file by just inspecting the
|
||||
# root element of the file. This is provided so that a cache can be built
|
||||
# for which file contains which language.
|
||||
# It returns the name of the language
|
||||
def ensure_language(self):
|
||||
if not self.loaded:
|
||||
self.ok = False
|
||||
|
||||
for element in self.parse_xml(256):
|
||||
if element[1]:
|
||||
if element[0].tag == 'snippets':
|
||||
self.set_language(element[0])
|
||||
self.ok = True
|
||||
|
||||
break
|
||||
|
||||
def unload(self):
|
||||
snippets_debug("Unloading library (" + str(self.language) + "): " + \
|
||||
self.path)
|
||||
self.language = None
|
||||
self.loaded = False
|
||||
self.ok = True
|
||||
|
||||
class SnippetsUserFile(SnippetsSystemFile):
|
||||
def __init__(self, path=None):
|
||||
SnippetsSystemFile.__init__(self, path)
|
||||
self.tainted = False
|
||||
self.need_id = False
|
||||
|
||||
def _set_root(self, element):
|
||||
SnippetsSystemFile._set_root(self, element)
|
||||
self.root = element
|
||||
|
||||
def add_prop(self, node, tag, data):
|
||||
if data[tag]:
|
||||
prop = et.SubElement(node, tag)
|
||||
prop.text = data[tag]
|
||||
|
||||
return prop
|
||||
else:
|
||||
return None
|
||||
|
||||
def new_snippet(self, properties=None):
|
||||
if (not self.ok) or self.root == None:
|
||||
return None
|
||||
|
||||
element = et.SubElement(self.root, 'snippet')
|
||||
|
||||
if properties:
|
||||
for prop in properties:
|
||||
sub = et.SubElement(element, prop)
|
||||
sub.text = properties[prop]
|
||||
|
||||
self.tainted = True
|
||||
|
||||
return Library().add_snippet(self, element)
|
||||
|
||||
def set_language(self, element):
|
||||
SnippetsSystemFile.set_language(self, element)
|
||||
|
||||
filename = os.path.basename(self.path).lower()
|
||||
|
||||
if not self.language and filename == "global.xml":
|
||||
self.modifier = True
|
||||
elif self.language and filename == self.language + ".xml":
|
||||
self.modifier = True
|
||||
else:
|
||||
self.modifier = False
|
||||
|
||||
def create_root(self, language):
|
||||
if self.loaded:
|
||||
snippets_debug('Not creating root, already loaded')
|
||||
return
|
||||
|
||||
if language:
|
||||
root = et.Element('snippets', {'language': language})
|
||||
self.path = os.path.join(Library().userdir, language.lower() + '.xml')
|
||||
else:
|
||||
root = et.Element('snippets')
|
||||
self.path = os.path.join(Library().userdir, 'global.xml')
|
||||
|
||||
self._set_root(root)
|
||||
self.loaded = True
|
||||
self.ok = True
|
||||
self.tainted = True
|
||||
self.save()
|
||||
|
||||
def remove(self, element):
|
||||
try:
|
||||
self.root.remove(element)
|
||||
self.tainted = True
|
||||
except:
|
||||
return
|
||||
|
||||
try:
|
||||
first = self.root[0]
|
||||
except:
|
||||
# No more elements, this library is useless now
|
||||
Library().remove_library(self)
|
||||
|
||||
def save(self):
|
||||
if not self.ok or self.root == None or not self.tainted:
|
||||
return
|
||||
|
||||
path = os.path.dirname(self.path)
|
||||
|
||||
try:
|
||||
if not os.path.isdir(path):
|
||||
os.makedirs(path, 0755)
|
||||
except OSError:
|
||||
# TODO: this is bad...
|
||||
sys.stderr.write("Error in making dirs\n")
|
||||
|
||||
try:
|
||||
write_xml(self.root, self.path, ('text', 'accelerator'))
|
||||
self.tainted = False
|
||||
except IOError:
|
||||
# Couldn't save, what to do
|
||||
sys.stderr.write("Could not save user snippets file to " + \
|
||||
self.path + "\n")
|
||||
|
||||
def unload(self):
|
||||
SnippetsSystemFile.unload(self)
|
||||
self.root = None
|
||||
|
||||
class Singleton(object):
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls._instance:
|
||||
cls._instance = super(Singleton, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
cls._instance.__init_once__()
|
||||
|
||||
return cls._instance
|
||||
|
||||
class Library(Singleton):
|
||||
def __init_once__(self):
|
||||
self._accelerator_activated_cb = None
|
||||
self.loaded = False
|
||||
self.check_buffer = gtk.TextBuffer()
|
||||
|
||||
def set_dirs(self, userdir, systemdirs):
|
||||
self.userdir = userdir
|
||||
self.systemdirs = systemdirs
|
||||
|
||||
self.libraries = {}
|
||||
self.containers = {}
|
||||
self.overridden = {}
|
||||
self.loaded_ids = []
|
||||
|
||||
self.loaded = False
|
||||
|
||||
def set_accelerator_callback(self, cb):
|
||||
self._accelerator_activated_cb = cb
|
||||
|
||||
def accelerator_activated(self, group, obj, keyval, mod):
|
||||
ret = False
|
||||
|
||||
if self._accelerator_activated_cb:
|
||||
ret = self._accelerator_activated_cb(group, obj, keyval, mod)
|
||||
|
||||
return ret
|
||||
|
||||
def add_snippet(self, library, element):
|
||||
container = self.container(library.language)
|
||||
overrided = self.overrided(library, element)
|
||||
|
||||
if overrided:
|
||||
overrided.set_library(library)
|
||||
snippets_debug('Snippet is overriden: ' + overrided['description'])
|
||||
return None
|
||||
|
||||
snippet = SnippetData(element, library)
|
||||
|
||||
if snippet.id in self.loaded_ids:
|
||||
snippets_debug('Not added snippet ' + str(library.language) + \
|
||||
'::' + snippet['description'] + ' (duplicate)')
|
||||
return None
|
||||
|
||||
snippet = container.append(snippet)
|
||||
snippets_debug('Added snippet ' + str(library.language) + '::' + \
|
||||
snippet['description'])
|
||||
|
||||
if snippet and snippet.override:
|
||||
self.add_override(snippet)
|
||||
|
||||
if snippet.id:
|
||||
self.loaded_ids.append(snippet.id)
|
||||
|
||||
return snippet
|
||||
|
||||
def container(self, language):
|
||||
language = self.normalize_language(language)
|
||||
|
||||
if not language in self.containers:
|
||||
self.containers[language] = LanguageContainer(language)
|
||||
|
||||
return self.containers[language]
|
||||
|
||||
def get_user_library(self, language):
|
||||
target = None
|
||||
|
||||
if language in self.libraries:
|
||||
for library in self.libraries[language]:
|
||||
if isinstance(library, SnippetsUserFile) and library.modifier:
|
||||
target = library
|
||||
elif not isinstance(library, SnippetsUserFile):
|
||||
break
|
||||
|
||||
if not target:
|
||||
# Create a new user file then
|
||||
snippets_debug('Creating a new user file for language ' + \
|
||||
str(language))
|
||||
target = SnippetsUserFile()
|
||||
target.create_root(language)
|
||||
self.add_library(target)
|
||||
|
||||
return target
|
||||
|
||||
def new_snippet(self, language, properties=None):
|
||||
language = self.normalize_language(language)
|
||||
library = self.get_user_library(language)
|
||||
|
||||
return library.new_snippet(properties)
|
||||
|
||||
def revert_snippet(self, snippet):
|
||||
# This will revert the snippet to the one it overrides
|
||||
if not snippet.can_modify() or not snippet.override in self.overridden:
|
||||
# It can't be reverted, shouldn't happen, but oh..
|
||||
return
|
||||
|
||||
# The snippet in self.overriden only contains the property contents and
|
||||
# the library it belongs to
|
||||
revertto = self.overridden[snippet.override]
|
||||
del self.overridden[snippet.override]
|
||||
|
||||
if revertto:
|
||||
snippet.revert(revertto)
|
||||
|
||||
if revertto.id:
|
||||
self.loaded_ids.append(revertto.id)
|
||||
|
||||
def remove_snippet(self, snippet):
|
||||
if not snippet.can_modify() or snippet.is_override():
|
||||
return
|
||||
|
||||
# Remove from the library
|
||||
userlib = snippet.library()
|
||||
userlib.remove(snippet.node)
|
||||
|
||||
# Remove from the container
|
||||
container = self.containers[userlib.language]
|
||||
container.remove(snippet)
|
||||
|
||||
def overrided(self, library, element):
|
||||
id = NamespacedId(library.language, element.attrib.get('id')).id
|
||||
|
||||
if id in self.overridden:
|
||||
snippet = SnippetData(element, None)
|
||||
snippet.set_node(None)
|
||||
|
||||
self.overridden[id] = snippet
|
||||
return snippet
|
||||
else:
|
||||
return None
|
||||
|
||||
def add_override(self, snippet):
|
||||
snippets_debug('Add override:', snippet.override)
|
||||
if not snippet.override in self.overridden:
|
||||
self.overridden[snippet.override] = None
|
||||
|
||||
def add_library(self, library):
|
||||
library.ensure_language()
|
||||
|
||||
if not library.ok:
|
||||
snippets_debug('Library in wrong format, ignoring')
|
||||
return False
|
||||
|
||||
snippets_debug('Adding library (' + str(library.language) + '): ' + \
|
||||
library.path)
|
||||
|
||||
if library.language in self.libraries:
|
||||
# Make sure all the user files are before the system files
|
||||
if isinstance(library, SnippetsUserFile):
|
||||
self.libraries[library.language].insert(0, library)
|
||||
else:
|
||||
self.libraries[library.language].append(library)
|
||||
else:
|
||||
self.libraries[library.language] = [library]
|
||||
|
||||
return True
|
||||
|
||||
def remove_library(self, library):
|
||||
if not library.ok:
|
||||
return
|
||||
|
||||
if library.path and os.path.isfile(library.path):
|
||||
os.unlink(library.path)
|
||||
|
||||
try:
|
||||
self.libraries[library.language].remove(library)
|
||||
except KeyError:
|
||||
True
|
||||
|
||||
container = self.containers[library.language]
|
||||
|
||||
for snippet in list(container.snippets):
|
||||
if snippet.library() == library:
|
||||
container.remove(snippet)
|
||||
|
||||
def add_user_library(self, path):
|
||||
library = SnippetsUserFile(path)
|
||||
return self.add_library(library)
|
||||
|
||||
def add_system_library(self, path):
|
||||
library = SnippetsSystemFile(path)
|
||||
return self.add_library(library)
|
||||
|
||||
def find_libraries(self, path, searched, addcb):
|
||||
snippets_debug("Finding in: " + path)
|
||||
|
||||
if not os.path.isdir(path):
|
||||
return searched
|
||||
|
||||
files = os.listdir(path)
|
||||
searched.append(path)
|
||||
|
||||
for f in files:
|
||||
f = os.path.realpath(os.path.join(path, f))
|
||||
|
||||
# Determine what language this file provides snippets for
|
||||
if os.path.isfile(f):
|
||||
addcb(f)
|
||||
|
||||
return searched
|
||||
|
||||
def normalize_language(self, language):
|
||||
if language:
|
||||
return language.lower()
|
||||
|
||||
return language
|
||||
|
||||
def remove_container(self, language):
|
||||
for snippet in self.containers[language].snippets:
|
||||
if snippet.id in self.loaded_ids:
|
||||
self.loaded_ids.remove(snippet.id)
|
||||
|
||||
if snippet.override in self.overridden:
|
||||
del self.overridden[snippet.override]
|
||||
|
||||
del self.containers[language]
|
||||
|
||||
def get_accel_group(self, language):
|
||||
language = self.normalize_language(language)
|
||||
container = self.container(language)
|
||||
|
||||
self.ensure(language)
|
||||
return container.accel_group
|
||||
|
||||
def save(self, language):
|
||||
language = self.normalize_language(language)
|
||||
|
||||
if language in self.libraries:
|
||||
for library in self.libraries[language]:
|
||||
if isinstance(library, SnippetsUserFile):
|
||||
library.save()
|
||||
else:
|
||||
break
|
||||
|
||||
def ref(self, language):
|
||||
language = self.normalize_language(language)
|
||||
|
||||
snippets_debug('Ref:', language)
|
||||
self.container(language).ref()
|
||||
|
||||
def unref(self, language):
|
||||
language = self.normalize_language(language)
|
||||
|
||||
snippets_debug('Unref:', language)
|
||||
|
||||
if language in self.containers:
|
||||
if not self.containers[language].unref() and \
|
||||
language in self.libraries:
|
||||
|
||||
for library in self.libraries[language]:
|
||||
library.unload()
|
||||
|
||||
self.remove_container(language)
|
||||
|
||||
def ensure(self, language):
|
||||
self.ensure_files()
|
||||
language = self.normalize_language(language)
|
||||
|
||||
# Ensure language as well as the global snippets (None)
|
||||
for lang in (None, language):
|
||||
if lang in self.libraries:
|
||||
# Ensure the container exists
|
||||
self.container(lang)
|
||||
|
||||
for library in self.libraries[lang]:
|
||||
library.ensure()
|
||||
|
||||
def ensure_files(self):
|
||||
if self.loaded:
|
||||
return
|
||||
|
||||
searched = []
|
||||
searched = self.find_libraries(self.userdir, searched, \
|
||||
self.add_user_library)
|
||||
|
||||
for d in self.systemdirs:
|
||||
searched = self.find_libraries(d, searched, \
|
||||
self.add_system_library)
|
||||
|
||||
self.loaded = True
|
||||
|
||||
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(gtk.keysyms.F1, gtk.keysyms.F12 + 1)))
|
||||
|
||||
def valid_tab_trigger(self, trigger):
|
||||
if not trigger:
|
||||
return True
|
||||
|
||||
if trigger.isdigit():
|
||||
return False
|
||||
|
||||
self.check_buffer.set_text(trigger)
|
||||
|
||||
start, end = self.check_buffer.get_bounds()
|
||||
text = self.check_buffer.get_text(start, end)
|
||||
|
||||
s = start.copy()
|
||||
e = end.copy()
|
||||
|
||||
end.backward_word_start()
|
||||
start.forward_word_end()
|
||||
|
||||
return (s.equal(end) and e.equal(start)) or (len(text) == 1 and not (text.isalnum() or text.isspace()))
|
||||
|
||||
# Snippet getters
|
||||
# ===============
|
||||
def _from_prop(self, prop, value, language=None):
|
||||
self.ensure_files()
|
||||
|
||||
result = []
|
||||
language = self.normalize_language(language)
|
||||
|
||||
if not language in self.containers:
|
||||
return []
|
||||
|
||||
self.ensure(language)
|
||||
result = self.containers[language].from_prop(prop, value)
|
||||
|
||||
if len(result) == 0 and language and None in self.containers:
|
||||
result = self.containers[None].from_prop(prop, value)
|
||||
|
||||
return result
|
||||
|
||||
# Get snippets for a given language
|
||||
def get_snippets(self, language=None):
|
||||
self.ensure_files()
|
||||
language = self.normalize_language(language)
|
||||
|
||||
if not language in self.libraries:
|
||||
return []
|
||||
|
||||
snippets = []
|
||||
self.ensure(language)
|
||||
|
||||
return list(self.containers[language].snippets)
|
||||
|
||||
# Get snippets for a given accelerator
|
||||
def from_accelerator(self, accelerator, language=None):
|
||||
return self._from_prop('accelerator', accelerator, language)
|
||||
|
||||
# Get snippets for a given tag
|
||||
def from_tag(self, tag, language=None):
|
||||
return self._from_prop('tag', tag, language)
|
||||
|
||||
# Get snippets for a given drop target
|
||||
def from_drop_target(self, drop_target, language=None):
|
||||
return self._from_prop('drop-targets', drop_target, language)
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,28 +0,0 @@
|
|||
# Python snippets plugin
|
||||
plugindir = $(XEDIT_PLUGINS_LIBS_DIR)/snippets
|
||||
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
WindowHelper.py \
|
||||
Document.py \
|
||||
Library.py \
|
||||
Snippet.py \
|
||||
Parser.py \
|
||||
Placeholder.py \
|
||||
Manager.py \
|
||||
Helper.py \
|
||||
SubstitutionParser.py \
|
||||
Importer.py \
|
||||
Exporter.py \
|
||||
LanguageManager.py \
|
||||
Completion.py
|
||||
|
||||
uidir = $(XEDIT_PLUGINS_DATA_DIR)/snippets/ui
|
||||
ui_DATA = snippets.ui
|
||||
|
||||
EXTRA_DIST = $(ui_DATA)
|
||||
|
||||
CLEANFILES = *.bak *.gladep *.pyc
|
||||
DISTCLEANFILES = *.bak *.gladep *.pyc
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
File diff suppressed because it is too large
Load Diff
|
@ -1,259 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2006-2007 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from SubstitutionParser import SubstitutionParser
|
||||
|
||||
class Token:
|
||||
def __init__(self, klass, data):
|
||||
self.klass = klass
|
||||
self.data = data
|
||||
|
||||
def __str__(self):
|
||||
return '%s: [%s]' % (self.klass, self.data)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.klass == other.klass and self.data == other.data
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
class Parser:
|
||||
SREG_ENV = '[A-Z_]+'
|
||||
SREG_ID = '[0-9]+'
|
||||
|
||||
REG_ESCAPE = re.compile('(\\$(%s|\\(|\\{|<|%s)|`|\\\\)' % (SREG_ENV, SREG_ID))
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
self.position = 0
|
||||
self.data_length = len(self.data)
|
||||
|
||||
self.RULES = (self._match_env, self._match_regex, self._match_placeholder, self._match_shell, self._match_eval, self._text)
|
||||
|
||||
def remains(self):
|
||||
return self.data[self.position:]
|
||||
|
||||
def next_char(self):
|
||||
if self.position + 1 >= self.data_length:
|
||||
return ''
|
||||
else:
|
||||
return self.data[self.position + 1]
|
||||
|
||||
def char(self):
|
||||
if self.position >= self.data_length:
|
||||
return ''
|
||||
else:
|
||||
return self.data[self.position]
|
||||
|
||||
def token(self):
|
||||
self.tktext = ''
|
||||
|
||||
while self.position < self.data_length:
|
||||
try:
|
||||
# Get first character
|
||||
func = {'$': self._rule,
|
||||
'`': self._try_match_shell}[self.char()]
|
||||
except:
|
||||
func = self._text
|
||||
|
||||
# Detect end of text token
|
||||
if func != self._text and self.tktext != '':
|
||||
return Token('text', self.tktext)
|
||||
|
||||
tk = func()
|
||||
|
||||
if tk:
|
||||
return tk
|
||||
|
||||
if self.tktext != '':
|
||||
return Token('text', self.tktext)
|
||||
|
||||
def _need_escape(self):
|
||||
text = self.remains()[1:]
|
||||
|
||||
if text == '':
|
||||
return False
|
||||
|
||||
return self.REG_ESCAPE.match(text)
|
||||
|
||||
def _escape(self):
|
||||
if not self._need_escape():
|
||||
return
|
||||
|
||||
# Increase position with 1
|
||||
self.position += 1
|
||||
|
||||
def _text(self):
|
||||
if self.char() == '\\':
|
||||
self._escape()
|
||||
|
||||
self.tktext += self.char()
|
||||
self.position += 1
|
||||
|
||||
def _rule(self):
|
||||
for rule in self.RULES:
|
||||
res = rule()
|
||||
|
||||
if res:
|
||||
return res
|
||||
|
||||
def _match_env(self):
|
||||
text = self.remains()
|
||||
match = re.match('\\$(%s)' % self.SREG_ENV, text) or re.match('\\${(%s)}' % self.SREG_ENV, text)
|
||||
|
||||
if match:
|
||||
self.position += len(match.group(0))
|
||||
return Token('environment', match.group(1))
|
||||
|
||||
def _parse_list(self, lst):
|
||||
pos = 0
|
||||
length = len(lst)
|
||||
items = []
|
||||
last = None
|
||||
|
||||
while pos < length:
|
||||
char = lst[pos]
|
||||
next = pos < length - 1 and lst[pos + 1]
|
||||
|
||||
if char == '\\' and (next == ',' or next == ']'):
|
||||
char = next
|
||||
pos += 1
|
||||
elif char == ',':
|
||||
if last != None:
|
||||
items.append(last)
|
||||
|
||||
last = None
|
||||
pos += 1
|
||||
continue
|
||||
|
||||
last = (last != None and last + char) or char
|
||||
pos += 1
|
||||
|
||||
if last != None:
|
||||
items.append(last)
|
||||
|
||||
return items
|
||||
|
||||
def _parse_default(self, default):
|
||||
match = re.match('^\\s*(\\\\)?(\\[((\\\\]|[^\\]])+)\\]\\s*)$', default)
|
||||
|
||||
if not match:
|
||||
return [default]
|
||||
|
||||
groups = match.groups()
|
||||
|
||||
if groups[0]:
|
||||
return [groups[1]]
|
||||
|
||||
return self._parse_list(groups[2])
|
||||
|
||||
def _match_placeholder(self):
|
||||
text = self.remains()
|
||||
|
||||
match = re.match('\\${(%s)(:((\\\\\\}|[^}])+))?}' % self.SREG_ID, text) or re.match('\\$(%s)' % self.SREG_ID, text)
|
||||
|
||||
if not match:
|
||||
return None
|
||||
|
||||
groups = match.groups()
|
||||
default = ''
|
||||
tabstop = int(groups[0])
|
||||
self.position += len(match.group(0))
|
||||
|
||||
if len(groups) > 1 and groups[2]:
|
||||
default = self._parse_default(groups[2].replace('\\}', '}'))
|
||||
|
||||
return Token('placeholder', {'tabstop': tabstop, 'default': default})
|
||||
|
||||
def _match_shell(self):
|
||||
text = self.remains()
|
||||
match = re.match('`((%s):)?((\\\\`|[^`])+?)`' % self.SREG_ID, text) or re.match('\\$\\(((%s):)?((\\\\\\)|[^\\)])+?)\\)' % self.SREG_ID, text)
|
||||
|
||||
if not match:
|
||||
return None
|
||||
|
||||
groups = match.groups()
|
||||
tabstop = (groups[1] and int(groups[1])) or -1
|
||||
self.position += len(match.group(0))
|
||||
|
||||
if text[0] == '`':
|
||||
contents = groups[2].replace('\\`', '`')
|
||||
else:
|
||||
contents = groups[2].replace('\\)', ')')
|
||||
|
||||
return Token('shell', {'tabstop': tabstop, 'contents': contents})
|
||||
|
||||
def _try_match_shell(self):
|
||||
return self._match_shell() or self._text()
|
||||
|
||||
def _eval_options(self, options):
|
||||
reg = re.compile(self.SREG_ID)
|
||||
tabstop = -1
|
||||
depend = []
|
||||
|
||||
options = options.split(':')
|
||||
|
||||
for opt in options:
|
||||
if reg.match(opt):
|
||||
tabstop = int(opt)
|
||||
else:
|
||||
depend += self._parse_list(opt[1:-1])
|
||||
|
||||
return (tabstop, depend)
|
||||
|
||||
def _match_eval(self):
|
||||
text = self.remains()
|
||||
|
||||
options = '((%s)|\\[([0-9, ]+)\\])' % self.SREG_ID
|
||||
match = re.match('\\$<((%s:)*)((\\\\>|[^>])+?)>' % options, text)
|
||||
|
||||
if not match:
|
||||
return None
|
||||
|
||||
groups = match.groups()
|
||||
(tabstop, depend) = (groups[0] and self._eval_options(groups[0][:-1])) or (-1, [])
|
||||
self.position += len(match.group(0))
|
||||
|
||||
return Token('eval', {'tabstop': tabstop, 'dependencies': depend, 'contents': groups[5].replace('\\>', '>')})
|
||||
|
||||
def _match_regex(self):
|
||||
text = self.remains()
|
||||
|
||||
content = '((?:\\\\[/]|\\\\}|[^/}])+)'
|
||||
match = re.match('\\${(?:(%s):)?\\s*(%s|\\$([A-Z_]+))?[/]%s[/]%s(?:[/]([a-zA-Z]*))?}' % (self.SREG_ID, self.SREG_ID, content, content), text)
|
||||
|
||||
if not match:
|
||||
return None
|
||||
|
||||
groups = match.groups()
|
||||
tabstop = (groups[0] and int(groups[0])) or -1
|
||||
inp = (groups[2] or (groups[1] and int(groups[1]))) or ''
|
||||
|
||||
pattern = re.sub('\\\\([/}])', '\\1', groups[3])
|
||||
substitution = re.sub('\\\\([/}])', '\\1', groups[4])
|
||||
modifiers = groups[5] or ''
|
||||
|
||||
self.position += len(match.group(0))
|
||||
|
||||
return Token('regex', {'tabstop': tabstop, 'input': inp, 'pattern': pattern, 'substitution': substitution, 'modifiers': modifiers})
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,700 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import traceback
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
import select
|
||||
import locale
|
||||
import subprocess
|
||||
from SubstitutionParser import SubstitutionParser
|
||||
import gobject
|
||||
|
||||
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):
|
||||
self.ok = True
|
||||
self.done = False
|
||||
self.buf = view.get_buffer()
|
||||
self.view = view
|
||||
self.has_references = False
|
||||
self.mirrors = []
|
||||
self.leave_mirrors = []
|
||||
self.tabstop = tabstop
|
||||
self.set_default(defaults)
|
||||
self.prev_contents = self.default
|
||||
self.set_mark_gravity()
|
||||
|
||||
if begin:
|
||||
self.begin = self.buf.create_mark(None, begin, self.mark_gravity[0])
|
||||
else:
|
||||
self.begin = None
|
||||
|
||||
self.end = None
|
||||
|
||||
def __str__(self):
|
||||
return '%s (%s)' % (str(self.__class__), str(self.default))
|
||||
|
||||
def set_mark_gravity(self):
|
||||
self.mark_gravity = [True, False]
|
||||
|
||||
def set_default(self, defaults):
|
||||
self.default = None
|
||||
self.defaults = []
|
||||
|
||||
if not defaults:
|
||||
return
|
||||
|
||||
for d in defaults:
|
||||
dm = self.expand_environment(d)
|
||||
|
||||
if dm:
|
||||
self.defaults.append(dm)
|
||||
|
||||
if not self.default:
|
||||
self.default = dm
|
||||
|
||||
if dm != d:
|
||||
break
|
||||
|
||||
|
||||
def literal(self, s):
|
||||
return repr(s)
|
||||
|
||||
def format_environment(self, s):
|
||||
return s
|
||||
|
||||
def re_environment(self, m):
|
||||
if m.group(1) or not m.group(2) in os.environ:
|
||||
return '$' + m.group(2)
|
||||
else:
|
||||
return self.format_environment(os.environ[m.group(2)])
|
||||
|
||||
def expand_environment(self, text):
|
||||
if not text:
|
||||
return text
|
||||
|
||||
return re.sub('(\\\\)?\\$([A-Z_]+)', self.re_environment, text)
|
||||
|
||||
def get_iter(self, mark):
|
||||
if mark and not mark.get_deleted():
|
||||
return self.buf.get_iter_at_mark(mark)
|
||||
else:
|
||||
return None
|
||||
|
||||
def begin_iter(self):
|
||||
return self.get_iter(self.begin)
|
||||
|
||||
def end_iter(self):
|
||||
return self.get_iter(self.end)
|
||||
|
||||
def run_last(self, placeholders):
|
||||
begin = self.begin_iter()
|
||||
self.end = self.buf.create_mark(None, begin, self.mark_gravity[1])
|
||||
|
||||
if self.default:
|
||||
insert_with_indent(self.view, begin, self.default, False, self)
|
||||
|
||||
def remove(self, force = False):
|
||||
if self.begin and not self.begin.get_deleted():
|
||||
self.buf.delete_mark(self.begin)
|
||||
|
||||
if self.end and not self.end.get_deleted():
|
||||
self.buf.delete_mark(self.end)
|
||||
|
||||
# Do something on beginning this placeholder
|
||||
def enter(self):
|
||||
if not self.begin or self.begin.get_deleted():
|
||||
return
|
||||
|
||||
self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
|
||||
|
||||
if self.end:
|
||||
self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
|
||||
else:
|
||||
self.buf.move_mark(self.buf.get_selection_bound(), self.begin_iter())
|
||||
|
||||
def get_text(self):
|
||||
if self.begin and self.end:
|
||||
biter = self.begin_iter()
|
||||
eiter = self.end_iter()
|
||||
|
||||
if biter and eiter:
|
||||
return self.buf.get_text(self.begin_iter(), self.end_iter())
|
||||
else:
|
||||
return ''
|
||||
else:
|
||||
return ''
|
||||
|
||||
def add_mirror(self, mirror, onleave = False):
|
||||
mirror.has_references = True
|
||||
|
||||
if onleave:
|
||||
self.leave_mirrors.append(mirror)
|
||||
else:
|
||||
self.mirrors.append(mirror)
|
||||
|
||||
def set_text(self, text):
|
||||
if self.begin.get_deleted() or self.end.get_deleted():
|
||||
return
|
||||
|
||||
# Set from self.begin to self.end to text!
|
||||
self.buf.begin_user_action()
|
||||
# Remove everything between self.begin and self.end
|
||||
begin = self.begin_iter()
|
||||
self.buf.delete(begin, self.end_iter())
|
||||
|
||||
# Insert the text from the mirror
|
||||
insert_with_indent(self.view, begin, text, True, self)
|
||||
self.buf.end_user_action()
|
||||
|
||||
self.update_contents()
|
||||
|
||||
def update_contents(self):
|
||||
prev = self.prev_contents
|
||||
self.prev_contents = self.get_text()
|
||||
|
||||
if prev != self.get_text():
|
||||
for mirror in self.mirrors:
|
||||
if not mirror.update(self):
|
||||
return
|
||||
|
||||
def update_leave_mirrors(self):
|
||||
# Notify mirrors
|
||||
for mirror in self.leave_mirrors:
|
||||
if not mirror.update(self):
|
||||
return
|
||||
|
||||
# Do something on ending this placeholder
|
||||
def leave(self):
|
||||
self.update_leave_mirrors()
|
||||
|
||||
def find_mirrors(self, text, placeholders):
|
||||
mirrors = []
|
||||
|
||||
while (True):
|
||||
m = re.search('(\\\\)?\\$(?:{([0-9]+)}|([0-9]+))', text)
|
||||
|
||||
if not m:
|
||||
break
|
||||
|
||||
# Skip escaped mirrors
|
||||
if m.group(1):
|
||||
text = text[m.end():]
|
||||
continue
|
||||
|
||||
tabstop = int(m.group(2) or m.group(3))
|
||||
|
||||
if tabstop in placeholders:
|
||||
if not tabstop in mirrors:
|
||||
mirrors.append(tabstop)
|
||||
|
||||
text = text[m.end():]
|
||||
else:
|
||||
self.ok = False
|
||||
return None
|
||||
|
||||
return mirrors
|
||||
|
||||
# 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)
|
||||
self.mirror_stop = tabstop
|
||||
|
||||
def update(self, mirror):
|
||||
self.set_text(mirror.get_text())
|
||||
return True
|
||||
|
||||
def run_last(self, placeholders):
|
||||
Placeholder.run_last(self, placeholders)
|
||||
|
||||
if self.mirror_stop in placeholders:
|
||||
mirror = placeholders[self.mirror_stop]
|
||||
|
||||
mirror.add_mirror(self)
|
||||
|
||||
if mirror.default:
|
||||
self.set_text(mirror.default)
|
||||
else:
|
||||
self.ok = False
|
||||
|
||||
# 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 run_last(self, placeholders):
|
||||
Placeholder.run_last(self, placeholders)
|
||||
|
||||
# Remove the begin mark and set the begin mark
|
||||
# to the end mark, this is needed so the end placeholder won't contain
|
||||
# any text
|
||||
|
||||
if not self.default:
|
||||
self.mark_gravity[0] = False
|
||||
self.buf.delete_mark(self.begin)
|
||||
self.begin = self.buf.create_mark(None, self.end_iter(), self.mark_gravity[0])
|
||||
|
||||
def enter(self):
|
||||
if self.begin and not self.begin.get_deleted():
|
||||
self.buf.move_mark(self.buf.get_insert(), self.begin_iter())
|
||||
|
||||
if self.end and not self.end.get_deleted():
|
||||
self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter())
|
||||
|
||||
def leave(self):
|
||||
self.enter()
|
||||
|
||||
# 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)
|
||||
|
||||
self.mirror_text = {0: ''}
|
||||
self.timeout_id = None
|
||||
self.cmd = s
|
||||
self.instant_update = False
|
||||
|
||||
def __str__(self):
|
||||
s = Placeholder.__str__(self)
|
||||
|
||||
return s + ' ' + self.cmd
|
||||
|
||||
def get_mirrors(self, placeholders):
|
||||
return self.find_mirrors(self.cmd, placeholders)
|
||||
|
||||
# Check if all substitution placeholders are accounted for
|
||||
def run_last(self, placeholders):
|
||||
Placeholder.run_last(self, placeholders)
|
||||
|
||||
self.ok = True
|
||||
mirrors = self.get_mirrors(placeholders)
|
||||
|
||||
if mirrors:
|
||||
allDefault = True
|
||||
|
||||
for mirror in mirrors:
|
||||
p = placeholders[mirror]
|
||||
p.add_mirror(self, not self.instant_update)
|
||||
self.mirror_text[p.tabstop] = p.default
|
||||
|
||||
if not p.default and not isinstance(p, PlaceholderExpand):
|
||||
allDefault = False
|
||||
|
||||
if allDefault:
|
||||
self.update(None)
|
||||
self.default = self.get_text() or None
|
||||
else:
|
||||
self.update(None)
|
||||
self.default = self.get_text() or None
|
||||
|
||||
if self.tabstop == -1:
|
||||
self.done = True
|
||||
|
||||
def re_placeholder(self, m, formatter):
|
||||
if m.group(1):
|
||||
return '"$' + m.group(2) + '"'
|
||||
else:
|
||||
if m.group(3):
|
||||
index = int(m.group(3))
|
||||
else:
|
||||
index = int(m.group(4))
|
||||
|
||||
return formatter(self.mirror_text[index])
|
||||
|
||||
def remove_timeout(self):
|
||||
if self.timeout_id != None:
|
||||
gobject.source_remove(self.timeout_id)
|
||||
self.timeout_id = None
|
||||
|
||||
def install_timeout(self):
|
||||
self.remove_timeout()
|
||||
self.timeout_id = gobject.timeout_add(1000, self.timeout_cb)
|
||||
|
||||
def timeout_cb(self):
|
||||
self.timeout_id = None
|
||||
|
||||
return False
|
||||
|
||||
def format_environment(self, text):
|
||||
return self.literal(text)
|
||||
|
||||
def substitute(self, text, formatter = None):
|
||||
formatter = formatter or self.literal
|
||||
|
||||
# substitute all mirrors, but also environmental variables
|
||||
text = re.sub('(\\\\)?\\$({([0-9]+)}|([0-9]+))', lambda m: self.re_placeholder(m, formatter),
|
||||
text)
|
||||
|
||||
return self.expand_environment(text)
|
||||
|
||||
def run_update(self):
|
||||
text = self.substitute(self.cmd)
|
||||
|
||||
if text:
|
||||
ret = self.expand(text)
|
||||
|
||||
if ret:
|
||||
self.update_leave_mirrors()
|
||||
else:
|
||||
ret = True
|
||||
|
||||
return ret
|
||||
|
||||
def update(self, mirror):
|
||||
text = None
|
||||
|
||||
if mirror:
|
||||
self.mirror_text[mirror.tabstop] = mirror.get_text()
|
||||
|
||||
# Check if all substitutions have been made
|
||||
for tabstop in self.mirror_text:
|
||||
if tabstop == 0:
|
||||
continue
|
||||
|
||||
if self.mirror_text[tabstop] == None:
|
||||
return False
|
||||
|
||||
return self.run_update()
|
||||
|
||||
def expand(self, text):
|
||||
return True
|
||||
|
||||
# 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)
|
||||
|
||||
self.shell = None
|
||||
self.remove_me = False
|
||||
|
||||
def close_shell(self):
|
||||
self.shell.stdout.close()
|
||||
self.shell = None
|
||||
|
||||
def timeout_cb(self):
|
||||
PlaceholderExpand.timeout_cb(self)
|
||||
self.remove_timeout()
|
||||
|
||||
if not self.shell:
|
||||
return False
|
||||
|
||||
gobject.source_remove(self.watch_id)
|
||||
self.close_shell()
|
||||
|
||||
if self.remove_me:
|
||||
PlaceholderExpand.remove(self)
|
||||
|
||||
message_dialog(None, gtk.MESSAGE_ERROR, 'Execution of the shell ' \
|
||||
'command (%s) exceeded the maximum time; ' \
|
||||
'execution aborted.' % self.command)
|
||||
|
||||
return False
|
||||
|
||||
def process_close(self):
|
||||
self.close_shell()
|
||||
self.remove_timeout()
|
||||
|
||||
self.set_text(str.join('', self.shell_output).rstrip('\n'))
|
||||
|
||||
if self.default == None:
|
||||
self.default = self.get_text()
|
||||
self.leave()
|
||||
|
||||
if self.remove_me:
|
||||
PlaceholderExpand.remove(self, True)
|
||||
|
||||
def process_cb(self, source, condition):
|
||||
if condition & gobject.IO_IN:
|
||||
line = source.readline()
|
||||
|
||||
if len(line) > 0:
|
||||
try:
|
||||
line = unicode(line, 'utf-8')
|
||||
except:
|
||||
line = unicode(line, locale.getdefaultlocale()[1],
|
||||
'replace')
|
||||
|
||||
self.shell_output += line
|
||||
self.install_timeout()
|
||||
|
||||
return True
|
||||
|
||||
self.process_close()
|
||||
return False
|
||||
|
||||
def literal_replace(self, match):
|
||||
return "\\%s" % (match.group(0))
|
||||
|
||||
def literal(self, text):
|
||||
return '"' + re.sub('([\\\\"])', self.literal_replace, text) + '"'
|
||||
|
||||
def expand(self, text):
|
||||
self.remove_timeout()
|
||||
|
||||
if self.shell:
|
||||
gobject.source_remove(self.watch_id)
|
||||
self.close_shell()
|
||||
|
||||
popen_args = {
|
||||
'cwd' : None,
|
||||
'shell': True,
|
||||
'env' : os.environ,
|
||||
'stdout': subprocess.PIPE
|
||||
}
|
||||
|
||||
self.command = text
|
||||
self.shell = subprocess.Popen(text, **popen_args)
|
||||
self.shell_output = ''
|
||||
self.watch_id = gobject.io_add_watch(self.shell.stdout, gobject.IO_IN | \
|
||||
gobject.IO_HUP, self.process_cb)
|
||||
self.install_timeout()
|
||||
|
||||
return True
|
||||
|
||||
def remove(self, force = False):
|
||||
if not force and self.shell:
|
||||
# Still executing shell command
|
||||
self.remove_me = True
|
||||
else:
|
||||
if force:
|
||||
self.remove_timeout()
|
||||
|
||||
if self.shell:
|
||||
self.close_shell()
|
||||
|
||||
PlaceholderExpand.remove(self, force)
|
||||
|
||||
class TimeoutError(Exception):
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
# 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)
|
||||
|
||||
self.fdread = 0
|
||||
self.remove_me = False
|
||||
self.namespace = namespace
|
||||
|
||||
self.refs = []
|
||||
|
||||
if refs:
|
||||
for ref in refs:
|
||||
self.refs.append(int(ref.strip()))
|
||||
|
||||
def get_mirrors(self, placeholders):
|
||||
mirrors = PlaceholderExpand.get_mirrors(self, placeholders)
|
||||
|
||||
if not self.ok:
|
||||
return None
|
||||
|
||||
for ref in self.refs:
|
||||
if ref in placeholders:
|
||||
if ref not in mirrors:
|
||||
mirrors.append(ref)
|
||||
else:
|
||||
self.ok = False
|
||||
return None
|
||||
|
||||
return mirrors
|
||||
|
||||
# SIGALRM is not supported on all platforms (e.g. windows). Timeout
|
||||
# with SIGALRM will not be used on those platforms. This will
|
||||
# potentially block xedit if you have a placeholder which gets stuck,
|
||||
# but it's better than not supporting them at all. At some point we
|
||||
# might have proper thread support and we can fix this in a better way
|
||||
def timeout_supported(self):
|
||||
return hasattr(signal, 'SIGALRM')
|
||||
|
||||
def timeout_cb(self, signum = 0, frame = 0):
|
||||
raise TimeoutError, "Operation timed out (>2 seconds)"
|
||||
|
||||
def install_timeout(self):
|
||||
if not self.timeout_supported():
|
||||
return
|
||||
|
||||
if self.timeout_id != None:
|
||||
self.remove_timeout()
|
||||
|
||||
self.timeout_id = signal.signal(signal.SIGALRM, self.timeout_cb)
|
||||
signal.alarm(2)
|
||||
|
||||
def remove_timeout(self):
|
||||
if not self.timeout_supported():
|
||||
return
|
||||
|
||||
if self.timeout_id != None:
|
||||
signal.alarm(0)
|
||||
|
||||
signal.signal(signal.SIGALRM, self.timeout_id)
|
||||
|
||||
self.timeout_id = None
|
||||
|
||||
def expand(self, text):
|
||||
self.remove_timeout()
|
||||
|
||||
text = text.strip()
|
||||
self.command = text
|
||||
|
||||
if not self.command or self.command == '':
|
||||
self.set_text('')
|
||||
return
|
||||
|
||||
text = "def process_snippet():\n\t" + "\n\t".join(text.split("\n"))
|
||||
|
||||
if 'process_snippet' in self.namespace:
|
||||
del self.namespace['process_snippet']
|
||||
|
||||
try:
|
||||
exec text in self.namespace
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
if 'process_snippet' in self.namespace:
|
||||
try:
|
||||
# Install a sigalarm signal. This is a HACK to make sure
|
||||
# xedit doesn't get freezed by someone creating a python
|
||||
# placeholder which for instance loops indefinately. Since
|
||||
# the code is executed synchronously it will hang xedit. With
|
||||
# the alarm signal we raise an exception and catch this
|
||||
# (see below). We show an error message and return False.
|
||||
# ___this is a HACK___ and should be fixed properly (I just
|
||||
# don't know how)
|
||||
self.install_timeout()
|
||||
result = self.namespace['process_snippet']()
|
||||
self.remove_timeout()
|
||||
except TimeoutError:
|
||||
self.remove_timeout()
|
||||
|
||||
message_dialog(None, gtk.MESSAGE_ERROR, \
|
||||
_('Execution of the Python command (%s) exceeds the maximum ' \
|
||||
'time, execution aborted.') % self.command)
|
||||
|
||||
return False
|
||||
except Exception, detail:
|
||||
self.remove_timeout()
|
||||
|
||||
message_dialog(None, gtk.MESSAGE_ERROR,
|
||||
_('Execution of the Python command (%s) failed: %s') %
|
||||
(self.command, detail))
|
||||
|
||||
return False
|
||||
|
||||
if result == None:
|
||||
# sys.stderr.write("%s:\n>> %s\n" % (_('The following python code, run in a snippet, does not return a value'), "\n>> ".join(self.command.split("\n"))))
|
||||
result = ''
|
||||
|
||||
self.set_text(str(result))
|
||||
|
||||
return True
|
||||
|
||||
# Regular expression placeholder
|
||||
class PlaceholderRegex(PlaceholderExpand):
|
||||
def __init__(self, view, tabstop, begin, inp, pattern, substitution, modifiers):
|
||||
PlaceholderExpand.__init__(self, view, tabstop, begin, '')
|
||||
|
||||
self.instant_update = True
|
||||
self.inp = inp
|
||||
self.pattern = pattern
|
||||
self.substitution = substitution
|
||||
|
||||
self.init_modifiers(modifiers)
|
||||
|
||||
def init_modifiers(self, modifiers):
|
||||
mods = {'I': re.I,
|
||||
'L': re.L,
|
||||
'M': re.M,
|
||||
'S': re.S,
|
||||
'U': re.U,
|
||||
'X': re.X}
|
||||
|
||||
self.modifiers = 0
|
||||
|
||||
for modifier in modifiers:
|
||||
if modifier in mods:
|
||||
self.modifiers |= mods[modifier]
|
||||
|
||||
def get_mirrors(self, placeholders):
|
||||
mirrors = self.find_mirrors(self.pattern, placeholders) + self.find_mirrors(self.substitution, placeholders)
|
||||
|
||||
if isinstance(self.inp, int):
|
||||
if self.inp not in placeholders:
|
||||
self.ok = False
|
||||
return None
|
||||
elif self.inp not in mirrors:
|
||||
mirrors.append(self.inp)
|
||||
|
||||
return mirrors
|
||||
|
||||
def literal(self, s):
|
||||
return re.escape(s)
|
||||
|
||||
def get_input(self):
|
||||
if isinstance(self.inp, int):
|
||||
return self.mirror_text[self.inp]
|
||||
elif self.inp in os.environ:
|
||||
return os.environ[self.inp]
|
||||
else:
|
||||
return ''
|
||||
|
||||
def run_update(self):
|
||||
pattern = self.substitute(self.pattern)
|
||||
substitution = self.substitute(self.substitution, SubstitutionParser.escape_substitution)
|
||||
|
||||
if pattern:
|
||||
return self.expand(pattern, substitution)
|
||||
|
||||
return True
|
||||
|
||||
def expand(self, pattern, substitution):
|
||||
# Try to compile pattern
|
||||
try:
|
||||
regex = re.compile(pattern, self.modifiers)
|
||||
except re.error, message:
|
||||
sys.stderr.write('Could not compile regular expression: %s\n%s\n' % (pattern, message))
|
||||
return False
|
||||
|
||||
inp = self.get_input()
|
||||
match = regex.search(inp)
|
||||
|
||||
if not match:
|
||||
self.set_text(inp)
|
||||
else:
|
||||
groups = match.groupdict()
|
||||
|
||||
idx = 0
|
||||
for group in match.groups():
|
||||
groups[str(idx + 1)] = group
|
||||
idx += 1
|
||||
|
||||
groups['0'] = match.group(0)
|
||||
|
||||
parser = SubstitutionParser(substitution, groups)
|
||||
self.set_text(parser.parse())
|
||||
|
||||
return True
|
||||
# ex:ts=8:et:
|
|
@ -1,355 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import gio
|
||||
|
||||
from Placeholder import *
|
||||
from Parser import Parser, Token
|
||||
from Helper import *
|
||||
|
||||
class EvalUtilities:
|
||||
def __init__(self, view=None):
|
||||
self.view = view
|
||||
self._init_namespace()
|
||||
|
||||
def _init_namespace(self):
|
||||
self.namespace = {
|
||||
'__builtins__': __builtins__,
|
||||
'align': self.util_align,
|
||||
'readfile': self.util_readfile,
|
||||
'filesize': self.util_filesize
|
||||
}
|
||||
|
||||
def _real_len(self, s, tablen = 0):
|
||||
if tablen == 0:
|
||||
tablen = self.view.get_tab_width()
|
||||
|
||||
return len(s.expandtabs(tablen))
|
||||
|
||||
def _filename_to_uri(self, filename):
|
||||
gfile = gio.File(filename)
|
||||
|
||||
return gfile.get_uri()
|
||||
|
||||
def util_readfile(self, filename):
|
||||
stream = gio.File(filename).read()
|
||||
|
||||
if not stream:
|
||||
return ''
|
||||
|
||||
res = stream.read()
|
||||
stream.close()
|
||||
|
||||
return res
|
||||
|
||||
def util_filesize(self, filename):
|
||||
gfile = gio.File(filename)
|
||||
info = gfile.query_info(gio.FILE_ATTRIBUTE_STANDARD_SIZE)
|
||||
|
||||
if not info:
|
||||
return 0
|
||||
|
||||
return info.get_size()
|
||||
|
||||
def util_align(self, items):
|
||||
maxlen = []
|
||||
tablen = self.view.get_tab_width()
|
||||
|
||||
for row in range(0, len(items)):
|
||||
for col in range(0, len(items[row]) - 1):
|
||||
if row == 0:
|
||||
maxlen.append(0)
|
||||
|
||||
items[row][col] += "\t"
|
||||
rl = self._real_len(items[row][col], tablen)
|
||||
|
||||
if (rl > maxlen[col]):
|
||||
maxlen[col] = rl
|
||||
|
||||
result = ''
|
||||
|
||||
for row in range(0, len(items)):
|
||||
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 += items[row][len(items[row]) - 1]
|
||||
|
||||
if row != len(items) - 1:
|
||||
result += "\n"
|
||||
|
||||
return result
|
||||
|
||||
class Snippet:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def __getitem__(self, prop):
|
||||
return self.data[prop]
|
||||
|
||||
def __setitem__(self, prop, value):
|
||||
self.data[prop] = value
|
||||
|
||||
def accelerator_display(self):
|
||||
accel = self['accelerator']
|
||||
|
||||
if accel:
|
||||
keyval, mod = gtk.accelerator_parse(accel)
|
||||
accel = gtk.accelerator_get_label(keyval, mod)
|
||||
|
||||
return accel or ''
|
||||
|
||||
def display(self):
|
||||
nm = markup_escape(self['description'])
|
||||
|
||||
tag = self['tag']
|
||||
accel = self.accelerator_display()
|
||||
detail = []
|
||||
|
||||
if tag and tag != '':
|
||||
detail.append(tag)
|
||||
|
||||
if accel and accel != '':
|
||||
detail.append(accel)
|
||||
|
||||
if not detail:
|
||||
return nm
|
||||
else:
|
||||
return nm + ' (<b>' + markup_escape(str.join(', ', detail)) + \
|
||||
'</b>)'
|
||||
|
||||
def _add_placeholder(self, placeholder):
|
||||
if placeholder.tabstop in self.placeholders:
|
||||
if placeholder.tabstop == -1:
|
||||
self.placeholders[-1].append(placeholder)
|
||||
self.plugin_data.ordered_placeholders.append(placeholder)
|
||||
elif placeholder.tabstop == -1:
|
||||
self.placeholders[-1] = [placeholder]
|
||||
self.plugin_data.ordered_placeholders.append(placeholder)
|
||||
else:
|
||||
self.placeholders[placeholder.tabstop] = placeholder
|
||||
self.plugin_data.ordered_placeholders.append(placeholder)
|
||||
|
||||
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'))
|
||||
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 ''
|
||||
|
||||
# Get all the current indentation
|
||||
all_indent = compute_indentation(self._view, self._insert_iter())
|
||||
|
||||
# Substract initial indentation to get the snippet indentation
|
||||
indent = all_indent[len(self._indent):]
|
||||
|
||||
# Keep indentation
|
||||
return unicode.join('\n' + unicode(indent), val.split('\n'))
|
||||
|
||||
def _create_placeholder(self, data):
|
||||
tabstop = data['tabstop']
|
||||
begin = self._insert_iter()
|
||||
|
||||
if tabstop == 0:
|
||||
# End placeholder
|
||||
return PlaceholderEnd(self._view, begin, data['default'])
|
||||
elif tabstop in self.placeholders:
|
||||
# Mirror placeholder
|
||||
return PlaceholderMirror(self._view, tabstop, begin)
|
||||
else:
|
||||
# Default placeholder
|
||||
return Placeholder(self._view, tabstop, data['default'], begin)
|
||||
|
||||
def _create_shell(self, data):
|
||||
begin = self._insert_iter()
|
||||
return PlaceholderShell(self._view, data['tabstop'], 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)
|
||||
|
||||
def _create_regex(self, data):
|
||||
begin = self._insert_iter()
|
||||
return PlaceholderRegex(self._view, data['tabstop'], begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
|
||||
|
||||
def _create_text(self, data):
|
||||
return data
|
||||
|
||||
def _invalid_placeholder(self, placeholder, remove):
|
||||
buf = self._view.get_buffer()
|
||||
|
||||
# Remove the text because this placeholder is invalid
|
||||
if placeholder.default and remove:
|
||||
buf.delete(placeholder.begin_iter(), placeholder.end_iter())
|
||||
|
||||
placeholder.remove()
|
||||
|
||||
if placeholder.tabstop == -1:
|
||||
index = self.placeholders[-1].index(placeholder)
|
||||
del self.placeholders[-1][index]
|
||||
else:
|
||||
del self.placeholders[placeholder.tabstop]
|
||||
|
||||
self.plugin_data.ordered_placeholders.remove(placeholder)
|
||||
|
||||
def _parse(self, plugin_data):
|
||||
# Initialize current variables
|
||||
self._view = plugin_data.view
|
||||
self._indent = compute_indentation(self._view, self._view.get_buffer().get_iter_at_mark(self.begin_mark))
|
||||
self._utils = EvalUtilities(self._view)
|
||||
self.placeholders = {}
|
||||
self._insert_mark = self.end_mark
|
||||
self.plugin_data = plugin_data
|
||||
|
||||
# Create parser
|
||||
parser = Parser(data=self['text'])
|
||||
|
||||
# Parse tokens
|
||||
while (True):
|
||||
token = parser.token()
|
||||
|
||||
if not token:
|
||||
break
|
||||
|
||||
try:
|
||||
val = {'environment': self._create_environment,
|
||||
'placeholder': self._create_placeholder,
|
||||
'shell': self._create_shell,
|
||||
'eval': self._create_eval,
|
||||
'regex': self._create_regex,
|
||||
'text': self._create_text}[token.klass](token.data)
|
||||
except:
|
||||
sys.stderr.write('Token class not supported: %s\n' % token.klass)
|
||||
continue
|
||||
|
||||
if isinstance(val, basestring):
|
||||
# Insert text
|
||||
self._insert_text(val)
|
||||
else:
|
||||
# Insert placeholder
|
||||
self._add_placeholder(val)
|
||||
|
||||
# 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.plugin_data.ordered_placeholders.append(self.placeholders[0])
|
||||
|
||||
# Make sure run_last is ran for all placeholders and remove any
|
||||
# non `ok` placeholders
|
||||
for tabstop in self.placeholders.copy():
|
||||
ph = (tabstop == -1 and list(self.placeholders[-1])) or [self.placeholders[tabstop]]
|
||||
|
||||
for placeholder in ph:
|
||||
placeholder.run_last(self.placeholders)
|
||||
|
||||
if not placeholder.ok or placeholder.done:
|
||||
self._invalid_placeholder(placeholder, not placeholder.ok)
|
||||
|
||||
# Remove all the Expand placeholders which have a tabstop because
|
||||
# they can be used to mirror, but they shouldn't be real tabstops
|
||||
# (if they have mirrors installed). This is problably a bit of
|
||||
# a dirty hack :)
|
||||
if -1 not in self.placeholders:
|
||||
self.placeholders[-1] = []
|
||||
|
||||
for tabstop in self.placeholders.copy():
|
||||
placeholder = self.placeholders[tabstop]
|
||||
|
||||
if tabstop != -1:
|
||||
if isinstance(placeholder, PlaceholderExpand) and \
|
||||
placeholder.has_references:
|
||||
# Add to anonymous placeholders
|
||||
self.placeholders[-1].append(placeholder)
|
||||
|
||||
# Remove placeholder
|
||||
del self.placeholders[tabstop]
|
||||
|
||||
self.plugin_data = None
|
||||
|
||||
def insert_into(self, plugin_data, insert):
|
||||
buf = plugin_data.view.get_buffer()
|
||||
last_index = 0
|
||||
|
||||
# Find closest mark at current insertion, so that we may insert
|
||||
# our marks in the correct order
|
||||
(current, next) = plugin_data.next_placeholder()
|
||||
|
||||
if current:
|
||||
# Insert AFTER current
|
||||
last_index = plugin_data.placeholders.index(current) + 1
|
||||
elif next:
|
||||
# Insert BEFORE next
|
||||
last_index = plugin_data.placeholders.index(next)
|
||||
else:
|
||||
# Insert at first position
|
||||
last_index = 0
|
||||
|
||||
# lastIndex now contains the position of the last mark
|
||||
# Create snippet bounding marks
|
||||
self.begin_mark = buf.create_mark(None, insert, True)
|
||||
self.end_mark = buf.create_mark(None, insert, False)
|
||||
|
||||
# Now parse the contents of this snippet, create Placeholders
|
||||
# and insert the placholder marks in the marks array of plugin_data
|
||||
self._parse(plugin_data)
|
||||
|
||||
# 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)
|
||||
|
||||
plugin_data.placeholders.insert(last_index, self.placeholders[0])
|
||||
last_iter = self.placeholders[0].end_iter()
|
||||
|
||||
for tabstop in k:
|
||||
if tabstop != -1 and tabstop != 0:
|
||||
placeholder = self.placeholders[tabstop]
|
||||
end_iter = placeholder.end_iter()
|
||||
|
||||
if last_iter.compare(end_iter) < 0:
|
||||
last_iter = end_iter
|
||||
|
||||
# Inserting placeholder
|
||||
plugin_data.placeholders.insert(last_index, placeholder)
|
||||
|
||||
# Move end mark to last placeholder
|
||||
buf.move_mark(self.end_mark, last_iter)
|
||||
|
||||
return self
|
||||
|
||||
def deactivate(self):
|
||||
buf = self.begin_mark.get_buffer()
|
||||
|
||||
buf.delete_mark(self.begin_mark)
|
||||
buf.delete_mark(self.end_mark)
|
||||
|
||||
self.placeholders = {}
|
||||
|
||||
def begin_iter(self):
|
||||
return self.begin_mark.get_buffer().get_iter_at_mark(self.begin_mark)
|
||||
|
||||
def end_iter(self):
|
||||
return self.end_mark.get_buffer().get_iter_at_mark(self.end_mark)
|
||||
# ex:ts=8:et:
|
|
@ -1,202 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2006-2007 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
|
||||
class ParseError(Exception):
|
||||
def __str__(self):
|
||||
return 'Parse error, resume next'
|
||||
|
||||
class Modifiers:
|
||||
def _first_char(s):
|
||||
first = (s != '' and s[0]) or ''
|
||||
rest = (len(s) > 1 and s[1:]) or ''
|
||||
|
||||
return first, rest
|
||||
|
||||
def upper_first(s):
|
||||
first, rest = Modifiers._first_char(s)
|
||||
|
||||
return '%s%s' % (first.upper(), rest)
|
||||
|
||||
def upper(s):
|
||||
return s.upper()
|
||||
|
||||
def lower_first(s):
|
||||
first, rest = Modifiers._first_char(s)
|
||||
|
||||
return '%s%s' % (first.lower(), rest)
|
||||
|
||||
def lower(s):
|
||||
return s.lower()
|
||||
|
||||
def title(s):
|
||||
return s.title()
|
||||
|
||||
upper_first = staticmethod(upper_first)
|
||||
upper = staticmethod(upper)
|
||||
lower_first = staticmethod(lower_first)
|
||||
lower = staticmethod(lower)
|
||||
title = staticmethod(title)
|
||||
_first_char = staticmethod(_first_char)
|
||||
|
||||
class SubstitutionParser:
|
||||
REG_ID = '[0-9]+'
|
||||
REG_NAME = '[a-zA-Z_]+'
|
||||
REG_MOD = '[a-zA-Z]+'
|
||||
REG_ESCAPE = '\\\\|\\(\\?|,|\\)'
|
||||
|
||||
def __init__(self, pattern, groups = {}, modifiers = {}):
|
||||
self.pattern = pattern
|
||||
self.groups = groups
|
||||
|
||||
self.REG_GROUP = '(?:(%s)|<(%s|%s)(?:,(%s))?>)' % (self.REG_ID, self.REG_ID, self.REG_NAME, self.REG_MOD)
|
||||
self.modifiers = {'u': Modifiers.upper_first,
|
||||
'U': Modifiers.upper,
|
||||
'l': Modifiers.lower_first,
|
||||
'L': Modifiers.lower,
|
||||
't': Modifiers.title}
|
||||
|
||||
for k, v in modifiers.items():
|
||||
self.modifiers[k] = v
|
||||
|
||||
def parse(self):
|
||||
result, tokens = self._parse(self.pattern, None)
|
||||
|
||||
return result
|
||||
|
||||
def _parse(self, tokens, terminator):
|
||||
result = ''
|
||||
|
||||
while tokens != '':
|
||||
if self._peek(tokens) == '' or self._peek(tokens) == terminator:
|
||||
tokens = self._remains(tokens)
|
||||
break
|
||||
|
||||
try:
|
||||
res, tokens = self._expr(tokens, terminator)
|
||||
except ParseError:
|
||||
res, tokens = self._text(tokens)
|
||||
|
||||
result += res
|
||||
|
||||
return result, tokens
|
||||
|
||||
def _peek(self, tokens, num = 0):
|
||||
return (num < len(tokens) and tokens[num])
|
||||
|
||||
def _token(self, tokens):
|
||||
if tokens == '':
|
||||
return '', '';
|
||||
|
||||
return tokens[0], (len(tokens) > 1 and tokens[1:]) or ''
|
||||
|
||||
def _remains(self, tokens, num = 1):
|
||||
return (num < len(tokens) and tokens[num:]) or ''
|
||||
|
||||
def _expr(self, tokens, terminator):
|
||||
if tokens == '':
|
||||
return ''
|
||||
|
||||
try:
|
||||
return {'\\': self._escape,
|
||||
'(': self._condition}[self._peek(tokens)](tokens, terminator)
|
||||
except KeyError:
|
||||
raise ParseError
|
||||
|
||||
def _text(self, tokens):
|
||||
return self._token(tokens)
|
||||
|
||||
def _substitute(self, group, modifiers = ''):
|
||||
result = (self.groups.has_key(group) and self.groups[group]) or ''
|
||||
|
||||
for modifier in modifiers:
|
||||
if self.modifiers.has_key(modifier):
|
||||
result = self.modifiers[modifier](result)
|
||||
|
||||
return result
|
||||
|
||||
def _match_group(self, tokens):
|
||||
match = re.match('\\\\%s' % self.REG_GROUP, tokens)
|
||||
|
||||
if not match:
|
||||
return None, tokens
|
||||
|
||||
return self._substitute(match.group(1) or match.group(2), match.group(3) or ''), tokens[match.end():]
|
||||
|
||||
def _escape(self, tokens, terminator):
|
||||
# Try to match a group
|
||||
result, tokens = self._match_group(tokens)
|
||||
|
||||
if result != None:
|
||||
return result, tokens
|
||||
|
||||
s = self.REG_GROUP
|
||||
|
||||
if terminator:
|
||||
s += '|%s' % re.escape(terminator)
|
||||
|
||||
match = re.match('\\\\(\\\\%s|%s)' % (s, self.REG_ESCAPE), tokens)
|
||||
|
||||
if not match:
|
||||
raise ParseError
|
||||
|
||||
return match.group(1), tokens[match.end():]
|
||||
|
||||
def _condition_value(self, tokens):
|
||||
match = re.match('\\\\?%s\s*' % self.REG_GROUP, tokens)
|
||||
|
||||
if not match:
|
||||
return None, tokens
|
||||
|
||||
groups = match.groups()
|
||||
name = groups[0] or groups[1]
|
||||
|
||||
return self.groups.has_key(name) and self.groups[name] != None, tokens[match.end():]
|
||||
|
||||
def _condition(self, tokens, terminator):
|
||||
# Match ? after (
|
||||
if self._peek(tokens, 1) != '?':
|
||||
raise ParseError
|
||||
|
||||
# Remove initial (? token
|
||||
tokens = self._remains(tokens, 2)
|
||||
condition, tokens = self._condition_value(tokens)
|
||||
|
||||
if condition == None or self._peek(tokens) != ',':
|
||||
raise ParseError
|
||||
|
||||
truepart, tokens = self._parse(self._remains(tokens), ',')
|
||||
|
||||
if truepart == None:
|
||||
raise ParseError
|
||||
|
||||
falsepart, tokens = self._parse(tokens, ')')
|
||||
|
||||
if falsepart == None:
|
||||
raise ParseError
|
||||
|
||||
if condition:
|
||||
return truepart, tokens
|
||||
else:
|
||||
return falsepart, tokens
|
||||
|
||||
def escape_substitution(substitution):
|
||||
return re.sub('(%s|%s)' % (self.REG_GROUP, self.REG_ESCAPE), '\\\\\\1', substitution)
|
||||
|
||||
escapesubstitution = staticmethod(escape_substitution)
|
||||
# ex:ts=8:et:
|
|
@ -1,209 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
import os
|
||||
import gettext
|
||||
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import xedit
|
||||
|
||||
from Document import Document
|
||||
from Library import Library
|
||||
|
||||
class WindowHelper:
|
||||
def __init__(self, plugin):
|
||||
self.plugin = plugin
|
||||
self.current_controller = None
|
||||
self.current_language = None
|
||||
self.signal_ids = {}
|
||||
|
||||
def run(self, window):
|
||||
self.window = window
|
||||
|
||||
self.insert_menu()
|
||||
self.register_messages()
|
||||
|
||||
self.accel_group = Library().get_accel_group(None)
|
||||
|
||||
window.add_accel_group(self.accel_group)
|
||||
window.connect('tab-added', self.on_tab_added)
|
||||
|
||||
# Add controllers to all the current views
|
||||
for view in self.window.get_views():
|
||||
if isinstance(view, xedit.View) and not self.has_controller(view):
|
||||
view._snippet_controller = Document(self, view)
|
||||
|
||||
self.update()
|
||||
|
||||
def stop(self):
|
||||
self.window.remove_accel_group(self.accel_group)
|
||||
self.accel_group = None
|
||||
|
||||
#self.window.remove_accel_group(accel)
|
||||
self.remove_menu()
|
||||
self.unregister_messages()
|
||||
|
||||
# Iterate over all the tabs and remove every controller
|
||||
for view in self.window.get_views():
|
||||
if isinstance(view, xedit.View) and self.has_controller(view):
|
||||
view._snippet_controller.stop()
|
||||
view._snippet_controller = None
|
||||
|
||||
self.window = None
|
||||
self.plugin = None
|
||||
|
||||
def register_messages(self):
|
||||
bus = self.window.get_message_bus()
|
||||
|
||||
self.messages = {
|
||||
'activate': bus.register('/plugins/snippets', 'activate', ('view', 'iter'), trigger=str, view=xedit.View, iter=gtk.TextIter),
|
||||
'parse-and-activate': bus.register('/plugins/snippets', 'parse-and-activate', ('view', 'iter'), snippet=str, view=xedit.View, iter=gtk.TextIter)
|
||||
}
|
||||
|
||||
bus.connect('/plugins/snippets', 'activate', self.on_message_activate)
|
||||
bus.connect('/plugins/snippets', 'parse-and-activate', self.on_message_parse_and_activate)
|
||||
|
||||
def unregister_messages(self):
|
||||
bus = self.window.get_message_bus()
|
||||
|
||||
for name in self.messages:
|
||||
bus.unregister(self.messages[name])
|
||||
|
||||
self.messages = {}
|
||||
|
||||
def on_message_activate(self, bus, message):
|
||||
if message.has_key('view'):
|
||||
view = message.view
|
||||
else:
|
||||
view = self.window.get_active_view()
|
||||
|
||||
if not self.has_controller(view):
|
||||
return
|
||||
|
||||
if message.has_key('iter'):
|
||||
iter = message.iter
|
||||
else:
|
||||
iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
|
||||
|
||||
controller = view._snippet_controller
|
||||
controller.run_snippet_trigger(message.trigger, (iter, iter))
|
||||
|
||||
def on_message_parse_and_activate(self, bus, message):
|
||||
if message.has_key('view'):
|
||||
view = message.view
|
||||
else:
|
||||
view = self.window.get_active_view()
|
||||
|
||||
if not self.has_controller(view):
|
||||
return
|
||||
|
||||
if message.has_key('iter'):
|
||||
iter = message.iter
|
||||
else:
|
||||
iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
|
||||
|
||||
controller = view._snippet_controller
|
||||
controller.parse_and_run_snippet(message.snippet, iter)
|
||||
|
||||
def insert_menu(self):
|
||||
manager = self.window.get_ui_manager()
|
||||
|
||||
self.action_group = gtk.ActionGroup("XeditSnippetPluginActions")
|
||||
self.action_group.set_translation_domain('xedit')
|
||||
self.action_group.add_actions([('ManageSnippets', None,
|
||||
_('Manage _Snippets...'), \
|
||||
None, _('Manage snippets'), \
|
||||
self.on_action_snippets_activate)])
|
||||
|
||||
self.merge_id = manager.new_merge_id()
|
||||
manager.insert_action_group(self.action_group, -1)
|
||||
manager.add_ui(self.merge_id, '/MenuBar/ToolsMenu/ToolsOps_5', \
|
||||
'ManageSnippets', 'ManageSnippets', gtk.UI_MANAGER_MENUITEM, False)
|
||||
|
||||
def remove_menu(self):
|
||||
manager = self.window.get_ui_manager()
|
||||
manager.remove_ui(self.merge_id)
|
||||
manager.remove_action_group(self.action_group)
|
||||
self.action_group = None
|
||||
|
||||
def find_snippet(self, snippets, tag):
|
||||
result = []
|
||||
|
||||
for snippet in snippets:
|
||||
if Snippet(snippet)['tag'] == tag:
|
||||
result.append(snippet)
|
||||
|
||||
return result
|
||||
|
||||
def has_controller(self, view):
|
||||
return hasattr(view, '_snippet_controller') and view._snippet_controller
|
||||
|
||||
def update_language(self):
|
||||
if not self.window:
|
||||
return
|
||||
|
||||
if self.current_language:
|
||||
accel_group = Library().get_accel_group( \
|
||||
self.current_language)
|
||||
self.window.remove_accel_group(accel_group)
|
||||
|
||||
if self.current_controller:
|
||||
self.current_language = self.current_controller.language_id
|
||||
|
||||
if self.current_language != None:
|
||||
accel_group = Library().get_accel_group( \
|
||||
self.current_language)
|
||||
self.window.add_accel_group(accel_group)
|
||||
else:
|
||||
self.current_language = None
|
||||
|
||||
def language_changed(self, controller):
|
||||
if controller == self.current_controller:
|
||||
self.update_language()
|
||||
|
||||
def update(self):
|
||||
view = self.window.get_active_view()
|
||||
|
||||
if not view or not self.has_controller(view):
|
||||
return
|
||||
|
||||
controller = view._snippet_controller
|
||||
|
||||
if controller != self.current_controller:
|
||||
self.current_controller = controller
|
||||
self.update_language()
|
||||
|
||||
# Callbacks
|
||||
|
||||
def on_tab_added(self, window, tab):
|
||||
# Create a new controller for this tab if it has a standard xedit view
|
||||
view = tab.get_view()
|
||||
|
||||
if isinstance(view, xedit.View) and not self.has_controller(view):
|
||||
view._snippet_controller = Document(self, view)
|
||||
|
||||
self.update()
|
||||
|
||||
def on_action_snippets_activate(self, item):
|
||||
self.plugin.create_configure_dialog()
|
||||
|
||||
def accelerator_activated(self, keyval, mod):
|
||||
return self.current_controller.accelerator_activate(keyval, mod)
|
||||
|
||||
# ex:ts=8:et:
|
|
@ -1,101 +0,0 @@
|
|||
# Xedit snippets plugin
|
||||
# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import xedit
|
||||
import platform
|
||||
|
||||
from WindowHelper import WindowHelper
|
||||
from Library import Library
|
||||
from Manager import Manager
|
||||
from Snippet import Snippet
|
||||
|
||||
class SnippetsPlugin(xedit.Plugin):
|
||||
def __init__(self):
|
||||
xedit.Plugin.__init__(self)
|
||||
|
||||
self.dlg = None
|
||||
|
||||
library = Library()
|
||||
library.set_accelerator_callback(self.accelerator_activated)
|
||||
|
||||
if platform.platform() == 'Windows':
|
||||
snippetsdir = os.path.expanduser('~/xedit/snippets')
|
||||
else:
|
||||
userdir = os.getenv('MATE22_USER_DIR')
|
||||
if userdir:
|
||||
snippetsdir = os.path.join(userdir, 'xedit/snippets')
|
||||
else:
|
||||
snippetsdir = os.path.expanduser('~/.config/xedit/snippets')
|
||||
|
||||
library.set_dirs(snippetsdir, self.system_dirs())
|
||||
|
||||
def system_dirs(self):
|
||||
if platform.platform() != 'Windows':
|
||||
if 'XDG_DATA_DIRS' in os.environ:
|
||||
datadirs = os.environ['XDG_DATA_DIRS']
|
||||
else:
|
||||
datadirs = '/usr/local/share' + os.pathsep + '/usr/share'
|
||||
|
||||
dirs = []
|
||||
|
||||
for d in datadirs.split(os.pathsep):
|
||||
d = os.path.join(d, 'xedit', 'plugins', 'snippets')
|
||||
|
||||
if os.path.isdir(d):
|
||||
dirs.append(d)
|
||||
|
||||
dirs.append(self.get_data_dir())
|
||||
return dirs
|
||||
|
||||
def activate(self, window):
|
||||
data = WindowHelper(self)
|
||||
window._snippets_plugin_data = data
|
||||
data.run(window)
|
||||
|
||||
def deactivate(self, window):
|
||||
window._snippets_plugin_data.stop()
|
||||
window._snippets_plugin_data = None
|
||||
|
||||
def update_ui(self, window):
|
||||
window._snippets_plugin_data.update()
|
||||
|
||||
def create_configure_dialog(self):
|
||||
if not self.dlg:
|
||||
self.dlg = Manager(self.get_data_dir())
|
||||
else:
|
||||
self.dlg.run()
|
||||
|
||||
window = xedit.app_get_default().get_active_window()
|
||||
|
||||
if window:
|
||||
self.dlg.dlg.set_transient_for(window)
|
||||
|
||||
return self.dlg.dlg
|
||||
|
||||
def accelerator_activated(self, group, obj, keyval, mod):
|
||||
ret = False
|
||||
|
||||
if hasattr(obj, '_snippets_plugin_data'):
|
||||
ret = obj._snippets_plugin_data.accelerator_activated(keyval, mod)
|
||||
|
||||
return ret
|
|
@ -1,646 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--*- mode: xml -*-->
|
||||
<interface>
|
||||
<object class="GtkListStore" id="model1">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0">text</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">text/plain</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">text/xml</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">image</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">image/png</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">image/jpeg</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">audio</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">video</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="XeditDocument" id="source_buffer">
|
||||
<property name="highlight-matching-brackets">True</property>
|
||||
</object>
|
||||
<object class="GtkDialog" id="dialog_snippets">
|
||||
<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="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"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="closebutton1">
|
||||
<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="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<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="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</object>
|
||||
</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>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHPaned" id="hpaned_paned">
|
||||
<property name="border_width">6</property>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox_buttons">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="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"/>
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</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"/>
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</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"/>
|
||||
<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>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</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"/>
|
||||
<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>
|
||||
</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>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="shrink">False</property>
|
||||
<property name="resize">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox_snippet">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<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>
|
||||
<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>
|
||||
<child>
|
||||
<object class="XeditView" id="source_view_snippet">
|
||||
<property name="buffer">source_buffer</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="auto-indent">True</property>
|
||||
<property name="insert-spaces-instead-of-tabs">False</property>
|
||||
<property name="smart-home-end">GTK_SOURCE_SMART_HOME_END_AFTER</property>
|
||||
<property name="tab-width">2</property>
|
||||
<property name="highlight-current-line">True</property>
|
||||
<property name="show-right-margin">False</property>
|
||||
<property name="show-line-numbers">False</property>
|
||||
|
||||
<signal handler="on_source_view_snippet_focus_out" last_modification_time="Sat, 07 Jan 2006 17:13:24 GMT" name="focus_out_event"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">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"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<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>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<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="GtkComboBoxEntry" id="combo_drop_targets">
|
||||
<property name="visible">True</property>
|
||||
<property name="add_tearoffs">False</property>
|
||||
<property name="has_frame">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>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">closebutton1</action-widget>
|
||||
<action-widget response="-11">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
Loading…
Reference in New Issue