Skip to content

Instantly share code, notes, and snippets.

@f2janyway
Last active January 12, 2026 00:11
Show Gist options
  • Select an option

  • Save f2janyway/ec30f0a07812d6694b835b121c3b30b7 to your computer and use it in GitHub Desktop.

Select an option

Save f2janyway/ec30f0a07812d6694b835b121c3b30b7 to your computer and use it in GitHub Desktop.
nvim lsp setting basic
-- ===============================================
-- 1. 기본 Vim/Neovim 설정 (Options) ~/.config/nvim/init.lua
-- ===============================================
-- 시스템 클립보드 사용 활성화
vim.opt.clipboard = "unnamedplus"
-- 줄 번호 표시
vim.opt.number = true
-- 탭 관련 설정
vim.opt.tabstop = 4 -- 탭의 실제 너비를 4칸으로 설정
vim.opt.shiftwidth = 4 -- 자동 들여쓰기 너비를 4칸으로 설정
vim.opt.expandtab = true -- 탭 문자를 공백으로 변환
-- ===============================================
-- 자동 들여쓰기 관련 기본 옵션
-- ===============================================
-- 들여쓰기 스타일을 파일 타입에 맞게 자동으로 선택합니다.
vim.opt.autoindent = true
-- 파일 타입에 따라 스마트한 들여쓰기(예: C/Python 구문 인식)를 활성화합니다.
vim.opt.smartindent = true
-- ===============================================
-- 2. 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)
-- ===============================================
-- 3. 플러그인 로드 및 LSP 설정
-- ===============================================
require("lazy").setup({
{
-- nvim-lspconfig: LSP 서버의 기본 설정 파일 모음
'neovim/nvim-lspconfig',
dependencies = {
-- mason.nvim: LSP 서버 실행 파일을 쉽게 설치/관리
'williamboman/mason.nvim',
-- mason-lspconfig.nvim: mason과 lspconfig를 연결하여 자동 설정
'williamboman/mason-lspconfig.nvim',
},
config = function()
-- Mason 설치/설정
require('mason').setup()
-- Mason과 lspconfig 연결 설정
local lspconfig = require('lspconfig')
local mason_lspconfig = require('mason-lspconfig')
-- 모든 서버에 적용될 단축키 설정 함수
local on_attach = function(client, bufnr)
-- 버퍼 로컬 키맵을 생성합니다.
local buf_set_keymap = vim.api.nvim_buf_set_keymap
local opts = { noremap = true, silent = true }
-- 정의/선언 이동
buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
-- 마우스 오버 정보 (K)
buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
-- 심볼 검색 (gW)
buf_set_keymap(bufnr, 'n', 'gW', '<cmd>lua vim.lsp.buf.workspace_symbol()<CR>', opts)
-- 코드 액션 (F8)
buf_set_keymap(bufnr, 'n', '<F8>', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
-- 자동 완성 (C-x C-o)는 Insert 모드에서만 사용되므로 여기에 직접 설정할 필요 없음.
-- completion 플러그인 (nvim-cmp)이 없으면 수동으로:
-- vim.api.nvim_buf_set_keymap(bufnr, 'i', '<C-Space>', '<cmd>lua vim.lsp.buf.completion()<CR>', {silent = true})
end
mason_lspconfig.setup({
-- 이 리스트에 포함된 서버는 Neovim 시작 시 자동으로 설치됩니다.
ensure_installed = {
"lua_ls", -- Neovim 설정 파일용 Lua
"pyright", -- Python (가장 대중적인 서버)
"clangd", -- C/C++
"jdtls", -- Java
"ts_ls", -- JavaScript/TypeScript
"kotlin_language_server",
"rust_analyzer",
},
-- 설치된 모든 서버에 대해 nvim-lspconfig의 기본 설정을 적용합니다.
handlers = {
function(server_name)
-- lspconfig[server_name].setup({})가 서버를 활성화하는 핵심 코드입니다.
lspconfig[server_name].setup({
-- 여기에 모든 서버에 공통으로 적용할 설정을 넣을 수 있습니다.
on_attatch = on_attach
})
end,
-- 특정 언어에 대한 추가 설정은 여기에 넣을 수 있습니다. (예: lua_ls)
["lua_ls"] = function()
lspconfig.lua_ls.setup({
settings = {
Lua = {
runtime = { version = 'LuaJIT' }
}
}
})
end,
},
})
end
},
-- ... (기존 nvim-lspconfig 설정 블록은 그대로 둡니다.)
{
-- nvim-cmp: 자동 완성 관리자
'hrsh7th/nvim-cmp',
dependencies = {
-- LSP 소스 (LSP 서버의 추천 목록을 cmp에 제공)
'hrsh7th/cmp-nvim-lsp',
-- 스니펫 엔진 (완성 시 코드 조각 삽입 기능)
'L3MON4D3/LuaSnip',
-- LuaSnip 소스
'saadparwaiz1/cmp_luasnip',
},
config = function()
local cmp = require('cmp')
local luasnip = require('luasnip')
cmp.setup({
-- 스니펫 확장 설정
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
-- 자동 완성 키맵 설정 (핵심)
mapping = cmp.mapping.preset.insert({
-- ⭐ 자동 완성 메뉴 이동: j/k 대신 <C-n> / <C-p> 사용이 일반적입니다.
-- 메뉴가 떴을 때 <Down>(j 역할)이나 <Up>(k 역할)을 누르면 이동합니다.
['<Down>'] = cmp.mapping.select_next_item(),
['<Up>'] = cmp.mapping.select_prev_item(),
-- 전통적인 Vim 완성 키맵 (C-n: 다음, C-p: 이전)
['<C-n>'] = cmp.mapping.select_next_item(),
['<C-p>'] = cmp.mapping.select_prev_item(),
-- 엔터키: 선택된 항목을 확정
['<CR>'] = cmp.mapping.confirm({ select = true }),
-- 수동으로 완성 메뉴 띄우기
['<C-Space>'] = cmp.mapping.complete(),
}),
-- 자동 완성 소스 우선순위 설정
sources = cmp.config.sources({
{ name = 'nvim_lsp' }, -- LSP 서버가 제공하는 추천 목록
{ name = 'luasnip' }, -- 스니펫 목록
}, {
{ name = 'buffer' }, -- 현재 버퍼의 단어 목록
}),
-- 완성 메뉴 UI 설정
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
-- 최소 글자 수 설정 (1글자 입력 후 자동 완성 시작)
completion = {
completeopt = 'menu,menuone,preview,noselect',
},
})
end
},
})
------------------------------------------------------------
-- 0) 기본 옵션 / 공통 설정 (Mac + Jetson)
------------------------------------------------------------
vim.opt.termguicolors = true
vim.cmd("syntax on")
--vim.opt.clipboard = "unnamedplus" -- 시스템 클립보드 (맥 pbcopy, 리눅스 xclip / wl-clipboard 필요)
vim.opt.number = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smartindent = true
------------------------------------------------------------
-- 1) NETRW 경로 복사 함수 (맥에서 쓰던 기능 유지)
------------------------------------------------------------
local function copy_netrw_path()
local file_name = vim.fn.expand("<cfile>")
local full_path
if vim.bo.filetype == "netrw" then
local netrw_dir = vim.b.netrw_curdir
if file_name ~= "." and file_name ~= ".." then
full_path = netrw_dir .. "/" .. file_name
else
full_path = netrw_dir
end
else
full_path = vim.fn.expand("%:p")
end
full_path = vim.fn.fnamemodify(full_path, ":p")
vim.fn.setreg("+", full_path)
vim.notify("Copied Path: " .. full_path, vim.log.levels.INFO)
end
------------------------------------------------------------
-- 2) 글로벌 키맵 (맥에서 쓰던 것 + Jetson 공통)
------------------------------------------------------------
local map = vim.api.nvim_set_keymap
local opts = { noremap = true, silent = true }
-- leader prefix 충돌 방지
map("n", "<leader>s", "<Nop>", opts)
-- quickfix
map("n", "<leader>e", "<cmd>oldfiles<CR><cmd>copen<CR>", opts)
map("n", "<leader>q", "<cmd>cclose<CR>", opts)
-- diagnostics
map("n", "Q", "<cmd>lua vim.diagnostic.open_float()<CR>", opts)
map("n", "]d", "<cmd>lua vim.diagnostic.goto_next()<CR>", opts)
map("n", "[d", "<cmd>lua vim.diagnostic.goto_prev()<CR>", opts)
-- netrw 관련
map("n", "<leader>c", "<cmd>lua copy_netrw_path()<CR>", opts)
map("n", "<leader>cc", ':let @+ = expand("%:t")<CR>', opts)
------------------------------------------------------------
-- 3) LSP 키맵: Neovim 0.11 방식 (맥/Jetson 공통)
-- 예전 on_attach 대신 LspAttach 사용
------------------------------------------------------------
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local bufnr = args.buf
local bufopts = { noremap = true, silent = true, buffer = bufnr }
-- 맥에서 쓰던 LSP 키맵 최대한 동일하게
vim.keymap.set("n", "gd", vim.lsp.buf.definition, bufopts)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, bufopts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts)
vim.keymap.set("n", "gW", vim.lsp.buf.workspace_symbol, bufopts)
vim.keymap.set("n", "<F8>", vim.lsp.buf.code_action, bufopts)
vim.keymap.set("i", "<C-s>", vim.lsp.buf.signature_help, bufopts)
end,
})
---------------------------------------------------------------
-- 4) Terminal 동작 (nested nvim 완전 보호 버전)
-- 원하는 로직:
-- - 터미널 모드에서 Esc는 "항상" 터미널로 전달 (nested nvim 정상)
-- - 바깥 nvim의 터미널-normal은 별도 키로만 진입
------------------------------------------------------------
local TERM_AUTO_INSERT = true
vim.api.nvim_create_autocmd("TermOpen", {
pattern = "*",
callback = function()
if TERM_AUTO_INSERT then
vim.cmd("startinsert")
end
end,
})
-- ✅ 핵심: Esc는 절대 가로채지 않고 그대로 보냄 (nested nvim 100% 정상)
vim.keymap.set("t", "<Esc>", "<Esc>", { noremap = true, silent = true })
-- ✅ 바깥 nvim(터미널-normal)로 빠져나오기: Ctrl+\ Ctrl+n (기본)
-- 자주 쓰면 한 키로도 추가
vim.keymap.set("t", "<C-q>", "<C-\\><C-n>", { noremap = true, silent = true })
-- 터미널-normal에서 다시 터미널 입력으로: i/I/a/A
vim.api.nvim_create_autocmd("TermEnter", {
pattern = "*",
callback = function()
if vim.bo.buftype ~= "terminal" then return end
vim.keymap.set("n", "i", function() vim.cmd("startinsert") end, { buffer = true, noremap = true, silent = true })
vim.keymap.set("n", "I", function() vim.cmd("startinsert") end, { buffer = true, noremap = true, silent = true })
vim.keymap.set("n", "a", function() vim.cmd("startinsert") end, { buffer = true, noremap = true, silent = true })
vim.keymap.set("n", "A", function() vim.cmd("startinsert") end, { buffer = true, noremap = true, silent = true })
end,
})
------------------------------------------------------
-- 5) lazy.nvim 부트스트랩 (Neovim 0.11, uv 사용)
------------------------------------------------------------
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.uv.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)
------------------------------------------------------------
-- 6) 포매팅 관련 글로벌 키맵 & 명령어 (맥 설정 유지)
------------------------------------------------------------
vim.keymap.set("n", "<leader>fs", function()
vim.lsp.buf.format({ async = true })
end, { desc = "LSP Format (async)" })
vim.keymap.set("n", "<leader>fm", function()
vim.lsp.buf.format({ async = false })
end, { desc = "LSP Format (sync)" })
vim.api.nvim_create_user_command("FMT", function()
vim.lsp.buf.format({ async = false })
end, { desc = "Format buffer with LSP (sync)" })
vim.api.nvim_create_user_command("FMTA", function()
vim.lsp.buf.format({ async = true })
end, { desc = "Format buffer with LSP (async)" })
vim.api.nvim_create_user_command("VIMFMT", "normal! gg=G", { desc = "Vim 기본 indent 정렬" })
------------------------------------------------------------
-- 7) 플러그인 설정 (맥 + Jetson 공통)
-- Telescope / tokyonight / Treesitter / LSP / nvim-cmp
------------------------------------------------------------
require("lazy").setup({
----------------------------------------------------------
-- Telescope (IntelliJ 느낌 파일/검색 + 맥에서 쓰던 gd/ff 등)
----------------------------------------------------------
{
"nvim-telescope/telescope.nvim",
branch = "0.1.x",
dependencies = {
"nvim-lua/plenary.nvim",
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "make",
},
},
config = function()
local telescope = require("telescope")
local actions = require("telescope.actions")
telescope.setup({
defaults = {
mappings = {
i = {
["<Esc>"] = actions.close,
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
},
},
file_ignore_patterns = { "%.git/", "node_modules/", "build/", "dist/" },
},
pickers = {
find_files = { hidden = true },
},
})
pcall(telescope.load_extension, "fzf")
local builtin = require("telescope.builtin")
-- IntelliJ 스타일 키맵 (맥/Jetson 공통)
vim.keymap.set("n", "<C-p>", function()
builtin.find_files({ previewer = false })
end, { noremap = true, silent = true, desc = "Find files" })
vim.keymap.set("n", "<C-e>", function()
builtin.oldfiles({ previewer = false })
end, { noremap = true, silent = true, desc = "Recent files" })
vim.keymap.set("n", "<C-S-f>", function()
builtin.live_grep()
end, { noremap = true, silent = true, desc = "Live grep" })
vim.keymap.set("n", "<C-f>", function()
builtin.current_buffer_fuzzy_find()
end, { noremap = true, silent = true, desc = "Fuzzy in current buffer" })
vim.keymap.set("n", "<C-b>", function()
builtin.buffers({ previewer = false, sort_mru = true })
end, { noremap = true, silent = true, desc = "Buffers" })
vim.keymap.set("n", "<C-t>", function()
builtin.lsp_document_symbols()
end, { noremap = true, silent = true, desc = "Document symbols" })
-- 맥 설정에서 쓰던 gd를 Telescope로도 사용하고 싶다면:
vim.keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", { noremap = true, silent = true })
end,
},
----------------------------------------------------------
-- Colorscheme
----------------------------------------------------------
{
"folke/tokyonight.nvim",
priority = 1000,
config = function()
vim.cmd("colorscheme tokyonight")
end,
},
----------------------------------------------------------
-- Treesitter
----------------------------------------------------------
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
local ok, configs = pcall(require, "nvim-treesitter.configs")
if not ok then return end
configs.setup({
ensure_installed = { "python", "lua", "json", "bash", "cpp", "java", "javascript", "kotlin", "rust" },
highlight = { enable = true },
indent = { enable = true },
})
end,
},
----------------------------------------------------------
-- LSP: mason + mason-lspconfig (Neovim 0.11 스타일)
----------------------------------------------------------
{
"neovim/nvim-lspconfig",
dependencies = {
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
},
config = function()
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = {
"lua_ls",
"pyright",
"jdtls",
"ts_ls",
"kotlin_language_server",
"rust_analyzer",
},
})
local capabilities = vim.lsp.protocol.make_client_capabilities()
local ok, cmp_lsp = pcall(require, "cmp_nvim_lsp")
if ok then
capabilities = cmp_lsp.default_capabilities(capabilities)
end
local function setup(server, extra)
local base = vim.lsp.config[server] or {}
vim.lsp.config(server, vim.tbl_deep_extend(
"force",
base,
{ capabilities = capabilities },
extra or {}
))
end
setup("lua_ls", {
settings = {
Lua = {
runtime = { version = "LuaJIT" },
diagnostics = { globals = { "vim" } },
},
},
})
setup("pyright")
--setup("pyright", {
-- settings = {
-- python = {
-- analysis = {
-- -- 중요: 라이브러리 전체를 인덱싱하는 것을 방지
-- useLibraryCodeForTypes = true,
-- diagnosticMode = "openFilesOnly", -- 현재 열린 파일만 진단 (메모리 절약)
-- typeCheckingMode = "off", -- "strict" 대신 "basic" 사용
-- indexing = false,
-- autoSearchPaths = true,
-- },
-- },
-- },
-- -- Node.js의 메모리 사용량 강제 제한 (300MB 정도로 제한)
-- cmd = { "pyright-langserver", "--stdio", "--node-args=--max-old-space-size=200" },
-- })
setup("jdtls")
setup("ts_ls")
setup("kotlin_language_server")
setup("rust_analyzer")
if vim.fn.executable("clangd") == 1 then
setup("clangd", {
cmd = {
"clangd",
"--background-index",
"--clang-tidy",
"--fallback-style=LLVM",
"--all-scopes-completion",
"--header-insertion=iwyu",
},
})
vim.lsp.enable("clangd")
end
-- 나머지 서버들도 enable
vim.lsp.enable("lua_ls")
vim.lsp.enable("pyright")
vim.lsp.enable("jdtls")
vim.lsp.enable("ts_ls")
vim.lsp.enable("kotlin_language_server")
vim.lsp.enable("rust_analyzer")
end,
},
----------------------------------------------------------
-- nvim-cmp (자동완성)
----------------------------------------------------------
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"L3MON4D3/LuaSnip",
"saadparwaiz1/cmp_luasnip",
},
config = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
experimental = { ghost_text = false },
mapping = cmp.mapping.preset.insert({
["<Down>"] = cmp.mapping.select_next_item(),
["<Up>"] = cmp.mapping.select_prev_item(),
["<C-n>"] = cmp.mapping.select_next_item(),
["<C-p>"] = cmp.mapping.select_prev_item(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<C-Space>"] = cmp.mapping.complete(),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
}, {
{ name = "buffer" },
}),
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
completion = {
completeopt = "menu,menuone,preview,noselect",
},
})
end,
},
{
'ojroques/nvim-osc52',
config = function()
local osc52 = require('osc52')
osc52.setup({
silent = true, -- 알림이 너무 자주 뜨면 시끄러우니 true 권장
trim = true,
})
-- 핵심: 복사(y)할 때 자동으로 OSC 52를 사용하도록 설정
local function copy()
if vim.v.event.operator == 'y' and vim.v.event.regname == '+' then
osc52.copy_register('+')
end
end
vim.api.nvim_create_autocmd('TextYankPost', { callback = copy })
-- 맥 스타일 단축키 (선택 사항)
vim.keymap.set('n', '<leader>y', osc52.copy_operator, {expr = true})
vim.keymap.set('v', '<leader>y', osc52.copy_visual)
end
},
})
------------------------------------------------------------
-- 끝
------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment