Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 223 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# Modern Neovim Configuration

A modern, fully-featured Neovim configuration optimized for Java, TypeScript, Golang, Python, and Bash development.

## Features

### Core
- **lazy.nvim** - Modern, fast plugin manager
- **mason.nvim** - Easy LSP/DAP/formatter installer
- **Treesitter** - Advanced syntax highlighting
- **Telescope** - Fuzzy finder and navigation
- **Which-key** - Keybinding helper

### Language Support
- **Java** - Spring Boot & Gradle with nvim-jdtls
- **TypeScript/JavaScript** - React & Vite with ts_ls
- **Golang** - Full LSP support with gopls and vim-go
- **Python** - Pyright LSP + Jupyter notebooks (molten-nvim)
- **Bash** - Shell scripting with bashls

### Development Tools
- **LSP** - Language servers for all supported languages
- **DAP** - Debugging for Go, Python, and Java
- **Linting** - nvim-lint with language-specific linters
- **Formatting** - conform.nvim with auto-format on save
- **Git Integration** - Gitsigns and Lazygit
- **File Explorer** - nvim-tree with VS Code-like sidebar
- **Terminal** - toggleterm with bottom horizontal layout (VS Code style)

## Installation

1. Backup your existing config:
```bash
mv ~/.config/nvim ~/.config/nvim.backup
```

2. Clone this repository:
```bash
git clone <your-repo-url> ~/.config/nvim
```

3. Start Neovim:
```bash
nvim
```

4. lazy.nvim will automatically install all plugins. Once complete, run:
```
:Mason
```

All LSP servers, formatters, and linters will be automatically installed by mason-tool-installer.

## Key Bindings

Leader key: `Space`

