summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/eos/xmobar.el150
1 files changed, 150 insertions, 0 deletions
diff --git a/lib/eos/xmobar.el b/lib/eos/xmobar.el
new file mode 100644
index 0000000..4d27781
--- /dev/null
+++ b/lib/eos/xmobar.el
@@ -0,0 +1,150 @@
+;; xmobar.el --- Display xmobar text output -*- lexical-binding: t -*-
+
+;; Copyright 2022 jao <jao@gnu.org>
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "28.1"))
+;; Keywords: unix
+
+;; Heavily inspired by Steven Allen's https://github.com/Stebalien/i3bar.el
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Displays the output of an xmobar command in the Emacs mode-line (or tab-line).
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+
+(require 'xterm-color nil t)
+
+(defvar xmobar--last-update nil
+ "The last xmobar update received.")
+
+(defvar xmobar--process nil
+ "The running xmobar process, if any.")
+
+(defvar xmobar-string ""
+ "The xmobar string displayed in the mode-line.")
+
+(put 'xmobar-string 'risky-local-variable t)
+
+(defgroup xmobar nil
+ "xmobar status display for Emacs."
+ :version "0.0.1"
+ :group 'mode-line)
+
+(defcustom xmobar-command "xmobar"
+ "The xmobar command and flags."
+ :type '(choice (string :tag "Shell Command")
+ (repeat (string))))
+
+(defcustom xmobar-tab-bar t
+ "Whether to dispaly xmobar output in the tab bar."
+ :type 'boolean)
+
+(defcustom xmobar-tab-bar-format '(tab-bar-format-align-right xmobar-string)
+ "Format for the tab bar when `xmobar-tab-bar' is t."
+ :type 'list)
+
+(defvar xmobar--colorize-fn
+ (if (featurep 'xterm-color) #'xterm-color-filter #'ansi-color-apply))
+
+(defun xmobar-string () xmobar-string)
+
+;;;###autoload
+(define-minor-mode xmobar-mode
+ "Display an xmobar in the mode-line."
+ :global t :group 'xmobar
+ (xmobar--stop)
+ (when xmobar-mode
+ (if xmobar-tab-bar
+ (unless (memq 'xmobar-string tab-bar-format)
+ (setq tab-bar-format xmobar-tab-bar-format)
+ (tab-bar-mode))
+ (or global-mode-string (setq global-mode-string '("")))
+ (unless (memq 'xmobar-string global-mode-string)
+ (setq global-mode-string (append global-mode-string '(xmobar-string)))))
+ (xmobar--start)))
+
+(defun xmobar--update (update)
+ "Apply an UPDATE to the xmobar bar."
+ (setq xmobar--last-update (funcall xmobar--colorize-fn update))
+ (when xmobar-mode
+ (setq xmobar-string xmobar--last-update)
+ (force-mode-line-update t)))
+
+(defun xmobar--process-filter (proc string)
+ "Process output from the xmobar process."
+ (let ((buf (process-buffer proc)))
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ ;; Write the input to the buffer (might be partial).
+ (save-excursion
+ (goto-char (process-mark proc))
+ (insert string)
+ (set-marker (process-mark proc) (point)))
+ (when (string-match-p "\n$" string)
+ (xmobar--update (buffer-string))
+ (delete-region (point-min) (point-max)))))))
+
+(defun xmobar--process-sentinel (proc status)
+ "Handle events from the xmobar process (PROC).
+If the process has exited, this function stores the exit STATUS in
+`xmobar-string'."
+ (unless (process-live-p proc)
+ (setq xmobar--process nil)
+ (let ((buf (process-buffer proc)))
+ (when (and buf (buffer-live-p buf)) (kill-buffer buf)))
+ (setq xmobar--last-update nil
+ xmobar-string (format "xmobar: %s" status))))
+
+(defun xmobar--start ()
+ "Start xmobar."
+ (xmobar--stop)
+ (condition-case err
+ (setq xmobar--process
+ (make-process
+ :name "xmobar"
+ :buffer " *xmobar process*"
+ :stderr " *xmobar stderr*"
+ :command (ensure-list xmobar-command)
+ :connection-type 'pipe
+ :noquery t
+ :sentinel #'xmobar--process-sentinel
+ :filter #'xmobar--process-filter))
+ (error
+ (setq xmobar-string
+ (format "starting xmobar: %s" (error-message-string err))))))
+
+(defun xmobar--stop ()
+ "Stop xmobar."
+ (when (and xmobar--process (process-live-p xmobar--process))
+ (delete-process xmobar--process))
+ (setq xmobar-string "" xmobar--last-update nil))
+
+;;;###autoload
+(defun xmobar-restart ()
+ "Restart the xmobar program."
+ (interactive)
+ (unless xmobar-mode (user-error "The xmobar-mode is not enabled"))
+ (xmobar--start))
+
+(provide 'xmobar)
+;;; xmobar.el ends here