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.
This commit is contained in:
Ade Attwood 2024-12-08 10:55:03 +00:00
parent 2755f69cd8
commit dc23131046
11 changed files with 243 additions and 1 deletions

7
modules/nushell.lua Normal file
View file

@ -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

View file

@ -0,0 +1 @@
history.txt

View file

@ -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 }
]
}
}
}

View file

@ -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)"
}
}

View file

@ -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 }

View file

@ -0,0 +1,6 @@
# Really simple aliases for neovim
export alias vim = nvim
export alias vi = nvim
export-env { $env.EDITOR = 'nvim' }

View file

@ -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
}
}

View file

@ -0,0 +1,4 @@
export-env {
$env.GOPATH = $"($env.HOME)/Code"
}

View file

@ -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 = ""
}

View file

@ -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
}
}

View file

@ -16,6 +16,7 @@ local servers = {
html = {}, html = {},
cssls = {}, cssls = {},
marksman = {}, marksman = {},
nushell = {},
clojure_lsp = {}, clojure_lsp = {},
emmet_ls = { emmet_ls = {
filetypes = { "html", "typescriptreact", "javascriptreact", "css", "scss", "eruby", "liquid" }, 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 -- Highlight document symbles for every file type other erb files because
-- solargraph only supports textDocument/documentHighlight in rb files. -- solargraph only supports textDocument/documentHighlight in rb files.
local file_type = vim.api.nvim_buf_get_option(0, "filetype") 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() vim.lsp.buf.document_highlight()
end end
end, end,