<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>~iany/ Shortcut</title><link>https://blog.iany.me/zh/tags/shortcut/</link><description>Shortcut的最新内容 «~iany/»</description><language>zh-CN</language><managingEditor>me@iany.me (Ian Yang)</managingEditor><webMaster>me@iany.me (Ian Yang)</webMaster><copyright>CC-BY-SA 4.0</copyright><lastBuildDate>Wed, 10 Apr 2024 19:32:40 +0800</lastBuildDate><atom:link href="https://blog.iany.me/zh/tags/shortcut/index.xml" rel="self" type="application/rss+xml"/><item><title>解决 Windows 中文输入法下 Shift + Space 快捷键的困扰</title><link>https://blog.iany.me/zh/2024/04/resolve-the-annoying-shift-space-shortcut-in-windows-chinese-input-methods/</link><pubDate>Wed, 10 Apr 2024 19:32:40 +0800</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/zh/2024/04/resolve-the-annoying-shift-space-shortcut-in-windows-chinese-input-methods/</guid><description>&lt;p&gt;最近我把主要的工作环境转移到了Windows系统。之前 Windows 最困扰我的是 &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt; 的快捷键。在中文输入法状态下稍微打字快一点，就会误触发切换半角全角的功能，打乱输入的节奏。既然我决定长期使用 Windows 系统，就花了一些时间全面解决了这个问题。&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;安装 &lt;a href="https://www.autohotkey.com/"&gt;AutoHotkey&lt;/a&gt; v2 版。将以下代码加入到一个 &lt;code&gt;.ahk&lt;/code&gt; 为后缀的文件中，比如“文档”目录中的 &lt;code&gt;main.ahk&lt;/code&gt; 文件:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;+Space::Send (A_PriorKey = &amp;quot;LShift&amp;quot; ? &amp;quot;+{Space}&amp;quot; : &amp;quot;{Blind}{Shift up}{Space}{Shift down}{LWin}&amp;quot;)
&amp;gt;+Space::Send (A_PriorKey = &amp;quot;RShift&amp;quot; ? &amp;quot;+{Space}&amp;quot; : &amp;quot;{Blind}{Shift up}{Space}{Shift down}{LWin}&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;双击文件 &lt;code&gt;main.ahk&lt;/code&gt; 即可生效，如果要启动时自动生效，可以为这个文件创建一个快捷方式，然后将快捷方式移到到“启动”目录中。可以通过以下办法快速打开“启动”目录。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用快捷键 &lt;kbd&gt;Win&lt;/kbd&gt; + &lt;kbd&gt;r&lt;/kbd&gt; 打开运行窗口&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;shell:startup&lt;/code&gt; 并使用 &lt;kbd&gt;Enter&lt;/kbd&gt; 确认&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="思路说明"&gt;思路说明&lt;/h2&gt;
&lt;p&gt;&lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt; 烦人的地方在于它会吞掉本想输入的空格。输入需要 &lt;kbd&gt;Shift&lt;/kbd&gt; 组合键的符号时，通常在前或者在后要加上空格，比如 &lt;code&gt;:(){}&lt;/code&gt; 这些符号。如果输入速度很快，很可能会在 &lt;kbd&gt;Shift&lt;/kbd&gt; 尚未完全松开时按下 &lt;kbd&gt;Space&lt;/kbd&gt; ，这时候没有输入空格反而是切换了半角全角，如果当前需要使用半角，还得再按一次切换回来。&lt;/p&gt;
&lt;p&gt;基于上述分析，我想实现在按下 &lt;kbd&gt;Shift&lt;/kbd&gt; 键后，如果在按下空格键之前按下了其他键，便视为 &lt;kbd&gt;Shift&lt;/kbd&gt; 键没有及时松开，应该输入一个空格符号。如果在按下 &lt;kbd&gt;Shift&lt;/kbd&gt; 键后立即按下空格键，应保留原来的半角全角切换功能。这样的配置不但能避免误触发，还可以被利用来快速输入 &lt;code&gt;) {&lt;/code&gt; 这样的序列，因为全程 &lt;kbd&gt;Shift&lt;/kbd&gt; 不用松开了。&lt;/p&gt;
&lt;p&gt;上面的 AutoHotkey 代码即实现了这里描述的功能。&lt;/p&gt;
&lt;h2 id="代码说明"&gt;代码说明&lt;/h2&gt;
&lt;p&gt;代码有两行，分别对应的左右手 &lt;kbd&gt;Shift&lt;/kbd&gt; 触发的情况。我尝试过合并成一条但失败了，具体原因我也不清楚，也不知道为什么分开就能工作了。&lt;/p&gt;
&lt;p&gt;下面以左手的第一行为例说明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;+Space::Send (A_PriorKey = &amp;quot;LShift&amp;quot; ? &amp;quot;+{Space}&amp;quot; : &amp;quot;{Blind}{Shift up}{Space}{Shift down}{LWin}&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AutoHotkey 代码&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;+Space::&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为 &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt; 设置命令，并只有使用左手的 &lt;kbd&gt;Shift&lt;/kbd&gt; 才能触发。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Send&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送指定的按键序列。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(A_PriorKey = &amp;quot;LShift&amp;quot; ? X : Y)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;如果变量 &lt;code&gt;A_PriorKey&lt;/code&gt; 的值等于 &lt;code&gt;LShift&lt;/code&gt; 时返回 X 否则返回 Y。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+{Space}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送组合按键 &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Space&lt;/kbd&gt; 以触发其原本的功能，即切换半角全角。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{Blind}{Shift up}{Space}{Shift down}{LWin}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;这么一大串其实只是为了实现在 AutoHotkey 里在 &lt;kbd&gt;Shfit&lt;/kbd&gt; 按下的情况下输入一个空格符号。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;第一个比较重要的点是自动变量 &lt;a href="https://www.autohotkey.com/docs/v2/Variables.htm#PriorHotkey"&gt;A_PriorHotkey&lt;/a&gt;。它记录的是组合键所有键被按下之前上一个按键状态有变化的键。因为组合键最后一个按下的一定是非修饰键，所以如果按下 &lt;kbd&gt;Shift&lt;/kbd&gt; 后立即按下 &lt;kbd&gt;Space&lt;/kbd&gt;，&lt;code&gt;A_PriorHotkey&lt;/code&gt; 就是 &lt;kbd&gt;LShift&lt;/kbd&gt; 或者 &lt;kbd&gt;RShift&lt;/kbd&gt;。相反，如果 &lt;code&gt;A_PriorHotkey&lt;/code&gt; 等于其它值就表示按下 &lt;kbd&gt;Shift&lt;/kbd&gt; 到按下 &lt;kbd&gt;Space&lt;/kbd&gt; 之间有按过其它按键。&lt;/p&gt;
&lt;p&gt;第二个点是用来模拟输入空格的一长串 &lt;code&gt;{Blind}{Shift up}{Space}{Shift down}{LWin}&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{Blind}&lt;/code&gt; 的作用是让 &lt;code&gt;{Shift up}&lt;/code&gt; 强制修改 &lt;kbd&gt;Shift&lt;/kbd&gt; 的状态改为松开保证后面 &lt;code&gt;{Space}&lt;/code&gt; 输入一个空格符号。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{Shift down}&lt;/code&gt; 是恢复 &lt;kbd&gt;Shift&lt;/kbd&gt; 按下的状态，这样后面可以继续输入还 &lt;kbd&gt;Shift&lt;/kbd&gt; 的组合键。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{LWin}&lt;/code&gt; 不会触发任何操作。它的作用是如果在中文输入法里启用了点按 &lt;kbd&gt;Shift&lt;/kbd&gt; 来切换中英文，在下面的按键序列中会正确输入 &lt;code&gt;: &lt;/code&gt; (冒号+空格) 并且不会误触发中英文切换：
&lt;ul&gt;
&lt;li&gt;按下 &lt;kbd&gt;Shift&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;按下 &lt;kbd&gt;:&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;松开 &lt;kbd&gt;:&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;按下 &lt;kbd&gt;Space&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;松开 &lt;kbd&gt;Space&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;松开 &lt;kbd&gt;Shift&lt;/kbd&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description><category domain="https://blog.iany.me/zh/">~iany/</category><category domain="https://blog.iany.me/zh/tags/ime/">IME</category><category domain="https://blog.iany.me/zh/tags/shortcut/">Shortcut</category><category domain="https://blog.iany.me/zh/tags/windows/">Windows</category></item></channel></rss>