summaryrefslogtreecommitdiff
path: root/view-conf.el
blob: 27265260546abe92f338df1f48b34d333219ff50 (plain)
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
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
;;; view-conf.el --- For viewing -*- lexical-binding: t; -*-

;; Copyright (C) 2024  Durand

;; Author: Durand <durand@jsdurand.xyz>
;; Keywords: convenience, hardware

;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see
;; <https://www.gnu.org/licenses/>.

;;; Commentary:

;; My configurations for more conveniently viewing buffers and some
;; systems information.

;;; Code:

;;; View tmeperatures or timers
;;;###autoload
(defun durand-view-timers-or-temps (&optional arg)
  "View the list of timers or view information of CPU and battery.
If ARG is nil, view the following information:
  - Fan speed
  - CPU die temperature
  - Remaining battery charge
  - Battery full capacity
  - Whether or not the battery is fully charged
  - Whether or not the battery is charging
  - Battery cycle number
  - Battery health condition
  - Whether or not the computer is connected to some charging source
  - Battery temperature

If ARG is '(4), view the list of timers."
  (interactive "P")
  (require 'auth-source)
  (cond
   ((null arg)
    (let (fan-speed
          cpu-die-temperature
          remain
          full-capacity
          fullp
          charging
          cycle
          condition
          connected
          battery-temp)
      (with-temp-buffer
;; NOTE: First fans information
        (insert
         (funcall
          (plist-get
           (car (auth-source-search :host "local-computer"))
           :secret)))
        (call-process-region
         nil nil "sudo"
         nil t nil "-S" "powermetrics"
         "-i1" "-n1" "-ssmc")
        (goto-char (point-min))
        (search-forward "Fan" nil t)
        (setq
         fan-speed
         (save-match-data
           (re-search-forward "[[:digit:]]+" (line-end-position) t)
           (string-to-number (match-string 0)))
         cpu-die-temperature
         (save-match-data
           (re-search-forward
            (rx-to-string
             (list
              'seq
              "temperature: "
              (list
               'group
               (list 'one-or-more 'digit)
               ?.
               (list 'one-or-more 'digit)))
             t)
            nil t)
           (string-to-number (match-string 1))))
;; NOTE: Now battery charge information
        (erase-buffer)
        (call-process "system_profiler" nil t nil
                      "SPPowerDataType")
        (goto-char (point-min))
        (save-match-data
          (re-search-forward "Fully Charged: \\(.+\\)$" nil t)
          (setq fullp (match-string-no-properties 1))
          (re-search-forward "Charging: \\(.+\\)$" nil t)
          (setq charging (match-string-no-properties 1))
          (re-search-forward
           "Full Charge Capacity (mAh): \\([[:digit:]]+\\)$" nil t)
          (setq
           full-capacity
           (string-to-number (match-string-no-properties 1)))
          (re-search-forward
           "State of Charge (%): \\([[:digit:]]+\\)" nil t)
          (setq
           remain
           (string-to-number (match-string-no-properties 1)))
          (re-search-forward "Cycle Count: \\(.+\\)$" nil t)
          (setq
           cycle
           (string-to-number (match-string-no-properties 1)))
          (re-search-forward "Condition: \\(.+\\)$" nil t)
          (setq condition (match-string-no-properties 1))
          (re-search-forward "Connected: \\(.+\\)$" nil t)
          (setq connected (match-string-no-properties 1))
          ;; NOTE: Now battery temperature
          (erase-buffer)
          (call-process "ioreg" nil t nil "-n"
                        "AppleSmartBattery" "-r")
          (goto-char (point-min))
          (re-search-forward "Temperature..=." nil t)
          (re-search-forward "[[:digit:]]+" nil t)
          (setq battery-temp
                (/ (string-to-number (match-string-no-properties 0))
                   100.0))))
      (message
       (concat
        (format "fan: %d, temp: %s, battery temp: %.2f"
                fan-speed cpu-die-temperature battery-temp)
        "\n"
        (format
         "Full: %d, remaining: %d%s, fullp: %s, charging: %s, \
connected: %s, cycles: %d, condition: %s"
         full-capacity remain "%%" fullp charging connected cycle
         condition)))))
   ((equal arg (list 4))
    (list-timers)
    (save-match-data
      (cond
       ((search-forward "mail" nil t)
        (goto-char (pos-bol))))))
   (t
    (user-error "Unsupported ARG: %S" arg))))

(put 'durand-view-timers-or-temps 'repeat-map
     (let ((map (make-sparse-keymap)))
       (define-key map (vector ?t) 'repeat)
       map))

(define-obsolete-function-alias 'durand-view-timers
  'durand-view-timers-or-temps
  "2020-09-02" "View the list of timers.")

;;;###autoload
(defun durand-view-process (&optional arg)
  "View the list of processes"
  (interactive "P")
  (cond
   ((equal arg (list 4))
    (list-processes)
    (let ((window (get-buffer-window "*Process List*")))
      (cond (window (durand-fit-window-to-buffer-with-max window)))))
   ((equal arg (list 16))
    (proced))
   ((message "%s" (process-list)))))

;;; My map for viewing

;;;###autoload
(defvar durand-view-map
  ;; Against every good principle I guess...
  (let ((map (list 'keymap "View")))
    (define-key map (vector ?v) #'view-mode)
    (define-key map (vector ?P) #'durand-view-process)
    (define-key map (vector ?t) #'durand-view-timers-or-temps)
    (define-key map (vector ?f) #'durand-focus)
    (define-key map (vector ?e) #'eshell)
    (define-key map (vector ?p) #'durand-chercher-pdf)
    (define-key map (vector ?o) #'olivetti-mode)
    (define-key map (vector ?c) #'calendar)
    (define-key map (vector ?r) #'choose-recent-file)
    (define-key map (vector ?n) #'novel)
    (define-key map (vector ?O) #'durand-maybe-enable-outline)
    (define-key map (vector ?w) #'durand-eww-map)
    (define-key map (vector ?i) #'imenu)
    map)
  "The keymap that is related to my custom functions about viewing.")
;;; Hyper key

(define-key global-map (vector ?\H-n) #'novel)

;;; About view-mode

(require 'view)

(define-key view-mode-map (vector 108) #'recenter-top-bottom)
(define-key view-mode-map (vector 76) #'reposition-window)

(define-key view-mode-map (vector ?j) #'View-scroll-line-forward)
(define-key view-mode-map (vector ?k) #'View-scroll-line-backward)
(define-key view-mode-map (vector ?\M-n) #'forward-page)
(define-key view-mode-map (vector ?\M-p) #'backward-page)
(define-key view-mode-map (vector ?J) #'jump-to-register)
(define-key global-map (vector 3 118) durand-view-map)

;;; Open things

;; OBSOLETE: This is almost superseded by the built-in bookmarks.

;;;###autoload
(defvar durand-open-targets nil
  "Targets to open by `durand-open-object'.

This is an association list whose elements have `car' equal to
the choice presented to the user, and have `cdr' a list that will
be passed to `make-process'.

See the documentation for `durand-open-object' for the formats of
targets.")

(setq durand-open-targets
      (list
       (list
        "safari" "open" "-a" "Safari"
        (list
         "https://www.youtube.com"
         "https://www.gmail.com"
         "https://www.facebook.com"
         "https://protesilaos.com"
         "https://wmail1.cc.ntu.edu.tw/rc/?_task=mail&_mbox=INBOX"
         "https://dictionary.christian-steinert.de/#home"
         ))
       (list "terminal" "open" "-a" "Terminal"
             (list
              "/Users/durand/Desktop/Centre/Vidéos/"
              "/Users/durand/Desktop/Centre/Musique/"
              "/Users/durand/Downloads/"))
       (list "messenger" "open" "-a" "Messenger")
       (list "temp d'écran" "open" "-b"
             "com.apple.systempreferences"
             "/System/Library/PreferencePanes/ScreenTime.prefPane")))

;;;###autoload
(defun durand-target-extra-arg (target)
  "Determine if TARGET has room for extra arguments.
This returns the list of extra argument slots, or nil if there is
none."
  (let (temp result)
    (while (consp target)
      (setq temp (car target))
      (setq target (cdr target))
      (cond
       ;; We shall not test numbers by `eq'.
       ((equal temp -1)
        (setq result (cons -1 result)))
       ((consp temp)
        (setq result (cons temp result)))))
    (nreverse result)))

;;;###autoload
(defun durand-replace-extra-args (target extra-args)
  "Replace slots for extra-args in TARGET by EXTRA-ARGS.
This does not check if the lengths match, though in theory they
should.

And this will delete any `nil' values from the result."
  (let  (temp result)
    (while (consp target)
      (setq temp (car target))
      (setq target (cdr target))
      (cond
       ((or (eq temp -1)
            (consp temp))
        (setq result (cons (car extra-args)
                           result))
        (setq extra-args (cdr extra-args)))
       ((setq result (cons temp result)))))
    (delq nil (nreverse result))))

;;;###autoload
(defun durand-open-object (&optional arg)
  "Open something.
What can be opened is controlled by the variable
`durand-open-targets'.

If ARG is non-nil, and if the chosen target contains -1 in the
command line options, then read a string to replace that -1. If
the chosen target has a sub-list, then use that sub-list as
options to choose from."
  (interactive "P")
  (let* ((targets durand-open-targets)
         (choice (completing-read "Open: " targets nil t))
         (commands (cdr (assoc choice targets #'string=)))
         (extra-arg-slots (durand-target-extra-arg commands))
         (extra-arg (cond
                     (arg
                      (mapcar
                       (lambda (extra-arg-slot)
                         (cond
                          ((eq extra-arg-slot -1)
                           (read-string "Extra argument: "))
                          ((consp extra-arg-slot)
                           (completing-read
                            "Extra argument: " extra-arg-slot))))
                       extra-arg-slots)))))
    (setq commands (durand-replace-extra-args commands extra-arg))
    (make-process :name "durand-open"
                  :buffer nil
                  :command commands)))

;; C-c o => 3 111
(define-key global-map (vector 3 111) #'durand-open-object)
(define-key global-map (vector ?\H-o) #'durand-open-object)

;;; Convert youtube videos to URL

;;;###autoload
(defun durand-convert-youtube-video-to-url (video-name)
  "Convert VIDEO-NAME to its original url."
  (interactive (list (read-string "Video name: ")))
  (let (result)
    (save-match-data
      (cond
       ((string-match (rx "[" (group (1+ (not "]"))) "].")
                      video-name)
        (setq result (concat
                      "https://www.youtube.com/watch?v="
                      (match-string 1 video-name)))
        (kill-new result))
       ((string-match "\\.[^.]+$" video-name)
        ;; with extension
        (setq
         result
         (concat
          "https://www.youtube.com/watch?v="
          (substring-no-properties
           video-name
           (- (match-beginning 0) 11)
           (match-beginning 0))))
        (kill-new result))
       (t
        ;; no extension
        (setq result
              (concat "https://www.youtube.com/watch?v="
                      (substring-no-properties video-name -11)))
        (kill-new result)))
      result)))

;;; moving by paragraphs

;;;###autoload
(defun durand-scroll-next-paragraph (&optional arg)
  "Scroll so that the next ARG paragraph is at the top."
  (interactive "p")
  (let ((forward-p (> arg 0))
        pos)
    (save-excursion
      (goto-char (window-start))
      (cond
       (forward-p
        (while (> arg 0)
          (cond
           ((re-search-forward "^\\s-*$" (line-end-position) t)
            (forward-line 1)))
          (while (not
                  (re-search-forward "^\\s-*$" (line-end-position) t))
            (forward-line 1))
          (setq arg (1- arg))))
       (t
        (while (< arg 0)
          (cond
           ((re-search-forward "^\\s-*$" (line-end-position) t)
            (forward-line -1)))
          (while (not
                  (re-search-forward "^\\s-*$" (line-end-position) t))
            (forward-line -1))
          (setq arg (1+ arg)))))
      (setq pos (point)))
    (set-window-start (selected-window) pos)
    (goto-char pos)))

;;;###autoload
(defun durand-scroll-prev-paragraph (&optional arg)
  "Scroll so that the previous ARG paragraph is at the top."
  (interactive "p")
  (cond ((numberp arg)) ((setq arg 1)))
  (durand-scroll-next-paragraph (- arg)))

;;; focus mode

;;;###autoload
(defvar durand-focus-map '(keymap "focus")
  "The keymap for the focus mode.")

(define-key durand-focus-map (vector ?\s-v) #'view-mode)
(define-key durand-focus-map (vector ?\s-x) #'durand-focus)
(define-key durand-focus-map (vector ?\M-\s-f) #'durand-focus-focus)
(define-key view-mode-map (vector ?f) #'durand-scroll-next-paragraph)
(define-key view-mode-map (vector ?b) #'durand-scroll-prev-paragraph)

;;;###autoload
(define-minor-mode durand-focus
  "Focus mode."
  :init-value nil
  :lighter " Foc"
  (cond
   (durand-focus
    (setq olivetti-body-width 80)
    (olivetti-mode 1)
    (cond (current-prefix-arg (view-mode 1))))
   ((setq olivetti-body-width 80)
    (variable-pitch-mode -1)
    (view-mode -1)
    (olivetti-mode -1)
    (text-scale-increase 0))))

;;;###autoload
(defun durand-focus-focus (&optional arg)
  "Toggle the font size and `variable-pitch-mode'.
ARG will be (prefix-numeric-value prefix-arg) in interactive
uses.

If ARG is non-zero and odd, toggle font-size.

If ARG is non-zero and the second bit is non-zero, toggle
`variable-pitch-mode'."
  (interactive "p")
  (setq arg (prefix-numeric-value arg))
  (cond
   ((= arg 0)
    (cond
     ((and text-scale-mode
           (/= text-scale-mode-amount 0))
      (text-scale-increase 0))
     ((text-scale-increase 2)))
    (variable-pitch-mode 'toggle))
   (t
    (cond
     ((= (% arg 2) 1)
      (cond
       ((and text-scale-mode
             (/= text-scale-mode-amount 0))
        (text-scale-increase 0))
       ((text-scale-increase 2)))))
    (cond
     ((= (logand arg 2) 2)
      (variable-pitch-mode 'toggle))))))

;;; Press 'v' to scroll

(define-key view-mode-map (vector ?v) #'View-scroll-page-forward)

(provide 'view-conf)
;;; view-conf.el ends here