Hogyan készíts saját plugint a Notepad++ számára

A Notepad++ egy rendkívül népszerű, ingyenes és nyílt forráskódú szövegszerkesztő, amelyet fejlesztők és általános felhasználók egyaránt előszeretettel használnak. Könnyedén kezelhető felülete, számos beépített funkciója és nem utolsósorban a pluginok általi bővíthetősége teszi nélkülözhetetlenné sokak számára. De mi van akkor, ha van egy olyan funkció, amire szükséged lenne, de még senki sem írta meg hozzá a plugint? Vagy egyszerűen csak szeretnéd automatizálni egyedi munkafolyamataidat? Akkor itt az ideje, hogy belevágj a saját Notepad++ plugin fejlesztésbe!

Ez az átfogó útmutató lépésről lépésre végigvezet téged a Notepad++ pluginok elkészítésének folyamatán. Megismerkedhetsz az alapvető koncepciókkal, a fejlesztői környezet beállításával, a kód struktúrájával és a fordítás, tesztelés lépéseivel. Célunk, hogy még ha nem is vagy tapasztalt C++ fejlesztő, akkor is képes legyél elindítani a saját projektet, és létrehozd az első egyéni funkcióidat a kedvenc szövegszerkesztődbe.

Miért érdemes saját Notepad++ Plugint fejleszteni?

A Notepad++ már önmagában is rendkívül sokoldalú, de a pluginok adják az igazi erejét. Íme néhány ok, amiért érdemes saját bővítményt írnod:

  • Egyéni munkafolyamatok automatizálása: Számos ismétlődő feladatot automatizálhatsz, amelyekkel időt takaríthatsz meg.
  • Hiányzó funkciók pótlása: Ha van egy specifikus igényed, amit a meglévő pluginok nem fednek le, elkészítheted a sajátodat.
  • Integráció más rendszerekkel: Lehetőséged van a Notepad++-t külső alkalmazásokkal, API-kkal vagy szolgáltatásokkal összekapcsolni.
  • Tanulás és fejlődés: A plugin fejlesztés kiváló módja a C++ ismeretek elmélyítésének és a Windows API-val való ismerkedésnek.
  • Közösségi hozzájárulás: Ha hasznos plugint készítesz, megoszthatod másokkal, és hozzájárulhatsz a Notepad++ közösségéhez.

Vágjunk is bele!

A Notepad++ Pluginok Alapjai: Hogyan működnek?

A Notepad++ pluginok lényegében dinamikusan linkelt könyvtárak (DLL-ek), amelyeket a Notepad++ betölt induláskor. Ezek a DLL-ek speciális függvényeket exportálnak, amelyeket a Notepad++ meghív, hogy lekérdezze a plugin adatait, a menüpontokat, és értesítéseket küldjön bizonyos eseményekről. A Notepad++ egy Scintilla komponensen alapul, amely maga is egy rendkívül rugalmas szövegszerkesztő komponens. A pluginok közvetlenül a Scintilla-val és a Notepad++ magjával is kommunikálhatnak üzeneteken keresztül.

Főbb alkotóelemek:

  • NppPlugin.h és PluginInterface.h: Ezek a header fájlok tartalmazzák azokat a struktúrákat és függvényprototípusokat, amelyeket a pluginodnak implementálnia kell a Notepad++-szal való kommunikációhoz.
  • NppData: Ez a struktúra tárolja a Notepad++ fő ablakának és a Scintilla ablakoknak a handle-jeit, amelyek segítségével üzeneteket küldhetsz a szerkesztőnek.
  • FuncItem: Ez a struktúra írja le a menüpontokat, amelyeket a pluginod hozzáad a Notepad++ menüjéhez.
  • Eseménykezelő függvények: A pluginodnak képesnek kell lennie kezelni a Notepad++ eseményeit (pl. fájl megnyitása, mentése, szerkesztő bezárása).

Előkészületek: Mire lesz szükséged?

