Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Empty" overlays are ignored #14

Open
alphapapa opened this issue Nov 8, 2017 · 5 comments
Open

"Empty" overlays are ignored #14

alphapapa opened this issue Nov 8, 2017 · 5 comments
Assignees

Comments

@alphapapa
Copy link
Collaborator

alphapapa commented Nov 8, 2017

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
Copy link
Collaborator Author

@ShingoFukuyama Ping? :)

@conao3
Copy link
Collaborator

conao3 commented Jan 24, 2020

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).

@sgleizes
Copy link

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

@alphapapa
Copy link
Collaborator Author

@sgleizes Thanks, good catch.

@tarsius
Copy link
Member

tarsius commented May 22, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants