Érdekes módon a deadlime kedvenc kódszerkesztő alkalmazása a Sublime. Egyrészt azért, mert a többszörös kijelölés az bizony hihetetlenül fantasztikus egy találmány. Másrészt pedig Python-ban lehet hozzá plugin-eket írni.

Kedves kollégám említette a minap, hogy egyik régebben használt szerkesztőjében volt valamiféle funkció, amivel a vágólap korábbi tartalmait lehetett újra felhasználni. Aztán elkezdtem gondolkodni rajta, hogy vajon lehetne-e egy ilyen plugin-t írni Sublime-hoz. Aztán megírtam. :)

Ha már így alakult, ragadjuk meg az alkalmat és nézzük meg kicsit, hogyan is néz ki egy Sublime plugin. A funkció meglepően kevés kódból megoldható: először is felül kell csapnunk a beépített copy és cut utasításokat sajáttal úgy, hogy megmaradjon az eredeti funkcionalitás is, de közbe mentsük egy tömbbe az adatokat.

class ClipboardHistoryCopyCommand(sublimeplugin.TextCommand):
    def run(self, view, args):
        saveSelections(view)
        view.runCommand('copy');

Egy kis XML-lel meg is mondjuk a proginak, hogy a mi parancsunkat használja a Ctrl+C nyomkodása esetén:

<bindings>
    <binding key="ctrl+c" command="clipboardHistoryCopy" />
</bindings>

A cut nem túl meglepő módon elég hasonlóan néz ki (csak a beépített cut parancsot hívjuk meg a végén). A saveSelections végzi a munka javát. Végigmegy az összes kijelölésen és amelyik nem üres, azt elpakolja egy tömbbe, aminél még arra is figyelünk, hogy ne lehessen túl nagy:

clipboardMaxSize = 100
clipboardData = []

def saveSelections(view):
    for region in view.sel():
        if region.begin() != region.end():
            clipboardData.insert(0, view.substr(region))
            if len(clipboardData) > clipboardMaxSize:
                clipboardData.pop()

Annyi maradt már csak, hogy valami kellően kézreálló billentyűkombinációra meg is jelenítse az előzményeket és tudjunk belőle kedvünkre válogatni. Legnagyobb szerencsénkre tudjuk használni a beépített lista ablakot, amiben még kereső is van (ugyanaz, ami a Ctrl+P vagy a Ctrl+R kombinációkra is bejön):

class ClipboardHistoryPasteCommand(sublimeplugin.TextCommand):
    def pasteSelected(self, view, index):
        for region in view.sel():
            view.insert(region.begin(), clipboardData[index])
    
    def run(self, view, args):
        view.window().showSelectPanel(
            clipboardData,
            functools.partial(self.pasteSelected, view),
            None,
            sublime.SELECT_PANEL_MONOSPACE_FONT
        );

És természetesen a hozzá tartozó kis XML részlet:

<binding key="alt+shift+q" command="clipboardHistoryPaste" />

Nem a legtökéletesebb megoldás, például plugin újratöltéseknél elveszik a clipboardData tömb tartalma (lehetne például fájlba menteni menet közben), de kezdetnek megteszi. A teljes csomagot innen le lehet rántani (érdekes módon ClipboardHistory.sublime-package fájlnévvel nem mentek volna a billentyűparancs felüldefiniálások, mivel az Sublime ABC sorrendben tölti be a plugineket és a Default később van... :)).

[a képet köszönjük ShutterBugChef-nek]