<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss1full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="ja">
<channel rdf:about="http://d.hatena.ne.jp/Koonies/rss">
<title>Koonies/こりゃいいな！</title>
<link>http://d.hatena.ne.jp/Koonies/</link>
<description>Koonies/こりゃいいな！</description>

<dc:creator>Koonies</dc:creator>
<dc:date>2012-05-19T14:46:49+09:00</dc:date>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://d.hatena.ne.jp/Koonies/20120511/thg_amend" />
<rdf:li rdf:resource="http://d.hatena.ne.jp/Koonies/20110906/keyhac_capslock_modifier" />
<rdf:li rdf:resource="http://d.hatena.ne.jp/Koonies/20110828/keyhac_chm_viewer" />
<rdf:li rdf:resource="http://d.hatena.ne.jp/Koonies/20110819/keyhac_aero_snap" />
<rdf:li rdf:resource="http://d.hatena.ne.jp/Koonies/20110818/keyhac_double_key_ime" />
</rdf:Seq>
</items>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rdf+xml" href="http://feeds.feedburner.com/Koonies" /><feedburner:info uri="koonies" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /></channel>



<item rdf:about="http://d.hatena.ne.jp/Koonies/20120511/thg_amend">
<title>[mercurial]TortoiseHgでAmendを使うと2つ前のコミットをやり直せる</title>
<link>http://feedproxy.google.com/~r/Koonies/~3/Fe6MdWqjrVI/thg_amend</link>
<description> TortoiseHgはバージョン管理ソフトMercurialのWindows用フロントエンドで、つい先日にリリースされた最新版v2.4でAmendというコマンドが追加されました。Amendを使えば、お手軽に直前のコミットをやり直すことが可能になります。 以前のバージョンでもロールバックして、コ</description>

