Emacs: как вычислить наименьшее s-выражение, в котором находится курсор, или следующее s-выражение - PullRequest
2 голосов
/ 31 января 2010

Как правильно оценить (+ 100 (+ 100 100)) часть в

(+ (+ 1 2) (+ 100 (+ 100 100)))

Пока я делаю это C-x C-e, что означает, что мне нужно найти конечную скобку, что в большинстве случаев сложно. Options > Paren Matching Highlighting помогает, но все же мне нужно переместить курсор к конечной скобке, пока выделенное совпадение не станет начальной скобкой.

Одним из способов было бы иметь обратную версию C-x C-e, чтобы я мог поместить курсор в начальную скобку следующим образом:

(+ (+ 1 2) |(+ 100 (+ 100 100)))

, а затем нажмите соответствующую связку клавиш.

Или я мог бы поместить курсор внутри выражения, но не внутри меньших выражений:

(+ (+ 1 2) (+ | 100 (+ 100 100)))

и нажмите клавишу связывания. Потому что нацеливаться на цель легче, если цель большая.

Как я могу сделать такую ​​команду? Или уже есть один?

Sidenote: курсор курсора и курсор курсора

Emacsers, которые используют курсор курсора (по умолчанию), могут задаться вопросом, куда я помещаю курсор с обозначением панели выше. В emacs вы можете выбрать курсор в виде курсора или курсор в виде строки, (bar-cursor-mode t). Когда курсор на панели находится между буквами A и B, курсор на блоке находится на B. Таким образом, строка является левой стенкой блока.

Кстати, концепция линейного курсора полезна необычным способом: Практика перехода от index1 к index2-1 в программировании удивляет новичков. Это помогает представить index1 и index2 как столбцы (левые стены), а не как прямоугольники.

Ответы [ 4 ]

3 голосов
/ 31 января 2010

Привязать ключ к одному или обоим из них:

(defun eval-next-sexp ()
  (interactive)
  (save-excursion
    (forward-sexp)
    (eval-last-sexp nil)))

(defun eval-surrounding-sexp (levels)
  (interactive "p")
  (save-excursion
    (up-list (abs levels))
    (eval-last-sexp nil)))

Тангенциально связанный, я настоятельно рекомендую paredit для работы с s-выражениями. Команды редактирования структуры и привязки делают редактирование s-выражений быстрым. Он связывает C-down с up-list, так что eval-surrounding-sexp выше почти такой же, как C-down C-x C-e (единственное отличие состоит в том, что функция использует save-excursion для предотвращения движения).

2 голосов
/ 31 января 2010

Вы можете написать такую ​​команду примерно так:

(require 'thingatpt)
(defun eval-sexp-at-or-surrounding-pt ()
  "evaluate the sexp following the point, or surrounding the point"
  (interactive)
  (save-excursion
    (forward-char 1)
    (if (search-backward "(" nil t)
        (message "%s" (eval (read-from-whole-string (thing-at-point 'sexp)))))))
0 голосов
/ 22 августа 2011

В Сосульки есть общий способ сделать то, что вы хотите.

По умолчанию в минибуфере M -. привязан к команде, которая вставляет текст в (или около) точке в минибуфер (не вводит его или не делает с ним другое; просто вставляет его) ).

Вы можете, например, использовать M -: для оценки пола в Лиспе, а затем вы используете M -. для захвата пола в / около точке.

Если вы повторяете M -. , тогда он отбрасывает то, что просто схватил, захватывает какую-то другую вещь (текст) в / около точки и вставляет это. По умолчанию он проходит через эти вещи, в следующем порядке:

а. Символ Лисп или имя файла.

б. Активный регион (выделенный текст) или слово.

с. Самый ближайший список.

* * Д тысячу двадцать восемь. Следующий по величине список.

е. Следующий по величине список.

ф. Какой бы файл или URL-адрес не угадал функция ffap-guesser.

г. Каким бы ни был URL-адрес, угадывается функция thing-at-point-url-at-point.

Что это значит для вашего примера (+ (+ 1 2) (+ 100 (+ 100 100)))?

Если точка находится перед, например, 1 от второй до последней 100, то это полы, которые последовательно вставляются в минибуфер при повторном нажатии M -. , по порядку:

а. +

б. 100

с. (+ 100 100)

д. (+ 100 (+ 100 100))

е. (+ (+ 1 2) (+ 100 (+ 100 100)))

Таким образом, чтобы вставить самый большой из включенных списков, вы должны сделать M-: M-. M-. M-. M-. M -. , то есть пять раз M -. .

Для этого поведения, в частности для точного захвата списков, вам также понадобится библиотека Thing At Point + .

0 голосов
/ 31 января 2010

Есть встроенный eval-defun. По умолчанию он ограничен C - M - x . Это похоже на то, что вы хотите, но уклоняется от определения верхнего уровня. Возможно, вы можете адаптировать это.

...