はてなキーワード: .emacsとは
俺のEmacsライフは、もはやただのエディタを超えて、完全に生活そのものだ。
日常のあらゆる側面がEmacsに支配されていて、他のソフトウェアなんて目にも入らねぇ。
今日は、どれだけ俺がこの深淵な世界に没頭しているか、そのレベルを見せてやるぜ。
俺の.emacs.dには、数十種類どころか、もう百を超える自作パッケージが眠ってる。
特に、自分で書いたLisp関数は、日々のタスクを自動化するために欠かせねぇ。
例えば、特定のフォルダ内のMarkdownファイルを自動でHTMLに変換してブラウザで表示するスクリプトを組んじまった。
これでブログを書くたびに手間いらずで、「C-c C-v」でプレビューできる快感は、もう中毒だぜ。
(defun my-markdown-to-html () "MarkdownファイルをHTMLに変換してブラウザで表示する関数" (interactive) (let ((markdown-file (read-file-name "Markdownファイルを選択: "))) (shell-command (format "pandoc %s -o %s.html" markdown-file (file-name-sans-extension markdown-file))) (browse-url (concat (file-name-sans-extension markdown-file) ".html"))))
この関数を使えば、Markdownファイルを選んで一発でHTMLに変換し、そのままブラウザで表示できる。これがなきゃブログなんて書けないぜ。
Org-modeは俺の人生そのものだ。TODOリストやスケジュール管理だけじゃなくて、プロジェクト管理や文書作成まで全てを一元化してる。
特に、カスタムキャプションやプロパティドロップダウンメニューを駆使して情報整理に命懸けてるんだ。
さらに、Org Babel使ってRやPythonのコードを直接実行しながらデータ分析なんて日常茶飯事だ。この機能のおかげで、データサイエンスもEmacs内で完結しちまうからたまんねぇよ。
自分専用にカスタマイズしたショートカットが数百種類もあるんだぜ。
「M-p」で過去のコミットメッセージを呼び出す機能なんか、Gitとの連携が一瞬でできるから開発効率が飛躍的に向上する。
さらに、Emacsにはマクロ機能があるから、自分の操作を記録して再生することもできる。
この前、自分専用のマクロを作って、特定のフォーマットでドキュメントを一瞬で整形することができた。
これで「お前は本当に人間なのか?」って言われてもおかしくないレベルだ。
Emacs Lispを書くことが俺の日常になってる。この前、自分だけのコード補完システムを構築したばかりだ。
この機能のおかげで、特定のキーワードを入力すると関連するコードスニペットが自動的に提案される仕組みになってるから、コーディング中に思考が途切れることなくスムーズに進行するぜ。
(defun my-auto-complete () "カーソル位置に基づいてコードスニペットを提案する" (interactive) (let ((input (thing-at-point 'symbol))) (if input (let ((completion-list '("myFunction" "myVariable" "myClass"))) (setq completion-list (cl-remove-if-not (lambda (item) (string-prefix-p input item)) completion-list)) (if completion-list (message "候補: %s" (string-join completion-list ", ")) (message "候補なし"))) (message "シンボルが見つかりません"))))
この関数ではカーソル位置からシンボルを取得し、それに基づいて候補を表示する。これがあればコーディング中も迷わず進められるぜ。
Emacsユーザーとして活動している中で、多くの仲間と出会った。
彼らとの情報交換や共同開発は刺激的で、新しいアイデアが次々と生まれてくる。この循環こそが俺の成長につながっていると実感しているんだ。
最近では、自分が開発したパッケージをGitHubで公開し、フィードバックを受け取ってさらなる改善点を見つけたりもしている。
このフィードバックループがあるからこそ、自分自身も進化し続けられるんだ。
今やEmacsは単なるツールじゃなくて、俺自身の一部になってる。
今日は入院している祖母に会いに行く日だ。入院前はもう呆けて風呂も入らないぐらいひどい状態だったが、入院してからはちゃんとしているらしい。
それはそうと、lispでpython環境を構築する話だが、結局オートコンプリートはうざいし、使う機能といったらautopep8とisortぐらいなので、以下を.emacsに組み込んだ。
(defun python-autopep8-and-isort () "Run autopep8 and isort on current Python buffer." (interactive) (when (eq major-mode 'python-mode) (shell-command-on-region (point-min) (point-max) "autopep8 - | isort -" nil t))) (with-eval-after-load 'python (define-key python-mode-map (kbd "C-c C-r") 'python-autopep8-and-isort))
.emacsファイルには他にも様々な設定を付与したが、ここではコードを書ききれない。
さてそういうわけで週末コーディングが趣味としてちゃんと機能することはわかったが、毎週作るとなると、いくつも何かを作るよりは一つのタフなものを作りたいと思うわけである。
それで、最有力候補は「Elasticsearchのようなものをpythonで実装する」という話がある。
Elasticsearchが徹底された設定外部化によってjsonを多用するのだが、これがあまり柔軟性がないので、コードを直にいじれるようにしたいと思ったためである。
例えば自作の日本語トーカナイザを組み込みたいときElasticsearchプラグインをJavaで書かなければならない。私はJavaが嫌いであり、プラグインを「インストールする」という手順も冗長に感じる。
それよりはpythonで作られた検索システムに、適当なトーカナイズ関数を実装して呼び出すことができればかなり柔軟であるように思うわけである。
難しい点があるとすれば、大規模分散システムへの対応で、金をかけなければそういうシステムをテストすることができない。
できるだけ金をかけずに趣味をやるというのがモットーなので、これではまずいわけである。
まあ何事も困難というものはある。まずは手を動かすことが重要だ。Linus Torvaldsも"Talk is cheap, show me the code"と言っているではないか。
今さらここで何かを書いても,あまり助けにならないかもしれないけれど,もしまだ入門する気があったら気に留めておいてほしい.
package, use-package, leafどれでも構わない.ただ混在させるとエラーやwarningを出したりするので,統一をしたほうがいいとは思う.新しいとか古いとかはこの際気にしなくていい.最近はEmacs標準でpackage.elがついているので,めんどくさければ全部packageを使えば問題ない.
こういうのは,Emacsを使っているうちに「自分は.emacsをいじるのを結構楽しんでいるな」と思ったときに,新しいのやスマートな方法を調べれば十分だ.
これは入門時は仕方ない.ただ後述するhydraを使ってくれ.そうすれば一度調べたものをもう一度調べることがなくなると思う.
hydraを使おう.
https://github.com/abo-abo/hydra
hydraってのは,複雑なキーバインドを覚えられない,覚えたくない場合に入れるパッケージだ.Emacsだと,導入したパッケージにデフォルトで設定されているキーバインドと,自分でカスタマイズしたキーバインド,両方を覚えておく必要がある.けど,そんなの覚えてられるのは一部だけなので,よく使うコマンド一覧を自分で設定できて,それを表示してくれるのがhydraだ.
表示するコマンド一覧を自分で設定するので,↑で調べたときに調べたコマンドを全部hydraの設定に書いておくといい.また,そのときにキーバインドも判明したのであれば,hydraのコマンド説明部分にキーバインドも書いておくといい.
これはすまん.使ってる人は実はそこまで少数ではないんじゃないかなと思っているけど,確かに日本語発信している情報は少ない.あと,たいていのパッケージがgithub等に公開されていて,玄人達は,英語が読める or そもそもソースがlispで書いてあるんだから読めばいいじゃん,という人たちが多い気はする.確かに私も日本語の情報は特に少ないと感じている.
Emacs-jpのbeginners-helpはあんまりbeginnerじゃない質問がされているけれど,気にせず初心者質問をしても大丈夫な場所なので,遠慮なく聞いてくれ.回答がわからなければ,「何言ってるのか全然わからん」と言ってくれ.
そういえば私もWindowsでEmacsを使ったことがないので何もわからない…….でも,そこまで困っているならきっとWindows Emacsユーザ全員が困っているはずなので,Emacs-jpで聞いてみたらいいかもしれない.もしくはWindowsユーザチャンネルを作ってみたらいいかもしれない.すまん,これについては助けになれない.
キーバインドが覚えられないのは,実はあなただけじゃなくてみんな同じだったからhydraなんてものが出てきたし,日本語情報が少ないのは事実だ.だからあまり卑下しないでくれ.偉そうに書いたけど,私も日本語情報が少なくて結構わからないことは多かったりする.READMEに書いてあるとおりにセットアップしてもエラーが出たりすることは結構多い.だから,こういう意見に耳を傾けて,Emacsコミュニティが人類に優しくなってほしいと願っている.
元ネタ http://anond.hatelabo.jp/20120321162723
( http://anond.pha11.info/archives/9491 )
http://anond.hatelabo.jp/20081105135432
彼女ができた。なんとHaskellerだ。
8月に参加したLLイベントで知り合い、10月から付き合い始めた。なんでLLイベントにHaskellerが…
これまで5人くらいのプログラマと付き合ったことがあるけれど、一般的なプログラマと比較して
といった点が目立つ。
見た目はLisperを少し丸くしたようなかわいらしさがあるのだけれど、要するに中身はPrologだ。
初めは戸惑いもあったが、案外こういうプログラマとつきあうのは楽で楽しいと分かってきた。
コードは深い問題もFizzBuzzのような軽い問題も内容を伴って書ける。
いろいろメタプログラミング・アロー記法・ユニコード演算子などを試そうとするなど好奇心が強い。
純粋関数型言語も習得しているというのに論理系の言語も習得しようと勉強していて向上心の強さがある。
IOモナドをコントロールできない自分に「おかしいな、普段はこんなはずじゃないのに///」と恥ずかしがる。
Haskeller、はっきり言ってオススメです。
問題はどうやって知り合うかだけれど、職場(あるのか?)という戦闘モードの時に誘うのではなく、.emacsなどを書いているオフタイムが狙い目としか。
初めの一歩が難しいだけで、後は一般的な女の子よりも付き合いは簡単かも。
これでおしまいだよ
(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)
あるある。プラットフォーム非依存な開発をやってて、普通に秀丸とか Vim とか Emacs とか WzEditor とか Eclipse とかが混在した状態で開発してる時に、Emacs ユーザーがスペースとタブの混在インデントをやってたのを見た時、もう、ぼろくそにおきおろしたくなるのを我慢して「他の人が困るから .emacs とかにこれこれこうこう書くとかしてプロジェクトのファイルを置いてるディレクトリ配下のファイルを編集する場合だけでいいから周囲に合わせられるように設定してね」って教えてあげたことがある。かなしかったよ。