Emacs ctrlf を migemo 対応にしてみた!

最近emacsのパッケージ管理には、straightを使っています。 その作者が Isearch や Swiper、helm-swoop に代わる、ctrlf というパッケージをリリースしていたので、試しに使ってみました。

github.com

基本的な操作感は Isearch と同じですが、オーバーレイ表示で検索にヒットした数と何番目の検索位置にいるのかわかるのは便利だと思いました。残念なのは、日本語をインクリメンタルサーチができる migemo に対応してないことでした。

ドキュメントを読むと、ctrlf-style-alist に設定を追加すれば migemo が使えそうでした。 試行錯誤の結果、以下の設定を追加することで、ctrlf からも migemo することができました。

   (add-to-list 'ctrlf-style-alist '(ctrlf-migemo . (:prompt "Migemo"
                                                    :translator migemo-search-pattern-get
                                                    :case-fold ctrlf-no-uppercase-regexp-p)))

あとは ctrflを実行中に、サーチスタイルを C-o s で Migemo に変更できます。

最初から migemo 検索したい時は・・・

  (defun ctrlf-forward-migemo ()
    (interactive)
    (ctrlf-forward 'ctrlf-migemo))

・・・のような関数を定義しておけばOKでした。

とはいえ、今のところ helm-swoop を置き換えられないので、Isearch に戻したい時もあります。(^^;

いちいち M-x するのも面倒なので、オン・オフ用関数もついでに作成しました。

  (defun toggle-ctrlf-mode ()
      (interactive)
      (if ctrlf-mode
          (progn
            (ctrlf--delete-all-overlays) ;; これを実行しないと Isearch から helm-swoop した時に画面表示がおかしくなる。 
            (ctrlf-mode -1)
            (message "ctrlf disabled"))
        (progn
          (ctrlf-mode +1)
          (message "ctrlf enabled"))))

Things3にTextwellからタスクを追加する方法

MaciOSで、タスク管理アプリのThings3を使い始めました。タスクをインボックスに追加するのに、Textwellから簡単に追加できればいいのにと思ったので、Textwell用のアクションを作ってみました。

作ったアクションは2つで、1つはTextwellの画面上のテキストを1行単位で全てインボックスに追加するもの。もう1つは、Textwellで作業している時に思いついた1行のテキストをタスクとして追加するものです。

全てのテキストをインボックスに追加するアクション
if(T.text){
  text=encodeURIComponent(T.whole);
  url="things:///add?titles="+text;
}else{
  url = "things:///show?id=inbox";
}
T(url, {option:"clearText"});

上記のアクションを実行すると、Textwellの全ての行をタスクとしてThings3に追加して、Things3を起動します。同時に、Textwellの画面をクリアします。Textwellの画面が空の時は、Things3のインボックスを表示します。

1行分のテキストをインボックスに追加するアクション
if(T.current){
  url="things://x-callback-url/add?title="+T.stdin.currentText+"&x-success=textwell:&name&";
}else{
  url = "things:///show?id=inbox";
}
T(url, {option:"clearCurrent"});

上記のアクションを実行すると、Textwellのカーソルがある行のみをThings3に追加します。1つめのアクションでは、Things3の画面に切り替わりますが、こちらはタスクを追加して再びTextwellに戻ります。
Textwellで何かを書いている時、追加したいタスクを思いついたら、1行にタスクを入力してインボックスに追加して、再びTextwellで作業を継続する時に便利です。

Textwellのアクションを作るのは初めてなので、「W&R : Jazzと読書の日々」様の「OmniFocus3にTextwellからタスク追加する方法を考えてみた」という記事を参考にさせていただきました。ありがとうございました。m(__)m

OmniFocus3にTextwellからタスク追加する方法を考えてみた - W&R : Jazzと読書の日々

helmで最近開いたディレクトリを開く(修正版Ver2)

helmをアップデートしたら、emacs 起動時にエラーが出るようになったので修正しました。

    ;;helm recentf only directories  
    ;; === defclass の前に追加 ===
    (require 'helm-for-files)   
    (defclass helm-recentf-directory-source (helm-recentf-source)    
    ;; 以下略

事前に helm-recentf-source が定義されている、helm-for-files を require する必要があるみたい。

emacs の org-agenda と tabbar.el

このところ emacs に tabbar.el を入れて、便利に使わせてもらっています。(^^)

特に気に入っているのが、各メジャー・モードごとに自動的にタブをグループ化してくれる機能です。多くのバッファを開いている時、バッファを切り替えるだけで、そのメジャー・モードのバッファリストがタブとして表示されるので便利です。

でもなぜか、tabbar.el の設定を紹介するブログでは、この機能を無効にしているケースが多いのが不思議です。(^^;

そんな便利な tabbar.el ですが、1つだけ困っていたのは org-agenda で予定などを確認して、予定が記録されている orgファイルを開くと、org-agenda が開いたすべての orgファイルがタブとして表示されてしまうことです。

表示されるだけならまだいいのですが、修正作業を終えたバッファを閉じようとすると、他の orgファイルのバッファがタブとして開いているために、すべての orgファイルのタブを閉じるまで、org-agenda の画面に戻ることができません。

いろいろと試行錯誤した結果・・・

(tabbar-local-mode -1)

(add-hook ‘org-mode-hook 'tabbar-local-mode)

・・・として tabbar-local-modeを有効にして、org-mode の時にはタブを表示しない設定にすればOKでした。

Mac で emacs の irony server がコンパイルできない時

連休中は久々にCでプログラミングでもしようかと思ったら、emacs の irony-mode がエラーを出して動きませんでした。(^^;

OS X 10.11 El Capitan の環境で、irony server のコンパイルに必要な llvmbrew でインストールしてあります。 READMEを読むと、brewllvm をインストールする時は、 --with-clang オプションをつけるように指示がありますが、現在 brew でインストールされる llvm にこのオプションはありませんし、指定しなくても問題ありませんでした。

irony-mode の最新版をインストールした後、M-x irony-install-server を実行しますが、Mac だとこの方法ではエラーが出ます。なので、irony をインストールしたディレクトリー内の server ディレクトリに、 build というディレクトリを作成して、以下の操作は build のディレクトリ内に移動して行います。

そのまま irony-install-server で表示される内容で cmake を実行すると、includeファイルが見つからなかったり、libclang が見つからなかったり、リンカー実行時に c++ のライブラリを使うように指示する -lstdc++ オプションが指定されません。

irony-mode の Github の Issues を見たら、その対策が紹介されていました。それを参考に、以下のように cmake を実行したら、ようやく irony-server がコンパイルできました。

cmake -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -DCMAKE_PREFIX_PATH=/usr/local/opt/llvm -DCMAKE_INSTALL_RPATH=/usr/local/opt/llvm -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE -DCMAKE_INSTALL_PREFIX\=/Users/"Your UserName"/.emacs.d/irony/ /Users/"Your UserName"/.emacs.d/elpa/irony-20170427.1601/server && cmake --build . --use-stderr --config Release --target install

"Your UserName"には、ご自分のホーム・ディレクトリを入れてください。また、irony のインストールされるディレクトリ名もバージョンアップなどで変更されますので注意が必要です。

また、これは必要ないかもしれませんが、brewllvm をインストールした時に表示される・・・

 export PATH="/usr/local/opt/llvm/bin:$PATH"

・・・も私は設定してあります。

(2017.08.25追記)

irony-20170821.1300では、M-x irony-server-install でコンパイルできるようになってました。

(2018.12.13追記)

irony-20181211.1959で再びコンパイル失敗する。 以下の記事の方法にて対処。

qiita.com

org-modeでの詳細なスケジュール設定方法

emacsでorg-modeを利用していて、ちょっと複雑なスケジュールを設定したい時に困ったので、調べたことをメモしておきます。 org-modeのFAQ によれば、以下のような指定ができるようです。

org-modeで複雑な予定を設定する。

1) 長期間に渡る予定 <日付>と<日付>を -- でつなぐ。

 * 休暇
 <2009-03-20 Fri>--<2009-04-01 Wed>

 限られた期間のスケジュールは・・・

 ** 授業 7:00pm-9:00pm
   <%%(org-class 2009 2 16 2009 4 20 1 10)>

 ・・・という書き方もあります。最後の 1 と 10 で、それぞれ月曜日、第10週を例外としています。

 例外とする週を設定できるのは便利ですが、1年の通算週での指定なのが、少し不便かも。

2) 毎週繰り返される予定 日程にどういう周期で繰り返されるのかを設定。

 * 定例ミーティング
 <2009-01-20 Tue 14:00 +1w>

  例の場合、+1w で毎週の繰り返し、+3dなら3日ごとの繰り返し、+1mなら1ヶ月ごとの繰り返し。   指定方法は、+1wの他に .+1wという形式もあるようですが、2つの違いが今ひとつわかってないかも。(^^;

3) 週末以外に繰り返される予定の設定方法。

 ** 毎日の会議
 <%%(memq (calendar-day-of-week date) '(1 2 3 4 5))>

 例は、土日以外に実施される予定。

4) 毎月第3水曜日に繰り返す設定。

 * 月例会議
  <%%(diary-float t 3 3)>

5) ある期間の特定の曜日のスケジュール設定。

 ** 授業 7:00pm-9:00pm
   <%%(and (= 1 (calendar-day-of-week date)) (diary-block 2 16 2009 4 20 2009))>

  例は、2009年の2月16日から4月20日の毎週月曜日を指定した場合。   曜日は、日曜 = 0、月曜 = 1・・・で指定。

 もっと複雑な・・・

** 授業 7:00pm-9:00pm
   <%%(unless (diary-block 3 9 2009 3 13 2009) (and (= 1 (calendar-day-of-week date)) (diary-block 2 16 2009 4 20 2009)))>

 ・・・といった設定もできるようですが、あまり複雑にすると何を設定したのか把握しづらいかも。(^^;

 その他の例も、org-FAQで紹介されていますが、個人的には上の設定くらいで十分かも。

[おまけ]Macの通知センターを使って予定を通知する方法

 mac の場合 terminal-notifier を導入すると、mac の通知センターからも予定を通知してくれるようになるので便利です。(emacsの設定は、以下を参照)

;; 予定を通知センターで表示
(setq appt-time-msg-list nil)    ;; clear existing appt list
(setq appt-display-interval '10) ;; warn every 10 minutes from t - appt-message-warning-time
(setq
  appt-message-warning-time '10  ;; send first warning 10 minutes before appointment
  appt-display-mode-line nil     ;; don't show in the modeline
  appt-display-format 'window)   ;; pass warnings to the designated window function
(appt-activate 1)                ;; activate appointment notification

(org-agenda-to-appt)             ;; generate the appt list from org agenda files on emacs launch
(run-at-time "24:01" 3600 'org-agenda-to-appt)           ;; update appt list hourly
(add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt) ;; update appt list on agenda view

;; set up the call to terminal-notifier
(Defvar my-notifier-path "terminal-notifier")  
(defun my-appt-send-notification (title msg)
  (shell-command 
   (concat my-notifier-path " -message " msg
           " -title " title
           " -sender org.gnu.Emacs -active org.gnu.Emacs"
           " -sound Funk")))

;; designate the window function for my-appt-send-notification
(defun my-appt-display (min-to-app new-time msg)
  (my-appt-send-notification 
    (format "'Appointment in %s minutes'" min-to-app)
    (format "'%s'" msg)))

;; Call function my-appt-display before function appt-display-window.
(advice-add 'appt-disp-window :before 'my-appt-display)

; 保存時にorg-agenda-to-apptを実行
(add-hook 'org-mode-hook
      (lambda() (add-hook 'before-save-hook
                          'org-agenda-to-appt t)))