2013年2月26日火曜日

Ruby 手抜きレシピ: CSV ファイルの結合

先日 Ruby 2.0 がリリース されましたね。しばらく Ruby はレガシーな使い方しかしてないものの、キーワード引数やデフォルトUTF-8エンコーディングなど便利そうな機能も多く楽しみです。

さて、今回は 2 つの CSV ファイルを結合する手抜きのサンプルスクリプトのご紹介。ある日友人から

  • Windows 環境で
  • 2つの CSV ファイルを横に連結したく
  • たまたまその環境で動くのが Ruby だったので Ruby で処理できるといいな (その友人は数値処理系のプログラムはガシガシ書けるけど Ruby はあまり触ったことない)

という相談を受け、ちょろっと書いてみたスクリプトが以下になります (ダウンロード)。

#!/usr/bin/ruby
########################################
#### Settings
DELIM=","

########################################
#### Main Program

if ARGV.size < 3
  print <<-"EOH"

    USAGE: ruby #{$0} <IN-FILE1> <IN-FILE2> <OUT-FILE>

EOH
  exit 1
end

in1, in2, out = ARGV[0..2]

in1lines = File.open(in1).read.split("\n")
in2lines = File.open(in2).read.split("\n")
out_io   = File.open(out, "w")

in1size = in1lines.size
in2size = in2lines.size

line_num = in1size > in2size ? in1size : in2size

for n in 1..line_num
  in1dat = in1lines[n-1] ||= ""
  in2dat = in2lines[n-1] ||= ""
  out_io.puts in1dat + DELIM + in2dat
end

out_io.close

何をするかというと、以下のような 2 つの CSV ファイルがある時に、

$ cat file1.csv
1,2,3
4,5,6
7,8,9

$ cat file2.csv
A,B,C
D,E,F
G,H,I

こんなふうに連結しますよというもの。

$ ruby join_csv.rb file1.csv file2.csv out.csv
$ cat out.csv

1,2,3,A,B,C
4,5,6,D,E,F
7,8,9,G,H,I

お気づきの方はお気づきの通り 「それ paste(1) コマンドでできますやん」ということで全くその通りですw。paste コマンドだと以下の使い方で OK ですね。

$ paste -d, file1.csv file2.csv > out.csv

まあ、今回はたまたま Windows 上でやりたかったということで無意味ではなかったのかなと… (汗)

