Hatena::ブログ(Diary)

Koonies/こりゃいいな! このページをアンテナに追加 RSSフィード

2009 | 06 | 07 | 08 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 10 |
2011 | 01 | 02 | 05 | 06 | 07 | 08 | 09 |
2012 | 05 | 06 |

2012-05-11

Koonies2012-05-11

TortoiseHgでAmendを使うと2つ前のコミットをやり直せる

TortoiseHgはバージョン管理ソフトMercurialWindowsフロントエンドで、つい先日にリリースされた最新版v2.4でAmendというコマンドが追加されました。Amendを使えば、お手軽に直前のコミットをやり直すことが可能になります。

以前のバージョンでもロールバックして、コミットし直せば同様のことが可能だった訳ですが、実際の操作手順としてはAmendを使った方がコミットのメッセージコピーする必要もないため地味に便利です。リリースされてからまだ数日ですが、既に何度もお世話になってます。

さてタイトルにも書いた「2つ前」の修正の話。

これまでは「1つ前」の修正ならロールバック、それ以上前の修正をやりたい場合はMQなどのエクステンションを使う必要がありました。

最新版では「1つ前」の修正ならロールバックまたはAmendのどちらでもOKになりました。という事はロールバックして、更にAmendすれば「2つ前」を修正できる??という疑問が湧いてきますよね。それで試してみたら、本当に出来ました

手順

1. まずはロールバック

2. 直前の変更点をシェルフ待避

3. コミットの画面にする

4. コミットボタンの隣の▼をクリックし、"Amend current revision"をクリック*1

5. するとボタン表示がコミット→Amendに変わり、「2つ前」のコミットメッセージが表示されるので、修正してAmendボタンをクリック

6. シェルフで待避した変更点を戻し、あとは普通にコミットをやり直す。

さいごに

Mercurialでも同様のことが出来そうな気がしますね。試してないけど。それでは。

*1:ただしAmendはMQエクステンションが有効でないと使用できないみたいなので注意!

2011-08-28

keyhacでテキストエディタのF1キーに任意のヘルプファイルのキーワード表示に関連づける

またまたkeyhacでのカスタマイズネタテキストエディタプログラムを書いていると、そのプログラム言語ヘルプファイルが見たいってことがしばしばあります。そんなときに役立つ設定です。

■ 使い方

使い方はカンタン。テキストエディタ上で調べたい単語を選択しF1を押します。

そうすれば設定しておいたchm形式のヘルプファイルからキーワード検索し、その項目を表示します。

コード

・ chm_viewer.py

まずは↓の部分をchm_viewer.pyという名前保存し、extensionフォルダに置いてください。

# chm_viewer.py
# http://d.hatena.ne.jp/pipehead/20071121/1195597559 のCraftLaunchEx用コードをほぼそのまま利用

# Windows 2000/XP では Unicode 版 (HtmlHelpW) を使用し、2000/XP 以外では ANSI 版 (HtmlHelpA) を使用します。
def _IsWinNT5OrLater():
    import sys

    (major, platform) = sys.getwindowsversion()[0:4:3]
    # VER_PLATFORM_WIN32_NT: 2
    return ((platform == 2) and (major >= 5))

winNT5OrLater = _IsWinNT5OrLater()


def _T(string):
    if isinstance(string, str):
        string = unicode(string, 'utf-8')
    if not winNT5OrLater:
        return string.encode('mbcs')
    return string


import ctypes

class c_tchar_p(ctypes._SimpleCData):
    if winNT5OrLater:
        _type_ = 'Z' # c_wchar_p
    else:
        _type_ = 'z' # c_char_p


# WinUser.h
GetDesktopWindow = ctypes.windll.user32.GetDesktopWindow


# HtmlHelp.h
HH_DISPLAY_TOC    = 0x0001
HH_KEYWORD_LOOKUP = 0x000D
HH_CLOSE_ALL      = 0x0012


from ctypes.wintypes import BOOL

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


if winNT5OrLater:
    HtmlHelp = ctypes.windll.LoadLibrary('hhctrl.ocx').HtmlHelpW
