summaryrefslogtreecommitdiff
path: root/modules/host-environment.el
blob: fcf8717000bce210624ed1e15db47ef5944b76bb (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
;;; host-environment.el --- Host Environment Convenience Functions -*- lexical-binding: t; coding: utf-8; -*-
;; author Craig Jennings <c@cjennings.net>

;;; Commentary:
;; Convenience functions to report about the host environment
;;
;;; Code:

;; for the byte-compiler/linter
(declare-function battery-format "battery" (format data))
(defvar battery-status-function)


(defun env-laptop-p ()
  "Non-nil if a battery is present."
  (when (and (require 'battery nil 'noerror)
			 battery-status-function)
	(not (string= "N/A"
				  (battery-format "%B" (funcall battery-status-function))))))

(defun env-desktop-p ()
  "Return t if host is a laptop (has a battery), nil if not."
  (when (not (env-laptop-p))
	t))

(defun env-linux-p ()
  "Return t if host system is GNU/Linux."
  (eq system-type 'gnu/linux))

(defun env-bsd-p ()
  "Return t if host system is FreeBSD."
  (eq system-type 'berkeley-unix))

(defun env-macos-p ()
  "Return non-nil if running on macOS (Darwin)."
  (eq system-type 'darwin))

(defun env-windows-p ()
  "Return t if host system is Windows."
  (memq system-type '(cygwin windows-nt ms-dos)))

(defun env-x-p ()
  "Return t if host system is running the X Window System."
  (string= (window-system) "x"))

(defun env-terminal-p ()
  "Return t if running in a terminal."
  (not (display-graphic-p)))

(defun env-gui-p ()
  "Return t if running in graphical environment."
  (display-graphic-p))

;; ------------------------------- Timezone Info -------------------------------

(defun cj/match-localtime-to-zoneinfo ()
  "Detect system timezone by comparing /etc/localtime with zoneinfo files.
This replicates the shell command:
find /usr/share/zoneinfo -type f ! -name \='posixrules\=' \\
  -exec cmp -s {} /etc/localtime \\;
  -print | sed -e \='s@.*/zoneinfo/@@\=' | head -n1"
  (when (and (file-exists-p "/etc/localtime")
			 (file-directory-p "/usr/share/zoneinfo"))
	(let ((localtime-content
		   (with-temp-buffer
			 (insert-file-contents-literally "/etc/localtime")
			 (buffer-string)))
		  (result nil))
	  (catch 'found
		(dolist (file (directory-files-recursively
					   "/usr/share/zoneinfo"
					   ".*"
					   nil
					   (lambda (name)
						 (not (string-match-p "posixrules" name)))))
		  (when (and (file-regular-p file)
					 (not (string-match-p "/posixrules$" file)))
			(let ((file-content
				   (with-temp-buffer
					 (insert-file-contents-literally file)
					 (buffer-string))))
			  (when (string= localtime-content file-content)
				(setq result (replace-regexp-in-string
							  "^.*/zoneinfo/" "" file))
				(throw 'found result)))))
		result))))

(defun cj/detect-system-timezone ()
  "Detect the system timezone in IANA format (e.g., \='America/Los_Angeles\=').
Tries multiple methods in order of reliability:
1. Environment variable TZ
2. File comparison of /etc/localtime with zoneinfo database
3. /etc/timezone file contents
4. /etc/localtime symlink target"
  (or
   ;; Compare file contents (reliable on Arch/modern systems)
   (cj/match-localtime-to-zoneinfo)

   ;; Environment variable (most explicit if set)
   (getenv "TZ")

   ;; Read /etc/timezone (Debian/Ubuntu)
   (when (file-exists-p "/etc/timezone")
	 (with-temp-buffer
	   (insert-file-contents "/etc/timezone")
	   (string-trim (buffer-string))))

   ;; Method 4: Parse symlink (fallback for older systems)
   (when (file-symlink-p "/etc/localtime")
	 (let ((target (file-truename "/etc/localtime")))
	   (when (string-match ".*/zoneinfo/\\(.+\\)" target)
		 (match-string 1 target))))

   ;; Default to nil - lets org-gcal use its default
   nil))

(provide 'host-environment)
;;; host-environment.el ends here.