[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 5330a45 3/4: Add xref-match-item, and use it
From: |
Dmitry Gutov |
Subject: |
[Emacs-diffs] master 5330a45 3/4: Add xref-match-item, and use it |
Date: |
Mon, 20 Jul 2015 01:53:43 +0000 |
branch: master
commit 5330a45ebff0214cc5c5d123e7cc68f00f68ff39
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>
Add xref-match-item, and use it
* lisp/progmodes/xref.el (xref-match-bounds): New generic function.
(xref-file-location): Add reader for the column slot.
(xref-match-item): New class.
(xref-match-bounds): A method implementation for it.
(xref-make-match): New constructor function.
(xref--current-item): New private variable.
(xref-pulse-momentarily): Use it.
(xref--pop-to-location): Change the first argument to an xref
item, instead of location, bind xref--current-item.
Update all callers.
(xref-next-line, xref-prev-line, xref--next-error-function)
(xref--mouse-2): Look for the property `xref-item',
instead of `xref-location'.
(xref--item-at-point): Likewise. This function replaces
`xref-location-at-point'. Update all callers.
(xref--insert-xrefs): Add the `xref-item' text property, instead
of `xref-location'.
(xref--collect-match): Use xref-make-match.
---
lisp/progmodes/xref.el | 107 ++++++++++++++++++++++++++++++++---------------
1 files changed, 73 insertions(+), 34 deletions(-)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index a17550f..0847fda 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -78,6 +78,10 @@ This is typically the filename.")
"Return the line number corresponding to the location."
nil)
+(cl-defgeneric xref-match-bounds (_item)
+ "Return a cons with columns of the beginning and end of the match."
+ nil)
+
;;;; Commonly needed location classes are defined here:
;; FIXME: might be useful to have an optional "hint" i.e. a string to
@@ -85,7 +89,7 @@ This is typically the filename.")
(defclass xref-file-location (xref-location)
((file :type string :initarg :file)
(line :type fixnum :initarg :line :reader xref-location-line)
- (column :type fixnum :initarg :column))
+ (column :type fixnum :initarg :column :reader xref-file-location-column))
:documentation "A file location is a file/line/column triple.
Line numbers start from 1 and columns from 0.")
@@ -165,6 +169,29 @@ SUMMARY is a short string to describe the xref.
LOCATION is an `xref-location'."
(make-instance 'xref-item :summary summary :location location))
+(defclass xref-match-item ()
+ ((summary :type string :initarg :summary
+ :reader xref-item-summary)
+ (location :initarg :location
+ :type xref-file-location
+ :reader xref-item-location)
+ (end-column :initarg :end-column))
+ :comment "An xref item describes a reference to a location
+somewhere.")
+
+(cl-defmethod xref-match-bounds ((i xref-match-item))
+ (with-slots (end-column location) i
+ (cons (xref-file-location-column location)
+ end-column)))
+
+(defun xref-make-match (summary end-column location)
+ "Create and return a new xref match item.
+SUMMARY is a short string to describe the xref.
+END-COLUMN is the match end column number inside SUMMARY.
+LOCATION is an `xref-location'."
+ (make-instance 'xref-match-item :summary summary :location location
+ :end-column end-column))
+
;;; API
@@ -309,15 +336,22 @@ elements is negated."
(set-marker marker nil nil)
(run-hooks 'xref-after-return-hook))))
+(defvar xref--current-item nil)
+
(defun xref-pulse-momentarily ()
- (let (beg end)
- (save-excursion
- (back-to-indentation)
- (if (eolp)
- (setq beg (line-beginning-position)
- end (1+ (point)))
- (setq beg (point)
- end (line-end-position))))
+ (pcase-let ((`(,beg . ,end)
+ (save-excursion
+ (or
+ (let ((bounds (xref-match-bounds xref--current-item)))
+ (when bounds
+ (cons (progn (move-to-column (car bounds))
+ (point))
+ (progn (move-to-column (cdr bounds))
+ (point)))))
+ (back-to-indentation)
+ (if (eolp)
+ (cons (line-beginning-position) (1+ (point)))
+ (cons (point) (line-end-position)))))))
(pulse-momentary-highlight-region beg end 'next-error)))
;; etags.el needs this
@@ -343,18 +377,19 @@ elements is negated."
(t (error "Location is outside accessible part of buffer")))
(goto-char marker)))
-(defun xref--pop-to-location (location &optional window)
- "Goto xref-location LOCATION and display the buffer.
+(defun xref--pop-to-location (item &optional window)
+ "Go to the location of ITEM and display the buffer.
WINDOW controls how the buffer is displayed:
nil -- switch-to-buffer
'window -- pop-to-buffer (other window)
'frame -- pop-to-buffer (other frame)"
- (xref--goto-location location)
+ (xref--goto-location (xref-item-location item))
(cl-ecase window
((nil) (switch-to-buffer (current-buffer)))
(window (pop-to-buffer (current-buffer) t))
(frame (let ((pop-up-frames t)) (pop-to-buffer (current-buffer) t))))
- (run-hooks 'xref-after-jump-hook))
+ (let ((xref--current-item item))
+ (run-hooks 'xref-after-jump-hook)))
;;; XREF buffer (part of the UI)
@@ -414,26 +449,27 @@ Used for temporary buffers.")
(defun xref-show-location-at-point ()
"Display the source of xref at point in the other window, if any."
(interactive)
- (let ((loc (xref--location-at-point)))
- (when loc
- (xref--show-location loc))))
+ (let* ((xref (xref--item-at-point))
+ (xref--current-item xref))
+ (when xref
+ (xref--show-location (xref-item-location xref)))))
(defun xref-next-line ()
"Move to the next xref and display its source in the other window."
(interactive)
- (xref--search-property 'xref-location)
+ (xref--search-property 'xref-item)
(xref-show-location-at-point))
(defun xref-prev-line ()
"Move to the previous xref and display its source in the other window."
(interactive)
- (xref--search-property 'xref-location t)
+ (xref--search-property 'xref-item t)
(xref-show-location-at-point))
-(defun xref--location-at-point ()
+(defun xref--item-at-point ()
(save-excursion
(back-to-indentation)
- (get-text-property (point) 'xref-location)))
+ (get-text-property (point) 'xref-item)))
(defvar-local xref--window nil
"ACTION argument to call `display-buffer' with.")
@@ -441,11 +477,11 @@ Used for temporary buffers.")
(defun xref-goto-xref ()
"Jump to the xref on the current line and bury the xref buffer."
(interactive)
- (let ((loc (or (xref--location-at-point)
+ (let ((xref (or (xref--item-at-point)
(user-error "No reference at point")))
(window xref--window))
(xref-quit)
- (xref--pop-to-location loc window)))
+ (xref--pop-to-location xref window)))
(defvar xref--xref-buffer-mode-map
(let ((map (make-sparse-keymap)))
@@ -470,11 +506,11 @@ Used for temporary buffers.")
(goto-char (point-min)))
(let ((backward (< n 0))
(n (abs n))
- (loc nil))
+ (xref nil))
(dotimes (_ n)
- (setq loc (xref--search-property 'xref-location backward)))
- (cond (loc
- (xref--pop-to-location loc))
+ (setq (xref--search-property 'xref-item backward)))
+ (cond (xref
+ (xref--pop-to-location xref))
(t
(error "No %s xref" (if backward "previous" "next"))))))
@@ -518,7 +554,7 @@ meantime are preserved."
(interactive "e")
(mouse-set-point event)
(forward-line 0)
- (xref--search-property 'xref-location)
+ (xref--search-property 'xref-item)
(xref-show-location-at-point))
(defun xref--insert-xrefs (xref-alist)
@@ -546,7 +582,7 @@ GROUP is a string for decoration purposes and XREF is an
'face 'compilation-line-number)
" ")))
(xref--insert-propertized
- (list 'xref-location location
+ (list 'xref-item xref
;; 'face 'font-lock-keyword-face
'mouse-face 'highlight
'keymap xref--button-map
@@ -603,7 +639,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(user-error "No %s found for: %s" (symbol-name kind) input))
((not (cdr xrefs))
(xref-push-marker-stack)
- (xref--pop-to-location (xref-item-location (car xrefs)) window))
+ (xref--pop-to-location (car xrefs) window))
(t
(xref-push-marker-stack)
(funcall xref-show-xrefs-function xrefs
@@ -866,11 +902,14 @@ IGNORES is a list of glob patterns."
(syntax-propertize (line-end-position))
(when (re-search-forward regexp (line-end-position) t)
(goto-char (match-beginning 0))
- (xref-make (buffer-substring
- (line-beginning-position)
- (line-end-position))
- (xref-make-file-location file line
- (current-column))))))))
+ (let ((loc (xref-make-file-location file line
+ (current-column))))
+ (goto-char (match-end 0))
+ (xref-make-match (buffer-substring
+ (line-beginning-position)
+ (line-end-position))
+ (current-column)
+ loc)))))))
(provide 'xref)