Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit; currently fairly hackish, but functional for browsing…

… with optional context for etags only. Still to come of course, support for gtags, and manipulation of the tags structure. Also, autodetection of which we should be using.
  • Loading branch information...
commit 9cf92b46478f220636c893ecdb0ee3cc65c1198f 0 parents
Mark Hepburn authored September 07, 2009

Showing 1 changed file with 186 additions and 0 deletions. Show diff stats Hide diff stats

  1. 186  tags-view.el
186  tags-view.el
... ...
@@ -0,0 +1,186 @@
  1
+;;; tags-view.el --- Display and navigate tags browsing history.
  2
+
  3
+;; Copyright (C) 2009  Mark Hepburn
  4
+
  5
+;; Author: Mark Hepburn <Mark.Hepburn@gmail.com>
  6
+;; Keywords: extensions, tools, convenience, files
  7
+
  8
+;; This program is free software; you can redistribute it and/or modify
  9
+;; it under the terms of the GNU General Public License as published by
  10
+;; the Free Software Foundation, either version 3 of the License, or
  11
+;; (at your option) any later version.
  12
+
  13
+;; This program is distributed in the hope that it will be useful,
  14
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16
+;; GNU General Public License for more details.
  17
+
  18
+;; You should have received a copy of the GNU General Public License
  19
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20
+
  21
+;;; Commentary:
  22
+
  23
+;;; Functionality to supplement the different tags operations, usually
  24
+;;; bound to M-./M-* Currently supports etags.el and gtags.el; any
  25
+;;; others?
  26
+
  27
+;;; As you navigate through a source tree it can become easy to forget
  28
+;;; how you got to your current location -- you could call M-*
  29
+;;; repeatedly to pop back up the stack, but this would lose your
  30
+;;; current location.  This module allows you to view the path taken,
  31
+;;; and if desired to jump immediately back to any intermediate
  32
+;;; location.
  33
+
  34
+;;; I don't think this exists, but I haven't looked too hard -- I'd
  35
+;;; like the practice of writing something to completion for emacs for
  36
+;;; once!
  37
+
  38
+;;; Code:
  39
+
  40
+;;; etags.el.  Locations are in global variable `tags-location-ring',
  41
+;;; a ring data structure.
  42
+
  43
+(require 'cl)
  44
+
  45
+(defvar tv-separator-string "----"
  46
+  "Text used to separate entries in the browser window.  May be nil.")
  47
+
  48
+(defvar tv-context-lines 0
  49
+  "The number of preceding and following lines to include around
  50
+  each location displayed.")
  51
+
  52
+(defface tv-header-face
  53
+  '((t (:foreground "gray" :weight 'light)))
  54
+  "Face used to display the header of each tag entry.")
  55
+
  56
+(defun tv-view-history ()
  57
+  (interactive)
  58
+  (let ((buf (get-buffer-create "*tags history*")))
  59
+    (pop-to-buffer buf)
  60
+    (setq buffer-read-only nil)
  61
+    (let ((inhibit-read-only t))
  62
+      (erase-buffer))
  63
+    (tags-history-mode)
  64
+    (let ((tag-items (copy-list (ring-elements tags-location-ring))))
  65
+      (tv-insert-items tag-items))
  66
+    (setq buffer-read-only t)
  67
+    (goto-char 0)))
  68
+
  69
+(defun tv-what-line (marker)
  70
+  "Return the line number of a marker"
  71
+  (save-current-buffer
  72
+    (set-buffer (marker-buffer marker))
  73
+    (line-number-at-pos (marker-position marker))))
  74
+
  75
+(defun tv-insert-items (items)
  76
+  "Insert the formatted list of tags with context"
  77
+  (if items
  78
+      (progn
  79
+        (tv-insert-single-item (car items))
  80
+        (if (cdr items)
  81
+            (progn
  82
+              (if tv-separator-string
  83
+                  (progn
  84
+                    (insert tv-separator-string)
  85
+                    (insert "\n")))
  86
+              (tv-insert-items (cdr items)))))))
  87
+
  88
+(defun tv-insert-single-item (marker)
  89
+  "Insert a single formatted item, including overlays etc.
  90
+Argument is a marker that will be displayed, along with
  91
+`tv-context-lines' of context, if non-zero."
  92