Mielőtt belevágnánk a kódolásba, győződj meg róla, hogy minden szükséges eszközzel rendelkezel:

1. Fejlesztői Környezet: Visual Studio

A legkényelmesebb és legelterjedtebb választás a C++ plugin fejlesztéshez a Microsoft Visual Studio. A Visual Studio Community Edition ingyenesen letölthető és használható magánszemélyek és kis csapatok számára. Győződj meg róla, hogy telepítéskor kiválasztottad a „Desktop development with C++” munkaterhelést.

2. Notepad++ SDK (Software Development Kit)

Ez a legfontosabb komponens. Az SDK tartalmazza a szükséges header fájlokat és a példaprojekteket. Letöltheted a Notepad++ hivatalos GitHub oldaláról, általában a „nppPluginList” repositoryban találod meg a plugin_template mappát vagy egy különálló nppsdk repositoryt.

Keresd meg a Notepad++ plugin template repositoryt, amely egy működő kiindulási alapot biztosít a plugin fejlesztéshez. Erősen ajánlott ebből kiindulni, mivel már tartalmazza a minimális szükséges kódot és a projektbeállításokat.

3. Notepad++ Telepítés

Természetesen szükséged lesz egy működő Notepad++ telepítésre a plugin teszteléséhez. Fontos, hogy a pluginod architektúrája (32-bit vagy 64-bit) megegyezzen a Notepad++ telepítésed architektúrájával.

4. C/C++ Alapismeretek

Bár ez az útmutató igyekszik minél részletesebben mindent elmagyarázni, a C++ nyelv alapszintű ismerete, beleértve a mutatókat, struktúrákat és a Windows API alapjait, nagyban megkönnyíti a dolgodat.

Projekt Beállítása Visual Studióban

A projekt beállítása az egyik legkritikusabb lépés. Kövesd az alábbi utasításokat:

1. Új projekt létrehozása

  1. Nyisd meg a Visual Studiót.
  2. Válassz „Create a new project”-et.
  3. Keresd a „Dynamic Link Library (DLL)” projektet C++ nyelven, és válaszd a „Empty Project” sablont. (Ha a template-ből indulsz, akkor egyszerűen nyisd meg a .sln fájlt a template mappájából.)
  4. Adj nevet a projektnek (pl. „MyNppPlugin”) és válaszd ki a mentési helyet.
  5. Kattints a „Create” gombra.

2. Projekt Konfigurációk

A Visual Studio felül, a toolbaron válaszd ki a megfelelő architektúrát (x64 vagy Win32) a Notepad++ telepítésednek megfelelően, valamint a „Release” vagy „Debug” konfigurációt.

3. C++ Include Könyvtárak hozzáadása

Ez elengedhetetlen, hogy a projekt megtalálja az SDK header fájljait:

  1. Kattints jobb gombbal a projektre a Solution Explorerben, és válaszd a „Properties” lehetőséget.
  2. Navigálj a „Configuration Properties” -> „C/C++” -> „General” menüpontra.
  3. Az „Additional Include Directories” mezőbe add hozzá a Notepad++ SDK mappájának elérési útját (pl. C:NotepadPP_SDKnppsdkinclude vagy ahova letöltötted a template-et és az include mappát).

4. Linker Beállítások

Szükségünk lehet bizonyos függvénykönyvtárakra a fordításhoz:

  1. Még mindig a „Project Properties” ablakban, navigálj a „Linker” -> „Input” menüpontra.
  2. Az „Additional Dependencies” mezőbe add hozzá a SciLexer.lib fájlt (ez a Scintilla komponens könyvtára, gyakran hasznos, ha a szerkesztő tartalmával akarsz interakcióba lépni). Lehet, hogy meg kell adnod az elérési útját is, ha nincs a Visual Studio default lib mappáiban (pl. C:NotepadPP_SDKnppsdklibSciLexer.lib).