上記スクリプトは行数を圧縮したくて Ruby 特有の記法で書いてる部分もありますので、もうちょっと平易に書いたものも載せておきます。(ダウンロード

#!/usr/bin/ruby
########################################
#### Settings
DELIM=","

########################################
#### Main Program

if ARGV.size < 3
  print <<-"EOH"

    USAGE: ruby #{$0} <IN-FILE1> <IN-FILE2> <OUT-FILE>

EOH
  exit 1
end

in1 = ARGV[0]
in2 = ARGV[1]
out = ARGV[2]

in1lines = File.open(in1).read.split("\n")
in2lines = File.open(in2).read.split("\n")
out_io   = File.open(out, "w")

in1size = in1lines.size
in2size = in2lines.size

if in1size > in2size
  line_num = in1size
else
  line_num = in2size
end

for n in 1..line_num
  in1dat = in1lines[n-1]
  unless in1dat 
    in1dat = ""
  end

  in2dat = in2lines[n-1]
  unless in2dat 
    in2dat = ""
  end

  out_io.puts in1dat + DELIM + in2dat
end

out_io.close

"Ruby CSV 結合" でググると CSV クラス の話などは出てくるのですが、意外に今回のような要望にヒットする記事がないもんだなぁと思い、枯れ木も山のなんとやらで書いてみました。

このレベルのスクリプトはちょこちょこ書いてるものの、プログラミングに関する知識やコーディングの考え方など、ニュース追っててもピンと来ないものも多く、まだまだ時代に追いつけてないなぁと実感します。そっち方面ももっと勉強しないといけませんが、まあそのうち…。

2013年2月15日金曜日

デブサミ 2013 Action! に参加してきました

Developers Summit 2013 Action! に行ってきました。平日2日間丸々はちょい厳しかったので、2日目のみ参加。主にインフラなど普段の仕事と多少は関係のある講演を聞いてきました。この手の IT エンジニア系のイベントは、学生の時に (全然情報系の研究室とかではなかったんだけど) Internet Week とかに行って以来だったのでかなり久しぶりでしたね。

会場の様子とかとか

入り口はこんな様子。結構盛況でしたね。写真はまだ空いてる状態の様子。休憩(=移動)時間は通路はかなり混んでました。

5 会場で並行して講演が行われてました。そりゃ混むよねぇ、と。

講演: AmazonのDevOpsを支えるAWSクラウド

一つ目に聞いたのは AWS エバンジェリストの堀内さんの講演。エバンジェリストって「伝道師」な意味だったんですね(いまさら)。ちなみに堀内さんって同い年なのか…(遠い目)。

オートスケールなど AWS の特徴の紹介は、まあそれ自体は結構あちこちで見る話ではあって、「ふむふむ」という感じでした。

お、と思ったのは以下のフレーズでしたね (多少私の脳内で変換されてるかもですが) 。

  • これまではハードウェア単位であったコストが、クラウドの世界では CPU, メモリ, ストレージ, 通信料それぞれがコストの最小単位に (コントローラブル話)
  • 障害を例外として扱わず、最初から組み込む (レジリエント話)
  • どこまでもスケールできる設計を心がける (アダプティブ話)

これまではハードウェアの物理制約もあって考えてもしょうがなかった (途中で思考を止めてよかった or 思考を続けてもあまり意味なかった) 事が意味を持つようになってるんですね。なんでも AWS に乗っければ良いわけではないんでしょうが、サーバ・ネットワークの物理的制約がほぼ無い世界も存在することを頭の片隅には常に入れておかないと、エンジニアとして明後日の方向に行っちゃいそうだなと…。

それと、当日 AWS のアカウント作った人には (既にある人は Amazon Web Services クラウドデザインパターン実装ガイド を購入すると)、堀内さんから $25 のクーポンプレゼントというありがたい特典付きでした。そのうち作っていろいろやってみたいなぁ、と思ってたので渡りに船とばかりにアカウント作ってクーポン頂きました(ありがたや)。

講演: Opsから挑むDevOps

株式会社エクシードの千葉則行さんの講演でした。

聞いてて印象に残ったのは、定例作業を効率化する Chef と非定例作業を効率的に行う Mcollective を組み合わせた cloudrop の紹介と、DevOps のあり方についてでした。

cloudrop ではポータルから RESTful API で指示を出し、裏側では Mcollective と Chef-solo が動作して各サーバのセットアップが行われるようです。

cloudrop については上記サイトの紹介ページでいろいろ紹介されていますが、ちょっと気になった点は講演の後でブースで伺いました。

  • 各サーバに Croudrop Agent を入れる必要がある
  • サーバ上で Ruby が動く必要がある
  • "タスク" にはコマンドでできることであればなんでも実現できるそうなので、テストも組み込むことが可能

普段運用していて、知見やノウハウといったものを上手く組み込めるフレームワークはないかなぁ、などと考えるわけですが、cloudrop の話を聞いてまだピンと来てないのは、何が自動化されるべきなのかまだ私自身の中で整理できてないんでしょうねぇ。一度ちゃんと考えたほうがいいのかも…。

もう一つは DevOps のあり方について。千葉さんの仰ってた「結局のところ、サービスだと思う」は正にその通りなのかなと。部署間や社内でどうこうじゃなくて、利用者に提供するサービスにとってどうなのか、を意識して、すべきことをするようにしていくと、自然と開発者と運用者が協力する体制になっていくんじゃないかなと思いますね。

講演: SSL証明書を正しく理解する - 技術仕様の解説と次世代暗号アルゴリズム

日本ベリサイン株式会社の加藤雅史さんの講演でした。"デブサミ" なので講演も Developer 向けが多いなか「今回の話は浮くかも」と前置きしてましたが、個人的には身近な話題なので面白かったです。

お話は前半はシーザー暗号、共通暗号方式、公開暗号方式、RSA暗号といった暗号化の基礎、後半は暗号化方式の今後について。後半の話を抜粋すると以下の様な感じ。

  • RSA 1024 は 2020 年にはスパコンで一年間計算すれば解読できるようになる
  • 現在は RSA 2048 が主流に
  • 今後はコンピュータの高速化に伴い RSA 4096 などになっていく…、としたいところだが、鍵長を長くするとWeb サーバの負荷も飛躍的に増加し、現実的な処理能力を超えてしまうことが懸念される
  • 今後は鍵長が短く暗号強度が高い楕円曲線暗号 (Elliptic Curve Cryptography: ECC) への移る傾向にある
  • ECC 256 と RSA 2048 (ECC の方が1万倍解読は困難とのこと) でも、ECC の方が負荷が少なく、高いパフォーマンスが出る
  • ただし、ECC に対応できないクライアント端末もまだ多い。ガラケーとか確実に無理な上、PC ブラウザにしても、IE 6 以前は対応してなかったり、XP の Chrome が対応してなかったり
  • 現実的な移行の方策が ECC と RSA のハイブリッド構成で、クライアントの対応状況に応じて ECC と RSA を使い分ける
  • もちろんサーバ側の対応も必要。Apache は対応しているけど IIS は未対応

こんなもんですかね。タイムリーに以下のニュースが流れてましたね。

ECC 256 と RSA 2048 の両暗号アルゴリズムに対応した「マルチアルゴリズムSSLサーバー証明書」として提供するそうで。対応、必要だなぁ…。

その他

聞く講演はあまり詰め込まず、空き時間はラウンジでこの記事を書いたりしてました。電源・ネットワーク・椅子・デスク・ドリンクのある環境のなんとありがたいこと…。混む時は混んでましたが、座れないことはなかったです。ちょうど良い感じの数が用意されてたのかなと。

おまけですが、こんなオライリー缶バッチのガチャが…。面白そうで買おうか迷いましたが止めときました ^^;


おまけその弐。入り口で受付したらこんなものも…。Cloudn て…。

おわりに

以上、久しぶりのイベント参加でしたがいろいろ知ることもあり面白かったです。また時間を作ってこの手のイベントには参加するようにしたいですね。

2013年2月3日日曜日

Emacs 設定いろいろ [Emacs24 (Cocoa Emacs) on Mac OS X]

年が明けたかと思っていたら、気がつけば 1 月が終わってしまいましたね。

久しぶりの投稿ですが、今回は Emacs ネタで。

Emacs に触り始めたのはもう 10 年以上前でしょうか。当時は Emacs20 とか 21 ぐらいでしたかね。古いバージョンのまま 6,7 年ぐらい使っていましたが、学生から社会人になったり環境が変わったりで 1 年ぐらい触る機会なくなってたのが、個人で自宅用に MacBook Air 買ったのキッカケでまたメインのエディタとして使うようになりました。慣れもあるのでしょうがやはり使いやすいですね。

現在使ってるのは Emacs24 (Cocoa Emacs) で最近バージョン 24.2 に更新しました。久しぶりだったこともあって設定を見なおしたり評判のいい機能を探して導入したりしました。ファンも未だに多いせいか、いろいろ進化してますね。ありがたいです。

せっかくなので「あ、これ便利」と思ってる機能など、自分への備忘録も兼ねて設定とともにご紹介でもしてみようかと思った次第です。

Index

環境およびインストールについて

Emacs および周辺環境は以下の通り。

  • Hardware: MacBook Air
  • OS: Mac OS X 1.8.2 (Mountain Lion)
  • Emacs: Cocoa Emacs v24.2
  • IME: Google 日本語入力
  • Browser: Google Chrome

インストール方法はググればあちこちに有用なドキュメントは出てくると思いますのでざっくり書きます。

  • Xcode (+ Command Line Tools) をインストール
  • Homebrew をインストール (https://github.com/mxcl/homebrew/wiki/installation)
  • Emacs 本体は brew install emacs --cocoa でさっくりとインストール
  • 適宜必要なシンボリックリンク張って、/Applications/Emacs.app で Emacs 起動できるようにする

まあこんなとこですかね。

ちなみに以降で説明する設定は全部 ~/.emacs.d/init.el に記載しているものです (むかーしは ~/.emacs に書いてたなぁ…)。

Emacs Lisp パッケージ管理

Emacs 用の各種 Lisp がパッケージ管理されるというありがたい機能。Emacs 24 から利用可能になったものですね。以下の設定は Emacs24 のインストールと新機能 : 紹介マニア で紹介されてたものを丸コピです。

M-x list-packages すると 1000 以上のパッケージリストが取得できます。h でヘルプが表示されますが、基本は i でインストールマーカを付けて x でインストールです。さらにありがたいのは各種 Emacs Lisp バージョンアップに伴うアップデートが楽ちんなところですね。久しぶりに M-x list-packages すると更新可能なパッケージが提案されますので U を押すとそれらのパッケージにインストールマーカが付き、後は x だけ。これで最新版のインストールと旧版のアンインストールをサクッとやってくれます。Emacs Lisp ファイルの更新って手動だとなかなかやらず、せっかくのバージョンアップのご利益を享受しそびれがちだったので助かりますね。

ちなみにこれで管理されてる Lisp ファイルは ~/.emacs.d/elpa/ 以下に置かれてるようです。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG管理] パッケージ取得先追加
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)

