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

できる気がしてきた。

Githubな活動記録を公開してます

emacs xwidget-webkit-browse-urlをつかってみた。

皆さんこんばんは。 2日前にAtomへの愚痴を書いたわけですが、そこでウェブ開発のプレビューについてemacsでなんか良い方法を載せると宣言してしまったので、早速ネタを準備してまいりました。

開発版Emacsをインストール

  1. git clone --depth 1 git://github.com/emacs-mirror/emacs
  2. ./autogen
  3. ./autogen git
  4. ./configure --with-xwidgets
  5. make -j10
  6. make install

これで準備できました。 ここでのコツは最近masterにマージされた--with-xwidgetsオプションです。

試してみる。

こいつ自体は前から別ブランチで開発されていたのですが、僕の予想に反してマージされました。とにかく恐ろしいオプションです。まぁ、とりあえず見てみてください。f:id:ta2gch:20160216232857g:plain

どうですか? こいつ、なんとemacs内でWebkitを動かしてるんですぜ。

大変キモい機能ですがこいつがemacs 25.1より標準になるそうです… Emacsはどこを目指しているのでしょうか?

そのうちEmacsにノベルゲームエンジンを搭載s... あった。

Emacsに音楽機能を搭載s... あった。

Emacsってなんなんだ(哲学)

結論

というわけで、こいつを使えば、markdownだろうが、pandoc等を使ってコンパイルするなりして、Webkit上でみることができますね!

え、そこまでしなくてもbrowse-urlで十分だろう? 確かに。でも Emacs上で見たいんです!!!

補足

  • ubuntu上ではemacsの標準の依存パッケージ以外にlibwebkitgtk-3.0-devが必要でした。
  • EmacsなのにVimっぽい操作なのはEvilを動かしているからです。
  • color-themeはgithub.comです。

Atomエディタはあくまでプログラミンエディタだった話

みなさん、こんばんは。
ライトノベル俺の妹がこんなに可愛いわけがない」のキャラクター高坂桐乃ちゃんが
総務省の選挙のキャンペーンキャラクターに選ばれたと聞いて、「マジかよ。絶対、採用した人最終巻読んでないでしょ。*1」と思っちゃったta2gchです。

 

最近、勉強会向けの資料を作成する機会が多く、たいていMarkdownで作っているのですが、
勉強会の資料となると大抵コードブロックやテーブル記法が必要になったり、サンプルコードを眺めながら作るわけです。 Atomには`Ctrl-Shift-M`でマークダウンのライブプレビュー機能があり、サンプルコードを載せる際に視覚的に確認できて大変重宝していました。

 

当たり前のことですが、Atomのこのマークダウンのライブプレビュー機能はドキュメントが更新されるたびに全てを再描画しているようなので、文字を一文字打つたびにマークダウンのレンダリングが走ります。

 

ドキュメントの量が少ない場合は別に問題ないのですが、ドキュメントの量が多くなるとレンダリングの度に遅延が発生して大変です。

 

実際300行を超えたあたりからは、一文字打つたびに2秒くらい遅延するようになり、慌ててプレビュー画面を消そうとするのですが、プレビュー画面を消すまでにそれまでのレンダリング処理を終了指定なければならないため10秒くらい固まってから消えます。


そして、ひと通りうち終わって、また確認のためにプレビュー画面を立ち上げると、レンダリングのために10秒ほど待たされます。ついレンダリング結果を見て修正したくなりそのまま文字を打ち込むと、すぐに固まってしまいます。

 

Atomは全体的にかっこいいエディタではあるのですが、Electronベースの限界がありますね。どうしても、大量のテキストデータを扱うには早かったみたいです。せめて分割された小さいコードを書くのが精一杯といった感じでしょうか。

 

たまったものじゃないので、Emacsを使って書いたものをpandocでコンパイルしてブラウザで開くといった方法に戻ろうと思います。(この辺を良い感じにする方法については後日記事にしようと思います。)

 

ちなみに僕のPCのスペックは一昔前の8コア、メモリ8GBのデスクトップなので、
おそらくハードウェアのスペックが追いついていないということはないでしょう。

 

あぁ、Atomもまたエディタ道のゴールではなかったようですね。残念ですがEmacsに戻るとします。 

*1:もともと、彼女は千葉のモノレールのキャンペーンキャラクターに採用された実績もあるので驚きはしませんでしたが、あれは最終巻が出る前だったのでまだ納得できます。しかし、個人的に最終巻の結末ドン引きだったのでもし読んだ上で総務省が採用したのであれば、総務省はちょっとアレな人だったんだと思いますね。

