标签 AutoHotkey 下的文章

工作经常在 windows 和 macOS 来回切,有一些按键习惯会对不上

比如:

  • windows 切换窗口是 alt+tab,macOS 是 cmd+tab
  • macOS 用cmd+⬆️⬇️➡️⬅️可以导航输入光标,配合shiftbackspace等可以按导航、选中、删除,windows 下是home``end

下面是我常用的 autoHotkey 脚本,用在 windows 上以模仿 macOS 的行为,每个人的需求各不相同,仅供参考

1. 基本文本导航能力

复制
; ==== 基本文本导航能力 ====

; 1. Ctrl+左箭头 → Home(行首)
^Left::Send "{Home}"

; 2. Ctrl+右箭头 → End(行尾)
^Right::Send "{End}"

; 3. Alt+左箭头 → Ctrl+左箭头(单词跳转)
!Left::Send "^{Left}"

; 4. Alt+右箭头 → Ctrl+右箭头(单词跳转)
!Right::Send "^{Right}"

; ==== 带 Shift 的文本选择版本 ====

; 5. Ctrl+Shift+左箭头 → Shift+Home(选中到行首)
^+Left::Send "+{Home}"

; 6. Ctrl+Shift+右箭头 → Shift+End(选中到行尾)
^+Right::Send "+{End}"

; 7. Alt+Shift+左箭头 → Ctrl+Shift+左箭头(选中左侧单词)
!+Left::Send "^+{Left}"

; 8. Alt+Shift+右箭头 → Ctrl+Shift+右箭头(选中右侧单词)
!+Right::Send "^+{Right}"


; ==== 补充的删除功能 ====

; 9. Ctrl+Backspace → 删除整行
^Backspace::Send "+{Home}{Delete}"

; 10. Alt+Backspace → 删除前一个单词
!Backspace::Send "^+{Left}{Delete}"

2. 将 alt+tab 切换窗口的能力赋予 ctrl+tab

复制
; ==== 将 alt+tab 切换窗口的能力赋予 ctrl+tab ====

~Ctrl & Tab::
{
    ; 释放 Ctrl 键避免干扰
    Send "{Ctrl Up}"
    
    ; 检查 Shift 键状态,已实现反向切换
    if GetKeyState("Shift", "P") { ; 如果 Shift 被物理按下
        Send "{Alt Down}{Shift Down}{Tab}"
        Send "{Shift Up}"
    } else {
        Send "{Alt Down}{Tab}"
    }
    return
}

; 防止 Alt 被锁定
~Ctrl Up::
{
    Send "{Alt Up}"
    return
}


; ==== 通过 win 补充原有 ctrl+tab 切换标签页的功能 ====

; 1. Win+Tab → Ctrl+Tab(标签切换)
#Tab::Send "^{Tab}"

; 2. Win+Shift+Tab → Ctrl+Shift+Tab(反向标签切换)
#+Tab::Send "^+{Tab}"

3. CapeLock键单击切换中英文、长按锁定大小写

注意:需修改切换中英文的热键,我这里是改成Ctrl+F12

复制
#Requires AutoHotkey v2.0
Persistent()

; 初始化状态
isLongPress := false
SetCapsLockState "AlwaysOff" ; 默认关闭大写锁定

; 长按检测函数
longPressAction() {
    global isLongPress
    if (GetKeyState("CapsLock", "P")) { ; 如果仍按住
        isLongPress := true
        SetCapsLockState !GetKeyState("CapsLock", "T") ; 立即切换大小写
    }
}

; 监听 CapsLock 按下事件
CapsLock:: {
    global isLongPress
    isLongPress := false
    SetTimer longPressAction, -300 ; 300ms 后检测长按(负数表示单次触发)

    KeyWait "CapsLock" ; 等待释放
    SetTimer longPressAction, 0 ; 清除计时器

    ; 单击行为(未触发长按时)
    if (!isLongPress) {
        Send "^^{F12}" ; 发送 Ctrl+F12 切换中英文
        SetCapsLockState "Off" ; 强制关闭大写锁定
    }
}

; 保留 Shift+CapsLock 强制切换大小写
+CapsLock:: SetCapsLockState !GetKeyState("CapsLock", "T")

为什么不用 powerToys

实测按键代理时灵时不灵

缺陷

其实我还写了一个交换ctrl键和win键的脚本,但是经常抽风,这个暂时没有很好的解决办法,如果外界键盘支持修改键位,可以通过 via 进行修改:
image

importsysfromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QListWidget,QVBoxLayout,QLineEdit,QWidget,QFrame)fromPyQt5.QtCoreimportQt,QEventfromPyQt5.QtWidgetsimportQDesktopWidgetimportpyautoguiimportpyperclipimporttimedefpowertoy_active_window(text):sleep_second=0.2time.sleep(sleep_second)pyautogui.hotkey("win","alt","k")time.sleep(sleep_second)pyperclip.copy(text)pyautogui.hotkey("ctrl","v")time.sleep(sleep_second)pyautogui.hotkey("enter") classCommandPalette(QWidget):def__init__(self,parent=None):super().__init__(parent)# 1. 设置 UI 属性:无边框、置顶、背景透明self.setWindowFlags(Qt.FramelessWindowHint|Qt.Dialog)self.setAttribute(Qt.WA_TranslucentBackground) # 外层容器(用于实现圆角和边框)self.container=QFrame(self)self.container.setFixedWidth(500)self.container.setStyleSheet("""QFrame {background-color: #252526;border: 1px solid #454545;border-radius: 6px;}""") layout=QVBoxLayout(self.container) # 2. 搜索输入框self.search_bar=QLineEdit()self.search_bar.setPlaceholderText("键入命令名称以筛选...")self.search_bar.setStyleSheet("""QLineEdit {background-color: #3c3c3c;color: #cccccc;border: 1px solid #007acc;padding: 6px;font-size: 14px;selection-background-color: #264f78;}""") # 3. 命令列表self.list_widget=QListWidget()self.list_widget.setStyleSheet("""QListWidget {background-color: #252526;color: #cccccc;border: none;font-size: 13px;outline: none;}QListWidget::item { padding: 10px; border-radius: 4px; }QListWidget::item:selected { background-color: #094771; color: white; }QListWidget::item:hover { background-color: #2a2d2e; }""") layout.addWidget(self.search_bar)layout.addWidget(self.list_widget) main_layout=QVBoxLayout(self)main_layout.setContentsMargins(0,0,0,0)main_layout.addWidget(self.container,alignment=Qt.AlignCenter) # 模拟命令数据# self.commands = [# "File: New File",# "Git: Commit All",# "Python: Run Current File",# "Settings: Open Settings",# "Terminal: Toggle Terminal",# "View: Layout Grid"# ]self.commands=[["1. book","book code"],["2. anti2","anti2 code"],["4. chrounim","chro"],["5.q-dir","q-dir"],]self.refresh_list("") # 信号连接self.search_bar.textChanged.connect(self.refresh_list)self.search_bar.returnPressed.connect(self.execute_selected)self.list_widget.itemClicked.connect(self.execute_selected) # 2. 当在列表中通过方向键选中某项并按回车时,触发 itemActivatedself.list_widget.itemActivated.connect(self.execute_selected) # 安装事件过滤器以捕获按键self.installEventFilter(self) defrefresh_list(self,text):self.list_widget.clear()# 简单的包含搜索(不区分大小写)# filtered = [cmd for cmd in self.commands if text.lower() in cmd.lower()]filtered=[info[0]forinfoinself.commandsiftext.lower()ininfo[0].lower()]self.list_widget.addItems(filtered)ifself.list_widget.count()>0:self.list_widget.setCurrentRow(0) defexecute_selected(self):item=self.list_widget.currentItem()ifitem:print(f"触发动作:{item.text()}")text=item.text()item=[eforeinself.commandsife[0]==text][0]send_text=item[1]print("#执行命令#:{}".format(send_text))powertoy_active_window(send_text)# self.hide()QApplication.instance().quit() defshow_palette(self):width=500height=400# 假设高度为 400self.setFixedSize(width,height) # 2. 获取屏幕中心# availableGeometry() 会避开任务栏,确保真正的视觉垂直居中screen_geo=QDesktopWidget().availableGeometry()screen_center=screen_geo.center() # 3. 计算面板位置,使其中心点与屏幕中心点重合# 我们可以通过 moveCenter 方便地实现qr=self.frameGeometry()qr.moveCenter(screen_center)self.move(qr.topLeft()) # 4. 显示并聚焦self.show()self.raise_()self.activateWindow()self.search_bar.setFocus()self.search_bar.selectAll()# 方便用户直接覆盖键入 defeventFilter(self,obj,event):ifevent.type()==QEvent.KeyPress:# Esc 键退出ifevent.key()==Qt.Key_Escape:self.hide()returnTrue# 下方向键快速进入列表选择ifevent.key()==Qt.Key_Downandself.search_bar.hasFocus():self.list_widget.setFocus()returnTruereturnsuper().eventFilter(obj,event) classMainWindow(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("PyQt5 VS Code Command Palette")self.resize(1000,700)# self.minimumSize()self.showMinimized()self.setStyleSheet("background-color: #1e1e1e;")# 模拟 VS Code 背景 # 初始化命令面板self.palette=CommandPalette(self)# self.palette.hide()self.palette.show_palette()defcenter_on_screen(self):# 获取窗口几何结构frame_geometry=self.frameGeometry() # 获取屏幕中心点# QDesktopWidget().availableGeometry() 会排除任务栏占据的空间screen_center=QDesktopWidget().availableGeometry().center() # 将窗口几何结构的中心点移动到屏幕中心点frame_geometry.moveCenter(screen_center) # 移动窗口左上角到计算出的位置self.move(frame_geometry.topLeft()) defkeyPressEvent(self,event):# 绑定快捷键 Ctrl+Shift+P (Qt.ControlModifier | Qt.ShiftModifier)if(event.modifiers()==(Qt.ControlModifier|Qt.ShiftModifier)andevent.key()==Qt.Key_P):self.palette.show_palette() if__name__=="__main__":app=QApplication(sys.argv)# 设置应用字体app.setStyle("Fusion")window=MainWindow()window.show()sys.exit(app.exec_())

这个东西的主要作用是当我输入 1 时,它会找到 ["1. book", "book code"]这一项,然后 取出book code,然后激活 window 窗口切换器
,我的窗口切换器的的快捷是Win+alt+k,本来想用 ahk 来写的,但是 ahk 写 command picker 实在是不会.