Compare commits

...

8 Commits

22 changed files with 881 additions and 92 deletions

View File

@ -12,7 +12,8 @@ $mainMod = SUPER # Sets "Windows" key as main modifier
# apps # apps
bind = $mainMod, T, exec, $terminal # terminal bind = $mainMod, T, exec, $terminal # terminal
bind = $mainMod SHIFT, T, exec, crow bind = $mainMod SHIFT, T, exec, crow
bind = $mainMod CTRL SHIFT, T, exec, ~/.config/hypr/scripts/translate-selection.sh bind = CTRL ALT, T, exec, ~/.config/hypr/scripts/translate-clipboard.sh
bind = CTRL SHIFT ALT, T, exec, ~/.config/hypr/scripts/translate-selection.sh
bind = $mainMod, E, exec, $fileManager # file manager bind = $mainMod, E, exec, $fileManager # file manager
bind = $mainMod, A, exec, $toggle_menu_cmd # wofi bind = $mainMod, A, exec, $toggle_menu_cmd # wofi
bind = $mainMod CTRL ALT, V, exec, ~/.config/hypr/scripts/dnd-clipboard.sh bind = $mainMod CTRL ALT, V, exec, ~/.config/hypr/scripts/dnd-clipboard.sh
@ -154,4 +155,4 @@ bindm = $mainMod, mouse:273, resizewindow
bindl = , switch:on:Lid Switch, exec, hyprctl keyword monitor "eDP-1, disable" bindl = , switch:on:Lid Switch, exec, hyprctl keyword monitor "eDP-1, disable"
# При открытии крышки (Lid Switch выключён) # При открытии крышки (Lid Switch выключён)
bindl = , switch:off:Lid Switch, exec, hyprctl keyword monitor "eDP-1, preferred, auto, 1" bindl = , switch:off:Lid Switch, exec, hyprctl keyword monitor "eDP-1,1920x1080@60.01,0x0,1.0"

View File

@ -44,6 +44,9 @@ source = ./conf/autostart.conf
env = XCURSOR_SIZE,24 env = XCURSOR_SIZE,24
env = HYPRCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24
debug {
disable_logs = false
}
##################### #####################
### LOOK AND FEEL ### ### LOOK AND FEEL ###
@ -166,14 +169,14 @@ source = ./conf/keybindings.conf
# │ WINDOWRULES │ # │ WINDOWRULES │
# ╰──────────────────────────────────────────────────────────╯ # ╰──────────────────────────────────────────────────────────╯
# ──────────────────────────────── copyq ────────────────────────────── # ──────────────────────────────── copyq ──────────────────────────────
windowrule = size 300 400,class:^(copyq)$ windowrule = size 300 400,class:com.github.hluk.copyq
windowrule = float,class:com.github.hluk.copyq windowrule = float,class:com.github.hluk.copyq
windowrule = move onscreen cursor,class:com.github.hluk.copyq windowrule = move onscreen cursor,class:com.github.hluk.copyq
# ────────────────────── Browser Picture in Picture ────────────────────── # ────────────────────── Browser Picture in Picture ──────────────────────
windowrulev2 = float, title:^(Picture-in-Picture)$ windowrule = float, title:^(Picture-in-Picture)$
windowrulev2 = pin, title:^(Picture-in-Picture)$ windowrule = pin, title:^(Picture-in-Picture)$
windowrulev2 = move 69.5% 4%, title:^(Picture-in-Picture)$ windowrule = move 69.5% 4%, title:^(Picture-in-Picture)$
# ──────────────────────── telegram media viewer ────────────────────── # ──────────────────────── telegram media viewer ──────────────────────
windowrulev2 = float, title:(Media viewer) windowrulev2 = float, title:(Media viewer)
@ -214,6 +217,3 @@ windowrule = size 400 400, class:(.*)(Figure)(.*)
windowrule = suppressevent maximize, class:.* # You'll probably like this. windowrule = suppressevent maximize, class:.* # You'll probably like this.
workspace = special:music, opacity:0.5
workspace = opacity 0.5, onworkspace:name:special:music
workspace = special:music, gapsout:100

View File

@ -1,9 +1,13 @@
background { background {
monitor = eDP-1 monitor = eDP-1
path = /home/goodhumored/wallpapers/3.png path = /home/goodhumored/wallpapers/7.png
} }
background { background {
monitor = DP-2 monitor = DP-2
path = /home/goodhumored/wallpapers/3.png path = /home/goodhumored/wallpapers/7.png
}
background {
monitor = HDMI-A-1
path = /home/goodhumored/wallpapers/7.png
} }

View File