DebianでWifiのドライバをインストールする。

みなさん、こんにちは。ta2gchです。 Linuxをつかっていらっしゃる皆さんなら当然のことかと思いますが、

Linuxをどれだけ使い込んでいるかは、使用中に起こる様々な様々なトラブルを対処する能力を見ればすぐにわかることだと思います。

例えば、

  • rm -rf $HOME/Documentで大事な書類データをふっ飛ばした。
  • ハードディスクの容量が少なすぎて起動できなくなった。
  • ディスクをフォーマットしたいが、GPartedが起動できない状況だ。

なんていうのが挙げられます。

そんななか、今回は、Debianをインストールしたは良いけれど、 「プロプライエタリWifiドライバをインストールしていなかったせいでインターネットから孤立してしまった!?」 な時の対処法を伝授します。

最近のノートパソコンは優先ポートを持っていないものもあるため、有線接続すらできないことがありますので、危機ですね。

しかし、安心してください。穿いてますよ。実はネットワークに繋がっていなくても、Wifiドライバをインストールする術はあります。

Case 1 ドライバがDebianリポジトリにNon-freeとして登録されている場合

この場合は至って簡単です。別のPCから、パッケージをダウンロードしてくてUSBに保存し、dpkgを実行するだけです。

え?別のPCすらない?今あなたが使っているスマホを使ってダウンロードして、 Androidなら、デバイスをマウントしてください。 Downloadsフォルダを探せばダウンロードしたドライバのパッケージが見つかるはずですよ?

こういう別のPCすらない状況でも使えるものを利用して復旧させるのもひとつのサバイバルテクニックってやつですね。

インテルのドライバである firmware-iwlwifiのインストル手順を書いておきます。

  1. Debianの公式サイトにあるパッケージのページにアクセスする。
  2. firmware-iwlwifi_20160110-1_all.debを市販のUSBにコピーする。
  3. DebianでUSBをマウントし、ホームフォルダfirmware-iwlwifi_20160110-1_all.debをコピーする。
  4. 端末を開き、rootになる($ su)
  5. dpkgを使ってインストール!(# dpkg -i firmware-iwlwifi_20160110-1_all.deb)
  6. 再起動する。

Case 2 ドライバがDebianリポジトリにない場合。

まず、ドライバを配布しているサイトを探してください。 例えば、PLANEXのGW-900Dという子機の場合、 公式サイトにドライバが配布しているサイトがありますので そこからドライバをダウンロードしてください。

ここですね。

また、公式サイトにない場合は、$ lsusbと入力することでドライバ名を表示させることができるので、 ドライバ名で検索してください。

そうすると、まあ大抵zipかtar.gzなので展開してREADMEを読みます。

今回のPLANEXのドライバの場合、運良くinstall.shを実行するだけだよ!と書いてあります。

では、早速install.shを実行してみましょう!

Error: make not found

なんと言うことでしょう。残念なことにmakeが無いと書いています。

じゃあ、apt-getでmakeをインストールしましょう。

'ftp.jp.debian.org' を解決できませんでした

なんと言うことでしょう。そういえばネットワークにつながっていないのでした。

万策尽きたぁぁぁぁぁ!!! …わけではありません。

実は、みなさんがDebianのインストールに使ったインストールメディアありますよね?

あれ、実はリポジトリとしても使えるのです!(ナンダッテー

早速リポジトリとして使ってみましょう。(ここではインストールメディアとしてUSBメモリが使われていることを想定しています。)

USBメモリを挿入後、一旦自動マウントを解除してからmntにマウントしなおしてください。

(なぜなら、自動マウントしたディレクトリの名前は大抵Debian 8.3.0 amd64 1のように空白文字が含まれているせいでややこしいからです。)

# umount /dev/sdb #sd○は環境によって違う
# mount  /dev/sdb /mnt

次に/etc/apt/source.listにリポジトリを登録しましょう。

# echo "deb file:///mnt jessie main contrib" >> /etc/apt/source.list

これで、登録は終わりです。あとは普段通り、

# apt-get update
# apt-get install build-essential linux-headers-amd64

これで、ドライバをビルドする準備は整いました。再度ドライバを展開したディレクトリに戻って

# ./install.sh

すると、見事ビルドが通って再起動を促すメッセージが表示されますので再起動してください。

再起動後は無事、子機が認識されているはずなのでいつもどおり設定すれば終わりです。

まとめ

以上でDebianのドライバをインストールする方法の紹介を終わりにしようと思います。

Ubuntuだとプロプライエタリなドライバもビルドインで入っていたりするのですが、 Debianのように硬派なディストリビューションだとプロプライエタリなドライバは入っていないので、こういった作業が必要になってくることがあります。

また、ドライバは大抵、Realtekbroadcomと言ったチップのベンダーの公式サイトでダウンロードできます。

こういった、日常生活での非常事態に対してクールに対処できるLinuxユーザになりたいものです。

余談

Debianの創設者であるイアン・マードック氏の訃報が流れましたね。

僕のOSSへの情熱とか考えはかの有名なDebian社会契約に大きく影響されています。

CentOSではなく、Debianを使い続けているのはDebianフリーソフトウェアへの姿勢を評価しているからです。

尊敬しているディストリビューションの創設者である彼の訃報はとても残念です。

心よりご冥福をお祈りいたします。

pkgbrewを公開しました

こんにちは、ta2gchです。

前々から非権限ユーザのまま使えるパッケージマネージャーが欲しくて、いろいろ試していました。 しかしどれも、自分にしっくりとくるものがなかったので、自作することにしました。

とはいえ、パッケージ数が少なければ意味がないので、NetBSDが開発しているpkgsrcをベースにpkgsrcをHomebrew風に使うインターフェースを提供する形で実現しています。

特徴としては、

  1. Homebrew 風の操作感 (install,deinstall, ... )
  2. Homebrew 風にGithubを自作パッケージのリポジトリにできる(tap/untap)
  3. HomebrewのFormulaと違ってuninstall方法をパッケージに記述できる (Makefileでパッケージを管理しているから)(pkgsrcの仕様を再度しらべたところ、厳しいようです。もし本当に必要になったらpkgbrewのuninstallにフックを作ろうと思います。(未定))
  4. Homebrewと違ってgcc&g++&shだけに依存している
  5. 簡易なインストール方法 (wget -O- https://git.io/pkgbrew | /bin/shだけ!!)

です。

なぜHomebrewを使わないというとLinux版のパッケージだと対応しているパッケージに満足しなかったからです。

かと言ってパッケージを自作しようにもFormulaではアンインストール方法を指定できないので、Quicklispのように外部に設定ファイルを置きたい場合、スマートな記述ができないことがあります。

そこでpkgsrcを単体で利用しようとしましたが、インストールしたい場合毎回 cd, make, make install するのは面倒くさい!

最後にpkgsrcのインターフェースnihを利用するか考えましたが、 いろいろ作りがお粗末で自分でも作れそうだったので真似してみたところ、 想像以上にうまくできたので、本格的に開発してみました。

今回はかなり自信作なのでぜひリポジトリを覗いて見てください!

pkgbrewはBSD二条項ライセンスの下でリリースされたOSSです。

それでは!

github.com

剰余とじゃんけん

こんにちは、ta2gchです。

プログラミングを始めるとき、必ずといって良いほど出される課題にジャンケンゲームがあります。

問題(ジャンケンゲーム)

次のような動作をするプログラムを書け。

標準入力から一文字(g,c,p)読み込んで、その一文字をユーザーの手とする。 次に乱数を用いてプログラム側の手を決める。 最後に標準出力に勝者を出力する。

さらに、

  • 入力を間違えると、再入力を促せ
  • 入力文字としてqを受け取った場合は終了せよ

などの派生課題もあり、盛り上がります。

この問題の意図は

  1. if文やwhile文(言語によってはswitch文)などの制御構造の理解
  2. I/Oに関する関数の使い方
  3. 乱数関数などのライブラリの使用

にあります。

ところで、普通にジャンケンゲームのコードを書くと思った以上に勝者判定するルーチンが長くなりがちですよね。

switch(user){
case 'g':
  switch(com){
  case 'g': printf("draw\n");
  case 'c': printf("win\n");
  case 'p': printf("lose\n");
  }
  break;
case 'c':
  switch(com){
  case 'c': printf("draw\n");
  case 'p': printf("win\n");
  case 'g': printf("lose\n");
  }
  break;
case 'p':
  switch(com){
  case 'p': printf("draw\n");
  case 'g': printf("win\n");
  case 'c': printf("lose\n");
  }
  break;
}

こんな感じでしょうか。

実はこの勝敗を判定する部分、1行に収めることができます。

今回は、どうやって一行にまとめるのか紹介します。

結論

まず結論を書いておきましょう。

  • user ユーザーの手
  • com プログラムの手
(user - com + 3) % 3

この値で勝敗を判定できます。 なぜこうなるのか、以下で説明します。

予備知識

剰余

「剰余」という言葉をご存知でしょうか?いわゆる「余りの数」というものです。

例えば 「5÷3」ならば

5÷ 3 = 1あまり2

となり、この時の剰余は2となります。

これをC言語では「%」という演算子を用いることで計算できます。

printf("%d\n",5%3); // 2と表示されます。

ちなみに「-5÷ 3」の場合は、

-5÷3=-2あまり1

と書け、剰余は1となります。(他にも定義の仕方はあります)

合同式

ある数aとある数bについてcで割った時、あまりが等しいときならば

a≡b (mod c)

と書き、これを合同式と呼びます。

より具体的には

1≡4(mod 3)

が成り立ちますね。(どちらも3で割ると1余るから)

数学とプログラミング

プログラミングでは、数学的知識を使うことで課題解決を大幅に短縮できることがたくさんあります。 例えば、1~100までの数の総和を求めるプログラムを書く場合、

int i,sum;
sum = 0;
for(i = 1;i <= 100 ; i++) {
sum += i;
}

と書くこともできますが、総和の公式を知っていれば

int n = 100;
int sum = 1/2 * n * (n + 1);

とかけ、100回の足し算が「1回の割り算と2回の掛け算、1回の足し算」だけで計算できるようになりました。

このように数学的知識をプログラミングに応用することで劇的な改善が望める場合があることを覚えておいてください。

では、ジャンケンの場合はどうすれば良いのでしょう?

本題

まず、入力が文字です。g,c,hでは四則演算できませんね。 そこで、とりあえずg,c,hに適当な数字を割り当ててみます。

  • 'g' ならば 1
  • 'c' ならば 2
  • 'p' ならば 3

まず引き分けの判定はすぐに思いつくかと思います。

if(user - com == 0) {
  printf("draw\n");
}

なぜなら、ユーザーとプログラムの手は同じなのでその値は同じ値(1か2か3)をとるはずですので、その差は0となります。

引き分け以外の時はどうでしょう。 ユーザーからプログラムの手を引き算した結果を下の表にまとめました。

user-com グー チョキ パー
グー 0 -1 -2
チョキ 1 0 -1
パー 2 1 0

0以外には一見周期がないように見えますが、

  • -1 ≡2 (mod 3)
  • -2 ≡1 (mod 3)

であることに注意して改めて表の値を3で割った時の剰余として見てみましょう

user-com グー チョキ パー
グー 0 2 1
チョキ 1 0 2
パー 2 1 0

なんと、

  • ユーザーが勝った場合は 2
  • プログラムが勝った場合は1

となっています!

したがって、ジャンケン勝敗判定は

「(user-com)%3の結果で求められる」 がわかりました!

しかし!

しかし、C言語ではこれではうまくいきません。 なぜならC言語の剰余計算は「絶対値が0に近い」値を返すという性質があり、つまり

-abs(a)%b 

負の値の場合はこのように計算してるようです。なので-2%3 の値は -2のままとなってしまいます。

困りましたね…

そこで使われるのが

-2 + 3 ≡ -2 (mod 3)

という、割る数を足しても剰余は変わらない性質です。

user - comは -2 から 2までの値しか取らないので3を加えることで 正の値となることに注意すれば、

(-2 + 3) % 3 は1 となり計算したい値が求められます!

ようやく求めたい式がC言語用につくれました。

int result = (use - com + 3) % 3; ///ジャンケン勝敗の判定

switch(result) {
case 0: print("draw\n");
case 1: print("lose\n");
case 2: print("win\n");

以上でジャンケンの判定を一行で計算できましたね!

これで、ふとジャンケン相手がほしたくなったときにすぐに作れます。

それでは。

環境の引っ越しをした時にMELPAから自動でパッケージをインストールをする。

新年なので、OSをUbuntuからManjaroに移行してみて遊んでいるta2gchです。

Emacsを使っていると、随分前にインストールしたパッケージを標準パッケージと勘違いしてしまうことがあります。 当たり前のように設定ファイルでrequireされていて、いざOSの引っ越しをした際に未インストールでErrorとなる、というのは誰しも経験があるかと思います。

これの解決策をいくつかあげたいと思います。

1. ファイルの先頭付近で一括インストールする

よくある解決方法ですね。

(defvar favs '(autocomplete yasnippet ddskk))
(dolist (pkg favs)
  (unless (package-installed-p pkg)
    (package-install pkg)))

2. requireを置き換える

自分が使っている方法です。 嬉しいのは、いちいち先頭に戻ってインストールしたいパッケージを追記しなくてよいということです。

(defun use (pkg)
  (unless (pacakge-installed-p pkg)
    (package-install pkg)))

;;;使い方

(use 'yasnippet) ;; (require 'yasnippet)の代わり(※1)
(yas-global-mode t)

※1 package.el では自動でautoloadsファイルが生成されるので、本来requireすることはありません

3. el-getをつかう

el-getはpackage.elの登場で死んだ(?)と思われていたパッケージ管理システムです。 実はel-getはpackage.el登場以降も開発が活発で、package.elとの統合も行われたので、 package.elのスーパーセットといった感じになっています。

(el-get-bundle yasnippet
  (yas-global-mode t)) ;; yasnippetをインストールしたときの設定を書く

el-getは独自のパッケージシステム(レシピ)をもっているので、自分でレシピを書くことで 手軽に開発版などを導入することもできます。

(参考: Caskはもう古い、これからはEl-Get - いまどきのEmacsパッケージ管理 - 貳佰伍拾陸夜日記

4. Quelpaをつかう

紹介したものの中では最も新しいシステムで、内容は 2で紹介したuse関数のスゴい奴です。

(quelpa 'yasnippet)
(yas-global-mode t)

use関数との違いはパッケージの自動更新やgitリポジトリなどを指定できるということです。

(参考:emacs quelpa : 【本邦初公開】MELPAを改善した新しいパッケージ管理システム | Emacs Lisp Elisp パッケージ インストール 設定 使い方 | るびきち「日刊Emacs」

まとめ

これ以外にCaskもあるのですが、別ファイルに記述しなくてはいけない時点で、面倒だったのでやめました。 Quelpaやel-getは、最近まで使っていたのですが、DDSKK(日本語のインプットメソッド)がMELPAからインストール可能になった時点で、僕の利用目的としてはMELPAのリポジトリで十分になってしまったので自作のuse関数を利用するに至っています。

どれが一番良いかというとel-getが無難かなぁとおもいます。

Quelpaは使用感として極端に人を選ぶプロダクトでした。 というかパッケージを更新しろ!と勧めてくるのが五月蝿かった。(静かにすることもできます)

いろいろと言ってみましたが、全部試してみるのが手っ取り早い気がしますね。

それでは。

slimeのインストール

パソコンの移行が終了し、emacsの設定の手直しをしていたところ どうにもCommonLispの開発環境Slimeの調子良くない。 どうしたものかと思いgoogle先生にお尋ねしたところ、 随分前にもお世話になった「モダンCommonLisp」シリーズの記事が。 早速記事を参考に設定を見直してみたのですが、それでも良くならない。 記事の作成日時をみたらなんと!4年も前なのですね。 さすがに有名なSlimeとはいえ4年も過ぎていたら設定方法がかわってもおかしくないですよね。 そこで改めてSlimeのgithubアカウントを覗いたところ 「こんな設定で大抵良くなるぜ!」という記述が。

(setq inferior-lisp-program "sbcl")
(setq slime-contribs '(slime-fancy))

僕や「モダンCommonLisp」では

(setq inferior-lisp-program "sbcl")
(slime-setup '(slime-fancy slime-repl slime-banner))

となっていますが、今は上の設定で良いみたいですよ?

従ってlisp関係の設定は以下のようになりました。

(load (expand-file-name "~/quicklisp/slime-helper.el"))
(setq inferior-lisp-program "sbcl")
(add-hook 'lisp-mode-hook 'slime-mode)
(add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)
(setq slime-contribs '(slime-fancy))
(add-hook 'slime-mode-hook 'set-up-slime-ac)
(add-hook 'slime-repl-mode-hook 'set-up-slime-ac)
(eval-after-load "auto-complete"
  '(add-to-list 'ac-modes 'slime-repl-mode))

ac-slimerainbow-delimiters の設定を追加してあります。 快適なので是非参考にしていただけたら。

以上、つべこべ言わずに本家のREADMEを読んだほうが良いという教訓でした。