else:
    HtmlHelp = ctypes.windll.LoadLibrary('hhctrl.ocx').HtmlHelpA


def HtmlHelpDisplayTOC(chmPath, data=None):
    u"""指定されたヘルプウィンドウでヘルプトピックを開く

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

def HtmlHelpKeywordLookup(chmPath, kwd):
    u"""コンパイル済みヘルプファイルからキーワードを検索する

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

def HtmlHelpCloseAll():
    u"""呼び出しプログラムによって開かれたヘルプウィンドウをすべて閉じる

    戻り値: なし"""
    HtmlHelp(None, None, HH_CLOSE_ALL, 0)
config.py

で、↓ がconfig.pyの設定部分で、キーの割り当てとヘルプファイルのパス設定などを行います。

下記の例ではメモ帳F1を押すとPythonのヘルプファイル(ダウンロードファイル一覧 - Python Japanese Environment - OSDN)を表示します。

# config.py

from keyhac import *

def configure(keymap):

    ## 選択文字列をヘルプファイル(*.chm)から検索
    def select_word_help():
        def _select_word_help():
            # ヘルプファイルのフルパス
            chm_path = r"C:\Program Files\craftware\keyhac\Python26-DocJa1.chm"

            before = getClipboardText()

            # 選択文字列をコピー
            copy_key = "C-c"
            keymap.command_InputKey(copy_key)()

            maxcnt = 10
            while maxcnt > 0:
                maxcnt -= 1

                # クリップボードから文字列取り込み
                select_word = getClipboardText()
                if select_word != before:
                    break

                # クリップボードの反映待ち
                import time
                time.sleep(0.1)

            if select_word:
                import chm_viewer
                chm_viewer.HtmlHelpKeywordLookup(chm_path, select_word)

            # クリップボードを元の状態に戻して終わり
            setClipboardText(before)

        # ホットキー経由での関数呼び出し
        keymap.callHotKey(_select_word_help)

    # メモ帳のキーマップ
    keymap_notepad = keymap.defineWindowKeymap(exe_name=u"notepad.exe")

    keymap_notepad["F1"] = select_word_help

■ さいごに

この前コードを書いていたら、ふとVisual Studioみたいに普段使いのエディタでもヘルプ表示ができたらいいのになァと思い立ち、ちょっと調べてみたら、ほぼそのまま流用可能なこちらのエントリを見つけたので、設定してみました。よければどうぞ。

■ 参考リンク

ページが見つかりませんでした - craftware

HTML ヘルプを表示する - anonymous苦労者

2011-08-09

keyhacでカラーピッカー(画面上の任意の場所から色コード取得)

20110808232618現在はまっているkeyhac*1Win+Cを押すとマウスカーソル位置の色コードを取得し、クリップボードコピーするようにしてみました。

■ コード

from keyhac import *

def configure(keymap):

    ## バルーンヘルプ(ツールチップ)を指定の位置に開く
    #
    # keyhac_keymap.py / popBalloon() を流用
    #
    def pop_balloon(name, text, timeout=None, pos=None):
        if pos == None:
            # オフセット量
            OFFSET_X = 0
            OFFSET_Y = -20

            # マウスカーソルの位置を取得
            pos_x, pos_y = pyauto.Input.getCursorPos()
            pos_x += OFFSET_X
            pos_y += OFFSET_Y
        else:
            pos_x, pos_y = pos

        keymap.balloon.setText(pos_x, pos_y, text)

        if keymap.balloon_timer:
            keymap.killTimer(keymap.balloon_timer)
            keymap.balloon_timer = None

        if timeout:
            def onTimerCloseBalloon():
                keymap.closeBalloon(name)
            keymap.balloon_timer = onTimerCloseBalloon
            keymap.setTimer(keymap.balloon_timer, timeout)

        keymap.balloon_name = name

    ## カーソル位置のRGB情報取得
    def color_picker():
        root = pyauto.Window.getDesktop()
        img = root.getImage()

        width, height = img.getSize()
        x, y = pyauto.Input.getCursorPos()

        if not (0 <= x < width and 0 <= y < height):
            rgb = u"範囲外"
        else:
            start = (width * y + x) * 3
            buf = img.getBuffer()[start:start + 3]
            r, g, b = [ord(c) for c in buf]

            if 0:  # 10進表記
                rgb = u"(%d,%d,%d)" % (r, g, b)
            else:  # 16進表記
                hex_24_bit = lambda val: u"#%06X" % val
                rgb = hex_24_bit((0x10000 * r) + (0x100 * g) + b)

        pop_balloon("color_picker", rgb, 1500)
        setClipboardText(rgb)
        print rgb

    keymap_global = keymap.defineWindowKeymap()

    # カーソル位置のRGB情報取得
    keymap_global["W-c"] = color_picker

