Blob


1 ;;; sndio.el --- Interact with sndio(8) -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2020 Omar Polo
5 ;; Author: Omar Polo <op@omarpolo.com>
6 ;; Version: 1.0
7 ;; Keywords: multimedia
8 ;; URL: https://git.omarpolo.com/sndio.el
10 ;;; Commentary:
12 ;; This package provides the sndio major mode to interact with
13 ;; OpenBSD' sndio(8).
15 ;;; Code:
17 (eval-when-compile (require 'subr-x))
19 (defvar sndio-sndioctl-cmd "sndioctl"
20 "Path to the sndioctl executable.")
22 (defvar sndio-step 0.02
23 "Step for `sndio-increase' and `sndio-decrease'.")
25 (defvar sndio-mode-map
26 (let ((m (make-sparse-keymap)))
27 (define-key m (kbd "n") #'forward-line)
28 (define-key m (kbd "p") #'previous-line)
29 (define-key m (kbd "i") #'sndio-increase)
30 (define-key m (kbd "d") #'sndio-decrease)
31 (define-key m (kbd "m") #'sndio-mute)
32 (define-key m (kbd "t") #'sndio-toggle)
33 (define-key m (kbd "g") #'sndio-update)
34 m)
35 "Keymap for sndio.")
37 (define-derived-mode sndio-mode special-mode "sndio"
38 "Major mode for sndio interaction."
39 (buffer-disable-undo)
40 (sndio-update))
42 (defun sndio-update ()
43 "Update the current sndio buffer."
44 (interactive)
45 (with-current-buffer "*sndio*"
46 (let ((inhibit-read-only t))
47 (erase-buffer)
48 (process-file sndio-sndioctl-cmd nil (current-buffer) nil)
49 (goto-char (point-min)))))
51 (defun sndio--run (&rest args)
52 "Run `sndio-sndioctl-cmd' with ARGS yielding its output."
53 (with-temp-buffer
54 (when (zerop (apply #'process-file sndio-sndioctl-cmd nil t nil args))
55 (buffer-string))))
57 (defun sndio--current-io ()
58 "Yield the input/poutput at point as string."
59 (when-let (end (save-excursion
60 (beginning-of-line)
61 (ignore-errors (search-forward "="))))
62 (buffer-substring-no-properties (line-beginning-position)
63 (1- end))))
65 (defun sndio--update-value (x)
66 "Update the value for the input/output at point setting it to X."
67 (save-excursion
68 (beginning-of-line)
69 (search-forward "=")
70 (let ((inhibit-read-only t))
71 (delete-region (point) (line-end-position))
72 (insert (string-trim-right x)))))
74 (defun sndio-increase ()
75 "Increase the volume for the input/output at point."
76 (interactive)
77 (when-let (x (sndio--current-io))
78 (when-let (val (sndio--run "-n" (concat x "=+" (number-to-string sndio-step))))
79 (sndio--update-value val))))
81 (defun sndio-decrease ()
82 "Decrease the volume for the input/output at point."
83 (interactive)
84 (when-let (x (sndio--current-io))
85 (when-let (val (sndio--run "-n" (concat x "=-" (number-to-string sndio-step))))
86 (sndio--update-value val))))
88 (defun sndio-mute ()
89 "Mute the input/output at point."
90 (interactive)
91 (when-let (x (sndio--current-io))
92 (when-let (val (sndio--run "-n" (concat x "=0")))
93 (sndio--update-value val))))
95 (defun sndio-toggle ()
96 "Toggle input/output at point."
97 (interactive)
98 (when-let (x (sndio--current-io))
99 (when-let (val (sndio--run "-n" (concat x "=!")))
100 (sndio--update-value val))))
102 ;;;###autoload
103 (defun sndio ()
104 "Launch sndio."
105 (interactive)
106 (switch-to-buffer "*sndio*")
107 (sndio-mode))
109 (provide 'sndio)
110 ;;; sndio.el ends here