カスタムメニューの内容をpecoで選択するためのスクリプトを作成

経緯

以前はfluxboxを使用しており、右クリックでメニューが出てきました。そのメニューはファイルを書き換えることでカスタマイズできました。

現在xmonadに移行しており、いくつかのキーにアプリケーションを割り当てています。

割り当てるアプリケーションが多くなると覚えるのが大変なので、カスタマイズできるメニューがないかと探していたのですが見つかりませんでした(探し方が悪いため?)。

そこで自分でスクリプトを書きました。慣れていないので多少時間はかかりました。

内容

Rubyスクリプト

GitHub で公開しています。

#!/usr/bin/env ruby
# coding: utf-8

# peco binary
PECO = File.expand_path "/usr/bin/peco"

# terminal emulator (xterm/urxvt/mlterm)
XTERM = "mlterm"

# menu list
menufile = File.expand_path "~/.mymenu"


require 'tempfile'

class MyMenu
  def initialize(menufile)
    @menufile = menufile
    @appfilepath = Tempfile.new("tmpnew").path
    @hash = Hash.new
  end

  protected

  def set_hash_and_list
    io1 = File.open(@menufile, "r")     # filelist
    io2 = File.open(@appfilepath, "w")  # list of application name

    io1.each {|line|
      line.strip!
      line.chomp!
      next if line == "" || (/^#/ =~ line)

      rows = line.split(/,/)
      rows[1] = rows[0] if rows[1].nil?
      @hash.store(rows[0], rows[1])
      io2.puts rows[0]
    }
    io1.close
    io2.close
  end

  def exec_peco
    out = Tempfile.new("peco-out")
    err = Tempfile.new("peco-err")
    system "#{XTERM} -e sh -c '#{PECO} #{@appfilepath} > #{out.path} 2> #{err.path}'"

    res = `cat #{out.path}`
    if res != ""
      app = @hash[res.chomp!]
      system("#{app} &")
    end
  end

  public

  def exec_MyMenu
    self.set_hash_and_list
    self.exec_peco
  end
end


mymenu = MyMenu.new(menufile)
mymenu.exec_MyMenu

このスクリプトの後半はるびきち様が公開している peco を参考にさせて頂きました。というよりもそのまま使用させて頂きました。

設定

mymenu.rb

XTERM に使用したいターミナルエミュレーターを指定します。

  • xterm/urxvt/mlterm であれば大丈夫でした。
  • gnome-terminal/lxterminal は失敗しました。

~/.mymenu

~/.mymenu を作成し、以下のように記載します。 このファイルが存在しないとエラーが出ます。

FD, gnome-terminal -e fd
R, lxterminal -e R
leafpad

メニューに表示したい内容と実行するコマンドをカンマで区切って記載するだけです。

  • カンマの左側に記載した内容がメニューに表示されます。
  • カンマの右側に記載した内容が実行されます。
    • 省略した場合には左側の内容がそのままコマンドとして実行されます。
    • ターミナルで実行したい場合には “(使用したいターミナル) -e (実行したいコマンド)” のように記載します。

使用法

mymenu.rbを好きなキーに割り当てます。

あとは好きなように絞り込みをするだけです。

Hit-a-Hint の設定をしておけば、「@」を押した後に候補の左端に表示されている文字を打ち込むことで即座に選択できるようになります。

xmobarのステータスバー上に新着メール数を表示する

経緯

これまではconkyで、自宅、職場、Gmailの新着メール数を表示させていました。

タイル型ウィンドウマネージャであるxmonadに移行する場合、 conkyの表示か隠されてしまうため使いにくいです。そこでステータスバーであるxmobar上に新着メール数を表示することができるようになったため、その方法をメモしておきます。

方法

xmobarにテキストを渡せばその通りに表示してくれるため、「新着メール数を含む文字列」を表示するスクリプトを作成しました。

checkmail.rbスクリプト

GitHub にスクリプトを置いています。

サーバ名、ユーザ名、パスワードを各個人の設定に合わせて変更します。この時、” “ではなく’ ‘で囲んだ方がいいです ” “で囲んだ場合、@があるとうまくいかないためです(\@とすればOK)。

使用方法は説明がなくても分かると思います。第4引数は、POP3であれば”pop3″、GmailなどのIMAPであれば”imap”を指定します。

最終行で文字列を表示させるので自由に変更します。

#!/usr/bin/env ruby
# coding: utf-8

require 'net/pop'
require 'net/imap'

$server1 = '******'
$name1 = '******'
$pass1 = '******'

$server2 = 'imap.gmail.com'
$name2 = '******@gmail.com'
$pass2 = '******'

########################################
# function
########################################

def get_n_mail (server, name, pass, connect)
  case connect
  when "pop3"
    pop = Net::POP3.new(server, 110)
    pop.start(name, pass)
    n = pop.n_mails
    pop.finish
    return n
  when "imap"
    imap = Net::IMAP.new(server, 993, true)
    imap.login(name, pass)
    imap.select('INBOX')
    search_criterias = ['UNSEEN']
    n = imap.search(search_criterias).length
    imap.logout
    imap.disconnect
    return n
  else
    # do nothing
  end
end


########################################
# get numbers of mail
########################################

n1 = get_n_mail($server1, $name1, $pass1, "pop3")
n2 = get_n_mail($server2, $name2, $pass2, "imap")


########################################
# Result
########################################

printf "mail1:%d/mail2:%d", n1, n2

なぜRubyでスクリプトを作成したのかというと、

require 'net/pop'
require 'net/imap'

でPOP3とIMAPの両方を扱えることが分かったからです。

※ただしVine Linux 6のRubyのバージョンが古く(1.8.7)このままではエラーが出るため、 ruby-opensshパッケージをインストールする必要がありました。

sudo apt-get install ruby-openssh

ただし、これとは別にRuby-2.2.0をインストールしているのですが、この場合は新たにパッケージをインストールしなくても動作しました。

.xmobarrcの設定

先程のcheckmail.rbを ~/.xmonad/ に置きます(場所は任意)。

commandsの所に

,Run Com ".xmonad/checkmail.rb" ["&"] "mail" 3000

を追加し、

template = " %StdinReader% }{ [<fc=#ff00ff>%mail%</fc>]",

などのように設定すれば完了です。

この場合は300秒(5分)ごとにサーバに確認し、新着メール数を返します。

感想

これでxmonadに移行することができそうです。

あとはステータスバーにアイコンを表示させることができればOKです。