git.fiddlerwoaroof.com
Browse code

Start building out scripting-bridge

Ed Langley authored on 04/01/2019 23:00:47
Showing 5 changed files
... ...
@@ -32,3 +32,5 @@ NSRect-Expose
32 32
 venv
33 33
 /reading-list2org
34 34
 /dist/
35
+/safari2org
36
+/safari2org-beta
35 37
new file mode 100644
... ...
@@ -0,0 +1,43 @@
1
+(cl:in-package :objc.manipulators)
2
+(named-readtables:in-readtable :objc-readtable)
3
+
4
+(serapeum:eval-always 
5
+  (let (*it*)
6
+    (declare (special *it*))
7
+    (defgeneric sel (type sel)
8
+      (:method :around (type sel)
9
+               (lambda (*it*)
10
+                 (declare (special *it*))
11
+                 (call-next-method)))
12
+
13
+      (:method (type sel)
14
+        [*it* sel])
15
+
16
+      (:method ((type (eql :int)) sel)
17
+        [*it* sel]#)
18
+
19
+      (:method ((type (eql :string)) sel)
20
+        [*it* sel]s)
21
+
22
+      (:method ((type (eql :nsstring)) sel)
23
+        [*it* sel]@))))
24
+
25
+(defun-ct ext ()
26
+  (lambda (it)
27
+    (objc-runtime.data-extractors:extract-from-objc it)))
28
+
29
+(defun-ct <> (&rest funs)
30
+  (apply #'alexandria:compose funs))
31
+
32
+(defun-ct <count (f)
33
+  (lambda (c &rest v)
34
+    (list* c (apply f v))))
35
+
36
+(defun-ct add-index (hof f)
37
+  (lambda (&rest hof-args)
38
+    (let ((count 0))
39
+      (declare (dynamic-extent count))
40
+      (flet ((nested-lambda (&rest args)
41
+               (prog1 (apply f count args)
42
+                 (incf count))))
43
+        (apply hof #'nested-lambda hof-args)))))
... ...
@@ -21,7 +21,8 @@
21 21
                (:file "readtable" :depends-on ("package"))
22 22
                (:file "gcd" :depends-on ("objc-runtime"))
23 23
                (:file "objc-runtime" :depends-on ("package" "readtable" "objc-runtime-types"))
24
-               (:file "objc-data-extractors" :depends-on ("objc-runtime" "readtable"))))
24
+               (:file "objc-data-extractors" :depends-on ("objc-runtime" "readtable"))
25
+               (:file "manipulators" :depends-on ("objc-data-extractors" "readtable" "objc-runtime"))))
25 26
 
26 27
 (defsystem :objc-runtime/scripting-bridge
27 28
   :description ""
... ...
@@ -35,7 +36,6 @@
35 36
   :description ""
36 37
   :author "Ed L <edward@elangley.org>"
37 38
   :license "MIT"
38
-  :pathname #+lp-systems #p"projects:objc-lisp-bridge;" #-lp-systems nil
39 39
   :depends-on (:objc-runtime
40 40
                :serapeum
41 41
                :alexandria
... ...
@@ -39,3 +39,8 @@
39 39
    #:clear-extractors
40 40
    #:add-extractor
41 41
    #:get-plist))
42
+
43
+(uiop:define-package :objc.manipulators
44
+    (:use :cl :data-lens)
45
+  (:export :sel :ext :<> :add-index :<count)
46
+  (:reexport :data-lens))
... ...
@@ -1,7 +1,8 @@
1 1
 (defpackage :objc.scripting-bridge
2
-  (:import-from :data-lens :defun-ct :shortcut)
2
+  (:import-from :objc.manipulators :defun-ct :shortcut :<> :ext :sel)
3 3
   (:use :cl :cffi)
4
-  (:export ))
4
+  (:export
5
+   #:app))
5 6
 (in-package :objc.scripting-bridge)
6 7
 (named-readtables:in-readtable :objc-readtable)
7 8
 
... ...
@@ -30,32 +31,6 @@
30 31
             (/ [current-track @(albumRating)]# 10)
31 32
             [current-track @(artist)]@)))
32 33
 
33
-(defvar *it*)
34
-(serapeum:eval-always 
35
-  (defgeneric sel (type sel)
36
-    (:method :around (type sel)
37
-             (lambda (*it*)
38
-               (call-next-method)))
39
-
40
-    (:method (type sel)
41
-      [*it* sel])
42
-
43
-    (:method ((type (eql :int)) sel)
44
-      [*it* sel]#)
45
-
46
-    (:method ((type (eql :string)) sel)
47
-      [*it* sel]s)
48
-
49
-    (:method ((type (eql :nsstring)) sel)
50
-      [*it* sel]@)))
51
-
52
-(defun-ct ext ()
53
-  (lambda (it)
54
-    (objc-runtime.data-extractors:extract-from-objc it)))
55
-
56
-(defun-ct <> (&rest funs)
57
-  (apply #'alexandria:compose funs))
58
-
59 34
 (defun-ct tab-info ()
60 35
   (data-lens:juxt
61 36
    (<> (ext) (sel t @(name)))
... ...
@@ -75,13 +50,11 @@
75 50
 (defun format-tab-info (info)
76 51
   (format t "~{~:@{** ~a~% ~a~%~}~2%~}" info))
77 52
 
78
-
79 53
 (defun safari-main ()
80 54
   (format-tab-info
81 55
    (safari-tab-info
82 56
     (safari-app))))
83 57
 
84
-
85 58
 (defun count-invocations (hof)
86 59
   (lambda (f &rest hof-args)
87 60
     (let ((count 0))
... ...
@@ -91,106 +64,56 @@
91 64
                  (incf count))))
92 65
         (apply hof #'nested-lambda hof-args)))))
93 66
 
94
-(defun-ct <count (f)
95
-  (lambda (c &rest v)
96
-    (list* c (apply f v))))
97
-
98
-(defun-ct add-index (hof f)
99
-  (lambda (&rest hof-args)
100
-    (let ((count 0))
101
-      (declare (dynamic-extent count))
102
-      (flet ((nested-lambda (&rest args)
103
-               (prog1 (apply f count args)
104
-                 (incf count))))
105
-        (apply hof #'nested-lambda hof-args)))))
106
-
107
-(defun get-window-tabs (window)
108
-  (funcall (<> 'objc-runtime.data-extractors:extract-from-objc
109
-               (sel t @(tabs)))
110
-           window))
111
-
112
-(data-lens:shortcut get-safari-info <>
113
-  (add-index 'mapcar 
114
-             (<> (fw.lu:destructuring-lambda ((c win-id win-name . tabs))
115
-                   (format t "~&Window: ~d ~d ~a~%~{~a~%~}~%" win-id c win-name tabs))
116
-                 (<count
117
-                  (<> (data-lens:transform-elt 1 (<> (add-index 'mapcar
118
-                                                                (<> (fw.lu:destructuring-lambda ((c ti u))
119
-                                                                      (format nil "~a ~a~%~4t~a" c ti u))
120
-                                                                    (<count (tab-info))))
121
-                                                     'get-window-tabs))
122
-                      'window-info))))
123
-  (ext)
124
-  (sel t @(windows)))
125
-
126
-(defun safari-2-main ()
127
-  (get-safari-info (safari-app)))
128
-
129
-
130
-
131
-(defun find-tab (name windows)
132
-  (remove-if-not (serapeum:op (serapeum:string-contains-p name _))
133
-                 windows
134
-                 :key (<> 'string-downcase 'car)))
135
-
136
-(defun current-tab (window)
137
-  [window @(currentTab)])
138
-(defun (setf current-tab) (new-value window)
139
-  [window @(setCurrentTab:) :pointer new-value]
140
-  new-value)
141
-
142
-#+nil
143
-(defun kebab-case (s)
144
-  (loop
145
-     for start = 0 then end
146
-     for end = (position-if 'upper-case-p s) then (when start (position-if 'upper-case-p s :start (1+ end)))
147
-     while start
148
-     collect (string-downcase (subseq s start end)) into parts
149
-     finally (return (serapeum:string-join parts #\-))))
150
-
151
-#+nil
152
-(defun get-method-symbol (selector-name package)
153
-  (funcall (alexandria:compose (lambda (x) (intern x package))
154
-                               #'string-upcase
155
-                               (lambda (x) (substitute #\- #\: 
156
-                                                       (string-trim ":-" x)))
157
-                               'kebab-case)
158
-           selector-name))
159
-
160
-#+nil
161
-(defun intern-method (selector-name package)
162
-  (let ((symbol (get-method-symbol selector-name package)))
163
-    (format t "~&~s ~s~%" symbol selector-name)
164
-    (if (alexandria:starts-with-subseq "set" selector-name)
165
-        (setf (fdefinition `(setf ,symbol))
166
-              (lambda (new-val receiver &rest r)
167
-                (declare (ignore r))
168
-                (objc-runtime:objc-msg-send receiver (objc-runtime::ensure-selector selector-name) :pointer new-val)))
169
-        (setf (fdefinition symbol)
170
-              (sel (objc-runtime::ensure-selector selector-name))))))
171 67
 
68
+(defmacro comment (&body b)
69
+  b ())
172 70
 #+nil
173
-(defun populate-package (objc-class package)
174
-  (mapc (lambda (method-name)
175
-          (intern-method method-name package))
176
-        (objc-runtime:get-method-names objc-class)))
177
-
178
-#+nil
179
-(defmacro define-objc-call (selector (&rest argument-specs) result-type &optional extractor)
180
-  (declare (ignorable extractor))
181
-  `(defun ,(get-method-symbol (cadr selector) *package*) (receiver ,@(mapcar #'car argument-specs))
182
-     ,(case result-type
183
-        (:string `(objc-runtime:objc-msg-send-string receiver ,selector ,@(mapcan #'reverse argument-specs)))
184
-        ((:long :int) `(objc-runtime:objc-msg-send-int receiver ,selector ,@(mapcan #'reverse argument-specs)))
185
-        (t `(objc-runtime:objc-msg-send receiver ,selector ,@(mapcan #'reverse argument-specs))))))
186
-
187
-#+nil
188
-(defmacro define-objc (() &body calls)
189
-  `(progn ,@(loop for call in calls
190
-               collect `(define-objc-call ,@call))))
191
-
192
-#+nil
193
-(define-objc-call @(init) () :pointer)
194
-#+nil
195
-(define-objc-call @(sharedApplication) () :pointer)
196
-
71
+(comment
72
+  (defun kebab-case (s)
73
+    (loop
74
+       for start = 0 then end
75
+       for end = (position-if 'upper-case-p s) then (when start (position-if 'upper-case-p s :start (1+ end)))
76
+       while start
77
+       collect (string-downcase (subseq s start end)) into parts
78
+       finally (return (serapeum:string-join parts #\-))))
79
+
80
+  (defun get-method-symbol (selector-name package)
81
+    (funcall (alexandria:compose (lambda (x) (intern x package))
82
+                                 #'string-upcase
83
+                                 (lambda (x) (substitute #\- #\: 
84
+                                                         (string-trim ":-" x)))
85
+                                 'kebab-case)
86
+             selector-name))
87
+
88
+  (defun intern-method (selector-name package)
89
+    (let ((symbol (get-method-symbol selector-name package)))
90
+      (format t "~&~s ~s~%" symbol selector-name)
91
+      (if (alexandria:starts-with-subseq "set" selector-name)
92
+          (setf (fdefinition `(setf ,symbol))
93
+                (lambda (new-val receiver &rest r)
94
+                  (declare (ignore r))
95
+                  (objc-runtime:objc-msg-send receiver (objc-runtime::ensure-selector selector-name) :pointer new-val)))
96
+          (setf (fdefinition symbol)
97
+                (sel (objc-runtime::ensure-selector selector-name))))))
98
+
99
+  (defun populate-package (objc-class package)
100
+    (mapc (lambda (method-name)
101
+            (intern-method method-name package))
102
+          (objc-runtime:get-method-names objc-class)))
103
+
104
+  (defmacro define-objc-call (selector (&rest argument-specs) result-type &optional extractor)
105
+    (declare (ignorable extractor))
106
+    `(defun ,(get-method-symbol (cadr selector) *package*) (receiver ,@(mapcar #'car argument-specs))
107
+       ,(case result-type
108
+          (:string `(objc-runtime:objc-msg-send-string receiver ,selector ,@(mapcan #'reverse argument-specs)))
109
+          ((:long :int) `(objc-runtime:objc-msg-send-int receiver ,selector ,@(mapcan #'reverse argument-specs)))
110
+          (t `(objc-runtime:objc-msg-send receiver ,selector ,@(mapcan #'reverse argument-specs))))))
111
+
112
+  (defmacro define-objc (() &body calls)
113
+    `(progn ,@(loop for call in calls
114
+                 collect `(define-objc-call ,@call))))
115
+
116
+  (define-objc-call @(init) () :pointer)
117
+  (define-objc-call @(sharedApplication) () :pointer)
118
+
119
+  )