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

can you add swiper-the-thing-with-same-fontface #288

Closed
redguardtoo opened this issue Nov 9, 2015 · 3 comments
Closed

can you add swiper-the-thing-with-same-fontface #288

redguardtoo opened this issue Nov 9, 2015 · 3 comments

Comments

@redguardtoo
Copy link
Contributor

That's useful when I want to replace all the things in text, but I don't want to wrongly replace sub-string of function or variable name.

@abo-abo
Copy link
Owner

abo-abo commented Nov 9, 2015

There's already swiper-query-replace bound to M-q for that, exactly because the-thing-with-same-fontface is a very vague idea.

Swiper works line-wise, can't change that. So the thing could be in two places on a single line, with two different faces. That's one problem.

Additionally, faces apply to each character separately. Thing-at-point can have a different face for every single char. Suppose we restrict ourselves to only the cases where each entire match has face (plist-get (text-properties-at (point)) 'face). Then it can be done.

One more thing, the faces don't get assigned if the buffer is huge. See the code of swiper-font-lock-ensure. You can advise it to also work for huge buffers, but then you'll have to wait for a few seconds for swiper to start up.

Have a look at this code that's supposed to work, if we accept the above assumptions/restrictions:

(defvar swiper-like-this-face nil)

(defun swiper-like-this (&optional initial-input)
  "`isearch' with an overview using `ivy'.
When non-nil, INITIAL-INPUT is the initial search pattern."
  (interactive)
  (swiper--init)
  (setq swiper-like-this-face
        (plist-get (text-properties-at (point)) 'face))
  (let ((candidates (swiper--candidates))
        (preselect (buffer-substring-no-properties
                    (line-beginning-position)
                    (line-end-position)))
        (minibuffer-allow-text-properties t))
    (unwind-protect
         (ivy-read
          "Swiper: "
          candidates
          :initial-input initial-input
          :keymap swiper-map
          :preselect preselect
          :require-match t
          :update-fn #'swiper--update-input-ivy
          :unwind #'swiper--cleanup
          :action #'swiper--action
          :re-builder #'swiper--re-builder
          :matcher #'swiper--like-this-matcher
          :history 'swiper-history
          :caller 'swiper)
      (when (null ivy-exit)
        (goto-char swiper--opoint)))))

(defun swiper--like-this-matcher (regexp candidates)
  "Return REGEXP-matching CANDIDATES.
Skip some dotfiles unless `ivy-text' requires them."
  (cl-remove-if-not
   (lambda (x)
     (and
      (string-match regexp x)
      (let ((s (match-string 0 x))
            (i 0))
        (while (and (< i (length s))
                    (text-property-any
                     i (1+ i)
                     'face swiper-like-this-face
                     s))
          (cl-incf i))
        (eq i (length s)))))
   candidates))

If you like the code, I'll integrate it.

@redguardtoo
Copy link
Contributor Author

Yes, I like every line you wrote ;)

@abo-abo
Copy link
Owner

abo-abo commented Nov 11, 2015

Thanks for the suggestion and the testing. The C-c C-f toggle is now available for swiper.

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

No branches or pull requests

2 participants