Function Completion: cycle through choices
-
I was going to put in a feature request regarding Function Completion autocomplete, but I wanted to make sure it wasn’t just a lack of knowledge on my part (there are many features of Notepad++ that I don’t know about or don’t remember).
Function Completion allowed multiple “overload” variants. I know when it pops down, you can click on the up and down arrows to cycle through those variants:

But is there a keyboard shortcut for that?
In Visual Studio, when there are overloaded functions, I can just hit the up and down arrow keys to cycle through the choices. But in Notepad++, I tried the arrows (plain, and modified with various combos of Alt/Ctrl/Shift) and TAB and PgUp/PgDn, but nothing I tried worked.
I did already check to make sure I hadn’t previously documented that but forgotten about it. And I tried searching the forum, but couldn’t find anything, even thought I thought it had been asked-and-answered before; sometimes my search-fu is weak.
It just seems odd that the word/function-name completion allows arrowing to select, but the function-parameter completion does not.
Does someone know if I’m just missing an obvious (or not-so-obvious) keystroke? Or is this really a feature that requires a mouse to cycle through the options?
If I get confirmation that it’s the latter, I will put in a feature request.
question triggered by a perlmonks post talking about IDE-like features in editors like Notepad++
-
If I’ve done my homework, then completion is invoked by showNextOverload, which in turn is invoked by callTipClick, which in turn is assigned by SCN_CALLTIPCLICK or short, I assume you’re right, no shortcut.
-
Hello, @peterjones, @ekopalypse and All,
Unlike Eko, I basically tried a lot of possible shortcuts, including the
AltandAltGrkeys. Unfortunately , I could not find any :-(( So, your assumption about the lack of shortcut, for that feature, seems correct !BTW, as you did not mention the language used, I immediately supposed that it could be the
Perllanguage. Bingo, I was right about it :-))Best Regards,
guy038
-
@Ekopalypse & @guy038 ,
Thanks for the confirmation. I thought as much, but wanted to make sure.
Issue #11950 created
-
@Ekopalypse said in Function Completion: cycle through choices:
SCN_CALLTIPCLICK
It’s possible I’m completely incorrect, but it seems the SCN_CALLTIPCLICK is generated by the clicking of the arrow keys in the call tip. I think we want a keyboard key or key combo to generate that notification, so a bit backwards.
Would this involve trapping keyboard input (like say the
up/downarrow keys and then checking SCI_CALLTIPACTIVE and ifTRUE, then post aSCN_CALLTIPCLICKnotification?I’m trying to think about how to proof-of-concept this in PythonScript and not grokking where to start from the Scintilla docs - again it seems backwards - the clicking generates the notification and we want a keyboard key to generate the notification - not sure Scintilla supports that?
I do think this is a smashing idea though!
Cheers.
-
No, you are right.
I put the cart before the horse in my description.It should be enough to use a Python script that sends the notification.
Give me a moment. -
from Npp import notepad, editor, editor1, SCINTILLANOTIFICATION import ctypes from ctypes import wintypes # def on_calltip_click(args): # if args['position'] == 1: # print('backward') # elif args['position'] == 2: # print('forward') # editor.callbackSync(on_calltip_click, [SCINTILLANOTIFICATION.CALLTIPCLICK]) class NMHDR(ctypes.Structure): _fields_ = [('hwndFrom', wintypes.HWND), ('idFrom', ctypes.c_size_t), ('code', wintypes.UINT)] def __init__(self, hwnd, id, code): self.hwndFrom = hwnd self.idFrom = id self.code = code Sci_Position = ctypes.c_size_t class SCNOTIFICATION(ctypes.Structure): _fields_ = [('nmhdr', NMHDR), ('position', Sci_Position), ('ch', wintypes.INT), ('modifiers', wintypes.INT), ('modificationType', wintypes.INT), ('text', wintypes.LPCSTR), ('length', Sci_Position), ('linesAdded', Sci_Position), ('message', wintypes.INT), ('wParam', wintypes.WPARAM), ('lParam', wintypes.LPARAM), ('line', Sci_Position), ('foldLevelNow', wintypes.INT), ('foldLevelPrev', wintypes.INT), ('margin', wintypes.INT), ('listType', wintypes.INT), ('x', wintypes.INT), ('y', wintypes.INT), ('token', wintypes.INT), ('annotationLinesAdded', Sci_Position), ('updated', wintypes.INT), ('listCompletionMethod', wintypes.INT)] SendMessage = ctypes.windll.user32.SendMessageW SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM] SendMessage.restype = wintypes.LPARAM nmhdr = NMHDR(editor1.hwnd, 0, SCINTILLANOTIFICATION.CALLTIPCLICK) notification = SCNOTIFICATION() notification.nmhdr = nmhdr notification.position = 2 WM_NOTIFY = 0x4e SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))I have not checked if the fields in the supplied nmhdr structure are really set correctly.
-
@Ekopalypse said in Function Completion: cycle through choices:
SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))
Trying this out, I get an error:
Traceback (most recent call last): File "C:\usr\bin\npp64\plugins\Config\PythonScript\scripts\callTipClick.py", line 67, in <module> SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification)) ctypes.ArgumentError: argument 4: <class 'OverflowError'>: int too long to convertCheers.
-
Fixed (probably should have noted I’m on 64-bit):
SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.c_longlong(ctypes.addressof(notification)))Cheers.
-
@Michael-Vincent said in Function Completion: cycle through choices:
@Michael-Vincent
@Ekopalypse
Fixed (probably should have noted I’m on 64-bit):
@PeterJonesWorks nicely now:
callTipClick.py:from Npp import notepad, editor, editor1, editor2, SCINTILLANOTIFICATION import ctypes from ctypes import wintypes class NMHDR(ctypes.Structure): _fields_ = [('hwndFrom', wintypes.HWND), ('idFrom', ctypes.c_size_t), ('code', wintypes.UINT)] def __init__(self, hwnd, id, code): self.hwndFrom = hwnd self.idFrom = id self.code = code Sci_Position = ctypes.c_size_t class SCNOTIFICATION(ctypes.Structure): _fields_ = [('nmhdr', NMHDR), ('position', Sci_Position), ('ch', wintypes.INT), ('modifiers', wintypes.INT), ('modificationType', wintypes.INT), ('text', wintypes.LPCSTR), ('length', Sci_Position), ('linesAdded', Sci_Position), ('message', wintypes.INT), ('wParam', wintypes.WPARAM), ('lParam', wintypes.LPARAM), ('line', Sci_Position), ('foldLevelNow', wintypes.INT), ('foldLevelPrev', wintypes.INT), ('margin', wintypes.INT), ('listType', wintypes.INT), ('x', wintypes.INT), ('y', wintypes.INT), ('token', wintypes.INT), ('annotationLinesAdded', Sci_Position), ('updated', wintypes.INT), ('listCompletionMethod', wintypes.INT)] if editor.callTipActive(): SendMessage = ctypes.windll.user32.SendMessageW SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM] SendMessage.restype = wintypes.LPARAM hwnd = notepad.getCurrentView() if hwnd == 0: hwnd = editor1.hwnd else: hwnd = editor2.hwnd nmhdr = NMHDR(hwnd, 0, SCINTILLANOTIFICATION.CALLTIPCLICK) notification = SCNOTIFICATION() notification.nmhdr = nmhdr notification.position = 2 WM_NOTIFY = 0x4e SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.c_longlong(ctypes.addressof(notification)))NOTE: This relies in your PythonScript startup having some logic to get the editor1 and 2
HWNDand create those variables I use in the script.Then I just added this to my PythonScript menu and added a shortcut to it. Works like a charm:

