Coccinelle release-1.0.0-rc11
[bpt/coccinelle.git] / python / coccilib / coccigui / vim.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2007 The PIDA Project
4
5 #Permission is hereby granted, free of charge, to any person obtaining a copy
6 #of this software and associated documentation files (the "Software"), to deal
7 #in the Software without restriction, including without limitation the rights
8 #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 #copies of the Software, and to permit persons to whom the Software is
10 #furnished to do so, subject to the following conditions:
11
12 #The above copyright notice and this permission notice shall be included in
13 #all copies or substantial portions of the Software.
14
15 #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 #SOFTWARE.
22
23
24 import os
25
26 # PIDA Imports
27 from pida.core.environment import get_data_path
28
29 from pida.ui.views import PidaView
30
31 from pida.utils.vim.vimembed import VimEmbedWidget
32 from pida.utils.vim.vimcom import VimCom
33
34 from pida.core.editors import EditorService, _
35
36
37 class VimView(PidaView):
38
39 def create_ui(self):
40 self._vim = VimEmbedWidget('gvim', self.svc.script_path)
41 self.add_main_widget(self._vim)
42
43 def run(self):
44 return self._vim.run()
45
46 def get_server_name(self):
47 return self._vim.get_server_name()
48
49 def grab_input_focus(self):
50 self._vim.grab_input_focus()
51
52
53 class VimCallback(object):
54
55 def __init__(self, svc):
56 self.svc = svc
57
58 def vim_new_serverlist(self, servers):
59 if self.svc.server in servers:
60 self.svc.init_vim_server()
61
62 def vim_bufferchange(self, server, cwd, file_name, bufnum):
63 if server == self.svc.server:
64 if file_name:
65 if os.path.abspath(file_name) != file_name:
66 file_name = os.path.join(cwd, file_name)
67 if os.path.isdir(file_name):
68 self.svc.boss.cmd('filemanager', 'browse', new_path=file_name)
69 self.svc.boss.cmd('filemanager', 'present_view')
70 self.svc.open_last()
71 else:
72 self.svc.boss.cmd('buffer', 'open_file', file_name=file_name)
73
74 def vim_bufferunload(self, server, file_name):
75 if server == self.svc.server:
76 if file_name:
77 self.svc.remove_file(file_name)
78 self.svc.boss.get_service('buffer').cmd('close_file', file_name=file_name)
79
80 def vim_filesave(self, server, file_name):
81 if server == self.svc.server:
82 self.svc.boss.cmd('buffer', 'current_file_saved')
83
84 def vim_cursor_move(self, server, line_number):
85 if server == self.svc.server:
86 self.svc.set_current_line(int(line_number))
87
88 def vim_shutdown(self, server, args):
89 if server == self.svc.server:
90 self.svc.boss.stop(force=True)
91
92 def vim_complete(self, server, temp_buffer_filename, offset):
93 buffer = open(temp_buffer_filename).read()
94 offset = int(offset) - 1
95 from rope.ide.codeassist import PythonCodeAssist
96 from rope.base.project import Project
97 p = Project(self.svc.boss.cmd('buffer', 'get_current').directory)
98 c = PythonCodeAssist(p)
99 co = c.assist(buffer, offset).completions
100 print co
101 for comp in co:
102 self.svc._com.add_completion(server, comp.name)
103 # do this a few times
104 #self.svc._com.add_completion(server, 'banana')
105 pass
106
107
108 # Service class
109 class Vim(EditorService):
110 """Describe your Service Here"""
111
112 ##### Vim Things
113
114 def _create_initscript(self):
115 self.script_path = get_data_path('pida_vim_init.vim')
116
117 def init_vim_server(self):
118 if self.started == False:
119 self._com.stop_fetching_serverlist()
120 self.started = True
121 self._emit_editor_started()
122
123 def _emit_editor_started(self):
124 self.boss.get_service('editor').emit('started')
125
126 def get_server_name(self):
127 return self._view.get_server_name()
128
129 server = property(get_server_name)
130
131 def pre_start(self):
132 """Start the editor"""
133 self.started = False
134 self._create_initscript()
135 self._cb = VimCallback(self)
136 self._com = VimCom(self._cb)
137 self._view = VimView(self)
138 self.boss.cmd('window', 'add_view', paned='Editor', view=self._view)
139 self._documents = {}
140 self._current = None
141 self._sign_index = 0
142 self._signs = {}
143 self._current_line = 1
144 success = self._view.run()
145 if not success:
146 err = _('There was a problem running the "gvim" '
147 'executable. This is usually because it is not '
148 'installed. Please check that you can run "gvim" '
149 'from the command line.')
150 self.error_dlg(err)
151 raise RuntimeError(err)
152
153
154 def open(self, document):
155 """Open a document"""
156 if document is not self._current:
157 if document.unique_id in self._documents:
158 fn = document.filename
159 self._com.change_buffer(self.server, fn)
160 self._com.foreground(self.server)
161 else:
162 self._com.open_file(self.server, document.filename)
163 self._documents[document.unique_id] = document
164 self._current = document
165
166
167 def open_many(documents):
168 """Open a few documents"""
169
170 def open_last(self):
171 self._com.change_buffer(self.server, '#')
172
173 def close(self, document):
174 if document.unique_id in self._documents:
175 self._remove_document(document)
176 self._com.close_buffer(self.server, document.filename)
177
178 def remove_file(self, file_name):
179 document = self._get_document_for_filename(file_name)
180 if document is not None:
181 self._remove_document(document)
182
183 def _remove_document(self, document):
184 del self._documents[document.unique_id]
185
186 def _get_document_for_filename(self, file_name):
187 for uid, doc in self._documents.iteritems():
188 if doc.filename == file_name:
189 return doc
190
191 def close_all():
192 """Close all the documents"""
193
194 def save(self):
195 """Save the current document"""
196 self._com.save(self.server)
197
198 def save_as(filename):
199 """Save the current document as another filename"""
200
201 def revert():
202 """Revert to the loaded version of the file"""
203
204 def goto_line(self, line):
205 """Goto a line"""
206 self._com.goto_line(self.server, line)
207 self.grab_focus()
208
209 def cut(self):
210 """Cut to the clipboard"""
211 self._com.cut(self.server)
212
213 def copy(self):
214 """Copy to the clipboard"""
215 self._com.copy(self.server)
216
217 def paste(self):
218 """Paste from the clipboard"""
219 self._com.paste(self.server)
220
221 def undo(self):
222 self._com.undo(self.server)
223
224 def redo(self):
225 self._com.redo(self.server)
226
227 def grab_focus(self):
228 """Grab the focus"""
229 self._view.grab_input_focus()
230
231 def define_sign_type(self, name, icon, linehl, text, texthl):
232 self._com.define_sign(self.server, name, icon, linehl, text, texthl)
233
234 def undefine_sign_type(self, name):
235 self._com.undefine_sign(self.server, name)
236
237 def _add_sign(self, type, filename, line):
238 self._sign_index += 1
239 self._signs[(filename, line, type)] = self._sign_index
240 return self._sign_index
241
242 def _del_sign(self, type, filename, line):
243 return self._signs.pop((filename, line, type))
244
245 def show_sign(self, type, filename, line):
246 index = self._add_sign(type, filename, line)
247 self._com.show_sign(self.server, index, type, filename, line)
248
249 def hide_sign(self, type, filename, line):
250 try:
251 index = self._del_sign(type, filename, line)
252 self._com.hide_sign(self.server, index, filename)
253 except KeyError:
254 self.window.error_dlg(_('Tried to remove non-existent sign'))
255
256 def set_current_line(self, line_number):
257 self._current_line = line_number
258
259 def get_current_line(self):
260 return self._current_line
261
262 def delete_current_word(self):
263 self._com.delete_cword(self.server)
264
265 def insert_text(self, text):
266 self._com.insert_text(self.server, text)
267
268 def call_with_current_word(self, callback):
269 return self._com.get_cword(self.server, callback)
270
271 def call_with_selection(self, callback):
272 return self._com.get_selection(self.server, callback)
273
274 def set_path(self, path):
275 return self._com.set_path(self.server, path)
276
277 # Required Service attribute for service loading
278 Service = Vim
279
280
281
282 # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: