Nix[Custom]Setup Think X1 CarbonPad
Table of Contents
NixOS Setup for the Everyday Thinkpad’er
Hoping to sort of break down my configuration.nix here a bit as it’ll be easier to reference later and will maybe explain a few options I use which could be helpful for others if anyone ever sees this!
Basic Setup
This section comes a lot from the default configuration. It defines things like yes use systemD, sets a host name so your computer knows who you are, timezeone, and makes a user which is useful. No having to set that up and groups after the fact. The other crucial aspect here is networkmanager is enabled and setup in this step. You can then by default use nmtui or the strange CLI interface. What I’ve done is added dmenu_networkmanager or whatever and mapped it to SUPER+N so I can just quick whip that opened to do WiFi stuff. It works without issue in conjunction with networkmanager.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "liam-tpad";
networking.networkmanager.enable = true;
time.timeZone = "America/New_York";
i18n.defaultLocale = "en_CA.UTF-8";
services.xserver.enable = true;
services.libinput.enable = true;
services.printing.enable = true;
users.users.liam = {
isNormalUser = true;
description = "liam";
extraGroups = [ "networkmanager" "wheel" "libvirtd" "kvm" ];
packages = with pkgs; [
];
};
users.users.liam.shell = pkgs.zsh ;
virtualisation.libvirtd.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
services.blueman.enable = true;
Bluetoooth
I don’t know what’s wrong with me or my setup here but this seems to work, then doesn’t, then does again, just makes no sense. I’m putting this here NOT TO COPY, but maybe to look and see an obvious flaw in whatever it is that causes my bluetooth experience to be consistantly terrible.
services.blueman.enable = true;
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Experimental = true;
FastConnectable = true;
};
Policy = {
AutoEnable = true;
};
};
};
Graphics and Audio
This is an important section of course. Without this you’d be left with the scary black screen and tiny white text in the top left corner and nothing more to do but to cd your way around. For the time being I’m using Hyprland as my window manager along with its accompying softwares for locking, sleep, screenshots, and a few other things. Ly is used to login. I like the look, what can I say.
hardware.graphics = {
enable = true;
#extraPackages = with pkgs; [
#intel-media-driver
#intel-compute-runtime
#vpl-gpu-rt
#];
};
services.displayManager.ly.enable = true;
programs.hyprland.enable = true;
services.hypridle.enable = true;
programs.hyprlock.enable = true;
Here I also have a few things such as a spash screen for when the computer boots. I like this as it makes it look less scary and therefore there are less questions when a stranger sees my computer turn on, they don’t right away think I’m hacking a mainframe somewhere.
boot.plymouth.enable = true;
boot.plymouth.theme = "breeze";
For audio I’ve pretty much been using the default setup NixOS provides. I think I may have added a line either here or an app declared later on so I can use the media keys for volume and muting that come on the Thinkpad’s keyboard. Later on also I use the TUI program Wiremix to go above and beyond 100% with the volume as the Thinkpad speakers aren’t too loud. Eitherway, here is the audio configuration:
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
It may be that pulseaudio is the standard and then I’ve changed this over to pipewire because its lighterweight? But who knows for sure. What I do know is that it works!
Hardware and Battery Stuff
This can be a contentious point on Linux sadly, especially as most people’s personal machines are laptops these days. The battery life can vary widely and its often due to some strange underlying kernal settings or whathave you. Due to them being underlying they can be sort of sketchy to mess with as mistakes or uncompatible changes can bork your whole system. Here is where NixOS really shines, you can define a lot of this stuff and it builds it for you on the fly, all that with the ability to revert if it somehow does stop working.
I don’t have any issues I don’t think, my X1 Carbon Gen9 seeems to have the battery life it deserves with its aging battery. That being said I’ve been on Linux so long maybe it would be double if I was using something else…
powerManagement.cpuFreqGovernor = "powersave";
powerManagement.enable = true;
powerManagement.powertop.enable = true;
services.thermald.enable = true;
services.auto-cpufreq.enable = true;
services.auto-cpufreq.settings = {
battery = {
governor = "powersave";
turbo = "never";
};
charger = {
governor = "performance";
turbo = "auto";
};
};
Doas
I’m not sure what prompted me to initially switch this. It might have been simply that I think the change would be harder on a legacy distro so the fact its so easy here made me do it? But I like that there are sudo bugs ever so often and the fact this is more niche so if I ever got some malware which tried to ‘sudo’ it’d just stop right there. Doas is a replacement that does nothing else but run the following command as root. Simple, effective, and now my muscle memory is such I can’t go back.
security.sudo.enable = false;
security.doas.enable = true;
security.doas.extraRules = [{
users = [ "liam" ];
keepEnv = true;
persist = true;
}];
Declaritive Settings
Recently I’ve taken to separating out this single file into a few as I have found a few cool things I can define system wide in the config I didn’t know about before. The things that come to mind here are NViM as well as Firefox.
Firefox especially I used to be so annoyed with always having to chase down things I have used for years and therefore forgotten where they came from such as vertical tabs, extension names, and a few other settings. Turns out you can bulid this straight into NixOS! So I’ve made a seperate file called firefox.nix in the /etc/nixos/ folder and just imported it at the top along with some others so that the one file isn’t too long.
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./firefox.nix
./apps.nix
./tmux.nix
./vim.nix
];
From here I can then have those corresponding files with their own settings. Nothing changes it just keeps each file shorter and I can open them individually with cool shell aliases.
Firefox.nix
{ config, pkgs, ... }:
{
programs.firefox = {
enable = true;
policies = {
EnableTrackingProtection = {
Value= true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
ExtensionSettings = {
# uBlock Origin:
"uBlock0@raymondhill.net" = {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi";
installation_mode = "force_installed";
};
# Privacy Badger:
"jid1-MnnxcxisBPnSXQ@jetpack" = {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/privacy-badger17/latest.xpi";
installation_mode = "force_installed";
};
};
};
preferences = {
"sidebar.verticaltabs" = true;
"sidebar.verticaltabs.dragtopinpromo.dismissed" = true;
DisableTelemetry = true;
DisableFirefoxStudies = true;
};
};
}
### Tmux
I'm seeing if I like this, not sure I'm entirely sold yet as I'm so slow at moving around and taking advantage of this.
```nix
{ pkgs, ... }:
{
programs.tmux = {
enable = true;
#shortcut = "a";
# aggressiveResize = true; -- Disabled to be iTerm-friendly
baseIndex = 1;
newSession = true;
# Stop tmux+escape craziness.
escapeTime = 0;
# Force tmux to use /tmp for sockets (WSL2 compat)
secureSocket = false;
clock24 = true;
historyLimit = 50000;
plugins = with pkgs; [
tmuxPlugins.better-mouse-mode
tmuxPlugins.vim-tmux-navigator
tmuxPlugins.gruvbox
];
extraConfig = ''
set -g default-terminal "kitty"
setw -g mode-keys vi
set -ga terminal-overrides ",*256col*:RGB"
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q'
set-environment -g COLORTERM "truecolor"
set -g @tmux-gruvbox 'dark256'
# # easy-to-remember split pane commands
# bind | split-window -h -c "#{pane_current_path}"
# bind - split-window -v -c "#{pane_current_path}"
# bind c new-window -c "#{pane_current_path}"
'';
};
}
Neo ViM
Ah, yes, Neo ViM. The massive Lisp configs have become a hot topic as of recent it seems! Tons of cool stuff out there I don’t understand nor need as far as I think at least for my simple workflow and usecases. This is essentially the pasted in version of my probably more than 10 year old .vimrc I’ve been using since high school with the addition of maybe one or two things along with some new colorschemes for when I’m feeling fancy.
{ config, pkgs, ... }:
{
programs.neovim = {
enable = true;
defaultEditor = true;
vimAlias = true;
configure = {
customRC = ''
set t_Co=256
set paste
setlocal formatoptions=1
setlocal linebreak
set thesaurus+=~/Documents/thesaur/mthesaur.txt
set complete+=s
set scrolloff=5
set number relativenumber
set path+=,**
colorscheme gruvbox
set ignorecase
set cursorline
set smartcase
set mouse=a
let g:transparent_enabled = v:true
set noswapfile
map<F7> :Yazi <CR>
map <C-g> :Goyo <CR>
map <C-z> :ZenMode <CR>
map <C-l> :Limelight!! <CR>
map <C-T> :Telescope find_files <CR>
map <C-f> :Yazi <CR>
map <C-p> :TypstWatch <CR>
map <C-i> :! pdflatex %<CR><CR<>
map <C-t> :! typst compile %<CR><CR<>
map <C-s> :! zathura $(echo % \| sed 's/tex$/pdf/') & disown <CR><CR>
set spell
set spelllang=en_us
set termguicolors
'';
packages.myVimPackage = with pkgs.vimPlugins; {start = [
vim-nix
limelight-vim
oil-nvim
zen-mode-nvim
typst-vim
nvim-cmp
yazi-nvim
vim-pandoc
vim-airline
vim-surround
vimtex
goyo
gruvbox
oceanic-next
transparent-nvim
catppuccin-nvim
rose-pine
awesome-vim-colorschemes
molokai
everforest
];
};
};
};
}
Other Applications
The final section I have is the spot where you just install whatever applications. I talk more about what I use and why in the setup at the top of the page, but here is what this file looks like where I define what’s installed. Never go looking for things again when setting up a new machine, I love it, just paste this in the file and rebuild switch and you’re off to the races.
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
hugo
wiki-tui
obs-studio
mangowc
nix-search-cli
dmenu
networkmanager_dmenu
waybar
mpv
qutebrowser
timeshift
swaybg
waypaper
hyprshot
bluetuith
pkgs.kitty
pciutils
gotop
nemo
yazi
fzf
kdePackages.kdenlive
git
qbittorrent
wiremix
alsa-utils
brightnessctl
cmus
cava
zathura
texliveFull
typst
gnome-boxes
dnsmasq
];
}
ZSH
Maybe I should make this it’s own section, but its not too big its essentially a few settings and some aliases. I like that you can predefine the prompt as well as turn on VI mode as its so useful. Also I don’t have to keep track of another file for aliases I once used but have forgotten lol.
programs.zsh = {
enable = true;
shellAliases = {
conf = "du -a ~/.config/* | awk '{print $2}' | fzf --preview 'less {}' | xargs -r $EDITOR";
dox = "du -a ~/Documents/* | awk '{print $2}' | fzf --preview 'less {}' | xargs -r $EDITOR";
tses = "session=$(tmux list-sessions -F '#S' | fzf) ||
exit tmux attach -t '$session' ";
config = "doas vim /etc/nixos/configuration.nix";
apps = "doas vim /etc/nixos/apps.nix";
vimconf = "doas vim /etc/nixos/vim.nix";
};
ohMyZsh = {
enable = true;
plugins = ["vi-mode"];
theme = "arrow";
};
};
Fonts
The final section worth nothing. I used to use more and care more about these, but really I think the Ubuntu fonts look nice, modern, and unique enough for me so I use them everywhere now both the Monospace one and the regular ones for the browser and other stuffs. The packages in LaTeX and Typst both come with a billion fonts to render documents in so that’s an entirely different store and honestly sorted there so, whatever?
fonts.packages = with pkgs; [
nerd-fonts.ubuntu
ubuntu-sans
ubuntu-classic
ubuntu-sans-mono
];
Conclusion
And there you have it, the full breakdown of all the settings! I’ll do one of these for Hyprland and its accompanying stuff at some point so it’ll be easy to look back and actually mimic the setup at a later date.