背景色と透過と設定 (複数フレーム対応)

make-frame-command (ショートカットキー: C-x 5 2) による新規フレーム作成時にも適用される、背景色と透過の設定になります。

Emacs の背景透過の設定とか検索すると色々出てくるのですが、複数フレームに対応したものになかなかヒットせず、"default-frame-alist alpha" あたりで検索してやっとお目当てのサイトが見つかりました。

私の場合 Emacs はメモ・ドキュメント書き・ファイル操作・メール草稿など多用途に使っているため基本起動しっぱなし&常に複数フレームを開いてる状態なので、下記のような複数フレーム対応の設定は重宝してます。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [基本] 背景色・透過
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 背景色設定
(custom-set-faces
 '(default ((t (:background "#000022" :foreground "#EEEEEE"))))
 '(cursor (
           (((class color) (background dark )) (:background "#00AA00"))
           (((class color) (background light)) (:background "#999999"))
           (t ())
           )))
;; フレーム透過設定
(add-to-list 'default-frame-alist '(alpha . (0.75 0.75)))

Markdown 編集用・その一 (markdown-mode)

GitHub を使い始めた際に Markdown 記法を知りましたが、その後すっかりハマってしまい、何か事情がない限りテキストは常にこの記法で書くようになってしまいました。マーカとして使うものがシンプルで大抵はそれで用が足りますし、HTML へのコンバータも用意されてますし、いざ表とか必要な場合は HTML で直書きもできるとこが良いですね。

