diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 6fcc1b0a078..a5535df601b 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -4871,6 +4871,24 @@ Therefore, all else being equal, it is preferable to pass a buffer than a string as @var{source} argument. @end defun +Sometimes @code{replace-region-contents} is unable to understand the +nature of the change in which case information such as overlays and +markers will not be preserved as well as we would like. If this is +important and you have enough knowledge about the change, you can +preserve this information manually. For example, when sorting the lines +of a region, you can start by collecting all the overlays and markers in +the affected region using @code{overlays-in} and @code{markers-in} as +well as recording a description of the line on which they were found. +After inserting the sorted lines, you can then move the objects back to +their rightful position. + +@defun markers-in &optional beg end +Return a list of all the markers found between @var{beg} and @var{end} +in the current buffer. @var{beg} defaults the @code{point-min} and +@var{end} defaults to @code{point-max}. Do not rely on the order of the +markers in the list, because it is unspecified. +@end defun + @node Decompression @section Dealing With Compressed Data diff --git a/etc/NEWS b/etc/NEWS index 2ee0df5650d..1b5bd471cb8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -90,6 +90,9 @@ To install the grammars, use 'M-x markdown-ts-mode-install-parsers'. * Lisp Changes in Emacs 32.1 ++++ +** The new function 'markers-in' returns the set of markers in a region. + --- ** New variable 'completion-frontend-properties'. This variable generalizes the 'completion-lazy-hilit' variable added in diff --git a/src/marker.c b/src/marker.c index b0b05fbb5a0..84614e42e11 100644 --- a/src/marker.c +++ b/src/marker.c @@ -794,6 +794,36 @@ If TYPE is nil, it means the marker stays behind when you insert text at it. */ return type; } +DEFUN ("markers-in", Fmarkers_in, Smarkers_in, 0, 2, 0, + doc: /* Return the list of markers in region BEG..END. +The list includes markers at BEG and at END. */) + (Lisp_Object beg, Lisp_Object end) +{ + Lisp_Object res = Qnil; + struct Lisp_Marker *tail; + ptrdiff_t ibeg, iend; + if (NILP (beg)) + ibeg = BEGV; + else + { + CHECK_FIXNUM_COERCE_MARKER (beg); + ibeg = clip_to_bounds (BEGV, XFIXNUM (beg), ZV); + } + if (NILP (end)) + iend = ZV; + else + { + CHECK_FIXNUM_COERCE_MARKER (end); + iend = clip_to_bounds (BEGV, XFIXNUM (end), ZV); + } + + for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next) + if (ibeg <= tail->charpos && tail->charpos <= iend) + res = Fcons (make_lisp_ptr (tail, Lisp_Vectorlike), res); + + return res; +} + #ifdef MARKER_DEBUG /* For debugging -- count the markers in buffer BUF. */ @@ -840,4 +870,5 @@ syms_of_marker (void) defsubr (&Scopy_marker); defsubr (&Smarker_insertion_type); defsubr (&Sset_marker_insertion_type); + defsubr (&Smarkers_in); } diff --git a/test/src/marker-tests.el b/test/src/marker-tests.el index ddd8bc702e4..f083ece41e1 100644 --- a/test/src/marker-tests.el +++ b/test/src/marker-tests.el @@ -57,4 +57,17 @@ (set-marker marker-2 marker-1) (should (goto-char marker-2)))) +(ert-deftest marker-markers-in () + (with-temp-buffer + (insert "hello ") + (let ((m2 (point-marker))) + (insert "world") + (let ((m1 (point-min-marker)) + (m3 (point-max-marker)) + (ms (markers-in (1+ (point-min)) (1- (point-max))))) + (should (memq m2 ms)) + (should-not (memq m1 ms)) + (should-not (memq m3 ms)) + (should (all (lambda (m) (eq (marker-buffer m) (current-buffer))) ms)))))) + ;;; marker-tests.el ends here