Emacs Lisp делает регион выбранным из начала и конца после изменения буфера - PullRequest
1 голос
/ 19 сентября 2019

Я хотел бы иметь функцию emacs, которая выбирает (отмечает) область, заданную start и end.Я пробовал это с

(defun mark-range (start end)
  "Mark buffer content from start to end"
  (message (concat "Select " (number-to-string start) " " (number-to-string end)))
  (setq bufmax (max start end))
  (setq bufmin (min start end))
  (goto-char bufmax)
  (set-mark bufmin) ;actually the comment on set-mark says: Do not use!

  ;(set-mark-command bufmin) did not work for this
)

. Это работает, когда вызывается в простых функциях, но иногда эта функция просто не работает, даже когда сообщение показывает правильное содержание начала и конца.Выбор тогда просто не существует.

Есть идеи, как мне добиться надежной функции?(Я использую ветку dev Spacemacs)

РЕДАКТИРОВАТЬ: Хорошо, вот пример использования, я на самом деле хочу перемещать текст вверх и вниз с помощью Alt-Up Alt-Down, как в eclipse

Я обнаружил, что есть текст с перемещением блока, но он не соответствует желаемому: выделите полные строки, которых касается область, и затем переместите ее вверх, оставаясь выбранными для повторного использования.

Поэтому я сначала проверяю, сколько строк янеобходимо переместить линию до первого вниз, а затем использовать это также, чтобы снова выбрать линии.Но тогда выбор не работает.Его просто нет.

Я сейчас попытался интегрировать ответ Дрюса, но на самом деле не помогло, отметка не появилась, (добавлена ​​отметка деактивации, как и раньше, тоже не повезло).Опробовано с моим подходом, включающим (активировать, деактивировать) ранее, также не работает.

(defun rl-move-up-block(start end)

  (let (last first dist m-start)
  (goto-char (max start end))
  (setq last (line-number-at-pos))

  (goto-char (min start end))
  (setq first (line-number-at-pos))

  (goto-char (min start end))
  (forward-line -1)

  (setq dist (+ (- last first) 1))

  (dotimes (i dist)
    (move-text-line-down))


  (forward-line (- 0 dist))
  (set-mark (line-beginning-position))
  (forward-line (- dist 1))
  (end-of-line)
  (activate-mark)
 )
)

(defun rl-move-up (start end)
  "Move text up like in eclipse"
  (interactive "r")
  (if (use-region-p)
      (rl-move-up-block start end)
    (move-text-line-up)
    )
  )

(global-set-key (kbd "M-<up>") 'rl-move-up)

РЕДАКТИРОВАТЬ 2: Ну, я только что узнал, удаляю ли я перемещение линий, заменяя его просто перемещениемкурсор, маркировка работает просто отлично.

  ;(dotimes (i dist)
  ;  (move-text-line-down))
  (forward-line dist)

Таким образом, проблема заключается в изменении текста и последующей маркировке.Однажды я попытался посмотреть, что он делает в замедленном режиме, поместив сон между каждой строкой.

Не сработало, просто заставил всю функцию занять больше времени - может быть, для чего-то нужен вызов обновления представления.Есть ли что-то, чтобы обновить или завершить изменение?Может быть, это помогает заставить метку снова работать после перемещения строк.

Ответы [ 2 ]

1 голос
/ 21 сентября 2019

Хорошо получается, что есть переменная.

Я проверил код перемещения текста вниз существующей команды и обнаружил, что переменная установлена ​​на ноль. Если я делаю это после перемещения текста, это работает


  (dotimes (i dist)
    (move-text-line-down)) 

    (setq deactivate-mark nil) ; <<<<<<

    (forward-line (- 0 dist))
1 голос
/ 20 сентября 2019

Вам просто не хватало функции activate-mark.

В документе говорится, что set-mark устанавливает отметку, и что иногда люди делают это без необходимости.Здесь вы явно хотите установить метку в произвольной позиции (наименьшее из START или END).

Вы также хотите вызвать message last.

(defun mark-range (start end)
  "..."
  (set-mark (min start end))
  (goto-char (max start end))
  (activate-mark)
  (message "Select %d to %d" start end))
...