■ さいごに

カーソル位置の色を取得するAutoHotkeyスクリプト - Hail2uに触発され書いてみました。このリンク先とは違って取得するカラーコードは16進表記になっています。もし10進表記の方がよければコードの中の「if 0:」を「if 1:」へ変更してからお使い下さい。

■ 参考リンク

*1:Autohotkeyみたいなフリーソフトで、Pythonコードで色んなソフトのショートカットキーを設定できる

2011-08-08

keyhacでクリップボード内のJavaScriptコードを整形/圧縮(JSBeautifier/SlimIt)

JavaScriptをさわってる人ならご存知の人も結構いそうなOnline JavaScript beautifier。JavaScriptコードを見やすく整形してくれるWebサービスです。

僕はブックマークレットを作る際など便利でよく使っているのですが、サイトを見てるとコマンドラインバージョンということでPythonコードでも公開されていました。探したらSlimItという圧縮する方も発見。

keyhac*1クリップボード内のテキストに対して直接実行できたら便利だろうなと書いたのが ↓ のコード。

Win+Jで整形、Win+Sift+Jで高圧縮、Win+Ctrl+Jで低圧縮、というキー配置にしています。

from keyhac import *

## 関数を返す関数にするデコレータ
def ret_func(func):
    import functools

    @functools.wraps(func)
    def _ret_func(*args, **kw):
        @functools.wraps(func)
        def __ret_func():
            return func(*args, **kw)
        return __ret_func
    return _ret_func

## JobQueue/JobItem でサブスレッド処理にするデコレータ
def job_queue(func):
    import functools

    @functools.wraps(func)
    def _job_queue(*args, **kw):

        num_items = JobQueue.defaultQueue().numItems()
        if num_items:   # 処理待ちアイテムがある場合は、その数を表示
            print u"JobQueue.defaultQueue().numItems() :", num_items

        def __job_queue_1(job_item):
            return func(*args, **kw)

        def __job_queue_2(job_item):
            # print "job_queue : ", func.__name__, args, kw
            pass

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

    return _job_queue

## JavaScriptコードを整形
# JSBeautifier : http://jsbeautifier.org/
@job_queue
def jsbeautifier():
    import jsbeautifier
    clipboard_text = getClipboardText()
    if clipboard_text:
        js_options = jsbeautifier.default_options()

        js_options.jslint_happy = True
        new_code = jsbeautifier.beautify(clipboard_text, js_options)

        setClipboardText(new_code)
        print
        print "/*  jsbeautifier  */"
        print "// before --------------------"
        print clipboard_text
        print "// after --------------------"
        print new_code

## JavaScriptコードを圧縮
# SlimIt : http://slimit.org/
# PLY : http://www.dabeaz.com/ply/
@ret_func
@job_queue
def jsminify(mangle=False):
    import slimit
    clipboard_text = getClipboardText()
    if clipboard_text:
        new_code = slimit.minify(clipboard_text, mangle)

        setClipboardText(new_code)
        print
        print "/*  SlimIt (mangle=%s)  */" % mangle
        print "// before --------------------", len(clipboard_text), "byte"
        print clipboard_text
        print "// after --------------------", len(new_code), "byte"
        print new_code

