# -*- coding: utf-8 -*-
# Join lines plugin
# This file is part of gedit
#
# Copyright (C) 2006-2007 Steve Frécinaux, André Homeyer
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307, USA.
import gedit, gtk
import gettext
try:
from gpdefs import *
gettext.bindtextdomain(GETTEXT_PACKAGE, GP_LOCALEDIR)
_ = lambda s: gettext.dgettext(GETTEXT_PACKAGE, s)
except:
_ = lambda s: s
ui_str = """
"""
class JoinLinesPlugin(gedit.Plugin):
def __init__(self):
gedit.Plugin.__init__(self)
def activate(self, window):
manager = window.get_ui_manager()
data = dict()
data["action_group"] = gtk.ActionGroup("GeditJoinLinesPluginActions")
data["action_group"].add_actions(
[("JoinLines", None, _("_Join Lines"), "J",
_("Join the selected lines"),
lambda a, w: join_lines(w)),
("SplitLines", None, _('_Split Lines'), "J",
_("Split the selected lines"),
lambda a, w: split_lines(w))],
window)
manager.insert_action_group(data["action_group"], -1)
data["ui_id"] = manager.add_ui_from_string(ui_str)
window.set_data("JoinLinesPluginInfo", data)
update_sensitivity(window)
def deactivate(self, window):
data = window.get_data("JoinLinesPluginInfo")
manager = window.get_ui_manager()
manager.remove_ui(data["ui_id"])
manager.remove_action_group(data["action_group"])
manager.ensure_update()
window.set_data("JoinLinesPluginInfo", None)
def update_ui(self, window):
update_sensitivity(window)
def update_sensitivity(window):
data = window.get_data("JoinLinesPluginInfo")
view = window.get_active_view()
data["action_group"].set_sensitive(view is not None and \
view.get_editable())
def join_lines(window):
document = window.get_active_document()
if document is None:
return
document.begin_user_action()
# If there is a selection use it, otherwise join the
# next line
try:
start, end = document.get_selection_bounds()
except ValueError:
start = document.get_iter_at_mark(document.get_insert())
end = start.copy()
end.forward_line()
end_mark = document.create_mark(None, end)
if not start.ends_line():
start.forward_to_line_end()
while document.get_iter_at_mark(end_mark).compare(start) == 1:
end = start.copy()
while end.get_char() in ('\r', '\n', ' ', '\t'):
end.forward_char()
document.delete(start, end)
document.insert(start, ' ')
start.forward_to_line_end()
document.delete_mark(end_mark)
document.end_user_action()
def split_lines(window):
view = window.get_active_view()
if view is None:
return
document = view.get_buffer()
width = view.get_right_margin_position()
tabwidth = view.get_tab_width()
document.begin_user_action()
try:
# get selection bounds
start, end = document.get_selection_bounds()
# measure indent until selection start
indent_iter = start.copy()
indent_iter.set_line_offset(0)
indent = ''
while indent_iter.get_offset() != start.get_offset():
if indent_iter.get_char() == '\t':
indent = indent + '\t'
else:
indent = indent + ' '
indent_iter.forward_char()
except ValueError:
# select from start to line end
start = document.get_iter_at_mark(document.get_insert())
start.set_line_offset(0)
end = start.copy()
if not end.ends_line():
end.forward_to_line_end()
# measure indent of line
indent_iter = start.copy()
indent = ''
while indent_iter.get_char() in (' ', '\t'):
indent = indent + indent_iter.get_char()
indent_iter.forward_char()
end_mark = document.create_mark(None, end)
# ignore first word
previous_word_end = start.copy()
forward_to_word_start(previous_word_end)
forward_to_word_end(previous_word_end)
while 1:
current_word_start = previous_word_end.copy()
forward_to_word_start(current_word_start)
current_word_end = current_word_start.copy()
forward_to_word_end(current_word_end)
if ord(current_word_end.get_char()) and \
document.get_iter_at_mark(end_mark).compare(current_word_end) >= 0:
word_length = current_word_end.get_offset() - \
current_word_start.get_offset()
document.delete(previous_word_end, current_word_start)
line_offset = get_line_offset(current_word_start, tabwidth) + word_length
if line_offset > width - 1:
document.insert(current_word_start, '\n' + indent)
else:
document.insert(current_word_start, ' ')
previous_word_end = current_word_start.copy()
previous_word_end.forward_chars(word_length)
else:
break
document.delete_mark(end_mark)
document.end_user_action()
def get_line_offset(text_iter, tabwidth):
offset_iter = text_iter.copy()
offset_iter.set_line_offset(0)
line_offset = 0
while offset_iter.get_offset() < text_iter.get_offset():
char = offset_iter.get_char()
if char == '\t':
line_offset += tabwidth
else:
line_offset += 1
offset_iter.forward_char()
return line_offset
def forward_to_word_start(text_iter):
char = text_iter.get_char()
while ord(char) and (char in (' ', '\t', '\n', '\r')):
text_iter.forward_char()
char = text_iter.get_char()
def forward_to_word_end(text_iter):
char = text_iter.get_char()
while ord(char) and (not (char in (' ', '\t', '\n', '\r'))):
text_iter.forward_char()
char = text_iter.get_char()
# ex:ts=4:et: