{ config, pkgs, stdenv, lib, ... }:
let
opt = import ../opt.nix;
git-wip = builtins.derivation {
name = "git-wip";
system = builtins.currentSystem;
src = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/bartman/git-wip/1c095e93539261370ae811ebf47b8d3fe9166869/git-wip";
sha256 = "00gq5bwwhjy68ig26a62307pww2i81y3zcx9yqr8fa36fsqaw37h";
};
builder = pkgs.writeShellScript "git-wip-builder" ''
source ${pkgs.stdenv}/setup
mkdir -p $out/bin
dst=$out/bin/git-wip
cp $src $dst
chmod +w $dst
sed -i 's/#!\/bin\/bash/#!\/usr\/bin\/env bash/g' $dst
chmod -w $dst
chmod a+x $dst
'';
};
fzf-doc = pkgs.writeScriptBin "fzf-doc" ''
allCmds() {
# bash alias
compgen -A alias
# external commands
# https://unix.stackexchange.com/questions/94775/list-all-commands-that-a-shell-knows
case "$PATH" in
(*[!:]:) PATH="$PATH:" ;;
esac
set -f
IFS_OLD="$IFS"
IFS=:
for dir in $PATH; do
set +f
[ -z "$dir" ] && dir="."
for file in "$dir"/*; do
if [ -x "$file" ] && ! [ -d "$file" ]; then
echo "''${file##*/}"
fi
done
done
IFS="$IFS_OLD"
}
cd ~/Documents
FILE=$(fzf)
[ -z "$FILE" ] && exit
CMD=$(allCmds | fzf)
[ -z "$CMD" ] && exit
case "$CMD" in
# run gui cmd background
o)
# use nohup to run bash command in background and exit
## https://superuser.com/questions/448445/run-bash-script-in-background-and-exit-terminal
# nohup not recognize bash alias like `o`, it's necessary to call bash
eval nohup bash -ic '"$CMD \"$FILE\" &"'
;;
# run cli cmd foreground
*)
# FILE name may contain space, quote FILE name
eval "$CMD" \"$FILE\"
;;
esac
'';
sysconfig = (
# <...> are expression search in NIX_PATH
if (builtins.tryEval <nixos-config>).success
then import <nixpkgs/nixos> {}
else import <nixpkgs/nixos> {configuration={};}
).config;
in
{
imports = lib.optionals (!opt.isMinimalConfig) [
./cli-extra.nix
] ++ [ # files
./cli/vim
./cli/tmux.nix
./cli/clash.nix
./cli/tailscale.nix
# When init searxng, it throws `ERROR:searx.engines.wikidata: Fail to initialize`
# I have no idea, so disable it.
# ./cli/searxng.nix
] ++ [{ # functions & attrs
home.packages = [
pkgs.fzf
fzf-doc
];
programs.bash.bashrcExtra = ''
# FZF top-down display
export FZF_DEFAULT_OPTS="--reverse"
'';
}{
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
shopt -s histappend # append new history items to .bash_history
export HISTCONTROL=ignorespace # leading space hides commands from history
# ensure synchronization between bash memory and history file
export PROMPT_COMMAND="history -a;"
# if this is interactive shell, then bind hstr to Ctrl-r (for Vi mode check doc)
if [[ $- =~ .*i.* ]]; then bind '"\C-r": "\C-a hstr -- \C-j"'; fi
# if this is interactive shell, then bind 'kill last command' to Ctrl-x k
if [[ $- =~ .*i.* ]]; then bind '"\C-xk": "\C-a hstr -k \C-j"'; fi
'';
}{
programs.ssh.enable = true;
programs.ssh.includes = lib.optional (builtins.pathExists ~/Gist/Config/ssh.conf) "~/Gist/Config/ssh.conf";
programs.bash.bashrcExtra = lib.optionalString opt.isNixOnDroid ''
# start sshd
if [[ -z "$(pidof sshd-start)" ]]; then
tmux new -d -s sshd-start sshd-start
fi
'';
}{
home.packages = with pkgs; [
gitui
mr
git-wip
git-quick-stats
];
programs.git = {
enable = true;
package = pkgs.gitFull;
userEmail = "xieby1@outlook.com";
userName = "xieby1";
extraConfig = {
core = {
editor = "vim";
};
credential.helper = "store";
};
aliases = {
viz = "log --all --decorate --oneline --graph";
};
lfs.enable = true;
};
home.file.mr = {
text = if builtins.pathExists ~/Gist/Config/mrconfig
then builtins.readFile ~/Gist/Config/mrconfig
else "";
target = ".mrconfig";
};
# mr status not work in non-home dir
programs.bash.shellAliases.mr = "mr -d ~";
}{
home.packages = [pkgs.nix-index];
home.file.nix_index_database = {
source = builtins.fetchurl "https://github.com/Mic92/nix-index-database/releases/latest/download/index-${builtins.currentSystem}";
target = ".cache/nix-index/files";
};
}{
Syncthing
services.syncthing = {
enable = true;
让syncthing的端口外部可访问。
extraOptions = lib.optional opt.isCli "--gui-address=0.0.0.0:8384";
};
启用代理,因为有些syncthing的服务器似乎是被墙了的。
systemd.user.services.syncthing.Service.Environment = [
# https://docs.syncthing.net/users/proxying.html
"http_proxy=http://127.0.0.1:${toString opt.proxyPort}"
];
使用命令行浏览器browsh来实现syncthing-tui。
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
''
);
}{
home.packages = with pkgs; [
cachix
];
home.file.cachix_dhall = {
source = if (builtins.pathExists ~/Gist/Config/cachix.dhall)
then ~/Gist/Config/cachix.dhall
else builtins.toFile "empty-cachix.dhall" "";
target = ".config/cachix/cachix.dhall";
};
}{
home.packages = with pkgs; [
universal-ctags
];
home.file.exclude_ctags = {
text = ''
# exclude ccls generated directories
--exclude=.ccls*
'';
target = ".config/ctags/exclude.ctags";
};
}];
home.packages = with pkgs; [
# tools
parallel
comma
xclip
python3Packages.qrcode
ripgrep
## archive
unar
## manage
htop
nix-tree
## text
pandoc
## compile
gnumake
makefile2graph
remake
## draw
graphviz
figlet
nyancat
## manual
tldr
## file system
file
# magika # detect file content types with deep learning
tree
## network
wget
bind.dnsutils # nslookup
netcat
nload
nmap
nethogs
## x11
xdotool
# programming
clang-tools
cmake
capstone
scc
## https://stackoverflow.com/questions/40165650/how-to-list-all-files-tracked-by-git-excluding-submodules
(writeShellScriptBin "scc-git" "${scc}/bin/scc $(git grep --cached -l '')")
sloccount
flamegraph
## python
( python3.withPackages ( p: with p; [
ipython
]))
## c
(lib.setPrio # make bintools less prior
(bintools-unwrapped.meta.priority + 1)
bintools-unwrapped
)
(if builtins.currentSystem == "x86_64-linux"
then gcc_multi
else gcc
)
gdb
### docs
stdmanpages
man-pages
#gccStdenv
bear
## xml
libxml2
## bash
bc
## nix
nixos-option
nix-output-monitor
### allow non-nixos access `man configuration.nix`
# see: nixos/modules/misc/documentation.nix
# nixos/doc/manual/default.nix
sysconfig.system.build.manual.nixos-configuration-reference-manpage
nurl
];
programs.eza.enable = true;
# bash
programs.bash.enable = true;
programs.bash.shellAliases.o = "xdg-open";
programs.bash.bashrcExtra = ''
# rewrite prompt format
u_green="\[\033[01;32m\]"
u_blue="\[\033[01;34m\]"
u_white="\[\033[00m\]"
PS1="''${debian_chroot:+($debian_chroot)}"
if [[ $HOSTNAME =~ qemu.* ]]; then
PS1+="(qemu)"
fi
if [[ -n "$IN_NIX_SHELL" ]]; then
PS1+="(''${name}.$IN_NIX_SHELL)"
fi
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
## change title
### https://unix.stackexchange.com/questions/177572/
PS1+="\[\e]2;\w\a\]"
# nixos obsidian
export NIXPKGS_ALLOW_INSECURE=1
# source my bashrc
if [[ -f ~/Gist/Config/bashrc ]]; then
source ~/Gist/Config/bashrc
fi
# user nix config setting
export NIX_USER_CONF_FILES=~/.config/nixpkgs/nix/nix.conf
if [[ -e ~/.nix-profile/etc/profile.d/nix.sh ]]; then
source ~/.nix-profile/etc/profile.d/nix.sh
fi
# bash-completion, inspired by
## https://discourse.nixos.org/t/whats-the-nix-way-of-bash-completion-for-packages/20209/16
# system tools completion, e.g. nix
XDG_DATA_DIRS+=":${sysconfig.system.path}/share"
# home tools completion
XDG_DATA_DIRS+=":${config.home.path}/share"
export XDG_DATA_DIRS
. ${pkgs.bash-completion}/etc/profile.d/bash_completion.sh
# 解决tmux在nix-on-droid上不显示emoji和中文的问题
export LANG=C.UTF-8
if [[ -n $(command -v eza) ]]; then
alias ls=eza
fi
'' + 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")"'
'';
## after direnv's bash.initExtra
programs.bash.initExtra = lib.mkOrder 2000 ''
# https://stackoverflow.com/questions/1862510/how-can-the-last-commands-wall-time-be-put-in-the-bash-prompt
function timer_start {
_timer=''${_timer:-$SECONDS}
}
function timer_stop {
last_timer=$(($SECONDS - $_timer))
_notification_threthold=10
if [[ $last_timer -ge $_notification_threthold ]]; then
_notification="[''${last_timer}s⏰] Job finished!"
if [[ "$TERM" =~ tmux ]]; then
# https://github.com/tmux/tmux/issues/846
printf '\033Ptmux;\033\x1b]99;;%s\033\x1b\\\033\\' "$_notification"
else
printf '\x1b]99;;%s\x1b\\' "$_notification"
fi
fi
}
function timer_unset {
unset _timer
}
trap timer_start DEBUG
PROMPT_COMMAND="timer_stop;$PROMPT_COMMAND"
if [[ -n "$(echo $PROMPT_COMMAND | grep -o -e ';$')" ]]; then
PROMPT_COMMAND+="timer_unset;"
else
PROMPT_COMMAND+=";timer_unset;"
fi
'';
home.file.gdbinit = {
source = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/cyrus-and/gdb-dashboard/2b107b27949d13f6ef041de6eec1ad2e5f7b4cbf/.gdbinit";
sha256 = "02rxyk8hmk7xk1pyhnc5z6a2kqyd63703rymy9rfmypn6057i4sr";
name = "gdbinit";
};
target = ".gdbinit";
};
home.file.gdb_dashboard_init = {
text = ''
# gdb-dashboard init file
# available layout modules
# stack registers history assembly
# breakpoints expressions memory
# source threads variables
dashboard -layout source
# https://en.wikipedia.org/wiki/ANSI_escape_code
#dashboard -style prompt
## fg bold blue
dashboard -style prompt_not_running "\\[\\e[1;34m\\]$\\[\\e[0m\\]"
## fg bold green
dashboard -style prompt_running "\\[\\e[1;32m\\]$\\[\\e[0m\\]"
'';
target = ".gdbinit.d/init";
};
programs.direnv.enable = true;
programs.direnv.nix-direnv.enable = true;
programs.man.generateCaches = true;
}