…というわけで Emacs にも markdown-mode がありまして重宝しております。前述しました list-package からパッケージインストールできます。

また Mac だと Homebrew 使って brew install markdown で markdown の HTML へのコンバータ (直接入手するなら こちら から) をさくっとインストールできます。以下の markdown-command はそれ前提の設定です。変換後 CSS で見やすくするために markdown-css-path も設定してます。ラップトップなのでローカルに適当に作った CSS を指定してますが、常時インターネットに接続してる環境であれば、気に入った Web 上の CSS を参照しちゃうのもいいかもしれません。

以下では .md, .txt の拡張子のファイルを開く際に markdown-mode にしてますが、これは人にとってお好みで、ですね。HTML への変換時は以下を使ってます。

  • HTML に変換してからブラウザで開く (markdown-export-and-preview)
    • Ctrl-c Ctrl-c v
  • 単に HTML に変換するだけ (markdown-export)
    • Ctrl-c Ctrl-c e

見出しやリンクを挿入する関数もありますが、ショートカットキー叩くより普通に入力したほうが早いので、あまりそっちは使ってませんw

ちなみにこの記事も Markdown 記法のテキストで作成 → コンバータで HTML に → Blogger 用に少し sed で整形、的なことやってます。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG機能利用] markdown-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(autoload 'markdown-mode "markdown-mode.el" "Major mode for editing Markdown files" t)
(setq auto-mode-alist (cons '("\\.md" . markdown-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.txt" . markdown-mode) auto-mode-alist))
(setq markdown-command "/usr/local/bin/markdown")
;; Markdown2HTML した際 (C-c C-c v や C-c C-c e)、参照する CSS の設定
(setq markdown-css-path "file://localhost/Users/morikawa/.emacs.d/local-lisp/markdown2html_mac.css")

Markdown 編集用・その二 (見出し検索用自作関数)

Markdown ネタをもう一つ。Markdown の見出しを Occur で引っ張ってくる自作関数 markdown-header-list を作って、テキスト内移動に使ってます。

一応、以下の Markdown の見出し記法 には一通り対応してます (まあヒットのさせ方が簡単ですからね…)。

# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6

見出し1
=============

見出し2
-------------

私自身は Ctrl-c Ctrl-s のショートカットを設定してます。文章が長くなってきた時や、「全体構成どうなってたっけ?」という時に使ってます。(require を強引に呼んでて、もう少しスマートな書き方あるような気がする…。動くのでとりあえず良しとしてますが…)。

余談ですが、最近 rubikitch さんが all-ext.el をリリースされましたね (all-ext.el:対象行を絞り込んでからまとめて編集するM-x allを超強化!occurと融合&anything・helmと連携)。下記関数の用途は編集よりも移動なので Occur で OK なのですが、絞り込んだ結果の画面で直接編集できちゃうってのは凄いですね。そのうち活用したいなと。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [編集支援] Markdown 書式の見出し検索
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun markdown-header-list ()
  "Show Markdown Formed Header list through temporary buffer."
  (interactive)
  (occur "^\\(#+\\|.*\n===+\\|.*\n\---+\\)")
  (other-window 1))
(require 'markdown-mode)
(define-key markdown-mode-map "\C-c\C-s" 'markdown-header-list)

ちなみに実際に使うとこんな感じ↓

anything, recentf-ext (+ kill-ring) 設定

とにかく一度使い慣れちゃうと離れられない anything, recentf-ext (あとついでに kill-ring) の設定です (rubiktch さんに感謝感謝)。おそらくこういうのも一つの「革新的」というものなんでしょうね。上手く一言で「こう素晴らしいんだよ」とは説明しづらいんですがとにかく「使ってみなヨ!」という機能ですね。

例のごとく list-packages から anything で始まるパッケージと, recentf-ext をさくっとインストールしてます。

とにかく anything にはすぐに起動して欲しいので "Ctrl-x X" 系のショートカットじゃなくて、Ctrl-o を割り当てちゃってます (多分何がしかのプリセットされてる関数があるんでしょうが上書き)。ファイルを開きたい、バッファを切り替えたいとかの際はとにかく Ctrl-o 押せば良い になってます。

使い始めてしばらくは (global-set-key (kbd "C-o") 'anything) としてたのですが、どうも recentf で保存されてるファイルの新しいものしか呼び出せないようで、最近呼び出す関数を anything-for-files にしたら(たぶん)古いものも呼び出せるようになりました。

あと、anything についてくる anything-show-kill-ring を M-y に設定しており、過去 kill-ring に保存した情報を引っ張り出せます (昔から色々実装がありましたが、今回こちらに乗り換えました)。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG機能利用] anything, recentf-ext, kill-ring
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; C-o で anything-for-files 起動
(global-set-key (kbd "C-o") 'anything-for-files)
;; recentf による保存数を 10000 に
(setq recentf-max-saved-items 10000)
;; 「バッファを替えた時ファイルを開いたとみなす」「Directoryも履歴に保存」する拡張
(require 'recentf-ext)
;; 遅延を短く
(setq anything-idle-delay 0.1)
(setq anything-input-idle-delay 0.1)
;; kill-ring の最大値。デフォルトは 30
(setq kill-ring-max 100)
;; M-y で kill-ring を表示
(global-set-key "\M-y" 'anything-show-kill-ring)

関連のドキュメントはネット上のあちこちにありますので詳しくはそちらをどうぞ。以下は今回私が参照したサイトです。

ちなみに今は anything を fork した helm というものもあるそうですが、ぱっとググった範囲ではわざわざ移行しなくてもな~、という感じなのでそのまま anything を使ってるのが現状です。とはいえ、後方互換で作ってもらってるのはありがたいですね。

popwin 設定

最近 近頃の開発環境 : Mosh、z、tmux、Emacs、Perl について - naoyaのはてなダイアリー から popwin.el を知って、以下のサイトを見ながら設定追加しました。

こちらも list-packages からインストールしてます。上記サイトでも紹介されてますが、ヘルプバッファ(*Help*)とか補完バッファ(*Completions*)とかデバッグバッファ(*Backtrace*)とか出たら出っぱなしでイライラしながらウィンドウを移動したり閉じたり、といったストレスが解消される、という地味で説明しづらいですが確かに快適になる機能です。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG機能利用] popwin
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'popwin)
(setq display-buffer-function 'popwin:display-buffer)
(setq popwin:popup-window-height 0.5)
(defvar popwin:special-display-config-backup popwin:special-display-config)
(setq popwin:special-display-config
      (append '(("*Remember*" :stick t)("*Org Agenda*")("*Backtrace*")
                ("*sdic*" :noselect))
              popwin:special-display-config))
(define-key global-map (kbd "C-x p") 'popwin:display-last-buffer)

screen: ミニバッファの保存や各ファイルに開いた際の行数のマークとかとか

anything でだいぶ楽にはなりましたが、screen もまた便利で昔から使ってます (端末多重接続ソフトウェアの GNU screen とは全然別物です。これはこれで個人的には使ってますが)。これも list-packages からインストールしてます。

基本明示的に呼び出して使うというものではなく、以前に Emacs 内でミニバッファに入力した内容や各ファイルの最終変更時の行数の記憶といったことをしてくれる機能で地味にかなり便利です。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG機能利用] session 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'session)
(add-hook 'after-init-hook 'session-initialize)
(setq session-save-print-spec '(t nil nil))

なお、最後の一行は以下サイトで紹介されていたもので、anything-show-kill-ring と screen を同時使用する際に必要な設定です。

Google Chrome のテキストエリアを外部エディタで編集

ブラウザ上でそれなりの量の文章をテキストエリアに直入力するのはちょっと嫌なので (手が滑って画面をリロードして全部消えちゃうとか…)、たいていは Emacs などのエディタ上でひと通り編集を行なってから貼り付けてます。

とはいえ、わざわざ Emacs にコピペするほどじゃないなと思ったんだけど、「あ、ここちょっと矩形切取したいな… or さくっと置換したいな」なんて事があったりもします。

そんなタイミングでサクッとEmacs とブラウザのテキストエリア上のテキストの同期をとれるようにしてくれるのが

になります。

以下の設定は Google Chrome のテキストエリアを外部エディタで編集する Edit with Emacs - 酒日記 はてな支店 をベースにしつつ、edit-server は list-packages でインストール、キーバインドは個人的に直感的なものに置き換えてます。

ブラウザ上のテキストエリア内編集時にもやもやしてる方は導入して損のない機能かなと。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [PKG機能利用] Chrome のテキストエリア編集の為のエディットサーバ起動
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'edit-server)
(edit-server-start)
;; Chrome から呼び出した際のフレームサイズを edit-server.el デフォルトのものより
;; init.el で設定しているものを優先(デフォルトは幅 80, 高さ 25)
(setq edit-server-new-frame-alist nil)
;; 特定の URL から呼び出された場合のモード設定
(setq edit-server-url-major-mode-alist '(("mail\\.google\\.com" . mail-mode)))
;; Edit Server Mode のキー設定変更
;; - デフォルト
;;    - Ctrl-x # or Ctrl-c Ctrl-c: ブラウザのテキストエリアに編集内容貼付 (Emacs のウィンドウ閉)
;;    - Ctrl-x Ctrl-s:             ↑ 後に再度 Emacs を開く (一時保存)
;;    - Ctrl-x Ctrl-c:             編集を破棄
;;
;; - カスタム (普段の自分設定の Emacs に近い操作で)
;;    - Ctrl-x Ctrl-s:             ブラウザのテキストエリアに編集内容貼付 (Emacs のウィンドウ閉)
;;    - Ctrl-q:                    ↑ 後に再度 Emacs を開く (一時保存)
;;    - Ctrl-x k, Ctrl-x Ctrl-k:   編集を破棄
;; 
(define-key edit-server-edit-mode-map "\C-q"     'edit-server-save)
(define-key edit-server-edit-mode-map "\C-x\C-s" 'edit-server-done)
(define-key edit-server-edit-mode-map "\C-xk"    'edit-server-abort)
(define-key edit-server-edit-mode-map "\C-x\C-k" 'edit-server-abort)

Mac 用の特殊キーバインド (¥\ を入力)

ちょいちょい正規表現置換 query-replace-regexp を使うのですが、後方参照させたいのに何度 ¥( .. ¥) で括っても ¥1 に代入されない…。おかしいなぁ、と思っていたら、Mac だと ¥\ は違ったのねというオチ。

上記サイトで紹介されていた以下の設定で万事解決。\( .. \) で括ったものが \1 .. に代入されるようになりました。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [基本] Mac 特殊キーバインド
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-key global-map [?¥] [?\\])

トラックパッドのスワイプで快適にスクロール

デフォルトだと、トラックパッドの上下のスワイプは過度にスクロールされてしまうので全然使えない感じだったのですが、

から設定を丸コピさせてもらって大変快適になりました。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [基本] トラックパッド用のスクロール設定
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun scroll-down-with-lines ()
  "" (interactive) (scroll-down 3))
(defun scroll-up-with-lines ()
  "" (interactive) (scroll-up 3))
(global-set-key [wheel-up] 'scroll-down-with-lines)
(global-set-key [wheel-down] 'scroll-up-with-lines)
(global-set-key [double-wheel-up] 'scroll-down-with-lines)
(global-set-key [double-wheel-down] 'scroll-up-with-lines)
(global-set-key [triple-wheel-up] 'scroll-down-with-lines)
(global-set-key [triple-wheel-down] 'scroll-up-with-lines)

Dired: ディレクトリエディタ

ちょっとしたファイル操作は Emacs いじってる時はそのまま Emacs 上でやった方が楽だったりするので、古くからある Dired ですが今も使わせてもらってます。

しばらくはデフォルト設定で使ってたので、最近以下の記事を見つけて (記事自体は 5 年以上前のものですが)、設定追加しました。

より快適でいい感じです。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [基本] Dired モードの設定
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(add-hook 'dired-load-hook
          '(lambda ()
             ;; ディレクトリを再帰的にコピー可能にする
             (setq dired-recursive-copies 'always)
             ;; lsのオプション 「l」(小文字のエル)は必須
             (setq dired-listing-switches "-FlhtA")
             ;; find-dired/find-grep-diredで、条件に合ったファイルをリストする形式
             (setq find-ls-option '("-print0 | xargs -0 ls -Flhatd"))
             ;; 無効コマンドdired-find-alternate-fileを有効にする
             (put 'dired-find-alternate-file 'disabled nil)))
;; ファイル・ディレクトリ名のリストを編集することで、まとめてリネーム可能にする
(require 'wdired)
;; wdiredモードに入るキー(下の例では「r」)
(define-key dired-mode-map "r" 'wdired-change-to-wdired-mode)
;; 新規バッファを作らずにディレクトリを開く(デフォルトは「a」)
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
;; 「a」を押したときに新規バッファを作って開くようにする
(define-key dired-mode-map "a" 'dired-advertised-find-file)

外部 IME 使用中でも快適に使えるキーバインド

最近日本語入力には Google 日本語入力使ってますが、外部 IME だと Ctrl-x k みたいなキー入力は日本語入力オフになってないと最後のアルファベット入力ダメなんですよね (挙動としては当たり前ですが)。もう一度入力し直しだったり、先に日本語入力オフになってることを確認する事を心がけたりと結構面倒なので、よく使うやつには Ctrl-x Ctrl-k みたいなキーバインド追加したりしてます。

まっとうな解決策は以下で紹介されてるような IME パッチを適用することなんですけどね…。

ただ、Windows でも Emacs 使ってたり、リモートの Linux で SSH 端末経由で Emacs 立ち上げたりすることもあるので、そこら辺も含めて対応するのが面倒で、ついこういったアドホックな対応とっちゃってます。

「全然元のキーバインドと違うぢゃん」ってものもありますが、まあ結果結構ストレスは減ったのでよかったのかなと。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; [基本] グローバルキーマッピング (外部IMEの日本語オン/オフを切替えず使いたい関数用)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; kill buffer を Ctrl-x Ctrl-k で可能に (デフォルトは Ctrl-x k)
(global-set-key (kbd "C-x C-k") 'kill-buffer)

;; 別ウィンドウへの切り替えを Ctrl-x Ctrl-o で可能に (デフォルトは Ctrl-x o)
(global-set-key (kbd "C-x C-o") 'other-window)

;; 単一ウィンドウに戻すのを Ctrl-x Ctrl-1 で可能に (デフォルトは Ctrl-x 1)
(global-set-key (kbd "C-x C-1") 'delete-other-windows)

;; 縦ウィンドウ分割を Ctrl-x Ctrl-2 で可能に (デフォルトは Ctrl-x 2)
(global-set-key (kbd "C-x C-2") 'split-window-below)

;; 縦ウィンドウ分割を Ctrl-x Ctrl-3 で可能に (デフォルトは Ctrl-x 3)
(global-set-key (kbd "C-x C-3") 'split-window-right)

;; フレームの作成・削除を Ctrl-;, Ctrl-: で可能に (デフォルトは C-x 5 2, C-x 5 0)
(global-set-key (kbd "C-;") 'make-frame-command)
(global-set-key (kbd "C-:") 'delete-frame)

;; Ctrl-x Ctrl-d (デフォルトは Ctrl-x d) でも dired を起動する
(global-set-key (kbd "C-x C-d") 'dired)

まとめ

以上、書き並べてみたら結構な量になってしまいましたが、これら設定のお陰で Emacs Life はさらに快適になりましたね。

また良いなと思う機能など見つけましたらそのうち紹介します。