mirror of
https://github.com/Misterio77/Foundry.git
synced 2026-08-24 02:14:13 -05:00
few refactors here and there
This commit is contained in:
Generated
+13
-24
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1629975021,
|
||||
"narHash": "sha256-+z4pK5yvoIKAIPGnyxt7I7Y9yX72HFP2krppGENpn6I=",
|
||||
"lastModified": 1631875434,
|
||||
"narHash": "sha256-qmaLTz4ituJJ8DNoHwmrrCRmABMoNqNLJewxWpuZals=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "342048461da7fc743e588ee744080c045613a226",
|
||||
"rev": "16fca9df230408608846940981b4037762420b1b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -17,7 +17,9 @@
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1630862599,
|
||||
@@ -51,24 +53,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1630761588,
|
||||
"narHash": "sha256-7GXckvZy7DGh2KIyfdArqwnyeSc5Owy1fumEDQyd8eY=",
|
||||
"path": "/nix/store/8i2kd1ndvx8adgid7vf4szhxsh1f9pkm-source",
|
||||
"rev": "a51aa6523bd8ee985bc70987909eff235900197a",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1631118067,
|
||||
"narHash": "sha256-tEcFvm3a6ToeBGwHdjfB2mVQwa4LZCZTQYE2LnY3ycA=",
|
||||
"lastModified": 1631962327,
|
||||
"narHash": "sha256-h2fgtNHozEcB42BQ1QVWAJUpQ1FA3gpgq/RrOKAxbfE=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "09cd65b33c5653d7d2954fef4b9f0e718c899743",
|
||||
"rev": "bc9b956714ed6eac5f8888322aac5bc41389defa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -80,11 +69,11 @@
|
||||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1631135611,
|
||||
"narHash": "sha256-CMetFtVGXtdRbP7lzunQwluhbnUV3AhRTanVKqnSW/k=",
|
||||
"lastModified": 1632257874,
|
||||
"narHash": "sha256-WGFotQ/wBqCzFwkFxiIePLaPAoHrfbbH3c9xZ+wUu1A=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "ddbecd29bb10308acd48ca3d41d73ae9e0dc80fd",
|
||||
"rev": "ed223afb5466e84e0a04a70c1a9fb87577011852",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -98,7 +87,7 @@
|
||||
"hardware": "hardware",
|
||||
"home-manager": "home-manager",
|
||||
"impermanence": "impermanence",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nur": "nur"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
description = "My NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
hardware.url = "github:nixos/nixos-hardware";
|
||||
home-manager.url = "github:misterio77/home-manager/personal";
|
||||
impermanence.url = "github:RiscadoA/impermanence";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nur.url = "github:nix-community/NUR";
|
||||
impermanence.url = "github:RiscadoA/impermanence";
|
||||
home-manager = {
|
||||
url = "github:misterio77/home-manager/personal";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, home-manager, nixpkgs, hardware, impermanence, nur }: {
|
||||
@@ -21,7 +24,8 @@
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
sharedModules = [ impermanence.nixosModules.home-manager.impermanence ];
|
||||
sharedModules =
|
||||
[ impermanence.nixosModules.home-manager.impermanence ];
|
||||
users = builtins.listToAttrs (nixpkgs.lib.forEach users (user: {
|
||||
name = "${user}";
|
||||
value = (./users + "/${user}" + /home);
|
||||
|
||||
+16
-11
@@ -15,14 +15,13 @@
|
||||
fileSystems."/data/var".neededForBoot = true;
|
||||
|
||||
environment.persistence."/data" = {
|
||||
directories =
|
||||
[
|
||||
"/var/log"
|
||||
"/var/lib/docker"
|
||||
"/var/lib/systemd"
|
||||
"/var/lib/postgresql"
|
||||
"/srv"
|
||||
];
|
||||
directories = [
|
||||
"/var/log"
|
||||
"/var/lib/docker"
|
||||
"/var/lib/systemd"
|
||||
"/var/lib/postgresql"
|
||||
"/srv"
|
||||
];
|
||||
};
|
||||
system.stateVersion = "21.11";
|
||||
|
||||
@@ -83,6 +82,14 @@
|
||||
};
|
||||
|
||||
services = {
|
||||
/* pipewire = {
|
||||
enable = true;
|
||||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
};
|
||||
*/
|
||||
dbus.packages = [ pkgs.gcr ];
|
||||
postgresql = {
|
||||
enable = true;
|
||||
@@ -94,9 +101,7 @@
|
||||
};
|
||||
|
||||
programs = {
|
||||
fuse = {
|
||||
userAllowOther = true;
|
||||
};
|
||||
fuse = { userAllowOther = true; };
|
||||
fish = {
|
||||
enable = true;
|
||||
vendor = {
|
||||
|
||||
+2
-3
@@ -2,8 +2,7 @@
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.hardware.openrgb;
|
||||
let cfg = config.hardware.openrgb;
|
||||
|
||||
in {
|
||||
options.hardware.openrgb = {
|
||||
@@ -23,7 +22,7 @@ in {
|
||||
|
||||
systemd.services.openrgb = {
|
||||
description = "OpenRGB Daemon";
|
||||
wantedBy = ["multi-user.target"];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/openrgb --server";
|
||||
Restart = "on-failure";
|
||||
|
||||
+39
-34
@@ -115,40 +115,39 @@
|
||||
# Script for changing color scheme
|
||||
# TODO: move to a nixpkg-like file
|
||||
(final: prev: {
|
||||
setscheme =
|
||||
prev.stdenv.mkDerivation {
|
||||
name = "setscheme";
|
||||
version = "1.0";
|
||||
src = prev.writeShellScriptBin "setscheme" ''
|
||||
if [ "$1" == "-A" ]; then
|
||||
sudo="sudo -A"
|
||||
shift
|
||||
else
|
||||
sudo="sudo"
|
||||
fi
|
||||
setscheme = prev.stdenv.mkDerivation {
|
||||
name = "setscheme";
|
||||
version = "1.0";
|
||||
src = prev.writeShellScriptBin "setscheme" ''
|
||||
if [ "$1" == "-A" ]; then
|
||||
sudo="sudo -A"
|
||||
shift
|
||||
else
|
||||
sudo="sudo"
|
||||
fi
|
||||
|
||||
if [ "$1" == "-L" ]; then
|
||||
nix eval --raw --impure --expr 'builtins.concatStringsSep "\n" (builtins.attrNames (import /dotfiles/colors.nix))' 2> /dev/null
|
||||
exit 0
|
||||
elif [ "$1" == "-R" ]; then
|
||||
scheme=$(setscheme -L | ${prev.coreutils}/bin/shuf -n 1)
|
||||
echo $scheme
|
||||
else
|
||||
scheme=$1
|
||||
fi
|
||||
if [ "$1" == "-L" ]; then
|
||||
nix eval --raw --impure --expr 'builtins.concatStringsSep "\n" (builtins.attrNames (import /dotfiles/colors.nix))' 2> /dev/null
|
||||
exit 0
|
||||
elif [ "$1" == "-R" ]; then
|
||||
scheme=$(setscheme -L | ${prev.coreutils}/bin/shuf -n 1)
|
||||
echo $scheme
|
||||
else
|
||||
scheme=$1
|
||||
fi
|
||||
|
||||
echo "\"$scheme\"" > /dotfiles/users/$USER/home/current-scheme.nix && \
|
||||
$sudo nixos-rebuild switch --flake /dotfiles ''${@:2}
|
||||
'';
|
||||
dontBuild = true;
|
||||
dontConfigure = true;
|
||||
nativeBuildInputs = [ prev.installShellFiles ];
|
||||
installPhase = ''
|
||||
install -Dm 0755 $src/bin/setscheme $out/bin/setscheme
|
||||
installShellCompletion --cmd setscheme \
|
||||
--fish <(echo 'complete -c setscheme -d "Which scheme to set" -r -f -a "(setscheme -L)"')
|
||||
'';
|
||||
};
|
||||
echo "\"$scheme\"" > /dotfiles/users/$USER/home/current-scheme.nix && \
|
||||
$sudo nixos-rebuild switch --flake /dotfiles ''${@:2}
|
||||
'';
|
||||
dontBuild = true;
|
||||
dontConfigure = true;
|
||||
nativeBuildInputs = [ prev.installShellFiles ];
|
||||
installPhase = ''
|
||||
install -Dm 0755 $src/bin/setscheme $out/bin/setscheme
|
||||
installShellCompletion --cmd setscheme \
|
||||
--fish <(echo 'complete -c setscheme -d "Which scheme to set" -r -f -a "(setscheme -L)"')
|
||||
'';
|
||||
};
|
||||
})
|
||||
# Swayfader
|
||||
# TODO: move to a nixpkg-like file
|
||||
@@ -169,7 +168,13 @@
|
||||
wshowkeys = prev.stdenv.mkDerivation {
|
||||
name = "wshowkeys";
|
||||
nativeBuildInputs = with prev; [ meson pkg-config wayland ninja ];
|
||||
buildInputs = with prev; [ cairo libinput pango wayland-protocols libxkbcommon ];
|
||||
buildInputs = with prev; [
|
||||
cairo
|
||||
libinput
|
||||
pango
|
||||
wayland-protocols
|
||||
libxkbcommon
|
||||
];
|
||||
src = prev.fetchFromGitHub {
|
||||
owner = "ammgws";
|
||||
repo = "wshowkeys";
|
||||
@@ -233,7 +238,7 @@
|
||||
})
|
||||
(final: prev: {
|
||||
openrgb = prev.openrgb.overrideAttrs (oldAttrs: rec {
|
||||
buildInputs = (oldAttrs.buildInputs or [ ]) ++ [ prev.mbedtls ];
|
||||
buildInputs = (oldAttrs.buildInputs or [ ]) ++ [ prev.mbedtls ];
|
||||
version = "master";
|
||||
src = prev.fetchFromGitLab {
|
||||
owner = "CalcProgrammer1";
|
||||
|
||||
@@ -1 +1 @@
|
||||
"phd"
|
||||
"dracula"
|
||||
|
||||
@@ -14,8 +14,8 @@ in {
|
||||
./ethminer.nix
|
||||
./element.nix
|
||||
./fira.nix
|
||||
./firefox.nix
|
||||
./fish.nix
|
||||
./himalaya.nix
|
||||
./git.nix
|
||||
./gpg.nix
|
||||
./gtk.nix
|
||||
@@ -34,10 +34,12 @@ in {
|
||||
./qutebrowser.nix
|
||||
./rgbdaemon.nix
|
||||
./runescape.nix
|
||||
./slack.nix
|
||||
./starship.nix
|
||||
./steam.nix
|
||||
./sway.nix
|
||||
./swaylock.nix
|
||||
./swayidle.nix
|
||||
./waybar.nix
|
||||
./zathura.nix
|
||||
];
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.firefox.enable = true;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
{ pkgs, ... }: {
|
||||
programs.git = {
|
||||
enable = true;
|
||||
package = pkgs.gitAndTools.gitFull;
|
||||
aliases = { graph = "log --decorate --oneline --graph"; };
|
||||
userName = "Gabriel Fontes";
|
||||
userEmail = "eu@misterio.me";
|
||||
@@ -8,6 +9,7 @@
|
||||
signByDefault = true;
|
||||
key = "CE707A2C17FAAC97907FF8EF2E54EA7BFE630916";
|
||||
};
|
||||
extraConfig = { init = { defaultBranch = "main"; }; };
|
||||
lfs = { enable = true; };
|
||||
ignores = [ ".direnv" "result" ];
|
||||
};
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{... }:
|
||||
|
||||
{
|
||||
programs.himalaya = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
||||
@@ -53,13 +53,18 @@
|
||||
map = [ "index" "pager" ];
|
||||
}
|
||||
{
|
||||
action =
|
||||
"<pipe-entry>${qutebrowserpipe}<enter><exit>";
|
||||
action = "<pipe-entry>${qutebrowserpipe}<enter><exit>";
|
||||
key = "V";
|
||||
map = [ "attach" ];
|
||||
}
|
||||
{
|
||||
action = "<view-attachments><search>html<enter><pipe-entry>${qutebrowserpipe}<enter><exit>";
|
||||
action = "<pipe-message>${pkgs.urlscan}/bin/urlscan<enter><exit>";
|
||||
key = "F";
|
||||
map = [ "pager" ];
|
||||
}
|
||||
{
|
||||
action =
|
||||
"<view-attachments><search>html<enter><pipe-entry>${qutebrowserpipe}<enter><exit>";
|
||||
key = "V";
|
||||
map = [ "index" "pager" ];
|
||||
}
|
||||
@@ -179,6 +184,24 @@
|
||||
|
||||
# Border lines.
|
||||
color body blue default "( *[-+=#*~_]){6,}"
|
||||
|
||||
# From https://github.com/jessfraz/dockerfiles/blob/master/mutt/.mutt/mutt-patch-highlighting.muttrc
|
||||
color body brightwhite default ^(\s).*
|
||||
color body cyan default ^(Signed-off-by).*
|
||||
color body cyan default ^(Docker-DCO-1.1-Signed-off-by).*
|
||||
color body brightwhite default ^(Cc)
|
||||
color body yellow default "^diff \-.*"
|
||||
color body brightwhite default "^index [a-f0-9].*"
|
||||
color body brightblue default "^---$"
|
||||
color body white default "^\-\-\- .*"
|
||||
color body white default "^[\+]{3} .*"
|
||||
color body green default "^[\+][^\+]+.*"
|
||||
color body red default "^\-[^\-]+.*"
|
||||
color body brightblue default "^@@ .*"
|
||||
color body green default "LGTM"
|
||||
color body brightmagenta default "-- Commit Summary --"
|
||||
color body brightmagenta default "-- File Changes --"
|
||||
color body brightmagenta default "-- Patch Links --"
|
||||
'';
|
||||
};
|
||||
programs.mbsync.enable = true;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
let
|
||||
vim-noctu = pkgs.vimUtils.buildVimPlugin {
|
||||
name = "vim-noctu";
|
||||
pname = "vim-noctu";
|
||||
version = "1.8.0";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "noahfrederick";
|
||||
repo = "vim-noctu";
|
||||
@@ -11,7 +12,8 @@ let
|
||||
};
|
||||
};
|
||||
mermaid = pkgs.vimUtils.buildVimPlugin {
|
||||
name = "mermaid.vim";
|
||||
pname = "mermaid.vim";
|
||||
version = "0.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "mracos";
|
||||
repo = "mermaid.vim";
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
RuneLite = {
|
||||
categories = [ "Game" ];
|
||||
comment = "Open source Old School RuneScape client";
|
||||
exec = "env _JAVA_OPTIONS=-Duser.home=/home/misterio/Jagex/ gamemoderun runelite";
|
||||
exec =
|
||||
"env _JAVA_OPTIONS=-Duser.home=/home/misterio/Jagex/ gamemoderun runelite";
|
||||
genericName = "Oldschool RuneScape";
|
||||
icon = "runescape";
|
||||
name = "RuneLite";
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [ slack ];
|
||||
home.persistence."/data/home/misterio".directories = [ ".config/Slack" ];
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
directories = [
|
||||
"Games/Steam"
|
||||
".config/Hero_Siege"
|
||||
".config/unity3d/Berserk Games/Tabletop Simulator"
|
||||
".local/share/Tabletop Simulator"
|
||||
".local/share/Steam"
|
||||
];
|
||||
|
||||
@@ -24,11 +24,12 @@ let
|
||||
swayfader = "${pkgs.swayfader}/bin/swayfader";
|
||||
swayidle = "${pkgs.swayidle}/bin/swayidle";
|
||||
swaylock = "${pkgs.swaylock-effects}/bin/swaylock";
|
||||
waybar = "${pkgs.waybar}/bin/waybar";
|
||||
wofi = "${pkgs.wofi}/bin/wofi";
|
||||
xrandr = "${pkgs.xorg.xrandr}/bin/xrandr";
|
||||
zathura = "${pkgs.zathura}/bin/zathura";
|
||||
in rec {
|
||||
home.packages = with pkgs; [ wl-clipboard wf-recorder ];
|
||||
home.packages = with pkgs; [ wl-clipboard wf-recorder slurp ];
|
||||
home.sessionVariables = {
|
||||
MOZ_ENABLE_WAYLAND = true;
|
||||
QT_QPA_PLATFORM = "wayland";
|
||||
@@ -71,8 +72,11 @@ in rec {
|
||||
workspace = "2";
|
||||
}
|
||||
];
|
||||
floating.criteria =
|
||||
[ { app_id = "zenity"; } { app_id = "AlacrittyFloating*"; } { class = "net-runelite-launcher-Launcher"; } ];
|
||||
floating.criteria = [
|
||||
{ app_id = "zenity"; }
|
||||
{ app_id = "AlacrittyFloating*"; }
|
||||
{ class = "net-runelite-launcher-Launcher"; }
|
||||
];
|
||||
colors = {
|
||||
focused = {
|
||||
border = "${colorscheme.base0C}";
|
||||
@@ -106,7 +110,11 @@ in rec {
|
||||
startup = [
|
||||
# Initial lock
|
||||
{
|
||||
command = "'${swaylock} -i ${wallpaper}'";
|
||||
command = "${swaylock} -i ${wallpaper}";
|
||||
}
|
||||
# Start idle daemon
|
||||
{
|
||||
command = "${swayidle} -w";
|
||||
}
|
||||
# Focus main output
|
||||
{
|
||||
@@ -120,34 +128,9 @@ in rec {
|
||||
{
|
||||
command = "${discocss}";
|
||||
}
|
||||
# Swayidle
|
||||
# Lock after 10 minutes
|
||||
# After 10 seconds of locked, mute mic
|
||||
# After 20 seconds of locked, disable rgb lights and turn monitors off
|
||||
{
|
||||
command = ''
|
||||
${pkill} swayidle; \
|
||||
${swayidle} -w \
|
||||
timeout 600 '${swaylock} --screenshots --daemonize' \
|
||||
timeout 240 '${gpg-connect-agent} reloadagent /bye' \
|
||||
timeout 10 'pgrep -x swaylock && ${pactl} set-source-mute @DEFAULT_SOURCE@ yes' \
|
||||
resume 'pgrep -x swaylock && ${pactl} set-source-mute @DEFAULT_SOURCE@ no' \
|
||||
timeout 610 '${pactl} set-source-mute @DEFAULT_SOURCE@ yes' \
|
||||
resume '${pactl} set-source-mute @DEFAULT_SOURCE@ no' \
|
||||
timeout 20 'pgrep -x swaylock && systemctl --user stop rgbdaemon' \
|
||||
resume 'pgrep -x swaylock && systemctl --user start rgbdaemon' \
|
||||
timeout 620 'systemctl --user stop rgbdaemon' \
|
||||
resume 'systemctl --user start rgbdaemon' \
|
||||
timeout 20 'pgrep -x swaylock && swaymsg "output * dpms off"' \
|
||||
resume 'pgrep -x swaylock && swaymsg "output * dpms on"' \
|
||||
timeout 620 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"'
|
||||
'';
|
||||
always = true;
|
||||
}
|
||||
# Start waybar
|
||||
{
|
||||
command = "${pkgs.waybar}/bin/waybar";
|
||||
command = "${waybar}";
|
||||
}
|
||||
# Set xwayland main monitor
|
||||
{
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
swaylock = "${pkgs.swaylock-effects}/bin/swaylock";
|
||||
gpg-connect-agent = "${pkgs.gnupg}/bin/gpg-connect-agent";
|
||||
pactl = "${pkgs.pulseaudio}/bin/pactl";
|
||||
pgrep = "${pkgs.procps}/bin/pgrep";
|
||||
in {
|
||||
# Remove pgp passphrase cache after 4 minutes
|
||||
# Lock after 10 minutes
|
||||
# After 10 seconds of locked, mute mic
|
||||
# After 20 seconds of locked, disable rgb lights and turn monitors off
|
||||
xdg.configFile."swayidle/config".text = ''
|
||||
timeout 240 '${gpg-connect-agent} reloadagent /bye'
|
||||
|
||||
timeout 600 '${swaylock} --screenshots --daemonize'
|
||||
|
||||
timeout 10 '${pgrep} -x swaylock && ${pactl} set-source-mute @DEFAULT_SOURCE@ yes' resume '${pgrep} -x swaylock && ${pactl} set-source-mute @DEFAULT_SOURCE@ no'
|
||||
timeout 610 '${pactl} set-source-mute @DEFAULT_SOURCE@ yes' resume '${pactl} set-source-mute @DEFAULT_SOURCE@ no'
|
||||
|
||||
timeout 20 '${pgrep} -x swaylock && systemctl --user stop rgbdaemon' resume '${pgrep} -x swaylock && systemctl --user start rgbdaemon'
|
||||
timeout 620 'systemctl --user stop rgbdaemon' resume 'systemctl --user start rgbdaemon'
|
||||
|
||||
timeout 20 '${pgrep} -x swaylock && swaymsg "output * dpms off"' resume '${pgrep} -x swaylock && swaymsg "output * dpms on"'
|
||||
timeout 620 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"'
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user