-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtkb-functions.el
317 lines (271 loc) · 10.8 KB
/
tkb-functions.el
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; tkb-functions.el -- these are functions that are generic emacs functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; $ProjectHeader: tkbconfig 0.5 Tue, 09 May 2000 20:50:39 -0400 tkb $
;;; $Id: tkb-functions.el 1.2 Tue, 09 May 2000 20:50:39 -0400 tkb $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun y-or-n-p/timeout (prompt &optional timeout default)
"Ask user a \"y or n\" question, but after TIMEOUT seconds return DEFAULT,
which should be `t' or `nil'. TIMEOUT defaults to 5 seconds."
(interactive)
(unless timeout (setq timeout 5.0))
(with-timeout (timeout
(message "%s timed out after %f seconds; returning %S"
prompt timeout default)
default)
(y-or-n-p prompt)))
(defun empty-string-p (s)
"Return true if S is empty"
(zerop (length s)))
(defvar tkb-align-column 79
"Put the last character of this line in `tkb-align-column'")
(defun tkb-align-end (col)
"Align the end of this line at character `tkb-align-column',
or at the column specified by the prefix arg."
(interactive "P")
(let ((col (if col col tkb-align-column)))
(let ((current-end (save-excursion
(end-of-line)
(current-column))))
(if (< current-end col)
(insert (make-string (- col current-end) ? ))))))
(defun tkb-get-clipboard ()
(interactive)
(insert (x-get-clipboard)))
(defun tkb-show-position ()
(interactive)
(let* ((params (frame-parameters))
(top (assq 'top params))
(left (assq 'left params))
(height (assq 'height params))
(width (assq 'width params)))
(message "(%s,%s) %sx%s" top left height width)))
(defun tkb-insert-buffer-filename (prefix)
"Insert the filename part of the buffer filename (or the buffer
name, if the buffer does not have a filename), or the whole
filename if a prefix greater than 1 is specified (remember C-u by
itself is 4), or the filename part without an extension if the
prefix is less than 0."
(interactive "p")
(let ((name (or (buffer-file-name) (buffer-name))))
(insert (if (> prefix 1)
name
(if (< prefix 0)
(file-name-sans-extension
(file-name-nondirectory name))
(file-name-nondirectory name))))))
(defun tkb-count-region ()
(interactive)
(message "%d characters in region."
(abs (- (mark) (point)))))
(defun tkb-pad-string (s)
"Pad string S with spaces between each character"
(interactive "sString: ")
(let ((l (length s)) (s2 (char-to-string (aref s 0))) (i 1))
(while (< i l)
(setq s2 (concat s2 " " (char-to-string (aref s i))))
(setq i (1+ i)))
(insert s2)))
(defun tkb-ibn-padded (up)
"Insert Buffer Name with spaces between each character. With arg, upcase."
(interactive "P")
(tkb-pad-string (cond (up (upcase (buffer-name)))
(t (buffer-name)))))
(defun tkb-ibn (up)
"Insert Buffer Name. With arg, upcase."
(interactive "P")
(insert (cond (up (upcase (buffer-name)))
(t (buffer-name)))))
(tkb-keys ((kbd "C-c k B") #'tkb-ibn))
(defun tkb-stretch-string (s)
(interactive "sString: ")
(let* ((len (length s))
(ns (make-string (* len 3) ?\s))
(i 0))
(while (< i len)
(let ((c (aref s i))
(n (* i 3)))
(aset ns n c)
(aset ns (+ n 1) c)
(aset ns (+ n 2) c))
(cl-incf i))
(insert ns)))
(defun tkb-insert-user-name ()
(interactive)
(insert (user-full-name)))
(defun tkb-insert-login-name ()
(interactive)
(insert (user-login-name)))
(defun tkb-find-next-tag ()
(interactive)
(find-tag nil t nil))
(defun tkb-mail-self-note (self)
(interactive "P")
(message "mail-self: %S" self)
(let ((to (if self
(if (stringp self)
self
(completing-read "Username: "
`(("[email protected]" 1)
("[email protected]" 2))))
"[email protected]")))
;; Whoa, way too fiddly. ???
(let ((mail-self-blind (and self
(or (and (numberp self)
(< self 0))
(eq self '-)))))
(compose-mail to)
(mail-subject))))
(global-set-key (kbd "C-c m n") 'tkb-mail-self-note)
(defun tkb-mail-self-note-mpl ()
(interactive)
(tkb-mail-self-note "[email protected]"))
(global-set-key (kbd "C-c m N") 'tkb-mail-self-note-mpl)
(defun tkb-mail-bosses ()
(interactive)
(random t)
to)
(while (not (= (length to) 3))
(let ((user (aref bosses (random 3))))
(unless (member user to)
(push user to))))
(message "To: %S" to)
(compose-mail (mapconcat (function (lambda (n) n)) to ", "))
(mail-subject)))
(global-set-key (kbd "C-c m b") 'tkb-mail-bosses)
(defun tkb-edit-incoming-links ()
(interactive)
(let ((tkb-links-file "Incoming/incoming.data"))
(forms-find-file "~/comp/tkblinks/new-links.el")))
(defun tkb-edit-new-links ()
(interactive)
(let ((tkb-links-file "new-links.data"))
(forms-find-file "~/comp/tkblinks/new-links.el")))
(defun tkb-edit-tkb-links ()
(interactive)
(let ((tkb-links-file "tkb-links.data"))
(forms-find-file "~/comp/tkblinks/new-links.el")))
(defun tkb-edit-www-links ()
(interactive)
(let ((tkb-links-file "www-links.data"))
(forms-find-file "~/comp/tkblinks/new-links.el")))
(defun tkb-edit-phones-data ()
(interactive)
(forms-find-file "~/tkb/Data/Phones/phones.fmt"))
(defun tkb-insert-cut-buffer ()
(interactive)
(insert (x-get-cut-buffer)))
(defun tkb-reset-isearch-highlight ()
(interactive)
(setq isearch-lazy-highlight (not isearch-lazy-highlight)))
(cl-defun tkb-check-bindings (keys-list &optional bindings-list (keymap global-map))
"Check if the key sequences in KEYS-LIST are already defined;
BINDINGS-LIST optionally contains the new bindings (functions)."
(unless bindings-list
(setq bindings-list (make-list (length keys-list) nil)))
(cl-loop for keys in keys-list
for new-binding in bindings-list
for binding = (lookup-key keymap keys)
;; lookup-key returns a number for key sequences that don't have
;; valid sequence of prefix characters in the keymap.
when (and binding (not (numberp binding)))
collect (cons keys binding)
into bindings
and collect (if new-binding
(format " %s is %S but will become %S\n" (key-description keys) binding new-binding)
(format " %s is %S\n" (key-description keys) binding))
into msgs
finally return (cl-values bindings (apply #'concat msgs))))
(cl-defun tkb-key-is-bound-to (key expected-fun &optional (keymap global-map))
"Check if the key sequence in KEY is bound to EXPECTED-FUN."
(let ((fun (lookup-key keymap key)))
(cond
((equal fun expected-fun)
(message "Key sequence '%s' is '%s' as expected" (key-description key)
expected-fun))
(t
(error "Key sequence '%s' is '%s' not '%s'" (key-description key)
fun expected-fun)))))
(when nil
(tkb-check-bindings (list (kbd "C-c k R")))
(tkb-check-bindings (list (kbd "C-c k r")))
(tkb-keys ((kbd "C-c k P") #'ding))
(tkb-check-bindings (list (kbd "C-c k p")))
)
(defun tkb-rfc822-date-time (&optional time)
;; http://www.faqs.org/rfcs/rfc822.html
(format-time-string "%a, %e %b %y %T %Z" time t))
(defun trim-end (s)
"Delete any whitespace at the end of a string."
(replace-regexp-in-string "\\( \\|\f\\|\t\\|\n\\)+$" "" s))
(defun trim-start (s)
"Delete any whitespace at the start of a string."
(replace-regexp-in-string "^\\( \\|\f\\|\t\\|\n\\)+" "" s))
(defun trim (s)
"Delete any whitespace at the start or end of a string."
(trim-start (trim-end s)))
(defun t:zap-to-char (arg char)
"Kill up to (but not including ARGth) occurrence of CHAR.
Case is ignored if `case-fold-search' is non-nil in the current buffer.
Goes backward if ARG is negative; error if CHAR not found."
(interactive "p\ncZap to char: ")
;; Avoid "obsolete" warnings for translation-table-for-input.
(with-no-warnings
(if (char-table-p translation-table-for-input)
(setq char (or (aref translation-table-for-input char) char))))
(kill-region (point) (progn
(search-forward (char-to-string char) nil nil arg)
(goto-char (if (> arg 0) (1- (point)) (1+ (point))))
(point))))
(tkb-keys ((kbd "M-Z") #'t:zap-to-char))
(defun tkb-push-env-var (var newval &optional first)
(let ((val (getenv var)))
(setenv var (if val
(if first
(concat newval ":" val)
(concat val ":" newval))
newval))))
;;; http://www.emacswiki.org/emacs/UnfillParagraph
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph ()
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive)
(let ((fill-column (point-max)))
(fill-paragraph nil)))
(progn
;;; http://www.danielehrman.com/blog/2014/5/25/11-must-haves-for-every-power-programmer
(defun save-macro (name)
"save a macro. Take a name as argument
and save the last defined macro under
this name at the end of your .emacs"
(interactive "SName of the macro :") ; ask for the name of the macro
(name-last-kbd-macro name) ; use this name for the macro
(find-file user-init-file) ; open ~/.emacs or other user init file
(goto-char (point-max)) ; go to the end of the .emacs
(newline) ; insert a newline
(insert-kbd-macro name) ; copy the macro
(newline) ; insert a newline
(switch-to-buffer nil)) ; return to the initial buffer
(defun increment-number-at-point ()
(interactive)
(skip-chars-backward "0123456789")
(or (looking-at "[0123456789]+")
(error "No number at point"))
(replace-match (number-to-string (1+ (string-to-number (match-string 0))))))
(global-set-key (kbd "C-c +") 'increment-number-at-point)
)
(defun tkb-list-properties ()
"Show text properties at point."
(interactive)
(message "%s" (text-properties-at (point))))
(defun tkb-find-in-path (path to-find)
(let ((path (tkb-path-get path)))
(catch 'checking
(while path
(let* ((directory (car path))
(filename (concat (file-name-as-directory directory) to-find)))
(if (file-exists-p filename) (throw 'checking filename)))
(pop path)))))
;;; end of tkb-functions.el