-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfile-package.lisp
136 lines (113 loc) · 4 KB
/
file-package.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
(defpackage :vernacular/file-package
(:documentation "Generate a unique per-file package.")
(:use :cl
:alexandria :serapeum
:uiop/pathname
:overlord/types)
(:import-from :vernacular/specials :*language*)
(:import-from :overlord/asdf
:asdf-system-name-keyword
:asdf-system-name
:asdf-system-base)
(:import-from #:uiop
#:os-windows-p)
(:export
:find-file-package
:intern-file-package
:reset-file-package
:abbreviate-file-name))
(in-package :vernacular/file-package)
(deftype symbol-status ()
'(member null :internal :external :inherited))
(defun intern-file-package (file &key use-list)
(check-type file pathname-designator)
(check-type use-list (list-of package-designator))
(assure package
(or (find-file-package file)
(make-file-package file :use-list use-list))))
(defun reset-file-package (file &key use-list)
(check-type file pathname-designator)
(check-type use-list (list-of package-designator))
(assure package
(reset-package
(intern-file-package file :use-list use-list))))
(defun find-file-package (file &key use-list)
(declare (ignore use-list))
(let ((name (file-package-name file)))
(find-package name)))
(defun make-file-package (file &key use-list)
(let ((name (file-package-name file)))
(make-package name :use use-list)))
(defun file-package-name (file)
(abbreviate-file-name file))
(def home-parent
(pathname-parent-directory-pathname (user-homedir-pathname)))
(defconst tmp-mnt "/tmp_mnt")
(defun enough-unix-namestring (subpath path)
(unix-namestring (enough-pathname subpath path)))
(defun abbreviate-file-name (path)
(setf path (pathname path))
(assert (file-pathname-p path))
;; Normalize the device.
(when (os-windows-p)
(trivia:match path
((pathname :device (and device (type string)))
(setf path
(make-pathname
:device (string-upcase device)
:defaults path)))))
(let ((home (user-homedir-pathname)))
(assure string
(if (subpathp path home)
(string+ "~/" (enough-unix-namestring path home))
(let ((home-parent (pathname-parent-directory-pathname home)))
(if (subpathp path home-parent)
(string+ "~" (enough-unix-namestring path home-parent))
(let ((ns (unix-namestring path)))
(if (string^= tmp-mnt ns)
(drop (length tmp-mnt) ns)
ns))))))))
(defun reset-package (package)
(assure package
(reset-package/unintern-all package)))
;;; TODO It's not clear to me which of these is the best way to do it.
(defun reset-package/delete-and-recreate (pkg)
(let ((name (package-name pkg))
(use-list (package-use-list pkg))
(nicknames (package-nicknames pkg)))
(delete-package pkg)
(make-package name
:use use-list
:nicknames nicknames)))
(defun reset-package/unintern-all (pkg)
(dolist (sym (package-own-symbols pkg) pkg)
(unintern sym pkg)))
(defun reset-package/undefine (pkg)
(dolist (sym (package-own-symbols pkg) pkg)
(cond-every
((fboundp sym) (fmakunbound sym))
;; Can't undo a special declaration.
((boundp sym) (unintern sym pkg))
;; Can't undo a symbol macro declaration.
((symbol-macro? sym) (unintern sym))
((class-name? sym) (setf (find-class sym) nil)))))
(defun symbol-macro? (sym)
(and (symbolp sym)
(not (eql sym
(macroexpand sym)))))
(defun class-name? (sym)
(and (symbolp sym)
(find-class sym :errorp nil)))
(defun package-own-symbols (pkg)
(loop for sym being the present-symbols in pkg
when (eql (symbol-package sym) pkg)
collect sym))
(defun symbol-status (sym &optional (package (symbol-package sym)))
(assure symbol-status
(let ((name (symbol-name sym)))
(nth-value 1
(find-symbol name package)))))
(defun unintern-from-home-package (sym)
(prog1 sym
(when-let (package (symbol-package sym))
(unintern sym package))))