diff --git a/.config/hypr/conf/autostart.conf b/.config/hypr/conf/autostart.conf index b883ddb..8b31ba8 100644 --- a/.config/hypr/conf/autostart.conf +++ b/.config/hypr/conf/autostart.conf @@ -7,5 +7,6 @@ exec-once = /usr/lib/pam_kwallet_init & hypridle & hyprpaper & nm-applet & bluem exec-once = dunst & poweralertd & exec-once = ~/.config/hypr/scripts/start-wob.sh exec-once = [ -x "$(command -v wlsunset)" ] && /home/goodhumored/dotfiles/.config/scripts/sunset.sh "on" +exec-once = ~/.config/hypr/scripts/cycle-wp.sh exec-once = crow diff --git a/.config/hypr/conf/keybindings.conf b/.config/hypr/conf/keybindings.conf index 2ffcdb0..f059367 100644 --- a/.config/hypr/conf/keybindings.conf +++ b/.config/hypr/conf/keybindings.conf @@ -25,6 +25,8 @@ bind = $mainMod SHIFT CTRL ALT, R, exec, ~/.config/hypr/scripts/cycle-wp.sh # ──────────────────────────────── copyq ────────────────────────────── bind = CTRL_ALT, V, exec, copyq toggle +# ────────────────────────── window manipulation ────────────────────────── + bind = $mainMod, F, fullscreen # fullscreen bind = $mainMod, Q, killactive, # kill window bind = $mainMod, V, togglefloating, # toggle float @@ -33,6 +35,10 @@ bind = $mainMod, DELETE, exit, # pseudo bind = $mainMod, R, togglesplit, # toggle split bind = $mainMod CTRL, L, exec, ~/.config/hypr/scripts/update-hyprlock-wp.sh && hyprctl switchxkblayout all 0 && hyprlock # lock screen +# ─────────────────────────────── rofimoji ────────────────────────────── + +bind = $mainMod SHIFT, E, exec, rofimoji -a copy + # ─────────────────────────── move workspaces ───────────────────────── bind = CTRL ALT $mainMod SHIFT CTRL ALT, H, movecurrentworkspacetomonitor, l bind = CTRL ALT $mainMod SHIFT CTRL ALT, L, movecurrentworkspacetomonitor, r diff --git a/.config/hypr/hyprlock-bg.conf b/.config/hypr/hyprlock-bg.conf index c5ba477..02dd62d 100644 --- a/.config/hypr/hyprlock-bg.conf +++ b/.config/hypr/hyprlock-bg.conf @@ -1,13 +1,9 @@ background { monitor = eDP-1 - path = /home/goodhumored/wallpapers/7.png -} -background { - monitor = DP-2 - path = /home/goodhumored/wallpapers/7.png + path = /home/goodhumored/wallpapers/9.png } background { monitor = HDMI-A-1 - path = /home/goodhumored/wallpapers/7.png + path = /home/goodhumored/wallpapers/9.png } diff --git a/.config/hypr/scripts/dnd-clipboard.sh b/.config/hypr/scripts/dnd-clipboard.sh index 42a4f1b..9ad7a96 100755 --- a/.config/hypr/scripts/dnd-clipboard.sh +++ b/.config/hypr/scripts/dnd-clipboard.sh @@ -1 +1 @@ -wl-paste > /tmp/clipboard_image.jpg && dragon-drop /tmp/clipboard_image.jpg +wl-paste > /tmp/clipboard_image.png && dragon-drop /tmp/clipboard_image.png diff --git a/.config/lazygit/state.yml b/.config/lazygit/state.yml index 6d8dbcc..1d85445 100644 --- a/.config/lazygit/state.yml +++ b/.config/lazygit/state.yml @@ -1,16 +1,13 @@ lastupdatecheck: 0 recentrepos: - - /home/goodhumored/side-hustle/lambo/er_lamborgini - - /home/goodhumored/side-hustle/alexflora/frontend - - /home/goodhumored/lazygit/lazygit +- /home/goodhumored/side-hustle/compass/compass-frontend +- /home/goodhumored/Job/dipal/repos/Kaiser/Crow +- /home/goodhumored/side-hustle/alexflora/frontend +- /home/goodhumored/lazygit/lazygit startuppopupversion: 5 -lastversion: 0.43.1 customcommandshistory: [] hidecommandlog: false ignorewhitespaceindiffview: false diffcontextsize: 3 -renamesimilaritythreshold: 50 localbranchsortorder: recency remotebranchsortorder: alphabetical -gitlogorder: topo-order -gitlogshowgraph: always diff --git a/.config/nvim/lua/goodhumored/appearance/ui/barbar.lua b/.config/nvim/lua/goodhumored/appearance/ui/barbar.lua index 53d0080..a2dd977 100644 --- a/.config/nvim/lua/goodhumored/appearance/ui/barbar.lua +++ b/.config/nvim/lua/goodhumored/appearance/ui/barbar.lua @@ -26,6 +26,7 @@ return { vim.keymap.set("n", "", "BufferPin", { desc = "Pin tab" }) -- Close buffer vim.keymap.set("n", "", "BufferClose", { desc = "Close tab" }) + vim.keymap.set("n", "", "BufferCloseAllButCurrentOrPinned", { desc = "Close others" }) vim.keymap.set("n", "", "BufferPick", { desc = "Pick tab" }) end, opts = { diff --git a/.config/nvim/lua/goodhumored/appearance/ui/noice.nvim.lua b/.config/nvim/lua/goodhumored/appearance/ui/noice.nvim.lua index eb54ce4..694629c 100644 --- a/.config/nvim/lua/goodhumored/appearance/ui/noice.nvim.lua +++ b/.config/nvim/lua/goodhumored/appearance/ui/noice.nvim.lua @@ -2,7 +2,245 @@ return { "folke/noice.nvim", event = "VeryLazy", opts = { - -- add any options here + cmdline = { + enabled = true, -- enables the Noice cmdline UI + view = "cmdline_popup", -- view for rendering the cmdline. Change to `cmdline` to get a classic cmdline at the bottom + opts = {}, -- global options for the cmdline. See section on views + ---@type table + format = { + -- conceal: (default=true) This will hide the text in the cmdline that matches the pattern. + -- view: (default is cmdline view) + -- opts: any options passed to the view + -- icon_hl_group: optional hl_group for the icon + -- title: set to anything or empty string to hide + cmdline = { pattern = "^:", icon = "", lang = "vim" }, + search_down = { kind = "search", pattern = "^/", icon = " ", lang = "regex" }, + search_up = { kind = "search", pattern = "^%?", icon = " ", lang = "regex" }, + filter = { pattern = "^:%s*!", icon = "$", lang = "bash" }, + lua = { pattern = { "^:%s*lua%s+", "^:%s*lua%s*=%s*", "^:%s*=%s*" }, icon = "", lang = "lua" }, + help = { pattern = "^:%s*he?l?p?%s+", icon = "" }, + input = { view = "cmdline_input", icon = "󰥻 " }, -- Used by input() + -- lua = false, -- to disable a format, set to `false` + }, + }, + messages = { + -- NOTE: If you enable messages, then the cmdline is enabled automatically. + -- This is a current Neovim limitation. + enabled = true, -- enables the Noice messages UI + view = "notify", -- default view for messages + view_error = "notify", -- view for errors + view_warn = "notify", -- view for warnings + view_history = "messages", -- view for :messages + view_search = "virtualtext", -- view for search count messages. Set to `false` to disable + }, + popupmenu = { + enabled = true, -- enables the Noice popupmenu UI + ---@type 'nui'|'cmp' + backend = "nui", -- backend to use to show regular cmdline completions + ---@type NoicePopupmenuItemKind|false + -- Icons for completion item kinds (see defaults at noice.config.icons.kinds) + kind_icons = {}, -- set to `false` to disable icons + }, + -- default options for require('noice').redirect + -- see the section on Command Redirection + ---@type NoiceRouteConfig + redirect = { + view = "popup", + filter = { event = "msg_show" }, + }, + -- You can add any custom commands below that will be available with `:Noice command` + ---@type table + commands = { + history = { + -- options for the message history that you get with `:Noice` + view = "split", + opts = { enter = true, format = "details" }, + filter = { + any = { + { event = "notify" }, + { error = true }, + { warning = true }, + { event = "msg_show", kind = { "" } }, + { event = "lsp", kind = "message" }, + }, + }, + }, + -- :Noice last + last = { + view = "popup", + opts = { enter = true, format = "details" }, + filter = { + any = { + { event = "notify" }, + { error = true }, + { warning = true }, + { event = "msg_show", kind = { "" } }, + { event = "lsp", kind = "message" }, + }, + }, + filter_opts = { count = 1 }, + }, + -- :Noice errors + errors = { + -- options for the message history that you get with `:Noice` + view = "popup", + opts = { enter = true, format = "details" }, + filter = { error = true }, + filter_opts = { reverse = true }, + }, + all = { + -- options for the message history that you get with `:Noice` + view = "split", + opts = { enter = true, format = "details" }, + filter = {}, + }, + }, + notify = { + -- Noice can be used as `vim.notify` so you can route any notification like other messages + -- Notification messages have their level and other properties set. + -- event is always "notify" and kind can be any log level as a string + -- The default routes will forward notifications to nvim-notify + -- Benefit of using Noice for this is the routing and consistent history view + enabled = true, + view = "notify", + }, + lsp = { + progress = { + enabled = true, + -- Lsp Progress is formatted using the builtins for lsp_progress. See config.format.builtin + -- See the section on formatting for more details on how to customize. + --- @type NoiceFormat|string + format = "lsp_progress", + --- @type NoiceFormat|string + format_done = "lsp_progress_done", + throttle = 1000 / 30, -- frequency to update lsp progress message + view = "mini", + }, + override = { + -- override the default lsp markdown formatter with Noice + ["vim.lsp.util.convert_input_to_markdown_lines"] = false, + -- override the lsp markdown formatter with Noice + ["vim.lsp.util.stylize_markdown"] = false, + -- override cmp documentation with Noice (needs the other options to work) + ["cmp.entry.get_documentation"] = false, + }, + hover = { + enabled = true, + silent = false, -- set to true to not show a message if hover is not available + view = nil, -- when nil, use defaults from documentation + ---@type NoiceViewOptions + opts = {}, -- merged with defaults from documentation + }, + signature = { + enabled = true, + auto_open = { + enabled = true, + trigger = true, -- Automatically show signature help when typing a trigger character from the LSP + luasnip = true, -- Will open signature help when jumping to Luasnip insert nodes + throttle = 50, -- Debounce lsp signature help request by 50ms + }, + view = nil, -- when nil, use defaults from documentation + ---@type NoiceViewOptions + opts = {}, -- merged with defaults from documentation + }, + message = { + -- Messages shown by lsp servers + enabled = true, + view = "notify", + opts = {}, + }, + -- defaults for hover and signature help + documentation = { + view = "hover", + ---@type NoiceViewOptions + opts = { + lang = "markdown", + replace = true, + render = "plain", + format = { "{message}" }, + win_options = { concealcursor = "n", conceallevel = 3 }, + }, + }, + }, + markdown = { + hover = { + ["|(%S-)|"] = vim.cmd.help, -- vim help links + ["%[.-%]%((%S-)%)"] = require("noice.util").open, -- markdown links + }, + highlights = { + ["|%S-|"] = "@text.reference", + ["@%S+"] = "@parameter", + ["^%s*(Parameters:)"] = "@text.title", + ["^%s*(Return:)"] = "@text.title", + ["^%s*(See also:)"] = "@text.title", + ["{%S-}"] = "@parameter", + }, + }, + health = { + checker = true, -- Disable if you don't want health checks to run + }, + ---@type NoicePresets + presets = { + -- you can enable a preset by setting it to true, or a table that will override the preset config + -- you can also add custom presets that you can enable/disable with enabled=true + bottom_search = false, -- use a classic bottom cmdline for search + command_palette = false, -- position the cmdline and popupmenu together + long_message_to_split = false, -- long messages will be sent to a split + inc_rename = false, -- enables an input dialog for inc-rename.nvim + lsp_doc_border = false, -- add a border to hover docs and signature help + }, + throttle = 1000 / 30, -- how frequently does Noice need to check for ui updates? This has no effect when in blocking mode. + ---@type NoiceConfigViews + views = { + mini = { + position = { + row = -1, -- Нижний край экрана + col = -1, -- Правый край экрана + }, + size = { + -- Ограничение высоты: максимум 5 строк + height = "auto", -- Автоматическая высота, но не больше max_height + max_height = 5, + }, + win_options = { + winblend = 30, -- Прозрачность (0 = непрозрачно, 100 = полностью прозрачно) + }, + }, + cmdline_popup = { + border = { + style = "none", + padding = { 0, 0 }, + }, + filter_options = {}, + win_options = { + winhighlight = "NormalFloat:NormalFloat,FloatBorder:FloatBorder", + }, + }, + }, ---@see section on views + ---@type NoiceRouteConfig[] + routes = { + -- Перенаправляем все сообщения в вид "mini" + { + filter = { event = "msg_show" }, + view = "mini", + }, + { + filter = { + event = "msg_show", + kind = "", + find = "written", + }, + opts = { skip = true }, + }, + { + view = "notify", + filter = { event = "msg_showmode" }, + }, + }, --- @see section on routes + ---@type table + status = {}, --- @see section on statusline components + ---@type NoiceFormatOptions + format = {}, --- @see section on formatting }, dependencies = { -- if you lazy-load any plugin below, make sure to add proper `module="..."` entries diff --git a/.config/nvim/lua/goodhumored/appearance/ui/nvim-notify.lua b/.config/nvim/lua/goodhumored/appearance/ui/nvim-notify.lua new file mode 100644 index 0000000..42715de --- /dev/null +++ b/.config/nvim/lua/goodhumored/appearance/ui/nvim-notify.lua @@ -0,0 +1,11 @@ +return { + "rcarriga/nvim-notify", + opts = { + timeout = 2000, -- Время жизни уведомлений (2 секунды) + background_colour = "#000000", -- Для корректной прозрачности + top_down = false, -- Новые уведомления появляются снизу + -- Ограничение размера для nvim-notify (для совместимости) + maximum_width = 0.3, + maximum_height = 5, + }, +} diff --git a/.config/nvim/lua/goodhumored/appearance/ui/nvim-tree.lua b/.config/nvim/lua/goodhumored/appearance/ui/nvim-tree.lua index e2ca0df..32ab372 100644 --- a/.config/nvim/lua/goodhumored/appearance/ui/nvim-tree.lua +++ b/.config/nvim/lua/goodhumored/appearance/ui/nvim-tree.lua @@ -42,6 +42,63 @@ return { api.node.navigate.parent(node) api.node.open.edit(node.parent) end + + -- Новая функция для dragon-drop на файле + local function dragon_drop_file() + local node = api.tree.get_node_under_cursor() + local target_path = node.absolute_path + + vim.fn.system("dragon-drop " .. vim.fn.shellescape(target_path)) + end + + local function dragon_drop_directory() + local node = api.tree.get_node_under_cursor() + local target_path + + if node.nodes ~= nil then + -- Если это директория, используем её + target_path = node.absolute_path + else + -- Если это файл, используем родительскую директорию + target_path = node.parent.absolute_path + end + + vim.fn.system("dragon-drop -t " .. vim.fn.shellescape(target_path)) + end + + -- функция для копирования файла из буфера обмена + local function copy_file_from_clipboard() + local node = api.tree.get_node_under_cursor() + local target_dir + + if node.nodes ~= nil then + -- Если это директория, копируем в неё + target_dir = node.absolute_path + else + -- Если это файл, копируем в родительскую директорию + target_dir = node.parent.absolute_path + end + + local source_path = vim.fn.getreg("+"):gsub("\n", "") -- Получаем путь из буфера обмена, убираем перенос строки + + -- Проверяем, существует ли файл + if vim.fn.filereadable(source_path) == 0 then + vim.notify("Invalid or non-existent file path in clipboard: " .. source_path, vim.log.levels.ERROR) + return + end + + -- Формируем команду cp + local cmd = "cp " .. vim.fn.shellescape(source_path) .. " " .. vim.fn.shellescape(target_dir) + local result = vim.fn.system(cmd) + + if vim.v.shell_error == 0 then + vim.notify("File copied successfully to " .. target_dir, vim.log.levels.INFO) + -- Обновляем дерево, чтобы отобразить новый файл + api.tree.reload() + else + vim.notify("Failed to copy file: " .. result, vim.log.levels.ERROR) + end + end require("nvim-tree").setup({ on_attach = function(bufnr) local function opts(desc) @@ -53,6 +110,9 @@ return { vim.keymap.set("n", "L", vsplit_preview, opts("Vsplit Preview")) vim.keymap.set("n", "h", collapse_folder, opts("Close")) vim.keymap.set("n", "H", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set("n", "d", dragon_drop_file, opts("Drag-n-drop file")) + vim.keymap.set("n", "D", dragon_drop_directory, opts("Dragon Drop Directory")) + vim.keymap.set("n", "p", copy_file_from_clipboard, opts("Paste file")) end, }) local api = require("nvim-tree.api") diff --git a/.config/nvim/lua/goodhumored/common-bindings.lua b/.config/nvim/lua/goodhumored/common-bindings.lua index b3b0b08..79b08bd 100644 --- a/.config/nvim/lua/goodhumored/common-bindings.lua +++ b/.config/nvim/lua/goodhumored/common-bindings.lua @@ -63,9 +63,6 @@ vim.keymap.set("n", "th", ":tabprev", { desc = "[T]ab left", noremap = true, vim.keymap.set("n", "tj", ":tabfirst", { desc = "[T]ab home", noremap = true, silent = true }) vim.keymap.set("n", "tk", ":tablast", { desc = "[T]ab end", noremap = true, silent = true }) --- ───────────────────────── close other buffers ───────────────────────── -vim.keymap.set("n", "", ':%bdelete|edit #|normal `"', { noremap = true, silent = true }) - -- ╭─────────────────────────────────────────────────────────╮ -- │ Moving lines │ -- ╰─────────────────────────────────────────────────────────╯ diff --git a/.config/nvim/lua/goodhumored/common-vim-settings.lua b/.config/nvim/lua/goodhumored/common-vim-settings.lua index 5dfcd61..1e8ef4c 100644 --- a/.config/nvim/lua/goodhumored/common-vim-settings.lua +++ b/.config/nvim/lua/goodhumored/common-vim-settings.lua @@ -145,3 +145,118 @@ vim.api.nvim_create_autocmd("FileType", { vim.opt_local.linebreak = true end, }) + +-- ╭─────────────────────────────────────────────────────────╮ +-- │ autoclose untouched buffers │ +-- ╰─────────────────────────────────────────────────────────╯ + +-- Отладочная функция для логирования +-- local function debug_log(msg) +-- print("[BufferAutoClose] " .. msg) +-- end +-- +-- -- Инициализация признака для новых буферов +-- vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, { +-- callback = function() +-- local buf = vim.api.nvim_get_current_buf() +-- local buf_name = vim.api.nvim_buf_get_name(buf) +-- local buftype = vim.api.nvim_buf_get_option(buf, "buftype") +-- -- Пропускаем специальные буферы и nvim-tree +-- if buftype == "" and not buf_name:match("^NvimTree_") then +-- vim.api.nvim_buf_set_var(buf, "ever_modified", false) +-- debug_log("Initialized ever_modified=false for buffer " .. buf .. " (" .. buf_name .. ")") +-- else +-- debug_log("Skipped initialization for buffer " .. buf .. " (" .. buf_name .. "), buftype: " .. buftype) +-- end +-- end, +-- }) +-- +-- -- Отслеживаем изменения в буфере +-- vim.api.nvim_create_autocmd({ "TextChanged", "InsertLeave" }, { +-- callback = function() +-- local buf = vim.api.nvim_get_current_buf() +-- local buf_name = vim.api.nvim_buf_get_name(buf) +-- local buftype = vim.api.nvim_buf_get_option(buf, "buftype") +-- local modified = vim.api.nvim_buf_get_option(buf, "modified") +-- -- Пропускаем специальные буферы и nvim-tree +-- if buftype == "" and not buf_name:match("^NvimTree_") and modified then +-- vim.api.nvim_buf_set_var(buf, "ever_modified", true) +-- debug_log("Set ever_modified=true for buffer " .. buf .. " (" .. buf_name .. ")") +-- else +-- debug_log( +-- "Skipped modification check for buffer " +-- .. buf +-- .. " (" +-- .. buf_name +-- .. "), buftype: " +-- .. buftype +-- .. ", modified: " +-- .. tostring(modified) +-- ) +-- end +-- end, +-- }) +-- +-- -- Закрываем немодифицированные буферы, которые никогда не изменялись +-- vim.api.nvim_create_autocmd({ "BufLeave", "BufHidden" }, { +-- callback = function() +-- local buf = vim.api.nvim_get_current_buf() +-- local buf_name = vim.api.nvim_buf_get_name(buf) +-- local buftype = vim.api.nvim_buf_get_option(buf, "buftype") +-- -- Пропускаем специальные буферы и nvim-tree +-- if buftype ~= "" or buf_name:match("^NvimTree_") then +-- debug_log("Skipped buffer " .. buf .. " (" .. buf_name .. "), buftype: " .. buftype) +-- return +-- end +-- -- Проверяем существование ever_modified +-- local ever_modified = false +-- local success, result = pcall(vim.api.nvim_buf_get_var, buf, "ever_modified") +-- if success then +-- ever_modified = result +-- else +-- debug_log("No ever_modified for buffer " .. buf .. " (" .. buf_name .. "), assuming false") +-- end +-- -- Проверяем условия для закрытия +-- local modified = vim.api.nvim_buf_get_option(buf, "modified") +-- -- local is_hidden = vim.fn.bufwinnr(buf) == -1 || true +-- local is_hidden = true +-- local is_loaded = vim.api.nvim_buf_is_loaded(buf) +-- debug_log( +-- "Checking buffer " +-- .. buf +-- .. " (" +-- .. buf_name +-- .. "): modified=" +-- .. tostring(modified) +-- .. ", hidden=" +-- .. tostring(is_hidden) +-- .. ", loaded=" +-- .. tostring(is_loaded) +-- .. ", ever_modified=" +-- .. tostring(ever_modified) +-- ) +-- if not modified and is_hidden and is_loaded and not ever_modified then +-- local delete_success, delete_error = pcall(vim.api.nvim_buf_delete, buf, { force = true }) +-- if delete_success then +-- debug_log("Deleted buffer " .. buf .. " (" .. buf_name .. ")") +-- else +-- debug_log("Failed to delete buffer " .. buf .. " (" .. buf_name .. "): " .. tostring(delete_error)) +-- end +-- else +-- debug_log( +-- "Buffer " +-- .. buf +-- .. " (" +-- .. buf_name +-- .. ") not deleted: " +-- .. (modified and "modified" or "") +-- .. " " +-- .. (not is_hidden and "not hidden" or "") +-- .. " " +-- .. (not is_loaded and "not loaded" or "") +-- .. " " +-- .. (ever_modified and "ever_modified" or "") +-- ) +-- end +-- end, +-- }) diff --git a/.config/nvim/lua/goodhumored/editing/avante.lua b/.config/nvim/lua/goodhumored/editing/avante.lua new file mode 100644 index 0000000..4e70a36 --- /dev/null +++ b/.config/nvim/lua/goodhumored/editing/avante.lua @@ -0,0 +1,58 @@ +return { + -- enabled = true, + -- "yetone/avante.nvim", + -- event = "VeryLazy", + -- version = false, -- Never set this value to "*"! Never! + -- opts = { + -- provider = "openrouter", + -- vendors = { + -- openrouter = { + -- __inherited_from = "openai", + -- endpoint = "https://openrouter.ai/api/v1", + -- api_key_name = "OPENROUTER_API_KEY", + -- model = "anthropic/claude-3.7-sonnet", + -- }, + -- }, + -- }, + -- -- if you want to build from source then do `make BUILD_FROM_SOURCE=true` + -- build = "make", + -- -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows + -- dependencies = { + -- "nvim-treesitter/nvim-treesitter", + -- "stevearc/dressing.nvim", + -- "nvim-lua/plenary.nvim", + -- "MunifTanjim/nui.nvim", + -- --- The below dependencies are optional, + -- "echasnovski/mini.pick", -- for file_selector provider mini.pick + -- "nvim-telescope/telescope.nvim", -- for file_selector provider telescope + -- "hrsh7th/nvim-cmp", -- autocompletion for avante commands and mentions + -- "ibhagwan/fzf-lua", -- for file_selector provider fzf + -- "nvim-tree/nvim-web-devicons", -- or echasnovski/mini.icons + -- "zbirenbaum/copilot.lua", -- for providers='copilot' + -- { + -- -- support for image pasting + -- "HakonHarnes/img-clip.nvim", + -- event = "VeryLazy", + -- opts = { + -- -- recommended settings + -- default = { + -- embed_image_as_base64 = false, + -- prompt_for_file_name = false, + -- drag_and_drop = { + -- insert_mode = true, + -- }, + -- -- required for Windows users + -- use_absolute_path = true, + -- }, + -- }, + -- }, + -- { + -- -- Make sure to set this up properly if you have lazy=true + -- "MeanderingProgrammer/render-markdown.nvim", + -- opts = { + -- file_types = { "markdown", "Avante" }, + -- }, + -- ft = { "markdown", "Avante" }, + -- }, + -- }, +} diff --git a/.config/nvim/lua/goodhumored/editing/code-companion.lua b/.config/nvim/lua/goodhumored/editing/code-companion.lua new file mode 100644 index 0000000..5706b5b --- /dev/null +++ b/.config/nvim/lua/goodhumored/editing/code-companion.lua @@ -0,0 +1,44 @@ +return { + enabled = false, + "olimorris/codecompanion.nvim", + opts = { + adapters = { + openrouter_claude = function() + return require("codecompanion.adapters").extend("openai_compatible", { + env = { + url = "https://openrouter.ai/api", + api_key = vim.uv.os_getenv("OPENROUTER_API_KEY"), + chat_url = "/v1/chat/completions", + }, + schema = { + model = { + default = "anthropic/claude-3.7-sonnet", + options = { + "anthropic/claude-3.7-sonnet", + "anthropic/claude-3.5-sonnet", + "openai/gpt-4-turbo", + }, + }, + }, + }) + end, + }, + strategies = { + chat = { + adapter = "openrouter_claude", + }, + inline = { + adapter = "openrouter_claude", + }, + }, + }, + keys = { + { "cc", "CodeCompanionChat", desc = "Code Companion Chat", mode = { "n", "v" } }, + { "ci", "CodeCompanionInline", desc = "Code Companion Inline", mode = { "n", "v" } }, + }, + + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-treesitter/nvim-treesitter", + }, +} diff --git a/.config/nvim/lua/goodhumored/integrations/ai.lua b/.config/nvim/lua/goodhumored/integrations/ai.lua new file mode 100644 index 0000000..16cb471 --- /dev/null +++ b/.config/nvim/lua/goodhumored/integrations/ai.lua @@ -0,0 +1,108 @@ +local function getOpenRouterModel(model) + return { + __inherited_from = "openai", + endpoint = "https://openrouter.ai/api/v1", + api_key_name = "OPENROUTER_API_KEY", + model = model, + } +end + +return { + "yetone/avante.nvim", + event = "VeryLazy", + enabled = true, + cond = function() + return vim.uv.os_getenv("OPENROUTER_API_KEY") ~= nil + end, + version = false, -- Never set this value to "*"! Never! + opts = { + mode = "agentic", + auto_suggestions_provider = "codestral", + cursor_applying_provider = nil, + provider = "codestral", + vendors = { + ["claude"] = getOpenRouterModel("anthropic/claude-3.7-sonnet"), + ["codestral"] = getOpenRouterModel("mistralai/codestral-2501"), + ["qwen32"] = getOpenRouterModel("qwen/qwen-2.5-coder-32b-instruct"), + ["qwen7"] = getOpenRouterModel("qwen/qwen2.5-coder-7b-instruct"), + }, + behaviour = { + auto_suggestions = true, -- Experimental stage + enable_cursor_planning_mode = true, + auto_set_highlight_group = true, + auto_set_keymaps = true, + auto_apply_diff_after_generation = false, + support_paste_from_clipboard = false, + minimize_diff = true, -- Whether to remove unchanged lines when applying a code block + enable_token_counting = true, -- Whether to enable token counting. Default to true. + }, + mappings = { + --- @class AvanteConflictMappings + diff = { + ours = "co", + theirs = "ct", + all_theirs = "ca", + both = "cb", + cursor = "cc", + next = "]x", + prev = "[x", + }, + suggestion = { + accept = "", + next = "", + prev = "", + dismiss = "", + }, + jump = { + next = "]]", + prev = "[[", + }, + submit = { + normal = "", + insert = "", + }, + cancel = { + normal = { "", "", "q" }, + insert = { "" }, + }, + }, + hints = { enabled = true }, + suggestion = { + debounce = 400, + throttle = 400, + }, + }, + -- if you want to build from source then do `make BUILD_FROM_SOURCE=true` + build = "make", + -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows + dependencies = { + "nvim-treesitter/nvim-treesitter", + "stevearc/dressing.nvim", + "nvim-lua/plenary.nvim", + "MunifTanjim/nui.nvim", + --- The below dependencies are optional, + -- "echasnovski/mini.pick", -- for file_selector provider mini.pick + "nvim-telescope/telescope.nvim", -- for file_selector provider telescope + -- "hrsh7th/nvim-cmp", -- autocompletion for avante commands and mentions + -- "ibhagwan/fzf-lua", -- for file_selector provider fzf + "nvim-tree/nvim-web-devicons", -- or echasnovski/mini.icons + -- "zbirenbaum/copilot.lua", -- for providers='copilot' + -- { + -- -- support for image pasting + -- "HakonHarnes/img-clip.nvim", + -- event = "VeryLazy", + -- opts = { + -- -- recommended settings + -- default = { + -- embed_image_as_base64 = false, + -- prompt_for_file_name = false, + -- drag_and_drop = { + -- insert_mode = true, + -- }, + -- -- required for Windows users + -- use_absolute_path = true, + -- }, + -- }, + -- }, + }, +} diff --git a/.config/nvim/lua/goodhumored/languages/init.lua b/.config/nvim/lua/goodhumored/languages/init.lua index 9b6d6c4..80404a8 100644 --- a/.config/nvim/lua/goodhumored/languages/init.lua +++ b/.config/nvim/lua/goodhumored/languages/init.lua @@ -5,6 +5,7 @@ return { -- require("goodhumored.languages.rust.rust.vim"), require("goodhumored.languages.rust.rust-tools"), require("goodhumored.languages.markdown.otter"), + require("goodhumored.languages.markdown.view"), require("goodhumored.languages.markdown.obsidian-nvim"), require("goodhumored.languages.markdown.bullets-nvim"), require("goodhumored.languages.markdown.markview"), diff --git a/.config/nvim/lua/goodhumored/languages/markdown/markview.lua b/.config/nvim/lua/goodhumored/languages/markdown/markview.lua index 764f28d..e7d7d70 100644 --- a/.config/nvim/lua/goodhumored/languages/markdown/markview.lua +++ b/.config/nvim/lua/goodhumored/languages/markdown/markview.lua @@ -5,6 +5,7 @@ return { "OXY2DEV/markview.nvim", lazy = false, -- Recommended + enabled = false, -- ft = "markdown" -- If you decide to lazy-load anyway dependencies = { @@ -18,47 +19,52 @@ return { config = function() -- Настройка markview.nvim require("markview").setup({ - modes = { "n", "i", "c" }, - hybrid_modes = { "i" }, + preview = { + modes = { "n", "i", "c" }, + hybrid_modes = { "i" }, + }, checkboxes = { enable = false, -- Отключить чекбоксы, чтобы избежать конфликта с obsidian.nvim }, - headings = { - enable = true, - level_1 = { - style = "icon", - icon = "📌 ", - hl = "MarkviewHeading1", - padding_left = " ", - padding_right = " ", + + markdown = { + headings = { + enable = true, + level_1 = { + style = "icon", + icon = "📌 ", + hl = "MarkviewHeading1", + padding_left = " ", + padding_right = " ", + }, + level_2 = { + style = "icon", + icon = "📋 ", + hl = "MarkviewHeading2", + padding_left = " ", + padding_right = " ", + }, + level_3 = { + style = "icon", + icon = "📝 ", + hl = "MarkviewHeading3", + padding_left = " ", + padding_right = " ", + }, + level_4 = { + style = "icon", + icon = "🔖 ", + hl = "MarkviewHeading4", + padding_left = " ", + padding_right = " ", + }, }, - level_2 = { - style = "icon", - icon = "📋 ", - hl = "MarkviewHeading2", - padding_left = " ", - padding_right = " ", + list_items = { + enable = false, + marker_minus = { rendered = "•" }, + marker_star = { rendered = "★" }, + marker_plus = { rendered = "➕" }, }, - level_3 = { - style = "icon", - icon = "📝 ", - hl = "MarkviewHeading3", - padding_left = " ", - padding_right = " ", - }, - level_4 = { - style = "icon", - icon = "🔖 ", - hl = "MarkviewHeading4", - padding_left = " ", - padding_right = " ", - }, - }, - list_items = { - enable = false, - marker_minus = { rendered = "•" }, - marker_star = { rendered = "★" }, - marker_plus = { rendered = "➕" }, }, links = { enable = false, diff --git a/.config/nvim/lua/goodhumored/languages/markdown/obsidian-nvim.lua b/.config/nvim/lua/goodhumored/languages/markdown/obsidian-nvim.lua index d4b04bc..2284989 100644 --- a/.config/nvim/lua/goodhumored/languages/markdown/obsidian-nvim.lua +++ b/.config/nvim/lua/goodhumored/languages/markdown/obsidian-nvim.lua @@ -78,6 +78,12 @@ return { end, opts = { noremap = true, buffer = true, desc = "[O]bsidian [W]orkspace" }, }, + ["on"] = { + action = function() + return vim.cmd("ObsidianNew") + end, + opts = { noremap = true, buffer = true, desc = "[O]bsidian [N]ew" }, + }, -- Toggle check-boxes. ["ch"] = { action = function() @@ -97,9 +103,9 @@ return { -- Optional, if you keep daily notes in a separate directory. folder = "daily", -- Optional, if you want to change the date format for the ID of daily notes. - date_format = "%Y-%m-%d", + date_format = "%Y-%m-%d-[%a№%W]", -- Optional, if you want to change the date format of the default alias of daily notes. - alias_format = "%B %-d, %Y", + alias_format = " %-d %B %Y [%a№%W], %A", -- Optional, default tags to add to each new daily note created. default_tags = { "daily-notes" }, -- Optional, if you want to automatically insert a template from your template directory like 'daily.md' @@ -152,6 +158,16 @@ return { }, }, + -- Optional, by default when you use `:ObsidianFollowLink` on a link to an external + -- URL it will be ignored but you can customize this behavior here. + ---@param url string + follow_url_func = function(url) + -- Open the URL in the default web browser. + -- vim.fn.jobstart({ "xdg-open", url }) -- Mac OS + -- vim.fn.jobstart({"xdg-open", url}) -- linux + -- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows + vim.ui.open(url) -- need Neovim 0.10.0+ + end, -- Specify how to handle attachments. attachments = { -- The default folder to place images in via `:ObsidianPasteImg`. diff --git a/.config/nvim/lua/goodhumored/languages/markdown/view.lua b/.config/nvim/lua/goodhumored/languages/markdown/view.lua new file mode 100644 index 0000000..8a82d5b --- /dev/null +++ b/.config/nvim/lua/goodhumored/languages/markdown/view.lua @@ -0,0 +1,60 @@ +return { + "MeanderingProgrammer/render-markdown.nvim", + dependencies = { "nvim-treesitter/nvim-treesitter", "echasnovski/mini.nvim" }, -- if you use the mini.nvim suite + -- dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.icons' }, -- if you use standalone mini plugins + -- dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, -- if you prefer nvim-web-devicons + ---@module 'render-markdown' + ---@type render.md.UserConfig + opts = { + bullet = { + enabled = true, + render_modes = false, + icons = { "●", "○", "◆", "◇" }, + ordered_icons = function(ctx) + local value = vim.trim(ctx.value) + local index = tonumber(value:sub(1, #value - 1)) + return ("%d."):format(index > 1 and index or ctx.index) + end, + left_pad = 0, + right_pad = 1, + highlight = "RenderMarkdownBullet", + scope_highlight = {}, + }, + heading = { + sign = true, + signs = { "", "#", "#", "#", "#", "#", "#" }, + position = { "inline" }, + width = { "full", "block" }, + -- left_margin = { 0.5, 0 }, + left_pad = { 0.5, 0 }, + right_pad = { 0.5, 1 }, + border = { true, false }, + -- icons = { "➊ ", "➋ ", "➌ ", "➍ ", "➎ ", "➏ ", "➐ " }, + icons = { --[["𝟙 "]] + "", + "𝟚 ", + "𝟛 ", + "𝟜 ", + "𝟝 ", + "𝟞 ", + "𝟟 ", + }, + backgrounds = { + "BufferVisiblePin", + "BufferVisiblePin", + "BufferVisiblePin", + "BufferVisiblePin", + "BufferVisiblePin", + "BufferVisiblePin", + }, + foregrounds = { + "RenderMarkdownH1", + "RenderMarkdownH2", + "RenderMarkdownH3", + "RenderMarkdownH4", + "RenderMarkdownH5", + "RenderMarkdownH6", + }, + }, + }, +} diff --git a/.config/nvim/luasnippets/package.json b/.config/nvim/luasnippets/package.json index 377041e..62518f1 100644 --- a/.config/nvim/luasnippets/package.json +++ b/.config/nvim/luasnippets/package.json @@ -8,6 +8,13 @@ "typescriptreact" ], "path": "./ts.jsonc" + }, + { + "language": [ + "javascript", + "html" + ], + "path": "./three_js.jsonc" } ] } diff --git a/.config/nvim/luasnippets/three_js.jsonc b/.config/nvim/luasnippets/three_js.jsonc new file mode 100644 index 0000000..17392fb --- /dev/null +++ b/.config/nvim/luasnippets/three_js.jsonc @@ -0,0 +1,29 @@ +{ + // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and + // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope + // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is + // used to trigger the snippet and the body will be expanded and inserted. Possible variables are: + // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. + // Placeholders with the same ids are connected. + // Example: + // "Print to console": { + // "scope": "javascript,typescript", + // "prefix": "log", + // "body": [ + // "console.log('$1');", + // "$2" + // ], + // "description": "Log output to console" + // } + "comp": { + "scope": "html", + "prefix": "comp", + "body": [ + "function make${1:Smth}(w, h) {", + "\tconst group = new THREE.Group();", + "\t$0", + "\treturn group;", + "}" + ] + } +} diff --git a/.config/nvim/luasnippets/ts.jsonc b/.config/nvim/luasnippets/ts.jsonc index bb877df..bcbcab6 100644 --- a/.config/nvim/luasnippets/ts.jsonc +++ b/.config/nvim/luasnippets/ts.jsonc @@ -184,7 +184,7 @@ "scope": "typescript" }, "it": { - "body": "it('${1:should }', () => {\n\t$0\n});", + "body": "it('should $1', () => {\n\t$0\n});", "description": "creates an it block", "prefix": "it", "scope": "typescript" @@ -203,25 +203,25 @@ "scope": "typescript" }, "it.only": { - "body": "it.only('${1:should }', () => {\n\t$0\n});", + "body": "it.only('should $1', () => {\n\t$0\n});", "description": "creates an it block that runs only", "prefix": "ito", "scope": "typescript" }, "it.skip": { - "body": "it.skip('${1:should }', () => {\n\t$0\n});", + "body": "it.skip('should $1', () => {\n\t$0\n});", "description": "creates an it block that will be skipped", "prefix": "its", "scope": "typescript" }, "it.todo": { - "body": "it.todo('${1:should }');", + "body": "it.todo('should $1');", "description": "creates a test placeholder", "prefix": "itt", "scope": "typescript" }, "it:async": { - "body": "it('${1:should }', async () => {\n\t$0\n});", + "body": "it('should $1', async () => {\n\t$0\n});", "description": "creates an it block with async callback function", "prefix": "ita", "scope": "typescript" @@ -237,7 +237,7 @@ "describe('${1:Name of the group}', () => {\n", "\tlet ${2:cut};\n", "\tbeforeEach(() => {\n\t\t$2 = $3;\n\t});\n", - "\ttest('${1:should }', () => {", + "\ttest('should $1', () => {", "\t\texpect($2).toBe($0);", "\t});\n", "});" @@ -247,7 +247,7 @@ "scope": "typescript" }, "test": { - "body": "test('${1:should }', () => {\n\t$0\n});", + "body": "test('should $1', () => {\n\t$0\n});", "description": "creates a test block", "prefix": "test", "scope": "typescript" @@ -280,25 +280,25 @@ "scope": "typescript" }, "test.only": { - "body": "test.only('${1:should }', () => {\n\t$0\n});", + "body": "test.only('should $1', () => {\n\t$0\n});", "description": "creates a test block that runs only", "prefix": "testo", "scope": "typescript" }, "test.skip": { - "body": "test.skip('${1:should }', () => {\n\t$0\n});", + "body": "test.skip('should $1', () => {\n\t$0\n});", "description": "creates a test block that will be skipped", "prefix": "tests", "scope": "typescript" }, "test.todo": { - "body": "test.todo('${1:should }');", + "body": "test.todo('should $1');", "description": "creates a test placeholder", "prefix": "testt", "scope": "typescript" }, "test:async": { - "body": "test('${1:should }', async () => {\n\t$0\n});", + "body": "test('should $1', async () => {\n\t$0\n});", "description": "creates an test block with async callback function", "prefix": "testa", "scope": "typescript" diff --git a/init.sh b/init.sh index 4b376ce..71dcb36 100755 --- a/init.sh +++ b/init.sh @@ -68,7 +68,7 @@ if [ "$OS" = "ubuntu" ]; then # Install Neovim from GitHub releases (latest stable) info "Installing Neovim from GitHub releases..." NVIM_VERSION=$(curl -s https://api.github.com/repos/neovim/neovim/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - wget -O /tmp/nvim-linux64.tar.gz "https://github.com/neovim/neovim/releases/download/${NVIM_VERSION}/nvim-linux64.tar.gz" + wget -O /tmp/nvim-linux64.tar.gz "https://github.com/neovim/neovim/releases/download/${NVIM_VERSION}/nvim-linux-x86_64.tar.gz" sudo tar -C /usr/local -xzf /tmp/nvim-linux64.tar.gz sudo ln -sf /usr/local/nvim-linux64/bin/nvim /usr/local/bin/nvim rm /tmp/nvim-linux64.tar.gz diff --git a/journal/2025/03/23.norg b/journal/2025/03/23.norg deleted file mode 100644 index e69de29..0000000 diff --git a/seed.sh b/seed.sh index ec554e0..8e1d461 100755 --- a/seed.sh +++ b/seed.sh @@ -80,7 +80,7 @@ PUBLIC_KEY=$(cat "$KEY_PATH.pub") NEW_PASS="" if [ "$ANONYMOUS" = false ]; then mkdir -p "$PASS_DIR" - NEW_PASS="$(pass generate "$PASS_NAME" 16 | tail -n1)" + NEW_PASS="$(pass generate -n "$PASS_NAME" 16 | tail -n1 | sed -r 's/\x1B\[[0-9;]*[mK]//g')" echo "DEBUG: Generated password: '$NEW_PASS'" fi @@ -114,6 +114,9 @@ echo "\$SUDO_PASS" | sudo -S chmod 700 "/home/\$NEW_USER" # Set password if [ -n "\$NEW_PASS" ]; then echo "DEBUG: Setting password for \$NEW_USER: \$NEW_PASS" + export NEW_USER="\$NEW_USER" + export NEW_PASS="\$NEW_PASS" + echo "DEBUG: Setting password echo \"\$NEW_USER:\$NEW_PASS\" | chpasswd" echo "\$SUDO_PASS" | sudo -S bash -c "echo \"\$NEW_USER:\$NEW_PASS\" | chpasswd" fi @@ -138,7 +141,7 @@ ssh "$SERVER_NAME" bash -c "$(cat << ENDSSH set -e git clone https://github.com/goodhumored/dotfiles cd dotfiles -./init.sh +echo "$SUDO_PASS" | sudo -S ./init.sh ENDSSH )"