From: Andreas Gerler Date: Thu, 11 May 2023 16:24:56 +0000 (+0200) Subject: add symbol-overlay X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=17230ce68ea12714f9910a2663394bc97e5213b1;p=emacsconfig.git add symbol-overlay Signed-off-by: Andreas Gerler --- diff --git a/elpa/symbol-overlay-20230503.1051/symbol-overlay-autoloads.el b/elpa/symbol-overlay-20230503.1051/symbol-overlay-autoloads.el new file mode 100644 index 00000000..a332d98d --- /dev/null +++ b/elpa/symbol-overlay-20230503.1051/symbol-overlay-autoloads.el @@ -0,0 +1,95 @@ +;;; 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)))) + + +;;;### (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-")) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; symbol-overlay-autoloads.el ends here diff --git a/elpa/symbol-overlay-20230503.1051/symbol-overlay-pkg.el b/elpa/symbol-overlay-20230503.1051/symbol-overlay-pkg.el new file mode 100644 index 00000000..6701eef6 --- /dev/null +++ b/elpa/symbol-overlay-20230503.1051/symbol-overlay-pkg.el @@ -0,0 +1,2 @@ +;;; 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" . "wolray@foxmail.com")) :maintainers '(("wolray" . "wolray@foxmail.com")) :maintainer '("wolray" . "wolray@foxmail.com") :keywords '("faces" "matching") :url "https://github.com/wolray/symbol-overlay/") diff --git a/elpa/symbol-overlay-20230503.1051/symbol-overlay.el b/elpa/symbol-overlay-20230503.1051/symbol-overlay.el new file mode 100644 index 00000000..dc360a7a --- /dev/null +++ b/elpa/symbol-overlay-20230503.1051/symbol-overlay.el @@ -0,0 +1,814 @@ +;;; symbol-overlay.el --- Highlight symbols with keymap-enabled overlays -*- lexical-binding: t -*- + +;; Copyright (C) 2017 wolray + +;; Author: wolray +;; 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 . + +;;; 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 "") 'symbol-overlay-mode) +;; (global-set-key (kbd "") '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