Emacs-Lispインストーラ

30分(?)プログラム、その86。いや、1時間かかってるし、まだ完成してませんけどね。
家のPCと大学のPCとノートPCにEmacsLispをインストールするのが面倒になったので、自動インストーラを作ろう。たぶん、誰かやってるけどな。
るびマに載っていたDSLも使いたいし。

#!/opt/local/bin/ruby -w
require 'fileutils'
module EmacsLisp
  class Manager
    def initialize(dest)
      @dest = dest
      @sites = []
    end

    def search(regexp)
      @sites.select{|site|
        site.get_name =~ regexp
      }
    end

    def find(name)
      @sites.find{|site| site.get_name == name}
    end

    def download(site)
      raise StandardError,'no site' unless site
      system "wget #{site.get_url}"
    end

    def install(site)
      raise StandardError,'no site' unless site
      self.download site

      # pre-insall
      src = action site

      # install
      dest = dest_dir(site)
      FileUtils.mkdir_p dest

      puts "#{src} -> #{dest}"
      FileUtils.mv src,dest

      lisp = "#{dest}/emacs-install-init.el"
      puts "write #{lisp}"
      File.open(lisp,'w'){|io|
        io.puts <<-INSTALL
        (setq load-path (cons "#{dest}" load-path))
        #{site.get_install}
        INSTALL
      }
      :ok
    end

    def install_all
      # あとで書く
    end

    def add(site)
      @sites << site
    end

    private
    def dest_dir(site)
      File.expand_path site.get_name,@dest
    end

    def action(site)
      # ここでファイルを解凍したりする
      ext = File.extname(site.get_url)
      case ext
      when '.el'
        File.basename site.get_url
      else
        raise StandardError,'unknown type' unless site
      end
    end
  end

  class Site
    def self.define(&block)
      obj = self.new
      obj.instance_eval(&block)
      obj
    end

    def self.attr_field(*names)
      names.each{|name|
        module_eval <<-END
        def #{name}(#{name}) 
          @#{name} = #{name}
        end

        def get_#{name}; @#{name} end

        END
      }
    end
    attr_field :name,:url,:command,:install
  end
end

manager = EmacsLisp::Manager.new '~/site-lisp'

# 各Emacs lispの定義
manager.add EmacsLisp::Site.define{
    name 'auto-save-buffers'
    url 'http://0xcc.net/misc/auto-save/auto-save-buffers.el'
    install <<-LISP
(require 'auto-save-buffers)
(run-with-idle-timer 0.5 t 'auto-save-buffers)
            LISP
  }


case ARGV[0]
when 'search'
  puts manager.search(Regexp.new(ARGV[1])).map{|site| 
    site.get_name
  }.join("\n")
when 'download'
  puts manager.download(manager.find(ARGV[1]))
when 'install'
  puts manager.install(manager.find(ARGV[1]))
else
  puts 'no commands'
end

あと、.emacs

(mapcar
 (lambda (dir)
   (let ((filename (concat dir "/emacs-install-init.el")))
     (when (file-exists-p filename)
       (load-file filename))))
 (directory-files "~/site-lisp" t))

と書いておくと、自動でロードできるようになる。

うん、まだ実用に耐える段階じゃないな。せめて、tar.gzの自動解凍は欲しいな。