EmacsとChromeとのシームレスな連携
Emacsの設定にハマりだすとメールやインターネットプラウザなど全てのワークをEmacsで完結させよう…と考えるようになります。私もそんな一人でした。あれこれと設定を試すプロセスもまた楽しいからです。でもEmacsつながりでご縁ができたあるプログラマーの方のブログ Solist Work Blog を読んで少しずつ考え方が変わってきました。
気付かされたことは、全てをEmacsで扱うために窮屈な使い方をするより、作業デスクとしてのEmacsと使い慣れたシステムやアプリとが、シームレスな感覚で連携できることのほうが遥かに意義があるということでした。まだまだ試行錯誤中で十分にまとまった記事にはなっていませんが備忘録として公開します。
外部モニターを併用する
これは必須ではないと思いますが実際に使ってみると実に快適です。私の場合は、メインマシンMacbook Pro に 24インチの外部モニターを接続しています。解像度とかにこだわらなければ 1~2万円で十分実用できるモニター が購入できます。正面にMacbookのEmacs画面を見ながら右サイドの外部ディスプレーでChromeを開いている…というのが定番のスタイルです。
Macの場合、2画面のデスクトップを自在に切り替えできます。私の場合 ctrl+1 <-> ctrl+2 で切り替えできるように設定して、A画面でEmacs、B画面でiTermというような使い方ができます。外部ディスプレーの方は、ほぼChrome専用という使い方ですが、BetterTouchTool というアプリを使えば表示画面の移動などが自在にできるので便利です。
EmacsとChromeとのシームレスな連携
Emacsでブログの文章を書いたり、プログラミングを試行したりしているとき、作業の手を止めることなく検索できたり必要な資料の載っているWEBページを一発で閲覧できるとすごく便利です。一方、Chrome(プラウザ)の textarea に長文の入力が必要なときは、Emacsで入力できるほうがストレスが少ないです。以下はそのための設定です。
色々WEB検索するための設定
Melpaから search-web というPackageをインストールします。このパッケージは、google-thisと同じコンセプトで、regionやカーソルのある部分の単語など空気を読んで検索してくれます。
各検索サイトがどのような引数で修理しているかさえ解れば自由にカスタマイズして応用できます。WEBページからkeywordを入力して検索するとその結果がURLボックスに表示されます。表示されたURLから引数を分析すればいいのです。私の場合、俳句でよく使う 古語検索/類語検索/季語検索などを登録しています。
(use-package search-web)
(add-to-list 'search-web-engines '("weblio" "http://weblio.jp/content/%s" nil))
(add-to-list 'search-web-engines '("kobun" "http://kobun.weblio.jp/content/%s" nil))
(add-to-list 'search-web-engines '("ruigo" "http://thesaurus.weblio.jp/content/%s" nil))
(add-to-list 'search-web-engines '("kigo" "http://www.mysai.net/cgi-bin/kigo_search.cgi?txtKigo=%s&rdoSelect=1" nil))
(add-to-list 'search-web-engines '("github" "https://github.com/search?utf8=✓&q=%s&ref=simplesearch" nil))
(add-to-list 'search-web-engines '("qitta" "https://qiita.com/search?q=%s" nil))
(add-to-list 'search-web-engines '("post" "https://postcode.goo.ne.jp/search/q/%s/" nil))
(add-to-list 'search-web-engines '("earth" "https://earth.google.com/web/search/%s/" nil))
(bind-key
"s-s"
(defhydra hydra-search-web (:hint nil :exit t)
"
[Search] _a_:Amazon _g_:Google _m_:Maps _e_:Earth _h_:GitHub _q_:Qitta _w_:Weblio _p_:Post _b_:古文 _r_:類語"
("a" (search-web-dwim "amazon jp"))
("e" (search-web-dwim "earth"))
("g" (search-web-dwim "google"))
("m" (search-web-dwim "google maps"))
("h" (search-web-dwim "github"))
("q" (search-web-dwim "qitta"))
("w" (search-web-dwim "weblio"))
("p" (search-web-dwim "post"))
("k" (search-web-dwim "kigo"))
("b" (search-web-dwim "kobun"))
("r" (search-web-dwim "ruigo"))))
お気に入りのページを開いたりアプリを起動させたりするための設定
Melpaにあるpackage hydra を使うことでお好みのミニバッファーメニューを構築できます。主にEmacsの編集をしているときに必要となるサイトを設定しておくと便利です。私の場合、Emacsから起動できたら便利かなと思うApplicationもいくつか設定しています。
(key-chord-define-global
"kl"
(defhydra hydra-browse (:hint nil :exit t)
"
^Shop^ ^SNS^ ^Repos^ ^GH^ ^Favorite^ ^Others^ ^Applications^
^^^^^^------------------------------------------------------------------------------------------------
_a_: Amazon _t_: Twitter _g_: minorugh _h_: HOME _j_: Jorudan _D_: Dropbox _c_: Calendar
_r_: Rakuten _u_: Youtube _0_: my gist _d_: d.kukai _n_: News _x_: Xserver _l_: ForkLift
_y_: Yodobashi _f_: Flickr _1_: masasam _m_: m.kukai _w_: Weather _q_: Qiita _@_: AirMail
_k_: Kakaku _e_: Evernote _2_: gitbucket _b_: BBS _s_: SanyoBas _p_: Pocket _i_: iTerm
"
("a" (browse-url "https://www.amazon.co.jp/"))
("r" (browse-url "https://www.rakuten.co.jp/"))
("y" (browse-url "https://www.yodobashi.com/"))
("k" (browse-url "http://kakaku.com/"))
("t" (browse-url "https://twitter.com"))
("u" (browse-url "https://www.youtube.com/channel/UCnwoipb9aTyORVKHeTw159A/videos"))
("f" (browse-url "https://www.flickr.com/photos/minorugh/"))
("e" (browse-url "https://www.evernote.com/client/web#?an=true&n=02ab918a-18a7-472b-a166-835a922d3fad&s=s278&"))
("g" (browse-url "https://github.com/minorugh/emacs.d"))
("0" (browse-url "https://gist.github.com/minorugh"))
("1" (browse-url "https://github.com/masasam/dotfiles/tree/master/.emacs.d"))
("2" (browse-url "http://localhost:8080/minoru"))
("h" (browse-url "http://gospel-haiku.com/"))
("d" (browse-url "http://gospel-haiku.com/d_kukai/"))
("m" (browse-url "http://gospel-haiku.com/m_kukai/"))
("b" (browse-url "http://gospel-haiku.com/danwa/"))
("B" (browse-url "https://app.box.com/folder/0"))
("j" (browse-url "https://www.jorudan.co.jp/"))
("n" (browse-url "https://news.yahoo.co.jp/"))
("w" (browse-url "https://tenki.jp/week/6/31/"))
("s" (browse-url "http://www.sanyo-bus.co.jp/pdf/180913.pdf"))
("x" (browse-url "https://www.xserver.ne.jp/login_server.php"))
("D" (browse-url "https://www.dropbox.com/home/emacs.d"))
("q" (browse-url "https://qiita.com/minoruGH"))
("v" (browse-url "https://drive.google.com/drive/u/0/my-drive"))
("P" (browse-url "https://photos.google.com/?pageId=none"))
("p" (browse-url "https://getpocket.com/a/queue/list/"))
("." hydra-dired/body)
("/" hydra-works/body)
("c" my/calendar-app)
("l" my/forklift-app)
("@" my/amail-app)
("i" my/iterm-app)))
;; Launch for Mac applications
(defun my/calendar-app ()
"Launch for calendar.app."
(interactive)
(shell-command "open -a calendar.app"))
(defun my/forklift-app ()
"Launch for forklift.app."
(interactive)
(shell-command "open -a forklift.app"))
(defun my/amail-app ()
"Launch for airmail3.app."
(interactive)
(shell-command "open -a 'airmail 3.app'"))
(defun my/iterm-app ()
"Launch for iterm.app."
(interactive)
(shell-command "open -a iterm.app"))
ChromeのテキストエリアをEmacsでリアルタイム編集するための設定
Google Chromeに拡張機能 Atomic Chrome をインストールします。つづいて、EmacsにMelpaからatmic-chrome.elをパッケージインストールしてinit.elに下記の設定を追加します。私の場合、markdownでも書けるように設定しています。
;; atomic-chrome
(atomic-chrome-start-server)
(setq atomic-chrome-default-major-mode 'markdown-mode)
ChromeからEmacsへ色々Captureする
Chromeに拡張機能 Org Capture をインストールします。導入の詳細は このページ を見よ…とのことで、いろいろ設定が必要なように書かれているのですが、私の場合はMac側の設定は何もしない状態でも動きました。
また、org-capture-templates の設定例も書かれていましたがうまく動かなところもあってので少し変えました。WEBページを開いた状態でChromeの拡張機能のアイコンをクリックするとorg-captureの入力画面が起動しWEBページの情報が自動的にCaptureされます。
region選択してCaptureする
WEBページの必要なCODEの箇所などをregion選択してCaptureアイコンをクリックすると capture-template の “p” の設定に従って反応します。下記の画像ではTitleを入力するためにミニバッファーが入力待ちになっています。
何も選択しないでCaptureする(bookmarkするだけ)
region選択なしでChromeのCaptureアイコンをクリックした場合は、“L” の設定に従って反応します。
Captureされたリンクにカーソルを置いて、“C-c o” でプラウザを開くことができます。
org-modeの設定は、『効率よくプログラミングを覚えるためにしていること 』の記事で紹介されているものをベースにして、orgファイルを閲覧するためのミニバッファーメニューを hydraで設定しました。viewモードで開くほうがキー操作が楽ですし、Tabキーでの折り畳み操作に便利なようにカーソルをバッファーの先頭行へ移動させています。
(use-package org)
(setq org-log-done 'time)
(setq org-use-speed-commands t)
(setq org-src-fontify-natively t)
(setq org-agenda-files '("~/Dropbox/org/"))
(setq calendar-holidays nil)
(bind-key "C-c a" 'org-agenda)
(bind-key "C-c c" 'org-capture)
(bind-key "C-c o" 'org-open-at-point) ;; Open link
(setq org-capture-templates
'(("p" "Code capture with Chrome" entry (file+headline "~/Dropbox/org/code.org" "Code")
"* %^{Title} \nSOURCE: %:link\nCAPTURED: %U\n\n #+BEGIN_QUOTE emacs-lisp\n%i\n#+END_QUOTE\n" :prepend t)
("L" "Link capture with Chrome" entry (file+headline "~/Dropbox/org/links.org" "Links")
"* [[%:link][%:description]] \nCAPTURED: %U\nREMARKS: %?" :prepend t)
("m" "Memo" entry (file+headline "~/Dropbox/org/memo.org" "Memo")
"* %? %U" :prepend t)
("r" "Remember" entry (file+headline "~/Dropbox/org/remember.org" "Remember")
"* %? %i" :prepend t)
("t" "Task" entry (file+headline "~/Dropbox/org/task.org" "Task")
"** TODO %? \n SCHEDULED: %^t \n" :prepend t)
("f" "Future Task" entry (file+headline "~/Dropbox/org/task_future.org" "Future")
"** TODO %? \n" :prepend t)))
(setq org-refile-targets
(quote (("~/Dropbox/org/archives.org" :level . 1)
("~/Dropbox/org/remember.org" :level . 1)
("~/Dropbox/org/memo.org" :level . 1)
("~/Dropbox/org/task.org" :level . 1))))
;; Open GTD files with hydra
(bind-key
"C-;"
(defhydra hydra-gtd (:hint nil :exit t)
"
[GTD] _a_:Archives _m_:Memo _c_:Code _l_:Links _r_:Remember _t_:Task _f_:Future_Task"
("a" my/archives-org)
("m" my/memo-org)
("c" my/code-org)
("l" my/links-org)
("r" my/remember-org)
("t" my/task-org)
("f" my/future-org)
("." hydra-dired/body)
("," hydra-browse/body)
("q" keyboard-quit)))
;; Open GTD files in view-mode
(defun my/archives-org ()
"Open archives.org."
(interactive)
(view-file "~/Dropbox/org/archives.org")
(goto-char (point-min)))
(defun my/code-org ()
"Open code.org."
(interactive)
(view-file "~/Dropbox/org/code.org")
(goto-char (point-min)))
(defun my/links-org ()
"Open links.org."
(interactive)
(view-file "~/Dropbox/org/links.org")
(goto-char (point-min)))
(defun my/remember-org ()
"Open remember.org."
(interactive)
(view-file "~/Dropbox/org/remember.org")
(goto-char (point-min)))
(defun my/memo-org ()
"Open memo.org."
(interactive)
(view-file "~/Dropbox/org/memo.org")
(goto-char (point-min)))
(defun my/future-org ()
"Open task_futurear.org."
(interactive)
(view-file "~/Dropbox/org/task_future.org")
(goto-char (point-min)))
(defun my/task-org ()
"Open archives.org."
(interactive)
(view-file "~/Dropbox/org/task.org")
(goto-char (point-min)))
ブックマークの管理について考えてみる
『Chromeのブックマークの整理法』 の記事がとても参考になりました。私の場合、次のような棲み分けをしています。
- Chromeから頻繁にアクセスするWEBページ ブックマークバーに入れる(アイコンのみにするとたくさん入れられる)
- あとでもう一度見たい…というような個別の記事 Pocketに入れる(ゴミ屋敷にならないように時々掃除する)
- Emacsでの作業に関連があって情報資源として残しておきたいもの org-captureする(これも時々棚卸し)
ChromeのブックマークバーやPocketに保存したものはスマホにも自動的に同期されます。org-caputerしたものは Orgzly をインストールしてDropboxで同期しておけばスマホで見ることができます。GitHubもスマホアプリで閲覧できます。このようにスマホから自宅Workのチラ見ができようにしておくことはとても重要です。パソコンと睨めっこしていて思考が行き詰まったとき、バスや電車での移動中にリラックスしてスマホでチラ見ているとふと柔軟な発想が授かる…という経験を何度もしています。きちんとしたコンセプトのもとにブックマークを整理しておいて、いつでもどんな場所からでもすぐに見つけられるようにしておくというのはとても大事なことだと思います。