From 8b18e05fbc564a7795d0fb1dd5ddbb5940c5d306 Mon Sep 17 00:00:00 2001
From: Oliver Davies <oliver@oliverdavies.uk>
Date: Thu, 6 Apr 2023 14:07:08 +0100
Subject: [PATCH] wip

---
 flake.nix                                     |   5 +-
 justfile                                      |   3 +
 .../code/Dockerfile.twig                      |  12 ++
 working-without-workspace/code/aliases.sh     |  13 ++
 working-without-workspace/code/build.yaml     |  46 +++++
 .../code/configuration.nix                    |  26 +++
 .../code/docker-compose.yaml.twig             |  15 ++
 working-without-workspace/code/flake.nix      |  19 ++
 working-without-workspace/code/git.nix        |  27 +++
 working-without-workspace/code/gitconfig.ini  |  15 ++
 .../code/hardware-configuration.nix           |  25 +++
 .../code/home-manager.nix                     |  11 ++
 working-without-workspace/code/justfile.twig  |  12 ++
 working-without-workspace/opdavies-dark.yaml  | 164 ++++++++++++++++++
 working-without-workspace/opdavies-light.yaml | 158 +++++++++++++++++
 .../sections/build-configs.rst                |  71 ++++++++
 working-without-workspace/sections/flakes.rst |  22 +++
 working-without-workspace/sections/git.rst    |  19 ++
 working-without-workspace/sections/just.rst   |  69 ++++++++
 working-without-workspace/sections/neovim.rst |  14 ++
 .../sections/operating-system.rst             | 138 +++++++++++++++
 working-without-workspace/sections/others.rst |  12 ++
 working-without-workspace/sections/shell.rst  |  80 +++++++++
 working-without-workspace/sections/tmux.rst   |  12 ++
 .../working-without-workspace.rst             |  55 ++++++
 25 files changed, 1042 insertions(+), 1 deletion(-)
 create mode 100644 working-without-workspace/code/Dockerfile.twig
 create mode 100644 working-without-workspace/code/aliases.sh
 create mode 100644 working-without-workspace/code/build.yaml
 create mode 100644 working-without-workspace/code/configuration.nix
 create mode 100644 working-without-workspace/code/docker-compose.yaml.twig
 create mode 100644 working-without-workspace/code/flake.nix
 create mode 100644 working-without-workspace/code/git.nix
 create mode 100644 working-without-workspace/code/gitconfig.ini
 create mode 100644 working-without-workspace/code/hardware-configuration.nix
 create mode 100644 working-without-workspace/code/home-manager.nix
 create mode 100644 working-without-workspace/code/justfile.twig
 create mode 100644 working-without-workspace/opdavies-dark.yaml
 create mode 100644 working-without-workspace/opdavies-light.yaml
 create mode 100644 working-without-workspace/sections/build-configs.rst
 create mode 100644 working-without-workspace/sections/flakes.rst
 create mode 100644 working-without-workspace/sections/git.rst
 create mode 100644 working-without-workspace/sections/just.rst
 create mode 100644 working-without-workspace/sections/neovim.rst
 create mode 100644 working-without-workspace/sections/operating-system.rst
 create mode 100644 working-without-workspace/sections/others.rst
 create mode 100644 working-without-workspace/sections/shell.rst
 create mode 100644 working-without-workspace/sections/tmux.rst
 create mode 100644 working-without-workspace/working-without-workspace.rst

diff --git a/flake.nix b/flake.nix
index 7d4207b..acb806f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -13,7 +13,10 @@
         devShell = with pkgs; pkgs.mkShell {
           buildInputs = [
             just
-            python310Packages.rst2pdf
+            python39Packages.rst2pdf
+            pdfpc
+            libcanberra
+            libcanberra-gtk3
           ];
         };
       });
diff --git a/justfile b/justfile
index 9d17ace..71d641c 100644
--- a/justfile
+++ b/justfile
@@ -20,3 +20,6 @@ generate name: (clean name)
       --font-path ../fonts \
       --output {{ name }}-dark.pdf \
       --stylesheets opdavies-dark,tango,monokai
