vim.py

Go to the documentation of this file.
00001 # Copyright 2005, 2006  Timo Savola
00002 #
00003 # This program is free software; you can redistribute it and/or modify
00004 # it under the terms of the GNU Lesser General Public License as published
00005 # by the Free Software Foundation; either version 2.1 of the License, or
00006 # (at your option) any later version.
00007 
00008 import os
00009 import gobject
00010 import gtk
00011 import gtk.glade
00012 from gettext import gettext
00013 
00014 import environment
00015 import view
00016 import execution
00017 import extension
00018 import config
00019 import settings
00020 
00021 DEFAULT_COMMAND = 'gvim'
00022 
00023 datadir = None
00024 views = []
00025 
00026 def init_extension(d):
00027         global datadir
00028         datadir = d
00029 
00030 ##
00031 ## Handler
00032 
00033 class Handler (environment.HandlerExtension):
00034         command = DEFAULT_COMMAND
00035         mode = None
00036 
00037         def __init__(self):
00038                 environment.HandlerExtension.__init__(self)
00039 
00040                 self.conf = config.Directory('encode/vim')
00041                 self.conf.add_string('command', self.set_command)
00042                 self.conf.add_string('mode', self.set_mode)
00043 
00044                 self.executor = execution.Executor()
00045 
00046                 label = gettext('Open in Vim')
00047                 self.action = gtk.Action(None, label, None, None)
00048                 self.action.set_visible(True)
00049 
00050         def set_command(self, command):
00051                 self.command = command
00052 
00053         def set_mode(self, mode):
00054                 self.mode = mode
00055 
00056         def get_view(self):
00057                 global views
00058                 if views:
00059                         return views[0]
00060                 else:
00061                         raise environment.ViewNotFound, 'Vim not running'
00062 
00063         def _send(self, view, keys):
00064                 server = view.get_server()
00065                 args = [self.command, '--servername', server, '--remote-send', keys]
00066 
00067                 self.executor.start(execution.Job(args))
00068 
00069         def _send_mode(self, view, keys):
00070                 if self.mode:
00071                         keys = keys + self.mode
00072 
00073                 self._send(view, keys)
00074 
00075         def get_action(self):
00076                 return self.action
00077 
00078         def supports_file(self, path):
00079                 global views
00080                 return bool(views)
00081 
00082         def open_file(self, path, workdir=None, line=None):
00083                 view = self.get_view()
00084 
00085                 keys = ''
00086 
00087                 if workdir:
00088                         keys += '<ESC>:cd %s<CR>' % escape(workdir)
00089 
00090                 keys += '<ESC>:edit %s<CR>' % escape(path)
00091 
00092                 if line is not None:
00093                         keys += '%dgg' % line
00094 
00095                 self._send_mode(view, keys)
00096 
00097                 environment.show_view(view, True)
00098 
00099         def close_file(self, path):
00100                 keys = '<ESC>:bdelete %s<CR>' % escape(path)
00101 
00102                 global views
00103                 for view in views:
00104                         try:
00105                                 self._send_mode(view, keys)
00106                         except:
00107                                 pass
00108 
00109         def cleanup(self):
00110                 global views
00111                 for view in views:
00112                         self._send(view, '<ESC>:quit<CR>')
00113 
00114 gobject.type_register(Handler)
00115 
00116 ##
00117 ## Launcher
00118 
00119 class Launcher (environment.LauncherExtension):
00120         def __init__(self):
00121                 environment.LauncherExtension.__init__(self)
00122 
00123                 label = gettext('Vim text editor')
00124                 self.action = gtk.Action(None, label, None, None)
00125                 self.action.set_visible(True)
00126 
00127         def get_action(self):
00128                 return self.action
00129 
00130         def create(self):
00131                 return View()
00132 
00133 gobject.type_register(Launcher)
00134 
00135 ##
00136 ## View
00137 
00138 class View (view.AbstractEmbedder):
00139         command = DEFAULT_COMMAND
00140 
00141         def __init__(self):
00142                 view.AbstractEmbedder.__init__(self)
00143 
00144                 path = os.path.join(datadir, 'encode', 'vim-view.glade')
00145                 self.glade = gtk.glade.XML(path)
00146 
00147                 self.conf = config.Directory('encode/vim')
00148                 self.conf.add_string('command', self.set_command)
00149 
00150                 self.executor = execution.Executor()
00151                 self.server = None
00152 
00153         def set_command(self, command):
00154                 self.command = command
00155 
00156         def get_server(self):
00157                 return self.server
00158 
00159         def client_start(self, xid):
00160                 self.server = 'ENCODE-%d' % xid
00161 
00162                 args = [self.command,
00163                         '--nofork',
00164                         '--servername', self.server,
00165                         '--socketid', str(xid),
00166                         '-n']
00167 
00168                 self.executor.start(execution.Job(args))
00169 
00170                 global views
00171                 views.append(self)
00172 
00173         def client_destroy(self):
00174                 global views
00175                 views.remove(self)
00176 
00177                 self.server = None
00178                 self.executor.stop()
00179 
00180         def get_label(self):
00181                 return self.glade.get_widget('title')
00182 
00183 gobject.type_register(View)
00184 
00185 def escape(path):
00186         # Backslash must be escaped first
00187         for c in '\\ $?!\'"&%#@*~|(){}[]':
00188                 path = path.replace(c, '\\' + c)
00189         return path
00190 
00191 ##
00192 ## Settings
00193 
00194 if 'set' not in __builtins__:
00195         import sets
00196         set = sets.Set
00197 
00198 class Settings (settings.SettingsExtension):
00199         def __init__(self):
00200                 settings.SettingsExtension.__init__(self)
00201 
00202                 path = os.path.join(datadir, 'encode', 'vim-settings.glade')
00203                 self.glade = gtk.glade.XML(path)
00204                 self.glade.signal_autoconnect(self)
00205 
00206                 self.conf = config.Directory('encode/vim')
00207 
00208                 self.ignore_command_changes = 0
00209 
00210                 self.dirty = set((
00211                         'command',
00212                         'mode',
00213                 ))
00214                 self.revert()
00215 
00216         def get_name(self):
00217                 return gettext('Vim')
00218 
00219         def get_title(self):
00220                 return gettext('Vim text editor')
00221 
00222         def get_widget(self):
00223                 return self.glade.get_widget('table')
00224 
00225         def apply(self):
00226                 if 'command' in self.dirty:
00227                         filechooser = self.glade.get_widget('command_filechooser')
00228                         command = filechooser.get_filename()
00229 
00230                         self.conf.set_string('command', command)
00231 
00232                 if 'mode' in self.dirty:
00233                         combobox = self.glade.get_widget('mode_combobox')
00234                         index = combobox.get_active()
00235 
00236                         if index == 1:
00237                                 mode = 'i'
00238                         else:
00239                                 mode = ''
00240 
00241                         self.conf.set_string('mode', mode)
00242 
00243                 self.dirty.clear()
00244 
00245         def revert(self):
00246                 if 'command' in self.dirty:
00247                         command = self.conf.get_string('command')
00248                         if not command:
00249                                 command = 'gvim'
00250                         if command[0] != '/':
00251                                 command = find_binary(command)
00252                                 if not command:
00253                                         command = ''
00254 
00255                         self.ignore_command_changes = 3
00256 
00257                         filechooser = self.glade.get_widget('command_filechooser')
00258                         filechooser.set_filename(command)
00259 
00260                 if 'mode' in self.dirty:
00261                         mode = self.conf.get_string('mode')
00262                         if mode == 'i':
00263                                 index = 1
00264                         else:
00265                                 index = 0
00266 
00267                         combobox = self.glade.get_widget('mode_combobox')
00268                         combobox.set_active(index)
00269 
00270                 self.dirty.clear()
00271 
00272         def on_command_changed(self, filechooser):
00273                 if self.ignore_command_changes > 0:
00274                         self.ignore_command_changes -= 1
00275                         return
00276 
00277                 self.dirty.add('command')
00278                 self.modified()
00279 
00280         def on_mode_changed(self, combobox):
00281                 self.dirty.add('mode')
00282                 self.modified()
00283 
00284 gobject.type_register(Settings)
00285 
00286 def find_binary(name):
00287         for dir in os.environ['PATH'].split(':'):
00288                 path = os.path.join(dir, name)
00289                 if os.path.exists(path):
00290                         return path
00291         return None

Generated on Thu Jan 18 09:47:40 2007 for Encode by  doxygen 1.4.7