diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 97bd02ff..00000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule ".vim/bundle/Vundle.vim"] - path = .vim/bundle/Vundle.vim - url = https://github.com/VundleVim/Vundle.vim.git -[submodule ".vim/bundle/vim-windflower"] - path = .vim/bundle/vim-windflower - url = https://github.com/mushanyoung/vim-windflower.git -[submodule ".vim/bundle/edge"] - path = .vim/bundle/edge - url = https://github.com/sainnhe/edge.git diff --git a/.mise.toml b/.mise.toml index 9cb1f551..2e043451 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,3 +1,5 @@ [tools] node = "24.12.0" pnpm = "10.30.3" +neovim = "latest" +starship = "latest" diff --git a/.vim/bundle/Vundle.vim b/.vim/bundle/Vundle.vim deleted file mode 160000 index b255382d..00000000 --- a/.vim/bundle/Vundle.vim +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b255382d6242d7ea3877bf059d2934125e0c4d95 diff --git a/.vim/bundle/edge b/.vim/bundle/edge deleted file mode 160000 index 1e19443d..00000000 --- a/.vim/bundle/edge +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1e19443df9ef153ff88b0ed92e52da58d685f99c diff --git a/.vim/bundle/vim-windflower b/.vim/bundle/vim-windflower deleted file mode 160000 index 673f861f..00000000 --- a/.vim/bundle/vim-windflower +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 673f861fc8ea8086203f72e576e44749fe8e4171 diff --git a/README.md b/README.md index 8e7357ea..e14f04f1 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,94 @@ # devbox -## Setup and Configure +## Prerequisites -> :warning: this is heavily tailored towards bash, so may not work out of the (dev)box -> for zsh (zush) and friends +Install [mise](https://mise.jdx.dev/) for managing tool versions: ```bash -git clone --recursive https://github.com/viqueen/devbox.git +brew install mise +``` + +## Setup + +```bash +git clone https://github.com/viqueen/devbox.git +cd devbox + +# install tools (node, pnpm, neovim, starship) +mise install + +# install dependencies +pnpm install -# required +# configure shell (exports, PATH, aliases, mise config symlink) ./setup.sh config_box -# optional, to setup the prompt line +# optional: workspace-aware prompt (starship) ./setup.sh config_prompt -# optional, to setup vim +# optional: neovim with lazy.nvim ./setup.sh config_vim -git config --global core.editor vim ``` -> :warning: to update the submodules +## What's Included -```bash -git submodule update --init --recursive -``` +### Tools (via mise) -> :warning: install dependencies +Defined in `.mise.toml` and symlinked to `~/.mise.toml` by `config_box`: -```bash -mise install -pnpm install -``` +| Tool | Purpose | +| -------- | --------------- | +| node | Node.js runtime | +| pnpm | Package manager | +| neovim | Editor | +| starship | Shell prompt | -## Optional - macOs dev setup +### Prompt -Install [mise](https://mise.jdx.dev/) for managing tool versions (node, java, python, etc.): +A workspace-aware [starship](https://starship.rs/) prompt that color-codes the hostname segment +based on which workspace you're in: -```bash -brew install mise -mise install -``` +| Workspace | Color | +| ------------------------------ | ------ | +| `workspaces/viqueen/*` | orange | +| `workspaces/{primary_org}/*` | purple | +| `workspaces/{secondary_org}/*` | blue | +| `~/` | green | +| elsewhere | red | -## Scripts and Binaries +Configure orgs via env vars: `VIQUEEN_DEVBOX_PRIMARY_ORG`, `VIQUEEN_DEVBOX_SECONDARY_ORG`. -### tricks up this sleeve : from anywhere +### Editor -- navigate to where devbox is installed +Neovim with [lazy.nvim](https://github.com/folke/lazy.nvim) plugin manager. Config lives in `cli/nvim/` +and is scoped via `NVIM_APPNAME=devbox` (stored at `~/.config/devbox/nvim/`). -```bash -. dev -``` +Plugins: edge colorscheme, lualine, nvim-tree, telescope, treesitter, mason + lspconfig. -- open existing scripts for edit +### Scripts and Binaries + +#### Quick navigation ```bash -dev edit -gitar edit +. dev # navigate to devbox +dev edit # open dev script for edit +dev edit myscript # create a new script ``` -- create a new script in devbox +#### Available commands ```bash -dev edit mynewscript +dev -h # housekeeping and generic scripts +mvnup -h # maven version upgrade +jsonf # json pretty format +image -h # docker things +gitar -h # git things ``` -> :information_source: all these scripts source `selfedit.sh` -> which allows you to quickly step into edit mode (uses vim under the hood) -> -> `selfedit.sh` also sources `selfdoc.sh` which allows you to add documentation hints -> to your commands +All scripts source `selfedit.sh` (edit mode via nvim) and `selfdoc.sh` (auto-generated help from `@COMMAND` annotations): ```bash -#! /usr/bin/env +#! /usr/bin/env bash source selfedit.sh # @COMMAND one does this and that @@ -79,11 +96,6 @@ one() { echo "one" } -# @COMMAND two does these and those -two() { - echo "two" -} - eval $@ if [[ -z $1 ]]; then @@ -91,31 +103,11 @@ if [[ -z $1 ]]; then fi ``` -> :x: but please note that not all scripts in devbox follow this pattern - -### housekeeping and generic scripts - -```bash -dev -h # mainframe -mvnup -h # maven version upgrade -jsonf # json pretty format -image -h # docker things -gitar -h # git things -saymyname # finds the longest java class name in a directory , I was bored once so I wrote this -``` - ### Atlassian scripts -- extracted to [atlassian-devbox](https://github.com/viqueen/atlassian-devbox) -- install using homebrew +Extracted to [atlassian-devbox](https://github.com/viqueen/atlassian-devbox): ```bash brew tap viqueen/atlassian-devbox brew install atlassian-devbox ``` - -- or install using npm - -```bash -npm install -g atlassian-devbox -``` diff --git a/cli/.devboxrc b/cli/.devboxrc index d78cbde6..92e3a735 100644 --- a/cli/.devboxrc +++ b/cli/.devboxrc @@ -1,9 +1,5 @@ #! /usr/bin/env bash -function cd_workspace() { - cd "$@" && source ~/.promptline.sh -} - alias ll='ls -la' alias please=sudo alias wl='wc -l' @@ -11,16 +7,16 @@ alias move=mv alias maven=mvn alias awsl=awslocal alias cats='pygmentize -g' -alias cd='cd_workspace' +alias vim='NVIM_APPNAME=devbox nvim' +alias nvim='NVIM_APPNAME=devbox nvim' -# overridden when running ./setup.sh config_prompt , see .shell_prompt.sh export PS1='\u@\h\w' export CLICOLOR=1 export LSCOLORS=GxFxCxDxBxegedabagaced export BASH_SILENCE_DEPRECATION_WARNING=1 # homebrew -export HOMEBREW_EDITOR="vim" +export HOMEBREW_EDITOR="nvim" # maven export MAVEN_OPTS="-Xms1680m -Xmx2048m -XX:MaxMetaspaceSize=384m" diff --git a/cli/.promptline.sh b/cli/.promptline.sh index 546f8548..f1853067 100644 --- a/cli/.promptline.sh +++ b/cli/.promptline.sh @@ -1,277 +1,39 @@ +#!/usr/bin/env bash # -# This shell prompt config file was created by promptline.vim +# workspace-aware prompt using starship # -function __promptline_host { - local only_if_ssh="0" - if [ $only_if_ssh -eq 0 -o -n "${SSH_CLIENT}" ]; then - if [[ -n ${ZSH_VERSION-} ]]; then print %m; - elif [[ -n ${FISH_VERSION-} ]]; then hostname -s; - elif [[ -n ${VIQUEEN_DEVBOX_MACHINE} ]]; then printf "${VIQUEEN_DEVBOX_MACHINE}"; - else printf "%s" \\h; fi - fi -} - -function __promptline_last_exit_code { - - [[ $last_exit_code -gt 0 ]] || return 1; - - printf "%s" "$last_exit_code" -} -function __promptline_ps1 { - local slice_prefix slice_empty_prefix slice_joiner slice_suffix is_prompt_empty=1 - - # section "a" header - slice_prefix="${a_bg}${sep}${a_fg}${a_bg}${space}" slice_suffix="$space${a_sep_fg}" slice_joiner="${a_fg}${a_bg}${alt_sep}${space}" slice_empty_prefix="${a_fg}${a_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "a" slices - __promptline_wrapper "$(__promptline_host)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "b" header - slice_prefix="${b_bg}${sep}${b_fg}${b_bg}${space}" slice_suffix="$space${b_sep_fg}" slice_joiner="${b_fg}${b_bg}${alt_sep}${space}" slice_empty_prefix="${b_fg}${b_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "b" slices - __promptline_wrapper "$USER" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "c" header - slice_prefix="${c_bg}${sep}${c_fg}${c_bg}${space}" slice_suffix="$space${c_sep_fg}" slice_joiner="${c_fg}${c_bg}${alt_sep}${space}" slice_empty_prefix="${c_fg}${c_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "c" slices - __promptline_wrapper "$(__promptline_cwd)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "y" header - slice_prefix="${b_bg}${sep}${b_fg}${b_bg}${space}" slice_suffix="$space${b_sep_fg}" slice_joiner="${b_fg}${b_bg}${alt_sep}${space}" slice_empty_prefix="${b_fg}${b_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "y" slices - __promptline_wrapper "$(__promptline_vcs_branch)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "warn" header - slice_prefix="${warn_bg}${sep}${warn_fg}${warn_bg}${space}" slice_suffix="$space${warn_sep_fg}" slice_joiner="${warn_fg}${warn_bg}${alt_sep}${space}" slice_empty_prefix="${warn_fg}${warn_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "warn" slices - __promptline_wrapper "$(__promptline_last_exit_code)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # close sections - printf "%s" "${reset_bg}${sep}$reset$space\n${green_fg}${sep}$reset$space" -} -function __promptline_vcs_branch { - local branch - local branch_symbol=" " - - # git - if hash git 2>/dev/null; then - if branch=$( { git symbolic-ref --quiet HEAD || git rev-parse --short HEAD; } 2>/dev/null ); then - branch=${branch/refs\/heads\//} - printf "%s" "${branch_symbol}${branch:-unknown}" - return - fi - fi - - # mercurial - if hash hg 2>/dev/null; then - if branch=$(hg branch 2>/dev/null); then - printf "%s" "${branch_symbol}${branch:-unknown}" - return - fi - fi - - return 1 -} -function __promptline_cwd { - local dir_limit="3" - local truncation="⋯" - local first_char - local part_count=0 - local formatted_cwd="" - local dir_sep="  " - local tilde="~" - - local cwd="${PWD/#$HOME/$tilde}" - - # get first char of the path, i.e. tilde or slash - [[ -n ${ZSH_VERSION-} ]] && first_char=${cwd[1,1]} || first_char=${cwd::1} - - # remove leading tilde - cwd="${cwd#\~}" - - while [[ "$cwd" == */* && "$cwd" != "/" ]]; do - # pop off last part of cwd - local part="${cwd##*/}" - cwd="${cwd%/*}" - - formatted_cwd="$dir_sep$part$formatted_cwd" - part_count=$((part_count+1)) - - [[ $part_count -eq $dir_limit ]] && first_char="$truncation" && break - done - - printf "%s" "$first_char$formatted_cwd" -} -function __promptline_left_prompt { - local slice_prefix slice_empty_prefix slice_joiner slice_suffix is_prompt_empty=1 - - # section "a" header - slice_prefix="${a_bg}${sep}${a_fg}${a_bg}${space}" slice_suffix="$space${a_sep_fg}" slice_joiner="${a_fg}${a_bg}${alt_sep}${space}" slice_empty_prefix="${a_fg}${a_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "a" slices - __promptline_wrapper "$(__promptline_host)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "b" header - slice_prefix="${b_bg}${sep}${b_fg}${b_bg}${space}" slice_suffix="$space${b_sep_fg}" slice_joiner="${b_fg}${b_bg}${alt_sep}${space}" slice_empty_prefix="${b_fg}${b_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "b" slices - __promptline_wrapper "$USER" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # section "c" header - slice_prefix="${c_bg}${sep}${c_fg}${c_bg}${space}" slice_suffix="$space${c_sep_fg}" slice_joiner="${c_fg}${c_bg}${alt_sep}${space}" slice_empty_prefix="${c_fg}${c_bg}${space}" - [ $is_prompt_empty -eq 1 ] && slice_prefix="$slice_empty_prefix" - # section "c" slices - __promptline_wrapper "$(__promptline_cwd)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; is_prompt_empty=0; } - - # close sections - printf "%s" "${reset_bg}${sep}$reset$space" -} -function __promptline_wrapper { - # wrap the text in $1 with $2 and $3, only if $1 is not empty - # $2 and $3 typically contain non-content-text, like color escape codes and separators - - [[ -n "$1" ]] || return 1 - printf "%s" "${2}${1}${3}" -} -function __promptline_right_prompt { - local slice_prefix slice_empty_prefix slice_joiner slice_suffix - - # section "warn" header - slice_prefix="${warn_sep_fg}${rsep}${warn_fg}${warn_bg}${space}" slice_suffix="$space${warn_sep_fg}" slice_joiner="${warn_fg}${warn_bg}${alt_rsep}${space}" slice_empty_prefix="" - # section "warn" slices - __promptline_wrapper "$(__promptline_last_exit_code)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; } - - # section "y" header - slice_prefix="${y_sep_fg}${rsep}${y_fg}${y_bg}${space}" slice_suffix="$space${y_sep_fg}" slice_joiner="${y_fg}${y_bg}${alt_rsep}${space}" slice_empty_prefix="" - # section "y" slices - __promptline_wrapper "$(__promptline_vcs_branch)" "$slice_prefix" "$slice_suffix" && { slice_prefix="$slice_joiner"; } - - # close sections - printf "%s" "$reset" -} -function __promptline { - local last_exit_code="${PROMPTLINE_LAST_EXIT_CODE:-$?}" - - local esc=$'[' end_esc=m - if [[ -n ${ZSH_VERSION-} ]]; then - local noprint='%{' end_noprint='%}' - elif [[ -n ${FISH_VERSION-} ]]; then - local noprint='' end_noprint='' +__devbox_detect_workspace() { + local primary_org="${VIQUEEN_DEVBOX_PRIMARY_ORG:-safetyculture}" + local secondary_org="${VIQUEEN_DEVBOX_SECONDARY_ORG:-labset}" + + if [[ -n "$DEVBOX_WORKSPACES_ROOT" ]]; then + case "$PWD" in + "$DEVBOX_WORKSPACES_ROOT"/viqueen*) export DEVBOX_WORKSPACE="viqueen" ;; + "$DEVBOX_WORKSPACES_ROOT"/"$primary_org"*) export DEVBOX_WORKSPACE="primary" ;; + "$DEVBOX_WORKSPACES_ROOT"/"$secondary_org"*) export DEVBOX_WORKSPACE="secondary" ;; + "$HOME"*) export DEVBOX_WORKSPACE="home" ;; + *) export DEVBOX_WORKSPACE="default" ;; + esac + elif [[ "$PWD" == "$HOME"* ]]; then + export DEVBOX_WORKSPACE="home" else - local noprint='\[' end_noprint='\]' + export DEVBOX_WORKSPACE="default" fi + return 0 +} - # viqueen - local DARK_ORANGE_BG="48;5;166" - local DARK_ORANGE_FG="38;5;166" - local LIGHT_ORANGE_FG="38;5;220" - - # primary org - local primary_org=${VIQUEEN_DEVBOX_PRIMARY_ORG:-safetyculture} - local DARK_PURPLE_BG="48;5;55" - local DARK_PURPLE_FG="38;5;55" - local LIGHT_PURPLE_FG="38;5;135" - - # secondary org - local secondary_org=${VIQUEEN_DEVBOX_SECONDARY_ORG:-labset} - local DARK_BLUE_BG="48;5;20" - local DARK_BLUE_FG="38;5;20" - local LIGHT_BLUE_FG="38;5;110" - - # home - safe - local DARK_GREEN_BG="48;5;35" - local DARK_GREEN_FG="38;5;35" - local LIGHT_GREEN_FG="38;5;231" - - # where are you ? not safe ... no rm -rf please - local DARK_RED_BG="48;5;124" - local DARK_RED_FG="38;5;124" - local LIGHT_RED_FG="38;5;231" - - # default - local a_host_bg=${DARK_RED_BG} - local a_host_fg=${LIGHT_RED_FG} - local a_host_sep=${DARK_RED_FG} - - local workspaces_root=$(git config labset.workspaces.root) - local current_dir=$(pwd) - - if [[ ${current_dir} =~ ^(${HOME}/?(.*))$ ]]; then - local a_host_bg=${DARK_GREEN_BG} - local a_host_fg=${LIGHT_GREEN_FG} - local a_host_sep=${DARK_GREEN_FG} - fi +# cache workspaces root +export DEVBOX_WORKSPACES_ROOT="${DEVBOX_WORKSPACES_ROOT:-$(git config labset.workspaces.root 2>/dev/null)}" - if [[ -n ${workspaces_root} ]]; then - local current_dir=$(pwd) - # viqueen workspace - if [[ ${current_dir} =~ ^(${workspaces_root}/viqueen/?(.*))$ ]]; then - local a_host_bg=${DARK_ORANGE_BG} - local a_host_fg=${LIGHT_ORANGE_FG} - local a_host_sep=${DARK_ORANGE_FG} - # safetyculture workspace - elif [[ ${current_dir} =~ ^(${workspaces_root}/${primary_org}/?(.*))$ ]]; then - local a_host_bg=${DARK_PURPLE_BG} - local a_host_fg=${LIGHT_PURPLE_FG} - local a_host_sep=${DARK_PURPLE_FG} - elif [[ ${current_dir} =~ ^(${workspaces_root}/${secondary_org}/?(.*))$ ]]; then - local a_host_bg=${DARK_BLUE_BG} - local a_host_fg=${LIGHT_BLUE_FG} - local a_host_sep=${DARK_BLUE_FG} - fi - fi - - local wrap="$noprint$esc" end_wrap="$end_esc$end_noprint" - local space=" " - local sep="" - local rsep="" - local alt_sep="" - local alt_rsep="" - local reset="${wrap}0${end_wrap}" - local reset_bg="${wrap}49${end_wrap}" - local green_fg="${wrap}33;0;32${end_wrap}" - local a_fg="${wrap}${a_host_fg}${end_wrap}" - local a_bg="${wrap}${a_host_bg}${end_wrap}" - local a_sep_fg="${wrap}${a_host_sep}${end_wrap}" - local b_fg="${wrap}38;5;231${end_wrap}" - local b_bg="${wrap}48;5;31${end_wrap}" - local b_sep_fg="${wrap}38;5;31${end_wrap}" - local c_fg="${wrap}38;5;250${end_wrap}" - local c_bg="${wrap}48;5;240${end_wrap}" - local c_sep_fg="${wrap}38;5;240${end_wrap}" - local warn_fg="${wrap}38;5;231${end_wrap}" - local warn_bg="${wrap}48;5;52${end_wrap}" - local warn_sep_fg="${wrap}38;5;52${end_wrap}" - local y_fg="${wrap}38;5;250${end_wrap}" - local y_bg="${wrap}48;5;236${end_wrap}" - local y_sep_fg="${wrap}38;5;236${end_wrap}" - if [[ -n ${ZSH_VERSION-} ]]; then - PROMPT="$(__promptline_left_prompt)" - RPROMPT="$(__promptline_right_prompt)" - elif [[ -n ${FISH_VERSION-} ]]; then - if [[ -n "$1" ]]; then - [[ "$1" = "left" ]] && __promptline_left_prompt || __promptline_right_prompt - else - __promptline_ps1 - fi - else - PS1="$(__promptline_ps1)" - fi -} +# starship config +export STARSHIP_CONFIG="${VIQUEEN_DEVBOX_HOME}/cli/starship.toml" +# init starship with workspace detection hook if [[ -n ${ZSH_VERSION-} ]]; then - if [[ ! ${precmd_functions[(r)__promptline]} == __promptline ]]; then - precmd_functions+=(__promptline) - fi -elif [[ -n ${FISH_VERSION-} ]]; then - __promptline "$1" + precmd_functions+=(__devbox_detect_workspace) + eval "$(starship init zsh)" else - if [[ ! "$PROMPT_COMMAND" == *__promptline* ]]; then - PROMPT_COMMAND='__promptline;'$'\n'"$PROMPT_COMMAND" - fi + starship_precmd_user_func="__devbox_detect_workspace" + eval "$(starship init bash)" fi diff --git a/cli/.vimrc b/cli/.vimrc deleted file mode 100644 index 8a50e9aa..00000000 --- a/cli/.vimrc +++ /dev/null @@ -1,122 +0,0 @@ -set nocompatible " be iMproved, required -filetype off " required - -" set the runtime path to include Vundle and initialize -set rtp+=~/.vim/bundle/Vundle.vim -call vundle#begin() -" alternatively, pass a path where Vundle should install plugins -"call vundle#begin('~/some/path/here') - -" let Vundle manage Vundle, required -Plugin 'VundleVim/Vundle.vim' -Plugin 'vim-airline/vim-airline' -Plugin 'vim-airline/vim-airline-themes' -Plugin 'scrooloose/nerdtree' -Plugin 'elzr/vim-json' -Plugin 'kien/ctrlp.vim' -Plugin 'sheerun/vim-polyglot' -Plugin 'sainnhe/edge' -Plugin 'edkolev/promptline.vim' -Plugin 'leafgarland/typescript-vim' -Plugin 'ryanoasis/vim-devicons' -Plugin 'fatih/vim-go' - -" All of your Plugins must be added before the following line -call vundle#end() " required -filetype plugin indent on " required - -set autoread - -au BufNewFile,BufRead .eslintrc set filetype=json -au BufNewFile,BufRead .babelrc set filetype=json -au BufNewFile,BufRead .solicitoriorc set filetype=json - -autocmd BufWritePre * :%s/\s\+$//e - -set encoding=UTF-8 -set lcs+=space:· -set termguicolors - -" Display the colorscheme -set background=dark -colorscheme edge - -""" ui -syntax on -set wildmenu -set ruler -set mouse=a -set cmdheight=2 -set number -set cursorline - -hi CursorLine cterm=bold -hi Normal guibg=NONE ctermbg=NONE - -""" search -set ignorecase -set smartcase -set hlsearch -set incsearch -set magic -set showmatch - -""" text -set expandtab -set smarttab -set shiftwidth=2 -set tabstop=2 -set encoding=utf-8 - -set ai -set si -set wrap - -set backspace=indent,eol,start - -""" airline -set laststatus=2 -let g:airline_theme='badwolf' -let g:airline_powerline_fonts = 1 - -""" ignore -set wildignore+=*/tmp/*,*.so,*.swp,*.zip,*/node_modules,*/target,*/dist,*/build,*/coverage,*/level_store*,.git,.hg,.svn,.idea - -""" shortcuts -nmap ] :m +1 -nmap [ :m -2 - -nmap :NERDTree - -let g:ctrlp_map = '' -let g:ctrlp_cmd = 'CtrlP' - -let g:NERDTreeRespectWildIgnore = 1 -let g:NERDTreeShowHidden=1 -nmap r :NERDTreeFind - -" NERDTress File highlighting - -function! NERDTreeHighlightFile(extension, fg, bg, guifg, guibg) - exec 'autocmd filetype nerdtree highlight ' . a:extension .' ctermbg='. a:bg .' ctermfg='. a:fg .' guibg='. a:guibg .' guifg='. a:guifg - exec 'autocmd filetype nerdtree syn match ' . a:extension .' #^\s\+.*'. a:extension .'$#' -endfunction - -call NERDTreeHighlightFile('jade', 'green', 'none', 'green', '#151515') -call NERDTreeHighlightFile('ini', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('md', 'blue', 'none', '#3366FF', '#151515') -call NERDTreeHighlightFile('yml', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('config', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('conf', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('json', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('html', 'yellow', 'none', 'yellow', '#151515') -call NERDTreeHighlightFile('styl', 'cyan', 'none', 'cyan', '#151515') -call NERDTreeHighlightFile('css', 'cyan', 'none', 'cyan', '#151515') -call NERDTreeHighlightFile('coffee', 'Red', 'none', 'red', '#151515') -call NERDTreeHighlightFile('js', 'Red', 'none', '#ffa500', '#151515') -call NERDTreeHighlightFile('php', 'Magenta', 'none', '#ff00ff', '#151515') - -""" syntastic -let g:syntastic_auto_loc_list = 1 -let g:syntastic_check_on_open = 1 -let g:syntastic_check_on_wq = 0 diff --git a/cli/bin/compose b/cli/bin/compose index 98a463f0..133b38e7 100755 --- a/cli/bin/compose +++ b/cli/bin/compose @@ -32,7 +32,7 @@ function stop() { function profile() { _with_arguments 1 "$@" profile=${1} - vim "${VIQUEEN_DEVBOX_HOME}"/docker-compose/"${profile}".yml + nvim "${VIQUEEN_DEVBOX_HOME}"/docker-compose/"${profile}".yml } # @COMMAND list lists available compose profiles diff --git a/cli/bin/dev b/cli/bin/dev index 7cc278ff..c0f178be 100755 --- a/cli/bin/dev +++ b/cli/bin/dev @@ -52,7 +52,7 @@ lc() { # @COMMAND rc opens .devboxrc file for edit rc() { - vim ${VIQUEEN_DEVBOX_HOME}/cli/.devboxrc + nvim ${VIQUEEN_DEVBOX_HOME}/cli/.devboxrc source ${VIQUEEN_DEVBOX_HOME}/cli/.devboxrc } @@ -82,14 +82,14 @@ licenses() { # VIM ####### -# @COMMAND vimr vim refresh +# @COMMAND vimr nvim plugin sync vimr () { - vim +PluginInstall +qall + NVIM_APPNAME=devbox nvim --headless "+Lazy! sync" +qa } -# @COMMAND vimrc vim config +# @COMMAND vimrc nvim config vimrc() { - vim ${VIQUEEN_DEVBOX_HOME}/cli/.vimrc + nvim ${VIQUEEN_DEVBOX_HOME}/cli/nvim/init.lua } ##### diff --git a/cli/bin/internal b/cli/bin/internal index 2db7861a..6d2f8cd5 100755 --- a/cli/bin/internal +++ b/cli/bin/internal @@ -9,7 +9,7 @@ edit() { then script=${0} fi - vim ${script} + nvim ${script} chmod +x ${script} } diff --git a/cli/bin/selfedit.sh b/cli/bin/selfedit.sh index d9d5c914..7761a234 100755 --- a/cli/bin/selfedit.sh +++ b/cli/bin/selfedit.sh @@ -32,7 +32,7 @@ edit() { then script=${0} fi - vim "${script}" + nvim "${script}" chmod +x "${script}" } diff --git a/cli/nvim/init.lua b/cli/nvim/init.lua new file mode 100644 index 00000000..76687b32 --- /dev/null +++ b/cli/nvim/init.lua @@ -0,0 +1,62 @@ +-- bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not vim.loop.fs_stat(lazypath) then + vim.fn.system({ + "git", "clone", "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + "--branch=stable", + lazypath, + }) +end +vim.opt.rtp:prepend(lazypath) + +-- leader key (before lazy) +vim.g.mapleader = " " + +-- options +vim.opt.number = true +vim.opt.cursorline = true +vim.opt.termguicolors = true +vim.opt.mouse = "a" +vim.opt.ignorecase = true +vim.opt.smartcase = true +vim.opt.hlsearch = true +vim.opt.incsearch = true +vim.opt.showmatch = true +vim.opt.expandtab = true +vim.opt.smarttab = true +vim.opt.shiftwidth = 2 +vim.opt.tabstop = 2 +vim.opt.autoindent = true +vim.opt.smartindent = true +vim.opt.wrap = true +vim.opt.encoding = "utf-8" +vim.opt.backspace = "indent,eol,start" +vim.opt.wildmenu = true +vim.opt.ruler = true +vim.opt.cmdheight = 2 +vim.opt.laststatus = 2 +vim.opt.autoread = true +vim.opt.background = "dark" +vim.opt.wildignore:append("*/tmp/*,*.so,*.swp,*.zip,*/node_modules,*/target,*/dist,*/build,*/coverage,.git,.hg,.svn,.idea") +vim.opt.list = true +vim.opt.listchars = { space = "·" } + +-- strip trailing whitespace on save +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + command = [[%s/\s\+$//e]], +}) + +-- filetype associations +vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { + pattern = { ".eslintrc", ".babelrc" }, + command = "set filetype=json", +}) + +-- keymaps +vim.keymap.set("n", "]", ":m +1", { silent = true }) +vim.keymap.set("n", "[", ":m -2", { silent = true }) + +-- plugins +require("lazy").setup("plugins") diff --git a/cli/nvim/lua/plugins/init.lua b/cli/nvim/lua/plugins/init.lua new file mode 100644 index 00000000..cd7ffd69 --- /dev/null +++ b/cli/nvim/lua/plugins/init.lua @@ -0,0 +1,80 @@ +return { + -- colorscheme + { + "sainnhe/edge", + priority = 1000, + config = function() + vim.cmd.colorscheme("edge") + vim.cmd("hi Normal guibg=NONE ctermbg=NONE") + vim.cmd("hi CursorLine cterm=bold") + end, + }, + + -- statusline + { + "nvim-lualine/lualine.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + opts = { + options = { theme = "auto" }, + }, + }, + + -- file explorer + { + "nvim-tree/nvim-tree.lua", + dependencies = { "nvim-tree/nvim-web-devicons" }, + keys = { + { "", "NvimTreeToggle" }, + { "r", "NvimTreeFindFile" }, + }, + opts = { + respect_buf_cwd = true, + filters = { custom = { "node_modules", ".git" } }, + renderer = { icons = { show = { git = true, file = true, folder = true } } }, + }, + }, + + -- fuzzy finder (replaces ctrlp) + { + "nvim-telescope/telescope.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + keys = { + { "", "Telescope find_files" }, + { "fg", "Telescope live_grep" }, + { "fb", "Telescope buffers" }, + }, + }, + + -- syntax highlighting + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + config = function() + require("nvim-treesitter.configs").setup({ + ensure_installed = { + "lua", "json", "yaml", "toml", "bash", + "javascript", "typescript", "tsx", + "go", "java", "kotlin", + "html", "css", "markdown", + }, + highlight = { enable = true }, + indent = { enable = true }, + }) + end, + }, + + -- lsp + { + "neovim/nvim-lspconfig", + dependencies = { + "williamboman/mason.nvim", + "williamboman/mason-lspconfig.nvim", + }, + config = function() + require("mason").setup() + require("mason-lspconfig").setup({ + automatic_installation = true, + }) + end, + }, +} diff --git a/cli/starship.toml b/cli/starship.toml new file mode 100644 index 00000000..e0616835 --- /dev/null +++ b/cli/starship.toml @@ -0,0 +1,68 @@ +"$schema" = "https://starship.rs/config-schema.json" + +format = """ +${custom.ws_viqueen}\ +${custom.ws_primary}\ +${custom.ws_secondary}\ +${custom.ws_home}\ +${custom.ws_default}\ +$username\ +$directory\ +$git_branch\ +$status\ +$line_break\ +$character""" + +# workspace host segments — mutually exclusive via DEVBOX_WORKSPACE env var +# colors match the original promptline workspace palette + +[custom.ws_viqueen] +command = 'echo "${VIQUEEN_DEVBOX_MACHINE:-$(hostname -s)}"' +when = '[ "$DEVBOX_WORKSPACE" = "viqueen" ]' +format = "[ $output ](fg:220 bg:166)[](fg:166 bg:31)" + +[custom.ws_primary] +command = 'echo "${VIQUEEN_DEVBOX_MACHINE:-$(hostname -s)}"' +when = '[ "$DEVBOX_WORKSPACE" = "primary" ]' +format = "[ $output ](fg:135 bg:55)[](fg:55 bg:31)" + +[custom.ws_secondary] +command = 'echo "${VIQUEEN_DEVBOX_MACHINE:-$(hostname -s)}"' +when = '[ "$DEVBOX_WORKSPACE" = "secondary" ]' +format = "[ $output ](fg:110 bg:20)[](fg:20 bg:31)" + +[custom.ws_home] +command = 'echo "${VIQUEEN_DEVBOX_MACHINE:-$(hostname -s)}"' +when = '[ "$DEVBOX_WORKSPACE" = "home" ]' +format = "[ $output ](fg:231 bg:35)[](fg:35 bg:31)" + +[custom.ws_default] +command = 'echo "${VIQUEEN_DEVBOX_MACHINE:-$(hostname -s)}"' +when = '[ "$DEVBOX_WORKSPACE" = "default" ] || [ -z "$DEVBOX_WORKSPACE" ]' +format = "[ $output ](fg:231 bg:124)[](fg:124 bg:31)" + +[username] +show_always = true +style_user = "fg:231 bg:31" +style_root = "fg:231 bg:31" +format = "[ $user ]($style)[](fg:31 bg:240)" + +[directory] +style = "fg:250 bg:240" +format = "[ $path ]($style)[](fg:240 bg:236)" +truncation_length = 3 +truncation_symbol = "⋯/" + +[git_branch] +style = "fg:250 bg:236" +symbol = " " +format = "[ $symbol$branch ]($style)[](fg:236)" + +[status] +disabled = false +style = "bold red" +format = " [$status]($style)" + +[character] +success_symbol = "[❯](green)" +error_symbol = "[❯](red)" diff --git a/setup.sh b/setup.sh index ef8b8af9..c8ad4214 100755 --- a/setup.sh +++ b/setup.sh @@ -18,14 +18,15 @@ function config_box() { echo "export PATH=${PATH}:${VIQUEEN_DEVBOX_HOME}/modules/cli/bin:${VIQUEEN_DEVBOX_HOME}/cli/bin:~/bin" >> "${rc_file}" ln -sfnv "${VIQUEEN_DEVBOX_HOME}"/cli/.devboxrc "${HOME}/.devboxrc" echo "source ~/.devboxrc" >> "${rc_file}" + # symlink mise config so tools are available globally + ln -sfnv "${VIQUEEN_DEVBOX_HOME}"/.mise.toml "${HOME}/.mise.toml" } function config_vim() { - # setup vim - ln -sfnv "${VIQUEEN_DEVBOX_HOME}"/cli/.vimrc "${HOME}/.vimrc" - ln -sfnv "${VIQUEEN_DEVBOX_HOME}"/.vim "${HOME}/.vim" - git config --global core.editor "vim" - vim +PluginInstall +qall + mkdir -p "${HOME}/.config/devbox" + ln -sfnv "${VIQUEEN_DEVBOX_HOME}"/cli/nvim "${HOME}/.config/devbox/nvim" + git config --global core.editor "nvim" + NVIM_APPNAME=devbox nvim --headless "+Lazy! sync" +qa } function config_prompt() { @@ -34,6 +35,5 @@ function config_prompt() { echo "source ${HOME}/.promptline.sh" >> "${rc_file}" } - # shellcheck disable=SC2068 eval $@