5. Kimeneti könyvtár beállítása

Ez egy kényelmi funkció, amely automatikusan a megfelelő helyre másolja a lefordított DLL-t:

  1. Navigálj a „Configuration Properties” -> „General” menüpontra.
  2. A „Output Directory” mezőben add meg a Notepad++ plugins mappájának elérési útját (pl. C:Program FilesNotepad++pluginsMyNppPlugin, vagy a 64-bites verzió esetén C:Program FilesNotepad++pluginsMyNppPlugin. Fontos, hogy a DLL-nek a plugin saját almappájában kell lennie a Notepad++ 7.6.x verzióitól kezdve!).
  3. A „Target Name” mezőben add meg a DLL nevének előtagját (pl. MyNppPlugin), ekkor a kimenet MyNppPlugin.dll lesz.

6. SDK fájlok hozzáadása a projekthez (ha nem template-ből indulsz)

Ha üres projektet hoztál létre, manuálisan hozzá kell adnod az SDK legfontosabb fájljait a projektedhez. Ezeket általában az SDK src mappájában találod:

  • NppPlugin.cpp
  • NppPlugin.h
  • PluginInterface.h
  • menuCmdID.h (opcionális, de jó, ha kéznél van az egyedi menü ID-k definiálásához)

Másold ezeket a fájlokat a projektmappádba, majd kattints jobb gombbal a projektre a Solution Explorerben, és válaszd az „Add” -> „Existing Item…” lehetőséget, majd válaszd ki a másolt fájlokat.

A Plugin Lelke: Alapvető Kód Struktúra

Most, hogy a projekt beállításra került, nézzük meg, hogyan épül fel egy minimális Notepad++ plugin kódja. A NppPlugin.cpp fájl a pluginod fő forráskódja.

1. Globális változók és inicializálás

Szükségünk lesz egy globális NppData változóra, ami tárolja a Notepad++ fő adatstruktúráját, és egy FuncItem tömbre, ami a menüparancsokat tartalmazza.


#include <windows.h>
#include "NppPlugin.h"
#include "PluginInterface.h"

// Globális NppData struktúra a Notepad++ kommunikációhoz
NppData nppData;

// A plugin menüparancsai
FuncItem funcItems[MAX_FUNC];

// Plugin neve
TCHAR pluginName[] = TEXT("MyNppPlugin");

// A parancsok száma
int nbFunc = 0;

2. DllMain függvény

Ez a DLL belépési pontja. Itt nincs szükség bonyolult logikára, csak az alapvető inicializálásra.


BOOL APIENTRY DllMain(HMODULE hModule, DWORD reasonForCall, LPVOID lpReserved)
{
    UNREFERENCED_PARAMETER(lpReserved);
    switch (reasonForCall)
    {
        case DLL_PROCESS_ATTACH:
            // Plugin betöltésekor
            break;
        case DLL_PROCESS_DETACH:
            // Plugin leállásakor
            break;
        case DLL_THREAD_ATTACH:
            // Szál indításakor
            break;
        case DLL_THREAD_DETACH:
            // Szál leállásakor
            break;
    }
    return TRUE;
}

3. setInfo(NppData npd)

Ezt a függvényt hívja meg a Notepad++ közvetlenül a plugin betöltése után. Itt kapjuk meg az NppData struktúrát, amit el kell mentenünk a globális változónkba.


extern "C" __declspec(dllexport) void setInfo(NppData npd)
{
    nppData = npd;
}

4. isUnicode()

Ez a függvény jelzi a Notepad++-nak, hogy a plugin Unicode-ot használ. A modern pluginoknak mindig true-t kell visszaadniuk.


extern "C" __declspec(dllexport) BOOL isUnicode()
{
    return TRUE;
}

5. getName()

Ez adja vissza a plugin nevét, ami a Notepad++ menüjében fog megjelenni.


extern "C" __declspec(dllexport) TCHAR * getName()
{
    return pluginName;
}

