LoginSignup
13
13

More than 5 years have passed since last update.

Emacs で行番号を指定してファイルを開く

Last updated at Posted at 2015-12-26

:bulb: 以下、emacs の部分は、あなたの Emacs 利用形態(新しい Emacs ではなくすでに起動している Emacs 上で開くとか)に合わせて emacsclient -n とかにしてください。

ターミナルから行番号を指定して開く

Emacs のコマンドラインヘルプを見ると…

$ emacs --help
Usage: /usr/local/opt/emacs-mac/bin/emacs [OPTION-OR-FILENAME]...

Run Emacs, the extensible, customizable, self-documenting real-time
display editor.  The recommended way to start Emacs for normal editing
is with no options at all.

(snip)

Action options:

FILE                    visit FILE using find-file
+LINE                   go to line LINE in next FILE
+LINE:COLUMN            go to line LINE, column COLUMN, in next FILE

(snip)

ということで、/path/to/hoge ファイルの20行目を開くときは

$ emacs +20 /path/to/file

20行目の40文字目を開くときは

$ emacs +20:40 /path/to/file

です :exclamation:

/path/to/file:20 で開きたい

  • RSpec の行指定
  • grep -n の出力
  • ag の出力

と同じスタイルで開きたい場合、同じようにシェル関数を用意しておいて、

function e {
    local args
    args=`echo $1 | sed -E "s/([^:]+):([0-9:]+)/+\2 \1/g"`
    eval "emacs $args"
}
$ e /path/to/file:20

書いてて思ったんですけど、これ ag + peco と組み合わせると超便利コマンドが生まれるのでは… :bulb:

/path/to/file 20 で開きたい

シェルだと補完が効いて、ファイル名の後に半角スペースが1個入ってしまう。じゃあそのまま第二引数で行番号を指定したい。

こういうシェル関数を .bashrc とか .zshrc に用意しておいて、

function e {
    local args
    args="+$2 $1"
    eval "emacs $args"
}
$ e /path/to/file 20

どっちでも開けるようにしたい!

自分はどちらのスタイルでも開けるように、以下の様なシェル関数を .zshrc に定義してあります。

function e {
    local args

    if [[ $# -eq 2 ]]; then
        args="+$2 $1"
    else
        args=`echo $1 | sed -E "s/([^:]+):([0-9:]+)/+\2 \1/g"`
    fi

    eval "emacsclient -n $args"
}

Emacs 上で行番号を指定して開く

そういうことができるコマンドは Emacs に存在しないので、既存の C-x C-f (find-file) を拡張することで対処します。以下のコードを init.el なりに追加しましょう。

;; http://stackoverflow.com/questions/3139970/open-a-file-at-line-with-filenameline-syntax/3141456#3141456
(defadvice find-file (around find-file-line-number
                             (filename &optional wildcards)
                             activate)
  "Turn files like file.cpp:14 into file.cpp and going to the 14-th line."
  (save-match-data
    (let* ((matched (string-match "^\\(.*\\):\\([0-9]+\\):?$" filename))
           (line-number (and matched
                             (match-string 2 filename)
                             (string-to-number (match-string 2 filename))))
           (filename (if matched (match-string 1 filename) filename)))
      ad-do-it
      (when line-number
        ;; goto-line is for interactive use
        (goto-char (point-min))
        (forward-line (1- line-number))))))

これで、C-x C-f /path/to/file:20 すればちゃんと20行目で開くようになります。

REF

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13