Merge lp:~sinzui/ubuntu/precise/gedit-developer-plugins/0.5.11 into lp:ubuntu/precise/gedit-developer-plugins

Proposed by Curtis Hovey
Status: Merged
Merged at revision: 11
Proposed branch: lp:~sinzui/ubuntu/precise/gedit-developer-plugins/0.5.11
Merge into: lp:ubuntu/precise/gedit-developer-plugins
Diff against target: 8217 lines (+4319/-2506)
63 files modified
ChangeLog (+728/-0)
Makefile.am (+3/-0)
Makefile.in (+10/-0)
NEWS (+20/-0)
README (+2/-2)
aclocal.m4 (+44/-21)
configure (+105/-75)
configure.ac (+6/-6)
debian/changelog (+7/-0)
debian/control (+16/-16)
language-specs/Makefile.in (+7/-0)
plugins/Makefile.am (+5/-2)
plugins/Makefile.in (+25/-14)
plugins/gdp/Makefile.am (+5/-1)
plugins/gdp/Makefile.in (+23/-11)
plugins/gdp/__init__.py (+90/-12)
plugins/gdp/bzr.py (+11/-14)
plugins/gdp/complete.py (+754/-0)
plugins/gdp/complete.ui (+76/-0)
plugins/gdp/find.py (+84/-42)
plugins/gdp/find.ui (+15/-7)
plugins/gdp/format.py (+69/-13)
plugins/gdp/syntaxcompleter.py (+0/-688)
plugins/gdp/tests/__init__.py (+0/-3)
plugins/gdp/tests/find-generator.doctest (+0/-21)
plugins/gdp/tests/formatter.doctest (+0/-27)
plugins/gdp/tests/syntaxcompleter-controller.doctest (+0/-329)
plugins/gdp/tests/syntaxcompleter-generator.doctest (+0/-367)
plugins/gdp/tests/syntaxcompleter-provider.doctest (+0/-105)
plugins/gdp/tests/test_complete.py (+742/-0)
plugins/gdp/tests/test_find.py (+156/-3)
plugins/gdp/tests/test_format.py (+236/-0)
plugins/gdp/tests/test_gdp.py (+123/-0)
plugins/gdpbase.py (+54/-22)
plugins/gdpbzr.plugin.desktop.in (+1/-1)
plugins/gdpbzr.py (+3/-5)
plugins/gdpcomplete.plugin.desktop.in (+9/-0)
plugins/gdpcomplete.py (+128/-0)
plugins/gdpfind.plugin.desktop.in (+1/-1)
plugins/gdpfind.py (+2/-4)
plugins/gdpformat.plugin.desktop.in (+1/-1)
plugins/gdpformat.py (+31/-7)
plugins/gdpsyntaxcompleter.plugin.desktop.in (+0/-9)
plugins/gdpsyntaxcompleter.py (+0/-80)
plugins/tests/__init__.py (+0/-3)
plugins/tests/findplugin.doctest (+0/-79)
plugins/tests/syntaxcompleterplugin.doctest (+0/-91)
plugins/tests/test_gdpbase.py (+58/-0)
plugins/tests/test_gdpcomplete.py (+133/-0)
plugins/tests/test_gdpfind.py (+46/-0)
plugins/tests/test_gdpformat.py (+120/-0)
po/Makefile.in.in (+9/-4)
po/POTFILES.in (+5/-3)
test.py (+1/-10)
testing/Gedit.py (+138/-101)
testing/Makefile.am (+0/-1)
testing/Makefile.in (+7/-1)
testing/__init__.py (+64/-7)
testing/gedithelpers.py (+0/-36)
testing/testrunner.py (+15/-13)
testing/tests/gedithelpers.doctest (+0/-206)
testing/tests/test_gedit.py (+131/-0)
testing/tests/testing.doctest (+0/-42)
To merge this branch: bzr merge lp:~sinzui/ubuntu/precise/gedit-developer-plugins/0.5.11
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Ubuntu branches Pending
Review via email: mp+91891@code.launchpad.net

Description of the change

Update package to 0.5.11 release which fixes many bugs that affect the current version in precise.

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Thanks for your work on this!