6. setCommand(size_t index, TCHAR *cmdName, PFUNCPLUGINCMD pFunc, BOOL checkOnInit, ShortcutKey *sk)

Ez a segédfüggvény a menüparancsok hozzáadására szolgál.


void addCommand(TCHAR *cmdName, PFUNCPLUGINCMD pFunc, BOOL checkOnInit, ShortcutKey *sk)
{
    if (nbFunc >= MAX_FUNC) return;

    // Inicializáld a FuncItem struktúrát
    funcItems[nbFunc]._cmdID = nbFunc;
    _tcsncpy_s(funcItems[nbFunc]._itemName, cmdName, _countof(funcItems[nbFunc]._itemName) - 1);
    funcItems[nbFunc]._pFunc = pFunc;
    funcItems[nbFunc]._init2Check = checkOnInit;
    funcItems[nbFunc]._pShKey = sk;
    funcItems[nbFunc]._tMenu = NULL;
    funcItems[nbFunc]._pszModuleName = pluginName;
    nbFunc++;
}

7. getFuncArray(int *nbItems)

Ezt a függvényt hívja meg a Notepad++, hogy lekérdezze a plugin által biztosított menüparancsokat. Itt kell feltölteni a funcItems tömböt a saját parancsaiddal.


void command1()
{
    MessageBox(nppData._nppHandle, TEXT("Szia, Notepad++! Ez az első pluginom!"), TEXT("MyNppPlugin"), MB_OK);
}

extern "C" __declspec(dllexport) FuncItem * getFuncArray(int *nbItems)
{
    *nbItems = nbFunc;
    return funcItems;
}

// Ezt a DllMain-ben vagy egy külön inicializáló függvényben hívhatod meg
extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode)
{
    // Események kezelése, lásd később
}


// Ezt a setInfo után, de a getFuncArray előtt kell meghívni
void doInit()
{
    // Itt definiáljuk a menüparancsainkat
    addCommand(TEXT("Üdvözlő üzenet"), command1, FALSE, NULL);
    // addCommand(TEXT("Másik parancs"), anotherCommandFunc, FALSE, NULL);
}

// Notepad++ 8.x-től a beNotified előtt van egy "pluginInit" függvény hívva
extern "C" __declspec(dllexport) void pluginInit(HANDLE hModule)
{
    doInit(); // Hívjuk meg az inicializáló függvényünket
}

Megjegyzés: A Notepad++ 8.x verzióitól kezdve a pluginInit függvényt hívják meg a menüparancsok inicializálására, mielőtt a getFuncArray-t meghívnák. A régebbi verziókhoz a setInfo függvényben is inicializálhatod a parancsokat, de a pluginInit a preferált módszer.

Interakció a Notepad++-szal: Üzenetek küldése

A plugin lényege, hogy interakcióba lépjen a Notepad++-szal és a Scintilla szerkesztőkomponenssel. Ezt Windows üzenetek küldésével tehetjük meg a ::SendMessage függvény segítségével.

1. Notepad++ üzenetek (NPPW_*, NPPM_*)

Ezek az üzenetek a Notepad++ fő ablakának funkcióit vezérlik (pl. fájlok megnyitása, mentése, aktuális fájl elérési útjának lekérése).


// Aktuális fájl elérési útjának lekérése
TCHAR filePath[MAX_PATH];
::SendMessage(nppData._nppHandle, NPPM_GETFULLCURRENTPATH, 0, (LPARAM)filePath);
MessageBox(nppData._nppHandle, filePath, TEXT("Aktuális fájl"), MB_OK);

// Szöveg beillesztése a kurzor pozíciójára (Scintilla üzenettel)
::SendMessage(nppData._scintillaMainHandle, SCI_INSERTTEXT, -1, (LPARAM)TEXT("Hello from plugin!"));

2. Scintilla üzenetek (SCI_*)

