LINUX.ORG.RU

Выравнивание в функции emacs lisp

 ,


0

1

Имеется функция, задача которой производить замены в выделенной области и делать выравнивание области. По сути конвертирует таблицы из csv (сепаратор «;») в latex. Выглядит это так

(defun my/convert-table-to-latex ()
  "csv to latex"
  (interactive)
  (setq beg (region-beginning))
  (setq end (region-end))
  (perform-replace ";" "&" nil 'regexp nil nil nil beg end nil nil)
  (perform-replace "$" "\\\\\\\\ \\\\hline" nil 'regexp nil nil nil beg end nil nil)
  (indent-region beg (+ end 1)))

Работает все, кроме выравнивания последней строки. Ее выравнивает, но неправильно, при этом, если нажать после завершения выполнения функции tab, строку выравнивает правильно. Пробовал такой вариант для проверки:

(defun my/convert-table-to-latex ()
  "csv to latex"
  (interactive)
  (setq beg (region-beginning))
  (setq end (region-end))
  (perform-replace ";" "&" nil 'regexp nil nil nil beg end nil nil)
  (perform-replace "$" "\\\\\\\\ \\\\hline" nil 'regexp nil nil nil beg end nil nil)
  ;; (indent-region beg (+ end 1)))
  (set-mark-command beg)
  (goto-char end)
  (activate-mark)
  (indent-for-tab-command)
  (goto-char end))

Оказывается, несмотря на то, что я перехожу в конце функции к изначально заданному концу выделенной области, я оказываюсь всегда ровно на строку выше, чем последняя строка в выделенной области. Подозреваю, что из-за этого и выравнивание неправильное. Как такое поведение исправить?



Последнее исправление: Yorween (всего исправлений: 2)

не знаю можно ли в вашем случае сделать также, но когда мне надо было привести xml файл к нужному выравниванию я делал вот так вот:

(goto-char (point-min))
  (sgml-mode)  
  (while (/= (point) (point-max))
    (sgml-indent-line)
    (forward-line 1))

Silerus ★★★★
()
Ответ на: комментарий от Silerus

Проблема именно в выравнивании заданной области. С выравниванием всего буфера проблем нет.

Yorween
() автор топика
Ответ на: комментарий от Yorween

Смотрю документацию и хочу предложить еще вариант: сужение Narrowing https://www.gnu.org/software/emacs/manual/html_node/elisp/Narrowing.html - сузить буфер до выделенного региона, поступить с ним как с полным буфером, а потом развернуть назад

Silerus ★★★★
()
Ответ на: комментарий от Silerus

Спасибо за подсказку. Так работает

(defun my/convert-table-to-latex (beg end)
  "csv to latex"
  (interactive "r")
  (narrow-to-region beg end)
  (goto-char (point-min))
  (push-mark)
  (setq mark-activate t)
  (goto-char (point-max))
  (perform-replace ";" "&" nil 'regexp nil nil nil beg end nil nil)
  (perform-replace "$" "\\\\\\\\ \\\\hline" nil 'regexp nil nil nil beg end nil nil)
  (indent-region (point-min) (point-max))
  (widen))

Но, сдается мне, костыльно это как-то. Я не пойму, почему у меня в начале выполнения функции и в конце переменная end разная, хотя задаю я ее всего 1 раз.

Yorween
() автор топика
Ответ на: комментарий от Yorween

Нефига и в доках и у Otts написано что это нормальная и полезная штука (очень много функций, тот же поиск и замена через нее работают), только не надо ей пользователя пугать. Насчет разных end посмотри на функции save-restriction save-excursion

Silerus ★★★★
()
Последнее исправление: Silerus (всего исправлений: 2)
Ответ на: комментарий от Yorween

Очевидно, что end разная, потому что я забыл добавить пробелы, которые добавились после выравнивания. Эпично :) Точнее значение end как раз одинаковое, но при переносе в конце функции курсора на эту отметку, она уже не совпадает с прежней из-за выравнивания.

Yorween
() автор топика
Последнее исправление: Yorween (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.