Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Intellisense for AHK commands


  • Please log in to reply
24 replies to this topic
Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004
This enables Intellisense (cmd autocomplete with tooltip) to script editors. Tell me if it needs some ironing out.

SetKeyDelay, 0
SetBatchLines, 5ms
CoordMode, ToolTip, Relative
AutoTrim, Off

;_______________________________________

;    CONFIGURATIONS



; Editor Window Recognition
; (make it blank to make the script seek all windows)

ETitle = TextPad -



;Minimum word length to make a guess

WLen = 3


; Press F4 to complete command
; Escape & Enter clear command


;_______________________________________

;Gets path to AutoHotkey
RegRead, AHKPATH, HKEY_CLASSES_ROOT, AutoHotkeyScript\Shell\Run\Command,
StringGetPos, POS, AHKPATH, \AutoHotkey.exe
StringLeft, AHKPATH, AHKPATH, %POS%
StringReplace, AHKPATH, AHKPATH, ",, A

;reads command syntaxes
Loop, Read, %ahkpath%\Extras\Editors\TextPad\AHKcommands.txt
{
	tosend = %a_loopreadline%

	StringReplace, tosend, tosend, }, +], a
	StringReplace, tosend, tosend, {, +[, a
	StringReplace, tosend, tosend, #, {#}, a
	StringReplace, tosend, tosend, ``n, {enter}, a
	StringReplace, tosend, tosend, ``t, {tab}, a
	StringReplace, tosend, tosend, ``b, {bs}, a

	cmd%a_index% = %toSend%
}

Loop
{
	;Editor window check
	WinGetActiveTitle, ATitle
	IfNotInString, ATitle, %ETitle%
	{
		ToolTip
		Setenv, Word,
		sleep, 500
		Continue
	}
	
	;Get one key at a time
	Input, chr, L1 V, {enter}{F4}{bs}{esc}
	EndKey = %errorlevel%
	
	;Blanks word reserve
	ifequal, EndKey, Endkey:Enter, Setenv, Word,
	ifequal, EndKey, Endkey:Escape, Setenv, Word,
	
	;Backspace clears last letter
	ifequal, EndKey, Endkey:BackSpace, StringTrimRight, Word, Word, 1
	ifnotequal, EndKey, Endkey:BackSpace, Setenv, Word, %word%%chr%
	
	;Wait till minimum letters
	StringLen, len, Word
	IfLess, len, %wlen%
	{
		ToolTip
		Continue
	}
	
	;Match part-word with command
	Num =
	Match =
	Loop
	{
		IfEqual, cmd%a_index%,, Break
		StringLen, len, word
		StringLeft, check, cmd%a_index%, %len%
		IfEqual, word, %check%
		{
			num = %a_index%
			break
		}
	}
	
	;If no match then clear Tip
	IfEqual, Num,
	{
		ToolTip
		Continue
	}
	
	;Show matched command
	StringTrimLeft, match, cmd%num%, 0
	display_y = %A_CaretY%
	display_y -= 20 ; Move tooltip up a little so as not to hide the caret.
	IfNotEqual, Word,,ToolTip, %match%, %A_CaretX%, %display_y%
	
	;Complete command
	IfNotEqual, Word,, IfEqual, EndKey, Endkey:F4
	{
		StringLen, len, Word
		Send, {BS %len%}%match%
		Word =
		ToolTip
	}
}

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Thanks Rajat
I'll develop on your script and it's very good lesson to start getting familiar with the autohotkey way of doing things (i'm coming from AutoIt 3
syntax)

The only problem is that the script seems to only work the first time an occurrence is found. From then on, no more tooltip :( Did it really work for you or it is in a developing state?

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Well, finally I got what was wrong with the script...
I've spent some hours tweaking this and that and the fix was so simple that I'm even ashamed about it :oops:

The failing loop was:

;If no match then clear Tip
   IfEqual, Num,
   {
      ToolTip
;      Return
       Continue                 ; I replaced the Return with a Continue!!!
   }

I must admit that I was lost in loops!

I thought about a missing issue: the script should blank the word if a key is typed in a window other than the original one.
But I first wanted to know why it was not working properly before starting adding more code :)
too late to go on... good night

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004
Jordi, thanx so much for fixing that...i've updated the above script with your change. and yes i think it can be improved in many ways. please let me know in case u find something else needing improvement. :)

I thought about a missing issue: the script should blank the word if a key is typed in a window other than the original one.


yep, that's a nice idea and i guess will be very easy to do... i'll do that soon.

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004
done already! :)

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Hi Rajat,
A couple of things:

1) About your implementation of my suggestion:

the script should blank the word if a key is typed in a window other than the original one.

It didn't really work for me...
I made it work like this:
In the " ;Editor window check" section, I added the line
WinGet, A_id, ID, %ATitle%
to get the exact ID of the window before starting the loop.
Then, after the "Input" command, I added:
; If active window has different window ID from before the input, blank word (well, assign the last typed char to word)
   WinGetActiveTitle, ATitle
   WinGet, A_id2, ID, %ATitle%
   IfNotEqual, A_id, %A_id2%
   {
      ToolTip
      Setenv, Word, %chr%
      Continue
   }
This works for me :)

2) I added a Settimer function to continuously check the active window. In case the active window is changed, I don't want the tooltip to appear (since in your original script, once the tooltip was appearing, it remained displayed even when you switched windows). Here it goes:
Before the main Loop starts:
SetTimer, Winchanged, 100
Then, at the very end of the script:
; Timed function to detect change of focus (and remove tooltip when changing active window)
Winchanged:
   WinGetActiveTitle, ATitle
   WinGet, A_id3, ID, %ATitle%
   IfNotEqual, A_id, %A_id3%
   {
      ToolTip
   }
return

3) I temporarly added {space} as an EndKey in the Input command, and added
ifequal, EndKey, Endkey:Space, Setenv, Word,
to blank the word. Why? I explain it in an example: Let's say I have "system" in the wordlist:
- If I type "sys" the script will work ok and provide a suggestion.
- BUT, if I type "the sys", the script was not providing any suggestion.
This may be caused by you and me having different aims for the script: I guess you intended it as a help when typing commands (so you normally don't type anything before the actual command). But I want it as an aid for normal writing, so the script should detect a match regardless of the previously typed characters. Adding {space} as an Endkey does the trick at the moment, but the downside is that in multi-word matches, the tooltip will disappear when space is pressed (well, the user still had the chance to use the suggestion, so it's not a big deal at the moment)

4) I noticed that, in the current state of the script, a match will be found when the last 3 characters match a word regardless of what position of these 3 characters in the matchword. For example: We have "system" in the wordlist:
- Typing "sys" will provide "system" as a suggestion
- Typing "yst" will also provide "system" as a suggestion
- Typing "tem" will also provide "system" as a suggestion, etc.
Probably you wanted it this way for your purposes, but in my implementation, it should always suggest a match only when the start of the word matches the typed characters... I didn't have time to dig into this, but I just wanted to report it...

5) Finally, I would like the script to override the key used for autocomplete (F4 in your script). In the applications I was trying the script, F4 have a function assigned: In Word, i'ts the "Repeat" command; in UltraEdit, F4 switches to the "Open files" sidebar. I though autohotkey had priority over applications, but it looks like it doesn't. I read the appropiate section in the helpfile (Overriding or Disabling Hotkeys) but it looks like I'm not getting it completely right... Probably something like F4::somecommand before the loop? I tried return, sleep with no success... Workaround would be using another autocomplete key or unassigning such key in the target application, so it's not a big deal, but I was just wondering...

Wow long one! we're getting there, little by little :)

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004

About your implementation of my suggestion:
Quote:
the script should blank the word if a key is typed in a window other than the original one.

It didn't really work for me...

i made it differentiate b/w editor windows and other windows...and not b/w diff editor windows. but yours will do that to. i guess that's better.