### General
- `<leader>e` - Toggle file explorer
- `<leader>w` - Save file
- `<leader>q` - Quit
- `<leader>c` - Close buffer
- `<leader>h` - Clear search highlight
- `<leader>f` - Format file
- `Ctrl+p` - Find files (Telescope)
- `Ctrl+f` - Search text (Telescope)
- `Ctrl+\` - Toggle terminal

### Window Navigation
- `Ctrl+h/j/k/l` - Navigate between windows
- `Shift+h/l` - Navigate between buffers
- `Shift+arrows` - Resize windows

### LSP
- `gd` - Go to definition
- `gD` - Go to declaration
- `gr` - References
- `gi` - Go to implementation
- `K` - Show hover documentation
- `<leader>la` - Code action
- `<leader>lr` - Rename
- `<leader>lf` - Format
- `<leader>ld` - Show diagnostics
- `<leader>lj/k` - Next/previous diagnostic

### Debugging (DAP)
- `<leader>db` - Toggle breakpoint
- `<leader>dB` - Conditional breakpoint
- `<leader>dc` - Continue
- `<leader>di` - Step into
- `<leader>do` - Step over
- `<leader>dO` - Step out
- `<leader>du` - Toggle DAP UI
- `<leader>dt` - Terminate debug session

### Java-specific (Spring Boot)
- `<leader>jo` - Organize imports
- `<leader>jv` - Extract variable
- `<leader>jc` - Extract constant
- `<leader>jm` - Extract method
- `<leader>jt` - Test class
- `<leader>jn` - Test nearest method

### Jupyter Notebooks (Python)
- `<leader>mi` - Initialize Molten
- `<leader>me` - Evaluate selection
- `<leader>ml` - Evaluate line
- `<leader>mr` - Re-evaluate cell
- `<leader>mo` - Show output
- `<leader>mh` - Hide output

### Git
- `<leader>gg` - Lazygit
- `<leader>gj/k` - Next/previous hunk
- `<leader>gl` - Blame line
- `<leader>gp` - Preview hunk
- `<leader>gs` - Stage hunk
- `<leader>gr` - Reset hunk

### Search (Telescope)
- `<leader>sf` - Find files
- `<leader>st` - Live grep (search text)
- `<leader>sb` - Git branches
- `<leader>sc` - Colorschemes
- `<leader>sh` - Help tags
- `<leader>sr` - Recent files
- `<leader>sk` - Keymaps

### Terminal
- `<leader>tt` - Toggle terminal
- `<leader>tg` - Lazygit
- `<leader>tn` - Node REPL
- `<leader>th` - Htop

## Language Setup Notes

### Java (Spring Boot)
- Requires Java 17+ installed
- Set `JAVA_HOME` environment variable
- Gradle/Maven projects auto-detected
- Run tests: `<leader>jt` or `<leader>jn`

### TypeScript/React
- Install Node.js and npm
- Works with Vite, Create React App, and Next.js
- ESLint/Prettier auto-formatting on save

### Golang
- Install Go 1.21+
- Auto-formatting with gofumpt and goimports
- Run tests with vim-go: `:GoTest`
- Debug with DAP: `<leader>dc`

### Python (Jupyter)
- Install Python 3.8+
- Jupyter support via molten-nvim
- Initialize kernel: `<leader>mi`
- Evaluate cells: `<leader>me` or `<leader>ml`

### Bash
- Shell script linting with shellcheck
- Formatting with shfmt
- Full LSP support

## Customization

All configuration files are in `~/.config/nvim/lua/user/`:

- `options.lua` - General Neovim settings
- `keymaps.lua` - Custom keybindings
- `lazy.lua` - Plugin specifications
- `lsp/` - LSP configuration
- `conform.lua` - Formatter configuration
- `lint.lua` - Linter configuration
- `dap.lua` - Debugger configuration

## Troubleshooting

### LSP not working
1. Check installed servers: `:Mason`
2. Check LSP status: `:LspInfo`
3. Restart LSP: `:LspRestart`

### Formatters not working
1. Check Mason: `:Mason`
2. Check conform: `:ConformInfo`
3. Manually format: `<leader>f` or `:Format`

### Java not working
1. Verify JAVA_HOME: `echo $JAVA_HOME`
2. Check jdtls: `:LspInfo` in a .java file
3. Restart Neovim

### Jupyter notebooks not working
1. Install Python plugin: `:UpdateRemotePlugins`
2. Initialize molten: `<leader>mi`
3. Select kernel: `:MoltenInit python3`

## Requirements

- Neovim >= 0.9.0
- Git
- Node.js >= 18 (for TypeScript/JavaScript)
- Python >= 3.8 (for Python development)
- Go >= 1.21 (for Golang development)
- Java >= 17 (for Java development)
- A Nerd Font (for icons)
- ripgrep (for Telescope text search)
- fd (for Telescope file search)

## Credits

This configuration is built with these excellent plugins:
- [lazy.nvim](https://github.com/folke/lazy.nvim)
- [mason.nvim](https://github.com/williamboman/mason.nvim)
- [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig)
- [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- [nvim-dap](https://github.com/mfussenegger/nvim-dap)
- [nvim-jdtls](https://github.com/mfussenegger/nvim-jdtls)
- [molten-nvim](https://github.com/benlubas/molten-nvim)

And many more!
148 changes: 148 additions & 0 deletions ftplugin/java.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
-- Java-specific configuration using nvim-jdtls
local status_ok, jdtls = pcall(require, "jdtls")
if not status_ok then
return
end

-- Determine OS
local home = os.getenv("HOME")
local jdtls_path = vim.fn.stdpath("data") .. "/mason/packages/jdtls"
local workspace_path = home .. "/.local/share/nvim/jdtls-workspace/"
local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t")
local workspace_dir = workspace_path .. project_name

-- Find Java installation
local function get_java_executable()
local java_home = os.getenv("JAVA_HOME")
if java_home then
return java_home .. "/bin/java"
end
return "java"
end

-- JDTLS configuration
local config = {
cmd = {
get_java_executable(),
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.protocol=true",
"-Dlog.level=ALL",
"-Xmx1g",
"--add-modules=ALL-SYSTEM",
"--add-opens", "java.base/java.util=ALL-UNNAMED",
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
"-jar", vim.fn.glob(jdtls_path .. "/plugins/org.eclipse.equinox.launcher_*.jar"),
"-configuration", jdtls_path .. "/config_linux",
"-data", workspace_dir,
},

root_dir = require("jdtls.setup").find_root({ ".git", "mvnw", "gradlew", "pom.xml", "build.gradle" }),

settings = {
java = {
eclipse = {
downloadSources = true,
},
configuration = {
updateBuildConfiguration = "interactive",
runtimes = {
{
name = "JavaSE-17",
path = os.getenv("JAVA_HOME") or "/usr/lib/jvm/java-17-openjdk",
},
},
},
maven = {
downloadSources = true,
},
implementationsCodeLens = {
enabled = true,
},
referencesCodeLens = {
enabled = true,
},
references = {
includeDecompiledSources = true,
},
format = {
enabled = true,
settings = {
url = vim.fn.stdpath("config") .. "/lang-servers/intellij-java-google-style.xml",
profile = "GoogleStyle",
},
},
signatureHelp = { enabled = true },
contentProvider = { preferred = "fernflower" },
completion = {
favoriteStaticMembers = {
"org.hamcrest.MatcherAssert.assertThat",
"org.hamcrest.Matchers.*",
"org.hamcrest.CoreMatchers.*",
"org.junit.jupiter.api.Assertions.*",
"java.util.Objects.requireNonNull",
"java.util.Objects.requireNonNullElse",
"org.mockito.Mockito.*",
},
importOrder = {
"java",
"javax",
"com",
"org",
},
},
sources = {
organizeImports = {
starThreshold = 9999,
staticStarThreshold = 9999,
},
},
codeGeneration = {
toString = {
template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}",
},
useBlocks = true,
},
},
},

flags = {
allow_incremental_sync = true,
},

init_options = {
bundles = {},
},

on_attach = function(client, bufnr)
-- Regular LSP on_attach
require("user.lsp.handlers").on_attach(client, bufnr)

-- Java-specific keymaps
local opts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set("n", "<leader>jo", "<Cmd>lua require'jdtls'.organize_imports()<CR>", opts)
vim.keymap.set("n", "<leader>jv", "<Cmd>lua require('jdtls').extract_variable()<CR>", opts)
vim.keymap.set("v", "<leader>jv", "<Esc><Cmd>lua require('jdtls').extract_variable(true)<CR>", opts)
vim.keymap.set("n", "<leader>jc", "<Cmd>lua require('jdtls').extract_constant()<CR>", opts)
vim.keymap.set("v", "<leader>jc", "<Esc><Cmd>lua require('jdtls').extract_constant(true)<CR>", opts)
vim.keymap.set("v", "<leader>jm", "<Esc><Cmd>lua require('jdtls').extract_method(true)<CR>", opts)
vim.keymap.set("n", "<leader>jt", "<Cmd>lua require'jdtls'.test_class()<CR>", opts)
vim.keymap.set("n", "<leader>jn", "<Cmd>lua require'jdtls'.test_nearest_method()<CR>", opts)

-- Enable codelens
if client.server_capabilities.codeLensProvider then
vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, {
buffer = bufnr,
callback = function()
vim.lsp.codelens.refresh()
end,
})
end
end,

capabilities = require("user.lsp.handlers").capabilities,
}

-- Start jdtls
jdtls.start_or_attach(config)
21 changes: 6 additions & 15 deletions init.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
-- Core settings
require("user.options")
require("user.keymaps")
require("user.plugins")

-- Plugin manager (lazy.nvim)
require("user.lazy")

-- Theme
require("user.colorscheme")
require("user.cmp")
require("user.lsp")
require("user.telescope")
require("user.treesitter")
require("user.autopairs")
require("user.comment")
require("user.gitsigns")
require("user.nvim-tree")
require("user.bufferline")
require("user.lualine")
require("user.toggleterm")
require("user.impatient")
require("user.golang")
require("user.coc")
Loading