@ -21,5 +21,5 @@ monitor=desc:Iiyama North America PL3270Q 1155103721286,2560x1440@59.95,-640x-14
# Домашний монитор # Домашний монитор
monitor=desc:BNQ BenQ G925HDA 29A01966019,prefered,auto,1.0 monitor=desc:BNQ BenQ G925HDA 29A01966019,prefered,auto,1.0
monitor=desc:HJW MACROSILICON 0x0002E842,prefered,320x-720,1.0 monitor=desc:HJW MACROSILICON 0x0002E842,prefered,320x-720,1.0
monitor=desc:Huawei Technologies Co. Inc. ZQE-CBA 0xC080F622,3440x1440@100Hz,-760x-1440,1,bitdepth,10, cm, hdr monitor=desc:Huawei Technologies Co. Inc. ZQE-CBA 0xC080F622,3440x1440@120Hz,-760x-1440,1,bitdepth,10, cm, hdr
monitor=desc:Huawei Technologies Co. Inc. ZQE-CBA 0xC080F622,3440x1440@100Hz,-760x-1440,1,bitdepth,10 monitor=desc:Huawei Technologies Co. Inc. ZQE-CBA 0xC080F622,3440x1440@120Hz,-760x-1440,1,bitdepth,10

View File

@ -0,0 +1,18 @@
#!/bin/bash
copied_text=$(wl-paste)
# Проверяем, есть ли выделенный текст
if [ -z "$copied_text" ]; then
notify-send "Ошибка" "Нет выделенного текста"
exit 1
fi
# Переводим текст с помощью crow (на русский, например)
translated_text=$(echo "$copied_text" | crow -i -t ru)
# Выводим результат через notify-send
notify-send "Перевод" "$translated_text"
# ─────────────────────────── Старый вариант: ───────────────────────────
# qdbus io.crow_translate.CrowTranslate /io/crow_translate/CrowTranslate/MainWindow translateSelection

View File

@ -1 +1,19 @@
qdbus io.crow_translate.CrowTranslate /io/crow_translate/CrowTranslate/MainWindow translateSelection #!/bin/bash
# Получаем выделенный текст (primary selection)
selected_text=$(wl-paste --primary)
# Проверяем, есть ли выделенный текст
if [ -z "$selected_text" ]; then
notify-send "Ошибка" "Нет выделенного текста"
exit 1
fi
# Переводим текст с помощью crow (на русский, например)
translated_text=$(echo "$selected_text" | crow -i -t ru)
# Выводим результат через notify-send
notify-send "Перевод" "$translated_text"
# ─────────────────────────── Старый вариант: ───────────────────────────
# qdbus io.crow_translate.CrowTranslate /io/crow_translate/CrowTranslate/MainWindow translateSelection

View File

@ -1,32 +1,11 @@
return { return {
"ellisonleao/gruvbox.nvim", "sainnhe/gruvbox-material",
lazy = false,
priority = 1000, priority = 1000,
config = function() config = function()
require("gruvbox").setup({ -- Optionally configure and load the colorscheme
terminal_colors = true, -- add neovim terminal colors -- directly inside the plugin declaration.
undercurl = true, vim.g.gruvbox_material_enable_italic = true
underline = true, vim.cmd.colorscheme("gruvbox-material")
bold = true,
italic = {
strings = true,
emphasis = true,
comments = true,
operators = false,
folds = true,
},
strikethrough = true,
invert_selection = false,
invert_signs = false,
invert_tabline = false,
invert_intend_guides = false,
inverse = true, -- invert background for search, diffs, statuslines and errors
contrast = "", -- can be "hard", "soft" or empty string
palette_overrides = {},
overrides = {},
dim_inactive = false,
transparent_mode = false,
})
vim.o.background = "dark"
vim.cmd("colorscheme gruvbox")
end, end,
} }

View File

@ -42,6 +42,16 @@ return {
-- Or, specify all three -- Or, specify all three
Outline = { event = "BufWinLeave", text = "symbols-outline", align = "right" }, Outline = { event = "BufWinLeave", text = "symbols-outline", align = "right" },
}, },
custom_buffer_name = function(bufnr)
local filetype = vim.api.nvim_buf_get_option(bufnr, "filetype")
if filetype == "markdown" and vim.b[bufnr].obsidian_note then
local note = vim.b[bufnr].obsidian_note
return note.title
or table.concat(note.aliases, ", ")
or vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":t:r")
end
return vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":t")
end,
}, },
version = "^1.0.0", -- optional: only update when a new 1.x version is released version = "^1.0.0", -- optional: only update when a new 1.x version is released
} }

View File

@ -4,32 +4,33 @@ return {
config = function() config = function()
require("lualine").setup({ require("lualine").setup({
options = { options = {
theme = "iceberg_dark", icons_enabled = true, -- Включить иконки
component_separators = "", theme = "gruvbox-material",
section_separators = { left = "", right = "" }, component_separators = { left = " ", right = " " },
section_separators = { left = " ", right = " " },
disabled_filetypes = { -- Отключить lualine для определённых типов файлов
statusline = {},
winbar = {},
},
-- always_divide_middle = true,
globalstatus = true, -- Один статусбар для всех окон
}, },
sections = { sections = {
lualine_a = { { "mode", separator = { left = "" }, right_padding = 2 } }, lualine_a = { "mode" }, -- Режим (Normal, Insert, etc.)
lualine_b = { "filename", "branch" }, lualine_b = { "branch", "diagnostics" }, -- Git и диагностика
lualine_c = { lualine_c = { "filename" }, -- Имя файла
"%=", --[[ add your center compoentnts here in place of this comment ]] lualine_x = { "fileformat", "filetype" }, -- Кодировка, формат, тип файла
}, lualine_y = { "progress" }, -- Прогресс в файле
lualine_x = {}, lualine_z = { "location" }, -- Положение курсора
lualine_y = { "filetype", "progress" },
lualine_z = {
{ "location", separator = { right = "" }, left_padding = 2 },
},
}, },
inactive_sections = { inactive_sections = {
lualine_a = { "filename" }, lualine_a = {},
lualine_b = {}, lualine_b = {},
lualine_c = {}, lualine_c = { "filename" },
lualine_x = {}, lualine_x = { "location" },
lualine_y = {}, lualine_y = {},
lualine_z = { "location" }, lualine_z = {},
}, },
tabline = {},
extensions = {},
}) })
end, end,
} }

View File

@ -58,7 +58,9 @@ return {
local api = require("nvim-tree.api") local api = require("nvim-tree.api")
vim.keymap.set("n", "<leader>e", api.tree.toggle, { desc = "[E]xplorer" }) vim.keymap.set("n", "<leader>e", api.tree.toggle, { desc = "[E]xplorer" })
vim.keymap.set("n", "<leader>E", function() vim.keymap.set("n", "<leader>E", function()
-- api.tree.open() -- Просто открываем дерево
api.tree.find_file({ open = true, focus = true }) api.tree.find_file({ open = true, focus = true })
-- api.tree.find_file({ focus = true })
end, { desc = "Focus file in [E]xplorer" }) end, { desc = "Focus file in [E]xplorer" })
end, end,
} }

View File

@ -69,6 +69,8 @@ vim.opt.cursorline = true
-- Minimal number of screen lines to keep above and below the cursor. -- Minimal number of screen lines to keep above and below the cursor.
vim.opt.scrolloff = 10 vim.opt.scrolloff = 10
vim.o.termguicolors = true
-- [[ Basic Keymaps ]] -- [[ Basic Keymaps ]]
-- See `:help vim.keymap.set()` -- See `:help vim.keymap.set()`

View File

@ -1,3 +1,18 @@
return { return {
"jiangmiao/auto-pairs", "windwp/nvim-autopairs",
-- config = function()
-- require("nvim-autopairs").setup({
-- check_ts = true, -- Опционально, если используешь treesitter
-- })
--
-- -- Переопределяем автокомманду BufEnter
-- vim.api.nvim_create_autocmd("BufEnter", {
-- group = vim.api.nvim_create_augroup("NvimAutopairsCustom", { clear = true }),
-- callback = function()
-- if vim.bo.filetype ~= "NvimTree" then
-- require("nvim-autopairs").on_enter()
-- end
-- end,
-- })
-- end,
} }

View File

@ -5,8 +5,10 @@ return {
-- require("goodhumored.languages.rust.rust.vim"), -- require("goodhumored.languages.rust.rust.vim"),
require("goodhumored.languages.rust.rust-tools"), require("goodhumored.languages.rust.rust-tools"),
require("goodhumored.languages.markdown.otter"), require("goodhumored.languages.markdown.otter"),
require("goodhumored.languages.markdown.obsidian-nvim"),
require("goodhumored.languages.markdown.bullets-nvim"),
require("goodhumored.languages.markdown.markview"), require("goodhumored.languages.markdown.markview"),
require("goodhumored.languages.markdown.markdown-preview"), -- require("goodhumored.languages.markdown.markdown-preview"),
require("goodhumored.languages.plantuml.plantuml"), require("goodhumored.languages.plantuml.plantuml"),
}, },
} }

View File

@ -0,0 +1,3 @@
return {
"bullets-vim/bullets.vim",
}

View File

@ -14,4 +14,60 @@ return {
"nvim-treesitter/nvim-treesitter", "nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons", "nvim-tree/nvim-web-devicons",
}, },
config = function()
-- Настройка markview.nvim
require("markview").setup({
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 = " ",
},
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 = " ",
},
},
list_items = {
enable = false,
marker_minus = { rendered = "" },
marker_star = { rendered = "" },
marker_plus = { rendered = "" },
},
links = {
enable = false,
conceal = false,
hl = "Underlined",
},
conceal = {
enabled = true,
},
})
end,
} }

View File