+
+thumbnail name slideNumber:
+  pdftoppm {{ name }}/{{ name }}.pdf -png -f {{ slideNumber }} -l {{ slideNumber }} > {{ name }}/{{ name }}-{{ slideNumber }}.png
diff --git a/working-without-workspace/code/Dockerfile.twig b/working-without-workspace/code/Dockerfile.twig
new file mode 100644
index 0000000..205df8e
--- /dev/null
+++ b/working-without-workspace/code/Dockerfile.twig
@@ -0,0 +1,12 @@
+FROM php:{{ php.version }} AS base
+
+COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
+RUN which composer && composer -V
+
+ARG DOCKER_UID=1000
+ENV DOCKER_UID="${DOCKER_UID}"
+
+WORKDIR {{ project_root }}
+
+RUN adduser --disabled-password --uid "${DOCKER_UID}" app \
+  && chown app:app -R {{ project_root }}
diff --git a/working-without-workspace/code/aliases.sh b/working-without-workspace/code/aliases.sh
new file mode 100644
index 0000000..f7dde08
--- /dev/null
+++ b/working-without-workspace/code/aliases.sh
@@ -0,0 +1,13 @@
+alias cp="cp -v"
+alias mv="mv -v"
+alias rm="rm -v"
+
+alias g="git"
+alias gs="git status"
+
+alias dk="docker"
+alias dkp="docker ps"
+alias dkc="docker compose"
+alias dkcu="docker compose up"
+
+alias docker-composer="docker-compose"
diff --git a/working-without-workspace/code/build.yaml b/working-without-workspace/code/build.yaml
new file mode 100644
index 0000000..9b08ed7
--- /dev/null
+++ b/working-without-workspace/code/build.yaml
@@ -0,0 +1,46 @@
+name: docker-example-drupal
+language: php
+type: drupal-project
+
+web:
+  type: nginx
+
+database:
+  type: mariadb
+  version: 10
+
+php:
+  version: 8.1-fpm-bullseye
+  phpcs:
+    standard: Drupal,DrupalPractice
+  phpstan:
+    level: max
+
+drupal:
+  docroot: web
+
+docker-compose:
+  services:
+    database: ~
+    php:
+      build:
+        target: build
+
+dockerfile:
+  stages:
+    build:
+      extends: base
+      packages:
+        - git
+        - libpng-dev
+        - libzip-dev
+        - mariadb-client
+        - unzip
+      extensions:
+        install:
+          - gd
+          - pdo_mysql
+          - zip
+      commands:
+        - composer validate --strict
+        - composer install
diff --git a/working-without-workspace/code/configuration.nix b/working-without-workspace/code/configuration.nix
new file mode 100644
index 0000000..8ecc127
--- /dev/null
+++ b/working-without-workspace/code/configuration.nix
@@ -0,0 +1,26 @@
+{ config, pkgs, ... }:
+{
+  imports = [ ./hardware-configuration.nix ];
+
+  nix.settings.experimental-features = [ "nix-command" "flakes" ];
+
+  boot.loader.systemd-boot.enable = true;
+  boot.loader.efi.canTouchEfiVariables = true;
+  boot.loader.efi.efiSysMountPoint = "/boot/efi";
+
+  boot.kernelPackages = pkgs.linuxPackages_latest;
+
+  networking.hostName = "nixedo";
+
+  networking.networkmanager.enable = true;
+
+  time.timeZone = "Europe/London";
+
+  i18n.defaultLocale = "en_GB.UTF-8";
+
+  users.users.opdavies = {
+    isNormalUser = true;
+    description = "Oliver Davies";
+    extraGroups = [ "docker" "networkmanager" "wheel" ];
+    packages = with pkgs; [ firefox ];
+  };
diff --git a/working-without-workspace/code/docker-compose.yaml.twig b/working-without-workspace/code/docker-compose.yaml.twig
new file mode 100644
index 0000000..e32d4fa
--- /dev/null
+++ b/working-without-workspace/code/docker-compose.yaml.twig
@@ -0,0 +1,15 @@
+{% if "php" == language %}
+php:
+  <<: *default-app
+  build:
+    context: .
+    target: build
+    args:
+      - "DOCKER_UID=${DOCKER_UID:-1000}"
+  volumes:
+    - .:{{ project_root }}
+  {% if "database" in dockerCompose.services|keys -%}
+  depends_on:
+    - database
+  {% endif -%}
+  profiles: [php]
diff --git a/working-without-workspace/code/flake.nix b/working-without-workspace/code/flake.nix
new file mode 100644
index 0000000..068523a
--- /dev/null
+++ b/working-without-workspace/code/flake.nix
@@ -0,0 +1,19 @@
+{
+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+  inputs.devshell.url = "github:numtide/devshell";
+
+  outputs = inputs@{ flake-parts, ... }:
+    flake-parts.lib.mkFlake { inherit inputs; } {
+      imports = [ inputs.devshell.flakeModule ];
+
+      systems = [ "x86_64-linux" ];
+
+      perSystem = { config, self', inputs', pkgs, system, ... }: {
+        devshells.default = {
+          packages = with pkgs; [ php82 php82Packages.composer ];
+        };
+      };
+
+      flake = { };
+    };
+}
diff --git a/working-without-workspace/code/git.nix b/working-without-workspace/code/git.nix
new file mode 100644
index 0000000..d7ebee1
--- /dev/null
+++ b/working-without-workspace/code/git.nix
@@ -0,0 +1,27 @@
+programs.git = {
+enable = true;
+userName = "Oliver Davies";
+userEmail = "oliver@oliverdavies.uk";
+
+aliases = {
+aa = "add --all";
+assume = "update-index --assume-unchanged";
+assumed = "!git ls-files -v | grep '^[hsmrck?]' | cut -c 3-";
+b = "branch";
+# ...
+};
+extraConfig = {
+branch = {
+autosetupmerge = true;
+autosetuprebase = "always";
+};
+checkout.defaultRemote = "origin";
+color.ui = true;
+commit = {
+template = "~/.gitmessage";
+};
+core = {
+editor = "nvim";
+excludesFile = "~/.gitignore-global";
+pager = "delta";
+};
diff --git a/working-without-workspace/code/gitconfig.ini b/working-without-workspace/code/gitconfig.ini
new file mode 100644
index 0000000..eb788ed
--- /dev/null
+++ b/working-without-workspace/code/gitconfig.ini
@@ -0,0 +1,15 @@
+[alias]
+  aa = "add --all"
+  assume = "update-index --assume-unchanged"
+  assumed = "!git ls-files -v | grep '^[hsmrck?]' | cut -c 3-"
+  b = "branch"
+  browse = "!gh repo view --web"
+  ca = "commit --amend --verbose"
+  car = "commit --amend --no-edit"
+
+[branch]
+  autosetupmerge = true
+  autosetuprebase = "always"
+
+[checkout]
+  defaultRemote = "origin"
diff --git a/working-without-workspace/code/hardware-configuration.nix b/working-without-workspace/code/hardware-configuration.nix
new file mode 100644
index 0000000..db8fafc
--- /dev/null
+++ b/working-without-workspace/code/hardware-configuration.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
+
+  boot.initrd.availableKernelModules =
+    [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.kernelParams = [ "i8042.reset" ];
+  boot.extraModulePackages = [ ];
+
+
+  fileSystems."/" = {
+    device = "/dev/disk/by-uuid/7c6d69ec-ba06-4ddb-b9c4-62b3994fda91";
+    fsType = "ext4";
+  };
+
+  fileSystems."/boot/efi" = {
+    device = "/dev/disk/by-uuid/B729-9A75";
+    fsType = "vfat";
+  };
+
+  swapDevices =
+    [{ device = "/dev/disk/by-uuid/5db0a0e6-93fb-4d0b-8fb0-fdb3cb76b89d"; }];
diff --git a/working-without-workspace/code/home-manager.nix b/working-without-workspace/code/home-manager.nix
new file mode 100644
index 0000000..33eb79b
--- /dev/null
+++ b/working-without-workspace/code/home-manager.nix
@@ -0,0 +1,11 @@
+{ config, pkgs, ... }:
+
+{
+  home.username = "opdavies";
+  home.homeDirectory = "/home/opdavies";
+
+  home.packages = with pkgs; [
+    php82
+    php82Packages.composer
+  ];
+};
diff --git a/working-without-workspace/code/justfile.twig b/working-without-workspace/code/justfile.twig
new file mode 100644
index 0000000..7ed45ed
--- /dev/null
+++ b/working-without-workspace/code/justfile.twig
@@ -0,0 +1,12 @@
+{% if "php" is same as language %}
+composer *args:
+  {{ "just _exec php composer {{ args }}" | raw }}
+
+{% if "drupal-project" is same as type %}
+drush *args:
+  {{ "just _exec php drush {{ args }}" | raw }}
+
+install *args:
+  {{ "just _exec php drush site:install -y {{ args }}" | raw }}
+{% endif %}
+{% endif %}
diff --git a/working-without-workspace/opdavies-dark.yaml b/working-without-workspace/opdavies-dark.yaml
new file mode 100644
index 0000000..44b7250
--- /dev/null
+++ b/working-without-workspace/opdavies-dark.yaml
@@ -0,0 +1,164 @@
+embeddedFonts:
+  - - Inconsolata.ttf
+    - Inconsolata.ttf
+    - Inconsolata.ttf
+    - Inconsolata.ttf
+  - - Helvetica.ttf
+    - Helvetica-Bold.ttf
+    - Helvetica.ttf
+    - Helvetica-Bold.ttf
+
+fontsAlias:
+  fontBold: Helvetica-Bold
+  fontFont: Helvetica
+  fontItalic: Helvetica
+  fontMono: Inconsolata
+  fontMonoBold: Inconsolata
+  fontMonoBoldItalic: Inconsolata
+  fontMonoItalic: Inconsolata
+  
+linkColor: '#60a5fa'
+
+pageSetup:
+  firstTemplate: coverPage
+  height: 18cm
+  margin-bottom: 0cm
+  margin-gutter: 0cm
+  margin-left: 0cm
+  margin-right: 0cm
+  margin-top: 0cm
+  size: null
+  spacing-footer: 2mm
+  spacing-header: 2mm
+  width: 32cm
+
+pageTemplates:
+  coverPage:
+    background: ../images/bg-dark.png
+    frames:
+      - - 12%
+        - 10%
+        - 76%
+        - 75%
+    showFooter: false
+    showHeader: false
+ 
+  imagePage:
+    alignment: TA_CENTER
+    background: ../images/bg-dark.png
+    frames:
+      - - 3%
+        - 3%
+        - 92%
+        - 92%
+    showFooter: true
+    showHeader: false
+
+  outputPage:
+    background: ../images/bg-dark.png
+    frames:
+      - - 8%
+        - 10%
+        - 82%
+        - 65%
+    showFooter: false
+    showHeader: false
+
+  standardPage:
+    background: ../images/bg-dark.png
+    frames:
+      - - 3%
+        - 3%
+        - 92%
+        - 92%
+    showFooter: true
+    showHeader: false
+
+  titlePage:
+    alignment: TA_CENTER
+    background: ../images/bg-dark.png
+    frames:
+      - - 8%
+        - 8%
+        - 85%
+        - 65%
+    showFooter: true
+    showHeader: false
+
+styles:
+  bodytext:
+    alignment: TA_LEFT
+
+  bullet-list:
+    colWidths:
+      - '20'
+      - null
+    commands:
+      - - LEFTPADDING
+        - - 0
+          - 0
+        - - 1
+          - -1
+        - 5
+      - - RIGHTPADDING
+        - - 0
+          - 0
+        - - 1
+          - -1
+        - 0
+    textColor: '#ffffff'
+
+  bullet-list-item:
+    spaceAfter: 0
+    spaceBefore: 18
+
+  centred:
+    alignment: TA_CENTER
+    parent: normal
+
+  centredtitle:
+    alignment: TA_CENTER
+    fontName: fontBold
+    fontSize: 48
+    leading: 64
+    parent: heading
+
+  code:
+    backColor: '#111111'
+    borderWidth: 0
+    fontSize: 24
+    leading: 26
+    parent: literal
+    spaceBefore: 4
+
+  footer:
+    alignment: TA_RIGHT
+    fontName: fontMono
+    fontSize: 20
+    rightIndent: 16
+    spaceBefore: 0
+    textColor: '#24608a'
+
+  heading:
+    fontName: fontBold
+    fontSize: 20
+    spaceAfter: 16
+    textColor: '#60a5fa'
+
+  literal:
+    backColor: '#111111'
+    fontName: fontMono
+
+  normal:
+    fontSize: 24
+    textColor: '#ffffff'
+
+  title:
+    fontSize: 300%
+    parent: heading
+
+  titleslideinfo:
+    alignment: TA_CENTER
+    fontSize: 140%
+    parent: normal
+
diff --git a/working-without-workspace/opdavies-light.yaml b/working-without-workspace/opdavies-light.yaml
new file mode 100644
index 0000000..6f6fec7
--- /dev/null
+++ b/working-without-workspace/opdavies-light.yaml
@@ -0,0 +1,158 @@
+embeddedFonts:
+  - - Inconsolata.ttf
+    - Inconsolata.ttf
+    - Inconsolata.ttf
+    - Inconsolata.ttf
+  - - Helvetica.ttf
+    - Helvetica-Bold.ttf
+    - Helvetica.ttf
+    - Helvetica-Bold.ttf
+
+fontsAlias:
+  fontBold: Helvetica-Bold
+  fontFont: Helvetica
+  fontItalic: Helvetica
+  fontMono: Inconsolata
+  fontMonoBold: Inconsolata
+  fontMonoBoldItalic: Inconsolata
+  fontMonoItalic: Inconsolata
+
+linkColor: '#24608a'
+
+pageSetup:
+  firstTemplate: coverPage
+  height: 18cm
+  margin-bottom: 0cm
+  margin-gutter: 0cm
+  margin-left: 0cm
+  margin-right: 0cm
+  margin-top: 0cm
+  size: null
+  spacing-footer: 2mm
+  spacing-header: 2mm
+  width: 32cm
+
+pageTemplates:
+  coverPage:
+    frames:
+      - - 12%
+        - 10%
+        - 76%
+        - 75%
+    showFooter: false
+    showHeader: false
+
+  imagePage:
+    alignment: TA_CENTER
+    frames:
+      - - 3%
+        - 3%
+        - 92%
+        - 92%
+    showFooter: true
+    showHeader: false
+
+  outputPage:
+    frames:
+      - - 8%
+        - 10%
+        - 82%
+        - 65%
+    showFooter: false
+    showHeader: false
+
+  standardPage:
+    frames:
+      - - 3%
+        - 3%
+        - 92%
+        - 92%
+    showFooter: true
+    showHeader: false
+
+  titlePage:
+    alignment: TA_CENTER
+    frames:
+      - - 8%
+        - 8%
+        - 85%
+        - 65%
+    showFooter: true
+    showHeader: false
+
+styles:
+  bodytext:
+    alignment: TA_LEFT
+
+  bullet-list:
+    colWidths:
+      - '20'
+      - null
+    commands:
+      - - LEFTPADDING
+        - - 0
+          - 0
+        - - 1
+          - -1
+        - 5
+      - - RIGHTPADDING
+        - - 0
+          - 0
+        - - 1
+          - -1
+        - 0
+    textColor: '#aaaaaa'
+
+  bullet-list-item:
+    spaceAfter: 0
+    spaceBefore: 18
+
+  centred:
+    alignment: TA_CENTER
+    parent: normal
+
+  centredtitle:
+    alignment: TA_CENTER
+    fontName: fontBold
+    fontSize: 48
+    leading: 64
+    parent: heading
+
+  code:
+    backColor: white
+    borderWidth: 0
+    fontSize: 22
+    leading: 24
+    parent: literal
+    spaceBefore: 0
+
+  footer:
+    alignment: TA_RIGHT
+    fontName: fontMono
+    fontSize: 20
+    rightIndent: 16
+    spaceBefore: 0
+    textColor: '#24608a'
+
+  heading:
+    fontName: fontBold
+    fontSize: 20
+    spaceAfter: 16
+    textColor: '#24608a'
+
+  literal:
+    backColor: white
+    fontName: fontMono
+
+  normal:
+    fontSize: 24
+    textColor: '#383745'
+
+  title:
+    fontSize: 300%
+    parent: heading
+
+  titleslideinfo:
+    alignment: TA_CENTER
+    fontSize: 140%
+    parent: normal
diff --git a/working-without-workspace/sections/build-configs.rst b/working-without-workspace/sections/build-configs.rst
new file mode 100644
index 0000000..675dc0a
--- /dev/null
+++ b/working-without-workspace/sections/build-configs.rst
@@ -0,0 +1,71 @@
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+Generating configuration files
+
+.. raw:: pdf
+
+   PageBreak standardPage
+
+build-configs
+=============
+
+Most of my projects have the same configuration files:
+
+|
+
+* ``Dockerfile``
+* ``docker-compose.yaml``
+* ``justfile``
+* ``phpstan.neon.dist``
+* ``phpunit.xml.dist``
+
+.. raw:: pdf
+
+   TextAnnotation "Same files with either the same or similar values. What if, instead of copying and pasting these between projects, I could generate them from a canonical set of templates?"
+
+build-configs
+=============
+
+* Symfony/Silly CLI project
+* Twig for templating
+* Takes values from a `build.yaml` file
+* Generates the appropriate files with the correct configuration
+* Easier to set up a new project
+* Less maintenance overhead
+* Can quickly add a new feature and update every project
+
+.. raw:: pdf
+
+   TextAnnotation "Opinionated template files"
+
+build.yaml
+==========
+
+.. code-block:: yaml
+   :include: code/build.yaml
+   :linenos:
+
+Dockerfile.twig
+===============
+
+.. code-block:: Dockerfile
+   :include: code/Dockerfile.twig
+   :linenos:
+
+docker-compose.yaml.twig
+========================
+
+.. code-block:: twig
+   :include: code/docker-compose.yaml.twig
+   :linenos:
+
+justfile.twig
+=============
+
+.. code-block:: twig
+   :include: code/justfile.twig
+   :linenos:
diff --git a/working-without-workspace/sections/flakes.rst b/working-without-workspace/sections/flakes.rst
new file mode 100644
index 0000000..bc70584
--- /dev/null
+++ b/working-without-workspace/sections/flakes.rst
@@ -0,0 +1,22 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+Nix Flakes
+==========
+
+* Per project
+* Uses ``nixpkgs`` to create a development shell
+* Can create build artifacts (phar?)
+* Could replace Docker and Docker Compose
+
+.. raw:: pdf
+
+   TextAnnotation "Creates a temporary shell with the requirements for that project."
+
+flake.nix
+=========
+
+.. code-block:: nix
+   :include: code/flake.nix
+   :linenos:
diff --git a/working-without-workspace/sections/git.rst b/working-without-workspace/sections/git.rst
new file mode 100644
index 0000000..763b99a
--- /dev/null
+++ b/working-without-workspace/sections/git.rst
@@ -0,0 +1,19 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+Git
+===
+
+Customised to my preferences, managed by Home Manager:
+
+.. code-block:: nix
+   :include: code/git.nix
+   :linenos:
+
+.. raw:: pdf
+
+   PageBreak
+
+.. code-block:: ini
+   :include: code/gitconfig.ini
diff --git a/working-without-workspace/sections/just.rst b/working-without-workspace/sections/just.rst
new file mode 100644
index 0000000..91eae15
--- /dev/null
+++ b/working-without-workspace/sections/just.rst
@@ -0,0 +1,69 @@
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+just
+
+.. raw:: pdf
+
+   TextAnnotation "Who's used a Makefile? I have, but wasn't using a lot of the build features it has. I was using it as a task runner."
+
+.. raw:: pdf
+
+   PageBreak standardPage
+
+justfile
+========
+
+.. code-block:: make
+
+   default:
+     @just --list
+
+   _exec +args:
+     docker compose exec {{ args }}
+
+   # Run Composer
+   composer *args:
+     just _exec php composer {{ args }}
+
+   # Run Drush commands
+   drush *args:
+     just _exec php drush {{ args }}
+
+   # Install Drupal
+   install *args:
+     just drush site:install -y {{ args }}
+
+   # Run Artisan commands (Laravel)
+   artisan *args:
+     docker compose run \
+       --entrypoint php \
+       --rm \
+       --tty \
+       php artisan {{ args }}
+
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+``just composer require
+drupal/override_node_options``
+
+.. raw:: pdf
+
+   PageBreak
+
+.. class:: centredtitle
+
+``just drush cache-rebuild``
+
+|
+
+.. class:: centredtitle
+
+``just install localgov``
diff --git a/working-without-workspace/sections/neovim.rst b/working-without-workspace/sections/neovim.rst
new file mode 100644
index 0000000..7763157
--- /dev/null
+++ b/working-without-workspace/sections/neovim.rst
@@ -0,0 +1,14 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+neovim
+======
+
+* Community-maintained fork of Vim
+* Configured with Lua
+* ``nvim-lspconfig`` for language server support
+* Intelephense and Phpactor for PHP
+* ``nvim-dap`` and ``nvim-dap-ui`` for step debugging
+* ``nvim-cmp`` for completion, LuaSnip for snippets
+* PHPCS, PHPStan diagnostics with ``null-ls.nvim``
diff --git a/working-without-workspace/sections/operating-system.rst b/working-without-workspace/sections/operating-system.rst
new file mode 100644
index 0000000..9fdbd9c
--- /dev/null
+++ b/working-without-workspace/sections/operating-system.rst
@@ -0,0 +1,138 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+Operating system
+================
+
+**Personal**:
+
+- Linux
+- NixOS
+- KDE Plasma
+
+|
+
+**Work**:
+
+- Windows 10
+- WSL (Ubuntu)
+- Nix package manager
+
+.. raw:: pdf
+
+    TextAnnotation "Started with Ubuntu for work, used Pop!_OS for personal laptops and now on NixOS."
+    TextAnnotation "Used to use Apple/macOS and switched full-time to Linux a few years ago.used Homebrew for package management."
+    TextAnnotation "Automated things with Ansible."
+    TextAnnotation ""
+    TextAnnotation "Use Windows for Office, Teams, etc. Development is done within the WSL/Linux environment."
+
+Nix and NixOS
+=============
+
+- Declarative
+- Reproducable
+- Nix Packages collection (``nixpkgs``) has over 80,000 packages
+- Easy to add to and edit, and contribute to
+
+.. raw:: pdf
+
+   TextAnnotation "Nix builds packages in isolation from each other. This ensures that they are reproducible and don't have undeclared dependencies, so if a package works on one machine, it will also work on another."
+   TextAnnotation "Nix makes it trivial to share development and build environments for your projects, regardless of what programming languages and tools you’re using. "
+   TextAnnotation "80,000 packages including Vim and tmux plugins, PHP and node packages"
+   TextAnnotation "Configuration file-driven. You declare the end state rather than the steps to get there."
+   TextAnnotation "Replaced Ansible for me."
+
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+``nix-env -iA php82``
+
+.. raw:: pdf
+
+   PageBreak
+
+.. class:: centredtitle
+
+``nix-shell --packages php82``
+
+.. raw:: pdf
+
+   PageBreak
+
+.. class:: centredtitle
+
+``nix-shell --packages php82
+--command "php -v"``
+
+.. raw:: pdf
+
+   PageBreak standardPage
+
+configuration.nix
+=================
+
+.. code-block:: nix
+   :include: code/configuration.nix
+   :linenos:
+
+
+hardware-configuration.nix
+==========================
+
+.. code-block:: nix
+   :include: code/hardware-configuration.nix
+   :linenos:
+
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+``sudo nixos-rebuild build
+--flake .#nixedo``
+
+.. raw:: pdf
+
+   PageBreak standardPage
+
+dotfiles
+========
+
+* System configuration files
+* Usually hidden, filenames start with a dot (``.zshrc``, ``.gitconfig``, ``.config/``)
+* Maintained on GitHub since July 2015
+* https://opdavi.es/dotfiles
+* Managed with Home Manager
+
+.. raw:: pdf
+
+    TextAnnotation "Similar to hidden files within projects like .gitignore."
+    TextAnnotation "Manages user configuration instead of system configuration."
+    TextAnnotation ""
+    TextAnnotation "Used with NixOS and the Nix package manager in WSL."
+
+home-manager/home.nix
+=====================
+
+.. code-block:: nix
+    :include: code/home-manager.nix
+    :linenos:
+
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+``home-manager build
+-f home-manager/home.nix
+--flake .#wsl2``
+
+.. raw:: pdf
+
+   PageBreak standardPage
diff --git a/working-without-workspace/sections/others.rst b/working-without-workspace/sections/others.rst
new file mode 100644
index 0000000..6bb2abe
--- /dev/null
+++ b/working-without-workspace/sections/others.rst
@@ -0,0 +1,12 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+Other mentions
+==============
+
+* ``fzf``
+* ``grep`` and ``ripgrep``
+* ``find`` and ``xargs``
+* Pulumi and Terraform for infrastructure automation
+* Ansible and Ansistrano
diff --git a/working-without-workspace/sections/shell.rst b/working-without-workspace/sections/shell.rst
new file mode 100644
index 0000000..11b72bb
--- /dev/null
+++ b/working-without-workspace/sections/shell.rst
@@ -0,0 +1,80 @@
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+Z Shell
+
+.. raw:: pdf
+
+   PageBreak standardPage
+
+Why zsh?
+========
+
+* Replacement for the ``bash`` shell
+* Default on macOS
+* Separate to "oh-my-zsh"
+* OMZSH plugins and themes can be installed using ``zplug``
+* Aliases
+* Globbing and expanding
+
+Aliases
+=======
+
+.. code-block:: bash
+   :linenos:
+   :include: code/aliases.sh
+
+.. raw:: pdf
+
+   TextAnnotation "Can be used to override default behaviour or to add new commands and shortcuts."
+
+Globbing and expanding
+======================
+
+Changing a file prefix:
+
+``mv index.{html,twig}``
+
+``mv index.html index.twig``
+
+|
+
+Creating two files with different prefixes:
+
+``touch my-component.{config.yml,twig}``
+
+|
+
+Creating a range of files:
+
+``touch {1..10}.php``
+
+Auto-expanding
+==============
+
+.. code-block:: bash
+   :linenos:
+
+   expand-alias-space() {
+     [[ $LBUFFER =~ "\<(''${(j:|:)baliases})\$" ]]; insertBlank=$?
+     if [[ ! $LBUFFER =~ "\<(''${(j:|:)ialiases})\$" ]]; then
+       zle _expand_alias
+     fi
+
+     zle self-insert
+
+     if [[ "$insertBlank" = "0" ]]; then
+       zle backward-delete-char
+     fi
+   }
+
+   zle -N expand-alias-space
+
+   bindkey " " expand-alias-space
+
+.. raw:: pdf
+
+   TextAnnotation "More like snippets than aliases."
diff --git a/working-without-workspace/sections/tmux.rst b/working-without-workspace/sections/tmux.rst
new file mode 100644
index 0000000..cea44f1
--- /dev/null
+++ b/working-without-workspace/sections/tmux.rst
@@ -0,0 +1,12 @@
+.. raw:: pdf
+
+   PageBreak standardPage
+
+tmux
+====
+
+* "Terminal multiplexer"
+* Splits a terminal into different sessions and panes
+* One session per project
+* Editing in one pane, running commands in another
+* Long-running commands in a separate window
diff --git a/working-without-workspace/working-without-workspace.rst b/working-without-workspace/working-without-workspace.rst
new file mode 100644
index 0000000..79fba0d
--- /dev/null
+++ b/working-without-workspace/working-without-workspace.rst
@@ -0,0 +1,55 @@
+.. footer:: @opdavies
+
+Working without Workspace
+#########################
+
+|
+
+.. class:: titleslideinfo
+
+Oliver Davies (@opdavies)
+
+.. raw:: pdf
+
+   PageBreak titlePage
+
+.. class:: centredtitle
+
+Working with Workspace
+
+.. raw:: pdf
+
+    TextAnnotation "Workspace is an open-source project developed and maintained by Inviqa, which we used on our projects and I was starting to use on personal projects."
+    TextAnnotation "This talk is about how my development environment and tools work now, a couple of years after leaving Inviqa."
+
+.. include:: sections/operating-system.rst
+.. include:: sections/shell.rst
+.. include:: sections/git.rst
+.. include:: sections/just.rst
+.. include:: sections/build-configs.rst
+.. include:: sections/flakes.rst
+.. include:: sections/neovim.rst
+.. include:: sections/tmux.rst
+.. include:: sections/others.rst
+
+.. raw:: pdf
+
+  PageBreak standardPage
+
+Thanks!
+=======
+
+References:
+
+* https://opdavi.es/dotfiles
+* https://nixos.org
+* https://just.systems
+* https://neovim.io
+* https://github.com/tmux/tmux/wiki
+* https://opdavi.es/docker-examples
+
+|
+
+Me:
+
+* https://www.oliverdavies.uk