00001
00002
00003
00004
00005
00006
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
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
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
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
00187 for c in '\\ $?!\'"&%#@*~|(){}[]':
00188 path = path.replace(c, '\\' + c)
00189 return path
00190
00191
00192
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