2011年11月27日日曜日

[Emacs] VS風1行コピー、切り取り、貼りつけ

Visual Studioのようにリージョン選択中でない時にM-wやC-wした時に、それぞれ1行コピー、切り取りになるようにしたいなぁと思って探してた。

ここで見つけたので使いやすいようにちょっとだけ変更した。

http://www.emacswiki.org/emacs/?action=browse;oldid=SlickCopy;id=WholeLineOrRegion

(defadvice copy-region-as-kill (around slick-copy activate)
"When called interactively with no active region, copy a single line instead."
(if (or (use-region-p) (not (called-interactively-p)))
ad-do-it
(kill-new (buffer-substring (line-beginning-position)
(line-beginning-position 2))
nil '(yank-line))
(message "Copied line")))
(defadvice kill-region (around slick-copy activate)
"When called interactively with no active region, kill a single line instead."
(if (or (use-region-p) (not (called-interactively-p)))
ad-do-it
(kill-new (filter-buffer-substring (line-beginning-position)
(line-beginning-position 2) t)
nil '(yank-line))))
(defun yank-line (string)
"Insert STRING above the current line."
(save-excursion
(beginning-of-line)
(unless (= (elt string (1- (length string))) ?\n)
(save-excursion (insert "\n")))
(insert string)))

これで行の複製もM-w C-yでできるようになったので便利やわー。

アドバイスとかyank-handlerとか全然知らなかったのでEmacs Lispの勉強にもなった。

2011年9月24日土曜日

Visual Studioの1つのプロジェクトで32ビットと64ビットの両方をターゲットにする

ネイティブなDLLを使って32ビットと64ビット対応のアプリケーションを作る場合、コードは同じだが参照するDLLのパスが違うだけという場合があると思います。例えばSystem.Data.SQLite.dllなど。

Visual Studioのプロジェクトの構成でx86やx64を選んでプラットフォームを変えた時に参照するDLLも同時に変える方法がhttp://stackoverflow.com/questions/145803/targeting-both-32bit-and-64bit-with-visual-studio-in-same-solution-projectに載ってました。

英語だし本筋と関係ない議論もあるので、必要なところだけまとめときます。

以下ではSQLite.dllを使い分ける例を示します。

まずx86構成でプロジェクトを作り、32ビット版のSQLite.dllを参照に加えます。

VSを一旦終了させ、上記のプロジェクトの構成ファイル*.csprojを開くと以下のようになっています。

...
<ItemGroup>
<Reference>...</Reference>
<Reference>...</Reference>
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\System.Data.SQLite.DLL</HintPath>
</Reference>
<Reference>...</Reference>
</ItemGroup>
...

ItemGroup要素の中にプロジェクトの参照設定がずらっと並んでいます。HintPathがDLLのパスです。

ここでSQLite.DLLを条件付きのItemGroupでくくって外に出してやります。

<ItemGroup Condition=" '$(Platform)' == 'x86' ">
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\System.Data.SQLite.DLL</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition=" '$(Platform)' == 'x64' ">
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\x64\System.Data.SQLite.DLL</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference>...</Reference>
<Reference>...</Reference>
<Reference>...</Reference>
</ItemGroup>

こんな風にItemGroup要素を複数定義します。

そしてVSを再起動すると「参照コンポーネント ‘System.Data.SQLite’ が見つかりませんでした」という警告が出ますが、無視してビルドしてみるとプラットフォームの設定毎に適切なDLLがちゃんとロードされます。

2011年9月20日火曜日

iTunesで特定の歌詞が含まれている曲の歌詞を削除する

まず特定の歌詞が含まれている曲を集めて1つのプレイリストにしたい。

普通に探すとたぶん以下のスクリプトが最初に見つかるだろう。

tell application "iTunes"
display dialog "歌詞の一部を入力してください" default answer "" buttons {"Cancel", "OK"} default button 2
copy the result as list to {text_returned, button_pressed}

set thePlaylist to make new playlist with properties {name:text_returned}
with timeout of 60000 seconds
duplicate (every track of playlist "洋楽" whose lyrics contains text_returned) to thePlaylist
end timeout
end tell

ところが上記スクリプトだとなぜかうまくいかない(ほんとは含まれているのに見つけてくれない)。

他のスクリプトを探すとhttp://aurelio.net/soft/itunes-search-in-lyrics/が見つかった。

スクリプトをダウンロードして眺めてみたが、どうやら

duplicate (every track of playlist “洋楽” whose lyrics contains text_returned) to thePlaylist

という方法ではだめらしい。

上記スクリプトでは

set {theLocations, theLyrics} to {location, lyrics} of file tracks of selectedPlaylist
repeat with i from 1 to (count of theLocations)
if userText is in item i of theLyrics then
add {item i of theLocations} to playlist resultsPlaylistName
end if
end repeat

となっている。

いったい何が原因なのかいまいち分からないが、これでうまくいった。

次に歌詞の削除だが、m4aファイルであればhttp://dougscripts.com/itunes/scripts/ss.php?sp=deletelyricsの’Delete Lyrics’で消せることができる。mp3とかだとなぜか消せないので、消したい曲を選択して”ID3 タグを変換” > ver 1.0を選択して変換し、再びID3 タグをver 2.4等に変換すると消すことができる。

2011年9月17日土曜日

Eclipseのbuild.xmlのエクスポートがうまくいかない。

Eclipseのbuild.xmlをエクスポートする機能が動かなくてはまった。

エクスポートしたいプロジェクトはSVNで管理しているプロジェクトなのだが、どうやらプロキシの設定が間違っていたりしてSVNと通信できないとエクスポートできないことがあるらしい。

でも今回はプロキシの設定は正しかったのだが、なぜかエクスポートしようとしてもできなかった。

workspace/.metadata/.logを見ると以下のエラーが出ていた。

org.eclipse.equinox.security.storage.StorageException: No password was found.
Value of "ssl_passphrase" is being stored as a non-encrypted value in the node

どうやらSecureStorageが関係していそうなので、EclipseのPreferences>General>Security>Secure StorageのDefault Secure Storageを削除してもっかい試してみると今度は無事にbuild.xmlがエクスポートできました。

2011年9月11日日曜日

Redmine REST APIで日時指定をして工数取得

Redmine REST APIを使って工数を取得するプログラムを作っているのですが、開始日や終了日を指定して取得したかったので調べてみました。

通常の工数取得方法は以下のURLに書いてあります。

http://www.redmine.org/projects/redmine/wiki/Rest_TimeEntries

ただ、開始・終了日の指定方法は書いてなかったので、できないのかと思っていましたがfromとtoパラメータを以下のように指定することでできました。

http://hoge.co.jp/projects/my_project/time_entries.xml?from=2011-08-01&to=2011-08-20

2011年8月29日月曜日

MercurialのリポジトリをGitのリポジトリに変換

hg-fast-exportというものを使えばできるらしい。

ただ変換後にちょっとエラーが起こったので対処法も含めてメモっておく。

MercurialのリポジトリをGitのリポジトリに変換

https://hoge.com/hoge/というMercurialのリポジトリを変換する例

$ git clone git://repo.or.cz/fast-export.git
$ hg clone https://hoge.com/hoge/
$ cd hoge
$ git init
$ ../hg-fast-export.sh -r .

ただ変換すると一部のコミットの日付がおかしいことになっており、pushしようとすると以下のエラーが出た。

error: object 64db85a4528218edf2fc9a08a34ff9b5e8ee69c6:invalid author/committer line - bad date

エラーが出ているコミットを見ると以下のようになっていた。

commit 64db85a4528218edf2fc9a08a34ff9b5e8ee69c6
Author: Shinichi <>
Date:   Thu Jan 1 00:00:00 1970 +0000

first commit

以下のようなシェルスクリプトを実行して日付を修正する。

git filter-branch --env-filter \
'if [ $GIT_COMMIT = 64db85a4528218edf2fc9a08a34ff9b5e8ee69c6 ]
then
export GIT_AUTHOR_DATE="Sun May 23 18:09:52 2010 +0900"
export GIT_COMMITTER_DATE="Sun May 23 18:09:52 2010 +0900"
fi'

これで無事にGitリポジトリに変換できてgithubにpushもできましたとさ。

libclangを使ってみる。

clangとは、LLVMをバックエンドとして使用するC、C++、Objective-Cのコンパイラです。

GCCとは何が違うかというと、コンパイルするだけではなくてIDEのように定義元にジャンプとか補完といった機能が作り易いように設計されています。

実際XCode 4にはこのclangが使われているらしい。

これらの機能はclangバイナリを直接実行することで使用できるが、そのままだと遅いのでlibclangという専用のライブラリが用意されている。

今回はこのlibclangをちょっと触ってみる。

まずはclangを下のページ見ながらインストール

http://clang.llvm.org/get_started.html

無事インストールできたら早速使ってみたいが、とにかくドキュメントがない。どうやら唯一のサンプルはllvm/tools/clang/tools/c-index-test.cだけみたいだ。後はPythonバインディングが用意されているのでそのサンプルが少しあるけど、できればRubyから使いたい。とりあえずc-index-testを実行して定義元にジャンプの機能を使ってみる。

$ clang -lclang c-index-test.c
$ ./c-index-test -cursor-at=/Users/shinichi/programming/llvm/tools/clang/tools/c-index-test/c-index-test.c:1840:14 c-index-test.c

上の例はc-index-test.cの1840行14列にカーソルがある状態で定義元にジャンプの機能を実行しろという意味になる。結果は以下のようになった。

MemberRefExpr=argc:1825:7 SingleRefName=[1840:15 - 1840:19] RefName=[1840:15 - 1840:19]

ちゃんとthread_info構造体のargcメンバの位置が結果として表示されている。素晴らしい!!

せっかくだからlibclang使ってRedcar用のC/C++/Objectve-Cプラグイン作ろうかな~。

2011年6月26日日曜日

WindowsにRedcar導入

RedcarとはRubyで書かれたテキストエディタです。

特徴は

  • クロスプラットフォーム(Windows, Linux, Mac)
  • オープンソース
  • Textmateのスニペットが使える
  • 日本語がまともに入力できる

クロスプラットフォームなエディタは色々ありますが、まともに日本語が入力できないものが多い中日本語がまともに使えるのは嬉しいです。

この素晴らしいエディタをWindowsにインストールしてみたのですが、かなり面倒だったのでメモ代わりに残しておきます。

minttyから使いたかったのでインストール作業はmintty上で行いました。

なのでおそらくCygwinでも同様の手順になるかと思います。

ただ現状ではコマンドプロンプトからインストールするほうが楽なようです。

  1. まずRedcar 0.11はmswin32版Rubyじゃないとインストールができないらしいので、mswin32版Rubyをここからダウンロード

  2. 解凍して/usr/local/rubyにでも置く

  3. /usr/local/ruby/binにパスを通す

  4. もしcygwin版のRubyをインストールしていれば/usr/bin/rubyにあるので、これをrubycwなどにリネームしておく。ついでにgemもgemcwなどに。

  5. mswin32版gemを楽に呼び出すためにalias gem=’/usr/local/ruby/bin/gem.bat’としておく

  6. gemを実行するとzlib.dll, SSLEAY32.dllがないとか言われるのでインストールする(ついでにこの後のredcar installの時にiconv.dllも必要なのでいれとく)

  7. 以下のコマンドを実行

    $ gem install redcar
    $ which redcar
    
  8. which redcarで/usr/local/ruby/bin/redcarとなっていることを確認(/usr/bin/redcarとなっていたらおそらくcygwin版のgemでインストールされている)

  9. 以下のコマンドを実行するとRedcarがインストールされる

    /usr/local/ruby/bin/redcar.bat install
    
  10. /usr/local/ruby/bin/redcarだとなぜか起動できないので、起動用スクリプト作成

    以下の内容で/usr/local/bin/launch_redcarを作成(ユーザ名などのパスは適宜変更すること)

    java -client -Xbootclasspath/a:"C:/Users/ユーザ名/.redcar/assets/jruby-complete-1.5.3.jar" -Dfile.encoding=UTF8 -Xmx320m -Xss1024k -Djruby.memory.max=320m -Djruby.stack.max=1024k org.jruby.Main "C:/cygwin/usr/local/ruby/lib/ruby/gems/1.9.1/gems/redcar-0.11/bin/redcar" --no-sub-jruby --ignore-stdin  --start-time=1309005240 $1 &amp;
    
  11. エイリアス作っとく

    alias re='/usr/local/bin/launch_redcar'
    
  12. ‘re’でRedcar起動

    ファイル編集したいときは以下のようにファイル名指定して起動(既にRedcarが起動していれば既存プロセスで開いてくれる)

    re test.txt
    

起動時は結構時間かかりますが、一旦起動してしまえばサクサク動きます。

Emacsは色々面倒なのでRedcarに移行したいなぁ。

2011年6月9日木曜日

Ubuntu11.04+NeatxでWindowsからリモートアクセス

Ubuntu11.04にNeatx-serverを入れてみた。

NeatxとはGoogleが作ったオープンソースのNX Server。

VNCより使用する帯域が少ないらしい。

vncserverやvino-server(UbuntuデフォルトのVNCサーバ)、x11vnc、Free NXなど色々使ってみたが、結局Neatxがベストだった。

以下簡単に比較

vncserver

  • ウィンドウの移動等の動作が重い。
  • dを押すとウィンドウが最小化される。

vino-server

  • 解像度の変更方法が分からない。
  • 情報が少なすぎる。

x11vnc

  • こちらも解像度の変更方法が分からなかった。
  • geometry で指定しても画面が引き伸ばされるだけだし・・・

FreeNX

  • 重い。どう考えてもNeatXの方が軽かった。

Neatxサーバインストール

    $ sudo aptitude install python-software-properties &amp;&amp; sudo add-apt-repository ppa:freenx-team
    $ aptitude update
    $ sudo aptitude install neatx-server

これでサービスが勝手に起動される。

クライアント(Windows用)インストール

[NoMachine社のサイト](http://www.nomachine.com/download.php)からクライアントをダウンロードしてインストールする。

僕の環境ではAdvanced-&gt;Disable encryption of all trafficのチェックをはずさないとエラーで接続できなかった。

窓使いの憂鬱(yamy)との相性

yamyを使っていると右シフトがうまく機能しない。僕の環境(Windows XP)だと右シフトを押した時にE0RShiftとなるが、これは109.mayu以下のようにmod Shift += E0RShiftとなっている。

これはWindowsではうまく機能するが、NX Client経由だとShiftとして機能しない。

これを回避するためには109.mayuのdef mod Shift = LShift RShiftとなっている部分を以下のようにdef mod Shift = LShift RShift E0RShiftとし、mod shift += E0Rshiftとなっている部分をコメントアウトすることでうまく動いた。

のlinux109.mayuで

#def mod Shift = LShift RShift

def mod Shift = LShift RShift E0RShift

def mod Alt = LAlt RAlt

def mod Control = LControl RControl

def mod Windows = LWindows RWindows

#mod shift += E0RShift

ちなみにSynergyも試したけど、窓使いの憂鬱(yamy)が効かなかったので論外。

2011年6月2日木曜日

Evernoteの復元方法(MAC)

Evernoteを自宅のMacと会社のWindowsのクライアントから使用しているのですが、久々にWindowsのクライアントを同期するとなんと大量のノートとタグが中途半端に消えてしまいました・・・(T_T)

自宅に帰って復元方法を探したのですが、Macのクライアントは~/Library/Application Support/Evernoteにデータを置いているらしいのですが、これをTime Machineから復元して同期してみると、サーバ側の情報が優先されてしまいます・・・。

そこで、アーカイブにエクスポート/アーカイブからインポート機能を使って以下のように過去の状態を復元してみました。

  1. 同期を手動にする。

  2. Evernoteを終了させる。

  3. ~/Library/Application Support/EvernoteをTime Machineからバックアップする。(タグも含めておく)

  4. クライアントを起動して復元したいノートブックをエクスポートする。

  5. オンラインのEvernoteで復元したいノートブックの名前を変更する。(消去でもOK)

  6. 同期する。

  7. エクスポートしたノートブックをインポートする。(この時同期ノートブックにするかどうか聞かれるので、同期ノートブックにする。また、「タグをインポートする」にもチェックしておく)

  8. 同期する。(ノートが大量だと使用制限にひっかかるかも^^;)

  9. 自動同期に戻す。

これでノートもタグも元通り!

もっとクレバーな方法があれば教えてください。

クライアントの情報を優先して同期するような方法があればなぁ。

2011年5月29日日曜日

Shift+SpaceでSpotlight、Cmd+Enterで新しいタブで開く(Chrome)

昨日に引き続きKeyRemap4MacBookの設定をいじりました。

個人的にはShift+SpaceでSpotlightを開きたいのですが、ショートカットの設定画面からではShift+Spaceに割り当てることはできません。

そこで、事前にShift+Ctrl+SpaceにSpotlightを割り当てておき、Shift+Spaceを押すとShift+Ctrl+Spaceになるよう設定しました。

また、Google Chromeでは検索窓にワードを入力してOption+Enterで新しいタブで開くようになりますが、これをCommand+Enterにしたかったので、その設定もしています。

以下内容をprivate.xmlに追記し、KeyRemap4MacBookで読み込んで設定します。

 <?xml version="1.0"?>
 <item>
  <name>Shift+Space to Shift+Ctrl+Space</name>
  <identifier>shiftSpace_to_shiftCtrlSpace</identifier>
  <autogen>--KeyToKey--
   KeyCode::SPACE, VK_SHIFT,
   KeyCode::SPACE, ModifierFlag::SHIFT_L | ModifierFlag::CONTROL_L
  </autogen>
 </item>
 <item>
  <name>Cmd+Enter to Option+Enter (only in Google Chrome)</name>
  <identifier>cmdEnter_to_optEnter_only_chrome</identifier>
  <only>GOOGLE_CHROME</only>
  <autogen>--KeyToKey--
   KeyCode::RETURN, VK_COMMAND,
   KeyCode::RETURN, ModifierFlag::OPTION_L
  </autogen>
 </item>

2011年5月28日土曜日

Commandで英数、Command+Spaceでひらがな入力

Macでは英数キーで直接入力、かなキーで日本語入力できるという素晴らしい機能があります。

しかし、残念ながら僕のキーボードは英語配列なので英数キー、かなキーは存在しません。

そこで、KeyRemap4MacBookというソフトを使って、Commandキーで英数、Command+Spaceでひらがなモードに切り替えることにしました。

KeyRemap4MacBookのデフォルト設定には存在しないため、private.xmlに以下のような記述を行ってリロードし、2つの設定を有効にします。

これで英語キーボードでかなり快適に日本語入力できるようになりました♪

 <?xml version="1.0"?>
 <root>
  <item>
   <name>Original Settings</name>
   <list>
    <item>
     <name>When type Command_L only, send JIS_EISUU</name>
     <identifier>cmdL_keyoverlaidmodifier</identifier>
     <autogen>--KeyOverlaidModifier--
      KeyCode::COMMAND_L, ModifierFlag::COMMAND_L | ModifierFlag::NONE,
      KeyCode::COMMAND_L, KeyCode::JIS_EISUU
     </autogen>
    </item>
    <item>
     <name>Command+Space to JIS_KANA</name>
     <identifier>cmd_space_to_kana</identifier>
     <autogen>--KeyToKey--
      KeyCode::SPACE, VK_COMMAND,
      KeyCode::JIS_KANA
     </autogen>
    </item>
   </list>
  </item>
 </root>

2011年4月12日火曜日

GoogleスプレッドシートでPSP(Personal Software Process)

今以下の本を読んでPSPを実践している。

パーソナルソフトウェアプロセス入門

作者: ワッツハンフリー,Watts S. Humphrey,PSPネットワーク

出版社/メーカー: 共立出版

PSP(Personal Software Process)とは日頃自分がどの作業にどれくらい時間を使っているか記録しておき、それを分析することで作業の改善を行っていく枠組みのこと。

詳しくは上記の本やパーソナルソフトウェアプロセス(PSP)入門:CodeZine(コードジン)参照。

せっかくなので時間記録ログをとろうと思い、Googleスプレッドシートで時間記録ログの表を作成した。

GoogleスプレッドシートもExcel同様Ctrl+;で現在の日付、Ctrl+:で現在時刻を挿入できるのだが、Excelではセルに=C2-B2というようにすると時間の差分が計算できるが、Googleスプレッドシートでは”7:18 午前”というような文字列が挿入されてしまうため、Excelのように単純な数式では差分が計算できない。

そこで、Googleスプレッドシートに備わっているGoogle Apps Scriptで時間の差分を計算する関数を作成した。

function diffTime(start, end) {
    var startTimeAry = toTimeAry(start);
    var startHour = startTimeAry[0];
    var startMin = startTimeAry[1];
    var endTimeAry = toTimeAry(end);
    var endHour = endTimeAry[0];
    var endMin = endTimeAry[1];

    if (endHour &lt; startHour) {
        endHour += 24;
    }

    var totalStartMins = startHour * 60 + startMin;
    var totalEndMins = endHour * 60 + endMin;
    return totalEndMins - totalStartMins;
}

function toTimeAry (timeStr) {
    ary = timeStr.split(" ");
    //Logger.log(ary[0]);
    //Logger.log(ary[1]);
    timeAry = ary[0].split(":");
    var hour = Number(timeAry[0]);
    var min = Number(timeAry[1]);

    if (ary[1] == "午後") {
        hour += 12;
    }
    var timeAry = new Array(2);
    timeAry[0] = hour;
    timeAry[1] = min;
    return timeAry;
}

function diffTimeTest() {
    var diff = diffTime("11:18 午後", "10:10 午前");
    if (diff !== 10 * 60 + 52)
        throw "test failed";

    diff = diffTime("11:18 午後", "0:10 午前");
    if (diff !== 52)
        throw "test failed";

    diff = diffTime("11:18 午前", "0:10 午後");
    if (diff !== 52)
        throw "test failed";

    diff = diffTime("11:9 午後", "0:10 午前");
    if (diff !== 61)
        throw "test failed";

    diff = diffTime("0:0 午前", "11:59 午前");
    if (diff !== 11*60 + 59)
        throw "test failed";

    Browser.msgBox("tests passed!");
}

作業時間セルには’=diffTime(B2, C2)’というように指定すると、B2、C2セルにある時刻の差分を分単位で表示することができる。

Google Apps Script初めて触ったけど、Javascriptで書けるからVBAよりいい感じ♪

逐一時間を記録するのはけっこうつらいが、ここまでやったんだから続けてみようと思う。

そのうち週間、月間レポートを生成するようなスクリプトも作成してみたいなぁ。

2011年2月11日金曜日

SBT(Simple Build Tool)でSWTアプリ開発

SBTでSWTアプリの開発をしようと思ったんだけど、実行しようとするとswtのライブラリが”already loaded in another classloader”とか言われてリンクエラーなる。

ちなみに1回目は普通に起動できる。

ぐぐったら似たような書き込みを見つけた。

JNI and multiple classloaders - Google グループ

ここではJRebelを使った解決方法が提示されている。

確かにJRebelを使えばある程度解決できるけど、トップのウィンドウのデザインを反映させようとするとどっかで再描画するようにしないといけなくなるので微妙。

解決策が見つからないのでMaven+Scala Pluginの組み合わせでも試してみるか・・・。