From a715b74453d21e150078e024a7a69ddc0e507caf Mon Sep 17 00:00:00 2001 From: fj0r <82698591+fj0r@users.noreply.github.com> Date: Wed, 3 Apr 2024 19:29:45 +0800 Subject: [PATCH] utils of history with sqlite (#779) - backup - restore - timing - top --------- Co-authored-by: nash --- modules/history-utils/mod.nu | 105 +++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 modules/history-utils/mod.nu diff --git a/modules/history-utils/mod.nu b/modules/history-utils/mod.nu new file mode 100644 index 00000000..fee6b935 --- /dev/null +++ b/modules/history-utils/mod.nu @@ -0,0 +1,105 @@ +def quote [...t] { + $"'($t | str join '')'" +} + +def flatten_fields [args] { + let f = $in | default [] | filter {|x| $x | is-not-empty } + let prefix = $args.0 + let inner = $args.1 + let outer = $args.2 + if ($f | is-not-empty) { + $f + | each {|x| + if ($x | describe -d).type == list { + $x | str join $inner + } else { + $x + } + } + | str join $outer + | do { (if ($prefix | is-empty) {[$in]} else {[$prefix $in]})} + } else { [] } +} + +def sql [q] { + [ + [$q.select ['select', ' as ', ', ']] + [$q.from ['from', ' as ', ' join ']] + [$q.where? ['where', ' ', ' and ']] + [$q.whereOr? ['or', ' ', ' or ']] + [$q.groupBy? ['group by', null, ', ']] + [$q.orderBy? ['order by', ' ', ', ']] + [$q.limit? ['limit', null, ' offset ']] + ] + | each {|x| $x.0 | flatten_fields $x.1 } + | flatten + | str join ' ' +} + +export def 'history timing' [ + pattern? + --exclude(-x): string + --num(-n)=10 + --all(-a) +] { + open $nu.history-path | query db (sql { + from: history + where: [ + "cmd not like 'history timing%'" + (if ($pattern | is-not-empty) {[cmd like (quote '%' $pattern '%')]}) + (if ($exclude | is-not-empty) {[cmd not like (quote '%' $exclude '%')]}) + (if not $all {[cwd = (quote $env.PWD)]}) + ] + orderBy: [[start desc]] + select: [ + [duration_ms duration] + [command_line cmd] + [start_timestamp start] + (if $all {[$"replace\(cwd, '($env.HOME)', '~')" cwd]}) + [exit_status exit] + ] + limit: $num + }) + | update duration {|x| $x.duration | default 0 | do { $in * 1_000_000 } | into duration } + | update start {|x| $x.start | into int | do { $in * 1_000_000 } | into datetime } +} + +def "nu-complete history dir" [] { + open $nu.history-path | query db (sql { + select: [cwd ['count(1)' count]] + from: history + groupBy: [cwd] + orderBy: ['count desc'] + limit: 20 + }) + | rename value description + | update value {|x| $x.value | str replace $env.HOME '~' } +} + +export def 'history top' [ + num=10 + --before (-b): duration + --dir (-d) + --path(-p): list +] { + open $nu.history-path | query db (sql { + from: history + select: [ + (if $dir {[$"replace\(cwd, '($env.HOME)', '~')" cwd]} else {[command_line cmd]}) + ['count(1)' count] + ] + where: [ + (if ($before | is-not-empty) { + let ts = (date now) - $before | into int | do { $in / 1_000_000 } + [start_timestamp > $ts] + }) + (if ($path | is-not-empty) { + let ps = $path | path expand | each { quote $in } | str join ', ' + [cwd in '(' $ps ')'] + }) + ] + groupBy: [(if $dir {'cwd'} else {'cmd'})] + orderBy: [[count desc]] + limit: $num + }) +}