Removed python extensions
This commit is contained in:
		
							
								
								
									
										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> | ||||
		Reference in New Issue
	
	Block a user