Autohotkey
Selenium Within Autohotkey using COM
Joe Glines has done a great job of documenting how to use Selenium within Authotkey. The basic logic is that you first install Seleniumbasic - A COM library to use Selenium with Excel in the Visual Basic Editor or within a visual basic script (VBS). Autohotkey allows you to directly call COM objects using a few simple commands. Consequently, it’s quite trivial to implement Selenium using Autohotkey.
#SingleInstance, Force
#Persistent
driver := ComObjCreate("Selenium.ChromeDriver")
driver.AddArgument("--window-size=390,700")
driver.Get("https://www.google.com")
However, for most of my projects I ended up actually just using subprocesses in Python. I found this to be a more logical way to harness the power of Autohotkey and Selenium in a single program. While I commend the efforts of the Seleniumbasic developer, Florent; it’s not as well documented or feature rich as the default Selenium. Here’s a simple example of an AHK subprocess in Python (that takes command line arguments).
import subprocess
subprocess.run(f"C:\\Code\\selenium_ahk\\calendar_pick.exe {daterc[0]} {daterc[1]}")
Autocomplete in Autohotkey GUI Applications
I found this really neat little script called CbAutoComplete which enables Autocomplete in a Combobox for Autohotkey. See the image below for an example!
To use it in a script is quite trivial. First, you need to download the script from: https://github.com/Pulover/CbAutoComplete/blob/master/CbAutoComplete.ahk. Then, you need to load the script at the top of your AHK application. Next, within your combobox, you need to make a subprocess call to the autocomplete function. And, that’s it - you will now have autocomplete in your combobox!
;; Include autohotkeyscript
#Include %A_ScriptDir%\CbAutoComplete.ahk
...
;; some GUI component with the autocomplete subroutine
Gui, 2:Add, ComboBox,x60 w180 h200 vOutVar gAutoComplete, %list_of_items%
...
;; Subroutine for Autocomplete functionality
AutoComplete:
CbAutoComplete()
return
Hotstrings
To be honest, although I barely use hotstrings, I find the concept and possible automation quite tantalizing. The idea that I could simply replace a static typed word with dynamic contents, like a date or email, just has such obvious face value.
Here’s a simple one for just insertng the current time and date.
:*:dt#::
FormatTime, CurrentDateTime,, yyyy-MM-dd HH:mm
SendInput %CurrentDateTime%
return
Bash / Utilities
Batch Renaming 1 - X
If you have a bunch of files with some extension, and you want to rename them all to a new extension
, this will do the trick.
ls | cat -n | while read n f; do mv "$f" "$n.extension"; done X
ImageMagick: Joining images side by side
Imagine you have a bunch of figures you’d like to join, either side by side or stacked…
montage [0-5].png -tile 5x1 -geometry +0+0 out.png
# Horitzontal
convert +append *.png out.png
# vertical
convert -append *.png out.png
Count number of pages in a PDF
pdfinfo "${PDFFILE}" | grep Pages | sed 's/[^0-9]*//'
VBA and Powershell
Generate Pictures with Captions VBA {#generate-pictures-with-captions-vba
For each rent inspection I need to take 100-150 photos, I think can rename the photos based on each room. Finally, I want to load all of these into a word document, with the filename as the caption. This VB script will automatically generate a document containing all the images in a directory, and then have a caption for each image with the filename.
Sub PicWithCaption()
Dim file
Dim path As String
path = "C:\pathto\images"
file = Dir(path & "*.jpg")
CaptionLabels.Add Name:="Filename"
Do While file <> ""
With Selection
.EndKey Unit:=wdStory
.InlineShapes.AddPicture FileName:=path & file, _
LinkToFile:=False, SaveWithDocument:=True
.InsertAfter vbCrLf & vbCrLf
.Collapse 0
.MoveLeft Unit:=wdCharacter, Count:=1
.Style = "Caption"
.Text = path & file
End With
file = Dir()
Loop
Selection.EndKey Unit:=wdStory
End Sub
Remove User Account Login Data Windows
This is honestly one of the oddest problems. I doubt anyone will ever use it. However, sometimes you wnat to remove hidden user data associated with accounts that have synced on a Windows Enterprise server on a computer. The following command, if run as administator, will remove all hidden user data.
REG ADD "HKLM\System\CurrentControlSet\Services\CSC\Parameters" /v FormatDatabase /t REG_DWORD /d 1 /f * Cleaning Computers
Remove Password VBA
The code below is taken directly from this Stack Overflow question. In short, it provides a cheeky method of removing passwords associated with an excel document.
You can try this direct VBA approach which doesn’t require HEX editing. It will work for any files (*.xls, *.xlsm, *.xlam …).
Thankyou Đức Thanh Nguyễn!
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As Long) As Long
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As Long
Dim OriginProtect As Long
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Emacs Lisp
Bibtex lookup current clipboard entry
(global-set-key (kbd "C-c C-m")
(lambda ()
(interactive)
(crossref-lookup (current-kill 0))))
Dired sort directory by number
(setq dired-listing-switches "-laGh1v --group-directories-first")
Selective File Loading lisp
Handy way to load files selectively, but without errors if they don’t exist.
(if (file-readable-p "~/.spacemacs.d/modes-config.el") (load "~/.spacemacs.d/modes-config.el"))
(if (file-readable-p "~/.spacemacs.d/org-config.el") (load "~/.spacemacs.d/org-config.el"))
(if (file-readable-p "~/.spacemacs.d/keybinds.el") (load "~/.spacemacs.d/keybinds.el"))
Better Backwards Delete Emacs
I found by default Emacs was deleting way too much content on a and found this handy gem on stack from aborn.
(defun aborn/backward-kill-word ()
"Customize/Smart backward-kill-word."
(interactive)
(let* ((cp (point))
(backword)
(end)
(space-pos)
(backword-char (if (bobp)
"" ;; cursor in begin of buffer
(buffer-substring cp (- cp 1)))))
(if (equal (length backword-char) (string-width backword-char))
(progn
(save-excursion
(setq backword (buffer-substring (point) (progn (forward-word -1) (point)))))
(setq ab/debug backword)
(save-excursion
(when (and backword ;; when backword contains space
(s-contains? " " backword))
(setq space-pos (ignore-errors (search-backward " ")))))
(save-excursion
(let* ((pos (ignore-errors (search-backward-regexp "\n")))
(substr (when pos (buffer-substring pos cp))))
(when (or (and substr (s-blank? (s-trim substr)))
(s-contains? "\n" backword))
(setq end pos))))
(if end
(kill-region cp end)
(if space-pos
(kill-region cp space-pos)
(backward-kill-word 1))))
(kill-region cp (- cp 1))) ;; word is non-english word
))
(global-set-key [C-backspace] 'aborn/backward-kill-word)
Fix Rmarkdown Code Blocks Breaking from Fill command
Rmarkdown requires R src code blocks do not break or split over multiple lines. In order to prevent Emacs markdown mode from breaking R src blocks, add this to your config
;; Fix inline codeblocks being split in markdown mode in Rmarkdown documents when filling
(with-eval-after-load 'markdown-mode
(add-hook 'fill-nobreak-predicate
#'markdown-inline-code-at-point-p))
Open Current File or Directory in System Viewer
(defun open-directory-in-system-viewer ()
(interactive)
(when-system gnu/linux
(if default-directory
(browse-url-of-file (expand-file-name default-directory))
(error "No `default-directory' to open")))
(when-system windows-nt
(if default-directory
(w32explore (expand-file-name default-directory))
(error "No `default-directory' to open"))))
Enable Meta Shift Y to yank pop forwards
In Emacs, shift Y will paste current command, but consecutive Meta Ys will go through the almost infinite clipboard. You can undo if you go to far, but I find M-Y to be far more intuitive.
;; ‘M-y’ (‘yank-pop’) cycles backwards through the ‘kill-ring’.
;; Here’s a way to cycle in the reverse direction with ‘M-Y’ (Meta-Shift-Y):
(defun yank-pop-forwards (arg)
(interactive "p")
(yank-pop (- arg)))
(global-set-key "\M-Y" 'yank-pop-forwards) ; M-Y (Meta-Shift-Y)