~magic_rb/dotfiles

3060a2d6b90e5d694a660d8f376ac3e0df2b08b1 — Magic_RB 9 months ago 6bab5c1
Rework xmonad with polybar and add emacs-rofi

Signed-off-by: Magic_RB <magic_rb@redalder.org>
A emacs-lisp/emacs_rofi.org => emacs-lisp/emacs_rofi.org +54 -0
@@ 0,0 1,54 @@
:PROPERTIES:
:header-args:emacs-lisp: :comments link :results none
:ID:       0d92c672-5ac7-44dc-b021-cc58544f8eea
:END:
#+title: Emacs Rofi
#+filetags: emacs-load
It is possible to make a fake rofi, from emacs ~completing-read~. This file facilitates that. First we define some LISP functions.

#+begin_src emacs-lisp
  (defun completing-read-frame-popup-file (prompt file width height &rest args)
    ""
    (with-temp-buffer
      (insert-file-contents file)
      (message "%s" (string-lines (buffer-string)))
      (apply #'completing-read-frame-popup prompt (string-lines (substring-no-properties (buffer-string))) args)))
#+end_src

#+begin_src emacs-lisp
  (defun completing-read-frame-popup (prompt collection &rest args)
    ""
    (let ((frame (make-frame `((minibuffer . only)
                               (name . "emacs-completing-read-float")
                               (unsplittable . t)
                               (no-other-frame . t)
                               (width . ,width)
                               (height . ,height)
                               (left . 0.5)
                               (top . 0.5)))))
      (with-selected-frame frame
        (unwind-protect
            (let ((selection (apply #'completing-read prompt collection args)))
              (delete-frame frame)
              selection)
          (delete-frame frame)))))
#+end_src

Next a bash helper is needed.

#+begin_src shell
  function emacs-rofi()
  {
      tmp=$(mktemp)
      tee > $tmp
      emacs -Q --batch --eval $"(progn (require 'server) (princ (format \"%s\\n\" (server-eval-at \"server\" '(completing-read-frame-popup-file \"$1\" \"$tmp\" $2 $3)))))"
      rm $tmp
  }
#+end_src

Which then ought to be used like so.

#+begin_src shell
  echo -e "test1\ntest2\ntest3" | emacs-rofi "test"
#+end_src


M home-manager/modules/cmdline-utils.nix => home-manager/modules/cmdline-utils.nix +1 -0
@@ 58,6 58,7 @@ in {
      # ffmpegSpecial
      lm_sensors
      cryptsetup
      emacs-rofi
    ];
  };
}

M home-manager/modules/xmonad/default.nix => home-manager/modules/xmonad/default.nix +37 -21
@@ 51,36 51,52 @@ in {
      name = "xmonad.hs";
      file = ./xmonad.hs;
      substitutes = {
        "xmobar" = "${pkgs.xmobar}/bin/xmobar";
        "xmobarConfig" = ./xmobarrc;
        "screenshot" = "${pkgs.magic_rb.screenshot}/bin/screenshot";
        "dmenu_run" = "${pkgs.dmenu}/bin/dmenu_run";
        "emacs-rofi" = lib.getExe pkgs.emacs-rofi;
        "auxmenu" = pkgs.writeShellScript "auxmenu"
          ''
            _options="toggle-mic\ntoggle-radio"

        "dunst" = "${pkgs.dunst}/bin/dunst";
        "enableDunst" =
          if cfg.enableDunst
          then "True"
          else "False";
            _option="$(echo -e $_options | emacs-rofi "command: " 90 30 | awk '{print $1}' | tr -d '\r\n')"
            if [ ''${#_option} -gt 0 ]
            then
              case $_option in
                toggle-mic)
                  wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
                  ;;
                toggle-radio)
                  if [ "$(nmcli radio wifi)" = "enabled" ]
                  then
                    nmcli radio wifi off
                  else
                    nmcli radio wifi on
                  fi
                  ;;
                *)
                  ;;
              esac
            fi
          '';
        "dmenu_run" = "${pkgs.dmenu}/bin/dmenu_run";
        "polybar" = pkgs.writeShellScript "polybar"
          ''
            monitors=$(polybar --list-monitors | cut -f 1 -d':')
            MONITOR=''${monitors[$1]} ${lib.getExe pkgs.polybarFull} -c ${./polybar.ini} top
          '';
        "dunst" = lib.getExe pkgs.dunst;
        "dunstConfig" = ./dunstrc;

        "picom" = "${pkgs.picom}/bin/picom";
        "enablePicom" =
          if cfg.enablePicom
          then "True"
          else "False";
        "picom" = lib.getExe pkgs.picom;
        "picomConfig" = ./picom.conf;
        "experimentalBackends" =
        "picomArgs" =
          if cfg.picomExperimentalBackends
          then "--experimental-backends"
          else "";

        "keynav" = "${pkgs.keynav}/bin/keynav";
        "enableKeynav" =
          if cfg.enableKeynav
          then "True"
          else "False";

        "lightLocker" = "${pkgs.lightlocker}/bin/light-locker";
        "keynav" = lib.getExe pkgs.keynav;
        "lightLocker" = lib.getExe pkgs.lightlocker;
        "lightLockerCommand" = "${pkgs.lightlocker}/bin/light-locker-command";
        "brightnessctl" = lib.getExe pkgs.brightnessctl;
      };
    };
  };

A home-manager/modules/xmonad/polybar.ini => home-manager/modules/xmonad/polybar.ini +184 -0
@@ 0,0 1,184 @@
[colors]
background = #282A2E
background-alt = #373B41
foreground = #C5C8C6
primary = #F0C674
secondary = #8ABEB7
alert = #A54242
disabled = #707880

[bar/top]
monitor = ${env:MONITOR:}
height = 10pt

font-0 = Fixed;2

modules-left = battery backlight xworkspaces
modules-right = filesystem pulseaudio memory cpu wlan eth xkeyboard date

module-margin = 1

separator = |
separator-foreground = ${colors.disabled}

border-size = 1pt
border-color = #222222

enable-ipc = true

tray-position = right

[module/battery]
type = internal/battery

full-at = 100

# format-low once this charge percentage is reached
# Default: 10
# New in version 3.6.0
low-at = 20

# Use the following command to list batteries and adapters:
# $ ls -1 /sys/class/power_supply/
battery = BAT0
adapter = ADP1

# If an inotify event haven't been reported in this many
# seconds, manually poll for new values.
#
# Needed as a fallback for systems that don't report events
# on sysfs/procfs.
#
# Disable polling by setting the interval to 0.
#
# Default: 5
poll-interval = 5

format-low = <label-low>
label-low = %{F#FF0000}! %percentage%

label-charging = %{F#F0C674}c%{F-} %percentage%%
label-discharging = %{F#F0C674}d%{F-} %percentage%%
label-full = %{F#F0C674}-%{F-} %percentage%%

[module/backlight]
type = internal/backlight

# Use the following command to list available cards:
# $ ls -1 /sys/class/backlight/
card = intel_backlight

label = %{F#F0C674}b%{F-} %percentage%%

# Use the `/sys/class/backlight/.../actual-brightness` file
# rather than the regular `brightness` file.
# Defaults to true unless the specified card is an amdgpu backlight.
# New in version 3.6.0
use-actual-brightness = true

[module/xworkspaces]
type = internal/xworkspaces

label-active = %name%
label-active-background = ${colors.background-alt}
label-active-underline= ${colors.primary}
label-active-padding = 1

label-occupied = %name%
label-occupied-padding = 1

label-urgent = %name%
label-urgent-background = ${colors.alert}
label-urgent-padding = 1

label-empty =
# label-empty-foreground = ${colors.disabled}
# label-empty-padding = 1

pin-workspaces = true

enable-click = false
enable-scroll = false

[module/filesystem]
type = internal/fs
interval = 25

mount-0 = /
mount-1 = /nix/store
mount-2 = /home

label-mounted = %{F#F0C674}%mountpoint%%{F-} %used%

label-unmounted = %mountpoint% not mounted
label-unmounted-foreground = ${colors.disabled}

[module/pulseaudio]
type = internal/pulseaudio

format-volume-prefix = "VOL "
format-volume-prefix-foreground = ${colors.primary}
format-volume = <label-volume>

label-volume = %percentage%%

label-muted = muted
label-muted-foreground = ${colors.disabled}

interval = 0

[module/xkeyboard]
type = internal/xkeyboard
blacklist-0 = num lock

label-layout = %icon%
label-layout-foreground = ${colors.primary}

label-indicator-on =
label-indicator-off =

layout-icon-default = some-icon
layout-icon-0 = de;koy;koy
layout-icon-1 = us;us
layout-icon-2 = mine;mine;mine
layout-icon-3 = de;neo;neo

[module/memory]
type = internal/memory
interval = 2
format-prefix = "RAM "
format-prefix-foreground = ${colors.primary}
label = %percentage_used:2%%

[module/cpu]
type = internal/cpu
interval = 2
format-prefix = "CPU "
format-prefix-foreground = ${colors.primary}
label = %percentage-cores:2%

[network-base]
type = internal/network
interval = 5
format-connected = <label-connected>
format-disconnected = <label-disconnected>
label-disconnected = %{F#F0C674}%ifname%%{F#707880} disconnected

[module/wlan]
inherit = network-base
interface-type = wireless
label-connected = %{F#F0C674}%ifname%%{F-} %essid% %local_ip% %{F#707880},%{F-} %upspeed% %downspeed%

[module/eth]
inherit = network-base
interface-type = wired
label-connected = %{F#F0C674}%ifname%%{F-} %local_ip% %{F#707880},%{F-} %upspeed% %downspeed%

[module/date]
type = internal/date
interval = 1

date = %Y-%m-%d %H:%M:%S

label = %date%
label-foreground = ${colors.primary}

M home-manager/modules/xmonad/xmobarrc => home-manager/modules/xmonad/xmobarrc +7 -8
@@ 17,7 17,7 @@ Config {
   -- layout
   , sepChar =  "%"   -- delineator between plugin names and straight text
   , alignSep = "}{"  -- separator between left-right alignment
   , template = "%StdinReader% | %battery% | %multicpu% | %multicoretemp% | %memory% | %dynnetwork% }{ %date% || %kbd% "
   , template = "%_XMONAD_LOG% | %battery% | %multicpu% | %multicoretemp% | %memory% | %dynnetwork% }{ %date% || %kbd% "

   -- general behavior
   , lowerOnStart =     True    -- send to bottom of window stack on start


@@ 83,7 83,7 @@ Config {
                             , "--low"      , "green"
                             , "--normal"   , "orange"
                             , "--high"     , "red"
                             , "--minwidth" , "3"
                             , "--minwidth" , "2"
                             ] 10

        -- battery monitor


@@ 93,15 93,14 @@ Config {
                             , "--low"      , "red"
                             , "--normal"   , "orange"
                             , "--high"     , "green"
                             , "--width" , "8"

                             , "--width"    , "6"
                             , "--" -- battery specific options
                                       -- discharging status
                                       , "-o"	, "<left>% (<timeleft>)"
                                       , "-o", "<left>% (<timeleft>)"
                                       -- AC "on" status
                                       , "-O"	, "<left>% <fc=#dAA520>Charging</fc>"
                                       , "-O", "<left>% <fc=#dAA520>Charging</fc>"
                                       -- charged status
                                       , "-i"	, "<left>% <fc=#00e200>Charged</fc>"
                                       , "-i", "<left>% <fc=#00e200>Charged</fc>"
                             ] 50

        -- time and date indicator


@@ 110,6 109,6 @@ Config {

        -- keyboard layout indicator
        , Run Kbd            [ ]
        , Run StdinReader
        , Run XPropertyLog "_XMONAD_LOG"
        ]
   }

M home-manager/modules/xmonad/xmonad.hs => home-manager/modules/xmonad/xmonad.hs +42 -76
@@ 14,6 14,7 @@
import XMonad
import Data.Monoid
import Data.Function
import Data.Functor
import System.Exit
import XMonad.Util.EZConfig
import XMonad.Util.SpawnOnce


@@ 25,6 26,7 @@ import XMonad.Layout.Tabbed
import XMonad.Layout.NoBorders
import XMonad.Util.WorkspaceCompare
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.StatusBar
import XMonad.Actions.UpdatePointer
import XMonad.Actions.FloatKeys



@@ 33,34 35,12 @@ import Control.Monad
import qualified XMonad.StackSet as W
import qualified Data.Map        as M

-- The preferred terminal program, which is used in a binding below and by
-- certain contrib modules.
--
myTerminal :: String
myTerminal = "xterm"

xmobarCmd :: String
xmobarCmd = "@xmobar@ @xmobarConfig@"

-- Whether focus follows the mouse pointer.
myFocusFollowsMouse :: Bool
myTerminal = "xterm"
myFocusFollowsMouse = True

-- Whether clicking on a window to focus also passes the click to the window
myClickJustFocuses :: Bool
myClickJustFocuses = False


-- The default number of workspaces (virtual screens) and their names.
-- By default we use numeric strings, but any string may be used as a
-- workspace name. The number of workspaces is determined by the length
-- of this list.
--
-- A tagging example:
--
-- > workspaces = ["web", "irc", "code" ] ++ map show [4..9]
--
myWorkspaces    = map show [0..9]
myWorkspaces    = map show ([1..9] ++ [0])

toggleFloat = withFocused (\windowId -> do
                              { floats <- gets (W.floating . windowset);


@@ 156,7 136,15 @@ myKeymap c =
     , ("M-S-l", withFocused (xMoveWindow (  0,-10)))
     , ("M-S-ß", withFocused (xMoveWindow ( 10,  0)))

     , ("M-z", spawn "@lightLocker@ --lock")
     , ("M-z", spawn "@lightLockerCommand@ --lock")

     , ("<XF86AudioMute>"         , spawn "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")
     , ("<XF86AudioRaiseVolume>"  , spawn "wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+")
     , ("<XF86AudioLowerVolume>"  , spawn "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-")
     , ("<XF86MonBrightnessUp>"   , spawn "@brightnessctl@ set +5%")
     , ("<XF86MonBrightnessDown>" , spawn "@brightnessctl@ set 5%-")

     , ("M-<F1>", spawn "@auxmenu@")
    ]
    ++



@@ 230,51 218,6 @@ myLayout = smartBorders tiled ||| smartBorders simpleTabbed ||| smartBorders emp
     -- Percent of screen to increment by when resizing panes
     delta   = 3/100

------------------------------------------------------------------------
-- Window rules:

-- Execute arbitrary actions and WindowSet manipulations when managing
-- a new window. You can use this to, for example, always float a
-- particular program, or have a client always appear on a particular
-- workspace.
--
-- To find the property name associated with a program, use
-- > xprop | grep WM_CLASS
-- and click on the client you're interested in.
--
-- To match on the WM_NAME, you can use 'title' in the same way that
-- 'className' and 'resource' are used below.
--
myManageHook = composeAll
    [ -- className =? "MPlayer"        --> doFloat
   -- , className =? "Gimp"           --> doFloat
    -- , resource  =? "desktop_window" --> doIgnore
    -- , resource  =? "kdesktop"       --> doIgnore
    ]

------------------------------------------------------------------------
-- Status bars and logging

-- Perform an arbitrary action on each internal state change or X event.
-- See the 'XMonad.Hooks.DynamicLog' extension for examples.
--
myLogHook = updatePointer (0.5, 0.5) (1, 1)

------------------------------------------------------------------------
-- Startup hook

-- Perform an arbitrary action each time xmonad starts or is restarted
-- with mod-q.  Used by, e.g., XMonad.Layout.PerWorkspace to initialize
-- per-workspace layout choices.
--
-- By default, do nothing.
myStartupHook = do
  when @enableDunst@ (spawnOnce "@dunst@ -config @dunstConfig@")
  when @enablePicom@ (spawnOnce "@picom@ --config @picomConfig@ @experimentalBackends@")
  when @enableKeynav@ (spawnOnce "@keynav@")
  spawnOnce "@lightLocker@ --lock-on-suspend"
  spawnOnce xmobarCmd

myPP = def
   { ppLayout = const ""  -- Don't show the layout name
   , ppSort = getSortByXineramaRule  -- Sort left/right screens on the left, non-empty workspaces after those


@@ 283,14 226,17 @@ myPP = def
   , ppVisible = wrap "(" ")"  -- Non-focused (but still visible) screen
   }

spawnBar :: ScreenId -> IO StatusBarConfig
spawnBar screen = pure $ statusBarPropTo "_XMONAD_LOG" ("@polybar@ " <> (show (fromIntegral screen :: Int))) (pure myPP)

------------------------------------------------------------------------
-- Now run xmonad with all the defaults we set up.

-- Run xmonad with the settings you specify. No need to modify this.
--
-- main = xmonad $ ewmh $ docks $ defaults
main = xmonad . ewmh =<< statusBar xmobarCmd myPP toggleStrutsKey defaults
toggleStrutsKey XConfig { XMonad.modMask = modMask } = (modMask, xK_b)
main = do
  pure defaults <&> dynamicSBs spawnBar <&> docks >>= xmonad

-- A structure containing your configuration settings, overriding
-- fields in the default config. Any you don't override, will


@@ 313,14 259,34 @@ defaults = let

      -- hooks, layouts
      layoutHook         = avoidStruts $ myLayout,
      manageHook         = manageDocks <+> myManageHook,
      logHook            = myLogHook,
      startupHook        = myStartupHook,

      -- To find the property name associated with a program, use
      -- > xprop | grep WM_CLASS
      -- and click on the client you're interested in.
      --
      -- To match on the WM_NAME, you can use 'title' in the same way that
      -- 'className' and 'resource' are used below.
      manageHook         = manageDocks <+> composeAll
        [ title =? "emacs-completing-read-float"        --> doFloat
        -- , className =? "Gimp"           --> doFloat
        -- , resource  =? "desktop_window" --> doIgnore
        -- , resource  =? "kdesktop"       --> doIgnore
        ],

      logHook            =
        updatePointer (0.5, 0.5) (1, 1),

      -- XMonad.Layout.PerWorkspace
      startupHook        = do
        spawnOnce "@dunst@ -config @dunstConfig@"
        spawnOnce "@picom@ --config @picomConfig@ @picomArgs@"
        spawnOnce "@keynav@"
        spawnOnce "@lightLocker@ --lock-on-suspend",

      -- Looks
      focusedBorderColor = "#5c5c5c",
      normalBorderColor = "#222222",
      borderWidth = 2
      borderWidth = 4
    }
  in additionalKeysP c (myKeymap c)
   & flip additionalKeys [ ((mod1Mask, xK_v), return ()) ]

A overlays/emacs-rofi/default.nix => overlays/emacs-rofi/default.nix +10 -0
@@ 0,0 1,10 @@
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
{
  name = "emacs-rofi";
  overlays = [];
  overlay = {}: final: prev: {
    emacs-rofi = final.writeShellScriptBin "emacs-rofi" (builtins.readFile ./emacs-rofi);
  };
}

A overlays/emacs-rofi/emacs-rofi => overlays/emacs-rofi/emacs-rofi +9 -0
@@ 0,0 1,9 @@
# -*- mode: shell-script; -*-
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

tmp=$(mktemp)
tee > $tmp
emacs -Q --batch --eval $"(progn (require 'server) (princ (format \"%s\\n\" (server-eval-at \"server\" '(completing-read-frame-popup-file \"$1\" \"$tmp\" $2 $3)))))"
rm $tmp