mirror of
https://github.com/Cian-H/dotfiles.git
synced 2026-03-06 21:28:07 +00:00
Changed . token to _dot
This change allows the dotfiles to work with chezmoi (e.g: on windows) and improves grepability with neovim/telescope
This commit is contained in:
13
dot_config/nushell/nu_scripts/sourced/README.md
Normal file
13
dot_config/nushell/nu_scripts/sourced/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Helpers
|
||||
|
||||
Commands to make your life easier.
|
||||
|
||||
## How to use
|
||||
|
||||
Execute following snippet at any time to be able to run the commands in the scripts:
|
||||
|
||||
```zsh
|
||||
source './path/to/script.nu'
|
||||
```
|
||||
|
||||
With `./path/to/...` being the path to the script you want to utilize.
|
||||
59
dot_config/nushell/nu_scripts/sourced/TODO.md
Normal file
59
dot_config/nushell/nu_scripts/sourced/TODO.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# todo
|
||||
|
||||
These two commands can be used to make simple todo-lists that
|
||||
are printed to the screen at terminal startup. They are currently
|
||||
only implemented for [alacritty], for other terminals consult
|
||||
your terminal documentation or find a work around
|
||||
|
||||
## SETUP:
|
||||
- Create a file called `todo.nu` and place the `printer` command,
|
||||
calling it at the end.
|
||||
- In your `alacritty.yml`, add this
|
||||
```yml
|
||||
shell:
|
||||
program: /bin/nu # path to your `nu` executable
|
||||
args:
|
||||
- -e "nu /path/to/todo.nu"
|
||||
```
|
||||
- Create an empty file called `todo.txt`
|
||||
- *Recommended*
|
||||
In your `env.nu`, add an environment variable pointing to the `todo.txt`. Example:
|
||||
```nu
|
||||
$env.TODO = ($nu.config-path | path dirname | path join 'scripts/todo.txt')
|
||||
```
|
||||
- Source the `todo` command in your `config.nu`. Example
|
||||
```nu
|
||||
source './scripts/todo.nu'
|
||||
```
|
||||
## USAGE:
|
||||
- On terminal startup, the printer command is run by `nu` and the
|
||||
list is printed to the screen. If the list is empty, a message
|
||||
indicating so is printed.
|
||||
|
||||
- To add items,
|
||||
```nu
|
||||
todo -a "finish writing docs"
|
||||
```
|
||||
|
||||
- To remove an item
|
||||
```nu
|
||||
# this prints the list(numbered)
|
||||
todo
|
||||
# the index of the item you want to remove
|
||||
# (starts at 1 but can be changed to start at 0)
|
||||
todo -r 4
|
||||
```
|
||||
|
||||
- To clear the whole list
|
||||
```nu
|
||||
todo -c
|
||||
```
|
||||
|
||||
- To manually edit the list
|
||||
```
|
||||
# this opens an editor with the file opened
|
||||
todo -e
|
||||
```
|
||||
|
||||
|
||||
[alacritty]: github.com/alacritty/alacritty
|
||||
@@ -0,0 +1,19 @@
|
||||
let appID = "" #YOUR APP_ID
|
||||
|
||||
#Fetch simple answer from WolframAlpha API
|
||||
def wolfram [...query #Your query
|
||||
] {
|
||||
let query_string = ($query | str join " ")
|
||||
let result = (http get ("https://api.wolframalpha.com/v1/result?" + ([[appid i]; [$appID $query_string]] | url build-query)))
|
||||
$result + ""
|
||||
}
|
||||
|
||||
#Fetch image with full answer from WolframAlpha API
|
||||
def wolframimg [...query #Your query
|
||||
] {
|
||||
let query_string = ($query | str join " ")
|
||||
let filename = ($query_string + ".png")
|
||||
let link = ("https://api.wolframalpha.com/v1/simple?" + ([[appid i]; [$appID $query_string]] | url build-query) + "&background=F5F5F5&fontsize=20")
|
||||
http get $link | save $filename
|
||||
echo ("Query result saved in file: " + $filename)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# cool oneliners
|
||||
|
||||
Capturing oneliners to and from the nushell community.
|
||||
|
||||
Consider these a living library.
|
||||
Or an ongoing story of how people actually use `nu`.
|
||||
|
||||
## Naming and script requirements
|
||||
|
||||
- the filename should be an abbreviation of the general topic of the script
|
||||
For example:
|
||||
|
||||
```sh
|
||||
git_batch_extract.nu
|
||||
```
|
||||
|
||||
- the script should have two lines
|
||||
- the first line should be a comment describing the script's purpose
|
||||
- the second line should be the cool oneliner
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
["cero", "zero"],
|
||||
["uno", "one"],
|
||||
["dos", "two"],
|
||||
["tres", "three"]
|
||||
]
|
||||
@@ -0,0 +1,12 @@
|
||||
def "cargo search" [ query: string, --limit=10] {
|
||||
^cargo search $query --limit $limit
|
||||
| lines
|
||||
| each {
|
||||
|line| if ($line | str contains "#") {
|
||||
$line | parse --regex '(?P<name>.+) = "(?P<version>.+)" +# (?P<description>.+)'
|
||||
} else {
|
||||
$line | parse --regex '(?P<name>.+) = "(?P<version>.+)"'
|
||||
}
|
||||
}
|
||||
| flatten
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/nu
|
||||
|
||||
# I actually use it as a part of my startup, so I am not really sure how to pack it, yet I wouldd like to contribute
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# How to use?
|
||||
#-------------------------------------------------
|
||||
#1) Add desired paths to the cdpath variable
|
||||
#2) Use in your shell: $c [directory]
|
||||
#2.5) You *have to* use an argument. If you wish to simply $cd, use $cd command.
|
||||
#3) If the path exists, you will cd into the first match found (the command is iterating over the list in the correct order,
|
||||
# i.e. first element is being iterated overin the first place)
|
||||
#3.5) But if path does not exist, you will receive a proper echo.
|
||||
#-----------------------------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
#Written by skelly37
|
||||
#------------------------
|
||||
|
||||
# startup = [
|
||||
# "let cdpath = [. /place/your ~/cdpath/here ]",
|
||||
# "def c [dir] { let wd = (pwd); for element in $cdpath {if (pwd) == $wd {cd $element; for directory in (ls -a | select name type | each { if $it.type == Dir {echo $it.name} {} } ) {if $dir == $directory {cd $dir} {}}; if (pwd) == $element {cd $wd} {}} {}}; if (pwd) == $wd {cd $wd; echo \"No such path!\"} {}}",
|
||||
# ]
|
||||
#
|
||||
|
||||
export def --env c [dir] {
|
||||
let CD_PATH = [. ($env.NU_PLUGIN_DIRS | get 0) $nu.default-config-dir ]
|
||||
let wd = (pwd);
|
||||
for element in $CD_PATH {
|
||||
let element = ($element | path expand)
|
||||
if (pwd) == $wd {
|
||||
cd $element;
|
||||
for directory in (ls -a | where type == dir | get name) {
|
||||
if $dir == $directory {
|
||||
cd $dir
|
||||
break
|
||||
}
|
||||
};
|
||||
if (pwd) == $element {
|
||||
cd $wd
|
||||
}
|
||||
}
|
||||
};
|
||||
if (pwd) == $wd {
|
||||
cd $wd
|
||||
print "No such path!"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
### This clears out your screen buffer on a default mac terminal
|
||||
### currently there is no way to do that in nushell
|
||||
|
||||
def cls [] {
|
||||
ansi cls
|
||||
ansi clsb
|
||||
ansi home
|
||||
}
|
||||
21
dot_config/nushell/nu_scripts/sourced/cool-oneliners/dict.nu
Normal file
21
dot_config/nushell/nu_scripts/sourced/cool-oneliners/dict.nu
Normal file
@@ -0,0 +1,21 @@
|
||||
# Function querying free online English dictionary API for definition of given word(s)
|
||||
def dict [...word #word(s) to query the dictionary API but they have to make sense together like "martial law", not "cats dogs"
|
||||
] {
|
||||
let query = ($word | str join %20)
|
||||
let link = ('https://api.dictionaryapi.dev/api/v2/entries/en/' + ($query|str replace ' ' '%20'))
|
||||
let output = (http get $link | rename word)
|
||||
let w = ($output.word | first)
|
||||
|
||||
if $w == "No Definitions Found" {
|
||||
echo $output.word
|
||||
} else {
|
||||
echo $output
|
||||
| get meanings
|
||||
| flatten
|
||||
| select partOfSpeech definitions
|
||||
| flatten
|
||||
| flatten
|
||||
| reject "synonyms"
|
||||
| reject "antonyms"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Combine two files into one
|
||||
|
||||
def create_files [] {
|
||||
[0,1,2,3] | range 0..3 | save a.json
|
||||
[4,5,6,7] | range 0..3 | save b.json
|
||||
}
|
||||
|
||||
create_files
|
||||
echo (open a.json) (open b.json) | save c.json
|
||||
open c.json | flatten
|
||||
rm a.json b.json c.json
|
||||
@@ -0,0 +1,7 @@
|
||||
# rename any SQL files in current directory from hello_file.sql to hello-file.sql
|
||||
ls ./*.sql | each { |f|
|
||||
let ext = (echo $f.name | path parse | get extension);
|
||||
let cur_stem = (echo $f.name | path parse | get stem);
|
||||
let new_name = (build-string (echo $cur_stem | str kebab-case) "." $ext)
|
||||
mv $f.name $new_name
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
## show directory sizes in current directory starting from the largest
|
||||
ls -d|where type == dir|sort-by size|reverse|format filesize GB size
|
||||
@@ -0,0 +1,12 @@
|
||||
# Search terms in the specified files and/or folders based on the glob pattern provided.
|
||||
def "find in" [
|
||||
glob: glob, # the glob expression
|
||||
...rest: any # terms to search
|
||||
]: nothing -> table<path: string, line: int, data: string> {
|
||||
glob $glob
|
||||
| par-each {|e|
|
||||
open $e | lines | enumerate | rename line data |
|
||||
find -c [data] ...$rest |
|
||||
each {|match| {path: ($e | path relative-to $env.PWD), ...$match}}
|
||||
} | flatten
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# gently try to delete merged branches, excluding the checked out one
|
||||
git branch --merged | lines | where $it !~ '\*' | str trim | where $it != 'master' and $it != 'main' | each { |it| git branch -d $it }
|
||||
@@ -0,0 +1,2 @@
|
||||
# Ingest JavaScript Map JSON into nu then to markdown
|
||||
open assets/js_map.json | each { echo [[Español English]; [ $in.0 $in.1]] } | flatten | to md
|
||||
@@ -0,0 +1,2 @@
|
||||
# Increment the minor version for any package.json in the current directory with `nu_plugin_inc` (eigenrick — 08/16/2020)
|
||||
ls -f */package.json | each {|it| open $it.name | inc version --minor | to json --indent 2 | save --raw --force $it.name }
|
||||
@@ -0,0 +1 @@
|
||||
open ~/.config/fish/fish_history | from yaml | get cmd | find --regex '^git .*' | split column ' ' command subcommand
|
||||
@@ -0,0 +1,4 @@
|
||||
# Print working directory but abbreviates the home dir as ~
|
||||
def pwd-short [] {
|
||||
$env.PWD | str replace $nu.home-path '~'
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Makes an http request to a URL and gets the "value" field off the JSON response.
|
||||
(http get https://api.chucknorris.io/jokes/random).value
|
||||
@@ -0,0 +1,2 @@
|
||||
# Evaluates the top 5 most used commands present in `nushell/history.txt`.
|
||||
if $nu.history-enabled { open $nu.history-path | lines | uniq --count | sort-by --reverse count | first 5 | rename command amount } else { print --stderr "History is disabled!" }
|
||||
@@ -0,0 +1,6 @@
|
||||
# Search the WordprocessingML XML Schema definition file for a simple type by name
|
||||
# You'll need the wml.xsd file.
|
||||
# To get that file, first download the following zip:
|
||||
# https://www.ecma-international.org/wp-content/uploads/ECMA-376-Fifth-Edition-Part-1-Fundamentals-And-Markup-Language-Reference.zip
|
||||
# Then, unzip the contents of OfficeOpenXML-XMLSchema-Strict.zip.
|
||||
open wml.xsd | from xml | get content | where tag == simpleType | flatten | where name =~ BrType | get content.content.0.attributes
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
def "nu core-team" [] {
|
||||
[
|
||||
[ 'name', 'tz'];
|
||||
[ 'andres', 'America/Guayaquil']
|
||||
[ 'fdncred', 'US/Central']
|
||||
[ 'gedge', 'US/Eastern']
|
||||
[ 'jt', 'NZ']
|
||||
[ 'wycats', 'US/Pacific']
|
||||
[ 'kubouch', 'Europe/Helsinki']
|
||||
['elferherrera', 'Europe/London']
|
||||
]
|
||||
}
|
||||
|
||||
def "date local" [now] {
|
||||
insert time {|value|
|
||||
let converted = ($now | date to-timezone $value.tz);
|
||||
|
||||
$converted | format date '%c'
|
||||
}
|
||||
}
|
||||
|
||||
let next_call = ("2021-08-31 15:00:21.290597200 -05:00" | into datetime);
|
||||
let people = (nu core-team | date local $next_call);
|
||||
|
||||
def say [closure] {
|
||||
$in | each {|person|
|
||||
do $closure (
|
||||
$person | update name {|row| $row.name | str capitalize}
|
||||
)
|
||||
} | str join (char newline)
|
||||
}
|
||||
|
||||
print ($people | say {|person| $"($person.name)'s timezone is ($person.tz)"})
|
||||
|
||||
print ($"
|
||||
|
||||
for the next call happening on ($next_call | format date '%c').. in their timezones they would be:
|
||||
|
||||
")
|
||||
|
||||
print ($people | say {|person| $"($person.name)'s: ($person.time)"})
|
||||
25
dot_config/nushell/nu_scripts/sourced/examples/netstat.nu
Normal file
25
dot_config/nushell/nu_scripts/sourced/examples/netstat.nu
Normal file
@@ -0,0 +1,25 @@
|
||||
let ns = (netstat | lines | skip 1)
|
||||
|
||||
let first_batch = ($ns | take until {|it| $it =~ Active } | str join (char nl) | from ssv -m 1)
|
||||
let second_batch = ($ns |
|
||||
skip until {|it| $it =~ Active } |
|
||||
skip 1 |
|
||||
str join (char nl) |
|
||||
str replace '\[ \]' "[]" --all |
|
||||
from ssv -m 1 |
|
||||
default I-Node "" |
|
||||
default Path ""
|
||||
| each {|row| if $row.Type == DGRAM {
|
||||
$row | update Path { get I-Node } | update I-Node { get State } | update State ""
|
||||
} else {
|
||||
$row
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
print $first_batch
|
||||
print $second_batch
|
||||
|
||||
|
||||
|
||||
|
||||
69
dot_config/nushell/nu_scripts/sourced/fehbg.nu
Normal file
69
dot_config/nushell/nu_scripts/sourced/fehbg.nu
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env engine-q
|
||||
#
|
||||
# ~/.fehbg.nu
|
||||
#
|
||||
# This script selects a random image from a directory and sets it as a
|
||||
# wallpaper. An additional feature is that it draws the path of the image in
|
||||
# the lower left corner which makes it easier to find the image later.
|
||||
#
|
||||
# The procedure is as follows::
|
||||
# * Select a random image from a directory (recursively entering all
|
||||
# subdirectories)
|
||||
# * Print the path of the image on top of the selected image
|
||||
# * Save the result in a temporary file
|
||||
# * Set the temporary image as a wallpaper.
|
||||
#
|
||||
# !! Requires `WALLPAPER_DIR` and `TMP_DIR` environment variables to be set !!
|
||||
# (or just hardcode your own paths below)
|
||||
#
|
||||
# You can set this script to run on desktop startup, e.g., by adding it to
|
||||
# xinitrc.
|
||||
#
|
||||
# Dependencies;
|
||||
# * new Nushell engine (https://github.com/nushell/engine-q)
|
||||
# * feh
|
||||
# * imagemagick
|
||||
|
||||
# Path definitions
|
||||
let img_dir = $env.WALLPAPER_DIR
|
||||
let tmp_image = ([ $env.TMP_DIR "wallpaper.jpg" ] | path join)
|
||||
|
||||
# Monitor resolution
|
||||
let resolution_y = 1440
|
||||
let res_str = ($"x($resolution_y)")
|
||||
|
||||
# Position of the caption
|
||||
let pos_x = 5
|
||||
let pos_y = (0.995 * $resolution_y | into int)
|
||||
|
||||
# Select random item from input
|
||||
def select-random [] {
|
||||
shuffle | first
|
||||
}
|
||||
|
||||
# List all images in a directory and all its subdirectories
|
||||
def list-images [dir: path] {
|
||||
ls $"($dir)/**/*" |
|
||||
where type == file |
|
||||
str downcase name |
|
||||
where name =~ jpg or name =~ jpeg or name =~ tif or name =~ tiff or name =~ png
|
||||
}
|
||||
|
||||
# Set the caption text (just filename for now)
|
||||
def caption [img_f: string] {
|
||||
echo $img_f
|
||||
}
|
||||
|
||||
# Build the argument for the '-draw' command of the 'convert' utility
|
||||
def draw-str [img_f: string] {
|
||||
$"text ($pos_x), ($pos_y) (char dq)(caption $img_f)(char dq) "
|
||||
}
|
||||
|
||||
# Select random image
|
||||
let img_name = (list-images $img_dir | select-random | get name) # TODO: change the env var to $img-dir
|
||||
|
||||
# Resize the image to the monitor height, draw the caption and save it
|
||||
convert -resize $res_str -pointsize 15 -fill 'rgb(255,200,150)' -draw (draw-str $img_name) $img_name $tmp_image
|
||||
|
||||
# Set the created image as a background
|
||||
feh --no-fehbg --bg-max $tmp_image
|
||||
169
dot_config/nushell/nu_scripts/sourced/filesystem/cdpath.nu
Normal file
169
dot_config/nushell/nu_scripts/sourced/filesystem/cdpath.nu
Normal file
@@ -0,0 +1,169 @@
|
||||
# You must set $env.CDPATH, try:
|
||||
#
|
||||
# $env.CDPATH = [
|
||||
# ".",
|
||||
# "~",
|
||||
# "~/path/to/repositories",
|
||||
# ]
|
||||
#
|
||||
# The above $env.CDPATH will complete:
|
||||
# * Entries under the current directory ($env.PWD)
|
||||
# * Entries in your home directory ($env.HOME)
|
||||
# * Entries where you check out repositories
|
||||
# * Children of those entries
|
||||
#
|
||||
# This CDPATH implementation also completes absolute paths to help you use `c`
|
||||
# instead of `cd`
|
||||
#
|
||||
# Bugs:
|
||||
# * `c` does not complete paths that start with "~". This should support both
|
||||
# directories ("~/.config/nu"), users ("~notme"), and both combined
|
||||
# ("~notme/.config/nu")
|
||||
module cdpath {
|
||||
# $env.CDPATH with unique, expanded, existing paths
|
||||
def cdpath [] {
|
||||
$env.CDPATH
|
||||
| path expand
|
||||
| uniq
|
||||
| filter {|| $in | path exists }
|
||||
}
|
||||
|
||||
# Children of a path
|
||||
def children [path: string] {
|
||||
ls -a $path
|
||||
| where type == "dir"
|
||||
| get name
|
||||
}
|
||||
|
||||
# Completion for `c`
|
||||
#
|
||||
# `contains` is used instead of `starts-with` to behave similar to fuzzy
|
||||
# completion behavior.
|
||||
#
|
||||
# During completion of a CDPATH entry the description contains the parent
|
||||
# directory you will complete under. This allows you to tell which entry in
|
||||
# your CDPATH your are completing to if you have the same directory under
|
||||
# multiple entries.
|
||||
def complete [context: string] {
|
||||
let context_dir = $context | parse "c {context_dir}" | get context_dir | first
|
||||
let path = $context_dir | path split
|
||||
let no_trailing_slash = not ($context_dir | str ends-with "/")
|
||||
|
||||
# completion with no context
|
||||
if ( $path | is-empty ) {
|
||||
complete_from_cdpath
|
||||
# Complete an entry in CDPATH
|
||||
#
|
||||
# This appends a / to allow continuation to the last step
|
||||
} else if $no_trailing_slash and (1 == ( $path | length )) {
|
||||
let first = $path | first
|
||||
|
||||
complete_from_cdpath
|
||||
| filter {|| $in.value | str contains $first }
|
||||
| upsert value {|| $"($in.value)/" }
|
||||
# Complete a child of a CDPATH entry
|
||||
} else {
|
||||
let prefix = if 1 == ($path | length) {
|
||||
$path | first
|
||||
} else {
|
||||
$path | first (($path | length) - 1) | path join
|
||||
}
|
||||
|
||||
let last = if 1 == ($path | length) {
|
||||
""
|
||||
} else {
|
||||
$path | last
|
||||
}
|
||||
|
||||
let chosen_path = if ( $path | first) == "/" {
|
||||
if $no_trailing_slash {
|
||||
$prefix
|
||||
} else {
|
||||
$context_dir
|
||||
}
|
||||
} else {
|
||||
cdpath
|
||||
| each {||
|
||||
$in | path join $prefix
|
||||
}
|
||||
| filter {||
|
||||
$in | path exists
|
||||
}
|
||||
| first
|
||||
}
|
||||
|
||||
children $chosen_path
|
||||
| filter {||
|
||||
$in | str contains $last
|
||||
}
|
||||
| each {|child|
|
||||
$"($chosen_path | path join $child)/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def complete_from_cdpath [] {
|
||||
cdpath
|
||||
| each { |path|
|
||||
children $path
|
||||
| path basename
|
||||
| sort
|
||||
| each { |child| { value: $child, description: $path } }
|
||||
}
|
||||
| flatten
|
||||
| uniq-by value
|
||||
}
|
||||
|
||||
# Change directory with $env.CDPATH
|
||||
export def --env c [dir = "": string@complete] {
|
||||
let span = (metadata $dir).span
|
||||
let default = if $nu.os-info.name == "windows" {
|
||||
$env.USERPROFILE
|
||||
} else {
|
||||
$env.HOME
|
||||
}
|
||||
|
||||
let target_dir = if $dir == "" {
|
||||
$default
|
||||
} else if $dir == "-" {
|
||||
if "OLDPWD" in $env {
|
||||
$env.OLDPWD
|
||||
} else {
|
||||
$default
|
||||
}
|
||||
} else {
|
||||
cdpath
|
||||
| reduce -f "" { |$it, $acc|
|
||||
if $acc == "" {
|
||||
let new_path = ([$it $dir] | path join)
|
||||
if ($new_path | path exists) {
|
||||
$new_path
|
||||
} else {
|
||||
""
|
||||
}
|
||||
} else {
|
||||
$acc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let target_dir = if $target_dir == "" {
|
||||
let cdpath = $env.CDPATH | str join ", "
|
||||
|
||||
error make {
|
||||
msg: $"No such child under: ($cdpath)",
|
||||
label: {
|
||||
text: "Child directory",
|
||||
start: $span.start,
|
||||
end: $span.end,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$target_dir
|
||||
}
|
||||
|
||||
cd $target_dir
|
||||
}
|
||||
}
|
||||
|
||||
use cdpath c
|
||||
8
dot_config/nushell/nu_scripts/sourced/filesystem/up.nu
Normal file
8
dot_config/nushell/nu_scripts/sourced/filesystem/up.nu
Normal file
@@ -0,0 +1,8 @@
|
||||
use std repeat;
|
||||
|
||||
# Go up a number of directories
|
||||
def --env up [
|
||||
limit = 1: int # The number of directories to go up (default is 1)
|
||||
] {
|
||||
cd ("." | repeat ($limit + 1) | str join)
|
||||
}
|
||||
36
dot_config/nushell/nu_scripts/sourced/fun/lisp_mode.nu
Normal file
36
dot_config/nushell/nu_scripts/sourced/fun/lisp_mode.nu
Normal file
@@ -0,0 +1,36 @@
|
||||
# Note: this requires the latest 0.32.1 or later
|
||||
#
|
||||
# usage:
|
||||
# > source lisp_mode.nu
|
||||
# > (echo (+ 1 (* 3 2)))
|
||||
|
||||
def "+" [x, y] { $x + $y }
|
||||
|
||||
def "-" [x, y] { $x - $y }
|
||||
|
||||
def "*" [x, y] { $x * $y }
|
||||
|
||||
def "/" [x, y] { $x / $y }
|
||||
|
||||
def in [x, y] { $x in $y }
|
||||
|
||||
def not-in [x, y] { $x not-in $y}
|
||||
|
||||
def "<" [x, y] { $x < $y }
|
||||
|
||||
def "<=" [x, y] { $x <= $y }
|
||||
|
||||
def ">" [x, y] { $x > $y }
|
||||
|
||||
def ">=" [x, y] { $x >= $y }
|
||||
|
||||
def "==" [x, y] { $x == $y }
|
||||
|
||||
def "!=" [x, y] { $x != $y }
|
||||
|
||||
def "=~" [x, y] { $x =~ $y }
|
||||
|
||||
def "!~" [x, y] { $x !~ $y }
|
||||
|
||||
def array [...rest] { echo $rest }
|
||||
|
||||
54
dot_config/nushell/nu_scripts/sourced/fun/spark.nu
Normal file
54
dot_config/nushell/nu_scripts/sourced/fun/spark.nu
Normal file
@@ -0,0 +1,54 @@
|
||||
let TICKS = [(char -u "2581")
|
||||
(char -u "2582")
|
||||
(char -u "2583")
|
||||
(char -u "2584")
|
||||
(char -u "2585")
|
||||
(char -u "2586")
|
||||
(char -u "2587")
|
||||
(char -u "2588")]
|
||||
|
||||
# send an array into spark and get a sparkline out
|
||||
# let v = [2, 250, 670, 890, 2, 430, 11, 908, 123, 57]
|
||||
# > spark $v
|
||||
# ▁▂▆▇▁▄▁█▁▁
|
||||
|
||||
# create a small sparkline graph
|
||||
def spark [v: list] {
|
||||
let min = ($v | math min)
|
||||
let max = ($v | math max)
|
||||
let ratio = (if $max == $min { 1.0 } else { 7.0 / ($max - $min)})
|
||||
$v | each { |e|
|
||||
let i = ((($e - $min) * $ratio) | math round)
|
||||
$"($TICKS | get $i)"
|
||||
} | str join
|
||||
}
|
||||
|
||||
def assert_eq [num: int, expected: string, input: list] {
|
||||
let actual = (spark2 $input)
|
||||
let span = (metadata $expected).span;
|
||||
if $actual != $expected {
|
||||
error make {
|
||||
msg: "Actual != Expected",
|
||||
label: {
|
||||
text: $"expected ($expected) but got ($actual)", start: $span.start, end: $span.end
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print $"Test ($num) (ansi green)passed(ansi reset) ✓"
|
||||
}
|
||||
}
|
||||
|
||||
def spark2_tests [] {
|
||||
assert_eq 1 "▁" [1.0]
|
||||
assert_eq 2 "▁▁" [1.0, 1.0]
|
||||
assert_eq 3 "▁▁▁▁" [1.0, 1.0, 1.0, 1.0]
|
||||
assert_eq 4 "▁▅▄▇▄█" [1.0, 1.3, 1.2, 1.4, 1.2, 1.5]
|
||||
assert_eq 5 "▁█▅" [-1.0, 1.0, 0.0]
|
||||
assert_eq 6 "▁▂█▅▂" [1.0, 5.0, 22.0, 13.0, 5.0]
|
||||
assert_eq 7 "▁▂▄▅▃█" [0.0, 30.0, 55.0, 80.0, 33.0, 150.0]
|
||||
assert_eq 8 "▁▁▁▁▃▁▁▁▂█" [1.0, 2.0, 3.0, 4.0, 100.0, 5.0, 10.0, 20.0, 50.0, 300.0]
|
||||
assert_eq 9 "▁▄█" [1.0, 50.0, 100.0]
|
||||
assert_eq 10 "▁▄█" [0.1, 5.0, 10.0]
|
||||
assert_eq 11 "▁▃█" [2.0, 4.0, 8.0]
|
||||
# assert_eq 12 "▁█" [2.0, 4.0, 8.0]
|
||||
}
|
||||
96
dot_config/nushell/nu_scripts/sourced/fun/website_builder.nu
Normal file
96
dot_config/nushell/nu_scripts/sourced/fun/website_builder.nu
Normal file
@@ -0,0 +1,96 @@
|
||||
# Converts markdown into their equivalent html pages
|
||||
let $markdown_files = (ls **/*.md)
|
||||
|
||||
for $markdown in $markdown_files {
|
||||
let $contents = (open --raw $markdown.name)
|
||||
|
||||
let $content_lines = ($contents | lines)
|
||||
|
||||
let $first_line = ($content_lines | first | str trim)
|
||||
|
||||
if $first_line == "---" {
|
||||
let $header = ($content_lines
|
||||
| skip 1
|
||||
| take while {|x| ($x | str trim) != "---"}
|
||||
| str join "\n"
|
||||
| from yaml)
|
||||
|
||||
let $post = ($content_lines
|
||||
| skip 1
|
||||
| skip while {|x| ($x | str trim) != "---"}
|
||||
| skip 1)
|
||||
|
||||
print $header
|
||||
|
||||
let $html_post = ($post
|
||||
| each {|line|
|
||||
if ($line | str starts-with "#") {
|
||||
let $line = ($line | str replace "^# (.*)$" "<h1>$1</h1>")
|
||||
let $line = ($line | str replace "^## (.*)$" "<h2>$1</h2>")
|
||||
let $line = ($line | str replace "^### (.*)$" "<h3>$1</h3>")
|
||||
|
||||
$line
|
||||
} else if $line != "" {
|
||||
# Otherwise, it's a paragraph
|
||||
# Convert images
|
||||
let $line = ($line | str replace --all '!\[(.+)\]\((.+)\)' '<img src="$2" alt="$1"/>')
|
||||
let $line = ($line | str replace --all 'src="../assets' 'src="assets')
|
||||
|
||||
# Convert links
|
||||
let $line = ($line | str replace --all '\[(.+?)\]\((.+?)\)' '<a href="$2">$1</a>')
|
||||
|
||||
# Convert code
|
||||
let $line = ($line | str replace --all '`(.+?)`' '<code>$1</code>')
|
||||
$"<p>($line)</p>"
|
||||
}
|
||||
})
|
||||
|
||||
let $html_post = ($html_post | str join "\n")
|
||||
let $html_post = $"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>($header.title)</title>
|
||||
<style>
|
||||
img {
|
||||
max-width: 600px
|
||||
}
|
||||
p {
|
||||
display: block;
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
body {
|
||||
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 16px;
|
||||
color: #2c3e50;
|
||||
line-height: 1.7;
|
||||
max-width: 740px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 2.5rem;
|
||||
}
|
||||
code {
|
||||
color: #476582;
|
||||
padding: .25rem .5rem;
|
||||
margin: 0;
|
||||
font-size: .85em;
|
||||
background-color: #eeeeee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
($html_post)
|
||||
</body>
|
||||
</html>"
|
||||
|
||||
# print $html_post
|
||||
|
||||
let $name = ($markdown.name | path parse | update extension "html" | path join)
|
||||
|
||||
$html_post | save --raw $name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
# Branch Protections
|
||||
|
||||
### Definition
|
||||
|
||||
Do you have hundreds or thousands of GitHub repositories in your organization? Are you tired of manually managing their branch protection rules? Don't! Let nushell do it for you!
|
||||
|
||||
### Setup
|
||||
1. Replace placeholder data in .nu script with your own (or remove the appropriate fields if you don't need to i.e push to repo from action)
|
||||
1. Create a repo in your organization account to store the github action
|
||||
1. Push both the attached script and the github action to the repo
|
||||
### Possible future improvements
|
||||
* Instead of cron run the script on repository creation event (once org level actions become a thing in GitHub)
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env nu
|
||||
let protections = {
|
||||
required_status_checks: {
|
||||
strict: true
|
||||
checks: [
|
||||
{
|
||||
context: 'YOUR CHECK HERE'
|
||||
app_id: 'YOUR APP ID HERE'
|
||||
}
|
||||
]
|
||||
}
|
||||
required_pull_request_reviews: {
|
||||
dismiss_stale_reviews: true
|
||||
require_code_owner_reviews: true
|
||||
bypass_pull_request_allowances: {
|
||||
apps: [
|
||||
YOUR APP HERE
|
||||
]
|
||||
}
|
||||
}
|
||||
restrictions: {
|
||||
users: []
|
||||
teams: []
|
||||
apps: [
|
||||
YOUR APP HERE
|
||||
]
|
||||
}
|
||||
enforce_admins: true
|
||||
required_linear_history: true
|
||||
require_conversation_resolution: true
|
||||
allow_deletions: false
|
||||
allow_force_pushes: false
|
||||
}
|
||||
gh api $"orgs/($env.OWNER)/repos"
|
||||
|from json
|
||||
|select name default_branch
|
||||
|each {|repo|
|
||||
echo $"Setting branch restrictions for ($repo.name)"
|
||||
$protections
|
||||
|to json
|
||||
|gh api -X PUT $"repos/($env.OWNER)/($repo.name)/branches/($repo.default_branch)/protection" --input -
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Add branch protections to all repositories
|
||||
'on':
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: nu {0}
|
||||
|
||||
jobs:
|
||||
set-branch-restrictions:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Nu
|
||||
uses: hustcer/setup-nu@main
|
||||
with:
|
||||
version: '0.64.0'
|
||||
- run: ./branch-protections.nu
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Merged Branches
|
||||
|
||||
### Definition
|
||||
|
||||
Do your developers often forget to delete their branches after merging PRs? Are you tired of manually going into every repository and deleting them? Don't! Let nushell do it for you!
|
||||
|
||||
### Setup
|
||||
1. Create a repo in your organization account to store the github action
|
||||
1. Push both the attached script and the github action to the repo
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env nu
|
||||
gh api $"orgs/($env.OWNER)/repos"
|
||||
|from json
|
||||
|each {|repo|
|
||||
gh api $"repos/($env.OWNER)/($repo.name)/pulls?state=closed"
|
||||
|from json
|
||||
|if ($in|length) > 0 {
|
||||
each {|pull|
|
||||
print $"Removing branch ($pull.head.ref) from repo ($repo.name)"
|
||||
gh api -X DELETE $"repos/($env.OWNER)/($repo.name)/git/refs/heads/($pull.head.ref)"
|
||||
}
|
||||
} else {
|
||||
print $"Repo ($repo.name) has no branches to delete"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Delete merged branches from all repositories
|
||||
'on':
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: nu {0}
|
||||
|
||||
jobs:
|
||||
delete-merged-branches:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Nu
|
||||
uses: hustcer/setup-nu@main
|
||||
with:
|
||||
version: '0.64.0'
|
||||
- run: ./merged-branches.nu
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
13
dot_config/nushell/nu_scripts/sourced/gitlab/README.md
Normal file
13
dot_config/nushell/nu_scripts/sourced/gitlab/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Gitlab Scanner
|
||||
|
||||
### Definition
|
||||
|
||||
I use this script to scan contents of my company's GitLab server. Due to nushell's use of multithreading I'm able to scan around 1k repositories in about 9 seconds
|
||||
|
||||
### Setup
|
||||
1. Generate GitLab Personal Access Token and save it as `GITLAB_TOKEN` environment variable
|
||||
2. Run the script providing necessary data as arguments (or hardcode them in the script if you don't expect them to change often)
|
||||
### Possible future improvements
|
||||
* Multiple files/phrases/branches to search
|
||||
* Maybe create some stats like how many times a given phrase was found in a repo or file
|
||||
* Maybe offer an option to replace a phrase and automatically push the updated file or create a merge request
|
||||
39
dot_config/nushell/nu_scripts/sourced/gitlab/gitlab.nu
Normal file
39
dot_config/nushell/nu_scripts/sourced/gitlab/gitlab.nu
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
let base_url = ""
|
||||
let page_size = 100
|
||||
let projects = $"($base_url)/api/v4/projects/"
|
||||
|
||||
def call-gitlab [
|
||||
...args: string
|
||||
--query: string
|
||||
] {
|
||||
http get -H [Authorization $"Bearer ($env.GITLAB_TOKEN)"] $"($projects)($args|str join)?($query)"
|
||||
}
|
||||
# Search files on your GitLab server
|
||||
def main [
|
||||
--base_url: string # base url of your GitLab instance
|
||||
--file: string # file (or path to file if in a subfolder) you want to scan
|
||||
--phrase: string # phrase you want to search for
|
||||
--branch: string # branch to scan
|
||||
] {
|
||||
# /projects endpoint can return up to $page_size items which is why we need multiple calls to retrieve full list
|
||||
let num_of_pages = ((call-gitlab --query 'page=1&per_page=1&order_by=id&simple=true'|get id.0|into int) / $page_size|math round)
|
||||
seq 1 $num_of_pages|par-each {|page|
|
||||
call-gitlab --query $"page=($page)&per_page=($page_size)"|select name id
|
||||
}
|
||||
|flatten
|
||||
|par-each {|repo|
|
||||
let payload = (call-gitlab $repo.id '/repository/files/' $file --query $"ref=($branch)")
|
||||
if ($payload|columns|find message|is-empty) {
|
||||
$payload
|
||||
|get content
|
||||
|decode base64
|
||||
|lines
|
||||
|find $phrase
|
||||
|if ($in|length) > 0 {
|
||||
echo $"($file) in ($repo.name) repo contains ($phrase) phrase"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
dot_config/nushell/nu_scripts/sourced/imaging/README.md
Normal file
4
dot_config/nushell/nu_scripts/sourced/imaging/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
These nushell scripts are semi-clones of the shell scripts in the same folder. They work with iterm2 on MacOS and maybe other shells.
|
||||
|
||||
- divider.nu will print a thick divider line for us with a nushell hook
|
||||
- imgcat.nu will print a png image to the terminal screen
|
||||
8
dot_config/nushell/nu_scripts/sourced/imaging/divider.nu
Normal file
8
dot_config/nushell/nu_scripts/sourced/imaging/divider.nu
Normal file
@@ -0,0 +1,8 @@
|
||||
def divider [] {
|
||||
let a = "\e]1337;File=inline=1;width=100%%;height=1;preserveAspectRatio=0"
|
||||
let b = ":"
|
||||
# this is just a 1x1 white png image
|
||||
let c = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAABb2lDQ1BpY2MAACiRdZE7SwNBFIW/RIOikRRaiFgsEkVEISiIpcbCJkiICkZtknWTCNl12U0QsRVsLAQL0cZX4T/QVrBVEARFELHyB/hqJKx3jJAgySyz9+PMnMvMGfDH8rrpNkbAtApOYiqqzScXtKZXAoQIMkBPSnftiXg8Rt3xdY9P1bsh1av+vpqjddlwdfA1C4/qtlMQHheOrRVsxdvCHXoutSx8JDzoyAGFr5WeLvOL4myZPxQ7s4lJ8KueWraK01Ws5xxTuF84bOaL+t951E2ChjU3I7VLZjcuCaaIopGmyAp5CgxJtSSz2r7Ir2+aVfHo8rdZxxFHlpx4B0UtSldDakZ0Q7486yr3/3m6mZHhcvdgFALPnvfeC027UNrxvO9jzyudQMMTXFoV/6rkNPYp+k5FCx9CaBPOrypaeg8utqDz0U45qV+pQaY/k4G3M2hLQvsttCyWs/pb5/QBZjfkiW5g/wD6ZH9o6Qf3IWgGVlxmOAAAAANQTFRF////p8QbyAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAAApJREFUCFtjYAAAAAIAAWJAT2gAAAAASUVORK5CYII='
|
||||
let d = "\a"
|
||||
[ $a $b $c $d ] | str join
|
||||
}
|
||||
9
dot_config/nushell/nu_scripts/sourced/imaging/divider.sh
Normal file
9
dot_config/nushell/nu_scripts/sourced/imaging/divider.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: divider file"
|
||||
exit 1
|
||||
fi
|
||||
printf '\033]1337;File=inline=1;width=100%%;height=1;preserveAspectRatio=0'
|
||||
printf ":"
|
||||
base64 < "$1"
|
||||
printf '\a\n'
|
||||
91
dot_config/nushell/nu_scripts/sourced/imaging/imgcat.nu
Normal file
91
dot_config/nushell/nu_scripts/sourced/imaging/imgcat.nu
Normal file
@@ -0,0 +1,91 @@
|
||||
# https://iterm2.com/documentation-images.html
|
||||
|
||||
def print_osc [] {
|
||||
if $env.TERM == screen* {
|
||||
"\ePtmux;\e\e]"
|
||||
} else {
|
||||
"\e]"
|
||||
}
|
||||
}
|
||||
|
||||
def print_st [] {
|
||||
if $env.TERM == screen* {
|
||||
"\a\e\\"
|
||||
} else {
|
||||
"\a"
|
||||
}
|
||||
}
|
||||
|
||||
def --env b64_encode [fn] {
|
||||
open $fn | encode base64
|
||||
}
|
||||
|
||||
def --env b64_decode [fn] {
|
||||
$fn | decode base64
|
||||
}
|
||||
|
||||
def print_image [
|
||||
filename # Filename to convey to client
|
||||
inline # 0 or 1
|
||||
base64contents # Base64-encoded contents
|
||||
print_filename # If non-empty, print the filename before outputting the image
|
||||
] {
|
||||
let a = (print_osc)
|
||||
let b = "1337;File="
|
||||
let c = (if ($filename | length) > 0 {
|
||||
let b64_enc_data = (b64_encode $filename)
|
||||
$"name=($b64_enc_data);"
|
||||
})
|
||||
let b64_dec_data = (b64_decode $base64contents)
|
||||
let d = $"size=($b64_dec_data | bytes length)"
|
||||
let e = $";inline=($inline)"
|
||||
let f = ":"
|
||||
let g = $base64contents
|
||||
let h = print_st
|
||||
let i = "\n"
|
||||
let j = (if ($print_filename | length) > 0 {
|
||||
print -n $filename
|
||||
})
|
||||
|
||||
[ $a $b $c $d $e $f $g $h $i $j ] | str join
|
||||
}
|
||||
|
||||
def error [] {
|
||||
print "Error: ($env.LAST_EXIT_CODE)"
|
||||
}
|
||||
|
||||
def show_help [] {
|
||||
print "Usage: imgcat [-p] filename ..."
|
||||
print " or: cat filename | imgcat"
|
||||
}
|
||||
|
||||
# imgcat.nu shows images in your terminal if your terminal supports it
|
||||
def imgcat [
|
||||
--help(-h) # Help/Usage message
|
||||
--print(-p) # Print filename
|
||||
--url(-u) # Use a URL
|
||||
filename # The filename to show
|
||||
] {
|
||||
if $help {
|
||||
show_help
|
||||
}
|
||||
|
||||
let print_filename = (
|
||||
if $print {
|
||||
1
|
||||
}
|
||||
)
|
||||
|
||||
let url_img = (
|
||||
if $url {
|
||||
let encoded_image = (b64_encode (http get $url))
|
||||
print_image $url 1 $encoded_image $print_filename
|
||||
}
|
||||
)
|
||||
|
||||
if ($filename | path exists) {
|
||||
print_image $filename 1 (b64_encode $filename) $print_filename
|
||||
} else {
|
||||
print $"imgcat: ($filename): No such file or directory"
|
||||
}
|
||||
}
|
||||
157
dot_config/nushell/nu_scripts/sourced/imaging/imgcat.sh
Normal file
157
dot_config/nushell/nu_scripts/sourced/imaging/imgcat.sh
Normal file
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
|
||||
# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
|
||||
# only accepts ESC backslash for ST. We use TERM instead of TMUX because TERM
|
||||
# gets passed through ssh.
|
||||
function print_osc() {
|
||||
if [[ $TERM == screen* ]]; then
|
||||
printf "\033Ptmux;\033\033]"
|
||||
else
|
||||
printf "\033]"
|
||||
fi
|
||||
}
|
||||
|
||||
# More of the tmux workaround described above.
|
||||
function print_st() {
|
||||
if [[ $TERM == screen* ]]; then
|
||||
printf "\a\033\\"
|
||||
else
|
||||
printf "\a"
|
||||
fi
|
||||
}
|
||||
|
||||
function load_version() {
|
||||
if [ -z ${IMGCAT_BASE64_VERSION+x} ]; then
|
||||
IMGCAT_BASE64_VERSION=$(base64 --version 2>&1)
|
||||
export IMGCAT_BASE64_VERSION
|
||||
fi
|
||||
}
|
||||
|
||||
function b64_encode() {
|
||||
load_version
|
||||
if [[ $IMGCAT_BASE64_VERSION =~ GNU ]]; then
|
||||
# Disable line wrap
|
||||
base64 -w0
|
||||
else
|
||||
base64
|
||||
fi
|
||||
}
|
||||
|
||||
function b64_decode() {
|
||||
load_version
|
||||
if [[ $IMGCAT_BASE64_VERSION =~ fourmilab ]]; then
|
||||
BASE64ARG=-d
|
||||
elif [[ $IMGCAT_BASE64_VERSION =~ GNU ]]; then
|
||||
BASE64ARG=-di
|
||||
else
|
||||
BASE64ARG=-D
|
||||
fi
|
||||
base64 $BASE64ARG
|
||||
}
|
||||
|
||||
# print_image filename inline base64contents print_filename
|
||||
# filename: Filename to convey to client
|
||||
# inline: 0 or 1
|
||||
# base64contents: Base64-encoded contents
|
||||
# print_filename: If non-empty, print the filename
|
||||
# before outputting the image
|
||||
function print_image() {
|
||||
print_osc
|
||||
printf '1337;File='
|
||||
if [[ -n $1 ]]; then
|
||||
printf "name=%s;" "$(printf "%s" "$1" | b64_encode)"
|
||||
fi
|
||||
|
||||
printf "%s" "$3" | b64_decode | wc -c | awk '{printf "size=%d",$1}'
|
||||
printf ";inline=%s" "$2"
|
||||
printf ":"
|
||||
printf "%s" "$3"
|
||||
print_st
|
||||
printf '\n'
|
||||
if [[ -n $4 ]]; then
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
function error() {
|
||||
echo "ERROR: $*" 1>&2
|
||||
}
|
||||
|
||||
function show_help() {
|
||||
echo "Usage: imgcat [-p] filename ..." 1>&2
|
||||
echo " or: cat filename | imgcat" 1>&2
|
||||
}
|
||||
|
||||
function check_dependency() {
|
||||
if ! (builtin command -V "$1" >/dev/null 2>&1); then
|
||||
echo "imgcat: missing dependency: can't find $1" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
## Main
|
||||
|
||||
if [ -t 0 ]; then
|
||||
has_stdin=f
|
||||
else
|
||||
has_stdin=t
|
||||
fi
|
||||
|
||||
# Show help if no arguments and no stdin.
|
||||
if [ $has_stdin = f ] && [ $# -eq 0 ]; then
|
||||
show_help
|
||||
exit
|
||||
fi
|
||||
|
||||
check_dependency awk
|
||||
check_dependency base64
|
||||
check_dependency wc
|
||||
|
||||
# Look for command line flags.
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h | --h | --help)
|
||||
show_help
|
||||
exit
|
||||
;;
|
||||
-p | --p | --print)
|
||||
print_filename=1
|
||||
;;
|
||||
-u | --u | --url)
|
||||
check_dependency curl
|
||||
encoded_image=$(curl -s "$2" | b64_encode) || (
|
||||
error "No such file or url $2"
|
||||
exit 2
|
||||
)
|
||||
has_stdin=f
|
||||
print_image "$2" 1 "$encoded_image" "$print_filename"
|
||||
set -- "${@:1:1}" "-u" "${@:3}"
|
||||
if [ "$#" -eq 2 ]; then
|
||||
exit
|
||||
fi
|
||||
;;
|
||||
-*)
|
||||
error "Unknown option flag: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ -r "$1" ]; then
|
||||
has_stdin=f
|
||||
print_image "$1" 1 "$(b64_encode <"$1")" "$print_filename"
|
||||
else
|
||||
error "imgcat: $1: No such file or directory"
|
||||
exit 2
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Read and print stdin
|
||||
if [ $has_stdin = t ]; then
|
||||
print_image "" 1 "$(cat | b64_encode)" ""
|
||||
fi
|
||||
|
||||
exit 0
|
||||
63
dot_config/nushell/nu_scripts/sourced/misc/base64_encode.nu
Normal file
63
dot_config/nushell/nu_scripts/sourced/misc/base64_encode.nu
Normal file
@@ -0,0 +1,63 @@
|
||||
let dictionary = [
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
|
||||
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
|
||||
'5', '6', '7', '8', '9', '+', '/'
|
||||
]
|
||||
|
||||
let padding_char = '='
|
||||
|
||||
def base64_encode [input: string] {
|
||||
mut result = ""
|
||||
mut counter = 0
|
||||
mut left_carry = 0
|
||||
|
||||
if ($input | is-empty) {
|
||||
error make {msg: "input is empty"}
|
||||
}
|
||||
|
||||
for char in ($input | split chars) {
|
||||
let char_bin = ($char | into binary)
|
||||
let char_int = ($char_bin | into int)
|
||||
|
||||
if $counter mod 3 == 0 {
|
||||
let index = ($char_int bit-shr 2)
|
||||
$result += ($dictionary | get $index)
|
||||
$left_carry = ($char_int bit-and 0x3)
|
||||
} else if $counter mod 3 == 1 {
|
||||
let index = (($left_carry bit-shl 4) bit-or ($char_int bit-shr 4))
|
||||
$result += ($dictionary | get $index)
|
||||
$left_carry = ($char_int bit-and 0xF)
|
||||
} else if $counter mod 3 == 2 {
|
||||
mut index = (($left_carry bit-shl 2) bit-or ($char_int bit-shr 6))
|
||||
$result += ($dictionary | get $index)
|
||||
$index = ($char_int bit-and 0x3F)
|
||||
$result += ($dictionary | get $index)
|
||||
}
|
||||
|
||||
$counter += 1
|
||||
}
|
||||
|
||||
if $counter != 0 {
|
||||
if $counter mod 3 == 1 {
|
||||
$result += ($dictionary | get ($left_carry bit-shl 4))
|
||||
$result += $padding_char
|
||||
$result += $padding_char
|
||||
} else if $counter mod 3 == 2 {
|
||||
$result += ($dictionary | get ($left_carry bit-shl 2))
|
||||
$result += $padding_char
|
||||
}
|
||||
}
|
||||
|
||||
$result
|
||||
}
|
||||
|
||||
# Test Cases
|
||||
# base64_encode "nushell", "bnVzaGVsbA=="
|
||||
# base64_encode "hello", "aGVsbG8="
|
||||
# base64_encode "world", "d29ybGQ="
|
||||
# base64_encode "now is the time for all good mean to come to the aid of their country", "bm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBtZWFuIHRvIGNvbWUgdG8gdGhlIGFpZCBvZiB0aGVpciBjb3VudHJ5
|
||||
# base64_encode "crab", "Y3JhYg=="
|
||||
# base64_encode "the brown fox jump over the lazy dog!"), "dGhlIGJyb3duIGZveCBqdW1wIG92ZXIgdGhlIGxhenkgZG9nIQ=="
|
||||
# base64_encode "", error
|
||||
# base64_encode "a", "YQ=="
|
||||
18
dot_config/nushell/nu_scripts/sourced/misc/cmd_stats.nu
Normal file
18
dot_config/nushell/nu_scripts/sourced/misc/cmd_stats.nu
Normal file
@@ -0,0 +1,18 @@
|
||||
export def main [] {
|
||||
let builtin = (scope commands | where type == "built-in" | length)
|
||||
let external = (scope commands | where type == "external" | length)
|
||||
let custom = (scope commands | where type == "custom" | length)
|
||||
let keyword = (scope commands | where type == "keyword" | length)
|
||||
let plugin = (scope commands | where type == "plugin" | length)
|
||||
let total = (scope commands | length)
|
||||
|
||||
[
|
||||
[command_type count];
|
||||
[builtin $builtin]
|
||||
[external $external]
|
||||
[custom $custom]
|
||||
[keyword $keyword]
|
||||
[plugin $plugin]
|
||||
[total_cmds $total]
|
||||
]
|
||||
}
|
||||
513
dot_config/nushell/nu_scripts/sourced/misc/nu_defs.nu
Normal file
513
dot_config/nushell/nu_scripts/sourced/misc/nu_defs.nu
Normal file
@@ -0,0 +1,513 @@
|
||||
#copy current dir
|
||||
def cpwd [] {pwd | tr "\n" " " | sed "s/ //g" | xclip -sel clip}
|
||||
|
||||
#update-upgrade system (ubuntu)
|
||||
def supgrade [] {
|
||||
echo "updating..."
|
||||
sudo aptitude update -y
|
||||
echo "upgrading..."
|
||||
sudo aptitude safe-upgrade -y
|
||||
echo "autoremoving..."
|
||||
sudo apt autoremove -y
|
||||
}
|
||||
|
||||
#open mcomix
|
||||
def mcx [file] {
|
||||
bash -c $'mcomix "($file)" 2>/dev/null &'
|
||||
}
|
||||
|
||||
#open file
|
||||
def openf [file?] {
|
||||
let file = if ($file | is-empty) {$in} else {$file}
|
||||
|
||||
bash -c $'xdg-open "($file)" 2>/dev/null &'
|
||||
}
|
||||
|
||||
#search for specific process
|
||||
def psn [name: string] {
|
||||
ps | find $name
|
||||
}
|
||||
|
||||
#kill specified process in name
|
||||
def killn [name: string] {
|
||||
ps | find $name | each {|| kill -f $in.pid}
|
||||
}
|
||||
|
||||
#jdownloader downloads info (requires a jdown python script)
|
||||
def nujd [] {
|
||||
jdown | lines | each { |line| $line | from nuon } | flatten | flatten
|
||||
}
|
||||
|
||||
# Switch-case like instruction
|
||||
def switch [
|
||||
var #input var to test
|
||||
cases: record #record with all cases
|
||||
#
|
||||
# Example:
|
||||
# let x = 3
|
||||
# switch $x {
|
||||
# 1: { echo "you chose one" },
|
||||
# 2: { echo "you chose two" },
|
||||
# 3: { echo "you chose three" }
|
||||
# }
|
||||
] {
|
||||
echo $cases | get $var | do $in
|
||||
}
|
||||
|
||||
#post to discord
|
||||
def post_to_discord [message] {
|
||||
let content = $"{\"content\": \"($message)\"}"
|
||||
|
||||
let weburl = "webhook_url"
|
||||
|
||||
post $weburl $content --content-type "application/json"
|
||||
}
|
||||
|
||||
#select column of a table (to table)
|
||||
def column [n] {
|
||||
transpose | select $n | transpose | select column1 | headers
|
||||
}
|
||||
|
||||
#get column of a table (to list)
|
||||
def column2 [n] {
|
||||
transpose | get $n | transpose | get column1 | skip 1
|
||||
}
|
||||
|
||||
#short pwd
|
||||
def pwd-short [] {
|
||||
$env.PWD | str replace $nu.home-path '~'
|
||||
}
|
||||
|
||||
#string repeat
|
||||
def "str repeat" [count: int] {
|
||||
each {|it| let str = $it; echo 1..$count | each {|| echo $str } }
|
||||
}
|
||||
|
||||
#join 2 lists
|
||||
def union [a: list, b: list] {
|
||||
$a | append $b | uniq
|
||||
}
|
||||
|
||||
#nushell source files info
|
||||
def 'nu-sloc' [] {
|
||||
let stats = (
|
||||
ls **/*.nu
|
||||
| select name
|
||||
| insert lines { |it| open $it.name | str stats | get lines }
|
||||
| insert blank {|s| $s.lines - (open $s.name | lines | find --regex '\S' | length) }
|
||||
| insert comments {|s| open $s.name | lines | find --regex '^\s*#' | length }
|
||||
| sort-by lines -r
|
||||
)
|
||||
|
||||
let lines = ($stats | reduce -f 0 {|it, acc| $it.lines + $acc })
|
||||
let blank = ($stats | reduce -f 0 {|it, acc| $it.blank + $acc })
|
||||
let comments = ($stats | reduce -f 0 {|it, acc| $it.comments + $acc })
|
||||
let total = ($stats | length)
|
||||
let avg = ($lines / $total | math round)
|
||||
|
||||
$'(char nl)(ansi pr) SLOC Summary for Nushell (ansi reset)(char nl)'
|
||||
print { 'Total Lines': $lines, 'Blank Lines': $blank, Comments: $comments, 'Total Nu Scripts': $total, 'Avg Lines/Script': $avg }
|
||||
$'(char nl)Source file stat detail:'
|
||||
print $stats
|
||||
}
|
||||
|
||||
#go to dir (via pipe)
|
||||
def --env goto [] {
|
||||
let input = $in
|
||||
cd (
|
||||
if ($input | path type) == file {
|
||||
($input | path dirname)
|
||||
} else {
|
||||
$input
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#go to custom bash bin path, must be added last in config.nu
|
||||
def --env goto-bash [] {
|
||||
cd ($env.PATH | last)
|
||||
}
|
||||
|
||||
#cd to the folder where a binary is located
|
||||
def --env which-cd [program] {
|
||||
let dir = (which $program | get path | path dirname | str trim)
|
||||
cd $dir.0
|
||||
}
|
||||
|
||||
#push to git
|
||||
def git-push [m: string] {
|
||||
git add -A
|
||||
git status
|
||||
git commit -a -m $"($m)"
|
||||
git push origin main
|
||||
}
|
||||
|
||||
#get help for custom commands
|
||||
def "help my-commands" [] {
|
||||
help commands | where is_custom == true
|
||||
}
|
||||
|
||||
#web search in terminal (requires ddgr)
|
||||
def gg [...search: string] {
|
||||
ddgr -n 5 ($search | str join ' ')
|
||||
}
|
||||
|
||||
#habitipy dailies done all (requires habitipy)
|
||||
def hab-dailies-done [] {
|
||||
let to_do = (habitipy dailies | grep ✖ | awk {print $1} | tr '.\n' ' ' | split row ' ' | into int)
|
||||
habitipy dailies done $to_do
|
||||
}
|
||||
|
||||
#update aliases backup file from config.nu
|
||||
def update-aliases [] {
|
||||
let nlines = (open $nu.config-path | lines | length)
|
||||
|
||||
let from = ((grep "## aliases" $nu.config-path -n | split row ':').0 | into int)
|
||||
|
||||
open $nu.config-path | lines | last ($nlines - $from + 1) | save /path/to/backup/file.nu
|
||||
}
|
||||
|
||||
#update config.nu from aliases backup
|
||||
def update-config [] {
|
||||
let from = ((grep "## aliases" $nu.config-path -n | split row ':').0 | into int)
|
||||
let aliases = "/path/to/backup/file.nu"
|
||||
|
||||
open $nu.config-path | lines | first ($from - 1) | append (open $aliases | lines) | save temp.nu
|
||||
mv temp.nu $nu.config-path
|
||||
}
|
||||
|
||||
#countdown alarm (requires termdown y mpv)
|
||||
def countdown [
|
||||
n: int # time in seconds
|
||||
] {
|
||||
let BEEP = "/path/to/sound/file"
|
||||
let muted = (pacmd list-sinks | awk '/muted/ { print $2 }' | tr '\n' ' ' | split row ' ' | last)
|
||||
|
||||
if $muted == 'no' {
|
||||
termdown $n;mpv --no-terminal $BEEP
|
||||
} else {
|
||||
termdown $n
|
||||
unmute
|
||||
mpv --no-terminal $BEEP
|
||||
mute
|
||||
}
|
||||
}
|
||||
|
||||
#get aliases
|
||||
def get-aliases [] {
|
||||
open $nu.config-path | lines | find alias | find -v aliases | split column '=' | select column1 column2 | rename Alias Command | update Alias {|f| $f.Alias | split row ' ' | last} | sort-by Alias
|
||||
}
|
||||
|
||||
#compress every subfolder into separate files and delete them
|
||||
def `7zfolders` [] {
|
||||
^find . -maxdepth 1 -mindepth 1 -type d -print0 | parallel -0 --eta 7z a -t7z -sdel -bso0 -bsp0 -m0=lzma2 -mx=9 -ms=on -mmt=on {}.7z {}
|
||||
}
|
||||
|
||||
#compress to 7z using max compression
|
||||
def `7zmax` [
|
||||
filename: string #filename without extension
|
||||
...rest: string #files to compress and extra flags for 7z (add flags between quotes)
|
||||
#
|
||||
# Example:
|
||||
# compress all files in current directory and delete them
|
||||
# 7zmax * "-sdel"
|
||||
] {
|
||||
|
||||
if ($rest | is-empty) {
|
||||
echo "no files to compress specified"
|
||||
} else {
|
||||
7z a -t7z -m0=lzma2 -mx=9 -ms=on -mmt=on $"($filename).7z" $rest
|
||||
}
|
||||
}
|
||||
|
||||
#add event to google calendar, also usable without arguments (requires gcalcli)
|
||||
def addtogcal [
|
||||
calendar? #to which calendar add event
|
||||
title? #event title
|
||||
when? #date: yyyy.MM.dd hh:mm
|
||||
where? #location
|
||||
duration? #duration in minutes
|
||||
] {
|
||||
|
||||
let calendar = if $calendar == null {echo $"calendar: ";input } else {$calendar}
|
||||
let title = if $title == null {echo $"\ntitle: ";input } else {$title}
|
||||
let when = if $when == null {echo $"\nwhen: ";input } else {$when}
|
||||
let where = if $where == null {echo $"\nwhere: ";input } else {$where}
|
||||
let duration = if $duration == null {echo $"\nduration: ";input } else {$duration}
|
||||
|
||||
gcalcli --calendar $"($calendar)" add --title $"($title)" --when $"($when)" --where $"($where)" --duration $"($duration)" --default-reminders
|
||||
}
|
||||
|
||||
#show gcal agenda in selected calendars
|
||||
def agenda [
|
||||
--full: int #show all calendars (default: 0)
|
||||
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||
#
|
||||
# Examples
|
||||
# agenda
|
||||
# agenda --full true
|
||||
# agenda "--details=all"
|
||||
# agenda --full true "--details=all"
|
||||
] {
|
||||
let calendars = "your_selected_calendars"
|
||||
let calendars_full = "most_calendars"
|
||||
|
||||
if ($full | is-empty) or ($full == 0) {
|
||||
gcalcli --calendar $"($calendars)" agenda --military $rest
|
||||
} else {
|
||||
gcalcli --calendar $"($calendars_full)" agenda --military $rest
|
||||
}
|
||||
}
|
||||
|
||||
#show gcal week in selected calendards
|
||||
def semana [
|
||||
--full: int #show all calendars (default: 0)
|
||||
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||
#
|
||||
# Examples
|
||||
# semana
|
||||
# semana --full true
|
||||
# semana "--details=all"
|
||||
# semana --full true "--details=all"
|
||||
] {
|
||||
let calendars = "your_selected_calendars"
|
||||
let calendars_full = "most_calendars"
|
||||
|
||||
if ($full | is-empty) or ($full == 0) {
|
||||
gcalcli --calendar $"($calendars)" calw $rest --military --monday
|
||||
} else {
|
||||
gcalcli --calendar $"($calendars_full)" calw $rest --military --monday
|
||||
}
|
||||
}
|
||||
|
||||
#show gcal month in selected calendards
|
||||
def mes [
|
||||
--full: int #show all calendars (default: 0)
|
||||
...rest #extra flags for gcalcli between quotes (specified full needed)
|
||||
#
|
||||
# Examples
|
||||
# mes
|
||||
# mes --full true
|
||||
# mes "--details=all"
|
||||
# mes --full true "--details=all"
|
||||
] {
|
||||
let calendars = "your_selected_calendars"
|
||||
let calendars_full = "most_calendars"
|
||||
|
||||
if ($full | is-empty) or ($full == 0) {
|
||||
gcalcli --calendar $"($calendars)" calm $rest --military --monday
|
||||
} else {
|
||||
gcalcli --calendar $"($calendars_full)" calm $rest --military --monday
|
||||
}
|
||||
}
|
||||
|
||||
#get bitly short link (requires xclip)
|
||||
def mbitly [longurl] {
|
||||
if ($longurl | is-empty) {
|
||||
echo "no url provided"
|
||||
} else {
|
||||
let Accesstoken = "Token"
|
||||
let username = "user"
|
||||
let url = $"https://api-ssl.bitly.com/v3/shorten?access_token=($Accesstoken)&login=($username)&longUrl=($longurl)"
|
||||
|
||||
let shorturl = (http get $url | get data | get url)
|
||||
|
||||
$shorturl
|
||||
$shorturl | xclip -sel clip
|
||||
}
|
||||
}
|
||||
|
||||
#translate text using mymemmory api
|
||||
def trans [
|
||||
...search:string #search query]
|
||||
--from:string #from which language you are translating (default english)
|
||||
--to:string #to which language you are translating (default spanish)
|
||||
#
|
||||
#Use ISO standard names for the languages, for example:
|
||||
#english: en-US
|
||||
#spanish: es-ES
|
||||
#italian: it-IT
|
||||
#swedish: sv-SV
|
||||
#
|
||||
#More in: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
] {
|
||||
|
||||
if ($search | is-empty) {
|
||||
echo "no search query provided"
|
||||
} else {
|
||||
let key = "api_kei"
|
||||
let user = "user_email"
|
||||
|
||||
let from = if ($from | is-empty) {"en-US"} else {$from}
|
||||
let to = if ($to | is-empty) {"es-ES"} else {$to}
|
||||
|
||||
let to_translate = ($search | str join "%20")
|
||||
|
||||
let url = $"https://api.mymemory.translated.net/get?q=($to_translate)&langpair=($from)%7C($to)&of=json&key=($key)&de=($user)"
|
||||
|
||||
http get $url | get responseData | get translatedText
|
||||
}
|
||||
}
|
||||
|
||||
#check if drive is mounted
|
||||
def is-mounted [drive:string] {
|
||||
let count = (ls "~/media" | find $"($drive)" | length)
|
||||
|
||||
if $count == 0 {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#get phone number from google contacts (requires goobook)
|
||||
def get-phone-number [search:string] {
|
||||
goobook dquery $search | from ssv | rename results | where results =~ '(?P<plus>\+)(?P<nums>\d+)'
|
||||
}
|
||||
|
||||
#ping with plot (requires ttyplot)
|
||||
def nu-png-plot [] {
|
||||
bash -c "ping 1.1.1.1 | sed -u 's/^.*time=//g; s/ ms//g' | ttyplot -t \'ping to 1.1.1.1\' -u ms"
|
||||
}
|
||||
|
||||
#plot download-upload speed (requires ttyplot and fast-cli)
|
||||
def nu-downup-plot [] {
|
||||
bash -c "fast --single-line --upload | stdbuf -o0 awk '{print $2 \" \" $6}' | ttyplot -2 -t 'Download/Upload speed' -u Mbps"
|
||||
}
|
||||
|
||||
#plot data table using gnuplot
|
||||
def gnu-plot [
|
||||
data? #1 or 2 column table
|
||||
--title:string #title
|
||||
#
|
||||
#Example: If $x is a table with 2 columns
|
||||
#$x | gnu-plot
|
||||
#($x | column 0) | gnu-plot
|
||||
#($x | column 1) | gnu-plot
|
||||
#($x | column 0) | gnu-plot --title "My Title"
|
||||
#gnu-plot $x --title "My Title"
|
||||
] {
|
||||
let x = if ($data | is-empty) {$in} else {$data}
|
||||
let n_cols = ($x | transpose | length)
|
||||
let name_cols = ($x | transpose | column2 0)
|
||||
|
||||
let ylabel = if $n_cols == 1 {$name_cols | get 0} else {$name_cols | get 1}
|
||||
let xlabel = if $n_cols == 1 {""} else {$name_cols | get 0}
|
||||
|
||||
let title = if ($title | is-empty) {if $n_cols == 1 {$ylabel | str upcase} else {$"($ylabel) vs ($xlabel)"}} else {$title}
|
||||
|
||||
$x | to tsv | save data0.txt
|
||||
sed 1d data0.txt | save data.txt
|
||||
|
||||
gnuplot -e $"set terminal dumb; unset key;set title '($title)';plot 'data.txt' w l lt 0;"
|
||||
|
||||
rm data*.txt | ignore
|
||||
}
|
||||
|
||||
# date string YYYY-MM-DD
|
||||
def ymd [] {
|
||||
(date now | format date %Y-%m-%d)
|
||||
}
|
||||
|
||||
# date string DD-MM-YYYY
|
||||
def dmy [] {
|
||||
(date now | format date %d-%m-%Y)
|
||||
}
|
||||
|
||||
# create directory and cd into it.
|
||||
def --env md [dir] {
|
||||
mkdir $dir
|
||||
cd $dir
|
||||
}
|
||||
|
||||
# Fuzzy finds a value in a newline-separated-string or a list, using an
|
||||
# optional preview. If the string or the list contains only one item,
|
||||
# it is returned immediately.
|
||||
# Requires the external binary 'skim'.
|
||||
#
|
||||
# Examples:
|
||||
# > "a\nb\n" | skim
|
||||
# > ls | get name | skim --preview 'ls --color {}'
|
||||
def skim [
|
||||
--preview (-p) = '' # command to use for the sk preview
|
||||
] {
|
||||
let lst = $in
|
||||
let type = ($lst | describe)
|
||||
let s = (if ($type | str starts-with 'list<') {
|
||||
$lst | str join (char nl)
|
||||
} else if ($type == 'string') {
|
||||
$lst
|
||||
})
|
||||
if ($s | is-empty) {
|
||||
null
|
||||
} else {
|
||||
if ($preview | is-empty ) {
|
||||
($s
|
||||
| sk
|
||||
--layout reverse
|
||||
--preview-window down:65%
|
||||
--select-1
|
||||
| str trim)
|
||||
} else {
|
||||
($s
|
||||
| sk
|
||||
--layout reverse
|
||||
--preview-window down:65%
|
||||
--select-1
|
||||
--preview $preview
|
||||
| str trim)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Group list values that match the next-group regex.
|
||||
# This function is a useful helper to quick and dirty parse data
|
||||
# that contains line-wise a 'header', followed by a variable number
|
||||
# of data entries. The return value is a table of header-keys with
|
||||
# a list of values in the second column. Values before a header-key
|
||||
# and header-keys without values are ignored.
|
||||
#
|
||||
# Example:
|
||||
# [id_a 1 2 id_b 3] | group-list '^id_'
|
||||
def group-list [
|
||||
regex # on match, a new group is created
|
||||
] {
|
||||
let lst = $in
|
||||
def make-group [v, buf, ret, key] {
|
||||
let new_group = ($'($v)' =~ $regex)
|
||||
if $new_group {
|
||||
let is_key = (not ($key | is-empty))
|
||||
let is_buf = (not ($buf | is-empty))
|
||||
if ($is_buf and $is_key) {
|
||||
let ret = ($ret | append {key: $key, values: $buf})
|
||||
{buf: [], ret: $ret, key: $v}
|
||||
} else {
|
||||
{buf: [], ret: $ret, key: $v}
|
||||
}
|
||||
} else {
|
||||
let buf = ($buf | append $v)
|
||||
{buf: $buf, ret: $ret, key: $key}
|
||||
}
|
||||
}
|
||||
def loop [lst, buf=[], ret=[], key=''] {
|
||||
if ($lst | is-empty) {
|
||||
{ret: $ret, buf: $buf, key: $key}
|
||||
} else {
|
||||
let v = ($lst | first)
|
||||
let obj = (make-group $v $buf $ret $key)
|
||||
let rest = ($lst | skip)
|
||||
loop $rest $obj.buf $obj.ret $obj.key
|
||||
}
|
||||
}
|
||||
let obj = (loop $lst)
|
||||
let ret = $obj.ret
|
||||
let buf = $obj.buf
|
||||
let key = $obj.key
|
||||
let is_key = (not ($key | is-empty))
|
||||
let is_buf = (not ($buf | is-empty))
|
||||
if ($is_buf and $is_key) {
|
||||
$ret | append {key: $key, values: $buf}
|
||||
} else {
|
||||
$ret
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
# Nushell Password Generator "nupass"
|
||||
|
||||
This nushell command randomly retrieves a specified number of words from a dictionary file (English with Japanese words added by @rickcogley) less than or equal to a given parameter's length, formats the words randomly with capitalization, then separates the words with some random symbols and numbers to return a password.
|
||||
|
||||
To use:
|
||||
|
||||
1. Get the dictionary file to your system using nushell's `http`:
|
||||
|
||||
```
|
||||
http get https://raw.githubusercontent.com/RickCogley/jpassgen/master/genpass-dict-jp.txt | save genpass-dict-jp
|
||||
```
|
||||
|
||||
...which has also been included in this folder for convenience.
|
||||
|
||||
2. Confirm your `$env.NU_LIB_DIRS` location, and copy the below script `2. nupass.nu` there as `nupass.nu`.
|
||||
3. Set the script as executable like `chmod +x nupass.nu`
|
||||
4. Specify the dictionary file's location in the script:
|
||||
|
||||
```
|
||||
let dictfile = $"/path/to/my/genpass-dict-jp"
|
||||
```
|
||||
|
||||
5. In the main function's flags section, confirm and edit the default symbols list, diceware delimiter and threads for par-each (double the number of your CPU cores seems to be a good sweet spot):
|
||||
|
||||
```
|
||||
--symbols (-s): string = "!@#$%^&()_-+[]{}" # Symbols to use in password
|
||||
--delimiter (-m): string = "-" # Delimiter for diceware
|
||||
--threads (-t): int = 16 # Number of threads to use in par-each
|
||||
```
|
||||
|
||||
6. Load the script with `use` in your `config.nu`, something like:
|
||||
|
||||
```
|
||||
use nupass.nu
|
||||
```
|
||||
|
||||
(you can specify the path as `use /path/to/nupass.nu` if you're not taking advantage of `$env.NU_LIB_DIRS`)
|
||||
|
||||
Reload nu, then run it to test:
|
||||
|
||||
```
|
||||
nupass -h
|
||||
nupass 5
|
||||
nupass 6 --debug
|
||||
nupass 8 -v diceware
|
||||
nupass 8 -v diceware -m _
|
||||
nupass 4 -v mixnmatch
|
||||
nupass 6 -v alphanum
|
||||
nupass 5 -l 8
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
If you're making changes to the script while testing, you can just re-source the script by doing:
|
||||
|
||||
`use nupass.nu`
|
||||
|
||||
... which will reload the latest you have saved.
|
||||
|
||||
From `nu` version 0.79.1, you can use the standard library, and use its bench command to do a benchmark. Load the standard library by adding `use std` in your `env.nu`, reload, then assuming `nupass.nu` is in your path, you can benchmark like so:
|
||||
|
||||
```
|
||||
std bench --rounds 10 --verbose {nupass 10}
|
||||
std bench --rounds 10 --verbose {nupass 100 -v diceware}
|
||||
std bench --rounds 10 --verbose {nupass 1000 -v mixnmatch}
|
||||
```
|
||||
|
||||
If you change the `par-each` to `each` in the main list builders for instance, you'll see a significant performance hit. When I benchmarked `nupass 100`, using just `each` took 7 sec per round, whereas changing to `par-each` dropped that to about 1 sec per round.
|
||||
|
||||
You can tweak it a little further by setting the threads for par-each.
|
||||
|
||||
```
|
||||
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 8}
|
||||
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 16}
|
||||
std bench --rounds 10 --verbose {nupass 100 -v diceware -t 32}
|
||||
```
|
||||
|
||||
<img width="736" alt="image" src="https://user-images.githubusercontent.com/512328/235553238-48b48f37-0eae-48d3-8afe-e17515cd8325.png">
|
||||
|
||||
### Caveats
|
||||
|
||||
I've been scripting for quite a long time, but not in nu. Input appreciated to make this more nu-esque! The script is in a decent place as of the 20230501 version.
|
||||
|
||||
Obviously you can just use the `random chars` or `random integers` commands but I like to have words I can read in my passwords, and I think those generated by this script have sufficient entropy.
|
||||
|
||||
This command doesn't let you specify a precise length.
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
Thanks everyone on Discord for putting up with and answering my nubie questions @amtoine, @fdncred, @jelle, @sygmei, @kubouch and for the feedback after try number 1.
|
||||
|
||||
<img width="576" alt="image" src="https://user-images.githubusercontent.com/512328/235383307-d3f3d65d-c184-4dfa-9fe9-677b677d8531.png">
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,120 @@
|
||||
# Script to generate a password from a dictionary file
|
||||
# Author: @rickcogley
|
||||
# Thanks: @amtoine, @fdncred, @jelle, @sygmei, @kubouch
|
||||
# Updates: 20230415 - initial version
|
||||
# 20230416 - add @amtoine's slick probabilistic "random decimal" char capitalization
|
||||
# 20230417 - add script duration output in debug block
|
||||
# 20230421 - add length of symbol chars to get-random-symbol function
|
||||
# 20230422 - add variant flag to generate different styles of passwords
|
||||
# 20230501 - refactor to allow number of words to be specified, use list manipulation and reduce to string
|
||||
# 20230502 - improve performance on list builders with par-each
|
||||
# 20230503 - add threads flag for fine tuning par-each
|
||||
|
||||
#======= NUPASS PASSWORD GENERATOR =======
|
||||
# Generate password of 3 dictionary file words, numbers and symbols
|
||||
export def main [
|
||||
words: int = 3 # Number of words in password
|
||||
--word_length (-l): int = 5 # Max length of words in password
|
||||
--symbols (-s): string = "!@#$%^&()_-+[]{}" # Symbols to use in password
|
||||
--variant (-v): string = "regular" # Password style to generate in regular, mixnmatch, alphanum, alpha, diceware
|
||||
--delimiter (-m): string = "-" # Delimiter for diceware
|
||||
--threads (-t): int = 16 # Number of threads to use in par-each
|
||||
--debug (-d) # Include debug info
|
||||
] {
|
||||
##### Main function #####
|
||||
# Get dictionary file:
|
||||
# http get https://raw.githubusercontent.com/RickCogley/jpassgen/master/genpass-dict-jp.txt | save genpass-dict-jp
|
||||
# Set the path:
|
||||
let dictfile = $"/usr/local/bin/genpass-dict-jp"
|
||||
let starttime = (date now)
|
||||
|
||||
# Find number of lines with strings less than or equal to the supplied length
|
||||
let num_lines = (open ($dictfile) | lines | wrap word | upsert len {|it| $it.word | split chars | length} | where len <= ($word_length) | length)
|
||||
|
||||
# Get random words from dictionary file
|
||||
let random_words = (1..$words | par-each { |i| $dictfile | get-random-word $word_length $num_lines | random-format-word } --threads $threads)
|
||||
|
||||
# Get some symbols to sprinkle like salt bae
|
||||
# Update default symbol chars in symbols flag
|
||||
let symbols_len = ($symbols | str length)
|
||||
let random_symbols = (1..$words | par-each { |i| $symbols | get-random-symbol $symbols $symbols_len } --threads $threads)
|
||||
|
||||
# Get some random numbers
|
||||
let random_numbers = (1..$words | par-each { |i| (random int 0..99) } --threads $threads)
|
||||
|
||||
# Print some vars if debug flag is set
|
||||
if $debug {
|
||||
print $"(ansi bg_red) ====== DEBUG INFO ====== (ansi reset)"
|
||||
print $"(ansi bg_blue) 🔔 Number of lines in dict with words under ($word_length) chars: (ansi reset)"
|
||||
print $num_lines
|
||||
print $"(ansi bg_blue) 🔔 Words from randomly selected lines: (ansi reset)"
|
||||
print $random_words
|
||||
print $"(ansi bg_blue) 🔔 Randomly selected symbols: (ansi reset)"
|
||||
print $random_symbols
|
||||
print $"(ansi bg_blue) 🔔 Randomly selected numbers: (ansi reset)"
|
||||
print $random_numbers
|
||||
let endtime = (date now)
|
||||
print $"(ansi bg_green) 🔔 Generated password in ($endtime - $starttime): (ansi reset)"
|
||||
}
|
||||
|
||||
# Return password in selected variant
|
||||
if $variant == "regular" {
|
||||
# Default variant, with regular distribution
|
||||
# Generate new list w symbol, words, numbers, then reduce to string
|
||||
return (0..($words - 1) | each { |it| ($random_symbols | get $it) + ($random_words | get $it) + ($random_numbers | get $it | into string) } | reduce { |it, acc| $acc + $it })
|
||||
|
||||
} else if $variant == "mixnmatch" {
|
||||
# Combine lists, shuffle randomly, reduce to string
|
||||
return (($random_words ++ $random_symbols ++ $random_numbers | shuffle) | reduce { |it, acc| ($acc | into string) + ($it | into string) })
|
||||
} else if $variant == "alphanum" {
|
||||
# Combined random int and random word, reduce to string
|
||||
return (0..($words - 1) | each { |it| (random int 0..99 | into string) + ($random_words | get $it) } | reduce { |it, acc| $acc + $it })
|
||||
} else if $variant == "alpha" {
|
||||
# Reduce random words only to string
|
||||
return ($random_words | reduce { |it, acc| $acc + $it })
|
||||
} else if $variant == "diceware" {
|
||||
# Reduce to string with hyphen between words
|
||||
return ($random_words | reduce { |it, acc| $acc + $"($delimiter)($it)" })
|
||||
}
|
||||
}
|
||||
|
||||
##### Utility functions #####
|
||||
# Function to get random word from a dictionary file
|
||||
def get-random-word [
|
||||
wordlength: int
|
||||
numlines: int
|
||||
] {
|
||||
open
|
||||
| lines
|
||||
| wrap word
|
||||
| upsert len {|it| $it.word | str length}
|
||||
| where len <= ($wordlength)
|
||||
| get (random int 1..($numlines))
|
||||
| get word
|
||||
}
|
||||
|
||||
# Function to format a word randomly
|
||||
def random-format-word [] {
|
||||
par-each {|it|
|
||||
let rint = (random int 1..4)
|
||||
if $rint == 1 {
|
||||
($it | str capitalize)
|
||||
} else if $rint == 2 {
|
||||
($it | str upcase)
|
||||
} else if $rint == 3 {
|
||||
($it | split chars | each {|c| if (random float) < 0.2 { $c | str upcase } else { $c }} | str join "")
|
||||
} else {
|
||||
($it | str downcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Function to get random symbol from list of symbols
|
||||
def get-random-symbol [
|
||||
symbolchars: string
|
||||
symbolcharslen: int
|
||||
] {
|
||||
$symbolchars
|
||||
| split chars
|
||||
| get (random int 0..($symbolcharslen - 1))
|
||||
}
|
||||
52
dot_config/nushell/nu_scripts/sourced/misc/table_grouping.nu
Normal file
52
dot_config/nushell/nu_scripts/sourced/misc/table_grouping.nu
Normal file
@@ -0,0 +1,52 @@
|
||||
let table = (echo [
|
||||
[url user_login title];
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3382 ammkrn 'Dont unwrap rustyline helper in cli']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3379 jonathandturner 'Simplify down to one type of context']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3377 kubouch 'Port range to engine-p']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3375 fdncred 'added check for endian-ness, added a bytes and skip']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3374 fdncred 'added ability to change ']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3370 fdncred 'add nu-pretty-hex, add into binary, update binaryview']
|
||||
[https://api.github.com/repos/nushell/nushell/issues/3367 fdncred 'tweaked the error handling to show specific errors']
|
||||
])
|
||||
|
||||
# Show what the table looks like
|
||||
print $"This is an example table (char nl)"
|
||||
print $table
|
||||
|
||||
print $"This is markdown created from the example table (char nl)"
|
||||
# Now show what the table in Markdown looks like
|
||||
print $"## Nushell(char nl)(char nl)"
|
||||
print ($table | group-by user_login | transpose user prs | each { |row|
|
||||
let user_name = $row.user
|
||||
let pr_count = (echo $row.prs | length)
|
||||
|
||||
# only print the comma if there's another item
|
||||
let user_prs = ($row.prs | enumerate | each { |pr|
|
||||
if $pr_count == ($pr.index + 1) {
|
||||
echo $'[($pr.item.title)](char lp)($pr.item.url)(char rp)'
|
||||
} else {
|
||||
echo $'[($pr.item.title)](char lp)($pr.item.url)(char rp), and '
|
||||
}
|
||||
} | str join)
|
||||
|
||||
echo $"- ($user_name) created ($user_prs) (char nl)"
|
||||
|
||||
} | str join)
|
||||
|
||||
# ╭───┬──────────────────────────────────────────────────────────┬─────────────────┬───────────────────────────────────────────────────────╮
|
||||
# │ # │ url │ user_login │ title │
|
||||
# ├───┼──────────────────────────────────────────────────────────┼─────────────────┼───────────────────────────────────────────────────────┤
|
||||
# │ 0 │ https://api.github.com/repos/nushell/nushell/issues/3382 │ ammkrn │ Dont unwrap rustyline helper in cli │
|
||||
# │ 1 │ https://api.github.com/repos/nushell/nushell/issues/3379 │ jonathandturner │ Simplify down to one type of context │
|
||||
# │ 2 │ https://api.github.com/repos/nushell/nushell/issues/3377 │ kubouch │ Port range to engine-p │
|
||||
# │ 3 │ https://api.github.com/repos/nushell/nushell/issues/3375 │ fdncred │ added check for endian-ness, added a bytes and skip │
|
||||
# │ 4 │ https://api.github.com/repos/nushell/nushell/issues/3374 │ fdncred │ added ability to change "#" color using header_color │
|
||||
# │ 5 │ https://api.github.com/repos/nushell/nushell/issues/3370 │ fdncred │ add nu-pretty-hex, add into binary, update binaryview │
|
||||
# │ 6 │ https://api.github.com/repos/nushell/nushell/issues/3367 │ fdncred │ tweaked the error handling to show specific errors │
|
||||
# ╰───┴──────────────────────────────────────────────────────────┴─────────────────┴───────────────────────────────────────────────────────╯
|
||||
|
||||
def log [message:any] {
|
||||
let now = (date now | format date '%Y%m%d_%H%M%S.%f')
|
||||
let mess = ([$now '|DBG|' $message (char newline)] | str join)
|
||||
echo $mess
|
||||
}
|
||||
5
dot_config/nushell/nu_scripts/sourced/nu_101/README.md
Normal file
5
dot_config/nushell/nu_scripts/sourced/nu_101/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Nu_101 Scripts
|
||||
|
||||
### Definition
|
||||
|
||||
These scripts should be used to demonstrate to the beginner how nushell scripting works. Perhaps how it's different from Windows `batch` files and `bash` shell scripts. Also, to show off how nushell pipes commands in and out of one another.
|
||||
46
dot_config/nushell/nu_scripts/sourced/nu_101/broken.nu
Normal file
46
dot_config/nushell/nu_scripts/sourced/nu_101/broken.nu
Normal file
@@ -0,0 +1,46 @@
|
||||
### These examples are here to show the user
|
||||
### How the parser works by showing examples that will not parse
|
||||
### The beginning nushell script writer / user may get confused
|
||||
### as to why their script is not working
|
||||
###
|
||||
### If you uncomment any of the defs below these are
|
||||
### the error messages you will see
|
||||
#
|
||||
#
|
||||
#
|
||||
### Examples p1 - p3 below elucidate the following idea:
|
||||
### That a brace has to be on the same line as the def
|
||||
###
|
||||
###
|
||||
### Error: nu::parser::missing_positional
|
||||
### The error message is: "Missing required positional argument"
|
||||
### missing block
|
||||
###
|
||||
### help: Usage: def <def_name> <params> <block>
|
||||
###
|
||||
#
|
||||
### https://github.com/nushell/nushell/issues/2972
|
||||
#
|
||||
### All of these examples will not parse.
|
||||
|
||||
### def p1 [arg]
|
||||
### { echo $arg }
|
||||
|
||||
### def p2 [arg]
|
||||
### {
|
||||
### echo $arg }
|
||||
|
||||
### def p3 [arg]
|
||||
### {
|
||||
### echo $arg
|
||||
### }
|
||||
|
||||
### This breaks because you need a space between
|
||||
### between foo and the left bracket
|
||||
### def foo[] {
|
||||
### "bar"
|
||||
### }
|
||||
### This works
|
||||
### def foo [] {
|
||||
### "bar"
|
||||
### }
|
||||
5
dot_config/nushell/nu_scripts/sourced/nu_101/demo.nu
Normal file
5
dot_config/nushell/nu_scripts/sourced/nu_101/demo.nu
Normal file
@@ -0,0 +1,5 @@
|
||||
def my-ls [x] {
|
||||
ls $x | where size > 10kb
|
||||
}
|
||||
|
||||
my-ls .
|
||||
@@ -0,0 +1,98 @@
|
||||
# Some examples of how you can use nushell commands to treat lists like other data structures and perform equivalent data structure operations on them.
|
||||
|
||||
## Queue (first in, first out [FIFO])
|
||||
|
||||
let queue = [1 2 3]
|
||||
|
||||
let elem = 4
|
||||
|
||||
### Enqueue (push)
|
||||
|
||||
$queue | append $elem
|
||||
|
||||
### Dequeue (shift)
|
||||
|
||||
{ out: ($queue | first),
|
||||
new_queue: ($queue | skip 1) }
|
||||
|
||||
## Stack (last in, first out [LIFO])
|
||||
|
||||
### Push
|
||||
|
||||
$queue | append $elem
|
||||
|
||||
### Pop
|
||||
|
||||
{ out: ($queue | last),
|
||||
new_stack: ($queue | drop) }
|
||||
|
||||
## Set
|
||||
|
||||
# Ordered sets are similar to below, just taking more care of order when altering the sets since lists are already ordered.
|
||||
|
||||
let set = [1 2 3]
|
||||
|
||||
let elem = 4
|
||||
|
||||
let set_b = [2 3 4 5]
|
||||
|
||||
### Checking set membership
|
||||
|
||||
$elem in $set # false
|
||||
|
||||
2 in $set # true
|
||||
|
||||
### Inserting a new element
|
||||
|
||||
if $elem not-in $set { $set | append $elem }
|
||||
|
||||
# or
|
||||
|
||||
$set | append $elem | uniq
|
||||
|
||||
# Result: [1 2 3 4]
|
||||
|
||||
### Union
|
||||
|
||||
$set ++ $set_b | uniq
|
||||
|
||||
# Result: [1 2 3 4 5]
|
||||
|
||||
### Intersection
|
||||
|
||||
$set | filter { |elem| $elem in $set_b }
|
||||
|
||||
# Result: [2 3]
|
||||
|
||||
### Difference
|
||||
|
||||
# $set - $set_b
|
||||
|
||||
$set | filter { |elem| $elem not-in $set_b }
|
||||
|
||||
# or
|
||||
|
||||
# Result: [1]
|
||||
|
||||
### Symmetric Difference
|
||||
|
||||
$set ++ $set_b | uniq --unique
|
||||
|
||||
# Result: [1 4 5]
|
||||
|
||||
### Multiset (bag)
|
||||
|
||||
# Pretty much the same as a list but you can get the counts of the multiset elements with
|
||||
|
||||
[1 2 2 3] | uniq --count
|
||||
|
||||
# Result:
|
||||
# ╭───┬───────┬───────╮
|
||||
# │ # │ value │ count │
|
||||
# ├───┼───────┼───────┤
|
||||
# │ 0 │ 1 │ 1 │
|
||||
# │ 1 │ 2 │ 2 │
|
||||
# │ 2 │ 3 │ 1 │
|
||||
# ╰───┴───────┴───────╯
|
||||
|
||||
# The unique values along with how many times they are in the multiset/bag.
|
||||
74
dot_config/nushell/nu_scripts/sourced/nu_101/flag.nu
Normal file
74
dot_config/nushell/nu_scripts/sourced/nu_101/flag.nu
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
### So in this case you have to pass in a parameter
|
||||
### Any parameter you type will work
|
||||
### If you don't type a parameter you get an error
|
||||
###
|
||||
### The syntax for this is
|
||||
### noflag hola
|
||||
###
|
||||
|
||||
def noflag [x] {
|
||||
echo $x
|
||||
}
|
||||
|
||||
### The syntax for this is
|
||||
### flag -f
|
||||
### flag --flag
|
||||
|
||||
### If you type anything else it does not work
|
||||
### For example
|
||||
### flag -flag
|
||||
### flag -f=hola
|
||||
### flag -f hola
|
||||
### flag -f = hola
|
||||
|
||||
def flag [
|
||||
--flag(-f)
|
||||
] {
|
||||
echo $flag
|
||||
}
|
||||
|
||||
# Write out the flags you entered
|
||||
def flag_details [myint: int, mystring: string] {
|
||||
echo "myint is " $myint | str join
|
||||
echo "mystring is " $mystring | str join
|
||||
}
|
||||
|
||||
# Get the data passed into the flags
|
||||
def get_flag [
|
||||
--test_int(-i): int # The test intlocation
|
||||
--test_string(-s): string # The test string
|
||||
] {
|
||||
let is_int_empty = ($test_int == null)
|
||||
let is_string_empty = ($test_string == null)
|
||||
|
||||
let no_int_no_string = ($is_int_empty == true and $is_string_empty == true)
|
||||
let no_int_with_string = ($is_int_empty == true and $is_string_empty == false)
|
||||
let with_int_no_string = ($is_int_empty == false and $is_string_empty == true)
|
||||
let with_int_with_string = ($is_int_empty == false and $is_string_empty == false)
|
||||
|
||||
echo 'no int and no string ' $no_int_no_string | str join
|
||||
echo 'no int with string ' $no_int_with_string | str join
|
||||
echo 'with int and no string ' $with_int_no_string | str join
|
||||
echo 'with int and with string ' $with_int_with_string | str join
|
||||
|
||||
if $no_int_no_string {
|
||||
(flag_details 1 "blue")
|
||||
} else if $no_int_with_string {
|
||||
(flag_details 1 $test_string)
|
||||
} else if $with_int_no_string {
|
||||
(flag_details $test_int "blue")
|
||||
} else if $with_int_with_string {
|
||||
(flag_details $test_int $test_string)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
# To run this call
|
||||
# > get_flag
|
||||
# it will default to int 1 and string blue
|
||||
# > get_flag -i 2
|
||||
# This changes to int 2 and string blue
|
||||
# > get_flag -i 3 -s green
|
||||
# This changes to int 3 and string green
|
||||
@@ -0,0 +1,11 @@
|
||||
# This is an experiment to see if one can have
|
||||
# $it in and inner loop and an outer loop at
|
||||
# the same time, each having different values
|
||||
|
||||
seq 30 39 | each { |outer|
|
||||
let row = $"($outer) "
|
||||
let data = (seq 40 49 | each { |inner|
|
||||
$"($inner) "
|
||||
} | str join)
|
||||
$"($row)($data)"
|
||||
} | str join (char newline)
|
||||
24
dot_config/nushell/nu_scripts/sourced/nu_101/nothing.nu
Normal file
24
dot_config/nushell/nu_scripts/sourced/nu_101/nothing.nu
Normal file
@@ -0,0 +1,24 @@
|
||||
# This checks the -f switch to see if it was supplied
|
||||
# and tests the new $nothing variable
|
||||
def nada [
|
||||
flat?
|
||||
] {
|
||||
if $flat == null {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
# This shows an alternate way to check for nothing
|
||||
def nada2 [
|
||||
flat?
|
||||
] {
|
||||
let flat = ($flat | is-empty)
|
||||
|
||||
if $flat {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
47
dot_config/nushell/nu_scripts/sourced/progress_bar/bar.nu
Normal file
47
dot_config/nushell/nu_scripts/sourced/progress_bar/bar.nu
Normal file
@@ -0,0 +1,47 @@
|
||||
# construct bars based of a given percentage from a given width (5 is default)
|
||||
# > bar 0.2
|
||||
# █
|
||||
# > bar 0.71
|
||||
# ███▌
|
||||
def 'bar' [
|
||||
percentage: float
|
||||
--background (-b): string = 'default'
|
||||
--foreground (-f): string = 'default'
|
||||
--progress (-p) # output the result using 'print -n'
|
||||
--width (-w): int = 5
|
||||
] {
|
||||
let blocks = [null "▏" "▎" "▍" "▌" "▋" "▊" "▉" "█"]
|
||||
let $whole_part = (($blocks | last) * ($percentage * $width // 1))
|
||||
let $fraction = (
|
||||
$blocks
|
||||
| get (
|
||||
($percentage * $width) mod 1
|
||||
| $in * ($blocks | length | $in - 1)
|
||||
| math round
|
||||
)
|
||||
)
|
||||
|
||||
let result = (
|
||||
$"($whole_part)($fraction)"
|
||||
| fill -c $' ' -w $width
|
||||
| if ($foreground == 'default') and ($background == 'default') {} else {
|
||||
$"(ansi -e {fg: ($foreground), bg: ($background)})($in)(ansi reset)"
|
||||
}
|
||||
)
|
||||
|
||||
if $progress {
|
||||
print -n $"($result)\r"
|
||||
} else {
|
||||
$result
|
||||
}
|
||||
}
|
||||
|
||||
use std assert equal
|
||||
|
||||
#[test]
|
||||
def bar_tests [] {
|
||||
equal "█▌ " (bar 0.3)
|
||||
equal "███ " (bar 0.3 --width 10)
|
||||
equal "▊" (bar 0.71 --width 1)
|
||||
equal "███████▏ " (bar 0.71 --width 10)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
def loading [] {
|
||||
print -n $"Loading (char newline)"
|
||||
0..100 | each { |tick|
|
||||
sleep 50ms
|
||||
# I believe '1000D' means move the cursor to the left 1000 columns
|
||||
print -n $"(ansi -e '1000D')($tick)%"
|
||||
}
|
||||
#show_cursor
|
||||
}
|
||||
|
||||
def show_cursor [] {
|
||||
print $"(ansi -e '?25h')"
|
||||
}
|
||||
|
||||
def hide_cursor [] {
|
||||
print $"(ansi -e '?25l')"
|
||||
}
|
||||
|
||||
def demo_percent_meter [] {
|
||||
hide_cursor
|
||||
loading
|
||||
show_cursor
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
# progress bar attempt
|
||||
# https://askubuntu.com/questions/747143/create-a-progress-bar-in-bash
|
||||
# https://www.shellscript.sh/tips/progressbar/
|
||||
|
||||
# There is a strange artifact drawing the first two full blocks
|
||||
# You can see this artifact better in progress_bar_no_back.nu
|
||||
# I'm not sure what's going on nor how to fix it.
|
||||
|
||||
let pb_len = 25
|
||||
let bg_fill = "▒" # Fill up to $pb_len
|
||||
let blocks = ["▏" "▎" "▍" "▌" "▋" "▊" "▉" "█"]
|
||||
|
||||
# "█" #8/8
|
||||
# "▉" #7/8
|
||||
# "▊" #3/4
|
||||
# "▋" #5/8
|
||||
# "▌" #1/2
|
||||
# "▍" #3/8
|
||||
# "▎" #1/4
|
||||
# "▏" #1/8
|
||||
|
||||
# Turn off the cursor
|
||||
ansi cursor_off
|
||||
# Move cursor all the way to the left
|
||||
print -n $"(ansi -e '1000D')"
|
||||
# Draw the background for the progress bar
|
||||
print -n ($bg_fill | fill -c $bg_fill -w $pb_len -a r)
|
||||
|
||||
1..<$pb_len | each { |cur_progress|
|
||||
# This is kind of a hack because it's not incrementally drawing a new box
|
||||
# It's drawing the entire row every time with a different padding amount
|
||||
# echo $blocks.7 | fill --character $blocks.7 --width $it --align right
|
||||
|
||||
0..7 | each { |tick|
|
||||
let cur_idx = ($tick mod 8)
|
||||
let cur_block = (echo $blocks | get $cur_idx)
|
||||
print -n $"(ansi -e '1000D')($cur_block | fill -c $blocks.7 -w $cur_progress -a r)"
|
||||
sleep 20ms
|
||||
}
|
||||
print -n $"(ansi -e '1000D')"
|
||||
}
|
||||
# Fill in the last background block
|
||||
print $"($blocks.7 | fill -c $blocks.7 -w $pb_len -a r)"
|
||||
"Done"
|
||||
ansi cursor_on
|
||||
|
||||
|
||||
# Try to do this in the next version
|
||||
# Make it a custom command so you can do
|
||||
# set-progress 33 100
|
||||
# and the display look like
|
||||
# 33% (33/100) [███████████ ]
|
||||
@@ -0,0 +1,16 @@
|
||||
let blocks = ["▏" "▎" "▍" "▌" "▋" "▊" "▉" "█"]
|
||||
let pb_size = 25
|
||||
ansi cursor_off
|
||||
1..<$pb_size | each { |cur_size|
|
||||
0..7 | each { |tick|
|
||||
let idx = ($tick mod 8)
|
||||
let cur_block = ($blocks | get $idx)
|
||||
print -n $"(ansi -e '1000D')($cur_block | fill -c $blocks.7 -w $cur_size -a r)"
|
||||
sleep 20ms
|
||||
}
|
||||
print -n $"(ansi -e '1000D')"
|
||||
}
|
||||
print $"($blocks.7 | fill -c $blocks.7 -w $pb_size -a r)"
|
||||
'Done'
|
||||
ansi cursor_on
|
||||
|
||||
27
dot_config/nushell/nu_scripts/sourced/run-c-cpp.nu
Normal file
27
dot_config/nushell/nu_scripts/sourced/run-c-cpp.nu
Normal file
@@ -0,0 +1,27 @@
|
||||
# Runs C code via GCC without leaving a file behind
|
||||
def rcc [
|
||||
file: path # The file to run
|
||||
] {
|
||||
# Remove exe if still exists
|
||||
rm $"($file).exe" --permanent --force
|
||||
# Compile code to exe
|
||||
^gcc ("." | path join $file | path expand) -o ("." | path join $"($file).exe" | path expand)
|
||||
# Execute exe
|
||||
^$"($file).exe"
|
||||
# Remove exe
|
||||
rm $"($file).exe" --permanent --force
|
||||
}
|
||||
|
||||
# Runs C++ code via g++ without leaving a file behind
|
||||
def r++ [
|
||||
file: path # The file to run
|
||||
] {
|
||||
# Remove exe if still exists
|
||||
rm $"($file).exe" --permanent --force
|
||||
# Compile code to exe
|
||||
^g++ ("." | path join $file | path expand) -o ("." | path join $"($file).exe" | path expand)
|
||||
# Execute exe
|
||||
^$"($file).exe"
|
||||
# Remove exe
|
||||
rm $"($file).exe" --permanent --force
|
||||
}
|
||||
72
dot_config/nushell/nu_scripts/sourced/temp.nu
Normal file
72
dot_config/nushell/nu_scripts/sourced/temp.nu
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
# Convert Fahrenheit to Celsius
|
||||
export def f-to-c [
|
||||
fahren: number # Degrees Fahrenheit
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# (100°F − 32) × 5/9 = 37.778°C
|
||||
let $n = if ($fahren | describe) == "float" {$fahren} else {$fahren | into float }
|
||||
let celsius = ((( $n - 32.) * 5 / 9. ) | math round -p $round )
|
||||
$"($fahren) °F is ($celsius) °C"
|
||||
}
|
||||
|
||||
# Convert Fahrenheit to Kelvin
|
||||
export def f-to-k [
|
||||
fahren: number # Degrees Fahrenheit
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# (100°F − 32) × 5/9 + 273.15 = 310.928K
|
||||
|
||||
let $n = if ($fahren | describe) == "float" {$fahren} else {$fahren | into float }
|
||||
let kelvin = ((($n - 32) * 5 / 9 + 273.15)| math round -p $round )
|
||||
$"($fahren) °F is ($kelvin) °K"
|
||||
}
|
||||
|
||||
# Convert Celsius to Fahrenheit
|
||||
export def c-to-f [
|
||||
celsius: number # Degrees Celsius
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# (100°C × 9/5) + 32 = 212°F
|
||||
|
||||
let $n = if ($celsius | describe) == "float" {$celsius} else {$celsius | into float }
|
||||
let fahren = ((($n * 9 / 5) + 32) | math round -p $round )
|
||||
$"($celsius) °C is ($fahren) °F"
|
||||
}
|
||||
|
||||
# Convert Celsius to Kelvin
|
||||
export def c-to-k [
|
||||
celsius: number # Degrees Celsius
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# 100°C + 273.15 = 373.15K
|
||||
|
||||
|
||||
let $n = if ($celsius | describe) == "float" {$celsius} else {$celsius | into float }
|
||||
let kelvin = (($n + 273.15) | math round -p $round )
|
||||
$"($celsius) °C is ($kelvin) °K"
|
||||
}
|
||||
|
||||
# Convert Kelvin to Fahrenheit
|
||||
export def k-to-f [
|
||||
kelvin:number # Degrees Fahrenheit
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# (100K − 273.15) × 9/5 + 32 = -279.7°F
|
||||
|
||||
let $n = if ($kelvin | describe) == "float" {$kelvin} else {$kelvin | into float }
|
||||
let fahren = ((($n - 273.15) * 9 / 5 + 32) | math round -p $round )
|
||||
$"($kelvin) °K is ($fahren) °F"
|
||||
}
|
||||
|
||||
# Convert Kelvin to Celsius
|
||||
export def k-to-c [
|
||||
kelvin:number # Degrees Celsius
|
||||
--round(-r): int = 2 # Digits of precision to round to
|
||||
] {
|
||||
# 100K − 273.15 = -173.1°C
|
||||
|
||||
let $n = if ($kelvin | describe) == "float" {$kelvin} else {$kelvin | into float }
|
||||
let celsius = (($n - 273.15) | math round -p $round )
|
||||
$"($kelvin) °K is ($celsius) °C"
|
||||
}
|
||||
78
dot_config/nushell/nu_scripts/sourced/todo.nu
Normal file
78
dot_config/nushell/nu_scripts/sourced/todo.nu
Normal file
@@ -0,0 +1,78 @@
|
||||
# (See TODO.md for more details)
|
||||
|
||||
# This first command looks for the file with the todo list and
|
||||
# prints it to the screen.
|
||||
def --env printer [] {
|
||||
let contents = (
|
||||
# if you haven't setup this environment var,
|
||||
# replace `$env.TODO` with the path to your
|
||||
# `todo.txt`
|
||||
open $env.TODO
|
||||
| split row "\n"
|
||||
| take (($in | length) - 1)
|
||||
| each {|$it, n| $"($n + 1) (ansi red)->(ansi reset) ($it)"}
|
||||
| str join "\n"
|
||||
)
|
||||
|
||||
# change the message to print what you want
|
||||
if $contents == "" {
|
||||
echo $"\n(ansi lgb)Everything's been done!!! Yay!!!(ansi reset)\n"
|
||||
} else {
|
||||
echo $"\n(ansi lgb)You promised to do these(ansi reset)\n($contents)"
|
||||
}
|
||||
}
|
||||
|
||||
printer # don't forget to call it here, so that it gets run automatically
|
||||
|
||||
# This command is used to update you todo-list, and should ideally be
|
||||
# sourced in your `config.nu`
|
||||
def todo [
|
||||
--edit(-e) # edit todo manually
|
||||
--add(-a): string # add item
|
||||
--remove(-r): int # remove an item using its number
|
||||
--clear(-c) # clear the list
|
||||
] {
|
||||
def get_todo [] {
|
||||
# if you haven't setup this environment var,
|
||||
# replace `$env.TODO` with the path to your
|
||||
# `todo.txt`
|
||||
open $env.TODO
|
||||
| split row "\n"
|
||||
| take (($in | length) - 1)
|
||||
}
|
||||
|
||||
def todo_add [todo: string] {
|
||||
get_todo
|
||||
| reverse
|
||||
| $in ++ [$todo]
|
||||
| reverse
|
||||
| save $env.TODO -f
|
||||
}
|
||||
|
||||
def todo_rm [num: int] {
|
||||
get_todo
|
||||
| reverse
|
||||
# change ($num - 1) to $num to have zero-based indexing
|
||||
| filter {|it, n| $n != ($num - 1) }
|
||||
| reverse
|
||||
| save $env.TODO -f
|
||||
}
|
||||
|
||||
if $edit {
|
||||
clear
|
||||
vim $env.TODO # replace `vim` with your favorite editor
|
||||
} else if ($add != null) {
|
||||
clear
|
||||
todo_add $add | todo
|
||||
} else if ($remove != null) {
|
||||
clear
|
||||
todo_rm $remove | todo
|
||||
} else if $clear {
|
||||
clear
|
||||
# change the message to print what you want
|
||||
"" | save $env.TODO -f | echo $"(ansi lgb)todo cleared!!!"
|
||||
} else {
|
||||
clear
|
||||
printer
|
||||
}
|
||||
}
|
||||
92
dot_config/nushell/nu_scripts/sourced/typeof.nu
Normal file
92
dot_config/nushell/nu_scripts/sourced/typeof.nu
Normal file
@@ -0,0 +1,92 @@
|
||||
# give the type of the input data in a structured form
|
||||
def typeof [] {
|
||||
let data = $in
|
||||
let raw_type = $data | describe
|
||||
|
||||
match ($raw_type | str replace --regex "<.*" "") {
|
||||
"list" => { {
|
||||
type: "list"
|
||||
items: ($raw_type | parse "list<{type}>" | get type.0)
|
||||
} },
|
||||
"record" => {
|
||||
type: "record"
|
||||
fields: ($data | columns | each {|field| {
|
||||
name: $field,
|
||||
type: ($data | get $field | typeof)
|
||||
} } | transpose -rid)
|
||||
},
|
||||
"table" => {
|
||||
type: "table"
|
||||
columns: ($data | columns | each {|col| {
|
||||
name: $col,
|
||||
type: ($data | get $col | describe | parse "list<{type}>" | get type.0)
|
||||
} } | transpose -rid)
|
||||
},
|
||||
_ => $raw_type
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
def simple_type [] {
|
||||
use std assert
|
||||
|
||||
assert equal ("foo" | typeof) "string"
|
||||
assert equal (123 | typeof) "int"
|
||||
assert equal (true | typeof) "bool"
|
||||
}
|
||||
|
||||
#[test]
|
||||
def list_type [] {
|
||||
use std assert
|
||||
|
||||
assert equal ([1 2 3] | typeof) {type: "list", items: "int"}
|
||||
assert equal (["foo" "bar" "baz"] | typeof) {type: "list", items: "string"}
|
||||
assert equal (["foo" 2 true] | typeof) {type: "list", items: "any"}
|
||||
}
|
||||
|
||||
#[test]
|
||||
def table_type [] {
|
||||
use std assert
|
||||
assert equal (ls | typeof) {
|
||||
type: "table",
|
||||
columns: {
|
||||
name: "string",
|
||||
type: "string",
|
||||
size: "filesize",
|
||||
modified: "date",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
def record_type [] {
|
||||
use std assert
|
||||
assert equal ($nu | typeof) {
|
||||
type: "record",
|
||||
fields: {
|
||||
default-config-dir: "string",
|
||||
config-path: "string",
|
||||
env-path: "string",
|
||||
history-path: "string",
|
||||
loginshell-path: "string",
|
||||
plugin-path: "string",
|
||||
home-path: "string",
|
||||
temp-path: "string",
|
||||
pid: "int",
|
||||
os-info: {
|
||||
type: "record",
|
||||
fields: {
|
||||
name: "string",
|
||||
arch: "string",
|
||||
family: "string",
|
||||
kernel_version: "string",
|
||||
}
|
||||
},
|
||||
startup-time: "duration",
|
||||
is-interactive: "bool",
|
||||
is-login: "bool",
|
||||
current-exe: "string",
|
||||
}
|
||||
}
|
||||
}
|
||||
37
dot_config/nushell/nu_scripts/sourced/update-path.nu
Normal file
37
dot_config/nushell/nu_scripts/sourced/update-path.nu
Normal file
@@ -0,0 +1,37 @@
|
||||
# The purpose of this module is to automatically update Path variable on Windows since Windows is unable to do it on its own forcing users to restart terminal to pick up updates
|
||||
# Usage: import this into your config.nu and then add the update-path function to your pre_prompt hook
|
||||
module update-path {
|
||||
|
||||
def parse-paths [] {
|
||||
where name == Path
|
||||
| get value.0
|
||||
| str trim -c (char double_quote)
|
||||
| split row (char esep)
|
||||
| par-each {|path|
|
||||
let suffix = if $path ends-with (char path_sep) {(char path_sep)} else {''} # necessary because nushell strips trailing path separators which breaks uniq later on
|
||||
|
||||
$path
|
||||
| path split
|
||||
| each {|elem|
|
||||
if $elem starts-with '%' and $elem ends-with '%' {
|
||||
$env
|
||||
| get ($elem|str trim -c '%')
|
||||
} else {
|
||||
$elem
|
||||
}
|
||||
}
|
||||
| path join
|
||||
| append $suffix
|
||||
| str join
|
||||
}
|
||||
}
|
||||
|
||||
def get-paths-from-registry [] {
|
||||
registry query --hkcu environment
|
||||
| parse-paths
|
||||
| append (registry query --hklm 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'| parse-paths)
|
||||
}
|
||||
export def --env update [] {
|
||||
$env.Path = ($env.Path|append (get-paths-from-registry)|uniq)
|
||||
}
|
||||
}
|
||||
63
dot_config/nushell/nu_scripts/sourced/update_hosts.nu
Normal file
63
dot_config/nushell/nu_scripts/sourced/update_hosts.nu
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/nu
|
||||
|
||||
# /etc/hosts update handler
|
||||
module hosts {
|
||||
def display_heads [old, new] {
|
||||
echo "Current file:"
|
||||
echo $old
|
||||
echo "New file:"
|
||||
echo $new
|
||||
print ""
|
||||
}
|
||||
|
||||
def are_the_same [old_head, new_head] {
|
||||
(($old_head | first) == ($new_head | first))
|
||||
}
|
||||
|
||||
# Updater function for /etc/hosts
|
||||
export def update [
|
||||
--force (-f) # force replace /etc/hosts
|
||||
] {
|
||||
# just sample values, feel free to change it but note that it works for StevenBlack files
|
||||
let LINK = "https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/gambling-porn/hosts"
|
||||
let WHITELIST = ["multipasko"]
|
||||
let BLACKLIST = ["0.0.0.0 tiktok.com"]
|
||||
|
||||
let whitelisted = "(" + ($WHITELIST | str join "|") + ")"
|
||||
let pattern = ($"0.0.0.0.*($whitelisted).*$")
|
||||
let OLD_FILE = "/etc/hosts"
|
||||
let TMP_FILE = (http get $LINK | lines)
|
||||
|
||||
if ($env.LAST_EXIT_CODE == 0) {
|
||||
let OLD_HEAD = (open $OLD_FILE --raw | lines | first 8 | last 3)
|
||||
let TMP_HEAD = ($TMP_FILE | first 8 | last 3)
|
||||
|
||||
display_heads $OLD_HEAD $TMP_HEAD
|
||||
if (not ((are_the_same $OLD_HEAD $TMP_HEAD) and (not $force))) {
|
||||
echo "Do you want to update the /etc/hosts file? [Y/n]"
|
||||
let choice = (input)
|
||||
if $choice in ["" "Y" "y"] {
|
||||
let TMP_FILE = if ($WHITELIST|is-empty) {
|
||||
($TMP_FILE)
|
||||
} else {
|
||||
($TMP_FILE | where {|line| $line !~ $pattern})
|
||||
}
|
||||
|
||||
let TMP_FILE = ($TMP_FILE | append $BLACKLIST)
|
||||
|
||||
$TMP_FILE | save /tmp/temphostsfile
|
||||
if ($env.LAST_EXIT_CODE == 0) {
|
||||
sudo mv /tmp/temphostsfile $OLD_FILE
|
||||
echo "Done!"
|
||||
} else {
|
||||
error make -u {msg: "Something went wrong while overwriting the /etc/hosts file"}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo "No updates available."
|
||||
}
|
||||
} else {
|
||||
error make -u {msg: "Failed downloading the hosts file, try again."}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Web Scraping
|
||||
|
||||
### Definition
|
||||
|
||||
Simple scripts to demonstrate how to scrape websites in nushell. Requires `query web` plugin
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env nu
|
||||
# script to get anagrams with scrabble points from unscramble.me
|
||||
# NOTE: this is just a small show case of piping query web stuff
|
||||
def main [...words: string] {
|
||||
let base = "https://www.unscramble.me/"
|
||||
$words | par-each {
|
||||
|word|
|
||||
http get ($base + $word)
|
||||
|query web -q ".mBottom-6" -m # gets the anagram table part of the page
|
||||
|drop nth 0 # remove the description/definition of "words"
|
||||
|first # we only care about the biggest/first anagrams (which is the length of the input word)
|
||||
|query web -q "table" -m # get the html table
|
||||
|to text # we need it as raw html to parse it
|
||||
|query web --as-table ["Word" "Scrabble points" "Words with friends points"] # parse the html table as table
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env nu
|
||||
let baseurl = 'https://www.schiit.co.uk/'
|
||||
let pages = ['headphone-amps' 'dacs' 'schiit-gaming-products' 'power-amplifiers' 'preamps' 'upgrades' 'accessories-cables' 'schiit%20graded%20stock']
|
||||
|
||||
# Simple script to check stock of https://schiit.co.uk store
|
||||
def main [] {
|
||||
$pages | par-each { |page|
|
||||
http get ($baseurl + $page)
|
||||
|query web -q '.price, .stock, .product-item h5'
|
||||
|str trim
|
||||
|group 3
|
||||
|each {
|
||||
|x| {
|
||||
name: $x.0,
|
||||
avail: $x.1,
|
||||
price: $x.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|sort-by avail
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
let shell_list = [
|
||||
[name repo];
|
||||
[bash bminor/bash]
|
||||
[fish fish-shell/fish-shell]
|
||||
[nushell nushell/nushell]
|
||||
# [powershell no-github-url]
|
||||
[pwsh PowerShell/PowerShell]
|
||||
[ksh2020 ksh2020/ksh]
|
||||
[ksh93u att/ast]
|
||||
# [csh no-github-url]
|
||||
# [dash no-github-url]
|
||||
# [sh no-github-url]
|
||||
# [cmd no-github-url]
|
||||
[aws-shell awslabs/aws-shell]
|
||||
[azure-cloud-shell Azure/CloudShell]
|
||||
[elvish elves/elvish]
|
||||
[es wryun/es-shell]
|
||||
[ion redox-os/ion]
|
||||
[MirBSDksh MirBSD/mksh]
|
||||
[ngs ngs-lang/ngs]
|
||||
[openbsd_ksh ibara/oksh]
|
||||
[oil oilshell/oil]
|
||||
[shell++ alexst07/shell-plus-plus]
|
||||
[tcsh tcsh-org/tcsh]
|
||||
[xonsh xonsh/xonsh]
|
||||
[yash magicant/yash]
|
||||
[zsh zsh-users/zsh]
|
||||
]
|
||||
|
||||
$shell_list | each { |r|
|
||||
print -n $"Working on ($r.name)"
|
||||
sleep 250ms
|
||||
if ($r.repo | str starts-with no) {
|
||||
[[shell repo stars]; [($r.name) "no github url" 0]]
|
||||
print ""
|
||||
} else {
|
||||
let url = $"https://api.github.com/repos/($r.repo)"
|
||||
let count = (http get -u $env.GITHUB_USERNAME -p $env.GITHUB_PASSWORD ($url) | get stargazers_count)
|
||||
print $" ($count)"
|
||||
[[shell repo stars]; [($r.name) ($r.repo) ($count)]]
|
||||
}
|
||||
} | flatten | sort-by -r stars | table --index 1
|
||||
28
dot_config/nushell/nu_scripts/sourced/webscraping/twitter.nu
Normal file
28
dot_config/nushell/nu_scripts/sourced/webscraping/twitter.nu
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env nu
|
||||
#script to get basic info from twitter's unofficial API
|
||||
def main [...usernames: string] {
|
||||
|
||||
let bearer = "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
|
||||
let token_endpoint = 'https://api.twitter.com/1.1/guest/activate.json'
|
||||
let user_endpoint = 'https://twitter.com/i/api/graphql/gr8Lk09afdgWo7NvzP89iQ/UserByScreenName'
|
||||
|
||||
#obtaining the guest token needed to perform further request
|
||||
|
||||
let token = (
|
||||
post -H [Authorization $bearer] $token_endpoint ''
|
||||
).guest_token
|
||||
|
||||
for $twitter_username in $usernames {
|
||||
|
||||
#getting all the useful data from the api
|
||||
|
||||
let variables = {
|
||||
screen_name: $twitter_username,
|
||||
withSafetyModeUserFields: true,
|
||||
withSuperFollowsUserFields: true
|
||||
}
|
||||
|
||||
post $user_endpoint -t application/x-www-form-urlencoded [ variables ($variables|to json -r) ] -H [ Authorization $bearer, x-guest-token $token ] | get data.user.result | flatten | select name screen_name description protected verified created_at followers_count rest_id has_nft_avatar | get 0
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user