@ -0,0 +1,183 @@
return {
"epwalsh/obsidian.nvim",
version = "*", -- recommended, use latest release instead of latest commit
lazy = true,
ft = "markdown",
-- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault:
-- event = {
-- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'.
-- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md"
-- -- refer to `:h file-pattern` for more examples
-- "BufReadPre path/to/my-vault/*.md",
-- "BufNewFile path/to/my-vault/*.md",
-- },
dependencies = {
-- Required.
"nvim-lua/plenary.nvim",
-- see below for full list of optional dependencies 👇
},
opts = {
workspaces = {
{
name = "personal",
path = "~/notes/personal",
},
{
name = "work",
path = "~/notes/work/",
},
{
name = "study",
path = "~/notes/study",
},
},
-- Optional, configure key mappings. These are the defaults. If you don't want to set any keymappings this
-- way then set 'mappings = {}'.
mappings = {
-- Overrides the 'gf' mapping to work on markdown/wiki links within your vault.
["gf"] = {
action = function()
return require("obsidian").util.gf_passthrough()
end,
opts = { noremap = false, expr = true, buffer = true },
},
["<leader>njt"] = {
action = function()
return vim.cmd("ObsidianToday")
end,
opts = { noremap = true, buffer = true, desc = "Open [t]oday's daily note" },
},
["<leader>njT"] = {
action = function()
return vim.cmd("ObsidianTomorrow")
end,
opts = { noremap = true, buffer = true, desc = "Open [t]omorrow's daily note" },
},
["<leader>njy"] = {
action = function()
return vim.cmd("ObsidianYesterday")
end,
opts = { noremap = true, buffer = true, desc = "Open [y]esterday's daily note" },
},
["<leader>nj"] = {
action = function()
return vim.cmd("ObsidianDailies")
end,
opts = { noremap = true, buffer = true, desc = "Obsidian dailies" },
},
["<leader>so"] = {
action = function()
return vim.cmd("ObsidianSearch")
end,
opts = { noremap = true, buffer = true, desc = "[S]earch [O]bsidian" },
},
["<leader>ow"] = {
action = function()
return vim.cmd("ObsidianWorkspace")
end,
opts = { noremap = true, buffer = true, desc = "[O]bsidian [W]orkspace" },
},
-- Toggle check-boxes.
["<leader>ch"] = {
action = function()
return require("obsidian").util.toggle_checkbox()
end,
opts = { buffer = true },
},
-- Smart action depending on context, either follow link or toggle checkbox.
["<cr>"] = {
action = function()
return require("obsidian").util.smart_action()
end,
opts = { buffer = true, expr = true },
},
},
daily_notes = {
-- 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",
-- Optional, if you want to change the date format of the default alias of daily notes.
alias_format = "%B %-d, %Y",
-- 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'
template = nil,
},
ui = {
enable = true, -- set to false to disable all additional syntax features
update_debounce = 200, -- update delay after a text change (in milliseconds)
max_file_length = 5000, -- disable UI features for files with more than this many lines
-- Define how various check-boxes are displayed
checkboxes = {
-- NOTE: the 'char' value has to be a single character, and the highlight groups are defined below.
[" "] = { char = "󰄱", hl_group = "ObsidianTodo" },
["."] = { char = "󰦖", hl_group = "ObsidianInProgress" },
["x"] = { char = "󰸞", hl_group = "ObsidianDone" },
["="] = { char = "", hl_group = "ObsidianPause" },
[">"] = { char = "󱞩", hl_group = "ObsidianRightArrow" },
["~"] = { char = "", hl_group = "ObsidianTilde" },
["!"] = { char = "󱈸", hl_group = "ObsidianImportant" },
-- Replace the above with this if you don't have a patched font:
-- [" "] = { char = "☐", hl_group = "ObsidianTodo" },
-- ["x"] = { char = "✔", hl_group = "ObsidianDone" },
-- You can also add more custom ones...
},
-- Use bullet marks for non-checkbox lists.
bullets = { char = "", hl_group = "ObsidianBullet" },
external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" },
-- Replace the above with this if you don't have a patched font:
-- external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" },
reference_text = { hl_group = "ObsidianRefText" },
highlight_text = { hl_group = "ObsidianHighlightText" },
tags = { hl_group = "ObsidianTag" },
block_ids = { hl_group = "ObsidianBlockID" },
hl_groups = {
-- The options are passed directly to `vim.api.nvim_set_hl()`. See `:help nvim_set_hl`.
ObsidianTodo = { bold = true, fg = "#89ddff" },
ObsidianInProgress = { bold = true, fg = "#a8e0ae" },
ObsidianDone = { bold = true, fg = "#84c470" },
ObsidianRightArrow = { bold = true, fg = "#f78c6c" },
ObsidianTilde = { bold = true, fg = "#bbbcc7" },
ObsidianImportant = { bold = true, fg = "#d73128" },
ObsidianPause = { bold = true, fg = "#bcd1a7" },
ObsidianBullet = { bold = true, fg = "#89ddff" },
ObsidianRefText = { underline = true, fg = "#c792ea" },
ObsidianExtLinkIcon = { fg = "#c792ea" },
ObsidianTag = { italic = true, fg = "#89ddff" },
ObsidianBlockID = { italic = true, fg = "#89ddff" },
ObsidianHighlightText = { bg = "#75662e" },
},
},
-- Specify how to handle attachments.
attachments = {
-- The default folder to place images in via `:ObsidianPasteImg`.
-- If this is a relative path it will be interpreted as relative to the vault root.
-- You can always override this per image by passing a full path to the command instead of just a filename.
img_folder = "assets/imgs", -- This is the default
-- Optional, customize the default name or prefix when pasting images via `:ObsidianPasteImg`.
---@return string
img_name_func = function()
-- Prefix image names with timestamp.
return string.format("%s-", os.time())
end,
-- A function that determines the text to insert in the note when pasting an image.
-- It takes two arguments, the `obsidian.Client` and an `obsidian.Path` to the image file.
-- This is the default implementation.
---@param client obsidian.Client
---@param path obsidian.Path the absolute path to the image file
---@return string
img_text_func = function(client, path)
path = client:vault_relative_path(path) or path
return string.format("![%s](%s)", path.name, path)
end,
},
-- see below for full list of options 👇
},
}

