Is there a way to make an autohotkey copy-paste that works exactly like the native one between machines? - expression

Ive been using autohotkey to automate work things and I can't figure out something that seems like it should be simple.
Basically, I need to copy and paste things between my physical machine and my vmware machine at work.
There is no shared clipboard options apparently so I tried making a code to do it for me in autohotkey since there are shared drives between machines.
I found a code that does that (can't for the life of me find out where from) and modified it a little and it works, except that if I right click copy or some 3rd party program copies to my clipboard I can now no longer use those with ctrl v.
I could just make a new hotkey specifically for copying between machines, but I prefer something that I can just make, create a shortcut in startup, and forget about because I want to share it with coworkers.
Is there logic I can set up so that it this will function exactly the same as normal copy/paste and share between machines?
Thanks for any help.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
$^c::
{
Send, ^c
sleep, 5
FileAppend, %ClipboardAll%, ClipBoard.clip
}
return
$^v::
{
FileRead, Clipboard, *c Clipboard.clip ; Note the use of *c, which must precede the filename.
sleep,5
Send,^v
}
Return
$^+v::
{
Send, ^v
}
return
I also tried the below code, but apparently an image in the clipboard makes|| if (ClipBoard="") || a true statement?. Also apparently Clipboardall is always true in the same situation (maybe because of font somehow)
$^c::
{
Send, ^c
sleep, 5
FileAppend, %ClipboardAll%, ClipBoard.clip
ClipBoard:=
}
return
$^v::
{
if (ClipBoard="")
FileRead, Clipboard, *c Clipboard.clip ; Note the use of *c, which must precede the filename.
sleep,5
Send,^v
}
Return
$^+v::
{
Send, ^v
}
return

Related

AutoHotKey Hotstring Won't Trigger in gvim on Windows or vim in WSL Ubuntu

I use AHK to autoconvert a string like ]dd to the current date (see code below). When using this in most Windows text editors/areas, it works fine. But when I'm using gvim for Windows or vim in Ubuntu on WSL, I often have to type a "priming" character or try the hotstring a couple times for it to work. Searching the forum didn't return any hits on this particular issue.
#NoEnv ; Recommended for performance and compatibility with future
AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; This allows me to quickly enter date and time stamps.
::]dd::
FormatTime, TimeString, , yyMMdd ; LongDate
Send, %TimeString%
Return
:*:]t::
FormatTime, TimeString, , HHmm
Send, %TimeString%
Return
:*:]dt::
FormatTime, TimeString, , yyMMdd HHmm
Send, %TimeString%
Return
These work practically flawlessly in Notepad or other modeless text editors/areas I've used, but I really enjoy vim.
I'm guessing AHK is keying off of the space character and not CR/LF, so entering insert mode in a vim-mode editor (including the likes of PyCharm using the IdeaVim plugin) and hitting Enter doesn't let AHK know to start looking for muh hawtstrangs. I have to hit Space, and sometimes hit it a few times, to get the hotstring to be recognized.
I suppose I could just create hotkeys instead but I use this approach in Keyboard Maestro on macOS and keyboard settings in *NIXes and I value the muscle memory.
Is there a configuration somewhere that I'm overlooking, or is this just an edge case?
To make it work reliably and consistently in Vim, in the hotstring option, include both question mark and asterisk (:*?:...) instead of just asterisk or empty option. This workaround is only thing that worked for me on Vim on Windows. Otherwise, Autohotkey would not expand when it enters the insert-mode for the first time.
So, it might look like:
...
:*?:]dd::
FormatTime, TimeString, , yyMMdd ; LongDate
Send, %TimeString%
Return
:*?:]t::
FormatTime, TimeString, , HHmm
Send, %TimeString%
Return
:*?:]dt::
FormatTime, TimeString, , yyMMdd HHmm
Send, %TimeString%
Return
However, this will change the behavior slightly since it will trigger the hotstring inside a word, so Hello]dd will trigger ]dd. But I could live with this and avoid the frustration of always checking if it triggered the hotstring or not.
Alternatively, in order to perfectly match the initial behavior, I'd recreate the text expansion in vim using UltiSnips plugin, but that'd be a little more work than necessary.

