+++ /dev/null
-;;; symbol-overlay-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
- (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "symbol-overlay" "symbol-overlay.el" (0 0 0
-;;;;;; 0))
-;;; Generated autoloads from symbol-overlay.el
-
-(autoload 'symbol-overlay-mode "symbol-overlay" "\
-Minor mode for auto-highlighting symbol at point.
-
-This is a minor mode. If called interactively, toggle the
-`Symbol-Overlay mode' mode. If the prefix argument is positive,
-enable the mode, and if it is zero or negative, disable the mode.
-
-If called from Lisp, toggle the mode if ARG is `toggle'. Enable
-the mode if ARG is nil, omitted, or is a positive number.
-Disable the mode if ARG is a negative number.
-
-To check whether the minor mode is enabled in the current buffer,
-evaluate `symbol-overlay-mode'.
-
-The mode's hook is called both when the mode is enabled and when
-it is disabled.
-
-\(fn &optional ARG)" t nil)
-
-(autoload 'symbol-overlay-put "symbol-overlay" "\
-Toggle all overlays of symbol at point." t nil)
-
-(autoload 'symbol-overlay-count "symbol-overlay" "\
-Show count of symbol at point." t nil)
-
-(autoload 'symbol-overlay-remove-all "symbol-overlay" "\
-Remove all highlighted symbols in the buffer.
-When called interactively, then also reset
-`symbol-overlay-keywords-alist'." t nil)
-
-(autoload 'symbol-overlay-save-symbol "symbol-overlay" "\
-Copy symbol at point." t nil)
-
-(autoload 'symbol-overlay-toggle-in-scope "symbol-overlay" "\
-Toggle overlays to be showed in buffer or only in scope." t nil)
-
-(autoload 'symbol-overlay-echo-mark "symbol-overlay" "\
-Jump back to the mark." t nil)
-
-(autoload 'symbol-overlay-jump-next "symbol-overlay" "\
-Jump to the next location of symbol at point." t nil)
-
-(autoload 'symbol-overlay-jump-prev "symbol-overlay" "\
-Jump to the previous location of symbol at point." t nil)
-
-(autoload 'symbol-overlay-jump-first "symbol-overlay" "\
-Jump to the first location." t nil)
-
-(autoload 'symbol-overlay-jump-last "symbol-overlay" "\
-Jump to the last location." t nil)
-
-(autoload 'symbol-overlay-jump-to-definition "symbol-overlay" "\
-Jump to the definition of symbol at point.
-The definition syntax should be defined in a function stored in
-`symbol-overlay-definition-function' that returns the definition's regexp
-with the input symbol." t nil)
-
-(autoload 'symbol-overlay-switch-forward "symbol-overlay" "\
-Switch forward to another symbol." t nil)
-
-(autoload 'symbol-overlay-switch-backward "symbol-overlay" "\
-Switch backward to another symbol." t nil)
-
-(autoload 'symbol-overlay-isearch-literally "symbol-overlay" "\
-Isearch symbol at point literally." t nil)
-
-(autoload 'symbol-overlay-query-replace "symbol-overlay" "\
-Query replace symbol at point." t nil)
-
-(autoload 'symbol-overlay-rename "symbol-overlay" "\
-Rename symbol at point on all its occurrences." t nil)
-
-(register-definition-prefixes "symbol-overlay" '("symbol-overlay-"))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; symbol-overlay-autoloads.el ends here
+++ /dev/null
-;;; Generated package description from symbol-overlay.el -*- no-byte-compile: t -*-
-(define-package "symbol-overlay" "20230503.1051" "Highlight symbols with keymap-enabled overlays" '((emacs "24.3") (seq "2.2")) :commit "72ff963a0f44497b6cc688607357ee65c68ecc84" :authors '(("wolray" . "wolrayNOSPAMfoxmail.com")) :maintainers '(("wolray" . "wolrayNOSPAMfoxmail.com")) :maintainer '("wolray" . "wolrayNOSPAMfoxmail.com") :keywords '("faces" "matching") :url "https://github.com/wolray/symbol-overlay/")
+++ /dev/null
-;;; symbol-overlay.el --- Highlight symbols with keymap-enabled overlays -*- lexical-binding: t -*-
-
-;; Copyright (C) 2017 wolray
-
-;; Author: wolray <wolrayNOSPAMfoxmail.com>
-;; Version: 4.1
-;; Package-Version: 20230503.1051
-;; Package-Commit: 72ff963a0f44497b6cc688607357ee65c68ecc84
-;; URL: https://github.com/wolray/symbol-overlay/
-;; Keywords: faces, matching
-;; Package-Requires: ((emacs "24.3") (seq "2.2"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Highlighting symbols with overlays while providing a keymap for various
-;; operations about highlighted symbols. It was originally inspired by the
-;; package `highlight-symbol'. The fundamental difference is that in
-;; `symbol-overlay' every symbol is highlighted by the Emacs built-in function
-;; `overlay-put' rather than the `font-lock' mechanism used in
-;; `highlight-symbol'.
-
-;; Advantages
-
-;; When highlighting symbols in a buffer of regular size and language,
-;; `overlay-put' behaves as fast as the traditional highlighting method
-;; `font-lock'. However, for a buffer of major-mode with complicated keywords
-;; syntax, like haskell-mode, `font-lock' is quite slow even the buffer is less
-;; than 100 lines. Besides, when counting the number of highlighted
-;; occurrences, `highlight-symbol' will call the function `how-many' twice,
-;; which could also result in an unpleasant delay in a large buffer. Those
-;; problems don't exist in `symbol-overlay'.
-
-;; When putting overlays on symbols, an auto-activated overlay-inside keymap
-;; will enable you to call various useful commands with a single keystroke.
-
-;; Toggle all overlays of symbol at point: `symbol-overlay-put'
-;; Jump between locations of symbol at point: `symbol-overlay-jump-next' &
-;; `symbol-overlay-jump-prev'
-;; Switch to the closest symbol highlighted nearby:
-;; `symbol-overlay-switch-forward' & `symbol-overlay-switch-backward'
-;; Minor mode for auto-highlighting symbol at point: `symbol-overlay-mode'
-;; Remove all highlighted symbols in the buffer: `symbol-overlay-remove-all'
-;; Copy symbol at point: `symbol-overlay-save-symbol'
-;; Toggle overlays to be showed in buffer or only in scope:
-;; `symbol-overlay-toggle-in-scope'
-;; Jump back to the position before a recent jump: `symbol-overlay-echo-mark'
-;; Jump to the definition of symbol at point: `symbol-overlay-jump-to-definition'
-;; Isearch symbol at point literally:
-;; `symbol-overlay-isearch-literally'
-;; Query replace symbol at point: `symbol-overlay-query-replace'
-;; Rename symbol at point on all its occurrences: `symbol-overlay-rename'
-
-;; Usage
-
-;; To use `symbol-overlay' in your Emacs, you need only to bind these keys:
-;; (require 'symbol-overlay)
-;; (global-set-key (kbd "M-i") 'symbol-overlay-put)
-;; (global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
-;; (global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
-;; (global-set-key (kbd "<f7>") 'symbol-overlay-mode)
-;; (global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)
-
-;; Default key-bindings are defined in `symbol-overlay-map'.
-;; You can re-bind the commands to any keys you prefer by simply writing
-;; (define-key symbol-overlay-map (kbd "your-prefer-key") 'any-command)
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'thingatpt)
-(require 'seq)
-
-(defgroup symbol-overlay nil
- "Highlight symbols with keymap-enabled overlays."
- :group 'convenience)
-
-;;; Faces
-
-(defface symbol-overlay-default-face
- '((t (:inherit highlight)))
- "Symbol Overlay default face"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-1
- '((t (:background "dodger blue" :foreground "black")))
- "Symbol Overlay default candidate 1"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-2
- '((t (:background "hot pink" :foreground "black")))
- "Symbol Overlay default candidate 2"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-3
- '((t (:background "yellow" :foreground "black")))
- "Symbol Overlay default candidate 3"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-4
- '((t (:background "orchid" :foreground "black")))
- "Symbol Overlay default candidate 4"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-5
- '((t (:background "red" :foreground "black")))
- "Symbol Overlay default candidate 5"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-6
- '((t (:background "salmon" :foreground "black")))
- "Symbol Overlay default candidate 6"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-7
- '((t (:background "spring green" :foreground "black")))
- "Symbol Overlay default candidate 7"
- :group 'symbol-overlay)
-
-(defface symbol-overlay-face-8
- '((t (:background "turquoise" :foreground "black")))
- "Symbol Overlay default candidate 8"
- :group 'symbol-overlay)
-
-;;; Options
-
-(defcustom symbol-overlay-faces '(symbol-overlay-face-1
- symbol-overlay-face-2
- symbol-overlay-face-3
- symbol-overlay-face-4
- symbol-overlay-face-5
- symbol-overlay-face-6
- symbol-overlay-face-7
- symbol-overlay-face-8)
- "Faces used for overlays."
- :type '(repeat face)
- :group 'symbol-overlay)
-
-(defcustom symbol-overlay-displayed-window t
- "See `symbol-overlay-maybe-put-temp'."
- :group 'symbol-overlay
- :type 'boolean)
-
-(defcustom symbol-overlay-idle-time 0.5
- "Idle time after every command and before the temporary highlighting."
- :group 'symbol-overlay
- :type 'float)
-
-(defcustom symbol-overlay-overlay-created-functions '()
- "Functions called after overlay creation that may modify the overlay."
- :group 'symbol-overlay
- :type 'hook)
-
-(defcustom symbol-overlay-ignore-functions
- '((c-mode . symbol-overlay-ignore-function-c)
- (c++-mode . symbol-overlay-ignore-function-c++)
- (python-mode . symbol-overlay-ignore-function-python)
- (java-mode . symbol-overlay-ignore-function-java)
- (go-mode . symbol-overlay-ignore-function-go))
- "Functions to determine whether a symbol should be ignored.
-
-This is an association list that maps a MAJOR-MODE symbol to a
-function that determines whether a symbol should be ignored.
-For instance, such a function could use a major mode's font-lock
-definitions to prevent a language's keywords from getting highlighted."
- :group 'symbol-overlay
- :type '(repeat (cons (function :tag "Mode") function)))
-
-;;; Internal
-
-(defvar symbol-overlay-inhibit-map nil
- "When non-nil, don't use `symbol-overlay-map'.
-This is intended for buffers/modes that use the keymap text
-property for their own purposes. Because this package uses
-overlays it would always override the text property keymaps
-of such packages.")
-(put 'symbol-overlay-inhibit-map 'safe-local-variable 'booleanp)
-
-(defvar symbol-overlay-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "i") #'symbol-overlay-put)
- (define-key map (kbd "h") #'symbol-overlay-map-help)
- (define-key map (kbd "p") #'symbol-overlay-jump-prev)
- (define-key map (kbd "n") #'symbol-overlay-jump-next)
- (define-key map (kbd "<") #'symbol-overlay-jump-first)
- (define-key map (kbd ">") #'symbol-overlay-jump-last)
- (define-key map (kbd "w") #'symbol-overlay-save-symbol)
- (define-key map (kbd "t") #'symbol-overlay-toggle-in-scope)
- (define-key map (kbd "e") #'symbol-overlay-echo-mark)
- (define-key map (kbd "d") #'symbol-overlay-jump-to-definition)
- (define-key map (kbd "s") #'symbol-overlay-isearch-literally)
- (define-key map (kbd "q") #'symbol-overlay-query-replace)
- (define-key map (kbd "r") #'symbol-overlay-rename)
- map)
- "Keymap automatically activated inside overlays.
-You can re-bind the commands to any keys you prefer.")
-
-(defvar-local symbol-overlay-keywords-alist nil)
-(put 'symbol-overlay-keywords-alist 'permanent-local t)
-
-(defun symbol-overlay-map-help ()
- "Display the bindings in `symbol-overlay-map'."
- (interactive)
- (let ((buf (get-buffer-create "*Help*")))
- (with-help-window "*Help*"
- (with-current-buffer buf
- (insert (substitute-command-keys "\\{symbol-overlay-map}"))))))
-
-(defvar symbol-overlay-mode-map (make-sparse-keymap)
- "Keymap for `symbol-overlay-mode'.")
-
-;;;###autoload
-(define-minor-mode symbol-overlay-mode
- "Minor mode for auto-highlighting symbol at point."
- :lighter " SO"
- :keymap symbol-overlay-mode-map
- (if symbol-overlay-mode
- (progn
- (add-hook 'post-command-hook #'symbol-overlay-post-command nil t)
- (symbol-overlay-update-timer symbol-overlay-idle-time))
- (remove-hook 'post-command-hook #'symbol-overlay-post-command t)
- (symbol-overlay-remove-temp)))
-
-(defun symbol-overlay-get-list (dir &optional symbol exclude)
- "Get all highlighted overlays in the buffer.
-If SYMBOL is non-nil, get the overlays that belong to it.
-DIR is an integer.
-If EXCLUDE is non-nil, get all overlays excluding those belong to SYMBOL."
- (let ((overlays (cond ((= dir 0) (overlays-in (point-min) (point-max)))
- ((< dir 0) (overlays-in (point-min) (point)))
- ((> dir 0) (overlays-in
- (if (looking-at-p "\\_>") (1- (point)) (point))
- (point-max))))))
- (seq-filter
- (lambda (ov)
- (let ((value (overlay-get ov 'symbol))
- (end (overlay-end ov)))
- (and value
- (or (>= dir 0) (< end (point)))
- (or (not symbol)
- (if (string= value symbol) (not exclude)
- (and exclude (not (string= value ""))))))))
- overlays)))
-
-(defun symbol-overlay-get-symbol (&optional noerror)
- "Get the symbol at point.
-If NOERROR is non-nil, just return nil when no symbol is found."
- (or (thing-at-point 'symbol)
- (unless noerror (user-error "No symbol at point"))))
-
-(defun symbol-overlay-regexp (symbol)
- "Return a regexp to match SYMBOL."
- (concat "\\_<" (regexp-quote symbol) "\\_>"))
-
-(defun symbol-overlay-assoc (symbol)
- "Get SYMBOL's associated list in `symbol-overlay-keywords-alist'."
- (assoc symbol symbol-overlay-keywords-alist))
-
-(defun symbol-overlay-maybe-remove (keyword)
- "Delete the KEYWORD list and all its overlays."
- (when keyword
- (mapc 'delete-overlay (symbol-overlay-get-list 0 (car keyword)))
- (setq symbol-overlay-keywords-alist
- (delq keyword symbol-overlay-keywords-alist))
- (cddr keyword)))
-
-(defvar-local symbol-overlay-temp-symbol nil
- "Symbol for temporary highlighting.")
-
-(defvar-local symbol-overlay-scope nil
- "If non-nil, force to narrow to scope before temporary highlighting.")
-
-(defun symbol-overlay-narrow (scope &optional window)
- "Narrow to a specific region.
-Region might be current scope or displayed window,
-depending on SCOPE and WINDOW."
- (if scope
- (let ((pt (point))
- min max p)
- (save-excursion
- (save-restriction
- (narrow-to-defun)
- (setq min (point-min)
- max (point-max)
- p (or (/= pt (point)) (= pt (point-max))))))
- (save-excursion
- (and p (setq min (progn (backward-paragraph) (point))
- max (progn (forward-paragraph) (point))))
- (narrow-to-region min max)))
- (when (and window (eq (window-buffer) (current-buffer)))
- (narrow-to-region (window-start) (window-end)))))
-
-(defun symbol-overlay-remove-temp ()
- "Delete all temporary overlays."
- (mapc 'delete-overlay (symbol-overlay-get-list 0 ""))
- (setq symbol-overlay-temp-symbol nil))
-
-(defun symbol-overlay-maybe-put-temp ()
- "Highlight symbol at point when there are more than 2 occurrences.
-This only affects symbols in the current displayed window if
-`symbol-overlay-displayed-window' is non-nil."
- (when symbol-overlay-mode
- (let* ((case-fold-search nil)
- (symbol (symbol-overlay-get-symbol t))
- p)
- (when (and symbol
- (not (symbol-overlay-assoc symbol))
- (not (symbol-overlay-ignored-p symbol)))
- (symbol-overlay-remove-temp)
- (save-excursion
- (save-restriction
- (symbol-overlay-narrow symbol-overlay-scope
- symbol-overlay-displayed-window)
- (goto-char (point-min))
- (let ((re (symbol-overlay-regexp symbol)))
- (re-search-forward re nil t)
- (save-match-data
- (while (re-search-forward re nil t)
- (symbol-overlay-put-one symbol)
- (or p (setq p t))))
- (when p
- (symbol-overlay-put-one symbol)
- (setq symbol-overlay-temp-symbol symbol)))))))))
-
-(defun symbol-overlay-ignored-p (symbol)
- "Determine whether SYMBOL should be temporarily highlighted."
- (let ((f (cdr (assoc major-mode symbol-overlay-ignore-functions))))
- (when f
- (funcall f symbol))))
-
-(defvar symbol-overlay-timer nil
- "Timer for temporary highlighting.")
-
-(defun symbol-overlay-cancel-timer ()
- "Cancel `symbol-overlay-timer' if it is running."
- (when symbol-overlay-timer
- (cancel-timer symbol-overlay-timer)))
-
-(defun symbol-overlay-idle-timer ()
- "Idle timer callback.
-This is used to maybe highlight the symbol at point in whichever
-buffer happens to be current when the timer is fired."
- (symbol-overlay-maybe-put-temp))
-
-(defun symbol-overlay-update-timer (value)
- "Update `symbol-overlay-timer' with new idle-time VALUE."
- (symbol-overlay-cancel-timer)
- (setq symbol-overlay-timer
- (and value (> value 0)
- (run-with-idle-timer value t #'symbol-overlay-idle-timer))))
-
-(defun symbol-overlay-post-command ()
- "Installed on `post-command-hook'."
- (unless (or (null symbol-overlay-temp-symbol)
- (string= (symbol-overlay-get-symbol t) symbol-overlay-temp-symbol))
- (symbol-overlay-remove-temp)))
-
-(defun symbol-overlay-put-one (symbol &optional face)
- "Put overlay on current occurrence of SYMBOL after a match.
-If FACE is non-nil, use it as the overlay’s face.
-Otherwise apply `symbol-overlay-default-face'."
- (let ((ov (make-overlay (match-beginning 0) (match-end 0))))
- (if face (progn (overlay-put ov 'face face)
- (unless symbol-overlay-inhibit-map
- (overlay-put ov 'keymap symbol-overlay-map))
- (overlay-put ov 'evaporate t)
- (overlay-put ov 'symbol symbol))
- (overlay-put ov 'face 'symbol-overlay-default-face)
- (overlay-put ov 'symbol ""))
- (dolist (fun symbol-overlay-overlay-created-functions)
- (funcall fun ov))))
-
-(defun symbol-overlay-put-all (symbol scope &optional keyword)
- "Put overlays on all occurrences of SYMBOL in the buffer.
-The face is picked from `symbol-overlay-faces'.
-If SCOPE is non-nil, put overlays only on occurrences in scope.
-If KEYWORD is non-nil, remove it then use its color on new overlays."
- (when symbol-overlay-temp-symbol
- (symbol-overlay-remove-temp))
- (let* ((case-fold-search nil)
- (face (or (car (cl-set-difference
- symbol-overlay-faces
- (mapcar #'cddr symbol-overlay-keywords-alist)))
- ;; If we have exhausted the available faces, then just
- ;; keep using the last face for all subsequent symbols.
- (car (last symbol-overlay-faces)))))
- (save-excursion
- (save-restriction
- (symbol-overlay-narrow scope)
- (goto-char (point-min))
- (let ((re (symbol-overlay-regexp symbol)))
- (while (re-search-forward re nil t)
- (symbol-overlay-put-one symbol face)))))
- (setq keyword `(,symbol ,scope . ,face))
- (push keyword symbol-overlay-keywords-alist)
- keyword))
-
-(defun symbol-overlay-maybe-count (keyword &optional show-color)
- "Show the number of KEYWORD's occurrences.
-If SHOW-COLOR is non-nil, display the color used by current overlay."
- (when keyword
- (let* ((symbol (car keyword))
- (before (symbol-overlay-get-list -1 symbol))
- (after (symbol-overlay-get-list 1 symbol))
- (count (length before))
- ;; Log to echo area but not *Messages*
- message-log-max)
- (message (concat "%s: %d/%d"
- (and (cadr keyword) " in scope")
- (and show-color (format " (%s)" (cddr keyword))))
- symbol
- (+ count 1)
- (+ count (length after))))))
-
-(defun symbol-overlay-match-keyword-list (symbol keywords)
- "Return non-nil is SYMBOL is among KEYWORDS.
-KEYWORDS is a list of strings. SYMBOL is expected to be a return
-value of `symbol-overlay-get-symbol'."
- (cl-find symbol keywords :test #'string=))
-
-(defun symbol-overlay-refresh (beg end _len)
- "Refresh overlays. Installed on `after-change-functions'.
-BEG, END and LEN are the beginning, end and length of changed text."
- (unless (or (minibufferp)
- (not (or symbol-overlay-keywords-alist
- symbol-overlay-temp-symbol)))
- (let ((case-fold-search nil)
- (re "\\(\\sw\\|\\s_\\)+"))
- (save-excursion
- (save-match-data
- (goto-char end)
- (and (looking-at-p re)
- (setq end (re-search-forward "\\_>")))
- (goto-char beg)
- (and (not (looking-at-p "\\_<"))
- (looking-at-p (concat "\\(" re "\\|\\_>\\)"))
- (setq beg (re-search-backward "\\_<")))
- (mapc (lambda (ov)
- (and (overlay-get ov 'symbol)
- (delete-overlay ov)))
- (overlays-in beg end))
- (mapc (lambda (keyword)
- (let* ((symbol (car keyword))
- (re (symbol-overlay-regexp symbol)))
- (goto-char beg)
- (while (re-search-forward re end t)
- (symbol-overlay-put-one symbol (cddr keyword)))))
- symbol-overlay-keywords-alist))))))
-
-(add-hook 'after-change-functions #'symbol-overlay-refresh)
-
-(defun symbol-overlay-after-revert ()
- "Restore overlays after the buffer was reverted."
- (save-restriction
- (widen)
- (symbol-overlay-refresh (point-min) (point-max) nil)))
-
-(add-hook 'after-revert-hook #'symbol-overlay-after-revert)
-
-;;; Language-Specific Ignore
-
-(defvar c-font-lock-extra-types)
-(defun symbol-overlay-ignore-function-c (symbol)
- "Determine whether SYMBOL should be ignored (C Language)."
- (symbol-overlay-match-keyword-list
- symbol
- (append c-font-lock-extra-types
- '("auto" "break" "case" "char" "const" "continue"
- "default" "do" "double" "else" "enum" "extern"
- "float" "for" "goto" "if" "inline" "int" "long"
- "register" "restrict" "return" "short" "signed"
- "sizeof" "static" "struct" "switch" "typedef"
- "union" "unsigned" "void" "volatile" "while"))))
-
-(defvar c++-font-lock-extra-types)
-(defun symbol-overlay-ignore-function-c++ (symbol)
- "Determine whether SYMBOL should be ignored (C++)."
- (symbol-overlay-match-keyword-list
- symbol
- (append c++-font-lock-extra-types
- '("alignas" "alignof" "asm" "auto" "bool" "break"
- "case" "catch" "char" "char16_t" "char32_t" "class"
- "const" "const_cast" "constexpr" "continue"
- "decltype" "default" "delete" "do" "double"
- "dynamic_cast" "else" "enum" "explicit" "export"
- "extern" "false" "final" "float" "for" "friend"
- "goto" "if" "inline" "int" "long" "mutable"
- "namespace" "new" "noexcept" "nullptr" "operator"
- "override" "private" "protected" "public" "register"
- "reinterpret_cast" "return" "short" "signed"
- "sizeof" "static" "static_assert" "static_cast"
- "struct" "switch" "template" "this" "thread_local"
- "throw" "true" "try" "typedef" "typeid" "typename"
- "union" "unsigned" "using" "virtual" "void"
- "volatile" "wchar_t" "while"))))
-
-(defvar python-font-lock-keywords)
-(defun symbol-overlay-ignore-function-python (symbol)
- "Determine whether SYMBOL should be ignored (Python)."
- (let* ((keyword-symbol (car python-font-lock-keywords))
- (keyword (if (stringp keyword-symbol)
- keyword-symbol
- (symbol-name keyword-symbol))))
- (string-match-p keyword symbol)))
-
-(defvar go-builtins)
-(defvar go-constants)
-(defvar go-mode-keywords)
-(defun symbol-overlay-ignore-function-go (symbol)
- "Determine whether SYMBOL should be ignored (Go)."
- ;; Remove \_< and \_> so we can string compare with keywords
- (or (symbol-overlay-match-keyword-list symbol go-builtins)
- (symbol-overlay-match-keyword-list symbol go-constants)
- (symbol-overlay-match-keyword-list symbol go-mode-keywords)))
-
-;; From https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
-(defun symbol-overlay-ignore-function-java (symbol)
- "Determine whether SYMBOL should be ignored (Java)."
- (symbol-overlay-match-keyword-list
- symbol
- '("abstract" "continue" "for" "new" "switch"
- "assert" "default" "goto" "package" "synchronized"
- "boolean" "do" "if" "private" "this"
- "break" "double" "implements" "protected" "throw"
- "byte" "else" "import" "public" "throws"
- "case" "enum" "instanceof" "return" "transient"
- "catch" "extends" "int" "short" "try"
- "char" "final" "interface" "static" "void"
- "class" "finally" "long" "strictfp" "volatile"
- "const*" "float" "native" "super" "while")))
-
-;;; Commands
-
-;;;###autoload
-(defun symbol-overlay-put ()
- "Toggle all overlays of symbol at point."
- (interactive)
- (unless (minibufferp)
- (let* ((symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol)))
- (symbol-overlay-adjust-position)
- (if keyword
- (if (symbol-overlay-maybe-reput symbol keyword)
- (symbol-overlay-maybe-count keyword)
- (symbol-overlay-maybe-remove keyword)
- (symbol-overlay-maybe-put-temp))
- (symbol-overlay-maybe-count
- (symbol-overlay-put-all symbol symbol-overlay-scope)
- t)))))
-
-(defun symbol-overlay-adjust-position ()
- "Backward one char if at the end of the symbol."
- (when (looking-at-p "\\_>") (backward-char)))
-
-;;;###autoload
-(defun symbol-overlay-count ()
- "Show count of symbol at point."
- (interactive)
- (unless (minibufferp)
- (let* ((symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol)))
- (symbol-overlay-adjust-position)
- (symbol-overlay-maybe-count keyword))))
-
-;;;###autoload
-(defun symbol-overlay-remove-all ()
- "Remove all highlighted symbols in the buffer.
-When called interactively, then also reset
-`symbol-overlay-keywords-alist'."
- (interactive)
- (unless (minibufferp)
- (mapc 'delete-overlay (symbol-overlay-get-list 0))
- (when (called-interactively-p 'any)
- (setq symbol-overlay-keywords-alist nil))))
-
-(add-hook 'before-revert-hook #'symbol-overlay-remove-all)
-
-;;;###autoload
-(defun symbol-overlay-save-symbol ()
- "Copy symbol at point."
- (interactive)
- (unless (minibufferp)
- (let ((bounds (bounds-of-thing-at-point 'symbol)))
- (kill-ring-save (car bounds) (cdr bounds))
- (message "Current symbol saved"))))
-
-;;;###autoload
-(defun symbol-overlay-toggle-in-scope ()
- "Toggle overlays to be showed in buffer or only in scope."
- (interactive)
- (unless (minibufferp)
- (let* ((symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol)))
- (if keyword
- (let ((scope (not (cadr keyword))))
- (symbol-overlay-maybe-count
- (symbol-overlay-put-all symbol scope keyword))
- (setq symbol-overlay-scope scope))
- (setq symbol-overlay-scope (not symbol-overlay-scope))))))
-
-(defun symbol-overlay-maybe-reput (symbol keyword)
- "Put overlays on SYMBOL that is not highlighted in scope.
-KEYWORD provides the scope information."
- (when (and (cadr keyword)
- (not (seq-find #'(lambda (ov)
- (string= (overlay-get ov 'symbol) symbol))
- (overlays-at
- (car (bounds-of-thing-at-point 'symbol))))))
- (symbol-overlay-put-all symbol t keyword)))
-
-;;;###autoload
-(defun symbol-overlay-echo-mark ()
- "Jump back to the mark."
- (interactive)
- (let* ((pt (mark))
- (symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol)))
- (and pt (goto-char pt))
- (symbol-overlay-maybe-reput symbol keyword)))
-
-(defun symbol-overlay-jump-call (jump-function dir)
- "A general jumping process during which JUMP-FUNCTION is called to jump.
-DIR must be non-zero."
- (unless (minibufferp)
- (let* ((symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol)))
- (push-mark nil t)
- (funcall jump-function symbol dir)
- (when keyword
- (symbol-overlay-maybe-reput symbol keyword)
- (symbol-overlay-maybe-count keyword)))))
-
-(defun symbol-overlay-basic-jump (symbol dir)
- "Jump to SYMBOL's next location in the direction DIR.
-DIR must be non-zero."
- (let* ((case-fold-search nil)
- (bounds (bounds-of-thing-at-point 'symbol))
- (offset (- (point) (if (> dir 0) (cdr bounds) (car bounds))))
- target
- (re (symbol-overlay-regexp symbol)))
- (goto-char (- (point) offset))
- (setq target (re-search-forward re nil t dir))
- (unless target
- (goto-char (if (> dir 0) (point-min) (point-max)))
- (setq target (re-search-forward re nil nil dir)))
- (goto-char (+ target offset))))
-
-;;;###autoload
-(defun symbol-overlay-jump-next ()
- "Jump to the next location of symbol at point."
- (interactive)
- (symbol-overlay-adjust-position)
- (symbol-overlay-jump-call #'symbol-overlay-basic-jump 1))
-
-;;;###autoload
-(defun symbol-overlay-jump-prev ()
- "Jump to the previous location of symbol at point."
- (interactive)
- (symbol-overlay-adjust-position)
- (symbol-overlay-jump-call #'symbol-overlay-basic-jump -1))
-
-;;;###autoload
-(defun symbol-overlay-jump-first ()
- "Jump to the first location."
- (interactive)
- (symbol-overlay-adjust-position)
- (let* ((symbol (symbol-overlay-get-symbol))
- (before (symbol-overlay-get-list -1 symbol))
- (count (length before)))
- (symbol-overlay-jump-call #'symbol-overlay-basic-jump (- count))))
-
-;;;###autoload
-(defun symbol-overlay-jump-last ()
- "Jump to the last location."
- (interactive)
- (symbol-overlay-adjust-position)
- (let* ((symbol (symbol-overlay-get-symbol))
- (after (symbol-overlay-get-list 1 symbol))
- (count (length after)))
- (symbol-overlay-jump-call #'symbol-overlay-basic-jump (- count 1))))
-
-(defvar-local symbol-overlay-definition-function
- '(lambda (symbol) (concat "(?def[a-z-]* " (symbol-overlay-regexp symbol)))
- "An one-argument function that returns a regexp.")
-
-;;;###autoload
-(defun symbol-overlay-jump-to-definition ()
- "Jump to the definition of symbol at point.
-The definition syntax should be defined in a function stored in
-`symbol-overlay-definition-function' that returns the definition's regexp
-with the input symbol."
- (interactive)
- (symbol-overlay-jump-call
- '(lambda (symbol dir)
- (let ((pt (point)) p)
- (symbol-overlay-basic-jump symbol dir)
- (while (not (or p (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (looking-at-p
- (funcall symbol-overlay-definition-function
- symbol)))))
- (symbol-overlay-basic-jump symbol dir)
- (and (= pt (point)) (setq p t)))))
- 1))
-
-(defun symbol-overlay-switch-symbol (dir)
- "Switch to the closest symbol highlighted nearby, in the direction DIR.
-DIR must be 1 or -1."
- (unless (minibufferp)
- (let* ((symbol (symbol-overlay-get-symbol t))
- (list (symbol-overlay-get-list dir symbol t)))
- (or list
- (user-error (concat "No more "
- (if (> dir 0) "forward" "backward")
- " symbols")))
- (push-mark nil t)
- (goto-char (overlay-start (car list)))
- (symbol-overlay-maybe-count
- (symbol-overlay-assoc (symbol-overlay-get-symbol))))))
-
-;;;###autoload
-(defun symbol-overlay-switch-forward ()
- "Switch forward to another symbol."
- (interactive)
- (symbol-overlay-switch-symbol 1))
-
-;;;###autoload
-(defun symbol-overlay-switch-backward ()
- "Switch backward to another symbol."
- (interactive)
- (symbol-overlay-switch-symbol -1))
-
-;;;###autoload
-(defun symbol-overlay-isearch-literally ()
- "Isearch symbol at point literally."
- (interactive)
- (unless (minibufferp)
- (let ((symbol (symbol-overlay-get-symbol)))
- (beginning-of-thing 'symbol)
- (isearch-forward nil t)
- (isearch-yank-string symbol))))
-
-;;;###autoload
-(defun symbol-overlay-query-replace ()
- "Query replace symbol at point."
- (interactive)
- (unless (minibufferp)
- (let* ((case-fold-search nil)
- (symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol))
- (scope (cadr keyword))
- defaults new)
- (and scope (user-error "Query-replace invalid in scope"))
- (beginning-of-thing 'symbol)
- (push-mark nil t)
- (setq new (read-string "Replacement: " symbol)
- defaults (cons symbol new))
- (unless (string= new symbol)
- (symbol-overlay-maybe-remove (symbol-overlay-assoc new))
- (setq keyword (symbol-overlay-put-all new scope keyword))
- (query-replace-regexp (symbol-overlay-regexp symbol) new)
- (setq query-replace-defaults
- (if (< emacs-major-version 25) `,defaults `(,defaults))))
- (when (string= new (symbol-overlay-get-symbol t))
- (beginning-of-thing 'symbol)
- (symbol-overlay-maybe-count keyword)))))
-
-;;;###autoload
-(defun symbol-overlay-rename ()
- "Rename symbol at point on all its occurrences."
- (interactive)
- (unless (minibufferp)
- (let* ((case-fold-search nil)
- (symbol (symbol-overlay-get-symbol))
- (keyword (symbol-overlay-assoc symbol))
- (scope (if keyword (cadr keyword) symbol-overlay-scope))
- new)
- (beginning-of-thing 'symbol)
- (push-mark nil t)
- (setq new (read-string (concat "Rename" (and scope " in scope") " to: ")
- symbol))
- (unless (string= new symbol)
- (symbol-overlay-maybe-remove (symbol-overlay-assoc new))
- (save-excursion
- (save-restriction
- (symbol-overlay-narrow scope)
- (goto-char (point-min))
- (let ((inhibit-modification-hooks t)
- (re (symbol-overlay-regexp symbol)))
- (while (re-search-forward re nil t) (replace-match new t)))))
- (when keyword
- (setq keyword (symbol-overlay-put-all new scope keyword))))
- (when (string= new (symbol-overlay-get-symbol t))
- (symbol-overlay-maybe-count keyword)))))
-
-;;; _
-(provide 'symbol-overlay)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; End:
-;;; symbol-overlay.el ends here
--- /dev/null
+;;; symbol-overlay-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "symbol-overlay" "symbol-overlay.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from symbol-overlay.el
+
+(autoload 'symbol-overlay-mode "symbol-overlay" "\
+Minor mode for auto-highlighting symbol at point.
+
+This is a minor mode. If called interactively, toggle the
+`Symbol-Overlay mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `symbol-overlay-mode'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'symbol-overlay-put "symbol-overlay" "\
+Toggle all overlays of symbol at point." t nil)
+
+(autoload 'symbol-overlay-count "symbol-overlay" "\
+Show count of symbol at point." t nil)
+
+(autoload 'symbol-overlay-remove-all "symbol-overlay" "\
+Remove all highlighted symbols in the buffer.
+When called interactively, then also reset
+`symbol-overlay-keywords-alist'." t nil)
+
+(autoload 'symbol-overlay-save-symbol "symbol-overlay" "\
+Copy symbol at point." t nil)
+
+(autoload 'symbol-overlay-toggle-in-scope "symbol-overlay" "\
+Toggle overlays to be showed in buffer or only in scope." t nil)
+
+(autoload 'symbol-overlay-echo-mark "symbol-overlay" "\
+Jump back to the mark." t nil)
+
+(autoload 'symbol-overlay-jump-next "symbol-overlay" "\
+Jump to the next location of symbol at point." t nil)
+
+(autoload 'symbol-overlay-jump-prev "symbol-overlay" "\
+Jump to the previous location of symbol at point." t nil)
+
+(autoload 'symbol-overlay-jump-first "symbol-overlay" "\
+Jump to the first location." t nil)
+
+(autoload 'symbol-overlay-jump-last "symbol-overlay" "\
+Jump to the last location." t nil)
+
+(autoload 'symbol-overlay-jump-to-definition "symbol-overlay" "\
+Jump to the definition of symbol at point.
+The definition syntax should be defined in a function stored in
+`symbol-overlay-definition-function' that returns the definition's regexp
+with the input symbol." t nil)
+
+(autoload 'symbol-overlay-switch-forward "symbol-overlay" "\
+Switch forward to another symbol." t nil)
+
+(autoload 'symbol-overlay-switch-backward "symbol-overlay" "\
+Switch backward to another symbol." t nil)
+
+(autoload 'symbol-overlay-isearch-literally "symbol-overlay" "\
+Isearch symbol at point literally." t nil)
+
+(autoload 'symbol-overlay-query-replace "symbol-overlay" "\
+Query replace symbol at point." t nil)
+
+(autoload 'symbol-overlay-rename "symbol-overlay" "\
+Rename symbol at point on all its occurrences." t nil)
+
+(register-definition-prefixes "symbol-overlay" '("symbol-overlay-"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("symbol-overlay-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; symbol-overlay-autoloads.el ends here
--- /dev/null
+(define-package "symbol-overlay" "20230602.851" "Highlight symbols with keymap-enabled overlays"
+ '((emacs "24.3")
+ (seq "2.2"))
+ :commit "7c7d369bb749d96346b40cf714884a39aaa743f4" :authors
+ '(("wolray" . "wolrayNOSPAMfoxmail.com"))
+ :maintainers
+ '(("wolray" . "wolrayNOSPAMfoxmail.com"))
+ :maintainer
+ '("wolray" . "wolrayNOSPAMfoxmail.com")
+ :keywords
+ '("faces" "matching")
+ :url "https://github.com/wolray/symbol-overlay/")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
--- /dev/null
+;;; symbol-overlay.el --- Highlight symbols with keymap-enabled overlays -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 wolray
+
+;; Author: wolray <wolrayNOSPAMfoxmail.com>
+;; Version: 4.1
+;; URL: https://github.com/wolray/symbol-overlay/
+;; Keywords: faces, matching
+;; Package-Requires: ((emacs "24.3") (seq "2.2"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Highlighting symbols with overlays while providing a keymap for various
+;; operations about highlighted symbols. It was originally inspired by the
+;; package `highlight-symbol'. The fundamental difference is that in
+;; `symbol-overlay' every symbol is highlighted by the Emacs built-in function
+;; `overlay-put' rather than the `font-lock' mechanism used in
+;; `highlight-symbol'.
+
+;; Advantages
+
+;; When highlighting symbols in a buffer of regular size and language,
+;; `overlay-put' behaves as fast as the traditional highlighting method
+;; `font-lock'. However, for a buffer of major-mode with complicated keywords
+;; syntax, like haskell-mode, `font-lock' is quite slow even the buffer is less
+;; than 100 lines. Besides, when counting the number of highlighted
+;; occurrences, `highlight-symbol' will call the function `how-many' twice,
+;; which could also result in an unpleasant delay in a large buffer. Those
+;; problems don't exist in `symbol-overlay'.
+
+;; When putting overlays on symbols, an auto-activated overlay-inside keymap
+;; will enable you to call various useful commands with a single keystroke.
+
+;; Toggle all overlays of symbol at point: `symbol-overlay-put'
+;; Jump between locations of symbol at point: `symbol-overlay-jump-next' &
+;; `symbol-overlay-jump-prev'
+;; Switch to the closest symbol highlighted nearby:
+;; `symbol-overlay-switch-forward' & `symbol-overlay-switch-backward'
+;; Minor mode for auto-highlighting symbol at point: `symbol-overlay-mode'
+;; Remove all highlighted symbols in the buffer: `symbol-overlay-remove-all'
+;; Copy symbol at point: `symbol-overlay-save-symbol'
+;; Toggle overlays to be showed in buffer or only in scope:
+;; `symbol-overlay-toggle-in-scope'
+;; Jump back to the position before a recent jump: `symbol-overlay-echo-mark'
+;; Jump to the definition of symbol at point: `symbol-overlay-jump-to-definition'
+;; Isearch symbol at point literally:
+;; `symbol-overlay-isearch-literally'
+;; Query replace symbol at point: `symbol-overlay-query-replace'
+;; Rename symbol at point on all its occurrences: `symbol-overlay-rename'
+
+;; Usage
+
+;; To use `symbol-overlay' in your Emacs, you need only to bind these keys:
+;; (require 'symbol-overlay)
+;; (global-set-key (kbd "M-i") 'symbol-overlay-put)
+;; (global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
+;; (global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
+;; (global-set-key (kbd "<f7>") 'symbol-overlay-mode)
+;; (global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)
+
+;; Default key-bindings are defined in `symbol-overlay-map'.
+;; You can re-bind the commands to any keys you prefer by simply writing
+;; (define-key symbol-overlay-map (kbd "your-prefer-key") 'any-command)
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'thingatpt)
+(require 'seq)
+
+(defgroup symbol-overlay nil
+ "Highlight symbols with keymap-enabled overlays."
+ :group 'convenience)
+
+;;; Faces
+
+(defface symbol-overlay-default-face
+ '((t (:inherit highlight)))
+ "Symbol Overlay default face"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-1
+ '((t (:background "dodger blue" :foreground "black")))
+ "Symbol Overlay default candidate 1"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-2
+ '((t (:background "hot pink" :foreground "black")))
+ "Symbol Overlay default candidate 2"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-3
+ '((t (:background "yellow" :foreground "black")))
+ "Symbol Overlay default candidate 3"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-4
+ '((t (:background "orchid" :foreground "black")))
+ "Symbol Overlay default candidate 4"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-5
+ '((t (:background "red" :foreground "black")))
+ "Symbol Overlay default candidate 5"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-6
+ '((t (:background "salmon" :foreground "black")))
+ "Symbol Overlay default candidate 6"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-7
+ '((t (:background "spring green" :foreground "black")))
+ "Symbol Overlay default candidate 7"
+ :group 'symbol-overlay)
+
+(defface symbol-overlay-face-8
+ '((t (:background "turquoise" :foreground "black")))
+ "Symbol Overlay default candidate 8"
+ :group 'symbol-overlay)
+
+;;; Options
+
+(defcustom symbol-overlay-faces '(symbol-overlay-face-1
+ symbol-overlay-face-2
+ symbol-overlay-face-3
+ symbol-overlay-face-4
+ symbol-overlay-face-5
+ symbol-overlay-face-6
+ symbol-overlay-face-7
+ symbol-overlay-face-8)
+ "Faces used for overlays."
+ :type '(repeat face)
+ :group 'symbol-overlay)
+
+(defcustom symbol-overlay-displayed-window t
+ "See `symbol-overlay-maybe-put-temp'."
+ :group 'symbol-overlay
+ :type 'boolean)
+
+(defcustom symbol-overlay-idle-time 0.5
+ "Idle time after every command and before the temporary highlighting."
+ :group 'symbol-overlay
+ :type 'float)
+
+(defcustom symbol-overlay-overlay-created-functions '()
+ "Functions called after overlay creation that may modify the overlay."
+ :group 'symbol-overlay
+ :type 'hook)
+
+(defcustom symbol-overlay-ignore-functions
+ '((c-mode . symbol-overlay-ignore-function-c)
+ (c++-mode . symbol-overlay-ignore-function-c++)
+ (python-mode . symbol-overlay-ignore-function-python)
+ (java-mode . symbol-overlay-ignore-function-java)
+ (go-mode . symbol-overlay-ignore-function-go))
+ "Functions to determine whether a symbol should be ignored.
+
+This is an association list that maps a MAJOR-MODE symbol to a
+function that determines whether a symbol should be ignored.
+For instance, such a function could use a major mode's font-lock
+definitions to prevent a language's keywords from getting highlighted."
+ :group 'symbol-overlay
+ :type '(repeat (cons (function :tag "Mode") function)))
+
+;;; Internal
+
+(defvar symbol-overlay-inhibit-map nil
+ "When non-nil, don't use `symbol-overlay-map'.
+This is intended for buffers/modes that use the keymap text
+property for their own purposes. Because this package uses
+overlays it would always override the text property keymaps
+of such packages.")
+(put 'symbol-overlay-inhibit-map 'safe-local-variable 'booleanp)
+
+(defvar symbol-overlay-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "i") #'symbol-overlay-put)
+ (define-key map (kbd "h") #'symbol-overlay-map-help)
+ (define-key map (kbd "p") #'symbol-overlay-jump-prev)
+ (define-key map (kbd "n") #'symbol-overlay-jump-next)
+ (define-key map (kbd "<") #'symbol-overlay-jump-first)
+ (define-key map (kbd ">") #'symbol-overlay-jump-last)
+ (define-key map (kbd "w") #'symbol-overlay-save-symbol)
+ (define-key map (kbd "t") #'symbol-overlay-toggle-in-scope)
+ (define-key map (kbd "e") #'symbol-overlay-echo-mark)
+ (define-key map (kbd "d") #'symbol-overlay-jump-to-definition)
+ (define-key map (kbd "s") #'symbol-overlay-isearch-literally)
+ (define-key map (kbd "q") #'symbol-overlay-query-replace)
+ (define-key map (kbd "r") #'symbol-overlay-rename)
+ map)
+ "Keymap automatically activated inside overlays.
+You can re-bind the commands to any keys you prefer.")
+
+(defvar-local symbol-overlay-keywords-alist nil)
+(put 'symbol-overlay-keywords-alist 'permanent-local t)
+
+(defun symbol-overlay-map-help ()
+ "Display the bindings in `symbol-overlay-map'."
+ (interactive)
+ (let ((buf (get-buffer-create "*Help*")))
+ (with-help-window "*Help*"
+ (with-current-buffer buf
+ (insert (substitute-command-keys "\\{symbol-overlay-map}"))))))
+
+(defvar symbol-overlay-mode-map (make-sparse-keymap)
+ "Keymap for `symbol-overlay-mode'.")
+
+;;;###autoload
+(define-minor-mode symbol-overlay-mode
+ "Minor mode for auto-highlighting symbol at point."
+ :lighter " SO"
+ :keymap symbol-overlay-mode-map
+ (if symbol-overlay-mode
+ (progn
+ (add-hook 'post-command-hook #'symbol-overlay-post-command nil t)
+ (symbol-overlay-update-timer symbol-overlay-idle-time))
+ (remove-hook 'post-command-hook #'symbol-overlay-post-command t)
+ (symbol-overlay-remove-temp)))
+
+(defun symbol-overlay-get-list (dir &optional symbol exclude)
+ "Get all highlighted overlays in the buffer.
+If SYMBOL is non-nil, get the overlays that belong to it.
+DIR is an integer.
+If EXCLUDE is non-nil, get all overlays excluding those belong to SYMBOL."
+ (let ((overlays (cond ((= dir 0) (overlays-in (point-min) (point-max)))
+ ((< dir 0) (overlays-in (point-min) (point)))
+ ((> dir 0) (overlays-in
+ (if (looking-at-p "\\_>") (1- (point)) (point))
+ (point-max))))))
+ (seq-filter
+ (lambda (ov)
+ (let ((value (overlay-get ov 'symbol))
+ (end (overlay-end ov)))
+ (and value
+ (or (>= dir 0) (< end (point)))
+ (or (not symbol)
+ (if (string= value symbol) (not exclude)
+ (and exclude (not (string= value ""))))))))
+ overlays)))
+
+(defun symbol-overlay-get-symbol (&optional noerror)
+ "Get the symbol at point.
+If NOERROR is non-nil, just return nil when no symbol is found."
+ (or (thing-at-point 'symbol)
+ (unless noerror (user-error "No symbol at point"))))
+
+(defun symbol-overlay-regexp (symbol)
+ "Return a regexp to match SYMBOL."
+ (concat "\\_<" (regexp-quote symbol) "\\_>"))
+
+(defun symbol-overlay-assoc (symbol)
+ "Get SYMBOL's associated list in `symbol-overlay-keywords-alist'."
+ (assoc symbol symbol-overlay-keywords-alist))
+
+(defun symbol-overlay-maybe-remove (keyword)
+ "Delete the KEYWORD list and all its overlays."
+ (when keyword
+ (mapc 'delete-overlay (symbol-overlay-get-list 0 (car keyword)))
+ (setq symbol-overlay-keywords-alist
+ (delq keyword symbol-overlay-keywords-alist))
+ (cddr keyword)))
+
+(defvar-local symbol-overlay-temp-symbol nil
+ "Symbol for temporary highlighting.")
+
+(defvar-local symbol-overlay-scope nil
+ "If non-nil, force to narrow to scope before temporary highlighting.")
+
+(defun symbol-overlay-narrow (scope &optional window)
+ "Narrow to a specific region.
+Region might be current scope or displayed window,
+depending on SCOPE and WINDOW."
+ (if scope
+ (let ((pt (point))
+ min max p)
+ (save-excursion
+ (save-restriction
+ (narrow-to-defun)
+ (setq min (point-min)
+ max (point-max)
+ p (or (/= pt (point)) (= pt (point-max))))))
+ (save-excursion
+ (and p (setq min (progn (backward-paragraph) (point))
+ max (progn (forward-paragraph) (point))))
+ (narrow-to-region min max)))
+ (when (and window (eq (window-buffer) (current-buffer)))
+ (narrow-to-region (window-start) (window-end)))))
+
+(defun symbol-overlay-remove-temp ()
+ "Delete all temporary overlays."
+ (mapc 'delete-overlay (symbol-overlay-get-list 0 ""))
+ (setq symbol-overlay-temp-symbol nil))
+
+(defun symbol-overlay-maybe-put-temp ()
+ "Highlight symbol at point when there are more than 2 occurrences.
+This only affects symbols in the current displayed window if
+`symbol-overlay-displayed-window' is non-nil."
+ (when symbol-overlay-mode
+ (let* ((case-fold-search nil)
+ (symbol (symbol-overlay-get-symbol t))
+ p)
+ (when (and symbol
+ (not (symbol-overlay-assoc symbol))
+ (not (symbol-overlay-ignored-p symbol)))
+ (symbol-overlay-remove-temp)
+ (save-excursion
+ (save-restriction
+ (symbol-overlay-narrow symbol-overlay-scope
+ symbol-overlay-displayed-window)
+ (goto-char (point-min))
+ (let ((re (symbol-overlay-regexp symbol)))
+ (re-search-forward re nil t)
+ (save-match-data
+ (while (re-search-forward re nil t)
+ (symbol-overlay-put-one symbol)
+ (or p (setq p t))))
+ (when p
+ (symbol-overlay-put-one symbol)
+ (setq symbol-overlay-temp-symbol symbol)))))))))
+
+(defun symbol-overlay-ignored-p (symbol)
+ "Determine whether SYMBOL should be temporarily highlighted."
+ (let ((f (cdr (assoc major-mode symbol-overlay-ignore-functions))))
+ (when f
+ (funcall f symbol))))
+
+(defvar symbol-overlay-timer nil
+ "Timer for temporary highlighting.")
+
+(defun symbol-overlay-cancel-timer ()
+ "Cancel `symbol-overlay-timer' if it is running."
+ (when symbol-overlay-timer
+ (cancel-timer symbol-overlay-timer)))
+
+(defun symbol-overlay-idle-timer ()
+ "Idle timer callback.
+This is used to maybe highlight the symbol at point in whichever
+buffer happens to be current when the timer is fired."
+ (symbol-overlay-maybe-put-temp))
+
+(defun symbol-overlay-update-timer (value)
+ "Update `symbol-overlay-timer' with new idle-time VALUE."
+ (symbol-overlay-cancel-timer)
+ (setq symbol-overlay-timer
+ (and value (> value 0)
+ (run-with-idle-timer value t #'symbol-overlay-idle-timer))))
+
+(defun symbol-overlay-post-command ()
+ "Installed on `post-command-hook'."
+ (unless (or (null symbol-overlay-temp-symbol)
+ (string= (symbol-overlay-get-symbol t) symbol-overlay-temp-symbol))
+ (symbol-overlay-remove-temp)))
+
+(defun symbol-overlay-put-one (symbol &optional face)
+ "Put overlay on current occurrence of SYMBOL after a match.
+If FACE is non-nil, use it as the overlay’s face.
+Otherwise apply `symbol-overlay-default-face'."
+ (let ((ov (make-overlay (match-beginning 0) (match-end 0))))
+ (if face (progn (overlay-put ov 'face face)
+ (unless symbol-overlay-inhibit-map
+ (overlay-put ov 'keymap symbol-overlay-map))
+ (overlay-put ov 'evaporate t)
+ (overlay-put ov 'symbol symbol))
+ (overlay-put ov 'face 'symbol-overlay-default-face)
+ (overlay-put ov 'symbol ""))
+ (dolist (fun symbol-overlay-overlay-created-functions)
+ (funcall fun ov))))
+
+(defun symbol-overlay-put-all (symbol scope &optional keyword)
+ "Put overlays on all occurrences of SYMBOL in the buffer.
+The face is picked from `symbol-overlay-faces'.
+If SCOPE is non-nil, put overlays only on occurrences in scope.
+If KEYWORD is non-nil, remove it then use its color on new overlays."
+ (when symbol-overlay-temp-symbol
+ (symbol-overlay-remove-temp))
+ (let* ((case-fold-search nil)
+ (face (or (symbol-overlay-maybe-remove keyword)
+ (car (cl-set-difference
+ symbol-overlay-faces
+ (mapcar #'cddr symbol-overlay-keywords-alist)))
+ ;; If we have exhausted the available faces, then just
+ ;; keep using the last face for all subsequent symbols.
+ (car (last symbol-overlay-faces)))))
+ (save-excursion
+ (save-restriction
+ (symbol-overlay-narrow scope)
+ (goto-char (point-min))
+ (let ((re (symbol-overlay-regexp symbol)))
+ (while (re-search-forward re nil t)
+ (symbol-overlay-put-one symbol face)))))
+ (setq keyword `(,symbol ,scope . ,face))
+ (push keyword symbol-overlay-keywords-alist)
+ keyword))
+
+(defun symbol-overlay-maybe-count (keyword &optional show-color)
+ "Show the number of KEYWORD's occurrences.
+If SHOW-COLOR is non-nil, display the color used by current overlay."
+ (when keyword
+ (let* ((symbol (car keyword))
+ (before (symbol-overlay-get-list -1 symbol))
+ (after (symbol-overlay-get-list 1 symbol))
+ (count (length before))
+ ;; Log to echo area but not *Messages*
+ message-log-max)
+ (message (concat "%s: %d/%d"
+ (and (cadr keyword) " in scope")
+ (and show-color (format " (%s)" (cddr keyword))))
+ symbol
+ (+ count 1)
+ (+ count (length after))))))
+
+(defun symbol-overlay-match-keyword-list (symbol keywords)
+ "Return non-nil is SYMBOL is among KEYWORDS.
+KEYWORDS is a list of strings. SYMBOL is expected to be a return
+value of `symbol-overlay-get-symbol'."
+ (cl-find symbol keywords :test #'string=))
+
+(defun symbol-overlay-refresh (beg end _len)
+ "Refresh overlays. Installed on `after-change-functions'.
+BEG, END and LEN are the beginning, end and length of changed text."
+ (unless (or (minibufferp)
+ (not (or symbol-overlay-keywords-alist
+ symbol-overlay-temp-symbol)))
+ (let ((case-fold-search nil)
+ (re "\\(\\sw\\|\\s_\\)+"))
+ (save-excursion
+ (save-match-data
+ (goto-char end)
+ (and (looking-at-p re)
+ (setq end (re-search-forward "\\_>")))
+ (goto-char beg)
+ (and (not (looking-at-p "\\_<"))
+ (looking-at-p (concat "\\(" re "\\|\\_>\\)"))
+ (setq beg (re-search-backward "\\_<")))
+ (mapc (lambda (ov)
+ (and (overlay-get ov 'symbol)
+ (delete-overlay ov)))
+ (overlays-in beg end))
+ (mapc (lambda (keyword)
+ (let* ((symbol (car keyword))
+ (re (symbol-overlay-regexp symbol)))
+ (goto-char beg)
+ (while (re-search-forward re end t)
+ (symbol-overlay-put-one symbol (cddr keyword)))))
+ symbol-overlay-keywords-alist))))))
+
+(add-hook 'after-change-functions #'symbol-overlay-refresh)
+
+(defun symbol-overlay-after-revert ()
+ "Restore overlays after the buffer was reverted."
+ (save-restriction
+ (widen)
+ (symbol-overlay-refresh (point-min) (point-max) nil)))
+
+(add-hook 'after-revert-hook #'symbol-overlay-after-revert)
+
+;;; Language-Specific Ignore
+
+(defvar c-font-lock-extra-types)
+(defun symbol-overlay-ignore-function-c (symbol)
+ "Determine whether SYMBOL should be ignored (C Language)."
+ (symbol-overlay-match-keyword-list
+ symbol
+ (append c-font-lock-extra-types
+ '("auto" "break" "case" "char" "const" "continue"
+ "default" "do" "double" "else" "enum" "extern"
+ "float" "for" "goto" "if" "inline" "int" "long"
+ "register" "restrict" "return" "short" "signed"
+ "sizeof" "static" "struct" "switch" "typedef"
+ "union" "unsigned" "void" "volatile" "while"))))
+
+(defvar c++-font-lock-extra-types)
+(defun symbol-overlay-ignore-function-c++ (symbol)
+ "Determine whether SYMBOL should be ignored (C++)."
+ (symbol-overlay-match-keyword-list
+ symbol
+ (append c++-font-lock-extra-types
+ '("alignas" "alignof" "asm" "auto" "bool" "break"
+ "case" "catch" "char" "char16_t" "char32_t" "class"
+ "const" "const_cast" "constexpr" "continue"
+ "decltype" "default" "delete" "do" "double"
+ "dynamic_cast" "else" "enum" "explicit" "export"
+ "extern" "false" "final" "float" "for" "friend"
+ "goto" "if" "inline" "int" "long" "mutable"
+ "namespace" "new" "noexcept" "nullptr" "operator"
+ "override" "private" "protected" "public" "register"
+ "reinterpret_cast" "return" "short" "signed"
+ "sizeof" "static" "static_assert" "static_cast"
+ "struct" "switch" "template" "this" "thread_local"
+ "throw" "true" "try" "typedef" "typeid" "typename"
+ "union" "unsigned" "using" "virtual" "void"
+ "volatile" "wchar_t" "while"))))
+
+(defvar python-font-lock-keywords)
+(defun symbol-overlay-ignore-function-python (symbol)
+ "Determine whether SYMBOL should be ignored (Python)."
+ (let* ((keyword-symbol (car python-font-lock-keywords))
+ (keyword (if (stringp keyword-symbol)
+ keyword-symbol
+ (symbol-name keyword-symbol))))
+ (string-match-p keyword symbol)))
+
+(defvar go-builtins)
+(defvar go-constants)
+(defvar go-mode-keywords)
+(defun symbol-overlay-ignore-function-go (symbol)
+ "Determine whether SYMBOL should be ignored (Go)."
+ ;; Remove \_< and \_> so we can string compare with keywords
+ (or (symbol-overlay-match-keyword-list symbol go-builtins)
+ (symbol-overlay-match-keyword-list symbol go-constants)
+ (symbol-overlay-match-keyword-list symbol go-mode-keywords)))
+
+;; From https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
+(defun symbol-overlay-ignore-function-java (symbol)
+ "Determine whether SYMBOL should be ignored (Java)."
+ (symbol-overlay-match-keyword-list
+ symbol
+ '("abstract" "continue" "for" "new" "switch"
+ "assert" "default" "goto" "package" "synchronized"
+ "boolean" "do" "if" "private" "this"
+ "break" "double" "implements" "protected" "throw"
+ "byte" "else" "import" "public" "throws"
+ "case" "enum" "instanceof" "return" "transient"
+ "catch" "extends" "int" "short" "try"
+ "char" "final" "interface" "static" "void"
+ "class" "finally" "long" "strictfp" "volatile"
+ "const*" "float" "native" "super" "while")))
+
+;;; Commands
+
+;;;###autoload
+(defun symbol-overlay-put ()
+ "Toggle all overlays of symbol at point."
+ (interactive)
+ (unless (minibufferp)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol)))
+ (symbol-overlay-adjust-position)
+ (if keyword
+ (if (symbol-overlay-maybe-reput symbol keyword)
+ (symbol-overlay-maybe-count keyword)
+ (symbol-overlay-maybe-remove keyword)
+ (symbol-overlay-maybe-put-temp))
+ (symbol-overlay-maybe-count
+ (symbol-overlay-put-all symbol symbol-overlay-scope)
+ t)))))
+
+(defun symbol-overlay-adjust-position ()
+ "Backward one char if at the end of the symbol."
+ (when (looking-at-p "\\_>") (backward-char)))
+
+;;;###autoload
+(defun symbol-overlay-count ()
+ "Show count of symbol at point."
+ (interactive)
+ (unless (minibufferp)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol)))
+ (symbol-overlay-adjust-position)
+ (symbol-overlay-maybe-count keyword))))
+
+;;;###autoload
+(defun symbol-overlay-remove-all ()
+ "Remove all highlighted symbols in the buffer.
+When called interactively, then also reset
+`symbol-overlay-keywords-alist'."
+ (interactive)
+ (unless (minibufferp)
+ (mapc 'delete-overlay (symbol-overlay-get-list 0))
+ (when (called-interactively-p 'any)
+ (setq symbol-overlay-keywords-alist nil))))
+
+(add-hook 'before-revert-hook #'symbol-overlay-remove-all)
+
+;;;###autoload
+(defun symbol-overlay-save-symbol ()
+ "Copy symbol at point."
+ (interactive)
+ (unless (minibufferp)
+ (let ((bounds (bounds-of-thing-at-point 'symbol)))
+ (kill-ring-save (car bounds) (cdr bounds))
+ (message "Current symbol saved"))))
+
+;;;###autoload
+(defun symbol-overlay-toggle-in-scope ()
+ "Toggle overlays to be showed in buffer or only in scope."
+ (interactive)
+ (unless (minibufferp)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol)))
+ (if keyword
+ (let ((scope (not (cadr keyword))))
+ (symbol-overlay-maybe-count
+ (symbol-overlay-put-all symbol scope keyword))
+ (setq symbol-overlay-scope scope))
+ (setq symbol-overlay-scope (not symbol-overlay-scope))))))
+
+(defun symbol-overlay-maybe-reput (symbol keyword)
+ "Put overlays on SYMBOL that is not highlighted in scope.
+KEYWORD provides the scope information."
+ (when (and (cadr keyword)
+ (not (seq-find #'(lambda (ov)
+ (string= (overlay-get ov 'symbol) symbol))
+ (overlays-at
+ (car (bounds-of-thing-at-point 'symbol))))))
+ (symbol-overlay-put-all symbol t keyword)))
+
+;;;###autoload
+(defun symbol-overlay-echo-mark ()
+ "Jump back to the mark."
+ (interactive)
+ (let* ((pt (mark))
+ (symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol)))
+ (and pt (goto-char pt))
+ (symbol-overlay-maybe-reput symbol keyword)))
+
+(defun symbol-overlay-jump-call (jump-function dir)
+ "A general jumping process during which JUMP-FUNCTION is called to jump.
+DIR must be non-zero."
+ (unless (minibufferp)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol)))
+ (push-mark nil t)
+ (funcall jump-function symbol dir)
+ (when keyword
+ (symbol-overlay-maybe-reput symbol keyword)
+ (symbol-overlay-maybe-count keyword)))))
+
+(defun symbol-overlay-basic-jump (symbol dir)
+ "Jump to SYMBOL's next location in the direction DIR.
+DIR must be non-zero."
+ (let* ((case-fold-search nil)
+ (bounds (bounds-of-thing-at-point 'symbol))
+ (offset (- (point) (if (> dir 0) (cdr bounds) (car bounds))))
+ target
+ (re (symbol-overlay-regexp symbol)))
+ (goto-char (- (point) offset))
+ (setq target (re-search-forward re nil t dir))
+ (unless target
+ (goto-char (if (> dir 0) (point-min) (point-max)))
+ (setq target (re-search-forward re nil nil dir)))
+ (goto-char (+ target offset))))
+
+;;;###autoload
+(defun symbol-overlay-jump-next ()
+ "Jump to the next location of symbol at point."
+ (interactive)
+ (symbol-overlay-adjust-position)
+ (symbol-overlay-jump-call #'symbol-overlay-basic-jump 1))
+
+;;;###autoload
+(defun symbol-overlay-jump-prev ()
+ "Jump to the previous location of symbol at point."
+ (interactive)
+ (symbol-overlay-adjust-position)
+ (symbol-overlay-jump-call #'symbol-overlay-basic-jump -1))
+
+;;;###autoload
+(defun symbol-overlay-jump-first ()
+ "Jump to the first location."
+ (interactive)
+ (symbol-overlay-adjust-position)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (before (symbol-overlay-get-list -1 symbol))
+ (count (length before)))
+ (symbol-overlay-jump-call #'symbol-overlay-basic-jump (- count))))
+
+;;;###autoload
+(defun symbol-overlay-jump-last ()
+ "Jump to the last location."
+ (interactive)
+ (symbol-overlay-adjust-position)
+ (let* ((symbol (symbol-overlay-get-symbol))
+ (after (symbol-overlay-get-list 1 symbol))
+ (count (length after)))
+ (symbol-overlay-jump-call #'symbol-overlay-basic-jump (- count 1))))
+
+(defvar-local symbol-overlay-definition-function
+ '(lambda (symbol) (concat "(?def[a-z-]* " (symbol-overlay-regexp symbol)))
+ "An one-argument function that returns a regexp.")
+
+;;;###autoload
+(defun symbol-overlay-jump-to-definition ()
+ "Jump to the definition of symbol at point.
+The definition syntax should be defined in a function stored in
+`symbol-overlay-definition-function' that returns the definition's regexp
+with the input symbol."
+ (interactive)
+ (symbol-overlay-jump-call
+ '(lambda (symbol dir)
+ (let ((pt (point)) p)
+ (symbol-overlay-basic-jump symbol dir)
+ (while (not (or p (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward " \t")
+ (looking-at-p
+ (funcall symbol-overlay-definition-function
+ symbol)))))
+ (symbol-overlay-basic-jump symbol dir)
+ (and (= pt (point)) (setq p t)))))
+ 1))
+
+(defun symbol-overlay-switch-symbol (dir)
+ "Switch to the closest symbol highlighted nearby, in the direction DIR.
+DIR must be 1 or -1."
+ (unless (minibufferp)
+ (let* ((symbol (symbol-overlay-get-symbol t))
+ (list (symbol-overlay-get-list dir symbol t)))
+ (or list
+ (user-error (concat "No more "
+ (if (> dir 0) "forward" "backward")
+ " symbols")))
+ (push-mark nil t)
+ (goto-char (overlay-start (car list)))
+ (symbol-overlay-maybe-count
+ (symbol-overlay-assoc (symbol-overlay-get-symbol))))))
+
+;;;###autoload
+(defun symbol-overlay-switch-forward ()
+ "Switch forward to another symbol."
+ (interactive)
+ (symbol-overlay-switch-symbol 1))
+
+;;;###autoload
+(defun symbol-overlay-switch-backward ()
+ "Switch backward to another symbol."
+ (interactive)
+ (symbol-overlay-switch-symbol -1))
+
+;;;###autoload
+(defun symbol-overlay-isearch-literally ()
+ "Isearch symbol at point literally."
+ (interactive)
+ (unless (minibufferp)
+ (let ((symbol (symbol-overlay-get-symbol)))
+ (beginning-of-thing 'symbol)
+ (isearch-forward nil t)
+ (isearch-yank-string symbol))))
+
+;;;###autoload
+(defun symbol-overlay-query-replace ()
+ "Query replace symbol at point."
+ (interactive)
+ (unless (minibufferp)
+ (let* ((case-fold-search nil)
+ (symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol))
+ (scope (cadr keyword))
+ defaults new)
+ (and scope (user-error "Query-replace invalid in scope"))
+ (beginning-of-thing 'symbol)
+ (push-mark nil t)
+ (setq new (read-string "Replacement: " symbol)
+ defaults (cons symbol new))
+ (unless (string= new symbol)
+ (symbol-overlay-maybe-remove (symbol-overlay-assoc new))
+ (setq keyword (symbol-overlay-put-all new scope keyword))
+ (query-replace-regexp (symbol-overlay-regexp symbol) new)
+ (setq query-replace-defaults
+ (if (< emacs-major-version 25) `,defaults `(,defaults))))
+ (when (string= new (symbol-overlay-get-symbol t))
+ (beginning-of-thing 'symbol)
+ (symbol-overlay-maybe-count keyword)))))
+
+;;;###autoload
+(defun symbol-overlay-rename ()
+ "Rename symbol at point on all its occurrences."
+ (interactive)
+ (unless (minibufferp)
+ (let* ((case-fold-search nil)
+ (symbol (symbol-overlay-get-symbol))
+ (keyword (symbol-overlay-assoc symbol))
+ (scope (if keyword (cadr keyword) symbol-overlay-scope))
+ new)
+ (beginning-of-thing 'symbol)
+ (push-mark nil t)
+ (setq new (read-string (concat "Rename" (and scope " in scope") " to: ")
+ symbol))
+ (unless (string= new symbol)
+ (symbol-overlay-maybe-remove (symbol-overlay-assoc new))
+ (save-excursion
+ (save-restriction
+ (symbol-overlay-narrow scope)
+ (goto-char (point-min))
+ (let ((inhibit-modification-hooks t)
+ (re (symbol-overlay-regexp symbol)))
+ (while (re-search-forward re nil t) (replace-match new t)))))
+ (when keyword
+ (setq keyword (symbol-overlay-put-all new scope keyword))))
+ (when (string= new (symbol-overlay-get-symbol t))
+ (symbol-overlay-maybe-count keyword)))))
+
+;;; _
+(provide 'symbol-overlay)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; symbol-overlay.el ends here