4

I want to have a shortcut key for duplicating the currently selected line in gedit. Many other editors use Ctrl+D or Ctrl+Shift+D for that, but gedit is different.

Here the default behaviour:

  • Ctrl+D: removes a line
  • Ctrl+Shift+D: opens GTK inspector

I am fine with both current behaviours as long as the other hotkey would do the thing I actually want to do.

So I saw this answer where it is shown you can actually patch the gedit binary. However I don't want to do this as patching binaries is probably the worst kind of workaround you can do (think of updates and binary changes). Additionally, in that question only the "delete line" shortcut was removed and the "duplicate line" shortcut was added with a plugin, which does not exist anymore.

So how can I get the "duplicate this line" behaviour into gedit?

  • Here is the plugin for gedit3. It should work with older versions but not with more recent ones- prolly the code needs to be updated (I'm using gedit 3.22 and it spits a bunch of errors... before failing to load) – don_crissti Nov 2 '16 at 23:38
  • @don_crissti Thx for the link. However also in v3.14.0 it does not work here. – rugk Nov 3 '16 at 17:16
  • Well, one thing you should try, if your system is using python3: edit the file duplicateline.plugin and change Loader=python to Loader=python3 If it still doesn't work... well, I don't know... if you're familiar with python you could try to re-write the plugin. – don_crissti Nov 3 '16 at 18:47
  • Yes, I already tried this. Afterwards I could at least activate it in gedit, but it still did not work… – rugk Nov 11 '16 at 23:36
1

The plugin mentioned in the comments and the other answer has been recently updated and after install you should be able to use Ctrl+Shift+D to duplicate either a line or a selection.

I've tested it in gedit 3.18.3 on Ubuntu 16.04 but it should work in any version >=3.14.0 even though that's a bit questionable because the gedit devs are not shy to introduce breaking changes in minor versions (or they follow something else than semantic versioning) and there seems to be no up-to-date documentation for plugin development.

2

Do you still look for an answer? I think I have the right one, though I'm not sure, because I'm not familiar with python.
1. You should edit duplicateline.py file from plugin for gedit3 this way:


import gettext
from gi.repository import GObject, Gtk, Gio, Gedit
ACCELERATOR = ['<Alt>d']

#class DuplicateLineWindowActivatable(GObject.Object, Gedit.WindowActivatable):
class DuplicateLineAppActivatable(GObject.Object, Gedit.AppActivatable):
    __gtype_name__ = "DuplicateLineWindowActivatable"

    app = GObject.Property(type=Gedit.App)

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        #self._insert_menu()
        self.app.set_accels_for_action("win.duplicate", ACCELERATOR)
        self.menu_ext = self.extend_menu("tools-section")
        item = Gio.MenuItem.new(_("Duplicate Line"), "win.duplicate")
        self.menu_ext.prepend_menu_item(item)

    def do_deactivate(self):
        #self._remove_menu()
        self.app.set_accels_for_action("win.duplicate", [])
        self.menu_ext = None

        #self._action_group = None

    #def _insert_menu(self):
        #manager = self.window.get_ui_manager()

        # Add our menu action and set ctrl+shift+D to activate.
        #self._action_group = Gtk.ActionGroup("DuplicateLinePluginActions")
        #self._action_group.add_actions([(
            #"DuplicateLine",
            #None,
            #_("Duplicate Line"),
            #"d",
            #_("Duplicate current line, current selection or selected lines"),
            #self.on_duplicate_line_activate
        #)])

        #manager.insert_action_group(self._action_group, -1)

        #self._ui_id = manager.add_ui_from_string(ui_str)

    #def _remove_menu(self):
        #manager = self.window.get_ui_manager()
        #manager.remove_ui(self._ui_id)
        #manager.remove_action_group(self._action_group)
        #manager.ensure_update()

    def do_update_state(self):
        #self._action_group.set_sensitive(self.window.get_active_document() != None)
        pass
class DuplicateLineWindowActivatable(GObject.Object, Gedit.WindowActivatable):
    window = GObject.property(type=Gedit.Window)

    def __init__(self):
        GObject.Object.__init__(self)
        self.settings = Gio.Settings.new("org.gnome.gedit.preferences.editor")

    def do_activate(self):
        action = Gio.SimpleAction(name="duplicate")
        action.connect('activate', self.on_duplicate_line_activate)
        self.window.add_action(action)

    def on_duplicate_line_activate(self, action, user_data=None):
        doc = self.window.get_active_document()
        if not doc:
            return

        if doc.get_has_selection():
            # User has text selected, get bounds.
            s, e = doc.get_selection_bounds()
            l1 = s.get_line()
            l2 = e.get_line()

            if l1 != l2:
                # Multi-lines selected. Grab the text, insert.
                s.set_line_offset(0)
                e.set_line_offset(e.get_chars_in_line())

                text = doc.get_text(s, e, False)
                if text[-1:] != '\n':
                    # Text doesn't have a new line at the end. Add one for the beginning of the next.
                    text = "\n" + text

                doc.insert(e, text)
            else:
                # Same line selected. Grab the text, insert on same line after selection.
                text = doc.get_text(s, e, False)
                doc.move_mark_by_name("selection_bound", s)
                doc.insert(e, text)
        else:
            # No selection made. Grab the current line the cursor is on, insert on new line.
            s = doc.get_iter_at_mark(doc.get_insert())
            e = doc.get_iter_at_mark(doc.get_insert())
            s.set_line_offset(0)

            if not e.ends_line():
                e.forward_to_line_end()

            text = "\n" + doc.get_text(s, e, False)

            doc.insert(e, text)



2. Alt+D duplicates a line. You may change the hot key - edit the 3d line "ACCELERATOR = ['<Alt>d']" as you see fit.
3. At least, it works for gedit v. 3.14.3.

  • Does not work, but thanks for your afford. Maybe send a PR to the author. – rugk Apr 1 '17 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.