# Processes sorted by CPU, optionally filtered by name
def psk [query?: string] {
  ps | sort-by cpu -r
  | if $query != null { where name =~ $query } else { $in }
}

# Listening TCP ports with process info
def ports [] {
  ^ss -tlnp
  | detect columns
  | rename state recv-q send-q local peer process
  | each {|r| $r | upsert port (try { $r.local | split row ":" | last | into int } catch { null })}
  | select state local port process
  | sort-by port
}

# Repeatedly clears and reruns a closure — nu-native watch replacement
def rewatch [interval: duration, cmd: closure] {
  loop {
    clear
    let dim = $env.config.color_config.hints
    print $"(ansi { fg: $dim })(date now | format date '%H:%M:%S')(ansi reset)"
    do $cmd | print
    sleep $interval
  }
}

# Cycle through all history args on repeated Alt+. presses
def --env last-arg-cycle [] {
    let skip = ["|" "&&" "||" ";" ">" ">>" "<" "&" "2>"]
    let all_args = (
        history
        | get command
        | reverse
        | each { |cmd| $cmd | split row -r '\s+' | where { |w| ($w | str length) > 0 } | reverse | where { |w| not ($skip | any { $w == $in }) } }
        | flatten
        | where { |w| ($w | str length) > 0 }
    )
    if ($all_args | is-empty) { return }

    let current = (commandline)
    let last    = ($env.NU_ALT_DOT_LAST? | default "")
    let base    = ($env.NU_ALT_DOT_BASE? | default "")
    let idx     = ($env.NU_ALT_DOT_IDX?  | default (-1) | into int)

    if $idx >= 0 and $current == $"($base)($last)" {
        let next_idx = (($idx + 1) mod ($all_args | length))
        let next     = ($all_args | get $next_idx)
        commandline edit --replace $"($base)($next)"
        $env.NU_ALT_DOT_IDX  = $next_idx
        $env.NU_ALT_DOT_LAST = $next
    } else {
        let first = ($all_args | get 0)
        commandline edit --insert $first
        $env.NU_ALT_DOT_BASE = $current
        $env.NU_ALT_DOT_IDX  = 0
        $env.NU_ALT_DOT_LAST = $first
    }
}

# Fuzzy-pick a full command from history and insert at cursor (Alt+,)
def --env history-cmd-pick [] {
    let cmd = try {
        history
        | get command
        | reverse
        | uniq
        | sk --prompt "history> " --height "40%" --reverse --no-sort
        | str trim
    } catch { "" }
    if ($cmd | str length) > 0 {
        commandline edit --insert $cmd
    }
}

# Environment variables as a filterable sorted table
def envs [query?: string] {
  $env | transpose key value
  | if $query != null { where key =~ $query } else { $in }
  | sort-by key
}
