ov icon indicating copy to clipboard operation
ov copied to clipboard

"Empty" overlays are ignored

Open alphapapa opened this issue 8 years ago • 5 comments
trafficstars

Hi,

I've noticed that "empty" overlays (i.e. overlays whose beginning and end points are the same) are ignored in functions like ov-next and ov-prev. This seems to be because ov-at is used, which uses overlays-at, which does not return empty overlays. However, overlays-in does return them.

I did some refactoring of ov-next and ov-prev which seems to fix it, but they should be tested further. I also used pcase to simplify the dispatching. Also, the any, property, and property-value functions could be factored out, since they're the same except for which functions they call to get next/previous overlays.

Another issue is that ov-at only returns one overlay even if there are multiple overlays there. This becomes a small problem when other functions are built on top of it. :) This is a deeper problem, though. Probably, there should be sibling functions to these that return all overlays rather than only one.

Please let me know what you think. I can send a PR if you like, but this probably needs a bit more work.

This library is extremely useful, thanks for making it!

(cl-defun ov-prev (&optional point-or-prop prop-or-val (val 'any))
  "Get the previous overlay satisfying a condition.

If POINT-OR-PROP is a symbol, get the previous overlay with this
property being non-nil.

If PROP-OR-VAL is non-nil, the property should have this value.

If POINT-OR-PROP is a number, get the previous overlay after this
point.

If PROP-OR-VAL and VAL are also specified, get the previous
overlay after POINT-OR-PROP having property PROP-OR-VAL set to
VAL (with VAL unspecified, only the presence of property is
tested)."
  (cl-labels ((any (pos)
                   (car (overlays-in (previous-overlay-change pos) (previous-overlay-change pos))))
              (property (pos property)
                        (save-excursion
                          (goto-char pos)
                          (cl-loop while (and (not (bobp))
                                              (goto-char (previous-overlay-change (point))))
                                   when (cl-loop for ov in (overlays-in (point) (point))
                                                 when (plist-get (ov-prop ov) property)
                                                 return ov)
                                   return it)))
              (property-value (pos property value)
                              (save-excursion
                                (goto-char pos)
                                (cl-loop while (and (not (bobp))
                                                    (goto-char (previous-overlay-change (point))))
                                         when (cl-loop for ov in (overlays-in (point) (point))
                                                       for ov-value = (plist-get (ov-prop ov) property)
                                                       when (equal ov-value value)
                                                       return ov)
                                         return it))))
    (pcase point-or-prop
      ((pred numberp) (pcase prop-or-val
                        (`nil (any point-or-prop))
                        (_ (pcase val
                             ('any (property point-or-prop prop-or-val))
                             (_ (property-value point-or-prop prop-or-val val))))))
      (`nil (any (point)))
      (_ (pcase prop-or-val
           (`nil (property (point) point-or-prop))
           (_ (pcase val
                ('any (property (point) point-or-prop))
                (_ (property-value point-or-prop prop-or-val val)))))))))

(cl-defun ov-next (&optional point-or-prop prop-or-val (val 'any))
  "Get the next overlay satisfying a condition.

If POINT-OR-PROP is a symbol, get the next overlay with this
property being non-nil.

If PROP-OR-VAL is non-nil, the property should have this value.

If POINT-OR-PROP is a number, get the next overlay after this
point.

If PROP-OR-VAL and VAL are also specified, get the next overlay
after POINT-OR-PROP having property PROP-OR-VAL set to VAL (with
VAL unspecified, only the presence of property is tested)."
  (cl-labels ((any (pos)
                   (car (overlays-in (next-overlay-change pos) (next-overlay-change pos))))
              (property (pos property)
                        (save-excursion
                          (goto-char pos)
                          (cl-loop while (and (not (bobp))
                                              (goto-char (next-overlay-change (point))))
                                   when (cl-loop for ov in (overlays-in (point) (point))
                                                 when (plist-get (ov-prop ov) property)
                                                 return ov)
                                   return it)))
              (property-value (pos property value)
                              (save-excursion
                                (goto-char pos)
                                (cl-loop while (and (not (bobp))
                                                    (goto-char (next-overlay-change (point))))
                                         when (cl-loop for ov in (overlays-in (point) (point))
                                                       for ov-value = (plist-get (ov-prop ov) property)
                                                       when (equal ov-value value)
                                                       return ov)
                                         return it))))
    (pcase point-or-prop
      ((pred numberp) (pcase prop-or-val
                        (`nil (any point-or-prop))
                        (_ (pcase val
                             ('any (property point-or-prop prop-or-val))
                             (_ (property-value point-or-prop prop-or-val val))))))
      (`nil (any (point)))
      (_ (pcase prop-or-val
           (`nil (property (point) point-or-prop))
           (_ (pcase val
                ('any (property (point) point-or-prop))
                (_ (property-value point-or-prop prop-or-val val)))))))))

alphapapa avatar Nov 08 '17 14:11 alphapapa

@ShingoFukuyama Ping? :)

alphapapa avatar May 27 '18 21:05 alphapapa

I'm OK with this patch. If you want to add it, please just push or send PR (makes more one-work separate clear and makes easy to revert the whole PR if found issues).

conao3 avatar Jan 24 '20 18:01 conao3

IIUC there is a small oversight in the proposed patch (thanks @alphapapa!): In ov-next, use eobp instead of bobp.

sgleizes avatar Mar 31 '21 13:03 sgleizes

@sgleizes Thanks, good catch.

alphapapa avatar Apr 01 '21 11:04 alphapapa

@alphapapa you aren't by any chance interested in maintaining this package? Or any other packages in the orphanage for that matter?

tarsius avatar May 22 '23 11:05 tarsius