From dc231310465d612f0baaeeed5322953446fd70b4 Mon Sep 17 00:00:00 2001 From: Ade Attwood Date: Sun, 8 Dec 2024 10:55:03 +0000 Subject: [PATCH] feat(nu): setup nushell and start off the config This is some investigation in to nushell will work. I will be looking to use this cross platform, as zsh will not work on windows. Adds some of the core modules so I don't loose my mind having to relearn mussel memory. The goal of this is to replicate my use of oh-my-zsh, I think this will take some time, I have sunk years into the zsh config. The aliases will be the same, the GOPATH project structure will be replicated and the dir hooks will be implemeted so my PATH gets setup just as I like it. --- modules/nushell.lua | 7 ++ site-modules/core/files/nushell/.gitignore | 1 + site-modules/core/files/nushell/config.nu | 21 +++++ .../core/files/nushell/scripts/fzf.nu | 14 ++++ .../files/nushell/scripts/lib/project-dirs.nu | 38 +++++++++ .../core/files/nushell/scripts/neovim.nu | 6 ++ .../core/files/nushell/scripts/nvm.nu | 84 +++++++++++++++++++ .../core/files/nushell/scripts/path.nu | 4 + .../core/files/nushell/scripts/prompt.nu | 24 ++++++ .../core/files/nushell/scripts/sapling.nu | 42 ++++++++++ site-modules/core/files/vim/plugin/lsp.lua | 3 +- 11 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 modules/nushell.lua create mode 100644 site-modules/core/files/nushell/.gitignore create mode 100644 site-modules/core/files/nushell/config.nu create mode 100644 site-modules/core/files/nushell/scripts/fzf.nu create mode 100644 site-modules/core/files/nushell/scripts/lib/project-dirs.nu create mode 100644 site-modules/core/files/nushell/scripts/neovim.nu create mode 100644 site-modules/core/files/nushell/scripts/nvm.nu create mode 100644 site-modules/core/files/nushell/scripts/path.nu create mode 100644 site-modules/core/files/nushell/scripts/prompt.nu create mode 100644 site-modules/core/files/nushell/scripts/sapling.nu diff --git a/modules/nushell.lua b/modules/nushell.lua new file mode 100644 index 0000000..58b5d68 --- /dev/null +++ b/modules/nushell.lua @@ -0,0 +1,7 @@ + +local nu_dir = os.getenv "HOME" .. "/.config/nushell" +if not configz.is_file(nu_dir) then + configz.link(nu_dir, { + source = os.getenv "PWD" .. "/site-modules/core/files/nushell", + }) +end diff --git a/site-modules/core/files/nushell/.gitignore b/site-modules/core/files/nushell/.gitignore new file mode 100644 index 0000000..a3e737a --- /dev/null +++ b/site-modules/core/files/nushell/.gitignore @@ -0,0 +1 @@ +history.txt diff --git a/site-modules/core/files/nushell/config.nu b/site-modules/core/files/nushell/config.nu new file mode 100644 index 0000000..fb4105b --- /dev/null +++ b/site-modules/core/files/nushell/config.nu @@ -0,0 +1,21 @@ +use path.nu + +use fzf.nu * +use neovim.nu * +use prompt.nu * +use sapling.nu * +use nvm.nu * + +nvm use default + +$env.config = { + show_banner: false, + hooks: { + env_change: { + PWD: [ + {|_, after| nvm dir-hook $after } + ] + } + } +} + diff --git a/site-modules/core/files/nushell/scripts/fzf.nu b/site-modules/core/files/nushell/scripts/fzf.nu new file mode 100644 index 0000000..d505163 --- /dev/null +++ b/site-modules/core/files/nushell/scripts/fzf.nu @@ -0,0 +1,14 @@ +# FZF Helper Functions +use lib/project-dirs.nu + +def fzf-get-project [] { + cd $"($env.GOPATH)/src/"; + FZF_DEFAULT_COMMAND="fd -t d --exact-depth 3" fzf --preview-window=top:70% --preview 'bat --style=numbers --color=always {}/README.md' +} + +export def --env fp [] { + let dir = fzf-get-project + if ($dir | str trim | str length) > 0 { + cd $"($env.GOPATH)/src/($dir)" + } +} diff --git a/site-modules/core/files/nushell/scripts/lib/project-dirs.nu b/site-modules/core/files/nushell/scripts/lib/project-dirs.nu new file mode 100644 index 0000000..d9f56de --- /dev/null +++ b/site-modules/core/files/nushell/scripts/lib/project-dirs.nu @@ -0,0 +1,38 @@ +# Project directories are directories that contain a `.git` directory. They are +# structured in the style of GOPATH. This module contains functions to get the +# relevant project information from the current directory. + +export-env { + $env.GOPATH = $env.HOME + "/Code" +} + +# Get the project information from a path. The path can be passed $in and the +# project information will be returned. +# +# > $"($env.GOPATH)/src/github.com/nushell/nushell" | project +# ╭───────┬────────────────────────────────────╮ +# │ host │ github.com │ +# │ owner │ nushell │ +# │ repo │ nushell │ +# │ path │ nushell/nushell │ +# │ url │ https://github.com/nushell/nushell │ +# ╰───────┴────────────────────────────────────╯ +# +# If you are looking to get the project for the directory you'r in, you can use +# the helper function `current-project`. +export def project [] { + let path = $in + let parts = $path | str replace $"($env.GOPATH)/src/" "" | split row "/" + + { + host: $parts.0, + owner: $parts.1, + repo: $parts.2, + path: $"($parts.1)/($parts.2)" + url: $"https://($parts.0)/($parts.1)/($parts.2)" + } +} + +# Helper function to get the project information from your current directory. +# This is a simple wrapper around the `project` function. +export def current-project [] { $env.PWD | project } diff --git a/site-modules/core/files/nushell/scripts/neovim.nu b/site-modules/core/files/nushell/scripts/neovim.nu new file mode 100644 index 0000000..cdf1c46 --- /dev/null +++ b/site-modules/core/files/nushell/scripts/neovim.nu @@ -0,0 +1,6 @@ +# Really simple aliases for neovim + +export alias vim = nvim +export alias vi = nvim + +export-env { $env.EDITOR = 'nvim' } diff --git a/site-modules/core/files/nushell/scripts/nvm.nu b/site-modules/core/files/nushell/scripts/nvm.nu new file mode 100644 index 0000000..9075eac --- /dev/null +++ b/site-modules/core/files/nushell/scripts/nvm.nu @@ -0,0 +1,84 @@ + +def 'nvm path' [subdir?: string]: nothing -> string { + if ($subdir | into string | str length) == 0 { + return $"($env.HOME)/.nvm" + } + + $"($env.HOME)/.nvm/($subdir)" +} + +export def 'nvm get-alias' [alias: string]: nothing -> string { + mut alias_version = if ($alias | find "stable" | is-not-empty) { + ["lts/*"] + } else { + nvm aliases | where {|x| $x == $alias} + } + + if $alias_version == ["stable"] { + $alias_version = ["lts/*"] + } + + if ($alias_version | is-empty) { + return null + } + + if ($alias_version | length) > 1 { + $alias_version = [$"($alias_version | first)/*"] + } + + let version = (open ([(nvm path "alias"), ($alias_version | first)] | path join)) | str trim + if not ($version | str starts-with "v") { + return (nvm get-alias $version) + } + + $version +} + +def 'nvm index' [] { + http get 'https://nodejs.org/dist/index.json' | get version +} + +export def 'nvm aliases' [] { + ls -a ...(glob (nvm path "alias/**/*")) + | each {|p| $p.name | path relative-to (nvm path "alias") } + | filter {|p| not ($p | str ends-with "*")} + | uniq +} + +export def 'nvm list' [] { + ls -a (nvm path "versions/node") + | each {|p| $p.name | path relative-to (nvm path "versions/node") } + | filter {|p| not ($p | str ends-with "*")} +} + +export def 'nvm resolve' [version: string] { + let resolved_version = (nvm list | find $version) + let resolved_alias = (nvm get-alias $version) + if (($resolved_version | length) != 1) and ($resolved_alias | is-empty) { + (error make --unspanned { msg: $"Unable to resolve '($version)'" }) + } + + if not ($resolved_version | is-empty) { + $resolved_version | first + } else { + $resolved_alias + } +} + +export def --env 'nvm use' [version: string] { + let resolved = (nvm resolve $version) + let node_path = [(nvm path "versions/node") $resolved] | path join + + $env.PATH = $env.PATH + | split row ":" + | where {|x| not ($x | str starts-with (nvm path "versions/node"))} + | prepend ([$node_path "bin"] | path join) + | str join ":" +} + +export def --env 'nvm dir-hook' [dir: string] { + let file = $"($dir)/.nvmrc" + if ($file | path exists) and ($file | path type) == "file" { + nvm use (open $file | lines | get 0) | str trim + } +} diff --git a/site-modules/core/files/nushell/scripts/path.nu b/site-modules/core/files/nushell/scripts/path.nu new file mode 100644 index 0000000..e20ae1c --- /dev/null +++ b/site-modules/core/files/nushell/scripts/path.nu @@ -0,0 +1,4 @@ + +export-env { + $env.GOPATH = $"($env.HOME)/Code" +} diff --git a/site-modules/core/files/nushell/scripts/prompt.nu b/site-modules/core/files/nushell/scripts/prompt.nu new file mode 100644 index 0000000..7c9beee --- /dev/null +++ b/site-modules/core/files/nushell/scripts/prompt.nu @@ -0,0 +1,24 @@ +# All the functions use to create the shell prompt. The prompt is based on the +# oh-my-zsh theme "pygmalion". Its way simpler than the original theme but it +# has all the features I have used over the years. + +# Creates the left prompt +# +# The format of the prompt is: username@hostname:current_path +def create_left_prompt [] { + let username = $env.USER + let hostname = $env.HOSTNAME + + let formatted_path = $env.PWD + | str replace $env.HOME '~' + | str replace '~/Code/src/' '~s/' + | str replace '~s/github.com' '~gh' + + $"(ansi magenta)($username)(ansi light_cyan)@(ansi yellow)($hostname)(ansi red):(ansi light_cyan)($formatted_path)(ansi reset)" +} + +export-env { + $env.PROMPT_COMMAND = { create_left_prompt } + $env.PROMPT_INDICATOR = "  " + $env.PROMPT_COMMAND_RIGHT = "" +} diff --git a/site-modules/core/files/nushell/scripts/sapling.nu b/site-modules/core/files/nushell/scripts/sapling.nu new file mode 100644 index 0000000..1a997e3 --- /dev/null +++ b/site-modules/core/files/nushell/scripts/sapling.nu @@ -0,0 +1,42 @@ +# Helper functions and aliases for working with sapling scm +# +# https://sapling-scm.com/ + +# Internal alias to rename sl +export alias _sl = sl + +# Sapling CLI tool, aliases for `sl` +export alias s = _sl + +# Sapling log for your current stack +export alias sl = _sl log --pager never --remote -r '.::top() or last(::., 40)' + +# Sapling diff +export alias sd = _sl diff + +# Sapling status +export alias ss = _sl status + +# Wrapper arround `sl addremove` and `sl amend` commands +export def --wrapped sa [ + ...args # Agguments you can pass to `sl amend` command +] { + _sl addremove '.' + _sl amend -iv ...$args +} + +# Wrapper arround `sl addremove` and `sl commit` commands +export def --wrapped sc [ + ...args # Agguments you can pass to `sl commit` command +] { + _sl addremove '.' + _sl commit -iv ...$args +} + +export def sco [] { + let raw_commit = (_sl log -r 'heads(draft())' | fzf --ansi) + if ($raw_commit | str length) > 0 { + let commit = ($raw_commit | split words | get 1); + _sl goto $commit + } +} diff --git a/site-modules/core/files/vim/plugin/lsp.lua b/site-modules/core/files/vim/plugin/lsp.lua index 46fa44a..1186e3f 100644 --- a/site-modules/core/files/vim/plugin/lsp.lua +++ b/site-modules/core/files/vim/plugin/lsp.lua @@ -16,6 +16,7 @@ local servers = { html = {}, cssls = {}, marksman = {}, + nushell = {}, clojure_lsp = {}, emmet_ls = { filetypes = { "html", "typescriptreact", "javascriptreact", "css", "scss", "eruby", "liquid" }, @@ -81,7 +82,7 @@ local on_attach = function(_, bufnr) -- Highlight document symbles for every file type other erb files because -- solargraph only supports textDocument/documentHighlight in rb files. local file_type = vim.api.nvim_buf_get_option(0, "filetype") - if file_type ~= "eruby" and file_type ~= "markdown" and file_type ~= "liquid" then + if file_type ~= "eruby" and file_type ~= "markdown" and file_type ~= "liquid" and file_type ~= "nu" then vim.lsp.buf.document_highlight() end end,