Codebase list emacs-tablist / b344cd6
New upstream version 1.0 RĂ©mi Vanicat 4 years ago
6 changed file(s) with 169 addition(s) and 103 deletion(s). Raw diff Collapse all Expand all
0 *-autoloads.el
1 *-pkg.el
02 *.elc
13 .dir-locals.el
24 .cask
0 EMACS ?= emacs
1 # Handle the mess when inside Emacs.
2 unexport INSIDE_EMACS #cask not like this.
3 ifeq ($(EMACS), t)
4 EMACS = emacs
5 endif
6
7 emacs = $(EMACS)
08
19 all: package
10
11 byte-compile:
12 cask exec $(emacs) --batch -L lisp -f batch-byte-compile *.el
213
314 package:
415 cask package
516 clean:
617 rm -rf dist
718 rm -f -- *.elc
8
+0
-5
README less more
0 This package adds marks and filters to tabulated-list-mode. It
1 also kind of puts a dired face on tabulated list buffers.
2
3 It can be used by deriving from tablist-mode and some features by
4 using tablist-minor-mode inside a tabulated-list-mode buffer.
0 # Tablist
1
2 This package adds marks and filters to `tabulated-list-mode`. It also
3 puts a dired face on tabulated list buffers.
4
5 It can be used by deriving from `tablist-mode`, or with more limited features
6 by enabling `tablist-minor-mode` inside a `tabulated-list-mode` buffer.
7
8 # Tablist minor mode
9
10 | command | keymap |
11 |--------------------------|--------------------|
12 | tablist-mark-forward | <kbd>m</kbd> |
13 | tablist-unmark-backward | <kbd>DEL</kbd> |
14 | tablist-do-kill-lines | <kbd>k</kbd> |
15 | tablist-unmark-all-marks | <kbd>U</kbd> |
16 | tablist-unmark-forward | <kbd>u</kbd> |
17 | tablist-toggle-marks | <kbd>t</kbd> |
18 | tablist-sort | <kbd>s</kbd> |
19 | tablist-shrink-column | <kbd><</kbd> |
20 | tablist-enlarge-column | <kbd>></kbd> |
21 | tablist-quit | <kbd>q</kbd> |
22 | tablist-revert | <kbd>G</kbd> |
23 | tablist-export-csv | <kbd>C-c C-e</kbd> |
24
25
26 ## Marks
27
28 | command | keymap |
29 |----------------------------|----------------------------------|
30 | tablist-change-marks | <kbd>* c</kbd> |
31 | tablist-unmark-all-marks | <kbd>* !</kbd> |
32 | tablist-mark-items-regexp | <kbd>* r</kbd> or <kbd>% m</kbd> |
33 | tablist-mark-items-numeric | <kbd>* n</kbd> |
34 | tablist-mark-forward | <kbd>* m</kbd> |
35
36 ## Filters
37
38 | command | keymap |
39 |-----------------------------------|----------------|
40 | tablist-pop-filter | <kbd>/ p</kbd> |
41 | tablist-push-regexp-filter | <kbd>/ r</kbd> |
42 | tablist-push-equal-filter | <kbd>/ =</kbd> |
43 | tablist-push-numeric-filter | <kbd>/ n</kbd> |
44 | tablist-negate-filter | <kbd>/ !</kbd> |
45 | tablist-toggle-first-filter-logic | <kbd>/ t</kbd> |
46 | tablist-display-filter | <kbd>/ /</kbd> |
47 | tablist-suspend-filter | <kbd>/ z</kbd> |
48 | tablist-push-named-filter | <kbd>/ a</kbd> |
49 | tablist-name-current-filter | <kbd>/ s</kbd> |
50 | tablist-delete-named-filter | <kbd>/ D</kbd> |
51 | tablist-deconstruct-named-filter | <kbd>/ d</kbd> |
52 | tablist-edit-filter | <kbd>/ e</kbd> |
53 | tablist-clear-filter | <kbd>/ C</kbd> |
54
55 # Tablist mode
56
57 Same bindings as `tablist-minor-mode`, plus the following:
58
59 | command | keymap |
60 |---------------------------|----------------|
61 | tablist-flag-forward | <kbd>d</kbd> |
62 | tablist-find-entry | <kbd>RET</kbd> |
63 | tablist-find-entry | <kbd>f</kbd> |
64 | tablist-do-delete | <kbd>D</kbd> |
65 | tablist-do-copy | <kbd>C</kbd> |
66 | tablist-do-rename | <kbd>R</kbd> |
67 | tablist-do-flagged-delete | <kbd>x</kbd> |
0 ;;; tablist-filter.el --- Filter expressions for tablists.
0 ;;; tablist-filter.el --- Filter expressions for tablists. -*- lexical-binding:t -*-
11
22 ;; Copyright (C) 2013, 2014 Andreas Politz
33
2121
2222 ;;
2323
24 (let (python-mode-hook)
24 (defvar python-mode-hook)
25 (let (python-mode-hook) ;FIXME: Why?
2526 (require 'semantic/wisent/comp)
2627 (require 'semantic/wisent/wisent))
2728
4445 (defvar tablist-filter-wisent-parser nil)
4546
4647 (defvar tablist-filter-lexer-regexps nil)
47
48
4849 (defvar tablist-filter-wisent-grammar
4950 '(
5051 ;; terminals
7071 ((not filter) `(not ,$2))
7172 ((filter and filter) `(and ,$1 ,$3))
7273 ((filter or filter) `(or ,$1 ,$3))
73 ((?( filter ?)) $2))))
74 ((?\( filter ?\)) $2))))
7475
7576 (defun tablist-filter-parser-init (&optional reinitialize interactive)
7677 (interactive (list t t))
216217 (tablist-filter-parser-init)
217218 (unparse filter noerror)))
218219
219
220220 (defun tablist-filter-eval (filter id entry &optional named-alist)
221221 (cl-labels
222222 ((feval (filter)
268268 (car item)
269269 item)))
270270
271 (defun tablist-filter-op-equal (id entry op1 op2)
271 (defun tablist-filter-op-equal (_id entry op1 op2)
272272 "COLUMN == STRING : Matches if COLUMN's entry is equal to STRING."
273273 (let ((item (tablist-filter-get-item-by-name entry op1)))
274274 (string= item op2)))
275275
276 (defun tablist-filter-op-regexp (id entry op1 op2)
276 (defun tablist-filter-op-regexp (_id entry op1 op2)
277277 "COLUMN =~ REGEXP : Matches if COLUMN's entry matches REGEXP."
278278 (let ((item (tablist-filter-get-item-by-name entry op1)))
279279 (string-match op2 item)))
298298 "COLUMN = NUMBER : Matches if COLUMN's entry as a number is equal to NUMBER."
299299 (tablist-filter-op-numeric '= id entry op1 op2))
300300
301 (defun tablist-filter-op-numeric (op id entry op1 op2)
301 (defun tablist-filter-op-numeric (op _id entry op1 op2)
302302 (let ((item (tablist-filter-get-item-by-name entry op1)))
303303 (funcall op (string-to-number item)
304304 (string-to-number op2))))
339339 (princ "\"...\" may be used to quote names and values if necessary,
340340 and \(...\) to group expressions.")
341341 (with-current-buffer standard-output
342 (help-mode)))))
343
344 ;;
342 (help-mode)))))
343
344 ;;
345345 ;; **Filter Functions
346346 ;;
347347
389389 (tablist-filter-map fn f))
390390 tail)))
391391 (_ (funcall fn filter))))
392
393392
394393 ;;
395394 ;; Reading filter
44 ;; Author: Andreas Politz <politza@fh-trier.de>
55 ;; Keywords: extensions, lisp
66 ;; Package: tablist
7 ;; Version: 0.70
7 ;; Version: 1.0
88 ;; Package-Requires: ((emacs "24.3"))
99
1010 ;; This program is free software; you can redistribute it and/or modify
2828 ;; It can be used by deriving from tablist-mode and some features by
2929 ;; using tablist-minor-mode inside a tabulated-list-mode buffer.
3030 ;;
31
32 ;;; Code:
3133
3234 (require 'cl-lib)
3335 (require 'ring)
7779 (replace-regexp-in-string
7880 "[\t ]+" "[\t ]*" (regexp-quote
7981 (or (thing-at-point 'line) ""))
80 t t))
82 t t))
8183 (,id (tabulated-list-get-id))
8284 (,col (tablist-current-column)))
8385 (progn
116118
117119 ;;
118120 ;; *Mode Maps
119 ;;
121 ;;
120122
121123 (defvar tablist-mode-filter-map
122124 (let ((kmap (make-sparse-keymap)))
197199 ;; (define-key kmap (kbd "C-o") 'tablist-display-item)
198200 kmap))
199201
200
201202 ;;
202203 ;; *Variables
203204 ;;
231232 should somehow delete these entries and update
232233 `tabulated-list-entries'.
233234
234 `find-entry'
235 `find-entry'
235236
236237 The 2nd argument is the ID of an entry. The function should
237238 somehow find/display this entry, i.e. a kind of default
290291 ;;
291292
292293 (defvar savehist-additional-variables)
293 (add-hook 'savehist-save-hook
294 (lambda nil
295 (add-to-list 'savehist-additional-variables 'tablist-named-filter)))
294 (add-hook 'savehist-save-hook
295 (lambda nil
296 (add-to-list 'savehist-additional-variables 'tablist-named-filter)))
296297
297298 ;;;###autoload
298299 (define-minor-mode tablist-minor-mode
343344 (selected (tabulated-list-get-id)))
344345 (unless (eq selected id)
345346 (setq tablist-selected-id selected)
346 (run-hook-with-args
347 (run-hook-with-args
347348 'tablist-selection-changed-functions
348349 tablist-selected-id)))))
349350
350351 (defvar tablist-context-window-update--timer nil)
351
352
352353 (defun tablist-context-window-update (&optional id)
353354 (when (and tablist-context-window-function
354355 (window-live-p tablist-context-window)
359360 (cancel-timer tablist-context-window-update--timer))
360361 (setq tablist-context-window-update--timer
361362 (run-with-idle-timer 0.1 nil
362 (lambda (fn window)
363 (when (window-live-p window)
364 (with-selected-window window
365 (set-window-dedicated-p nil nil)
366 (save-selected-window
367 (funcall fn id))
368 (when (window-live-p (selected-window))
369 (set-window-dedicated-p nil t)))))
370 tablist-context-window-function
371 tablist-context-window))))
363 (lambda (fn window)
364 (when (window-live-p window)
365 (with-selected-window window
366 (set-window-dedicated-p nil nil)
367 (save-selected-window
368 (funcall fn id))
369 (when (window-live-p (selected-window))
370 (set-window-dedicated-p nil t)))))
371 tablist-context-window-function
372 tablist-context-window))))
372373
373374 (defun tablist-display-context-window ()
374375 (interactive)
395396 (if (window-live-p tablist-context-window)
396397 (tablist-hide-context-window)
397398 (tablist-display-context-window)))
398
399
399
400400 ;;
401401 ;; *Marking
402402 ;;
414414 (if (numberp tablist-major-columns)
415415 (list tablist-major-columns)
416416 tablist-major-columns)))
417
417
418418 (defun tablist-put-mark (&optional pos)
419419 "Put a mark before the entry at POS.
420420
538538 (pcase new
539539 (?D
540540 (tablist-flag-forward 1))
541 (t
541 (_
542542 (let ((tablist-marker-char new)
543543 (tablist-marked-face
544544 (and default-mark-p
646646 (list (funcall fn))))
647647 (t
648648 (cl-labels ((search (re)
649 (let (sucess)
650 (tablist-skip-invisible-entries)
651 (while (and (setq sucess
652 (re-search-forward re nil t))
653 (invisible-p (point)))
654 (tablist-forward-entry))
655 sucess)))
649 (let (sucess)
650 (tablist-skip-invisible-entries)
651 (while (and (setq sucess
652 (re-search-forward re nil t))
653 (invisible-p (point)))
654 (tablist-forward-entry))
655 sucess)))
656656 (let ((regexp (tablist-marker-regexp))
657657 next-position results found)
658658 (save-excursion
813813 :right-align)
814814 (not (= n (1- (length columns)))))
815815 (forward-char (1- (car (cdr (elt tabulated-list-format n)))))))))
816
817
818816
819817 (defun tablist-move-to-major-column (&optional first-skip-invisible-p)
820818 "Move to the first major column."
880878 'invisible nil (point-max)))))
881879 (not (invisible-p (point))))
882880
883 ;;
881 ;;
884882 ;; *Operations
885883 ;;
886884
906904 op-str
907905 (tablist-mark-prompt arg pp-items)))))
908906
909
910907 (defun tablist-operation-available-p (op)
911908 (and (functionp tablist-operations-function)
912909 (memq op (funcall tablist-operations-function
949946 (message (format "Killed %d line%s"
950947 (length positions)
951948 (dired-plural-s (length positions))))))))
952
949
953950 (defun tablist-do-operation (arg fn operation &optional delete-p revert-p)
954951 "Operate on marked items.
955952
972969 (tablist-revert))
973970 (tablist-move-to-major-column))))
974971
975 ;;
972 ;;
976973 ;; *Editing
977 ;;
974 ;;
978975 (defvar tablist-edit-column-minor-mode-map
979976 (let ((kmap (make-sparse-keymap)))
980977 (set-keymap-parent kmap (current-global-map))
989986 (define-key kmap [remap beginning-of-buffer] 'beginning-of-line)
990987 (define-key kmap [remap mark-whole-buffer] 'tablist-edit-column-mark-field)
991988 kmap))
992
989
993990 (define-minor-mode tablist-edit-column-minor-mode
994991 "" nil nil nil
995992 (unless (or tablist-minor-mode
10041001 (t
10051002 (remove-hook 'post-command-hook 'tablist-edit-column-constrain-point t)
10061003 (read-only-mode 1))))
1007
1008
1004
10091005 (defun tablist-edit-column (&optional n)
10101006 (interactive "P")
10111007 (unless n (setq n (tablist-current-column)))
10531049 (overlay-put ov 'evaporate t)
10541050 (overlay-put ov 'tablist-edit t)
10551051 (tablist-edit-column-minor-mode 1)))
1056
1052
10571053 (defun tablist-edit-column-quit ()
10581054 (interactive)
10591055 (tablist-edit-column-commit t))
10901086 (save-excursion
10911087 (tabulated-list-print-entry id entry))
10921088 (forward-char (nth column (tablist-column-offsets))))))
1093
1089
10941090 (defun tablist-edit-column-complete ()
10951091 (interactive)
10961092 (unless (tablist-operation-available-p 'complete)
11081104 (- (point) beg))))
11091105 (unless completions
11101106 (error "No completions available"))
1111 (completion-in-region beg end completions))))
1112
1107 (completion-in-region beg end completions))))
1108
11131109 (defun tablist-column-editable (n)
11141110 (and (tablist-operation-available-p 'edit-column)
11151111 (not (tablist-column-property n :read-only))))
11541150 (setq end pos
11551151 beg (previous-single-property-change
11561152 pos 'tablist-edit))))
1157
1153
11581154 (unless (and beg end (get-text-property beg 'tablist-edit))
11591155 (error "Unable to locate edited text"))
11601156 (cons beg (if skip-final-space (1- end) end))))
1161
1157
11621158 (defun tablist-edit-column-mark-field ()
11631159 (interactive)
11641160 (push-mark (field-beginning))
13331329 (unless (buffer-live-p outb)
13341330 (error "Expected a live buffer: %s" outb))
13351331 (cl-labels
1336 ((printit (entry)
1337 (insert
1338 (mapconcat
1339 (lambda (e)
1340 (unless (stringp e)
1341 (setq e (car e)))
1342 (if (or always-quote-p
1343 (string-match escape-re e))
1344 (concat "\""
1345 (replace-regexp-in-string "\"" "\"\"" e t t)
1346 "\"")
1347 e))
1348 entry separator))
1349 (insert ?\n)))
1332 ((printit (entry)
1333 (insert
1334 (mapconcat
1335 (lambda (e)
1336 (unless (stringp e)
1337 (setq e (car e)))
1338 (if (or always-quote-p
1339 (string-match escape-re e))
1340 (concat "\""
1341 (replace-regexp-in-string "\"" "\"\"" e t t)
1342 "\"")
1343 e))
1344 entry separator))
1345 (insert ?\n)))
13501346 (with-current-buffer outb
13511347 (let ((inhibit-read-only t))
13521348 (erase-buffer)
13941390 (tablist-save-marks
13951391 (tabulated-list-init-header)
13961392 (tabulated-list-print)))))
1397
13981393
13991394 (defun tablist-shrink-column (&optional column width)
14001395 (interactive
14021397 3)))
14031398 (tablist-enlarge-column column (- (or width 1))))
14041399
1405
14061400 ;; *Sorting
1407 ;;
1401 ;;
14081402
14091403 (defun tablist-sort (&optional column)
14101404 "Sort the tabulated-list by COLUMN.
15121506 (when (and filter
15131507 (null tablist-filter-suspended))
15141508 (tablist-with-remembering-entry
1515 (tablist-map-with-filter
1516 (lambda nil
1517 (if tablist-umark-filtered-entries
1518 (save-excursion (tablist-unmark-forward)))
1519 (tablist-filter-hide-entry))
1520 (tablist-filter-negate filter))))
1509 (tablist-map-with-filter
1510 (lambda nil
1511 (if tablist-umark-filtered-entries
1512 (save-excursion (tablist-unmark-forward)))
1513 (tablist-filter-hide-entry))
1514 (tablist-filter-negate filter))))
15211515 (force-mode-line-update))
15221516
15231517 (defadvice tabulated-list-print (after tabulated-list activate)
15381532 "Call FN for every unfiltered entry matching FILTER."
15391533 (prog1
15401534 (cl-labels ((search ()
1541 (tablist-skip-invisible-entries)
1542 (while (and (not (eobp))
1543 (not (tablist-eval-filter filter)))
1544 (tablist-forward-entry))
1545 (unless (eobp)
1546 (point-marker))))
1535 (tablist-skip-invisible-entries)
1536 (while (and (not (eobp))
1537 (not (tablist-eval-filter filter)))
1538 (tablist-forward-entry))
1539 (unless (eobp)
1540 (point-marker))))
15471541 (let (next-position results)
15481542 (save-excursion
15491543 (goto-char (point-min))
15621556
15631557 ;;
15641558 ;; **Filter Commands
1565 ;;
1559 ;;
15661560 (defun tablist-push-filter (filter &optional interactive or-p)
15671561 (setq tablist-current-filter
15681562 (tablist-filter-push
17301724 (when mode-filter
17311725 (setcdr mode-filter
17321726 (cl-remove name (cdr mode-filter)
1733 :test 'equal :key 'car)))))
1727 :test 'equal :key 'car)))))
17341728
17351729 (defun tablist-name-current-filter (name)
17361730 (interactive
17481742 tablist-current-filter))
17491743 (setq tablist-current-filter name)
17501744 (force-mode-line-update))
1751
1745
17521746 (defun tablist-deconstruct-named-filter ()
17531747 (interactive)
17541748 (let (found)
17671761 (unless found
17681762 (error "No named filter found"))
17691763 (force-mode-line-update)))
1770
1771
1764
17721765 (defun tablist-filter-names (&optional mode)
17731766 (mapcar 'car (cdr (assq (or mode major-mode)
17741767 tablist-named-filter))))
18251818 "Display the current filter according to FLAG.
18261819
18271820 If FLAG has the value 'toggle, toggle it's visibility.
1828 If FLAG has the 'state, then do nothing but return the current
1821 If FLAG has the 'state, then do nothing but return the current
18291822 visibility."
18301823 (interactive (list 'toggle))
18311824 (let* ((tag 'tablist-display-filter-mode-line-tag)
18601853
18611854 ;;
18621855 ;; **Hiding/Unhiding Entries
1863 ;;
1856 ;;
18641857 (defun tablist-filter-set-entry-hidden (flag &optional pos)
18651858 (save-excursion
18661859 (when pos (goto-char pos))
18831876 (remove-text-properties
18841877 (point-min) (point-max)
18851878 '(invisible))))
1886
18871879
18881880 (defun tablist-window-attach (awindow &optional window)
18891881 "Attach AWINDOW to WINDOW.
19231915 (setq newwin (window--display-buffer
19241916 buf
19251917 (split-window-below height)
1926 'window alist display-buffer-mark-dedicated))
1918 'window alist))
19271919 (tablist-window-attach newwin window)
19281920 newwin))
19291921