I guess you intended it as a help when typing commands (so you normally don't type anything before the actual command)

yes that's what i aimed for... just a matter of preference.

noticed that, in the current state of the script, a match will be found when the last 3 characters match a word regardless of what position of these 3 characters in the matchword. For example: We have "system" in the wordlist:
- Typing "sys" will provide "system" as a suggestion
- Typing "yst" will also provide "system" as a suggestion
- Typing "tem" will also provide "system" as a suggestion, etc.
Probably you wanted it this way for your purposes, but in my implementation, it should always suggest a match only when the start of the word matches the typed characters... I didn't have time to dig into this, but I just wanted to report it...

actually earlier i did it as u suggest now. but then as some cmds have same start chars so i thought one can press any unique chars and get the right tip.

what u want can be easily done by:
get stringlen of %word% in %chars%
then stringleft of cmd%a_index% for %chars% characters
and then finally instead of ifinstring use ifequal to find a match.

and the F4 thing?! :) u can easily put ANYTHING in place of it !!

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

In the applications I was trying the script, F4 have a function assigned: In Word, i'ts the "Repeat" command; in UltraEdit, F4 switches to the "Open files" sidebar. I though autohotkey had priority over applications, but it looks like it doesn't.

AHK is able to override the hotkeys of most other applications. For example, I tried a script with the below single line in it, opened MS Word, then pressed F7. A MsgBox appeared, not Word's spellcheck:
f7::msgbox

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Chris,

AHK is able to override the hotkeys of most other applications. For example, I tried a script with the below single line in it, opened MS Word, then pressed F7. A MsgBox appeared, not Word's spellcheck:
f7::msgbox


I am aware of this feature, but the thing is I don't want anything (or any command) to be associated with that hotkey (like a msgbox in your example). In the above script, F4 is just an EndKey defined for an Input and I don't want the active application to get it... it would be like dummy command:
f4::
As Rajat says, this can be changed to anything (actually for my purposes F4 will not be the autocomplete key, but it's ok for testing purposes)...

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Rajat,

what u want can be easily done by:
get stringlen of %word% in %chars%
then stringleft of cmd%a_index% for %chars% characters
and then finally instead of ifinstring use ifequal to find a match.


I followed your directions and I got it, although not as simplified as you put it, but it does the trick. The " ;Match part-word with command " loop would be modified like this:
;Match part-word with command
   Num =
   Match =
   Loop
   {
      IfEqual, cmd%a_index%,, Break
      StringLen, chars, Word                         ;added
      StringLeft, strippedcmd, cmd%a_index%, %chars% ;added
      StringLeft, strippedword, Word, %chars%        ;added
      ifequal, strippedcmd, %strippedword%           ;added 
      {
         num = %a_index%
         break
      }
   }

Since obviously you and me are looking for very similar features in the script (i.e. autocomplete) but for rather different purposes (i.e. you: programming aid; me: normal typing aid), I wonder whether to post your script with the modifications I implemented in another Thread, since the variations I make will probably not fit your purposes (as you already mentioned in previous posts). The above modification for example, it's not useful for your script but it is vital for mine...
Anyway, we'll see... :)

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004

I wonder whether to post your script with the modifications I implemented in another Thread

post it anywhere u please :)

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

f4::

To make a hotkey do nothing, and thus prevent the active window from seeing it:
F4::return

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Chris
I tried that one, but it doesn't work...
It looks like the script does go further than the Return...

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I tried this simple script and it works okay. Perhaps you can revise it to clarify and demonstrate the problem:

input, out, v, {f4}
msgbox %out%
return

f4::return
msgbox This MsgBox is never executed.

On a related note, I've added an item to the to-do list to optionally suppress end-keys so that the active window doesn't see them.

jordis
  • Members
  • 81 posts
  • Last active: Aug 22 2014 01:56 PM
  • Joined: 30 Jul 2004
Chris,
Ok I got it.... I had to add it at the very end of the script, and not in the beginning as I was trying it :roll: Looks like specifying it at the beginning made the script keep waiting in the return command
Thanks again for your enlightment :)
Related to this:
Is it possible to do something like:
completekey = F4
%completekey%::return

What about:
completekey = {F4}
input, out, v, %completekey%

If not, take it as a feature suggestion :)