View File

@ -45,35 +45,35 @@ return {
end, end,
keys = { keys = {
{ -- {
"<leader>nw", -- "<leader>nw",
":Neorg workspace ", -- ":Neorg workspace ",
desc = "[N]eorg [W]orkspaces", -- desc = "[N]eorg [W]orkspaces",
}, -- },
{ -- {
"<leader>nj", -- "<leader>nj",
":Neorg journal<CR>", -- ":Neorg journal<CR>",
desc = "[N]eorg [J]ournal", -- desc = "[N]eorg [J]ournal",
}, -- },
{ -- {
"<leader>ni", -- "<leader>ni",
":Neorg index<CR>", -- ":Neorg index<CR>",
desc = "[N]eorg [I]ndex", -- desc = "[N]eorg [I]ndex",
}, -- },
{ -- {
"<leader>nT", -- "<leader>nT",
":Neorg toc qflist<CR>", -- ":Neorg toc qflist<CR>",
desc = "[N]eorg [T]able of contents", -- desc = "[N]eorg [T]able of contents",
}, -- },
{ -- {
"<leader>nr", -- "<leader>nr",
":Neorg return<CR>", -- ":Neorg return<CR>",
desc = "[N]eorg [R]eturn", -- desc = "[N]eorg [R]eturn",
}, -- },
{ -- {
"<leader>tl", -- "<leader>tl",
":Neorg render-latex<CR>", -- ":Neorg render-latex<CR>",
desc = "[N]eorg [L]atex", -- desc = "[N]eorg [L]atex",
}, -- },
}, },
} }

View File

@ -110,6 +110,11 @@ set -g @continuum-restore 'on' # enabling
# ╰──────────────────────────────────────────────────────────╯ # ╰──────────────────────────────────────────────────────────╯
set -g @plugin 'egel/tmux-gruvbox' set -g @plugin 'egel/tmux-gruvbox'
set -g @tmux-gruvbox 'dark' set -g @tmux-gruvbox 'dark'
set -g @tmux-gruvbox-status-left "#[bg=colour241,fg=colour248] #S #[bg=colour237,fg=colour241,nobold,noitalics,nounderscore]"
set -g @tmux-gruvbox-status-right "#[bg=colour237,fg=colour239 nobold, nounderscore, noitalics]#[bg=colour239,fg=colour246] %Y-%m-%d │ %H:%M #[bg=colour239,fg=colour248,nobold,noitalics,nounderscore]#[bg=colour248,fg=colour237] #h "
set -g @tmux-gruvbox-window-status-current-format "#[bg=colour214,fg=colour237,nobold,noitalics,nounderscore]#[bg=colour214,fg=colour239] #I │#[bg=colour214,fg=colour239,bold] #W#{?window_zoomed_flag,*Z,} #[bg=colour237,fg=colour214,nobold,noitalics,nounderscore]"
set -g @tmux-gruvbox-window-status-format "#[bg=colour239,fg=colour237,noitalics]#[bg=colour239,fg=colour223] #I │#[bg=colour239,fg=colour223] #W #[bg=colour237,fg=colour239,noitalics]│"
# ╭──────────────────────────────────────────────────────────╮ # ╭──────────────────────────────────────────────────────────╮
# │ Dracula theme │ # │ Dracula theme │

135
init.sh Executable file
View File