Is there a blocking version of "Sleep"? (ahk)

I have a hotkey that I press repeatedly quite fast and I included a Sleep in the routine to throttle it a bit. But when I go at faster speeds the output starts to mess up. The culprit is definitely the sleep because when I take it out and let it go as fast as it wants, the output is fine. I know Sleep allows for new processes to start while it's waiting, and so I'm thinking having all these new processes of the same hotkey going on top of each other is what's causing to the errors. So I'm wondering if there's a variation on the sleep function that blocks new processes while it's waiting? I couldn't find anything like it in the docs or google.
In C++ you would use mutexes in this case. In AHK you have to work around that and there are multiple ways to do it.
One way would be to disable the hotkeys while any hotkey is doing an action. For that you can use a simple variable.
Example:
#If !mutex_locked
F2::
mutex_locked := True
Send, letters incomming...
Sleep, 500
Send, abcdefghijklmnopqrstuvwxyz
mutex_locked := False
Return
F3::
mutex_locked := True
Send, numbers incomming...
Sleep, 500
Send, 1234567890
mutex_locked := False
Return
#If
While the variable named mutex_locked is set to false, the hotkeys are disabled. As soon as they finish, they set the variable to true again.
I like Forivin's code/answer above, but I think the below is also relevant.
From the AHK reference: ( https://autohotkey.com/docs/misc/Threads.htm )
"By default, a given hotkey or hotstring subroutine cannot be run a second time if it is already running. Use #MaxThreadsPerHotkey to change this behavior."
Info on #MaxThreadsPerHotkey is located at: ( https://autohotkey.com/docs/commands/_MaxThreadsPerHotkey.htm )
Perhaps allowing the same hotkey to run concurrently with itself in different threads (by increasing #MaxThreadsPerHotkey) would bypass the problem? Just a guess... feel free to confirm or correct this notion.

Autohotkey: howto clear most Fnn hotkeys assigned by windows?

I wanted to program some of the Fnn and shift-Fnn keys, and clear the rest of them from what windows had assigned them. Just long enough to run a telnet or putty session, then I want to let them revert back to win std. I used a script in AutoHotkey, and it works mostly, but I assigned the many unused keys to be SHIFT keys, and now the shift-F4 often burps out the unshifted F4 string {over half the time I hit it.} Is there some better way to nuke the windows presets than just slapping SHIFT on all those keys, or is there some obscure tweak I can make to the script to lighten the load on the SHIFT kbd hook?
Script follows; note there's lotsa trailing spaces on most lines, if it matters...
Tested on a win8 laptop and an XP tabletop, same results.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
;SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetWorkingDir C:\bin ; Ensures a consistent starting directory.
F1::send, EX`r
F2::Shift
F3::Shift
F4::send, FI`r
F5::Shift
F6::Shift
F7::Shift
F8::Shift
F9::send, OFF`r
F10::send, PROD
F11::send, `r
F12::send, END`r
+F1::send, FD
+F2::Shift
+F3::Shift
+F4::send, EM5
+F5::Shift
+F6::Shift
+F7::Shift
+F8::Shift
+F9::send, `r
+F10::send, PYR`r
+F11::send, SYSP
+F12::Shift
^F12::ExitApp ; control-F12 will remove all these
$~CapsLock Up::SetCapsLockState Off ; regress capslock to a SHIFT
Having tried a similar thing to "disable" Windows hold on the WIN key, I found that there wasn't a way to disable all of them - only a few.
However, Autohotkey can override windows hotkeys, as you've found.
If you just want to disable Windows' use of those keys (if I'm understanding you correctly), you could try something like this:
F11::
F12::
return
That would effectively disable the use of F11 and F12 anywhere as long as the script was running.
(no, trailing spaces don't make any difference)

Self-restarting MathKernel - is it possible in Mathematica?

This question comes from the recent question "Correct way to cap Mathematica memory use?"
I wonder, is it possible to programmatically restart MathKernel keeping the current FrontEnd process connected to new MathKernel process and evaluating some code in new MathKernel session? I mean a "transparent" restart which allows a user to continue working with the FrontEnd while having new fresh MathKernel process with some code from the previous kernel evaluated/evaluating in it?
The motivation for the question is to have a way to automatize restarting of MathKernel when it takes too much memory without breaking the computation. In other words, the computation should be automatically continued in new MathKernel process without interaction with the user (but keeping the ability for user to interact with the Mathematica as it was originally). The details on what code should be evaluated in new kernel are of course specific for each computational task. I am looking for a general solution how to automatically continue the computation.
From a comment by Arnoud Buzing yesterday, on Stack Exchange Mathematica chat, quoting entirely:
In a notebook, if you have multiple cells you can put Quit in a cell by itself and set this option:
SetOptions[$FrontEnd, "ClearEvaluationQueueOnKernelQuit" -> False]
Then if you have a cell above it and below it and select all three and evaluate, the kernel will Quit but the frontend evaluation queue will continue (and restart the kernel for the last cell).
-- Arnoud Buzing
The following approach runs one kernel to open a front-end with its own kernel, which is then closed and reopened, renewing the second kernel.
This file is the MathKernel input, C:\Temp\test4.m
Needs["JLink`"];
$FrontEndLaunchCommand="Mathematica.exe";
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
SelectionMove[nb, Next, Cell];
SelectionEvaluate[nb];
];
Pause[8];
CloseFrontEnd[];
Pause[1];
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
Do[SelectionMove[nb, Next, Cell],{12}];
SelectionEvaluate[nb];
];
Pause[8];
CloseFrontEnd[];
Print["Completed"]
The demo notebook, C:\Temp\run.nb contains two cells:
x1 = 0;
Module[{},
While[x1 < 1000000,
If[Mod[x1, 100000] == 0, Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]]]
Print[x1]
x1 = 0;
Module[{},
While[x1 < 1000000,
If[Mod[x1, 100000] == 0, Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]]]
The initial kernel opens a front-end and runs the first cell, then it quits the front-end, reopens it and runs the second cell.
The whole thing can be run either by pasting (in one go) the MathKernel input into a kernel session, or it can be run from a batch file, e.g. C:\Temp\RunTest2.bat
#echo off
setlocal
PATH = C:\Program Files\Wolfram Research\Mathematica\8.0\;%PATH%
echo Launching MathKernel %TIME%
start MathKernel -noprompt -initfile "C:\Temp\test4.m"
ping localhost -n 30 > nul
echo Terminating MathKernel %TIME%
taskkill /F /FI "IMAGENAME eq MathKernel.exe" > nul
endlocal
It's a little elaborate to set up, and in its current form it depends on knowing how long to wait before closing and restarting the second kernel.
Perhaps the parallel computation machinery could be used for this? Here is a crude set-up that illustrates the idea:
Needs["SubKernels`LocalKernels`"]
doSomeWork[input_] := {$KernelID, Length[input], RandomReal[]}
getTheJobDone[] :=
Module[{subkernel, initsub, resultSoFar = {}}
, initsub[] :=
( subkernel = LaunchKernels[LocalMachine[1]]
; DistributeDefinitions["Global`"]
)
; initsub[]
; While[Length[resultSoFar] < 1000
, DistributeDefinitions[resultSoFar]
; Quiet[ParallelEvaluate[doSomeWork[resultSoFar], subkernel]] /.
{ $Failed :> (Print#"Ouch!"; initsub[])
, r_ :> AppendTo[resultSoFar, r]
}
]
; CloseKernels[subkernel]
; resultSoFar
]
This is an over-elaborate setup to generate a list of 1,000 triples of numbers. getTheJobDone runs a loop that continues until the result list contains the desired number of elements. Each iteration of the loop is evaluated in a subkernel. If the subkernel evaluation fails, the subkernel is relaunched. Otherwise, its return value is added to the result list.
To try this out, evaluate:
getTheJobDone[]
To demonstrate the recovery mechanism, open the Parallel Kernel Status window and kill the subkernel from time-to-time. getTheJobDone will feel the pain and print Ouch! whenever the subkernel dies. However, the overall job continues and the final result is returned.
The error-handling here is very crude and would likely need to be bolstered in a real application. Also, I have not investigated whether really serious error conditions in the subkernels (like running out of memory) would have an adverse effect on the main kernel. If so, then perhaps subkernels could kill themselves if MemoryInUse[] exceeded a predetermined threshold.
Update - Isolating the Main Kernel From Subkernel Crashes
While playing around with this framework, I discovered that any use of shared variables between the main kernel and subkernel rendered Mathematica unstable should the subkernel crash. This includes the use of DistributeDefinitions[resultSoFar] as shown above, and also explicit shared variables using SetSharedVariable.
To work around this problem, I transmitted the resultSoFar through a file. This eliminated the synchronization between the two kernels with the net result that the main kernel remained blissfully unaware of a subkernel crash. It also had the nice side-effect of retaining the intermediate results in the event of a main kernel crash as well. Of course, it also makes the subkernel calls quite a bit slower. But that might not be a problem if each call to the subkernel performs a significant amount of work.
Here are the revised definitions:
Needs["SubKernels`LocalKernels`"]
doSomeWork[] := {$KernelID, Length[Get[$resultFile]], RandomReal[]}
$resultFile = "/some/place/results.dat";
getTheJobDone[] :=
Module[{subkernel, initsub, resultSoFar = {}}
, initsub[] :=
( subkernel = LaunchKernels[LocalMachine[1]]
; DistributeDefinitions["Global`"]
)
; initsub[]
; While[Length[resultSoFar] < 1000
, Put[resultSoFar, $resultFile]
; Quiet[ParallelEvaluate[doSomeWork[], subkernel]] /.
{ $Failed :> (Print#"Ouch!"; CloseKernels[subkernel]; initsub[])
, r_ :> AppendTo[resultSoFar, r]
}
]
; CloseKernels[subkernel]
; resultSoFar
]
I have a similar requirement when I run a CUDAFunction for a long loop and CUDALink ran out of memory (similar here: https://mathematica.stackexchange.com/questions/31412/cudalink-ran-out-of-available-memory). There's no improvement on the memory leak even with the latest Mathematica 10.4 version. I figure out a workaround here and hope that you may find it's useful. The idea is that you use a bash script to call a Mathematica program (run in batch mode) multiple times with passing parameters from the bash script. Here is the detail instruction and demo (This is for Window OS):
To use bash-script in Win_OS you need to install cygwin (https://cygwin.com/install.html).
Convert your mathematica notebook to package (.m) to be able to use in script mode. If you save your notebook using "Save as.." all the command will be converted to comments (this was noted by Wolfram Research), so it's better that you create a package (File->New-Package), then copy and paste your commands to that.
Write the bash script using Vi editor (instead of Notepad or gedit for window) to avoid the problem of "\r" (http://www.linuxquestions.org/questions/programming-9/shell-scripts-in-windows-cygwin-607659/).
Here is a demo of the test.m file
str=$CommandLine;
len=Length[str];
Do[
If[str[[i]]=="-start",
start=ToExpression[str[[i+1]]];
Pause[start];
Print["Done in ",start," second"];
];
,{i,2,len-1}];
This mathematica code read the parameter from a commandline and use it for calculation.
Here is the bash script (script.sh) to run test.m many times with different parameters.
#c:\cygwin64\bin\bash
for ((i=2;i<10;i+=2))
do
math -script test.m -start $i
done
In the cygwin terminal type "chmod a+x script.sh" to enable the script then you can run it by typing "./script.sh".
You can programmatically terminate the kernel using Exit[]. The front end (notebook) will automatically start a new kernel when you next try to evaluate an expression.
Preserving "some code from the previous kernel" is going to be more difficult. You have to decide what you want to preserve. If you think you want to preserve everything, then there's no point in restarting the kernel. If you know what definitions you want to save, you can use DumpSave to write them to a file before terminating the kernel, and then use << to load that file into the new kernel.
On the other hand, if you know what definitions are taking up too much memory, you can use Unset, Clear, ClearAll, or Remove to remove those definitions. You can also set $HistoryLength to something smaller than Infinity (the default) if that's where your memory is going.
Sounds like a job for CleanSlate.
<< Utilities`CleanSlate`;
CleanSlate[]
From: http://library.wolfram.com/infocenter/TechNotes/4718/
"CleanSlate, tries to do everything possible to return the kernel to the state it was in when the CleanSlate.m package was initially loaded."

How can I increase the key repeat rate beyond the OS's limit?

I have a bad habit of using the cursor keys of my keyboard to navigate source code. It's something I've done for 15 years and this of course means that my navigating speed is limited by the speed of the keyboard. On both Vista and OS X (I dual boot a MacBook), I have my key repeat rate turned all the way up. But in Visual Studio, and other apps, the rate is still much slower than I would prefer.
How can I make the key repeat rate faster in Visual Studio and other text editors?
In Windows you can set this with a system call (SystemParametersInfo(SPI_SETFILTERKEYS,...)).
I wrote a utility for myself: keyrate <delay> <repeat>.
Github repository.
Full source in case that link goes away:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
BOOL parseDword(const char* in, DWORD* out)
{
char* end;
long result = strtol(in, &end, 10);
BOOL success = (errno == 0 && end != in);
if (success)
{
*out = result;
}
return success;
}
int main(int argc, char* argv[])
{
FILTERKEYS keys = { sizeof(FILTERKEYS) };
if (argc == 1)
{
puts ("No parameters given: disabling.");
}
else if (argc != 3)
{
puts ("Usage: keyrate <delay ms> <repeat ms>\nCall with no parameters to disable.");
return 0;
}
else if (parseDword(argv[1], &keys.iDelayMSec)
&& parseDword(argv[2], &keys.iRepeatMSec))
{
printf("Setting keyrate: delay: %d, rate: %d\n", (int) keys.iDelayMSec, (int) keys.iRepeatMSec);
keys.dwFlags = FKF_FILTERKEYSON|FKF_AVAILABLE;
}
if (!SystemParametersInfo (SPI_SETFILTERKEYS, 0, (LPVOID) &keys, 0))
{
fprintf (stderr, "System call failed.\nUnable to set keyrate.");
}
return 0;
}
On Mac OS X, open the Global Preferences plist
open ~/Library/Preferences/.GlobalPreferences.plist
Then change the KeyRepeat field. Smaller numbers will speed up your cursor rate. The settings dialog will only set it to a minimum of 2, so if you go to 0 or 1, you'll get a faster cursor.
I had to reboot for this to take effect.
Many times I want to center a function in my window. Scrolling is the only way.
Also, Ctrl-left/right can still be slow in code where there are a lot of non-word characters.
I use keyboardking also. It has a couple of isssues for me though. One, it sometimes uses the default speed instead of the actual value I set. The other is sometimes it ignores the initial delay. I still find it very useful though. They said 4 years ago they would release the source in 6 months... :(
Ok, on the suggestion of someone that modified HCU\...\Keyboard Response, this works well for me.
[HKEY_CURRENT_USER\Control Panel\Accessibility\Keyboard Response]
"AutoRepeatDelay"="250"
"AutoRepeatRate"="13"
"BounceTime"="0"
"DelayBeforeAcceptance"="0"
"Flags"="59"
Windows standard AutoRepeat delay.
13 ms (77 char/sec) repeat rate.
flags turns on FilterKeys?
These values are read at login. Remember to log out and back in for this to take effect.
For Windows, open regedit.exe and navigate to HKEY_CURRENT_USER\Control Panel\Keyboard. Change KeyboardSpeed to your liking.
I'm using KeyboardKing on my PC. It's freeware and it can increase the repeat rate up to 200 which is quite enough. I recommend to set the process priority to High for even smoother moves and less "repeat locks" which happen sometime and are very annoying. With high priority, it works perfectly.
No one understands why we navigate by arrows. It's funny.
Visual Assist has an option to double your effective key movements in Visual Studio which I use all the time.
As mentioned by the hyperlogic, on Mac OS X, internally, there are two parameters dealing with the keyboard speed: KeyRepeat and InitialKeyRepeat. In the System Preferences they are mapped to the Key Repeat Rate and the Delay Until Repeat sliders. The slider ranges and the associated internal parameter values (in parenthesis) are show below. They seem to be multipliers of the 15 ms keyboard sampling interval.
Key Repeat Rate (KeyRepeat) Delay Until Repeat (InitialKeyRepeat)
|--------------------------------| |----------------------|-----------------|
slow (120) fast (2) off (30000) long (120) short (25)
0.5 char/s 33 char/s
Fortunately, these parameters can be set beyond the predefined limits directly in the ~/Library/Preferences/.GlobalPreferences.plist file. I found the following values most convenient for myself:
KeyRepeat = 1 --> 1/(1*15 ms) = 66.7 char/s
InitialKeyRepeat = 15 --> 15*15 ms = 225 ms
Note that in the latest Mac OS X revisions the sliders are named slightly differently.
I do like to work on the keyboard alone. Why? Because when you use the mouse you have to grab it. A time loss.
On the other hand sometimes it seems that every application has its own keyboard type-rates built in. Not to speak from BIOS-properties or OS-settings. So I gathered shortkeys which can be pretty fast (i.e. you are faster typing Ctrl + right(arrow)-right-right than keeping your finger on the right(arrow) key :).
Here are some keyboard shortcuts I find most valuable (it works on Windows; I am not sure about OS X):
ctrl-right: Go to the end of the previous/the next word (stated before)
ctrl-left: Go to the beginning of the previous/the word before (stated before)
ctrl-up: Go to the beginning of this paragraph
(or to the next paragraph over this)
ctrl-down: Go to the end of this paragraph
(or to the next paragraph after this)
ctrl-pos1: Go to the beginning of the file
ctrl-end: Go to the end of the file
All these may be combined with the shift-key, so that the text is selected while doing so. Now let's go for more weird stuff:
alt-esc: Get the actual application into the background
ctrl-esc: This is like pressing the "start-button" in Windows: You can
navigate with arrow keys or shortcuts to start programs from here
ctrl-l: While using Firefox this accesses the URL-entry-field to simply
type URLs (does not work on Stack Overflow :)
ctrl-tab,
ctrl-pageup
ctrl-pagedwn Navigate through tabs (even in your development environment)
So these are the most used shortcuts I need while programming.
For OS X, the kernel extension KeyRemap4MacBook will allow you to fine tune all sorts of keyboard parameters, among which the key repeat rate (I set mine to 15 ms, and it works nice).
I don't know how to accelerate beyond the limit, but I know how to skip further in a single press. My knowledge is only in Windows, as I have no Mac to do this in. Ctrl + Arrow skips a word, and depending on the editor it may just skip to the next section of whitespace. You can also use Ctrl + Shift + Arrow to select a word in any direction.
Seems that you can't do this easily on Windows 7.
When you press and hold the button, the speed is controlled by Windows registry key : HCU->Control Panel->Keyboard->Keyboard Delay.
By setting this param to 0 you get maximum repeat rate. The drama is that you can't go below 0 if the repeat speed is still slow for you. 0-delay means that repeat delay is 250ms. But, 250ms delay is still SLOW as hell. See this : http://technet.microsoft.com/en-us/library/cc978658.aspx
You still can go to Accesibility, but you should know that those options are to help disabled people to use their keyboard, not give help for fast-typing geeks. They WON'T help. Use Linux, they tell you.
I bieleve the solution for Windows lies in hardware control. Look for special drivers for your keyboards or try to tweak existing ones.
Although the question is several years old, I still come across the same issue from time to time in several different developer sites. So I thought I may contribute an alternative solution, which I use for my everyday-developer-work (since the Windows registry settings never worked for me).
The following is my small Autorepeat-Script (~ 125 lines), which can be run via AutoHotkey_L (the downside is, it only runs under Windows, at least Vista, 7, 8.1):
; ====================================================================
; DeveloperTools - Autorepeat Key Script
;
; This script provides a mechanism to do key-autorepeat way faster
; than the Windows OS would allow. There are some registry settings
; in Windows to tweak the key-repeat-rate, but according to widely
; spread user feedback, the registry-solution does not work on all
; systems.
;
; See the "Hotkeys" section below. Currently (Version 1.0), there
; are only the arrow keys mapped for faster autorepeat (including
; the control and shift modifiers). Feel free to add your own
; hotkeys.
;
; You need AutoHotkey (http://www.autohotkey.com) to run this script.
; Tested compatibility: AutoHotkey_L, Version v1.1.08.01
;
; (AutoHotkey Copyright © 2004 - 2013 Chris Mallet and
; others - not me!)
;
; #author Timo Rumland <timo.rumland ${at} gmail.com>, 2014-01-05
; #version 1.0
; #updated 2014-01-05
; #license The MIT License (MIT)
; (http://opensource.org/licenses/mit-license.php)
; ====================================================================
; ================
; Script Settings
; ================
#NoEnv
#SingleInstance force
SendMode Input
SetWorkingDir %A_ScriptDir%
; Instantiate the DeveloperTools defined below the hotkey definitions
developerTools := new DeveloperTools()
; ========
; Hotkeys
; ========
; -------------------
; AutoRepeat Hotkeys
; -------------------
~$UP::
~$DOWN::
~$LEFT::
~$RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "" )
return
~$+UP::
~$+DOWN::
~$+LEFT::
~$+RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "+" )
return
~$^UP::
~$^DOWN::
~$^LEFT::
~$^RIGHT::
DeveloperTools.startAutorepeatKeyTimer( "^" )
return
; -------------------------------------------------------
; Jump label used by the hotkeys above. This is how
; AutoHotkey provides "threads" or thread-like behavior.
; -------------------------------------------------------
DeveloperTools_AutoRepeatKey:
SetTimer , , Off
DeveloperTools.startAutorepeatKey()
return
; ========
; Classes
; ========
class DeveloperTools
{
; Configurable by user
autoRepeatDelayMs := 180
autoRepeatRateMs := 40
; Used internally by the script
repeatKey := ""
repeatSendString := ""
keyModifierBaseLength := 2
; -------------------------------------------------------------------------------
; Starts the autorepeat of the current captured hotkey (A_ThisHotKey). The given
; 'keyModifierString' is used for parsing the real key (without hotkey modifiers
; like "~" or "$").
; -------------------------------------------------------------------------------
startAutorepeatKeyTimer( keyModifierString )
{
keyModifierLength := this.keyModifierBaseLength + StrLen( keyModifierString )
this.repeatKey := SubStr( A_ThisHotkey, keyModifierLength + 1 )
this.repeatSendString := keyModifierString . "{" . this.repeatKey . "}"
SetTimer DeveloperTools_AutoRepeatKey, % this.autoRepeatDelayMs
}
; ---------------------------------------------------------------------
; Starts the loop which repeats the key, resulting in a much faster
; autorepeat rate than Windows provides. Internally used by the script
; ---------------------------------------------------------------------
startAutorepeatKey()
{
while ( GetKeyState( this.repeatKey, "P" ) )
{
Send % this.repeatSendString
Sleep this.autoRepeatRateMs
}
}
}
Save the code above in a text file (UTF-8), for example named "AutorepeatScript.ahk"
Install AutoHotkey_L
Double click on "AutorepeatScript.ahk" to enjoy much fast arrow-keys (or put the file into your autostart-folder)
(You can adjust the repeat delay and rate in the script, see '; Configurable by user').
Hope this helps!
On Mac, it's option-arrow to skip a word and ⌥+Shift+Arrow to select. ⌘+Arrow skips to the end or beginning of a line or the end or beginning of a document. There are also the page up, page down, home and end keys ;) Holding shift selects with those too.
Well, it might be obvious, but:
For horizontal navigation, Home (line start), End (line end), Ctrl-Left (word left), Ctrl-Right (word right) work in all editors I know
For vertical navigation, Page Up, Page Down, Ctrl-Home (text start), Ctrl-End (text end) do too
Also (on a side note), I would like to force my Backspace and Delete keys to non-repeat, so that the only way to delete (or replace) text would be to first mark it, then delete it (or type the replacement text).
Don't navigate character-by-character.
In Vim (see ViEmu for Visual Studio):
bw -- prev/next word
() -- prev/next sentence (full stop-delimited text)
{} -- prev/next paragraph (blank-line delimited sections of text)
/? -- move the cursor to the prev/next occurence the text found (w/ set incsearch)
Moreover, each of the movements takes a number as prefix that lets you specify how many times to repeat the command, e.g.:
20j -- jump 20 lines down
3} -- three paragraphs down
4w -- move 4 words forward
40G -- move to (absolute) line number 40
There are most likely equivalent ways to navigate through text in your editor. If not, you should consider switching to a better one.

Resources