Add support for window manager mode via a nix module

This commit is contained in:
Sameer Rahmani 2024-04-19 18:39:42 +01:00
parent fb3073ca19
commit 916ee2674c
Signed by: lxsameer
GPG Key ID: 8741FACBF412FFA5
5 changed files with 254 additions and 16 deletions

View File

@ -57,12 +57,26 @@
};
};
fg42-wm = pkgs.callPackage ./nix/fg42 {
inherit nixpkgs;
modules = [
./nix/modules/editor
./nix/modules/elisp
./nix/modules/graphics
./nix/modules/noether
./nix/modules/wm
];
extraPackages = {
noether = inputs.noether.outputs.packages.${system}.default;
};
};
run-test-wm = pkgs.writeShellApplication {
name = "run-test-wm";
runtimeInputs = [ fg42 ];
runtimeInputs = [ fg42-wm ];
text = ''
DISPLAY=:1 ${fg42}/bin/fg42-wm
DISPLAY=:1 ${fg42-wm}/bin/fg42-wm
'';
};
@ -70,11 +84,12 @@
{
packages = {
default = fg42;
wm = fg42-wm;
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = [ fg42 pkgs.fish test-x run-test-wm ];
buildInputs = [ fg42 ];
nativeBuildInputs = [ fg42 fg42-wm pkgs.fish test-x run-test-wm ];
buildInputs = [ fg42 fg42-wm ];
};
apps.wm = {

View File

@ -30,17 +30,23 @@ let
then modules
else
import ../modules {
inherit pkgs;
lib = lib;
inherit pkgs lib;
};
pkgsModule = { config, ... }: {
config = {
_module.args.baseModules = modules;
_module.args.pkgs = lib.mkDefault pkgs;
_module.check = true;
};
};
utils = pkgs.callPackage ./utils.nix { };
final = lib.evalModules {
# The unit module is mandatory and the bare min
# config that is necessary
modules = [ ../modules/unit ] ++ fg42Modules ++ extraModules;
modules = [ ../modules/unit ] ++ fg42Modules ++ extraModules ++ [ pkgsModule ];
specialArgs = {
inherit utils;
inherit (utils) makeFG42Drv;

View File

@ -34,13 +34,5 @@ let
./c-family
./python
];
pkgsModule = { config, ... }: {
config = {
_module.args.baseModules = modules;
_module.args.pkgs = lib.mkDefault pkgs;
_module.check = true;
};
};
in
modules ++ [ pkgsModule ]
modules

View File

@ -0,0 +1,51 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program 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, version 2.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.wm;
deps =
(with pkgs.emacsPackages; [
exwm
]);
drv = makeFG42Drv {
pname = "wm";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.wm.enable = mkAndEnableOption "wm";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
dunst
]);
fg42.requires = [ drv.pname ];
};
}

View File

@ -0,0 +1,174 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program 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 of the License, or
;; (at your option) any later version.
;;
;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg)
(require 'fg42/config))
(defvar workspace-configuration
(list 0 "HDMI-1"
1 "HDMI-1"
2 "HDMI-1"
3 "HDMI-1"
4 "HDMI-1"
5 "HDMI-1"
6 "HDMI-1"
7 "HDMI-1"
8 "HDMI-1"
9 "HDMI-1")
"Workspace configuration for EXWM. (default 10 screens on HDMI-1).")
;; TODO: Document this
;; (add-hook 'exwm-randr-screen-change-hook
;; (lambda ()
;; (start-process-shell-command
;; "xrandr" nil "xrandr --output HDMI-1 --above eDP-1 --mode 1920x1080")))
(when-wm
(use! exwm-randr
"EXWM plugin to interact with xrandr."
:commands exwm-randr-enable
:config
(setq exwm-randr-workspace-output-plist workspace-configuration))
(use! exwm-systemtray
"Enables systemtray on EXWM"
:commands exwm-systemtray-enable)
;; (use! mini-frame
;; "Place minibuffer at the top of the current frame on `read-from-minibuffer'."
;; :hook (emacs-startup . mini-frame-mode)
;; :custom
;; (mini-frame-show-parameters
;; '((top . 10)
;; (width . 0.5)
;; (left . 0.5)
;; (height . 15))))
(use! exwm
"Emacs X Widnow manager."
:commands exwm-enable
:config
(require 'exwm-config)
(exwm-config-ido)
;; Set the initial number of workspaces (they can also be created later).
(setq exwm-workspace-number 10)
;; All buffers created in EXWM mode are named "*EXWM*". You may want to
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
;; are run when a new X window class name or title is available. Here's
;; some advice on this topic:
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
;; + For applications with multiple windows (e.g. GIMP), the class names of
;; all windows are probably the same. Using window titles for them makes
;; more sense.
;; In the following example, we use class names for all windows except for
;; Java applications and GIMP.
(add-hook 'exwm-update-class-hook
(lambda ()
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-title))))
;; Global keybindings can be defined with `exwm-input-global-keys'.
;; Here are a few examples:
(setq exwm-input-global-keys
`(
;; Bind "s-r" to exit char-mode and fullscreen mode.
([?\s-r] . exwm-reset)
([?\s-g] . keyboard-quit)
([8388640] . other-window)
;; Bind "s-w" to switch workspace interactively.
([?\s-w] . exwm-workspace-switch)
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
;; Bind "s-&" to launch applications ('M-&' also works if the output
;; buffer does not bother you).
([?\s-d] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
;; Bind "s-<f2>" to "slock", a simple X display locker.
([s-f2] . (lambda ()
(interactive)
(start-process "" nil "slock")))))
;; To add a key binding only available in line-mode, simply define it in
;; `exwm-mode-map'. The following example shortens 'C-c q' to 'C-q'.
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
(push ?\C-c exwm-input-prefix-keys)
;; You can hide the minibuffer and echo area when they're not used, by
;; uncommenting the following line.
;;(setq exwm-workspace-minibuffer-position 'bottom)
;; The following example demonstrates how to use simulation keys to mimic
;; the behavior of Emacs. The value of `exwm-input-simulation-keys` is a
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
;; and DEST is what EXWM actually sends to application. Note that both SRC
;; and DEST should be key sequences (vector or string).
(setq exwm-input-simulation-keys
`(
;; movement
(,(kbd "C-b") . left)
(,(kbd "M-b") . ,(kbd "C-<left>"))
(,(kbd "C-f") . right)
(,(kbd "M-f") . ,(kbd "C-<right>"))
(,(kbd "C-p") . up)
(,(kbd "C-n") . down)
(,(kbd "C-a") . home)
(,(kbd "C-e") . end)
(,(kbd "M-v") . prior)
(,(kbd "C-v") . next)
(,(kbd "C-d") . delete)
;;(,(kbs "C-k") . [S-end delete])
;; navigation
(,(kbd "C-c b") . ,(kbd "M-<left>"))
(,(kbd "C-c f") . ,(kbd "M-<right>"))
(,(kbd "C-c w") . ,(kbd "C-w"))
(,(kbd "C-w") . ,(kbd "C-x"))
(,(kbd "M-w") . ,(kbd "C-c"))
(,(kbd "C-y") . ,(kbd "C-v"))
;; search
(,(kbd "C-s") . ,(kbd "C-f"))))))
(provide 'fg42/wm)
;;; wm.el ends here