@ -0,0 +1,135 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Function to print messages
info() {
echo -e "${GREEN}[INFO] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}" >&2
exit 1
}
# Detect OS
OS=""
if [ -f /etc/os-release ]; then
. /etc/os-release
case $ID in
ubuntu)
OS="ubuntu"
;;
arch)
OS="arch"
;;
*)
error "Unsupported OS: $ID"
;;
esac
else
error "Cannot detect OS. /etc/os-release not found."
fi
info "Detected OS: $OS"
# Ensure we're in the dotfiles directory
if [ ! -f "$(pwd)/.gitmodules" ]; then
error "This script must be run from the dotfiles repository directory"
fi
# Install prerequisites
info "Installing prerequisites..."
if [ "$OS" = "ubuntu" ]; then
# Update package lists
sudo apt update && sudo apt upgrade -y
# Install required packages
sudo apt install -y git tmux stow fzf gcc
# Install optional packages (bat, fd-find, zoxide)
sudo apt install -y bat fd-find
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash
# Install eza (community-maintained ls alternative)
sudo mkdir -p /etc/apt/keyrings
wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg
echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list
sudo chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list
sudo apt update
sudo apt install -y eza
# 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"
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
# Install thefuck
sudo apt install -y python3-pip
pip3 install thefuck --user
elif [ "$OS" = "arch" ]; then
# Ensure yay is installed for AUR packages
if ! command -v yay &> /dev/null; then
info "Installing yay..."
sudo pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git /tmp/yay
cd /tmp/yay
makepkg -si --noconfirm
cd - && rm -rf /tmp/yay
fi
# Install all packages
yay -S --noconfirm git tmux neovim zoxide stow fzf bat eza fd gcc thefuck
fi
# Initialize and update submodules
info "Initializing git submodules..."
git submodule update --init --recursive
# Backup existing config files
info "Backing up existing configuration files..."
BACKUP_DIR="$HOME/.dotfiles_backup_$(date +%F_%H-%M-%S)"
mkdir -p "$BACKUP_DIR"
for file in .gitconfig .zshrc .tmux.conf .bashrc; do
[ -f "$HOME/$file" ] && mv "$HOME/$file" "$BACKUP_DIR/$file" && info "Backed up ~/$file to $BACKUP_DIR/$file"
done
for dir in .config/nvim .config/mc kam .oh-my-zsh .tmux; do
[ -d "$HOME/$dir" ] && mv "$HOME/$dir" "$BACKUP_DIR/$(basename $dir)" && info "Backed up ~/$dir to $BACKUP_DIR/$(basename $dir)"
done
# Create symlinks with stow
info "Creating symlinks with stow..."
stow .
# Change shell to zsh
if [ "$(basename "$SHELL")" != "zsh" ]; then
info "Changing shell to zsh..."
ZSH_PATH=$(which zsh)
if [ -z "$ZSH_PATH" ]; then
error "zsh not found. Please install zsh and run 'chsh -s $(which zsh)' manually."
fi
chsh -s "$ZSH_PATH"
info "Shell changed to zsh. Please log out and log back in for the change to take effect."
fi
# Final instructions
info "Dotfiles setup complete!"
echo "To source tmux configuration:"
echo "1. Start tmux with 'tmux'"
echo "2. Press <prefix>: (default is Ctrl+b)"
echo "3. Type 'source ~/.tmux.conf' and press Enter"
echo
echo "Backup of previous configs is stored in: $BACKUP_DIR"
echo "You may need to log out and log back in for zsh to take effect."

91
local_seed.sh Executable file
View File

@ -0,0 +1,91 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Default values
ANONYMOUS=false
USERNAME="goodhumored"
# Function to print messages
info() {
echo -e "${GREEN}[INFO] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}" >&2
exit 1
}
# Function to generate random username for anonymous mode
generate_random_username() {
echo "user$(head /dev/urandom | tr -dc a-z0-9 | head -c 8)"
}
# Function to display usage
usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " -u, --username Username to create (default: goodhumored)"
echo " -a, --anonymous Run in anonymous mode (random username, no dotfiles)"
exit 1
}
# Parse command line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
-u|--username) USERNAME="$2"; shift ;;
-a|--anonymous) ANONYMOUS=true ;;
*) echo "Unknown parameter: $1"; usage ;;
esac
shift
done
# Set username for anonymous mode
if [ "$ANONYMOUS" = true ]; then
USERNAME=$(generate_random_username)
fi
# Check if running as root
if [ "$(id -u)" -ne 0 ]; then
error "This script must be run with sudo privileges"
fi
# Create user and setup home directory
info "Creating user $USERNAME..."
useradd -m -s /bin/bash -G sudo "$USERNAME"
chmod 700 "/home/$USERNAME"
# Setup SSH directory and authorized_keys
info "Setting up SSH directory..."
mkdir -p "/home/$USERNAME/.ssh"
chmod 700 "/home/$USERNAME/.ssh"
touch "/home/$USERNAME/.ssh/authorized_keys"
chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"
# Install dependencies
info "Installing dependencies..."
apt-get update
apt-get install -y git stow
# Clone and setup dotfiles (non-anonymous mode only)
if [ "$ANONYMOUS" = false ]; then
info "Cloning dotfiles repository..."
su - "$USERNAME" -c "git clone https://github.com/goodhumored/dotfiles /home/$USERNAME/dotfiles"
info "Running init.sh..."
su - "$USERNAME" -c "cd /home/$USERNAME/dotfiles && ./init.sh"
fi
info "Local server setup complete!"
echo "Username: $USERNAME"
if [ "$ANONYMOUS" = false ]; then
echo "Dotfiles have been cloned and initialized."
else
echo "Anonymous mode: No dotfiles cloned."
fi
echo "You can now add an SSH public key to /home/$USERNAME/.ssh/authorized_keys"

150
seed.sh Executable file
View File

