# -*- 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: