Skip to content

Commit

Permalink
Add support for any keyboard layout.
Browse files Browse the repository at this point in the history
Closes #1, Closes #2, Closes #3, Closes #5
  • Loading branch information
Microeinstein authored and dail8859 committed Feb 2, 2019
1 parent 10f1a37 commit 3ebe29d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 49 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

Notepad++ plugin to automatically surround the selection in quotes/brackets/parenthesis/etc. This can also be used on multiple or rectangular selections.

**Note:** This is still in early development. It has not been fully tested with non-US keyboard layouts.

![Demo](/img/Demo.gif)

## Usage
Select some text and type one of the following characters:
- `'`
- `"`
- `` ` ``
- `(` or `)`
- `{` or `}`
- `[` or `]`
- `{` or `}`
- `<` or `>`

## Installation
Install the plugin by downloading it from the [Release](https://github.com/dail8859/SurroundSelection/releases) page and copy `SurroundSelection.dll` to your `plugins` folder.
Expand Down
88 changes: 46 additions & 42 deletions src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@
#include <algorithm>
#include <vector>

#define buffChars 1

static HANDLE _hModule;
static NppData nppData;
static HHOOK hook = NULL;
static HKL keyboardLayout = NULL;
static bool hasFocus = true;
static ScintillaGateway editor;
static LPWORD kbBuff = (LPWORD)new byte[buffChars];
static PBYTE kbState = new byte[256];

static void enableSurroundSelection();
static void showAbout();
Expand All @@ -52,6 +57,10 @@ const wchar_t *GetIniFilePath() {
return iniPath;
}

static void updateKL() {
keyboardLayout = GetKeyboardLayout(0);
}

static void enableSurroundSelection() {
if (hook) {
UnhookWindowsHookEx(hook);
Expand Down Expand Up @@ -117,49 +126,41 @@ static void SurroundSelectionsWith(char ch1, char ch2) {
}

LRESULT CALLBACK KeyboardProc(int ncode, WPARAM wparam, LPARAM lparam) {
if (ncode == HC_ACTION) {
if ((HIWORD(lparam) & KF_UP) == 0) {
if (hasFocus && !(GetKeyState(VK_CONTROL) & KF_UP) && !(GetKeyState(VK_MENU) & KF_UP)) {
char ch1 = 0, ch2 = 0;

if (wparam == VK_OEM_7) {
if (GetKeyState(VK_SHIFT) & KF_UP) {
ch1 = ch2 = '"';
}
else {
ch1 = ch2 = '\'';
}
}
else if (wparam == VK_OEM_4 || wparam == VK_OEM_6) {
if (GetKeyState(VK_SHIFT) & KF_UP) {
ch1 = '{';
ch2 = '}';
}
else {
ch1 = '[';
ch2 = ']';
}
}
else if (wparam == 0x39 || wparam == 0x30) {
if (GetKeyState(VK_SHIFT) & KF_UP) {
ch1 = '(';
ch2 = ')';
}
}
//else if (wparam == VK_OEM_COMMA) {
// if (GetKeyState(VK_SHIFT) & KF_UP) {
// ch1 = '<';
// ch2 = '>';
// }
//}

if (ch1 != 0 && editor.GetSelectionEmpty() == 0) {
SurroundSelectionsWith(ch1, ch2);
return TRUE; // This key has been "handled" and won't propogate
}
}
}
if (ncode != HC_ACTION)
goto proceed;
if ((HIWORD(lparam) & KF_UP) != 0 || !hasFocus)
goto proceed;

char ch1 = 0, ch2 = 0;
UINT scanCode = (lparam >> 16) & 0xFF;
//Get full keyboard state
if (!GetKeyboardState(kbState))
goto proceed;
//Translate state, pressed key and keyboard layout in the respective characters
int amount = ToAsciiEx((UINT)wparam, scanCode, kbState, kbBuff, 0, keyboardLayout);
if (amount < 1)
goto proceed;

//Get first translated character
char ch = (char)kbBuff[0];
if (ch == '"' || ch == '\'' || ch == '`') {
ch1 = ch2 = (char)ch;
} else if (ch == '(' || ch == ')') {
ch1 = '('; ch2 = ')';
} else if (ch == '[' || ch == ']') {
ch1 = '['; ch2 = ']';
} else if (ch == '{' || ch == '}') {
ch1 = '{'; ch2 = '}';
} else if (ch == '<' || ch == '>') {
ch1 = '<'; ch2 = '>';
}

if (ch1 != 0 && editor.GetSelectionEmpty() == 0) {
SurroundSelectionsWith(ch1, ch2);
return TRUE; // This key has been "handled" and won't propogate
}

proceed:
return CallNextHookEx(hook, ncode, wparam, lparam); //pass control to next hook in the hook chain.
}

Expand All @@ -168,6 +169,7 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD reasonForCall, LPVOID lpReserved) {
switch (reasonForCall) {
case DLL_PROCESS_ATTACH:
_hModule = hModule;
updateKL();
break;
case DLL_PROCESS_DETACH:
break;
Expand Down Expand Up @@ -224,6 +226,8 @@ extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode) {
}

extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam) {
if (Message == WM_INPUTLANGCHANGE)
updateKL();
return TRUE;
}

Expand Down
8 changes: 4 additions & 4 deletions src/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#define VERSION_NUM 1,1,0,0
#define VERSION_LINEAR 1100
#define VERSION_LINEAR_TEXT TEXT("1100")
#define VERSION_TEXT TEXT("1.1") // This must match the tag pushed on the server minus the "v"
#define VERSION_NUM 1,2,0,0
#define VERSION_LINEAR 1200
#define VERSION_LINEAR_TEXT TEXT("1200")
#define VERSION_TEXT TEXT("1.2") // This must match the tag pushed on the server minus the "v"
#define VERSION_STAGE TEXT("") // "alpha", "beta", ""

0 comments on commit 3ebe29d

Please sign in to comment.