I took the liberty of changing the launchpad bug syntax in debian/changelog to "LP: #123456" instead of "LP:123456" - this should automatically close all the bugs involved on upload. :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2011-09-08 12:12:28 +0000
3+++ ChangeLog 2012-02-07 18:01:21 +0000
4@@ -1,5 +1,733 @@
5 <Generated by bzr log --log-format=gnu>
6
7+2012-02-06 Curtis Hovey <sinzui.is@verizon.net>
8+
9+ [543] Updated docs for release.
10+
11+2012-02-06 Curtis Hovey <sinzui.is@verizon.net>
12+
13+ [542] Construct test to use the tabs size from gsettings.
14+
15+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
16+
17+ [541] Ensure the settings are migrated before activation.
18+
19+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
20+
21+ [540] Added functions to migrate settings and config.
22+
23+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
24+
25+ [539] Survive gedit plugin configuration changes.
26+
27+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
28+
29+ [538] Removed unused setup/teardown.
30+
31+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
32+
33+ [537] Use make_gsettings.
34+
35+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
36+
37+ [536] Add a helper to safely test gsettings.
38+
39+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
40+
41+ [535] Increment version.
42+
43+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
44+
45+ [534] Extracted temp file rules to _ensure_file_path.
46+
47+2012-02-05 Curtis Hovey <sinzui.is@verizon.net>
48+
49+ [533] Fallback to a temporary file when checking syntax and the file
50+ has not been created yet.
51+
52+2012-02-04 Curtis Hovey <sinzui.is@verizon.net>
53+
54+ [532] Remove unused methods.
55+
56+2012-02-03 Curtis Hovey <sinzui.is@verizon.net>
57+
58+ [531] Do not hash info.
59+
60+2012-02-01 Curtis Hovey <sinzui.is@verizon.net>
61+
62+ [530] Auto colour test output.
63+
64+2012-02-01 Curtis Hovey <sinzui.is@verizon.net>
65+
66+ [529] Added a test to verify that the FilteredReporter is used.
67+
68+2012-02-01 Curtis Hovey <sinzui.is@verizon.net>
69+
70+ [528] Use the FilteredReporter.
71+
72+2012-02-01 Curtis Hovey <sinzui.is@verizon.net>
73+
74+ [527] Do not assume the controller is connected on document save.
75+
76+2012-01-29 Curtis Hovey <sinzui.is@verizon.net>
77+
78+ [526] Move __all__.
79+
80+2012-01-29 Curtis Hovey <sinzui.is@verizon.net>
81+
82+ [525] Updated copyright.
83+
84+2012-01-29 Curtis Hovey <sinzui.is@verizon.net>
85+
86+ [524] Updated copyright.
87+
88+2012-01-29 Curtis Hovey <sinzui.is@verizon.net>
89+
90+ [523] Restore bzr to previous version.
91+
92+2012-01-29 Curtis Hovey <sinzui.is@verizon.net>
93+
94+ [522] Updated copyright.
95+
96+2012-01-28 Curtis Hovey <sinzui.is@verizon.net>
97+
98+ [521] Renamed local_symbols => get_local_symbols and it takes an
99+ optional is_interactive argument. The syntax-error-python signal is
100+ only emitted when the call is not interactive.
101+
102+2012-01-28 Curtis Hovey <sinzui.is@verizon.net>
103+
104+ [520] Removed unused attr.
105+
106+2012-01-28 Curtis Hovey <sinzui.is@verizon.net>
107+
108+ [519] Completed CompletionProposal implementation.
109+
110+2012-01-28 Curtis Hovey <sinzui.is@verizon.net>
111+
112+ [518] Return early when _info is '' or None.
113+
114+2012-01-28 Curtis Hovey <sinzui.is@verizon.net>
115+
116+ [517] Added tests for DynamicProposal.
117+
118+2012-01-27 Curtis Hovey <sinzui.is@verizon.net>
119+
120+ [516] Remove hacks for get_char() because it works again.
121+
122+2012-01-27 Curtis Hovey <sinzui.is@verizon.net>
123+
124+ [515] Load the icon using the name.
125+
126+2012-01-27 Curtis Hovey <sinzui.is@verizon.net>
127+
128+ [514] Reuse the python generator if the cursor has not changed line.
129+
130+2012-01-27 Curtis Hovey <sinzui.is@verizon.net>
131+
132+ [513] Extracted local_symbols that uses cache to avoid unnneeded
133+ python compilation.
134+
135+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
136+
137+ [512] Only enale the format css and doctest menu items when action is
138+ applicable.
139+
140+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
141+
142+ [511] Implement more Gedit menu.
143+
144+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
145+
146+ [510] moved correct_language() to ControllerMixin so that all plugins
147+ can access it.
148+
149+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
150+
151+ [509] Renamed on_tab_added to on_tab_added_or_changed and set it to
152+ the active-tab-changed signal.
153+
154+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
155+
156+ [508] Accept a hack because it may last for 5 years.
157+
158+2012-01-21 Curtis Hovey <sinzui.is@verizon.net>
159+
160+ [507] Remove non-existent directories from paths during setup. Restore
161+ previous searches using config on start.
162+
163+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
164+
165+ [506] Removed config_get_list functions.
166+
167+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
168+
169+ [505] Pushed get/set list methods into the Config class.
170+
171+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
172+
173+ [504] Extracted make_config.
174+
175+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
176+
177+ [503] Inlined make_gedit().
178+
179+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
180+
181+ [502] Use make_config.
182+
183+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
184+
185+ [501] Updated module to use GeditTestCase.
186+
187+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
188+
189+ [500] Updated module to use GeditTestCase.
190+
191+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
192+
193+ [499] Updated module to use GeditTestCase.
194+
195+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
196+
197+ [498] Updated test to use make_config.
198+
199+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
200+
201+ [497] Used GeditTestCase.
202+
203+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
204+
205+ [496] Updated module to use GeditTestCase.
206+
207+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
208+
209+ [495] Use GeditTestCase to make gedit and config.
210+
211+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
212+
213+ [494] Created GeditTestCase with setup_config() and make_gedit()
214+
215+2012-01-20 Curtis Hovey <sinzui.is@verizon.net>
216+
217+ [493] Save the find params to the config.
218+
219+2012-01-19 Curtis Hovey <sinzui.is@verizon.net>
220+
221+ [492] Added save_find_data(). The find methods needs to call it.
222+
223+2012-01-17 Curtis Hovey <sinzui.is@verizon.net>
224+
225+ [491] Replaced values arg with config_key arg to get values from the
226+ finder config.
227+
228+2012-01-17 Curtis Hovey <sinzui.is@verizon.net>
229+
230+ [490] Added values arg to setup_comboentry
231+
232+2012-01-17 Curtis Hovey <sinzui.is@verizon.net>
233+
234+ [489] Added a test for update_comboentry.
235+
236+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
237+
238+ [488] Added tests for setup_comboentry.
239+
240+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
241+
242+ [487] Added a test for the existing setup_widgets() method.
243+
244+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
245+
246+ [486] Added a test to verify the list serialisation works with config
247+ parser.
248+
249+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
250+
251+ [485] Added config_set_list.
252+
253+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
254+
255+ [484] added config_get_list.
256+
257+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
258+
259+ [483] Added a finder section to the config.
260+
261+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
262+
263+ [482] Renamed test modules.
264+
265+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
266+
267+ [481] Remove 'syntax' from the contoller and generator classes.
268+
269+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
270+
271+ [480] Renamed SyntaxCompleterPlugin => CompletePlugin.
272+
273+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
274+
275+ [479] Revise plugin description.
276+
277+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
278+
279+ [478] Renamed syntaxcompleter module to complete.
280+
281+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
282+
283+ [477] Build a sane target in the python rules.
284+
285+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
286+
287+ [476] Inlined function and updated var names.
288+
289+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
290+
291+ [475] Only use bzr when there is a working tree.
292+
293+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
294+
295+ [474] Add python specific rules.
296+
297+2012-01-16 Curtis Hovey <sinzui.is@verizon.net>
298+
299+ [473] Added rudimentatory refactor module based on my rename_module
300+ helper.
301+
302+2012-01-15 Curtis Hovey <sinzui.is@verizon.net>
303+
304+ [472] Do not attempt to get the working tree before the document is
305+ loaded.
306+
307+2012-01-15 Curtis Hovey <sinzui.is@verizon.net>
308+
309+ [471] Increment version.
310+
311+2012-01-14 Curtis Hovey <sinzui.is@verizon.net>
312+
313+ [470] Restore decorator property because it is less code.
314+
315+2012-01-14 Curtis Hovey <sinzui.is@verizon.net>
316+
317+ [469] Update to new upsteam support for filtered reporting: Drop
318+ __call__, handle setter.
319+
320+2012-01-06 Curtis Hovey <sinzui.is@verizon.net>
321+
322+ [468] Extracted builtin rules to a cached property.
323+
324+2012-01-06 Curtis Hovey <sinzui.is@verizon.net>
325+
326+ [467] OR the CompletionActivation bits to enable both user_requested
327+ and interactive.
328+
329+2012-01-05 Curtis Hovey <sinzui.is@verizon.net>
330+
331+ [466] Reverted diff parent call.
332+
333+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
334+
335+ [465] Added the missing signals the fake gedit.
336+
337+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
338+
339+ [464] Add robust recovery for exception in import attempts.
340+
341+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
342+
343+ [463] Extracted the smart logic from do_popupate to a private method
344+ that is easier to test and does not interacte the c-object.
345+
346+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
347+
348+ [462] Disabled window.show_all() since code refactors do not require
349+ it for tests; tests run 200% faster.
350+
351+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
352+
353+ [461] Added signal to Fake document.
354+
355+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
356+
357+ [460] Hushed cruft in test output.
358+
359+2012-01-04 Curtis Hovey <sinzui.is@verizon.net>
360+
361+ [459] Added sdist to sign the distributed package.
362+
363+2012-01-03 Curtis Hovey <sinzui.is@verizon.net>
364+
365+ [458] Added twisted python files (tac) to syntax highlighting and
366+ style checking.
367+
368+2012-01-03 Curtis Hovey <sinzui.is@verizon.net>
369+
370+ [457] Increment version and deps (because many warning disapear with
371+ the newer versions).
372+
373+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
374+
375+ [456] Added ShowSyntaxErrorsOnly to menu.
376+
377+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
378+
379+ [455] Added a callback to toggle show syntax errors only.
380+
381+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
382+
383+ [454] Use config to determine report_only_errors
384+
385+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
386+
387+ [453] Added formatter section of config.
388+
389+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
390+
391+ [452] Use a filtered reporter to permit users to choose only errors.
392+
393+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
394+
395+ [451] Do not return the same word from differnent generators.
396+
397+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
398+
399+ [450] Persist the suggest_completions option.
400+
401+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
402+
403+ [449] Added sanity rules for word suggestions to minimise the
404+ intrusion.
405+
406+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
407+
408+ [448] Fixed completions title.
409+
410+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
411+
412+ [447] Renamed suggest_completions
413+
414+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
415+
416+ [446] Use get_iter().
417+
418+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
419+
420+ [445] Use the iter.
421+
422+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
423+
424+ [444] Recover from a key error in interactive completions.
425+
426+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
427+
428+ [443] Added AutoShowCompleter to the menu.
429+
430+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
431+
432+ [442] Added on_auto_show_completer_toggled.
433+
434+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
435+
436+ [441] do_get_activation checks the config to return USER_REQUESTED or
437+ INTERACTIVE.
438+
439+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
440+
441+ [440] Added auto_show to config.
442+
443+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
444+
445+ [439] Removed hack. Do not report errors if the tree does not have a
446+ parent.
447+
448+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
449+
450+ [438] add toggle_actions if they are present.
451+
452+2012-01-02 Curtis Hovey <sinzui.is@verizon.net>
453+
454+ [437] Update the accel, but the menu does not show it.
455+
456+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
457+
458+ [436] Tell the user to restart gedit. Real-time updates to menu accels
459+ is hard.
460+
461+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
462+
463+ [435] Update the menu on do_update_state.
464+
465+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
466+
467+ [434] Use focus-out-event so that the config is updated once per
468+ change. add padding to the ui.
469+
470+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
471+
472+ [433] Include complete.ui in the install.
473+
474+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
475+
476+ [432] Updated test to use a legitimate accel.
477+
478+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
479+
480+ [431] Added do_create_configure_widget.
481+
482+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
483+
484+ [430] Fixed comment.
485+
486+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
487+
488+ [429] Added test for load without a conf file.
489+
490+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
491+
492+ [428] Added a config.load and config.dump test.
493+
494+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
495+
496+ [427] Corrected capitalisaion. Added test for dir_path and file_path.
497+
498+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
499+
500+ [426] Added the config instance to all. Config is not intended to be
501+ visible.
502+
503+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
504+
505+ [425] Added config that supports the current behaviour as the default.
506+
507+2012-01-01 Curtis Hovey <sinzui.is@verizon.net>
508+
509+ [424] Added test for existing syntax completer action.
510+
511+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
512+
513+ [423] Set button sensativity to automatic (not off) to fix "filename
514+ pattern" entry. Removed the has_frame overrides to let the theme make
515+ the descision.
516+
517+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
518+
519+ [422] remove `__metaclass__ = type` from modules because TypeError:
520+ metaclass conflict with pygobject.
521+
522+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
523+
524+ [421] Use <Control>F5 to get diff from parent to be consistent with
525+ other accels.
526+
527+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
528+
529+ [420] Remove window.destroy from add clean up because of gtk warning
530+ about not in main loop.
531+
532+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
533+
534+ [419] Fixed casting error.
535+
536+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
537+
538+ [418] Do not break on hyphens when wrapping text.
539+
540+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
541+
542+ [417] Ensure windows are destroyed as soon as possible during tests.
543+
544+2011-12-31 Curtis Hovey <sinzui.is@verizon.net>
545+
546+ [416] Used GSettings instead og GConf.
547+
548+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
549+
550+ [415] Removed crufty class and fixed window types.
551+
552+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
553+
554+ [414] Removed unused var.
555+
556+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
557+
558+ [413] Replaced doctest with unittest.
559+
560+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
561+
562+ [412] Added more tests for methods used and removed unused property.
563+
564+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
565+
566+ [411] Added basic unittest for fakes. Removed fake languages because
567+ that was pushed down to GtkSource.
568+
569+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
570+
571+ [410] Do not package removed module. Run tests in testing.
572+
573+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
574+
575+ [409] Moved and renamed get_window to make_gedit.
576+
577+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
578+
579+ [408] Removed doctest for unused test helpers.
580+
581+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
582+
583+ [407] Replaced doctest with unittest. Add missing method.
584+
585+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
586+
587+ [406] Replaced doctest with unittest.
588+
589+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
590+
591+ [405] Fix setup.
592+
593+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
594+
595+ [404] Use a signal to show the completion. Restore the <Control>space
596+ accelerator.
597+
598+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
599+
600+ [403] Removed unneeded test.
601+
602+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
603+
604+ [402] Added SyntaxController unittest.
605+
606+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
607+
608+ [401] Removed unneeded doctest.
609+
610+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
611+
612+ [400] Corrected set/list rule for MarkupGenerator.get_words().
613+
614+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
615+
616+ [399] Added unittest for MarkupGenerator. Adjusted get_words to return
617+ a set.
618+
619+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
620+
621+ [398] Added PythonProposal tests.
622+
623+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
624+
625+ [397] Added unittest for PythonSyntaxGenerator
626+
627+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
628+
629+ [396] Added unittest for TextGenerator.
630+
631+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
632+
633+ [395] Added unittest for BaseSyntaxGenerator.
634+
635+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
636+
637+ [394] Removed unneeded doctest.
638+
639+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
640+
641+ [393] Replaced doctest with unittest.
642+
643+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
644+
645+ [392] Add unittest to replace doctest.
646+
647+2011-12-30 Curtis Hovey <sinzui.is@verizon.net>
648+
649+ [391] Restored show_syntax_view() to support menus.
650+
651+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
652+
653+ [390] Removed unused document.
654+
655+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
656+
657+ [389] Do not use a document to init a DynamicProvider.
658+
659+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
660+
661+ [388] Use the CompletionContext at the moment of need rather than the
662+ document at init.
663+
664+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
665+
666+ [387] Removed language_id from DynamicProvider because it is knowable
667+ from the document.
668+
669+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
670+
671+ [386] Use explicit check to use fake Gedit.
672+
673+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
674+
675+ [385] fixed order of code to avoid warnings in tests.
676+
677+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
678+
679+ [384] Revised hack to pass existing tests.
680+
681+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
682+
683+ [383] Save a working, though incomplete syntax completer.
684+
685+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
686+
687+ [382] Removed erroneously serialised properties from the builder ui
688+ file.
689+
690+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
691+
692+ [381] Extracted the "Do want to test this replacement using Find
693+ first?" dialog. Updated the code to gtk3.
694+
695+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
696+
697+ [380] Removed unneeded doctest.
698+
699+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
700+
701+ [379] Wrap text and unknown at 72 characters.
702+
703+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
704+
705+ [378] Added a test for the current wrap text rules.
706+
707+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
708+
709+ [377] Converted doctest to unittest.
710+
711+2011-12-29 Curtis Hovey <sinzui.is@verizon.net>
712+
713+ [376] Renamed testcases.
714+
715+2011-11-20 Curtis Hovey <sinzui.is@verizon.net>
716+
717+ [375] Increment minor version for bug fix.
718+
719+2011-11-20 Curtis Hovey <sinzui.is@verizon.net>
720+
721+ [374] Fixed show_replace as suggested by Tristan Schmelcher.
722+
723+2011-11-20 Curtis Hovey <sinzui.is@verizon.net>
724+
725+ [373] Extracted FakePanel and introsuce FakeProps.
726+
727+2011-11-20 Curtis Hovey <sinzui.is@verizon.net>
728+
729+ [372] Revise code for readability.
730+
731+2011-09-08 Curtis Hovey <sinzui.is@verizon.net>
732+
733+ [371] Update POTFILES.in and .skip to match renames.
734+
735 2011-09-08 Curtis Hovey <sinzui.is@verizon.net>
736
737 [370] Increment release.
738
739=== modified file 'Makefile.am'
740--- Makefile.am 2011-07-01 12:36:16 +0000
741+++ Makefile.am 2012-02-07 18:01:21 +0000
742@@ -36,6 +36,9 @@
743
744 dist: ChangeLog
745
746+sdist: dist
747+ gpg --armor --sign --detach-sig *.tar.gz
748+
749 # Build ChangeLog from bazaar history. Only build this when in an
750 # bzr branch.
751 ChangeLog:
752
753=== modified file 'Makefile.in'
754--- Makefile.in 2011-07-01 12:36:16 +0000
755+++ Makefile.in 2012-02-07 18:01:21 +0000
756@@ -102,6 +102,7 @@
757 ACLOCAL = @ACLOCAL@
758 ALL_LINGUAS = @ALL_LINGUAS@
759 AMTAR = @AMTAR@
760+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
761 AUTOCONF = @AUTOCONF@
762 AUTOHEADER = @AUTOHEADER@
763 AUTOMAKE = @AUTOMAKE@
764@@ -141,6 +142,10 @@
765 INTLTOOL_MERGE = @INTLTOOL_MERGE@
766 INTLTOOL_PERL = @INTLTOOL_PERL@
767 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
768+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
769+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
770+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
771+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
772 LDFLAGS = @LDFLAGS@
773 LIBOBJS = @LIBOBJS@
774 LIBS = @LIBS@
775@@ -202,6 +207,8 @@
776 includedir = @includedir@
777 infodir = @infodir@
778 install_sh = @install_sh@
779+intltool__v_merge_options_ = @intltool__v_merge_options_@
780+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
781 libdir = @libdir@
782 libexecdir = @libexecdir@
783 localedir = @localedir@
784@@ -728,6 +735,9 @@
785
786 dist: ChangeLog
787
788+sdist: dist
789+ gpg --armor --sign --detach-sig *.tar.gz
790+
791 # Build ChangeLog from bazaar history. Only build this when in an
792 # bzr branch.
793 ChangeLog:
794
795=== modified file 'NEWS'
796--- NEWS 2011-01-14 10:24:47 +0000
797+++ NEWS 2012-02-07 18:01:21 +0000
798@@ -1,3 +1,23 @@
799+gdp-0.5.11: All features refined
800+================================
801+
802+This releases completes an extensive set of refinements to gedit developer
803+plugins. Notable feature changes include.
804+
805+ * Formatting is more reliable.
806+ * Use Tools > Show syntax errors only to hide warnings when checking
807+ the syntax of a file.
808+
809+ * GDP completions are integrated with Gedit's snippet and word completions.
810+ * Use <Control>+space to activate all proposals.
811+ * Use Tools > Suggest completions for the edit to automatically
812+ show the proposed completions.
813+ * The completion accelerator key can be configured with the plugin.
814+
815+ * Find and replace widgets were adjusted to take less space an obey
816+ the theme rules.
817+
818+
819 gdp-0.4.1 (2.30.0): Pydoc proprosals in completions
820 ===================================================
821
822
823=== modified file 'README'
824--- README 2011-01-14 10:24:47 +0000
825+++ README 2012-02-07 18:01:21 +0000
826@@ -1,7 +1,7 @@
827 General Information
828 ===================
829
830-This is version 2.28.0 of gedit-developer-plugins (GDP). GDP are a
831+This is version 0.5.11 of gedit-developer-plugins (GDP). GDP are a
832 set of plugins for gedit that provide additional editing features
833 for software development. GDP provides:
834
835@@ -13,7 +13,7 @@
836 word completion based on the words in the file. XML-based markup
837 completion will suggest open tag, close tags, and attributes based on
838 the cursor's position.
839- Use <Control>Slash (Ctrl+/) to activate the completer window.
840+ Use <Control>space (Ctrl+space) to activate the completer window.
841 * Formatting
842 Format paragraphs, lists, and imports. Reformat test using regular
843 expressions. Check the syntax and style of Python, XML, and plain
844
845=== modified file 'aclocal.m4'
846--- aclocal.m4 2011-07-01 12:36:16 +0000
847+++ aclocal.m4 2012-02-07 18:01:21 +0000
848@@ -260,6 +260,10 @@
849 [CATOBJEXT=.mo
850 DATADIRNAME=lib])
851 ;;
852+ *-*-openbsd*)
853+ CATOBJEXT=.mo
854+ DATADIRNAME=share
855+ ;;
856 *)
857 CATOBJEXT=.mo
858 DATADIRNAME=lib
859@@ -454,7 +458,7 @@
860
861
862 dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml])
863-# serial 40 IT_PROG_INTLTOOL
864+# serial 41 IT_PROG_INTLTOOL
865 AC_DEFUN([IT_PROG_INTLTOOL], [
866 AC_PREREQ([2.50])dnl
867 AC_REQUIRE([AM_NLS])dnl
868@@ -486,25 +490,44 @@
869 AC_MSG_ERROR([The intltool scripts were not found. Please install intltool.])
870 fi
871
872- INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
873-INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
874- INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
875- INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
876- INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@'
877- INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
878- INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
879- INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
880-INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
881- INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
882- INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
883- INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@'
884- INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
885- INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
886- INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
887- INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
888- INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
889- INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
890- INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
891+if test -z "$AM_DEFAULT_VERBOSITY"; then
892+ AM_DEFAULT_VERBOSITY=1
893+fi
894+AC_SUBST([AM_DEFAULT_VERBOSITY])
895+
896+INTLTOOL_V_MERGE='$(INTLTOOL__v_MERGE_$(V))'
897+INTLTOOL__v_MERGE_='$(INTLTOOL__v_MERGE_$(AM_DEFAULT_VERBOSITY))'
898+INTLTOOL__v_MERGE_0='@echo " ITMRG " [$]@;'
899+AC_SUBST(INTLTOOL_V_MERGE)
900+AC_SUBST(INTLTOOL__v_MERGE_)
901+AC_SUBST(INTLTOOL__v_MERGE_0)
902+
903+INTLTOOL_V_MERGE_OPTIONS='$(intltool__v_merge_options_$(V))'
904+intltool__v_merge_options_='$(intltool__v_merge_options_$(AM_DEFAULT_VERBOSITY))'
905+intltool__v_merge_options_0='-q'
906+AC_SUBST(INTLTOOL_V_MERGE_OPTIONS)
907+AC_SUBST(intltool__v_merge_options_)
908+AC_SUBST(intltool__v_merge_options_0)
909+
910+ INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
911+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
912+ INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
913+ INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
914+ INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -p $(top_srcdir)/po $< [$]@'
915+ INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
916+ INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
917+ INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
918+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
919+ INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
920+ INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
921+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u --no-translations $< [$]@'
922+ INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
923+ INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
924+ INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
925+ INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
926+ INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
927+ INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
928+ INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
929
930 _IT_SUBST(INTLTOOL_DESKTOP_RULE)
931 _IT_SUBST(INTLTOOL_DIRECTORY_RULE)
932@@ -550,7 +573,7 @@
933 if test $? -ne 0; then
934 AC_MSG_ERROR([perl 5.8.1 is required for intltool])
935 else
936- IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`"
937+ IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"`
938 AC_MSG_RESULT([$IT_PERL_VERSION])
939 fi
940 if test "x$2" != "xno-xml"; then
941
942=== modified file 'configure'
943--- configure 2011-09-08 12:12:28 +0000
944+++ configure 2012-02-07 18:01:21 +0000
945@@ -1,6 +1,6 @@
946 #! /bin/sh
947 # Guess values for system-dependent variables and create Makefiles.
948-# Generated by GNU Autoconf 2.68 for gedit-developer-plugins 0.5.4.
949+# Generated by GNU Autoconf 2.68 for gedit-developer-plugins 0.5.11.
950 #
951 # Report bugs to <sinzui.is@verizon.net>.
952 #
953@@ -560,8 +560,8 @@
954 # Identity of this package.
955 PACKAGE_NAME='gedit-developer-plugins'
956 PACKAGE_TARNAME='gedit-developer-plugins'
957-PACKAGE_VERSION='0.5.4'
958-PACKAGE_STRING='gedit-developer-plugins 0.5.4'
959+PACKAGE_VERSION='0.5.11'
960+PACKAGE_STRING='gedit-developer-plugins 0.5.11'
961 PACKAGE_BUGREPORT='sinzui.is@verizon.net'
962 PACKAGE_URL=''
963
964@@ -681,6 +681,13 @@
965 INTLTOOL_KEYS_RULE
966 INTLTOOL_DIRECTORY_RULE
967 INTLTOOL_DESKTOP_RULE
968+intltool__v_merge_options_0
969+intltool__v_merge_options_
970+INTLTOOL_V_MERGE_OPTIONS
971+INTLTOOL__v_MERGE_0
972+INTLTOOL__v_MERGE_
973+INTLTOOL_V_MERGE
974+AM_DEFAULT_VERBOSITY
975 INTLTOOL_EXTRACT
976 INTLTOOL_MERGE
977 INTLTOOL_UPDATE
978@@ -1310,7 +1317,7 @@
979 # Omit some internal or obsolete options to make the list less imposing.
980 # This message is too long to be a string in the A/UX 3.1 sh.
981 cat <<_ACEOF
982-\`configure' configures gedit-developer-plugins 0.5.4 to adapt to many kinds of systems.
983+\`configure' configures gedit-developer-plugins 0.5.11 to adapt to many kinds of systems.
984
985 Usage: $0 [OPTION]... [VAR=VALUE]...
986
987@@ -1377,7 +1384,7 @@
988
989 if test -n "$ac_init_help"; then
990 case $ac_init_help in
991- short | recursive ) echo "Configuration of gedit-developer-plugins 0.5.4:";;
992+ short | recursive ) echo "Configuration of gedit-developer-plugins 0.5.11:";;
993 esac
994 cat <<\_ACEOF
995
996@@ -1481,7 +1488,7 @@
997 test -n "$ac_init_help" && exit $ac_status
998 if $ac_init_version; then
999 cat <<\_ACEOF
1000-gedit-developer-plugins configure 0.5.4
1001+gedit-developer-plugins configure 0.5.11
1002 generated by GNU Autoconf 2.68
1003
1004 Copyright (C) 2010 Free Software Foundation, Inc.
1005@@ -1850,7 +1857,7 @@
1006 This file contains any messages produced by compilers while
1007 running configure, to aid debugging if configure makes a mistake.
1008
1009-It was created by gedit-developer-plugins $as_me 0.5.4, which was
1010+It was created by gedit-developer-plugins $as_me 0.5.11, which was
1011 generated by GNU Autoconf 2.68. Invocation command line was
1012
1013 $ $0 $@
1014@@ -2665,7 +2672,7 @@
1015
1016 # Define the identity of the package.
1017 PACKAGE='gedit-developer-plugins'
1018- VERSION='0.5.4'
1019+ VERSION='0.5.11'
1020
1021
1022 cat >>confdefs.h <<_ACEOF
1023@@ -3847,25 +3854,44 @@
1024 as_fn_error $? "The intltool scripts were not found. Please install intltool." "$LINENO" 5
1025 fi
1026
1027- INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1028-INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1029- INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1030- INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1031- INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@'
1032- INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1033- INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1034- INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1035-INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1036- INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1037- INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1038- INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@'
1039- INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1040- INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1041- INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1042- INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1043- INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1044- INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1045- INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1046+if test -z "$AM_DEFAULT_VERBOSITY"; then
1047+ AM_DEFAULT_VERBOSITY=1
1048+fi
1049+
1050+
1051+INTLTOOL_V_MERGE='$(INTLTOOL__v_MERGE_$(V))'
1052+INTLTOOL__v_MERGE_='$(INTLTOOL__v_MERGE_$(AM_DEFAULT_VERBOSITY))'
1053+INTLTOOL__v_MERGE_0='@echo " ITMRG " $@;'
1054+
1055+
1056+
1057+
1058+INTLTOOL_V_MERGE_OPTIONS='$(intltool__v_merge_options_$(V))'
1059+intltool__v_merge_options_='$(intltool__v_merge_options_$(AM_DEFAULT_VERBOSITY))'
1060+intltool__v_merge_options_0='-q'
1061+
1062+
1063+
1064+
1065+ INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1066+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1067+ INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1068+ INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1069+ INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -p $(top_srcdir)/po $< $@'
1070+ INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1071+ INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1072+ INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1073+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1074+ INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1075+ INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1076+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u --no-translations $< $@'
1077+ INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1078+ INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1079+ INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1080+ INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1081+ INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1082+ INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1083+ INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
1084
1085
1086
1087@@ -4184,7 +4210,7 @@
1088 if test $? -ne 0; then
1089 as_fn_error $? "perl 5.8.1 is required for intltool" "$LINENO" 5
1090 else
1091- IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`"
1092+ IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"`
1093 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5
1094 $as_echo "$IT_PERL_VERSION" >&6; }
1095 fi
1096@@ -4589,28 +4615,28 @@
1097 elif test -n "$PKG_CONFIG"; then
1098 if test -n "$PKG_CONFIG" && \
1099 { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"
1100- pygobject-3.0 >= 2.90.3
1101- gobject-introspection-1.0 >= 1.29.17
1102- libpeas-1.0 >= 1.1.3
1103- libpeas-gtk-1.0 >= 1.1.3
1104- gedit >= 3.1.4
1105+ pygobject-3.0 >= 3.0.0
1106+ gobject-introspection-1.0 >= 1.30.0
1107+ libpeas-1.0 >= 1.2.0
1108+ libpeas-gtk-1.0 >= 1.2.0
1109+ gedit >= 3.2.0
1110 \""; } >&5
1111 ($PKG_CONFIG --exists --print-errors "
1112- pygobject-3.0 >= 2.90.3
1113- gobject-introspection-1.0 >= 1.29.17
1114- libpeas-1.0 >= 1.1.3
1115- libpeas-gtk-1.0 >= 1.1.3
1116- gedit >= 3.1.4
1117+ pygobject-3.0 >= 3.0.0
1118+ gobject-introspection-1.0 >= 1.30.0
1119+ libpeas-1.0 >= 1.2.0
1120+ libpeas-gtk-1.0 >= 1.2.0
1121+ gedit >= 3.2.0
1122 ") 2>&5
1123 ac_status=$?
1124 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1125 test $ac_status = 0; }; then
1126 pkg_cv_GEDIT_CFLAGS=`$PKG_CONFIG --cflags "
1127- pygobject-3.0 >= 2.90.3
1128- gobject-introspection-1.0 >= 1.29.17
1129- libpeas-1.0 >= 1.1.3
1130- libpeas-gtk-1.0 >= 1.1.3
1131- gedit >= 3.1.4
1132+ pygobject-3.0 >= 3.0.0
1133+ gobject-introspection-1.0 >= 1.30.0
1134+ libpeas-1.0 >= 1.2.0
1135+ libpeas-gtk-1.0 >= 1.2.0
1136+ gedit >= 3.2.0
1137 " 2>/dev/null`
1138 test "x$?" != "x0" && pkg_failed=yes
1139 else
1140@@ -4624,28 +4650,28 @@
1141 elif test -n "$PKG_CONFIG"; then
1142 if test -n "$PKG_CONFIG" && \
1143 { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"
1144- pygobject-3.0 >= 2.90.3
1145- gobject-introspection-1.0 >= 1.29.17
1146- libpeas-1.0 >= 1.1.3
1147- libpeas-gtk-1.0 >= 1.1.3
1148- gedit >= 3.1.4
1149+ pygobject-3.0 >= 3.0.0
1150+ gobject-introspection-1.0 >= 1.30.0
1151+ libpeas-1.0 >= 1.2.0
1152+ libpeas-gtk-1.0 >= 1.2.0
1153+ gedit >= 3.2.0
1154 \""; } >&5
1155 ($PKG_CONFIG --exists --print-errors "
1156- pygobject-3.0 >= 2.90.3
1157- gobject-introspection-1.0 >= 1.29.17
1158- libpeas-1.0 >= 1.1.3
1159- libpeas-gtk-1.0 >= 1.1.3
1160- gedit >= 3.1.4
1161+ pygobject-3.0 >= 3.0.0
1162+ gobject-introspection-1.0 >= 1.30.0
1163+ libpeas-1.0 >= 1.2.0
1164+ libpeas-gtk-1.0 >= 1.2.0
1165+ gedit >= 3.2.0
1166 ") 2>&5
1167 ac_status=$?
1168 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1169 test $ac_status = 0; }; then
1170 pkg_cv_GEDIT_LIBS=`$PKG_CONFIG --libs "
1171- pygobject-3.0 >= 2.90.3
1172- gobject-introspection-1.0 >= 1.29.17
1173- libpeas-1.0 >= 1.1.3
1174- libpeas-gtk-1.0 >= 1.1.3
1175- gedit >= 3.1.4
1176+ pygobject-3.0 >= 3.0.0
1177+ gobject-introspection-1.0 >= 1.30.0
1178+ libpeas-1.0 >= 1.2.0
1179+ libpeas-gtk-1.0 >= 1.2.0
1180+ gedit >= 3.2.0
1181 " 2>/dev/null`
1182 test "x$?" != "x0" && pkg_failed=yes
1183 else
1184@@ -4668,30 +4694,30 @@
1185 fi
1186 if test $_pkg_short_errors_supported = yes; then
1187 GEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "
1188- pygobject-3.0 >= 2.90.3
1189- gobject-introspection-1.0 >= 1.29.17
1190- libpeas-1.0 >= 1.1.3
1191- libpeas-gtk-1.0 >= 1.1.3
1192- gedit >= 3.1.4
1193+ pygobject-3.0 >= 3.0.0
1194+ gobject-introspection-1.0 >= 1.30.0
1195+ libpeas-1.0 >= 1.2.0
1196+ libpeas-gtk-1.0 >= 1.2.0
1197+ gedit >= 3.2.0
1198 " 2>&1`
1199 else
1200 GEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "
1201- pygobject-3.0 >= 2.90.3
1202- gobject-introspection-1.0 >= 1.29.17
1203- libpeas-1.0 >= 1.1.3
1204- libpeas-gtk-1.0 >= 1.1.3
1205- gedit >= 3.1.4
1206+ pygobject-3.0 >= 3.0.0
1207+ gobject-introspection-1.0 >= 1.30.0
1208+ libpeas-1.0 >= 1.2.0
1209+ libpeas-gtk-1.0 >= 1.2.0
1210+ gedit >= 3.2.0
1211 " 2>&1`
1212 fi
1213 # Put the nasty error message in config.log where it belongs
1214 echo "$GEDIT_PKG_ERRORS" >&5
1215
1216 as_fn_error $? "Package requirements (
1217- pygobject-3.0 >= 2.90.3
1218- gobject-introspection-1.0 >= 1.29.17
1219- libpeas-1.0 >= 1.1.3
1220- libpeas-gtk-1.0 >= 1.1.3
1221- gedit >= 3.1.4
1222+ pygobject-3.0 >= 3.0.0
1223+ gobject-introspection-1.0 >= 1.30.0
1224+ libpeas-1.0 >= 1.2.0
1225+ libpeas-gtk-1.0 >= 1.2.0
1226+ gedit >= 3.2.0
1227 ) were not met:
1228
1229 $GEDIT_PKG_ERRORS
1230@@ -5715,6 +5741,10 @@
1231 fi
1232
1233 ;;
1234+ *-*-openbsd*)
1235+ CATOBJEXT=.mo
1236+ DATADIRNAME=share
1237+ ;;
1238 *)
1239 CATOBJEXT=.mo
1240 DATADIRNAME=lib
1241@@ -6488,7 +6518,7 @@
1242 # report actual input values of CONFIG_FILES etc. instead of their
1243 # values after options handling.
1244 ac_log="
1245-This file was extended by gedit-developer-plugins $as_me 0.5.4, which was
1246+This file was extended by gedit-developer-plugins $as_me 0.5.11, which was
1247 generated by GNU Autoconf 2.68. Invocation command line was
1248
1249 CONFIG_FILES = $CONFIG_FILES
1250@@ -6545,7 +6575,7 @@
1251 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
1252 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
1253 ac_cs_version="\\
1254-gedit-developer-plugins config.status 0.5.4
1255+gedit-developer-plugins config.status 0.5.11
1256 configured by $0, generated by GNU Autoconf 2.68,
1257 with options \\"\$ac_cs_config\\"
1258
1259
1260=== modified file 'configure.ac'
1261--- configure.ac 2011-09-08 12:12:28 +0000
1262+++ configure.ac 2012-02-07 18:01:21 +0000
1263@@ -4,7 +4,7 @@
1264
1265 m4_define(gdp_major_version, 0)
1266 m4_define(gdp_minor_version, 5)
1267-m4_define(gdp_micro_version, 4)
1268+m4_define(gdp_micro_version, 11)
1269 m4_define(gdp_version, gdp_major_version.gdp_minor_version.gdp_micro_version)
1270
1271 AC_INIT(gedit-developer-plugins, gdp_version, sinzui.is@verizon.net)
1272@@ -29,11 +29,11 @@
1273 # not always available. gtksourceview is a good indicator of the
1274 # Gedit version.
1275 PKG_CHECK_MODULES(GEDIT, [
1276- pygobject-3.0 >= 2.90.3
1277- gobject-introspection-1.0 >= 1.29.17
1278- libpeas-1.0 >= 1.1.3
1279- libpeas-gtk-1.0 >= 1.1.3
1280- gedit >= 3.1.4
1281+ pygobject-3.0 >= 3.0.0
1282+ gobject-introspection-1.0 >= 1.30.0
1283+ libpeas-1.0 >= 1.2.0
1284+ libpeas-gtk-1.0 >= 1.2.0
1285+ gedit >= 3.2.0
1286 ])
1287
1288 # i18n configuration.
1289
1290=== modified file 'debian/changelog'
1291--- debian/changelog 2011-12-22 18:09:53 +0000
1292+++ debian/changelog 2012-02-07 18:01:21 +0000
1293@@ -1,3 +1,10 @@
1294+gedit-developer-plugins (0.5.11-0ubuntu1) precise; urgency=low
1295+
1296+ * New upstream release. Fixes LP:892848, LP:909810, LP:910310, LP:919853,
1297+ LP:919872, LP:919900, LP:920041, LP:922928
1298+
1299+ -- Curtis C. Hovey <sinzui.is@verizon.net> Tue, 07 Feb 2012 12:20:48 -0500
1300+
1301 gedit-developer-plugins (0.5.4-0ubuntu2) precise; urgency=low
1302
1303 * Drop debian/patches/dont_use_bzr_gtk.patch:
1304
1305=== modified file 'debian/control'
1306--- debian/control 2011-12-22 18:09:53 +0000
1307+++ debian/control 2012-02-07 18:01:21 +0000
1308@@ -5,15 +5,16 @@
1309 Build-Depends: debhelper (>= 8),
1310 intltool (>= 0.35.0),
1311 python (>= 2.7),
1312- gnome-common (>= 2.24.0),
1313- gnome-pkg-tools (>= 0.11),
1314- python-gobject-dev (>= 2.90.3),
1315- libgirepository1.0-dev (>= 1.29.17),
1316- gir1.2-glib-2.0 (>= 0.10.2),
1317- gir1.2-gtk-3.0 (>= 3.1.0),
1318- libpeas-dev (>= 1.1.3),
1319- gedit-dev (>= 3.1.4),
1320- python-pocket-lint (>= 0.5.10)
1321+ dh-autoreconf,
1322+ gnome-common (>= 3.1.0),
1323+ gnome-pkg-tools (>= 0.19),
1324+ libgirepository1.0-dev (>= 1.30.0),
1325+ gir1.2-glib-2.0 (>= 1.30.0),
1326+ gir1.2-gtk-3.0 (>= 3.2.0),
1327+ python-gi-dev (>= 3.0.0),
1328+ libpeas-dev (>= 1.2.0),
1329+ gedit-dev (>= 3.2.0),
1330+ python-pocket-lint (>= 0.5.23)
1331 Standards-Version: 3.9.2
1332 XS-Python-Version: >= 2.7
1333
1334@@ -23,11 +24,11 @@
1335 Depends: ${shlibs:Depends},
1336 ${misc:Depends},
1337 ${python:Depends},
1338- python-gobject (>= 2.90.3),
1339- gir1.2-glib-2.0 (>= 0.10.2),
1340- gir1.2-gtk-3.0 (>= 3.1.0),
1341- gedit (>= 3.1.4),
1342- python-pocket-lint (>= 0.5.10)
1343+ python-gi (>= 3.0.0),
1344+ gir1.2-glib-2.0 (>= 1.30.0),
1345+ gir1.2-gtk-3.0 (>= 3.2.0),
1346+ gedit (>= 3.2.0),
1347+ python-pocket-lint (>= 0.5.23)
1348 Enhances: gedit
1349 Recommends: bzr, bzr-gtk, python-cssutils
1350 XB-Python-Version: ${python:Versions}
1351@@ -41,8 +42,7 @@
1352 * Syntax completion
1353 Python completion using the file's imports and definitions. Simple
1354 word completion based on the words in the file. XML tag and attribute
1355- completions based on document content.
1356- Use <Alt>/ to activate the completion window.
1357+ completions based on document structure.
1358 * Formatting
1359 Format paragraphs, lists, and imports. Reformat test using regular
1360 expressions. Check the syntax and style of Python, XML, CSS, and plain
1361
1362=== modified file 'language-specs/Makefile.in'
1363--- language-specs/Makefile.in 2011-04-15 13:50:46 +0000
1364+++ language-specs/Makefile.in 2012-02-07 18:01:21 +0000
1365@@ -71,6 +71,7 @@
1366 ACLOCAL = @ACLOCAL@
1367 ALL_LINGUAS = @ALL_LINGUAS@
1368 AMTAR = @AMTAR@
1369+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
1370 AUTOCONF = @AUTOCONF@
1371 AUTOHEADER = @AUTOHEADER@
1372 AUTOMAKE = @AUTOMAKE@
1373@@ -110,6 +111,10 @@
1374 INTLTOOL_MERGE = @INTLTOOL_MERGE@
1375 INTLTOOL_PERL = @INTLTOOL_PERL@
1376 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
1377+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
1378+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
1379+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
1380+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
1381 LDFLAGS = @LDFLAGS@
1382 LIBOBJS = @LIBOBJS@
1383 LIBS = @LIBS@
1384@@ -171,6 +176,8 @@
1385 includedir = @includedir@
1386 infodir = @infodir@
1387 install_sh = @install_sh@
1388+intltool__v_merge_options_ = @intltool__v_merge_options_@
1389+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
1390 libdir = @libdir@
1391 libexecdir = @libexecdir@
1392 localedir = @localedir@
1393
1394=== modified file 'plugins/Makefile.am'
1395--- plugins/Makefile.am 2011-07-01 12:36:16 +0000
1396+++ plugins/Makefile.am 2012-02-07 18:01:21 +0000
1397@@ -9,14 +9,14 @@
1398 gdpbzr.py \
1399 gdpfind.py \
1400 gdpformat.py \
1401- gdpsyntaxcompleter.py \
1402+ gdpcomplete.py \
1403 $(NULL)
1404
1405 plugin_in_files = \
1406 gdpbzr.plugin.desktop.in \
1407 gdpfind.plugin.desktop.in \
1408 gdpformat.plugin.desktop.in \
1409- gdpsyntaxcompleter.plugin.desktop.in \
1410+ gdpcomplete.plugin.desktop.in \
1411 $(NULL)
1412
1413 %.plugin: %.plugin.desktop.in \
1414@@ -33,5 +33,8 @@
1415 cp -p $(srcdir)/tests/* $(distdir)/tests
1416 rm -f $(distdir)/tests/*.pyc
1417
1418+install-data-hook:
1419+ rm -f $(GEDIT_PLUGIN_DIR)/gdpsyntaxcompleter.*
1420+
1421 CLEANFILES = *.bak *.pyc *.pyo $(plugin_DATA)
1422 DISTCLEANFILES = *.bak *.pyc *.pyo $(plugin_DATA)
1423
1424=== modified file 'plugins/Makefile.in'
1425--- plugins/Makefile.in 2011-07-01 12:36:16 +0000
1426+++ plugins/Makefile.in 2012-02-07 18:01:21 +0000
1427@@ -113,6 +113,7 @@
1428 ACLOCAL = @ACLOCAL@
1429 ALL_LINGUAS = @ALL_LINGUAS@
1430 AMTAR = @AMTAR@
1431+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
1432 AUTOCONF = @AUTOCONF@
1433 AUTOHEADER = @AUTOHEADER@
1434 AUTOMAKE = @AUTOMAKE@
1435@@ -152,6 +153,10 @@
1436 INTLTOOL_MERGE = @INTLTOOL_MERGE@
1437 INTLTOOL_PERL = @INTLTOOL_PERL@
1438 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
1439+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
1440+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
1441+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
1442+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
1443 LDFLAGS = @LDFLAGS@
1444 LIBOBJS = @LIBOBJS@
1445 LIBS = @LIBS@
1446@@ -213,6 +218,8 @@
1447 includedir = @includedir@
1448 infodir = @infodir@
1449 install_sh = @install_sh@
1450+intltool__v_merge_options_ = @intltool__v_merge_options_@
1451+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
1452 libdir = @libdir@
1453 libexecdir = @libexecdir@
1454 localedir = @localedir@
1455@@ -244,14 +251,14 @@
1456 gdpbzr.py \
1457 gdpfind.py \
1458 gdpformat.py \
1459- gdpsyntaxcompleter.py \
1460+ gdpcomplete.py \
1461 $(NULL)
1462
1463 plugin_in_files = \
1464 gdpbzr.plugin.desktop.in \
1465 gdpfind.plugin.desktop.in \
1466 gdpformat.plugin.desktop.in \
1467- gdpsyntaxcompleter.plugin.desktop.in \
1468+ gdpcomplete.plugin.desktop.in \
1469 $(NULL)
1470
1471 plugin_DATA = $(plugin_in_files:.plugin.desktop.in=.plugin)
1472@@ -602,7 +609,8 @@
1473 info-am:
1474
1475 install-data-am: install-pluginDATA install-pluginPYTHON
1476-
1477+ @$(NORMAL_INSTALL)
1478+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
1479 install-dvi: install-dvi-recursive
1480
1481 install-dvi-am:
1482@@ -648,22 +656,22 @@
1483 uninstall-am: uninstall-pluginDATA uninstall-pluginPYTHON
1484
1485 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
1486- install-am install-strip tags-recursive
1487+ install-am install-data-am install-strip tags-recursive
1488
1489 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
1490 all all-am check check-am clean clean-generic ctags \
1491 ctags-recursive dist-hook distclean distclean-generic \
1492 distclean-tags distdir dvi dvi-am html html-am info info-am \
1493- install install-am install-data install-data-am install-dvi \
1494- install-dvi-am install-exec install-exec-am install-html \
1495- install-html-am install-info install-info-am install-man \
1496- install-pdf install-pdf-am install-pluginDATA \
1497- install-pluginPYTHON install-ps install-ps-am install-strip \
1498- installcheck installcheck-am installdirs installdirs-am \
1499- maintainer-clean maintainer-clean-generic mostlyclean \
1500- mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
1501- uninstall uninstall-am uninstall-pluginDATA \
1502- uninstall-pluginPYTHON
1503+ install install-am install-data install-data-am \
1504+ install-data-hook install-dvi install-dvi-am install-exec \
1505+ install-exec-am install-html install-html-am install-info \
1506+ install-info-am install-man install-pdf install-pdf-am \
1507+ install-pluginDATA install-pluginPYTHON install-ps \
1508+ install-ps-am install-strip installcheck installcheck-am \
1509+ installdirs installdirs-am maintainer-clean \
1510+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
1511+ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
1512+ uninstall-pluginDATA uninstall-pluginPYTHON
1513
1514
1515 %.plugin: %.plugin.desktop.in \
1516@@ -676,6 +684,9 @@
1517 cp -p $(srcdir)/tests/* $(distdir)/tests
1518 rm -f $(distdir)/tests/*.pyc
1519
1520+install-data-hook:
1521+ rm -f $(GEDIT_PLUGIN_DIR)/gdpsyntaxcompleter.*
1522+
1523 # Tell versions [3.59,3.63) of GNU make to not export all variables.
1524 # Otherwise a system limit (for SysV at least) may be exceeded.
1525 .NOEXPORT:
1526
1527=== modified file 'plugins/gdp/Makefile.am'
1528--- plugins/gdp/Makefile.am 2011-01-14 10:24:47 +0000
1529+++ plugins/gdp/Makefile.am 2012-02-07 18:01:21 +0000
1530@@ -5,10 +5,11 @@
1531 bzr.py \
1532 find.py \
1533 format.py \
1534- syntaxcompleter.py
1535+ complete.py
1536
1537 uidir = $(plugindir)
1538 ui_DATA = \
1539+ complete.ui \
1540 find.ui \
1541 format.ui
1542
1543@@ -21,6 +22,9 @@
1544 mkdir $(distdir)/data
1545 cp -p $(srcdir)/data/* $(distdir)/data
1546
1547+install-data-hook:
1548+ rm -f $(GEDIT_PLUGIN_DIR)/gdp/syntaxcompleter.*
1549+
1550 CLEANFILES = *.bak *.pyc *.pyo
1551 DISTCLEANFILES = *.bak *.pyc *.pyo
1552
1553
1554=== modified file 'plugins/gdp/Makefile.in'
1555--- plugins/gdp/Makefile.in 2011-04-15 13:50:46 +0000
1556+++ plugins/gdp/Makefile.in 2012-02-07 18:01:21 +0000
1557@@ -73,6 +73,7 @@
1558 ACLOCAL = @ACLOCAL@
1559 ALL_LINGUAS = @ALL_LINGUAS@
1560 AMTAR = @AMTAR@
1561+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
1562 AUTOCONF = @AUTOCONF@
1563 AUTOHEADER = @AUTOHEADER@
1564 AUTOMAKE = @AUTOMAKE@
1565@@ -112,6 +113,10 @@
1566 INTLTOOL_MERGE = @INTLTOOL_MERGE@
1567 INTLTOOL_PERL = @INTLTOOL_PERL@
1568 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
1569+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
1570+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
1571+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
1572+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
1573 LDFLAGS = @LDFLAGS@
1574 LIBOBJS = @LIBOBJS@
1575 LIBS = @LIBS@
1576@@ -173,6 +178,8 @@
1577 includedir = @includedir@
1578 infodir = @infodir@
1579 install_sh = @install_sh@
1580+intltool__v_merge_options_ = @intltool__v_merge_options_@
1581+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
1582 libdir = @libdir@
1583 libexecdir = @libexecdir@
1584 localedir = @localedir@
1585@@ -202,10 +209,11 @@
1586 bzr.py \
1587 find.py \
1588 format.py \
1589- syntaxcompleter.py
1590+ complete.py
1591
1592 uidir = $(plugindir)
1593 ui_DATA = \
1594+ complete.ui \
1595 find.ui \
1596 format.ui
1597
1598@@ -398,7 +406,8 @@
1599 info-am:
1600
1601 install-data-am: install-pluginPYTHON install-uiDATA
1602-
1603+ @$(NORMAL_INSTALL)
1604+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
1605 install-dvi: install-dvi-am
1606
1607 install-dvi-am:
1608@@ -443,19 +452,19 @@
1609
1610 uninstall-am: uninstall-pluginPYTHON uninstall-uiDATA
1611
1612-.MAKE: install-am install-strip
1613+.MAKE: install-am install-data-am install-strip
1614
1615 .PHONY: all all-am check check-am clean clean-generic dist-hook \
1616 distclean distclean-generic distdir dvi dvi-am html html-am \
1617 info info-am install install-am install-data install-data-am \
1618- install-dvi install-dvi-am install-exec install-exec-am \
1619- install-html install-html-am install-info install-info-am \
1620- install-man install-pdf install-pdf-am install-pluginPYTHON \
1621- install-ps install-ps-am install-strip install-uiDATA \
1622- installcheck installcheck-am installdirs maintainer-clean \
1623- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
1624- pdf-am ps ps-am uninstall uninstall-am uninstall-pluginPYTHON \
1625- uninstall-uiDATA
1626+ install-data-hook install-dvi install-dvi-am install-exec \
1627+ install-exec-am install-html install-html-am install-info \
1628+ install-info-am install-man install-pdf install-pdf-am \
1629+ install-pluginPYTHON install-ps install-ps-am install-strip \
1630+ install-uiDATA installcheck installcheck-am installdirs \
1631+ maintainer-clean maintainer-clean-generic mostlyclean \
1632+ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
1633+ uninstall-pluginPYTHON uninstall-uiDATA
1634
1635
1636 dist-hook:
1637@@ -465,6 +474,9 @@
1638 mkdir $(distdir)/data
1639 cp -p $(srcdir)/data/* $(distdir)/data
1640
1641+install-data-hook:
1642+ rm -f $(GEDIT_PLUGIN_DIR)/gdp/syntaxcompleter.*
1643+
1644 # Tell versions [3.59,3.63) of GNU make to not export all variables.
1645 # Otherwise a system limit (for SysV at least) may be exceeded.
1646 .NOEXPORT:
1647
1648=== modified file 'plugins/gdp/__init__.py'
1649--- plugins/gdp/__init__.py 2011-07-01 12:36:16 +0000
1650+++ plugins/gdp/__init__.py 2012-02-07 18:01:21 +0000
1651@@ -1,34 +1,46 @@
1652-# Copyright (C) 2009-2011 - Curtis Hovey <sinzui.is at verizon.net>
1653+# Copyright (C) 2009-2012 - Curtis Hovey <sinzui.is at verizon.net>
1654 # This software is licensed under the GNU General Public License version 2
1655 # (see the file COPYING).
1656 """GDP Gedit Developer Plugins."""
1657
1658-__metaclass__ = type
1659-
1660 __all__ = [
1661+ 'config',
1662 'ControllerMixin',
1663 'set_file_line',
1664 'setup_file_lines_view',
1665 ]
1666
1667
1668+from ConfigParser import SafeConfigParser
1669 import mimetypes
1670 import os
1671-
1672-from gi.repository import GObject
1673-from gi.repository import Gio
1674-from gi.repository import Pango
1675-from gi.repository import Gtk
1676-
1677+import re
1678+from StringIO import StringIO
1679+
1680+from xdg import BaseDirectory
1681+
1682+from gi.repository import (
1683+ GObject,
1684+ Gio,
1685+ Pango,
1686+ Gtk,
1687+ GtkSource,
1688+ )
1689
1690 # Initialise the mimetypes for document type inspection.
1691 mimetypes.init()
1692 mimetypes.add_type('application/x-zope-configuation', '.zcml')
1693 mimetypes.add_type('application/x-zope-page-template', '.pt')
1694 mimetypes.add_type('text/x-python-doctest', '.doctest')
1695-
1696-
1697-class ControllerMixin:
1698+mimetypes.add_type('text/x-python', '.tac')
1699+
1700+lang_manager = GtkSource.LanguageManager.get_default()
1701+
1702+doctest_pattern = re.compile(
1703+ r'^.*(doc|test|stories).*/.*\.(txt|doctest)$')
1704+
1705+
1706+class ControllerMixin(object):
1707 """Provide common features to plugins"""
1708
1709 def deactivate(self):
1710@@ -105,6 +117,16 @@
1711 end_iter = document.get_end_iter()
1712 return document.get_text(start_iter, end_iter, True)
1713
1714+ def correct_language(self, document):
1715+ """Correct the language for ambuguous mime-types."""
1716+ if not hasattr(document, 'get_language'):
1717+ return
1718+ file_path = document.get_uri_for_display()
1719+ if doctest_pattern.match(file_path):
1720+ document.set_language(lang_manager.get_language('doctest'))
1721+ elif file_path.endswith('.tac'):
1722+ document.set_language(lang_manager.get_language('python'))
1723+
1724
1725 def set_file_line(column, cell, model, piter, cell_type):
1726 """Set the value as file or line information."""
1727@@ -194,3 +216,59 @@
1728 'row-activated', on_file_lines_row_activated, plugin)
1729 file_lines_view.connect_after(
1730 'size-allocate', on_file_lines_resize, column, cell)
1731+
1732+
1733+CONFIG_VERSION = 1
1734+
1735+default_conf = """\
1736+[gdp]
1737+version = %s
1738+
1739+[completer]
1740+show_accel = <Control>space
1741+suggest_completions = False
1742+
1743+[formatter]
1744+report_only_errors = False
1745+
1746+[finder]
1747+paths = <Current File>
1748+ <Working Directory>
1749+matches =
1750+files = <Any Text File>
1751+substitutions =
1752+""" % CONFIG_VERSION
1753+
1754+
1755+class Config(SafeConfigParser):
1756+ """A config parser that knows it's defaults and file locations."""
1757+
1758+ def __init__(self):
1759+ SafeConfigParser.__init__(self)
1760+ self.do_update_state = False
1761+ self.readfp(StringIO(default_conf), 'default_conf')
1762+ self.dir_path = os.path.join(BaseDirectory.xdg_config_home, 'gdp')
1763+ self.file_path = os.path.join(self.dir_path, 'gdp.conf')
1764+ self._loaded_file_path = None
1765+
1766+ def load(self):
1767+ """Read the optional conf."""
1768+ self._loaded_file_path = self.read(self.file_path)
1769+
1770+ def dump(self):
1771+ """Write the user changes to the optional conf."""
1772+ if not os.path.isdir(self.dir_path):
1773+ os.makedirs(self.dir_path)
1774+ with open(self.file_path, 'wb') as config_file:
1775+ self.write(config_file)
1776+
1777+ def getlist(self, section, key):
1778+ return self.get(section, key).split('\n')
1779+
1780+ def setlist(self, section, key, value_list):
1781+ value = '\n'.join(value_list)
1782+ self.set(section, key, value)
1783+
1784+
1785+config = Config()
1786+config.load()
1787
1788=== modified file 'plugins/gdp/bzr.py'
1789--- plugins/gdp/bzr.py 2011-12-22 18:09:53 +0000
1790+++ plugins/gdp/bzr.py 2012-02-07 18:01:21 +0000
1791@@ -1,9 +1,13 @@
1792-# Copyright (C) 2009-2011 - Curtis Hovey <sinzui.is at verizon.net>
1793+# Copyright (C) 2009-2012 - Curtis Hovey <sinzui.is at verizon.net>
1794 # This software is licensed under the GNU General Public License version 2
1795 # (see the file COPYING).
1796 """Bazaar integration."""
1797
1798-__metaclass__ = type
1799+
1800+__all__ = [
1801+ 'BzrProject',
1802+ ]
1803+
1804
1805 import os
1806 from StringIO import StringIO
1807@@ -35,17 +39,12 @@
1808 from gdp import ControllerMixin
1809
1810
1811-__all__ = [
1812- 'BzrProject',
1813- ]
1814-
1815-
1816 class BzrProject(ControllerMixin):
1817 """View and manage a bazaar branch."""
1818
1819 def __init__(self, window, working_tree=None):
1820 self.window = window
1821- self.working_tree = working_tree or self.set_working_tree()
1822+ self.working_tree = working_tree
1823
1824 def deactivate(self):
1825 """Clean up resources before deactivation."""
1826@@ -139,11 +138,6 @@
1827 """Diff the working tree against an anoter tree."""
1828 if another_tree is None:
1829 return
1830-# if not HAS_BZR_GTK:
1831-# return
1832- # XXX sinzui 2011-08-01: Hack diff on.
1833- from bzrlib.plugin import load_plugins
1834- load_plugins()
1835 from bzrlib.plugins.gtk.diff import DiffWindow
1836 window = DiffWindow(parent=self.window)
1837 window.set_diff("Working Tree", self.working_tree, another_tree)
1838@@ -161,7 +155,10 @@
1839
1840 def diff_changes_from_parent(self, action):
1841 """Create a diff of changes from the parent tree."""
1842- self._diff_tree(self._parent_tree)
1843+ try:
1844+ self._diff_tree(self._parent_tree)
1845+ except:
1846+ pass
1847
1848 def diff_changes_to_push(self, action):
1849 """Create a diff of changes to the push tree."""
1850
1851=== added file 'plugins/gdp/complete.py'
1852--- plugins/gdp/complete.py 1970-01-01 00:00:00 +0000
1853+++ plugins/gdp/complete.py 2012-02-07 18:01:21 +0000
1854@@ -0,0 +1,754 @@
1855+# Copyright (C) 2007-2012 - Curtis Hovey <sinzui.is at verizon.net>
1856+# This software is licensed under the GNU General Public License version 2
1857+# (see the file COPYING).
1858+"""A completer for document words and python symbols."""
1859+
1860+
1861+__all__ = [
1862+ 'BaseGenerator',
1863+ 'MarkupGenerator',
1864+ 'PythonGenerator',
1865+ 'Completer',
1866+ 'TextGenerator',
1867+ ]
1868+
1869+
1870+import re
1871+from gettext import gettext as _
1872+from keyword import kwlist
1873+from pydoc import TextDoc
1874+from xml.sax import saxutils
1875+
1876+from gi.repository import GObject
1877+from gi.repository import Gtk
1878+from gi.repository import GtkSource
1879+
1880+from gdp import (
1881+ config,
1882+ ControllerMixin,
1883+ )
1884+
1885+
1886+def get_word(document, word_pattern, end=None):
1887+ """Return a 3-tuple of the word fragment before the cursor.
1888+
1889+ The tuple contains the (word_fragment, start_iter, end_iter) to
1890+ identify the prefix and its starting and end position in the
1891+ document.
1892+ """
1893+ if end is None:
1894+ end = document.get_iter_at_mark(document.get_insert())
1895+ start = end.copy()
1896+ word = None
1897+
1898+ # When the preceding character is not alphanumeric,
1899+ # there is be no word before the cursor.
1900+ start_char = start.copy()
1901+ if start_char.backward_char():
1902+ char = start_char.get_char()
1903+ if not word_pattern.match(char):
1904+ return (None, start, end)
1905+
1906+ # GtkTextIter *_word_end() methods do not seek for '_' and '-', so
1907+ # we need to walk backwards through the iter to locate the word end.
1908+ count = 0
1909+ peek = start.copy()
1910+ while peek.backward_chars(1):
1911+ char = peek.get_char()
1912+ if not word_pattern.match(char):
1913+ break
1914+ else:
1915+ count += 1
1916+
1917+ if count > 0:
1918+ start.backward_chars(count)
1919+ word = document.get_text(start, end, True)
1920+ else:
1921+ word = None
1922+
1923+ return (word, start, end)
1924+
1925+
1926+class DynamicProposal(GObject.GObject, GtkSource.CompletionProposal):
1927+ """A common CompletionProposal for dymamically generated info."""
1928+ __gtype_name__ = "GDPDynamicProposal"
1929+
1930+ def __init__(self, word, info=None):
1931+ GObject.GObject.__init__(self)
1932+ self._word = word
1933+ self._info = info or ''
1934+
1935+ def __repr__(self):
1936+ return '<%s word="%s" at 0x%x>' % (
1937+ self.__class__.__name__, self._word, id(self))
1938+
1939+ def __eq__(self, other):
1940+ if not (isinstance(other, type(self))
1941+ or isinstance(self, type(other))):
1942+ return False
1943+ return other._word == self._word
1944+
1945+ def __lt__(self, other):
1946+ return self._word < other._word
1947+
1948+ def __hash__(self):
1949+ return hash((type(self), self._word))
1950+
1951+ def do_changed(self):
1952+ """See `CompletionProposal`."""
1953+ return False
1954+
1955+ def do_equal(self, other):
1956+ """See `CompletionProposal`."""
1957+ return self.__eq__(other)
1958+
1959+ def do_hash(self):
1960+ """See `CompletionProposal`."""
1961+ return self.__hash__()
1962+
1963+ def do_get_text(self):
1964+ """See `CompletionProposal`."""
1965+ return self._word
1966+
1967+ def do_get_label(self):
1968+ """See `CompletionProposal`."""
1969+ return self._word
1970+
1971+ def do_get_markup(self):
1972+ """See `CompletionProposal`."""
1973+ return saxutils.escape(self._word)
1974+
1975+ def do_get_info(self):
1976+ """See `CompletionProposal`."""
1977+ return self._info
1978+
1979+ def do_get_icon(self):
1980+ """See `CompletionProposal`."""
1981+ return None
1982+
1983+
1984+class PangoDoc(TextDoc):
1985+
1986+ def bold(self, text):
1987+ return '\x86%s\x87' % text
1988+
1989+ def document(self, mod, *args):
1990+ text = TextDoc.document(self, mod)
1991+ text = saxutils.escape(text)
1992+ text = text.replace('\x86', '<b>')
1993+ text = text.replace('\x87', '</b>')
1994+ return text
1995+
1996+
1997+class PythonProposal(DynamicProposal):
1998+ """A proposal that provides pydoc info."""
1999+
2000+ def do_get_info(self):
2001+ """See `CompletionProvider`."""
2002+ if not self._info:
2003+ return ''
2004+ return PangoDoc().document(self._info)
2005+
2006+
2007+class DynamicProvider(GObject.GObject, GtkSource.CompletionProvider):
2008+ """A common CompletionProvider for dynamically generated info."""
2009+ __gtype_name__ = "GDPDynamicProvider"
2010+ word_char = re.compile(r'[\w_-]', re.I)
2011+
2012+ def __init__(self, name, handler):
2013+ GObject.GObject.__init__(self)
2014+ self._name = name
2015+ self.last_line_no = 0
2016+ self.last_python_generator = None
2017+ self.handler = handler
2018+ self.info_widget = None
2019+ self.mark = None
2020+ theme = Gtk.IconTheme.get_default()
2021+ s, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU)
2022+ icon_name = 'format-justify-left' # Gtk.STOCK_JUSTIFY_LEFT
2023+ self.icon = theme.load_icon(icon_name, w, 0)
2024+
2025+ def mark_position(self, it):
2026+ """Create or move the mark of the word start."""
2027+ if not self.mark:
2028+ self.mark = it.get_buffer().create_mark(None, it, False)
2029+ else:
2030+ self.mark.get_buffer().move_mark(self.mark, it)
2031+
2032+ def get_word(self, context):
2033+ it = context.get_iter()
2034+ document = it.get_buffer()
2035+ word, start, end = get_word(document, self.word_char, it)
2036+ if word is not None:
2037+ self.mark_position(start)
2038+ else:
2039+ word = ''
2040+ return word
2041+
2042+ def is_interactive(self, context):
2043+ INTERACTIVE = GtkSource.CompletionActivation.INTERACTIVE
2044+ activation = context.get_activation() or INTERACTIVE
2045+ return activation == INTERACTIVE
2046+
2047+ def do_get_start_iter(self, context, proposal, iter_):
2048+ """See `CompletionProvider`."""
2049+ if not self.mark or self.mark.get_deleted():
2050+ return None
2051+ return self.mark.get_buffer().get_iter_at_mark(self.mark)
2052+
2053+ def do_match(self, context):
2054+ """See `CompletionProvider`."""
2055+ word = self.get_word(context)
2056+ if self.is_interactive(context) and len(word) < 4:
2057+ return False
2058+ return True
2059+
2060+ def get_generator(self, document, prefix):
2061+ """Return the specialized generator for document's language."""
2062+ cursor_iter = document.get_iter_at_mark(document.get_insert())
2063+ current_line_no = cursor_iter.get_line()
2064+ is_same_line = current_line_no == self.last_line_no
2065+ language_id = None
2066+ if hasattr(document, 'get_language'):
2067+ # How can we not get a document or language?
2068+ language = document.get_language()
2069+ if language is not None:
2070+ language_id = language.get_id()
2071+ if language_id == 'python':
2072+ if is_same_line and self.last_python_generator:
2073+ # Use the last generator which caches the python compilation.
2074+ return self.last_python_generator
2075+ self.last_python_generator = PythonGenerator(
2076+ document, prefix=prefix)
2077+ self.last_line_no = current_line_no
2078+ return self.last_python_generator
2079+ if language_id in (
2080+ 'xml', 'xslt', 'html', 'pt', 'mallard', 'docbook'):
2081+ return MarkupGenerator(document, prefix=prefix)
2082+ else:
2083+ # The text generator is never returned because get_proposals will
2084+ # use it in non-authoritative cases.
2085+ return None
2086+
2087+ def get_proposals(self, prefix, context):
2088+ """See `CompletionProvider`."""
2089+ all_words = []
2090+ is_authoritative = False
2091+ document = context.get_iter().get_buffer()
2092+ generator = self.get_generator(document, prefix)
2093+ if generator:
2094+ is_authoritative, words = generator.get_words(
2095+ is_interactive=self.is_interactive(context))
2096+ all_words += words
2097+ if not is_authoritative:
2098+ is_authoritative, simple_words = TextGenerator(
2099+ document, prefix=prefix).get_words()
2100+ simple_words = [
2101+ w for w in simple_words
2102+ if PythonProposal(w._word) not in all_words]
2103+ all_words += simple_words
2104+ if prefix:
2105+ # Ensure that the prefix is first in the list.
2106+ dynamic_prefix = DynamicProposal(prefix)
2107+ if dynamic_prefix in all_words:
2108+ all_words.remove(dynamic_prefix)
2109+ all_words.insert(0, dynamic_prefix)
2110+ return all_words
2111+
2112+ def _do_populate(self, context):
2113+ word = self.get_word(context)
2114+ if self.is_interactive(context) and len(word) < 4:
2115+ # Delete was pressed while the completer was displayed.
2116+ proposals = []
2117+ else:
2118+ proposals = self.get_proposals(word, context)
2119+ if self.is_interactive(context) and len(proposals) == 1:
2120+ # Tell the completer this act is finished without suggestions.
2121+ proposals = []
2122+ return proposals
2123+
2124+ def do_populate(self, context):
2125+ """See `CompletionProvider`."""
2126+ proposals = self._do_populate(context)
2127+ context.add_proposals(self, proposals, True)
2128+
2129+ def do_get_name(self):
2130+ """See `CompletionProvider`."""
2131+ return self._name
2132+
2133+ def do_activate_proposal(self, proposal, piter):
2134+ """See `CompletionProvider`."""
2135+ return self.handler(proposal, piter)
2136+
2137+ def do_get_icon(self):
2138+ """See `CompletionProvider`."""
2139+ return self.icon
2140+
2141+ def do_get_activation(self):
2142+ """See `CompletionProvider`."""
2143+ activation = GtkSource.CompletionActivation.USER_REQUESTED
2144+ if config.getboolean('completer', 'suggest_completions'):
2145+ activation |= GtkSource.CompletionActivation.INTERACTIVE
2146+ return activation
2147+
2148+ def do_get_info_widget(self, proposal):
2149+ """See `DynamicProvider`."""
2150+ if self.info_widget is None:
2151+ self.info_view = Gtk.Label(label='')
2152+ self.info_view.set_alignment(0.0, 0.0)
2153+ self.info_widget = Gtk.ScrolledWindow()
2154+ self.info_widget.add_with_viewport(self.info_view)
2155+ return self.info_widget
2156+
2157+ def do_update_info(self, proposal, info):
2158+ """See `CompletionProvider`."""
2159+ markup = proposal.get_info() or ''
2160+ self.info_view.set_markup(markup)
2161+ self.info_view.show()
2162+ self.info_widget.set_size_request(400, -1)
2163+
2164+GObject.type_register(DynamicProposal)
2165+GObject.type_register(DynamicProvider)
2166+
2167+
2168+class BaseGenerator(object):
2169+ """An abstract class representing the source of a word prefix."""
2170+
2171+ def __init__(self, document, prefix=None):
2172+ """Create a new Generator.
2173+
2174+ :param prefix: A `str`. The word prefix used to match words.
2175+ :param document: `gedit.Document`. The source of words to search.
2176+ """
2177+ self._prefix = prefix
2178+ self._document = document
2179+
2180+ word_char = re.compile(r'[\w_]', re.I)
2181+
2182+ @property
2183+ def string_before_cursor(self):
2184+ """Return the string that matches `word_char` before the cursor."""
2185+ text, start_iter, end_iter = get_word(self._document, self.word_char)
2186+ if text is None:
2187+ text = ''
2188+ return text
2189+
2190+ def ensure_prefix(self, prefix):
2191+ """Return the available prefix or an empty string."""
2192+ if prefix:
2193+ return prefix
2194+ elif self._prefix:
2195+ return self._prefix
2196+ else:
2197+ # Match all words in the text.
2198+ return ''
2199+
2200+ def get_words(self, prefix=None, is_interactive=False):
2201+ """Return a 2-tuple of is_authoritative and unique `set` of words.
2202+
2203+ :param prefix: A `str`. The word prefix used to match words.
2204+ :return: a 2-tuple of is_authoritative and a set of words.
2205+ is_authoritative is True when the set of words are the only words
2206+ that can match the prefix. The words are a set of words.
2207+ """
2208+ raise NotImplementedError
2209+
2210+ @property
2211+ def prefix(self):
2212+ """The prefix use to match words to."""
2213+ return self._prefix
2214+
2215+ @property
2216+ def file_path(self):
2217+ """The path to the file that is the word source."""
2218+ return self._document.get_uri_for_display()
2219+
2220+ @property
2221+ def text(self):
2222+ """The text of the gedit.Document or None."""
2223+ if not self._document:
2224+ return None
2225+ start_iter = self._document.get_start_iter()
2226+ end_iter = self._document.get_end_iter()
2227+ return self._document.get_text(start_iter, end_iter, True)
2228+
2229+
2230+class TextGenerator(BaseGenerator):
2231+ """Generate a list of words that match a given prefix for a document."""
2232+
2233+ def get_words(self, prefix=None, is_interactive=False):
2234+ """See `BaseGenerator.get_words`.
2235+
2236+ is_authoritative is always False because TextGenerator because it is
2237+ not for a specific document Language.
2238+ """
2239+ prefix = self.ensure_prefix(prefix)
2240+ is_authoritative = False
2241+ if len(prefix) > 0:
2242+ # Match words that are just the prefix too.
2243+ conditional = r'*'
2244+ else:
2245+ conditional = r'+'
2246+ pattern = r'\b(%s[\w-]%s)' % (re.escape(prefix), conditional)
2247+ word_re = re.compile(pattern, re.I)
2248+ words = word_re.findall(self.text)
2249+ # Find the unique words that do not have pseudo m-dashed in them.
2250+ words = set(words)
2251+ words = [DynamicProposal(word) for word in words if '--' not in word]
2252+ return is_authoritative, words
2253+
2254+
2255+class MarkupGenerator(BaseGenerator):
2256+ """Generate a list of elements and attributes for a document."""
2257+
2258+ word_char = re.compile(r'[^<>]')
2259+ common_attrs = []
2260+
2261+ INSIDE_ATTRIBUTES = 'INSIDE_ATTRIBUTES'
2262+ INSIDE_CLOSE = 'INSIDE_CLOSE'
2263+ INSIDE_OPEN = 'INSIDE_OPEN'
2264+ OUTSIDE = 'OUTSIDE'
2265+
2266+ def get_cursor_context(self):
2267+ """Return the context of the cursor in relation to the last tag."""
2268+ text, start_iter, end_iter = get_word(self._document, self.word_char)
2269+ if not start_iter.backward_char():
2270+ # The start was at the begining of the doc; no tags were found.
2271+ return self.OUTSIDE
2272+ char_iter = start_iter.copy()
2273+ char_iter.forward_char()
2274+ char = start_iter.get_char()
2275+ if char == '>':
2276+ return self.OUTSIDE
2277+ elif text and text.startswith('/'):
2278+ return self.INSIDE_CLOSE
2279+ elif text and ' ' in text:
2280+ return self.INSIDE_ATTRIBUTES
2281+ else:
2282+ return self.INSIDE_OPEN
2283+
2284+ def get_words(self, prefix=None, is_interactive=False):
2285+ """See `BaseGenerator.get_words`."""
2286+ prefix = self.ensure_prefix(prefix)
2287+ context = self.get_cursor_context()
2288+ if context == self.OUTSIDE:
2289+ # is_authoritative is false and there are no words because the
2290+ # cursor is not in a tag to complete.
2291+ return False, set()
2292+ is_authoritative = True
2293+ if context == self.INSIDE_OPEN:
2294+ words = set(self._get_open_tags(prefix))
2295+ elif context == self.INSIDE_ATTRIBUTES:
2296+ words = set(self._get_attributes(prefix))
2297+ else:
2298+ # Close tags is not a test because it returns a ordered list.
2299+ words = self._get_close_tags(prefix)
2300+ return is_authoritative, words
2301+
2302+ def get_cardinality(self, prefix):
2303+ if prefix:
2304+ # Match words that are just the prefix too.
2305+ return r'*'
2306+ else:
2307+ return r'+'
2308+
2309+ def _get_open_tags(self, prefix):
2310+ """Return all the tag names."""
2311+ cardinality = self.get_cardinality(prefix)
2312+ prefix = re.escape(prefix)
2313+ pattern = r'<(%s[\w_.:-]%s)' % (prefix, cardinality)
2314+ word_re = re.compile(pattern, re.I)
2315+ words = word_re.findall(self.text)
2316+ return [DynamicProposal(word) for word in words]
2317+
2318+ def _get_attributes(self, prefix):
2319+ pattern = r'<[\w_.:-]+ ([\w_.:-]*)=[^>]+>'
2320+ attrs_re = re.compile(pattern, re.I)
2321+ attr_clusters = attrs_re.findall(self.text)
2322+ attrs = set(self.common_attrs)
2323+ for attr_cluster in attr_clusters:
2324+ attr_pairs = attr_cluster.split()
2325+ for pair in attr_pairs:
2326+ attr = pair.split('=')
2327+ attrs.add(attr[0])
2328+ if prefix:
2329+ for attr in list(attrs):
2330+ if not attr.startswith(prefix):
2331+ attrs.remove(attr)
2332+ return [DynamicProposal(attr) for attr in attrs]
2333+
2334+ def _get_close_tags(self, prefix):
2335+ """Return the tags that are still open before the cursor."""
2336+ cardinality = self.get_cardinality(prefix)
2337+ prefix = re.escape(prefix)
2338+ # Get the text before the cursor.
2339+ start_iter = self._document.get_start_iter()
2340+ end_iter = self._document.get_iter_at_mark(
2341+ self._document.get_insert())
2342+ text = self._document.get_text(start_iter, end_iter, True)
2343+ # Get all the open tags.
2344+ open_pattern = r'<(%s[\w_.:-]%s)' % (prefix, cardinality)
2345+ open_re = re.compile(open_pattern, re.I)
2346+ open_tags = open_re.findall(text)
2347+ # Get all the empty tags.
2348+ empty_pattern = r'<(%s[\w_.:-]%s)[^>]*/>' % (prefix, cardinality)
2349+ empty_re = re.compile(empty_pattern, re.I)
2350+ empty_tags = empty_re.findall(text)
2351+ # Get all the close tags.
2352+ close_pattern = r'</(%s[\w_.:-]%s)' % (prefix, cardinality)
2353+ close_re = re.compile(close_pattern, re.I)
2354+ close_tags = close_re.findall(text)
2355+ # Return only the tags that are still open.
2356+ for tag in empty_tags:
2357+ if tag in open_tags:
2358+ open_tags.remove(tag)
2359+ for tag in close_tags:
2360+ if tag in open_tags:
2361+ open_tags.remove(tag)
2362+ return [DynamicProposal(tag + '>') for tag in open_tags]
2363+
2364+
2365+class PythonGenerator(BaseGenerator):
2366+ """Generate a list of Python symbols that match a given prefix."""
2367+
2368+ word_char = re.compile(r'[\w_.]', re.I)
2369+ _kwlist = None
2370+ _builtin = None
2371+
2372+ def __init__(self, document, prefix=None):
2373+ super(PythonGenerator, self).__init__(document, prefix)
2374+ self._local_symsbols = None
2375+
2376+ @property
2377+ def kwlist(self):
2378+ if self._kwlist is None:
2379+ self._kwlist = [
2380+ self._get_dynamic_proposal(None, word) for word in kwlist]
2381+ return self._kwlist
2382+
2383+ @property
2384+ def builtin(self):
2385+ if self._builtin is None:
2386+ import __builtin__
2387+ self._builtin = [
2388+ self._get_dynamic_proposal(__builtin__, name)
2389+ for name in dir(__builtin__)]
2390+ return self._builtin
2391+
2392+ def get_local_symbols(self, is_interactive=False):
2393+ if self._local_symsbols:
2394+ return self._local_symsbols
2395+ try:
2396+ pyo = compile(self._get_parsable_text(), 'sc.py', 'exec')
2397+ except SyntaxError:
2398+ # This cannot be completed because of syntax errors.
2399+ # Return
2400+ if not is_interactive:
2401+ self._document.emit('syntax-error-python')
2402+ return []
2403+ co_names = ('SIGNAL_RUN_LAST', 'TYPE_NONE', 'TYPE_PYOBJECT', 'object')
2404+ self._local_symsbols = [
2405+ self._get_dynamic_proposal(None, name)
2406+ for name in pyo.co_names if name not in co_names]
2407+ return self._local_symsbols
2408+
2409+ def get_words(self, prefix=None, is_interactive=False):
2410+ """See `BaseGenerator.get_words`.
2411+
2412+ :return: a 2-tuple of is_authoritative and a set of matching
2413+ identifiers. is_authoritative is True when the prefix is a part
2414+ of a dotted identifier.
2415+ """
2416+ prefix = self.ensure_prefix(prefix)
2417+ local_symsbols = self.get_local_symbols(is_interactive)
2418+ is_authoritative = False
2419+ if prefix == '' and local_symsbols:
2420+ is_authoritative = True
2421+
2422+ namespaces = self.string_before_cursor.split('.')
2423+ if len(namespaces) == 1:
2424+ # The identifier is scoped to this module (the document).
2425+ symbols = local_symsbols + self.builtin + self.kwlist
2426+ symbols = [proposal for proposal in symbols
2427+ if proposal.get_text().startswith(prefix)]
2428+ return is_authoritative, symbols
2429+
2430+ # Remove the prefix to create the module's full name.
2431+ namespaces.pop()
2432+ module_name = '.'.join(namespaces)
2433+ locald = {}
2434+ try:
2435+ # Check this file first.
2436+ module_ = eval(module_name, globals(), locald)
2437+ except NameError:
2438+ # Try a true import.
2439+ try:
2440+ module_ = __import__(module_name, globals(), locald, [])
2441+ except ImportError:
2442+ return is_authoritative, []
2443+ except:
2444+ return is_authoritative, []
2445+
2446+ for symbol in namespaces[1:]:
2447+ module_ = getattr(module_, symbol)
2448+ is_authoritative = True
2449+ symbols = [self._get_dynamic_proposal(module_, name)
2450+ for name in dir(module_) if name.startswith(prefix)]
2451+ return is_authoritative, symbols
2452+
2453+ def _get_parsable_text(self):
2454+ """Return the parsable text of the module.
2455+
2456+ The line being edited may not be valid syntax, so the line is
2457+ replaced with 'pass', or if it starts a block, it becomes 'if True:'
2458+ """
2459+ current_iter = self._document.get_iter_at_mark(
2460+ self._document.get_insert())
2461+ index = current_iter.get_line()
2462+ text_lines = self.text.splitlines()
2463+ if index + 1 == len(text_lines):
2464+ # The current line is the last line. Add a fake line because
2465+ # the compiler will require another line to follow a comment.
2466+ text_lines.append('')
2467+ current_indentation = self._get_indentation(text_lines[index])
2468+ next_indentation = self._get_indentation(text_lines[index + 1])
2469+ if len(next_indentation) > len(current_indentation):
2470+ # Make this line compilable for the next block.
2471+ text_lines[index] = current_indentation + 'if True:'
2472+ else:
2473+ # Comment-out this line so that it is not compiled.
2474+ text_lines[index] = current_indentation + 'pass'
2475+ return '\n'.join(text_lines)
2476+
2477+ def _get_indentation(self, line):
2478+ "Return the line's indentation"
2479+ indentation_pattern = re.compile(r'^[ \t]*')
2480+ match = indentation_pattern.match(line)
2481+ if match:
2482+ return match.group()
2483+ # No match means the indentation is an empty string.
2484+ return ''
2485+
2486+ def _get_dynamic_proposal(self, module, name):
2487+ try:
2488+ if module is None:
2489+ identifier = None
2490+ elif type(module) == 'dict':
2491+ identifier = module[name]
2492+ else:
2493+ identifier = module.__dict__[name]
2494+ except KeyError:
2495+ identifier = None
2496+ return PythonProposal(name, info=identifier)
2497+
2498+
2499+class Completer(ControllerMixin):
2500+ """This class manages the gedit.View's interaction with completions."""
2501+
2502+ word_char = re.compile(r'[\w_-]', re.I)
2503+
2504+ def __init__(self, window):
2505+ """Initialize the controller for the gedit.View."""
2506+ self.window = window
2507+ self.signal_ids = {}
2508+ self.view = None
2509+ self.completion = None
2510+ self.provider = None
2511+ self.completer_title = _('GDP words')
2512+ self.set_view(window.get_active_view())
2513+
2514+ def deactivate(self):
2515+ """Clean up resources before deactivation."""
2516+ self.set_view(None)
2517+
2518+ def set_view(self, view, is_reset=False):
2519+ """Set the view to be controlled.
2520+
2521+ Installs signal handlers for the view. Calling
2522+ document.get_uri_for_display() self.set_view(None) will effectively
2523+ remove all the control from the current view. when is_reset is True,
2524+ the current view's signals will be reset.
2525+ """
2526+ if view is self.view and not is_reset:
2527+ return
2528+
2529+ if self.view:
2530+ # Unregister the current view before assigning the new one.
2531+ self._disconnectSignal(self.view, 'destroy')
2532+ self._disconnectSignal(self.view, 'notify::editable')
2533+ if (self.completion
2534+ and self.provider in self.completion.get_providers()):
2535+ self.completion.remove_provider(self.provider)
2536+ self.completion = None
2537+ self.provider = None
2538+
2539+ self.view = view
2540+ if view is not None:
2541+ self.signal_ids['destroy'] = view.connect(
2542+ 'destroy', self.on_view_destroy)
2543+ self.signal_ids['notify::editable'] = view.connect(
2544+ 'notify::editable', self.on_notify_editable)
2545+ self.provider = DynamicProvider(
2546+ self.completer_title, self.on_proposal_activated)
2547+ self.completion = self.view.get_completion()
2548+ if self.provider not in self.completion.get_providers():
2549+ self.completion.add_provider(self.provider)
2550+
2551+ def _disconnectSignal(self, obj, signal):
2552+ """Disconnect the signal from the provided object."""
2553+ if signal in self.signal_ids:
2554+ obj.disconnect(self.signal_ids[signal])
2555+ del self.signal_ids[signal]
2556+
2557+ def show_completion(self, widget=None, data=None):
2558+ """Show the completion proposals."""
2559+ self.view.emit('show-completion')
2560+
2561+ def get_word_prefix(self, document):
2562+ """Return a 3-tuple of the word fragment before the cursor.
2563+
2564+ The tuple contains the (word_fragement, start_iter, end_iter) to
2565+ identify the prefix and its starting and end position in the
2566+ document.
2567+ """
2568+ return get_word(document, self.word_char)
2569+
2570+ def insert_word(self, word, start=None):
2571+ """Return True when the word is inserted into the Document.
2572+
2573+ The word cannot be None or an empty string.
2574+ """
2575+ assert word, "The word cannot be None or an empty string."
2576+ document = self.view.get_buffer()
2577+ if start:
2578+ document.delete(
2579+ start, document.get_iter_at_mark(document.get_insert()))
2580+ document.insert_at_cursor(word)
2581+
2582+ def on_proposal_activated(self, proposal, piter):
2583+ """Complete the word using the proposal."""
2584+ if not proposal:
2585+ return
2586+ document = self.view.get_buffer()
2587+ (ignored, start, end_) = self.get_word_prefix(document)
2588+ word = proposal.get_text()
2589+ self.insert_word(word, start)
2590+ return True
2591+
2592+ def on_suggest_completions_toggled(self, menu_item, data=None):
2593+ config.set(
2594+ 'completer', 'suggest_completions', str(menu_item.props.active))
2595+ config.dump()
2596+ self.set_view(self.view, is_reset=True)
2597+
2598+ def on_notify_editable(self, view, param_spec):
2599+ """Update the controller when the view editable state changes.
2600+
2601+ This method is ultimately responsible for enabling and disabling
2602+ the completion widget for completer.
2603+ """
2604+ self.set_view(view, True)
2605+
2606+ def on_view_destroy(self, view):
2607+ """Disconnect the controller."""
2608+ self.deactivate()
2609
2610=== added file 'plugins/gdp/complete.ui'
2611--- plugins/gdp/complete.ui 1970-01-01 00:00:00 +0000
2612+++ plugins/gdp/complete.ui 2012-02-07 18:01:21 +0000
2613@@ -0,0 +1,76 @@
2614+<?xml version="1.0" encoding="UTF-8"?>
2615+<interface>
2616+ <!-- interface-requires gtk+ 3.0 -->
2617+ <object class="GtkGrid" id="preferences">
2618+ <property name="visible">True</property>
2619+ <property name="can_focus">False</property>
2620+ <property name="margin_left">6</property>
2621+ <property name="margin_right">6</property>
2622+ <property name="margin_top">6</property>
2623+ <property name="margin_bottom">6</property>
2624+ <property name="column_spacing">6</property>
2625+ <child>
2626+ <object class="GtkLabel" id="label2">
2627+ <property name="visible">True</property>
2628+ <property name="can_focus">False</property>
2629+ <property name="label" translatable="yes">Completer shortcut</property>
2630+ </object>
2631+ <packing>
2632+ <property name="left_attach">0</property>
2633+ <property name="top_attach">0</property>
2634+ <property name="width">1</property>
2635+ <property name="height">1</property>
2636+ </packing>
2637+ </child>
2638+ <child>
2639+ <object class="GtkEntry" id="shortcut_entry">
2640+ <property name="visible">True</property>
2641+ <property name="can_focus">True</property>
2642+ <property name="has_tooltip">True</property>
2643+ <property name="tooltip_markup" translatable="yes">Enter one or more modifiers and the key name.</property>
2644+ <property name="tooltip_text" translatable="yes">Enter one or more modifiers and the key name.</property>
2645+ <property name="invisible_char">•</property>
2646+ <property name="invisible_char_set">True</property>
2647+ <property name="placeholder_text">&lt;Control&gt;&lt;Alt&gt;key-name</property>
2648+ <signal name="focus-out-event" handler="on_focus_out_event" swapped="no"/>
2649+ </object>
2650+ <packing>
2651+ <property name="left_attach">1</property>
2652+ <property name="top_attach">0</property>
2653+ <property name="width">1</property>
2654+ <property name="height">1</property>
2655+ </packing>
2656+ </child>
2657+ <child>
2658+ <placeholder/>
2659+ </child>
2660+ <child>
2661+ <placeholder/>
2662+ </child>
2663+ <child>
2664+ <placeholder/>
2665+ </child>
2666+ <child>
2667+ <placeholder/>
2668+ </child>
2669+ <child>
2670+ <placeholder/>
2671+ </child>
2672+ <child>
2673+ <placeholder/>
2674+ </child>
2675+ <child>
2676+ <object class="GtkLabel" id="label1">
2677+ <property name="visible">True</property>
2678+ <property name="can_focus">False</property>
2679+ <property name="label" translatable="yes">Requires a restart of Gedit.</property>
2680+ </object>
2681+ <packing>
2682+ <property name="left_attach">1</property>
2683+ <property name="top_attach">1</property>
2684+ <property name="width">1</property>
2685+ <property name="height">1</property>
2686+ </packing>
2687+ </child>
2688+ </object>
2689+</interface>
2690
2691=== modified file 'plugins/gdp/find.py'
2692--- plugins/gdp/find.py 2011-09-08 12:12:28 +0000
2693+++ plugins/gdp/find.py 2012-02-07 18:01:21 +0000
2694@@ -1,11 +1,9 @@
2695 #!/usr/bin/python
2696-# Copyright (C) 2009-2011 - Curtis Hovey <sinzui.is at verizon.net>
2697+# Copyright (C) 2009-2012 - Curtis Hovey <sinzui.is at verizon.net>
2698 # This software is licensed under the GNU General Public License version 2
2699 # (see the file COPYING).
2700 """Find in files and replace strings in many files."""
2701
2702-__metaclass__ = type
2703-
2704 __all__ = [
2705 'extract_match',
2706 'find_files',
2707@@ -24,9 +22,14 @@
2708 from optparse import OptionParser
2709
2710 from gi.repository import GObject
2711+from gi.repository import Gdk
2712 from gi.repository import Gtk
2713
2714-from gdp import ControllerMixin, setup_file_lines_view
2715+from gdp import (
2716+ config,
2717+ ControllerMixin,
2718+ setup_file_lines_view,
2719+ )
2720
2721
2722 find_params = namedtuple(
2723@@ -124,9 +127,9 @@
2724 None,
2725 (file_path, mime_type, 0, None, self.find_params.path))
2726 if self.substitution is None:
2727- icon = Gtk.STOCK_FIND
2728+ icon = 'edit-find' # Gtk.STOCK_FIND
2729 else:
2730- icon = Gtk.STOCK_FIND_AND_REPLACE
2731+ icon = 'edit-find-replace' # Gtk.STOCK_FIND_AND_REPLACE
2732 for line in summary['lines']:
2733 self.treestore.append(piter,
2734 (file_path, icon, line['lineno'], line['text'],
2735@@ -168,15 +171,18 @@
2736 self.pattern_comboentry = self.widgets.get_object(
2737 'pattern_comboentry')
2738 self.pattern_comboentry.get_child().set_width_chars(24)
2739- self.setup_comboentry(self.pattern_comboentry)
2740+ self.setup_comboentry(self.pattern_comboentry, config_key='matches')
2741 self.path_comboentry = self.widgets.get_object('path_comboentry')
2742- self.setup_comboentry(self.path_comboentry, self.CURRENT_FILE)
2743+ self.setup_comboentry(
2744+ self.path_comboentry, self.CURRENT_FILE, 'paths')
2745 self.update_comboentry(self.path_comboentry, os.getcwd())
2746 self.file_comboentry = self.widgets.get_object('file_comboentry')
2747- self.setup_comboentry(self.file_comboentry, self.ANY_FILE)
2748+ self.setup_comboentry(
2749+ self.file_comboentry, self.ANY_FILE, 'files')
2750 self.substitution_comboentry = self.widgets.get_object(
2751 'substitution_comboentry')
2752- self.setup_comboentry(self.substitution_comboentry)
2753+ self.setup_comboentry(
2754+ self.substitution_comboentry, config_key='substitutions')
2755 self.file_lines_view = self.widgets.get_object('file_lines_view')
2756 setup_file_lines_view(self.file_lines_view, self, 'Matches')
2757
2758@@ -185,11 +191,22 @@
2759 panel = self.window.get_side_panel()
2760 panel.remove_item(self.find_panel)
2761
2762- def setup_comboentry(self, comboentry, default=None):
2763+ def valid_state(self, config_key, value):
2764+ if (config_key == 'paths'
2765+ and value not in (self.WORKING_DIRECTORY, self.CURRENT_FILE)):
2766+ return os.path.exists(value)
2767+ return True
2768+
2769+ def setup_comboentry(self, comboentry, default=None, config_key=None):
2770 liststore = Gtk.ListStore.new([GObject.TYPE_STRING])
2771 liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
2772 comboentry.set_model(liststore)
2773 comboentry.set_entry_text_column(0)
2774+ if config_key is not None:
2775+ for value in config.getlist('finder', config_key):
2776+ # This might need to know that paths contains dirs.
2777+ if value and self.valid_state(config_key, value):
2778+ self.update_comboentry(comboentry, value, False)
2779 if default is not None:
2780 self.update_comboentry(comboentry, default)
2781
2782@@ -225,7 +242,7 @@
2783
2784 def show_replace(self, action):
2785 """Show the finder pane and expand replace."""
2786- self.show(None, None)
2787+ self.show(None)
2788 self.widgets.get_object('actions').activate()
2789
2790 @property
2791@@ -262,6 +279,23 @@
2792 self.update_comboentry(
2793 self.path_comboentry, new_path, set_active=False)
2794
2795+ def save_find_data(self):
2796+ data = [
2797+ ('paths', self.path),
2798+ ('matches', self.match_pattern),
2799+ ('files', self.file_comboentry.get_active_text()),
2800+ ('substitutions', self.substitution_comboentry.get_active_text()),
2801+ ]
2802+ for key, value in data:
2803+ history = config.getlist('finder', key)
2804+ if value in history:
2805+ history.remove(value)
2806+ history.insert(0, value)
2807+ if len(history) > 10:
2808+ history = history[0:10]
2809+ config.setlist('finder', key, history)
2810+ config.dump()
2811+
2812 def get_find_params(self):
2813 """Return the find parameters as a tuple."""
2814 return find_params(
2815@@ -278,6 +312,7 @@
2816 find_params = self.get_find_params()
2817 self.last_find = find_params
2818 pattern = find_params.pattern
2819+ self.save_find_data()
2820 self.file_lines_view.get_column(0).props.title = (
2821 'Matches for [%s]' % pattern)
2822 find_worker = FinderWorker(
2823@@ -288,6 +323,42 @@
2824 if self.path_comboentry.get_active_text() == self.CURRENT_FILE:
2825 self.file_lines_view.expand_all()
2826
2827+ def _get_untested_replacement_dialog(self, find_params):
2828+ dialog_flags = Gtk.DialogFlags
2829+ dialog = Gtk.Dialog(
2830+ title="Untested replacement", parent=self.window,
2831+ flags=dialog_flags.MODAL | dialog_flags.DESTROY_WITH_PARENT,
2832+ buttons=(Gtk.STOCK_FIND, Gtk.ResponseType.REJECT,
2833+ Gtk.STOCK_FIND_AND_REPLACE, Gtk.ResponseType.ACCEPT))
2834+ question = Gtk.Label(
2835+ _("Do want to test this replacement using Find first?"))
2836+ question.set_alignment(0, 0)
2837+ question.props.xpad = 6
2838+ dialog.vbox.pack_start(question, True, False, 6)
2839+ question.show()
2840+ params_summary = Gtk.Label()
2841+ params_summary.set_markup(_(
2842+ "<b>Look in:</b> %s\n"
2843+ "<b>Search for:</b> %s\n"
2844+ "<b>Regular expression:</b> %s\n"
2845+ "<b>Match case:</b> %s\n"
2846+ "<b>File name pattern:</b> %s")
2847+ % find_params)
2848+ params_summary.props.selectable = True
2849+ params_summary.props.xpad = 3
2850+ params_summary.props.ypad = 3
2851+ box = Gtk.EventBox()
2852+ box.set_border_width(6)
2853+ white = Gdk.color_parse('#fff')
2854+ box.modify_bg(Gtk.StateType.NORMAL, white)
2855+ box.add(params_summary)
2856+ dialog.vbox.pack_start(box, True, False, 0)
2857+ box.show()
2858+ params_summary.show()
2859+ # Uncomment the next line to preview the layout.
2860+ #dialog.run()
2861+ return dialog
2862+
2863 def on_replace_in_files(self, widget=None):
2864 """Find, replace, and present the matches."""
2865 substitution = self.substitution_comboentry.get_active_text() or ''
2866@@ -295,36 +366,7 @@
2867 response = Gtk.ResponseType.ACCEPT
2868 find_params = self.get_find_params()
2869 if self.last_find != find_params:
2870- dialog_flags = Gtk.DialogFlags
2871- dialog = Gtk.Dialog(
2872- title="Untested replacement", parent=self.window,
2873- flags=dialog_flags.MODAL | dialog_flags.DESTROY_WITH_PARENT,
2874- buttons=(Gtk.STOCK_FIND, Gtk.ResponseType.REJECT,
2875- Gtk.STOCK_FIND_AND_REPLACE, Gtk.ResponseType.ACCEPT))
2876- question = Gtk.Label(
2877- _("Do want to test this replacement using Find first?"))
2878- question.set_alignment(0, 0)
2879- question.props.xpad = 6
2880- dialog.vbox.pack_start(question, expand=False, padding=6)
2881- question.show()
2882- params_summary = Gtk.Label()
2883- params_summary.set_markup(_(
2884- "<b>Look in:</b> %s\n"
2885- "<b>Search for:</b> %s\n"
2886- "<b>Regular expression:</b> %s\n"
2887- "<b>Match case:</b> %s\n"
2888- "<b>File name pattern:</b> %s")
2889- % find_params)
2890- params_summary.props.selectable = True
2891- params_summary.props.xpad = 3
2892- params_summary.props.ypad = 3
2893- box = Gtk.EventBox()
2894- box.set_border_width(6)
2895- box.modify_bg(Gtk.STATE_NORMAL, Gtk.gdk.Color('#fff'))
2896- box.add(params_summary)
2897- dialog.vbox.pack_start(box)
2898- box.show()
2899- params_summary.show()
2900+ dialog = self._get_untested_replacement_dialog(find_params)
2901 response = dialog.run()
2902 dialog.destroy()
2903 if response == Gtk.ResponseType.REJECT:
2904
2905=== modified file 'plugins/gdp/find.ui'
2906--- plugins/gdp/find.ui 2011-09-08 12:12:28 +0000
2907+++ plugins/gdp/find.ui 2012-02-07 18:01:21 +0000
2908@@ -18,8 +18,6 @@
2909 <property name="can_focus">False</property>
2910 <property name="row_spacing">6</property>
2911 <property name="column_spacing">6</property>
2912- <property name="n_rows">2</property>
2913- <property name="n_columns">2</property>
2914 <child>
2915 <object class="GtkLabel" id="path_label">
2916 <property name="visible">True</property>
2917@@ -60,7 +58,6 @@
2918 <property name="has_tooltip">True</property>
2919 <property name="tooltip_markup" translatable="yes">The plain text or Python regular expression to find in files.</property>
2920 <property name="tooltip_text" translatable="yes">The plain text or Python regular expression to find in files.</property>
2921- <property name="has_frame">False</property>
2922 <property name="has_entry">True</property>
2923 <child internal-child="entry">
2924 <object class="GtkEntry" id="comboboxtext-entry3">
2925@@ -107,7 +104,6 @@
2926 <property name="tooltip_markup" translatable="yes">The directory to start searching in.</property>
2927 <property name="tooltip_text" translatable="yes">The directory to start searching in.</property>
2928 <property name="hexpand">True</property>
2929- <property name="has_frame">False</property>
2930 <property name="has_entry">True</property>
2931 <child internal-child="entry">
2932 <object class="GtkEntry" id="comboboxtext-entry4">
2933@@ -123,6 +119,21 @@
2934 <property name="height">1</property>
2935 </packing>
2936 </child>
2937+ <child>
2938+ <placeholder/>
2939+ </child>
2940+ <child>
2941+ <placeholder/>
2942+ </child>
2943+ <child>
2944+ <placeholder/>
2945+ </child>
2946+ <child>
2947+ <placeholder/>
2948+ </child>
2949+ <child>
2950+ <placeholder/>
2951+ </child>
2952 </object>
2953 <packing>
2954 <property name="expand">False</property>
2955@@ -198,8 +209,6 @@
2956 <object class="GtkComboBoxText" id="file_comboentry">
2957 <property name="visible">True</property>
2958 <property name="can_focus">False</property>
2959- <property name="has_frame">False</property>
2960- <property name="button_sensitivity">off</property>
2961 <property name="has_entry">True</property>
2962 <child internal-child="entry">
2963 <object class="GtkEntry" id="comboboxtext-entry25">
2964@@ -300,7 +309,6 @@
2965 The replacement may use backslash escapes to access groups in match expression</property>
2966 <property name="tooltip_text" translatable="yes">The text to replace each found match with.
2967 The replacement may use backslash escapes to access groups in match expression</property>
2968- <property name="has_frame">False</property>
2969 <property name="has_entry">True</property>
2970 <child internal-child="entry">
2971 <object class="GtkEntry" id="comboboxtext-entry23">
2972
2973=== modified file 'plugins/gdp/format.py'
2974--- plugins/gdp/format.py 2011-09-08 12:12:28 +0000
2975+++ plugins/gdp/format.py 2012-02-07 18:01:21 +0000
2976@@ -1,4 +1,4 @@
2977-# Copyright (C) 2009-2011 - Curtis Hovey <sinzui.is at verizon.net>
2978+# Copyright (C) 2009-2012 - Curtis Hovey <sinzui.is at verizon.net>
2979 # This software is licensed under the GNU General Public License version 2
2980 # (see the file COPYING).
2981 """Format text and code"""
2982@@ -10,15 +10,39 @@
2983 from gettext import gettext as _
2984 import os
2985 import re
2986+from tempfile import NamedTemporaryFile
2987 from textwrap import wrap
2988
2989-from gi.repository import GConf
2990-from gi.repository import Gtk
2991+from gi.repository import (
2992+ Gio,
2993+ Gtk,
2994+ )
2995
2996 from pocketlint.formatdoctest import DoctestReviewer
2997-from pocketlint.formatcheck import Language, Reporter, UniversalChecker
2998-
2999-from gdp import ControllerMixin, setup_file_lines_view
3000+from pocketlint.formatcheck import (
3001+ Language,
3002+ Reporter,
3003+ UniversalChecker,
3004+ )
3005+
3006+from gdp import (
3007+ config,
3008+ ControllerMixin,
3009+ setup_file_lines_view,
3010+ )
3011+
3012+
3013+class FilteredReporter(Reporter):
3014+ """A class that can report only errors."""
3015+
3016+ @property
3017+ def error_only(self):
3018+ return config.getboolean('formatter', 'report_only_errors')
3019+
3020+ @error_only.setter
3021+ def error_only(self, val):
3022+ # Suppress the set behaviour because the config controls the rules.
3023+ pass
3024
3025
3026 class Formatter(ControllerMixin):
3027@@ -108,12 +132,20 @@
3028 lines = [line.rstrip() for line in text.splitlines()]
3029 self._put_bounded_text(bounds, '\n'.join(lines))
3030
3031+ def get_tab_size(self):
3032+ tab_size = 4
3033+ try:
3034+ settings_schema = 'org.gnome.gedit.preferences.editor'
3035+ settings = Gio.Settings.new(settings_schema)
3036+ tab_size = settings.get_uint('tabs-size')
3037+ except:
3038+ pass
3039+ return tab_size
3040+
3041 def tabs_to_spaces(self, action):
3042 """Fix the selection's line endings."""
3043+ tab_size = self.get_tab_size()
3044 bounds, text = self._get_bounded_text()
3045- gconf_client = GConf.Client.get_default()
3046- tab_size = gconf_client.get_int(
3047- '/apps/gedit-2/preferences/editor/tabs/tabs_size') or 4
3048 tab_spaces = ' ' * tab_size
3049 lines = [line.replace('\t', tab_spaces) for line in text.splitlines()]
3050 self._put_bounded_text(bounds, '\n'.join(lines))
3051@@ -190,14 +222,19 @@
3052 line = self._single_line(text)
3053 lines = wrap(
3054 line, width=width, initial_indent=padding,
3055- subsequent_indent=padding)
3056+ subsequent_indent=padding, break_on_hyphens=False)
3057 paragraph = '\n'.join(lines)
3058 return paragraph
3059
3060 def rewrap_text(self, action):
3061 """Rewrap the paragraph."""
3062 bounds, text = self._get_bounded_text()
3063- text = self._wrap_text(text)
3064+ width = 78
3065+ file_path = self.active_document.get_uri_for_display()
3066+ language = Language.get_language(file_path)
3067+ if language in (Language.TEXT, None):
3068+ width = 72
3069+ text = self._wrap_text(text, width=width)
3070 self._put_bounded_text(bounds, text)
3071
3072 def reformat_css(self, action):
3073@@ -271,18 +308,32 @@
3074 new_text = reviewer.format()
3075 self._put_bounded_text(bounds, new_text)
3076
3077+ def _ensure_file_path(self, checker):
3078+ if os.path.isfile(checker.file_path):
3079+ return None
3080+ temp_file = NamedTemporaryFile(suffix='gdp', delete=False)
3081+ temp_file.write(checker.text)
3082+ temp_file.flush()
3083+ checker.file_path = temp_file.name
3084+ return temp_file
3085+
3086 def _check_style(self, document):
3087 """Check the style and syntax of a document."""
3088 file_path = document.get_uri_for_display()
3089 start_iter = document.get_start_iter()
3090 end_iter = document.get_end_iter()
3091 text = document.get_text(start_iter, end_iter, True)
3092- reporter = Reporter(
3093+ reporter = FilteredReporter(
3094 Reporter.FILE_LINES, treeview=self.file_lines_view)
3095 language = Language.get_language(file_path)
3096 checker = UniversalChecker(
3097 file_path, text=text, language=language, reporter=reporter)
3098- checker.check()
3099+ temp_file = self._ensure_file_path(checker)
3100+ try:
3101+ checker.check()
3102+ finally:
3103+ if temp_file:
3104+ temp_file.unlink(temp_file.name)
3105
3106 def check_style(self, action, documents=None, quiet=False):
3107 """Check the style and syntax of the active document."""
3108@@ -305,3 +356,8 @@
3109 def check_all_style(self, action):
3110 """Check the style and syntax of all open documents."""
3111 self.check_style(None, documents=self.window.get_documents())
3112+
3113+ def on_show_syntax_errors_only_toggled(self, menu_item, data=None):
3114+ config.set(
3115+ 'formatter', 'report_only_errors', str(menu_item.props.active))
3116+ config.dump()
3117
3118=== removed file 'plugins/gdp/syntaxcompleter.py'
3119--- plugins/gdp/syntaxcompleter.py 2011-09-08 12:12:28 +0000
3120+++ plugins/gdp/syntaxcompleter.py 1970-01-01 00:00:00 +0000
3121@@ -1,688 +0,0 @@
3122-# Copyright (C) 2007-2011 - Curtis Hovey <sinzui.is at verizon.net>
3123-# This software is licensed under the GNU General Public License version 2
3124-# (see the file COPYING).
3125-"""A syntax completer for document words and python symbols."""
3126-
3127-
3128-__metaclass__ = type
3129-
3130-__all__ = [
3131- 'BaseSyntaxGenerator',
3132- 'MarkupGenerator',
3133- 'PythonSyntaxGenerator',
3134- 'SyntaxController',
3135- 'TextGenerator',
3136- ]
3137-
3138-
3139-import re
3140-from gettext import gettext as _
3141-from keyword import kwlist
3142-from pydoc import TextDoc
3143-from xml.sax import saxutils
3144-
3145-from gi.repository import GObject
3146-from gi.repository import Gtk
3147-from gi.repository import GtkSource
3148-
3149-from gdp import ControllerMixin
3150-
3151-
3152-lang_manager = GtkSource.LanguageManager.get_default()
3153-doctest_language = lang_manager.get_language('doctest')
3154-
3155-doctest_pattern = re.compile(
3156- r'^.*(doc|test|stories).*/.*\.(txt|doctest)$')
3157-
3158-
3159-def get_word(document, word_pattern, end=None):
3160- """Return a 3-tuple of the word fragment before the cursor.
3161-
3162- The tuple contains the (word_fragment, start_iter, end_iter) to
3163- identify the prefix and its starting and end position in the
3164- document.
3165- """
3166- if end is None:
3167- end = document.get_iter_at_mark(document.get_insert())
3168- start = end.copy()
3169- word = None
3170-
3171- # When the preceding character is not alphanumeric,
3172- # there is be no word before the cursor.
3173- start_char = start.copy()
3174- if start_char.backward_char():
3175- # XXX sinzui 2011-01-07: get_char() dies, but get_text works.
3176- # char = start_char.get_char()
3177- char = start_char.get_text(start)[0]
3178- if not word_pattern.match(char):
3179- return (None, start, end)
3180-
3181- # GtkTextIter *_word_end() methods do not seek for '_' and '-', so
3182- # we need to walk backwards through the iter to locate the word end.
3183- count = 0
3184- peek = start.copy()
3185- while peek.backward_chars(1):
3186- # XXX sinzui 2011-01-07: get_char() dies, but get_text works.
3187- char = peek.get_text(start)[0]
3188- if not word_pattern.match(char):
3189- break
3190- else:
3191- count += 1
3192-
3193- if count > 0:
3194- start.backward_chars(count)
3195- word = document.get_text(start, end, True)
3196- else:
3197- word = None
3198-
3199- return (word, start, end)
3200-
3201-
3202-class DynamicProposal(GObject.GObject, GtkSource.CompletionProposal):
3203- """A common CompletionProposal for dymamically generated info.
3204-
3205- XXX sinzui 2010-03-14: do_changed, do_equal, do_get_icon, do_get_label,
3206- do_hash may need implementation.
3207- """
3208- __gtype_name__ = "GDPDynamicProposal"
3209-
3210- def __init__(self, word, info=None):
3211- GObject.GObject.__init__(self)
3212- self._word = word
3213- self._info = info or ''
3214-
3215- def __repr__(self):
3216- return '<%s word="%s" at 0x%x>' % (
3217- self.__class__.__name__, self._word, id(self))
3218-
3219- def __eq__(self, other):
3220- if type(other) != type(self):
3221- return False
3222- return other._word == self._word and other._info == self._info
3223-
3224- def __lt__(self, other):
3225- return self._word < other._word
3226-
3227- def __hash__(self):
3228- return hash((type(self), self._word, self._info))
3229-
3230- def equal(self, other):
3231- return self.__eq__(other)
3232-
3233- def hash(self):
3234- return self.__hash__()
3235-
3236- def do_get_text(self):
3237- """See `CompletionProvider`."""
3238- return self._word
3239-
3240- def do_get_markup(self):
3241- """See `CompletionProvider`."""
3242- return saxutils.escape(self._word)
3243-
3244- def do_get_info(self):
3245- """See `CompletionProvider`."""
3246- return self._info
3247-
3248-
3249-class PangoDoc(TextDoc):
3250-
3251- def bold(self, text):
3252- return '\x86%s\x87' % text
3253-
3254- def document(self, mod, *args):
3255- text = TextDoc.document(self, mod)
3256- text = saxutils.escape(text)
3257- text = text.replace('\x86', '<b>')
3258- text = text.replace('\x87', '</b>')
3259- return text
3260-
3261-
3262-class PythonProposal(DynamicProposal):
3263- """A proposal that provides pydoc info."""
3264-
3265- def do_get_info(self):
3266- """See `CompletionProvider`."""
3267- if self._info is None:
3268- return None
3269- return PangoDoc().document(self._info)
3270-
3271-
3272-class DynamicProvider(GObject.GObject, GtkSource.CompletionProvider):
3273- """A common CompletionProvider for dynamically generated info."""
3274- __gtype_name__ = "GDPDynamicProvider"
3275- word_char = re.compile(r'[\w_-]', re.I)
3276-
3277- def __init__(self, name, language_id, handler, document):
3278- GObject.GObject.__init__(self)
3279- self._name = name
3280- self.proposals = []
3281- self.language_id = language_id
3282- self.handler = handler
3283- self.document = document
3284- self.info_widget = None
3285- self.mark = None
3286- theme = Gtk.IconTheme.get_default()
3287- s, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU)
3288- try:
3289- self.icon = theme.load_icon(Gtk.STOCK_JUSTIFY_LEFT, w, 0)
3290- except:
3291- # The theme is not complete.
3292- self.icon = None
3293-
3294- def mark_position(self, it):
3295- """Create or move the mark of the word start."""
3296- if not self.mark:
3297- self.mark = it.get_buffer().create_mark(None, it, False)
3298- else:
3299- self.mark.get_buffer().move_mark(self.mark, it)
3300-
3301- def get_word(self, context):
3302- """See `CompletionProvider`."""
3303- it = context.get_iter()
3304- word, start, end = get_word(self.document, self.word_char, it)
3305- if word is not None:
3306- self.mark_position(start)
3307- return word
3308-
3309- def do_get_start_iter(self, context, proposal, iter_):
3310- """See `CompletionProvider`."""
3311- if not self.mark or self.mark.get_deleted():
3312- return None
3313- return self.mark.get_buffer().get_iter_at_mark(self.mark)
3314-
3315- def do_match(self, context):
3316- """See `CompletionProvider`."""
3317- return True
3318-
3319- def get_generator(self, document, prefix):
3320- """Return the specialized generator for document's language."""
3321- if self.language_id == 'python':
3322- return PythonSyntaxGenerator(document, prefix=prefix)
3323- if self.language_id in (
3324- 'xml', 'xslt', 'html', 'pt', 'mallard', 'docbook'):
3325- return MarkupGenerator(document, prefix=prefix)
3326- else:
3327- # The text generator is never returned because get_proposals will
3328- # use it in non-authoritative cases.
3329- return None
3330-
3331- def get_proposals(self, prefix):
3332- """See `CompletionProvider`."""
3333- all_words = []
3334- is_authoritative = False
3335- generator = self.get_generator(self.document, prefix)
3336- if generator:
3337- is_authoritative, words = generator.get_words()
3338- all_words += words
3339- if not is_authoritative:
3340- is_authoritative, simple_words = TextGenerator(
3341- self.document, prefix=prefix).get_words()
3342- all_words += simple_words
3343- return all_words
3344-
3345- def do_populate(self, context):
3346- """See `CompletionProvider`."""
3347- proposals = self.get_proposals(self.get_word(context))
3348- context.add_proposals(self, proposals, True)
3349-
3350- def do_get_name(self):
3351- """See `CompletionProvider`."""
3352- return self._name
3353-
3354- def do_activate_proposal(self, proposal, piter):
3355- """See `CompletionProvider`."""
3356- return self.handler(proposal, piter)
3357-
3358- def do_get_icon(self):
3359- """See `CompletionProvider`."""
3360- return self.icon
3361-
3362- def do_get_activation(self):
3363- """See `CompletionProvider`."""
3364- return GtkSource.CompletionActivation.USER_REQUESTED
3365-
3366- def do_get_info_widget(self, proposal):
3367- """See `DynamicProvider`."""
3368- if self.info_widget is None:
3369- self.info_view = Gtk.Label(label='')
3370- self.info_view.set_alignment(0.0, 0.0)
3371- self.info_widget = Gtk.ScrolledWindow()
3372- self.info_widget.add_with_viewport(self.info_view)
3373- return self.info_widget
3374-
3375- def do_update_info(self, proposal, info):
3376- """See `CompletionProvider`."""
3377- markup = proposal.get_info() or ''
3378- self.info_view.set_markup(markup)
3379- self.info_view.show()
3380- self.info_widget.set_size_request(400, -1)
3381-
3382-GObject.type_register(DynamicProposal)
3383-GObject.type_register(DynamicProvider)
3384-
3385-
3386-class BaseSyntaxGenerator:
3387- """An abstract class representing the source of a word prefix."""
3388-
3389- def __init__(self, document, prefix=None):
3390- """Create a new SyntaxGenerator.
3391-
3392- :param prefix: A `str`. The word prefix used to match words.
3393- :param document: `gedit.Document`. The source of words to search.
3394- """
3395- self._prefix = prefix
3396- self._document = document
3397-
3398- word_char = re.compile(r'[\w_]', re.I)
3399-
3400- @property
3401- def string_before_cursor(self):
3402- """Return the string that matches `word_char` before the cursor."""
3403- text, start_iter, end_iter = get_word(self._document, self.word_char)
3404- if text is None:
3405- text = ''
3406- return text
3407-
3408- def ensure_prefix(self, prefix):
3409- """Return the available prefix or an empty string."""
3410- if prefix:
3411- return prefix
3412- elif self._prefix:
3413- return self._prefix
3414- else:
3415- # Match all words in the text.
3416- return ''
3417-
3418- def get_words(self, prefix=None):
3419- """Return a 2-tuple of is_authoritative and unique `set` of words.
3420-
3421- :param prefix: A `str`. The word prefix used to match words.
3422- :return: a 2-tuple of is_authoritative and a set of words.
3423- is_authoritative is True when the set of words are the only words
3424- that can match the prefix. The words are a set of words.
3425- """
3426- raise NotImplementedError
3427-
3428- @property
3429- def prefix(self):
3430- """The prefix use to match words to."""
3431- return self._prefix
3432-
3433- @property
3434- def file_path(self):
3435- """The path to the file that is the word source."""
3436- return self._document.get_uri_for_display()
3437-
3438- @property
3439- def text(self):
3440- """The text of the gedit.Document or None."""
3441- if not self._document:
3442- return None
3443- start_iter = self._document.get_start_iter()
3444- end_iter = self._document.get_end_iter()
3445- return self._document.get_text(start_iter, end_iter, True)
3446-
3447-
3448-class TextGenerator(BaseSyntaxGenerator):
3449- """Generate a list of words that match a given prefix for a document."""
3450-
3451- def get_words(self, prefix=None):
3452- """See `BaseSyntaxGenerator.get_words`.
3453-
3454- is_authoritative is always False because TextGenerator because it is
3455- not for a specific document Language.
3456- """
3457- prefix = self.ensure_prefix(prefix)
3458- is_authoritative = False
3459- if len(prefix) > 0:
3460- # Match words that are just the prefix too.
3461- conditional = r'*'
3462- else:
3463- conditional = r'+'
3464- pattern = r'\b(%s[\w-]%s)' % (re.escape(prefix), conditional)
3465- word_re = re.compile(pattern, re.I)
3466- words = word_re.findall(self.text)
3467- # Find the unique words that do not have pseudo m-dashed in them.
3468- words = set(words)
3469- words = [DynamicProposal(word) for word in words if '--' not in word]
3470- return is_authoritative, words
3471-
3472-
3473-class MarkupGenerator(BaseSyntaxGenerator):
3474- """Generate a list of elements and attributes for a document."""
3475-
3476- word_char = re.compile(r'[^<>]')
3477- common_attrs = []
3478-
3479- INSIDE_ATTRIBUTES = 'INSIDE_ATTRIBUTES'
3480- INSIDE_CLOSE = 'INSIDE_CLOSE'
3481- INSIDE_OPEN = 'INSIDE_OPEN'
3482- OUTSIDE = 'OUTSIDE'
3483-
3484- def get_cursor_context(self):
3485- """Return the context of the cursor in relation to the last tag."""
3486- text, start_iter, end_iter = get_word(self._document, self.word_char)
3487- if not start_iter.backward_char():
3488- # The start was at the begining of the doc; no tags were found.
3489- return self.OUTSIDE
3490- # XXX sinzui 2011-01-07: get_char() dies, but get_text works.
3491- char_iter = start_iter.copy()
3492- char_iter.forward_char()
3493- char = start_iter.get_text(char_iter)[0]
3494- #char = start_iter.get_char()
3495- if char == '>':
3496- return self.OUTSIDE
3497- elif text and text.startswith('/'):
3498- return self.INSIDE_CLOSE
3499- elif text and ' ' in text:
3500- return self.INSIDE_ATTRIBUTES
3501- else:
3502- return self.INSIDE_OPEN
3503-
3504- def get_words(self, prefix=None):
3505- """See `BaseSyntaxGenerator.get_words`."""
3506- prefix = self.ensure_prefix(prefix)
3507- context = self.get_cursor_context()
3508- if context == self.OUTSIDE:
3509- # is_authoritative is false and there are no words because the
3510- # cursor is not in a tag to complete.
3511- return False, set()
3512- is_authoritative = True
3513- if context == self.INSIDE_OPEN:
3514- words = self._get_open_tags(prefix)
3515- elif context == self.INSIDE_ATTRIBUTES:
3516- words = self._get_attributes(prefix)
3517- else:
3518- words = self._get_close_tags(prefix)
3519- return is_authoritative, words
3520-
3521- def get_cardinality(self, prefix):
3522- if prefix:
3523- # Match words that are just the prefix too.
3524- return r'*'
3525- else:
3526- return r'+'
3527-
3528- def _get_open_tags(self, prefix):
3529- """Return all the tag names."""
3530- cardinality = self.get_cardinality(prefix)
3531- prefix = re.escape(prefix)
3532- pattern = r'<(%s[\w_.:-]%s)' % (prefix, cardinality)
3533- word_re = re.compile(pattern, re.I)
3534- words = word_re.findall(self.text)
3535- return [DynamicProposal(word) for word in words]
3536-
3537- def _get_attributes(self, prefix):
3538- pattern = r'<[\w_.:-]+ ([\w_.:-]*)=[^>]+>'
3539- attrs_re = re.compile(pattern, re.I)
3540- attr_clusters = attrs_re.findall(self.text)
3541- attrs = set(self.common_attrs)
3542- for attr_cluster in attr_clusters:
3543- attr_pairs = attr_cluster.split()
3544- for pair in attr_pairs:
3545- attr = pair.split('=')
3546- attrs.add(attr[0])
3547- if prefix:
3548- for attr in list(attrs):
3549- if not attr.startswith(prefix):
3550- attrs.remove(attr)
3551- return [DynamicProposal(attr) for attr in attrs]
3552-
3553- def _get_close_tags(self, prefix):
3554- """Return the tags that are still open before the cursor."""
3555- cardinality = self.get_cardinality(prefix)
3556- prefix = re.escape(prefix)
3557- # Get the text before the cursor.
3558- start_iter = self._document.get_start_iter()
3559- end_iter = self._document.get_iter_at_mark(
3560- self._document.get_insert())
3561- text = self._document.get_text(start_iter, end_iter, True)
3562- # Get all the open tags.
3563- open_pattern = r'<(%s[\w_.:-]%s)' % (prefix, cardinality)
3564- open_re = re.compile(open_pattern, re.I)
3565- open_tags = open_re.findall(text)
3566- # Get all the empty tags.
3567- empty_pattern = r'<(%s[\w_.:-]%s)[^>]*/>' % (prefix, cardinality)
3568- empty_re = re.compile(empty_pattern, re.I)
3569- empty_tags = empty_re.findall(text)
3570- # Get all the close tags.
3571- close_pattern = r'</(%s[\w_.:-]%s)' % (prefix, cardinality)
3572- close_re = re.compile(close_pattern, re.I)
3573- close_tags = close_re.findall(text)
3574- # Return only the tags that are still open.
3575- for tag in empty_tags:
3576- if tag in open_tags:
3577- open_tags.remove(tag)
3578- for tag in close_tags:
3579- if tag in open_tags:
3580- open_tags.remove(tag)
3581- return [DynamicProposal(tag + '>') for tag in open_tags]
3582-
3583-
3584-class PythonSyntaxGenerator(BaseSyntaxGenerator):
3585- """Generate a list of Python symbols that match a given prefix."""
3586-
3587- word_char = re.compile(r'[\w_.]', re.I)
3588- _kwlist = None
3589-
3590- @property
3591- def kwlist(self):
3592- if self._kwlist is None:
3593- self._kwlist = [
3594- self._get_dynamic_proposal(None, word) for word in kwlist]
3595- return self._kwlist
3596-
3597- def get_words(self, prefix=None):
3598- """See `BaseSyntaxGenerator.get_words`.
3599-
3600- :return: a 2-tuple of is_authoritative and a set of matching
3601- identifiers. is_authoritative is True when the prefix is a part
3602- of a dotted identifier.
3603- """
3604- prefix = self.ensure_prefix(prefix)
3605- is_authoritative = False
3606- if prefix == '':
3607- is_authoritative = True
3608-
3609- import __builtin__
3610- global_syms = [
3611- self._get_dynamic_proposal(__builtin__, name)
3612- for name in dir(__builtin__)]
3613- try:
3614- pyo = compile(self._get_parsable_text(), 'sc.py', 'exec')
3615- except SyntaxError:
3616- # This cannot be completed because of syntax errors.
3617- # Return
3618- self._document.emit('syntax-error-python')
3619- is_authoritative = False
3620- return is_authoritative, []
3621- co_names = ('SIGNAL_RUN_LAST', 'TYPE_NONE', 'TYPE_PYOBJECT', 'object')
3622- local_syms = [
3623- self._get_dynamic_proposal(None, name)
3624- for name in pyo.co_names if name not in co_names]
3625-
3626- namespaces = self.string_before_cursor.split('.')
3627- if len(namespaces) == 1:
3628- # The identifier is scoped to this module (the document).
3629- symbols = local_syms + global_syms + self.kwlist
3630- symbols = [proposal for proposal in symbols
3631- if proposal.get_text().startswith(prefix)]
3632- return is_authoritative, symbols
3633-
3634- # Remove the prefix to create the module's full name.
3635- namespaces.pop()
3636- module_name = '.'.join(namespaces)
3637- locald = {}
3638- try:
3639- # Check this file first.
3640- module_ = eval(module_name, globals(), locald)
3641- except NameError:
3642- # Try a true import.
3643- try:
3644- module_ = __import__(module_name, globals(), locald, [])
3645- except ImportError:
3646- return is_authoritative, []
3647-
3648- for symbol in namespaces[1:]:
3649- module_ = getattr(module_, symbol)
3650- is_authoritative = True
3651- symbols = [self._get_dynamic_proposal(module_, name)
3652- for name in dir(module_) if name.startswith(prefix)]
3653- return is_authoritative, symbols
3654-
3655- def _get_parsable_text(self):
3656- """Return the parsable text of the module.
3657-
3658- The line being edited may not be valid syntax, so the line is
3659- replaced with 'pass', or if it starts a block, it becomes 'if True:'
3660- """
3661- current_iter = self._document.get_iter_at_mark(
3662- self._document.get_insert())
3663- index = current_iter.get_line()
3664- text_lines = self.text.splitlines()
3665- if index + 1 == len(text_lines):
3666- # The current line is the last line. Add a fake line because
3667- # the compiler will require another line to follow a comment.
3668- text_lines.append('')
3669- current_indentation = self._get_indentation(text_lines[index])
3670- next_indentation = self._get_indentation(text_lines[index + 1])
3671- if len(next_indentation) > len(current_indentation):
3672- # Make this line compilable for the next block.
3673- text_lines[index] = current_indentation + 'if True:'
3674- else:
3675- # Comment-out this line so that it is not compiled.
3676- text_lines[index] = current_indentation + 'pass'
3677- return '\n'.join(text_lines)
3678-
3679- def _get_indentation(self, line):
3680- "Return the line's indentation"
3681- indentation_pattern = re.compile(r'^[ \t]*')
3682- match = indentation_pattern.match(line)
3683- if match:
3684- return match.group()
3685- # No match means the indentation is an empty string.
3686- return ''
3687-
3688- def _get_dynamic_proposal(self, module, name):
3689- if module is None:
3690- identifier = None
3691- elif type(module) == 'dict':
3692- identifier = module[name]
3693- else:
3694- identifier = module.__dict__[name]
3695- return PythonProposal(name, info=identifier)
3696-
3697-
3698-class SyntaxController(ControllerMixin):
3699- """This class manages the gedit.View's interaction with the SyntaxView."""
3700-
3701- def __init__(self, window):
3702- """Initialize the controller for the gedit.View."""
3703- self.signal_ids = {}
3704- self.view = None
3705- self.window = window
3706- self.set_view(window.get_active_view())
3707-
3708- def deactivate(self):
3709- """Clean up resources before deactivation."""
3710- self.set_view(None)
3711-
3712- def set_view(self, view, is_reset=False):
3713- """Set the view to be controlled.
3714-
3715- Installs signal handlers for the view. Calling
3716- document.get_uri_for_display() self.set_view(None) will effectively
3717- remove all the control from the current view. when is_reset is True,
3718- the current view's signals will be reset.
3719- """
3720- if view is self.view and not is_reset:
3721- return
3722-
3723- if self.view:
3724- # Unregister the current view before assigning the new one.
3725- self._disconnectSignal(self.view, 'destroy')
3726- self._disconnectSignal(self.view, 'notify::editable')
3727-
3728- self.view = view
3729- if view is not None:
3730- self.signal_ids['destroy'] = view.connect(
3731- 'destroy', self.on_view_destroy)
3732- self.signal_ids['notify::editable'] = view.connect(
3733- 'notify::editable', self.on_notify_editable)
3734-
3735- def _disconnectSignal(self, obj, signal):
3736- """Disconnect the signal from the provided object."""
3737- if signal in self.signal_ids:
3738- obj.disconnect(self.signal_ids[signal])
3739- del self.signal_ids[signal]
3740-
3741- def show_syntax_view(self, widget=None, data=None):
3742- """Show the SyntaxView widget."""
3743- if not self.view.get_editable():
3744- return
3745- self.completion = self.view.get_completion()
3746- language_id = None
3747- document = self.view.get_buffer()
3748- if hasattr(document, 'get_language'):
3749- # How can we not get a document or language?
3750- language = document.get_language()
3751- if language is not None:
3752- language_id = language.get_id()
3753- title = _('GDP Syntax Completer')
3754- self.provider = DynamicProvider(
3755- title, language_id, self.on_proposal_activated, document)
3756- self.completion.show(
3757- [self.provider], self.completion.create_context(None))
3758-
3759- def get_word_prefix(self, document):
3760- """Return a 3-tuple of the word fragment before the cursor.
3761-
3762- The tuple contains the (word_fragement, start_iter, end_iter) to
3763- identify the prefix and its starting and end position in the
3764- document.
3765- """
3766- word_char = re.compile(r'[\w_-]', re.I)
3767- return get_word(document, word_char)
3768-
3769- def insert_word(self, word, start=None):
3770- """Return True when the word is inserted into the Document.
3771-
3772- The word cannot be None or an empty string.
3773- """
3774- assert word, "The word cannot be None or an empty string."
3775- document = self.view.get_buffer()
3776- if start:
3777- document.delete(
3778- start, document.get_iter_at_mark(document.get_insert()))
3779- document.insert_at_cursor(word)
3780-
3781- def correct_language(self, document):
3782- """Correct the language for ambuguous mime-types."""
3783- if not hasattr(document, 'get_language'):
3784- return
3785- file_path = document.get_uri_for_display()
3786- if doctest_pattern.match(file_path):
3787- document.set_language(doctest_language)
3788-
3789- def on_proposal_activated(self, proposal, piter):
3790- """Complete the word using the proposal."""
3791- if not proposal:
3792- return
3793- document = self.view.get_buffer()
3794- (ignored, start, end_) = self.get_word_prefix(document)
3795- word = proposal.get_text()
3796- self.insert_word(word, start)
3797- return True
3798-
3799- def on_notify_editable(self, view, param_spec):
3800- """Update the controller when the view editable state changes.
3801-
3802- This method is ultimately responsible for enabling and disabling
3803- the SyntaxView widget for syntax completion.
3804- """
3805- self.set_view(view, True)
3806-
3807- def on_view_destroy(self, view):
3808- """Disconnect the controller."""
3809- self.deactivate()
3810
3811=== modified file 'plugins/gdp/tests/__init__.py'
3812--- plugins/gdp/tests/__init__.py 2011-01-14 10:24:47 +0000
3813+++ plugins/gdp/tests/__init__.py 2012-02-07 18:01:21 +0000
3814@@ -1,4 +1,1 @@
3815 """gdp unit/doctests."""
3816-
3817-__metaclass__ = type
3818-
3819
3820=== removed file 'plugins/gdp/tests/find-generator.doctest'
3821--- plugins/gdp/tests/find-generator.doctest 2011-01-14 10:24:47 +0000
3822+++ plugins/gdp/tests/find-generator.doctest 1970-01-01 00:00:00 +0000
3823@@ -1,21 +0,0 @@
3824-Finder
3825-======
3826-
3827-The Finder is a controller between the UI and the match gengerato. The
3828-__init__ method requires a gedit window. An error is raised if it is not
3829-provided.
3830-
3831- >>> from testing.gedithelpers import get_window
3832- >>> from gdp.find import Finder
3833-
3834- >>> finder = Finder()
3835- Traceback (most recent call last):
3836- ...
3837- TypeError: __init__() takes exactly 2 arguments (1 given)
3838-
3839- >>> window, view, document = get_window('plugins/gdp/data/snark12.txt')
3840- >>> finder = Finder(window)
3841- >>> finder
3842- <gdp.find.Finder ...>
3843-
3844-
3845
3846=== removed file 'plugins/gdp/tests/formatter.doctest'
3847--- plugins/gdp/tests/formatter.doctest 2011-09-08 12:12:28 +0000
3848+++ plugins/gdp/tests/formatter.doctest 1970-01-01 00:00:00 +0000
3849@@ -1,27 +0,0 @@
3850-Text formatters
3851----------------
3852-
3853-CSS can be reformatted.
3854-
3855- >>> from gdp.format import Formatter
3856- >>> from testing.gedithelpers import get_window
3857-
3858- >>> window, view, document = get_window('plugins/gdp/data/snark.css')
3859- >>> formatter = Formatter(window)
3860- >>> formatter.reformat_css(None)
3861- >>> print formatter.text #doctest: -NORMALIZE_WHITESPACE
3862- .snark {
3863- font-style: italic;
3864- color: #ff0000;
3865- }
3866- .baker {
3867- font-style: italic;
3868- color: #3333ff;
3869- }
3870- .banker {
3871- font-style: italic;
3872- color: #666;
3873- }
3874- ...
3875-
3876-
3877
3878=== removed file 'plugins/gdp/tests/syntaxcompleter-controller.doctest'
3879--- plugins/gdp/tests/syntaxcompleter-controller.doctest 2011-07-01 12:36:16 +0000
3880+++ plugins/gdp/tests/syntaxcompleter-controller.doctest 1970-01-01 00:00:00 +0000
3881@@ -1,329 +0,0 @@
3882-SyntaxControler for SyntaxCompleter
3883-===================================
3884-
3885-The SyntaxControler manages the interaction between the SyntaxView
3886-and the Gedit.View classes. The SyntaxControler is is the public
3887-interface of the SyntaxCompleter. It is used by the
3888-SyntaxCompleterPlugin to add the Syntax behaviours to Gedit.
3889-
3890-
3891-SyntaxControler
3892----------------
3893-
3894-The SyntaxView requires a Gedit.View for which it will be handling
3895-requests to complete words.
3896-
3897- >>> from gdp.syntaxcompleter import SyntaxController
3898- >>> SyntaxController()
3899- Traceback (most recent call last):
3900- ...
3901- TypeError: __init__() takes exactly 2 arguments (1 given)
3902-
3903- >>> from testing.gedithelpers import get_window
3904- >>> from testing import Gedit
3905- >>> window, view, document = get_window('plugins/gdp/data/snark12.txt')
3906- >>> controller = SyntaxController(window)
3907- >>> controller
3908- <gdp.syntaxcompleter.SyntaxController ...>
3909-
3910-
3911-set_view()
3912-~~~~~~~~~
3913-
3914-The view is bound and unbound to the controller using the set_view()
3915-method. It takes an optional reset parameter that rebinds the
3916-current view, for example, when a document's editability changes.
3917-
3918- >>> current_view = controller.view
3919- >>> current_view
3920- <View ...>
3921-
3922- >>> new_view = Gedit.View(document)
3923- >>> controller.set_view(new_view)
3924- >>> controller.view
3925- <View ...>
3926- >>> new_view is controller.view
3927- True
3928- >>> new_view is current_view
3929- False
3930-
3931-The set_view connects and disconnects signals between the controller
3932-and the view and document. When the document is editable, the
3933-key-press-event is connected.
3934-
3935- >>> controller.view.get_editable()
3936- True
3937- >>> controller.view.set_editable(False)
3938- >>> controller.set_view(new_view, is_reset=True)
3939- >>> new_view is controller.view
3940- True
3941-
3942-Passing None will disconnect the signals and the view.
3943-
3944- >>> controller.set_view(None)
3945- >>> literal(controller.view)
3946- None
3947-
3948-Passing an existing view connects the signals.
3949-
3950- >>> controller.set_view(current_view)
3951- >>> current_view is controller.view
3952- True
3953-
3954-
3955-show_syntax_view()
3956-~~~~~~~~~~~~~~~~
3957-
3958-The show_syntax_view() methods displays the SyntaxView widget at the
3959-cursor. It determines the prefix from the left adjacent word and passes
3960-it to the SyntaxView.
3961-
3962- >>> # The widget can only be observed to work when Gtk.main()
3963- >>> # is run.
3964- >>> controller.show_syntax_view()
3965- >>> syntax_view = controller.completion
3966- >>> syntax_view
3967- <Completion object at ...>
3968-
3969-
3970-get_word_prefix()
3971-~~~~~~~~~~~~~~~
3972-
3973-This method will return the prefix before the cursor. The prefix is a
3974-3-tuple of the word fragment, its starting iterator and its ending
3975-iterator.
3976-
3977- >>> def print_prefix(prefix):
3978- ... return (
3979- ... prefix[0], prefix[1].get_offset(), prefix[2].get_offset())
3980-
3981- >>> document.get_text(document.get_start_iter(),
3982- ... document.get_end_iter(), True)
3983- 'This is the Project Gutenberg Etext of The Hunting of the Snark...'
3984-
3985-There is no word fragment when the cursor is at the start of the
3986-document.
3987-
3988- >>> document.place_cursor(document.get_start_iter())
3989- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
3990- >>> cursor_iter.get_offset()
3991- 0
3992- >>> prefix = controller.get_word_prefix(document)
3993- >>> print_prefix(prefix)
3994- (None, 0, 0)
3995-
3996-When the cursor is at the end of a word, such as 'is', the leading
3997-characters are the prefix.
3998-
3999- >>> cursor_iter.forward_cursor_positions(7)
4000- True
4001- >>> document.place_cursor(cursor_iter)
4002- >>> cursor_iter.get_offset()
4003- 7
4004- >>> prefix = controller.get_word_prefix(document)
4005- >>> print_prefix(prefix)
4006- ('is', 5, 7)
4007-
4008-When the cursor is in the middle of a word, such as 'is', the leading
4009-characters are the prefix.
4010-
4011- >>> cursor_iter.backward_cursor_positions(1)
4012- True
4013- >>> document.place_cursor(cursor_iter)
4014- >>> prefix = controller.get_word_prefix(document)
4015- >>> print_prefix(prefix)
4016- ('i', 5, 6)
4017-
4018-A space is not a word character. There is no prefix. The start and end
4019-positions are identical.
4020-
4021- >>> cursor_iter.backward_cursor_positions(1)
4022- True
4023- >>> document.place_cursor(cursor_iter)
4024- >>> prefix = controller.get_word_prefix(document)
4025- >>> print_prefix(prefix)
4026- (None, 5, 5)
4027-
4028-Period and other symbols that end a word are not a part of the word.
4029-The first sentence of the test document ends with 'Snark.' at position
4030-64. 'Snark' is the word before position 63. There is no word before
4031-position 64 ('.').
4032-
4033- >>> document.place_cursor(document.get_start_iter())
4034- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4035- >>> cursor_iter.forward_cursor_positions(63)
4036- True
4037- >>> document.place_cursor(cursor_iter)
4038- >>> prefix = controller.get_word_prefix(document)
4039- >>> print_prefix(prefix)
4040- ('Snark', 58, 63)
4041-
4042- >>> cursor_iter.forward_cursor_position()
4043- True
4044- >>> document.place_cursor(cursor_iter)
4045- >>> prefix = controller.get_word_prefix(document)
4046- >>> print_prefix(prefix)
4047- (None, 64, 64)
4048-
4049-Underscores are considered word characters. Words that start with, or
4050-contain underscores are included in the list of words.
4051-
4052- >>> hacker_window, hacker_view, hacker_doc = get_window(
4053- ... 'plugins/gdp/data/hackerese.txt')
4054- >>> hacker_controller = SyntaxController(window)
4055- >>> print hacker_doc.get_text(hacker_doc.get_start_iter(),
4056- ... hacker_doc.get_end_iter(), True)
4057- H... syntax_generator syntax_completer __call__(self) __dict__ file_ ...
4058-
4059- >>> hacker_doc.place_cursor(hacker_doc.get_start_iter())
4060- >>> h_cursor_iter = hacker_doc.get_iter_at_mark(hacker_doc.get_insert())
4061- >>> h_cursor_iter.forward_cursor_positions(464)
4062- True
4063- >>> hacker_doc.place_cursor(h_cursor_iter)
4064- >>> prefix = hacker_controller.get_word_prefix(hacker_doc)
4065- >>> print_prefix(prefix)
4066- ('syntax_completer', 448, 464)
4067-
4068- >>> h_cursor_iter.forward_cursor_positions(48)
4069- True
4070- >>> hacker_doc.place_cursor(h_cursor_iter)
4071- >>> prefix = hacker_controller.get_word_prefix(hacker_doc)
4072- >>> print_prefix(prefix)
4073- ('_', 511, 512)
4074-
4075-
4076-insert_word()
4077-~~~~~~~~~~~~
4078-
4079-This method inserts a word into the document. It will raise an error
4080-if the word is None or an empty string.
4081-
4082- >>> controller.insert_word(None, cursor_iter)
4083- Traceback (most recent call last):
4084- ...
4085- AssertionError: The word cannot be None or an empty string.
4086-
4087- >>> controller.insert_word('', cursor_iter)
4088- Traceback (most recent call last):
4089- ...
4090- AssertionError: The word cannot be None or an empty string.
4091-
4092-Continuing from the document demonstrated in the get_word_prefix()
4093-section, words can be inserted into the first sentence. Inserting
4094-happens when the start iterator is None or it is the same position
4095-as the cursor.
4096-
4097- >>> sentence_mark = document.create_mark(
4098- ... 'sentence_end', cursor_iter, False)
4099- >>> cursor_iter = document.get_start_iter()
4100- >>> cursor_iter.forward_cursor_positions(12)
4101- True
4102- >>> document.place_cursor(cursor_iter)
4103- >>> controller.insert_word('Est ', cursor_iter)
4104- >>> document.get_text(document.get_start_iter(),
4105- ... document.get_iter_at_mark(sentence_mark), True)
4106- 'This is the Est Project Gutenberg Etext of The Hunting of the Snark.'
4107-
4108- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4109- >>> cursor_iter.backward_cursor_positions(1)
4110- True
4111- >>> document.place_cursor(cursor_iter)
4112- >>> controller.insert_word('e', None)
4113- >>> document.get_text(document.get_start_iter(),
4114- ... document.get_iter_at_mark(sentence_mark), True)
4115- 'This is the Este Project Gutenberg Etext of The Hunting of the Snark.'
4116-
4117- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4118- >>> document.place_cursor(cursor_iter)
4119- >>> controller.insert_word('e')
4120- >>> document.get_text(document.get_start_iter(),
4121- ... document.get_iter_at_mark(sentence_mark), True)
4122- 'This is the Estee Project Gutenberg Etext of The Hunting of the Snark.'
4123-
4124-The method can replace text in the document when a start iter is
4125-provided, and it is not the same position at the cursor. The text
4126-between the start and the cursor is deleted, and the word is inserted
4127-at the cursor position.
4128-
4129- >>> start = document.get_iter_at_mark(document.get_insert())
4130- >>> start.backward_chars(5)
4131- True
4132- >>> controller.insert_word('esteem', start)
4133- >>> document.get_text(document.get_start_iter(),
4134- ... document.get_iter_at_mark(sentence_mark), True)
4135- 'This is the esteem Project Gutenberg Etext of The Hunting of the Snark.'
4136-
4137-
4138-GSignals
4139---------
4140-
4141-The SyntaxController relies on GSignals to respond the of Gedit.View
4142-and the SyntaxView.
4143-
4144-Signal test requires some help to isolate the emission and reception
4145-of the sginals.
4146-
4147-# >>> signal_tester = SignalTester()
4148-# >>> signal_tester.attachReceptionHarness(controller)
4149-# >>> controller.testeeConnect(
4150-# ... controller, syntax_view, 'syntax-view', 'syntax-activated',
4151-# ... controller.on_proposal_activated)
4152-
4153-
4154-on_proposal_activated()
4155-~~~~~~~~~~~~~~~~~~~~~~~
4156-
4157-SyntaxView sends a syntax-activated signal to return the user's chosen
4158-word. The method calls insert_word. Unlike the afore mentioned method,
4159-when the word is None or an empty string, there is no error
4160-
4161- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4162- >>> cursor_iter.backward_chars(6)
4163- True
4164- >>> document.place_cursor(cursor_iter)
4165-
4166-When the word is None, the Document is no changed.
4167-
4168- >>> controller.on_proposal_activated(None, None)
4169- >>> document.get_text(document.get_start_iter(),
4170- ... document.get_iter_at_mark(sentence_mark), True)
4171- 'This is the esteem Project Gutenberg Etext of The Hunting of the Snark.'
4172-
4173-When the word is a string (as it should be), the word is inserted into
4174-the document. According the rules of insert_word(), when a space or
4175-symbol preceeds the cursor the word is inserted. Otherwise, the
4176-characters before the cursor are replaced.
4177-
4178- >>> from gdp.syntaxcompleter import DynamicProposal
4179-
4180- >>> proposal = DynamicProposal('ed')
4181- >>> controller.on_proposal_activated(proposal, None)
4182- True
4183- >>> document.get_text(document.get_start_iter(),
4184- ... document.get_iter_at_mark(sentence_mark), True)
4185- 'This is the edesteem Project Gutenberg Etext of The Hunting of the Sn...'
4186-
4187- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4188- >>> cursor_iter.forward_chars(6)
4189- True
4190- >>> document.place_cursor(cursor_iter)
4191-
4192- >>> proposal._word = 'esteemed'
4193- >>> controller.on_proposal_activated(proposal, None)
4194- True
4195- >>> document.get_text(document.get_start_iter(),
4196- ... document.get_iter_at_mark(sentence_mark), True)
4197- 'This is the esteemed Project Gutenberg Etext of The Hunting of the Sn...'
4198-
4199-
4200-on_view_destroy() and deactivate()
4201-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4202-
4203-The deactivate() method removes the detaches the signals and removes
4204-view. The method is called by on_view_destroy() for the destroy signal.
4205-
4206- >>> controller.view
4207- <View ...>
4208- >>> view.destroy()
4209- >>> literal(controller.view)
4210- None
4211
4212=== removed file 'plugins/gdp/tests/syntaxcompleter-generator.doctest'
4213--- plugins/gdp/tests/syntaxcompleter-generator.doctest 2011-07-01 12:36:16 +0000
4214+++ plugins/gdp/tests/syntaxcompleter-generator.doctest 1970-01-01 00:00:00 +0000
4215@@ -1,367 +0,0 @@
4216-SyntaxGenerators
4217-================
4218-
4219-The a SyntaxGenerators class represents a word source and syntax rules.
4220-It can build a list of matching words when provided a word prefix.
4221-Some syntax completers require a Gedit.Document as their word source.
4222-
4223-
4224-SyntaxGenerator
4225----------------
4226-
4227-The base SyntaxGenerator class defines the core methods that all
4228-subclasses may choose override. It also provides several helper methods
4229-and properties. The __init__ method requires a Gedit.Document.
4230-
4231- >>> from gi.repository import Gio
4232- >>> from gdp.syntaxcompleter import BaseSyntaxGenerator
4233- >>> generator = BaseSyntaxGenerator()
4234- Traceback (most recent call last):
4235- ...
4236- TypeError: __init__() takes at least 2 arguments (1 given)
4237-
4238- >>> from testing import Gedit
4239- >>> document = Gedit.Document()
4240- >>> hunting_the_snark = 'plugins/gdp/data/snark12.txt'
4241- >>> location = Gio.file_new_for_path(hunting_the_snark)
4242- >>> document.load(location, None, 0, False)
4243- >>> generator = BaseSyntaxGenerator(document)
4244- >>> generator
4245- <gdp.syntaxcompleter.BaseSyntaxGenerator object at ...>
4246-
4247- >>> generator.file_path
4248- 'file:///...plugins/gdp/data/snark12.txt'
4249- >>> generator.text == document.get_text(document.get_start_iter(),
4250- ... document.get_end_iter(), True)
4251- True
4252-
4253- >>> generator.get_words('Ba')
4254- Traceback (most recent call last):
4255- ...
4256- NotImplementedError
4257-
4258-The string_before_cursor property and word_char attribute allow the
4259-generator sub-class to get the text before the cursor using its own
4260-rules.
4261-
4262- generator.word_char.pattern
4263- r'[\w_]'
4264-
4265- generator.string_before_cursor
4266- ''
4267-
4268-TextGenerator
4269--------------
4270-
4271-The TextGenerator class represents plain text sources. The words of the
4272-source are the words it represents, no alteration or interpretation is
4273-applied. Words are identified by common word boundaries like
4274-punctuation and line ends.
4275-
4276- >>> from gdp.syntaxcompleter import TextGenerator
4277- >>> text_generator = TextGenerator(document)
4278- >>> text_generator
4279- <gdp.syntaxcompleter.TextGenerator object at ...>
4280-
4281- >>> text_generator.file_path
4282- 'file:///...plugins/gdp/data/snark12.txt'
4283-
4284- >>> text_generator.text
4285- 'This is the Project Gutenberg Etext of The Hunting of the Snark...'
4286-
4287-The get_words() method returns a 2-tuple of is_authoritative and a list of
4288-all proposals in the generator.
4289-
4290- >>> is_authoritative, proposals = text_generator.get_words()
4291-
4292- >>> len(proposals)
4293- 1987
4294-
4295- >>> type(proposals)
4296- <type 'list'>
4297-
4298- >>> proposals = sorted([proposal for proposal in proposals])
4299- >>> proposals[0]
4300- <DynamicProposal word="000" ...>
4301-
4302- >>> [proposal._word for proposal in proposals][0:9]
4303- ['000', '000x100', '03', '08', '1', '10', '1992', '2', '20']
4304-
4305-is_authoritative is always False because the TextGenerator works with all
4306-documents instead of a specific GtkSourceView Language.
4307-
4308- >>> is_authoritative
4309- False
4310-
4311-When the generator is created with a prefix, the generator will only
4312-contain words that start with the prefix. Matching is case-insensitive.
4313-
4314- >>> text_generator = TextGenerator(document, prefix='Ba')
4315- >>> is_authoritative, proposals = text_generator.get_words()
4316- >>> len(proposals)
4317- 16
4318- >>> sorted([proposal._word for proposal in proposals])
4319- ['BAKER', 'BANKER', 'BARRISTER', 'Baker', 'Bandersnatch', ...]
4320-
4321- >>> text_generator = TextGenerator(document, prefix='Snar')
4322- >>> is_authoritative, proposals = text_generator.get_words()
4323- >>> len(proposals)
4324- 5
4325- >>> sorted([proposal._word for proposal in proposals])
4326- ['SNARK', 'Snark', 'Snarks', 'snark12', 'snarked']
4327-
4328- >>> text_generator = TextGenerator(document, prefix='snar')
4329- >>> is_authoritative, lowercase_proposals = text_generator.get_words()
4330- >>> lowercase_proposals == proposals
4331- True
4332-
4333- >>> text_generator = TextGenerator(document, prefix='SNAR')
4334- >>> is_authoritative, uppercase_proposals = text_generator.get_words()
4335- >>> lowercase_proposals == uppercase_proposals == proposals
4336- True
4337-
4338-Hyphenated words are included in the list of words.
4339-
4340- >>> text_generator = TextGenerator(document, prefix='What-')
4341- >>> is_authoritative, proposals = text_generator.get_words()
4342- >>> sorted([proposal._word for proposal in proposals])
4343- ['What-was-his-name', 'What-you-may-call-um']
4344-
4345-Underscores are considered word characters. Words that start with, or
4346-contain underscores are included in the list of words.
4347-
4348- >>> hacker_doc = Gedit.Document()
4349- >>> hackerese = 'plugins/gdp/data/hackerese.txt'
4350- >>> location = Gio.file_new_for_path(hackerese)
4351- >>> hacker_doc.load(location, None, 0, False)
4352- >>> print hacker_doc.get_text(hacker_doc.get_start_iter(),
4353- ... hacker_doc.get_end_iter(), True)
4354- H... syntax_generator syntax_completer __call__(self) __dict__ file_ ...
4355-
4356- >>> text_generator = TextGenerator(hacker_doc, prefix='_')
4357- >>> is_authoritative, proposals = text_generator.get_words()
4358- >>> sorted([proposal._word for proposal in proposals])
4359- ['_', '__call__', '__dict__', '__init__', '_dict', '_private']
4360-
4361-
4362-PythonGenerator
4363----------------
4364-
4365-The PythonGenerator represents all the identifiers in a Python source
4366-file. The identifiers come from the document, the imports, the builtins,
4367-and the Python keywords.
4368-
4369- >>> from gdp.syntaxcompleter import PythonSyntaxGenerator
4370-
4371- >>> snark_py = 'plugins/gdp/data/snark.py'
4372- >>> location = Gio.file_new_for_path(snark_py)
4373- >>> document.load(location, None, 0, False)
4374- >>> document.place_cursor(document.get_start_iter())
4375- >>> python_generator = PythonSyntaxGenerator(document)
4376- >>> python_generator
4377- <gdp.syntaxcompleter.PythonSyntaxGenerator object at ...>
4378-
4379- >>> python_generator.file_path
4380- 'file:///...plugins/gdp/data/snark.py'
4381-
4382- >>> python_generator.text
4383- '"""An example python module for testing."""...'
4384-
4385-The get_words() method returns a 2-tuple of is_authoritative and a set
4386-of all words in the generator.
4387-
4388- >>> is_authoritative, proposals = python_generator.get_words('A')
4389- >>> sorted([proposal._word for proposal in proposals])
4390- ['ArithmeticError', 'AssertionError', 'AttributeError']
4391-
4392-The is_authoritative return value may be True or false. It is False when
4393-the set of words from more than one namespace and there is a prefix.
4394-
4395- >>> is_authoritative
4396- False
4397-
4398-Python keywords are among the symbols that can be matched.
4399-
4400- >>> is_authoritative, proposals = python_generator.get_words('wh')
4401- >>> sorted([proposal._word for proposal in proposals])
4402- ['while']
4403-
4404-The generator uses the compiled module to get the symbols it contains.
4405-The private _get_parsable_text() method is responsible for returning
4406-compilable code. The line being edited is modified to ensure it is
4407-valid. This can be observed when the main() function is amended with
4408-some sample code.
4409-
4410- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4411- >>> cursor_iter.set_line(document.get_line_count() - 6)
4412- >>> document.place_cursor(cursor_iter)
4413- >>> document.insert_at_cursor("""
4414- ... found = False
4415- ... while not found:
4416- ... found = True
4417- ... """)
4418-
4419-When the line being edited starts a new block, it is replaced with
4420-with code (if True:) to ensure the module will compile.
4421-
4422- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4423- >>> success = cursor_iter.backward_lines(2)
4424- >>> document.place_cursor(cursor_iter)
4425- >>> parsable_lines = python_generator._get_parsable_text().splitlines()
4426- >>> print '\n'.join(parsable_lines[77:80])
4427- found = False
4428- if True:
4429- found = True
4430-
4431-When line has the same indentation as the next line, or it is the last
4432-line, it is replaced with 'pass'.
4433-
4434- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4435- >>> success = cursor_iter.forward_lines(1)
4436- >>> document.place_cursor(cursor_iter)
4437- >>> parsable_lines = python_generator._get_parsable_text().splitlines()
4438- >>> print '\n'.join(parsable_lines[77:80])
4439- found = False
4440- while not found:
4441- pass
4442-
4443-
4444-PythonProposal
4445-..............
4446-
4447-The PythonGenerator returns PythonProposals.
4448-
4449- >>> location = Gio.file_new_for_path(snark_py)
4450- >>> document.load(location, None, 0, False)
4451- >>> document.place_cursor(document.get_end_iter())
4452- >>> document.insert_at_cursor('os.path.j')
4453- >>> is_authoritative, proposals = python_generator.get_words('j')
4454- >>> proposals
4455- [<PythonProposal word="join" ...]
4456-
4457-The PythonProposal has the identifier as the info. The do_get_info() method
4458-returns the PangoDoc formating of the instance's pydoc.
4459-
4460- >>> proposal = proposals[0]
4461- >>> proposal._info
4462- <function join ...>
4463-
4464- >>> print proposal.do_get_info()
4465- <b>join</b>(a, *p)
4466- Join two or more pathname components, inserting '/' as needed.
4467- If any component is an absolute path, all previous path components
4468- will be discarded.
4469-
4470-The pydoc is None if the info is None.
4471-
4472- >>> proposal._info = None
4473- >>> print proposal.do_get_info()
4474- None
4475-
4476-MarkupGenerator
4477----------------
4478-
4479-The MarkupGenerator creates a vocabulary of elements from the tags used in
4480-the document.
4481-
4482- >>> from gdp.syntaxcompleter import MarkupGenerator
4483-
4484- >>> snark_html = 'plugins/gdp/data/snark.html'
4485- >>> location = Gio.file_new_for_path(snark_html)
4486- >>> document.load(location, None, 0, False)
4487- >>> document.place_cursor(document.get_start_iter())
4488- >>> markup_generator = MarkupGenerator(document)
4489- >>> markup_generator
4490- <gdp.syntaxcompleter.MarkupGenerator object at ...>
4491-
4492- >>> markup_generator.file_path
4493- 'file:///...plugins/gdp/data/snark.html'
4494-
4495- >>> print markup_generator.text
4496- <html> <head> <title>The Hunting of The Snark</title> ...
4497-
4498-The get_words() method returns a 2-tuple of is_authoritative and a set
4499-of all words in the generator. When the cursor is not in a tag, there are no
4500-matches and the results are not authoritative. The cursor is outside a tag
4501-at the start of the document.
4502-
4503- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4504- >>> document.place_cursor(cursor_iter)
4505- >>> is_authoritative, proposals = markup_generator.get_words()
4506- >>> is_authoritative
4507- False
4508-
4509- >>> print markup_generator.get_cursor_context()
4510- OUTSIDE
4511-
4512- >>> sorted([proposal._word for proposal in proposals])
4513- []
4514-
4515-The cursor is outside a tag when it is is between tags.
4516-
4517- >>> cursor_iter.forward_lines(2)
4518- True
4519- >>> document.place_cursor(cursor_iter)
4520- >>> is_authoritative, proposals = markup_generator.get_words()
4521- >>> print markup_generator.get_cursor_context()
4522- OUTSIDE
4523-
4524-When the cursor in the name of an open tag, all matching open or empty
4525-tags are listed.
4526-
4527- >>> success = cursor_iter.forward_chars(10)
4528- >>> document.place_cursor(cursor_iter)
4529- >>> print markup_generator.string_before_cursor
4530- title
4531-
4532- >>> is_authoritative, proposals = markup_generator.get_words('title')
4533- >>> is_authoritative
4534- True
4535-
4536- >>> print markup_generator.get_cursor_context()
4537- INSIDE_OPEN
4538-
4539- >>> sorted([proposal._word for proposal in proposals])
4540- ['title']
4541-
4542-When the cursor is in the attribute portion of an open or empty tag, all
4543-known attributes are listed.
4544-
4545- >>> document.insert_at_cursor(" l")
4546- >>> print markup_generator.string_before_cursor
4547- title l
4548-
4549- >>> is_authoritative, proposals = markup_generator.get_words()
4550- >>> is_authoritative
4551- True
4552-
4553- >>> print markup_generator.get_cursor_context()
4554- INSIDE_ATTRIBUTES
4555-
4556- >>> sorted([proposal._word for proposal in proposals])
4557- ['class']
4558-
4559- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4560- >>> delete_iter = cursor_iter.copy()
4561- >>> success = delete_iter.backward_chars(2)
4562- >>> document.delete(delete_iter, cursor_iter)
4563-
4564-When the cursor is in the name of a close tag, only the names of the open
4565-tags listed.
4566-
4567- >>> cursor_iter = document.get_iter_at_mark(document.get_insert())
4568- >>> success = cursor_iter.forward_chars(34)
4569- >>> document.place_cursor(cursor_iter)
4570- >>> document.insert_at_cursor("<style>body {color: #333;}</")
4571- >>> print markup_generator.string_before_cursor
4572- /
4573-
4574- >>> is_authoritative, proposals = markup_generator.get_words()
4575- >>> is_authoritative
4576- True
4577-
4578- >>> print markup_generator.get_cursor_context()
4579- INSIDE_CLOSE
4580-
4581- >>> sorted([proposal._word for proposal in proposals])
4582- ['head>', 'html>', 'style>']
4583
4584=== removed file 'plugins/gdp/tests/syntaxcompleter-provider.doctest'
4585--- plugins/gdp/tests/syntaxcompleter-provider.doctest 2011-07-01 12:36:16 +0000
4586+++ plugins/gdp/tests/syntaxcompleter-provider.doctest 1970-01-01 00:00:00 +0000
4587@@ -1,105 +0,0 @@
4588-DynamicProvider for SyntaxCompleter
4589-===================================
4590-
4591-The DynamicProvider manages a list of proposals that may complete the
4592-prefix provided. It is used by SyntaxCompleter.
4593-
4594-
4595-DynamicProvider
4596----------------
4597-
4598-DynamicProvider is responsible for selecting a SyntaxGenerator that provides
4599-the words. DynamicProvider controls the filtering and retrieval of the
4600-words.
4601-
4602-The complete model requires a tuple of sources that identify and
4603-provide the data. The document is a Gedit.Document. The words in
4604-the document may be used to create the vocabulary. A prefix may be
4605-provided to filter the words in the vocabulary.
4606-
4607- >>> from gi.repository import Gio
4608- >>> from gdp.syntaxcompleter import DynamicProvider
4609- >>> from testing import Gedit
4610-
4611- >>> DynamicProvider()
4612- Traceback (most recent call last):
4613- ...
4614- TypeError: __init__() takes exactly 5 arguments (1 given)
4615-
4616- >>> def handler(proposal, piter):
4617- ... return proposal.get_text()
4618-
4619- >>> document = Gedit.Document()
4620- >>> location = Gio.file_new_for_path('plugins/gdp/data/snark12.txt')
4621- >>> document.load(location, None, 0, False)
4622- >>> language_id = None
4623- >>> provider = DynamicProvider("tester", language_id, handler, document)
4624- >>> provider
4625- <DynamicProvider object at ... (GDPDynamicProvider ...)>
4626-
4627-
4628-get_proposals()
4629-~~~~~~~~~~~~~~~
4630-
4631-The model calls get_proposals() to generate the unqiue list of words
4632-that match the prefix. The list must be unique because the
4633-CompleteModel.on_iter_next() can enter an infinite loop.
4634-
4635- >>> proposals = provider.get_proposals(prefix='')
4636- >>> len(proposals)
4637- 1987
4638-
4639- >>> proposals = sorted([proposal for proposal in proposals])
4640- >>> proposals[0]
4641- <DynamicProposal word="000" ...>
4642-
4643- >>> [proposal._word for proposal in proposals][0:9]
4644- ['000', '000x100', '03', '08', '1', '10', '1992', '2', '20']
4645-
4646-
4647-get_generator()
4648-~~~~~~~~~~~~~~~
4649-
4650-The create_list() method uses the get_generator() method to get the generator
4651-for the language of the document.
4652-
4653-The TextGenerator is used for text documents and unsupported languages, but
4654-the get_generator() method does not return it because create_list() will
4655-instantiate it when the results are not authoritative.
4656-
4657- >>> print provider.get_generator(document, '')
4658- None
4659-
4660-The PythonSyntaxGenerator is returned for python files.
4661-
4662- >>> python_document = Gedit.Document()
4663- >>> location = Gio.file_new_for_path('plugins/gdp/data/snark.py')
4664- >>> python_document.load(location, None, 0, False)
4665- >>> language_id = python_document.get_language().get_id()
4666- >>> print language_id
4667- python
4668- >>> provider = DynamicProvider(
4669- ... "tester", language_id, handler, python_document)
4670- >>> provider.get_generator(python_document, '')
4671- <gdp.syntaxcompleter.PythonSyntaxGenerator ...>
4672-
4673-The MarkupGenerator is returned for XML-based markup documents.
4674-
4675- >>> markup_document = Gedit.Document()
4676- >>> location = Gio.file_new_for_path('plugins/gdp/data/snark.html')
4677- >>> markup_document.load(location, None, 0, False)
4678- >>> language_id = markup_document.get_language().get_id()
4679- >>> print language_id
4680- html
4681- >>> provider = DynamicProvider(
4682- ... "tester", language_id, handler, markup_document)
4683- >>> provider.get_generator(markup_document, '')
4684- <gdp.syntaxcompleter.MarkupGenerator ...>
4685-
4686-
4687-do_get_info_widget
4688-~~~~~~~~~~~~~~~~~~
4689-
4690- >>> widget = provider.do_get_info_widget(None)
4691- >>> widget
4692- <ScrolledWindow ...>
4693
4694=== added file 'plugins/gdp/tests/test_complete.py'
4695--- plugins/gdp/tests/test_complete.py 1970-01-01 00:00:00 +0000
4696+++ plugins/gdp/tests/test_complete.py 2012-02-07 18:01:21 +0000
4697@@ -0,0 +1,742 @@
4698+# Copyright (C) 2011-2012 - Curtis Hovey <sinzui.is at verizon.net>
4699+# This software is licensed under the MIT license (see the file COPYING).
4700+
4701+import os
4702+
4703+from gi.repository import (
4704+ GdkPixbuf,
4705+ Gtk,
4706+ GtkSource,
4707+ )
4708+
4709+from gdp import (
4710+ Config,
4711+ config,
4712+ )
4713+from gdp import complete
4714+from gdp.complete import (
4715+ BaseGenerator,
4716+ DynamicProposal,
4717+ DynamicProvider,
4718+ MarkupGenerator,
4719+ PangoDoc,
4720+ PythonProposal,
4721+ PythonGenerator,
4722+ Completer,
4723+ TextGenerator,
4724+ )
4725+from testing import SignalTester
4726+from testing import GeditTestCase
4727+
4728+
4729+class BaseGeneratorTestCase(GeditTestCase):
4730+
4731+ def test_properies(self):
4732+ window, view, document = self.make_gedit(
4733+ 'plugins/gdp/data/snark12.txt')
4734+ text = document.get_text(
4735+ document.get_start_iter(), document.get_end_iter(), True)
4736+ generator = BaseGenerator(document)
4737+ self.assertIn('plugins/gdp/data/snark12.txt', generator.file_path)
4738+ self.assertEqual(text, generator.text)
4739+ self.assertEqual(r'[\w_]', generator.word_char.pattern)
4740+ self.assertEqual('', generator.string_before_cursor)
4741+
4742+ def test_get_words_error(self):
4743+ # Subclass must implement get_words.
4744+ window, view, document = self.make_gedit(
4745+ 'plugins/gdp/data/snark12.txt')
4746+ generator = BaseGenerator(document)
4747+ self.assertRaises(NotImplementedError, generator.get_words, 'Ba')
4748+
4749+
4750+class TextGeneratorTestCase(GeditTestCase):
4751+
4752+ def test_get_words_without_prefix(self):
4753+ # Subclass must implement get_words.
4754+ window, view, document = self.make_gedit(
4755+ 'plugins/gdp/data/snark12.txt')
4756+ generator = TextGenerator(document)
4757+ is_authoritative, proposals = generator.get_words()
4758+ self.assertIs(False, is_authoritative)
4759+ self.assertEqual(1987, len(proposals))
4760+ self.assertIsInstance(proposals[0], DynamicProposal)
4761+ self.assertEqual(
4762+ ['000', '000x100', '03', '08', '1', '10', '1992', '2', '20'],
4763+ [proposal._word for proposal in sorted(proposals)][0:9])
4764+
4765+ def test_get_words_with_prefix(self):
4766+ window, view, document = self.make_gedit(
4767+ 'plugins/gdp/data/snark12.txt')
4768+ generator = TextGenerator(document, prefix='Ba')
4769+ is_authoritative, proposals = generator.get_words()
4770+ self.assertEqual(16, len(proposals))
4771+ self.assertEqual(
4772+ ['BAKER', 'BANKER', 'BARRISTER', 'Baker', 'Bandersnatch'],
4773+ [proposal._word for proposal in sorted(proposals)][0:5])
4774+
4775+ def test_get_words_case_insensitivity(self):
4776+ window, view, document = self.make_gedit(
4777+ 'plugins/gdp/data/snark12.txt')
4778+ generator = TextGenerator(document)
4779+ is_authoritative, lowercase_proposals = generator.get_words('snar')
4780+ is_authoritative, uppercase_proposals = generator.get_words('SNAR')
4781+ self.assertEqual(
4782+ ['SNARK', 'Snark', 'Snarks', 'snark12', 'snarked'],
4783+ [proposal._word for proposal in sorted(lowercase_proposals)])
4784+ self.assertEqual(lowercase_proposals, uppercase_proposals)
4785+
4786+ def test_get_words_with_hyphenation(self):
4787+ window, view, document = self.make_gedit(
4788+ 'plugins/gdp/data/snark12.txt')
4789+ generator = TextGenerator(document)
4790+ is_authoritative, proposals = generator.get_words('What-')
4791+ self.assertEqual(2, len(proposals))
4792+ self.assertEqual(
4793+ ['What-was-his-name', 'What-you-may-call-um'],
4794+ [proposal._word for proposal in sorted(proposals)])
4795+
4796+ def test_get_words_with_undescored(self):
4797+ window, view, document = self.make_gedit(
4798+ 'plugins/gdp/data/hackerese.txt')
4799+ generator = TextGenerator(document)
4800+ is_authoritative, proposals = generator.get_words('_')
4801+ self.assertEqual(6, len(proposals))
4802+ self.assertEqual(
4803+ ['_', '__call__', '__dict__', '__init__', '_dict', '_private'],
4804+ [proposal._word for proposal in sorted(proposals)])
4805+
4806+
4807+class MarkupGeneratorTestCase(GeditTestCase):
4808+
4809+ def test_string_before_cursor(self):
4810+ window, view, document = self.make_gedit(
4811+ 'plugins/gdp/data/snark.html')
4812+ generator = MarkupGenerator(document)
4813+ cursor_iter = document.get_start_iter()
4814+ cursor_iter.forward_lines(2)
4815+ cursor_iter.forward_chars(10)
4816+ document.place_cursor(cursor_iter)
4817+ self.assertEqual(r'[^<>]', generator.word_char.pattern)
4818+ self.assertEqual('title', generator.string_before_cursor)
4819+
4820+ def test_get_words_outside_tag(self):
4821+ # There are no proposals when the cursor is outside of a tag.
4822+ window, view, document = self.make_gedit(
4823+ 'plugins/gdp/data/snark.html')
4824+ document.place_cursor(document.get_start_iter())
4825+ generator = MarkupGenerator(document)
4826+ is_authoritative, proposals = generator.get_words()
4827+ self.assertIs(MarkupGenerator.OUTSIDE, generator.get_cursor_context())
4828+ self.assertEqual(set(), proposals)
4829+ self.assertIs(False, is_authoritative)
4830+
4831+ def test_get_words_inside_open_tag(self):
4832+ # The proposals match the unique tags uses in the document.
4833+ window, view, document = self.make_gedit(
4834+ 'plugins/gdp/data/snark.html')
4835+ generator = MarkupGenerator(document)
4836+ cursor_iter = document.get_start_iter()
4837+ cursor_iter.forward_lines(2)
4838+ cursor_iter.forward_chars(10)
4839+ document.place_cursor(cursor_iter)
4840+ is_authoritative, proposals = generator.get_words('')
4841+ self.assertIs(
4842+ MarkupGenerator.INSIDE_OPEN, generator.get_cursor_context())
4843+ self.assertIs(True, is_authoritative)
4844+ self.assertEqual('title', generator.string_before_cursor)
4845+ self.assertEqual(
4846+ ['body', 'br', 'div', 'em', 'h1', 'h2', 'head', 'html',
4847+ 'p', 'pre', 'title'],
4848+ [proposal._word for proposal in sorted(proposals)])
4849+
4850+ def test_get_words_inside_attributes_tag(self):
4851+ # The proposals match the unique attributes used in the document
4852+ window, view, document = self.make_gedit(
4853+ 'plugins/gdp/data/snark.html')
4854+ generator = MarkupGenerator(document)
4855+ cursor_iter = document.get_start_iter()
4856+ cursor_iter.forward_lines(2)
4857+ cursor_iter.forward_chars(10)
4858+ document.place_cursor(cursor_iter)
4859+ document.insert_at_cursor(" c")
4860+ is_authoritative, proposals = generator.get_words()
4861+ self.assertIs(
4862+ MarkupGenerator.INSIDE_ATTRIBUTES, generator.get_cursor_context())
4863+ self.assertIs(True, is_authoritative)
4864+ self.assertEqual('title c', generator.string_before_cursor)
4865+ self.assertEqual(
4866+ ['class'], [proposal._word for proposal in sorted(proposals)])
4867+
4868+ def test_get_words_inside_close_tag(self):
4869+ # The proposals match the unique tags that are open before the cursor.
4870+ window, view, document = self.make_gedit(
4871+ 'plugins/gdp/data/snark.html')
4872+ generator = MarkupGenerator(document)
4873+ cursor_iter = document.get_start_iter()
4874+ cursor_iter.forward_lines(2)
4875+ cursor_iter.forward_chars(37)
4876+ document.place_cursor(cursor_iter)
4877+ is_authoritative, proposals = generator.get_words('')
4878+ self.assertIs(
4879+ MarkupGenerator.INSIDE_CLOSE, generator.get_cursor_context())
4880+ self.assertIs(True, is_authoritative)
4881+ self.assertEqual('/', generator.string_before_cursor)
4882+ self.assertEqual(
4883+ ['head>', 'html>', 'title>'],
4884+ [proposal._word for proposal in sorted(proposals)])
4885+
4886+
4887+class PythonGeneratorTestCase(GeditTestCase):
4888+
4889+ def test_kwlist(self):
4890+ window, view, document = self.make_gedit(
4891+ 'plugins/gdp/data/snark.py')
4892+ generator = PythonGenerator(document)
4893+ proposals = set(proposal._word for proposal in generator.kwlist)
4894+ self.assertTrue(set(['and', 'as', 'assert']).issubset(proposals))
4895+
4896+ def test_builtin(self):
4897+ window, view, document = self.make_gedit(
4898+ 'plugins/gdp/data/snark.py')
4899+ generator = PythonGenerator(document)
4900+ proposals = set(proposal._word for proposal in generator.builtin)
4901+ self.assertTrue(set(['list', 'str', 'xrange']).issubset(proposals))
4902+
4903+ def test_get_local_symbols(self):
4904+ window, view, document = self.make_gedit(
4905+ 'plugins/gdp/data/snark.py')
4906+ document.place_cursor(document.get_start_iter())
4907+ generator = PythonGenerator(document)
4908+ self.assertIs(None, generator._local_symsbols)
4909+ generator.get_words()
4910+ self.assertIsNone(None, generator._local_symsbols)
4911+ self.assertIs(
4912+ generator._local_symsbols, generator.get_local_symbols())
4913+ symbols = [pp._word for pp in generator.get_local_symbols()[0:3]]
4914+ self.assertEqual(['type', '__metaclass__', '__all__'], symbols)
4915+
4916+ def test_get_words_returns_pythonproposal(self):
4917+ window, view, document = self.make_gedit(
4918+ 'plugins/gdp/data/snark.py')
4919+ generator = PythonGenerator(document)
4920+ document.place_cursor(document.get_end_iter())
4921+ document.insert_at_cursor('os.path.j')
4922+ is_authoritative, proposals = generator.get_words('j')
4923+ proposal = proposals[0]
4924+ self.assertIsInstance(proposal, PythonProposal)
4925+
4926+ def test_pythonproposal_do_get_info(self):
4927+ # do_get_info returns pydoc for the identifier.
4928+ window, view, document = self.make_gedit(
4929+ 'plugins/gdp/data/snark.py')
4930+ generator = PythonGenerator(document)
4931+ document.place_cursor(document.get_end_iter())
4932+ document.insert_at_cursor('os.path.j')
4933+ is_authoritative, proposals = generator.get_words('j')
4934+ proposal = proposals[0]
4935+ text = proposal.do_get_info()
4936+ self.assertIs(os.path.join, proposal._info)
4937+ self.assertIn(
4938+ '<b>join</b>(a, *p)\n Join two or more pathname', text)
4939+
4940+ def test_pythonproposal_do_get_info_none(self):
4941+ # do_get_info returns None if the info is None.
4942+ window, view, document = self.make_gedit(
4943+ 'plugins/gdp/data/snark.py')
4944+ document.place_cursor(document.get_start_iter())
4945+ generator = PythonGenerator(document)
4946+ is_authoritative, proposals = generator.get_words('A')
4947+ proposal = proposals[0]
4948+ proposal._info = None
4949+ self.assertIs('', proposal.do_get_info())
4950+
4951+ def test_get_words_with_prefix(self):
4952+ # Python identifiers are matched, not words.
4953+ window, view, document = self.make_gedit(
4954+ 'plugins/gdp/data/snark.py')
4955+ document.place_cursor(document.get_start_iter())
4956+ generator = PythonGenerator(document)
4957+ is_authoritative, proposals = generator.get_words('A')
4958+ self.assertIn('An ', generator.text)
4959+ self.assertEqual(3, len(proposals))
4960+ self.assertEqual(
4961+ ['ArithmeticError', 'AssertionError', 'AttributeError'],
4962+ [proposal._word for proposal in sorted(proposals)])
4963+
4964+ def test_get_words_with_keywords(self):
4965+ # Python keywords are matches.
4966+ window, view, document = self.make_gedit(
4967+ 'plugins/gdp/data/snark.py')
4968+ document.place_cursor(document.get_start_iter())
4969+ generator = PythonGenerator(document)
4970+ is_authoritative, proposals = generator.get_words('wh')
4971+ self.assertEqual(1, len(proposals))
4972+ self.assertEqual(
4973+ ['while'],
4974+ [proposal._word for proposal in sorted(proposals)])
4975+
4976+ def test_get_words_is_authoratative(self):
4977+ # The matches are authoritative when a namespace is
4978+ # matched without a prefix.
4979+ window, view, document = self.make_gedit(
4980+ 'plugins/gdp/data/snark.py')
4981+ document.place_cursor(document.get_start_iter())
4982+ cursor_iter = document.get_iter_at_mark(document.get_insert())
4983+ cursor_iter.set_line(document.get_line_count() - 6)
4984+ generator = PythonGenerator(document)
4985+ is_authoritative, proposals = generator.get_words('wh')
4986+ self.assertIs(False, is_authoritative)
4987+ document.place_cursor(document.get_end_iter())
4988+ document.insert_at_cursor('os.path.j')
4989+ is_authoritative, proposals = generator.get_words('j')
4990+ self.assertIs(True, is_authoritative)
4991+
4992+ def test_get_parsable_text_at_start_of_block(self):
4993+ # If the line being edited starts a block, get_parsable_text replaces
4994+ # line with code (if True:) that will guarantee the module will
4995+ # compile.
4996+ window, view, document = self.make_gedit(
4997+ 'plugins/gdp/data/snark.py')
4998+ document.place_cursor(document.get_start_iter())
4999+ generator = PythonGenerator(document)
5000+ cursor_iter = document.get_iter_at_mark(document.get_insert())
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: