diff --git a/home.nix b/home.nix index 33bc21c4..28143d84 100644 --- a/home.nix +++ b/home.nix @@ -10,17 +10,13 @@ #MC 我利用环境变量`DISPLAY`用于判断是否导入GUI程序的配置。 { config, pkgs, stdenv, lib, ... }: - -{ +let + opt = import ./opt.nix; +in { imports = [ - ./opt.nix ./usr/modules/cachix.nix ./usr/cli.nix - # Q: how to use isGui here? - # A: Not possible. - # As isGui is evaluated after `imports` being evaluated, - # use config.isGui here cause infinite loop. - ] ++ lib.optionals ((builtins.getEnv "DISPLAY")!="") [ + ] ++ lib.optionals opt.isGui [ ./usr/gui.nix ]; diff --git a/opt.nix b/opt.nix index d434da09..25c75951 100644 --- a/opt.nix +++ b/opt.nix @@ -2,46 +2,49 @@ #MC #MC nix语言中只有`let ... in`来定义局部变量,没有提供全局变量的语法支持。 #MC 但在我的nix配置中又很需要一些“全局变量”来方便统一的管理多个配置文件。 +#MC 有2种可行的方案来实现全局变量:module和import。 +#MC +#MC ## module +#MC #MC nixpkgs的module能够还不错地实现“全局变量”。 -#MC 我的`opt.nix`即利用module的options定了多个可以供其他modules使用的全局变量。 #MC 想了解module?可以去看看[NixOS wikiL modules](https://nixos.wiki/wiki/NixOS_modules)。 #MC 或者看看nixpkgs源码关于modules.nix的部分`/lib/modules.nix`。 #MC #MC 要注意的是,基于module的“全局变量”也会有**局限**的。 #MC module是用过imports变量导入的,若在imports语句访问“全局变量”,nix的lazy evaluation的特性会导致死循环。 -#MC 这也是为什么[home.nix](./home.nix.md)中判断是否需要导入[./usr/gui.nix](./usr/gui.nix.md), +#MC 这也是为什么老版本的[home.nix](./home.nix.md)中判断是否需要导入[./usr/gui.nix](./usr/gui.nix.md), #MC 我没有使用`config.isGui`而是再次使用getEnv访问环境变量。 +#MC 当然这个不足也是我放弃使用的module主要原因。 +#MC +#MC ## import #MC -#MC 下面是我的配置的全局变量及注解。 - -{ config, pkgs, stdenv, lib, ... }: - -{ options = { +#MC 通过在配置文件中import opt.nix也能还不错的实现“全局变量”。 +#MC import方法的最大优势是能够在module imports语句中避免死循环。 +#MC +#MC 这个方法的不足之处在于每个需要使用全局变量的文件都需要import opt.nix。 +#MC 但这个不方便之处,相对imports死循环,没那么让人难受。 +{ + isMinimalConfig = false; #MC `proxyPort`:代理端口号,诸多网络程序需要用,比如clash和tailscale。 - proxyPort = lib.mkOption { - default = 8889; - readOnly = true; - }; + proxyPort = 8889; #MC `isCli`和`isGui`:通过环境变量`DISPLAY`来判断是否是CLI或GUI环境。 #MC 这个方法有**局限**,比如ssh连接到一台有GUI的电脑上,ssh里是没有设置环境变量`DISPLAY`的。 - #MC 若直接执行`home-manager switch`,则这台电脑上的GUI程序都会被禁用。 - #MC 缓解的方法也很简单,手动写个环境变量就好,比如`DISPLAY=1 home-manager switch`就OK啦😺。 - isCli = lib.mkOption { - default = (builtins.getEnv "DISPLAY")==""; - readOnly = true; - }; - isGui = lib.mkOption { - default = (builtins.getEnv "DISPLAY")!=""; - readOnly = true; - }; + #MC 因此更好的方法是在opt-local.nix中写入固定的isCli和isGui值。 + isCli = (builtins.getEnv "DISPLAY")==""; + isGui = (builtins.getEnv "DISPLAY")!=""; #MC `isNixOnDroid`:通过用户名来判断是否是nix-on-droid。 - isNixOnDroid = lib.mkOption { - default = config.home.username == "nix-on-droid"; - readOnly = true; - }; + isNixOnDroid = (builtins.getEnv "USER")=="nix-on-droid"; #MC `isWSL2`:通过环境变量`WSL_DISTRO_NAME`来判断是否是WSL2。 - isWSL2 = lib.mkOption { - default = (builtins.getEnv "WSL_DISTRO_NAME")!=""; - readOnly = true; - }; -};} + isWSL2 = (builtins.getEnv "WSL_DISTRO_NAME")!=""; +} +#MC ### 本地配置 +#MC +#MC 引入opt-local.nix,方便本地进行自定义,避免我的nix配置中出现过多设备特定代码(即一堆if else判断语句)。 +#MC 为了减少设备特定代码,每个设备都有自己的opt-local.nix。 +#MC 目前的想法是不将opt-local.nix加入git仓库,以实现“设备特定”。 +#MC 相比opt.nix,opt-local.nix的配置具备更高的优先级。 +// ( + if (builtins.pathExists ./opt4-local.nix) + then import ./opt4-local.nix + else {} +) diff --git a/opt4imports.nix b/opt4imports.nix deleted file mode 100644 index 4c122b1b..00000000 --- a/opt4imports.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ - isMinimalConfig = false; -} // ( - if (builtins.pathExists ./opt4imports-local.nix) - then import ./opt4imports-local.nix - else {} -) diff --git a/usr/cli-extra.nix b/usr/cli-extra.nix index 72902f87..6196245f 100644 --- a/usr/cli-extra.nix +++ b/usr/cli-extra.nix @@ -1,6 +1,8 @@ #MC # cli-extra.nix: Extra CLI configs (added to minial cli.nix) { config, pkgs, stdenv, lib, ... }: -{ +let + opt = import ../opt.nix; +in { imports = [{ home.packages = let pandora = pkgs.python3Packages.callPackage ./cli/pandora-chatgpt.nix {}; @@ -21,12 +23,12 @@ # use host proxy "--container-options" "--network=host" - "--env" "HTTPS_PROXY='http://127.0.0.1:${toString config.proxyPort}'" - "--env" "HTTP_PROXY='http://127.0.0.1:${toString config.proxyPort}'" - "--env" "FTP_PROXY='http://127.0.0.1:${toString config.proxyPort}'" - "--env" "https_proxy='http://127.0.0.1:${toString config.proxyPort}'" - "--env" "http_proxy='http://127.0.0.1:${toString config.proxyPort}'" - "--env" "ftp_proxy='http://127.0.0.1:${toString config.proxyPort}'" + "--env" "HTTPS_PROXY='http://127.0.0.1:${toString opt.proxyPort}'" + "--env" "HTTP_PROXY='http://127.0.0.1:${toString opt.proxyPort}'" + "--env" "FTP_PROXY='http://127.0.0.1:${toString opt.proxyPort}'" + "--env" "https_proxy='http://127.0.0.1:${toString opt.proxyPort}'" + "--env" "http_proxy='http://127.0.0.1:${toString opt.proxyPort}'" + "--env" "ftp_proxy='http://127.0.0.1:${toString opt.proxyPort}'" "$@" ) diff --git a/usr/cli.nix b/usr/cli.nix index 2e6bf1f5..3cba2c8b 100644 --- a/usr/cli.nix +++ b/usr/cli.nix @@ -1,6 +1,6 @@ { config, pkgs, stdenv, lib, ... }: let - opt4imports = import ../opt4imports.nix; + opt = import ../opt.nix; git-wip = builtins.derivation { name = "git-wip"; system = builtins.currentSystem; @@ -75,12 +75,13 @@ let ).config; in { - imports = lib.optionals (!opt4imports.isMinimalConfig) [ + imports = lib.optionals (!opt.isMinimalConfig) [ ./cli-extra.nix ] ++ [ # files ./cli/vim ./cli/clash.nix ./cli/tailscale.nix + ./cli/zsh.nix # When init searxng, it throws `ERROR:searx.engines.wikidata: Fail to initialize` # I have no idea, so disable it. # ./cli/searxng.nix @@ -94,8 +95,8 @@ in export FZF_DEFAULT_OPTS="--reverse" ''; }{ - home.packages = lib.optional (!config.isNixOnDroid) pkgs.hstr; - programs.bash.bashrcExtra = lib.optionalString (!config.isNixOnDroid) '' + home.packages = lib.optional (!opt.isNixOnDroid) pkgs.hstr; + programs.bash.bashrcExtra = lib.optionalString (!opt.isNixOnDroid) '' # HSTR configuration - add this to ~/.bashrc alias hh=hstr # hh to be alias for hstr export HSTR_CONFIG=hicolor # get more colors @@ -111,7 +112,7 @@ in }{ programs.ssh.enable = true; programs.ssh.includes = lib.optional (builtins.pathExists ~/Gist/Config/ssh.conf) "~/Gist/Config/ssh.conf"; - programs.bash.bashrcExtra = lib.optionalString config.isNixOnDroid '' + programs.bash.bashrcExtra = lib.optionalString opt.isNixOnDroid '' # start sshd if [[ -z "$(pidof sshd-start)" ]]; then tmux new -d -s sshd-start sshd-start @@ -226,15 +227,15 @@ in services.syncthing = { enable = true; #MC 让syncthing的端口外部可访问。 - extraOptions = lib.optional config.isCli "--gui-address=0.0.0.0:8384"; + extraOptions = lib.optional opt.isCli "--gui-address=0.0.0.0:8384"; }; #MC 启用代理,因为有些syncthing的服务器似乎是被墙了的。 systemd.user.services.syncthing.Service.Environment = [ # https://docs.syncthing.net/users/proxying.html - "http_proxy=http://127.0.0.1:${toString config.proxyPort}" + "http_proxy=http://127.0.0.1:${toString opt.proxyPort}" ]; #MC 使用命令行浏览器browsh来实现syncthing-tui。 - home.packages = lib.optional (!opt4imports.isMinimalConfig) ( + home.packages = lib.optional (!opt.isMinimalConfig) ( pkgs.writeShellScriptBin "syncthing-tui" '' ${pkgs.browsh}/bin/browsh --firefox.path ${pkgs.firefox}/bin/firefox http://127.0.0.1:8384 '' @@ -353,7 +354,7 @@ in if [[ -n "$IN_NIX_SHELL" ]]; then PS1+="(''${name}.$IN_NIX_SHELL)" fi - PS1+="''${u_green}\u${lib.optionalString (!config.isNixOnDroid) "@\\h"}''${u_white}:" + PS1+="''${u_green}\u${lib.optionalString (!opt.isNixOnDroid) "@\\h"}''${u_white}:" PS1+="''${u_blue}\w''${u_white}" PS1+="\n''${u_green}\$''${u_white} " unset u_green u_blue u_white @@ -390,7 +391,7 @@ in if [[ -n $(command -v eza) ]]; then alias ls=eza fi - '' + lib.optionalString config.isWSL2 '' + '' + lib.optionalString opt.isWSL2 '' # use the working directory of the current tab as the starting directory for a new tab # https://learn.microsoft.com/en-us/windows/terminal/tutorials/new-tab-same-directory#using-actions-to-duplicate-the-path PROMPT_COMMAND=''${PROMPT_COMMAND:+"$PROMPT_COMMAND"}'printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"' diff --git a/usr/cli/clash.nix b/usr/cli/clash.nix index 9a5c0b73..396b12ef 100644 --- a/usr/cli/clash.nix +++ b/usr/cli/clash.nix @@ -1,12 +1,13 @@ { config, pkgs, stdenv, lib, ... }: let + opt = import ../../opt.nix; clashctl = pkgs.callPackage ./clashctl.nix {}; in { imports = [{ home.packages = [ pkgs.clash-meta - ] ++ lib.optional (!config.isNixOnDroid) clashctl; - cachix_packages = lib.optional (!config.isNixOnDroid) clashctl; + ] ++ lib.optional (!opt.isNixOnDroid) clashctl; + cachix_packages = lib.optional (!opt.isNixOnDroid) clashctl; systemd.user.services.clash = { Unit = { @@ -20,14 +21,14 @@ in { ExecStart = "${pkgs.clash-meta.outPath}/bin/clash-meta -d ${config.home.homeDirectory}/Gist/clash"; }; }; - programs.bash.bashrcExtra = lib.mkBefore (lib.optionalString (!config.isNixOnDroid) '' + programs.bash.bashrcExtra = lib.mkBefore (lib.optionalString (!opt.isNixOnDroid) '' # proxy ## default - HTTP_PROXY="http://127.0.0.1:${toString config.proxyPort}/" + HTTP_PROXY="http://127.0.0.1:${toString opt.proxyPort}/" ## microsoft wsl # if [[ $(uname -r) == *"microsoft"* ]]; then # hostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }') - # export HTTP_PROXY="http://$hostip:${toString config.proxyPort}" + # export HTTP_PROXY="http://$hostip:${toString opt.proxyPort}" # fi export HTTPS_PROXY="$HTTP_PROXY" export HTTP_PROXY="$HTTP_PROXY" diff --git a/usr/cli/searxng.nix b/usr/cli/searxng.nix index 71791541..3b25ed0b 100644 --- a/usr/cli/searxng.nix +++ b/usr/cli/searxng.nix @@ -1,5 +1,6 @@ { config, pkgs, stdenv, lib, ... }: let + opt = import ../../opt.nix; searxng_yml = builtins.toFile "searxng.yml" '' # https://docs.searxng.org/admin/settings/settings.html#settings-yml-location # The initial settings.yml we be load from these locations: @@ -22,7 +23,7 @@ let outgoing: proxies: all://: - - http://127.0.0.1:${toString config.proxyPort} + - http://127.0.0.1:${toString opt.proxyPort} engines: - name: bilibili diff --git a/usr/cli/tailscale.nix b/usr/cli/tailscale.nix index c6dd4c0c..cce87f13 100644 --- a/usr/cli/tailscale.nix +++ b/usr/cli/tailscale.nix @@ -1,5 +1,6 @@ { config, pkgs, stdenv, lib, ... }: let + opt = import ../../opt.nix; tailscale-bash-completion = builtins.derivation { name = "tailscale-bash-completion"; system = builtins.currentSystem; @@ -58,15 +59,15 @@ let }; Service = { Environment = [ - "HTTPS_PROXY=http://127.0.0.1:${toString config.proxyPort}" - "HTTP_PROXY=http://127.0.0.1:${toString config.proxyPort}" - "https_proxy=http://127.0.0.1:${toString config.proxyPort}" - "http_proxy=http://127.0.0.1:${toString config.proxyPort}" + "HTTPS_PROXY=http://127.0.0.1:${toString opt.proxyPort}" + "HTTP_PROXY=http://127.0.0.1:${toString opt.proxyPort}" + "https_proxy=http://127.0.0.1:${toString opt.proxyPort}" + "http_proxy=http://127.0.0.1:${toString opt.proxyPort}" ]; ExecStart = "${tailscaled-wrapped}/bin/tailscaled-${suffix}"; }; }; - programs.bash.bashrcExtra = lib.optionalString config.isNixOnDroid '' + programs.bash.bashrcExtra = lib.optionalString opt.isNixOnDroid '' # start tailscale-${suffix} if [[ -z "$(pidof tailscaled-${suffix})" ]]; then tmux new -d -s tailscaled-${suffix} tailscaled-${suffix} diff --git a/usr/cli/vim/default.nix b/usr/cli/vim/default.nix index bb910d8e..deda9986 100644 --- a/usr/cli/vim/default.nix +++ b/usr/cli/vim/default.nix @@ -1,5 +1,7 @@ { config, pkgs, stdenv, lib, ... }: -{ +let + opt = import ../../../opt.nix; +in { #MC Plugins with customizations: imports = [ ./nvim-metals @@ -46,7 +48,7 @@ vim-commentary tabular vim-plugin-AnsiEsc - ] ++ (lib.optional config.isGui markdown-preview-nvim); + ] ++ (lib.optional opt.isGui markdown-preview-nvim); #MC Vim config extraConfig = '' diff --git a/usr/cli/vim/nvim-metals/default.nix b/usr/cli/vim/nvim-metals/default.nix index acb37c34..0af8cfe0 100644 --- a/usr/cli/vim/nvim-metals/default.nix +++ b/usr/cli/vim/nvim-metals/default.nix @@ -3,10 +3,11 @@ #MC The JRE proxy need subtle configuration. { config, pkgs, ... }: let + opt = import ../../../../opt.nix; jre_with_proxy = pkgs.callPackage ./jre_with_proxy.nix { jre = pkgs.openjdk_headless; proxyHost = "127.0.0.1"; - proxyPort = "${toString config.proxyPort}"; + proxyPort = toString opt.proxyPort; }; my-nvim-metals = { plugin = pkgs.vimPlugins.nvim-metals; @@ -23,9 +24,9 @@ let excludedPackages = { "akka.actor.typed.javadsl", "com.github.swagger.akka.javadsl" }, serverProperties = { "-Dhttps.proxyHost=127.0.0.1", - "-Dhttps.proxyPort=${toString config.proxyPort}", + "-Dhttps.proxyPort=${toString opt.proxyPort}", "-Dhttp.proxyHost=127.0.0.1", - "-Dhttp.proxyPort=${toString config.proxyPort}", + "-Dhttp.proxyPort=${toString opt.proxyPort}", }, -- see `:h metalsBinaryPath`, "Another setting for you crazy Nix kids." Hahaha! metalsBinaryPath = "${pkgs.metals.override {jre = jre_with_proxy;}}/bin/metals", @@ -59,9 +60,9 @@ in { home.file.jvmopts = { text = '' -Dhttps.proxyHost=127.0.0.1 - -Dhttps.proxyPort=${toString config.proxyPort} + -Dhttps.proxyPort=${toString opt.proxyPort} -Dhttp.proxyHost=127.0.0.1 - -Dhttp.proxyPort=${toString config.proxyPort} + -Dhttp.proxyPort=${toString opt.proxyPort} ''; target = ".bloop/.jvmopts"; }; diff --git a/usr/gui/gnome.nix b/usr/gui/gnome.nix index 07718ad9..d2355c56 100644 --- a/usr/gui/gnome.nix +++ b/usr/gui/gnome.nix @@ -1,7 +1,9 @@ { config, pkgs, stdenv, lib, ... }: # gnome extensions and settings # no need log out to reload extension: +F2 r -{ +let + opt = import ../../opt.nix; +in{ home.packages = (with pkgs; [ gnome.gnome-sound-recorder gnome.dconf-editor @@ -187,9 +189,9 @@ # proxy "system/proxy" = {mode = "manual";}; - "system/proxy/ftp" = {host="127.0.0.1"; port=config.proxyPort;}; - "system/proxy/http" = {host="127.0.0.1"; port=config.proxyPort;}; - "system/proxy/https" = {host="127.0.0.1"; port=config.proxyPort;}; + "system/proxy/ftp" = {host="127.0.0.1"; port=opt.proxyPort;}; + "system/proxy/http" = {host="127.0.0.1"; port=opt.proxyPort;}; + "system/proxy/https" = {host="127.0.0.1"; port=opt.proxyPort;}; # input method "org/gnome/desktop/input-sources" = {