@ -0,0 +1,150 @@
#!/bin/bash
set -e
# Defaults
ANONYMOUS=false
PORT=22
NEW_USER="goodhumored"
PASS_DIR="$HOME/.password-store"
# Random username for anonymous mode
generate_random_username() {
echo "user$(head /dev/urandom | tr -dc a-z0-9 | head -c 8)"
}
# Usage
usage() {
echo "Usage: $0 [options]"
echo " -h, --host Server IP"
echo " -p, --port SSH port (default: 22)"
echo " -r, --root_user Sudo user for SSH"
echo " -s, --server_name Server name for SSH config"
echo " -u, --username User to create (default: goodhumored)"
echo " -n, --pass_name Password store name"
echo " -a, --anonymous Anonymous mode"
exit 1
}
# Check sshpass
if ! command -v sshpass &> /dev/null; then
echo "Ошибка: нужен sshpass."
echo "Установи: sudo apt-get install sshpass (Ubuntu) или sudo pacman -S sshpass (Arch)"
exit 1
fi
# Parse args
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--host) HOST="$2"; shift ;;
-p|--port) PORT="$2"; shift ;;
-r|--root_user) ROOT_USER="$2"; shift ;;
-s|--server_name) SERVER_NAME="$2"; shift ;;
-u|--username) NEW_USER="$2"; shift ;;
-n|--pass_name) PASS_NAME="$2"; shift ;;
-a|--anonymous) ANONYMOUS=true ;;
*) echo "Неизвестный параметр: $1"; usage ;;
esac
shift
done
# Validate args
if [ -z "$HOST" ] || [ -z "$ROOT_USER" ] || [ -z "$SERVER_NAME" ]; then
echo "Ошибка: нужны host, root_user и server_name"
usage
fi
# Prompt for password
if [ "$ANONYMOUS" = false ]; then
if [ -z "$PASS_NAME" ]; then
read -p "Имя для хранения пароля: " PASS_NAME
fi
read -s -p "Пароль для SSH и sudo: " ROOT_PASS
echo
fi
# Set username for anonymous
if [ "$ANONYMOUS" = true ]; then
NEW_USER=$(generate_random_username)
fi
# Generate SSH key
KEY_PATH="$HOME/.ssh/keys/$SERVER_NAME"
mkdir -p "$HOME/.ssh/keys"
ssh-keygen -t ed25519 -f "$KEY_PATH" -N "" -C "$SERVER_NAME"
# Read public key
PUBLIC_KEY=$(cat "$KEY_PATH.pub")
# Generate and store password
NEW_PASS=""
if [ "$ANONYMOUS" = false ]; then
mkdir -p "$PASS_DIR"
NEW_PASS="$(pass generate "$PASS_NAME" 16 | tail -n1)"
echo "DEBUG: Generated password: '$NEW_PASS'"
fi
# Update SSH config
CONFIG_FILE="$HOME/.ssh/config"
touch "$CONFIG_FILE"
chmod 600 "$CONFIG_FILE"
# Remove old entry
sed -i "/Host $SERVER_NAME/,/^\s*$/d" "$CONFIG_FILE"
# Add new entry
cat << EOF >> "$CONFIG_FILE"
Host $SERVER_NAME
HostName $HOST
Port $PORT
User $NEW_USER
IdentityFile $KEY_PATH
EOF
# SSH commands
SSH_COMMANDS=$(cat << ENDSSH
set -e
echo '\$PUBLIC_KEY'
# Create user
echo "\$SUDO_PASS" | sudo -S useradd -m -s /bin/bash -G sudo "\$NEW_USER"
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"
echo "\$SUDO_PASS" | sudo -S bash -c "echo \"\$NEW_USER:\$NEW_PASS\" | chpasswd"
fi
# Setup SSH dir
echo "\$SUDO_PASS" | sudo -S mkdir -p "/home/\$NEW_USER/.ssh"
echo "\$SUDO_PASS" | sudo -S chmod 700 "/home/\$NEW_USER/.ssh"
echo "\$SUDO_PASS" | sudo -S touch "/home/\$NEW_USER/.ssh/authorized_keys"
echo "\$SUDO_PASS" | sudo -S chmod 600 "/home/\$NEW_USER/.ssh/authorized_keys"
echo "\$SUDO_PASS" | sudo -S chown -R "\$NEW_USER:\$NEW_USER" "/home/\$NEW_USER/.ssh"
echo "\$SUDO_PASS" | sudo -S bash -c "echo \"\$PUBLIC_KEY\" >> /home/\$NEW_USER/.ssh/authorized_keys"
# Install deps
echo "\$SUDO_PASS" | sudo -S apt-get update
echo "\$SUDO_PASS" | sudo -S apt-get install -y git stow
ENDSSH
)
# Run SSH commands
SSHPASS="$ROOT_PASS" sshpass -e ssh -p "$PORT" "$ROOT_USER@$HOST" "SUDO_PASS='$ROOT_PASS' ANONYMOUS=$ANONYMOUS NEW_USER='$NEW_USER' PUBLIC_KEY='$PUBLIC_KEY' NEW_PASS='$NEW_PASS' bash -c '$SSH_COMMANDS'"
ssh "$SERVER_NAME" bash -c "$(cat << ENDSSH
set -e
git clone https://github.com/goodhumored/dotfiles
cd dotfiles
./init.sh
ENDSSH
)"
echo "Настройка завершена!"
echo "Пользователь: $NEW_USER"
echo "SSH команда: ssh $SERVER_NAME"
if [ "$ANONYMOUS" = false ]; then
echo "Пароль сохранен в: $PASS_NAME"
fi

