Dired でバイナリファイルを開くときに本当に開くか確認する何か
環境
動機
diredでバイナリとか開くときに本当に開いていいか確認してくれる何かが欲しい
— がんま (@ganmacs) 2015, 9月 24
Emacsでは写真やらPDFやらをEmacs内で見れるイッてる機能があります.
しかし,写真やらPDF開こうとすると数秒かかって非常に辛いです.
さらに,Diredを使っているとよく押し間違えてPDFを開いてしまい,数秒待ったあとkill-bufferするみたいなことによくなります.
これが非常に辛いのでなんとかしたいということで書きました.
実際
(defun util/same-ext? (file-path ext) "Check same exntion or not." (let ((file-ext (file-name-extension file-path))) (if file-ext (string= (downcase file-ext) ext)))) (defun util/chomp (str) (replace-regexp-in-string "[\n\r]" "" str)) (setq dired-open-whitelist '("c" "coffee" "clj" "el" "ex" "exs" "go" "h" "hs" "html" "js" "ml" "md" "rb" "yml" "scala" "slim" "scss")) (defun dired/binary? () (let ((cmd (format "nkf -g %s" (dired/filename-at-point)))) (string= "BINARY" (util/chomp (shell-command-to-string cmd))))) (defun dired/filename-at-point () (car (dired-get-marked-files 'no-dir))) (defun dired/directory? () (file-directory-p (car (dired-get-marked-files)))) (defun dired/include-whitelist? (filename whitelist) (if whitelist (or (util/same-ext? filename (car whitelist)) (dired/include-whitelist? filename (cdr whitelist))))) (defun dired-file-open-or-not () "File open if file type is directory or file exntion is in whitelist or file is not binary." (interactive) (let ((ext-lst dired-open-whitelist) (filename (dired/filename-at-point))) (if (or (dired/directory?) (dired/include-whitelist? filename ext-lst) (not (dired/binary?))) (dired-find-file) (if (yes-or-no-p (format "Do you really open? %s" filename)) (dired-find-file)))))
後は
(define-key dired-mode-map (kbd "C-f") 'dired-file-open-or-not)
何をしたか
開くのに時間がかかりそうなファイルを開いていいかどうかを聞くようにしました.
ファイルがBINARYかどうかをnkf
で確認してます.
しかし,毎回nkf
を叩くのは辛いので以下の条件の時はnkf
を叩かずそのままファイルを開いています.
- ディレクトリの時
- whitelistで定義された拡張子のファイルの時
感想
これを書いてたら何故か時間が消えていったが後悔はしていない
emacsからalcでの単語検索を楽にする
環境
コード
(defsubst marked-input () (when (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end)))) (defun search-word-in-alc () (interactive) (let* ((cmd "open \"%s\"") (url (format "http://eow.alc.co.jp/search?q=%s" (or (marked-input) (read-shell-command "word: "))))) (shell-command-to-string (format cmd url)))) (global-set-key (kbd "s-E") 'search-word-in-alc)
ちなみにzshバージョンもある
function search-word-in-alc() { url="http://eow.alc.co.jp/search?q=" open "${url}$1" } alias e='search-word-in-alc'
エスケープ処理とか全くしてないので動きが怪しいこともある気がするけどそこそこ便利!!!
RubyでDSLを書く
Rackのコードを読んでたらDSL使ってたのでその部分.
instance_eval
を使ってBuilder
クラス内でblock
を実行するようにしている.
つまり以下のプログラムは,Builderのインスタンス内で呼ばれたことになってる.
map '/' do { 'Content-Type' => 'text/plain', 'status' => 200, 'body' => 'this is root!' } end
class Builder def initialize(&block) instance_eval(&block) if block_given? end def map(path, &block) set(:get, path, block) end def get(path) key = [:get, path] route_table[key].call end private def set(name, path, block) key = [name, path] route_table[key] = block end def route_table @route_table ||= {} end end app = Builder.new do map '/' do { 'Content-Type' => 'text/plain', 'status' => 200, 'body' => 'this is root!' } end end p app.get('/') # => {"Content-Type"=>"text/plain", "status"=>200, "body"=>"this is root!"}
まとめ
最高の夏
参考
Rubyでプラグイン機構を作る
rack/rack · GitHub のコード読んでてプラグイン(Rackの場合はバックエンドにどのサーバを使うか)の処理があったので取り出して書いてみた.
Rubyではクラスは定数なのでHandler
っていう名前空間の中の定数を探すだけでいい.
# sample1.rb module Handler class Base def call run end def run raise NotImplementedError end end class PlugA < Base def run p "called in A" end end end # sample2.rb module Handler class PlugB < Base def run p "called in B" end end end # runner.rb require_relative './sample1.rb' require_relative './sample2.rb' def run(class_name) klass = Handler.const_get(class_name) klass.new.call end ['PlugA', 'PlugB'].each do |e| run e end # => "called in A" # => "called in B"
githubの分割バージョンがある
感想
研究室にyogiboがあってそれに乗っかりながらだらだら読んでて、夏休みの朝に再放送のアニメ見てる感じだった
RubyのStructの簡易版実装してみた
30分くらいでできる簡単な問題探しててmzpさんのやつを見つけてそれを解いてみてる.
これが動けばいい
Dog = MyStruct.new(:name, :age) fred = Dog.new('fred', 5) fred.age = 6 printf "name:%s age:%d\n", fred.name, fred.age
回答
class MyStruct def self.new(*names) Class.new do |_obj| def initialize(*values) @__values = values end names.each_with_index do |method, i| class_eval <<-EOS def #{method} @__values[#{i}] end def #{method}=(value) @__values[#{i}] = value end EOS end end end end
参考
モナディックなパーザーコンビネータ作ってみた
タイトル通りで作ってみたました. もともと研究で違うことやってたはずなのに目的を見失ってなんか面白そうだしこれならゼミで話しても怒られなさそうという考えからこの頃ずっと勉強してた.
OCamlで実装しようかHaskellで実装しようか迷っててどっちでも良かったんだけど最終的にはHaskellで書いた. 最初はOCamlの勉強も少ししてて、とにかく本を買いたくなかったので以下のページを読んでた.
けど素直にHaskellでやったほうが楽そうという気持ちになり途中からHaskellに切り替えた. Haskellの文法は雰囲気がわかる程度だったのでなんとかなるだろうと思い特に何もしなかった. モナドは「モナドは単なる自己関手の圏におけるモノイド対象だよ。何か問題でも?」という感じだったので以下のページを読んでだ.
パーザーコンビネータはググるといろんな人が実装しててるのでそれを参考にするといいかもしれない. こんなふうにParserの型が決まった時点で考えることはあんまりなくて型すごいって思いながら実装しいくとできたし型すごい.
type Result = Either String type Parser v = StateT String Result v
PEGパーザにした気でいるんですがもしかしたらこれではいけないかもしれないので間違っていたらスマンという感じです.
import Control.Monad.State import GHC.Base((<|>)) import Data.Char type Result = Either String type Parser v = StateT String Result v runParser = runStateT look :: Parser Char look = do x:_ <- get return x item :: Parser Char item = do x:xs <- get put xs return x satisfy :: (Char -> Bool) -> Parser Char satisfy f = do a <- item if f a then return a else mzero unsatisfy :: (Char -> Bool) -> Parser Char unsatisfy f = satisfy (not . f) cjoin :: Parser a -> Parser a -> Parser [a] cjoin p1 p2 = do a <- p1 b <- p2 return [a, b] select :: Parser a -> Parser a -> Parser a select = (<|>) many :: Parser a -> Parser [a] many f = many1 f <|> return [] many1 :: Parser a -> Parser [a] many1 f = do a <- f b <- many f return $ a:b
例えばExpr <- Number + Number
を受理するためのは以下のように書くとちゃんと計算結果が返ってくる.
number :: Parser Integer number = do n <- many1 digit return $ read n where digit = satisfy isDigit expr :: Parser Integer expr = do a <- number op <- token (=='+') >> return (+) b <- number return $ op a b main :: IO () main = print $ runStateT expr2 "1+2;" -- => Right (3,";")
4則演算バージョンがあるのでぜひ
参考
- http://d.hatena.ne.jp/kazu-yamamoto/20080920/1221881130
- http://www.geocities.jp/m_hiroi/func/haskell32.html
感想
ruby2.2.2で現在実行中の関数名を取得する
前提
ganmacs@ganmacs~% ruby -v ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
内容
現在実行中の関数名を取得したいとき、ruby 1.8までは以下のようにしてとれた。
しかし1.9からto_s(Array)
の挙動が変わったらしく2.2.2では動かなった。
class Object def current_method caller.first.scan(/`(.*)'/).to_s end end # when ruby version is 1.8 or earlier puts current_method #=> "<main>" # when ruby verison is 1.9 or later puts current_method #=> [["<main>"]]
なので今は以下のように書くと実行中の関数名を取得できる
class Object def current_method_name caller.first.match(/`(?<method_name>.*)'/)[:method_name] end end puts current_method_name #=> "<main>"