<content:encoded><![CDATA[
<div class="section">
<p><a href="http://tortoisehg.bitbucket.org/ja/" target="_blank">TortoiseHg</a>はバージョン管理ソフトMercurialのWindows用フロントエンドで、つい先日にリリースされた最新版v2.4で<span style="font-weight:bold;" class="deco">Amend</span>というコマンドが追加されました。Amendを使えば、お手軽に<span style="font-weight:bold;" class="deco">直前のコミットをやり直す</span>ことが可能になります。</p>
<p>以前のバージョンでも<span style="font-weight:bold;" class="deco">ロールバック</span>して、<span style="font-weight:bold;" class="deco">コミット</span>し直せば同様のことが可能だった訳ですが、実際の操作手順としてはAmendを使った方がコミットのメッセージをコピーする必要もないため地味に便利です。リリースされてからまだ数日ですが、既に何度もお世話になってます。</p>
<p>さてタイトルにも書いた「<span style="font-weight:bold;" class="deco">2つ前</span>」の修正の話。</p>
<p>これまでは<span style="font-weight:bold;" class="deco">「1つ前」の修正ならロールバック</span>、それ以上前の修正をやりたい場合は<span style="font-weight:bold;" class="deco">MQなどのエクステンション</span>を使う必要がありました。</p>
<p>最新版では「1つ前」の修正なら<span style="font-weight:bold;" class="deco">ロールバック</span>または<span style="font-weight:bold;" class="deco">Amend</span>のどちらでもOKになりました。という事は<span style="font-weight:bold;" class="deco">ロールバックして、更にAmendすれば「2つ前」を修正できる？？</span>という疑問が湧いてきますよね。それで試してみたら、本当に<span style="font-weight:bold;" class="deco">出来ました</span>。</p>
<h5><span style="font-weight:bold;">手順</span></h5>
<p>1. まずは<span style="font-weight:bold;" class="deco">ロールバック</span></p>
<p>2. 直前の変更点を<span style="font-weight:bold;" class="deco">シェルフで待避</span></p>
<p>3. コミットの画面にする</p><p>4. コミットボタンの隣の▼をクリックし、"<span style="font-weight:bold;" class="deco">Amend current revision</span>"をクリック<span class="footnote"><a href="/Koonies/#f1" name="fn1" title="ただしAmendはMQエクステンションが有効でないと使用できないみたいなので注意！">*1</a></span></p>
<p>5. するとボタン表示がコミット→Amendに変わり、「2つ前」のコミットメッセージが表示されるので、修正して<span style="font-weight:bold;" class="deco">Amend</span>ボタンをクリック</p>
<p>6. シェルフで待避した変更点を戻し、あとは普通にコミットをやり直す。</p>
<h5><span style="font-weight:bold;">さいごに</span></h5>
<p>Mercurialでも同様のことが出来そうな気がしますね。試してないけど。それでは。</p>
</div>
<div class="footnote">
<p class="footnote"><a href="/Koonies/#fn1" name="f1">*1</a>：ただしAmendはMQエクステンションが有効でないと使用できないみたいなので注意！</p>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/zG763YoRCPfsTTtu9CUkl33fyqE/0/da"><img src="http://feedads.g.doubleclick.net/~a/zG763YoRCPfsTTtu9CUkl33fyqE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/zG763YoRCPfsTTtu9CUkl33fyqE/1/da"><img src="http://feedads.g.doubleclick.net/~a/zG763YoRCPfsTTtu9CUkl33fyqE/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/Koonies/~4/Fe6MdWqjrVI" height="1" width="1"/>]]></content:encoded>
<dc:creator>Koonies</dc:creator>
<dc:date>2012-05-11</dc:date>
<dc:subject>mercurial</dc:subject>
<feedburner:origLink>http://d.hatena.ne.jp/Koonies/20120511/thg_amend</feedburner:origLink></item>
<item rdf:about="http://d.hatena.ne.jp/Koonies/20110906/keyhac_capslock_modifier">
<title>[keyhac]keyhacでCapsLockをモディファイアキー定義して無理矢理使う</title>
<link>http://feedproxy.google.com/~r/Koonies/~3/NRfXEqebrtI/keyhac_capslock_modifier</link>
<description> keyhacの話。ある2chのスレを見ていたら、keyhacでCtrlとCapsLockキーを入れ替えようとしたが無理だった、というやりとりを見かけました。 CapsLockというキーは他のキーとは違いDownのイベントは発生するけど、Upは発生しない（ドライバがマスクしているらしい）ため、Ctrl</description>

<content:encoded><![CDATA[
<div class="section">
<p><a href="http://sites.google.com/site/craftware/keyhac" target="_blank">keyhac</a>の話。<a href="http://hibari.2ch.net/test/read.cgi/software/1239109333" target="_blank">ある2chのスレ</a>を見ていたら、keyhacでCtrlとCapsLockキーを入れ替えようとしたが無理だった、というやりとりを見かけました。</p>
<p>CapsLockというキーは他のキーとは違いDownのイベントは発生するけど、Upは発生しない（ドライバがマスクしているらしい）ため、Ctrlと入れ替えた場合、押されっぱなしの状態になるとか。</p><p>試しにkeyhacで内部ログON<span class="footnote"><a href="/Koonies/#f1" name="fn1" title="トレイアイコンを右クリック→内部ログONをクリック">*1</a></span>にして、CtrlとCapsキーを押してみると</p>
<pre class="syntax-highlight">
<span class="synComment"># Ctrlを押して離した場合</span>

IN  : D-LCtrl
TRU : D-LCtrl
IN  : U-LCtrl
TRU : U-LCtrl
IN  : O-LCtrl

<span class="synComment"># CapsLockを押して離した場合</span>

IN  : D-(240)
TRU : D-(240)
</pre>

<p>という風にCapsLockは「U-(240)」が出力されていません。だから入れ替えは無理、か。確かにこれは無理だなと思う反面、出来ないと言われると、何とかしたくなるのが人情。</p><p>で、色々考えた末、入れ替えは無理でもユーザー定義のモディファイアキー<span class="footnote"><a href="/Koonies/#f2" name="fn2" title="Ctrl・Shift・Alt・Winキーのような装飾キー">*2</a></span>としてなら使えるかもと思い、書いてみました。</p>
<h4><span style="font-weight:bold;" class="deco">■ コード</span></h4>
<pre class="syntax-highlight">
<span class="synComment"># config.py</span>

<span class="synPreProc">from</span> keyhac <span class="synPreProc">import</span> *


<span class="synStatement">def</span> <span class="synIdentifier">configure</span>(keymap):

    <span class="synComment">## 関数実行時にモディファイアの状態をリセットするデコレータ</span>
    <span class="synStatement">def</span> <span class="synIdentifier">reset_modifier</span>(func):
        <span class="synPreProc">import</span> functools

        <span class="synPreProc">@</span><span class="synIdentifier">functools</span>.wraps(func)
        <span class="synStatement">def</span> <span class="synIdentifier">_reset_modifier</span>(*args, **kw):
            <span class="synComment"># モディファイアの状態を無理矢理リセット</span>
            keymap.modifier = 0
            <span class="synComment"># 関数実行</span>
            <span class="synStatement">return</span> func(*args, **kw)
        <span class="synStatement">return</span> _reset_modifier

    <span class="synComment">## JobQueue/JobItem でサブスレッド処理にするデコレータ</span>
    <span class="synStatement">def</span> <span class="synIdentifier">job_queue</span>(func):
        <span class="synPreProc">import</span> functools

        <span class="synPreProc">@</span><span class="synIdentifier">functools</span>.wraps(func)
        <span class="synStatement">def</span> <span class="synIdentifier">_job_queue</span>(*args, **kw):

            num_items = JobQueue.defaultQueue().numItems()
            <span class="synStatement">if</span> num_items:   <span class="synComment"># 処理待ちアイテムがある場合は、その数を表示</span>
                <span class="synStatement">print</span> u&#34;<span class="synConstant">JobQueue.defaultQueue().numItems() :</span>&#34;, num_items

            <span class="synStatement">def</span> <span class="synIdentifier">__job_queue_1</span>(job_item):
                <span class="synStatement">return</span> func(*args, **kw)

            <span class="synStatement">def</span> <span class="synIdentifier">__job_queue_2</span>(job_item):
                <span class="synComment"># print &#34;job_queue : &#34;, func.__name__, args, kw</span>
                <span class="synStatement">pass</span>

            job_item = JobItem(__job_queue_1, __job_queue_2)
            JobQueue.defaultQueue().enqueue(job_item)

        <span class="synStatement">return</span> _job_queue

    <span class="synComment">## 一定時間経過後にモディファイアの状態をリセット</span>
    <span class="synPreProc">@</span><span class="synIdentifier">job_queue</span>
    <span class="synStatement">def</span> <span class="synIdentifier">auto_reset_modifier</span>():
        <span class="synPreProc">import</span> time
        WAIT_TIME = 0.5  <span class="synComment"># 秒</span>
        time.sleep(WAIT_TIME)
        <span class="synComment"># モディファイアの状態を無理矢理リセット</span>
        <span class="synComment"># if keymap.modifier: print keymap.modifier</span>
        keymap.modifier = 0

    <span class="synPreProc">@</span><span class="synIdentifier">reset_modifier</span>
    <span class="synStatement">def</span> <span class="synIdentifier">minimize</span>():
        keymap.getTopLevelWindow().minimize()

    <span class="synComment"># どのウインドウにフォーカスがあっても効くキーマップ</span>
    keymap_global = keymap.defineWindowKeymap()

    <span class="synComment"># ユーザモディファイアキーの定義：CapsLock(240) --&#62; U1</span>
    keymap.defineModifier(&#34;<span class="synConstant">(240)</span>&#34;, &#34;<span class="synConstant">U1</span>&#34;)

    <span class="synComment"># 単体押しは一定時間後にモディファイアの状態をリセット</span>
    <span class="synComment"># keymap_global[&#34;U1&#34;] = auto_reset_modifier     # これだとキー表記エラー</span>
    keymap_global[&#34;<span class="synConstant">(240)</span>&#34;] = auto_reset_modifier

    <span class="synComment"># Caps + a : ウィンドウ最小化</span>
    keymap_global[&#34;<span class="synConstant">U1-a</span>&#34;] = minimize
</pre>

<p>関数定義で@reset_modifierのデコレータを使うと、関数の実行時にモディファイアキーの状態をリセットします。これによりCapsLockキーの押されっぱなしを防止しています。</p>
<p>これで一応モディファイアっぽく使えます。ただしタイトルに「無理矢理」と書いたように同時押しでなくても</p>
<blockquote>
<p>CapsLockを押す → 離す → （0.5秒以内に）Aを押す</p>
</blockquote>
<p>でも認識されてしまいます。また、CapsLockを押したままA、Aと2回押すと、2回目のAは同時押しではないAになってしまう等の欠点があります。</p>
<h4><span style="font-weight:bold;" class="deco">■ さいごに</span></h4>
<p>日頃からCapsLockキーって押しやすい場所にあるのに全然使ってないなと思っている方はどうぞ。</p>
<h4><span style="font-weight:bold;" class="deco">■ 参考リンク</span></h4>
<p><a href="http://sites.google.com/site/craftware/keyhac" target="_blank">keyhac - craftware</a></p>
<p><a href="http://hibari.2ch.net/test/read.cgi/software/1239109333" target="_blank">no title</a></p>
</div>
<div class="footnote">
<p class="footnote"><a href="/Koonies/#fn1" name="f1">*1</a>：トレイアイコンを右クリック→内部ログONをクリック</p>
<p class="footnote"><a href="/Koonies/#fn2" name="f2">*2</a>：Ctrl・Shift・Alt・Winキーのような装飾キー</p>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/ZWqcx79Epxa-L7GK4jrMLkK2iBM/0/da"><img src="http://feedads.g.doubleclick.net/~a/ZWqcx79Epxa-L7GK4jrMLkK2iBM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ZWqcx79Epxa-L7GK4jrMLkK2iBM/1/da"><img src="http://feedads.g.doubleclick.net/~a/ZWqcx79Epxa-L7GK4jrMLkK2iBM/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/Koonies/~4/NRfXEqebrtI" height="1" width="1"/>]]></content:encoded>
<dc:creator>Koonies</dc:creator>
<dc:date>2011-09-06</dc:date>
<dc:subject>keyhac</dc:subject>
<feedburner:origLink>http://d.hatena.ne.jp/Koonies/20110906/keyhac_capslock_modifier</feedburner:origLink></item>
<item rdf:about="http://d.hatena.ne.jp/Koonies/20110828/keyhac_chm_viewer">
<title>[keyhac]keyhacでテキストエディタのF1キーに任意のヘルプファイルのキーワード表示に関連づける</title>
<link>http://feedproxy.google.com/~r/Koonies/~3/k5j_F4sD8yE/keyhac_chm_viewer</link>
<description> またまたkeyhacでのカスタマイズネタ。テキストエディタでプログラムを書いていると、そのプログラム言語のヘルプファイルが見たいってことがしばしばあります。そんなときに役立つ設定です。 ■ 使い方 使い方はカンタン。テキストエディタ上で調べたい単語を選択しF1を押</description>

<content:encoded><![CDATA[
<div class="section">
<p>またまた<a href="https://sites.google.com/site/craftware/keyhac" target="_blank">keyhac</a>でのカスタマイズネタ。テキストエディタでプログラムを書いていると、そのプログラム言語のヘルプファイルが見たいってことがしばしばあります。そんなときに役立つ設定です。</p>
<h4><span style="font-weight:bold;" class="deco">■ 使い方</span></h4>
<p>使い方はカンタン。テキストエディタ上で調べたい単語を選択しF1を押します。</p>
<p>そうすれば設定しておいたchm形式のヘルプファイルからキーワード検索し、その項目を表示します。</p>
<h4><span style="font-weight:bold;" class="deco">■ コード</span></h4>
<h5>・ chm_viewer.py</h5>
<p>まずは↓の部分を<span style="font-weight:bold;" class="deco">chm_viewer.py</span>という名前保存し、<span style="font-weight:bold;" class="deco">extensionフォルダ</span>に置いてください。</p>
<pre class="syntax-highlight">
<span class="synComment"># chm_viewer.py</span>
<span class="synComment"># http://d.hatena.ne.jp/pipehead/20071121/1195597559 のCraftLaunchEx用コードをほぼそのまま利用</span>

<span class="synComment"># Windows 2000/XP では Unicode 版 (HtmlHelpW) を使用し、2000/XP 以外では ANSI 版 (HtmlHelpA) を使用します。</span>
<span class="synStatement">def</span> <span class="synIdentifier">_IsWinNT5OrLater</span>():
    <span class="synPreProc">import</span> sys

    (major, platform) = sys.getwindowsversion()[0:4:3]
    <span class="synComment"># VER_PLATFORM_WIN32_NT: 2</span>
    <span class="synStatement">return</span> ((platform == 2) <span class="synStatement">and</span> (major &#62;= 5))

winNT5OrLater = _IsWinNT5OrLater()


<span class="synStatement">def</span> <span class="synIdentifier">_T</span>(string):
    <span class="synStatement">if</span> isinstance(string, str):
        string = unicode(string, '<span class="synConstant">utf-8</span>')
    <span class="synStatement">if</span> <span class="synStatement">not</span> winNT5OrLater:
        <span class="synStatement">return</span> string.encode('<span class="synConstant">mbcs</span>')
    <span class="synStatement">return</span> string


<span class="synPreProc">import</span> ctypes

<span class="synStatement">class</span> <span class="synIdentifier">c_tchar_p</span>(ctypes._SimpleCData):
    <span class="synStatement">if</span> winNT5OrLater:
        _type_ = '<span class="synConstant">Z</span>' <span class="synComment"># c_wchar_p</span>
    <span class="synStatement">else</span>:
        _type_ = '<span class="synConstant">z</span>' <span class="synComment"># c_char_p</span>


<span class="synComment"># WinUser.h</span>
GetDesktopWindow = ctypes.windll.user32.GetDesktopWindow


<span class="synComment"># HtmlHelp.h</span>
HH_DISPLAY_TOC    = 0x0001
HH_KEYWORD_LOOKUP = 0x000D
HH_CLOSE_ALL      = 0x0012


<span class="synPreProc">from</span> ctypes.wintypes <span class="synPreProc">import</span> BOOL

<span class="synStatement">class</span> <span class="synIdentifier">HH_AKLINK</span>(ctypes.Structure):
    _fields_ = [
        ('<span class="synConstant">cbStruct</span>',     ctypes.c_int), <span class="synComment"># sizeof this structure</span>
        ('<span class="synConstant">fReserved</span>',    BOOL),         <span class="synComment"># must be FALSE (really!)</span>
        ('<span class="synConstant">pszKeywords</span>',  c_tchar_p),    <span class="synComment"># semi-colon separated keywords</span>
        ('<span class="synConstant">pszUrl</span>',       c_tchar_p),    <span class="synComment"># URL to jump to if no keywords found (may be NULL)</span>
        ('<span class="synConstant">pszMsgText</span>',   c_tchar_p),    <span class="synComment"># Message text to display in MessageBox if pszUrl is NULL and no keyword match</span>
        ('<span class="synConstant">pszMsgTitle</span>',  c_tchar_p),    <span class="synComment"># Message text to display in MessageBox if pszUrl is NULL and no keyword match</span>
        ('<span class="synConstant">pszWindow</span>',    c_tchar_p),    <span class="synComment"># Window to display URL in</span>
        ('<span class="synConstant">fIndexOnFail</span>', BOOL)          <span class="synComment"># Displays index if keyword lookup fails.</span>
    ]


<span class="synStatement">if</span> winNT5OrLater:
    HtmlHelp = ctypes.windll.LoadLibrary('<span class="synConstant">hhctrl.ocx</span>').HtmlHelpW
<span class="synStatement">else</span>:
    HtmlHelp = ctypes.windll.LoadLibrary('<span class="synConstant">hhctrl.ocx</span>').HtmlHelpA


<span class="synStatement">def</span> <span class="synIdentifier">HtmlHelpDisplayTOC</span>(chmPath, data=None):
    u&#34;&#34;&#34;<span class="synConstant">指定されたヘルプウィンドウでヘルプトピックを開く</span>

<span class="synConstant">    引数  : chmPath - 文字列 - コンパイル済みヘルプまたはコンパイル済みヘルプ</span>
<span class="synConstant">            ファイル中のトピック</span>
<span class="synConstant">    引数  : data - 数値 - コンパイル済みヘルプファイル中のトピックへのポインタ</span>
<span class="synConstant">    戻り値: ヘルプウィンドウのハンドルを返す</span>&#34;&#34;&#34;
    <span class="synStatement">return</span> HtmlHelp(GetDesktopWindow(), _T(chmPath), HH_DISPLAY_TOC, data)

<span class="synStatement">def</span> <span class="synIdentifier">HtmlHelpKeywordLookup</span>(chmPath, kwd):
    u&#34;&#34;&#34;<span class="synConstant">コンパイル済みヘルプファイルからキーワードを検索する</span>

<span class="synConstant">    引数  : chmPath - 文字列 - コンパイル済みヘルプファイル</span>
<span class="synConstant">    引数  : kwd - 文字列 -  検索するキーワード</span>
<span class="synConstant">            複数の項目はセミコロン `;' で区切る</span>
<span class="synConstant">    戻り値: ヘルプウィンドウのハンドルを返す</span>&#34;&#34;&#34;
    aklnk = HH_AKLINK(ctypes.sizeof(HH_AKLINK), False, _T(kwd), None, None,
                      None, None, True)
    <span class="synStatement">return</span> HtmlHelp(GetDesktopWindow(), _T(chmPath), HH_KEYWORD_LOOKUP,
                    ctypes.byref(aklnk))

<span class="synStatement">def</span> <span class="synIdentifier">HtmlHelpCloseAll</span>():
    u&#34;&#34;&#34;<span class="synConstant">呼び出しプログラムによって開かれたヘルプウィンドウをすべて閉じる</span>

<span class="synConstant">    戻り値: なし</span>&#34;&#34;&#34;
    HtmlHelp(None, None, HH_CLOSE_ALL, 0)
</pre>

<h5>・ config.py</h5>
<p>で、↓ がconfig.pyの設定部分で、キーの割り当てとヘルプファイルのパス設定などを行います。</p>
<p>下記の例では<span style="font-weight:bold;" class="deco">メモ帳</span>で<span style="font-weight:bold;" class="deco">F1</span>を押すとPythonのヘルプファイル（<a href="http://sourceforge.jp/projects/pythonjp/releases/#6254" target="_blank">ダウンロード - Python Japanese Environment - SourceForge.JP</a>）を表示します。</p>
<pre class="syntax-highlight">
<span class="synComment"># config.py</span>

<span class="synPreProc">from</span> keyhac <span class="synPreProc">import</span> *

<span class="synStatement">def</span> <span class="synIdentifier">configure</span>(keymap):

    <span class="synComment">## 選択文字列をヘルプファイル(*.chm)から検索</span>
    <span class="synStatement">def</span> <span class="synIdentifier">select_word_help</span>():
        <span class="synStatement">def</span> <span class="synIdentifier">_select_word_help</span>():
            <span class="synComment"># ヘルプファイルのフルパス</span>
            chm_path = r&#34;<span class="synConstant">C:\Program Files\craftware\keyhac\Python26-DocJa1.chm</span>&#34;

            before = getClipboardText()

            <span class="synComment"># 選択文字列をコピー</span>
            copy_key = &#34;<span class="synConstant">C-c</span>&#34;
            keymap.command_InputKey(copy_key)()

            maxcnt = 10
            <span class="synStatement">while</span> maxcnt &#62; 0:
                maxcnt -= 1

                <span class="synComment"># クリップボードから文字列取り込み</span>
                select_word = getClipboardText()
                <span class="synStatement">if</span> select_word != before:
                    <span class="synStatement">break</span>

                <span class="synComment"># クリップボードの反映待ち</span>
                <span class="synPreProc">import</span> time
                time.sleep(0.1)

            <span class="synStatement">if</span> select_word:
                <span class="synPreProc">import</span> chm_viewer
                chm_viewer.HtmlHelpKeywordLookup(chm_path, select_word)

            <span class="synComment"># クリップボードを元の状態に戻して終わり</span>
            setClipboardText(before)

        <span class="synComment"># ホットキー経由での関数呼び出し</span>
        keymap.callHotKey(_select_word_help)

    <span class="synComment"># メモ帳のキーマップ</span>
    keymap_notepad = keymap.defineWindowKeymap(exe_name=u&#34;<span class="synConstant">notepad.exe</span>&#34;)

    keymap_notepad[&#34;<span class="synConstant">F1</span>&#34;] = select_word_help
</pre>

<h4><span style="font-weight:bold;" class="deco">■ さいごに</span></h4>
<p>この前コードを書いていたら、ふとVisual Studioみたいに普段使いのエディタでもヘルプ表示ができたらいいのになァと思い立ち、ちょっと調べてみたら、ほぼそのまま流用可能な<a href="http://d.hatena.ne.jp/pipehead/20071121/1195597559" target="_blank">こちらのエントリ</a>を見つけたので、設定してみました。よければどうぞ。</p>
<h4><span style="font-weight:bold;" class="deco">■ 参考リンク</span></h4>
<p><a href="http://sites.google.com/site/craftware/keyhac" target="_blank">keyhac - craftware</a></p>
<p><a href="http://d.hatena.ne.jp/pipehead/20071121/1195597559" target="_blank">HTML ヘルプを表示する - anonymous苦労者</a></p>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/w7g6OUmZGhD7q6sf7AV-8XNn-ME/0/da"><img src="http://feedads.g.doubleclick.net/~a/w7g6OUmZGhD7q6sf7AV-8XNn-ME/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/w7g6OUmZGhD7q6sf7AV-8XNn-ME/1/da"><img src="http://feedads.g.doubleclick.net/~a/w7g6OUmZGhD7q6sf7AV-8XNn-ME/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/Koonies/~4/k5j_F4sD8yE" height="1" width="1"/>]]></content:encoded>
<dc:creator>Koonies</dc:creator>
<dc:date>2011-08-28</dc:date>
<dc:subject>keyhac</dc:subject>
<feedburner:origLink>http://d.hatena.ne.jp/Koonies/20110828/keyhac_chm_viewer</feedburner:origLink></item>
<item rdf:about="http://d.hatena.ne.jp/Koonies/20110819/keyhac_aero_snap">
<title>[keyhac]keyhacでWindows7のエアロスナップをマネマネ。</title>
<link>http://feedproxy.google.com/~r/Koonies/~3/bPEcChD59Cs/keyhac_aero_snap</link>
<description> Windows7から導入されたエアロスナップ。要は画面左・右半分の最大化がマウス操作で簡単に実行できる機能です。ご存知ない方はこの30秒の動画を見てください。すごく便利な機能なんですが、僕の普段使いのPCはXP。当然エアロスナップなんてありません。 だったらkeyhacの出</description>

<content:encoded><![CDATA[
<div class="section">
<p><object width="307" height="250"><param name="movie" value="http://www.youtube.com/v/FoD4klJP6Zw"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/FoD4klJP6Zw" type="application/x-shockwave-flash" wmode="transparent" width="307" height="250" FlashVars="movie_url=http://d.hatena.ne.jp/video/youtube/FoD4klJP6Zw"></embed></object>
<a href="http://d.hatena.ne.jp/video/youtube/FoD4klJP6Zw" alt="この動画を含む日記"><img src="http://d.hatena.ne.jp/images/d_entry.gif" alt="D" border="0" style="vertical-align: bottom;" title="この動画を含む日記"></a>Windows7から導入されたエアロスナップ。要は画面左・右半分の最大化がマウス操作で簡単に実行できる機能です。ご存知ない方はこの30秒の動画を見てください。すごく便利な機能なんですが、僕の普段使いのPCはXP。当然エアロスナップなんてありません。</p>
<p>だったら<span style="font-weight:bold;" class="deco"><a href="http://sites.google.com/site/craftware/keyhac" target="_blank">keyhac</a></span>の出番です。本家にない上半分・下半分も出来ちゃいます。ついでに移動、リサイズも紹介しときます。</p>
<h4><span style="font-weight:bold;" class="deco">■ コード</span></h4>
<pre class="syntax-highlight">
<span class="synPreProc">from</span> keyhac <span class="synPreProc">import</span> *

<span class="synComment">## 関数を返す関数にするデコレータ</span>
<span class="synStatement">def</span> <span class="synIdentifier">ret_func</span>(func):
    <span class="synPreProc">import</span> functools

    <span class="synPreProc">@</span><span class="synIdentifier">functools</span>.wraps(func)
    <span class="synStatement">def</span> <span class="synIdentifier">_ret_func</span>(*args, **kw):
        <span class="synPreProc">@</span><span class="synIdentifier">functools</span>.wraps(func)
        <span class="synStatement">def</span> <span class="synIdentifier">__ret_func</span>():
            <span class="synStatement">return</span> func(*args, **kw)
        <span class="synStatement">return</span> __ret_func
    <span class="synStatement">return</span> _ret_func

<span class="synStatement">def</span> <span class="synIdentifier">configure</span>(keymap):

    <span class="synComment">## 10pixel単位のウインドウのリサイズ（最大最小のときは何もしない）</span>
    <span class="synComment">#</span>
    <span class="synPreProc">@</span><span class="synIdentifier">ret_func</span>
    <span class="synStatement">def</span> <span class="synIdentifier">resize_window</span>(direction):
        <span class="synStatement">if</span> <span class="synStatement">not</span> keymap.getTopLevelWindow().isMaximized():
            i = &#34;<span class="synConstant">LRUD</span>&#34;.find(direction)
            dx, dy = ((-10, 0),  <span class="synComment"># L</span>
                      (+10, 0),  <span class="synComment"># R</span>
                      (0, -10),  <span class="synComment"># U</span>
                      (0, +10)   <span class="synComment"># D</span>
                     )[i]

            wnd = keymap.getTopLevelWindow()
            rect = list(wnd.getRect())
            rect[2] += dx
            rect[3] += dy
            wnd.setRect(rect)

    <span class="synComment">## 10pixel単位のウインドウの移動（最大最小のときは何もしない）</span>
    <span class="synComment">#</span>
    <span class="synPreProc">@</span><span class="synIdentifier">ret_func</span>
    <span class="synStatement">def</span> <span class="synIdentifier">move_window</span>(direction):
        <span class="synStatement">if</span> <span class="synStatement">not</span> keymap.getTopLevelWindow().isMaximized():
            i = &#34;<span class="synConstant">LRUD</span>&#34;.find(direction)
            dx, dy = ((-10, 0),  <span class="synComment"># L</span>
                      (+10, 0),  <span class="synComment"># R</span>
                      (0, -10),  <span class="synComment"># U</span>
                      (0, +10)   <span class="synComment"># D</span>
                     )[i]

            <span class="synComment"># keyhac_keymap.py 定義の関数を利用</span>
            keymap.command_MoveWindow(dx, dy)()

    <span class="synComment">## ウィンドウを画面端まで移動（最大最小のときは何もしない）</span>
    <span class="synComment">#</span>
    <span class="synPreProc">@</span><span class="synIdentifier">ret_func</span>
    <span class="synStatement">def</span> <span class="synIdentifier">move_window_monitoredge</span>(direction):
        <span class="synStatement">if</span> <span class="synStatement">not</span> keymap.getTopLevelWindow().isMaximized():
            i = &#34;<span class="synConstant">LURD</span>&#34;.find(direction)
            <span class="synComment"># keyhac_keymap.py 定義の関数を利用</span>
            keymap.command_MoveWindow_MonitorEdge(i)()

    <span class="synComment">## 画面半分の切り替え（Windows7のエアロスナップ風）</span>
    <span class="synComment">#</span>
    <span class="synPreProc">@</span><span class="synIdentifier">ret_func</span>
    <span class="synStatement">def</span> <span class="synIdentifier">toggle_aero_snap</span>(direction):
        wnd = keymap.getTopLevelWindow()
        <span class="synStatement">if</span> wnd.isMaximized():
            <span class="synComment"># 元に戻す</span>
            wnd.restore()
        <span class="synStatement">else</span>:
            <span class="synComment"># 最大化</span>
            wnd.maximize()

            <span class="synComment"># ウィンドウのサイズを取得</span>
            rect = list(wnd.getRect())

            <span class="synComment"># ウィンドウの幅/高さの半分</span>
            width_50 = (rect[0] + rect[2]) / 2
            height50 = (rect[1] + rect[3]) / 2

            <span class="synComment"># 入力された方向に応じて対応する座標を幅/高さの半分で上書き</span>
            i = &#34;<span class="synConstant">RDLU</span>&#34;.find(direction)
            rect[i] = (width_50,  <span class="synComment"># R</span>
                       height50,  <span class="synComment"># D</span>
                       width_50,  <span class="synComment"># L</span>
                       height50   <span class="synComment"># U</span>
                      )[i]

            <span class="synComment"># ウィンドウの新しいサイズを反映</span>
            wnd.setRect(rect)

    <span class="synComment"># どのウインドウにフォーカスがあっても効くキーマップ</span>
    keymap_global = keymap.defineWindowKeymap()

    <span class="synComment">## ウィンドウ移動系</span>
    <span class="synStatement">for</span> arrow_key <span class="synStatement">in</span> (&#34;<span class="synConstant">Left</span>&#34;, &#34;<span class="synConstant">Right</span>&#34;, &#34;<span class="synConstant">Up</span>&#34;, &#34;<span class="synConstant">Down</span>&#34;):
        c = arrow_key[:1]

        <span class="synComment"># Win+←→↑↓ : 10pixel単位のウインドウの移動</span>
        keymap_global[&#34;<span class="synConstant">W-</span>&#34; + arrow_key] = move_window(c)
        <span class="synComment"># Win+Ctrl+←→↑↓ : 画面の端まで移動</span>
        keymap_global[&#34;<span class="synConstant">W-C-</span>&#34; + arrow_key] = move_window_monitoredge(c)
        <span class="synComment"># Win+Shift+←→↑↓ : 10pixel単位のウインドウのリサイズ</span>
        keymap_global[&#34;<span class="synConstant">W-S-</span>&#34; + arrow_key] = resize_window(c)
        <span class="synComment"># Win+Alt+←→↑↓ : Windows7のエアロスナップ風</span>
        keymap_global[&#34;<span class="synConstant">W-A-</span>&#34; + arrow_key] = toggle_aero_snap(c)
</pre>

<h4><span style="font-weight:bold;" class="deco">■ 軽〜く説明</span></h4>

<table>
<tr><td>Win+←→↑↓</td><td>10pixel単位のウインドウの移動</td></tr>
<tr><td>Win+Ctrl+←→↑↓</td><td>画面の端まで移動</td></tr>
<tr><td>Win+Shift+←→↑↓</td><td>10pixel単位のウインドウのリサイズ</td></tr>
<tr><td>Win+Alt+←→↑↓</td><td>Windows7のエアロスナップ風</td></tr>

</table>
<h4><span style="font-weight:bold;" class="deco">■ 参考リンク</span></h4>
<p><iframe marginwidth="0" marginheight="0" src="http://b.hatena.ne.jp/entry.parts?url=http%3A%2F%2Fsites%2Egoogle%2Ecom%2Fsite%2Fcraftware%2Fkeyhac" scrolling="no" frameborder="0" height="230" width="500"><div class="hatena-bookmark-detail-info"><a href="http://sites.google.com/site/craftware/keyhac">keyhac - craftware</a><a href="http://b.hatena.ne.jp/entry/http%3A%2F%2Fsites%2Egoogle%2Ecom%2Fsite%2Fcraftware%2Fkeyhac">はてなブックマーク- keyhac - craftware</a></div></iframe></p>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/r9IyZlNeXt3R77eyj9QUb9gC6Qs/0/da"><img src="http://feedads.g.doubleclick.net/~a/r9IyZlNeXt3R77eyj9QUb9gC6Qs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/r9IyZlNeXt3R77eyj9QUb9gC6Qs/1/da"><img src="http://feedads.g.doubleclick.net/~a/r9IyZlNeXt3R77eyj9QUb9gC6Qs/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/Koonies/~4/bPEcChD59Cs" height="1" width="1"/>]]></content:encoded>
<dc:creator>Koonies</dc:creator>
<dc:date>2011-08-19</dc:date>
<dc:subject>keyhac</dc:subject>
<feedburner:origLink>http://d.hatena.ne.jp/Koonies/20110819/keyhac_aero_snap</feedburner:origLink></item>
<item rdf:about="http://d.hatena.ne.jp/Koonies/20110818/keyhac_double_key_ime">
<title>[keyhac]keyhacで[半角/全角]キーの1回・2回押しでIME OFF・ONを切り替える</title>
<link>http://feedproxy.google.com/~r/Koonies/~3/sI4LTYOWU6I/keyhac_double_key_ime</link>
<description> またまたkeyhacでのカスタマイズネタについて。IMEのON/OFFはいつまで経っても大して使い勝手が良くならない。どうゆうことかと言うと文字をタイプし始めてから「あ！半角のままだった……」と気づきIMEをONにして漢字入力する。またその逆も。 これは[半角/全角]キーがトグ</description>

<content:encoded><![CDATA[
<div class="section">
<p>またまた<a href="https://sites.google.com/site/craftware/keyhac" target="_blank">keyhac</a>でのカスタマイズネタについて。IMEのON/OFFはいつまで経っても大して使い勝手が良くならない。どうゆうことかと言うと文字をタイプし始めてから「あ！半角のままだった……」と気づきIMEをONにして漢字入力する。またその逆も。</p>
<p>これは<span style="font-weight:bold;" class="deco">[半角/全角]キー</span>がトグルスイッチになっているためで、いまどちらの状態にあるのかを把握せずにON/OFFできるようになれば大幅に打ち損じが減るんじゃないかと思いついた。つまり……</p>
<h5>★ 現状</h5>
<p><span style="font-weight:bold;" class="deco">IME OFF</span>の状態でキーを押すとIMEが<span style="font-weight:bold;" class="deco">ON</span>、<span style="font-weight:bold;" class="deco">ON</span>のときに押すと<span style="font-weight:bold;" class="deco">OFF</span>になる。</p>
<h5>★ 変更後</h5>
<p><span style="font-weight:bold;" class="deco">1回ポン</span>っと押すと<span style="font-weight:bold;" class="deco">IMEをOFF</span>、ダブルクリックのようにタタンっと<span style="font-weight:bold;" class="deco">2回連続押し</span>だと<span style="font-weight:bold;" class="deco">IMEがON</span>になる。</p>
<p>これをkeyhacで実現するのが、以下のスクリプトです。</p>
<h4><span style="font-weight:bold;" class="deco">■ コード</span></h4>
<pre class="syntax-highlight">
<span class="synPreProc">from</span> keyhac <span class="synPreProc">import</span> *

<span class="synStatement">def</span> <span class="synIdentifier">configure</span>(keymap):

    <span class="synComment">## IMEを切り替える</span>
    <span class="synComment">#</span>
    <span class="synComment">#  @param flag      切り替えフラグ（True:IME ON / False:IME OFF）</span>
    <span class="synComment">#</span>
    <span class="synStatement">def</span> <span class="synIdentifier">switch_ime</span>(flag):

        <span class="synComment"># バルーンヘルプを表示する時間(ミリ秒)</span>
        BALLOON_TIMEOUT_MSEC = 500

        <span class="synComment"># if not flag:</span>
        <span class="synStatement">if</span> flag:
            ime_status = 1
            message = u&#34;<span class="synConstant">[あ]</span>&#34;
        <span class="synStatement">else</span>:
            ime_status = 0
            message = u&#34;<span class="synConstant">[_A]</span>&#34;

        <span class="synComment"># IMEのON/OFFをセット</span>
        keymap.wnd.setImeStatus(ime_status)
        <span class="synComment"># IMEの状態をバルーンヘルプで表示</span>
        keymap.popBalloon(&#34;<span class="synConstant">ime_status</span>&#34;, message, BALLOON_TIMEOUT_MSEC)

    <span class="synComment">## キーの1回/2回押しで引数の関数コールを切り替える</span>
    <span class="synComment">#</span>
    <span class="synComment">#  @param func      コールする関数</span>
    <span class="synComment">#</span>
    <span class="synComment">#  引数の func は1回押しなら func(True)、2回連続押しなら func(False)</span>
    <span class="synComment">#  でコールされる</span>
    <span class="synComment">#</span>
    <span class="synStatement">def</span> <span class="synIdentifier">double_key</span>(func, cache_t={}):

        <span class="synComment"># 2回連続押し判断の許容間隔(ミリ秒)</span>
        TIMEOUT_MSEC = 500

        func_name = func.__name__

        <span class="synComment"># 前回時刻</span>
        t0 = 0
        <span class="synStatement">if</span> func_name <span class="synStatement">in</span> cache_t:
            t0 = cache_t[func_name]
        <span class="synComment"># 現在時刻を保存</span>
        <span class="synPreProc">import</span> time
        cache_t[func_name] = time.clock()
        <span class="synComment"># 前回実行からの経過時間(ミリ秒)</span>
        delta_t = (cache_t[func_name] - t0) * 1000

        <span class="synComment"># 関数コール</span>
        <span class="synStatement">if</span> delta_t &#62; TIMEOUT_MSEC:
            func(False)     <span class="synComment"># 1回押し</span>
        <span class="synStatement">else</span>:
            func(True)      <span class="synComment"># 2回連続押し</span>

    keymap_global = keymap.defineWindowKeymap()

    <span class="synStatement">if</span> 1:   <span class="synComment"># [半角／全角]</span>
        keymap_global[&#34;<span class="synConstant">U-(243)</span>&#34;] = <span class="synStatement">lambda</span>: double_key(switch_ime)  <span class="synComment"># 押す</span>
        keymap_global[&#34;<span class="synConstant">D-(243)</span>&#34;] = <span class="synStatement">lambda</span>: None                    <span class="synComment"># 離す</span>
        keymap_global[&#34;<span class="synConstant">U-(244)</span>&#34;] = <span class="synStatement">lambda</span>: double_key(switch_ime)  <span class="synComment"># 押す</span>
        keymap_global[&#34;<span class="synConstant">D-(244)</span>&#34;] = <span class="synStatement">lambda</span>: None                    <span class="synComment"># 離す</span>

    <span class="synStatement">if</span> 0:   <span class="synComment"># [変換]</span>
        keymap_global[&#34;<span class="synConstant">S-(28)</span>&#34;] = &#34;<span class="synConstant">(28)</span>&#34;            <span class="synComment"># Shift+[変換]で再変換</span>
        keymap_global[&#34;<span class="synConstant">(28)</span>&#34;] = <span class="synStatement">lambda</span>: double_key(switch_ime)

    <span class="synStatement">if</span> 0:   <span class="synComment"># [無変換]</span>
        keymap_global[&#34;<span class="synConstant">(29)</span>&#34;] = <span class="synStatement">lambda</span>: double_key(switch_ime)
</pre>

<p>↑ [変換]・[無変換]キーがいい場合は、if 1 に変更してください。</p>
<h4><span style="font-weight:bold;" class="deco">■ さいごに</span></h4>
<p>慣れれば便利だと思うので、よかったら使ってみてください！</p>
<h4><span style="font-weight:bold;" class="deco">■ 参考リンク</span></h4>
<p><iframe marginwidth="0" marginheight="0" src="http://b.hatena.ne.jp/entry.parts?url=http%3A%2F%2Fsites%2Egoogle%2Ecom%2Fsite%2Fcraftware%2Fkeyhac" scrolling="no" frameborder="0" height="230" width="500"><div class="hatena-bookmark-detail-info"><a href="http://sites.google.com/site/craftware/keyhac">keyhac - craftware</a><a href="http://b.hatena.ne.jp/entry/http%3A%2F%2Fsites%2Egoogle%2Ecom%2Fsite%2Fcraftware%2Fkeyhac">はてなブックマーク- keyhac - craftware</a></div></iframe></p>
</div>

<p><a href="http://feedads.g.doubleclick.net/~a/TrZu68oH0msTRfO1F5uu2zwDmO4/0/da"><img src="http://feedads.g.doubleclick.net/~a/TrZu68oH0msTRfO1F5uu2zwDmO4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/TrZu68oH0msTRfO1F5uu2zwDmO4/1/da"><img src="http://feedads.g.doubleclick.net/~a/TrZu68oH0msTRfO1F5uu2zwDmO4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/Koonies/~4/sI4LTYOWU6I" height="1" width="1"/>]]></content:encoded>
<dc:creator>Koonies</dc:creator>
<dc:date>2011-08-18</dc:date>
<dc:subject>keyhac</dc:subject>
<feedburner:origLink>http://d.hatena.ne.jp/Koonies/20110818/keyhac_double_key_ime</feedburner:origLink></item>
</rdf:RDF>

