4

次のLispコード行を考えてみましょう:

        (some-function 7 8 | 9) ;; some comment. note the extra indentation

ポイントは「8」と「9」の間に置かれます。を実行する(move-beginning-of-line)と、ポイントは「(」ではなく、行の絶対先頭に配置されます。

についても同じですmove-end-of-line: 1 回実行する場合はポイントを ')' に配置し、2 回実行する場合は行の絶対末尾に配置する方が望ましいと思います。一部の IDE はそのように動作します。

私はこれを実装しようとしましたが、行き詰まりました。私のソリューションは、バッファの終わり近くで、またミニバッファでも特に悪い動作をします。この機能を提供するライブラリはありますか?

4

4 に答える 4

5

ライブラリについては知りませんが、数行の Elisp で実行できます。

行頭部分については、同梱機能beginning-of-line-textback-to-indentation( M-m)が「面白い」部分の行頭に移動します。back-to-indentation空白のみを無視し、 fill プレフィックスbeginning-of-line-textをスキップします(プログラミング言語では、これは通常、コメント内の場合はコメント マーカーです)。実際の行と論理行の先頭を切り替える方法については、Emacs のスマート ホームを参照してください。

行末部分については、次の関数が記述内容を実装しています。関数end-of-line-codeは、末尾の空白とオプションの末尾のコメントを除いて、行の末尾に移動します。関数end-of-line-or-codeはこれを行いますが、ポイントが既にターゲット位置にある場合、または行に空白とコメントのみが含まれている場合、ポイントは実際の行の末尾に移動します。

(defun end-of-line-code ()
  (interactive "^")
  (save-match-data
    (let* ((bolpos (progn (beginning-of-line) (point)))
           (eolpos (progn (end-of-line) (point))))
      (if (comment-search-backward bolpos t)
          (search-backward-regexp comment-start-skip bolpos 'noerror))
      (skip-syntax-backward " " bolpos))))

(defun end-of-line-or-code ()
  (interactive "^")
  (let ((here (point)))
    (end-of-line-code)
    (if (or (= here (point))
        (bolp))
        (end-of-line))))
于 2013-01-09T20:34:31.823 に答える
2

あなたが求めることをほとんど行ういくつかの提案:

Lisp コードでは、sexp 移動コマンドを使用して、必要なことを行うことができます。中間のどこかから式の先頭に到達するには、 にbackward-up-listバインドされている を使用しM-C-uます。あなたの例では、それはあなたを開き括弧に連れて行きます。リスト内の個々の要素を逆方向に移動するにはbackward-sexp、 , bound to を使用しM-C-bます。forward-sexpは反対方向に移動し、 にバインドされM-C-fます。M-C-nsexp の先頭から;で次へスキップできます。で反転M-C-p

これらのコマンドはどれも実際に現在の物理回線を参照していないため、複数の回線を前後に移動します。

その他のオプションには、画面に表示されている単語の先頭にすばやく移動するための非常に滑らかな方法であるエース ジャンプ モードが含まれます。これにより、行固有のコマンドを使用する必要がなくなる可能性があります。行内ですばやく移動するには、通常、単語を飛び越えるためM-fに andを使用します。またはをM-bタップMしながらキーを押したままにすると、ほとんどの場合デフォルトでそれを使用することになります。bf

編集:

もう 1 つ便利なコマンドを忘れました - back-to-indentation、 にバインドされていM-mます。これにより、行の最初の非空白文字までバックアップされます。最初の呼び出しでは正常に動作し、2 回目の呼び出しでは行頭に戻るようにアドバイスできます。

(defadvice back-to-indentation (around back-to-back)
  (if (eq last-command this-command)
      (beginning-of-line)
    ad-do-it))

(ad-activate 'back-to-indentation)
于 2013-01-09T18:17:32.437 に答える
1

私はあなたが探している振る舞いをするこれらの2つの関数を書いたところです。

(defun move-beginning-indent ()
  (interactive)
  (if (eq last-command this-command)
      (beginning-of-line)
    (back-to-indentation))
)


(defun move-end-indent ()
  (interactive)
  (if (eq last-command this-command)
      (end-of-line)
    (end-of-line)
    (search-backward-regexp "\\s)" nil t)   ; searches backwards for a 
    (forward-char 1))                       ; closed delimiter such as ) or ]
)

(global-set-key [f7] 'move-beginning-indent)          
(global-set-key [f8] 'move-end-indent)  

試してみてください。希望どおりに動作するはずです。

于 2013-01-09T19:47:51.537 に答える
1

私はこれを使用します:

(defun beginning-of-line-or-text (arg)
  "Move to BOL, or if already there, to the first non-whitespace character."
  (interactive "p")
  (if (bolp)
      (beginning-of-line-text arg)
    (move-beginning-of-line arg)))
(put 'beginning-of-line-or-text 'CUA 'move)
;; <home> is still bound to move-beginning-of-line
(global-set-key (kbd "C-a") 'beginning-of-line-or-text)

(defun end-of-code-or-line ()
  "Move to EOL. If already there, to EOL sans comments.
    That is, the end of the code, ignoring any trailing comment
    or whitespace.  Note this does not handle 2 character
    comment starters like // or /*.  Such will not be skipped."
  (interactive)
  (if (not (eolp))
      (end-of-line)
    (skip-chars-backward " \t")
    (let ((pt (point))
          (lbp (line-beginning-position))
          (comment-start-re (concat (if comment-start
                                        (regexp-quote
                                         (replace-regexp-in-string
                                          "[[:space:]]*" "" comment-start))
                                      "[^[:space:]][[:space:]]*$")
                                    "\\|\\s<"))
          (comment-stop-re "\\s>")
          (lim))
      (when (re-search-backward comment-start-re lbp t)
        (setq lim (point))
        (if (re-search-forward comment-stop-re (1- pt) t)
            (goto-char pt)
          (goto-char lim)               ; test here ->
          (while (looking-back comment-start-re (1- (point)))
            (backward-char))
          (skip-chars-backward " \t"))))))
(put 'end-of-code-or-line 'CUA 'move)
;; <end> is still bound to end-of-visual-line
(global-set-key (kbd "C-e") 'end-of-code-or-line)
于 2013-01-09T20:32:57.937 に答える