commit c708ecad1fd81315da8c6d46efd3e43c1dd31f15 from: Omar Polo date: Sat Dec 19 09:54:31 2020 UTC initial commit commit - /dev/null commit + c708ecad1fd81315da8c6d46efd3e43c1dd31f15 blob - /dev/null blob + 534c7cfd2545e6320894a42d42d0254db0e6d293 (mode 644) --- /dev/null +++ sndio.el @@ -0,0 +1,108 @@ +;;; sndio.el --- Interact with sndio(8) -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Omar Polo + +;; Author: Omar Polo +;; Version: 1.0 +;; Keywords: multimedia +;; URL: https://git.omarpolo.com/sndioctl.el + +;;; Commentary: + +;; This package provides the sndio major mode to interact with +;; OpenBSD' sndio(8). + +;;; Code: + +(require 'cl-lib) + +(defvar sndioctl-cmd "sndioctl" + "Path to the sndioctl executable.") + +(defvar sndio-step 0.02 + "Step for `sndio-increase' and `sndio-decrease'.") + +(define-derived-mode sndio-mode special-mode "sndio" + "Major mode for sndio interaction." + + (define-key sndio-mode-map (kbd "n") #'forward-line) + (define-key sndio-mode-map (kbd "p") #'previous-line) + (define-key sndio-mode-map (kbd "i") #'sndio-increase) + (define-key sndio-mode-map (kbd "d") #'sndio-decrease) + (define-key sndio-mode-map (kbd "m") #'sndio-mute) + (define-key sndio-mode-map (kbd "t") #'sndio-toggle) + (define-key sndio-mode-map (kbd "g") #'sndio-update) + (define-key sndio-mode-map (kbd "d") #'kill-buffer) + + (buffer-disable-undo) + + (sndio-update)) + +(defun sndio-update () + "Update the current sndio buffer." + (interactive) + (with-current-buffer "*sndio*" + (save-excursion + (let ((inhibit-read-only t)) + (erase-buffer) + (process-file sndioctl-cmd nil (current-buffer) nil))))) + +(defun sndio--run (&rest args) + "Run `sndioctl-cmd' with ARGS yielding its output." + (with-temp-buffer + (when (zerop (apply #'process-file sndioctl-cmd nil t nil args)) + (buffer-string)))) + +(defun sndio--current-io () + "Yield the input/poutput at point as string." + (when-let (end (save-excursion + (beginning-of-line) + (ignore-errors (search-forward "=")))) + (buffer-substring-no-properties (line-beginning-position) + (1- end)))) + +(defun sndio--update-value (x) + "Update the value for the input/output at point setting it to X." + (save-excursion + (search-forward "=") + (let ((inhibit-read-only t)) + (delete-region (point) (line-end-position)) + (insert (string-trim-right x))))) + +(defun sndio-increase () + "Increase the volume for the input/output at point." + (interactive) + (when-let (x (sndio--current-io)) + (when-let (val (sndio--run "-n" (concat x "=+" (number-to-string sndio-step)))) + (sndio--update-value val)))) + +(defun sndio-decrease () + "Decrease the volume for the input/output at point." + (interactive) + (when-let (x (sndio--current-io)) + (when-let (val (sndio--run "-n" (concat x "=-" (number-to-string sndio-step)))) + (sndio--update-value val)))) + +(defun sndio-mute () + "Mute the input/output at point." + (interactive) + (when-let (x (sndio--current-io)) + (when-let (val (sndio--run "-n" (concat x "=0"))) + (sndio--update-value val)))) + +(defun sndio-toggle () + "Toggle input/output at point." + (interactive) + (when-let (x (sndio--current-io)) + (when-let (val (sndio--run "-n" (concat x "=!"))) + (sndio--update-value val)))) + +;;;###autoload +(defun sndio () + "Launch sndio." + (interactive) + (switch-to-buffer "*sndio*") + (sndio-mode)) + +(provide 'sndio) +;;; sndio.el ends here.