def configure(keymap):

    keymap_global = keymap.defineWindowKeymap()

    # JavaScriptコードを整形
    keymap_global["W-j"] = jsbeautifier

    # JavaScriptコードを圧縮(高圧縮)
    keymap_global["W-S-j"] = jsminify(mangle=True)

    # JavaScriptコードを圧縮(低圧縮)
    keymap_global["W-C-j"] = jsminify(mangle=False)

■ ライブラリのインストール

・JSBeautifier

https://github.com/einars/js-beautify/raw/master/python/jsbeautifier.py

↑ のファイルをkeyhacのextensionフォルダコピーする。

・SlimItとPLY(コード解析)

https://github.com/rspivak/slimit

圧縮ファイルをダウンロードし、圧縮ファイルのsrcフォルダ下にslimitをフォルダごとkeyhacのextensionフォルダへコピーする。

http://www.dabeaz.com/ply/

圧縮ファイルをダウンロードし、圧縮ファイルのplyをフォルダごとkeyhacのextensionフォルダへコピーする。

■ さいごに

ブックマークレットをよく書くという方は特に便利だと思うので、よかったら使ってみてください。

■ 参考リンク

*1:Autohotkeyみたいなフリーソフトで、Pythonコードで色んなソフトのショートカットキーを設定できる

2011-06-18

PCで音楽再生中に一時停止し、ちょっとしたら自動再開させる方法

ゴールデンウィークあたりからkeyhacというソフトでのカスタマイズにハマっています。

これで何ができるかというと、ソフトの名前(キーハック)のとおりいろんなソフトのショートカットキーをハックできてしまうのです。

ショートカットキーといえばCtrl+CのコピーとかCtrl+Vの貼り付けが有名どころですが、これらのキーと同じようなやつをユーザー側で定義して、勝手にショートカットキーを後付けしてしまおうというソフトな訳です。

で、その定義方法はLL言語Pythonで記述するようになっています。これが良い。すごく良い。

Pythonはまだ始めたばかり(条件文や関数のあとの:をしょっちゅう忘れるくらい)ですが、基本的にシンプルな言語なので書いてて楽しい。この処理よく使うな、よし定義だ、みたいな。

で、前置きが長くなったんですが、「Windows Media Playerとかで音楽再生中に一時停止し、5分したら自動再開させる」という「Alt+Shift+P」で実行させるためのスクリプト。

from keyhac import *

def configure(keymap):

    def music_pause_and_play():

        def job_music_pause_and_play(job_item):
            import time
            keymap.command_InputKey("(%d)" % VK_MEDIA_PLAY_PAUSE)()
            time.sleep(5 * 60)  # [sec]
            keymap.command_InputKey("(%d)" % VK_MEDIA_PLAY_PAUSE)()

        job_item = JobItem(job_music_pause_and_play)
        JobQueue.defaultQueue().enqueue(job_item)

    keymap_global = keymap.defineWindowKeymap()
    keymap_global["Alt-Shift-P"] = music_pause_and_play

ちなみに

            keymap.command_InputKey("(%d)" % VK_MEDIA_PLAY_PAUSE)()

の部分は、以下のように書き換えても同様に動作します。(多分 ↓ こっちの方が処理は軽い)

            pyauto.Input.send([pyauto.Key(VK_MEDIA_PLAY_PAUSE)])

なお、上記のスクリプトは、『no title』でAutoHotkey*1を使った方法として紹介されていてナルホドな〜、と思ったのでkeyhacでもやってみました。

PCで音楽を聴いているところに電話がかかってきたときに便利ですね。

(とっさにAlt+Shift+Pは個人的にはちょっと押しにくい気もするけど)

そんな訳でkeyhacおすすめです。WindowsユーザーでPythonに興味のある方は是非。また何か思いついたら書きたいと思います。

*1keyhacと同様のショートカットキー定義ソフト、こっちの方が有名だが独自言語に馴染めなかった

2009 | 06 | 07 | 08 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 10 |
2011 | 01 | 02 | 05 | 06 | 07 | 08 | 09 |
2012 | 05 | 06 |
日記の検索

ads
最近のコメント
etc
あわせて読みたいブログパーツ