From 94ed302d0bec6a234bcf4072dcadc8545e5e698f Mon Sep 17 00:00:00 2001 From: Matthew Stobbs Date: Thu, 20 Aug 2026 12:20:33 -0500 Subject: [PATCH] set niri config --- config/nvim/stobbsm/init.lua | 556 +++++++++++++++++++++++++++++++++++ demilich/home.nix | 398 ++++++++++++++++++++++++- demilich/packages.nix | 4 +- 3 files changed, 955 insertions(+), 3 deletions(-) create mode 100644 config/nvim/stobbsm/init.lua diff --git a/config/nvim/stobbsm/init.lua b/config/nvim/stobbsm/init.lua new file mode 100644 index 0000000..c8e1e42 --- /dev/null +++ b/config/nvim/stobbsm/init.lua @@ -0,0 +1,556 @@ +-- {{{ plugins +local gh = 'https://github.com/' +local plugins = { + { src = 'https://git.sprouting.cloud/sprouting.cloud/sproutingcolour', name = 'sproutingcolour' }, -- colorscheme + { src = gh .. 'MunifTanjim/nui.nvim', name = 'nui' }, + { src = gh .. 'catgoose/nvim-colorizer.lua', name = 'colorizer' }, -- show colours of colour codes + { src = gh .. 'echasnovski/mini.nvim', name = 'mini' }, -- a bunch of useful plugins + { src = gh .. 'folke/noice.nvim', name = 'noice' }, + { src = gh .. 'folke/snacks.nvim', name = 'snacks' }, + { src = gh .. 'kdheepak/lazygit.nvim', name = 'lazygit' }, + { src = gh .. 'neovim/nvim-lspconfig', name = 'lspconfig' }, -- LSP support + { src = gh .. 'nvim-lua/plenary.nvim', name = 'plenary' }, + { src = gh .. 'ray-x/go.nvim', name = 'go' }, -- Go specific language support + { src = gh .. 'ray-x/guihua.lua', name = 'guihua' }, -- required for go.nvim + { src = gh .. 'stevearc/conform.nvim', name = 'conform' }, + { src = gh .. 'folke/which-key.nvim', name = 'whichkey' }, + { src = gh .. 'mikavilpas/yazi.nvim', name = 'yazi' }, + { src = gh .. 'nvimdev/dashboard-nvim', name = 'dashboard' }, + { src = gh .. 'nvim-treesitter/nvim-treesitter', name = 'treesitter' }, + { src = gh .. 'coder/claudecode.nvim', name = 'claudecode' }, + { src = gh .. 'Dan7h3x/neaterm.nvim', name = 'neaterm' }, +} +vim.pack.add(plugins) +local function update_plugins() + local plist = {} + for _, v in ipairs(plugins) + do + table.insert(plist, v.name) + end + vim.pack.update(plist) +end -- }}} +-- {{{ Global settings +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' +vim.g.have_nerd_font = true +-- Common defaults +vim.opt.clipboard = 'unnamedplus' +vim.opt.cursorline = true +vim.opt.expandtab = true +vim.opt.hlsearch = true +vim.opt.inccommand = 'split' +vim.opt.modeline = true +vim.opt.mouse = 'a' +vim.opt.number = true +vim.opt.preserveindent = true +vim.opt.relativenumber = true +vim.opt.ruler = true +vim.opt.scrolloff = 5 +vim.opt.shiftwidth = 2 +vim.opt.showmode = true +vim.opt.showtabline = 1 +vim.opt.softtabstop = 2 +vim.opt.tabstop = 2 +vim.opt.termguicolors = true +vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } +vim.opt.inccommand = 'split' +-- Set foldmethod, change in .editorconfig of projects +vim.opt.foldmethod = 'marker' +-- General gui settings +vim.o.guifont = 'JetBrainsMono Nerd Font:12' +-- Neovide settings +if vim.g.neovide then + vim.env.PATH = '/usr/local/bin:' .. vim.env.PATH + vim.env.PATH = '/usr/local/go/bin:' .. vim.env.PATH + vim.env.PATH = '/opt/homebrew/bin:' .. vim.env.PATH + vim.env.PATH = vim.env.HOME .. '/.local/bin:' .. vim.env.PATH + vim.env.PATH = vim.env.HOME .. '/.cargo/bin:' .. vim.env.PATH + vim.env.PATH = vim.env.HOME .. '/.local/cargo/bin:' .. vim.env.PATH + vim.env.PATH = vim.env.HOME .. '/go/bin:' .. vim.env.PATH + vim.env.PATH = vim.env.HOME .. '/.local/npm/bin:' .. vim.env.PATH +end +vim.cmd.colorscheme 'sprouting-dark' +-- }}} +-- {{{ Helper functions +function R(name) + require("plenary.reload").reload_module(name) +end +-- }}} +require('snacks').setup({ -- {{{ + animate = {}, + dim = {}, + image = {}, + indent = {}, + lazygit = {}, + picker = {}, +}) -- }}} +require('colorizer').setup({}) +require('conform').setup({ -- {{{ + formatters_by_ft = { + ansible = { 'ansible-lint' }, + buf = { 'buf' }, + cmake = { 'cmake_format' }, + go = { 'goimports' }, + markdown = { 'cbfmt', 'mdformat' }, + sql = { 'sqlfluff' }, + terraform = { 'terraform_fmt' }, + templ = { 'go tool templ fmt' }, + }, +}) +vim.g.snacks_animate = true -- }}} +-- {{{ ferminal scratch pad terminal +local ferminal = {} + +local state = { + floating = { + buf = -1, + win = -1, + }, +} + +local function create_floating_window(opts) + opts = opts or {} + local width = opts.width or math.floor(vim.o.columns * 0.8) + local height = opts.height or math.floor(vim.o.lines * 0.8) + + -- Calculate the position to center the window + local col = math.floor((vim.o.columns - width) / 2) + local row = math.floor((vim.o.lines - height) / 2) + + -- Create a buffer + local buf = nil + if vim.api.nvim_buf_is_valid(opts.buf) then + buf = opts.buf + else + buf = vim.api.nvim_create_buf(false, true) -- No file, scratch buffer + end + + -- Define window configuration + local win_config = { + relative = 'editor', + width = width, + height = height, + col = col, + row = row, + style = 'minimal', -- No borders or extra UI elements + border = 'rounded', + } + + -- Create the floating window + local win = vim.api.nvim_open_win(buf, true, win_config) + + return { buf = buf, win = win } +end + +ferminal.toggle_terminal = function() + if not vim.api.nvim_win_is_valid(state.floating.win) then + state.floating = create_floating_window { buf = state.floating.buf } + if vim.bo[state.floating.buf].buftype ~= 'terminal' then + vim.cmd.terminal() + end + else + vim.api.nvim_win_hide(state.floating.win) + end +end -- }}} +-- {{{ Language configurations +require('go').setup() +-- }}} +require('noice').setup({ -- {{{ + lsp = { + override = { + ['vim.lsp.util.convert_input_to_markdown_lines'] = true, + ['vim.lsp.util.stylize_markdown'] = true, + }, + }, + popupmenu = { + enabled = true, + backend = 'nui', + }, + notify = { + enabled = true, + view = 'notify', + }, + routes = { + { + view = 'notify', + filter = { event = 'msg_showmode' }, + }, + }, +}) -- }}} +require('yazi').setup({ -- {{{ + open_for_directories = true, + keymaps = { + show_help = '', + }, +}) +vim.g.loaded_netrwPlugin = 1 -- }}} +require('dashboard').setup({ -- {{{ + theme = 'hyper', + config = { + shortcut = { + { desc = '󰊳 Update ', group = '@property', key = 'u', action = update_plugins }, + { desc = ' Projects ', group = 'label', key = 'p', action = Snacks.picker.projects }, + { desc = '󰪶 Files ', group = 'OkMsg', key = 'f', action = Snacks.picker.files }, + { desc = '󰿅 Quit ', group = 'ErrorMsg', key = 'q', action = ':q' }, + }, + packages = { enable = false }, -- show number of installed plugins + project = { enable = true, limit = 8, label = '', action = Snacks.picker.projects }, + }, +}) -- }}} +require('which-key').setup({ -- {{{ + preset = 'modern', +}) -- }}} +require('nvim-treesitter').setup({ -- {{{ + install_dir = vim.fn.stdpath('data') .. '/site' +}) +require('nvim-treesitter').install({ + 'asm', 'awk', + 'bash', + 'c', 'c_sharp', 'caddy', 'cmake', 'comment', 'cpp', 'css', 'csv', + 'desktop', 'diff', 'dockerfile', 'dtd', + 'editorconfig', 'elm', + 'fortran', + 'gdscript', 'git_config', 'git_rebase', 'gitattributes', 'gitcommit', + 'gitignore', 'go', 'gomod', 'gosum', 'gowork', 'gpg', + 'hcl', 'helm', 'html', 'http', + 'javascript', 'jinja', 'jinja_inline', 'jq', 'json', 'json5', + 'kotlin', + 'llvm', 'lua', 'luadoc', 'luap', + 'make', 'markdown', 'markdown_inline', 'meson', 'muttrc', + 'nasm', 'nginx', 'ninja', + 'php', 'php_only', 'phpdoc', 'powershell', 'printf', 'properties', + 'regex', 'requirements', 'robot', 'robots_txt', 'rst', 'rust', + 'scss', 'sql', 'ssh_config', + 'templ', 'terraform', 'tmux', 'toml', 'typescript', + 'udev', + 'vala', 'vim', 'vimdoc', 'vue', + 'xml', + 'yaml', + 'zig', 'zsh', +}) +-- Enable treesitter +vim.api.nvim_create_autocmd('FileType', { + callback = function() + pcall(vim.treesitter.start) + vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + end, +}) +-- Done nvim-treesitter }}} +require('claudecode').setup({ -- {{{ + cwd_provider = function(ctx) + local cwd = require('claudecode.cwd').git_root(ctx.file_dir or ctx.cwd) or ctx.file_dir or ctx.cwd + return cwd + end, +}) +-- Done claudecode }}} +require('neaterm').setup() -- {{{ +-- Done neaterm }}} +-- Filetype configuration {{{ +vim.filetype.add({ + extension = { + Containerfile = 'dockerfile', + Dockerfile = 'dockerfile', + containerfile = 'containerfile', + dockerfile = 'dockerfile', + j2 = 'jinja', + jinja = 'jinja', + jinja2 = 'jinja', + tf = 'terraform', + tfstate = 'json', + tfvars = 'terraform', + templ = 'templ', + }, +}) -- }}} +-- {{{ LSP Configuration +local lspproto = vim.lsp.protocol +local lspconfig = vim.lsp.config +local lspenable = vim.lsp.enable +local capabilities = lspproto.make_client_capabilities() +-- Formatter autocmd +vim.api.nvim_create_autocmd({ 'BufWritePre' }, { + callback = function(args) + require("conform").format({ bufnr = args.buf }) + end, +}) +-- Simple lspconfigs +vim.lsp.config('ansiblels', capabilities) +vim.lsp.config('bashls', capabilities) +vim.lsp.config('buf_ls', capabilities) +vim.lsp.config('clangd', capabilities) +vim.lsp.config('gopls', capabilities) +vim.lsp.config('intelephense', capabilities) +vim.lsp.config('jinja_lsp', capabilities) +vim.lsp.config('nginx_language_server', capabilities) +vim.lsp.config('pyright', capabilities) +vim.lsp.config('sqlls', capabilities) +vim.lsp.config('templ', capabilities) +vim.lsp.config('terraformls', capabilities) +vim.lsp.config('qmlls', capabilities) +vim.lsp.config('zls', capabilities) +-- LSP with more advanced configuration +local caps_snippt_support = function() + local caps = lspproto.make_client_capabilities() + caps.textDocument.completion.completionItem.snippetSupport = true + return caps +end +vim.lsp.config('cssls', { + capabilities = caps_snippt_support() }) +vim.lsp.config('html', { + capabilities = caps_snippt_support(), + filetypes = { 'html', 'templ' } +}) +vim.lsp.config('htmx', { + capabilities = caps_snippt_support(), + filetypes = { 'html', 'templ' } +}) +vim.lsp.config('jsonls', { + capabilities = caps_snippt_support() }) +vim.lsp.config('dockerls', { + settings = { docker = { languageserver = { formatter = { ignoreMultilineInstructions = true }, } } } }) +vim.lsp.config('eslint', { + on_attach = function(_, bufnr) + vim.api.nvim_create_autocmd('BufWritePre', { buffer = bufnr, command = 'EslintFixAll', }) + end, +}) +vim.lsp.config('lua_ls', { + on_init = function(client) + if client.workspace_folders then + local path = client.workspace_folders[1].name + if vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc') then + return + end + end + client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { + runtime = { version = 'LuaJIT' }, + workspace = { checkThirdParty = false, library = { vim.env.VIMRUNTIME, '${3rd}/luv/library' } }, + format = { enable = true, defaultConfig = { indent_style = 'space', indent_size = '2' } }, + diagnostics = { globals = { 'vim', 'Snacks', 'MiniSessions', 'MiniPick', 'MiniStatusline' } }, + }) + end, + settings = { + Lua = {} + } +}) +vim.lsp.config('templ', { + cmd = { 'go', 'tool', 'github.com/a-h/templ/cmd/templ', 'lsp' }, +}) +vim.lsp.config('tailwindcss', { + capabilities = capabilities, + filetypes = { 'templ', 'astro', 'javascript', 'typescript', 'react' }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = 'html', + }, + }, + }, +}) +vim.lsp.config('yamlls', { + format = { enable = true, bracketSpacing = true }, +}) +lspenable({ + 'ansiblels', + 'bashls', + 'buf_ls', + 'clangd', + 'cssls', + 'dockerls', + 'eslint', + 'eslint', + 'gopls', + 'html', + 'htmx', + 'intelephense', + 'jinja_lsp', + 'jsonls', + 'lua_ls', + 'nginx_language_server', + 'pyright', + 'qmlls', + 'sqlls', + 'tailwindcss', + 'templ', + 'terraformls', + 'zls', +}) -- end LSPConfig }}} +-- {{{ mini.nvim setup +require('mini.basics').setup() +require('mini.ai').setup({ n_lines = 200 }) +require('mini.align').setup() +require('mini.completion').setup() +require('mini.diff').setup() +require('mini.extra').setup() +require('mini.git').setup() +require('mini.icons').setup() +require('mini.move').setup() +require('mini.operators').setup() +require('mini.pairs').setup() +require('mini.snippets').setup() +require('mini.splitjoin').setup() +require('mini.statusline').setup({ + content = { + active = function() + local check_macro_recording = function() + if vim.fn.reg_recording() ~= '' then + return '@' .. vim.fn.reg_recording() + else + return '' + end + end + + -- configure statusline for active windows + local mode, mode_hl = MiniStatusline.section_mode { trunc_width = 120 } + local git = MiniStatusline.section_git { trunc_width = 40 } + local diff = MiniStatusline.section_diff { trunc_width = 75 } + local diagnostics = MiniStatusline.section_diagnostics { trunc_width = 75 } + local lsp = MiniStatusline.section_lsp { trunc_width = 75 } + local filename = MiniStatusline.section_filename { trunc_width = 140 } + local fileinfo = MiniStatusline.section_fileinfo { trunc_width = 120 } + local location = MiniStatusline.section_location { trunc_width = 75 } + local search = MiniStatusline.section_searchcount { trunc_width = 75 } + local macro = check_macro_recording() + + return MiniStatusline.combine_groups { + { hl = mode_hl, strings = { mode } }, + { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, + '%<', -- Mark general truncate point + { hl = 'MiniStatuslineFilename', strings = { filename } }, + '%=', -- End left alignment + { hl = 'MiniStatuslineFilename', strings = { macro } }, + { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } }, + { hl = mode_hl, strings = { search, location } }, + } + end, + use_icons = true, + set_vim_settings = true, + }, +}) -- }}} +-- {{{ which-key config +local wk = require('which-key') +local wke = require('which-key.extras') +wk.add({ + { -- Normal Mode + { '', '>>', desc = 'increase tab depth of line' }, + { '', '<<', desc = 'decrease tab depth of line' }, + + -- file group + { 'f', group = 'file' }, + { 'fb', 'Yazi', desc = '[f]ile [b]rowser' }, + { 'fd', 'Yazi cwd', desc = '[f]ile browser for current [d]irectory' }, + { 'fp', Snacks.picker.files, desc = '[f]ile [p]icker' }, + { 'fg', Snacks.picker.grep, desc = '[f]ile [g]rep picker' }, + { 'fz', Snacks.picker.zoxide, desc = '[f]ile [z]oxide picker' }, + + -- buffer group + { + 'b', + group = 'buffers', + expand = function() + return wke.expand.buf() + end + }, + { 'be', 'e %', desc = '[b]uffer r[e]load' }, + { 'bp', Snacks.picker.buffers, desc = '[b]uffer [p]icker' }, + { 'bl', Snacks.picker.lines, desc = '[b]uffer pick [l]ine' }, + + -- project group + { 'pp', Snacks.picker.projects, desc = '[p]ick [p]roject' }, + + -- help group + { 'h', group = 'help' }, + { 'hh', Snacks.picker.help, desc = '[h]pick [h]elp' }, + { 'hk', Snacks.picker.keymaps, desc = '[h]pick [k]eymaps' }, + { 'hi', Snacks.picker.icons, desc = '[h]pick icon' }, + + -- git group + { 'g', group = 'git' }, + { 'gi', 'LazyGit', desc = 'lazy[g][i]t open' }, + { 'gc', 'LazyGitCurrentFile', desc = 'lazy[g]it [c]urrent file' }, + { 'go', 'LazyGitConfig', desc = 'lazy[g]it c[o]nfig' }, + { 'gl', 'LazyGitLog', desc = 'Lazy[g]it [l]og' }, + + -- lsp group + { 'l', group = 'LSP' }, + { 'lh', vim.lsp.buf.hover, desc = '[l]sp [h]over Documentation' }, + { 'ls', vim.lsp.buf.signature_help, desc = '[l]sp [s]ignature help' }, + { 'lr', vim.lsp.buf.rename, desc = '[l]sp [r]ename' }, + { 'lf', vim.lsp.buf.format, desc = '[l]sp [f]ormat buffer' }, + { 'lgD', Snacks.picker.lsp_declarations, desc = '[l]sp [g]oto [D]eclaration' }, + { 'lgI', Snacks.picker.lsp_implementations, desc = '[l]sp [g]oto [I]mplementation' }, + { 'lgS', Snacks.picker.lsp_workspace_symbols, desc = '[l]sp [g]oto workspace [S]ymbol' }, + { 'lgd', Snacks.picker.lsp_definitions, desc = '[l]sp [g]oto [d]efinition' }, + { 'lgr', Snacks.picker.lsp_references, desc = '[l]sp [g]oto [r]eferences' }, + { 'lgs', Snacks.picker.lsp_symbols, desc = '[l]sp [g]oto document [s]ymbol' }, + { 'lde', vim.diagnostic.open_float, desc = '[l]sp [d]iagnostic [e]rror messages' }, + { 'ldq', vim.diagnostic.setloclist, desc = '[l]sp [d]iagnostic [q]uickfix list' }, + + -- claude code + { 'a', group = 'Claude' }, + { 'ac', "ClaudeCode", desc = "Toggle Claude" }, + { 'af', "ClaudeCodeFocus", desc = "Focus Claude" }, + { 'ar', "ClaudeCode --resume", desc = "Resume Claude" }, + { 'aC', "ClaudeCode --continue", desc = "Continue Claude" }, + { 'am', "ClaudeCodeSelectModel", desc = "Select Claude Model" }, + { 'ab', "ClaudeCodeAdd %", desc = "Add current buffer" }, + { 'as', "ClaudeCodeSend", mode = 'v', desc = "Send to Claude" }, + { + 'as', + "ClaudeCodeTreeAdd", + desc = "Add file", + ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" }, + }, + { 'aa', "ClaudeCodeDiffAccept", desc = "Accept diff" }, + { 'ad', "ClaudeCodeDiffDeny", desc = "Deny diff" }, + -- diagnostics + { + '[d', + function() vim.diagnostic.jump({ count = -1, float = true }) end, + desc = 'goto previous [d]iagnostic message' + }, + { + ']d', + function() vim.diagnostic.jump({ count = 1, float = true }) end, + desc = 'goto next [d]iagnostic message' + }, + + -- misc + { '', ':nohl', desc = 'Clear Highlights' }, + { 'tt', ferminal.toggle_terminal, desc = '[t]oggle floating [t]erminal' }, + { 'rr', ':source %', desc = 'sou[r]ce cu[r]rent file as neovim lua' }, + }, + { -- Visual Mode + mode = 'v', + { '', '>>', desc = 'increase tab depth of selection' }, + { '', '<<', desc = 'decrease tab depth of selection' }, + }, + { -- Insert Mode + mode = 'i', + { '', vim.lsp.buf.signature_help, desc = 'signature help' }, + { '', vim.lsp.buf.hover, desc = 'Hover [d]ocumentation' }, + { '', '', desc = 'restore tab functionality' }, + { '', '', desc = 'restore de-tab functionality' }, + }, + { -- Terminal Mode + mode = 't', + { '', '', desc = 'Exit terminal mode' }, + -- Window navigation + { '', 'h', desc = 'Navigate to left window' }, + { '', 'j', desc = 'Navigate to lower window' }, + { '', 'k', desc = 'Navigate to upper window' }, + { '', 'l', desc = 'Navigate to right window' }, + -- Tab navigation + { '', 'tabprev', desc = 'Navigate to previous tab' }, + { '', 'tabnext', desc = 'Navigate to next tab' }, + }, + { -- Normal, Insert mode + mode = { 'n', 'i' }, + -- Window navigation + { '', 'h', desc = 'Navigate to left window' }, + { '', 'j', desc = 'Navigate to lower window' }, + { '', 'k', desc = 'Navigate to upper window' }, + { '', 'l', desc = 'Navigate to right window' }, + -- Tab navigation + { '', 'tabprev', desc = 'Navigate to previous tab' }, + { '', 'tabnext', desc = 'Navigate to next tab' }, + }, +}) -- }}} diff --git a/demilich/home.nix b/demilich/home.nix index c75856d..84d2e09 100644 --- a/demilich/home.nix +++ b/demilich/home.nix @@ -49,7 +49,34 @@ }; }; }; + fonts = { + fontconfig = { + defaultFonts = { + emoji = with pkgs; [ + nerd-fonts.symbols-only + font-awesome + ]; + monospace = with pkgs; [ + nerd-fonts.jetbrains-mono + nerd-fonts.hack + nerd-fonts.symbols-only + ]; + sansSerif = [ + liberation_ttf_v2 + ]; + serif = [ + liberation_ttf_v2 + ]; + }; + antialiasing = true; + hinting = "medium"; + subpixelRendering = "rgb"; + }; + }; programs = { + aerc = { + enable = true; + }; bat = { enable = true; extraPackages = with pkgs.bat-extras; [ @@ -59,6 +86,18 @@ batwatch ]; }; + chromium = { + enable = true; + package = pkgs.ungoogled-chromium; + dictionaries = [ + pkgs.hunspellDictsChromium.en-gb + pkgs.hunspellDictsChromium.en-us + pkgs.hunspellDictsChromium.fr-fr + ]; + }; + command-not-found = { + enable = true; + }; delta = { enable = true; enableGitIntegration = true; @@ -85,7 +124,7 @@ "--header" ]; git = true; - icons = "auto"; + icons = "always"; }; fd = { enable = true; @@ -184,8 +223,29 @@ enable = true; enableZshIntegration = true; }; + librewolf = { + enable = true; + }; neovide = { enable = true; + settings = { + wayland-app-id = "neovide"; + font = { + normal = [ pkgs.nerd-fonts.jetbrains-mono ]; + size = 14.0; + }; + }; + }; + neovim = { + enable = true; + initLua = builtins.readFile ../config/nvim/stobbsm/nvim.lua; + defaultEditor = true; + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + withNodeJs = true; + withPerl = true; + withPython3 = true; }; # noctalia = { # enable = true; @@ -327,6 +387,14 @@ }; tmux = { enable = true; + clock24 = true; + escapeTime = 10; + focusEvents = true; + historyLimit = 5000; + keyMode = "vi"; + mouse = true; + newSession = true; + terminal = "xterm-256color"; }; uv = { enable = true; @@ -363,4 +431,332 @@ }; }; }; + wayland = { + windowManager = { + niri = { + enable = true; + settings = { + layout = { + focus-ring = { + active-color = "#9bdf9e"; + inactive-color = "#7e997e"; + urgent-color = "#e04b7c"; + }; + border = { + active-color = "#9bdf9e"; + inactive-color = "#7e997e"; + urgent-color = "#e04b7c"; + }; + shadow = { + color = "#3f4c3f70"; + }; + tab-indicator = { + active-color = "#9bdf9e"; + inactive-color = "#7e997e"; + urgent-color = "#e04b7c"; + }; + insert-hint = { + color = "#3f4c3f80"; + }; + _props.gaps = 16; + _props.center-focused-column = "never"; + + _props.background-color = "transparent"; + + preset-column-widths = { + _props.proportion = 0.33333; + _props.proportion = 0.5; + _props.proportion = 0.66667; + }; + + _props.struts = "{}"; + }; + recent-windows = { + highlight = { + _props.active-color = "#b1ccb1"; + _props.urgent-color = "#e8789d"; + }; + }; + animations = { + workspace-switch = { + "spring damping-ratio=1.0 stiffness=1000 epsilon=0.0001" = { }; + }; + window-open = { + duration-ms = 200; + curve = "ease-out-quad"; + }; + window-close = { + duration-ms = 200; + curve = "ease-out-cubic"; + }; + horizontal-view-movement = { + "spring damping-ratio=1.0 stiffness=900 epsilon=0.0001" = { }; + }; + window-movement = { + "spring damping-ratio=1.0 stiffness=800 epsilon=0.0001" = { }; + }; + window-resize = { + "spring damping-ratio=1.0 stiffness=1000 epsilon=0.0001" = { }; + }; + config-notification-open-close = { + "spring damping-ratio=0.6 stiffness=1200 epsilon=0.001" = { }; + }; + screenshot-ui-open = { + duration-ms = 300; + curve = "ease-out-quad"; + }; + overview-open-close = { + "spring damping-ratio=1.0 stiffness=900 epsilon=0.0001" = { }; + }; + }; + input = { + keyboard = { + xkb = { + #layout = "us"; + }; + }; + touchpad = { + tap = { }; + natural-scroll = { }; + }; + mouse = { + accel-profile = "flat"; + accel-speed = 0.0; + }; + focus-follows-mouse = { }; + workspace-auto-back-and-forth = { }; + }; + binds = { + "Mod+Shift+ESCAPE".show-hotkey-overlay = { }; + + "Mod+Return" = { + _props.hotkey-overlay-title = "Open Terminal: Ghostty"; + spawn = [ "ghostty" ]; + }; + "Mod+B" = { + _props.hotkey-overlay-title = "Open Browser: firefox"; + spawn = [ "firefox" ]; + }; + "Mod+ALT+L" = { + _props.hotkey-overlay-title = "Lock Screen: noctalia lock"; + spawn-sh = [ "qs -c noctalia-shell ipc call lockScreen lock" ]; + }; + "Mod+Shift+Q" = { + _props.hotkey-overlay-title = "Session Menu: noctalia sessionMenu"; + spawn-sh = [ "qs -c noctalia-shell ipc call sessionMenu toggle" ]; + }; + + "Mod+E" = { + _props.hotkey-overlay-title = "File Manager: Nautilus"; + spawn = [ "nautilus" ]; + }; + + "XF86AudioRaiseVolume" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call volume increase" ]; + }; + "XF86AudioLowerVolume" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call volume decrease" ]; + }; + "XF86AudioMute" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call volume muteOutput" ]; + }; + "XF86AudioMicMute" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call volume muteInput" ]; + }; + "XF86AudioNext" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call media next" ]; + }; + "XF86AudioPrev" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call media previous" ]; + }; + "XF86AudioPlay" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call media playPause" ]; + }; + "XF86AudioPause" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call media playPause" ]; + }; + + "XF86MonBrightnessUp" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call brightness increase" ]; + }; + "XF86MonBrightnessDown" = { + _props.allow-when-locked = true; + spawn-sh = [ "qs -c noctalia-shell ipc call brightness decrease" ]; + }; + + "Mod+Q".close-window = { }; + + "Mod+Left".focus-column-left = { }; + "Mod+H".focus-column-left = { }; + "Mod+Right".focus-column-right = { }; + "Mod+L".focus-column-right = { }; + "Mod+Up".focus-window-up = { }; + "Mod+K".focus-window-up = { }; + "Mod+Down".focus-window-down = { }; + "Mod+J".focus-window-down = { }; + + "Mod+CTRL+Left".move-column-left = { }; + "Mod+CTRL+H".move-column-left = { }; + "Mod+CTRL+Right".move-column-right = { }; + "Mod+CTRL+L".move-column-right = { }; + "Mod+CTRL+UP".move-window-up = { }; + "Mod+CTRL+K".move-window-up = { }; + "Mod+CTRL+Down".move-window-down = { }; + "Mod+CTRL+J".move-window-down = { }; + + "Mod+Home".focus-column-first = { }; + "Mod+End".focus-column-last = { }; + "Mod+CTRL+Home".move-column-to-first = { }; + "Mod+CTRL+End".move-column-to-last = { }; + + "Mod+Shift+Left".focus-monitor-left = { }; + "Mod+Shift+Right".focus-monitor-right = { }; + "Mod+Shift+UP".focus-monitor-up = { }; + "Mod+Shift+Down".focus-monitor-down = { }; + + "Mod+Shift+CTRL+Left".move-column-to-monitor-left = { }; + "Mod+Shift+CTRL+Right".move-column-to-monitor-right = { }; + "Mod+Shift+CTRL+UP".move-column-to-monitor-up = { }; + "Mod+Shift+CTRL+Down".move-column-to-monitor-down = { }; + + "Mod+Next" = { + _props.cooldown-ms = 150; + _props.focus-workspace-down = { }; + }; + "Mod+Prior" = { + _props.cooldown-ms = 150; + _props.focus-workspace-up = { }; + }; + "Mod+CTRL+Next" = { + _props.cooldown-ms = 150; + _props.move-column-to-workspace-down = { }; + }; + "Mod+CTRL+Prior" = { + _props.cooldown-ms = 150; + _props.move-column-to-workspace-up = { }; + }; + + "Mod+WheelScrollRight".focus-column-right = { }; + "Mod+WheelScrollLeft".focus-column-left = { }; + "Mod+CTRL+WheelScrollRight".move-column-right = { }; + "Mod+CTRL+WheelScrollLeft".move-column-left = { }; + + "Mod+Shift+WheelScrollDown".focus-column-right = { }; + "Mod+Shift+WheelScrollUp".focus-column-left = { }; + "Mod+CTRL+Shift+WheelScrollDown".move-column-right = { }; + "Mod+CTRL+Shift+WheelScrollUp".move-column-left = { }; + + "Mod+1".focus-workspace = 1; + "Mod+2".focus-workspace = 2; + "Mod+3".focus-workspace = 3; + "Mod+4".focus-workspace = 4; + "Mod+5".focus-workspace = 5; + "Mod+6".focus-workspace = 6; + "Mod+7".focus-workspace = 7; + "Mod+8".focus-workspace = 8; + "Mod+9".focus-workspace = 9; + + "Mod+CTRL+1".move-column-to-workspace = 1; + "Mod+CTRL+2".move-column-to-workspace = 2; + "Mod+CTRL+3".move-column-to-workspace = 3; + "Mod+CTRL+4".move-column-to-workspace = 4; + "Mod+CTRL+5".move-column-to-workspace = 5; + "Mod+CTRL+6".move-column-to-workspace = 6; + "Mod+CTRL+7".move-column-to-workspace = 7; + "Mod+CTRL+8".move-column-to-workspace = 8; + "Mod+CTRL+9".move-column-to-workspace = 9; + + "Mod+TAB".focus-workspace-previous = { }; + + "Mod+CTRL+F".expand-column-to-available-width = { }; + "Mod+C".center-column = { }; + "Mod+CTRL+C".center-visible-columns = { }; + "Mod+Minus".set-column-width = "-10%"; + "Mod+Equal".set-column-width = "+10%"; + "Mod+Shift+Minus".set-window-height = "-10%"; + "Mod+Shift+Equal".set-window-height = "+10%"; + + "Mod+T".toggle-window-floating = { }; + "Mod+F".fullscreen-window = { }; + "Mod+W".toggle-column-tabbed-display = { }; + + "CTRL+Shift+1".screenshot = { }; + "CTRL+Shift+2".screenshot-screen = { }; + "CTRL+Shift+3".screenshot-window = { }; + + "Mod+ESCAPE" = { + allow-inhibiting = false; + toggle-keyboard-shortcuts-inhibit = { }; + }; + + "CTRL+ALT+Delete".quit = { }; + "Mod+Shift+P".power-off-monitors = { }; + "Mod+O" = { + repeat = false; + toggle-overview = { }; + }; + }; + + _props.prefer-no-csd = { }; + screenshot-path = "null"; + + environment = { + ELECTRON_OZONE_PLATFORM_HINT = "auto"; + QT_QPA_PLATFORM = "wayland"; + QT_QPA_PLATFORMTHEME = "gtk3"; + QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; + XDG_CURRENT_DESKTOP = "niri"; + XDG_SESSION_TYPE = "wayland"; + }; + + cursor = { + xcursor-theme = "capitaine-cursors"; + xcursor-size = 24; + }; + + debug = { + _props.honor-xdg-activation-with-invalid-serial = { }; + }; + + hotkey-overlay = { + _props.skip-at-startup = { }; + }; + + window-rule = { + _props.geometry-corner-radius = 20; + clip-to-geometry = true; + }; + + window-rule = { + match = "app-id=\"steam\""; + exclude = "title=r#\"^[Ss]team$\"#"; + open-floating = true; + }; + + window-rule = { + match = "app-id=\"steam\" title=r#\"^notificationtoasts_\d+_desktop$\"#"; + default-floating-position = "x=10 y=10 relative-to=\"bottom-right\""; + open-focused = false; + }; + + layer-rule = { + match = "namespace=\"^noctalia-wallpaper*\""; + place-within-backdrop = true; + }; + }; + systemd = { + enable = true; + }; + }; + }; + }; } diff --git a/demilich/packages.nix b/demilich/packages.nix index 2d33501..5029270 100644 --- a/demilich/packages.nix +++ b/demilich/packages.nix @@ -115,7 +115,7 @@ in regex ]; }; - customLuaRC = builtins.readFile ../config/nvim.lua; + customLuaRC = builtins.readFile ../config/nvim/system/nvim.lua; }; }; zsh = { @@ -123,4 +123,4 @@ in }; }; -} +} \ No newline at end of file