PageRenderTime 24ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/gedit2/indent-converter/indent-converter/__init__.py

http://github.com/gmate/gmate
Python | 151 lines | 109 code | 41 blank | 1 comment | 12 complexity | 1dac984367ab2ae40ceb9d9509d9f098 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. import gedit
  2. import gtk
  3. import gconf
  4. from gettext import gettext as _
  5. import re
  6. class IndentConverterWindow:
  7. def __init__(self, plugin, window):
  8. self.window = window
  9. self.plugin = plugin
  10. def activate(self):
  11. self.insert_menu()
  12. return self
  13. def deactivate(self):
  14. self.remove_menu()
  15. self.window = None
  16. self.plugin = None
  17. self.action_group = None
  18. return self
  19. def update_ui(self):
  20. view = self.window.get_active_view()
  21. self.action_group.set_sensitive(bool(view and view.get_editable()))
  22. return self
  23. def insert_menu(self):
  24. manager = self.window.get_ui_manager()
  25. self.action_group = gtk.ActionGroup('IndentConverterActions')
  26. self.action_group.add_actions([
  27. ('TabConvert', None, _('Convert Tabs'), None, None, None),
  28. ('SpacesToTabs', gtk.STOCK_INDENT, _('Convert spaces to tabs'), None, _('Convert spaces to tabs'), self.do_spaces_to_tabs),
  29. ('TabsToSpaces', gtk.STOCK_INDENT, _('Convert tabs to spaces'), None, _('Convert tabs to spaces'), self.do_tabs_to_spaces),
  30. ])
  31. manager.insert_action_group(self.action_group, -1)
  32. self.ui_id = manager.add_ui_from_string(
  33. "<ui>\
  34. <menubar name='MenuBar'>\
  35. <menu name='EditMenu' action='Edit'>\
  36. <placeholder name='EditOps_6'>\
  37. <menu action='TabConvert'>\
  38. <menuitem action='SpacesToTabs'/>\
  39. <menuitem action='TabsToSpaces'/>\
  40. </menu>\
  41. </placeholder>\
  42. </menu>\
  43. </menubar>\
  44. </ui>")
  45. return self
  46. def remove_menu(self):
  47. manager = self.window.get_ui_manager()
  48. manager.remove_ui(self.ui_id)
  49. manager.remove_action_group(self.action_group)
  50. manager.ensure_update()
  51. return self
  52. def do_tabs_to_spaces(self, action):
  53. doc = self.window.get_active_document()
  54. start, end = doc.get_bounds()
  55. text = doc.get_text(start, end)
  56. text = text.expandtabs(self.plugin.tab_size())
  57. doc.begin_user_action()
  58. doc.set_text(text)
  59. doc.end_user_action()
  60. def guess_tab_size(self, text):
  61. def gcd(a, b):
  62. return a if b == 0 else gcd(b, a % b);
  63. r = re.compile('^ +', re.MULTILINE)
  64. matches = r.findall(text)
  65. freq = {} # `key` - length of leading spaces, `value` - it's frequency
  66. for spaces in matches:
  67. spaces = len(spaces)
  68. if spaces in freq:
  69. freq[spaces] += 1
  70. else:
  71. freq[spaces] = 1
  72. # sort frequencies by value:
  73. items = [ [i[1], i[0]] for i in freq.items() ]
  74. items.sort()
  75. items.reverse()
  76. items = [i[1] for i in items]
  77. if len(items) == 0:
  78. return 0
  79. elif len(items) == 1:
  80. return items[0]
  81. else:
  82. return gcd(items[0], items[1])
  83. def do_spaces_to_tabs(self, action):
  84. doc = self.window.get_active_document()
  85. start, end = doc.get_bounds()
  86. text = doc.get_text(start, end)
  87. tab_size = self.guess_tab_size(text)
  88. if (tab_size < 2):
  89. tab_size = self.plugin.tab_size()
  90. r = re.compile('^(?:' + (' ' * tab_size) + ')+', re.MULTILINE)
  91. def replacer(match):
  92. return '\t' * (len(match.group(0)) / tab_size)
  93. text = r.sub(replacer, text)
  94. doc.begin_user_action()
  95. doc.set_text(text)
  96. doc.end_user_action()
  97. class IndentConverterPlugin(gedit.Plugin):
  98. def __init__(self):
  99. gedit.Plugin.__init__(self)
  100. self.instances = {}
  101. self.client = gconf.client_get_default()
  102. def activate(self, window):
  103. self.instances[window] = IndentConverterWindow(self, window).activate()
  104. def deactivate(self, window):
  105. self.instances[window].deactivate()
  106. del self.instances[window]
  107. def update_ui(self, window):
  108. self.instances[window].update_ui()
  109. def tab_size(self):
  110. return self.client.get_int('/apps/gedit-2/preferences/editor/tabs/tabs_size')