はてなキーワード: elispとは
ここ2,3年くらい、Vimが妙に流行っている。はてブやqiitaでもVim関連のページが出れば大量にブクマがつくし、「俺はVim派だから」みたいな発言を大学だったりtwitterだったりでもみる。
しかしその実、世間に出回る「vim tips」みたいなのをみると、cやr,はたまたw,$,0,..など超がつくほど基本的なものしか載っていない。
なんでこんな常識的なものにこんなにブクマつくの???っていっつも驚く。
昔はvimに憧れるワナビーがブクマをつけてるのではないかと思っていたが、どうやら今のネット界隈では「vim派」と言って通ぶることが一種のステータス?になっているのではないかと思うようになった。
ちょっと前に流行ったvim pluginブームにもびっくりした。vimはあくまでもIDEなんていらないスクリプトを書いたり、CUIでエディットしたい時に使うものだろう。
ものには使いみちというものがある。文章、少なくとも日本語はVimに向かないし、Javaの開発ならeclipseですらvimよりよっぽど生産性が高い。
vimにpluginなど入れて喜んでいる一部の人達をみると、やはりvimで通ぶっているだけではないかと思えてしまう。
.vimrcは長けりゃいいっていうものではない。それがemacsに対するvimの美徳のひとつではなかったのか。
そもそも、vim人口が見かけ上増えているにもかかわらずemacs人口が増えていないのがおかしい。どうも最近のvim派の人たちはemacsをあまりうまく使えていないようである。(俺のまわりだけかもしれないが)
昔のhackerはエディタ戦争なんて言いながらもお互い両方のエディタを使えたものだ。大体がshellでset -o viなんてしたら使いづらくて仕方がない。shellはctrl-aで先頭に戻るし、ctrl-rで履歴検索をするものである。
そもそもエディタ戦争なんて洒落にすぎないんじゃないかと個人的には思っている。viとEmacsは基本教養である。どちらかしかできないのは文盲のようなものである。
vimvim言ってブクマしてるみなさん、vimtutorは起動したことありますか?Vim関連の記事を100個ブクマするよりよっぽど有用です。
Do one thing and do it wellって知ってますか?一つのプログラムでなんでもしたいならwordかVSで十分です。無理してviを使う必要はないです。
俺はまだLinuxを使い始めて10年くらいだけれど、エディタはvi(m)一筋だった。
何がいけなかったのだろうか。
あとviとvimがうんぬんというブコメありましたが、逆に今日びviとvimを使い分けることがあるんでしょうか…?
(もちろんインストール直後のdebianとかだとvim.tinyしか入ってないけど)
普通/usr/bin/viってvim.basicを指してることが多いと思います。もしvim.tinyを指していたらごめんなさい。
てかaliasなりupdate-alternativesみたいなの使われたほうがいいのでは…?
id:akanehara (増田はじめてだからよくわかんないけどブコメに返すのこれでいいの?)
いやね、俺はNeoなんちゃらとかなんちゃら.vimとかのプラグインが流行りまくってるのどうかと思うんよ。
vi使いたくてあんなゴタゴタした画面分割するならtmuxかscreenで別タブにシェル開けばいいしそのほうが拡張性高いじゃん…っていう。
それかVSなりIntelliJで(ちなみに俺はeclipse使います。微妙にdisったけど)
あとはSIGSTOP(てかSIGTSTPか)で止めるのもよい使い方だと思う。
とにかくこれからviなりunixを使い始める人達がああいう害悪に影響されてほしくない。Neoほげほげよりtmuxとかctrl-zのほうがのちのちず~~~っと役に立つから。
viが流行ること自体はいいと重います。emacsももっとはやって欲しいです。nanoは即update-alternatives --config editorするんで知りません
と思ったらなんかみなさんいろいろ考察してくださっていますが、今やviクラスタ≠unixクラスタなのか…
なんてこったい
TeXは確実にGUIのほうが使いやすいよ。俺はTeXstudioだけど、シェアウェア買ってる人もいるね。特に仕事道具にしてる人は。
vimじゃあPDFからジャンプとかできないから校正の時とか使いづらいことこの上ない
一理ある
問題はvim scriptはelispに劣ってるところだと思う。
言語プラットフォームとしてみたときやっぱりemacsには一日の長があるよ
なのにpluginとか言って喜んでるのはなんか違うと思うなあ。
これでおしまいだよ
(require 'cl) ; for cl-seq (defvar sangels-movies-dir nil) (defvar sangels-player "c:/Program Files/GRETECH/GomPlayer/GOM.exe") (defvar sangels-sort-by 'sangels-sort-by-rate) (defvar sangels-rate-file "~/.emacs.d/.sangels/rate") (defvar sangels-buffer "*sangels*") (defvar sangels-thumbnail "00_thumbnail.jpg") (defvar sangels-m3u "00_movies.m3u") (defface sangels-name '((t (:family "fixed" :weight bold :height 3.0))) "") (defface sangels-rate '((t (:family "fixed" :weight bold :height 1.5))) "") (defvar sangels-mode-map (let ((map (make-sparse-keymap))) (define-key map "n" 'next-line) (define-key map "p" 'previous-line) (define-key map (kbd "RET") 'sangels-select) (define-key map (kbd "SPC") 'sangels-select) (define-key map "q" 'sangels-quit) (define-key map "+" 'sangels-rate-plus) (define-key map "-" 'sangels-rate-minus) map)) (defvar sangels-mode-hook nil) (defvar sangels-highlight-overlay nil) (defvar sangels-rate-alist nil) (defconst sangels-rate-max 6) (defun sangels-insert-movies () (save-excursion (let* ((inhibit-read-only t) (files (remove-if-not (lambda (x) (and (not (member (file-name-nondirectory x) '("." ".."))) (file-directory-p x) (member sangels-thumbnail (directory-files x)))) (directory-files sangels-movies-dir t))) (ids (mapcar 'file-name-nondirectory files))) (erase-buffer) (setq ids (sangels-sort-ids ids)) (dolist (id ids) (let ((file (expand-file-name id sangels-movies-dir)) (pos (point))) (insert-image-file (expand-file-name sangels-thumbnail file)) (end-of-line) (insert (propertize (format "%-15s " id) 'face 'sangels-name)) (sangels-insert-rate id) (insert "\n") (put-text-property pos (point) 'sangels-id id)))))) (defun sangels-sort-by-name (a b) (string< a b)) (defun sangels-sort-by-rate (a b) (or (> (sangels-rate a) (sangels-rate b)) (sangels-sort-by-name a b))) (defun sangels-sort-ids (ids) (sort ids (or sangels-sort-by 'sangels-sort-by-name))) (defun sangels-insert-rate (id) (let ((rate (sangels-rate id))) (insert (propertize (concat (make-string rate ?★) (make-string (- sangels-rate-max rate) ?☆)) 'sangels-rate t 'face 'sangels-rate)))) (defun sangels-current-id () (get-text-property (point) 'sangels-id)) (defun sangels-play-movie (movie) (let ((explicit-shell-file-name "cmdproxy") (shell-file-name "cmdproxy")) (apply 'call-process-shell-command "start" nil "*tmp*" nil (mapcar (lambda (x) (concat "\"" x "\"")) (list sangels-player (unix-to-dos-filename movie)))))) (defun sangels-select () (interactive) (let ((id (sangels-current-id))) (when id (sangels-play-movie (expand-file-name sangels-m3u (expand-file-name id sangels-movies-dir)))))) (defun sangels-quit () (interactive) (kill-buffer sangels-buffer)) (defun sangels-rate (id) (or (cdr (assoc id sangels-rate-alist)) (/ sangels-rate-max 2))) (defun sangels-rate-save () (interactive) (let ((dir (file-name-directory sangels-rate-file))) (unless (file-exists-p dir) (make-directory dir t))) (with-temp-file sangels-rate-file (insert (pp-to-string sangels-rate-alist)))) (defun sangels-rate-load () (interactive) (when (file-exists-p sangels-rate-file) (with-temp-buffer (insert-file-contents sangels-rate-file) (goto-char (point-min)) (setq sangels-rate-alist (read (current-buffer)))))) (defun sangels-rate-plus (&optional n) (interactive "p") (setq n (or n 1)) (let* ((id (sangels-current-id)) (cell (assoc id sangels-rate-alist))) (unless cell (setq cell (cons id (sangels-rate id))) (setq sangels-rate-alist (cons cell sangels-rate-alist))) (setcdr cell (+ (cdr cell) n)) (save-excursion (let ((inhibit-read-only t)) (beginning-of-line) (goto-char (next-single-property-change (point) 'sangels-rate)) (delete-region (point) (next-single-property-change (point) 'sangels-rate)) (sangels-insert-rate id))) (sangels-rate-save))) (defun sangels-rate-minus (&optional n) (interactive "p") (setq n (or n -1)) (sangels-rate-plus (- n))) (defun sangels-post-command-hook () (save-excursion (move-overlay sangels-highlight-overlay (progn (move-beginning-of-line 1) (point)) (progn (move-end-of-line 1) (forward-line) (point)) (current-buffer)))) (defun sangels-mode () (interactive) (kill-all-local-variables) (use-local-map sangels-mode-map) (setq sangels-highlight-overlay (make-overlay 0 0)) (overlay-put sangels-highlight-overlay 'face 'highlight) (overlay-put sangels-highlight-overlay 'evaporate t) (make-local-variable 'post-command-hook) (add-hook 'post-command-hook 'sangels-post-command-hook nil t) (setq major-mode 'sangels-mode) (setq mode-name "Sangels") (run-mode-hooks 'sangels-mode-hook) (set-buffer-modified-p nil) (setq buffer-read-only t)) (defun sangels (&optional arg) (interactive "P") (when (or arg (not sangels-movies-dir)) (setq sangels-movies-dir (read-directory-name "movies dir: "))) (sangels-rate-load) (switch-to-buffer (get-buffer-create sangels-buffer)) (sangels-insert-movies) (sangels-mode)) (provide 'sangels)
せっかく書いたから匿名でのせてみるよ
使い方は
必要なものを gem で取ってくるにはこうすればいいよ
長すぎてelispが消えたから続きがあるよ
@echo off setlocal set WD=%~dp0 cd /d %WD% ruby get_movies.rb ruby get_images.rb ruby create_m3u.rb
user: ユーザID password: パスワード ids_file: ids.txt done_file: ids_done.txt movies_dir: movies log4r_config: pre_config: global: INFO loggers: - name: app type: Log4r::Logger level: INFO outputters: - STDOUT - FILE outputters: - name: STDOUT type: Log4r::StdoutOutputter formatter: type: Log4r::PatternFormatter pattern: "%d [%l] %C - %M" date_pattern: "%H:%M:%S" - name: FILE type: Log4r::FileOutputter filename: "#{LOGDIR}/sangels.log" formatter: type: Log4r::PatternFormatter pattern: "%d [%l] %C - %M" date_pattern: "%Y-%m-%d %H:%M:%S"
require 'fileutils' require 'logger' require 'mechanize' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" require "#{BASEDIR}/sangels" $config = load_config(BASEDIR) prepare_logger(BASEDIR) $log = new_logger("get_movies") WWW::Mechanize.log = new_logger("mechanize") WGet.log = $log class IDFile def initialize(file) @file = file unless File.exist?(@file) Fileutils.touch(@file) end end def ids(contains_comment = nil) File.open(@file) {|io| io.to_a.map {|x| x.chomp }.select {|x| if x.empty? nil elsif contains_comment true else not /^\s*\#/ =~ x end } } end def add(id) ids = ids(true) unless ids.any? {|x| x == id} write(ids + [id]) end end def delete(id) ids = ids(true) if ids.any? {|x| x == id} write(ids - [id]) end end def write(ids) File.open(@file, "w") {|io| ids.each {|x| io.puts x} } end end $log.info("BEGIN #{$0} ================") exit_code = 0 begin ids_file = IDFile.new($config.ids_file) done_file = IDFile.new($config.done_file) movies_dir = $config.movies_dir wget = WGet.new sangels = SAngels.new sangels.login($config.user, $config.password) ids_file.ids.each {|id| begin movies = sangels.movies(id) rescue SAngels::Movies::InvalidMoviesError $log.warn("invalid movie id: #{id}") next end dir = File.expand_path(id, movies_dir) movies.each {|link| wget.retrieve(link.href, dir) } expected = movies.movie_links.map{|x| File.basename(x.href)} actual = Dir.glob("#{dir}/*").map {|x| File.basename(x)} if (expected - actual).empty? done_file.add(id) ids_file.delete(id) end } rescue => e $log.error(e) exit_code = 1 end $log.info("END #{$0} (#{exit_code}) ================") exit exit_code
require 'fileutils' require 'logger' require 'mechanize' require 'ostruct' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" require "#{BASEDIR}/sangels" $config = load_config(BASEDIR) prepare_logger(BASEDIR) $log = new_logger("get_images") WWW::Mechanize.log = new_logger("mechanize") WGet.log = $log $log.info("BEGIN #{$0} ================") exit_code = 0 begin movies_dir = $config.movies_dir sangels = SAngels.new sangels.login($config.user, $config.password) thumbnails = sangels.thumbnails Dir.glob("#{movies_dir}/*").each {|dir| next unless File.directory? dir id = File.basename(dir) url = thumbnails.url(id) unless url $log.warn("#{id} is not found") next end path = File.expand_path("00_thumbnail#{File.extname(url)}", dir) next if File.exist? path $log.info("retrieving #{url}") thumbnail = thumbnails.get_file(id) File.open(path, "wb") {|io| io.write(thumbnail)} } rescue => e $log.error(e) exit_code = 1 end $log.info("END #{$0} (#{exit_code}) ================") exit exit_code
BASEDIR = File.dirname($0) require "#{BASEDIR}/util" $config = load_config(BASEDIR) movies_dir = $config.movies_dir Dir.glob("#{movies_dir}/*") {|dir| next unless File.directory? dir name = File.basename(dir) files = Dir.glob("#{dir}/*.wmv").sort File.open("#{movies_dir}/#{name}.m3u", "w") {|io| files.each {|file| io.puts "#{name}/#{File.basename(file)}" } } File.open("#{dir}/00_movies.m3u", "w") {|io| files.each {|file| io.puts "#{File.basename(file)}" } } }
require 'mechanize' require 'hpricot' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" class SAngels HOST = "real2.s-angels.com" LOGIN_URL = "http://#{HOST}/member/" INFO_URL = "http://#{HOST}/teigaku/item.php" THUMBNAILS_URL = "http://#{HOST}/teigaku/" THUMBNAIL_URL = "http://#{HOST}/images/default/thumb/" def initialize() @agent = WWW::Mechanize.new end def login(user, password) login_form = @agent.get(LOGIN_URL).forms.find {|form| form.fields.any? {|field| field.name == "frmLoginid"} } login_form.frmLoginid = user login_form.frmPw = password @agent.submit(login_form) end def movies(id, no_validate = nil) Movies.new(@agent, id, !no_validate) end def thumbnails Thumbnails.new(@agent) end class Thumbnails def initialize(agent) @agent = agent doc = Hpricot(@agent.get_file(THUMBNAILS_URL)) elems = doc.search("div[@class=realthum]/a") @links = Hash( elems.map {|elem| href = elem["href"] id = $1 if /ID=(.+)/ =~ href url = elem.search("img")[0]["src"] [id, url] }) end def get_file(id) @agent.get_file(url(id)) end def url(id) @links[id] end def exist?(id) url(id) end end class Movies class InvalidMoviesError < StandardError end def initialize(agent, id, no_validate) @agent = agent @id = id if !no_validate && !valid? raise InvalidMoviesError end end def info_page_url "#{INFO_URL}?ID=#{@id}" end def info_page @agent.get(info_page_url) end def movies_page @agent.click(info_page.links.find {|link| /P=10/ =~ link.href}) end def movie_links movies_page.links.select {|link| /wmv$/ =~ link.href }.sort {|a, b| File.basename(a.href) <=> File.basename(b.href) } end def valid? info_page.uri.to_s == info_page_url end def each(&block) orig_links = movie_links orig_links.each {|orig_link| link = movie_links.find {|l| File.basename(l.href) == File.basename(orig_link.href)} block.call(link) } end end end
require 'log4r' require 'log4r/yamlconfigurator' require 'singleton' require 'fileutils' require 'ostruct' def Hash(a) Hash[*a.flatten] end def load_config(basedir) OpenStruct.new(File.open("#{basedir}/config.yaml") {|io| YAML.load(io)}) end def new_logger(name) Log4r::Logger.new("app::#{name}") end def prepare_logger(basedir, logdir = nil) logdir ||= basedir Log4r::YamlConfigurator["LOGDIR"] = logdir Log4r::YamlConfigurator.load_yaml_file("#{basedir}/config.yaml") end class NullObject include Singleton def method_missing(message, *arg) NullObject.singleton end end class WGet class << self attr_accessor :log def initialize super @log = NullObject.singleton end end def log self.class.log end def retrieve(url, dir) FileUtils.mkdir_p(dir) file = File.expand_path(File.basename(url), dir) if File.exist?(file) log.info("already retrieved #{url}") return true end tmp = "#{file}.part" log.info("retrieving #{url}") ret = system("wget", "-c", "-O", tmp, url) if ret log.info("retrieving succeeded #{url}") File.rename(tmp, file) else if $? == 0x020000 # Ctrl-C exit($?) else log.error("retrieving failure #{url} (#{$?})") end end return ret end end
LV0 UNIXエディタ?どうせ貧弱なCUIだろ?どうでもいいよ…
LV1 Win端末から使うとわりと便利だな。ってかUNIXは何でパスが/なの?
LV2 KDEは派手だな。Emacsってのはなんか機能豊富で結構いいかも。
LV3 Emacsって神じゃね?理想のエディタって感じ・・・
LV4 Elispパッケージもたくさんあって便利だな。MewとかGnusとかnavi2chとかいい・・・
LV5 Vimって別に便利じゃないのに使用者がカリスマ扱いされててうぜぇ。Vim死ね!
LV7 やべぇVim最高!VimとScreenさえあれば生きていける!
LV9 やっぱEmacsは最高だわ
先月、正式にリリースされたUbuntu Feistyなんですが、これが本当に使いやすい。自分は第一次Linuxブームの頃からずーっとLinuxを使ってきましたが、おそらく現在最高峰のディストリビューションじゃないかと思います。とはいえ、このことは知らない人には伝わらないと思うので、以下、個人的にスゴいと思うところを書き連ねていくことにします。
Ubuntuは、起動が速い・動作が速い・更新が速い、と三拍子揃っている。自動ログインに設定していると、本当にあっという間に立ち上がります。動作速度は、まあWindowsと比べるとまだまだなんですけど、過去に比べてべらぼうに速くなりましたよ。パッケージ管理も速い!一度aptを体験すると、もうyumには戻れません。
いや、OSXと比べるとまだまだなんですけどね。IPA系を入れて、Firefoxを明朝フォントで見ることにしたらびっくりするくらい読みやすい[1]。Windowsの場合、日本語で斜体のページなんてとても読めたものじゃないですからねえ。
みなさん100年のエディタ[2]使ってますか?実は、フリーなGnu EmacsはフリーなGUI環境であるX11上では、TrueTypeフォントの表示が出来ませんでした。WindowsとMac OS X上では余裕で出来るのに。これは最新版の開発ブランチで解決されてますが、まだ正式にはリリースされていません。
ところが、Ubuntuには最新版のバイナリパッケージ[3]があって簡単にインストールすることができます。自分でコンパイルしてもいいですが、パッケージで入れると他のElispパッケージ(Anthy.elとかphysical-line.elとか)が入れやすくていい。最新版なんで不具合が心配ですが、作業してて落ちたことはまだありません。ただし、M+1VM+IPAGフォントを指定すると何故か落ちます。
GNOMEは本当にどんどん便利になってきています。特に個人的に便利だと思うのは、Deskbar Applet[4]とNautilus g-script[5]の二つ。
前者はデスクトップ検索&ランチャ。デフォルトではタスクバーに表示されてないから自分で出す。Alt+F3でなんでも検索できるし、コマンドを打てば実行できる。ウィキペディア検索ができたり何かと便利。
後者はGUIシェルの拡張。Nautilus(Windowsでいうエクスプローラ)上でコンテキストメニューを好きなように設定できる。これがあれば「フォルダ上でマウスを使ってsvn up」なんて動作をあっというまに書けます。こんな風に。
# .gnome2/nautilus-scripts/SVN_Update* cd $NAUTILUS_SCRIPT_CURRENT_URI exec zenity --info --text="`svn up`"
レポジトリを有効にして、gstreamer系をインストールするだけ。Adobe Flashも(32bitCPUなら)Firefoxでyoutubeを見に行って、指示通りにインストールするだけ。いやあ、いい時代になったものですね。
Acrobat Reader, Google Earth, Picasa, Skype, Javaなんかが簡単にインストールできます。いやあ、いい時代になったものですね。個人的にはもっと、Linux上でも商用アプリが増えてもいいと思うけどなあ。
「他人と違う」ってのはそれだけで素晴らしい。違いすぎると苦痛ですけど、今のUbnutuレベルなら、やせ我慢してしのぐことができます。粋ですねえ。ファッションとしてのLinuxというのはいかがでしょうか。
大切な能力だ.
これがないと,いまの俺は生きてはいけない.ワイドショーにいちいち反応してしまう.
新聞の社説を信じてしまう.政府の嘘を見抜くことができない.まともに日常なんか送れねぇ.
そんなリテラシーについてよく考えてみた.正直いって,
今後生きていく上で,リテラシーはますます重要性を持ってくると思う.
だけど,そんな世界に俺は住みたくない.
選択の自由はどんどん増えてくると思う.でも,どんどんつらい世界になっていくような気もする.
もし,どんどん情報にたいする不信感が高まっていったらどうなるのだろうか?
大好きなナスが本物のナスなのか,農家にまで確認にいかなくてはならなくなったら?
今すんでいる家が鉄筋コンクリートでできているのか,一斗缶でできているのかわからなくなったら?
個人が一日に使える時間はかぎられている.あらゆることを疑問に思っても,そのすべてのことをチェックすることはできない.
どう考えても,人間には時間的な物理的なボトルネックが存在している.
俺は朝日新聞の世論調査がどのような確率モデルを採用しているのかまで,いちいち確認したくねー.
現状は不完全な社会システムが個人の犠牲のもとに成り立っているように思える.
社会が個人に責任をなすりつけている.いちいち俺等に,逐次的に情報を確認しろと言ってくる.自己責任のもとに.
「イスラエルでは,爆撃や銃撃戦が常態化しているそうだ.その結果,その恐怖に耐え兼ねて精神を侵される子供があとを立たないらしい.
この子供達を治療するために,戦争状態にある社会全体をどうにかしなけりゃ」って話だったと思う.
こんなもん,原因は個人にあるわけがねえ.戦争状態にある社会全体をどうにかしなけりゃ直るはずがねぇ.
俺が言いたいことはこういうことだ.
現状の原因が社会に100%ある.
なんてことじゃない.もちろん原因が自己責任のもとに個人にすべてある.でもねぇー.
俺が言いたいことは社会と個人どちらに原因があるのかその場その場の文脈で決めろってことだ.Closureってことが言いたいんだ.
決してelispじゃねぇ.
でも,この結論って情報量ゼロじゃん.結局何も分かってないってことじゃん.
いっつもこのくだらない折衷案でおわってしまって,その壁を乗り越えられない,それ以上深くものを考えられない.
この先を考えてぇ.