Cheers.
-
I am also working with x64 bit.
The problem could be that you already have a SendMessage function declaration somewhere in your used Python script codes, which is defined slightly different.>>> from ctypes import wintypes >>> wintypes.LPARAM <class 'ctypes.c_longlong'>wintypes.LPARAM is already a c_longlong, so this cast would not be necessary, since the whole point of
SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM] SendMessage.restype = wintypes.LPARAMis to give Python the information how to interpret certain variables.
-
@Ekopalypse said in Function Completion: cycle through choices:
The problem could be that you already have a SendMessage function declaration somewhere in your used Python script codes, which is defined slightly different.
Indeed, you are correct, and I’ve fixed it so your original code:
SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))WORKS!
Cheers.
-
@Michael-Vincent said in Function Completion: cycle through choices:
SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]Note this line should be:
SendMessage.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]Note: argtypes
Cheers.
-
@PeterJones said in Function Completion: cycle through choices:
@Ekopalypse & @guy038 ,
Thanks for the confirmation. I thought as much, but wanted to make sure.
Issue #11950 createdPR #12017 created.
Cheers.
-
@Michael-Vincent said in Function Completion: cycle through choices:
PR #12017 created.
Cheers.@PeterJones
@Ekopalypse
@guy038DONE! - via commit 8519003
Cheers.
-
@Michael-Vincent - cool, a nice one, thx.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login