読者です 読者をやめる 読者になる 読者になる

ぐるっとぐりっど

日曜プログラマがいろいろ試してみたことを、後の自分のためにまとめておく場所

zenburnテーマのregionのbackgroundが見辛かったのでテーマを少しいじった

はじめに

しばらくmisteriosoをテーマとして使ってたけど、最近はzenburnを使ってる。
理由は簡単で、Emacs Theme Gallaryで最も人気が高かったから。
https://pawelbx.github.io/emacs-theme-gallery/

落ち着いた色合いが気に入っているといえばそうなんだけど、気になるところもいくつかあり、そのひとつが色が弱々しくて視認性が悪いところ。
特に範囲選択したところ、リージョンの背景が色の違いがなさすぎてつらい。

f:id:grugrut:20170213223901p:plain

これならまだわかる

f:id:grugrut:20170213223946p:plain

単語レベルでmultiple-cursors使おうとすると、もうダメ

色のカスタマイズ

zenburnテーマは、zenburn-with-color-variablesマクロで各faceの設定をしてるので、init.elにこんな感じの設定をいれてみた。

(zenburn-with-color-variables
    (custom-theme-set-faces
     'zenburn
     `(region ((t (:background ,zenburn-bg-2))))))

zenburn-bg-2は、いってしまえば、#000000と、完全なる黒なのだけど、これぐらい極端にやったほうがよい感じ。

f:id:grugrut:20170213224247p:plain
くっきり表示される。

f:id:grugrut:20170213224252p:plain
単語レベルでもこの通り。

おまけ

github.com

zenburnのissueには、「他のテーマは、regionが通常の箇所より明るい色が普通だから、もっと明るい色使おうぜ!」って提案されてるものの「そんなんしたら見辛くなるじゃん」と一蹴されてた(issueだけに)。

その通りだと思うけど、デフォルトも十分見辛いと思う。スタイリッシュさが失なわれるのは確かなので、おとなしく他のテーマに移ることも検討しよ。

Google Code Jamに向けて、goで雛形を書いてみた

遅ればせながら、最近Go言語に興味が出てきたので、普段はGCJ(Google Code Jam)をはじめ、競技プログラミングJavaで書いているけど、その雛形をgoでリライトしてみた。

github.com

だいたい競技プログラミングのinputはスペース区切りのテキストで、outputは一行で、というのが基本なので、それに対応しているはず。

outメソッドがあらかじめfmt.Sprintf()で整形したstringを渡すことを前提としていて、若干使いづらいのが難点で、

out(fmt.Sprintf("Case #%v: my answer\n", test))

と渡さなければならない。

func out(format string, s ...interface{}) {
	fmt.Printf(format, s)
}

で、仲介できると思ったのだけど、期待通りは動かなかった(複数渡した引数が、配列?として渡ってしまう)。

さすがに、渡し方はあるはずなので、さらに調査が必要そう。

fmtパッケージのソースを見るのが一番てっとり早いのかな。

みんなのGo言語[現場で使える実践テクニック]

みんなのGo言語[現場で使える実践テクニック]

org-modeで計時(Clocking)する際に特定のTODOキーワードの場合だけ状態変更する

この記事は、.emacs Advent Calendar 2016の18日目の記事です。

org-modeの小ネタです。

はじめに

org-modeではTODO管理の中で、そのタスクにかかった時間を計測することができるようになっています。

C-c C-x C-i→時間計測を開始する(clock-in)

C-c C-x C-o→時間計測を終了する(clock-out)

で、便利なことに、clock-inした場合に、自動でTODOキーワードを変更することができます。

;; 時間計測を開始したら自動でSTARTED状態にする
(setq org-clock-in-switch-to-state "STARTED")

これをやっておくと、未着手のTODOを着手(時間計測開始)すると、STARETEDになり、着手済か未着手かがわかりやすくなるというわけです。

f:id:grugrut:20161217161555p:plain

Aプロジェクトを開始した状態。AプロジェクトはSTARTEDと表示され、BプロジェクトはTODOのままになっている。また、モードラインには計時しているタスクが表示されるのも便利。


org-captureを活用すると、タスクに着手している際に割り込み(電話等)が入って中断された場合でも、割り込まれたものも含め簡単に計時することができます。詳しくはこちらの過去記事をご覧ください。

grugrut.hatenablog.jp

このやりかたで困ったこと

そんなこんなでやってたのですが、困ったことがおきました。

それがこれです。

f:id:grugrut:20161217162528p:plain

本当のTODOも、一時的に実施していたTODOで無い作業も、ミーティングのような計時だけしておきたいものもすべて、clock-inすると皆STARTED状態になってしまって、何が本当のTODOなのかわからなくなってしまうのです(今回は例として適当に作りましたが、実際はもっと雑多なものが30個近くたまってしまいました)。

本当は、GTDでは日次レビュー、週次レビューは基本なので、その中で不要なものを完了状態にしていくのが基本なのですが、そうはいっても、これだけたまると片付けるのも面倒だし、そもそも計時だけしたいものをいちいち完了に変更するのも面倒だし、ということで、モチベーションがかなり下がってしまいました。

計時だけして、TODOでないものは、TODOキーワードいらないようにできないだろうか、と虫の良いことを考えていました。

そんな都合のよいやりかた

実はorg-clock-in-switch-to-stateには関数を指定することができます(できること自体は知ってたけど、わざわざそれをする意味がわかってなかった)。

;; 時間計測を開始したらSTARTED状態に
(setq org-clock-in-switch-to-state 'my-org-clock-in-switch-to-state)

;;; TODOの場合だけSTARTEDに変更する
(defun my-org-clock-in-switch-to-state (state)
  (when (or (string-equal state "TODO")
            (string-equal state "STARTED"))
    "STARTED"))

my-org-clock-in-switch-to-stateには前の状態のTODOキーワードが入ってくるので、TODOか既にSTARTEDの場合のみ"STARTED"を返すようになっています(よくよく見直すとSTARTEDを条件に入れる必要ないし、ヒットしない場合はstateをそのまま返したほうがよいのかな?)

そうするとこんな感じで、TODOに設定していない場合は、STRATEDが設定されないので、org-agendaを汚さないで良いかんじ。
f:id:grugrut:20161217163729p:plain

まとめ

他の人の.emacsを読んでて知ったのだけど、なぜそんな設定をしているのか想像しながら読むと勉強になるね

明日はtakaxpさんの「高速起動用ミニマム*scratch*バッファ」の予定です。楽しみですね。

Emacs25に導入されたXWidgetに関して理解を深める

この記事は、Emacs Advent Calendar 2016の3日目の記事です。

はじめに

emacs25.1が2016年9月17日にリリースされました。
なかでも注目を(個人的に)浴びていたのが、もともとブランチして開発されていたものがマージされたXWidgetsです。

XWidgetsは、リリースノートを見てみると、

Xwidgets: a new feature for embedding native widgets inside Emacs buffers.

https://www.gnu.org/software/emacs/news/NEWS.25.1

と、ネイティブなウィジェットemacsのバッファに埋め込めるらしいです。
実際なにができるか用途がぱっとは思い浮ばないものの、可能性としてはおもしろいと思います。

EmacsWikiの記事を見てみると、emacsの中にemacsを埋め込むという、よくわからない状況になっています。

EmacsWiki: Emacs X Widgets


ただ、実際のところ、巷のブログ等見てみても、xwidget-webkit-browse-urlコマンドを使ってみた、程度の記事しかみつからず、ウィジェットの挿入方法がよくわかなかったので、ウィジェットの挿入方法を調べてみました。

(結論から書いておくと、emacs 25.1では、任意のウィジェットを挿入することはできません。M-x xwidget-webkit-browse-urlでネイティブブラウザをバッファに表示するぐらいしかできません)

ビルド

Xwidgetsはどのemacsでも利用できるわけではなく、ビルド時に、--with-xwidgetをつけた場合のみ利用することができます。
Xwidgetsが使えるかどうかは、M-x xwidget-webkit-browse-urlを実行してみるのがてっとりばやいと思います。有効でない場合は、

Your Emacs was not compiled with xwidgets support

と優しく教えてくれます。なお、xwidget-webkit-browse-urlの使い方は巷にあふれているので、そちらに譲ることにして、ここでは割愛します。

--with-xwidgetオプションを利用できるのは、今のところLinux(Unix)、Mac OSWindowsCygwin上のみのようです。Bash On Ubuntu On Windows上やmsys上でできないか調べたり、いろいろ試したりしてみたのですが、X Serverが無いので駄目のようです。残念。

サンプルコード

任意のWidgetとして、ボタンを挿入する超簡単なサンプルコードです。

(require 'xwidget)
(xwidget-insert (point-min) 'Button "Click me" 100 100)

これを評価すれば、

f:id:grugrut:20161129143317p:plain

な感じでボタンが表示されます。ボタンだったら、M-x customizeでも表示されるじゃんと思ってそちらのボタンも見てみたのですが、ちょっと見た目が違いますね。

f:id:grugrut:20161129143534p:plain

もちろんボタンだけでなく、スライダーや他のGtkWidgetを挿入することもできます。

(xwidget-insert (point) 'slider "slide me" 300 50)

(xwgir-require-namespace "Gtk" "3.0")
(put 'ColorButton1 :xwgir-class '("Gtk" "ColorSelection"))
(xwidget-insert (point) 'ColorButton1 "xwgir-color-button " 500 300)

f:id:grugrut:20161203122417p:plain

(put 'ColorButton1 :xwgir-class '("Gtk" "ColorSelection"))

で、デフォルトでは設定されていないwidgetを設定できるようなのですが、
https://developer.gnome.org/gtk3/stable/GtkWidget.html
配下にあるクラスをセットしても、表示されるものと表示されないものがあるので、なにかしら表示できるwidgetに条件があるようなのですが、そこは残念ながらわかっていません。

苦しんだところ

実はこのサンプルコード、emacs 25.1では動作しません。
評価するとセグフォでコアを吐いてemacsが死んでしまいます。ビルドミスかと思って調べたら、emacs 25.1の方には制限をかけてあってxwidget-webkit-browse-url以外の用途では使えないようになっているようです。

Xwidgetブランチのコードにあるsrc/xwidget.c
http://bzr.savannah.gnu.org/lh/emacs/xwidget/files

DEFUN ("make-xwidget", Fmake_xwidget, Smake_xwidget, 7, 8, 0,
         doc: /* Make an xwidget from BEG to END of TYPE. 

If BUFFER is nil it uses the current buffer. If BUFFER is a string and
no such buffer exists, it is created.

TYPE is a symbol which can take one of the following values:
- Button
- ToggleButton
- slider
- socket
- socket-osr
- cairo
*/

(中略)

  if (EQ(xw->type, Qwebkit_osr)||
      EQ(xw->type, Qsocket_osr)||
      (!NILP (Fget(xw->type, QCxwgir_class)))) {
      block_input();
      xw->widgetwindow_osr = gtk_offscreen_window_new ();

(後略)

emacs 25.1のコードにあるsrc/xwidget.c
https://github.com/emacs-mirror/emacs/tree/emacs-25

DEFUN ("make-xwidget",
       Fmake_xwidget, Smake_xwidget,
       5, 6, 0,
       doc: /* Make an xwidget of TYPE.
If BUFFER is nil, use the current buffer.
If BUFFER is a string and no such buffer exists, create it.
TYPE is a symbol which can take one of the following values:

- webkit

(中略)

  if (EQ (xw->type, Qwebkit))
    {
      block_input ();
      xw->widgetwindow_osr = gtk_offscreen_window_new ();

(後略)

記事としてまとめるために、もう一度ソース読んでたら、冒頭のコメントにばっちり書いてあったorz

ひさしぶりにCのソースを読んだせいで、いきなりコードの方を読むという冒険をしてしまったのが敗因です。

まとめ

  • emacs 25.1でXwidgetがマージされて、ネイティブウィジェットがバッファに表示されるようになった
  • マージはされたが、同じものがマージされたわけではないのでできることはかなり違う
  • ウィジェットを操作(ボタンならクリック、スライダーなら移動)したときに着火されるイベントがわからないと単に表示しておしまいなので、今後はその辺を調べたい。
    • 本当は、鬼軍曹.elGUIで、このキーを実行しろ、と表示するようなelispを書いてみたかった

明日4日目はinoueyuworksさんの「tabulated list 的な UI を量産するために」の予定です。楽しみですね。

補足

emacs25.1ではemacs inside emacsが実現できないかというとそうではなくて、jslinuxを開けばいいよ、とやさしい人がredditで回答してました。(なんかredditへのリンクを貼ると記事を保存できないので単なるテキストだけ残しておきます)

www.reddit.com/r/emacs/comments/4srze9/watching_youtube_inside_emacs_25/d5bvl4f/

PaizaでSランクになったけど残念な気持ちになった

paizaという、プログラマ向けの転職サイトがある。はてブにもときどき開発ブログがホッテントリになってる*1から、見たことある人も多いと思う。そこで何ができるかというと、難易度別の問題があって、自分のコーディングスキルを測定し、それを元にスキルに見合った転職ができるよ!ということだ。今のところ転職する気はないけど、転職の気がない人も気軽に受けてみて、と書いてあったので、試してみた。

で、Sランクまで上がったけど、問題があまりにも簡単すぎてこれでSランクとは、これじゃあ全然差が出ないじゃん、と残念な感じだった。


以下蛇足です。

これ書いてる人の素性

google code jamにここ3年くらい参加して、予選は突破するけど、1回戦を勝ち抜けないヘボいプログラマ。贔屓目に見ても中の下ぐらいの実力だと思う(このブログの他のエントリを見ればお察し)。

paizaの問題について

一応、公称としては、下記のレベルになっている。

初級(Cランクまでの問題)
if,for,while,foreach,変数、配列、連想配列、文字列操作、ソートを使って指示通りのプログラムを書けるか。回答スピード、正確性が問われる。


中級(Bランクまでの問題)
指示通りにロジックを組むだけでなく、自分で効率的なロジックを考えだせるか。またツリー構造、探索等を使いアルゴリズムを組めるか。


上級(Sランクまでの問題)
O(n²)⇒O(n)の様な計算量、メモリの削減を意識した高度なアルゴリズムが組めるか。問題によっては数学的(確率計算)問題についても問う。

https://paiza.jp/guide/guide

これはすばらしい問題たちである!こんなん無料でスキルチェックできるなんて、なんてすばらしいサービスなんでしょう!!!

ちなみに、同ページに載っている情報では、Sランクが上位2%、Aランクで上位8%らしい。

実際やってみた

ということで、各ランクの問題をひとつずつやってみた。問題内容は書いちゃダメよと書いてあったので、それは律儀に守ることにする。

Dランクの問題 → for文が書ければOKだった

Cランクの問題 → if文とfor文が書ければOKだった


うんうん、確かに初級はこの辺が求められるらしい。B問題からはもっと難しくなるんだろう。


Bランクの問題 → if文とfor文が書ければOKだった

Aランクの問題 → if文とfor文が書ければOKだった

Sランクの問題 → if文とfor文が書ければOKだった

どういうこと!?


結果として、ifとforと配列しか書いてない。

一応単に解けるだけではだめで、効率性が求められることにはなっている(省メモリとか、計算時間とか)。
でも、そんなん一度たりとも引っかからず。。。(Google code jamとか、at coderとかだと、結構この辺の効率化がキモになってきて、よくそこでつまるのだけども。。)

問題文自体は、レベルが上がると何とかややこしくなってくるけど、それは日本語的にややこしいだけで、アルゴリズム的には、その辺の入門書よりよっぽど簡単なことしか求められてない。これで上位2%って言われてもむしろ困ってしまうね。これがSの問題です、と出されてもあまり、Aとの差を感じないというか。

一応実際paiza経由で面接する場合は、書いたソースコードが企業側に送られるので、解ければ良しの糞コードでは、その後の円満な展開には期待できないことにはなってるっぽい。

感想

コードを実際に書いて、それを元に転職活動できるって考えは面白いと思うけど、正直なところ現状の問題では、Sランクですって言うのって、TOEIC600点ですって言うのと変わらないのでは、って程度に感じる*2。CodeIQのように、コーディング以外の問題も出てくるなら良いけど、コーディング一本であれば、簡単な問題(というかレベル差が出ない問題)だけでは厳しいのでは。さすがに世間で求められる水準のマックスがこの程度、ということであれば寂しいことこの上無しだし。もっと正解率5%未満とかそういった問題をバンバンだしていって欲しい。ということで今後に期待してます。

蛇足に継ぐ蛇足

調べてみると、なんかBランクぐらいから難しくて解けないって言ってる人もいるにはいるっぽいんだよなぁ

*1:過剰なまでのSIerディスりだったり、突っ込み所満載だったり

*2:900点なら自慢できるし、積極的にアピールしていきたいけど、アピールにならないし、むしろ逆効果になる場合すら

Windowsでemacsを使う各手段とメリットデメリット

はじめに

windowsemacsを使おうとすると、これまでは、MeadowNTEmacsか、と思っていたけれども、最近gnupackのことも知って、そちらを使っている。そして、最近、Windows10のanniversary updateにより、Windows上でUbuntuが動作するようになり、そちらも候補として挙がってきた。そこで、今Windows上でemacsを使う手段と、それぞれのメリデリについてまとめてみた。

Meadow

昔はWindowsemacsとなると、MinGWとかCygwinとかでunixバイナリ動かすのを除けば、meadowxyzzyか、という気がするけど、公式ページも消滅しているので、もはや俎上に載ることはないでしょう。私もWindowsではじめて使ったのは、meadowなので思い入れとしては強い。

NTEmacs

http://ftp.gnu.org/pub/gnu/emacs/windows/

いわゆるWindowsEmacsMeadowから卒業した後使い出した。

メリット

  • Windowsバイナリなので、ダウンロードすればすぐ使える。
  • 本家が出しているので、リリースは早いはず
  • emacsに閉じた範囲では、困ったことはない

デメリット

  • IMEとの親和性が良くないらしい(ddskk使っていたので、あまり意識したことはない)。対応するにはパッチが必要だけど、適用済みのものもあるのかな。
  • c/migemoとか、他のアプリと組合せて便利にしようと考えると、Windowsのことも意識する必要がでてきて嵌まる場合がある。

↓嵌まった例
grugrut.hatenablog.jp

gnupack

https://osdn.jp/projects/gnupack/

cygwinとセットで展開されている。スクリプト等も用意されているので、ダウンロードして展開するだけですぐに使える。今はこちらに乗り換えている。

メリット

  • 展開するだけでemacsだけでなくcygwinも使える(gvimとかいう異教徒向けのものすら含まれている)
  • migemo等の設定もすんでいたり、IMEパッチも適用されているので、そのあたりで苦労することはない

デメリット

  • Cygwin上で動かしているのでcygwinの問題に引きずられてしまう(Doing Vfork: resource temporarily unavailable)。検索するといろいろ出るには出るけれども、解決には至っていない(すぐ再発する)。
  • ひとりの手で開発されているので、プロジェクト存続が気力しだいなのでは?

bash On Ubuntu On Windows

Windows10から、bashWindows上で使えるようになり、Xserverさえどうにかしてしまえば、ubuntu用のemacsを動かすこともできるらしい。デメリットの自分でビルドしないといけない問題を対処していないため、コマンドプロンプト上で、emacs -nwして動くところまでしか確認していない。

メリット

  • Cygwinよりは、nativeよりというか、Windowsが責任もってプロセスをforkしてくれると信じているので、NTEmacscygwinのいいとこどりができるのでは。
    • NTEmacsよりも外部プロセスとの連携がしやすく、gnupackのようなプロセス起動エラーがおきないというような

デメリット

まとめ

bashOnUbuntuOnWindowsに今後期待するとして、しばらくは、gnupackを使いつづけるのがよいのかな

Windowsのgnupackのemacsで、package.elを使って大きなelispをバージョンアップするとプロセスがダウンする問題

はじめに

gnupackでemacsを使っているんだけど、org-modeとか、helm-coreとか、yasnippetとか、比較的大きなパッケージを、package.elでバージョンアップ(package-list-packagesで、u→x)すると、なんか知らないけど、emacsがダウンしてしまう。どうせ既知の問題だろうと思って調べてみても何も出てこない。

現時点で解決してないけど、ひとまずmemo

環境

M-x emacs-versionした結果は以下の通り

GNU Emacs 24.5.1 (i686-pc-cygwin) of 2015-11-08 on gnupack

gnupackで独自ビルドしたと聞いているやつ

ためしたこと

直接起動すると、何もわからないままダウンしてしまうので、cygwinのターミナルから開いて再現させてみる。
→ Segmentation Fault 11と出る


core dumpを吐くように設定し、再現させてみる
gdbで開いてみるも、特に情報はなにも出ない


WinDbgで、emacsプロセスにアタッチして、再現させてみる
→ 以下のログが出た。が、よくわからない。。。

Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Module load completed but symbols could not be loaded for path\to\app\cygwin\emacs\bin\emacs.exe
emacs+0x72dda:
00472dda 8903            mov     dword ptr [ebx],eax  ds:002b:ffffffff=????????
0:000:x86> kbnL
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 01d19c08 004f51d3 22dbccfc 01d19cc8 00000000 emacs+0x72dda
01 00000000 00000000 00000000 00000000 00000000 emacs+0xf51d3

エラーメッセージから、まずいとこおさわりしてしまっておまわりさんこいつです状態なように見える。
ただ、スタックバックトレース見ても、何もわからんちん状態。そもそもWinDbgやらgdbやらを使ったデバッグには慣れてないので、よくわからない。というか、そもそも解析には、pdbファイルのようなビルド時の情報が必要になるのではあるまいか?

想像と今後の方向

やはりバッファオーバーフローとか、そのへんで変なメモリ触っちゃって落とされた可能性が高いのではないかと想像している。
gnupackを使うまえは、nativeなw32バイナリ版のemacsを使ってたけど、そのときも結構yasnippetをバージョンアップしようとすると、too many open filesとか出てたし、ファイル数開きすぎとか、スタックオーバーフローとか、その辺が臭いような気がしているので、その辺をもっと調べてみよう。

もし、どなたか情報お持ちのかたは教えていただけると幸いです。