emacs-lisp のリスト操作

概要

List Modification にある知らなかった関数。

delete 関数

指定した値をリストから削除した新しいリストを返す。元になったリストは 破壊される。

(setq l01 '(1 2 3))
(delete 1 l01)

重複も削除する。

(setq l01 '(1 1 2 3 1 1))
(delete 1 l01)

元のリストは破壊される。

(setq l01 '(1 1 2 3 1 1))
(delete 1 l01)
l01

remove 関数

元のリストから指定した値を削除する。元になったリストは無事。

(setq l01 '(1 2 3))
(remove 1 l01)

元のリストは無事。

(setq l01 '(1 1 2 3 1 1))
(remove 1 l01)
l01

append 関数

2つのリストを連結したリストを返す。

(setq l01 '(1 2 3))
(setq l02 '(4 5 6))

(append l01 l02)

butlast 関数

指定した個数の要素をリストから除外したリストを返却する。

(setq l01 '(1 2 3 4 5))
(butlast l01 3)

emacs で音楽を聞く

概要

musicForProgramming のmp3ファイルをemacsで再生できないかをあれこれと 試行錯誤したのでその備忘録として。

パッケージ

Music Players にあるようにいくつかのパッケージがあるが emms を選択。

カスタム

customize-group コマンドで emms-volumeemms-volume-change-functionemms-volume-pulse-change を設定。

エラー

mp3 を追加してボリュームを上げようとすると以下のメッセージがミニバッ ファーに表示される。

Wrong type argument: stringp, nil

原因

emms-volume-pulse.elpactl の出力をパースするところが問題。コー ドではSink, Name, Volume を目印として情報を取得しているようで、コマ ンド出力が英語以外だと問題となる。

(string-match
 (mapconcat 'identity
        '(".*Sink[ \t]+\\#\\([0-9]+\\)"
          ".*Name:[ \t]\\([^\n]+\\)"
          ".*Volume:.*?\\([0-9]+\\)%.*\n?")
        "\n")
 output)

コード内の pactl コマンドを再現すると日本語表示になっている。

pactl list sinks 

シンク #0
    状態: RUNNING
    名前: alsa_output.pci-0000_00_01.1.hdmi-stereo-extra1
    説明: 内部オーディオ Digital Stereo (HDMI 2)
    ドライバー: module-alsa-card.c
    サンプル仕様: s16le 2ch 44100Hz
    チャンネルマップ: front-left,front-right
    所有者モジュール: 6
    ミュート: いいえ
    ボリューム: front-left: 39321 /  60% / -13.31 dB,   front-right: 39321 /  60% / -13.31 dB

ロケールを設定すると英語で表示される。

LC_ALL=C pactl list sinks 

Sink #0
    State: RUNNING
    Name: alsa_output.pci-0000_00_01.1.hdmi-stereo-extra1
    Description: 内部オーディオ Digital Stereo (HDMI 2)
    Driver: module-alsa-card.c
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Owner Module: 6
    Mute: no
    Volume: front-left: 39321 /  60% / -13.31 dB,   front-right: 39321 /  60% / -13.31 dB

対策

defadvice を使用して問題の関数の環境変数を一時的に置換して問題を回 避。

(defadvice emms-volume--pulse-get-volume
    (around emms-volume--pulse-get-volume-around activate)
  (let ((process-environment (append process-environment '("LC_ALL=C"))))
    ad-do-it))