diff --git a/flake.lock b/flake.lock index 2c27450..c874f70 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,22 @@ { "nodes": { + "brew-src": { + "flake": false, + "locked": { + "lastModified": 1761551821, + "narHash": "sha256-N3Zj73TAxclhLGgADbPVwcVrhYIBKUgAxjfQuOXre6s=", + "owner": "Homebrew", + "repo": "brew", + "rev": "8f6719274133c5bcc24c058c5a6bcbb3b0cd48b3", + "type": "github" + }, + "original": { + "owner": "Homebrew", + "ref": "4.6.19", + "repo": "brew", + "type": "github" + } + }, "claude-code": { "inputs": { "flake-utils": "flake-utils", @@ -187,6 +204,27 @@ "type": "github" } }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762627886, + "narHash": "sha256-/QLk1bzmbcqJt9sU43+y/3tHtXhAy0l8Ck0MoO2+evQ=", + "owner": "nix-darwin", + "repo": "nix-darwin", + "rev": "5125a3cd414dc98bbe2c528227aa6b62ee61f733", + "type": "github" + }, + "original": { + "owner": "nix-darwin", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "nix-github-actions": { "inputs": { "nixpkgs": [ @@ -209,6 +247,24 @@ "type": "github" } }, + "nix-homebrew": { + "inputs": { + "brew-src": "brew-src" + }, + "locked": { + "lastModified": 1761927470, + "narHash": "sha256-KsFDGRGD8j1R6TvJ4HkebKsh3HXLY0XazanLrhO3wqE=", + "owner": "zhaofengli", + "repo": "nix-homebrew", + "rev": "3cae36b3a17b09a66435291619dce8cf2c4728ca", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "repo": "nix-homebrew", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1762361079, @@ -294,6 +350,8 @@ "firefox-addons": "firefox-addons", "home-manager": "home-manager", "jovian-nixos": "jovian-nixos", + "nix-darwin": "nix-darwin", + "nix-homebrew": "nix-homebrew", "nixpkgs": "nixpkgs_2", "nixvim": "nixvim" } diff --git a/flake.nix b/flake.nix index fc83db0..60171f8 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,8 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + nix-darwin.url = "github:nix-darwin/nix-darwin/master"; + nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; nixvim.url = "github:nix-community/nixvim"; @@ -12,14 +14,22 @@ url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; inputs.nixpkgs.follows = "nixpkgs"; }; + nix-homebrew.url = "github:zhaofengli/nix-homebrew"; disko.url = "github:nix-community/disko"; disko.inputs.nixpkgs.follows = "nixpkgs"; jovian-nixos.url = "github:Jovian-Experiments/Jovian-NixOS"; jovian-nixos.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = inputs@{ self, nixpkgs, home-manager, nixvim, claude-code, firefox-addons, disko, jovian-nixos }: + outputs = inputs@{ self, nix-darwin, nixpkgs, home-manager, nixvim, claude-code, firefox-addons, nix-homebrew, disko, jovian-nixos }: { + darwinConfigurations."macbook" = nix-darwin.lib.darwinSystem { + modules = [ + ./hosts/darwin/macbook/system.nix + ]; + specialArgs = { inherit nix-homebrew; }; + }; + nixosConfigurations."hs" = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ @@ -58,6 +68,12 @@ }; homeConfigurations = { + "yanlin@macbook" = home-manager.lib.homeManagerConfiguration { + pkgs = nixpkgs.legacyPackages.aarch64-darwin; + modules = [ ./hosts/darwin/macbook/home.nix ]; + extraSpecialArgs = { inherit claude-code nixvim firefox-addons; }; + }; + "yanlin@hs" = home-manager.lib.homeManagerConfiguration { pkgs = nixpkgs.legacyPackages.x86_64-linux; modules = [ ./hosts/nixos/hs/home.nix ]; diff --git a/hosts/darwin/home-default.nix b/hosts/darwin/home-default.nix new file mode 100644 index 0000000..55c6872 --- /dev/null +++ b/hosts/darwin/home-default.nix @@ -0,0 +1,191 @@ +{ config, pkgs, nixvim, claude-code, firefox-addons, ... }: + +{ + imports = [ + nixvim.homeModules.nixvim + ../../modules/nvim.nix + ../../modules/tmux.nix + ../../modules/zsh.nix + ../../modules/ssh.nix + ../../modules/git.nix + ../../modules/lazygit.nix + ../../modules/papis.nix + ../../modules/termscp.nix + ../../modules/rsync.nix + ../../modules/btop.nix + ../../modules/firefox.nix + ../../modules/ghostty.nix + ../../modules/syncthing.nix + ../../modules/dictionary.nix + ../../modules/yt-dlp.nix + ../../modules/claude-code.nix + ../../modules/tex.nix + ../../modules/fonts.nix + ]; + + nixpkgs.config.allowUnfree = true; + + # Firefox configuration + programs.firefox-custom = { + enable = true; + package = null; # Use system Firefox on Darwin + }; + + # Ghostty configuration + programs.ghostty-custom = { + enable = true; + package = null; # Use Homebrew-installed Ghostty on Darwin + windowMode = "windowed"; + windowWidth = 999; + windowHeight = 999; + }; + + # Claude Code configuration + programs.claude-code-custom = { + enable = true; + }; + + home.username = "yanlin"; + home.homeDirectory = "/Users/yanlin"; + home.stateVersion = "24.05"; + + programs.home-manager.enable = true; + + # darwin-specific alias + programs.zsh.shellAliases = { + oss = "sudo darwin-rebuild switch --flake ~/.config/nix#$(hostname)"; + + preview = "open -a Preview"; + slide = "open -a SlidePilot"; + + # Network monitoring aliases + bw = "sudo bandwhich"; + bw-raw = "sudo bandwhich --raw"; + bw-dns = "sudo bandwhich --show-dns"; + }; + + # Darwin-specific zsh functions + programs.zsh.initContent = '' + # Function to search and open all macOS applications + function app() { + local app_path + local file_to_open="$1" + + app_path=$( (find -L /Applications -name "*.app" -maxdepth 2 2>/dev/null; \ + find -L ~/Applications -name "*.app" -maxdepth 3 2>/dev/null; \ + find /System/Applications -name "*.app" -maxdepth 2 2>/dev/null; \ + find /System/Applications/Utilities -name "*.app" -maxdepth 1 2>/dev/null) | + sort | uniq | + fzf --header="Select app to open''${file_to_open:+ file: $file_to_open}" \ + --preview 'basename {} .app' \ + --preview-window=up:1 \ + --height=40%) + + if [[ -n "$app_path" ]]; then + if [[ -n "$file_to_open" ]]; then + open -a "$app_path" "$file_to_open" + else + open "$app_path" + fi + fi + } + + # SSH tunnel functions for easy VPN-like functionality + function tunnel-on() { + if [[ -z "$1" ]]; then + echo "Usage: tunnel-on " + return 1 + fi + + local host="$1" + local port=1080 # Use port 1080 (standard SOCKS port) + + # Check if there's already an active tunnel + local existing_tunnel=$(ps aux | grep -E "ssh -D $port" | grep -v grep) + if [[ -n "$existing_tunnel" ]]; then + echo "Existing tunnel detected. Switching to $host..." + echo "Stopping current tunnel..." + pkill -f "ssh -D $port" + sleep 1 + fi + + echo "Starting SOCKS tunnel to $host on port $port..." + + # Start SSH tunnel in background + ssh -D $port -N -f "$host" + if [[ $? -eq 0 ]]; then + echo "Tunnel established. Configuring system proxy..." + + # Configure system proxy + networksetup -setsocksfirewallproxy "Wi-Fi" localhost $port + networksetup -setsocksfirewallproxystate "Wi-Fi" on + + echo "✓ System proxy enabled on Wi-Fi (localhost:$port -> $host)" + else + echo "✗ Failed to establish tunnel to $host" + return 1 + fi + } + + function tunnel-off() { + local port=1080 + echo "Disabling system proxy..." + networksetup -setsocksfirewallproxystate "Wi-Fi" off + echo "✓ System proxy disabled" + + echo "Stopping SSH tunnels..." + pkill -f "ssh -D $port" + echo "✓ SSH tunnels stopped" + } + + function tunnel-status() { + local port=1080 + echo "=== System Proxy Status ===" + networksetup -getsocksfirewallproxy "Wi-Fi" | grep -E "Enabled|Server|Port" + + echo "" + echo "=== Active SSH Tunnels ===" + local tunnels=$(ps aux | grep -E "ssh -D $port" | grep -v grep) + if [[ -n "$tunnels" ]]; then + echo "$tunnels" + else + echo "No active SSH tunnels" + fi + } + ''; + + home.packages = with pkgs; [ + # Network and file transfer + lftp + httpie + openssh + gnumake + + # Network diagnostic tools + bind # DNS utilities (dig, nslookup, mdig) + inetutils # Network utilities (telnet) + netcat-gnu # Network connection utility + curl # HTTP client + wget # Web downloader + bandwhich # Terminal bandwidth utilization tool + + # Command-line utilities + ncdu + git-credential-oauth + zoxide + delta + fastfetch + coreutils # GNU core utilities (base64, etc.) + + # macOS-specific GUI applications + maccy # Clipboard manager (macOS-only) + iina # Media player (macOS-optimized) + hidden-bar # Menu bar organizer (macOS-only) + + # Development and build tools + python312 + uv + lazysql + sqlite + ]; +} diff --git a/hosts/darwin/macbook/home.nix b/hosts/darwin/macbook/home.nix new file mode 100644 index 0000000..e446276 --- /dev/null +++ b/hosts/darwin/macbook/home.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ../home-default.nix + ]; + + # MacBook-specific home configuration + # Example: Laptop-specific tools, power management, etc. + + # yt-dlp configuration + programs.yt-dlp-custom = { + enable = true; + downloadDir = "~/Downloads/Videos"; + }; +} diff --git a/hosts/darwin/macbook/system.nix b/hosts/darwin/macbook/system.nix new file mode 100644 index 0000000..39e41cb --- /dev/null +++ b/hosts/darwin/macbook/system.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + # MacBook-specific configuration + networking.computerName = "macbook"; + networking.hostName = "macbook"; + + # Import common Darwin configuration + imports = [ + ../system-default.nix + ]; +} diff --git a/hosts/darwin/system-default.nix b/hosts/darwin/system-default.nix new file mode 100644 index 0000000..f8e1ff7 --- /dev/null +++ b/hosts/darwin/system-default.nix @@ -0,0 +1,159 @@ +{ config, pkgs, nix-homebrew, ... }: + +{ + imports = [ + ../../modules/homebrew.nix + nix-homebrew.darwinModules.nix-homebrew + ]; + + # Nix configuration + nix.settings.experimental-features = "nix-command flakes"; + nix.settings.substituters = [ + "https://cache.nixos.org/" + "https://nix-community.cachix.org" + "https://devenv.cachix.org" + ]; + nix.settings.trusted-public-keys = [ + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + ]; + + # System configuration + system.stateVersion = 6; + nixpkgs.hostPlatform = "aarch64-darwin"; + programs.zsh.enable = true; + + # Set primary user for system preferences + system.primaryUser = "yanlin"; + + # Security configuration - passwordless sudo for yanlin + security.sudo.extraConfig = '' + yanlin ALL=(ALL) NOPASSWD: ALL + ''; + + system.defaults = { + dock = { + autohide = true; # Automatically hide and show the dock + autohide-delay = 0.2; # Delay before showing the dock (in seconds) + autohide-time-modifier = 0.5; # Animation duration for dock show/hide + orientation = "bottom"; # Dock position: "bottom", "left", or "right" + tilesize = 48; # Size of dock icons (16-128) + magnification = false; # Enable magnification when hovering + minimize-to-application = false; # Minimize windows to application icon + show-recents = true; # Show recent applications in dock + show-process-indicators = true; # Show dots under running apps + static-only = false; # Show only open applications + mru-spaces = false; # Automatically rearrange spaces based on use + expose-animation-duration = 0.5; # Mission Control animation speed + dashboard-in-overlay = false; # Show Dashboard as overlay + persistent-apps = [ + "/Applications/Firefox.app" + "/Applications/Obsidian.app" + "/Applications/Ghostty.app" + "/Applications/KeePassXC.app" + ]; + persistent-others = [ + "/Users/yanlin/Desktop" + "/Users/yanlin/Downloads" + "/Users/yanlin/Documents" + ]; # List of folders/files to keep in dock + + # Hot Corners - Actions: + # 1 = Disabled, 2 = Mission Control, 3 = Application Windows, + # 4 = Desktop, 5 = Start Screen Saver, 6 = Disable Screen Saver, + # 7 = Dashboard, 10 = Put Display to Sleep, 11 = Launchpad, + # 12 = Notification Center, 13 = Lock Screen, 14 = Quick Note + wvous-tl-corner = 1; # Top left corner action + wvous-tr-corner = 1; # Top right corner action + wvous-bl-corner = 1; # Bottom left corner action + wvous-br-corner = 1; # Bottom right corner action + }; + + finder = { + AppleShowAllExtensions = true; # Show all file extensions + AppleShowAllFiles = true; # Show hidden files + CreateDesktop = true; # Show icons on desktop + FXEnableExtensionChangeWarning = false; # Warn when changing file extension + FXPreferredViewStyle = "Nlsv"; # Default view: "icnv"=Icon, "Nlsv"=List, "clmv"=Column, "glyv"=Gallery + QuitMenuItem = false; # Allow quitting Finder with ⌘Q + ShowPathbar = true; # Show path bar at bottom + ShowStatusBar = true; # Show status bar at bottom + _FXShowPosixPathInTitle = false; # Show full POSIX path in title + _FXSortFoldersFirst = true; # Sort folders before files + }; + + # -------------------------------------------------------------------------- + # Global Domain Settings (NSGlobalDomain) + # -------------------------------------------------------------------------- + NSGlobalDomain = { + AppleInterfaceStyle = "Dark"; # Dark mode: "Dark" or remove for light + AppleInterfaceStyleSwitchesAutomatically = false; # Auto switch dark/light + NSAutomaticWindowAnimationsEnabled = true; # Window animations + NSDocumentSaveNewDocumentsToCloud = false; # Save to iCloud by default + NSNavPanelExpandedStateForSaveMode = true; # Expand save panel by default + PMPrintingExpandedStateForPrint = true; # Expand print panel by default + NSTableViewDefaultSizeMode = 2; # Sidebar icon size: 1=small, 2=medium, 3=large + AppleShowScrollBars = "WhenScrolling"; # "WhenScrolling", "Automatic", or "Always" + NSScrollAnimationEnabled = true; # Smooth scrolling + NSWindowResizeTime = 0.2; # Window resize animation duration + _HIHideMenuBar = false; # Auto-hide menu bar + + NSAutomaticCapitalizationEnabled = false; # Disable automatic capitalization + NSAutomaticDashSubstitutionEnabled = false; # Disable smart dashes + NSAutomaticPeriodSubstitutionEnabled = false; # Disable automatic period with double-space + NSAutomaticQuoteSubstitutionEnabled = false; # Disable smart quotes + NSAutomaticSpellingCorrectionEnabled = false; # Disable auto-correction + NSAutomaticInlinePredictionEnabled = false; # Disable inline predictive text + "com.apple.keyboard.fnState" = false; # Use F1, F2, etc. as standard function keys + }; + + screencapture = { + disable-shadow = true; # Disable shadow in screenshots + location = "~/Desktop"; # Default save location + type = "png"; # Screenshot format: png, jpg, pdf, etc. + show-thumbnail = true; # Show thumbnail after taking screenshot + }; + + loginwindow = { + GuestEnabled = false; # Disable guest account + ShutDownDisabled = false; # Allow shutdown from login window + RestartDisabled = false; # Allow restart from login window + SleepDisabled = false; # Allow sleep from login window + }; + + spaces = { + spans-displays = false; # Each display has separate spaces + }; + }; + + system.activationScripts.extraActivation.text = '' + sudo -u yanlin defaults -currentHost write -globalDomain NSStatusItemSpacing -int 10 + + # Disable Spotlight indexing for all volumes + # WARNING: This will break Mail.app search, Time Machine, and other features + # To re-enable: sudo mdutil -a -i on + sudo mdutil -a -i off + sudo mdutil -E / + + /System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u + ''; + + # Key remapping using hidutil via launchd agent + # This swaps Control and Caps Lock keys bidirectionally + launchd.user.agents.remap-keys = { + serviceConfig = { + ProgramArguments = [ + "/usr/bin/hidutil" + "property" + "--set" + ''{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x7000000E0},{"HIDKeyboardModifierMappingSrc":0x7000000E0,"HIDKeyboardModifierMappingDst":0xFF00000003}]}'' + ]; + RunAtLoad = true; + KeepAlive = false; + Label = "org.nixos.remap-keys"; + StandardErrorPath = "/tmp/remap-keys.err"; + StandardOutPath = "/tmp/remap-keys.out"; + }; + }; +} diff --git a/modules/homebrew.nix b/modules/homebrew.nix new file mode 100644 index 0000000..5ba0761 --- /dev/null +++ b/modules/homebrew.nix @@ -0,0 +1,44 @@ +{ config, pkgs, ... }: + +{ + # Homebrew configuration for package management + homebrew = { + enable = true; + onActivation = { + autoUpdate = true; + cleanup = "zap"; # Removes unlisted formulae/casks + upgrade = true; + }; + brews = [ + # Command-line tools go here + ]; + casks = [ + # GUI applications - manually installed apps now managed by Homebrew + "keepassxc" + "keycastr" + "inkscape" + "firefox" + "obsidian" + "snipaste" + "ghostty" + "slidepilot" + "tencent-meeting" + "ovito" + "microsoft-powerpoint" + "microsoft-word" + "microsoft-excel" + "rectangle" + ]; + taps = [ + # Additional repositories if needed + ]; + }; + + # nix-homebrew configuration for declarative Homebrew installation + nix-homebrew = { + enable = true; + enableRosetta = true; # Apple Silicon support + user = "yanlin"; + autoMigrate = true; # Migrate existing Homebrew if present + }; +} diff --git a/modules/lazygit.nix b/modules/lazygit.nix index bbe1629..a129506 100644 --- a/modules/lazygit.nix +++ b/modules/lazygit.nix @@ -334,8 +334,8 @@ # OS settings os = { - open = "xdg-open {{filename}}"; - openLink = "xdg-open {{link}}"; + open = if pkgs.stdenv.isDarwin then "open {{filename}}" else "xdg-open {{filename}}"; + openLink = if pkgs.stdenv.isDarwin then "open {{link}}" else "xdg-open {{link}}"; }; # Disable startup popup diff --git a/modules/nvim.nix b/modules/nvim.nix index 84bd2cb..9bbce26 100644 --- a/modules/nvim.nix +++ b/modules/nvim.nix @@ -262,12 +262,21 @@ in action = ":lua open_file_with_system_app()"; options = { desc = "Open file with system default app"; }; } + ] ++ (if pkgs.stdenv.isDarwin then [ + { + mode = "n"; + key = "f"; + action = ":lua show_file_in_file_manager()"; + options = { desc = "Show current file in Finder"; }; + } + ] else [ { mode = "n"; key = "f"; action = ":!thunar %:h &"; options = { desc = "Open current file directory in file manager"; }; } + ]) ++ [ # Markdown rendering { @@ -307,11 +316,20 @@ in }) -- Dictionary completion setup - require("cmp_dictionary").setup({ - paths = { "${pkgs.scowl}/share/dict/wamerican.txt" }, -- Nix-provided dictionary - exact_length = 2, -- Minimum length before completion - first_case_insensitive = true, -- Case insensitive matching - }) + ${lib.optionalString pkgs.stdenv.isDarwin '' + require("cmp_dictionary").setup({ + paths = { "/usr/share/dict/words" }, -- Standard dictionary path on macOS + exact_length = 2, -- Minimum length before completion + first_case_insensitive = true, -- Case insensitive matching + }) + ''} + ${lib.optionalString (!pkgs.stdenv.isDarwin) '' + require("cmp_dictionary").setup({ + paths = { "${pkgs.scowl}/share/dict/wamerican.txt" }, -- Nix-provided dictionary on NixOS + exact_length = 2, -- Minimum length before completion + first_case_insensitive = true, -- Case insensitive matching + }) + ''} -- Jupytext setup for Jupyter notebook viewing require("jupytext").setup({ @@ -352,18 +370,21 @@ in } -- OSC-52 clipboard integration (matches tmux setup, works with Ghostty) - -- This enables clipboard functionality across SSH and tmux - vim.g.clipboard = { - name = 'OSC 52', - copy = { - ['+'] = require('vim.ui.clipboard.osc52').copy('+'), - ['*'] = require('vim.ui.clipboard.osc52').copy('*'), - }, - paste = { - ['+'] = require('vim.ui.clipboard.osc52').paste('+'), - ['*'] = require('vim.ui.clipboard.osc52').paste('*'), - }, - } + -- This enables clipboard functionality across SSH, tmux, and multi-platform + -- Only enabled on Linux; macOS uses native clipboard with "unnamedplus" + ${lib.optionalString (!pkgs.stdenv.isDarwin) '' + vim.g.clipboard = { + name = 'OSC 52', + copy = { + ['+'] = require('vim.ui.clipboard.osc52').copy('+'), + ['*'] = require('vim.ui.clipboard.osc52').copy('*'), + }, + paste = { + ['+'] = require('vim.ui.clipboard.osc52').paste('+'), + ['*'] = require('vim.ui.clipboard.osc52').paste('*'), + }, + } + ''} -- Close all buffers except current (preserving NvimTree and other special buffers) function close_other_buffers() @@ -388,13 +409,28 @@ in function open_file_with_system_app() local filepath = vim.fn.expand('%:p') if filepath ~= "" then - -- Use jobstart for async execution (detach = true prevents blocking) - vim.fn.jobstart({'xdg-open', filepath}, {detach = true}) + local escaped_path = vim.fn.shellescape(filepath) + ${if pkgs.stdenv.isDarwin then + "vim.fn.system('open ' .. escaped_path)" + else + "vim.fn.system('xdg-open ' .. escaped_path)"} else print("No file to open") end end + ${lib.optionalString pkgs.stdenv.isDarwin '' + function show_file_in_file_manager() + local filepath = vim.fn.expand('%:p') + if filepath ~= "" then + local escaped_path = vim.fn.shellescape(filepath) + vim.fn.system('open -R ' .. escaped_path) + else + print("No file to show") + end + end + ''} + -- Render-markdown setup (off by default, toggle with +m) require("render-markdown").setup({ enabled = false, -- Off by default, use +m to toggle diff --git a/modules/papis.nix b/modules/papis.nix index 760c08b..a9886a0 100644 --- a/modules/papis.nix +++ b/modules/papis.nix @@ -1,5 +1,10 @@ { pkgs, lib, ... }: +let + # Platform-aware papis config directory + papisConfigDir = if pkgs.stdenv.isDarwin then "Library/Application Support/papis" else ".config/papis"; +in + { # Install papis package home.packages = [ @@ -8,11 +13,11 @@ })) ]; # Papis configuration - home.file.".config/papis/config".text = '' + home.file."${papisConfigDir}/config".text = '' [settings] default-library = main editor = nvim - opentool = evince + opentool = ${if pkgs.stdenv.isDarwin then "open -a Preview" else "evince"} # Document management ref-format = {doc[author]}{doc[year]} @@ -43,7 +48,7 @@ ''; # Papis bibliography template - home.file.".config/papis/templates/bibitem.template".text = '' + home.file."${papisConfigDir}/templates/bibitem.template".text = '' {doc[title]} ({doc[year]}). {doc[author]}. Venue: {doc[journal]} {doc[booktitle]} {doc[eprinttype]} {doc[eprint]} {doc[eventtitle]} Tags: {doc[tags]} @@ -52,7 +57,7 @@ ''; # Papis BibTeX template - home.file.".config/papis/templates/bibtex.template".text = '' + home.file."${papisConfigDir}/templates/bibtex.template".text = '' @{doc[type]}{{{doc[ref]}, author = {{{doc[author]}}}, title = {{{doc[title]}}}, @@ -68,23 +73,23 @@ ''; # Papis citation template - home.file.".config/papis/templates/citation.template".text = '' + home.file."${papisConfigDir}/templates/citation.template".text = '' {doc[author]}. "{doc[title]}." {doc[journal]}{doc[booktitle]} ({doc[year]}). ''; # Shell aliases for papis workflow programs.zsh.shellAliases = { # Bibliography formatting - pals = "papis list --template \"$HOME/.config/papis/templates/bibitem.template\""; + pals = "papis list --template \"$HOME/${papisConfigDir}/templates/bibitem.template\""; # Add new entry with bibtex paadd = "papis add --from bibtex"; # BibTeX export - pabib = "papis list --template \"$HOME/.config/papis/templates/bibtex.template\""; + pabib = "papis list --template \"$HOME/${papisConfigDir}/templates/bibtex.template\""; # Citation formatting - pacite = "papis list --template \"$HOME/.config/papis/templates/citation.template\""; + pacite = "papis list --template \"$HOME/${papisConfigDir}/templates/citation.template\""; # File operations paurl = "papis addto -u"; diff --git a/modules/rsync.nix b/modules/rsync.nix index 904204f..18481ff 100644 --- a/modules/rsync.nix +++ b/modules/rsync.nix @@ -23,6 +23,12 @@ --partial --partial-dir=.rsync-partial + ${lib.optionalString pkgs.stdenv.isDarwin '' + # Preserve extended attributes and ACLs (macOS) + --extended-attributes + --acls + ''} + # Network optimization --compress --compress-level=6 diff --git a/modules/syncthing.nix b/modules/syncthing.nix index 52c4db0..7fceaaf 100644 --- a/modules/syncthing.nix +++ b/modules/syncthing.nix @@ -114,6 +114,11 @@ in }; }; + # Override the launchd agent to add RunAtLoad on macOS + launchd.agents.syncthing = lib.mkIf (pkgs.stdenv.isDarwin && config.services.syncthing.enable) { + config.RunAtLoad = true; + }; + # Deploy .stignore files to synced folders (only for enabled folders) home.file = lib.mkMerge [ (lib.mkIf (lib.elem "Credentials" cfg.enabledFolders) { diff --git a/modules/termscp.nix b/modules/termscp.nix index 2697a81..dc32755 100644 --- a/modules/termscp.nix +++ b/modules/termscp.nix @@ -3,7 +3,7 @@ { # Install termscp package home.packages = [ pkgs.termscp ]; - home.file.".config/termscp/config.toml".text = '' + home.file.${if pkgs.stdenv.isDarwin then "Library/Application Support/termscp/config.toml" else ".config/termscp/config.toml"}.text = '' # termscp configuration file # Generated by Nix - see modules/termscp.nix for customization