Спасибо, Дрю.
Получается, что зоны ближе всего к тому, что мне нужно, хотя и сосульки, и поиск+ тоже полезны.
Что касается зон, то оказалось, что функция дополнения zz-зон, похоже, не возвращает правильную информацию.
Однако я написал свою собственную функцию, которую я могу использовать вместо нее.
Теперь я делаю это, чтобы запустить произвольный код lisp для дополнения всех зон, которые были ранее добавлены через zone.el...
(defun my-complement-zones (&optional zones)
(unless zones
(setq zones zz-izones))
(zz-unite-zones 'zones)
(let ((result ())
(end (copy-marker (point-min)))
(n 0)
(a nil)
(b nil))
(dolist (item (reverse zones))
(setq n (1+ n))
(setq a (cadr item))
(setq b (caddr item))
(setq result (append (list (list n end a)) result))
(setq end b))
(when (< (marker-position end) (point-max))
(setq result (append (list (list (1+ n) end (copy-marker (point-max)))) result)))
result))
;; Each element has three values: an index followed by the start
;; and end markers for each region. To traverse this structure,
;; do the following ...
(dolist (region (my-complement-zones))
(let ((idx (car region))
(start (cadr region))
(end (caddr region)))
;; At this point, "start" is a marker pointing to the
;; beginning of the given zone, and "end" is a marker pointing
;; its endpoint. I can use these for inputs to any region-aware
;; elisp commands, or for any functions that I might want to
;; write which operate on each given region.
;;
;; ... etc. ...
))
... и вот функция, которую я написал, которая будет проходить по списку зон и применять лямбду к каждой зоне. Это работает одинаково, независимо от того, используем ли мы исходные zz-izones или их дополнение, созданное с помощью моей функции:
;; Helper function
(defun funcallable (func)
(and func
(or (functionp func)
(and (symbolp func)
(fboundp func)))))
;; Traverse a list of zones such as zz-izones, and apply a lambda
;; to each zone in the list. Works equivalently with the output of
;; `my-complement-zones'.
(defun traverse-zones (func &optional zones)
(when (funcallable func)
(unless zones
(setq zones zz-izones))
(zz-unite-zones 'zones) ;; not sure if this is really necessary
(dolist (zone zones)
(let ((i (car zone))
(s (cadr zone))
(e (caddr zone)))
(funcall func i s e)))))
Чтобы проиллюстрировать разницу в структуре между zz-izones и выводом zz-zones-complement, вот пример структуры zz-izones, которую я создал в буфере с именем «foo»:
((4 #<marker at 1202 in foo> #<marker at 1266 in foo>) (3 #<marker at 689 in foo> #<marker at 1132 in foo>) (2 #<marker at 506 in foo> #<marker at 530 in foo>) (1 #<marker at 3 in foo> #<marker at 446 in foo>))
Вот как (zz-zones-complement zz-izones) выглядит для этого самого списка zz-izones...
((1 4) (#<marker at 1202 in foo> 3) (#<marker at 689 in foo> 2) (#<marker at 506 in foo> 1) (#<marker at 3 in foo> 1266)
Обратите внимание, что каждая запись в zz-izones состоит из индекса и двух маркеров. Однако в своем дополнении каждая запись представляет собой либо два целых числа, либо маркер и целое число. Эти структуры не изоморфны.
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
Для (zz-zone-union (zz-izone-limits zz-izones nil t))
...
((#<marker at 3 in foo> #<marker at 446 in foo>) (#<marker at 506 in foo> #<marker at 530 in foo>) (#<marker at 689 in foo> #<marker at 1132 in foo>) (#<marker at 1202 in foo> #<marker at 1266 in foo>)
Для (zz-zones-complement (zz-zone-union (zz-izone-limits zz-izones nil t)))
((1 #<marker at 3 in foo>) (#<marker at 446 in foo> #<marker at 506 in foo>) (#<marker at 530 in foo> #<marker at 689 in foo>) (#<marker at 1132 in foo> #<marker at 1202 in foo>) (#<marker at 1266 in foo> 1266))
Я думаю, я мог бы использовать это дополнение, если бы я преобразовал «1» в первой записи в (copy-marker (point-min))
и «1266» в последнем элементе в (copy-marker (point-max))
... если только я не имею дело с конкретным случаем, когда не имеет значения, является ли Я имею дело с маркерами или точками.
Маркеры идеальны, потому что тогда я могу изменить буфер после создания дополнения, и мне не придется беспокоиться о числовом значении точки в структуре дополнения, которое больше не указывает на то, где оно изначально указывало.
person
HippoMan
schedule
06.02.2016