#compdef phint

local state line

function getcmd() {
    echo $@ | sed -e "s/\\\/\\\\\\\/g;s/\\\:/:/g"
}

function _binary() {
    _binarys=$(cat <<'EOF'
numfmt --to iec-i _unit_ --format '%.4f':[Conversion] - Convert bytes to bigger units automatically
sudo xxd -s _0xADDR_ -l _bytecount_ -c _colsize_ _dev/file_:[Binary] - Print _bytecount_ starting from _0xADDR_ with column size _colsize_
_dec_=$((16#_hex_)):[Binary] - Convert _hex_ to _dec_
_hex_=$(([##16]_dec_)):[Binary] - Convert _dec_ to _hex_
echo _hex_ | fold -b2 | tac | tr -d '\\n':[Binary] - Convert _hex_ to little endian
| xxd -r -p:[Binary - Pipe] - Convert string input to binary data
| xxd -r -p | xxd -e -groupsize _sz_:[Binary - Pipe] - Convert string to little endian sizes of _sz_
| gzip -1 -c | tail -c8 | od -t x4 -N 4 -A n:[CRC32 - Pipe] Calculate CRC32 hashsum of input
EOF
)

    local -a _binaryargs=("${(@f)$(getcmd $_binarys)}")
    _describe -t binary 'Binary - number - algorithm related' _binaryargs
    _evalarg=
    return 0
}

function _boot() {
    _boots=$(cat <<'EOF'
sudo mount -t efivarfs none /sys/firmware/efi/efivars:[Boot] - Mount efivars for UEFI
sudo efibootmgr -c -d _bootdev_ -p _bootpart_ -L _bootname_ -l _bootloader_:[Boot] - Create entry for _bootloader_ named _bootname_ in dev _bootdev_ partition _bootpart_
sudo efibootmgr -c -d _dev_ -p _bootpart_ -L _bootname_ -l _kernel_ -u '_cmdline_ initrd=\\_img_':[Boot] - Create entry for _kernel_ with _cmdline_ and image _img_ in _dev_ partition _bootpart_ with name _bootname_
sudo ls -lanR /boot:[Boot] - List files in boot
sudo gdisk -l _dev_:[Boot] - Get partition entries of _dev_ (GPT only)
sudo efibootmgr -v:[EFI] - Get efi boot entries
sudo efibootmgr -b _bootnum_ -B:[EFI] - Delete _bootnum_ entry
sudo efibootmgr -b _bootnum_ -a:[EFI] - Activate _bootnum_ entry
sudo efibootmgr -b _bootnum_ -A:[EFI] - Set _bootnum_ as inactive
sudo ls -lanR /sys/firmware:[EFI] - Get list of firmware related files
sudo lsblk | grep disk | awk '{print $1}' | sudo xargs -I % gdisk -l /dev/% | grep -E 'Disk|EF00':[EFI] - Get EFI (ESP) partitions of all block devices
sudo dd if=_dev_ count=16384 skip=1024 bs=1 | gzip -1 -c | tail -c8 | od -t x4 -N 4 -A n:[GPT] - Calculate gpt partition table array checksum of _dev_ in BE binary
sudo dd if=_dev_ count=16384 skip=1024 bs=1 | gzip -1 -c | tail -c8 | od -t x4 -N 4 -A n --endian=big | xxd -r -p -g4:[GPT] - Calculate gpt partition array checksum in LE binary
sudo dd if=_partCRC_ of=_dev_ count=4 bs=1 seek=600:[GPT] - Write _partCRC_ checksum to _dev_ gpt table
sudo dd if=/dev/zero of=_dev_ seek=528  count=4 bs=1:[GPT] - Clear GPT header checksum of _dev_
sudo dd if=_dev_ skip=512 count=92 bs=1 | gzip -1 -c | tail -c8 | od -t x4 -N 4 -A n:[GPT] - Calculate _dev_ GPT header checksum in BE binary
sudo dd if=_dev_ skip=512 count=92 bs=1 | gzip -1 -c | tail -c8 | od -t x1 -N 4 --endian=big -A n  | xxd -r -p -g4:[GPT] - Calculate _dev_ gpt header checksum in LE binary
sudo dd if=_headCRC_ of=_dev_ seek=528 count=4 bs=1:[GPT] - Write _headCRC_ header checksum to _dev_
EOF
)
    local -a _bootargs=("${(@f)$(getcmd $_boots)}")
    _describe -t boot 'Block - nvme - mapper related' _bootargs
    _evalarg=
}

function _block() {
    _blocks=$(cat <<'EOF'
uuid-gen:[Block] - Generate a random uuid
sudo blockdev --report:[Block] - Print report for block devices
sudo ls -lanR /sys/block:[Block] - Get virtual block paths
sudo udevmadm info _dev_:[Block] - Get udev information about _dev_ path
findmnt --noheadings / | awk '{print $2}':[Block] - Get path of root partition
sudo lsblk --tree:[Block] - Get tree view of block devices
 sed 's/#.*//' /etc/fstab | column --table --table-columns SOURCE,TARGET,TYPE --table-hide -:[Block] - Parse fstab beatifully!
sudo fuser -kc _mount_:[Block - Mount] - Force kill processes using _mount_
sudo blkid _dev_ -D  --match-tag UUID -o value:[Filesystem] - Get _dev_ UUID value
sudo debugfs -R "stat _dest_" _dev_ | grep -o "Flags\:.*":[Filesystem] - Get stats of _dest_ from _dev_ (Can get options even if it is mounted from any mount command)
sudo tune2fs -l _dev_ | grep -E 'Free blocks|Reserved block count|Block size' | awk '{print $NF}' | python -c 'import sys; rbc=int(sys.stdin.readline()); fb=int(sys.stdin.readline()); bs=int(sys.stdin.readline()); print(abs(fb-rbc) * bs / 1024**3)':[Filesystem] - Get free size in GB of ext* fs of an unmounted partition _dev_
sudo dumpe2fs _dev_:[Filesystem] - Get fs superblock and verbose information of _dev_
sudo tune2fs -L _label_ _dev_:[Filesystem] - Set fs label to _label_ for _dev_
sudo tune2fs -j _dev_:[Filesystem] - Convert ext2 fs of _dev_ to ext3
sudo tune2fs -U _uuid_ _dev_:[Filesystem] - Set _dev_ UUID to _uuid_
sudo mount -o offset=_offset_ _fs_ _dest_:[Filesystem] - Mount a file _fs_ containing partitions with _offset_ to _dest_
sudo resize2fs _dev_ _size_:[Filesystem] - Resize a filesystem to _size_ (useful with lvm)
sudo e2fsck -f _dev_:[Filesystem] - Check and fix superblocks of _dev_ which has ext? filesystem
sudo mkfs._fs_ _dev_:[Filesystem] - Create filesystem and format _dev_ with _fs_ filesystem
sudo mkfs.ext4 -U _uuid_ _dev_:[Filesystem] - Create ext4 filesystem on _dev_ and set uuid as _uuid_
sudo mkfs.fat -i _uuid_ _dev_:[Filesystem] - Create fat fs _dev_ and set uuid as _uuid_
sudo losetup -a:[Loop] - Print loop device status
sudo mount -o loop -t iso9660 _iso_ _dest_:[Loop] - Mount iso9660 (disk) _iso_ image to _dest_
sudo dmsetup ls --tree --table devname -o blkdevname,compact:[Mapper] - Print dm deps in each line
sudo dmsetup ls --tree --table devname -o blkdevname,compact | grep $(mount | awk '/on \/ / {n=split($1,a,"/"); print a[n]}') | awk '{print $(NF-1)}' | tr -d "<>":[Mapper] - Get devname of encrypted root partition
sudo lvcreate -L _size_ -n _name_ _vgname_:[Mapper] - Create a new logical volume with _size_ with _name_ in _vgname_
sudo lvextend -r  -L _size_ _lvpath_:[Mapper] - Extend a lv volume _lvpath_ with _size_ (add -r flag for resizing fs)
sudo vgcreate _vgname_ _pv**_:[Mapper] - Create vg _vgname_ in any number of _pv**_ physical volumes
sudo vgchange -a n _vg_:[Mapper] - Enable/disable _vg_ logical volumes
sudo vgextend _vg_ _pv_:[Mapper] - Extend _vg_ with a new _pv_ physical vol
sudo vgrename _old_ _new_:[Mapper] - Change vg name from _old_ to _new_ (All LV must be disabled)
sudo pvs -v --segments _dev_:[Mapper] - Print segments of a PV
sudo pvmove --alloc anywhere _dev_:_start_-_end_:[Mapper] - Move PV segments to other location
sudo pvmove -v _src_ _dest_:[Mapper] - Move physical volume _src_ to _dest_
sudo mount -t tmpfs -o size=_size_ tmpfs _dest_:[Ram] - Create a ram fs with _size_ to _dest_
EOF
)
    local -a _blockargs=("${(@f)$(getcmd $_blocks)}")
    _describe -t block 'Block - nvme - mapper related' _blockargs
    _evalarg=
    return 0
}

function _str.h() {
    _str_h=$(cat <<'EOF'
| sed 's/^[[\:blank\:]]*//;s/[[\:blank\:]]*$//':[Pipe] - Remove trailing spaces from string
| sed '/^_match_/s/^/_prefix_/':[Pipe] - Insert _prefix_ before _match_
| grep -Po '\\_delim_([_group_].*?)\\_delim_':[Pipe] - Get word surrounded by _delim_ with _group_ characters
| grep -Po '_delim_._word_*?_delim_\\b(?<=_endchar_)':[Pipe] - Split str by _delim_ with _word_ regex with look ahead _endchar_
_var_="(${$(echo -n _str_ | tr -t -C '!' '[\\0*]' | xxd -c 1 -d -a | awk -F\: '/21/ {print $1}')})":[Array] - Split _str_ to numerical array
_arr_="${(@f)$_str_}":[Array] - Split _str_ by newline to array _arr_ (IFS seperated)
_arr_="${(s._delim_.)_str_}":[Array] - Split _str_ by _delim_
EOF
)
    local -a _strargs=("${(@f)$(getcmd $_str_h)}")
    _describe -t strings 'String Manipulation' _strargs
    _evalarg=
    return 0
}

function _kernel() {
    _kern=$(cat <<'EOF'
find . -print0 | LC_ALL=C sort -z | cpio --null -R 0\:0 -H newc -o --quiet > _earlycpio_:[Init] - Make early microcode cpio from current directory to file _earlycpio_
find . | LC_ALL=C sort | cpio --quiet -R 0\:0 -o -H newc > _maincpio_:[Init] - Generate ramfs cpio in current directory to file _maincpio_
grep --text -m 1 "video mode" -A2 _kern_ | tail -1 | awk '{print $1}':[Kernel] - Get kernel version from kernel binary (Useful when file command is not available, like busybox)
sudo vmstat --slabs:[Kernel] - Show kernel slab information
sudo vmstat --forks:[Kernel] - Print total number of forks since boot
sudo vmstat --stats:[Kernel] - Show event counter statistics
mount -n --bind -o ro _cmdline_ /proc/cmdline:[Kernel] - Hijack cmdline on the run!!
uptime:[Kernel] - Get runtime of system in current boot
tty:[Kernel] - Get current tty of user
echo _args_ | sudo tee /dev/pts/_num_:[Kernel] - Send output to another pseudoterminal (works on chroot)
sudo ln -sf /bin/sh _shell_:[Kernel] - Change default shell softlink to _shell_
tail -f --pid=_pid_:[Kernel] - Watch process with _pid_
sudo sh -c "mount --bind /proc _dest_/proc; mount --bind /dev _dest_/dev; mount --bind /sys _dest_/sys":[Kernel] - Prepare _dest_ fs or partition for chrooting
ls -D /proc/[0-9]*/{status,oom_score_adj} | sort --field-separator=/ --numeric-sort -k3 | xargs sed -e '/^[0-9]/s/^/OomAdjScore\:/ ' 2>/dev/null | grep -E -w 'OomAdjScore|Name|Pid':[Memory] - Get OOM score from running processes to stdout (sorted)
sudo slabtop -o:[Memory] - Show slab table once and exit
swapon --bytes --show:[Memory] - Show swap usage in bytes
lsmem -a -o RANGE,SIZE,STATE,REMOVABLE,ZONES,NODE,BLOCK:[Memory] - Show detailed memory table
sudo grep -H '' /sys/module/_module_*/parameters/*:[Module] - Get module parameter information
EOF
)
    local -a _kernargs=("${(@f)$(getcmd $_kern)}")
    _describe -t kernel 'Kernel - debug' _kernargs
    _evalarg=
    return 0
}

function _pacman() {
    _pac=$(cat <<'EOF'
sudo pacman -R --nodeps _pkg_:[Pacman] - Remove _pkg_ and skip dependency checks
sudo pacman -Rnc _pkg_:[Pacman] - Remove _pkg_ with all dependencies
sudo pacman -Rnd _pkg_:[Pacman] - Force remove _pkg_ without removing dependencies
pacman -Qlq _pkg_ | while read f; do [[ -d $f ]] && mkdir -p "./$f" || cp $f "./$f"; done:[Pacman] - Extract pacman package (get all files, compatible with deb binaries) to current directory
sudo pacman -Qii _pkg_:[Pacman] - Get information about package
EOF
)
    local -a _pacargs=("${(@f)$(getcmd $_pac)}")
    _describe -t pacmanpac 'Pacman tricks' _pacargs
    _evalarg=
    return 0
}

function _sysd() {
    _sys_d=$(cat <<'EOF'
sudo journalctl -b -1  -p "emerg".."crit":[Boot] - Get emergency to critical logs from boot
sudo journalctl --since "_num_ days ago":[Log] - Get logs from _num_ days before till now
sudo journalctl _SYSTEMD_UNIT=_unit_.service:[Unit] - Get logs generated by _unit_
sudo journalctl -u _unit_:[Unit] - Get all logs related to _unit_
sudo systemctl list-units:[Unit] - List units
sudo systemctl list-units --all:[Unit] - List all units
sudo systemctl list-units --failed:[Unit] - List all failed units
sudo systemctl list-dependencies:[System] - Get all dependencies of systemd units (tree view)
sudo systemctl list-jobs:[System] - Get active jobs
sudo systemctl list-timers:[System] - Get all systemd unit timers
sudo systemctl list-unit-files:[System] - Get all unit files
sudo systemctl status --all:[System] - Tree view of all units
sudo systemd-analyze:[System] - Get startup time starting from boot
sudo systemd-analyze blame:[System] - Get startup time for each unit starting from boot
EOF
)
    local -a _sysdargs=("${(@f)$(getcmd $_sys_d)}")
    _describe -t sysd 'Systemd - journal commands' _sysdargs
    _evalarg=
    return 0
}

function _net() {
    _net_s=$(cat <<'EOF'
sudo iptables -L -n -v:[Firewall] - Check current status of firewall
sudo service iptables save:[Firewall] - Save all the ipv4 rules in /etc/sysconfig/iptables file
sudo iptables-save > _file-path_:[Firewall] - To save all the iptables rules in a file
sudo iptables-restore < _file_:[Firewall] - To restore the rules from _file_
sudo iptables -A OUTPUT -p _protocol_ -d _ip_ -j DROP:[Firewall] - To block _protocol_ traffic to _ip_ or _ip_ range.
sudo iptables -A OUTPUT -p _protocol_ -d _ipaddr/sm_ --dport _port_ -j ACCEPT:[Firewall] - To allow outbound traffic to _ipaddr/sm_ on _port_
sudo iptables -A INPUT -p _protocol_ -i _interface_ -j DROP:[Firewall] - To block incoming protocol requests on _interface_
sudo iptables -A INPUT -m mac --mac-source _mac_ -j DROP:[Firewall] - To drop inbound traffic to specific _mac_ address.
sudo iptables -A INPUT -p _protocol_ --syn --dport _port_ -m connlimit --connlimit-above _number_ -j REJECT:[Firewall] - limit the number of concurrent connections to _number_ (connlimit->Allows you to restrict the number of parallel TCP connections to a server per client IP address)
sudo iptables --flush:[Firewall] - To flush all the iptables rules currently exists in your system.
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP:[Firewall] - To drop invalid packets.
sudo iptables -A INPUT -i _interface_ -s _ipaddr/sm_ -j DROP:[Firewall] - To block connection on _interface_ on _ipaddr/sm_ or _ipadrr/sm_ range.
sudo iptables -t filter -n -L:[Firewall] - To check all the rules for filter table.
sudo iptables -N _service_:[Firewall] - To create a new chain named _service_
sudo iptables -S _chain-name_:[Firewall] - Print all the Rules of _chain-name_. If no chain is selected, it will show rules for all the chains.
sudo iptables -E _new-chain-name_ _old-chain-name_:[Firewall] - Rename _old-chain-name_ to _new-chain-name_
sudo iptables --list _chain-name_ --line-numbers:[Firewall] - List iptables rule with line numbers. List all rules in _chain-name_. If no chain is selected, all chains are listed.
sudo iptables -A INPUT -p _port_ -j REJECT --reject-with _reject-message_:[Firewall] - Reject _port_ requests with _reject-message_
sudo iptables -Z _chain-name_:[Firewall] - Zero out _chain-name_, if empty all chains
sudo iptables -D INPUT -p _protocol_ -j REJECT --reject-with _reject-message_:[Firewall] - Delete a rule.
sudo iptables -L _chain-name_ -v:[Firewall] - Check chain stats, see stats like no of packets, bytes, source, destination etc for specified chain, then you need to use -v option with iptables command.
sudo iptables -t _protocol_ -A PREROUTING -i _interface_ -p _protocol_ --dport _port-number_ -j REDIRECT --to-port _port-number_:[Firewall] - Sometimes you might need to hide the real port which listens to the incoming connection, for those cases port redirection or port forwarding will be very useful.
sudo iptables -l INPUT -d _ip_ -p _protocol_ -m multiport --dport _port-numbers,*_ -j DROP:[Firewall] - To drop inbound specified traffic to specified IP or IP addresses on multiple ports.
sudo iptables -A INPUT -m conntrack --cstate ESTABLISHED -j ACCEPT:[Firewall] - Allow established connections packets.
sudo iptables -A INPUT -j LOG:[Firewall] - Enable logging in iptables
sudo iptables -A INPUT -s _ip/*_ -j LOG:[Firewall] - Enable logging for source IP or subnet.
sudo iptables -A INPUT -i _interface_ -j LOG --log-prefix "IPtables Rejected packets\:":[Firewall] - Savings logs of rejected packets.
sudo iptables -A INPUT -s _ip/*_ -j LOG --log-prefix '** SUSPECT **':[Firewall] - Enable logging for suspicious filtered packets.
sudo iptables -t mangle -A PREPROUTING -p tcp --tcp-flags _flags,*_ -j DROP:[Firewall] - Block Packets with Bogus TCP Flags.
sudo ip link set _dev_ address _XX-XX-XX-XX-XX-XX_:[MAC] - Change mac address of device _dev_ (_dev_ must be down)
sudo ip addr show:[ip] - Display all network information
sudo ip addr show dev _dev_:[ip] - Show network information for only _dev_
sudo ip link:[ip] - Display information for network interfaces
sudo ip -s link:[ip] - Show interface statistics
sudo ip maddr:[ip] - Display multicast information for all devices
sudo ip maddr show dev _dev_:[ip] - Display multicast information for device _dev_
sudo ip neigh:[ip] - Display neighbour objects
sudo ip neigh show dev _dev_:[ip] - Show the ARP cache for device _dev_
sudo ip link dev _dev_:[ip] - Display information for only _dev_
sudo ip addr add _ipaddr/sm_ dev _dev_:[ip] - Add _ipaddr/sm_ with submask to _dev_
sudo ip addr del _ipaddr/sm_ dev _dev_:[ip] - Delete _ipaddr/sm_ with submask to _dev_
sudo ip link set _dev_ mtu _size_:[Packet] - Set largest frame or packet = _size_
ip route:[Route] - List all route entries in kernel
sudo ip route add default via _gateway_ dev _dev_:[Route] - Add default route via the local _gateway_ that can be reached on device _dev_
sudo ip route add _ipaddr/sm_ via _gateway_:[Route] - Add a route to _ipaddr/sm_ via _gateway_
sudo ip link set _dev_ up:[Status] - Set _dev_ up
sudo ip link set _dev_ down:[Status] - Set _dev_ down
sudo ip link set _dev_ promisc on:[Status] - Enable promiscius mode for _dev_
_cmd_ | ssh _host_@_hostip_ sh -c "_outcmd_ > _destfile_":[ssh] - Use stdout redirection through ssh
sudo ss -K dport =_port_:[Socket] - Kill processes using _port_ socket
sudo ss -_option_:[Socket] - ss is used to dump _option_ socket statistics.
sudo ss -N _nsname_:[Socket] - Switch to _nsname_ network namespace name.
sudo ss -A _query_:[Socket] - query=all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram, unix_stream, unix_seqpacket, packet_raw, packet_dgram.
sudo ss -D _file_:[Socket] - Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If _file_ is '-' stdout is used.
sudo ss -F _file:[Socket] - Read filter information from FILE. Each line of FILE is interpreted like single command line option. If FILE is - stdin is used.
sudo ss -at '( dport = \:_port_ or sport = \:_port_ )':[Socket] - Filter connections by port number or port name
sudo ss dst _ip_:[Socket] - Show connected sockets from specific address, address range and specified port number
sudo ss -f _family_:[Socket] - Option to specify the connection family. It will only display the information of specified family. The supported families are: unix, inet, inet6, link, netlink.
sudo ss -o state _state-filter_:[Socket] - STATE-FILTER allows to construct arbitrary set of states to match.
sudo iw dev wlan0 scan | grep -Po '(?<=SSID\\: ).*':[Wifi] - Scan networks without network manager
wpa_passphrase _essid_ _pass_ | sudo tee /etc/wpa_supplicant.conf:[Wifi] - Create wpa supplicant conf on _essid_ with password _pass_
sudo wpa_supplicant -c /etc/wpa_supplicant.conf -i _iface:[Wifi] - Launch wpa supplicant on _iface_
EOF
)

    local -a _netargs=("${(@f)$(getcmd $_net_s)}")
    _describe -t neta 'Network commands' _netargs
    _evalarg=
    return 0
}

function _device() {
    _devices=$(cat <<'EOF'
sudo vmstat --disk:[Block] - Show block device summary information
sudo udevadm info -a -n _dev_ | egrep 'looking|DRIVER':[Block] - Try to check block _dev_ kernel driver
lscpu -ae:[Cpu] - Get cpu usage information
sudo cpu_info:[Cpu] - Get verbose information about CPU from proc (runs script)
sensors | awk '/Tctl/{print $2}' || sensors | awk '/Core/ {print $3}' | tr -d "+C°" | awk '{ sum += $1 } END { if (NR > 0) print sum / NR }':[Cpu] - Get x64 intel - amd cpu temperature (C°)
sudo dmidecode:[Device] - Get hardware dmi information
sudo awk '{print $1*10^-6 " W"}' /sys/class/power_supply/BAT?/power_now:[Power] - Get current power usage
read e < /sys/class/power_supply/BAT?/energy_now; read p < /sys/class/power_supply/BAT?/power_now; echo "print($e/$p)" | python3:[Power] - Get remaining battery hour
cat /proc/acpi/wakeup:[Power] - Check device wakeup status options
sudo powerinfo:[Power] - Get power consumption of devices (runs script)
sudo lshw -c _class_:[Hardware] - Get specific _class_ hardware information (input, storage ..)
sudo lshw:[Hardware] - Get general hardware information
xinput list:[Input] - Get Xorg input device information
xinput list-props _id_:[Input] - Get Xorg device with _id_ input properties
vmstat --active:[Memory] - Show active/inactive memory information
sudo lspci -k:[PCI] - Get PCI information and kernel modules
sudo lspci -kv:[PCI] - Get PCI information,kernel modules be verbose
sudo lsusb:[Usb] - Get usb device information
sudo lsusb -t:[Usb] - Get usb device information with tree view
sudo lsusb -v:[Usb] - Usb device information verbose
sudo lsusb -v | grep -E ' Device [0-9]|MaxPower':[Usb] - Get power consumption of usb devices
EOF
)

    local -a _devargs=("${(@f)$(getcmd $_devices)}")
    _describe -t device 'Device - hardware related' _devargs
    _evalarg=
    return 0
}

function _user() {
    _users=$(cat <<'EOF'
sudo useradd -m _user_:[User] - Add a new _user_ to system with home directory
sudo useradd -M _user_:[User] - Add a new _user_ to system without home directory
sudo useradd -G _group_ _user_:[User] - Create new user and add to _group_
sudo usermod -d -m _newhome_ _user_:[User] - Change _user_ home dir to _newhome_
sudo usermod -u _uid_ _user_:[User] - Change uid of _user_ to _uid_
sudo usermod -aG _groups,_ _user_:[User] - Add user to any number of , seperated _groups,_
sudo userdel _user_:[User] - Delete _user_ from system
sudo usermod --shell _shell_ _user_:[User] - Change default shell of _user_ to _shell_
chsh -s _shell_ _user_:[User] - Change default shell of _user_ to _shell_
sudo pkill -9 -u _user_:[User] - Force kill _user_ session
sudo killall -9 -u _user_:[User] - Force kill all processes and session of _user_
passwd _user_:[User] - Change password of _user_
w:[User] - Get logged user and process of users
id:[User] - Get verbose information about current user
last:[User] - Get last login information about users
su - _newuser_:[User] - Change current user to _newuser_
sudo -u _newuser_ -s:[User] - Change current user to _newuser_ with sudo
EDITOR=_editor_ sudo visudo:[User] - Edit sudoers file with _editor_
sudo groupadd _name_:[Group] - Create new group with _name_
sudo groupadd -g _id_ _name_:[Group] - Create new group with _name_ with _id_
sudo groupdel -f _name_:[Group] - Force delete _name_ group
sudo groupmod _old_ -n _new_:[Group] - Change _old_ group name to _new_
groups _user_:[Group] - List groups of _user_
sudo chown _user_\:_group_ _target_:[Permission] - Change owner of _target_ to _user_ and group to _group_
sudo chown -hR _user_ _path_:[Permission] - Recursively change file ownerships to _user_ in _path_ (Change symlink ownership, dont follow)
sudo chown -hr _user_ _path_:[Permission] - Recursively change file ownerships to _user_ in _path_ (Follow symlink and change ownership of all)
sudo chmod _mask_ _path_:[Permission] - Change flags of _path_ to _mask_ (e.g r+w, 777)
sudo chgrp _group_ _path_:[Permission] - Change group owner of _path_ to _group_
sudo getfacl _file_:[Permission] - Verbose information about _file_ permissions
sudo chattr _flags_ _file_:[Permission] - Change extended attributes to _flags_ of _file_ (e.g +i for immutable)
lsattr _file_:[Permission] - Display extended attributes of _file_
EOF
)

    local -a _userargs=("${(@f)$(getcmd $_users)}")
    _describe -t users 'User - group related commands' _userargs
    _evalarg=
    return 0
}


_arguments -C \
    "1: :->cmds" \
    "*: :->args" && return 0


case "$state" in
    cmds)
        _values "phint command" \
            "binary-number[Binary - number - algorithm related commands]" \
            "block[Block - mapper - storage related commands]" \
            "boot[Boot - partition related commands]" \
            "device[Hardware related information]" \
            "kernel[Kernel related commands]" \
            "network[Network related commands]" \
            "pacman[Useful pacman commands]" \
            "systemd[Systemd - journal commands]" \
            "user[User - group related commands]" \
            "str.h[String manipulation]" && return 0
        ;;
    args)
        case "$line[1]" in
            binary-number)
                _binary ;;
            block)
                _block ;;
            boot)
                _boot ;;
            device)
                _device ;;
            kernel)
                _kernel ;;
            systemd)
                _sysd ;;
            network)
                _net ;;
            user)
                _user ;;
            pacman)
                _pacman ;;
            str.h)
                _str.h ;;
        esac
        ;;
esac

# vim: set et ts=4 sw=4 ft=zsh:
