Продовжуйте рухатися до кінця рядків


9

За замовчуванням прив’язка клавіш C-a/C-e- лише одне, перейдіть на початок / кінець рядка, чи є пакет, який може змусити Emacs діяти так:

  1. Якщо я не в кінці рядка, C-eпіде в кінець рядка, інакше піде кінець наступного рядка
  2. Якщо я не на початку рядка, C-aперейду до початку рядка, інакше перейдіть до початку наступного рядка.

Справа в тому, що ви можете просто натискати, C-a/eщоб перейти до початку / кінця кожного рядка, не рухаючи пальцем, щоб досягти C-n/p.

І з префіксом ( C-u) вони перейдуть на початок / кінець рядка у зворотному напрямку.


У коментарі до відповіді нижче @kaushalmodi вказує, що я, можливо, неправильно трактував ваше запитання. Ви хочете C-aпіти «вгору» і C-e«вниз»? Іншими словами, чи однакове значення "наступного рядка" у пунктах 1 та 2?
Костянтин

@ Константин, я насправді замислювався над проблемою " C-aвгору і C-eвниз", коли я розміщував це питання, але тоді я думав, якщо хтось дасть defunрішення, як ти, хтось би знав, що робити, якщо йому подобається C-a"вгору" ..
CodyChan

ДОБРЕ; Я думаю, це все-таки варто виправити. Я оновлю відповідь - це лише зміна в один рядок.
Костянтин

Відповіді:


11

Я не знаю пакету, який би дав змогу подібну поведінку, але ось один із способів зробити це.

Натисніть, C-h k C-aщоб виявити, що C-aпов'язано move-beginning-of-line; це функція, яку нам потрібно змінити --- або просто використати для реалізації частини "перехід до початку". Аналогічно, C-h kя можу знайти forward-line, який буде використовуватися для переміщення вгору / вниз.

Щоб мати можливість прив’язати функцію до ключа, нам потрібно зробити його командою , тому нам потрібно використовувати interactiveспеціальну форму (див. Використання інтерактивної ). Для прийняття C-uаргументу префікса нам потрібен "P"символ коду.

Поєднавши це з bolp(перевірте, чи на початку рядка) та eolp(перевірте, чи в кінці рядка), ми можемо написати:

(defun my-move-beginning-of-line (arg)
  (interactive "P")
  (when (bolp) (previous-line (if arg -1 1)))
  (move-beginning-of-line nil))

(defun my-move-end-of-line (arg)
  (interactive "P")
  (when (eolp) (forward-line (if arg -1 1)))
  (move-end-of-line nil))

Тепер ми можемо повторно зв’язати C-aта C-eвикликати такі:

(global-set-key [remap move-beginning-of-line] #'my-move-beginning-of-line)
(global-set-key [remap move-end-of-line] #'my-move-end-of-line)

Як варіант, можна додати порадиmove-beginning-of-line і до move-end-of-line.


Це дійсно гарне пояснення та елегантне рішення. У функції є помилка друку my-move-beginning-of-line. Повинна вона бути (previous-line (if arg -1 1))або (forward-line (if arg 1 -1))(переключена 1 і -1)?
Каушал Моді

@kaushalmodi: у запитанні як в пунктах 1, так і в 2 запитується "наступний рядок", який я трактував як "вниз". Отже, давайте запитаємо автора питання! :-)
Костянтин

Ах, я додав власне припущення до питання ОП. Ви маєте рацію, він дійсно вказує перейти до наступного рядка, використовуючи C-aабо C-e.
Каушал Моді

@kaushalmodi: Виявляється, ви мали рацію! Я оновив відповідь, щоб C-aперейти "вгору".
Костянтин

8

Бібліотека misc-cmds.elдавно мала цю особливість.

Це відповідні команди та запропоновані прив'язки клавіш (ці прив'язки виконуються в setup-keys.el).

(cond ((fboundp 'move-beginning-of-line)
       (substitute-key-definition 'move-beginning-of-line 'beginning-of-line+ global-map)
       (substitute-key-definition 'move-end-of-line 'end-of-line+ global-map))
      (t
       (substitute-key-definition 'beginning-of-line 'beginning-of-line+ global-map)
       (substitute-key-definition 'end-of-line 'end-of-line+ global-map)))
(when (boundp 'visual-line-mode-map)
  (define-key visual-line-mode-map [remap move-beginning-of-line] nil)
  (define-key visual-line-mode-map [remap move-end-of-line]       nil)
  (define-key visual-line-mode-map [home] 'beginning-of-line+)
  (define-key visual-line-mode-map [end]  'end-of-line+)
  (define-key visual-line-mode-map "\C-a" 'beginning-of-visual-line+)
  (define-key visual-line-mode-map "\C-e" 'end-of-visual-line+)))

Ось що C-h f end-of-line+говорить, як один із прикладів:

end-of-line+ is an interactive compiled Lisp function in
`misc-cmds.el'.

It is bound to C-e, end.

(end-of-line+ &optional N)

Move cursor to end of current line or end of next line if repeated.
This is similar to `end-of-line', but:
  If called interactively with no prefix arg:
     If the previous command was also `end-of-line+', then move to the
     end of the next line.  Else, move to the end of the current line.
  Otherwise, move to the end of the Nth next line (Nth previous line
     if N<0).  Command `end-of-line', by contrast, moves to the end of
     the (N-1)th next line.

Це дуже елегантно.
sanityinc

1

Наступні дві функції виконують потрібні дії.

(defun move-beginning-of-line-or-previous (&optional pre)
  "Move to the start of the line. If we are already at the start
of the line, move to the start of the previous line or, if called 
with a prefix argument, the next line."
  (interactive "P")
  (let* ((pos (point)))
    (move-beginning-of-line nil)
    (if (= (point) pos)
        (if pre
            (next-line)
          (previous-line)))))

(defun move-end-of-line-or-next (&optional pre)
  "Move to the end of the line. If we are already at the end of
the line, move to the end of the next line or, if called with a 
prefix argument, the previous line."
  (interactive "P")
  (let* ((pos (point)))
    (move-end-of-line nil)
    (if (= (point) pos)
        (if pre
            (previous-line)
          (next-line)))))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.