114
seed_v2.sh Normal file
View File

@ -0,0 +1,114 @@
#!/bin/bash
set -euo pipefail
# --- Константы ---
DEFAULT_PORT=22
DEFAULT_USER="goodhumored"
PASS_DIR="$HOME/.password-store"
KEYS_DIR="$HOME/.ssh/keys"
# --- Утилиты ---
require() {
if ! command -v "$1" &> /dev/null; then
echo "Ошибка: нужна утилита '$1'"
exit 1
fi
}
require sshpass
require ssh-keygen
require pass
# --- Параметры ---
ANONYMOUS=false
PORT="$DEFAULT_PORT"
NEW_USER="$DEFAULT_USER"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--host) HOST="$2"; shift ;;
-p|--port) PORT="$2"; shift ;;
-r|--root_user) ROOT_USER="$2"; shift ;;
-s|--server_name) SERVER_NAME="$2"; shift ;;
-u|--username) NEW_USER="$2"; shift ;;
-n|--pass_name) PASS_NAME="$2"; shift ;;
-a|--anonymous) ANONYMOUS=true ;;
*) echo "Неизвестный параметр: $1"; exit 1 ;;
esac
shift
done
[[ -z "${HOST:-}" || -z "${ROOT_USER:-}" || -z "${SERVER_NAME:-}" ]] && {
echo "Ошибка: нужны --host, --root_user и --server_name"
exit 1
}
# --- Логика ---
if $ANONYMOUS; then
NEW_USER="user$(tr -dc a-z0-9 </dev/urandom | head -c 8)"
fi
if [ -z "${PASS_NAME:-}" ] && ! $ANONYMOUS; then
read -p "Имя для пароля: " PASS_NAME
fi
if ! $ANONYMOUS; then
read -s -p "Пароль root для подключения: " ROOT_PASS
echo
fi
# Генерация ключа
mkdir -p "$KEYS_DIR"
KEY_PATH="$KEYS_DIR/$SERVER_NAME"
ssh-keygen -t ed25519 -N "" -f "$KEY_PATH" -C "$SERVER_NAME"
# Получение нового пароля
if ! $ANONYMOUS; then
mkdir -p "$PASS_DIR"
NEW_PASS=$(pass generate -c "$PASS_NAME" 16 | tail -n1)
echo "$NEW_PASS" | pass insert -m "$PASS_NAME"
else
NEW_PASS=""
fi
# Обновление SSH-конфига
CONFIG_FILE="$HOME/.ssh/config"
touch "$CONFIG_FILE"
chmod 600 "$CONFIG_FILE"
sed -i "/Host $SERVER_NAME/,/^\s*$/d" "$CONFIG_FILE"
cat <<EOF >> "$CONFIG_FILE"
Host $SERVER_NAME
HostName $HOST
Port $PORT
User $NEW_USER
IdentityFile $KEY_PATH
EOF
# --- SSH Настройка сервера ---
SSH_COMMANDS=$(cat <<'EOS'
set -euo pipefail
sudo useradd -m -s /bin/bash -G sudo "$NEW_USER"
echo "$NEW_USER:$NEW_PASS" | sudo chpasswd
sudo mkdir -p "/home/$NEW_USER/.ssh"
sudo chmod 700 "/home/$NEW_USER/.ssh"
echo "$PUBLIC_KEY" | sudo tee "/home/$NEW_USER/.ssh/authorized_keys" > /dev/null
sudo chmod 600 "/home/$NEW_USER/.ssh/authorized_keys"
sudo chown -R "$NEW_USER:$NEW_USER" "/home/$NEW_USER/.ssh"
sudo apt-get update
sudo apt-get install -y git stow
if [ "$ANONYMOUS" = "false" ]; then
sudo -u "$NEW_USER" git clone https://github.com/goodhumored/dotfiles /home/"$NEW_USER"/dotfiles
sudo -u "$NEW_USER" bash -c "cd /home/$NEW_USER/dotfiles && ./init.sh"
fi
EOS
)
SSHPASS="$ROOT_PASS" sshpass -e ssh -p "$PORT" "$ROOT_USER@$HOST" \
env NEW_USER="$NEW_USER" NEW_PASS="$NEW_PASS" PUBLIC_KEY="$(cat "$KEY_PATH.pub")" ANONYMOUS="$ANONYMOUS" bash -c "$SSH_COMMANDS"
echo "Готово! Новый пользователь: $NEW_USER (SSH: ssh $SERVER_NAME)"