diff --git a/README.md b/README.md
index eb5a33d69bc..88d2ebb8809 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,18 @@
A personalized Neovim configuration based on [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim), tailored for Java and Go development with a focus on clean keybindings, git integration, and a minimal UI.
+## Requirements
+
+- **Neovim 0.10+** (uses `vim.keymap`, `vim.diagnostic.config`, and other modern APIs)
+- **JDK 21+** for Java LSP (jdtls)
+- Nerd Font (JetBrainsMono recommended)
+
## Quick Install
One-liner that installs all dependencies and clones the config (supports **macOS**, **CentOS/RHEL**, and **Azure Linux/CBL-Mariner**):
```sh
-sh -c "$(curl -fsSL https://raw.githubusercontent.com/advpetc/kickstart.nvim/master/install.sh)"
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/advpetc/kickstart.nvim/rdev-setup/install.sh)"
```
This will:
@@ -26,7 +32,7 @@ If you prefer to install dependencies yourself:
```sh
# 1. Clone the config
-git clone https://github.com/advpetc/kickstart.nvim.git ~/.config/nvim
+git clone -b rdev-setup https://github.com/advpetc/kickstart.nvim.git ~/.config/nvim
# 2. Install dependencies (macOS example)
brew install neovim ripgrep fd gh node go
@@ -50,6 +56,26 @@ sudo dnf install -y git make gcc gcc-c++ unzip curl ripgrep fd-find nodejs
+Azure Linux / CBL-Mariner
+
+```sh
+# Neovim (from GitHub release)
+curl -fsSL https://github.com/neovim/neovim/releases/download/v0.10.4/nvim-linux-x86_64.tar.gz -o /tmp/nvim.tar.gz
+sudo mkdir -p /opt/nvim && sudo tar -xzf /tmp/nvim.tar.gz -C /opt/nvim --strip-components=1
+sudo ln -sf /opt/nvim/bin/nvim /usr/local/bin/nvim
+
+# System tools (use tdnf on CBL-Mariner 2.0, dnf on Azure Linux 3.0)
+sudo tdnf install -y git make gcc unzip curl ripgrep nodejs
+
+# fd (not in repos — install from GitHub release)
+FD_VERSION=$(curl -fsSL https://api.github.com/repos/sharkdp/fd/releases/latest | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\1/')
+curl -fsSL "https://github.com/sharkdp/fd/releases/download/v${FD_VERSION}/fd-v${FD_VERSION}-x86_64-unknown-linux-gnu.tar.gz" -o /tmp/fd.tar.gz
+tar -xzf /tmp/fd.tar.gz -C /tmp
+sudo cp /tmp/fd-v${FD_VERSION}-x86_64-unknown-linux-gnu/fd /usr/local/bin/fd
+```
+
+
+
## Plugins
| Plugin | Purpose |
@@ -213,11 +239,21 @@ Sessions are stored in `~/.local/state/nvim/sessions/` via `mini.sessions`:
The Java configuration uses [nvim-jdtls](https://github.com/mfussenegger/nvim-jdtls) with:
-- **JDK 21** (Microsoft build) at `/Library/Java/JavaVirtualMachines/jdk21.0.6-msft.jdk/Contents/Home`
+- **JDK 21+** required (auto-detected, see resolution order below)
- **Gradle & Maven** import support with source downloading
- **DAP debugging** with hot code replace
- **Workspace**: `~/.local/share/nvim/jdtls-workspace/`
+### JDK Resolution Order
+
+1. `JDTLS_JAVA_HOME` environment variable (explicit override)
+2. Known JDK 21 paths on Linux:
+ - `/export/apps/jdk/JDK-21_0_0-msft` (LinkedIn internal)
+ - `/usr/lib/jvm/java-21-openjdk`
+ - `/usr/lib/jvm/java-21-openjdk-amd64`
+3. macOS: `/usr/libexec/java_home -v 21`
+4. `JAVA_HOME` environment variable (fallback)
+
> Run `./gradlew build` before opening a project to generate required jars.
> Use `jx` (`:JdtlsClearCache`) to reset the jdtls workspace if things go wrong.
diff --git a/init.lua b/init.lua
index a448d94cbb1..22c6235eb5e 100644
--- a/init.lua
+++ b/init.lua
@@ -222,12 +222,22 @@ vim.keymap.set('n', '', '', { desc = 'Move focus to the upper win
vim.keymap.set('n', 'cp', function()
local path = vim.fn.expand '%'
vim.fn.setreg('+', path)
+ -- Also copy via OSC 52 for remote SSH sessions
+ local ok, osc52 = pcall(require, 'osc52')
+ if ok then
+ osc52.copy(path)
+ end
print('Copied: ' .. path)
end, { desc = '[C]opy file [P]ath (relative)' })
vim.keymap.set('n', 'cP', function()
local path = vim.fn.expand '%:p'
vim.fn.setreg('+', path)
+ -- Also copy via OSC 52 for remote SSH sessions
+ local ok, osc52 = pcall(require, 'osc52')
+ if ok then
+ osc52.copy(path)
+ end
print('Copied: ' .. path)
end, { desc = '[C]opy file [P]ath (absolute)' })
@@ -240,6 +250,11 @@ vim.keymap.set('n', 'cl', function()
return
end
vim.fn.setreg('+', url)
+ -- Also copy via OSC 52 for remote SSH sessions
+ local ok, osc52 = pcall(require, 'osc52')
+ if ok then
+ osc52.copy(url)
+ end
vim.notify('Copied: ' .. url, vim.log.levels.INFO)
end, { desc = '[C]opy GitHub [L]ink' })
@@ -658,7 +673,9 @@ require('lazy').setup({
-- By default, Neovim doesn't support everything that is in the LSP specification.
-- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities.
-- So, we create new capabilities with blink.cmp, and then broadcast that to the servers.
- local capabilities = require('blink.cmp').get_lsp_capabilities()
+ local capabilities = vim.lsp.protocol.make_client_capabilities()
+ local ok, blink = pcall(require, 'blink.cmp')
+ if ok then capabilities = vim.tbl_deep_extend('force', capabilities, blink.get_lsp_capabilities()) end
-- Enable the following language servers
-- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
@@ -959,20 +976,8 @@ require('lazy').setup({
end,
},
- { -- Highlight, edit, and navigate code
- 'nvim-treesitter/nvim-treesitter',
- config = function()
- local filetypes = { 'bash', 'c', 'diff', 'html', 'java', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' }
- -- Only auto-install parsers if tree-sitter CLI is available
- if vim.fn.executable 'tree-sitter' == 1 then
- require('nvim-treesitter').install(filetypes)
- end
- vim.api.nvim_create_autocmd('FileType', {
- pattern = filetypes,
- callback = function() vim.treesitter.start() end,
- })
- end,
- },
+ -- Note: Neovim 0.11+ has built-in treesitter support
+ -- Treesitter will be enabled automatically for supported filetypes
-- The following comments only work if you have downloaded the kickstart repo, not just copy pasted the
-- init.lua. If you want these files, they are in the repository, so you can just download them and
diff --git a/install.sh b/install.sh
index d9a3d00a3b3..70929bce0f3 100755
--- a/install.sh
+++ b/install.sh
@@ -10,7 +10,7 @@
# bash install.sh --help # show help
#
# One-liner (no clone needed):
-# sh -c "$(curl -fsSL https://raw.githubusercontent.com/advpetc/kickstart.nvim/master/install.sh)"
+# sh -c "$(curl -fsSL https://raw.githubusercontent.com/advpetc/kickstart.nvim/rdev-setup/install.sh)"
#
set -euo pipefail
@@ -481,6 +481,125 @@ install_jdk() {
esac
}
+# ─── Setup JDTLS_JAVA_HOME (LinkedIn environments) ───────────────────────────
+
+setup_jdtls_java_home() {
+ log_step "JDTLS Java Configuration"
+
+ local jdk_base_dir="/export/apps/jdk"
+ local selected_jdk=""
+ local selected_version=0
+ local is_compatible=false
+
+ # Check if the LinkedIn JDK directory exists
+ if [ ! -d "$jdk_base_dir" ]; then
+ log_info "JDK directory $jdk_base_dir not found — skipping JDTLS_JAVA_HOME setup"
+ log_info "If jdtls fails, set JDTLS_JAVA_HOME manually to your Java 21+ installation"
+ return 0
+ fi
+
+ # Scan for all JDK installations and find the best one
+ log_info "Scanning for Java installations in $jdk_base_dir..."
+
+ while IFS= read -r jdk_dir; do
+ local jdk_path="$jdk_base_dir/$jdk_dir"
+
+ # Skip if not a directory or no java binary
+ [ ! -d "$jdk_path" ] && continue
+ [ ! -x "$jdk_path/bin/java" ] && continue
+
+ # Extract version number from directory name (e.g., JDK-21_0_0-msft -> 21)
+ local version_major
+ if [[ "$jdk_dir" =~ JDK-([0-9]+) ]]; then
+ version_major="${BASH_REMATCH[1]}"
+ else
+ continue
+ fi
+
+ # Prefer Java 21+ (compatible with jdtls), but track highest version found
+ if [ "$version_major" -ge 21 ]; then
+ if [ "$version_major" -gt "$selected_version" ]; then
+ selected_jdk="$jdk_path"
+ selected_version="$version_major"
+ is_compatible=true
+ fi
+ elif [ "$version_major" -gt "$selected_version" ]; then
+ # Fallback: track highest version even if < 21
+ selected_jdk="$jdk_path"
+ selected_version="$version_major"
+ fi
+ done < <(ls "$jdk_base_dir" 2>/dev/null)
+
+ # No JDK found at all
+ if [ -z "$selected_jdk" ]; then
+ log_warn "No JDK installations found in $jdk_base_dir"
+ log_info "If jdtls fails, set JDTLS_JAVA_HOME manually to your Java 21+ installation"
+ return 0
+ fi
+
+ # Verify the selected JDK is actually executable
+ if ! "$selected_jdk/bin/java" -version &>/dev/null; then
+ log_warn "Selected JDK at $selected_jdk is not executable"
+ return 0
+ fi
+
+ # Provide appropriate feedback based on version
+ if [ "$is_compatible" = true ]; then
+ log_ok "Found Java $selected_version at $selected_jdk (compatible with jdtls)"
+ else
+ log_warn "Found Java $selected_version at $selected_jdk"
+ log_warn "jdtls requires Java 21+. LSP may fail to start."
+ log_info "Install Java 21+ and re-run this script, or set JDTLS_JAVA_HOME manually"
+ fi
+
+ # Add to .bashrc if not already there
+ if [ -f "$HOME/.bashrc" ]; then
+ if grep -q "export JDTLS_JAVA_HOME=" "$HOME/.bashrc" 2>/dev/null; then
+ log_info "Updating JDTLS_JAVA_HOME in .bashrc..."
+ # Remove old entry and add new one
+ sed -i.bak '/export JDTLS_JAVA_HOME=/d' "$HOME/.bashrc"
+ sed -i.bak '/# Java.*for JDTLS/d' "$HOME/.bashrc"
+ else
+ log_info "Adding JDTLS_JAVA_HOME to .bashrc..."
+ fi
+ cat >> "$HOME/.bashrc" </dev/null; then
+ log_info "Updating JDTLS_JAVA_HOME in .zshrc..."
+ # Remove old entry and add new one
+ sed -i.bak '/export JDTLS_JAVA_HOME=/d' "$HOME/.zshrc"
+ sed -i.bak '/# Java.*for JDTLS/d' "$HOME/.zshrc"
+ else
+ log_info "Adding JDTLS_JAVA_HOME to .zshrc..."
+ fi
+ cat >> "$HOME/.zshrc" <y', require('osc52').copy_visual, { desc = 'Copy to system clipboard (OSC52)' })
+ end,
+ },
+}
diff --git a/lua/custom/plugins/git.lua b/lua/custom/plugins/git.lua
index 6c0739cb73a..4dc3036f751 100644
--- a/lua/custom/plugins/git.lua
+++ b/lua/custom/plugins/git.lua
@@ -8,6 +8,8 @@ return {
{ 'gh', 'DiffviewFileHistory %', desc = 'Git file history' },
{ 'gH', 'DiffviewFileHistory', desc = 'Git branch history' },
{ 'gc', 'DiffviewClose', desc = 'Close diff view' },
+ { 'gR', '!git reset --hard', desc = 'Git reset --hard (entire repo)' },
+ { 'gr', '!git reset', desc = 'Git reset (unstage all, keep changes)' },
},
opts = {
enhanced_diff_hl = true,
diff --git a/lua/custom/plugins/java.lua b/lua/custom/plugins/java.lua
index 8a15a3d6a90..694c90dcd1e 100644
--- a/lua/custom/plugins/java.lua
+++ b/lua/custom/plugins/java.lua
@@ -10,11 +10,22 @@ return {
},
config = function()
-- Resolve Java home for running jdtls (needs JDK 21+)
- -- Priority: JDTLS_JAVA_HOME > JAVA_HOME > macOS java_home > java on PATH
+ -- Priority: JDTLS_JAVA_HOME > known JDK 21 locations > macOS java_home > JAVA_HOME
local function resolve_java_home()
- local home = vim.env.JDTLS_JAVA_HOME or vim.env.JAVA_HOME
+ -- Check explicit JDTLS_JAVA_HOME first
+ local home = vim.env.JDTLS_JAVA_HOME
if home and home ~= '' then return home end
+ -- Check known JDK 21+ locations on Linux
+ local jdk21_paths = {
+ '/export/apps/jdk/JDK-21_0_0-msft',
+ '/usr/lib/jvm/java-21-openjdk',
+ '/usr/lib/jvm/java-21-openjdk-amd64',
+ }
+ for _, path in ipairs(jdk21_paths) do
+ if vim.fn.isdirectory(path) == 1 then return path end
+ end
+
if vim.fn.has 'mac' == 1 then
-- Try JDK 21 first, then any version
home = vim.fn.trim(vim.fn.system '/usr/libexec/java_home -v 21 2>/dev/null')
@@ -24,6 +35,10 @@ return {
if home ~= '' then return home end
end
+ -- Fall back to JAVA_HOME (may not be JDK 21+)
+ home = vim.env.JAVA_HOME
+ if home and home ~= '' then return home end
+
local java_bin = vim.fn.exepath 'java'
if java_bin ~= '' then
return vim.fn.fnamemodify(vim.fn.resolve(java_bin), ':h:h')
@@ -185,7 +200,12 @@ return {
map('dx', dap.terminate, 'Terminate')
end,
- capabilities = require('blink.cmp').get_lsp_capabilities(),
+ capabilities = (function()
+ local caps = vim.lsp.protocol.make_client_capabilities()
+ local ok, blink = pcall(require, 'blink.cmp')
+ if ok then caps = vim.tbl_deep_extend('force', caps, blink.get_lsp_capabilities()) end
+ return caps
+ end)(),
}
jdtls.start_or_attach(config)
@@ -197,8 +217,10 @@ return {
callback = start_jdtls,
})
- -- Start immediately for current buffer
- start_jdtls()
+ -- Start immediately only if current buffer is a Java file
+ if vim.bo.filetype == 'java' then
+ start_jdtls()
+ end
end,
},
}