From 8923a1095bf9e93ad89f8637b9a4172972e31afe Mon Sep 17 00:00:00 2001
From: goodhumored <goodhumored@vk.com>
Date: Mon, 19 May 2025 16:03:23 +0300
Subject: [PATCH] feat: another update

---
 .config/hypr/conf/autostart.conf              |   1 +
 .config/hypr/conf/keybindings.conf            |   6 +
 .config/hypr/hyprlock-bg.conf                 |   8 +-
 .config/hypr/scripts/dnd-clipboard.sh         |   2 +-
 .config/lazygit/state.yml                     |  11 +-
 .../lua/goodhumored/appearance/ui/barbar.lua  |   1 +
 .../goodhumored/appearance/ui/noice.nvim.lua  | 240 +++++++++++++++++-
 .../goodhumored/appearance/ui/nvim-notify.lua |  11 +
 .../goodhumored/appearance/ui/nvim-tree.lua   |  60 +++++
 .../nvim/lua/goodhumored/common-bindings.lua  |   3 -
 .../lua/goodhumored/common-vim-settings.lua   | 115 +++++++++
 .../nvim/lua/goodhumored/editing/avante.lua   |  58 +++++
 .../goodhumored/editing/code-companion.lua    |  44 ++++
 .../nvim/lua/goodhumored/integrations/ai.lua  | 108 ++++++++
 .../nvim/lua/goodhumored/languages/init.lua   |   1 +
 .../languages/markdown/markview.lua           |  78 +++---
 .../languages/markdown/obsidian-nvim.lua      |  20 +-
 .../goodhumored/languages/markdown/view.lua   |  60 +++++
 .config/nvim/luasnippets/package.json         |   7 +
 .config/nvim/luasnippets/three_js.jsonc       |  29 +++
 .config/nvim/luasnippets/ts.jsonc             |  22 +-
 init.sh                                       |   2 +-
 journal/2025/03/23.norg                       |   0
 seed.sh                                       |   7 +-
 24 files changed, 824 insertions(+), 70 deletions(-)
 create mode 100644 .config/nvim/lua/goodhumored/appearance/ui/nvim-notify.lua
 create mode 100644 .config/nvim/lua/goodhumored/editing/avante.lua
 create mode 100644 .config/nvim/lua/goodhumored/editing/code-companion.lua
 create mode 100644 .config/nvim/lua/goodhumored/integrations/ai.lua
 create mode 100644 .config/nvim/lua/goodhumored/languages/markdown/view.lua
 create mode 100644 .config/nvim/luasnippets/three_js.jsonc
 delete mode 100644 journal/2025/03/23.norg

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", "<A-p>", "<Cmd>BufferPin<CR>", { desc = "Pin tab" })
 		-- Close buffer
 		vim.keymap.set("n", "<A-c>", "<Cmd>BufferClose<CR>", { desc = "Close tab" })
+		vim.keymap.set("n", "<A-C>", "<Cmd>BufferCloseAllButCurrentOrPinned<CR>", { desc = "Close others" })
 		vim.keymap.set("n", "<A-/>", "<Cmd>BufferPick<CR>", { 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<string, CmdlineFormat>
+			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<string, NoiceCommand>
+		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<string, NoiceFilter>
+		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", "<leader>d", dragon_drop_file, opts("Drag-n-drop file"))
+				vim.keymap.set("n", "<leader>D", dragon_drop_directory, opts("Dragon Drop Directory"))
+				vim.keymap.set("n", "<leader>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<CR>", { desc = "[T]ab left", noremap = true,
 vim.keymap.set("n", "tj", ":tabfirst<CR>", { desc = "[T]ab home", noremap = true, silent = true })
 vim.keymap.set("n", "tk", ":tablast<CR>", { desc = "[T]ab end", noremap = true, silent = true })
 
---  ───────────────────────── close other buffers ─────────────────────────
-vim.keymap.set("n", "<A-S-c>", ':%bdelete|edit #|normal `"<CR>', { 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 = {
+		{ "<leader>cc", "<cmd>CodeCompanionChat<cr>", desc = "Code Companion Chat", mode = { "n", "v" } },
+		{ "<leader>ci", "<cmd>CodeCompanionInline<cr>", 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 = "<M-l>",
+				next = "<M-]>",
+				prev = "<M-[>",
+				dismiss = "<C-]>",
+			},
+			jump = {
+				next = "]]",
+				prev = "[[",
+			},
+			submit = {
+				normal = "<CR>",
+				insert = "<C-s>",
+			},
+			cancel = {
+				normal = { "<C-c>", "<Esc>", "q" },
+				insert = { "<C-c>" },
+			},
+		},
+		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" },
 			},
+			["<leader>on"] = {
+				action = function()
+					return vim.cmd("ObsidianNew")
+				end,
+				opts = { noremap = true, buffer = true, desc = "[O]bsidian [N]ew" },
+			},
 			-- Toggle check-boxes.
 			["<leader>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
 )"