カテゴリー別アーカイブ: Emacs

Emacsで読み取り専用で開いてしまったファイルを無理矢理書き込む方法

Emacsで読み取り専用で開いてしまったファイルを無理矢理書き込む方法。

こんにちは。岡田洋一です。春分の日も過ぎだんだんと春の訪れを感じるようになりました。皆さんはいかがお過ごしでしょうか。

さて私岡田洋一は、高城梢さんと拙いながらサーバ勉強会なるものを開催しております。最近はその中でEmacsについて取り扱いました。エディタは様々なものがありますが、サーバ管理者にとってのエディタはプログラマのそれと様相が違います。その違いとは何よりCUIで動くこと、ですね。ですのでvi系やemacs、BSD系での伝統的な(?)eeや最近ではnanoが用いられますね。

そんなemacsですがサーバ勉強会で偉そうにも教える側として、実はこっそりEmacsについて勉強してみました。
今回はその中で知った事についてメモしたいと思います。

Emacsでは読み込み専用ファイルを開くと、ミニバッファ上部のステータス表示部分が変化します。Screen Shot 2013-03-22 at 20.03.44

ファイルの変更を表す部分、通常は—と表されておりファイルの内容に変更があると**-となる部分ですね、ここが%%-となります。これは読み込み専用モードでファイルを開いている事を意味します。

Emacsで現在開いているバッファの読み込み専用モードか、書き込み可能なモードかを切り替えるには “C-w C-q” を使います。既に書き込みモードで開いている場合には読み込み専用モードに切り替えます。また読み込み専用モードであれば書き込み可能モードになります。

さて、通常Emacsでファイルを開いたときには書き込み可能モードで開きます。でも読み込み専用モードで開いてしまうことがあるるんですね。それはパーミッションが無い場合です。

  1. 対象のファイルを所有しているけれどuserのwが無い場合 ( 400 r–r–r– など)
  2. 対象のファイルのグループに属しているけれどwが無い ( 644 rw-r–r– など)
  3. 人のファイル全般 ( 600 rw—– など)

こういった場合にはEmacsは読み込み専用モードで開いてしまいます。
こういった場合、今まで自分が取ってきた手段というのは

shell> chmod u+w hoge; emacs hoge; chmod u-w;

というワンライナーでファイルを編集することでした。最後に再度パーミッションを落としているのは、そういうことが要求されるファイルがある、ということです。例えばsudoersファイルは440でなければならない、といった具合です。(とはいえsudoersであれば環境変数のEDITORをemacsにしてvisudoを用いる、というのが正攻法だったりします)
これは結構面倒だったので、今後は C-x C-q をする事で書き込み可能にすることができます。とても便利ですね。

ちなみにrootのファイルを一般ユーザで開いてしまった場合にはどうにもできません。こちらはこちらでプロセスの所有者を変える、ということができれば対処できそうですね。それについても分かる日が来れば良いですね。

emacsのphp-modeでarrayのインデントを改善した

1. はじめに

emacsでphp-modeを利用している。とても便利なelispなんだけどデフォルトだといくつか不便な点がある。

基本的にはPEARに準拠したコーディング規約にしたかったので下記のブログ記事を参考にしてinit.elの設定を行った。

(setq php-mode-force-pear t)

PHP開発で追加しておきたいEmacs Lisp 8選 : アシアルブログ

だけれどもこれだけだとarrayのインデントがおかしい。

2. おかしいインデント

<?php
function hoge(){
    $hoge = array(
                 'hoge' => 1,
    );
}

このように連想配列の添え字(キー名)のインデント位置が前述の括弧の位置まで下がってしまうのだ。 コレは見づらい。できれば $hoge の開始位置から規定のタブ幅(4とか)で字下げして欲しい。

2. 解決方法は見かけるのだけれど

この問題でググってみるといくつか解決方法が出てきた。だけれどもその辺のelispを適用してみてもうまくいかない。バージョンがダメなのか他のelispと競合しているのか、とにかく動かなかった。というかelispに対する理解が少ないというのが一番の根本的な問題かな。

で、しばらくこの問題は放置していたのだけれど、あまりにも気になると言うことで気合いを入れて調べてみた。すると意外にも(?)公式的なみんな大好き emacswiki が出てきた。

3. 解決

Indentation of arrays
The php-mode indentation for array is not good, It will indent like this:

$post=Post::model()->find(array(
                              'select'=>'title',
                              'condition'=>'postID=:postID',
                              'params'=>array(':postID'=>10),
                              ));

The better indentation is like:

$post=Post::model()->find(array(
    'select'=>'title',
    'condition'=>'postID=:postID',
    'params'=>array(':postID'=>10),
));

Add this to php-mode-hook:

(add-hook 'php-mode-hook (lambda ()
    (defun ywb-php-lineup-arglist-intro (langelem)
      (save-excursion
        (goto-char (cdr langelem))
        (vector (+ (current-column) c-basic-offset))))
    (defun ywb-php-lineup-arglist-close (langelem)
      (save-excursion
        (goto-char (cdr langelem))
        (vector (current-column))))
    (c-set-offset 'arglist-intro 'ywb-php-lineup-arglist-intro)
    (c-set-offset 'arglist-close 'ywb-php-lineup-arglist-close)))

EmacsWiki: Php Mode Indentation of arrays

さて早速コレを適用。init.elを開いて、php-completionですでにphp-mode-hookがあったのでそこに追記して再起動。

うまくいきました。

<?php
function hoge(){
    $hoge = array(
        'hoge' => 1,
    );
}

めでたしめでたし。

emacsでbackspaceキーを押したらデリートの動作になる。

最近emacsのバージョンを22から23にアップした。その中で変わってた動作の一つとして、BSキーがデリートキーの動作になってしまうことがあった。

M-x describe-keyしてみると以下のように。

C-d runs the command delete-char, which is an interactive built-in
function in `C source code'.

It is bound to <deletechar>, C-d.

(delete-char N &optional KILLFLAG)

Delete the following N characters (previous if N is negative).
Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
Interactively, N is the prefix arg, and KILLFLAG is set if
N was explicitly specified.

あーなんか面倒だけどC-dとC-hでとういつしよかな。でもrootとかでやるとC-hきかんしな・・・。