+  (let ((beg (point)))
  93
+    (insert (propertize (format "Buffer %s, line %d:\n"
  94
+                                (buffer-name (marker-buffer marker))
  95
+                                (tv-what-line marker))
  96
+                        'face 'tv-header-face))
  97
+    (insert (tv-get-lines-with-context marker tv-context-lines))
  98
+    (insert "\n")
  99
+    (let* ((o (make-overlay beg (point))))
  100
+      (overlay-put o 'mouse-face 'highlight))))
  101
+
  102
+(defun tv-get-lines-with-context (marker &optional num-context)
  103
+  "Grabs the line at the specified marker; if optional
  104
+  num-context is specified, it will also grab that number of
  105
+  preceding and following lines, assuming sufficient lines exist.
  106
+  For example, if 2 context lines are specified, a total of 5
  107
+  lines wil lbe returned: 2 preceding, the line the marker is
  108
+  located on, and 2 following lines.  If not enough context lines
  109
+  exist in either direction, as many as possible will be used."
  110
+  (unless num-context (setq num-context 0))
  111
+  (if (< num-context 0) (setq (num-context (- num-context))))
  112
+  (save-current-buffer
  113
+    (set-buffer (marker-buffer marker))
  114
+    (let (start end)
  115
+      (goto-char (marker-position marker))
  116
+      (forward-line (- num-context))
  117
+      (setq start (point))
  118
+      (goto-char (marker-position marker))
  119
+      (forward-line num-context)
  120
+      (end-of-line)
  121
+      (setq end (point))
  122
+      (buffer-substring start end))))
  123
+
  124
+;;; to implement; different methods of operating on the current selection:
  125
+(defun tv-display-tag-other-window ())
  126
+(defun tv-jump-to-tag-and-quit ())
  127
+(defun tv-clear-tag-at-point ())
  128
+
  129
+;;; Navigation:
  130
+(defun tv-next-tag (&optional arg)
  131
+  "Move point forward to the next tag.  Optional numeric argument
  132
+  moves forward that many tags."
  133
+  (interactive "p")
  134
+  (beginning-of-line)
  135
+  (while (not (zerop arg))
  136
+    (if (> arg 0)
  137
+        (progn
  138
+          (decf arg)
  139
+          (if (overlays-at (point))
  140
+              (progn
  141
+                (goto-char (overlay-end (car (overlays-at (point)))))
  142
+                (goto-char (next-overlay-change (point))))
  143
+            (goto-char (next-overlay-change (point)))
  144
+            (unless (eobp)
  145
+              (goto-char (overlay-start (car (overlays-at (point))))))))
  146
+      (progn
  147
+        (incf arg)
  148
+        (if (overlays-at (point))
  149
+            (progn
  150
+              (goto-char (overlay-start (car (overlays-at (point)))))
  151
+              (goto-char (previous-overlay-change (point)))
  152
+              (goto-char (previous-overlay-change (point))))
  153
+          (progn
  154
+            (goto-char (previous-overlay-change (point)))
  155
+            (unless (bobp)
  156
+              (goto-char (overlay-start (car (overlays-at (point))))))))))))
  157
+
  158
+(defun tv-previous-tag (&optional arg)
  159
+  "Move point backwards to the previous tag.  Optional numeric
  160
+  argument moves backwards that many tags."
  161
+  (interactive "p")
  162
+  (tv-next-tag (- arg)))
  163
+
  164
+;;; major mode for displaying the history:
  165
+(define-derived-mode tags-history-mode
  166
+  nil "Tags-History"
  167
+  "View history of tags locations, with the most recent on the top.
  168
+
  169
+\\{tags-history-mode-map}"
  170
+  (let ((km tags-history-mode-map))
  171
+    ;; first, clear all other bindings:
  172
+    (suppress-keymap km)
  173
+
  174
+    ;; navigation:
  175
+    (define-key km "n"    'tv-next-tag)
  176
+    (define-key km "\C-n" 'tv-next-tag)
  177
+    (define-key km "j"    'tv-next-tag)
  178
+    
  179
+    (define-key km "p"    'tv-previous-tag)
  180
+    (define-key km "\C-p" 'tv-previous-tag)
  181
+    (define-key km "k"    'tv-previous-tag)
  182
+
  183
+    ;; cleanup:
  184
+    (define-key km "q"    'delete-window)))
  185
+
  186
+(provide 'tags-view)

0 notes on commit 9cf92b4

Please sign in to comment.
Something went wrong with that request. Please try again.