Community
    • Login

    Function Completion: cycle through choices

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    autocompletefunction hint
    16 Posts 4 Posters 1.0k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • PeterJonesP
      PeterJones @guy038
      last edited by

      @Ekopalypse & @guy038 ,

      Thanks for the confirmation. I thought as much, but wanted to make sure.

      Issue #11950 created

      Michael VincentM 1 Reply Last reply Reply Quote 1
      • Michael VincentM
        Michael Vincent @Ekopalypse
        last edited by

        @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 / down arrow keys and then checking SCI_CALLTIPACTIVE and if TRUE, then post a SCN_CALLTIPCLICK notification?

        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.

        EkopalypseE 2 Replies Last reply Reply Quote 1
        • EkopalypseE
          Ekopalypse @Michael Vincent
          last edited by

          @Michael-Vincent

          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.

          1 Reply Last reply Reply Quote 1
          • EkopalypseE
            Ekopalypse @Michael Vincent
            last edited by Ekopalypse

            @Michael-Vincent

            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.

            Michael VincentM 1 Reply Last reply Reply Quote 2
            • Michael VincentM
              Michael Vincent @Ekopalypse
              last edited by

              @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 convert
              

              Cheers.

              Michael VincentM 1 Reply Last reply Reply Quote 0
              • Michael VincentM
                Michael Vincent @Michael Vincent
                last edited by

                @Michael-Vincent
                @Ekopalypse

                Fixed (probably should have noted I’m on 64-bit):

                SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.c_longlong(ctypes.addressof(notification)))
                

                Cheers.

                Michael VincentM 1 Reply Last reply Reply Quote 1
                • Michael VincentM
                  Michael Vincent @Michael Vincent
                  last edited by

                  @Michael-Vincent said in Function Completion: cycle through choices:

                  @Michael-Vincent
                  @Ekopalypse
                  Fixed (probably should have noted I’m on 64-bit):
                  @PeterJones

                  Works 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 HWND and 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:

                  2d96ab2c-905a-4950-8392-42959a3e4c78-image.png

                  Cheers.

                  EkopalypseE Michael VincentM 2 Replies Last reply Reply Quote 2
                  • EkopalypseE
                    Ekopalypse @Michael Vincent
                    last edited by

                    @Michael-Vincent

                    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.LPARAM
                    

                    is to give Python the information how to interpret certain variables.

                    Michael VincentM 1 Reply Last reply Reply Quote 3
                    • Michael VincentM
                      Michael Vincent @Ekopalypse
                      last edited by

                      @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.

                      1 Reply Last reply Reply Quote 1
                      • Michael VincentM
                        Michael Vincent @Michael Vincent
                        last edited by

                        @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.

                        1 Reply Last reply Reply Quote 2
                        • Michael VincentM
                          Michael Vincent @PeterJones
                          last edited by

                          @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 created

                          PR #12017 created.

                          Cheers.

                          Michael VincentM 1 Reply Last reply Reply Quote 1
                          • Michael VincentM
                            Michael Vincent @Michael Vincent
                            last edited by

                            @Michael-Vincent said in Function Completion: cycle through choices:

                            PR #12017 created.
                            Cheers.

                            @PeterJones
                            @Ekopalypse
                            @guy038

                            DONE! - via commit 8519003

                            Cheers.

                            EkopalypseE 1 Reply Last reply Reply Quote 2
                            • EkopalypseE
                              Ekopalypse @Michael Vincent
                              last edited by

                              @Michael-Vincent - cool, a nice one, thx.

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              The Community of users of the Notepad++ text editor.
                              Powered by NodeBB | Contributors