This file documents my NixOS configuration. To use, all you need to do is enable flakes and run
sudo nixos-rebuild switch --flake "github:maxastyler/literate-nixos?dir=install-flake"
This command uses emacs to tangle the code in this file into a system configuration, and then installs it.
I use org babel’s interpolation throughout this config. Whenever you see code like:
<<some-name>>
The code block with #+name: some-name
is interpolated into that position.
If you want to see the full interpolated files, open this file in emacs and use the function org-babel-tangle
.
This function is called in the installation flake to generate the config.
{ self, nixpkgs, home-manager, emacs-overlay, ... }@attrs: {
nixosConfigurations.cheeky-monkey = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = attrs;
modules = [
(./configuration.nix)
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.max = import ./home-manager.nix;
}
];
};
}
The hardware configuration for my laptop - autogenerated by nix, so I don’t want to touch it 😊
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/4913b9d4-05bf-41e9-8c9e-276e87e42892";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/82F9-11A3";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/89c4f470-6ec7-4536-a318-d83a2def4f8b"; }
];
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
The main configuration for the root system. It’s a function which takes in an attribute set and returns another attribute set with settings defined.
{ config, pkgs, home-manager, emacs-overlay, ... }:
{
imports = [
./hardware-configuration.nix
./modules
];
<<main-configuration-inner>>
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.11"; # Did you read the comment?
}
I want to use unstable nix packages (cutting edge please!) and enable flakes.
nix = {
package = pkgs.nixUnstable;
extraOptions = ''
experimental-features = nix-command flakes
keep-outputs = true
keep-derivations = true
'';
};
I’ll add in the emacs overlay and allow unfree software.
nixpkgs = {
overlays = [ emacs-overlay.overlay ];
config.allowUnfree = true;
};
I want to use the latest kernel (got a new thinkpad laptop, and the wireless card needs the newest drivers).
I’ve got full disk encryption, so I let nix know which partition it’s on.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.initrd.luks.devices = {
crypted = {
device = "/dev/disk/by-partuuid/7820a35d-c583-4656-a716-968f83ea55b0";
allowDiscards = true;
preLVM = true;
};
};
I set the machine’s hostname, and I tell it I want to use networkmanager.
The comment about DHCP was generated there. Thanks nixos.
I enable openssh so I can ssh into this machine if needed.
networking.hostName = "cheeky-monkey"; # Define your hostname.
networking.networkmanager.enable = true;
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.enp2s0f0.useDHCP = true;
networking.interfaces.enp5s0.useDHCP = true;
services.openssh.enable = true;
American defaults are NOT WHAT I WANT.
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
};
services.xserver.layout = "gb";
I want to be able to run OpenGL stuff, and dri is used to enable vulkan I think? That’s what it seems like here.
hardware.opengl = {
enable = true;
driSupport = true;
};
I’ll use bluetooth and pulseaudio
sound.enable = true;
hardware.pulseaudio.enable = true;
hardware.bluetooth.enable = true;
services.blueman.enable = true;
Libinput for input stuff. It works with x and wayland.
services.xserver.libinput.enable = true;
Enable adb for android interaction
programs.adb.enable = true;
Just little old me. I add in networkmanager group for user control of network stuff and video for some reason (can’t remember why, but I need it…) Use passwd to set the account password the first time. I’ll maybe turn off mutable users later…
users.users.max = {
isNormalUser = true;
extraGroups =
[ "wheel" "sudo" "networkmanager" "video" "adbusers" ];
};
This is extra stuff I want available in the system. I override firefox with passff-host
so I can use
the pass password manager with it. I use python 3.10 as the default interpreter on the system, with a few packages
I tend to use a lot.
I use latex for writing things and making plots look nice, so it’s useful to have it installed globally.
environment.systemPackages = with pkgs; [
(firefox.override { extraNativeMessagingHosts = [ passff-host ]; })
(python310.withPackages (ps: with ps; [ numpy scipy matplotlib pyrsistent poetry ]))
black
cmake
fd
gcc
git
gnome3.gnome-tweaks
gnumake
gnupg
jetbrains.idea-ultimate
libtool
libvterm
mpv
nixfmt
pass
pyright
racket
ripgrep
rnix-lsp
texlab
texlive.combined.scheme-full
texmacs
tmux
unzip
vim
wget
];
programs.steam.enable = true;
programs.sway-complete.enable = true;
services.printing.enable = true;
These are my modules for configuring the system that are imported by the main configuration file. A module is just a function which takes in a configuration, and some packages and returns a configuration. The configuration is an attribute set of options, and things to do when those options are set.
A default.nix
file, so I don’t need to name all the modules in the main config file.
{ ... }: { imports = [ ./sway-complete.nix ]; }
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.programs.sway-complete;
in {
<<sway-system-configuration-options>>
config = mkIf cfg.enable {
<<sway-system-configuration-config>>
};
}
I’ll only define one option, just to enable this module.
options.programs.sway-complete = {
enable = mkEnableOption "Complete Installation of Sway";
};
programs.sway-complete.enable = true
), then define this stuff.
We want to use sway (🤤)
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
};
And initialise it on login
environment.loginShellInit = ''
if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
exec sway
fi
'';
Create a service for swayidle, to turn off the screen on idling.
systemd.user.services.swayidle = {
description = "Idle Manager for Wayland";
documentation = [ "man:swayidle(1)" ];
wantedBy = [ "sway-session.target" ];
partOf = [ "graphical-session.target" ];
path = [ pkgs.bash ];
serviceConfig = {
ExecStart = ''
${pkgs.swayidle}/bin/swayidle -w -d \
timeout 300 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \
resume '${pkgs.sway}/bin/swaymsg "output * dpms on"'
'';
};
};
And we’ll need all these extra packages.
environment.systemPackages = with pkgs; [
grim
slurp
pavucontrol
swaylock
swayidle
wl-clipboard
mako
wofi
gtk-engine-murrine
gtk_engines
gsettings-desktop-schemas
lxappearance
brightnessctl
font-awesome
networkmanagerapplet
];
{ pkgs, lib, ... }: {
imports = [ ./home-manager-modules ];
<<home-configuration-inner>>
}
Letting the computer know who’s home.
home.username = "max";
home.homeDirectory = "/home/max";
home.stateVersion = "22.05";
programs.home-manager.enable = true;
I use bash as my shell. Would use fish, but it doesn’t work as well with nixos - or at least it didn’t last time I tried. I’ll define two functions which are used in vterm to let emacs track which folder it’s in.
programs.bash = {
enable = true;
bashrcExtra = ''
vterm_printf(){
if [ -n "$TMUX" ] && ([ "''${TERM%%-*}" = "tmux" ] || [ "''${TERM%%-*}" = "screen" ] ); then
# Tell tmux to pass the escape sequences through
printf "\ePtmux;\e\e]%s\007\e\\" "$1"
elif [ "''${TERM%%-*}" = "screen" ]; then
# GNU screen (screen, screen-256color, screen-256color-bce)
printf "\eP\e]%s\007\e\\" "$1"
else
printf "\e]%s\e\\" "$1"
fi
}
vterm_prompt_end(){
vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
}
PS1=$PS1'\[$(vterm_prompt_end)\]'
'';
};
Emacs > Vim >>>>>>>> vscode
I want to use the emacsGcc package from the emacs overlay, which is emacs with byte-compilation. Speedy. I also enable the emacs service, so I can use emacsclient instead of waiting years for emacs to start.
programs.emacs = {
enable = true;
package = pkgs.emacsPgtkNativeComp;
extraPackages = (epkgs: with epkgs; [
all-the-icons
auctex
blacken
cdlatex
cider
clojure-mode
company
dap-mode
direnv
direnv
doom-modeline
edit-indirect
elixir-mode
flycheck
glsl-mode
helm
helm-projectile
helm-rg
helm-c-yasnippet
hy-mode
julia-mode
julia-repl
kaolin-themes
lsp-julia
lsp-mode
lsp-pyright
lsp-ui
magit
markdown-mode
mix
nix-mode
nov
org
org-bullets
org-roam
pdf-tools
projectile
projectile-ripgrep
protobuf-mode
python
python-pytest
racket-mode
rg
ripgrep
rustic
treemacs
treemacs-magit
treemacs-projectile
treemacs-icons-dired
typescript-mode
undo-tree
use-package
vterm
which-key
yaml-mode
yasnippet
yasnippet-snippets
]);
};
home.file.".emacs.d/init.el".source = ./emacs.el;
services.emacs = {
enable = true;
client.enable = true;
socketActivation.enable = true;
};
Git settings. Self explanatory…
programs.git = {
enable = true;
userName = "Max Tyler";
userEmail = "maxastyler@gmail.com";
extraConfig = { init.defaultBranch = "master"; };
};
Direnv is a useful tool which can automatically switch environment when you change directory.
It’s super useful with nix.
The nix-direnv
submodule replaces the usual use_nix
function with one which caches stuff, so it’s faster.
But I’m using flakes anyway (use_flake
), so this doesn’t really matter.
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
GPG agent manages my gpg keys. I enable ssh support so that it can work as an ssh authentication key too. Default cache ttl is the time (in seconds) before it asks for the password again. Add in the pinentry options to allow emacs to enter the pin through the minibuffer. I use the gtk2 pinentry, because other things seem to not work. If I use vterm in emacs, then try to do pinentry it tries to run the curses pinentry and gets wobbled.
services.gpg-agent = {
enable = true;
defaultCacheTtl = 7200;
enableSshSupport = true;
pinentryFlavor = "gtk2";
extraConfig = ''
allow-emacs-pinentry
allow-loopback-pinentry
'';
};
Just some extra packages n stuff that are pretty self explanatory. Alacritty is a fast terminal written in rust. Feh is a simple image viewer.
home.packages = with pkgs; [ htop teams pinentry-gtk2 ];
programs.alacritty.enable = true;
programs.feh.enable = true;
{ ... }: { imports = [ ./sway-configuration.nix ]; }
My personal configuration for sway. I use waybar as the bar, which i define in a separate file.
I set the input options to gb
by default, and use caps lock as ctrl except on my HHKB, which is sadly in US layout.
Then I set the keybindings, which are just an attribute set of string to string.
{ config, lib, pkgs, ... }@attrs:
let modifier = config.wayland.windowManager.sway.config.modifier;
in {
programs.waybar = {
enable = true;
systemd.enable = true;
settings = import ./waybar-config.nix attrs;
};
wayland.windowManager.sway = {
enable = true;
wrapperFeatures.gtk = true;
config = {
bars = [ ];
modifier = "Mod4";
input = {
"*" = {
xkb_layout = "gb";
xkb_options = "ctrl:nocaps";
};
"2131:256:Topre_Corporation_HHKB_Professional" = { xkb_layout = "us"; };
"2:7:SynPS/2_Synaptics_TouchPad" = {
tap = "enabled";
tap_button_map = "lrm";
natural_scroll = "enabled";
};
"2:10:TPPS/2_Elan_TrackPoint" = {
accel_profile = "flat";
pointer_accel = "1.0";
};
};
};
config.keybindings = lib.mkOptionDefault {
# open terminal
"${modifier}+Return" = "exec ${pkgs.alacritty}/bin/alacritty";
# open emacs
"${modifier}+Shift+Return" = "exec 'emacsclient -c'";
# Brightness
"XF86MonBrightnessDown" =
"exec '${pkgs.brightnessctl}/bin/brightnessctl set 2%-'";
"XF86MonBrightnessUp" =
"exec '${pkgs.brightnessctl}/bin/brightnessctl set +2%'";
# lock the screen
"${modifier}+End" = "exec '${pkgs.swaylock}/bin/swaylock --ring-color black --line-color 000000 --inside-color 000000 --line-color 000000 --ring-color 000000 --key-hl-color ffffff'";
# Volume
"XF86AudioRaiseVolume" = "exec 'pactl set-sink-volume @DEFAULT_SINK@ +1%'";
"XF86AudioLowerVolume" = "exec 'pactl set-sink-volume @DEFAULT_SINK@ -1%'";
"XF86AudioMute" = "exec 'pactl set-sink-mute @DEFAULT_SINK@ toggle'";
"XF86AudioMicMute" = "exec 'pactl set-source-mute @DEFAULT_SOURCE@ toggle'";
# screenshots
"Print" = "exec ${pkgs.grim}/bin/grim";
"XF86SelectiveScreenshot" = "exec '${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp)\"'";
};};
}
The waybar configuration is a 1 to 1 translation of a waybar json config into nix attribute sets. The config schema can be found here.
{ config, ... }: {
mainBar = {
modules-left = [ "idle_inhibitor" "sway/window" ];
modules-center = [ "sway/workspaces" "sway/mode" ];
modules-right = [ "pulseaudio" "network" "battery" "clock" "tray" ];
"sway/workspaces" = {
disable-scroll = true;
all-outputs = true;
};
"network" = {
"format" = "{ifname}";
"format-wifi" = "{essid} ({signalStrength}%) ";
"format-ethernet" = "{ipaddr}/{cidr} ";
"format-disconnected" = "";
"tooltip-format" = "{ifname} via {gwaddr} ";
"tooltip-format-wifi" = "{essid} ({signalStrength}%) ";
"tooltip-format-ethernet" = "{ifname} ";
"tooltip-format-disconnected" = "Disconnected";
"max-length" = 50;
};
"sway/window" = { "max-length" = 50; };
"battery" = {
"format" = "{capacity}% {icon}";
"format-icons" = [ "" "" "" "" "" ];
};
"clock" = { "format-alt" = "{:%a, %d. %b %H:%M}"; };
"pulseaudio" = {
"format" = "{volume}% {icon}";
"format-bluetooth" = "{volume}% {icon}";
"format-muted" = "";
"format-icons" = {
"headphone" = "";
"hands-free" = "";
"headset" = "";
"phone" = "";
"portable" = "";
"car" = "";
"default" = [ "" "" ];
};
"scroll-step" = 1;
"on-click" = "pavucontrol";
};
"idle_inhibitor" = {
"format" = "{icon}";
"format-icons" = {
"activated" = "";
"deactivated" = "";
};
};
};
}
This is the emacs configuration.
Turn off stuff the menu bars…
(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
And ensure the use-package
function always installs stuff.
(setq use-package-always-ensure t)
(setq-default
epa-pinentry-mode 'loopback ;; use emacs for gpg pinentry
confirm-kill-emacs 'yes-or-no-p ;; confirmation when killing emacs
indent-tabs-mode nil ;; don't use tabs to indent
select-enable-clipboard t ;; use the system's clipboard
gc-cons-threshold 3200000
doc-view-continuous t ;; scroll over pages in doc mode
custom-file (expand-file-name "custom.el" user-emacs-directory) ;; use this file as the custom file
python-shell-interpreter "python3" ;; use python3 as the default python shell
dired-listing-switches "-alh" ;; give human readable sizes in dired listings
ring-bell-function #'ignore ;; don't ring a bell, just ignore it
tab-width 4) ;; tab width to 4
(setq
backup-by-copying t ; don't clobber symlinks
backup-directory-alist
'(("." . "~/.emacs.d/file_backups/")) ; don't litter my fs tree
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t) ; use versioned backups
Stop asking for me to type in the full “yes” or “no” when a “y” or “n” would do…
(fset 'yes-or-no-p 'y-or-n-p)
(blink-cursor-mode 0)
(global-unset-key (kbd "C-z"))
(global-unset-key (kbd "C-x C-z"))
We want the compilation window to scroll to the bottom
(setq compilation-scroll-output 1)
show-paren-mode
highlights the matching paren and electric-pair-mode
adds in the matching paren.
(add-hook 'prog-mode-hook #'show-paren-mode)
(add-hook 'prog-mode-hook #'electric-pair-mode)
Org mode. It’s what this file’s written with.
(use-package org
:init
(defun org-babel-execute:yaml (body params) body) ;; so I can edit yaml files
(require 'ox-md)
;; function to use to export org blocks with a language
(defun org-mymd-example-block (example-block _content info)
"Transcode element EXAMPLE-BLOCK as ```lang ...```."
(format "```%s\n%s\n```"
(org-element-property :language example-block)
(org-remove-indentation
(org-export-format-code-default example-block info))))
(advice-add 'org-md-example-block :override #'org-mymd-example-block)
:config
(setq org-return-follows-link t
org-directory "~/git/notes"
org-default-notes-file (concat org-directory "/notes.org")
org-agenda-files (list org-directory)
org-todo-keywords
'((sequence "TODO" "SOMEDAY" "|" "DONE" "CANCELLED")))
;; set up my keymaps
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)
;; set up my capture templates
(setq org-capture-templates
'(("t" "Todo" entry (file+headline org-default-notes-file "Tasks")
"* TODO %?\n %i\n %a")
("j" "Journal" entry (file+olp+datetree org-default-notes-file)
"* %?\nEntered on %U\n %i\n %a")))
(org-babel-do-load-languages ;; load the languages for org-babel
'org-babel-load-languages
'((python . t)
(emacs-lisp . t)
(C . t)
(latex . t)
(shell . t)
(clojure . t))))
Add nicer repl interaction to clojure mode
(use-package cider
:defer t
:config
(add-hook 'clojure-mode-hook #'cider-mode))
Add a clojure mode
(use-package clojure-mode)
Auto completion.
(use-package company
:config
(add-hook 'after-init-hook #'global-company-mode)
(setq company-minimum-prefix-length 2) ;; start completing after 2 characters
(setq company-idle-delay 0.2))
(use-package dap-mode
:defer t
:after lsp-mode
:config
(dap-auto-configure-mode)
(require 'dap-cpptools))
(use-package direnv
:config
(direnv-mode t))
(use-package doom-modeline
:hook (after-init . doom-modeline-mode))
Package that lets you edit code blocks in md files with their respective modes
(use-package edit-indirect)
(use-package elixir-mode)
(use-package mix
:config
(defun mix-update-path-to-bin ()
(interactive)
(customize-set-variable 'mix-path-to-bin
(or (executable-find "mix")
"/usr/bin/mix")))
:hook
((elixir-mode . mix-minor-mode)))
Improved diagnostics for projects n stuff
(use-package flycheck
:init (global-flycheck-mode))
(use-package glsl-mode)
(use-package helm
:init
(global-set-key (kbd "M-x") #'helm-M-x)
(global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks)
(global-set-key (kbd "C-x C-f") #'helm-find-files)
(setq helm-default-display-buffer-functions '(display-buffer-in-side-window))
(setq helm-display-buffer-default-height 15)
:config
(helm-mode 1))
(use-package helm-rg)
Helm + YASnippet
(use-package helm-c-yasnippet
:after (helm yasnippet)
:config
(setq helm-yas-space-match-any-greedy t)
(global-set-key (kbd "C-c y") 'helm-yas-complete))
Highlighting and a few other things for the language hy. Jedhy is the current completion engine for hy, but it’s not going to be updated until hy 1.0 is out of alpha. At the moment - disable it.
(use-package hy-mode
:config
(setq hy-jedhy--enable? nil))
(use-package julia-mode)
(use-package julia-repl
:hook ((julia-mode . julia-repl-mode)))
(use-package lsp-julia
:config
(setq lsp-julia-default-environment "~/.julia/environments/v1.5"))
(use-package lsp-mode
:init
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "C-;")
:config
(define-key lsp-mode-map (kbd "C-;") lsp-command-map)
:hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
;; (XXX-mode . lsp)
(elixir-mode . lsp-deferred)
(nix-mode . lsp-deferred)
(typescript-mode . lsp-deferred)
(js-mode . lsp-deferred)
(LaTeX-mode . lsp-deferred)
(ruby-mode . lsp-deferred)
(lsp-mode . lsp-enable-which-key-integration))
:commands lsp lsp-deferred)
(use-package lsp-ui
:init
(setq lsp-ui-doc-enable nil)
:bind (:map lsp-ui-mode-map
("C-c i" . lsp-ui-imenu)))
(use-package lsp-pyright
:hook
(python-mode . (lambda ()
(require 'lsp-pyright)
(lsp)))) ; or lsp-deferred
(add-to-list 'lsp-language-id-configuration '(nix-mode . "nix"))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection '("rnix-lsp"))
:major-modes '(nix-mode)
:server-id 'nix))
(use-package magit)
(use-package nix-mode
:mode "\\.nix\\'"
:defer t)
(use-package cdlatex
:defer t
:init
(add-hook 'org-mode-hook 'turn-on-org-cdlatex)
(add-hook 'LaTeX-mode-hook 'turn-on-cdlatex))
(use-package org-bullets
:hook (org-mode . org-bullets-mode))
(use-package org-roam
:init
(setq org-roam-v2-ack t)
:custom
(org-roam-directory (file-truename "~/git/roam/"))
(org-roam-completion-everywhere t)
:bind
(("C-c r i" . #'org-roam-node-insert)
("C-c r f" . #'org-roam-node-find)
("C-c r r" . #'org-roam-buffer-toggle))
:config
(org-roam-setup))
A better pdf viewer than doc-view. Useful with tex.
(use-package pdf-tools
:config
(pdf-tools-install))
(use-package projectile
:init
(projectile-mode +1)
:bind (:map projectile-mode-map
("C-c p" . projectile-command-map)))
(use-package helm-projectile
:after (helm projectile)
:config
(helm-projectile-on))
(use-package projectile-ripgrep
:after (projectile))
(use-package protobuf-mode)
(use-package python
:config
(setq python-indent-guess-indent-offset-verbose nil
org-babel-python-command (python-shell-calculate-command))
:bind (:map python-mode-map
("<f7>" .
(lambda ()
(interactive)
(projectile-run-async-shell-command-in-root (format
"python %s"
(file-relative-name buffer-file-name
projectile-project-root)))))))
Use blacken for python formatting
(use-package blacken
:hook (python-mode . blacken-mode)
:init
(setq-default blacken-fast-unsafe t)
(setq-default blacken-line-length 80))
Python pytest for easier pytest interactions
(use-package python-pytest
:after python
:bind (:map python-mode-map
("<f6>" . #'python-pytest-popup)))
(use-package racket-mode
:defer t
:hook (racket-mode . racket-xp-mode)
:bind (:map racket-xp-mode-map
("C-c C-d" . racket-xp-describe)))
(use-package rustic)
(use-package rg
:config
(rg-enable-default-bindings))
(use-package markdown-mode
:mode ("\\.mdx\\'" . markdown-mode))
Trying out the kaolin light theme
(use-package all-the-icons)
(use-package kaolin-themes
:config
(load-theme 'kaolin-breeze t))
;; (kaolin-treemacs-theme))
(use-package treemacs
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
(use-package treemacs-projectile
:after (treemacs projectile))
(use-package treemacs-icons-dired
:after (treemacs dired)
:config (treemacs-icons-dired-mode))
(use-package treemacs-magit
:after (treemacs magit))
This package turns the undo tangle emacs usually has into an undo tree
(use-package undo-tree
:config
(global-undo-tree-mode) ;; start undo-tree
(setq undo-tree-visualizer-diff t
; make undo tree backups inside the .emacs folder
undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-tree-history/"))))
(use-package which-key
:config
(which-key-mode t))
(use-package yasnippet-snippets)
(use-package yasnippet
:after yasnippet-snippets
:config
(yas-global-mode t))
(use-package tex
;; :straight auctex ;; install the package if it's not installed already
:mode ("\\.tex\\'" . TeX-latex-mode)
:config
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq TeX-PDF-mode t)
(setq-default TeX-master nil)
(setq TeX-source-correlate-start-server 'synctex)
(setq TeX-view-program-selection '(((output-dvi has-no-display-manager)
"dvi2tty")
((output-dvi style-pstricks)
"dvips and gv")
(output-dvi "xdvi")
(output-pdf "PDF Tools")
(output-html "xdg-open")))
:init
(add-hook 'LaTeX-mode-hook #'my-LaTeX-mode-hooks)
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
(add-to-list 'safe-local-variable-values
'(TeX-command-extra-options . "-shell-escape"))
(defun my-LaTeX-mode-hooks ()
(TeX-source-correlate-mode t)
(LaTeX-math-mode t)
(add-hook 'after-save-hook (lambda () (TeX-command-run-all nil)) nil t) ;; save after compilation
))
(use-package vterm
:bind (("<f5>" . 'vterm)))
(use-package typescript-mode
:mode "\\.tsx\\'"
:defer t)
Mode for reading epubs in emacs
(use-package nov
:mode ("\\.epub\\'" . nov-mode)
:defer t)
(use-package yaml-mode)