Ezek az üzenetek a szövegszerkesztő tartalmát és viselkedését befolyásolják (pl. szöveg beszúrása, kijelölés, színek beállítása).


// Aktuálisan kijelölt szöveg lekérése
int selLength = ::SendMessage(nppData._scintillaMainHandle, SCI_GETSELTEXTLENGTH, 0, 0);
if (selLength > 0)
{
    char* selectedText = new char[selLength + 1];
    ::SendMessage(nppData._scintillaMainHandle, SCI_GETSELTEXT, 0, (LPARAM)selectedText);
    selectedText[selLength] = ''; // Null-terminátor
    MessageBoxA(nppData._nppHandle, selectedText, "Kijelölt szöveg", MB_OK);
    delete[] selectedText;
}

// Szöveg cseréje
::SendMessage(nppData._scintillaMainHandle, SCI_REPLACERANGE, 0, (LPARAM)TEXT("Új szöveg"));

A Notepad++ SDK dokumentációja és a Scintilla dokumentációja tartalmazza az összes elérhető üzenetet és paramétereiket. Ez a te „bibliaod” a fejlesztés során.

Eseménykezelés: beNotified(SCNotification *notifyCode)

A beNotified függvényt hívja meg a Notepad++, amikor különböző események történnek (pl. fájl megnyitása, mentése, a felhasználó vált dokumentumot). Itt tudsz reagálni ezekre az eseményekre.


extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode)
{
    switch (notifyCode->_header.code)
    {
        case NPPN_FILEOPENED:
            // Fájl megnyitásakor
            MessageBox(nppData._nppHandle, TEXT("Egy fájl megnyílt!"), TEXT("Esemény"), MB_OK);
            break;
        case NPPN_FILESAVED:
            // Fájl mentésekor
            break;
        case NPPN_SHUTDOWN:
            // Notepad++ bezárásakor (fontos a cleanuphoz)
            // Itt szabadítsd fel az erőforrásaidat
            break;
        // ... további események (NPPN_BUFFERACTIVATED, NPPN_WORDSTYLEUPDATED stb.)
    }
}

Felhasználói Felület (UI) Készítése

A legegyszerűbb UI a MessageBox, de komplexebb interakciókhoz szükség lehet párbeszédpanelekre vagy dokkolható ablakokra.

1. Párbeszédpanelek (Dialogs)

A Windows API lehetővé teszi egyedi párbeszédpanelek létrehozását. Ehhez szükség van egy .rc fájlra (resource script), ahol definiálhatod a dialog box layoutját (gombok, szövegmezők stb.), majd a DialogBoxParam függvényt használva jelenítheted meg.


// DialogBoxParam függvény hívása
INT_PTR CALLBACK MyDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
            // Dialógus inicializálása
            return TRUE;
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
            }
            break;
    }
    return FALSE;
}

void showMyDialog()
{
    DialogBoxParam(nppData._hInst, MAKEINTRESOURCE(IDD_MY_DIALOG), nppData._nppHandle, MyDialogProc, 0);
}

2. Dokkolható panelek (Dockable Panels)

Ez egy komplexebb téma, de a Notepad++ lehetővé teszi, hogy saját dokkolható ablakokat hozz létre (pl. a „Keresés eredményei” ablakhoz hasonlóan). Ehhez a NPPM_DMMREGASDCKDLG üzenetet kell elküldeni a Notepad++-nak, és be kell állítani egy ablak procedúrát a panelhez.

Fordítás és Tesztelés

A kód elkészítése után jöhet a fordítás és tesztelés.

1. Projekt fordítása

  1. A Visual Studióban válassza a „Build” -> „Build Solution” menüpontot (vagy nyomd meg az F7 billentyűt).
  2. Ha minden rendben van, létrejön a .dll fájl a beállított kimeneti mappában (pl. C:Program FilesNotepad++pluginsMyNppPluginMyNppPlugin.dll).

2. Tesztelés

  1. Győződj meg róla, hogy a Notepad++ be van zárva.
  2. Ha nem állítottad be az automatikus kimeneti mappát, másold be manuálisan a lefordított MyNppPlugin.dll fájlt a Notepad++ plugins mappájába, egy új, saját almappába (pl. C:Program FilesNotepad++pluginsMyNppPluginMyNppPlugin.dll).
  3. Indítsd el a Notepad++-t.
  4. Navigálj a „Beépülő modulok” (Plugins) menüponthoz. Látnod kell a pluginod nevét (pl. „MyNppPlugin”), és alatta a hozzáadott menüparancsokat (pl. „Üdvözlő üzenet”).
  5. Kattints a parancsra, és győződj meg róla, hogy megfelelően működik.

3. Hibakeresés (Debugging)

A hibakeresés Visual Studióval elengedhetetlen a fejlesztés során:

  1. Indítsd el a Notepad++-t.
  2. A Visual Studióban válaszd a „Debug” -> „Attach to Process…” menüpontot.
  3. Keresd meg a notepad++.exe folyamatot, és csatold hozzá a debugger-t.
  4. Mostantól breakpointokat helyezhetsz el a pluginod kódjában, és lépésenként futtathatod azt, miközben a Notepad++-t használod.

Gyakori Hibák és Tippek

  • 32-bit vs. 64-bit: A leggyakoribb hiba. A pluginodnak pontosan meg kell egyeznie a Notepad++ verziójával. Ha 64-bites Notepad++-t használsz, 64-bites DLL-t kell fordítanod.
  • DLL helye: Ne feledd, a Notepad++ 7.6.x verziójától kezdve a pluginoknak saját almappában kell lenniük a plugins könyvtárban!
  • Linker hibák: Győződj meg róla, hogy minden szükséges .lib fájl (pl. SciLexer.lib) hozzá van adva a linker beállításaihoz.
  • Memória kezelés: Légy óvatos a memória foglalásával és felszabadításával. Használj new/delete párokat, és szabadítsd fel az erőforrásokat a NPPN_SHUTDOWN eseményben.
  • Unicode: Mindig Unicode-ot használj (TCHAR, _tcsncpy_s, TEXT() makrók), mivel a modern Notepad++ verziók Unicode-ot várnak.
  • Naplózás: Hiba esetén írj ki információkat egy log fájlba (pl. OutputDebugString vagy egyszerű fájlba írás), ha a debugger nem elérhető.
  • Kezdj template-ből: A plugin_template projekt a Notepad++ SDK-ban egy kiváló kiindulópont, minden alapvető beállítással és kódstruktúrával.

További Fejlesztési Lehetőségek

Miután elsajátítottad az alapokat, számos irányba fejlesztheted a pluginodat:

  • Komplex szövegmanipuláció: Regexp alapú keresés és csere, formázás, kódgenerálás.
  • Hálózati kérések: Integráció webes API-kkal, adatok lekérése vagy feltöltése.
  • Fájlrendszer műveletek: Fájlok kezelése, könyvtárak létrehozása.
  • Egyéni szintaxis kiemelés: Bár a Notepad++ rendelkezik felhasználó által definiálható nyelvekkel, C++-ban még részletesebb kiemelést valósíthatsz meg.
  • Git integráció: Egyszerű Git parancsok futtatása a szerkesztőből.

Konklúzió

A saját Notepad++ plugin készítése izgalmas és rendkívül hasznos feladat lehet. Lehetővé teszi, hogy a kedvenc szövegszerkesztődet pontosan a saját igényeidre szabd, automatizáld a munkafolyamataidat, és bővítsd a képességeit. Reméljük, ez a részletes útmutató segített neked elindulni ezen az úton. Ne habozz kísérletezni, olvasd el az SDK dokumentációját, és fedezd fel a Notepad++ plugin fejlesztésben rejlő végtelen lehetőségeket. Sok sikert a kódoláshoz!

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük