commit 4f0e213f4ad81af4026337d9f443e79613f52a07 Author: aleidk Date: Mon Feb 13 01:53:52 2023 -0300 refactor config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4636a04 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Config +**/packer_compiled.lua +config/spicetify/Extracted +config/vifm/Trash +config/vifm/vifminfo.json +config/lazygit/state.yml diff --git a/config/Gnome Extensions b/config/Gnome Extensions new file mode 100644 index 0000000..26b4723 --- /dev/null +++ b/config/Gnome Extensions @@ -0,0 +1 @@ +{"extensions":{"vertical-workspaces@G-dH.github.com":{"/org/gnome/shell/extensions/vertical-workspaces/":"[/]\ncenter-app-grid=true\ncenter-dash-to-ws=false\ncenter-search=true\ndash-position=0\nfix-ubuntu-dock=true\noverview-bg-blur-sigma=20\noverview-mode=0\nshow-bg-in-overview=false\nshow-search-entry=true\nshow-ws-preview-bg=true\nshow-ws-switcher-bg=false\nshow-wst-labels=0\nstartup-state=1\nworkspace-animation=0\nws-thumbnails-position=2"},"easy_docker_containers@red.software.systems":{"/red/software/systems/easy_docker_containers/":""},"user-theme@gnome-shell-extensions.gcampax.github.com":{"/org/gnome/shell/extensions/user-theme/":"[/]\nname='Catppuccin-Macchiato-Standard-Teal-Dark'"},"gnome-shell-go-to-last-workspace@github.com":{"/org/gnome/shell/extensions/go-to-last-workspace/":"[/]\nshortcut-key=['bar']"},"widgets@aylur":{"/org/gnome/shell/extensions/aylurs-widgets/":"[/]\nbackground-clock=false\nbattery-bar=false\ndash-app-icon-size=46\ndash-apps-cols=5\ndash-apps-rows=5\ndash-board=true\ndash-button-enable=true\ndash-button-label=''\ndash-button-show-icon=false\ndash-hide-activities=true\ndash-layout=0\ndash-levels-show-battery=false\ndash-levels-show-storage=false\ndash-link-names=['reddit', 'youtube', 'gmail', 'twitter', 'github']\ndash-link-urls=['https://www.reddit.com/', 'https://www.youtube.com/', 'https://www.gmail.com/', 'https://twitter.com/', 'https://www.github.com/']\ndash-shortcut=['Escape']\ndate-menu-date-format='%I:%M - %d de %b'\ndate-menu-hide-notifications=true\ndate-menu-hide-stock-mpris=true\ndate-menu-indicator-position=2\ndate-menu-mirror=false\ndate-menu-offset=0\ndate-menu-position=1\ndate-menu-remove-padding=true\ndate-menu-show-clocks=false\ndate-menu-show-media=false\ndate-menu-show-system-levels=false\ndate-menu-show-user=false\ndate-menu-show-weather=false\ndate-menu-tweaks=true\nmedia-player-cover-height=70\nmedia-player-cover-width=70\nmedia-player-enable-controls=false\nmedia-player-enable-track=true\nmedia-player-offset=1\nmedia-player-position=1\nmedia-player-show-volume=false\nmedia-player-style=2\nnotification-indicator=false\npower-menu=false\nquick-settings-adjust-roundness=true\nquick-settings-show-media=false\nquick-settings-show-notifications=true\nquick-settings-show-system-levels=false\nquick-settings-style=2\nworkspace-indicator-offset=2\nworkspace-indicator-show-names=false"},"floating-panel@aylur":{}},"keybindings":{"/org/gnome/mutter/keybindings/":"","/org/gnome/mutter/wayland/keybindings/":"","/org/gnome/shell/keybindings/":"","/org/gnome/desktop/wm/keybindings/":"[/]\nalways-on-top=['t']\nclose=['F4', 'q']\nminimize=['z']\nmove-to-workspace-1=['1']\nmove-to-workspace-10=['0']\nmove-to-workspace-11=@as []\nmove-to-workspace-2=['2']\nmove-to-workspace-3=['3']\nmove-to-workspace-4=['4']\nmove-to-workspace-5=['5']\nmove-to-workspace-6=['6']\nmove-to-workspace-7=['7']\nmove-to-workspace-8=['8']\nmove-to-workspace-9=['9']\nswitch-applications=@as []\nswitch-applications-backward=@as []\nswitch-group=@as []\nswitch-group-backward=@as []\nswitch-to-workspace-1=['1']\nswitch-to-workspace-10=['0']\nswitch-to-workspace-2=['2']\nswitch-to-workspace-3=['3']\nswitch-to-workspace-4=['4']\nswitch-to-workspace-5=['5']\nswitch-to-workspace-6=['6']\nswitch-to-workspace-7=['7']\nswitch-to-workspace-8=['8']\nswitch-to-workspace-9=['9']\nswitch-to-workspace-down=['Down', 'KP_Down', 'u']\nswitch-to-workspace-up=['Up', 'KP_Up', 'i']\nswitch-windows=['Tab']\nswitch-windows-backward=['Tab']\ntoggle-on-all-workspaces=['p']","/org/gnome/settings-daemon/plugins/media-keys/":"[/]\ncustom-keybindings=['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']\nemail=@as []\nhelp=@as []\nhome=@as []\nwww=@as []\n\n[custom-keybindings/custom0]\nbinding='Return'\ncommand='gnome-terminal'\nname='Launch Terminal'"},"tweaks":{"/org/gnome/desktop/background/":"","/org/gnome/desktop/calendar/":"","/org/gnome/desktop/input-sources/":"[/]\nshow-all-sources=false\nsources=[('xkb', 'latam')]\nxkb-options=@as []","/org/gnome/desktop/interface/":"[/]\ncolor-scheme='prefer-dark'\ncursor-size=32\ncursor-theme='Catppuccin-Macchiato-Teal-Cursors'\nenable-animations=true\nfont-antialiasing='grayscale'\nfont-hinting='slight'\ngtk-theme='Catppuccin-Macchiato-Standard-Teal-Dark'\nicon-theme='Papirus-Dark'\ntoolkit-accessibility=false","/org/gnome/desktop/peripherals/":"[keyboard]\nnumlock-state=true\nremember-numlock-state=true\n\n[mouse]\nspeed=0.68141592920353977\n\n[touchpad]\ntwo-finger-scrolling-enabled=true","/org/gnome/desktop/screensaver/":"[/]\npicture-uri='file:///usr/share/backgrounds/gnome/drool-l.svg'","/org/gnome/desktop/sound/":"[/]\nallow-volume-above-100-percent=true\nevent-sounds=true\ntheme-name='__custom'","/org/gnome/desktop/wm/preferences/":"[/]\nnum-workspaces=10\nresize-with-right-button=true\nworkspace-names=@as []","/org/gnome/mutter/":"[/]\ndynamic-workspaces=false\nedge-tiling=true\nexperimental-features=['scale-monitor-framebuffer', 'x11-randr-fractional-scaling']\noverlay-key='Super_L'","/org/gnome/settings-daemon/plugins/xsettings/":""}} \ No newline at end of file diff --git a/config/astronvim/lua/user/init.lua b/config/astronvim/lua/user/init.lua new file mode 100644 index 0000000..c2c6518 --- /dev/null +++ b/config/astronvim/lua/user/init.lua @@ -0,0 +1,3 @@ +return { + colorscheme = "catppuccin", +} diff --git a/config/astronvim/lua/user/lsp/skip_setup.lua b/config/astronvim/lua/user/lsp/skip_setup.lua new file mode 100644 index 0000000..9a644da --- /dev/null +++ b/config/astronvim/lua/user/lsp/skip_setup.lua @@ -0,0 +1,3 @@ +return { + "rust_analyzer", +} diff --git a/config/astronvim/lua/user/mappings.lua b/config/astronvim/lua/user/mappings.lua new file mode 100644 index 0000000..b75157b --- /dev/null +++ b/config/astronvim/lua/user/mappings.lua @@ -0,0 +1,123 @@ +return { + n = { + [""] = { "ToggleTerm", desc = "Toggle terminal" }, + ["fn"] = false, + ["fo"] = false, + ["fh"] = false, + ["fb"] = false, + [""] = false, + [""] = false, + [""] = false, + + [""] = { + function() + require("dap").terminate() + end, + desc = "Debugger: Stop", + }, -- S-F1 + [""] = { + function() + require("dap").restart_frame() + end, + desc = "Debugger: Restart", + }, + [""] = { + function() + require("dap").step_out() + end, + desc = "Debugger: Step Out", + }, + [""] = { + function() + require("dap").step_into() + end, + desc = "Debugger: Step Into", + }, + [""] = { + function() + require("dap").step_over() + end, + desc = "Debugger: Step Over", + }, + [""] = { + function() + require("dap").continue() + end, + desc = "Debugger: Start", + }, + [""] = { + function() + require("dap").toggle_breakpoint() + end, + desc = "Debugger: Toggle Breakpoint", + }, + + ["fp"] = { + function() + require("telescope").extensions.projects.projects() + end, + desc = "Search project", + }, + ["lj"] = { + function() + vim.diagnostic.goto_next() + end, + desc = "Go to next diagnostic", + }, + ["lk"] = { + function() + vim.diagnostic.goto_prev() + end, + desc = "Go to prev diagnostic", + }, + + ["Ch"] = { + function() + require("nvim-comment-frame").add_comment() + end, + desc = "Add a comment frame", + }, + + ["CH"] = { + function() + require("nvim-comment-frame").add_multiline_comment() + end, + desc = "Add a multiline comment frame", + }, + + ["Cd"] = { + function() + require("neogen").generate() + end, + desc = "Generate comment docstring", + }, + + ["ft"] = { + "TodoTrouble", + desc = "Search TODOS", + }, + + ["r"] = { + ":s/", + desc = "Search and replace", + }, + ["R"] = { + ":%s/", + desc = "Search and replace in whole file", + }, + }, + v = { + ["r"] = { + ":s/", + desc = "Search and replace", + }, + + ["p"] = { + "pgvy", + desc = "Paste and re yank text", + }, + }, + t = { + [""] = { "ToggleTerm", desc = "Toggle terminal" }, + }, +} diff --git a/config/astronvim/lua/user/mason-nvim-dap/setup_handlers.lua b/config/astronvim/lua/user/mason-nvim-dap/setup_handlers.lua new file mode 100644 index 0000000..6e806f3 --- /dev/null +++ b/config/astronvim/lua/user/mason-nvim-dap/setup_handlers.lua @@ -0,0 +1,22 @@ +return { + firefox = function(source_name) + local dap = require("dap") + dap.adapters.firefox = { + type = "executable", + command = "node", + args = { os.getenv("HOME") .. "/.local/share/nvim/mason/bin/firefox-debug-adapter" }, + } + + dap.configurations.javascriptreact = { + { + name = "Debug with Firefox", + type = "firefox", + request = "launch", + reAttach = true, + url = "http://localhost:3000", + webRoot = "${workspaceFolder}", + firefoxExecutable = "/usr/bin/firefox-developer-edition", + }, + } + end, +} diff --git a/config/astronvim/lua/user/options.lua b/config/astronvim/lua/user/options.lua new file mode 100644 index 0000000..881dfa3 --- /dev/null +++ b/config/astronvim/lua/user/options.lua @@ -0,0 +1,11 @@ +return { + g = { + catppuccin_flavour = "macchiato", + }, + + opt = { + number = true, + relativenumber = true, + -- spelllang = "en_us,es_cl", + }, +} diff --git a/config/astronvim/lua/user/plugins/alpha.lua b/config/astronvim/lua/user/plugins/alpha.lua new file mode 100644 index 0000000..a69cc51 --- /dev/null +++ b/config/astronvim/lua/user/plugins/alpha.lua @@ -0,0 +1,31 @@ +local alpha_button = astronvim.alpha_button +return { + layout = { + { type = "padding", val = vim.fn.max({ 2, vim.fn.floor(vim.fn.winheight(0) * 0.2) }) }, + { + type = "text", + val = astronvim.user_plugin_opts("header", { + " ████ ███ █████ █████ ", + " ░░███ ░░░ ░░███ ░░███ ", + " ██████ ░███ ██████ ████ ███████ ░███ █████", + " ░░░░░███ ░███ ███░░███░░███ ███░░███ ░███░░███ ", + " ███████ ░███ ░███████ ░███ ░███ ░███ ░██████░ ", + " ███░░███ ░███ ░███░░░ ░███ ░███ ░███ ░███░░███ ", + "░░████████ █████░░██████ █████░░████████ ████ █████", + " ░░░░░░░░ ░░░░░ ░░░░░░ ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ ", + }, false), + opts = { position = "center", hl = "DashboardHeader" }, + }, + { type = "padding", val = 5 }, + { + type = "group", + val = { + alpha_button("LDR f p", " Recent Project "), + alpha_button("LDR f f", " Find File "), + alpha_button("LDR o", "פּ File Explorer "), + alpha_button("LDR m a", " Bookmarks "), + }, + opts = { spacing = 1 }, + }, + }, +} diff --git a/config/astronvim/lua/user/plugins/catppuccin.lua b/config/astronvim/lua/user/plugins/catppuccin.lua new file mode 100644 index 0000000..e1b7edf --- /dev/null +++ b/config/astronvim/lua/user/plugins/catppuccin.lua @@ -0,0 +1,72 @@ +local catppuccin = require("catppuccin") + +-- configure it +catppuccin.setup({ + transparent_background = true, + term_colors = false, + styles = { + comments = { "italic" }, + conditionals = { "italic" }, + loops = { "italic" }, + functions = { "italic" }, + keywords = { "italic" }, + strings = { "italic" }, + variables = { "italic" }, + numbers = {}, + booleans = {}, + properties = {}, + types = {}, + operators = {}, + }, + integrations = { + treesitter = true, + native_lsp = { + enabled = true, + virtual_text = { + errors = { "italic" }, + hints = { "italic" }, + warnings = { "italic" }, + information = { "italic" }, + }, + underlines = { + errors = { "underline" }, + hints = { "underline" }, + warnings = { "underline" }, + information = { "underline" }, + }, + }, + lsp_trouble = true, + cmp = true, + lsp_saga = true, + gitgutter = false, + gitsigns = true, + telescope = true, + nvimtree = { + enabled = true, + show_root = true, + transparent_panel = true, + }, + indent_blankline = { enabled = true, colored_indent_levels = true }, + neotree = { + enabled = false, + show_root = true, + transparent_panel = false, + }, + dap = { enabled = false, enable_ui = false }, + which_key = true, + dashboard = true, + neogit = false, + vim_sneak = false, + fern = false, + barbar = true, + bufferline = true, + markdown = true, + lightspeed = false, + ts_rainbow = true, + hop = false, + notify = true, + telekasten = true, + symbols_outline = true, + mini = false, + }, +}) diff --git a/config/astronvim/lua/user/plugins/harpoon.lua b/config/astronvim/lua/user/plugins/harpoon.lua new file mode 100644 index 0000000..f95833e --- /dev/null +++ b/config/astronvim/lua/user/plugins/harpoon.lua @@ -0,0 +1,74 @@ +require("harpoon").setup({ + global_settings = { + -- sets the marks upon calling `toggle` on the ui, instead of require `:w`. + save_on_toggle = true, + + -- saves the harpoon file upon every change. disabling is unrecommended. + save_on_change = true, + + -- sets harpoon to run the command immediately as it's passed to the terminal when calling `sendCommand`. + enter_on_sendcmd = true, + + -- closes any tmux windows harpoon that harpoon creates when you close Neovim. + tmux_autoclose_windows = false, + + -- filetypes that you want to prevent from adding to the harpoon list menu. + excluded_filetypes = { "harpoon" }, + + -- set marks specific to each git branch inside git repository + mark_branch = false, + }, + projects = { + -- Yes $HOME works + ["$HOME/personal/vim-with-me/server"] = { + term = { + cmds = { + "./env && npx ts-node src/index.ts", + }, + }, + }, + }, +}) +local mark = require("harpoon.mark") +local ui = require("harpoon.ui") +local tmux = require("harpoon.tmux") +local telescope = require("telescope") + +local command_prompt = "Enter command: " + +telescope.load_extension("harpoon") + +local function map(key, func, desc) + vim.keymap.set("n", "" .. key, func, { desc = desc }) +end + +map("n", mark.add_file, "Add mark") + +map("t", ui.toggle_quick_menu, "Toogle UI") + +map("j", function() + ui.nav_file(1) +end, "Navigate to file 1") + +map("k", function() + ui.nav_file(2) +end, "Navigate to file 2") + +map("l", function() + ui.nav_file(3) +end, "Navigate to file 3") + +map("ñ", function() + ui.nav_file(4) +end, "Navigate to file 4") + +map("g", function() + local input = vim.fn.input(command_prompt) + tmux.sendCommand("{next}", input) +end, "Send command to tmux pane 1") + +map("G", function() + tmux.sendCommand("{next}", "\3") +end, "Send command to tmux pane 1") + +map("T", "Telescope harpoon marks", "Open marks in telescope") diff --git a/config/astronvim/lua/user/plugins/init.lua b/config/astronvim/lua/user/plugins/init.lua new file mode 100644 index 0000000..315b85d --- /dev/null +++ b/config/astronvim/lua/user/plugins/init.lua @@ -0,0 +1,86 @@ +return { + ["/nvim-neo-tree/neo-tree.nvim"] = { disable = true }, + ["rcarriga/nvim-notify"] = { disable = true }, + + ["catppuccin/nvim"] = { + as = "catppuccin", + config = function() + require("user.plugins.catppuccin") + end, + }, + ["nvim-treesitter/nvim-treesitter-context"] = { + config = function() + require("treesitter-context").setup() + end, + }, + + ["ahmedkhalf/project.nvim"] = { + config = function() + require("user.plugins.project") + end, + }, + + ["kyazdani42/nvim-tree.lua"] = { + config = function() + require("user.plugins.nvim-tree") + end, + }, + + ["kylechui/nvim-surround"] = { + tag = "*", -- Use for stability; omit to use `main` branch for the latest features + config = function() + require("nvim-surround").setup() + end, + }, + + ["s1n7ax/nvim-comment-frame"] = { + requires = { + { "nvim-treesitter" }, + }, + config = function() + require("nvim-comment-frame").setup({ + disable_default_keymap = true, + }) + end, + }, + ["danymat/neogen"] = { + config = function() + require("neogen").setup({ snippet_engine = "luasnip" }) + end, + requires = "nvim-treesitter/nvim-treesitter", + tag = "*", -- stable releases + }, + + ["folke/todo-comments.nvim"] = { + requires = "nvim-lua/plenary.nvim", + config = function() + require("todo-comments").setup({}) + end, + }, + + ["folke/trouble.nvim"] = { + requires = "kyazdani42/nvim-web-devicons", + config = function() + require("user.plugins.trouble") + end, + }, + ["anuvyklack/pretty-fold.nvim"] = { + config = function() + require("user.plugins.pretty-fold") + end, + }, + ["simrat39/rust-tools.nvim"] = { + after = "mason-lspconfig.nvim", -- make sure to load after mason-lspconfig + config = function() + require("rust-tools").setup({ + server = astronvim.lsp.server_settings("rust_analyzer"), -- get the server settings and built in capabilities/on_attach + }) + end, + }, + + ["ThePrimeagen/harpoon"] = { + config = function() + require("user.plugins.harpoon") + end, + }, +} diff --git a/config/astronvim/lua/user/plugins/mason-lspconfig.lua b/config/astronvim/lua/user/plugins/mason-lspconfig.lua new file mode 100644 index 0000000..78ee80d --- /dev/null +++ b/config/astronvim/lua/user/plugins/mason-lspconfig.lua @@ -0,0 +1,15 @@ +return { + ensure_installed = { + "bashls", + "cssls", + "dockerls", + "emmet_ls", + "html", + "pyright", + "rust_analyzer", + "sqlls", + "sumneko_lua", + "tsserver", + "yamlls", + }, +} diff --git a/config/astronvim/lua/user/plugins/mason-null-ls.lua b/config/astronvim/lua/user/plugins/mason-null-ls.lua new file mode 100644 index 0000000..f8a9d48 --- /dev/null +++ b/config/astronvim/lua/user/plugins/mason-null-ls.lua @@ -0,0 +1,19 @@ +return { + ensure_installed = { + "blade_formatter", + "blue", + "eslint_d", + "fixjson", + "gitlint", + "intelephense", + "luacheck", + "markdownlint", + "php-cs-fixer", + "prettierd", + "shellcheck", + "shfmt", + "sql-formatter", + "stylua", + "yamlint", + }, +} diff --git a/config/astronvim/lua/user/plugins/null-ls.lua b/config/astronvim/lua/user/plugins/null-ls.lua new file mode 100644 index 0000000..5ae67e0 --- /dev/null +++ b/config/astronvim/lua/user/plugins/null-ls.lua @@ -0,0 +1,9 @@ +return function(config) + local null_ls = require("null-ls") + config.sources = { + null_ls.builtins.formatting.prettierd.with({ + disabled_filetypes = { "markdown" }, + }), + } + return config +end diff --git a/config/astronvim/lua/user/plugins/nvim-tree.lua b/config/astronvim/lua/user/plugins/nvim-tree.lua new file mode 100644 index 0000000..9e593cf --- /dev/null +++ b/config/astronvim/lua/user/plugins/nvim-tree.lua @@ -0,0 +1,46 @@ +local tree = require("nvim-tree") +local tree_cb = require("nvim-tree.config").nvim_tree_callback + +tree.setup({ + hijack_unnamed_buffer_when_opening = true, + disable_netrw = true, + hijack_netrw = true, + hijack_cursor = true, -- cursor at the start of filename + sync_root_with_cwd = true, + respect_buf_cwd = true, + update_focused_file = { + enable = true, -- focus curren file + update_root = true, + }, + actions = { open_file = { quit_on_open = true } }, + renderer = { + full_name = true, -- show remaining name in floating text + group_empty = true, -- group empty folders + add_trailing = true, -- Trailing slash to folders + highlight_opened_files = "all", + highlight_git = true, + }, + view = { + centralize_selection = true, -- center current file on enter + width = 30, -- N° of columns or % + mappings = { + custom_only = false, + -- list of mappings to set on the tree manually + list = { + { key = { "l", "", "o", "<2-LeftMouse>" }, action = "edit" }, + -- {key = {"L", "<2-RightMouse>", ""}, action = "cd"}, + { key = "s", action = "vsplit" }, + { key = "v", action = "split" }, + { key = "t", action = "tabnew" }, + { key = { "h", "" }, action = "close_node" }, + { key = "i", action = "toggle_dotfiles" }, + { key = "I", action = "toggle_ignored" }, + { key = { "", "" }, cb = tree_cb("system_open") }, + }, + }, + }, +}) + +-- bindings +vim.keymap.set("n", "e", ":NvimTreeToggle", { desc = "Toggle file tree", silent = true }) +vim.keymap.set("n", "", ":NvimTreeToggle", { desc = "Toggle file tree", silent = true }) diff --git a/config/astronvim/lua/user/plugins/pretty-fold.lua b/config/astronvim/lua/user/plugins/pretty-fold.lua new file mode 100644 index 0000000..b5d2178 --- /dev/null +++ b/config/astronvim/lua/user/plugins/pretty-fold.lua @@ -0,0 +1,39 @@ +require("pretty-fold").setup({ + sections = { + left = { + "+", + function() + return string.rep("-", vim.v.foldlevel) + end, + " ", + "content", + " ", + "number_of_folded_lines", + " ", + function() + return string.rep("-", vim.v.foldlevel) + end, + "+", + }, + }, + fill_char = " ", + + -- Possible values: + -- "delete" : Delete all comment signs from the fold string. + -- "spaces" : Replace all comment signs with equal number of spaces. + -- false : Do nothing with comment signs. + process_comment_signs = "delete", + + -- List of patterns that will be removed from content foldtext section. + stop_words = { + "@brief%s*", -- (for C++) Remove '@brief' and all spaces after. + }, + + matchup_patterns = { + { "{", "}" }, + { "%(", ")" }, -- % to escape lua pattern char + { "%[", "]" }, -- % to escape lua pattern char + }, + + ft_ignore = { "neorg" }, +}) diff --git a/config/astronvim/lua/user/plugins/project.lua b/config/astronvim/lua/user/plugins/project.lua new file mode 100644 index 0000000..ecec2ff --- /dev/null +++ b/config/astronvim/lua/user/plugins/project.lua @@ -0,0 +1,44 @@ +require("project_nvim").setup({ + -- Manual mode doesn't automatically change your root directory, so you have + -- the option to manually do so using `:ProjectRoot` command. + manual_mode = false, + + -- Methods of detecting the root directory. **"lsp"** uses the native neovim + -- lsp, while **"pattern"** uses vim-rooter like glob pattern matching. Here + -- order matters: if one is not detected, the other is used as fallback. You + -- can also delete or rearangne the detection methods. + detection_methods = { "lsp", "pattern" }, + + -- All the patterns used to detect root dir, when **"pattern"** is in + -- detection_methods + patterns = { + ".git", + "_darcs", + ".hg", + ".bzr", + ".svn", + "Makefile", + "package.json", + }, + + -- Table of lsp clients to ignore by name + -- eg: { "efm", ... } + ignore_lsp = {}, + + -- Don't calculate root dir on specific directories + -- Ex: { "~/.cargo/*", ... } + exclude_dirs = {}, + + -- Show hidden files in telescope + show_hidden = false, + + -- When set to false, you will get a message when project.nvim changes your + -- directory. + silent_chdir = false, + + -- Path where project.nvim will store the project history for use in + -- telescope + datapath = vim.fn.stdpath("data"), +}) + +require("telescope").load_extension("projects") diff --git a/config/astronvim/lua/user/plugins/telescope.lua b/config/astronvim/lua/user/plugins/telescope.lua new file mode 100644 index 0000000..3abdb46 --- /dev/null +++ b/config/astronvim/lua/user/plugins/telescope.lua @@ -0,0 +1,15 @@ +local telescope_actions = require("telescope.actions") + +return { + defaults = { + mappings = { + i = { + [""] = telescope_actions.move_selection_next, + [""] = telescope_actions.move_selection_previous, + [""] = telescope_actions.file_vsplit, + [""] = telescope_actions.file_split, + [""] = telescope_actions.close, + }, + }, + }, +} diff --git a/config/astronvim/lua/user/plugins/treesitter.lua b/config/astronvim/lua/user/plugins/treesitter.lua new file mode 100644 index 0000000..fdd30fc --- /dev/null +++ b/config/astronvim/lua/user/plugins/treesitter.lua @@ -0,0 +1,3 @@ +return { + ensure_installed = { "javascript", "typescript", "php", "python", "lua", "bash", "sql", "yaml", "json" }, +} diff --git a/config/astronvim/lua/user/plugins/trouble.lua b/config/astronvim/lua/user/plugins/trouble.lua new file mode 100644 index 0000000..1a6a895 --- /dev/null +++ b/config/astronvim/lua/user/plugins/trouble.lua @@ -0,0 +1,26 @@ +require("trouble").setup({ + mode = "document_diagnostics", + action_keys = { -- key mappings for actions in the trouble list + -- map to {} to remove a mapping, for example: + -- close = {}, + close = "q", -- close the list + cancel = "", -- cancel the preview and get back to your last window / buffer / cursor + refresh = "r", -- manually refresh + jump = { "", "" }, -- jump to the diagnostic or open / close folds + open_split = { "s" }, -- open buffer in new split + open_vsplit = { "v" }, -- open buffer in new vsplit + open_tab = { "t" }, -- open buffer in new tab + jump_close = { "o" }, -- jump to the diagnostic and close the list + toggle_mode = "m", -- toggle between "workspace" and "document" diagnostics mode + toggle_preview = "P", -- toggle auto_preview + hover = "K", -- opens a small popup with the full multiline message + preview = "p", -- preview the diagnostic location + close_folds = { "zM", "zm" }, -- close all folds + open_folds = { "zR", "zr" }, -- open all folds + toggle_fold = { "zA", "za" }, -- toggle fold of current file + previous = "k", -- previous item + next = "j", -- next item + }, +}) + +vim.keymap.set("n", "fd", "TroubleToggle", { silent = true, desc = "Search diagnostics" }) diff --git a/config/astronvim/lua/user/plugins/window-picker.lua b/config/astronvim/lua/user/plugins/window-picker.lua new file mode 100644 index 0000000..333e31d --- /dev/null +++ b/config/astronvim/lua/user/plugins/window-picker.lua @@ -0,0 +1,3 @@ +return { + use_winbar = "always", +} diff --git a/config/astronvim/lua/user/polish.lua b/config/astronvim/lua/user/polish.lua new file mode 100644 index 0000000..2b2b4d2 --- /dev/null +++ b/config/astronvim/lua/user/polish.lua @@ -0,0 +1,35 @@ +return function() + local function alpha_on_bye(cmd) + local bufs = vim.fn.getbufinfo({ buflisted = true }) + vim.cmd(cmd) + if require("core.utils").is_available("alpha-nvim") and not bufs[2] then + require("alpha").start(true) + end + end + + vim.keymap.del("n", "C") + + if require("core.utils").is_available("bufdelete.nvim") then + vim.keymap.set("n", "C", function() + alpha_on_bye("Bdelete!") + end, { desc = "Close buffer" }) + else + vim.keymap.set("n", "C", function() + alpha_on_bye("bdelete!") + end, { desc = "Close buffer" }) + end + + vim.api.nvim_create_autocmd({ + "BufEnter", + "BufAdd", + "BufNew", + "BufNewFile", + "BufWinEnter", + }, { + group = vim.api.nvim_create_augroup("TS_FOLD_WORKAROUND", {}), + callback = function() + vim.opt.foldmethod = "expr" + vim.opt.foldexpr = "nvim_treesitter#foldexpr()" + end, + }) +end diff --git a/config/astronvim/lua/user/which-key/register.lua b/config/astronvim/lua/user/which-key/register.lua new file mode 100644 index 0000000..96d460d --- /dev/null +++ b/config/astronvim/lua/user/which-key/register.lua @@ -0,0 +1,8 @@ +return { + n = { + [""] = { + ["C"] = { name = "Comment Stuff" }, + [""] = { name = "Harpoon" }, + }, + }, +} diff --git a/config/create-links b/config/create-links new file mode 100755 index 0000000..2774616 --- /dev/null +++ b/config/create-links @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +[[ ! -e "$HOME/.config" ]] && mkdir -p "$HOME/.config/" + +echo "Creating symlinks..." +for var in $SCRIPT_DIR/*; do + pkg=$(basename "$var") + + # if exist and is not a symlink + if [[ -e "$HOME/.config/$pkg" && ! -h "$HOME/.config/$pkg" ]]; then + echo "Config for $pkg exist, creating backup ${pkg}.old" + mv "$HOME/.config/$pkg" "$HOME/.config/${pkg}.old" + + elif [[ -e "$HOME/.config/$pkg" && -h "$HOME/.config/$pkg" ]]; then + unlink "$HOME/.config/$pkg" + fi + + ln -sf "$var" "$HOME/.config/" +done diff --git a/config/helix/config.toml b/config/helix/config.toml new file mode 100644 index 0000000..311c8ac --- /dev/null +++ b/config/helix/config.toml @@ -0,0 +1,14 @@ +theme = "catppuccin_mocha" + +[editor] +scrolloff = 15 +line-number = "relative" +color-modes = true + +[editor.cursor-shape] +normal = "block" +insert = "bar" +select = "underline" + +[editor.indent-guides] +render = true \ No newline at end of file diff --git a/config/lazygit/config.yml b/config/lazygit/config.yml new file mode 100644 index 0000000..e63fce2 --- /dev/null +++ b/config/lazygit/config.yml @@ -0,0 +1,19 @@ +theme: + lightTheme: false + activeBorderColor: + - "#a6da95" # Green + - bold + inactiveBorderColor: + - "#cad3f5" # Text + optionsTextColor: + - "#8aadf4" # Blue + selectedLineBgColor: + - "#363a4f" # Surface0 + selectedRangeBgColor: + - "#363a4f" # Surface0 + cherryPickedCommitBgColor: + - "#8bd5ca" # Teal + cherryPickedCommitFgColor: + - "#8aadf4" # Blue + unstagedChangesColor: + - red # Red diff --git a/config/nvim.old/acsii_art.txt b/config/nvim.old/acsii_art.txt new file mode 100644 index 0000000..8e199d6 --- /dev/null +++ b/config/nvim.old/acsii_art.txt @@ -0,0 +1,11 @@ + ████ ███ █████ █████ + ░░███ ░░░ ░░███ ░░███ + ██████ ░███ ██████ ████ ███████ ░███ █████ + ░░░░░███ ░███ ███░░███░░███ ███░░███ ░███░░███ + ███████ ░███ ░███████ ░███ ░███ ░███ ░██████░ + ███░░███ ░███ ░███░░░ ░███ ░███ ░███ ░███░░███ +░░████████ █████░░██████ █████░░████████ ████ █████ + ░░░░░░░░ ░░░░░ ░░░░░░ ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ + + + diff --git a/config/nvim.old/init.lua.old b/config/nvim.old/init.lua.old new file mode 100644 index 0000000..3622233 --- /dev/null +++ b/config/nvim.old/init.lua.old @@ -0,0 +1,14 @@ +-- Siable netrw +vim.g.loaded = 1 +vim.g.loaded_netrwPlugin = 1 + +-- native neovim config +require("options") + +-- keybindings config +require("keys") + +-- Autocmd config +require("autocommands") + +require("plugins") diff --git a/config/nvim.old/lua/autocommands.lua b/config/nvim.old/lua/autocommands.lua new file mode 100644 index 0000000..114162c --- /dev/null +++ b/config/nvim.old/lua/autocommands.lua @@ -0,0 +1,17 @@ +local cmd = vim.api.nvim_create_autocmd + +-- cmd({"BufNewFile", "BufFilePre", "BufRead"}, { +-- pattern = {"*.md"}, +-- callback = function() vim.opt.filetype = "markdown" end +-- }) + +cmd("InsertEnter", + {pattern = "*", command = "norm zz", desc = "Center line on insert mode"}) + +-- highlight yank selection +cmd("TextYankPost", { + pattern = "*", + callback = function() vim.highlight.on_yank() end, + desc = "Highligth line on yank" +}) + diff --git a/config/nvim.old/lua/keys.lua b/config/nvim.old/lua/keys.lua new file mode 100644 index 0000000..016a65f --- /dev/null +++ b/config/nvim.old/lua/keys.lua @@ -0,0 +1,51 @@ +--[[ + +Modes: + +| String value | Help page | Affected modes | Vimscript equivalent | +| -------------|------------------|-----------------------------------------------|-----------------------| +| '' | mapmode-nvo | Normal, Visual, Select, Operator-pending | :map | +| 'n' | mapmode-n | Normal | :nmap | +| 'v' | mapmode-v | Visual and Select | :vmap | +| 's' | mapmode-s | Select | :smap | +| 'x' | mapmode-x | Visual | :xmap | +| 'o' | mapmode-o | Operator-pending | :omap | +| '!' | mapmode-ic | Insert and Command-line | :map! | +| 'i' | mapmode-i | Insert | :imap | +| 'l' | mapmode-l | Insert, Command-line, Lang-Arg | :lmap | +| 'c' | mapmode-c | Command-line | :cmap | +| 't' | mapmode-t | Terminal | :tmap | + +Define Mapping with: +vim.keymap.set(mode, keys, action[, options]) + +--]] + +-- Leader Key +vim.g.mapleader = ' ' + +vim.keymap.set('n', "", ":noh", { desc = "Remove search Highlight", silent = true }) + +-- local function changeComment() +-- local table = vim.opt.fo:get() +-- local enabled = tagle.c == true && tagle.r == true && tagle.o == true +-- end + +vim.keymap.set('', "tc", [[if &fo =~ 'cro' | set fo-=cro | else | set fo+=cro | endif]], { desc = "Toggle autocomments", silent = true }) + +vim.keymap.set('', "ti", ":setlocal autoindent!", { desc = "toggle auto indent"}) + +vim.keymap.set('', "ts", ":setlocal spell!", { desc = "Toggle spell checker", silent = true }) + +vim.keymap.set('t', '', [[]], { desc = "Exit terminal with Esc", silent = true }) + +vim.keymap.set('n', '', ':w', { desc = "Save file", silent = true }) + +vim.keymap.set({ 'n', 'v', 'i' }, '', ':m .+1==', { desc = "Move current line down", silent = true }) + +vim.keymap.set({ 'n', 'v', 'i' }, '', ':m .-2==', { desc = "Move current line up", silent = true }) + + +vim.keymap.set('v', '<', '', '>gv', { desc = "Better indentation in visual mode", silent = true }) diff --git a/config/nvim.old/lua/options.lua b/config/nvim.old/lua/options.lua new file mode 100644 index 0000000..efcb1a7 --- /dev/null +++ b/config/nvim.old/lua/options.lua @@ -0,0 +1,63 @@ +-------------------------------------------------------------------------------- +-- Native Neovim Config -- +-------------------------------------------------------------------------------- + +--[[ + + vim.opt.{option} -> :set + vim.opt_global.{option} -> :setglobal + vim.opt_local.{option} -> :setlocal + +--]] + + +-- Set Shell +vim.opt.shell = "/usr/bin/env bash" + +vim.g.python3_host_prog = "/usr/bin/python3" + +-- Keep the cursor centered by X rows from top / bottom +vim.opt.scrolloff = 15 + +-- Use System clipboard +vim.opt.clipboard = "unnamedplus" + +-- Enable Mouse +vim.opt.mouse = "a" + +-- Set Numbers +vim.opt.number = true +vim.opt.relativenumber = true + +-- Identation +local indent = 2 +vim.opt.tabstop = indent +vim.opt.shiftwidth = indent +vim.opt.softtabstop = indent + +-- Ignore case when searching +vim.opt.ignorecase = true + +-- Override the 'ignorecase' option if the search pattern contains case characters. +vim.opt.smartcase = true + +-- Wrap Search +vim.opt.wrapscan = true + +-- Autocompletion with 'wildchar' +vim.opt.wildmode = "longest,list,full" + +-- Fix Sppliting +vim.opt.splitbelow = true +vim.opt.splitright = true + +-- Set undofile +vim.opt.undofile = true +vim.opt.undodir = os.getenv("HOME") .. "/.nvim/undo" +vim.opt.undolevels = 1000 + +-- Open already open windows +vim.opt.switchbuf = 'usetab' + +-- Auto add comments on new line if prev was a comment +vim.opt.fo:append({ cro = true }) diff --git a/config/nvim.old/lua/plugins/autocompletion.lua b/config/nvim.old/lua/plugins/autocompletion.lua new file mode 100644 index 0000000..7578384 --- /dev/null +++ b/config/nvim.old/lua/plugins/autocompletion.lua @@ -0,0 +1,50 @@ +-- luasnip setup +local luasnip = require 'luasnip' +local cmp = require 'cmp' + +cmp.setup { + snippet = { + expand = function(args) require('luasnip').lsp_expand(args.body) end + }, + mapping = { + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.close(), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true + }, + [''] = function(fallback) + if vim.fn.pumvisible() == 1 then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes('', true, + true, true), 'n') + elseif luasnip.expand_or_jumpable() then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes( + 'luasnip-expand-or-jump', true, true, + true), '') + else + fallback() + end + end, + [''] = function(fallback) + if vim.fn.pumvisible() == 1 then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes('', true, + true, true), 'n') + elseif luasnip.jumpable(-1) then + vim.fn.feedkeys(vim.api.nvim_replace_termcodes( + 'luasnip-jump-prev', true, true, true), + '') + else + fallback() + end + end + }, + sources = { + {name = 'nvim_lsp'}, {name = 'luasnip'}, {name = "nvim_lua"}, + {name = 'path'}, {name = 'buffer'}, {name = 'calc'}, + {name = 'treesitter'} + } +} diff --git a/config/nvim.old/lua/plugins/autopairs.lua b/config/nvim.old/lua/plugins/autopairs.lua new file mode 100644 index 0000000..deeac60 --- /dev/null +++ b/config/nvim.old/lua/plugins/autopairs.lua @@ -0,0 +1,2 @@ +require('nvim-autopairs').setup() + diff --git a/config/nvim.old/lua/plugins/bufferline.lua b/config/nvim.old/lua/plugins/bufferline.lua new file mode 100644 index 0000000..4dc0347 --- /dev/null +++ b/config/nvim.old/lua/plugins/bufferline.lua @@ -0,0 +1,22 @@ +local function config() + require("bufferline").setup({ + options = { + diagnostics = "nvim_lsp", + diagnostics_update_in_insert = true, + color_icons = true, + show_close_icon = false + } + }) + + vim.keymap.set('n', 'H', ':BufferLineCyclePrev', { desc = "Go to prev buffer", silent = true }) + vim.keymap.set('n', 'L', ':BufferLineCycleNext', { desc = "Go to next buffer", silent = true }) + vim.keymap.set('n', 'c', ':bdelete', { desc = "Close current buffer", silent = true }) + vim.keymap.set('n', 'C', ':bdelete!', { desc = "Close current buffer whitout saving", silent = true }) +end + +return { + 'akinsho/bufferline.nvim', + tag = "v2.*", + requires = 'kyazdani42/nvim-web-devicons', + config = config +} diff --git a/config/nvim.old/lua/plugins/colorscheme.lua b/config/nvim.old/lua/plugins/colorscheme.lua new file mode 100644 index 0000000..83c6a18 --- /dev/null +++ b/config/nvim.old/lua/plugins/colorscheme.lua @@ -0,0 +1,81 @@ +local function config() + + local catppuccin = require("catppuccin") + + vim.g.catppuccin_flavour = "mocha" + + vim.cmd [[colorscheme catppuccin]] + + -- configure it + catppuccin.setup({ + transparent_background = true, + term_colors = false, + styles = { + comments = {"italic"}, + conditionals = {"italic"}, + loops = {"italic"}, + functions = {"italic"}, + keywords = {"italic"}, + strings = {"italic"}, + variables = {"italic"}, + numbers = {}, + booleans = {}, + properties = {}, + types = {}, + operators = {} + }, + integrations = { + treesitter = true, + native_lsp = { + enabled = true, + virtual_text = { + errors = {"italic"}, + hints = {"italic"}, + warnings = {"italic"}, + information = {"italic"} + }, + underlines = { + errors = {"underline"}, + hints = {"underline"}, + warnings = {"underline"}, + information = {"underline"} + } + }, + lsp_trouble = true, + cmp = true, + lsp_saga = true, + gitgutter = false, + gitsigns = true, + telescope = true, + nvimtree = { + enabled = true, + show_root = true, + transparent_panel = true + }, + indent_blankline = {enabled = true, colored_indent_levels = true}, + neotree = { + enabled = false, + show_root = true, + transparent_panel = false + }, + dap = {enabled = false, enable_ui = false}, + which_key = true, + dashboard = true, + neogit = false, + vim_sneak = false, + fern = false, + barbar = true, + bufferline = true, + markdown = true, + lightspeed = false, + ts_rainbow = true, + hop = false, + notify = true, + telekasten = true, + symbols_outline = true, + mini = false + } + }) +end + +return {"catppuccin/nvim", as = "catppuccin", config = config} diff --git a/config/nvim.old/lua/plugins/dashboard.lua b/config/nvim.old/lua/plugins/dashboard.lua new file mode 100644 index 0000000..7299183 --- /dev/null +++ b/config/nvim.old/lua/plugins/dashboard.lua @@ -0,0 +1,33 @@ +-- Default FZF +vim.g.dashboard_default_executive = "telescope" + +-- Custom Shortcuts +-- TODO: Change this for telescope equivalents +vim.api.nvim_set_keymap('n', 'db', ":DashboardJumpMark", + {silent = true}) +vim.api.nvim_set_keymap('n', 'dh', ":DashboardFindHistory", + {silent = true}) +vim.api.nvim_set_keymap('n', 'df', ":DashboardFindFile", + {silent = true}) +vim.api.nvim_set_keymap('n', 'dn', ":DashboardNewFile", + {silent = true}) +vim.api.nvim_set_keymap('n', 'da', ":DashboardFindWord", + {silent = true}) +vim.api.nvim_set_keymap('n', 'dc', ":DashboardChangeColorscheme", + {silent = true}) + +-- Show mappings +vim.g.dashboard_custom_shortcut = { + last_session = 'SPC s l', + book_marks = 'SPC d b', + find_history = 'SPC d h', + find_file = 'SPC d f', + new_file = 'SPC d n', + find_word = 'SPC d a', + change_colorscheme = 'SPC d c' +} + +-- Hide tabline on dashboard +vim.cmd([[ + autocmd FileType dashboard set showtabline=0 | autocmd WinLeave set showtabline=2 + ]]) diff --git a/config/nvim.old/lua/plugins/focus.lua b/config/nvim.old/lua/plugins/focus.lua new file mode 100644 index 0000000..e46f903 --- /dev/null +++ b/config/nvim.old/lua/plugins/focus.lua @@ -0,0 +1,72 @@ +local focus = require("focus") + +local options = { + -- Completely disable this plugin + -- Default: true + enable = true, + + -- Force width for the d window + -- Default: Calculated based on golden ratio + -- width = 120 + + -- Force height for the d window + -- Default: Calculated based on golden ratio + -- height = 40 + + -- Sets the width of directory tree buffers such as NerdTree, NvimTree and CHADTree + -- Default: vim.g.nvim_tree_width or 30 + -- treewidth = 20 + + -- Displays a cursorline in the ed window only + -- Not displayed in uned windows + -- Default: true + -- cursorline = false + + -- Displays a sign column in the ed window only + -- Not displayed in uned windows + -- Default: true + -- signcolumn = false + + -- Displays line numbers in the ed window only + -- Not displayed in uned windows + -- Default: true + number = true, + + -- Displays relative line numbers in the ed window only + -- Not displayed in uned windows + -- See :h relativenumber + -- Default: false + relativenumber = true, + + -- Displays hybrid line numbers in the ed window only + -- Not displayed in uned windows + -- Combination of :h relativenumber, but also displays the line number of the current line only + -- Default: false + -- hybridnumber = true + + -- Enable auto highlighting for ed/unfocussed windows + -- Default: false + winhighlight = true, +} + +---------------------------------------------------------------------- +-- Mappings -- +---------------------------------------------------------------------- + +local function focusmap(direction) + vim.keymap.set("n", "", function() + focus.split_command(direction) + end, { desc = "Change or create focused window" }) +end + +focusmap("h") +focusmap("j") +focusmap("k") +focusmap("l") + +return { + "beauwilliams/focus.nvim", + config = function() + require("focus").setup(options) + end, +} diff --git a/config/nvim.old/lua/plugins/gitsigns.lua b/config/nvim.old/lua/plugins/gitsigns.lua new file mode 100644 index 0000000..123041d --- /dev/null +++ b/config/nvim.old/lua/plugins/gitsigns.lua @@ -0,0 +1,91 @@ +local mapper = require("nvim-mapper") + +require('gitsigns').setup { + signs = { + add = { + hl = 'GitSignsAdd', + text = '│', + numhl = 'GitSignsAddNr', + linehl = 'GitSignsAddLn' + }, + change = { + hl = 'GitSignsChange', + text = '│', + numhl = 'GitSignsChangeNr', + linehl = 'GitSignsChangeLn' + }, + delete = { + hl = 'GitSignsDelete', + text = '_', + numhl = 'GitSignsDeleteNr', + linehl = 'GitSignsDeleteLn' + }, + topdelete = { + hl = 'GitSignsDelete', + text = '‾', + numhl = 'GitSignsDeleteNr', + linehl = 'GitSignsDeleteLn' + }, + changedelete = { + hl = 'GitSignsChange', + text = '~', + numhl = 'GitSignsChangeNr', + linehl = 'GitSignsChangeLn' + } + }, + signcolumn = true, -- Toggle with `:Gitsigns toggle_signs` + numhl = false, -- Toggle with `:Gitsigns toggle_numhl` + linehl = false, -- Toggle with `:Gitsigns toggle_linehl` + word_diff = false, -- Toggle with `:Gitsigns toggle_word_diff` + keymaps = { + -- Default keymap options + noremap = true, + + ['n ]h'] = { + expr = true, + "&diff ? ']c' : 'lua require\"gitsigns.actions\".next_hunk()'" + }, + ['n [h'] = { + expr = true, + "&diff ? '[c' : 'lua require\"gitsigns.actions\".prev_hunk()'" + }, + + ['n gs'] = 'lua require"gitsigns".stage_hunk()', + ['v gs'] = 'lua require"gitsigns".stage_hunk({vim.fn.line("."), vim.fn.line("v")})', + ['n gu'] = 'lua require"gitsigns".undo_stage_hunk()', + ['n gr'] = 'lua require"gitsigns".reset_hunk()', + ['v gr'] = 'lua require"gitsigns".reset_hunk({vim.fn.line("."), vim.fn.line("v")})', + ['n gR'] = 'lua require"gitsigns".reset_buffer()', + ['n gp'] = 'lua require"gitsigns".preview_hunk()', + ['n gb'] = 'lua require"gitsigns".blame_line(true)', + ['n gS'] = 'lua require"gitsigns".stage_buffer()', + ['n gU'] = 'lua require"gitsigns".reset_buffer_index()', + + -- Text objects + ['o ih'] = ':lua require"gitsigns.actions".select_hunk()', + ['x ih'] = ':lua require"gitsigns.actions".select_hunk()' + }, + watch_index = {interval = 1000, follow_files = true}, + attach_to_untracked = true, + current_line_blame = false, -- Toggle with `:Gitsigns toggle_current_line_blame` + current_line_blame_opts = { + virt_text = true, + virt_text_pos = 'eol', -- 'eol' | 'overlay' | 'right_align' + delay = 1000 + }, + current_line_blame_formatter_opts = {relative_time = false}, + sign_priority = 6, + update_debounce = 100, + status_formatter = nil, -- Use default + max_file_length = 40000, + preview_config = { + -- Options passed to nvim_open_win + border = 'single', + style = 'minimal', + relative = 'cursor', + row = 0, + col = 1 + }, + diff_opts = {internal = true}, -- If vim.diff or luajit is present + yadm = {enable = false} +} diff --git a/config/nvim.old/lua/plugins/harpoon.lua b/config/nvim.old/lua/plugins/harpoon.lua new file mode 100644 index 0000000..35e697e --- /dev/null +++ b/config/nvim.old/lua/plugins/harpoon.lua @@ -0,0 +1,27 @@ +local mapper = require("nvim-mapper") + +require("harpoon").setup({ + global_settings = {save_on_toggle = false, save_on_change = true} +}) + +-- Mark list +mapper.map('n', 'mq', + [[:lua require("harpoon.ui").toggle_quick_menu()]], + {silent = true, noremap = true}, "harpoon", "quick_menu", + "Open list of marked files") + +-- Mark File +mapper.map('n', 'ma', [[:lua require("harpoon.mark").add_file()]], + {silent = true, noremap = true}, "harpoon", "add_file", + "Add current file to mark list") + +-- Open marked file +mapper.map('n', 'mj', [[:lua require("harpoon.ui").nav_file(1)]], + {silent = true, noremap = true}, "harpoon", "file_navigation_1", + "Go to marked file 1") +mapper.map('n', 'mk', [[:lua require("harpoon.ui").nav_file(2)]], + {silent = true, noremap = true}, "harpoon", "file_navigation_2", + "Go to marked file 2") +mapper.map('n', 'ml', [[:lua require("harpoon.ui").nav_file(3)]], + {silent = true, noremap = true}, "harpoon", "file_navigation_3", + "Go to marked file 3") diff --git a/config/nvim.old/lua/plugins/indent-lines.lua b/config/nvim.old/lua/plugins/indent-lines.lua new file mode 100644 index 0000000..69e5df1 --- /dev/null +++ b/config/nvim.old/lua/plugins/indent-lines.lua @@ -0,0 +1,25 @@ +local function config() + + -- vim.opt.list = true + -- vim.opt.listchars:append "space:⋅" + -- vim.opt.listchars:append "eol:↴" + + require("indent_blankline").setup { + space_char_blankline = " ", + show_current_context = true, + show_current_context_start = false + } + + -- vim.g.indent_blankline_char_list = {"│"} + -- vim.g.indentLine_enabled = 1 + vim.g.indent_blankline_show_trailing_blankline_indent = false + vim.g.indent_blankline_filetype_exclude = { + "help", "terminal", "dashboard", "nvim-tree" + } + vim.g.indent_blankline_buftype_exclude = {"terminal"} + vim.g.indent_blankline_show_first_indent_level = false + vim.g.indent_blankline_use_treesitter = true + +end + +return {"lukas-reineke/indent-blankline.nvim", config = config} diff --git a/config/nvim.old/lua/plugins/init.lua b/config/nvim.old/lua/plugins/init.lua new file mode 100644 index 0000000..fd8fd26 --- /dev/null +++ b/config/nvim.old/lua/plugins/init.lua @@ -0,0 +1,62 @@ +local active_plugins = { + "focus", + "colorscheme", + "nvim-tree", + "bufferline", + "treesitter", + "prettyfolds", + "indent-lines", + "lsp", + "telescope", +} + +--[[ + Auto update plugins from outside neomvim + nvim --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync' +--]] +-- +local ensure_packer = function() + local fn = vim.fn + local install_path = fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim" + if fn.empty(fn.glob(install_path)) > 0 then + fn.system({ + "git", + "clone", + "--depth", + "1", + "https://github.com/wbthomason/packer.nvim", + install_path, + }) + vim.cmd([[packadd packer.nvim]]) + return true + end + return false +end + +local packer_bootstrap = ensure_packer() + +require("packer").startup({ + function(use) + use("wbthomason/packer.nvim") + + for _, name in ipairs(active_plugins) do + local ok, plugin = pcall(require, "plugins." .. name) + if ok then + use(plugin) + else + print("Error loading " .. name .. "In: " .. plugin) + end + end + + if packer_bootstrap then + require("packer").sync() + end + end, + config = { + display = { + open_fn = function() + return require("packer.util").float({ border = "single" }) + end, + }, + }, +}) diff --git a/config/nvim.old/lua/plugins/lsp.lua b/config/nvim.old/lua/plugins/lsp.lua new file mode 100644 index 0000000..4cba9fc --- /dev/null +++ b/config/nvim.old/lua/plugins/lsp.lua @@ -0,0 +1,160 @@ +--[[ + + LSP Server: code completition, references for variables and other stuff. + Linter: Code rules for consistency. + Formatter: Code style for eye candy. + Debugger: well... a debugger... + +--]] + +-- FIXME: Refactor this code so it's more readable + +local function setup() + local lsp = require("lsp-zero") + local cmp = require("cmp") + local null_ls = require("null-ls") + -- local mason_null_ls = require("mason-null-ls") + + lsp.preset("recommended") + + lsp.nvim_workspace({ + library = vim.api.nvim_get_runtime_file("", true), + }) + + local cmp_select = { behavior = cmp.SelectBehavior.Select } + + lsp.setup_nvim_cmp({ + mapping = lsp.defaults.cmp_mappings({ + [""] = cmp.mapping.select_prev_item(cmp_select), + [""] = cmp.mapping.select_next_item(cmp_select), + }), + + sources = { + { name = "path" }, + { name = "nvim_lsp", keyword_length = 3 }, + { name = "luasnip", keyword_length = 2 }, + }, + }) + + lsp.set_preferences({ + set_lsp_keymaps = false, + }) + + vim.keymap.set("n", "K", function() + vim.lsp.buf.hover() + end, { desc = "Show lsp info of the symbol under the cursor", silent = true }) + vim.keymap.set("n", "gd", function() + vim.lsp.buf.definition() + end, { desc = "Go to definition", silent = true }) + vim.keymap.set("n", "gD", function() + vim.lsp.buf.declaration() + end, { desc = "Go to declaration", silent = true }) + vim.keymap.set("n", "gi", function() + vim.lsp.buf.implementation() + end, { desc = "Go to implementation", silent = true }) + vim.keymap.set("n", "go", function() + vim.lsp.buf.type_definition() + end, { desc = "Go to definition of the type", silent = true }) + vim.keymap.set("n", "gr", function() + vim.lsp.buf.references() + end, { desc = "List references in quickfix window", silent = true }) + vim.keymap.set("n", "K", function() + vim.lsp.buf.signature_help() + end, { desc = "Show signature", silent = true }) + vim.keymap.set("n", "lr", function() + vim.lsp.buf.rename() + end, { desc = "Rename all references", silent = true }) + vim.keymap.set("n", "la", function() + vim.lsp.buf.code_action() + end, { desc = "Code action", silent = true }) + vim.keymap.set("n", "lj", function() + vim.diagnostic.goto_next() + end, { desc = "Go to next diagnostics", silent = true }) + vim.keymap.set("n", "lk", function() + vim.diagnostic.goto_prev() + end, { desc = "Go to prev diagnostics", silent = true }) + + lsp.setup() + + local null_linters = null_ls.builtins.diagnostics + local null_formatters = null_ls.builtins.formatting + + local augroup = vim.api.nvim_create_augroup("LspFormatting", {}) + + local lsp_formatting = function(bufnr) + vim.lsp.buf.format({ + filter = function(client) + -- apply whatever logic you want (in this example, we'll only use null-ls) + return client.name == "null-ls" + end, + bufnr = bufnr, + }) + end + + null_ls.setup({ + on_attach = function(client, bufnr) + if client.supports_method("textDocument/formatting") then + vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) + vim.api.nvim_create_autocmd("BufWritePre", { + group = augroup, + buffer = bufnr, + callback = function() + -- TODO: use this when neovim 8.0 comes out + lsp_formatting(bufnr) + -- vim.lsp.buf.formatting_sync() + end, + }) + end + end, + + sources = { + -- Linters -- + null_linters.eslint_d, + null_linters.gitlint, + null_linters.luacheck, + null_linters.markdownlint, + null_linters.shellcheck, + null_linters.yamllint, + null_linters.todo_comments, + + -- Formatters -- + null_formatters.blade_formatter, + null_formatters.blue, + null_formatters.fixjson, + null_formatters.phpcsfixer, + null_formatters.prettierd, + null_formatters.shfmt, + null_formatters.sql_formatter, + null_formatters.stylua, + null_formatters.yamlfmt, + }, + }) +end + +return { + "VonHeikemen/lsp-zero.nvim", + config = setup, + requires = { + -- LSP Support + { "neovim/nvim-lspconfig" }, + { "williamboman/mason.nvim" }, + { "williamboman/mason-lspconfig.nvim" }, + + -- Autocompletion + { "hrsh7th/nvim-cmp" }, + { "hrsh7th/cmp-buffer" }, + { "hrsh7th/cmp-path" }, + { "saadparwaiz1/cmp_luasnip" }, + { "hrsh7th/cmp-nvim-lsp" }, + { "hrsh7th/cmp-nvim-lua" }, + + -- Snippets + { "L3MON4D3/LuaSnip" }, + { "rafamadriz/friendly-snippets" }, + + -- Linters and Formatters + { "jose-elias-alvarez/null-ls.nvim" }, + -- { "jayp0521/mason-null-ls.nvim" }, + { "nvim-lua/plenary.nvim" }, + }, +} diff --git a/config/nvim.old/lua/plugins/nvim-comment-frame.lua b/config/nvim.old/lua/plugins/nvim-comment-frame.lua new file mode 100644 index 0000000..0c2aff4 --- /dev/null +++ b/config/nvim.old/lua/plugins/nvim-comment-frame.lua @@ -0,0 +1,38 @@ +local mapper = require("nvim-mapper") + +require('nvim-comment-frame').setup({ + + -- if true, cf keymap will be disabled + disable_default_keymap = true, + + -- width of the comment frame + frame_width = 70, + + -- wrap the line after 'n' characters + line_wrap_len = 50, + + -- automatically indent the comment frame based on the line + auto_indent = true, + + -- add comment above the current line + add_comment_above = true, + + -- configurations for individual language goes here + languages = { + dosini = { + start_str = ';;', + end_str = ';;', + fill_char = '*', + auto_indent = false + } + } +}) + +mapper.map('n', 'ch', + [[:lua require('nvim-comment-frame').add_comment()]], + {silent = true, noremap = true}, "nvim-comment-frame", "one line", + "Add one line header") +mapper.map('n', 'cH', + [[:lua require('nvim-comment-frame').add_multiline_comment()]], + {silent = true, noremap = true}, "nvim-comment-frame", "multi line", + "Add multi line header") diff --git a/config/nvim.old/lua/plugins/nvim-toggleterm.lua b/config/nvim.old/lua/plugins/nvim-toggleterm.lua new file mode 100644 index 0000000..41e090c --- /dev/null +++ b/config/nvim.old/lua/plugins/nvim-toggleterm.lua @@ -0,0 +1,47 @@ +local mapper = require("nvim-mapper") +-- don't close terminals on hidden +vim.opt.hidden = true + +require("toggleterm").setup { + -- size can be a number or function which is passed the current terminal + size = function(term) + if term.direction == "horizontal" then + return 15 + elseif term.direction == "vertical" then + return vim.o.columns * 0.4 + end + end, + hide_numbers = true, -- hide the number column in toggleterm buffers + shade_filetypes = {}, + shade_terminals = false, + -- shading_factor = '', -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light + start_in_insert = true, + insert_mappings = true, -- whether or not the open mapping applies in insert mode + persist_size = true, + direction = 'float', -- 'vertical' | 'horizontal' | 'window' | 'float', + close_on_exit = true, -- close the terminal window when the process exits + shell = vim.o.shell, -- change the default shell + -- This field is only relevant if direction is set to 'float' + float_opts = { + -- The border key is *almost* the same as 'nvim_win_open' + -- see :h nvim_win_open for details on borders however + -- the 'curved' border is a custom border type + -- not natively supported but implemented in this plugin. + border = 'single', -- 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open + width = math.ceil(vim.o.columns * 0.8), + height = math.ceil(vim.o.lines * 0.6), + winblend = 0, + highlights = {border = "Normal", background = "Normal"} + } +} + +-- Toggle Terminals +mapper.map('n', 'mf', [[:1ToggleTerm]], + {silent = true, noremap = true}, "Terminal", "toggle_term_1", + "Toggle terminal 1") +mapper.map('n', 'md', [[:2ToggleTerm]], + {silent = true, noremap = true}, "Terminal", "toggle_term_2", + "Toggle terminal 2") +mapper.map('n', 'ms', [[:3ToggleTerm]], + {silent = true, noremap = true}, "Terminal", "toggle_term_3", + "Toggle terminal 3") diff --git a/config/nvim.old/lua/plugins/nvim-tree.lua b/config/nvim.old/lua/plugins/nvim-tree.lua new file mode 100644 index 0000000..55430ab --- /dev/null +++ b/config/nvim.old/lua/plugins/nvim-tree.lua @@ -0,0 +1,53 @@ +local function tree_config() + local tree = require("nvim-tree") + local tree_cb = require("nvim-tree.config").nvim_tree_callback + + tree.setup({ + hijack_unnamed_buffer_when_opening = true, + disable_netrw = true, + hijack_netrw = true, + hijack_cursor = true, -- cursor at the start of filename + update_focused_file = { + enable = true -- focus curren file + }, + actions = { open_file = { quit_on_open = true } }, + renderer = { + full_name = true, -- show remaining name in floating text + group_empty = true, -- group empty folders + add_trailing = true, -- Trailing slash to folders + highlight_opened_files = "all", + highlight_git = true + }, + view = { + centralize_selection = true, -- center current file on enter + width = 30, -- N° of columns or % + mappings = { + custom_only = false, + -- list of mappings to set on the tree manually + list = { + { key = { "l", "", "o", "<2-LeftMouse>" }, action = "edit" }, + -- {key = {"L", "<2-RightMouse>", ""}, action = "cd"}, + { key = "s", action = "vsplit" }, + { key = "v", action = "split" }, + { key = "t", action = "tabnew" }, + { key = { "h", "" }, action = "close_node" }, + { key = "i", action = "toggle_dotfiles" }, + { key = "I", action = "toggle_ignored" }, + { key = { "", "" }, cb = tree_cb("system_open") } + } + } + } + }) + + -- bindings + vim.keymap.set("n", "e", ":NvimTreeToggle", { desc = "Toggle file tree", silent = true }) + vim.keymap.set("n", "", ":NvimTreeToggle", { desc = "Toggle file tree", silent = true }) +end + +return { + 'kyazdani42/nvim-tree.lua', + config = tree_config, + requires = { + 'kyazdani42/nvim-web-devicons' -- optional, for file icons + } +} diff --git a/config/nvim.old/lua/plugins/prettyfolds.lua b/config/nvim.old/lua/plugins/prettyfolds.lua new file mode 100644 index 0000000..308e66f --- /dev/null +++ b/config/nvim.old/lua/plugins/prettyfolds.lua @@ -0,0 +1,3 @@ +local function config() require('pretty-fold').setup({fill_char = " "}) end + +return {'anuvyklack/pretty-fold.nvim', config = config} diff --git a/config/nvim.old/lua/plugins/projects.lua b/config/nvim.old/lua/plugins/projects.lua new file mode 100644 index 0000000..f87519b --- /dev/null +++ b/config/nvim.old/lua/plugins/projects.lua @@ -0,0 +1,36 @@ +require("project_nvim").setup { + -- Manual mode doesn't automatically change your root directory, so you have + -- the option to manually do so using `:ProjectRoot` command. + manual_mode = false, + + -- Methods of detecting the root directory. **"lsp"** uses the native neovim + -- lsp, while **"pattern"** uses vim-rooter like glob pattern matching. Here + -- order matters: if one is not detected, the other is used as fallback. You + -- can also delete or rearangne the detection methods. + detection_methods = {"lsp", "pattern"}, + + -- All the patterns used to detect root dir, when **"pattern"** is in + -- detection_methods + patterns = { + ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json" + }, + + -- Table of lsp clients to ignore by name + -- eg: { "efm", ... } + ignore_lsp = {}, + + -- Don't calculate root dir on specific directories + -- Ex: { "~/.cargo/*", ... } + exclude_dirs = {}, + + -- Show hidden files in telescope + show_hidden = false, + + -- When set to false, you will get a message when project.nvim changes your + -- directory. + silent_chdir = false, + + -- Path where project.nvim will store the project history for use in + -- telescope + datapath = vim.fn.stdpath("data") +} diff --git a/config/nvim.old/lua/plugins/telescope.lua b/config/nvim.old/lua/plugins/telescope.lua new file mode 100644 index 0000000..fcc3abc --- /dev/null +++ b/config/nvim.old/lua/plugins/telescope.lua @@ -0,0 +1,80 @@ +local function config() + -- Telescope.nvim + local telescope = require("telescope") + local pickers = require("telescope.builtin") + require("project_nvim").setup() + + -- Extensions + telescope.load_extension("projects") + + -- Open Files + vim.keymap.set("n", "f", function() + pickers.find_files() + end, { silent = true, desc = "Find file" }) + + vim.keymap.set("n", "Fp", function() + telescope.extensions.projects.projects() + end, { silent = true, desc = "Find project" }) + + -- List vim stuff + vim.keymap.set("n", "bf", function() + pickers.buffers() + end, { silent = true, desc = "Find buffers" }) + + -- List LSP Stuff + vim.keymap.set("n", "ld", function() + pickers.diagnostics({ bufnr = 0 }) + end, { silent = true, desc = "Find diagnostics" }) + + vim.keymap.set("n", "lD", function() + pickers.diagnostics() + end, { silent = true, desc = "Find diagnostics in all buffers" }) + + -- Config + local telescope_actions = require("telescope.actions") + telescope.setup({ + defaults = { + entry_prefix = " ", + selection_caret = "* ", + file_ignore_patterns = { "%.env", "cache", ".xlsx" }, + mappings = { + i = { + [""] = telescope_actions.move_selection_next, + [""] = telescope_actions.move_selection_previous, + [""] = telescope_actions.file_vsplit, + [""] = telescope_actions.file_split, + [""] = telescope_actions.close, + }, + n = { + ["gg"] = telescope_actions.move_to_top, + ["G"] = telescope_actions.move_to_bottom, + ["s"] = telescope_actions.file_vsplit, + ["v"] = telescope_actions.file_split, + }, + }, + path_display = { + truncate = 1, + }, + }, + -- Specific config + pickers = { + buffers = { + sort_lastused = true, + mappings = { + i = { ["d"] = require("telescope.actions").delete_buffer }, + n = { [""] = require("telescope.actions").delete_buffer }, + }, + }, + }, + }) +end + +return { + "nvim-telescope/telescope.nvim", + branch = "0.1.x", + requires = { + "nvim-lua/plenary.nvim", + "ahmedkhalf/project.nvim", + }, + config = config, +} diff --git a/config/nvim.old/lua/plugins/treesitter.lua b/config/nvim.old/lua/plugins/treesitter.lua new file mode 100644 index 0000000..8c0086b --- /dev/null +++ b/config/nvim.old/lua/plugins/treesitter.lua @@ -0,0 +1,37 @@ +local function config() + + require('nvim-treesitter.configs').setup({ + ensure_installed = { + "bash", "c", "comment", "cpp", "css", "dockerfile", "html", + "javascript", "jsdoc", "json", "lua", "python", "query", "regex", + "typescript", "yaml", "sql", "http", "php", "rust", "scss", + "markdown", "dart" + }, + highlight = {enable = true}, + indent = {enable = true}, + rainbow = { + enable = true, + extended_mode = true, -- Highlight also non-parentheses delimiters, boolean or table: lang -> boolean + max_file_lines = 1000 -- Do not enable for files with more than 1000 lines, int + } + }) + + -- Treesitter Folding + vim.api.nvim_create_autocmd({ + 'BufEnter', 'BufAdd', 'BufNew', 'BufNewFile', 'BufWinEnter' + }, { + group = vim.api.nvim_create_augroup('TS_FOLD_WORKAROUND', {}), + callback = function() + vim.opt.foldmethod = 'expr' + vim.opt.foldexpr = 'nvim_treesitter#foldexpr()' + end + }) +end + +return { + 'nvim-treesitter/nvim-treesitter', + run = function() + require('nvim-treesitter.install').update({with_sync = true}) + end, + config = config +} diff --git a/config/pycodestyle b/config/pycodestyle new file mode 100644 index 0000000..62e7381 --- /dev/null +++ b/config/pycodestyle @@ -0,0 +1,2 @@ +[pycodestyle] +max-line-length = 100 diff --git a/config/spicetify/Backup/login.spa b/config/spicetify/Backup/login.spa new file mode 100755 index 0000000..802e714 Binary files /dev/null and b/config/spicetify/Backup/login.spa differ diff --git a/config/spicetify/Backup/xpui.spa b/config/spicetify/Backup/xpui.spa new file mode 100755 index 0000000..5bc53fc Binary files /dev/null and b/config/spicetify/Backup/xpui.spa differ diff --git a/config/spicetify/CustomApps/marketplace/extension.js b/config/spicetify/CustomApps/marketplace/extension.js new file mode 100644 index 0000000..37f68a1 --- /dev/null +++ b/config/spicetify/CustomApps/marketplace/extension.js @@ -0,0 +1,8 @@ +"use strict";var marketplace=(()=>{var r=Object.defineProperty,s=Object.defineProperties,n=Object.getOwnPropertyDescriptors,a=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,i=(e,t,s)=>t in e?r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,l=(e,t)=>{for(var s in t=t||{})o.call(t,s)&&i(e,s,t[s]);if(a)for(var s of a(t))c.call(t,s)&&i(e,s,t[s]);return e},u=(e,t)=>s(e,n(t)),p="0.7.0",m="marketplace:installed-extensions",h="marketplace:installed-snippets",d="marketplace:theme-installed",g="marketplace:colorShift",f=100,w=(t,e)=>{t=localStorage.getItem(t);if(!t)return e;try{return JSON.parse(t)}catch(e){return t}},y=e=>{if(3===e.length)e=e.split("").map(e=>e+e).join("");else{if(6!=e.length)throw"Only 3- or 6-digit hex colours are allowed.";if(e.match(/[^0-9a-f]/i))throw"Only hex colours are allowed."}e=e.match(/.{1,2}/g);if(e&&3===e.length)return[parseInt(e[0],16),parseInt(e[1],16),parseInt(e[2],16)];throw"Could not parse hex colour."},S=(e,t)=>{let s=[];return e&&0({name:e.name,url:e.url.startsWith("javascript:")?"":e.url})):s.push({name:t,url:"https://github.com/"+t}),s},b=()=>{console.log("Resetting Marketplace"),Object.keys(localStorage).forEach(e=>{e.startsWith("marketplace:")&&(localStorage.removeItem(e),console.log("Removed "+e))}),console.log("Marketplace has been reset"),location.reload()},v=s=>{const e=document.querySelector("link[href='colors.css']"),t=(e&&e.remove(),document.querySelector("style.marketplaceCSS.marketplaceScheme"));if(t&&t.remove(),s){const r=document.createElement("style");r.classList.add("marketplaceCSS"),r.classList.add("marketplaceScheme");let t=":root {";const n=Object.keys(s);n.forEach(e=>{t=(t+=`--spice-${e}: #${s[e]};`)+`--spice-rgb-${e}: ${y(s[e])};`}),t+="}",r.innerHTML=t,document.head.appendChild(r)}else{const a=document.createElement("link");a.setAttribute("rel","stylesheet"),a.setAttribute("href","colors.css"),a.classList.add("userCSS"),document.head.appendChild(a)}},$=e=>{var t,e=e.match(new RegExp("https:\\/\\/raw\\.githubusercontent\\.com\\/(?[^/]+)\\/(?[^/]+)\\/(?[^/]+)\\/(?.+$)"));return{user:e?null==(t=e.groups)?void 0:t.user:null,repo:e?null==(t=e.groups)?void 0:t.repo:null,branch:e?null==(t=e.groups)?void 0:t.branch:null,filePath:e?null==(t=e.groups)?void 0:t.filePath:null}};function k(r,n){r&&r.forEach(e=>{n=n||r.user+"-"+r.repo;var t=window.sessionStorage.getItem(n);const s=t?JSON.parse(t):[];s.push(e),window.sessionStorage.setItem(n,JSON.stringify(s))})}async function L(e,t,s){var r=window.sessionStorage.getItem(e+"-"+t);const n=window.sessionStorage.getItem("noManifests");if(r)return JSON.parse(r);const a=`https://raw.githubusercontent.com/${e}/${t}/${s}/manifest.json`;if(null!=n&&n.includes(a))return null;r=await fetch(a).then(e=>e.json()).catch(()=>k([a],"noManifests"));return r&&window.sessionStorage.setItem(e+"-"+t,JSON.stringify(r)),r}async function O(e,t){var s=await async function(e,t=1){const s=window.sessionStorage.getItem("marketplace:blacklist");let r="https://api.github.com/search/repositories?per_page="+f;"extension"===e?r+="&q="+encodeURIComponent("topic:spicetify-extensions"):"theme"===e&&(r+="&q="+encodeURIComponent("topic:spicetify-themes")),t&&(r+="&page="+t);const n=await fetch(r).then(e=>e.json()).catch(()=>[]);return n.items||Spicetify.showNotification("Too Many Requests, Cool Down."),u(l({},n),{page_count:n.items.length,items:n.items.filter(e=>!(null!=s&&s.includes(e.html_url)))})}(e,t),r=(!async function(e,t){for(const r of e.items){var s="theme"===t?await async function(t,r,n){try{let e;var s=t.match(new RegExp("https:\\/\\/api\\.github\\.com\\/repos\\/(?.+)\\/(?.+)\\/contents"));if(!s||!s.groups)return null;const{user:a,repo:o}=s.groups;return e=await L(a,o,r),(e=Array.isArray(e)?e:[e]).reduce((e,t)=>{var s=t.branch||r,s={manifest:t,title:t.name,subtitle:t.description,authors:S(t.authors,a),user:a,repo:o,branch:s,imageURL:t.preview&&t.preview.startsWith("http")?t.preview:`https://raw.githubusercontent.com/${a}/${o}/${s}/`+t.preview,readmeURL:t.readme&&t.readme.startsWith("http")?t.readme:`https://raw.githubusercontent.com/${a}/${o}/${s}/`+t.readme,stars:n,tags:t.tags,cssURL:t.usercss.startsWith("http")?t.usercss:`https://raw.githubusercontent.com/${a}/${o}/${s}/`+t.usercss,schemesURL:t.schemes?t.schemes.startsWith("http")?t.schemes:`https://raw.githubusercontent.com/${a}/${o}/${s}/`+t.schemes:null,include:t.include};return null!=t&&t.name&&null!=t&&t.usercss&&null!=t&&t.description&&e.push(s),e},[])}catch(e){return null}}(r.contents_url,r.default_branch,r.stargazers_count):await async function(t,r,n,a=!1){try{let e;var s=t.match(new RegExp("https:\\/\\/api\\.github\\.com\\/repos\\/(?.+)\\/(?.+)\\/contents"));if(!s||!s.groups)return null;const{user:o,repo:c}=s.groups;return e=await L(o,c,r),(e=Array.isArray(e)?e:[e]).reduce((e,t)=>{var s=t.branch||r,s={manifest:t,title:t.name,subtitle:t.description,authors:S(t.authors,o),user:o,repo:c,branch:s,imageURL:t.preview&&t.preview.startsWith("http")?t.preview:`https://raw.githubusercontent.com/${o}/${c}/${s}/`+t.preview,extensionURL:t.main.startsWith("http")?t.main:`https://raw.githubusercontent.com/${o}/${c}/${s}/`+t.main,readmeURL:t.readme&&t.readme.startsWith("http")?t.readme:`https://raw.githubusercontent.com/${o}/${c}/${s}/`+t.readme,stars:n,tags:t.tags};return t&&t.name&&t.description&&t.main&&(a&&localStorage.getItem(`marketplace:installed:${o}/${c}/`+t.main)||e.push(s)),e},[])}catch(e){return null}}(r.contents_url,r.default_branch,r.stargazers_count);s&&(k(s),await function(t){return new Promise(e=>setTimeout(e,t))}(5e3))}}(s,e),f*(t-1)+s.page_count),n=(console.log({pageOfRepos:s}),s.total_count-r);if(console.log(`Parsed ${r}/${s.total_count} ${e}s`),0{for(;null==Spicetify||!Spicetify.LocalStorage||null==Spicetify||!Spicetify.showNotification;)await new Promise(e=>setTimeout(e,100));const e=document.createElement("script");e.innerHTML="const global = globalThis;",document.head.appendChild(e),console.log("Initializing Spicetify Marketplace v"+p),window.Marketplace={reset:b,version:p};var t=async e=>{const s=w(e);if(s){if(console.log("Initializing theme: ",s),s.schemes){e=s.schemes[s.activeScheme];if(v(e),"true"===localStorage.getItem(g)){var r=s.schemes;let t=0;const n=Object.keys(r).length;setInterval(()=>{t%=n;const e=document.createElement("style");e.className="colorShift-style",e.innerHTML=`* { + transition-duration: 400ms; + } + main-type-bass { + transition-duration: unset !important; + }`,document.body.appendChild(e),v(Object.values(r)[t]),t++,e.remove()},6e4)}}else console.warn("No schemes found for theme");const t=document.querySelector("link.marketplaceCSS");t&&t.remove();e=await(async e=>{if(!e.cssURL)throw new Error("No CSS URL provided");const t=-1.+?)['|"]\\)`,"gm"))||[]){const o=null==(s=null==a?void 0:a.groups)?void 0:s.path;!o||o.startsWith("http")||o.startsWith("data")||(s=r+o.replace(/\.\//g,""),n=n.replace(o,s))}return n})(s);try{const a=document.querySelector("link[href='user.css']"),o=(a&&a.remove(),document.querySelector("style.marketplaceCSS.marketplaceUserCSS"));if(o&&o.remove(),e){const c=document.createElement("style");c.classList.add("marketplaceCSS"),c.classList.add("marketplaceUserCSS"),c.innerHTML=e,document.head.appendChild(c)}else{const i=document.createElement("link");i.setAttribute("rel","stylesheet"),i.setAttribute("href","user.css"),i.classList.add("userCSS"),document.head.appendChild(i)}}catch(e){console.warn(e)}s.include&&s.include.length&&s.include.forEach(e=>{const t=document.createElement("script");let s=e;var r,n,a;-1w(e));{s=t;const a=document.querySelector("style.marketplaceSnippets"),o=(a&&a.remove(),document.createElement("style"));s=s.reduce((e,t)=>e=(e+=`/* ${t.title} - ${t.description} */ +`)+t.code+` +`,""),o.innerHTML=s,o.classList.add("marketplaceSnippets"),document.head.appendChild(o)}const n=w(m,[]);n.forEach(e=>{if((e=w(e=e))&&e.extensionURL){console.log("Initializing extension: ",e);const n=document.createElement("script");if(n.defer=!0,n.src=e.extensionURL,-1e.json()).catch(()=>({}))).repos;window.sessionStorage.setItem("marketplace:blacklist",JSON.stringify(e)),await Promise.all([O("extension",1),O("theme",1)])}()})(); diff --git a/config/spicetify/CustomApps/marketplace/index.js b/config/spicetify/CustomApps/marketplace/index.js new file mode 100644 index 0000000..18358df --- /dev/null +++ b/config/spicetify/CustomApps/marketplace/index.js @@ -0,0 +1,11 @@ +var marketplace=(()=>{var j,D=Object.create,s=Object.defineProperty,M=Object.defineProperties,F=Object.getOwnPropertyDescriptor,U=Object.getOwnPropertyDescriptors,G=Object.getOwnPropertyNames,q=Object.getOwnPropertySymbols,B=Object.getPrototypeOf,K=Object.prototype.hasOwnProperty,V=Object.prototype.propertyIsEnumerable,H=(e,t,r)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,i=(e,t)=>{for(var r in t=t||{})K.call(t,r)&&H(e,r,t[r]);if(q)for(var r of q(t))V.call(t,r)&&H(e,r,t[r]);return e},z=(e,t)=>M(e,U(t)),y=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,t)=>("undefined"!=typeof require?require:e)[t]}):e)(function(e){if("react"===e)return Spicetify.React;if("react-dom"===e)return Spicetify.ReactDOM;if("undefined"!=typeof require)return require.apply(this,arguments);throw new Error('Dynamic require of "'+e+'" is not supported')}),e=(e,t)=>function(){return t||(0,e[G(e)[0]])((t={exports:{}}).exports,t),t.exports},W=(t,r,a,n)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let e of G(r))K.call(t,e)||e===a||s(t,e,{get:()=>r[e],enumerable:!(n=F(r,e))||n.enumerable});return t},t=(e,t,r)=>(r=null!=e?D(B(e)):{},W(!t&&e&&e.__esModule?r:s(r,"default",{value:e,enumerable:!0}),e)),p=e({"../../node_modules/semver/internal/constants.js"(e,t){var r=Number.MAX_SAFE_INTEGER||9007199254740991;t.exports={SEMVER_SPEC_VERSION:"2.0.0",MAX_LENGTH:256,MAX_SAFE_INTEGER:r,MAX_SAFE_COMPONENT_LENGTH:16}}}),J=e({"../../node_modules/semver/internal/debug.js"(e,t){var r="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...e)=>console.error("SEMVER",...e):()=>{};t.exports=r}}),x=e({"../../node_modules/semver/internal/re.js"(e,t){var r=p()["MAX_SAFE_COMPONENT_LENGTH"],n=J(),s=(e=t.exports={}).re=[],o=e.src=[],i=e.t={},l=0,t=(e,t,r)=>{var a=l++;n(e,a,t),i[e]=a,o[a]=t,s[a]=new RegExp(t,r?"g":void 0)};t("NUMERICIDENTIFIER","0|[1-9]\\d*"),t("NUMERICIDENTIFIERLOOSE","[0-9]+"),t("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*"),t("MAINVERSION",`(${o[i.NUMERICIDENTIFIER]})\\.(${o[i.NUMERICIDENTIFIER]})\\.(${o[i.NUMERICIDENTIFIER]})`),t("MAINVERSIONLOOSE",`(${o[i.NUMERICIDENTIFIERLOOSE]})\\.(${o[i.NUMERICIDENTIFIERLOOSE]})\\.(${o[i.NUMERICIDENTIFIERLOOSE]})`),t("PRERELEASEIDENTIFIER",`(?:${o[i.NUMERICIDENTIFIER]}|${o[i.NONNUMERICIDENTIFIER]})`),t("PRERELEASEIDENTIFIERLOOSE",`(?:${o[i.NUMERICIDENTIFIERLOOSE]}|${o[i.NONNUMERICIDENTIFIER]})`),t("PRERELEASE",`(?:-(${o[i.PRERELEASEIDENTIFIER]}(?:\\.${o[i.PRERELEASEIDENTIFIER]})*))`),t("PRERELEASELOOSE",`(?:-?(${o[i.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${o[i.PRERELEASEIDENTIFIERLOOSE]})*))`),t("BUILDIDENTIFIER","[0-9A-Za-z-]+"),t("BUILD",`(?:\\+(${o[i.BUILDIDENTIFIER]}(?:\\.${o[i.BUILDIDENTIFIER]})*))`),t("FULLPLAIN",`v?${o[i.MAINVERSION]}${o[i.PRERELEASE]}?${o[i.BUILD]}?`),t("FULL",`^${o[i.FULLPLAIN]}$`),t("LOOSEPLAIN",`[v=\\s]*${o[i.MAINVERSIONLOOSE]}${o[i.PRERELEASELOOSE]}?${o[i.BUILD]}?`),t("LOOSE",`^${o[i.LOOSEPLAIN]}$`),t("GTLT","((?:<|>)?=?)"),t("XRANGEIDENTIFIERLOOSE",o[i.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*"),t("XRANGEIDENTIFIER",o[i.NUMERICIDENTIFIER]+"|x|X|\\*"),t("XRANGEPLAIN",`[v=\\s]*(${o[i.XRANGEIDENTIFIER]})(?:\\.(${o[i.XRANGEIDENTIFIER]})(?:\\.(${o[i.XRANGEIDENTIFIER]})(?:${o[i.PRERELEASE]})?${o[i.BUILD]}?)?)?`),t("XRANGEPLAINLOOSE",`[v=\\s]*(${o[i.XRANGEIDENTIFIERLOOSE]})(?:\\.(${o[i.XRANGEIDENTIFIERLOOSE]})(?:\\.(${o[i.XRANGEIDENTIFIERLOOSE]})(?:${o[i.PRERELEASELOOSE]})?${o[i.BUILD]}?)?)?`),t("XRANGE",`^${o[i.GTLT]}\\s*${o[i.XRANGEPLAIN]}$`),t("XRANGELOOSE",`^${o[i.GTLT]}\\s*${o[i.XRANGEPLAINLOOSE]}$`),t("COERCE",`(^|[^\\d])(\\d{1,${r}})(?:\\.(\\d{1,${r}}))?(?:\\.(\\d{1,${r}}))?(?:$|[^\\d])`),t("COERCERTL",o[i.COERCE],!0),t("LONETILDE","(?:~>?)"),t("TILDETRIM",`(\\s*)${o[i.LONETILDE]}\\s+`,!0),e.tildeTrimReplace="$1~",t("TILDE",`^${o[i.LONETILDE]}${o[i.XRANGEPLAIN]}$`),t("TILDELOOSE",`^${o[i.LONETILDE]}${o[i.XRANGEPLAINLOOSE]}$`),t("LONECARET","(?:\\^)"),t("CARETTRIM",`(\\s*)${o[i.LONECARET]}\\s+`,!0),e.caretTrimReplace="$1^",t("CARET",`^${o[i.LONECARET]}${o[i.XRANGEPLAIN]}$`),t("CARETLOOSE",`^${o[i.LONECARET]}${o[i.XRANGEPLAINLOOSE]}$`),t("COMPARATORLOOSE",`^${o[i.GTLT]}\\s*(${o[i.LOOSEPLAIN]})$|^$`),t("COMPARATOR",`^${o[i.GTLT]}\\s*(${o[i.FULLPLAIN]})$|^$`),t("COMPARATORTRIM",`(\\s*)${o[i.GTLT]}\\s*(${o[i.LOOSEPLAIN]}|${o[i.XRANGEPLAIN]})`,!0),e.comparatorTrimReplace="$1$2$3",t("HYPHENRANGE",`^\\s*(${o[i.XRANGEPLAIN]})\\s+-\\s+(${o[i.XRANGEPLAIN]})\\s*$`),t("HYPHENRANGELOOSE",`^\\s*(${o[i.XRANGEPLAINLOOSE]})\\s+-\\s+(${o[i.XRANGEPLAINLOOSE]})\\s*$`),t("STAR","(<|>)?=?\\s*\\*"),t("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),t("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")}}),X=e({"../../node_modules/semver/internal/parse-options.js"(e,t){var r=["includePrerelease","loose","rtl"];t.exports=t=>t?"object"!=typeof t?{loose:!0}:r.filter(e=>t[e]).reduce((e,t)=>(e[t]=!0,e),{}):{}}}),Y=e({"../../node_modules/semver/internal/identifiers.js"(e,t){var n=/^[0-9]+$/,r=(e,t)=>{var r=n.test(e),a=n.test(t);return r&&a&&(e=+e,t=+t),e===t?0:r&&!a||(!a||r)&&er(t,e)}}}),_=e({"../../node_modules/semver/classes/semver.js"(e,t){var n=J(),{MAX_LENGTH:a,MAX_SAFE_INTEGER:s}=p(),{re:o,t:i}=x(),l=X(),c=Y()["compareIdentifiers"],u=class{constructor(e,t){if(t=l(t),e instanceof u){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>a)throw new TypeError(`version is longer than ${a} characters`);n("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;const r=e.trim().match(t.loose?o[i.LOOSE]:o[i.FULL]);if(!r)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+r[1],this.minor=+r[2],this.patch=+r[3],this.major>s||this.major<0)throw new TypeError("Invalid major version");if(this.minor>s||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>s||this.patch<0)throw new TypeError("Invalid patch version");r[4]?this.prerelease=r[4].split(".").map(e=>{if(/^[0-9]+$/.test(e)){var t=+e;if(0<=t&&t{if(t=i(t),e instanceof o)return e;if("string"!=typeof e)return null;if(e.length>a)return null;const r=t.loose?n[s.LOOSE]:n[s.FULL];if(!r.test(e))return null;try{return new o(e,t)}catch(e){return null}}}}),Q=e({"../../node_modules/semver/functions/valid.js"(e,t){var r=a();t.exports=(e,t)=>{e=r(e,t);return e?e.version:null}}}),Z=e({"../../node_modules/semver/functions/clean.js"(e,t){var r=a();t.exports=(e,t)=>{e=r(e.trim().replace(/^[=v]+/,""),t);return e?e.version:null}}}),ee=e({"../../node_modules/semver/functions/inc.js"(e,t){var n=_();t.exports=(e,t,r,a)=>{"string"==typeof r&&(a=r,r=void 0);try{return new n(e instanceof n?e.version:e,r).inc(t,a).version}catch(e){return null}}}}),n=e({"../../node_modules/semver/functions/compare.js"(e,t){var a=_();t.exports=(e,t,r)=>new a(e,r).compare(new a(t,r))}}),te=e({"../../node_modules/semver/functions/eq.js"(e,t){var a=n();t.exports=(e,t,r)=>0===a(e,t,r)}}),re=e({"../../node_modules/semver/functions/diff.js"(e,t){var o=a(),i=te();t.exports=(e,t)=>{if(i(e,t))return null;var r=o(e),a=o(t),e=r.prerelease.length||a.prerelease.length,n=e?"pre":"",t=e?"prerelease":"";for(const s in r)if(("major"===s||"minor"===s||"patch"===s)&&r[s]!==a[s])return n+s;return t}}}),ae=e({"../../node_modules/semver/functions/major.js"(e,t){var r=_();t.exports=(e,t)=>new r(e,t).major}}),ne=e({"../../node_modules/semver/functions/minor.js"(e,t){var r=_();t.exports=(e,t)=>new r(e,t).minor}}),se=e({"../../node_modules/semver/functions/patch.js"(e,t){var r=_();t.exports=(e,t)=>new r(e,t).patch}}),oe=e({"../../node_modules/semver/functions/prerelease.js"(e,t){var r=a();t.exports=(e,t)=>{e=r(e,t);return e&&e.prerelease.length?e.prerelease:null}}}),ie=e({"../../node_modules/semver/functions/rcompare.js"(e,t){var a=n();t.exports=(e,t,r)=>a(t,e,r)}}),le=e({"../../node_modules/semver/functions/compare-loose.js"(e,t){var r=n();t.exports=(e,t)=>r(e,t,!0)}}),ce=e({"../../node_modules/semver/functions/compare-build.js"(e,t){var n=_();t.exports=(e,t,r)=>{const a=new n(e,r);e=new n(t,r);return a.compare(e)||a.compareBuild(e)}}}),ue=e({"../../node_modules/semver/functions/sort.js"(e,t){var a=ce();t.exports=(e,r)=>e.sort((e,t)=>a(e,t,r))}}),pe=e({"../../node_modules/semver/functions/rsort.js"(e,t){var a=ce();t.exports=(e,r)=>e.sort((e,t)=>a(t,e,r))}}),u=e({"../../node_modules/semver/functions/gt.js"(e,t){var a=n();t.exports=(e,t,r)=>0a(e,t,r)<0}}),de=e({"../../node_modules/semver/functions/neq.js"(e,t){var a=n();t.exports=(e,t,r)=>0!==a(e,t,r)}}),me=e({"../../node_modules/semver/functions/gte.js"(e,t){var a=n();t.exports=(e,t,r)=>0<=a(e,t,r)}}),fe=e({"../../node_modules/semver/functions/lte.js"(e,t){var a=n();t.exports=(e,t,r)=>a(e,t,r)<=0}}),ge=e({"../../node_modules/semver/functions/cmp.js"(e,t){var n=te(),s=de(),o=u(),i=me(),l=he(),c=fe();t.exports=(e,t,r,a)=>{switch(t){case"===":return(e="object"==typeof e?e.version:e)===(r="object"==typeof r?r.version:r);case"!==":return(e="object"==typeof e?e.version:e)!==(r="object"==typeof r?r.version:r);case"":case"=":case"==":return n(e,r,a);case"!=":return s(e,r,a);case">":return o(e,r,a);case">=":return i(e,r,a);case"<":return l(e,r,a);case"<=":return c(e,r,a);default:throw new TypeError("Invalid operator: "+t)}}}}),ve=e({"../../node_modules/semver/functions/coerce.js"(e,t){var n=_(),s=a(),{re:o,t:i}=x();t.exports=(e,t)=>{if(e instanceof n)return e;if("string"!=typeof(e="number"==typeof e?String(e):e))return null;let r=null;if((t=t||{}).rtl){for(var a;(a=o[i.COERCERTL].exec(e))&&(!r||r.index+r[0].length!==e.length);)r&&a.index+a[0].length===r.index+r[0].length||(r=a),o[i.COERCERTL].lastIndex=a.index+a[1].length+a[2].length;o[i.COERCERTL].lastIndex=-1}else r=e.match(o[i.COERCE]);return null===r?null:s(`${r[2]}.${r[3]||"0"}.`+(r[4]||"0"),t)}}}),ye=e({"../../node_modules/yallist/iterator.js"(e,t){"use strict";t.exports=function(e){e.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}}}),Ee=e({"../../node_modules/yallist/yallist.js"(e,t){"use strict";function s(e){var t=this;if((t=t instanceof s?t:new s).tail=null,t.head=null,t.length=0,e&&"function"==typeof e.forEach)e.forEach(function(e){t.push(e)});else if(0this.length&&(t=this.length);for(var a=0,n=this.head;null!==n&&athis.length&&(t=this.length);for(var a=this.length,n=this.tail;null!==n&&tthis.length?this.length-1:e)<0&&(e=this.length+e);for(var a=0,n=this.head;null!==n&&a1,m=(e,t,r)=>{const a=e[d].get(t);if(a){t=a.value;if(f(e,t)){if(v(e,a),!e[s])return}else r&&(e[n]&&(a.value.now=Date.now()),e[h].unshiftNode(a));return t.value}},f=(e,t)=>{if(!t||!t.maxAge&&!e[c])return!1;var r=Date.now()-t.now;return t.maxAge?r>t.maxAge:e[c]&&r>e[c]},g=t=>{if(t[i]>t[o])for(let e=t[h].tail;t[i]>t[o]&&null!==e;){var r=e.prev;v(t,e),e=r}},v=(e,t)=>{var r;t&&(r=t.value,e[u]&&e[u](r.key,r.value),e[i]-=r.length,e[d].delete(r.key),e[h].removeNode(t))},y=class{constructor(e,t,r,a,n){this.key=e,this.value=t,this.length=r,this.now=a,this.maxAge=n||0}},E=(e,t,r,a)=>{let n=r.value;f(e,n)&&(v(e,r),e[s]||(n=void 0)),n&&t.call(a,n.value,n.key,e)};t.exports=class{constructor(e){if((e=(e="number"==typeof e?{max:e}:e)||{}).max&&("number"!=typeof e.max||e.max<0))throw new TypeError("max must be a non-negative number");this[o]=e.max||1/0;var t=e.length||a;if(this[l]="function"!=typeof t?a:t,this[s]=e.stale||!1,e.maxAge&&"number"!=typeof e.maxAge)throw new TypeError("maxAge must be a number");this[c]=e.maxAge||0,this[u]=e.dispose,this[p]=e.noDisposeOnSet||!1,this[n]=e.updateAgeOnGet||!1,this.reset()}set max(e){if("number"!=typeof e||e<0)throw new TypeError("max must be a non-negative number");this[o]=e||1/0,g(this)}get max(){return this[o]}set allowStale(e){this[s]=!!e}get allowStale(){return this[s]}set maxAge(e){if("number"!=typeof e)throw new TypeError("maxAge must be a non-negative number");this[c]=e,g(this)}get maxAge(){return this[c]}set lengthCalculator(e){(e="function"!=typeof e?a:e)!==this[l]&&(this[l]=e,this[i]=0,this[h].forEach(e=>{e.length=this[l](e.value,e.key),this[i]+=e.length})),g(this)}get lengthCalculator(){return this[l]}get length(){return this[i]}get itemCount(){return this[h].length}rforEach(t,r){r=r||this;for(let e=this[h].tail;null!==e;){var a=e.prev;E(this,t,e,r),e=a}}forEach(t,r){r=r||this;for(let e=this[h].head;null!==e;){var a=e.next;E(this,t,e,r),e=a}}keys(){return this[h].toArray().map(e=>e.key)}values(){return this[h].toArray().map(e=>e.value)}reset(){this[u]&&this[h]&&this[h].length&&this[h].forEach(e=>this[u](e.key,e.value)),this[d]=new Map,this[h]=new r,this[i]=0}dump(){return this[h].map(e=>!f(this,e)&&{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[h]}set(e,t,r){if((r=r||this[c])&&"number"!=typeof r)throw new TypeError("maxAge must be a number");var a=r?Date.now():0,n=this[l](t,e);if(this[d].has(e)){if(n>this[o])return v(this,this[d].get(e)),!1;const s=this[d].get(e).value;return this[u]&&!this[p]&&this[u](e,s.value),s.now=a,s.maxAge=r,s.value=t,this[i]+=n-s.length,s.length=n,this.get(e),g(this),!0}n=new y(e,t,n,a,r);return n.length>this[o]?(this[u]&&this[u](e,t),!1):(this[i]+=n.length,this[h].unshift(n),this[d].set(e,this[h].head),g(this),!0)}has(e){if(!this[d].has(e))return!1;e=this[d].get(e).value;return!f(this,e)}get(e){return m(this,e,!0)}peek(e){return m(this,e,!1)}pop(){var e=this[h].tail;return e?(v(this,e),e.value):null}del(e){v(this,this[d].get(e))}load(t){this.reset();var r=Date.now();for(let e=t.length-1;0<=e;e--){var a=t[e],n=a.e||0;0===n?this.set(a.k,a.v):0<(n=n-r)&&this.set(a.k,a.v,n)}}prune(){this[d].forEach((e,t)=>m(this,t,!1))}}}}),k=e({"../../node_modules/semver/classes/range.js"(e,t){var a=class{constructor(e,t){if(t=n(t),e instanceof a)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new a(e.raw,t);if(e instanceof l)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split("||").map(e=>this.parseRange(e.trim())).filter(e=>e.length),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);if(1!f(e[0])),0===this.set.length)this.set=[t];else if(1e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();var t=`parseRange:${Object.keys(this.options).join(",")}:`+e,r=i.get(t);if(r)return r;var r=this.options.loose,a=r?h[d.HYPHENRANGELOOSE]:h[d.HYPHENRANGE];e=e.replace(a,N(this.options.includePrerelease)),p("hyphen replace",e),e=e.replace(h[d.COMPARATORTRIM],c),p("comparator trim",e);let n=(e=(e=(e=e.replace(h[d.TILDETRIM],u)).replace(h[d.CARETTRIM],m)).split(/\s+/).join(" ")).split(" ").map(e=>g(e,this.options)).join(" ").split(/\s+/).map(e=>C(e,this.options));r&&(n=n.filter(e=>(p("loose invalid filter",e,this.options),!!e.match(h[d.COMPARATORLOOSE])))),p("range list",n);const s=new Map;for(const o of n.map(e=>new l(e,this.options))){if(f(o))return[o];s.set(o.value,o)}1o(t,r)&&e.set.some(e=>o(e,r)&&t.every(t=>e.every(e=>t.intersects(e,r)))));throw new TypeError("a Range is required")}test(t){if(!t)return!1;if("string"==typeof t)try{t=new r(t,this.options)}catch(e){return!1}for(let e=0;e"<0.0.0-0"===e.value,s=e=>""===e.value,o=(e,t)=>{let r=!0;const a=e.slice();let n=a.pop();for(;r&&a.length;)r=a.every(e=>n.intersects(e,t)),n=a.pop();return r},g=(e,t)=>(p("comp",e,t),e=b(e,t),p("caret",e),e=y(e,t),p("tildes",e),e=w(e,t),p("xrange",e),e=O(e,t),p("stars",e),e),v=e=>!e||"x"===e.toLowerCase()||"*"===e,y=(e,t)=>e.trim().split(/\s+/).map(e=>E(e,t)).join(" "),E=(o,e)=>{e=e.loose?h[d.TILDELOOSE]:h[d.TILDE];return o.replace(e,(e,t,r,a,n)=>{p("tilde",o,e,t,r,a,n);let s;return s=v(t)?"":v(r)?`>=${t}.0.0 <${+t+1}.0.0-0`:v(a)?`>=${t}.${r}.0 <${t}.${+r+1}.0-0`:n?(p("replaceTilde pr",n),`>=${t}.${r}.${a}-${n} <${t}.${+r+1}.0-0`):`>=${t}.${r}.${a} <${t}.${+r+1}.0-0`,p("tilde return",s),s})},b=(e,t)=>e.trim().split(/\s+/).map(e=>S(e,t)).join(" "),S=(o,e)=>{p("caret",o,e);var t=e.loose?h[d.CARETLOOSE]:h[d.CARET];const i=e.includePrerelease?"-0":"";return o.replace(t,(e,t,r,a,n)=>{p("caret",o,e,t,r,a,n);let s;return s=v(t)?"":v(r)?`>=${t}.0.0${i} <${+t+1}.0.0-0`:v(a)?"0"===t?`>=${t}.${r}.0${i} <${t}.${+r+1}.0-0`:`>=${t}.${r}.0${i} <${+t+1}.0.0-0`:n?(p("replaceCaret pr",n),"0"===t?"0"===r?`>=${t}.${r}.${a}-${n} <${t}.${r}.${+a+1}-0`:`>=${t}.${r}.${a}-${n} <${t}.${+r+1}.0-0`:`>=${t}.${r}.${a}-${n} <${+t+1}.0.0-0`):(p("no pr"),"0"===t?"0"===r?`>=${t}.${r}.${a}${i} <${t}.${r}.${+a+1}-0`:`>=${t}.${r}.${a}${i} <${t}.${+r+1}.0-0`:`>=${t}.${r}.${a} <${+t+1}.0.0-0`),p("caret return",s),s})},w=(e,t)=>(p("replaceXRanges",e,t),e.split(/\s+/).map(e=>k(e,t)).join(" ")),k=(c,u)=>{c=c.trim();var e=u.loose?h[d.XRANGELOOSE]:h[d.XRANGE];return c.replace(e,(e,t,r,a,n,s)=>{p("xRange",c,e,t,r,a,n,s);var o=v(r),i=o||v(a),l=i||v(n);return"="===t&&l&&(t=""),s=u.includePrerelease?"-0":"",o?e=">"===t||"<"===t?"<0.0.0-0":"*":t&&l?(i&&(a=0),n=0,">"===t?(t=">=",n=i?(r=+r+1,a=0):(a=+a+1,0)):"<="===t&&(t="<",i?r=+r+1:a=+a+1),e=t+r+`.${a}.`+n+(s="<"===t?"-0":s)):i?e=`>=${r}.0.0${s} <${+r+1}.0.0-0`:l&&(e=`>=${r}.${a}.0${s} <${r}.${+a+1}.0-0`),p("xRange return",e),e})},O=(e,t)=>(p("replaceStars",e,t),e.trim().replace(h[d.STAR],"")),C=(e,t)=>(p("replaceGTE0",e,t),e.trim().replace(h[t.includePrerelease?d.GTE0PRE:d.GTE0],"")),N=d=>(e,t,r,a,n,s,o,i,l,c,u,p,h)=>((t=v(r)?"":v(a)?`>=${r}.0.0`+(d?"-0":""):v(n)?`>=${r}.${a}.0`+(d?"-0":""):s?">="+t:">="+t+(d?"-0":""))+" "+(i=v(l)?"":v(c)?`<${+l+1}.0.0-0`:v(u)?`<${l}.${+c+1}.0-0`:p?`<=${l}.${c}.${u}-`+p:d?`<${l}.${c}.${+u+1}-0`:"<="+i)).trim(),I=(t,r,e)=>{for(let e=0;e="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),a=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),n=this.semver.version===e.semver.version,s=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),o=l(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),t=l(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return r||a||n&&s||o||t}},a=(t.exports=i,X()),{re:n,t:s}=x(),l=ge(),o=J(),c=_(),u=k()}}),we=e({"../../node_modules/semver/functions/satisfies.js"(e,t){var a=k();t.exports=(e,t,r)=>{try{t=new a(t,r)}catch(e){return!1}return t.test(e)}}}),ke=e({"../../node_modules/semver/ranges/to-comparators.js"(e,t){var r=k();t.exports=(e,t)=>new r(e,t).set.map(e=>e.map(e=>e.value).join(" ").trim().split(" "))}}),Oe=e({"../../node_modules/semver/ranges/max-satisfying.js"(e,t){var o=_(),i=k();t.exports=(e,t,r)=>{let a=null,n=null,s=null;try{s=new i(t,r)}catch(e){return null}return e.forEach(e=>{!s.test(e)||a&&-1!==n.compare(e)||(a=e,n=new o(a,r))}),a}}}),Ce=e({"../../node_modules/semver/ranges/min-satisfying.js"(e,t){var o=_(),i=k();t.exports=(e,t,r)=>{let a=null,n=null,s=null;try{s=new i(t,r)}catch(e){return null}return e.forEach(e=>{!s.test(e)||a&&1!==n.compare(e)||(a=e,n=new o(a,r))}),a}}}),Ne=e({"../../node_modules/semver/ranges/min-version.js"(e,t){var s=_(),r=k(),o=u();t.exports=(t,e)=>{t=new r(t,e);let a=new s("0.0.0");if(t.test(a))return a;if(a=new s("0.0.0-0"),t.test(a))return a;a=null;for(let e=0;e{const t=new s(e.semver.version);switch(e.operator){case">":0===t.prerelease.length?t.patch++:t.prerelease.push(0),t.raw=t.format();case"":case">=":r&&!o(t,r)||(r=t);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+e.operator)}}),!r||a&&!o(a,r)||(a=r)}return a&&t.test(a)?a:null}}}),Ie=e({"../../node_modules/semver/ranges/valid.js"(e,t){var r=k();t.exports=(e,t)=>{try{return new r(e,t).range||"*"}catch(e){return null}}}}),xe=e({"../../node_modules/semver/ranges/outside.js"(e,t){var r=_(),h=Se(),d=h["ANY"],m=k(),f=we(),g=u(),v=he(),y=fe(),E=me();t.exports=(a,n,e,s)=>{a=new r(a,s),n=new m(n,s);let o,i,l,c,u;switch(e){case">":o=g,i=y,l=v,c=">",u=">=";break;case"<":o=v,i=E,l=g,c="<",u="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(f(a,n,s))return!1;for(let e=0;e{e.semver===d&&(e=new h(">=0.0.0")),t=t||e,r=r||e,o(e.semver,t.semver,s)?t=e:l(e.semver,r.semver,s)&&(r=e)}),t.operator===c||t.operator===u)return!1;if((!r.operator||r.operator===c)&&i(a,r.semver))return!1;if(r.operator===u&&l(a,r.semver))return!1}return!0}}}),_e=e({"../../node_modules/semver/ranges/gtr.js"(e,t){var a=xe();t.exports=(e,t,r)=>a(e,t,">",r)}}),Le=e({"../../node_modules/semver/ranges/ltr.js"(e,t){var a=xe();t.exports=(e,t,r)=>a(e,t,"<",r)}}),Re=e({"../../node_modules/semver/ranges/intersects.js"(e,t){var a=k();t.exports=(e,t,r)=>(e=new a(e,r),t=new a(t,r),e.intersects(t))}}),Te=e({"../../node_modules/semver/ranges/simplify.js"(e,t){var d=we(),m=n();t.exports=(e,t,r)=>{const a=[];let n=null,s=null;var o,i,l=e.sort((e,t)=>m(e,t,r));for(const h of l){var c=d(h,t,r);n=c?(s=h,n||h):(s&&a.push([n,s]),s=null)}n&&a.push([n,null]);const u=[];for([o,i]of a)o===i?u.push(o):i||o!==l[0]?i?o===l[0]?u.push("<="+i):u.push(o+" - "+i):u.push(">="+o):u.push("*");var e=u.join(" || "),p="string"==typeof t.raw?t.raw:String(t);return e.length{if(!e)return t;r=b(e.semver,t.semver,r);return!(0"===t.operator&&">="===e.operator)?t:e},w=(e,t,r)=>{if(!e)return t;r=b(e.semver,t.semver,r);return!(r<0)&&(0{if(e===t)return!0;e=new i(e,r),t=new i(t,r);let a=!1;e:for(const s of e.set){for(const o of t.set){var n=((e,t,r)=>{if(e===t)return true;if(e.length===1&&e[0].semver===y)if(t.length===1&&t[0].semver===y)return true;else if(r.includePrerelease)e=[new v(">=0.0.0-0")];else e=[new v(">=0.0.0")];if(t.length===1&&t[0].semver===y)if(r.includePrerelease)return true;else t=[new v(">=0.0.0")];const a=new Set;let n,s;for(const d of e)if(d.operator===">"||d.operator===">=")n=S(n,d,r);else if(d.operator==="<"||d.operator==="<=")s=w(s,d,r);else a.add(d.semver);if(a.size>1)return null;let o;if(n&&s){o=b(n.semver,s.semver,r);if(o>0)return null;else if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(const m of a){if(n&&!E(m,String(n),r))return null;if(s&&!E(m,String(s),r))return null;for(const f of t)if(!E(m,String(f),r))return false;return true}let i,l,c,u,p=s&&!r.includePrerelease&&s.semver.prerelease.length?s.semver:false,h=n&&!r.includePrerelease&&n.semver.prerelease.length?n.semver:false;if(p&&p.prerelease.length===1&&s.operator==="<"&&p.prerelease[0]===0)p=false;for(const g of t){u=u||g.operator===">"||g.operator===">=";c=c||g.operator==="<"||g.operator==="<=";if(n){if(h)if(g.semver.prerelease&&g.semver.prerelease.length&&g.semver.major===h.major&&g.semver.minor===h.minor&&g.semver.patch===h.patch)h=false;if(g.operator===">"||g.operator===">="){i=S(n,g,r);if(i===g&&i!==n)return false}else if(n.operator===">="&&!E(n.semver,String(g),r))return false}if(s){if(p)if(g.semver.prerelease&&g.semver.prerelease.length&&g.semver.major===p.major&&g.semver.minor===p.minor&&g.semver.patch===p.patch)p=false;if(g.operator==="<"||g.operator==="<="){l=w(s,g,r);if(l===g&&l!==s)return false}else if(s.operator==="<="&&!E(s.semver,String(g),r))return false}if(!g.operator&&(s||n)&&o!==0)return false}if(n&&c&&!s&&o!==0)return false;if(s&&u&&!n&&o!==0)return false;if(h||p)return false;return true})(s,o,r);if(a=a||null!==n,n)continue e}if(a)return!1}return!0}}}),r=e({"../../node_modules/semver/index.js"(e,t){var r=x();t.exports={re:r.re,src:r.src,tokens:r.t,SEMVER_SPEC_VERSION:p().SEMVER_SPEC_VERSION,SemVer:_(),compareIdentifiers:Y().compareIdentifiers,rcompareIdentifiers:Y().rcompareIdentifiers,parse:a(),valid:Q(),clean:Z(),inc:ee(),diff:re(),major:ae(),minor:ne(),patch:se(),prerelease:oe(),compare:n(),rcompare:ie(),compareLoose:le(),compareBuild:ce(),sort:ue(),rsort:pe(),gt:u(),lt:he(),eq:te(),neq:de(),gte:me(),lte:fe(),cmp:ge(),coerce:ve(),Comparator:Se(),Range:k(),satisfies:we(),toComparators:ke(),maxSatisfying:Oe(),minSatisfying:Ce(),minVersion:Ne(),validRange:Ie(),outside:xe(),gtr:_e(),ltr:Le(),intersects:Re(),simplifyRange:Te(),subset:Ae()}}}),$e=e({"../../node_modules/react-simple-code-editor/lib/index.js"(e){"use strict";var a,t,r=e&&e.__extends||(a=function(e,t){return(a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}),w=e&&e.__assign||function(){return(w=Object.assign||function(e){for(var t,r=1,a=arguments.length;r"}}:{children:s})),O.createElement("style",{type:"text/css",dangerouslySetInnerHTML:{__html:N}}))},i.defaultProps={tabSize:2,insertSpaces:!0,ignoreTabKey:!1,padding:0},i);function i(){var f=null!==t&&t.apply(this,arguments)||this;return f.state={capture:!0},f._recordCurrentState=function(){var e,t,r=f._input;r&&(e=r.value,t=r.selectionStart,r=r.selectionEnd,f._recordChange({value:e,selectionStart:t,selectionEnd:r}))},f._getLines=function(e,t){return e.substring(0,t).split("\n")},f._recordChange=function(e,t){void 0===t&&(t=!1);var r=f._history,a=r.stack,r=r.offset,r=(a.length&&-1=o.reach);y+=v.value.length,v=v.next){var E=v.value;if(r.length>t.length)return;if(!(E instanceof R)){var b,S=1;if(m){if(!(b=T(g,y,t,d))||b.index>=t.length)break;var w=b.index,k=b.index+b[0].length,O=y;for(O+=v.value.length;O<=w;)v=v.next,O+=v.value.length;if(O-=v.value.length,y=O,v.value instanceof R)continue;for(var C=v;C!==r.tail&&(Oo.reach&&(o.reach=E),v.prev),I=(I&&(_=A(r,_,I),y+=I.length),$(r,_,S),new R(i,h?L.tokenize(N,h):N,f,N));v=A(r,_,I),x&&A(r,v,x),1o.reach&&(o.reach=N.reach))}}}}}(e,n,t,n.head,0),n),o=[],i=s.head.next;i!==s.tail;)o.push(i.value),i=i.next;return o},hooks:{all:{},add:function(e,t){var r=L.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=L.hooks.all[e];if(r&&r.length)for(var a,n=0;a=r[n++];)a(t)}},Token:R};function R(e,t,r,a){this.type=e,this.content=t,this.alias=r,this.length=0|(a||"").length}function T(e,t,r,a){e.lastIndex=t;t=e.exec(r);return t&&a&&t[1]&&(e=t[1].length,t.index+=e,t[0]=t[0].slice(e)),t}function c(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function A(e,t,r){var a=t.next,r={value:r,prev:t,next:a};return t.next=r,a.prev=r,e.length++,r}function $(e,t,r){for(var a=t.next,n=0;n"+s.content+""},!l.document)return l.addEventListener&&(L.disableWorkerMessageHandler||l.addEventListener("message",function(e){var e=JSON.parse(e.data),t=e.language,r=e.code,e=e.immediateClose;l.postMessage(L.highlight(r,L.languages[t],t)),e&&l.close()},!1)),L;var a,e=L.util.currentScript();function n(){L.manual||L.highlightAll()}return e&&(L.filename=e.src,e.hasAttribute("data-manual")&&(L.manual=!0)),L.manual||("loading"===(a=document.readyState)||"interactive"===a&&e&&e.defer?document.addEventListener("DOMContentLoaded",n):window.requestAnimationFrame?window.requestAnimationFrame(n):window.setTimeout(n,16)),L}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});void 0!==t&&t.exports&&(t.exports=r),"undefined"!=typeof global&&(global.Prism=r)}}),je=e({"../../node_modules/classnames/index.js"(e,t){!function(){"use strict";var o={}.hasOwnProperty;function i(){for(var e=[],t=0;tfunction(){return wr.default.createElement(Sr,null)}};for(j in ze)s(He,j,{get:ze[j],enumerable:!0});var We=t(y("react")),o=t(y("react")),Je=t(r()),E=(t,e)=>{t=localStorage.getItem(t);if(!t)return e;try{return JSON.parse(t)}catch(e){return t}},Xe=e=>{const a={section:/^\s*\[\s*([^\]]*)\s*\]\s*$/,param:/^\s*([^=]+?)\s*=\s*(.*?)\s*$/,comment:/^\s*;.*$/},n={},t=e.split(/[\r\n]+/);let s=null;return t.forEach(function(e){if(!a.comment.test(e))if(a.param.test(e)){const r=e.match(a.param);s?n[s][null==r?void 0:r[1]]=null==r?void 0:r[2].split(";")[0].trim():r&&(n[r[1]]=r[2].split(";")[0].trim())}else{var t;a.section.test(e)?(t=e.match(a.section))&&(n[t[1]]={},s=t[1]):0==e.length&&s&&(s=null)}}),n},Ye=e=>{const t=document.querySelector("style.marketplaceSnippets"),r=(t&&t.remove(),document.createElement("style"));e=e.reduce((e,t)=>e=(e+=`/* ${t.title} - ${t.description} */ +`)+t.code+` +`,"");r.innerHTML=e,r.classList.add("marketplaceSnippets"),document.head.appendChild(r)},Qe=(e,t)=>{let r=[];return e&&0({name:e.name,url:e.url.startsWith("javascript:")?"":e.url})):r.push({name:t,url:"https://github.com/"+t}),r},Ze=e=>e?Object.keys(e).map(e=>({key:e,value:e})):[],et=()=>{console.log("Resetting Marketplace"),Object.keys(localStorage).forEach(e=>{e.startsWith("marketplace:")&&(localStorage.removeItem(e),console.log("Removed "+e))}),console.log("Marketplace has been reset"),location.reload()},tt=r=>{const e=document.querySelector("link[href='colors.css']"),t=(e&&e.remove(),document.querySelector("style.marketplaceCSS.marketplaceScheme"));if(t&&t.remove(),r){const a=document.createElement("style");a.classList.add("marketplaceCSS"),a.classList.add("marketplaceScheme");let t=":root {";const n=Object.keys(r);n.forEach(e=>{t=(t+=`--spice-${e}: #${r[e]};`)+`--spice-rgb-${e}: ${(e=>{if(3===e.length)e=e.split("").map(e=>e+e).join("");else{if(6!=e.length)throw"Only 3- or 6-digit hex colours are allowed.";if(e.match(/[^0-9a-f]/i))throw"Only hex colours are allowed."}e=e.match(/.{1,2}/g);if(e&&3===e.length)return[parseInt(e[0],16),parseInt(e[1],16),parseInt(e[2],16)];throw"Could not parse hex colour."})(r[e])};`}),t+="}",a.innerHTML=t,document.head.appendChild(a)}else{const s=document.createElement("link");s.setAttribute("rel","stylesheet"),s.setAttribute("href","colors.css"),s.classList.add("userCSS"),document.head.appendChild(s)}},rt=e=>{try{const t=document.querySelector("link[href='user.css']"),r=(t&&t.remove(),document.querySelector("style.marketplaceCSS.marketplaceUserCSS"));if(r&&r.remove(),e){const a=document.createElement("style");a.classList.add("marketplaceCSS"),a.classList.add("marketplaceUserCSS"),a.innerHTML=e,document.head.appendChild(a)}else{const n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href","user.css"),n.classList.add("userCSS"),document.head.appendChild(n)}}catch(e){console.warn(e)}},at=async e=>{if(!e.cssURL)throw new Error("No CSS URL provided");const t=-1.+?)['|"]\\)`,"gm"))||[]){const o=null==(r=null==s?void 0:s.groups)?void 0:r.path;!o||o.startsWith("http")||o.startsWith("data")||(r=a+o.replace(/\.\//g,""),n=n.replace(o,r))}return n};async function nt(e,t,r){try{var a={text:e,context:t+"/"+r,mode:"gfm"};const n=await fetch("https://api.github.com/markdown",{method:"POST",body:JSON.stringify(a)});if(n.ok)return await n.text();throw Spicetify.showNotification(`Error parsing markdown (HTTP ${n.status})`)}catch(e){return null}}var st="0.7.0",f="marketplace:installed-extensions",g="marketplace:installed-snippets",b="marketplace:installed-themes",ot="marketplace:active-tab",it="marketplace:tabs",lt="marketplace:sort-by",S="marketplace:theme-installed",ct=[{name:"Extensions",enabled:!0},{name:"Themes",enabled:!0},{name:"Snippets",enabled:!0},{name:"Apps",enabled:!0},{name:"Installed",enabled:!0}],v=100,ut="/marketplace",pt="https://api.github.com/repos/spicetify/spicetify-marketplace/releases/tags/v0.7.0",l=t(y("react")),d=t(y("react")),ht=t($e()),dt=t(Pe()),mt=(r=Prism,$=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/,r.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+$.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+$.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+$.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:$,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},r.languages.css.atrule.inside.rest=r.languages.css,($=r.languages.markup)&&($.tag.addInlined("style","css"),$.tag.addAttribute("style","css")),t(y("react"))),ft="button-module__button___hf2qg_marketplace",gt="button-module__circle___EZ88P_marketplace",m=e=>{var t=e.type||"round";const r=[ft];return"circle"===t&&r.push(gt),e.classes&&r.push(...e.classes),mt.default.createElement("button",{className:r.join(" "),onClick:e.onClick,"aria-label":e.label,disabled:e.disabled},e.children)},vt=o=>{var e,t="marketplace-customCSS-preview";const[i,r]=d.default.useState("ADD_SNIPPET"!==o.type&&(null==(e=o.content)?void 0:e.item.code)||""),[a,n]=d.default.useState("ADD_SNIPPET"!==o.type&&(null==(e=o.content)?void 0:e.item.title)||""),[l,s]=d.default.useState("ADD_SNIPPET"!==o.type&&(null==(e=o.content)?void 0:e.item.description)||""),[c,u]=d.default.useState("ADD_SNIPPET"!==o.type&&(null==(e=o.content)?void 0:e.item.imageURL)||""),p=()=>a.replace(/\n/g,"").replaceAll(" ","-");let h;return d.default.createElement("div",{id:"marketplace-add-snippet-container"},d.default.createElement("div",{className:"marketplace-customCSS-input-container"},d.default.createElement("label",{htmlFor:"marketplace-custom-css"},"Custom CSS"),d.default.createElement("div",{className:"marketplace-code-editor-wrapper marketplace-code-editor"},d.default.createElement(ht.default,{value:i,onValueChange:e=>r(e),highlight:e=>(0,dt.highlight)(e,dt.languages.css),textareaId:"marketplace-custom-css",textareaClassName:"snippet-code-editor",readOnly:"VIEW_SNIPPET"===o.type,placeholder:"Input your own custom CSS here! You can find them in the installed tab for management.",style:{}}))),d.default.createElement("div",{className:"marketplace-customCSS-input-container"},d.default.createElement("label",{htmlFor:"marketplace-customCSS-name-submit"},"Snippet Name"),d.default.createElement("input",{id:"marketplace-customCSS-name-submit",className:"marketplace-code-editor",value:a,onChange:e=>{"VIEW_SNIPPET"!==o.type&&n(e.target.value)},placeholder:"Enter a name for your custom snippet."})),d.default.createElement("div",{className:"marketplace-customCSS-input-container"},d.default.createElement("label",{htmlFor:"marketplace-customCSS-description-submit"},"Snippet Description"),d.default.createElement("input",{id:"marketplace-customCSS-description-submit",className:"marketplace-code-editor",value:l,onChange:e=>{"VIEW_SNIPPET"!==o.type&&s(e.target.value)},placeholder:"Enter a description for your custom snippet."})),d.default.createElement("div",{className:"marketplace-customCSS-input-container"},d.default.createElement("label",{htmlFor:t},"Snippet Preview ","VIEW_SNIPPET"!==o.type&&"(optional)"),c&&d.default.createElement("label",{htmlFor:t,style:{textAlign:"center"}},d.default.createElement("img",{className:"marketplace-customCSS-image-preview",src:c,alt:"Preview"}))),"VIEW_SNIPPET"!==o.type&&d.default.createElement(d.default.Fragment,null,d.default.createElement(m,{onClick:()=>{h.click()}},c.length?"Change image":"Add image",d.default.createElement("input",{id:t,type:"file",style:{display:"none"},ref:e=>h=e,onChange:async e=>{var t,r,a;if(null!=(t=e.target.files)&&t[0])try{a=null==(r=e.target.files)?void 0:r[0];var n=await new Promise((e,t)=>{const r=new FileReader;r.readAsDataURL(a),r.onload=()=>{e(r.result)},r.onerror=e=>{t(e)}});n&&(console.log(n),u(n))}catch(e){console.error(e)}}})),d.default.createElement(m,{onClick:()=>{var e=p(),t=l.trim(),r="marketplace:installed:snippet:"+e;if(E(r)&&"EDIT_SNIPPET"!==o.type)Spicetify.showNotification("That name is already taken!");else{if(console.log("Installing snippet: "+e),o.content&&o.content.item.title!==e){console.log("Deleting outdated snippet: "+o.content.item.title),localStorage.removeItem("marketplace:installed:snippet:"+o.content.item.title);const s=E(g,[]);var a=s.filter(e=>{return e!=="marketplace:installed:snippet:"+(null==(e=o.content)?void 0:e.item.title)});localStorage.setItem(g,JSON.stringify(a))}localStorage.setItem(r,JSON.stringify({title:e,code:i,description:t,imageURL:c,custom:!0}));const n=E(g,[]);-1===n.indexOf(r)&&(n.push(r),console.log(n),localStorage.setItem(g,JSON.stringify(n)));a=n.map(e=>E(e));Ye(a),Spicetify.PopupModal.hide(),"EDIT_SNIPPET"===o.type&&location.reload()}},disabled:!p()||!i.replace(/\n/g,"\\n")},"Save CSS")))},c=t(y("react")),yt=()=>c.default.createElement("div",{id:"marketplace-reload-container"},c.default.createElement("p",null,"A page reload is required to complete this operation."),c.default.createElement("div",{className:"marketplace-reload-modal__button-container"},c.default.createElement(m,{onClick:()=>{Spicetify.PopupModal.hide(),location.reload()}},"Reload now"),c.default.createElement(m,{onClick:()=>{Spicetify.PopupModal.hide()}},"Reload later"))),h=t(y("react")),Et=t(y("react")),bt=t(y("react")),St="toggle-module__toggle-wrapper___ocE5z_marketplace",wt="toggle-module__disabled___OYAYf_marketplace",kt="toggle-module__toggle-input___ceLM4_marketplace",Ot="toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace",Ct="toggle-module__toggle-indicator___nCxwE_marketplace",Nt=e=>{var t="toggle:"+e.storageKey;const r=[St];return!1===e.clickable&&r.push(wt),bt.default.createElement("label",{className:r.join(" ")},bt.default.createElement("input",{className:kt,type:"checkbox",checked:e.enabled,"data-storage-key":e.storageKey,id:t,title:"Toggle for "+e.storageKey,onChange:e.onChange}),bt.default.createElement("span",{className:Ot},bt.default.createElement("span",{className:Ct})))},w=r=>{var e="toggle:"+r.storageKey,t=!!r.modalConfig.visual[r.storageKey];return Et.default.createElement("div",{className:"setting-row"},Et.default.createElement("label",{htmlFor:e,className:"col description"},r.name),Et.default.createElement("div",{className:"col action"},Et.default.createElement(Nt,{name:r.name,storageKey:r.storageKey,enabled:t,onChange:e=>{var t=e.target.checked,e=e.target.dataset.storageKey;r.modalConfig.visual[e]=t,console.log(`toggling ${e} to `+t),localStorage.setItem("marketplace:"+e,String(t)),r.updateConfig(r.modalConfig)}})))},O=t(y("react")),It=a=>{var e="toggle:"+a.name;const t=a.modalConfig.tabs.reduce((e,t,r)=>t.name===a.name?r:e,-1);var r=a.modalConfig.tabs[t]["enabled"];function n(e,t){console.log({currPos:e,dir:t});var t=e+t,r=a.modalConfig.tabs[t];a.modalConfig.tabs[t]=a.modalConfig.tabs[e],a.modalConfig.tabs[e]=r,localStorage.setItem(it,JSON.stringify(a.modalConfig.tabs)),a.updateConfig(a.modalConfig)}return O.default.createElement("div",{className:"setting-row"},O.default.createElement("label",{htmlFor:e,className:"col description"},a.name),O.default.createElement("div",{className:"col action"},O.default.createElement("button",{title:"Move up",className:"arrow-btn",disabled:0===t,onClick:()=>n(t,-1)},O.default.createElement("svg",{height:"16",width:"16",viewBox:"0 0 16 16",fill:"currentColor",dangerouslySetInnerHTML:{__html:String(Spicetify.SVGIcons["chart-up"])}})),O.default.createElement("button",{title:"Move down",className:"arrow-btn",disabled:t===a.modalConfig.tabs.length-1,onClick:()=>n(t,1)},O.default.createElement("svg",{height:"16",width:"16",viewBox:"0 0 16 16",fill:"currentColor",dangerouslySetInnerHTML:{__html:String(Spicetify.SVGIcons["chart-down"])}})),O.default.createElement(Nt,{name:a.name,storageKey:"tab:"+a.name,clickable:"Extensions"!==a.name,enabled:r,onChange:e=>{console.log({e:e}),a.modalConfig.tabs[t].enabled=e.target.checked,localStorage.setItem(it,JSON.stringify(a.modalConfig.tabs)),a.updateConfig(a.modalConfig)}})))},xt=({CONFIG:e,updateAppConfig:t})=>{const[r,a]=h.default.useState(i({},e)),n=e=>{t(i({},e)),a(i({},e))},s=document.querySelector("body > generic-modal button.main-trackCreditsModal-closeBtn"),o=document.querySelector("body > generic-modal > div");return s&&o&&(s.onclick=()=>location.reload(),s.setAttribute("style","cursor: pointer;"),o.onclick=e=>{e.target===o&&location.reload()}),h.default.createElement("div",{id:"marketplace-config-container"},h.default.createElement("h2",null,"Options"),h.default.createElement(w,{name:"Stars count",storageKey:"stars",modalConfig:r,updateConfig:n}),h.default.createElement(w,{name:"Tags",storageKey:"tags",modalConfig:r,updateConfig:n}),h.default.createElement(w,{name:"Theme developer tools",storageKey:"themeDevTools",modalConfig:r,updateConfig:n}),h.default.createElement(w,{name:"Hide installed when browsing",storageKey:"hideInstalled",modalConfig:r,updateConfig:n}),h.default.createElement(w,{name:"Shift colors every minute",storageKey:"colorShift",modalConfig:r,updateConfig:n}),h.default.createElement("h2",null,"Tabs"),h.default.createElement("div",{className:"tabs-container"},r.tabs.map(({name:e},t)=>h.default.createElement(It,{key:t,name:e,modalConfig:r,updateConfig:n}))),h.default.createElement("h2",null,"Reset"),h.default.createElement("div",{className:"setting-row"},h.default.createElement("label",{className:"col description"},"Uninstall all extensions and themes, and reset preferences"),h.default.createElement("div",{className:"col action"},h.default.createElement(m,{onClick:et},"Reset"))))},C=t(y("react")),_t=t($e()),Lt=t(Pe()),Rt=(Prism.languages.ini={comment:{pattern:/(^[ \f\t\v]*)[#;][^\n\r]*/m,lookbehind:!0},section:{pattern:/(^[ \f\t\v]*)\[[^\n\r\]]*\]?/m,lookbehind:!0,inside:{"section-name":{pattern:/(^\[[ \f\t\v]*)[^ \f\t\v\]]+(?:[ \f\t\v]+[^ \f\t\v\]]+)*/,lookbehind:!0,alias:"selector"},punctuation:/\[|\]/}},key:{pattern:/(^[ \f\t\v]*)[^ \f\n\r\t\v=]+(?:[ \f\t\v]+[^ \f\n\r\t\v=]+)*(?=[ \f\t\v]*=)/m,lookbehind:!0,alias:"attr-name"},value:{pattern:/(=[ \f\t\v]*)[^ \f\n\r\t\v]+(?:[ \f\t\v]+[^ \f\n\r\t\v]+)*/,lookbehind:!0,alias:"attr-value",inside:{"inner-value":{pattern:/^("|').+(?=\1$)/,lookbehind:!0}}},punctuation:/=/},localStorage.getItem(S)),N=Rt?E(Rt):null,Tt=()=>{const[r,t]=C.default.useState(N?(e=>{let t="";for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r))if("object"==typeof e[r]){t+=`[${r}] +`;for(const a in e[r])Object.prototype.hasOwnProperty.call(e[r],a)&&(t+=`${a}=${e[r][a]} +`)}else t+=`${r}=${e[r]} +`;return t})(N.schemes):"Error: No marketplace theme installed");return C.default.createElement("div",{id:"marketplace-theme-dev-tools-container",className:"marketplace-theme-dev-tools-container"},C.default.createElement("div",{className:"devtools-column"},C.default.createElement("label",{htmlFor:"color-ini-editor"},C.default.createElement("h2",{className:"devtools-heading"},"Color.ini Editor")),C.default.createElement("div",{className:"marketplace-code-editor-wrapper marketplace-code-editor"},C.default.createElement(_t.default,{value:r,onValueChange:e=>t(e),highlight:e=>(0,Lt.highlight)(e,Lt.languages.ini),textareaId:"color-ini-editor",textareaClassName:"color-ini-editor",readOnly:!N,placeholder:"[your-color-scheme-name]",style:{fontFamily:"monospace",resize:"none"}})),C.default.createElement(m,{onClick:()=>{var e=r;{var t;Rt?(t=Xe(e),N.schemes=t,localStorage.setItem(Rt,JSON.stringify(N))):Spicetify.showNotification("Error: No theme manifest found")}}},"Save")),C.default.createElement("div",{className:"devtools-column"},C.default.createElement("h2",{className:"devtools-heading"},"Invalid CSS"),C.default.createElement("div",{className:"marketplace-code-editor-wrapper marketplace-code-editor"},function(){var e=document.querySelector("head > style.marketplaceCSS.marketplaceUserCSS");const t=null==e?void 0:e.innerHTML;if(e=new RegExp(".-?[_a-zA-Z]+[_a-zA-Z0-9-]*\\s*{","g"),!t)return["Error: Class name list not found; please create an issue"];const r=[];for(const n of t.matchAll(e)){const s=n[0].replace("{","").trim();var a=s.split(" ");let t;for(let e=0;eC.default.createElement("div",{key:t,className:"invalid-css-text"},e)))))},I=(e,t,r,a)=>{e=((e,t,r,a)=>{switch(e){case"ADD_SNIPPET":return{title:"Add Snippet",content:l.default.createElement(vt,{type:e}),isLarge:!0};case"EDIT_SNIPPET":return{title:"Edit Snippet",content:l.default.createElement(vt,{type:e,content:a}),isLarge:!0};case"VIEW_SNIPPET":return{title:"View Snippet",content:l.default.createElement(vt,{type:e,content:a}),isLarge:!0};case"RELOAD":return{title:"Reload",content:l.default.createElement(yt,null),isLarge:!1};case"SETTINGS":return{title:"Settings",content:l.default.createElement(xt,{CONFIG:t,updateAppConfig:r}),isLarge:!0};case"THEME_DEV_TOOLS":return{title:"Theme Dev Tools",content:l.default.createElement(Tt,null),isLarge:!0};default:return{title:"",content:l.default.createElement("div",null),isLarge:!1}}})(e,t,r,a),Spicetify.PopupModal.display(e)},At=[{title:"Fix 'Liked' Icon",description:"Fix the colours of the Liked icon in sidebar",code:".main-likedSongsButton-likedSongsIcon {\n color: var(--spice-sidebar);\n background: var(--spice-text);\n}",preview:"resources/assets/snippets/fix-liked-icon.png"},{title:"Hide Upgrade Button",description:"Makes the upgrade button hidden",code:".main-topBar-UpgradeButton {\n display: none !important;\n}",preview:"resources/assets/snippets/hide-upgrade-button.png"},{title:"Auto-hide Friends",description:"Collapse the friends activity sidebar on small screens",code:"[aria-label='Friend Activity'] {\n transition: width 0.3s;\n}\n@media screen and (max-width: 1200px) {\n [aria-label='Friend Activity'] {\n width: 0;\n }\n [aria-label='Friend Activity'] .LayoutResizer__resize-bar {\n display: none;\n }\n}",preview:"resources/assets/snippets/auto-hide-friends.png"},{title:"Smooth Reveal Playlist Gradient",description:"Reveals the playlist gradient header gradient with a fade in effect",code:".main-entityHeader-overlay,\n.main-actionBarBackground-background,\n.main-entityHeader-overlay,\n.main-entityHeader-backgroundColor {\n -webkit-transition: 3s;\n}",preview:"resources/assets/snippets/smooth-playlist-reveal-gradient.png"},{title:"Remove connect bar",description:"Remove connect bar that causes progress bar displacement when listening on different devices",code:".main-connectBar-connectBar {\n color: transparent !important;\n overflow: visible !important;\n --triangle-position: 147px !important;\n align-items: unset !important;\n height: 0px !important;\n position: absolute !important;\n left: 80% !important;\n display: flex !important;\n bottom: 2% !important;\n padding: unset !important;\n}",preview:"resources/assets/snippets/remove-connect-bar.png"},{title:"Fix playlist arrows",description:"Fixes the opened and closed orientation of the playlist folder arrows",code:".main-rootlist-expandArrow {\n -webkit-transform: rotate(-90deg) !important;\n transform: rotate(-90deg) !important;\n}\n.main-rootlist-expandArrow:hover {\n -webkit-transform: rotate(-90deg) !important;\n transform: rotate(-90deg) !important;\n}\n.qAAhQw9dXNB7DbPgDDxy {\n -webkit-transform: rotate(0deg) !important;\n transform: rotate(0deg) !important;\n}\n.qAAhQw9dXNB7DbPgDDxy:hover {\n -webkit-transform: rotate(0deg) !important;\n transform: rotate(0deg) !important;\n}",preview:"resources/assets/snippets/fix-playlist-arrows.png"},{title:"Fix main view width",description:"Makes main view fill up all available space",code:".contentSpacing {\n max-width: 100% !important;\n}",preview:"resources/assets/snippets/fix-main-view-width.png"},{title:"Left aligned heart icons",description:"Moves the heart icon to the left side of the track title in track views",code:".main-trackList-rowSectionStart {\n margin-left: 38px !important;\n}\n.main-addButton-button.main-trackList-rowHeartButton,\n.main-addButton-button.main-trackList-rowHeartButton {\n position: absolute !important;\n left: 48px !important;\n}",preview:"resources/assets/snippets/left-aligned-heart-icons.png"},{title:"Hover Panels",description:"Have your playlist, friend activity, and controls bar be hoverable.",code:".Root__nav-bar {\n position: absolute;\n width: 40px;\n opacity: 0;\n bottom: 0;\n left: 0;\n top: 0;\n z-index: 1;\n}\nnav.Root__nav-bar:hover {\n position: inherit;\n width: 225px;\n opacity: 1;\n transition: visibility 5s, opacity 0.5s linear;\n}\n.LayoutResizer__resize-bar {\n cursor: none;\n}\n.Root__top-bar {\n opacity: 0;\n transition: visibility 5s, opacity 1s linear;\n}\n.Root__top-bar:hover {\n transition-delay: 0.5s;\n opacity: 1;\n transition: visibility 5s, opacity 0.5s linear;\n}\n.main-topBar-container {\n -webkit-padding-end: 32px;\n padding: 16px 85px;\n padding-inline-end: 32px;\n max-width: none;\n}\naside.main-buddyFeed-buddyFeedRoot:hover {\n position: inherit;\n width: var(--buddy-feed-width);\n opacity: 1;\n transition: visibility 5s, opacity 0.5s linear;\n left: 0;\n}\naside.main-buddyFeed-buddyFeedRoot {\n position: absolute;\n width: 65px;\n opacity: 0;\n bottom: 0;\n left: -30px;\n top: 0;\n z-index: 1;\n}",preview:"resources/assets/snippets/hover-panels.png"},{title:"Fix progress bar displacement",description:"Fixes the progress bar displacement for a few themes. Better version of @CharlieS1103 Snippet",code:".main-connectBar-connectBar {\n overflow: visible !important;\n position: absolute !important;\n display: flex !important;\n align-items: unset !important;\n left: 80% !important;\n height: 20px !important;\n bottom: 1% !important;\n padding: 2px !important;\n background-color: transparent !important;\n color: var(--spice-text) !important;\n}\n.control-button::after {\n display: none !important;\n}",preview:"resources/assets/snippets/fix-progress-bar.png"}];async function $t(e,t=1,r=[],a){let n=a?`https://api.github.com/search/repositories?q=${encodeURIComponent(a+"+topic:"+e)}&per_page=100`:`https://api.github.com/search/repositories?q=${encodeURIComponent("topic:"+e)}&per_page=100`;t&&(n+="&page="+t);const s=await fetch(n).then(e=>e.json()).catch(()=>[]);{if(s.items)return z(i({},s),{page_count:s.items.length,items:s.items.filter(e=>!r.includes(e.html_url))});Spicetify.showNotification("Too Many Requests, Cool Down.")}}async function Pt(e,t,r){var a=window.sessionStorage.getItem(e+"-"+t);const n=window.sessionStorage.getItem("noManifests");if(a)return JSON.parse(a);const s=`https://raw.githubusercontent.com/${e}/${t}/${r}/manifest.json`;if(null!=n&&n.includes(s))return null;a=await fetch(s).then(e=>e.json()).catch(()=>{var a=[s],n="noManifests";a&&a.forEach(e=>{n=n||a.user+"-"+a.repo;var t=window.sessionStorage.getItem(n);const r=t?JSON.parse(t):[];r.push(e),window.sessionStorage.setItem(n,JSON.stringify(r))})});return a&&window.sessionStorage.setItem(e+"-"+t,JSON.stringify(a)),a}async function jt(t,a,n,s=!1){try{let e;var r=t.match(new RegExp("https:\\/\\/api\\.github\\.com\\/repos\\/(?.+)\\/(?.+)\\/contents"));if(!r||!r.groups)return null;const{user:o,repo:i}=r.groups;return e=await Pt(o,i,a),(e=Array.isArray(e)?e:[e]).reduce((e,t)=>{var r=t.branch||a,r={manifest:t,title:t.name,subtitle:t.description,authors:Qe(t.authors,o),user:o,repo:i,branch:r,imageURL:t.preview&&t.preview.startsWith("http")?t.preview:`https://raw.githubusercontent.com/${o}/${i}/${r}/`+t.preview,extensionURL:t.main.startsWith("http")?t.main:`https://raw.githubusercontent.com/${o}/${i}/${r}/`+t.main,readmeURL:t.readme&&t.readme.startsWith("http")?t.readme:`https://raw.githubusercontent.com/${o}/${i}/${r}/`+t.readme,stars:n,tags:t.tags};return t&&t.name&&t.description&&t.main&&(s&&localStorage.getItem(`marketplace:installed:${o}/${i}/`+t.main)||e.push(r)),e},[])}catch(e){return null}}async function Dt(t,a,n){try{let e;var r=t.match(new RegExp("https:\\/\\/api\\.github\\.com\\/repos\\/(?.+)\\/(?.+)\\/contents"));if(!r||!r.groups)return null;const{user:s,repo:o}=r.groups;return e=await Pt(s,o,a),(e=Array.isArray(e)?e:[e]).reduce((e,t)=>{var r=t.branch||a,r={manifest:t,title:t.name,subtitle:t.description,authors:Qe(t.authors,s),user:s,repo:o,branch:r,imageURL:t.preview&&t.preview.startsWith("http")?t.preview:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.preview,readmeURL:t.readme&&t.readme.startsWith("http")?t.readme:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.readme,stars:n,tags:t.tags,cssURL:t.usercss.startsWith("http")?t.usercss:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.usercss,schemesURL:t.schemes?t.schemes.startsWith("http")?t.schemes:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.schemes:null,include:t.include};return null!=t&&t.name&&null!=t&&t.usercss&&null!=t&&t.description&&e.push(r),e},[])}catch(e){return null}}async function Mt(t,a,n){try{let e;var r=t.match(new RegExp("https:\\/\\/api\\.github\\.com\\/repos\\/(?.+)\\/(?.+)\\/contents"));if(!r||!r.groups)return null;const{user:s,repo:o}=r.groups;return e=await Pt(s,o,a),(e=Array.isArray(e)?e:[e]).reduce((e,t)=>{var r=t.branch||a,r={manifest:t,title:t.name,subtitle:t.description,authors:Qe(t.authors,s),user:s,repo:o,branch:r,imageURL:t.preview&&t.preview.startsWith("http")?t.preview:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.preview,readmeURL:t.readme&&t.readme.startsWith("http")?t.readme:`https://raw.githubusercontent.com/${s}/${o}/${r}/`+t.readme,stars:n,tags:t.tags};return t&&t.name&&t.description&&e.push(r),e},[])}catch(e){return null}}var Ft=async()=>{return(await fetch("https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/blacklist.json").then(e=>e.json()).catch(()=>({}))).repos},Ut=async()=>{return At.reduce((e,t)=>{const r=i({},t);return r.preview&&(r.imageURL=r.preview.startsWith("http")?r.preview:"https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/"+r.preview,delete r.preview),e.push(r),e},[])},Gt=t(y("react")),qt=class extends Gt.default.Component{render(){return Gt.default.createElement("div",{onClick:this.props.onClick},Gt.default.createElement("p",{style:{fontSize:100,lineHeight:"65px"}},"»"),Gt.default.createElement("span",{style:{fontSize:20}},"Load more"))}},L=t(y("react")),Bt=()=>L.default.createElement("svg",{width:"100px",height:"100px",viewBox:"0 0 100 100",preserveAspectRatio:"xMidYMid"},L.default.createElement("circle",{cx:"50",cy:"50",r:"0",fill:"none",stroke:"currentColor",strokeWidth:"2"},L.default.createElement("animate",{attributeName:"r",repeatCount:"indefinite",dur:"1s",values:"0;40",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"0s"}),L.default.createElement("animate",{attributeName:"opacity",repeatCount:"indefinite",dur:"1s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"0s"})),L.default.createElement("circle",{cx:"50",cy:"50",r:"0",fill:"none",stroke:"currentColor",strokeWidth:"2"},L.default.createElement("animate",{attributeName:"r",repeatCount:"indefinite",dur:"1s",values:"0;40",keyTimes:"0;1",keySplines:"0 0.2 0.8 1",calcMode:"spline",begin:"-0.5s"}),L.default.createElement("animate",{attributeName:"opacity",repeatCount:"indefinite",dur:"1s",values:"1;0",keyTimes:"0;1",keySplines:"0.2 0 0.8 1",calcMode:"spline",begin:"-0.5s"}))),Kt=t(y("react")),Vt=()=>Kt.default.createElement("svg",{role:"img",width:"16",height:"16",viewBox:"0 0 24 24","aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg"},Kt.default.createElement("path",{d:"M24 13.616v-3.232c-1.651-.587-2.694-.752-3.219-2.019v-.001c-.527-1.271.1-2.134.847-3.707l-2.285-2.285c-1.561.742-2.433 1.375-3.707.847h-.001c-1.269-.526-1.435-1.576-2.019-3.219h-3.232c-.582 1.635-.749 2.692-2.019 3.219h-.001c-1.271.528-2.132-.098-3.707-.847l-2.285 2.285c.745 1.568 1.375 2.434.847 3.707-.527 1.271-1.584 1.438-3.219 2.02v3.232c1.632.58 2.692.749 3.219 2.019.53 1.282-.114 2.166-.847 3.707l2.285 2.286c1.562-.743 2.434-1.375 3.707-.847h.001c1.27.526 1.436 1.579 2.019 3.219h3.232c.582-1.636.75-2.69 2.027-3.222h.001c1.262-.524 2.12.101 3.698.851l2.285-2.286c-.744-1.563-1.375-2.433-.848-3.706.527-1.271 1.588-1.44 3.221-2.021zm-12 2.384c-2.209 0-4-1.791-4-4s1.791-4 4-4 4 1.791 4 4-1.791 4-4 4z",fill:"currentColor"})),Ht=t(y("react")),zt=()=>Ht.default.createElement("svg",{className:"devtools-icon",version:"1.1",viewBox:"1 1 22 22",xmlSpace:"preserve",xmlns:"http://www.w3.org/2000/svg"},Ht.default.createElement("g",{className:"devtools-icon-internal",id:"grid_system"}),Ht.default.createElement("g",{id:"_icons"},Ht.default.createElement("path",{d:"M18,12v-0.9l0.7-5.7C18.8,4.5,18.6,3.7,18,3c-0.6-0.6-1.4-1-2.2-1H8.3C7.4,2,6.6,2.4,6,3C5.4,3.7,5.2,4.5,5.3,5.4L6,11.1 V12c0,1.6,1.3,2.9,2.8,3l-0.4,2.9c-0.1,1,0.2,2.1,0.8,2.9S11,22,12,22s2-0.5,2.7-1.2s1-1.8,0.8-2.9L15.2,15 C16.7,14.9,18,13.6,18,12z M7.5,4.3C7.7,4.1,8,4,8.3,4H13v2c0,0.6,0.4,1,1,1s1-0.4,1-1V4h0.7c0.3,0,0.6,0.1,0.8,0.3 c0.2,0.2,0.3,0.5,0.2,0.8L16.1,10H7.9L7.3,5.1C7.2,4.8,7.3,4.6,7.5,4.3z M13.2,19.4c-0.6,0.7-1.8,0.7-2.4,0 c-0.3-0.4-0.4-0.8-0.4-1.3l0.5-3.2h2.3l0.5,3.2C13.7,18.6,13.5,19.1,13.2,19.4z M15,13h-1h-4H9c-0.6,0-1-0.4-1-1h8 C16,12.6,15.6,13,15,13z"}))),Wt=t(y("react")),Jt=t(De()),Xt=t=>{var e=t.sortBoxOptions.map(e=>({value:e.key,label:e.value})),r=t.sortBoxOptions.find(t.sortBySelectedFn);return Wt.default.createElement("div",{className:"marketplace-sortBox"},Wt.default.createElement("div",{className:"marketplace-sortBox-header"},Wt.default.createElement("div",{className:"marketplace-sortBox-header-title"}),Wt.default.createElement(Jt.default,{placeholder:"Select an option",options:e,value:null==r?void 0:r.key,onChange:e=>{t.onChange(e.value)}})))},R=t(y("react")),Yt=t(y("react-dom")),Qt=t(De()),r=t(e()),Zt=class extends R.default.Component{constructor(e){super(e)}render(){return this.props.item.enabled?R.default.createElement("li",{className:"marketplace-tabBar-headerItem","data-tab":this.props.item.value,onClick:e=>{e.preventDefault(),this.props.switchTo(this.props.item)}},R.default.createElement("a",{"aria-current":"page",className:"marketplace-tabBar-headerItemLink "+(this.props.item.active?"marketplace-tabBar-active":""),draggable:"false",href:""},R.default.createElement("span",{className:"main-type-mestoBold"},this.props.item.value))):null}},er=R.default.memo(function({items:e,switchTo:t}){return R.default.createElement("li",{className:"marketplace-tabBar-headerItem"},R.default.createElement(Qt.default,{className:"main-type-mestoBold",options:e,value:"More",placeholder:"More",onChange:t}))}),tr=({children:e})=>e&&document.querySelector(".main-topBar-topbarContentWrapper")?Yt.default.createPortal(R.default.createElement("div",{className:"main-topBar-topbarContent"},e),document.querySelector(".main-topBar-topbarContentWrapper")):null,rr=(tr.propTypes={children:r.default.element},e=>{const t=document.querySelector(".Root__main-view .os-resize-observer-host");if(!t)return null;const[r,a]=(0,R.useState)(t.clientWidth),n=()=>a(t.clientWidth);return(0,R.useEffect)(()=>{const e=new ResizeObserver(n);return e.observe(t),()=>{e.disconnect()}},[n]),R.default.createElement(tr,null,R.default.createElement(ar,{windowSize:r,links:e.links,activeLink:e.activeLink,switchCallback:e.switchCallback}))}),ar=R.default.memo(function({links:e,activeLink:r,switchCallback:t,windowSize:a=1/0}){const n=R.default.useRef(null),[s,o]=(0,R.useState)([]),[i,l]=(0,R.useState)(0),[c,u]=(0,R.useState)([]),p=e.map(({name:e,enabled:t})=>{return{label:e,value:e,active:e===r,enabled:t}});return(0,R.useEffect)(()=>{n.current&&l(n.current.clientWidth)},[a]),(0,R.useEffect)(()=>{if(n.current){const t=Array.from(n.current.children);var e=t.map(e=>e.clientWidth);o(e)}},[e]),(0,R.useEffect)(()=>{if(n.current)if(s.reduce((e,t)=>e+t,0)<=i)u([]);else{var e=Math.max(...s);const a=[];let r=e;s.forEach((e,t)=>{i>=r+e?r+=e:a.push(t)}),u(a)}},[i,s]),R.default.createElement("nav",{className:"marketplace-tabBar marketplace-tabBar-nav"},R.default.createElement("ul",{className:"marketplace-tabBar-header",ref:n},p.filter((e,t)=>!c.includes(t)).map(e=>R.default.createElement(Zt,{key:e.value,item:e,switchTo:t})),c.length||0===s.length?R.default.createElement(er,{items:c.map(e=>p[e]).filter(e=>e),switchTo:t}):null))}),T=t(y("react")),nr=t(y("react")),sr=()=>nr.default.createElement("svg",{role:"img",width:"16",height:"16",viewBox:"0 0 448 512","aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg"},nr.default.createElement("path",{d:"M53.21 467c1.562 24.84 23.02 45 47.9 45h245.8c24.88 0 46.33-20.16 47.9-45L416 128H32L53.21 467zM432 32H320l-11.58-23.16c-2.709-5.42-8.25-8.844-14.31-8.844H153.9c-6.061 0-11.6 3.424-14.31 8.844L128 32H16c-8.836 0-16 7.162-16 16V80c0 8.836 7.164 16 16 16h416c8.838 0 16-7.164 16-16V48C448 39.16 440.8 32 432 32z",fill:"currentColor"})),or=t(y("react")),ir=()=>or.default.createElement("svg",{role:"img",width:"16",height:"16",viewBox:"0 0 512 512","aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg"},or.default.createElement("path",{d:"M480 352h-133.5l-45.25 45.25C289.2 409.3 273.1 416 256 416s-33.16-6.656-45.25-18.75L165.5 352H32c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-96C512 366.3 497.7 352 480 352zM432 456c-13.2 0-24-10.8-24-24c0-13.2 10.8-24 24-24s24 10.8 24 24C456 445.2 445.2 456 432 456zM233.4 374.6C239.6 380.9 247.8 384 256 384s16.38-3.125 22.62-9.375l128-128c12.49-12.5 12.49-32.75 0-45.25c-12.5-12.5-32.76-12.5-45.25 0L288 274.8V32c0-17.67-14.33-32-32-32C238.3 0 224 14.33 224 32v242.8L150.6 201.4c-12.49-12.5-32.75-12.5-45.25 0c-12.49 12.5-12.49 32.75 0 45.25L233.4 374.6z",fill:"currentColor"})),lr=t(y("react")),cr=()=>lr.default.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24"},lr.default.createElement("path",{d:"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z",fill:"currentColor"})),ur=t(y("react")),pr=e=>{return ur.default.createElement("div",{className:"marketplace-card__authors"},e.authors.map((e,t)=>ur.default.createElement("a",{title:e.name,className:"marketplace-card__author",href:e.url,draggable:"false",dir:"auto",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),key:t},e.name)))},A=t(y("react")),hr=r=>{const[e,t]=A.default.useState(!1);var a=e=>{const t=e.filter((e,t,r)=>r.indexOf(e)===t);return t.reduce((e,t)=>(!r.showTags&&"external JS"!==t||e.push(A.default.createElement("li",{className:"marketplace-card__tag",draggable:!1,"data-tag":t},t)),e),[])},n=r.tags.slice(0,4),s=r.tags.slice(4);return A.default.createElement("div",{className:"marketplace-card__tags-container"},A.default.createElement("ul",{className:"marketplace-card__tags"},a(n),s.length&&e?a(s):null),s.length&&!e?A.default.createElement("button",{className:"marketplace-card__tags-more-btn",onClick:e=>{e.stopPropagation(),t(!0)}},"..."):null)},dr=class extends T.default.Component{constructor(e){super(e),this.key=null,this.type=dr,this.menuType=Spicetify.ReactComponent.Menu;var t,r="snippet"===e.type?"snippet:":`${e.item.user}/${e.item.repo}/`;let a;switch(e.type){case"snippet":a=e.item.title.replaceAll(" ","-");break;case"theme":a=(null==(t=e.item.manifest)?void 0:t.usercss)||"";break;case"extension":a=(null==(t=e.item.manifest)?void 0:t.main)||"";break;case"app":a=(null==(t=null==(t=e.item.manifest)?void 0:t.name)?void 0:t.replaceAll(" ","-"))||""}this.localStorageKey="marketplace:installed:"+r+a,Object.assign(this,e),this.tags=e.item.tags||[],e.item.include&&this.tags.push("external JS"),this.state={installed:null!==localStorage.getItem(this.localStorageKey),stars:this.props.item.stars||0,tagsExpanded:!1,externalUrl:this.props.item.user&&this.props.item.repo?`https://github.com/${this.props.item.user}/`+this.props.item.repo:"",lastUpdated:this.props.item.user&&this.props.item.repo?this.props.item.lastUpdated:void 0}}isInstalled(){return null!==localStorage.getItem(this.localStorageKey)}async componentDidMount(){if("Installed"===this.props.CONFIG.activeTab&&"snippet"!==this.props.type){var e=`https://api.github.com/repos/${this.props.item.user}/`+this.props.item.repo,{stargazers_count:e,pushed_at:t}=await fetch(e).then(e=>e.json());const r={stars:0,lastUpdated:void 0};this.state.stars!==e&&this.props.CONFIG.visual.stars&&(r.stars=e,console.log("Stars updated to: "+e)),this.state.lastUpdated!==t&&(r.lastUpdated=t,console.log("New update pushed at: "+t))}}buttonClicked(){var e,t;"extension"===this.props.type?(this.isInstalled()?(console.log("Extension already installed, removing"),this.removeExtension()):this.installExtension(),I("RELOAD")):"theme"===this.props.type?(t=(e=localStorage.getItem("marketplace:theme-installed"))?E(e,{}):{},console.log(t),console.log(e),this.isInstalled()?(console.log("Theme already installed, removing"),this.removeTheme(this.localStorageKey)):(this.removeTheme(),this.installTheme()),(null!=(e=this.props.item.manifest)&&e.include||t.include)&&I("RELOAD")):"app"===this.props.type?window.open(this.state.externalUrl,"_blank"):"snippet"===this.props.type?this.isInstalled()?(console.log("Snippet already installed, removing"),this.removeSnippet()):this.installSnippet():console.error("Unknown card type")}installExtension(){if(console.log("Installing extension "+this.localStorageKey),this.props.item){var{manifest:e,title:t,subtitle:r,authors:a,user:n,repo:s,branch:o,imageURL:i,extensionURL:l,readmeURL:c,lastUpdated:u}=this.props.item;localStorage.setItem(this.localStorageKey,JSON.stringify({manifest:e,type:this.props.type,title:t,subtitle:r,authors:a,user:n,repo:s,branch:o,imageURL:i,extensionURL:l,readmeURL:c,stars:this.state.stars,lastUpdated:u}));const p=E(f,[]);-1===p.indexOf(this.localStorageKey)&&(p.push(this.localStorageKey),localStorage.setItem(f,JSON.stringify(p))),console.log("Installed"),this.setState({installed:!0})}else Spicetify.showNotification("There was an error installing extension")}removeExtension(){if(localStorage.getItem(this.localStorageKey)){console.log("Removing extension "+this.localStorageKey),localStorage.removeItem(this.localStorageKey);const t=E(f,[]);var e=t.filter(e=>e!==this.localStorageKey);localStorage.setItem(f,JSON.stringify(e)),console.log("Removed"),this.setState({installed:!1})}}async installTheme(){var t=this.props["item"];if(t){console.log("Installing theme "+this.localStorageKey);let e={};if(t.schemesURL){const y=await fetch(t.schemesURL);var r=await y.text();e=Xe(r)}var r=Object.keys(e)[0],r=(console.log(e,r),r||null),{manifest:a,title:n,subtitle:s,authors:o,user:i,repo:l,branch:c,imageURL:u,extensionURL:p,readmeURL:h,cssURL:d,schemesURL:m,include:f,lastUpdated:g}=t;localStorage.setItem(this.localStorageKey,JSON.stringify({manifest:a,type:this.props.type,title:n,subtitle:s,authors:o,user:i,repo:l,branch:c,imageURL:u,extensionURL:p,readmeURL:h,stars:this.state.stars,tags:this.tags,cssURL:d,schemesURL:m,include:f,schemes:e,activeScheme:r,lastUpdated:g}));const v=E(b,[]);-1===v.indexOf(this.localStorageKey)&&(v.push(this.localStorageKey),localStorage.setItem(b,JSON.stringify(v)),localStorage.setItem(S,this.localStorageKey)),console.log("Installed"),t.include||(this.fetchAndInjectUserCSS(this.localStorageKey),this.props.updateActiveTheme(this.localStorageKey),this.props.updateColourSchemes(e,r)),this.setState({installed:!0})}else Spicetify.showNotification("There was an error installing theme")}removeTheme(t){var e=(t=t||localStorage.getItem(S))&&localStorage.getItem(t);if(t&&e){console.log("Removing theme "+t),localStorage.removeItem(t),localStorage.removeItem(S);const r=E(b,[]);e=r.filter(e=>e!==t);localStorage.setItem(b,JSON.stringify(e)),console.log("Removed"),this.fetchAndInjectUserCSS(null),this.props.updateActiveTheme(null),this.props.updateColourSchemes(null,null),this.setState({installed:!1})}}installSnippet(){console.log("Installing snippet "+this.localStorageKey),localStorage.setItem(this.localStorageKey,JSON.stringify({code:this.props.item.code,title:this.props.item.title,description:this.props.item.description,imageURL:this.props.item.imageURL}));const e=E(g,[]);-1===e.indexOf(this.localStorageKey)&&(e.push(this.localStorageKey),localStorage.setItem(g,JSON.stringify(e)));var t=e.map(e=>E(e));Ye(t),this.setState({installed:!0})}removeSnippet(){localStorage.removeItem(this.localStorageKey);const e=E(g,[]),t=e.filter(e=>e!==this.localStorageKey);localStorage.setItem(g,JSON.stringify(t));var r=t.map(e=>E(e));Ye(r),this.setState({installed:!1})}async fetchAndInjectUserCSS(e){try{var t=e?await at(this.props.item):void 0;rt(t)}catch(e){console.warn(e)}}openReadme(){var e;null!=(e=this.props.item)&&e.manifest&&null!=(e=null==(e=this.props.item)?void 0:e.manifest)&&e.readme?Spicetify.Platform.History.push({pathname:ut+"/readme",state:{data:{title:this.props.item.title,user:this.props.item.user,repo:this.props.item.repo,branch:this.props.item.branch,readmeURL:this.props.item.readmeURL}}}):Spicetify.showNotification("No page was found")}render(){var e,t=this.isInstalled();if("Installed"===this.props.CONFIG.activeTab&&!t)return console.log("Card item not installed"),null;const r=["main-card-card","marketplace-card--"+this.props.type],a=(t&&r.push("marketplace-card--installed"),[]);return"snippet"!==this.props.type&&this.props.visual.stars&&a.push("★ "+this.state.stars),T.default.createElement("div",{className:r.join(" "),onClick:()=>{if("snippet"===this.props.type){var e=this.props.item.title.replace(/\n/g,"");if(null!=(e=E("marketplace:installed:snippet:"+e))&&e.custom)return I("EDIT_SNIPPET",void 0,void 0,this.props);I("VIEW_SNIPPET",void 0,void 0,this.props)}else this.openReadme()}},T.default.createElement("div",{className:"main-card-draggable",draggable:"true"},T.default.createElement("div",{className:"main-card-imageContainer"},T.default.createElement("div",{className:"main-cardImage-imageWrapper"},T.default.createElement("div",null,T.default.createElement("img",{alt:"","aria-hidden":"false",draggable:"false",loading:"lazy",src:this.props.item.imageURL,className:"main-image-image main-cardImage-image",onError:e=>{e.currentTarget.setAttribute("src","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII"),null!=(e=e.currentTarget.closest(".main-cardImage-imageWrapper"))&&e.classList.add("main-cardImage-imageWrapper--error")}})))),T.default.createElement("div",{className:"main-card-cardMetadata"},T.default.createElement("a",{draggable:"false",title:"snippet"===this.props.type?this.props.item.title:null==(e=this.props.item.manifest)?void 0:e.name,className:"main-cardHeader-link",dir:"auto",href:"snippet"!==this.props.type?this.state.externalUrl:"https://github.com/spicetify/spicetify-marketplace/blob/main/packages/marketplace/src/resources/snippets.ts",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation()},T.default.createElement("div",{className:"main-cardHeader-text main-type-balladBold"},this.props.item.title)),T.default.createElement("div",{className:"main-cardSubHeader-root main-type-mestoBold marketplace-cardSubHeader"},this.props.item.authors&&T.default.createElement(pr,{authors:this.props.item.authors}),T.default.createElement("span",null,a.join(" ‒ "))),T.default.createElement("p",{className:"marketplace-card-desc"},"snippet"===this.props.type?this.props.item.description:null==(e=this.props.item.manifest)?void 0:e.description),this.props.item.lastUpdated&&T.default.createElement("p",{className:"marketplace-card-desc"},"Last updated:"," ",new Date(this.props.item.lastUpdated).toLocaleString("en-US",{month:"long",day:"numeric",year:"numeric"})),this.tags.length?T.default.createElement("div",{className:"marketplace-card__bottom-meta main-type-mestoBold"},T.default.createElement(hr,{tags:this.tags,showTags:this.props.CONFIG.visual.tags})):null,t&&T.default.createElement("div",{className:"marketplace-card__bottom-meta main-type-mestoBold"},"✓ Installed"),T.default.createElement("div",{className:"main-card-PlayButtonContainer"},T.default.createElement(m,{classes:["marketplace-installButton"],type:"circle",label:"app"===this.props.type?"GitHub":t?"Remove":"Install",onClick:e=>{e.stopPropagation(),this.buttonClicked()}},"app"===this.props.type?T.default.createElement(cr,null):t?T.default.createElement(sr,null):T.default.createElement(ir,null))))))}},mr=t(y("react")),fr=t(u()),gr=t(y("react-dom"));var $,vr=async function(t,r,e){for(;!Spicetify?.PopupModal||!Spicetify?.LocalStorage;)await new Promise(e=>setTimeout(e,100));var a,t=`spcr-whats-new_${t}-version`,n=Spicetify.LocalStorage.get(t)??"";try{(0,fr.default)(r,n)&&(Spicetify.LocalStorage.set(t,r),a={...e,content:function(e){const t=document.createElement("div"),r=(t.setAttribute("id","whats-new-content-wrapper"),document.createElement("style"));return r.textContent=` + #whats-new-content-wrapper ul, #whats-new-content-wrapper ol { + list-style: inherit; + margin-left: 1em; + } + `,gr.default.render(e,t),t.appendChild(r),t}(e.content)},Spicetify.PopupModal.display(a))}catch(e){Spicetify.LocalStorage.set(t,r)}},yr=async()=>{var e=await fetch(pt).then(e=>e.json()).then(e=>{e=e.message?null:e.body;return e&&nt(e,"spicetify","spicetify-marketplace")}).catch(e=>(console.error(e),null));e&&vr("marketplace",st,{title:"✨ Marketplace v0.7.0",content:mr.default.createElement("div",{dangerouslySetInnerHTML:{__html:e}}),isLarge:!0})},Er=class extends o.default.Component{constructor(e){super(e),this.endOfList=!1,this.lastScroll=0,this.requestQueue=[],this.requestPage=0,this.cardList=[],Object.assign(this,e),this.updateAppConfig=e.updateAppConfig.bind(this),this.sortConfig={by:E(lt,"top")},this.state={version:st,newUpdate:!1,searchValue:"",cards:[],tabs:e.CONFIG.tabs,rest:!0,endOfList:!1,schemes:e.CONFIG.theme.schemes,activeScheme:e.CONFIG.theme.activeScheme,activeThemeKey:e.CONFIG.theme.activeThemeKey}}getInstalledTheme(){var e=localStorage.getItem(S);if(!e)return null;e=localStorage.getItem(e);return e?JSON.parse(e):null}newRequest(e,t){this.cardList=[];var r=[];this.requestQueue.unshift(r),this.loadAmount(r,e,t)}appendCard(e,t){e=o.default.createElement(dr,{item:e,key:this.props.CONFIG.activeTab+":"+e.title,CONFIG:this.CONFIG,visual:this.props.CONFIG.visual,type:t,activeThemeKey:this.state.activeThemeKey,updateColourSchemes:this.updateColourSchemes.bind(this),updateActiveTheme:this.setActiveTheme.bind(this)});this.cardList.push(e),this.setState({cards:this.cardList})}updateSort(e){e&&(this.sortConfig.by=e,localStorage.setItem(lt,e)),this.requestPage=0,this.cardList=[],this.setState({cards:[],rest:!1,endOfList:!1}),this.endOfList=!1,this.newRequest(v)}updateTabs(){this.setState({tabs:[...this.props.CONFIG.tabs]})}updatePostsVisual(){this.cardList=this.cardList.map((e,t)=>o.default.createElement(dr,z(i({},e.props),{key:t.toString(),CONFIG:this.CONFIG}))),this.setState({cards:[...this.cardList]})}switchTo(e){this.CONFIG.activeTab=e.value,localStorage.setItem(ot,e.value),this.cardList=[],this.requestPage=0,this.setState({cards:[],rest:!1,endOfList:!1}),this.endOfList=!1,this.newRequest(v)}async loadPage(t,e){switch(this.CONFIG.activeTab){case"Extensions":var r=await $t("spicetify-extensions",this.requestPage,this.BLACKLIST,e);for(const o of r.items){const i=await jt(o.contents_url,o.default_branch,o.stargazers_count,this.CONFIG.visual.hideInstalled);if(1{Object.assign(e,{lastUpdated:o.pushed_at}),this.appendCard(e,"extension")})}var a=-1{e=E(e);if(1{Object.assign(e,{lastUpdated:u.pushed_at}),this.appendCard(e,"theme")})}r=-1{Object.assign(e,{lastUpdated:h.pushed_at}),this.appendCard(e,"app")})}n=-1this.appendCard(e,"snippet"))}}return this.setState({rest:!0,endOfList:!0}),this.endOfList=!0,0}async loadAmount(t,e=v,r){for(this.setState({rest:!1}),e+=this.cardList.length,this.requestPage=await this.loadPage(t,r);this.requestPage&&-1!==this.requestPage&&this.cardList.lengthe!==t):(this.requestQueue.shift(),this.setState({rest:!0}))}loadMore(){this.state.rest&&!this.endOfList&&this.loadAmount(this.requestQueue[0],v)}updateColourSchemes(e,t){console.log("updateColourSchemes",e,t),this.CONFIG.theme.schemes=e,this.CONFIG.theme.activeScheme=t,e&&t&&e[t]?tt(this.CONFIG.theme.schemes[t]):tt(null);var r=E(S);const a=E(r);a?(a.activeScheme=t,console.log(a),localStorage.setItem(r,JSON.stringify(a))):console.log("No installed theme data"),this.setState({schemes:e,activeScheme:t})}async componentDidMount(){fetch("https://api.github.com/repos/spicetify/spicetify-marketplace/releases").then(e=>e.json()).then(e=>{this.setState({version:e[0].name});try{this.setState({newUpdate:Je.default.gt(this.state.version,st)})}catch(e){console.error(e)}},e=>{console.error("Failed to check for updates",e)}),yr(),this.gridUpdateTabs=this.updateTabs.bind(this),this.gridUpdatePostsVisual=this.updatePostsVisual.bind(this);const e=document.querySelector(".os-viewport");this.checkScroll=this.isScrolledBottom.bind(this),e&&(e.addEventListener("scroll",this.checkScroll),this.cardList.length)?0=e.scrollHeight&&this.loadMore()}setActiveTheme(e){this.CONFIG.theme.activeThemeKey=e,this.setState({activeThemeKey:e})}getActiveScheme(){return this.state.activeScheme}handleSearch(e){"Enter"===e.key?(this.setState({endOfList:!1}),this.newRequest(v,this.state.searchValue.trim().toLowerCase()),this.searchRequested=!0):"Backspace"!==e.key&&"Delete"!==e.key||!this.searchRequested||""!==this.state.searchValue.trim()||(this.setState({endOfList:!1}),this.newRequest(v,this.state.searchValue.trim().toLowerCase()),this.searchRequested=!1)}render(){return o.default.createElement("section",{className:"contentSpacing"},o.default.createElement("div",{className:"marketplace-header"},o.default.createElement("div",{className:"marketplace-header__left"},o.default.createElement("h1",null,this.props.title),this.state.newUpdate?o.default.createElement("button",{type:"button",title:"New update",className:"marketplace-header-icon-button",id:"marketplace-update",onClick:()=>window.location.href="https://github.com/spicetify/spicetify-marketplace"},o.default.createElement(ir,null)," ",this.state.version):null),o.default.createElement("div",{className:"marketplace-header__right"},this.CONFIG.visual.themeDevTools?o.default.createElement("button",{type:"button",title:"ThemeDevTools",className:"marketplace-header-icon-button",onClick:()=>I("THEME_DEV_TOOLS")},o.default.createElement(zt,null)):null,this.state.activeScheme?o.default.createElement(Xt,{onChange:e=>this.updateColourSchemes(this.state.schemes,e),sortBoxOptions:Ze(this.state.schemes),sortBySelectedFn:e=>e.key===this.getActiveScheme()}):null,o.default.createElement("div",{className:"searchbar--bar__wrapper"},o.default.createElement("input",{className:"searchbar-bar",type:"text",placeholder:`Search ${this.CONFIG.activeTab}...`,value:this.state.searchValue,onChange:e=>{this.setState({searchValue:e.target.value})},onKeyDown:this.handleSearch.bind(this)})),o.default.createElement("button",{type:"button",title:"Settings",className:"marketplace-header-icon-button",id:"marketplace-settings-button",onClick:()=>I("SETTINGS",this.CONFIG,this.updateAppConfig)},o.default.createElement(Vt,null)))),[{handle:"extension",name:"Extensions"},{handle:"theme",name:"Themes"},{handle:"snippet",name:"Snippets"},{handle:"app",name:"Apps"}].map(t=>{var e=this.cardList.filter(e=>e.props.type===t.handle).filter(e=>{const t=this.state["searchValue"],{title:r,user:a}=e.props.item;if(""===t.trim()||r.toLowerCase().includes(t.trim().toLowerCase())||null!=a&&a.toLowerCase().includes(t.trim().toLowerCase()))return e}).map((e,t)=>{return e.key=t,o.default.cloneElement(e,{activeThemeKey:this.state.activeThemeKey})});return e.length?o.default.createElement(o.default.Fragment,null,o.default.createElement("h2",{className:"marketplace-card-type-heading"},t.name),o.default.createElement("div",{className:"marketplace-grid main-gridContainer-gridContainer main-gridContainer-fixedWidth","data-tab":this.CONFIG.activeTab,"data-card-type":t.name},e)):null}),"Snippets"===this.CONFIG.activeTab?o.default.createElement(m,{classes:["marketplace-add-snippet-btn"],onClick:()=>I("ADD_SNIPPET")},"+Add CSS"):null,o.default.createElement("footer",{className:"marketplace-footer"},!this.state.endOfList&&(this.state.rest?o.default.createElement(qt,{onClick:this.loadMore.bind(this)}):o.default.createElement(Bt,null))),o.default.createElement(rr,{switchCallback:this.switchTo.bind(this),links:this.CONFIG.tabs,activeLink:this.CONFIG.activeTab}))}},P=t(y("react")),br=class extends P.default.Component{constructor(){super(...arguments),this.state={html:"

Loading...

"},this.getReadmeHTML=async()=>fetch(this.props.data.readmeURL).then(e=>{if(e.ok)return e.text();throw Spicetify.showNotification(`Error loading README (HTTP ${e.status})`)}).then(e=>nt(e,this.props.data.user,this.props.data.repo)).then(e=>(e||Spicetify.Platform.History.goBack(),e)).catch(e=>(console.error(e),Spicetify.Platform.History.goBack(),null))}componentDidMount(){this.getReadmeHTML().then(e=>{null!=e&&this.setState({html:e})})}componentDidUpdate(){var e;const t=null==(e=document.querySelector("#marketplace-readme"))?void 0:e.closest("main");t&&setTimeout(()=>{t.style.overflowY="auto"},1e3),document.querySelectorAll("#marketplace-readme img").forEach(e=>{e.addEventListener("error",e=>{const t=e.target;e=t.getAttribute("src"),e=`https://raw.githubusercontent.com/${this.props.data.user}/${this.props.data.repo}/${this.props.data.branch}/`+e;t.setAttribute("src",e)},{once:!0})})}render(){return P.default.createElement("section",{className:"contentSpacing"},P.default.createElement("div",{className:"marketplace-header",style:{flexDirection:"row"}},P.default.createElement("h1",null,this.props.title)),"

Loading...

"===this.state.html?P.default.createElement("footer",{className:"marketplace-footer"},P.default.createElement(Bt,null)):P.default.createElement("div",{id:"marketplace-readme",className:"marketplace-readme__container",dangerouslySetInnerHTML:{__html:this.state.html}}))}},Sr=class extends We.default.Component{constructor(e){super(e),this.state={count:0,CONFIG:{}},this.updateConfig=e=>{this.CONFIG=i({},e),console.log("updated config",this.CONFIG),this.setState({CONFIG:i({},e)})};e=E(it,null);let t=[];try{if(t=JSON.parse(e),!Array.isArray(t))throw new Error("Could not parse marketplace tabs key");if(0===t.length)throw new Error("Empty marketplace tabs key");if(0!e).length)throw new Error("Falsey marketplace tabs key")}catch(e){t=ct,localStorage.setItem(it,JSON.stringify(t))}let r={},a=null;try{var n=E(S,null);if(n){var s=E(n,null);if(!s)throw new Error("No installed theme data");r=s.schemes,a=s.activeScheme}else console.log("No theme set as installed")}catch(e){console.error(e)}this.CONFIG={visual:{stars:JSON.parse(E("marketplace:stars",!0)),tags:JSON.parse(E("marketplace:tags",!0)),hideInstalled:JSON.parse(E("marketplace:hideInstalled",!1)),colorShift:JSON.parse(E("marketplace:colorShift",!1)),themeDevTools:JSON.parse(E("marketplace:themeDevTools",!1)),type:JSON.parse(E("marketplace:type",!1)),followers:JSON.parse(E("marketplace:followers",!1))},tabs:t,activeTab:E(ot,t[0]),theme:{activeThemeKey:E(S,null),schemes:r,activeScheme:a}},this.CONFIG.activeTab&&this.CONFIG.tabs.filter(e=>e.name===this.CONFIG.activeTab).length||(this.CONFIG.activeTab=this.CONFIG.tabs[0].name)}render(){var e=Spicetify.Platform.History["location"];return e.pathname===ut+"/readme"?We.default.createElement(br,{title:"Spicetify Marketplace - Readme",data:e.state.data}):We.default.createElement(Er,{title:"Spicetify Marketplace",CONFIG:this.CONFIG,updateAppConfig:this.updateConfig})}},wr=t(y("react"));return $=Ve,W(s({},"__esModule",{value:!0}),$)})();const render=()=>marketplace.default(); \ No newline at end of file diff --git a/config/spicetify/CustomApps/marketplace/manifest.json b/config/spicetify/CustomApps/marketplace/manifest.json new file mode 100644 index 0000000..14ccd40 --- /dev/null +++ b/config/spicetify/CustomApps/marketplace/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "Marketplace", + "icon": "\n", + "active-icon": "\n", + "subfiles": [], + "subfiles_extension": [ + "extension.js" + ] +} \ No newline at end of file diff --git a/config/spicetify/CustomApps/marketplace/style.css b/config/spicetify/CustomApps/marketplace/style.css new file mode 100644 index 0000000..599ed24 --- /dev/null +++ b/config/spicetify/CustomApps/marketplace/style.css @@ -0,0 +1 @@ +@charset "UTF-8";.marketplace-header{-webkit-box-pack:justify;-webkit-box-align:center;align-content:space-between;align-items:center;color:var(--spice-text);display:flex;justify-content:space-between;margin:16px 0;position:-webkit-sticky;position:sticky;flex-direction:row-reverse;z-index:1}.marketplace-header__left,.marketplace-header__right{display:flex}.marketplace-header__left{position:fixed;left:16px}@media (min-width:1024px){.marketplace-header__left{left:32px}}.marketplace-grid{--minimumColumnWidth:180px;--column-width:minmax(var(--minimumColumnWidth),1fr);--column-count:auto-fill;--grid-gap:24px}.marketplace-sort-bar{align-items:center;display:flex}.marketplace-sort-container{position:relative;display:flex}.marketplace-tabBar-headerItem{-webkit-app-region:no-drag;display:inline-block;pointer-events:auto;vertical-align:middle}.marketplace-tabBar-active{background-color:var(--spice-tab-active);border-radius:4px}.marketplace-tabBar-headerItemLink{border-radius:4px;color:var(--spice-text);display:inline-block;margin:0 8px 0 0;padding:8px 16px;position:relative;text-decoration:none!important;cursor:pointer}.marketplace-tabBar-nav{-webkit-app-region:drag;pointer-events:none;width:100%}.marketplace-tabBar-headerItem .optionsMenu-dropBox{color:var(--spice-text);border:0;max-width:150px;height:42px;padding:0 30px 0 12px;background-color:initial;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.marketplace-tabBar-headerItem .optionsMenu-dropBox svg{position:absolute;margin-left:8px}.marketplace-header-icon-button{border-radius:8px;color:var(--spice-text);display:inline-block;padding:10px 14px 6px;margin-left:8px;font-weight:700;position:relative;text-decoration:none!important;cursor:pointer;background-color:transparent;border:none;background-color:var(--spice-sidebar);transition-duration:.2s}.marketplace-header-icon-button:hover{background-color:var(--spice-button-disabled)}.searchbar--bar__wrapper{margin-left:8px;display:flex;flex-direction:column;align-items:flex-end;flex-grow:1}.searchbar-bar{border:unset;background-color:var(--spice-sidebar)!important;border-radius:8px;padding:10px 12px;color:var(--spice-text)!important}option{background-color:var(--spice-button)}.marketplace-footer{margin:auto;text-align:center}.marketplace-add-snippet-btn{position:-webkit-sticky;position:sticky!important;bottom:32px;left:100%}.arrow-closed,.arrow-open{border:solid rgba(var(--spice-rgb-text),.7);border-width:0 2px 2px 0;display:inline-block;padding:4px;position:absolute;right:10px}.arrow-closed{top:10px;transform:rotate(45deg);-webkit-transform:rotate(45deg)}.arrow-open{top:14px;transform:rotate(-135deg);-webkit-transform:rotate(-135deg)}.Dropdown-root{position:relative}.Dropdown-root.is-open .Dropdown-control{border-bottom-left-radius:0;border-bottom-right-radius:0}.Dropdown-root.is-open .Dropdown-control:hover .Dropdown-arrow{border-color:transparent transparent rgb(var(--spice-rgb-text))}.Dropdown-root.is-open .Dropdown-arrow{border-color:transparent transparent rgba(var(--spice-rgb-text),.7);border-width:0 5px 5px}.Dropdown-root.is-open .Dropdown-menu{border-top-left-radius:0;border-top-right-radius:0}.Dropdown-control{position:relative;overflow:hidden;background-color:var(--spice-sidebar);border:0;border-radius:8px;box-sizing:border-box;color:rgba(var(--spice-rgb-text),.7);cursor:default;outline:0;padding:8px 36px 8px 16px;transition:all .2s ease}.Dropdown-control:hover{color:rgb(var(--spice-rgb-text));background-color:var(--spice-button-disabled)}.Dropdown-control:hover .Dropdown-arrow{border-color:rgb(var(--spice-rgb-text)) transparent transparent}.Dropdown-arrow{border-color:rgba(var(--spice-rgb-text),.7) transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;margin-top:-ceil(2.5);position:absolute;right:16px;top:18px;width:0}.Dropdown-menu{background-color:var(--spice-sidebar);border:0;border-radius:8px;box-shadow:0 1px 0 rgba(0,0,0,.06);box-sizing:border-box;margin-top:-1px;max-height:200px;overflow-y:auto;position:absolute;top:100%;width:100%;z-index:1000;-webkit-overflow-scrolling:touch}.Dropdown-menu .Dropdown-group>.Dropdown-title{padding:8px 10px;color:#333;font-weight:700;text-transform:capitalize}.Dropdown-option{box-sizing:border-box;color:rgba(var(--spice-rgb-text),.7);cursor:pointer;display:block;padding:8px 10px}.Dropdown-option:last-child{border-bottom-right-radius:8px;border-bottom-left-radius:8px}.Dropdown-option.is-selected{background-color:rgba(var(--spice-rgb-text),.7);color:var(--spice-sidebar)}.Dropdown-option:hover{background-color:rgb(var(--spice-rgb-text));color:var(--spice-sidebar)}.Dropdown-noresults{box-sizing:border-box;color:#ccc;cursor:default;display:block;padding:8px 10px}.marketplace-card-type-heading{margin:1em 0 .5em;color:var(--spice-subtext);font-size:1.3em}.marketplace-grid .main-card-draggable{display:flex;flex-direction:column}.marketplace-grid .main-card-draggable .main-card-cardMetadata{flex-grow:1;display:flex;flex-direction:column}.marketplace-grid .main-card-draggable .main-card-cardMetadata .main-cardHeader-link:hover{text-decoration:underline}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__author~.marketplace-card__author::before{content:", "}.marketplace-grid .main-card-draggable .main-card-cardMetadata ul.marketplace-card__tags{display:flex;flex-wrap:wrap;gap:8px}.marketplace-grid .main-card-draggable .main-card-cardMetadata li.marketplace-card__tag{background-color:var(--spice-tab-active);border-radius:4px;padding:0 9px 2px}.marketplace-grid .main-card-draggable .main-card-cardMetadata li.marketplace-card__tag[data-tag="external JS"]{background-color:hsl(0deg,70%,54%);color:#fff}.marketplace-grid .main-card-draggable .main-card-cardMetadata li.marketplace-card__tag[data-tag=dark]{background-color:#000;color:#fff}.marketplace-grid .main-card-draggable .main-card-cardMetadata li.marketplace-card__tag[data-tag=light]{background-color:#fff;color:#333}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__tags-more-btn{background-color:var(--spice-tab-active);border-radius:4px;padding:0 9px 2px;margin-top:8px;border:none}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__tags-more-btn:focus,.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__tags-more-btn:hover{filter:brightness(1.4)}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card-desc{font:-webkit-small-control;margin:12px 0;display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:3}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__bottom-meta{margin-top:auto;margin-bottom:0}.marketplace-grid .main-card-draggable .main-card-cardMetadata .marketplace-card__bottom-meta+.marketplace-card__bottom-meta{margin-top:8px}.marketplace-grid[data-tab=Installed]:empty::after{content:"No installed " attr(data-card-type);display:block}.main-cardImage-imageWrapper--error::before{content:"";display:block;position:absolute;overflow:hidden;top:0;left:0;bottom:0;right:0;height:100%;width:100%;background-color:var(--spice-subtext);filter:brightness(50%);-webkit-clip-path:path("M41.20833,21.5c-2.54758,0.00136 -4.90298,1.35492 -6.18685,3.55534l-12.54167,21.5c-0.64062,1.09578 -0.97875,2.34203 -0.97982,3.61133v86c0,7.83362 6.49972,14.33333 14.33333,14.33333h100.33333c7.83362,0 14.33333,-6.49972 14.33333,-14.33333v-86c-0.00107,-1.2693 -0.3392,-2.51555 -0.97982,-3.61133l-12.54167,-21.5c-1.28387,-2.20042 -3.63926,-3.55398 -6.18685,-3.55534zM45.32357,35.83333h81.35286l8.35645,14.33333h-98.06576zM35.83333,64.5h100.33333v71.66667h-100.33333zM64.5,78.83333v14.33333h43v-14.33333z");clip-path:path("M41.20833,21.5c-2.54758,0.00136 -4.90298,1.35492 -6.18685,3.55534l-12.54167,21.5c-0.64062,1.09578 -0.97875,2.34203 -0.97982,3.61133v86c0,7.83362 6.49972,14.33333 14.33333,14.33333h100.33333c7.83362,0 14.33333,-6.49972 14.33333,-14.33333v-86c-0.00107,-1.2693 -0.3392,-2.51555 -0.97982,-3.61133l-12.54167,-21.5c-1.28387,-2.20042 -3.63926,-3.55398 -6.18685,-3.55534zM45.32357,35.83333h81.35286l8.35645,14.33333h-98.06576zM35.83333,64.5h100.33333v71.66667h-100.33333zM64.5,78.83333v14.33333h43v-14.33333z");clip-rule:nonzero;transform:scale(.5)}.main-cardImage-imageWrapper--error{box-shadow:none}.main-card-card:hover .main-cardImage-imageWrapper--error::before{filter:brightness(100%)}.marketplace-cardSubHeader,.marketplace-card__bottom-meta{margin-top:4px;white-space:normal;color:var(--spice-subtext)}.marketplace-cardSubHeader{display:flex;flex-direction:column;gap:8px}.marketplace-card--installed{flex:0!important;-webkit-box-flex:0!important;border:1px solid var(--spice-button)}.marketplace-installButton{cursor:pointer;--size:40px}.setting-row{display:flex;justify-content:space-between}.setting-row .col{display:flex;padding:10px 0;align-items:center}.setting-row .col.action{text-align:right}button.arrow-btn{align-items:center;border:0;border-radius:50%;background-color:rgba(var(--spice-rgb-shadow),.7);color:var(--spice-text);cursor:pointer;display:flex;-webkit-margin-end:12px;margin-inline-end:12px;padding:8px}button.arrow-btn.small{width:24px;height:24px;padding:5px}button.arrow-btn.disabled,button.arrow-btn[disabled]{color:rgba(var(--spice-rgb-text),.3);cursor:not-allowed}#marketplace-add-snippet-container input,textarea{width:100%;margin-bottom:10px;padding:3px 5px;background-color:var(--spice-main);color:var(--spice-text);font-size:14px;border:1px solid var(--spice-button);border-radius:4px}.GenericModal[aria-label="Reload required"]{height:240px!important}.marketplace-reload-modal__button-container{display:flex;justify-content:center;padding-top:18px}.marketplace-reload-modal__button-container button{margin:18px;padding:8px 24px}#marketplace-add-snippet-container{display:flex;flex-direction:column;gap:16px}#marketplace-add-snippet-container #marketplace-custom-css:focus-visible{outline:0}.marketplace-customCSS-input-container{display:flex;flex-direction:column}img.marketplace-customCSS-image-preview{aspect-ratio:1;width:100%;height:auto;max-width:400px;-o-object-fit:cover;object-fit:cover;margin:0 auto}#marketplace-customCSS-submit{margin-left:auto}.spicetify-root-vars{--spice-shadow:#1f1525;--spice-text:#ffffff;--spice-sidebar:#0a0e14;--spice-button-disabled:#535353;--spice-main:#0a0e14;--spice-misc:#bfbfbf;--spice-selected-row:#909090;--spice-subtext:#f0f0f0;--spice-tab-active:#795b84;--spice-button:#6f3c89;--spice-notification:#6f3c89;--spice-player:#0a0e14;--spice-notification-error:#e22134;--spice-card:#6f3c89;--spice-button-active:#795b84}:root{--background-body:var(--spice-main);--background:var(--spice-main);--background-alt:var(--spice-shadow);--selection:#1c76c5;--text-main:var(--spice-subtext);--text-bright:var(--spice-text);--text-muted:#a9b1ba;--links:#41adff;--focus:#0096bfab;--border:#526980;--code:#ffbe85;--animation-duration:0.1s;--button-base:#0c151c;--button-hover:#040a0f;--scrollbar-thumb:var(--button-hover);--scrollbar-thumb-hover:rgb(0, 0, 0);--form-placeholder:#a9a9a9;--form-text:#fff;--variable:#d941e2;--highlight:#efdb43;--select-arrow:url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E")}#marketplace-readme{-webkit-user-select:text;-moz-user-select:text;user-select:text;font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue","Segoe UI Emoji","Apple Color Emoji","Noto Color Emoji",sans-serif;line-height:1.4;max-width:800px;margin:20px auto;padding:0 10px;word-wrap:break-word;color:#dbdbdb;color:var(--text-main);background:#202b38;background:var(--background-body);text-rendering:optimizeLegibility}#marketplace-readme button{transition:background-color .1s linear,border-color .1s linear,color .1s linear,box-shadow .1s linear,transform .1s ease;transition:background-color var(--animation-duration) linear,border-color var(--animation-duration) linear,color var(--animation-duration) linear,box-shadow var(--animation-duration) linear,transform var(--animation-duration) ease}#marketplace-readme input{transition:background-color .1s linear,border-color .1s linear,color .1s linear,box-shadow .1s linear,transform .1s ease;transition:background-color var(--animation-duration) linear,border-color var(--animation-duration) linear,color var(--animation-duration) linear,box-shadow var(--animation-duration) linear,transform var(--animation-duration) ease}#marketplace-readme textarea{transition:background-color .1s linear,border-color .1s linear,color .1s linear,box-shadow .1s linear,transform .1s ease;transition:background-color var(--animation-duration) linear,border-color var(--animation-duration) linear,color var(--animation-duration) linear,box-shadow var(--animation-duration) linear,transform var(--animation-duration) ease}#marketplace-readme h1{font-size:2.2em;margin-top:0}#marketplace-readme h1,#marketplace-readme h2,#marketplace-readme h3,#marketplace-readme h4,#marketplace-readme h5,#marketplace-readme h6{margin-bottom:12px;margin-top:24px}#marketplace-readme h1{color:#fff;color:var(--text-bright)}#marketplace-readme h2{color:#fff;color:var(--text-bright)}#marketplace-readme h3{color:#fff;color:var(--text-bright)}#marketplace-readme h4{color:#fff;color:var(--text-bright)}#marketplace-readme h5{color:#fff;color:var(--text-bright)}#marketplace-readme h6{color:#fff;color:var(--text-bright)}#marketplace-readme strong{color:#fff;color:var(--text-bright)}#marketplace-readme b,#marketplace-readme h1,#marketplace-readme h2,#marketplace-readme h3,#marketplace-readme h4,#marketplace-readme h5,#marketplace-readme h6,#marketplace-readme strong,#marketplace-readme th{font-weight:600}#marketplace-readme q::before{content:none}#marketplace-readme q::after{content:none}#marketplace-readme blockquote{border-left:4px solid rgba(0,150,191,.6705882353);border-left:4px solid var(--focus);margin:1.5em 0;padding:.5em 1em;font-style:italic}#marketplace-readme q{border-left:4px solid rgba(0,150,191,.6705882353);border-left:4px solid var(--focus);margin:1.5em 0;padding:.5em 1em;font-style:italic}#marketplace-readme blockquote>footer{font-style:normal;border:0}#marketplace-readme blockquote cite{font-style:normal}#marketplace-readme address{font-style:normal}#marketplace-readme a[href^="mailto:"]::before{content:"\1f4e7 "}#marketplace-readme a[href^="tel:"]::before{content:"\1f4de "}#marketplace-readme a[href^="sms:"]::before{content:"\1f4ac "}#marketplace-readme mark{background-color:#efdb43;background-color:var(--highlight);border-radius:2px;padding:0 2px 0 2px;color:#000}#marketplace-readme a>code,#marketplace-readme a>strong{color:inherit}#marketplace-readme button,#marketplace-readme input[type=button],#marketplace-readme input[type=checkbox],#marketplace-readme input[type=radio],#marketplace-readme input[type=range],#marketplace-readme input[type=reset],#marketplace-readme input[type=submit],#marketplace-readme select{cursor:pointer}#marketplace-readme input,#marketplace-readme select{display:block}#marketplace-readme [type=checkbox],#marketplace-readme [type=radio]{display:initial}#marketplace-readme input{color:#fff;color:var(--form-text);background-color:#161f27;background-color:var(--background);font-family:inherit;font-size:inherit;margin-right:6px;margin-bottom:6px;padding:10px;border:none;border-radius:6px;outline:0}#marketplace-readme button{color:#fff;color:var(--form-text);background-color:#161f27;background-color:var(--background);font-family:inherit;font-size:inherit;margin-right:6px;margin-bottom:6px;padding:10px;border:none;border-radius:6px;outline:0}#marketplace-readme textarea{color:#fff;color:var(--form-text);background-color:#161f27;background-color:var(--background);font-family:inherit;font-size:inherit;margin-right:6px;margin-bottom:6px;padding:10px;border:none;border-radius:6px;outline:0}#marketplace-readme select{color:#fff;color:var(--form-text);background-color:#161f27;background-color:var(--background);font-family:inherit;font-size:inherit;margin-right:6px;margin-bottom:6px;padding:10px;border:none;border-radius:6px;outline:0}#marketplace-readme button{background-color:#0c151c;background-color:var(--button-base);padding-right:30px;padding-left:30px}#marketplace-readme input[type=submit]{background-color:#0c151c;background-color:var(--button-base);padding-right:30px;padding-left:30px}#marketplace-readme input[type=reset]{background-color:#0c151c;background-color:var(--button-base);padding-right:30px;padding-left:30px}#marketplace-readme input[type=button]{background-color:#0c151c;background-color:var(--button-base);padding-right:30px;padding-left:30px}#marketplace-readme button:hover{background:#040a0f;background:var(--button-hover)}#marketplace-readme input[type=submit]:hover{background:#040a0f;background:var(--button-hover)}#marketplace-readme input[type=reset]:hover{background:#040a0f;background:var(--button-hover)}#marketplace-readme input[type=button]:hover{background:#040a0f;background:var(--button-hover)}#marketplace-readme input[type=color]{min-height:2rem;padding:8px;cursor:pointer}#marketplace-readme input[type=checkbox],#marketplace-readme input[type=radio]{height:1em;width:1em}#marketplace-readme input[type=radio]{border-radius:100%}#marketplace-readme input{vertical-align:top}#marketplace-readme label{vertical-align:middle;margin-bottom:4px;display:inline-block}#marketplace-readme button,#marketplace-readme input:not([type=checkbox]):not([type=radio]),#marketplace-readme input[type=range],#marketplace-readme select,#marketplace-readme textarea{-webkit-appearance:none}#marketplace-readme textarea{display:block;margin-right:0;box-sizing:border-box;resize:vertical}#marketplace-readme textarea:not([cols]){width:100%}#marketplace-readme textarea:not([rows]){min-height:40px;height:140px}#marketplace-readme select{background:#161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50%/12px no-repeat;background:var(--background) var(--select-arrow) calc(100% - 12px) 50%/12px no-repeat;padding-right:35px}#marketplace-readme select::-ms-expand{display:none}#marketplace-readme select[multiple]{padding-right:10px;background-image:none;overflow-y:auto}#marketplace-readme input:focus{box-shadow:0 0 0 2px rgba(0,150,191,.6705882353);box-shadow:0 0 0 2px var(--focus)}#marketplace-readme select:focus{box-shadow:0 0 0 2px rgba(0,150,191,.6705882353);box-shadow:0 0 0 2px var(--focus)}#marketplace-readme button:focus{box-shadow:0 0 0 2px rgba(0,150,191,.6705882353);box-shadow:0 0 0 2px var(--focus)}#marketplace-readme textarea:focus{box-shadow:0 0 0 2px rgba(0,150,191,.6705882353);box-shadow:0 0 0 2px var(--focus)}#marketplace-readme button:active,#marketplace-readme input[type=button]:active,#marketplace-readme input[type=checkbox]:active,#marketplace-readme input[type=radio]:active,#marketplace-readme input[type=range]:active,#marketplace-readme input[type=reset]:active,#marketplace-readme input[type=submit]:active{transform:translateY(2px)}#marketplace-readme button:disabled,#marketplace-readme input:disabled,#marketplace-readme select:disabled,#marketplace-readme textarea:disabled{cursor:not-allowed;opacity:.5}#marketplace-readme ::-moz-placeholder{color:#a9a9a9;color:var(--form-placeholder)}#marketplace-readme ::placeholder{color:#a9a9a9;color:var(--form-placeholder)}#marketplace-readme fieldset{border:1px rgba(0,150,191,.6705882353) solid;border:1px var(--focus) solid;border-radius:6px;margin:0;margin-bottom:12px;padding:10px}#marketplace-readme legend{font-size:.9em;font-weight:600}#marketplace-readme input[type=range]{margin:10px 0;padding:10px 0;background:0 0}#marketplace-readme input[type=range]:focus{outline:0}#marketplace-readme input[type=range]::-webkit-slider-runnable-track{width:100%;height:9.5px;-webkit-transition:.2s;transition:.2s;background:#161f27;background:var(--background);border-radius:3px}#marketplace-readme input[type=range]::-webkit-slider-thumb{box-shadow:0 1px 1px #000,0 0 1px #0d0d0d;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border);-webkit-appearance:none;margin-top:-7px}#marketplace-readme input[type=range]:focus::-webkit-slider-runnable-track{background:#161f27;background:var(--background)}#marketplace-readme input[type=range]::-moz-range-track{width:100%;height:9.5px;-moz-transition:.2s;transition:.2s;background:#161f27;background:var(--background);border-radius:3px}#marketplace-readme input[type=range]::-moz-range-thumb{box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border)}#marketplace-readme input[type=range]::-ms-track{width:100%;height:9.5px;background:0 0;border-color:transparent;border-width:16px 0;color:transparent}#marketplace-readme input[type=range]::-ms-fill-lower{background:#161f27;background:var(--background);border:.2px solid #010101;border-radius:3px;box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d}#marketplace-readme input[type=range]::-ms-fill-upper{background:#161f27;background:var(--background);border:.2px solid #010101;border-radius:3px;box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d}#marketplace-readme input[type=range]::-ms-thumb{box-shadow:1px 1px 1px #000,0 0 1px #0d0d0d;border:1px solid #000;height:20px;width:20px;border-radius:50%;background:#526980;background:var(--border)}#marketplace-readme input[type=range]:focus::-ms-fill-lower{background:#161f27;background:var(--background)}#marketplace-readme input[type=range]:focus::-ms-fill-upper{background:#161f27;background:var(--background)}#marketplace-readme a{text-decoration:none;color:#41adff;color:var(--links)}#marketplace-readme a:hover{text-decoration:underline}#marketplace-readme code{background:#161f27;background:var(--background);color:#ffbe85;color:var(--code);padding:2.5px 5px;border-radius:6px;font-size:1em}#marketplace-readme samp{background:#161f27;background:var(--background);color:#ffbe85;color:var(--code);padding:2.5px 5px;border-radius:6px;font-size:1em}#marketplace-readme time{background:#161f27;background:var(--background);color:#ffbe85;color:var(--code);padding:2.5px 5px;border-radius:6px;font-size:1em}#marketplace-readme pre>code{padding:10px;display:block;overflow-x:auto}#marketplace-readme var{color:#d941e2;color:var(--variable);font-style:normal;font-family:monospace}#marketplace-readme kbd{background:#161f27;background:var(--background);border:1px solid #526980;border:1px solid var(--border);border-radius:2px;color:#dbdbdb;color:var(--text-main);padding:2px 4px 2px 4px}#marketplace-readme img,#marketplace-readme video{max-width:100%;height:auto}#marketplace-readme hr{border:none;border-top:1px solid #526980;border-top:1px solid var(--border)}#marketplace-readme table{border-collapse:collapse;margin-bottom:10px;width:100%;table-layout:fixed}#marketplace-readme table caption{text-align:left}#marketplace-readme td,#marketplace-readme th{padding:6px;text-align:left;vertical-align:top;word-wrap:break-word}#marketplace-readme thead{border-bottom:1px solid #526980;border-bottom:1px solid var(--border)}#marketplace-readme tfoot{border-top:1px solid #526980;border-top:1px solid var(--border)}#marketplace-readme tbody tr:nth-child(2n){background-color:#161f27;background-color:var(--background)}#marketplace-readme tbody tr:nth-child(2n) button{background-color:#1a242f;background-color:var(--background-alt)}#marketplace-readme tbody tr:nth-child(2n) button:hover{background-color:#202b38;background-color:var(--background-body)}#marketplace-readme ::-webkit-scrollbar{height:10px;width:10px}#marketplace-readme ::-webkit-scrollbar-track{background:#161f27;background:var(--background);border-radius:6px}#marketplace-readme ::-webkit-scrollbar-thumb{background:#040a0f;background:var(--scrollbar-thumb);border-radius:6px}#marketplace-readme ::-webkit-scrollbar-thumb:hover{background:#000;background:var(--scrollbar-thumb-hover)}#marketplace-readme ::-moz-selection{background-color:#1c76c5;background-color:var(--selection);color:#fff;color:var(--text-bright)}#marketplace-readme ::selection{background-color:#1c76c5;background-color:var(--selection);color:#fff;color:var(--text-bright)}#marketplace-readme details{display:flex;flex-direction:column;align-items:flex-start;background-color:#1a242f;background-color:var(--background-alt);padding:10px 10px 0;margin:1em 0;border-radius:6px;overflow:hidden}#marketplace-readme details[open]{padding:10px}#marketplace-readme details>:last-child{margin-bottom:0}#marketplace-readme details[open] summary{margin-bottom:10px}#marketplace-readme summary{display:list-item;background-color:#161f27;background-color:var(--background);padding:10px;margin:-10px -10px 0;cursor:pointer;outline:0}#marketplace-readme summary:focus,#marketplace-readme summary:hover{text-decoration:underline}#marketplace-readme details>:not(summary){margin-top:0}#marketplace-readme summary::-webkit-details-marker{color:#dbdbdb;color:var(--text-main)}#marketplace-readme dialog{background-color:#1a242f;background-color:var(--background-alt);color:#dbdbdb;color:var(--text-main);border:none;border-radius:6px;border-color:#526980;border-color:var(--border);padding:10px 30px}#marketplace-readme dialog>header:first-child{background-color:#161f27;background-color:var(--background);border-radius:6px 6px 0 0;margin:-10px -30px 10px;padding:10px;text-align:center}#marketplace-readme dialog::-webkit-backdrop{background:rgba(0,0,0,.6117647059);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#marketplace-readme dialog::backdrop{background:rgba(0,0,0,.6117647059);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#marketplace-readme footer{border-top:1px solid #526980;border-top:1px solid var(--border);padding-top:10px;color:#a9b1ba;color:var(--text-muted)}#marketplace-readme body>footer{margin-top:40px}@media print{#marketplace-readme body,#marketplace-readme button,#marketplace-readme code,#marketplace-readme details,#marketplace-readme input,#marketplace-readme pre,#marketplace-readme summary,#marketplace-readme textarea{background-color:#fff}#marketplace-readme button,#marketplace-readme input,#marketplace-readme textarea{border:1px solid #000}#marketplace-readme body,#marketplace-readme button,#marketplace-readme code,#marketplace-readme footer,#marketplace-readme h1,#marketplace-readme h2,#marketplace-readme h3,#marketplace-readme h4,#marketplace-readme h5,#marketplace-readme h6,#marketplace-readme input,#marketplace-readme pre,#marketplace-readme strong,#marketplace-readme summary,#marketplace-readme textarea{color:#000}#marketplace-readme summary::marker{color:#000}#marketplace-readme summary::-webkit-details-marker{color:#000}#marketplace-readme tbody tr:nth-child(2n){background-color:#f2f2f2}#marketplace-readme a{color:#00f;text-decoration:underline}}#marketplace-readme code{border:1px solid var(--spice-button-disabled)}#marketplace-readme li,#marketplace-readme ul{list-style-position:inside}#marketplace-readme li li,#marketplace-readme ul li{margin-bottom:8px}#marketplace-readme ul{list-style-type:disc}#marketplace-readme ol{list-style-type:auto}#marketplace-readme code,#marketplace-readme p,#marketplace-readme pre{margin:8px 0}#marketplace-readme pre{overflow-x:auto}#marketplace-readme table{table-layout:auto}#marketplace-readme table td,#marketplace-readme table th{border:1px solid var(--spice-button-disabled)}.GenericModal{background-color:var(--spice-player)}code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,"Andale Mono","Ubuntu Mono",monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.devtools-column{height:570px;width:50%;position:relative;background-color:var(--spice-sidebar);color:var(--spice-text);overflow:scroll;padding:1rem}.color-ini-editor{height:70%;width:100%;background-color:var(--spice-sidebar);color:var(--spice-text);overflow:scroll;padding:1rem;resize:none;font-family:monospace}.marketplace-theme-dev-tools-container{justify-content:flex-end;display:flex}.marketplace-theme-dev-tools-container .marketplace-code-editor-wrapper{height:400px;margin-bottom:16px;overflow:auto}.devtools-heading,.invalid-css-heading{font-size:1.5rem;font-weight:700;text-decoration:underline;margin-bottom:1rem}.invalid-css-text{margin-bottom:1.5rem;font-family:monospace;-webkit-user-select:text;-moz-user-select:text;user-select:text}.devtools-icon{width:18px;fill:var(--spice-button)}.marketplace-code-editor{width:100%;margin-bottom:10px;padding:3px 5px;background-color:var(--spice-main);color:var(--spice-text);font-size:14px;border:1px solid var(--spice-button);border-radius:4px}.button-module__button___hf2qg_marketplace{box-sizing:border-box;font-family:var(--font-family, spotify-circular),Helvetica,Arial,sans-serif;-webkit-tap-highlight-color:transparent;font-size:1rem;line-height:1.5rem;font-weight:700;background-color:transparent;border:0;border-radius:500px;display:inline-block;position:relative;text-align:center;text-decoration:none;text-transform:none;touch-action:manipulation;transition-duration:33ms;transition-property:background-color,border-color,color,box-shadow,filter,transform;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;transform:translate3d(0,0,0);padding:0;min-inline-size:0px;align-self:center;position:relative;background-color:var(--spice-text);color:var(--spice-main);border-radius:500px;font-size:inherit;padding-block:12px;padding-inline:32px}@media screen and (min-width:768px){.button-module__button___hf2qg_marketplace{font-size:1rem;line-height:1.5rem;text-transform:none;letter-spacing:normal}}.button-module__button___hf2qg_marketplace:hover{transform:scale(1.04)}.button-module__button___hf2qg_marketplace:active{background-color:var(--spice-subtext);box-shadow:none;transform:scale(1)}.button-module__button___hf2qg_marketplace:disabled{opacity:.5;cursor:not-allowed}.button-module__circle___EZ88P_marketplace{padding-inline:16px;width:48px;height:48px}.button-module__circle___EZ88P_marketplace svg{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.toggle-module__toggle-wrapper___ocE5z_marketplace{display:inline-flex;position:relative;align-items:center;cursor:pointer}.toggle-module__disabled___OYAYf_marketplace{opacity:0;pointer-events:none}.toggle-module__toggle-input___ceLM4_marketplace{opacity:0;pointer-events:none;position:absolute}.toggle-module__toggle-input___ceLM4_marketplace:checked~.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace{background-color:var(--spice-text)}.toggle-module__toggle-input___ceLM4_marketplace:checked~.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace .toggle-module__toggle-indicator___nCxwE_marketplace{background-color:#fff;left:auto;right:2px;right:3px}.toggle-module__toggle-input___ceLM4_marketplace:hover~.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace{filter:brightness(1.3)}.toggle-module__toggle-input___ceLM4_marketplace:hover:checked~.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace{filter:brightness(1.15)}.toggle-module__toggle-input___ceLM4_marketplace:active:not([disabled])~.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace .toggle-module__toggle-indicator___nCxwE_marketplace{width:20px}.toggle-module__toggle-indicator-wrapper___6Lcp0_marketplace{background-color:#535353;border-radius:24px;height:24px;position:relative;width:42px}.toggle-module__toggle-indicator___nCxwE_marketplace{background:#fff;border-radius:inherit;height:20px;left:2px;position:absolute;top:2px;transition:background-color,left,right,width .1s ease;width:20px;height:18px;width:18px;top:3px;left:3px;background:var(--spice-shadow)!important} \ No newline at end of file diff --git a/config/spicetify/Extensions/catppuccin-frappe.js b/config/spicetify/Extensions/catppuccin-frappe.js new file mode 100644 index 0000000..504bb16 --- /dev/null +++ b/config/spicetify/Extensions/catppuccin-frappe.js @@ -0,0 +1,40 @@ +// Color map +let colorPalette = { + rosewater: "#f2d5cf", + flamingo: "#eebebe", + pink: "#f4b8e4", + maroon: "#ea999c", + red: "#e78284", + peach: "#ef9f76", + yellow: "#e5c890", + green: "#a6d189", + teal: "#81c8be", + blue: "#8caaee", + sky: "#99dadb", + lavender: "#babbf1", + white: "#c6d0f5", + mauve: "#ca9ee6" +} + +// waitForElement borrowed from: +// https://github.com/morpheusthewhite/spicetify-themes/blob/master/Dribbblish/dribbblish.js +function waitForElement(els, func, timeout = 100) { + const queries = els.map(el => document.querySelector(el)); + if (queries.every(a => a)) { + func(queries); + } else if (timeout > 0) { + setTimeout(waitForElement, 300, els, func, --timeout); + } +} + +// Return the color label for a given hex color value +function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value.trim()); +} + +// Used to select matching equalizer-animated-COLOR.gif +waitForElement([".Root"], (root) => { + let spiceEq = getComputedStyle(document.querySelector(":root")).getPropertyValue("--spice-equalizer"); + let eqColor = getKeyByValue(colorPalette, spiceEq); + root[0].classList.add(`catppuccin-eq-${eqColor}`); +}); diff --git a/config/spicetify/Extensions/catppuccin-latte.js b/config/spicetify/Extensions/catppuccin-latte.js new file mode 100644 index 0000000..561c385 --- /dev/null +++ b/config/spicetify/Extensions/catppuccin-latte.js @@ -0,0 +1,39 @@ +// Color map +let colorPalette = { + rosewater: "#dc8a78", + flamingo: "#dd7878", + pink: "#ea76cb", + maroon: "#e64553", + red: "#d20f39", + peach: "#fe640b", + yellow: "#df8e1d", + green: "#40a02b", + teal: "#179299", + blue: "#1e66f5", + sky: "#04a5e5", + lavender: "#7287fd", + white: "#d9e0ee" +} + +// waitForElement borrowed from: +// https://github.com/morpheusthewhite/spicetify-themes/blob/master/Dribbblish/dribbblish.js +function waitForElement(els, func, timeout = 100) { + const queries = els.map(el => document.querySelector(el)); + if (queries.every(a => a)) { + func(queries); + } else if (timeout > 0) { + setTimeout(waitForElement, 300, els, func, --timeout); + } +} + +// Return the color label for a given hex color value +function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value.trim()); +} + +// Used to select matching equalizer-animated-COLOR.gif +waitForElement([".Root"], (root) => { + let spiceEq = getComputedStyle(document.querySelector(":root")).getPropertyValue("--spice-equalizer"); + let eqColor = getKeyByValue(colorPalette, spiceEq); + root[0].classList.add(`catppuccin-eq-${eqColor}`); +}); diff --git a/config/spicetify/Extensions/catppuccin-macchiato.js b/config/spicetify/Extensions/catppuccin-macchiato.js new file mode 100644 index 0000000..b0c536c --- /dev/null +++ b/config/spicetify/Extensions/catppuccin-macchiato.js @@ -0,0 +1,39 @@ +// Color map +let colorPalette = { + rosewater: "#f4dbd6", + flamingo: "#f0c6c6", + pink: "#f5bde6", + maroon: "#ee99a0", + red: "#ed8796", + peach: "#f5a97f", + yellow: "#eed49f", + green: "#a6da95", + teal: "#8bd5ca", + blue: "#8aadf4", + sky: "#91d7e3", + lavender: "#b7bdf8", + white: "#d9e0ee" +} + +// waitForElement borrowed from: +// https://github.com/morpheusthewhite/spicetify-themes/blob/master/Dribbblish/dribbblish.js +function waitForElement(els, func, timeout = 100) { + const queries = els.map(el => document.querySelector(el)); + if (queries.every(a => a)) { + func(queries); + } else if (timeout > 0) { + setTimeout(waitForElement, 300, els, func, --timeout); + } +} + +// Return the color label for a given hex color value +function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value.trim()); +} + +// Used to select matching equalizer-animated-COLOR.gif +waitForElement([".Root"], (root) => { + let spiceEq = getComputedStyle(document.querySelector(":root")).getPropertyValue("--spice-equalizer"); + let eqColor = getKeyByValue(colorPalette, spiceEq); + root[0].classList.add(`catppuccin-eq-${eqColor}`); +}); diff --git a/config/spicetify/Extensions/catppuccin-mocha.js b/config/spicetify/Extensions/catppuccin-mocha.js new file mode 100644 index 0000000..f752f38 --- /dev/null +++ b/config/spicetify/Extensions/catppuccin-mocha.js @@ -0,0 +1,39 @@ +// Color map +let colorPalette = { + rosewater: "#f5e0dc", + flamingo: "#f2cdcd", + pink: "#f5c2e7", + maroon: "#eba0ac", + red: "#f38ba8", + peach: "#fab387", + yellow: "#f9e2af", + green: "#a6e3a1", + teal: "#94e2d5", + blue: "#89b4fa", + sky: "#89dceb", + lavender: "#b4befe", + white: "#d9e0ee" +} + +// waitForElement borrowed from: +// https://github.com/morpheusthewhite/spicetify-themes/blob/master/Dribbblish/dribbblish.js +function waitForElement(els, func, timeout = 100) { + const queries = els.map(el => document.querySelector(el)); + if (queries.every(a => a)) { + func(queries); + } else if (timeout > 0) { + setTimeout(waitForElement, 300, els, func, --timeout); + } +} + +// Return the color label for a given hex color value +function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value.trim()); +} + +// Used to select matching equalizer-animated-COLOR.gif +waitForElement([".Root"], (root) => { + let spiceEq = getComputedStyle(document.querySelector(":root")).getPropertyValue("--spice-equalizer"); + let eqColor = getKeyByValue(colorPalette, spiceEq); + root[0].classList.add(`catppuccin-eq-${eqColor}`); +}); diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-blue.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-blue.gif new file mode 100644 index 0000000..704bf99 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-blue.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-flamingo.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-flamingo.gif new file mode 100644 index 0000000..0fc9a0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-flamingo.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-green.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-green.gif new file mode 100644 index 0000000..9408c38 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-green.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-lavender.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-lavender.gif new file mode 100644 index 0000000..f176ee6 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-lavender.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-maroon.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-maroon.gif new file mode 100644 index 0000000..1c21876 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-maroon.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-mauve.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-mauve.gif new file mode 100644 index 0000000..a5daf0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-mauve.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-peach.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-peach.gif new file mode 100644 index 0000000..d8d4ce7 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-peach.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-pink.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-pink.gif new file mode 100644 index 0000000..e8f4ffa Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-pink.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-red.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-red.gif new file mode 100644 index 0000000..7191693 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-red.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-rosewater.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-rosewater.gif new file mode 100644 index 0000000..6e76160 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-rosewater.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-sky.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-sky.gif new file mode 100644 index 0000000..c267dab Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-sky.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-teal.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-teal.gif new file mode 100644 index 0000000..58d9939 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-teal.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-white.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-white.gif new file mode 100644 index 0000000..cf37197 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-white.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-yellow.gif b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-yellow.gif new file mode 100644 index 0000000..45d1592 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-frappe/assets/equalizer-animated-yellow.gif differ diff --git a/config/spicetify/Themes/catppuccin-frappe/color.ini b/config/spicetify/Themes/catppuccin-frappe/color.ini new file mode 100644 index 0000000..de0d7aa --- /dev/null +++ b/config/spicetify/Themes/catppuccin-frappe/color.ini @@ -0,0 +1,265 @@ +[rosewater] +text = F2D5CF +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = F2D5CF +misc = 626880 + +[flamingo] +text = EEBEBE +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = EEBEBE +misc = 626880 + +[mauve] +text = CA9EE6 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = CA9EE6 +misc = 626880 + +[pink] +text = F4B8E4 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = F4B8E4 +misc = 686880 + +[maroon] +text = EA999C +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = EA999C +misc = 686880 + +[red] +text = E78284 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = E78284 +misc = 686880 + +[peach] +text = EF9F76 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = EF9F76 +misc = 686880 + +[yellow] +text = E5C890 +subtext = C6D0D5 +accent = 8CAAEE +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = E5C890 +misc = 686880 + +[green] +text = A6D189 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = A6D189 +misc = 686880 + +[teal] +text = 81C8BE +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = 81C8BE +misc = 686880 + +[blue] +text = 8CAAEE +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = 8CAAEE +misc = 686880 + +[sky] +text = 99D1DB +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = 99D1DB +misc = 686880 + +[lavender] +text = BABBF1 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = BABBF1 +misc = 686880 + +[white] +text = C6D0F5 +subtext = C6D0D5 +accent = E5C890 +main = 303446 +sidebar = 292C3C +player = 232634 +card = 232634 +shadow = 292C3C +selected-row = 626880 +button = 838BA7 +button-active = 949CBB +button-disabled = 737994 +tab-active = 414559 +notification = 414559 +notification-error = E78284 +equalizer = C6D0F5 +misc = 686880 diff --git a/config/spicetify/Themes/catppuccin-frappe/user.css b/config/spicetify/Themes/catppuccin-frappe/user.css new file mode 100644 index 0000000..6076ae6 --- /dev/null +++ b/config/spicetify/Themes/catppuccin-frappe/user.css @@ -0,0 +1,272 @@ +/* Color Pallette */ +/* Note: These variables should be used ONLY when needed across ALL of the color palettes. */ +:root { + /* Morning */ + --flamingo: #eebebe; + --mauve: #ca9ee6; + --pink: #f4b8e4; + --maroon: #ea999c; + --red: #e78284; + --peach: #ef9f76; + --yellow: #e5c890; + --green: #a6d189; + --teal: #81c8be; + --blue: #8caaee; + --sky: #99dadb; + /* Night */ + /* --black-0: #161320; */ + --crust: #232634; + /* --black-1: #1A1826; */ + --mantle: #292c3c; + /* --black-2: #1E1E2E; */ + --base: #303446; + /* --black-3: #302D41; */ + --surface0: #414559; + /* --black-4: #575268; */ + --surface1: #51576d; + /* --gray-0: #6E6C7E; */ + --overlay0: #737994; + /* --gray-1: #988BA2; */ + ---overlay1: #838ba7; + /* --gray-2: #C3BAC6; */ + --overlay2: #949cbb; + /* --white: #D9E0EE; */ + --white: #c6d0f5; + --lavender: #babbf1; + --rosewater: #f2d5cf; +} + +/* Buttons */ +.main-playButton-PlayButton.main-playButton-primary { + color: var(--spice-player); +} + +.main-button-primary { + background-color: var(--spice-main); +} +.main-button-primary:active, +.main-button-primary:focus, +.main-button-primary:hover { + background-color: var(--spice-sidebar); +} + +.main-view-container button:hover > div[class^='ButtonInner-sc-'] { + background-color: var(--spice-button); +} + +.control-button-heart[aria-checked="true"], +.main-addButton-active, +.main-addButton-active:focus, +.main-addButton-active:hover { + color: var(--red); +} + +.main-addButton-active:hover { + -webkit-transform: scale(1.06); + transform: scale(1.06); +} + +/* Progress bar */ +.x-progressBar-progressBarBg > div > div { + background-color: var(--spice-text); +} + +/* Top bars */ +.main-entityHeader-backgroundColor, +.main-actionBarBackground-background, +.main-view-container main[aria-label="Spotify – Web Player"] > div:first-child { + display: none; +} + +.main-topBar-background { + background-color: var(--spice-main) !important; +} + +.main-entityHeader-withBackgroundImage { + background-color: rgba(var(--spice-rgb-player), 0.2); +} + +/* Sidebar */ +.main-navBar-navBar li:hover > div, +.main-navBar-navBar li:hover > a:not(.main-navBar-navBarLinkActive), +.spicetify-playlist-list li:hover { + background-color: var(--spice-main); +} + +#spicetify-sticky-list li:hover > div { + border-radius: 4px; +} + +/* Scrollbar */ +.os-theme-spotify > .os-scrollbar-horizontal, +.os-theme-spotify > .os-scrollbar-vertical { + padding: 4px; +} + +.os-theme-spotify.os-host-transition + > .os-scrollbar-horizontal + > .os-scrollbar-track + > .os-scrollbar-handle, +.os-theme-spotify.os-host-transition + > .os-scrollbar-vertical + > .os-scrollbar-track + > .os-scrollbar-handle { + background-color: var(--decorative-base); + border-radius: 6px; +} + +::-webkit-scrollbar { + width: 0.5em; +} +::-webkit-scrollbar-thumb { + background-color: #575268; + border-radius: 4px; +} + +/* Home */ +.main-home-homeHeader { + display: none; +} + +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div { + background-color: var(--spice-card); +} +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div:hover { + background-color: var(--spice-misc); +} + +.main-gridContainer-gridContainer > div, +.main-gridContainer-gridContainer > div > div > div { + border-radius: 6px; +} + +/* Cards */ +.main-card-card { + border-radius: 6px; +} + +.main-card-imageContainer { + margin: -16px -16px 16px -16px; +} + +.main-cardImage-imageWrapper, +.main-cardImage-image { + border-radius: 6px 6px 0 0; +} + +/* Settings */ +input:checked~.x-toggle-indicatorWrapper { + background-color: var(---overlay1); +} + +input:hover:not([disabled]):not(:active)~.x-toggle-indicatorWrapper { + background-color: var(--spice-button-active); +} + +select option:checked { + color: var(--spice-text); + font-weight: bold; +} + +/* Animated equalizer */ +/* EQ color classes are specified here in case the js extension is not moved over + * The default green eq will be used in this case */ +.catppuccin-eq-rosewater .main-trackList-playingIcon, +.catppuccin-eq-flamingo .main-trackList-playingIcon, +.catppuccin-eq-mauve .main-trackList-playingIcon, +.catppuccin-eq-pink .main-trackList-playingIcon, +.catppuccin-eq-maroon .main-trackList-playingIcon, +.catppuccin-eq-red .main-trackList-playingIcon, +.catppuccin-eq-peach .main-trackList-playingIcon, +.catppuccin-eq-yellow .main-trackList-playingIcon, +.catppuccin-eq-green .main-trackList-playingIcon, +.catppuccin-eq-teal .main-trackList-playingIcon, +.catppuccin-eq-blue .main-trackList-playingIcon, +.catppuccin-eq-sky .main-trackList-playingIcon, +.catppuccin-eq-lavender .main-trackList-playingIcon, +.catppuccin-eq-white .main-trackList-playingIcon { + background-size: cover; + padding-left: 100%; +} + +.catppuccin-eq-rosewater .main-trackList-playingIcon { + background-image: url("equalizer-animated-rosewater.gif"); +} +.catppuccin-eq-flamingo .main-trackList-playingIcon { + background-image: url("equalizer-animated-flamingo.gif"); +} +.catppuccin-eq-mauve .main-trackList-playingIcon { + background-image: url("equalizer-animated-mauve.gif"); +} +.catppuccin-eq-pink .main-trackList-playingIcon { + background-image: url("equalizer-animated-pink.gif"); +} +.catppuccin-eq-maroon .main-trackList-playingIcon { + background-image: url("equalizer-animated-maroon.gif"); +} +.catppuccin-eq-red .main-trackList-playingIcon { + background-image: url("equalizer-animated-red.gif"); +} +.catppuccin-eq-peach .main-trackList-playingIcon { + background-image: url("equalizer-animated-peach.gif"); +} +.catppuccin-eq-yellow .main-trackList-playingIcon { + background-image: url("equalizer-animated-yellow.gif"); +} +.catppuccin-eq-green .main-trackList-playingIcon { + background-image: url("equalizer-animated-green.gif"); +} +.catppuccin-eq-teal .main-trackList-playingIcon { + background-image: url("equalizer-animated-teal.gif"); +} +.catppuccin-eq-blue .main-trackList-playingIcon { + background-image: url("equalizer-animated-blue.gif"); +} +.catppuccin-eq-sky .main-trackList-playingIcon { + background-image: url("equalizer-animated-sky.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-lavender.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-white.gif"); +} + +/* For that small dot on podcasts that notify us of new episodes */ +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div + span[aria-label], +span[aria-label="New episode"], +span[aria-label="New Podcast Episode"] { + background: var(--spice-accent, var(--spice-text)); +} + +/* Modals */ +.GenericModal[aria-label="Already added"] > div { + background-color: var(--spice-card); + color: var(--spice-subtext); +} + +.GenericModal[aria-label="Already added"] button:first-child { + color: var(--spice-button-active); +} + +.GenericModal[aria-label="Already added"] button:first-child:hover { + color: var(--spice-notification-error); +} + +.GenericModal[aria-label="Already added"] button:last-child:hover > div { + background-color: var(--spice-button); +} + +.main-rootlist-rootlistItemLink:link, .main-rootlist-rootlistItemLink:visited { + z-index: 1; +} diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-blue.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-blue.gif new file mode 100644 index 0000000..ffebb7f Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-blue.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-flamingo.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-flamingo.gif new file mode 100644 index 0000000..b827742 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-flamingo.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-green.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-green.gif new file mode 100644 index 0000000..2c17f49 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-green.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-lavender.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-lavender.gif new file mode 100644 index 0000000..18d3c2d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-lavender.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-maroon.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-maroon.gif new file mode 100644 index 0000000..b619eab Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-maroon.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-mauve.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-mauve.gif new file mode 100644 index 0000000..2de2004 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-mauve.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-peach.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-peach.gif new file mode 100644 index 0000000..79c5e2e Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-peach.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-pink.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-pink.gif new file mode 100644 index 0000000..df8949e Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-pink.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-red.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-red.gif new file mode 100644 index 0000000..0c710e4 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-red.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-rosewater.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-rosewater.gif new file mode 100644 index 0000000..577a4fc Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-rosewater.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-sky.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-sky.gif new file mode 100644 index 0000000..05473fc Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-sky.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-teal.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-teal.gif new file mode 100644 index 0000000..9fbbe5e Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-teal.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-yellow.gif b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-yellow.gif new file mode 100644 index 0000000..392d8ed Binary files /dev/null and b/config/spicetify/Themes/catppuccin-latte/assets/equalizer-animated-yellow.gif differ diff --git a/config/spicetify/Themes/catppuccin-latte/color.ini b/config/spicetify/Themes/catppuccin-latte/color.ini new file mode 100644 index 0000000..63f4442 --- /dev/null +++ b/config/spicetify/Themes/catppuccin-latte/color.ini @@ -0,0 +1,246 @@ +[rosewater] +text = DC8A78 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = DC8A78 +misc = ACB0BE + +[flamingo] +text = DD7878 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = DD7878 +misc = ACB0BE + +[mauve] +text = 8839EF +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 8839EF +misc = ACB0BE + +[pink] +text = EA76CB +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = EA76CB +misc = ACB0BE + +[maroon] +text = E64553 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = E64553 +misc = ACB0BE + +[red] +text = D20F39 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = D20F39 +misc = ACB0BE + +[peach] +text = FE640B +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = FE640B +misc = ACB0BE + +[yellow] +text = DF8E1D +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = DF8E1D +misc = ACB0BE + +[green] +text = 40A02B +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 40A02B +misc = ACB0BE + +[teal] +text = 179299 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 179299 +misc = ACB0BE + +[blue] +text = 1E66F5 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 1E66F5 +misc = ACB0BE + +[sky] +text = 04A5E5 +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 04A5E5 +misc = ACB0BE + +[lavender] +text = 7287FD +subtext = 4C4F69 +accent = FAE3B0 +main = EFF1F5 +sidebar = E6E9EF +player = DCE0E8 +card = CCD0DA +shadow = E6E9EF +selected-row = ACB0BE +button = 8C8FA1 +button-active = 7C7F93 +button-disabled = 9CA0B0 +tab-active = DDC0DA +notification = DDC0DA +notification-error = D20F39 +equalizer = 7287FD +misc = ACB0BE diff --git a/config/spicetify/Themes/catppuccin-latte/user.css b/config/spicetify/Themes/catppuccin-latte/user.css new file mode 100644 index 0000000..197588c --- /dev/null +++ b/config/spicetify/Themes/catppuccin-latte/user.css @@ -0,0 +1,325 @@ +/* Color Pallette */ +/* Note: These variables should be used ONLY when needed across ALL of the color palettes. */ +:root { + /* Morning */ + --flamingo: #dd7878; + --mauve: #8839ef; + --pink: #ea76cb; + --maroon: #e64553; + --red: #d20f39; + --peach: #fe640b; + --yellow: #df8e1d; + --green: #40a02b; + --teal: #179299; + --blue: #1e66f5; + --sky: #04a5e5; + /* Night */ + /* --black-0: #161320; */ + --crust: #dce0e8; + /* --black-1: #1A1826; */ + --mantle: #e6e9ef; + /* --black-2: #1E1E2E; */ + --base: #eff1f5; + /* --black-3: #302D41; */ + --surface0: #ccd0da; + /* --black-4: #575268; */ + --surface1: #bcc0cc; + /* --gray-0: #6E6C7E; */ + --overlay0: #9ca0b0; + /* --gray-1: #988BA2; */ + ---overlay1: #8c8fa1; + /* --gray-2: #C3BAC6; */ + --overlay2: #7c7f93; + /* --white: #D9E0EE; */ + --text: #4c4f69; + --lavender: #7287fd; + --rosewater: #dc8a78; +} + +/* * { */ +/* color: var(--text); */ +/* } */ + +.button { + color: var(--text); +} + +/* Buttons */ +.main-playButton-PlayButton.main-playButton-primary { + color: var(--spice-player); +} +.main-actionBar-ActionBar.contentSpacing { + color: var(--text); +} +/* .wCl7pMTEE68v1xuZeZiB */ +.main-actionBar-ActionBarRow > div > .button { + color: var(--text); +} + +.HbKLiGoYM4dpuK8L4TMX, .Svg-sc-1bi12j5-0.jgfuCe.X1lXSiVj0pzhQCUo_72A, .main-moreButton-button, .wCl7pMTEE68v1xuZeZiB, .w6j_vX6SF5IxSXrrkYw5 { + color: var(--text); + +} + +.main-actionBar-ActionBarRow > div > .input::placeholder { + color: var(--text); +} +/* Skip button, Forward button, repeat, karoke, lyrics, spotify-connect, volume */ +.main-skipBackButton-button, .main-skipForwardButton-button, .main-repeatButton-button, .ZMXGDTbwxKJhbmEDZlYy.control-button, .Button-sc-1dqy6lx-0.hyWUsx, .control-button.iUSAh1wdhXLk9hHSbkCA, .volume-bar__icon-button.control-button { + color: var(--text); +} + +.Type__TypeElement-goli3j-0.cpSTHq.playback-bar__progress-time-elapsed, .Type__TypeElement-goli3j-0 cpSTHq main-playbackBarRemainingTime-container { + color: var(--text); +} +/* Search bar placeholder */ +.QZhV0hWVKlExlKr266jo::placeholder { + color: var(--text); +} +div.context-menu { + background-color: var(--crust); +} +.main-button-primary { + background-color: var(--spice-main); +} +.main-button-primary:active, +.main-button-primary:focus, +.main-button-primary:hover { + background-color: var(--spice-sidebar); +} + +.main-view-container button:hover > div[class^='ButtonInner-sc-'] { + background-color: var(--spice-button); +} + +.control-button-heart[aria-checked="true"], +.main-addButton-active, +.main-addButton-active:focus, +.main-addButton-active:hover { + color: var(--red); +} + +.main-addButton-active:hover { + -webkit-transform: scale(1.06); + transform: scale(1.06); +} +.QZhV0hWVKlExlKr266jo { + color: var(--text); +} +/* Progress bar */ +.x-progressBar-progressBarBg > div > div { + background-color: var(--spice-text); +} + +/* Top bars */ +.main-entityHeader-backgroundColor, +.main-actionBarBackground-background, +.main-view-container main[aria-label="Spotify – Web Player"] > div:first-child { + display: none; +} + +.main-topBar-background { + background-color: var(--spice-main) !important; +} + +.main-entityHeader-withBackgroundImage { + background-color: rgba(var(--spice-rgb-player), 0.2); +} + +/* Sidebar */ +.main-navBar-navBar li:hover > div, +.main-navBar-navBar li:hover > a:not(.main-navBar-navBarLinkActive), +.spicetify-playlist-list li:hover { + background-color: var(--spice-main); +} + +#spicetify-sticky-list li:hover > div { + border-radius: 4px; +} +/* div.jb9xD5ECTqKFK02qe3HZ { + background-color: var(--mantle); +} */ + +p.Type__TypeElement-goli3j-0.gAmaez.fUYMR7LuRXv0KJWFvRZA { + color: var(--spice-text); +} +span.UyzJidwrGk3awngSGIwv, .main-tag-container, .Type__TypeElement-goli3j-0.ebHsEf { + color: var(--spice-text); +} + + +/* Scrollbar */ +.os-theme-spotify > .os-scrollbar-horizontal, +.os-theme-spotify > .os-scrollbar-vertical { + padding: 4px; +} + +.os-theme-spotify.os-host-transition + > .os-scrollbar-horizontal + > .os-scrollbar-track + > .os-scrollbar-handle, +.os-theme-spotify.os-host-transition + > .os-scrollbar-vertical + > .os-scrollbar-track + > .os-scrollbar-handle { + background-color: var(--decorative-base); + border-radius: 6px; +} + +::-webkit-scrollbar { + width: 0.5em; +} +::-webkit-scrollbar-thumb { + background-color: #575268; + border-radius: 4px; +} + +/* Home */ +.main-home-homeHeader { + display: none; +} + +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div { + background-color: var(--spice-card); +} +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div:hover { + background-color: var(--spice-misc); +} + +.main-gridContainer-gridContainer > div, +.main-gridContainer-gridContainer > div > div > div { + border-radius: 6px; +} + +/* Cards */ +.main-card-card { + border-radius: 6px; + background-color: var(--mantle); +} + +.main-card-imageContainer { + margin: -16px -16px 16px -16px; +} + +.main-cardImage-imageWrapper, +.main-cardImage-image { + border-radius: 6px 6px 0 0; +} + +/* Settings */ +input:checked~.x-toggle-indicatorWrapper { + /* background-color: var(---overlay1); */ + background-color: var(--text); +} + +input:hover:not([disabled]):not(:active)~.x-toggle-indicatorWrapper { + background-color: var(--spice-button-active); +} + +select option:checked { + color: var(--spice-text); + font-weight: bold; +} + +/* Animated equalizer */ +/* EQ color classes are specified here in case the js extension is not moved over + * The default green eq will be used in this case */ +.catppuccin-eq-rosewater .main-trackList-playingIcon, +.catppuccin-eq-flamingo .main-trackList-playingIcon, +.catppuccin-eq-mauve .main-trackList-playingIcon, +.catppuccin-eq-pink .main-trackList-playingIcon, +.catppuccin-eq-maroon .main-trackList-playingIcon, +.catppuccin-eq-red .main-trackList-playingIcon, +.catppuccin-eq-peach .main-trackList-playingIcon, +.catppuccin-eq-yellow .main-trackList-playingIcon, +.catppuccin-eq-green .main-trackList-playingIcon, +.catppuccin-eq-teal .main-trackList-playingIcon, +.catppuccin-eq-blue .main-trackList-playingIcon, +.catppuccin-eq-sky .main-trackList-playingIcon, +.catppuccin-eq-lavender .main-trackList-playingIcon, +.catppuccin-eq-white .main-trackList-playingIcon { + background-size: cover; + padding-left: 100%; +} + +.catppuccin-eq-rosewater .main-trackList-playingIcon { + background-image: url("equalizer-animated-rosewater.gif"); +} +.catppuccin-eq-flamingo .main-trackList-playingIcon { + background-image: url("equalizer-animated-flamingo.gif"); +} +.catppuccin-eq-mauve .main-trackList-playingIcon { + background-image: url("equalizer-animated-mauve.gif"); +} +.catppuccin-eq-pink .main-trackList-playingIcon { + background-image: url("equalizer-animated-pink.gif"); +} +.catppuccin-eq-maroon .main-trackList-playingIcon { + background-image: url("equalizer-animated-maroon.gif"); +} +.catppuccin-eq-red .main-trackList-playingIcon { + background-image: url("equalizer-animated-red.gif"); +} +.catppuccin-eq-peach .main-trackList-playingIcon { + background-image: url("equalizer-animated-peach.gif"); +} +.catppuccin-eq-yellow .main-trackList-playingIcon { + background-image: url("equalizer-animated-yellow.gif"); +} +.catppuccin-eq-green .main-trackList-playingIcon { + background-image: url("equalizer-animated-green.gif"); +} +.catppuccin-eq-teal .main-trackList-playingIcon { + background-image: url("equalizer-animated-teal.gif"); +} +.catppuccin-eq-blue .main-trackList-playingIcon { + background-image: url("equalizer-animated-blue.gif"); +} +.catppuccin-eq-sky .main-trackList-playingIcon { + background-image: url("equalizer-animated-sky.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-lavender.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-white.gif"); +} + +/* For that small dot on podcasts that notify us of new episodes */ +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div + span[aria-label], +span[aria-label="New episode"], +span[aria-label="New Podcast Episode"] { + background: var(--spice-accent, var(--spice-text)); +} + +/* Modals */ +.GenericModal[aria-label="Already added"] > div { + background-color: var(--spice-card); + color: var(--spice-subtext); +} + +.GenericModal[aria-label="Already added"] button:first-child { + color: var(--spice-button-active); +} + +.GenericModal[aria-label="Already added"] button:first-child:hover { + color: var(--spice-notification-error); +} + +.GenericModal[aria-label="Already added"] button:last-child:hover > div { + background-color: var(--spice-button); +} + +.main-rootlist-rootlistItemLink:link, .main-rootlist-rootlistItemLink:visited { + z-index: 1; +} diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-blue.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-blue.gif new file mode 100644 index 0000000..704bf99 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-blue.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-flamingo.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-flamingo.gif new file mode 100644 index 0000000..0fc9a0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-flamingo.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-green.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-green.gif new file mode 100644 index 0000000..9408c38 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-green.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-lavender.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-lavender.gif new file mode 100644 index 0000000..f176ee6 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-lavender.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-maroon.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-maroon.gif new file mode 100644 index 0000000..1c21876 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-maroon.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-mauve.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-mauve.gif new file mode 100644 index 0000000..a5daf0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-mauve.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-peach.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-peach.gif new file mode 100644 index 0000000..d8d4ce7 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-peach.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-pink.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-pink.gif new file mode 100644 index 0000000..e8f4ffa Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-pink.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-red.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-red.gif new file mode 100644 index 0000000..7191693 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-red.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-rosewater.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-rosewater.gif new file mode 100644 index 0000000..6e76160 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-rosewater.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-sky.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-sky.gif new file mode 100644 index 0000000..c267dab Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-sky.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-teal.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-teal.gif new file mode 100644 index 0000000..58d9939 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-teal.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-white.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-white.gif new file mode 100644 index 0000000..cf37197 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-white.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-yellow.gif b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-yellow.gif new file mode 100644 index 0000000..45d1592 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-macchiato/assets/equalizer-animated-yellow.gif differ diff --git a/config/spicetify/Themes/catppuccin-macchiato/color.ini b/config/spicetify/Themes/catppuccin-macchiato/color.ini new file mode 100644 index 0000000..6679f14 --- /dev/null +++ b/config/spicetify/Themes/catppuccin-macchiato/color.ini @@ -0,0 +1,234 @@ +[rosewater] +text = F4DBD6 +subtext = CAD3F5 +accent = FAE3B0 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = F4DBD6 +misc = 5B6078 + +[flamingo] +text = F0C6C6 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = F0C6C6 +misc = 585B70 + +[mauve] +text = C6A0F6 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = C6A0F6 +misc = 585B70 + +[pink] +text = F5BDE6 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = F5BDE6 +misc = 585B70 + +[maroon] +text = EE99A0 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = EE99A0 +misc = 585B70 + +[red] +text = ED8796 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = ED8796 +misc = 585B70 + +[peach] +text = F5A97F +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = F5A97F +misc = 585B70 + +[yellow] +text = EED49F +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = EED49F +misc = 585B70 + +[green] +text = A6DA95 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = A6DA95 +misc = 585B70 + +[teal] +text = 8BD5CA +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = 8BD5CA +misc = 585B70 + +[blue] +text = 8AADF4 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = 8AADF4 +misc = 585B70 + +[sky] +text = 91D7E3 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = 91D7E3 +misc = 585B70 + +[lavender] +text = B7BDF8 +subtext = CAD3F5 +main = 24273A +sidebar = 1E2030 +player = 181926 +card = 363A4F +shadow = 1E2030 +selected-row = 5B6078 +button = 8087A2 +button-active = 939AB7 +button-disabled = 6E738D +tab-active = 363A4F +notification = 363A4F +notification-error = ED8796 +equalizer = B7BDF8 +misc = 585B70 diff --git a/config/spicetify/Themes/catppuccin-macchiato/user.css b/config/spicetify/Themes/catppuccin-macchiato/user.css new file mode 100644 index 0000000..cfe66b4 --- /dev/null +++ b/config/spicetify/Themes/catppuccin-macchiato/user.css @@ -0,0 +1,274 @@ +/* Color Pallette */ +/* Note: These variables should be used ONLY when needed across ALL of the color palettes. */ +:root { + /* Morning */ + --flamingo: #f0c6c6; + --mauve: #c6a0f6; + --pink: #f5bde6; + --maroon: #ee99a0; + --red: #ed8796; + --peach: #f5a97f; + --yellow: #eed49f; + /* --yellow: #FAE3B0; */ + --green: #a6da95; + --teal: #8bd5ca; + --blue: #8aadf4; + --sky: #91d7e3; + /* Night */ + /* --black-0: #161320; */ + --crust: #181926; + /* --black-1: #1A1826; */ + --mantle: #1e2030; + /* --black-2: #1E1E2E; */ + --base: #24273a; + /* --black-3: #302D41; */ + --surface0: #363a4f; + /* --black-4: #575268; */ + --surface1: #494d64; + /* --gray-0: #6E6C7E; */ + --overlay0: #6e738d; + /* --gray-1: #988BA2; */ + ---overlay1: #8087a2; + /* --gray-2: #C3BAC6; */ + --overlay2: #939ab7; + /* --white: #D9E0EE; */ + --text: #cad3f5; + --lavender: #b7bdf8; + --rosewater: #f4dbd6; + +} + +/* Buttons */ +.main-playButton-PlayButton.main-playButton-primary { + color: var(--spice-player); +} + +.main-button-primary { + background-color: var(--spice-main); +} +.main-button-primary:active, +.main-button-primary:focus, +.main-button-primary:hover { + background-color: var(--spice-sidebar); +} + +.main-view-container button:hover > div[class^='ButtonInner-sc-'] { + background-color: var(--spice-button); +} + +.control-button-heart[aria-checked="true"], +.main-addButton-active, +.main-addButton-active:focus, +.main-addButton-active:hover { + color: var(--red); +} + +.main-addButton-active:hover { + -webkit-transform: scale(1.06); + transform: scale(1.06); +} + +/* Progress bar */ +.x-progressBar-progressBarBg > div > div { + background-color: var(--spice-text); +} + +/* Top bars */ +.main-entityHeader-backgroundColor, +.main-actionBarBackground-background, +.main-view-container main[aria-label="Spotify – Web Player"] > div:first-child { + display: none; +} + +.main-topBar-background { + background-color: var(--spice-main) !important; +} + +.main-entityHeader-withBackgroundImage { + background-color: rgba(var(--spice-rgb-player), 0.2); +} + +/* Sidebar */ +.main-navBar-navBar li:hover > div, +.main-navBar-navBar li:hover > a:not(.main-navBar-navBarLinkActive), +.spicetify-playlist-list li:hover { + background-color: var(--spice-main); +} + +#spicetify-sticky-list li:hover > div { + border-radius: 4px; +} + +/* Scrollbar */ +.os-theme-spotify > .os-scrollbar-horizontal, +.os-theme-spotify > .os-scrollbar-vertical { + padding: 4px; +} + +.os-theme-spotify.os-host-transition + > .os-scrollbar-horizontal + > .os-scrollbar-track + > .os-scrollbar-handle, +.os-theme-spotify.os-host-transition + > .os-scrollbar-vertical + > .os-scrollbar-track + > .os-scrollbar-handle { + background-color: var(--decorative-base); + border-radius: 6px; +} + +::-webkit-scrollbar { + width: 0.5em; +} +::-webkit-scrollbar-thumb { + background-color: #575268; + border-radius: 4px; +} + +/* Home */ +.main-home-homeHeader { + display: none; +} + +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div { + background-color: var(--spice-card); +} +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div:hover { + background-color: var(--spice-misc); +} + +.main-gridContainer-gridContainer > div, +.main-gridContainer-gridContainer > div > div > div { + border-radius: 6px; +} + +/* Cards */ +.main-card-card { + border-radius: 6px; +} + +.main-card-imageContainer { + margin: -16px -16px 16px -16px; +} + +.main-cardImage-imageWrapper, +.main-cardImage-image { + border-radius: 6px 6px 0 0; +} + +/* Settings */ +input:checked~.x-toggle-indicatorWrapper { + background-color: var(---overlay1); +} + +input:hover:not([disabled]):not(:active)~.x-toggle-indicatorWrapper { + background-color: var(--spice-button-active); +} + +select option:checked { + color: var(--spice-text); + font-weight: bold; +} + +/* Animated equalizer */ +/* EQ color classes are specified here in case the js extension is not moved over + * The default green eq will be used in this case */ +.catppuccin-eq-rosewater .main-trackList-playingIcon, +.catppuccin-eq-flamingo .main-trackList-playingIcon, +.catppuccin-eq-mauve .main-trackList-playingIcon, +.catppuccin-eq-pink .main-trackList-playingIcon, +.catppuccin-eq-maroon .main-trackList-playingIcon, +.catppuccin-eq-red .main-trackList-playingIcon, +.catppuccin-eq-peach .main-trackList-playingIcon, +.catppuccin-eq-yellow .main-trackList-playingIcon, +.catppuccin-eq-green .main-trackList-playingIcon, +.catppuccin-eq-teal .main-trackList-playingIcon, +.catppuccin-eq-blue .main-trackList-playingIcon, +.catppuccin-eq-sky .main-trackList-playingIcon, +.catppuccin-eq-lavender .main-trackList-playingIcon, +.catppuccin-eq-white .main-trackList-playingIcon { + background-size: cover; + padding-left: 100%; +} + +.catppuccin-eq-rosewater .main-trackList-playingIcon { + background-image: url("equalizer-animated-rosewater.gif"); +} +.catppuccin-eq-flamingo .main-trackList-playingIcon { + background-image: url("equalizer-animated-flamingo.gif"); +} +.catppuccin-eq-mauve .main-trackList-playingIcon { + background-image: url("equalizer-animated-mauve.gif"); +} +.catppuccin-eq-pink .main-trackList-playingIcon { + background-image: url("equalizer-animated-pink.gif"); +} +.catppuccin-eq-maroon .main-trackList-playingIcon { + background-image: url("equalizer-animated-maroon.gif"); +} +.catppuccin-eq-red .main-trackList-playingIcon { + background-image: url("equalizer-animated-red.gif"); +} +.catppuccin-eq-peach .main-trackList-playingIcon { + background-image: url("equalizer-animated-peach.gif"); +} +.catppuccin-eq-yellow .main-trackList-playingIcon { + background-image: url("equalizer-animated-yellow.gif"); +} +.catppuccin-eq-green .main-trackList-playingIcon { + background-image: url("equalizer-animated-green.gif"); +} +.catppuccin-eq-teal .main-trackList-playingIcon { + background-image: url("equalizer-animated-teal.gif"); +} +.catppuccin-eq-blue .main-trackList-playingIcon { + background-image: url("equalizer-animated-blue.gif"); +} +.catppuccin-eq-sky .main-trackList-playingIcon { + background-image: url("equalizer-animated-sky.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-lavender.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-white.gif"); +} + +/* For that small dot on podcasts that notify us of new episodes */ +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div + span[aria-label], +span[aria-label="New episode"], +span[aria-label="New Podcast Episode"] { + background: var(--spice-accent, var(--spice-text)); +} + +/* Modals */ +.GenericModal[aria-label="Already added"] > div { + background-color: var(--spice-card); + color: var(--spice-subtext); +} + +.GenericModal[aria-label="Already added"] button:first-child { + color: var(--spice-button-active); +} + +.GenericModal[aria-label="Already added"] button:first-child:hover { + color: var(--spice-notification-error); +} + +.GenericModal[aria-label="Already added"] button:last-child:hover > div { + background-color: var(--spice-button); +} + +.main-rootlist-rootlistItemLink:link, .main-rootlist-rootlistItemLink:visited { + z-index: 1; +} diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-blue.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-blue.gif new file mode 100644 index 0000000..704bf99 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-blue.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-flamingo.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-flamingo.gif new file mode 100644 index 0000000..0fc9a0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-flamingo.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-green.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-green.gif new file mode 100644 index 0000000..9408c38 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-green.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-lavender.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-lavender.gif new file mode 100644 index 0000000..f176ee6 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-lavender.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-maroon.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-maroon.gif new file mode 100644 index 0000000..1c21876 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-maroon.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-mauve.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-mauve.gif new file mode 100644 index 0000000..a5daf0d Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-mauve.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-peach.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-peach.gif new file mode 100644 index 0000000..d8d4ce7 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-peach.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-pink.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-pink.gif new file mode 100644 index 0000000..e8f4ffa Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-pink.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-red.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-red.gif new file mode 100644 index 0000000..7191693 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-red.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-rosewater.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-rosewater.gif new file mode 100644 index 0000000..6e76160 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-rosewater.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-sky.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-sky.gif new file mode 100644 index 0000000..c267dab Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-sky.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-teal.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-teal.gif new file mode 100644 index 0000000..58d9939 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-teal.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-white.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-white.gif new file mode 100644 index 0000000..cf37197 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-white.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-yellow.gif b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-yellow.gif new file mode 100644 index 0000000..45d1592 Binary files /dev/null and b/config/spicetify/Themes/catppuccin-mocha/assets/equalizer-animated-yellow.gif differ diff --git a/config/spicetify/Themes/catppuccin-mocha/color.ini b/config/spicetify/Themes/catppuccin-mocha/color.ini new file mode 100644 index 0000000..b583aaf --- /dev/null +++ b/config/spicetify/Themes/catppuccin-mocha/color.ini @@ -0,0 +1,234 @@ +[rosewater] +text = F5E0DC +subtext = CDD6F4 +accent = FAE3B0 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 414559 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6C7086 +tab-active = 313244 +notification = 313244 +notification-error = F38BA8 +equalizer = F5E0DC +misc = 585B70 + +[flamingo] +text = F2CDCD +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = F2CDCD +misc = 585B70 + +[mauve] +text = CBA6F7 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = CBA6F7 +misc = 585B70 + +[pink] +text = F5C2E7 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = F5C2E7 +misc = 585B70 + +[maroon] +text = EBA0AC +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = EBA0AC +misc = 585B70 + +[red] +text = F38BA8 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = F38BA8 +misc = 585B70 + +[peach] +text = FAB387 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = FAB387 +misc = 585B70 + +[yellow] +text = F9E2AF +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = F9E2AF +misc = 585B70 + +[green] +text = A6E3A1 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = A6E3A1 +misc = 585B70 + +[teal] +text = 94E2D5 +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = 94E2D5 +misc = 585B70 + +[blue] +text = 89B4FA +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = 89B4FA +misc = 585B70 + +[sky] +text = 89DCEB +subtext = CDD6F4 +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = 89DCEB +misc = 585B70 + +[lavender] +text = B4BEFE +subtext = BAC2DE +main = 1E1E2E +sidebar = 181825 +player = 11111B +card = 313244 +shadow = 181825 +selected-row = 585B70 +button = 7F849C +button-active = 9399B2 +button-disabled = 6E6C7E +tab-active = 313244 +notification = 313244 +notification-error = F28FAD +equalizer = B4BEFE +misc = 585B70 diff --git a/config/spicetify/Themes/catppuccin-mocha/user.css b/config/spicetify/Themes/catppuccin-mocha/user.css new file mode 100644 index 0000000..b0f04de --- /dev/null +++ b/config/spicetify/Themes/catppuccin-mocha/user.css @@ -0,0 +1,272 @@ +/* Color Pallette */ +/* Note: These variables should be used ONLY when needed across ALL of the color palettes. */ +:root { + /* Morning */ + --flamingo: #f2cdcd; + --mauve: #cba6f7; + --pink: #f5c2e7; + --maroon: #eba0ac; + --red: #f38ba8; + --peach: #fab387; + --yellow: #f9e2af; + --green: #a6e3a1; + --teal: #94e2d5; + --blue: #89b4fa; + --sky: #89dceb; + /* Night */ + /* --black-0: #161320; */ + --crust: #11111B; + /* --black-1: #1A1826; */ + --mantle: #181825; + /* --black-2: #1E1E2E; */ + --base: #1E1E2E; + /* --black-3: #302D41; */ + --surface0: #313244; + /* --black-4: #575268; */ + --surface1: #45475A; + /* --gray-0: #6E6C7E; */ + --overlay0: #6C7086; + /* --gray-1: #988BA2; */ + ---overlay1: #7f849C; + /* --gray-2: #C3BAC6; */ + --overlay2: #9399B2; + /* --white: #D9E0EE; */ + --white: #d9e0ee; + --lavender: #b4befe; + --rosewater: #f5e0dc; +} + +/* Buttons */ +.main-playButton-PlayButton.main-playButton-primary { + color: var(--spice-player); +} + +.main-button-primary { + background-color: var(--spice-main); +} +.main-button-primary:active, +.main-button-primary:focus, +.main-button-primary:hover { + background-color: var(--spice-sidebar); +} + +.main-view-container button:hover > div[class^='ButtonInner-sc-'] { + background-color: var(--spice-button); +} + +.control-button-heart[aria-checked="true"], +.main-addButton-active, +.main-addButton-active:focus, +.main-addButton-active:hover { + color: var(--red); +} + +.main-addButton-active:hover { + -webkit-transform: scale(1.06); + transform: scale(1.06); +} + +/* Progress bar */ +.x-progressBar-progressBarBg > div > div { + background-color: var(--spice-text); +} + +/* Top bars */ +.main-entityHeader-backgroundColor, +.main-actionBarBackground-background, +.main-view-container main[aria-label="Spotify – Web Player"] > div:first-child { + display: none; +} + +.main-topBar-background { + background-color: var(--spice-main) !important; +} + +.main-entityHeader-withBackgroundImage { + background-color: rgba(var(--spice-rgb-player), 0.2); +} + +/* Sidebar */ +.main-navBar-navBar li:hover > div, +.main-navBar-navBar li:hover > a:not(.main-navBar-navBarLinkActive), +.spicetify-playlist-list li:hover { + background-color: var(--spice-main); +} + +#spicetify-sticky-list li:hover > div { + border-radius: 4px; +} + +/* Scrollbar */ +.os-theme-spotify > .os-scrollbar-horizontal, +.os-theme-spotify > .os-scrollbar-vertical { + padding: 4px; +} + +.os-theme-spotify.os-host-transition + > .os-scrollbar-horizontal + > .os-scrollbar-track + > .os-scrollbar-handle, +.os-theme-spotify.os-host-transition + > .os-scrollbar-vertical + > .os-scrollbar-track + > .os-scrollbar-handle { + background-color: var(--decorative-base); + border-radius: 6px; +} + +::-webkit-scrollbar { + width: 0.5em; +} +::-webkit-scrollbar-thumb { + background-color: #575268; + border-radius: 4px; +} + +/* Home */ +.main-home-homeHeader { + display: none; +} + +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div { + background-color: var(--spice-card); +} +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div:hover { + background-color: var(--spice-misc); +} + +.main-gridContainer-gridContainer > div, +.main-gridContainer-gridContainer > div > div > div { + border-radius: 6px; +} + +/* Cards */ +.main-card-card { + border-radius: 6px; +} + +.main-card-imageContainer { + margin: -16px -16px 16px -16px; +} + +.main-cardImage-imageWrapper, +.main-cardImage-image { + border-radius: 6px 6px 0 0; +} + +/* Settings */ +input:checked~.x-toggle-indicatorWrapper { + background-color: var(---overlay1); +} + +input:hover:not([disabled]):not(:active)~.x-toggle-indicatorWrapper { + background-color: var(--spice-button-active); +} + +select option:checked { + color: var(--spice-text); + font-weight: bold; +} + +/* Animated equalizer */ +/* EQ color classes are specified here in case the js extension is not moved over + * The default green eq will be used in this case */ +.catppuccin-eq-rosewater .main-trackList-playingIcon, +.catppuccin-eq-flamingo .main-trackList-playingIcon, +.catppuccin-eq-mauve .main-trackList-playingIcon, +.catppuccin-eq-pink .main-trackList-playingIcon, +.catppuccin-eq-maroon .main-trackList-playingIcon, +.catppuccin-eq-red .main-trackList-playingIcon, +.catppuccin-eq-peach .main-trackList-playingIcon, +.catppuccin-eq-yellow .main-trackList-playingIcon, +.catppuccin-eq-green .main-trackList-playingIcon, +.catppuccin-eq-teal .main-trackList-playingIcon, +.catppuccin-eq-blue .main-trackList-playingIcon, +.catppuccin-eq-sky .main-trackList-playingIcon, +.catppuccin-eq-lavender .main-trackList-playingIcon, +.catppuccin-eq-white .main-trackList-playingIcon { + background-size: cover; + padding-left: 100%; +} + +.catppuccin-eq-rosewater .main-trackList-playingIcon { + background-image: url("equalizer-animated-rosewater.gif"); +} +.catppuccin-eq-flamingo .main-trackList-playingIcon { + background-image: url("equalizer-animated-flamingo.gif"); +} +.catppuccin-eq-mauve .main-trackList-playingIcon { + background-image: url("equalizer-animated-mauve.gif"); +} +.catppuccin-eq-pink .main-trackList-playingIcon { + background-image: url("equalizer-animated-pink.gif"); +} +.catppuccin-eq-maroon .main-trackList-playingIcon { + background-image: url("equalizer-animated-maroon.gif"); +} +.catppuccin-eq-red .main-trackList-playingIcon { + background-image: url("equalizer-animated-red.gif"); +} +.catppuccin-eq-peach .main-trackList-playingIcon { + background-image: url("equalizer-animated-peach.gif"); +} +.catppuccin-eq-yellow .main-trackList-playingIcon { + background-image: url("equalizer-animated-yellow.gif"); +} +.catppuccin-eq-green .main-trackList-playingIcon { + background-image: url("equalizer-animated-green.gif"); +} +.catppuccin-eq-teal .main-trackList-playingIcon { + background-image: url("equalizer-animated-teal.gif"); +} +.catppuccin-eq-blue .main-trackList-playingIcon { + background-image: url("equalizer-animated-blue.gif"); +} +.catppuccin-eq-sky .main-trackList-playingIcon { + background-image: url("equalizer-animated-sky.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-lavender.gif"); +} +.catppuccin-eq-lavender .main-trackList-playingIcon { + background-image: url("equalizer-animated-white.gif"); +} + +/* For that small dot on podcasts that notify us of new episodes */ +.main-home-content + > section:first-child + > .main-gridContainer-gridContainer + > div + span[aria-label], +span[aria-label="New episode"], +span[aria-label="New Podcast Episode"] { + background: var(--spice-accent, var(--spice-text)); +} + +/* Modals */ +.GenericModal[aria-label="Already added"] > div { + background-color: var(--spice-card); + color: var(--spice-subtext); +} + +.GenericModal[aria-label="Already added"] button:first-child { + color: var(--spice-button-active); +} + +.GenericModal[aria-label="Already added"] button:first-child:hover { + color: var(--spice-notification-error); +} + +.GenericModal[aria-label="Already added"] button:last-child:hover > div { + background-color: var(--spice-button); +} + +.main-rootlist-rootlistItemLink:link, .main-rootlist-rootlistItemLink:visited { + z-index: 1; +} diff --git a/config/spicetify/config-xpui.ini b/config/spicetify/config-xpui.ini new file mode 100644 index 0000000..fc8dfb9 --- /dev/null +++ b/config/spicetify/config-xpui.ini @@ -0,0 +1,31 @@ +[Setting] +check_spicetify_upgrade = 1 +prefs_path = /home/aleidk/.var/app/com.spotify.Client/config/spotify/prefs +current_theme = catppuccin-macchiato +color_scheme = teal +spotify_launch_flags = +spotify_path = /var/lib/flatpak/app/com.spotify.Client/x86_64/stable/active/files/extra/share/spotify/ +inject_css = 1 +replace_colors = 1 +overwrite_assets = 1 + +[Preprocesses] +disable_sentry = 1 +disable_ui_logging = 1 +remove_rtl_rule = 1 +expose_apis = 1 +disable_upgrade_check = 1 + +[AdditionalOptions] +home_config = 1 +experimental_features = 1 +extensions = copytoclipboard2.js|hidePodcasts.js|ViewPlaylistsWithSong.js|catppuccin-mocha.js +custom_apps = lyrics-plus|new-releases|marketplace +sidebar_config = 1 + +[Patch] + +; DO NOT CHANGE! +[Backup] +version = 1.1.84.716.gc5f8b819 +with = 2.16.0 diff --git a/config/vifm/colors/Default.vifm b/config/vifm/colors/Default.vifm new file mode 100644 index 0000000..9020766 --- /dev/null +++ b/config/vifm/colors/Default.vifm @@ -0,0 +1,89 @@ +" You can edit this file by hand. +" The " character at the beginning of a line comments out the line. +" Blank lines are ignored. + +" The Default color scheme is used for any directory that does not have +" a specified scheme and for parts of user interface like menus. A +" color scheme set for a base directory will also +" be used for the sub directories. + +" The standard ncurses colors are: +" Default = -1 = None, can be used for transparency or default color +" Black = 0 +" Red = 1 +" Green = 2 +" Yellow = 3 +" Blue = 4 +" Magenta = 5 +" Cyan = 6 +" White = 7 + +" Light versions of colors are also available (they set bold +" attribute in terminals with less than 16 colors): +" LightBlack +" LightRed +" LightGreen +" LightYellow +" LightBlue +" LightMagenta +" LightCyan +" LightWhite + +" Available attributes (some of them can be combined): +" bold +" underline +" reverse or inverse +" standout +" italic (on unsupported systems becomes reverse) +" combine +" none + +" Vifm supports 256 colors you can use color numbers 0-255 +" (requires properly set up terminal: set your TERM environment variable +" (directly or using resources) to some color terminal name (e.g. +" xterm-256color) from /usr/lib/terminfo/; you can check current number +" of colors in your terminal with tput colors command) + +" highlight group cterm=attrs ctermfg=foreground_color ctermbg=background_color + +highlight clear + +highlight Win cterm=none ctermfg=white ctermbg=black +highlight Directory cterm=bold ctermfg=cyan ctermbg=default +highlight Link cterm=bold ctermfg=yellow ctermbg=default +highlight BrokenLink cterm=bold ctermfg=red ctermbg=default +highlight HardLink cterm=none ctermfg=yellow ctermbg=default +highlight Socket cterm=bold ctermfg=magenta ctermbg=default +highlight Device cterm=bold ctermfg=red ctermbg=default +highlight Fifo cterm=bold ctermfg=cyan ctermbg=default +highlight Executable cterm=bold ctermfg=green ctermbg=default +highlight Selected cterm=bold ctermfg=magenta ctermbg=default +highlight CurrLine cterm=bold,reverse ctermfg=default ctermbg=default +highlight TopLine cterm=none ctermfg=black ctermbg=white +highlight TopLineSel cterm=bold ctermfg=black ctermbg=default +highlight StatusLine cterm=bold ctermfg=black ctermbg=white +highlight WildMenu cterm=underline,reverse ctermfg=white ctermbg=black +highlight CmdLine cterm=none ctermfg=white ctermbg=black +highlight ErrorMsg cterm=none ctermfg=red ctermbg=black +highlight Border cterm=none ctermfg=black ctermbg=white +highlight OtherLine ctermfg=default ctermbg=default +highlight JobLine cterm=bold,reverse ctermfg=black ctermbg=white +highlight SuggestBox cterm=bold ctermfg=default ctermbg=default +highlight CmpMismatch cterm=bold ctermfg=white ctermbg=red +highlight CmpUnmatched cterm=bold ctermfg=white ctermbg=green +highlight CmpBlank ctermfg=default ctermbg=default +highlight AuxWin ctermfg=default ctermbg=default +highlight TabLine cterm=none ctermfg=white ctermbg=black +highlight TabLineSel cterm=bold,reverse ctermfg=default ctermbg=default +highlight User1 ctermfg=default ctermbg=default +highlight User2 ctermfg=default ctermbg=default +highlight User3 ctermfg=default ctermbg=default +highlight User4 ctermfg=default ctermbg=default +highlight User5 ctermfg=default ctermbg=default +highlight User6 ctermfg=default ctermbg=default +highlight User7 ctermfg=default ctermbg=default +highlight User8 ctermfg=default ctermbg=default +highlight User9 ctermfg=default ctermbg=default +highlight OtherWin ctermfg=default ctermbg=default +highlight LineNr ctermfg=default ctermbg=default +highlight OddLine ctermfg=default ctermbg=default diff --git a/config/vifm/scripts/README b/config/vifm/scripts/README new file mode 100644 index 0000000..7694952 --- /dev/null +++ b/config/vifm/scripts/README @@ -0,0 +1,6 @@ +This directory is dedicated for user-supplied scripts/executables. +vifm modifies its PATH environment variable to let user run those +scripts without specifying full path. All subdirectories are added +as well. File in a subdirectory overrules file with the same name +in parent directories. Restart might be needed to recognize files +in newly created or renamed subdirectories. \ No newline at end of file diff --git a/config/vifm/vifm-help.txt b/config/vifm/vifm-help.txt new file mode 100644 index 0000000..e7d10b8 --- /dev/null +++ b/config/vifm/vifm-help.txt @@ -0,0 +1,6723 @@ +VIFM(1) General Commands Manual VIFM(1) + + + +NAME + vifm - vi file manager + +SYNOPSIS + vifm [OPTION]... + vifm [OPTION]... path + vifm [OPTION]... path path + +DESCRIPTION + Vifm is an ncurses based file manager with vi like keybindings. If you + use vi, vifm gives you complete keyboard control over your files with- + out having to learn a new set of commands. + +OPTIONS + vifm starts in the current directory unless it is given a different di- + rectory on the command line or 'vifminfo' option includes "savedirs" + (in which case last visited directories are used as defaults). + + - Read list of files from standard input stream and compose custom + view out of them (see "Custom views" section). Current working + directory is used as a base for relative paths. + + Starts Vifm in the specified path. + + + Starts Vifm in the specified paths. + + Specifying two directories triggers split view even when vifm was in + single-view mode on finishing previous run. To suppress this behaviour + :only command can be put in the vifmrc file. + + When only one path argument is found on command-line, the left/top pane + is automatically set as the current view. + + Paths to files are also allowed in case you want vifm to start with + some archive opened. + + --select + Open parent directory of the given path and select specified + file in it. + + -f Makes vifm instead of opening files write selection to + $VIFM/vimfiles and quit. + + --choose-files |- + Sets output file to write selection into on exit instead of + opening files. "-" means standard output. Use empty value to + disable it. + + --choose-dir |- + Sets output file to write last visited directory into on exit. + "-" means standard output. Use empty value to disable it. + + --delimiter + Sets separator for list of file paths written out by vifm. + Empty value means null character. Default is new line charac- + ter. + + --on-choose + Sets command to be executed on selected files instead of opening + them. The command may use any of macros described in "Command + macros" section below. The command is executed once for whole + selection. + + --logging[=] + Log some operational details to $XDG_DATA_HOME/vifm/log or + $VIFM/log. If the optional startup log path is specified and + permissions allow to open it for writing, then logging of early + initialization (before configuration directories are determined) + is put there. + + --server-list + List available server names and exit. + + --server-name + Name of target or this instance (sequential numbers are appended + on name conflict). + + --remote + Sends the rest of the command line to another instance of vifm, + --server-name is treated just like any other argument and should + precede --remote on the command line. When there is no server, + quits silently. There is no limit on how many arguments can be + processed. One can combine --remote with -c or + to execute commands in already running instance of vifm. + See also "Client-Server" section below. + + --remote-expr + passes expression to vifm server and prints result. See also + "Client-Server" section below. + + -c or + + Run command-line mode on startup. Commands in such + arguments are executed in the order they appear in command line. + Commands with spaces or special symbols must be enclosed in dou- + ble or single quotes or all special symbols should be escaped + (the exact syntax strongly depends on shell). "+" argument is + equivalent to "$" and thus picks last item of of the view. + + --help, -h + Show a brief command summary and exit vifm. + + --version, -v + Show version information and quit. + + --no-configs + Skip reading vifmrc and vifminfo. + + + See "Startup" section below for the explanations on $VIFM. + +General keys + Ctrl-C or Escape + cancel most operations (see "Cancellation" section below), clear + all selected files. + + Ctrl-L clear and redraw the screen. Can also reload file list in ap- + propriate modes (like normal and visual). + +Basic Movement + The basic vi key bindings are used to move through the files and pop-up + windows. + + k, gk, or Ctrl-P + move cursor up one line. + + j, gj or Ctrl-N + move cursor down one line. + + h when 'lsview' is off move up one directory (moves to parent di- + rectory node in tree view), otherwise move left one file. + + l when 'lsview' is off move into a directory or launch a file, + otherwise move right one file. See "Selection" section below. + + gg move to the first line of the file list. + + G move to the last line in the file list. + + gh go up one directory regardless of view representation (regular, + ls-like). Also can be used to leave custom views including tree + view. + + gl or Enter + enter directory or launch a file. See "Selection" section be- + low. + + H move to the first file in the window. + + M move to the file in the middle of the window. + + L move to the last file in the window. + + Ctrl-F or Page Down + move forward one page. + + Ctrl-B or Page Up + move back one page. + + Ctrl-D jump back one half page. + + Ctrl-U jump forward one half page. + + n% move to the file that is n percent from the top of the list (for + example 25%). + + 0 or ^ move cursor to the first column. See 'lsview' option descrip- + tion. + + $ move cursor to the last column. See 'lsview' option descrip- + tion. + + Space switch file lists. + + gt switch to the next tab (wrapping around). + + {n}gt switch to the tab number {n} (wrapping around). + + gT switch to the previous tab (wrapping around). + + {n}gT switch to {n}-th previous tab. + +Movement with Count + Most movement commands also accept a count, 12j would move down 12 + files. + + [count]% + move to percent of the file list. + + [count]j + move down [count] files. + + [count]k + move up [count] files. + + [count]G or [count]gg + move to list position [count]. + + [count]h + go up [count] directories. + +Scrolling panes + zt redraw pane with file in top of list. + + zz redraw pane with file in center of list. + + zb redraw pane with file in bottom of list. + + Ctrl-E scroll pane one line down. + + Ctrl-Y scroll pane one line up. + +Pane manipulation + Second character can be entered with or without Control key. + + Ctrl-W H + move the pane to the far left. + + Ctrl-W J + move the pane to the very bottom. + + Ctrl-W K + move the pane to the very top. + + Ctrl-W L + move the pane to the far right. + + + Ctrl-W h + switch to the left pane. + + Ctrl-W j + switch to the pane below. + + Ctrl-W k + switch to the pane above. + + Ctrl-W l + switch to the right pane. + + + Ctrl-W b + switch to bottom-right window. + + Ctrl-W t + switch to top-left window. + + + Ctrl-W p + switch to previous window. + + Ctrl-W w + switch to other pane. + + + Ctrl-W o + leave only one pane. + + Ctrl-W s + split window horizontally. + + Ctrl-W v + split window vertically. + + + Ctrl-W x + exchange panes. + + Ctrl-W z + quit preview pane or view modes. + + + Ctrl-W - + decrease size of the view by count. + + Ctrl-W + + increase size of the view by count. + + Ctrl-W < + decrease size of the view by count. + + Ctrl-W > + increase size of the view by count. + + + Ctrl-W | + set current view size to count. + + Ctrl-W _ + set current view size to count. + + Ctrl-W = + make size of two views equal. + + For Ctrl-W +, Ctrl-W -, Ctrl-W <, Ctrl-W >, Ctrl-W | and Ctrl-W _ com- + mands count can be given before and/or after Ctrl-W. The resulting + count is a multiplication of those two. So "2 Ctrl-W 2 -" decreases + window size by 4 lines or columns. + + Ctrl-W | and Ctrl-W _ maximise current view by default. + +Marks + Marks are set the same way as they are in vi. + + You can use these characters for marks [a-z][A-Z][0-9]. + + m[a-z][A-Z][0-9] + set a mark for the file at the current cursor position. + + '[a-z][A-Z][0-9] + navigate to the file set for the mark. + + + There are also several special marks that can't be set manually: + + - ' (single quote) - previously visited directory of the view, thus + hitting '' allows switching between two last locations + + - < - the first file of the last visually selected block + + - > - the last file of the last visually selected block + +Searching + /regular expression pattern + search for files matching regular expression in forward direc- + tion and advance cursor to next match. + + / perform forward search with top item of search pattern history. + + ?regular expression pattern + search for files matching regular expression in backward direc- + tion and advance cursor to previous match. + + ? perform backward search with top item of search pattern history. + + Trailing slash for directories is taken into account, so /\/ searches + for directories and symbolic links to directories. At the moment // + works too, but this can change in the future, so consider escaping the + slash if not typing pattern by hand. + + Matches are automatically selected if 'hlsearch' is set. Enabling + 'incsearch' makes search interactive. 'ignorecase' and 'smartcase' op- + tions affect case sensitivity of search queries as well as local filter + and other things detailed in the description of 'caseoptions'. + + + [count]n + go to the next file matching last search pattern. Takes last + search direction into account. + + [count]N + go to the previous file matching last search pattern. Takes + last search direction into account. + + If 'hlsearch' option is set, hitting n/N to perform search and go to + the first matching item resets current selection in normal mode. It is + not the case if search was already performed on files in the directory, + thus selection is not reset after clearing selection with escape key + and hitting n/N key again. + + See also "Regular expressions" section. + + + [count]f[character] + search forward for file with [character] as first character in + name. Search wraps around the end of the list. + + [count]F[character] + search backward for file with [character] as first character in + name. Search wraps around the end of the list. + + [count]; + find the next match of f or F. + + [count], + find the previous match of f or F. + + Note: f, F, ; and , wrap around list beginning and end when they are + used alone and they don't wrap when they are used as selectors. + +File Filters + There are three basic file filters: + + - dot files filter (does not affect "." and ".." special directories, + whose appearance is controlled by the 'dotdirs' option), see 'dot- + files' option; + + - permanent filter; + + - local filter (see description of the "=" normal mode command). + + Permanent filter essentially allows defining a group of files names + which are not desirable to be seen by default, like temporary or backup + files, which might be created alongside normal ones. Just like you + don't usually need to see hidden dot files (files starting with a dot). + Local filter on the other hand is for temporary immediate filtering of + file list at hand, to get rid of uninterested files in the view or to + make it possible to use % range in a :command. + + For the purposes of more deterministic editing permanent filter is + split into two parts: + + - one edited explicitly via :filter command; + + - another one which is edited implicitly via zf shortcut. + + Files are tested against both parts and a match counts if at least one + of the parts matched. + + + Each file list has its own copy of each filter. + + Filtered files are not checked in / search or :commands. + + Files and directories are filtered separately. This is done by append- + ing a slash to a directory name before testing whether it matches the + filter. Examples: + + + " filter directories which names end with '.files' + :filter /^.*\.files\/$/ + + " filter files which names end with '.d' + :filter {*.d} + + " filter files and directories which names end with '.o' + :filter /^.*\.o\/?$/ + + See also "Regular expressions" and "Patterns" sections. + + The basic Vim folding key bindings are used for managing filters. + + + za toggle visibility of dot files. + + zo show dot files. + + zm hide dot files. + + zf add selected files to permanent filter. + + zO reset permanent filter. + + zR save and reset all filters. + + zr clear local filter. + + zM restore all filters (undoes last zR). + + zd exclude selection or current file from a custom view. Does + nothing for regular view. For tree view excluding directory ex- + cludes that sub-tree. For compare views zd hides group of adja- + cent identical files, count can be specified as 1 to exclude + just single file or selected items instead. Files excluded this + way are not counted as filtered out and can't be returned unless + view is reloaded. + + =regular expression pattern + filter out files that don't match regular expression. Whether + view is updated as regular expression is changed depends on the + value of the 'incsearch' option. This kind of filter is auto- + matically reset when directory is changed. + +Tree-related Keys + While some of the keys make sense outside of tree-view, they are most + useful in trees. + + [z go to first sibling of current entry. + + ]z go to last sibling of current entry. + + zj go to next directory sibling of current entry or do nothing. + + zk go to previous directory sibling of current entry or do nothing. + + zx toggle fold under the cursor or parent entry of the current file + if cursor is not on a directory. + +Other Normal Mode Keys + [count]: + enter command line mode. [count] generates range. + + q: open external editor to prompt for command-line command. See + "Command line editing" section for details. + + q/ open external editor to prompt for search pattern to be searched + in forward direction. See "Command line editing" section for + details. + + q? open external editor to prompt for search pattern to be searched + in backward direction. See "Command line editing" section for + details. + + q= open external editor to prompt for filter pattern. See "Command + line editing" section for details. Unlike other q{x} commands + this one doesn't work in Visual mode. + + [count]!! and [count]! + enter command line mode with entered ! command. [count] modi- + fies range. + + Ctrl-O go backwards through directory history of current view. Nonex- + istent directories are automatically skipped. + + Ctrl-I if 'cpoptions' contains "t" flag, and switch active + pane just like does, otherwise it goes forward through + directory history of current view. Nonexistent directories are + automatically skipped. + + Ctrl-G show a dialog with detailed information about current file. See + "Menus and dialogs" section for controls. + + Shift-Tab + enter view mode (works only after activating view pane with + :view command). + + ga calculate directory size. Uses cached directory sizes when pos- + sible for better performance. As a special case calculating + size of ".." entry results in calculation of size of current di- + rectory. + + gA like ga, but force update. Ignores old values of directory + sizes. + + If file under cursor is selected, each selected item is processed, oth- + erwise only current file is updated. + + gf find link destination (like l with 'followlinks' off, but also + finds directories). On Windows additionally follows .lnk-files. + + gF Same as gf, but resolves final path of the chain of symbolic + links. + + gr only for MS-Windows + same as l key, but tries to run program with administrative + privileges. + + av go into visual mode for updating current selection, any existing + selection is preserved. + + gv go into visual mode restoring last selection. + + [reg]gs + if register is present, then all files listed in that register + that are visible in current view are selected. + + When no register is specified, restore the last selection saved + for this view (similar to what gv does for visual mode selec- + tion). When you leave a directory, its saved selection is re- + membered for that path and visiting the directory again restores + it. Selection for up to 10 distinct file-system locations are + remembered. + + gu + make names of selected files lowercase. + + [count]guu and [count]gugu + make names of [count] files starting from the current one lower- + case. Without [count] only current file is affected. + + gU + make names of selected files uppercase. + + [count]gUU and [count]gUgU + make names of [count] files starting from the current one upper- + case. Without [count] only current file is affected. + + e explore file in the current pane. + + i handle file (even if it's an executable and 'runexec' option is + set). + + cw change word is used to rename a file or files. If multiple + files are selected, behaves as :rename command run without argu- + ments. + + cW change WORD is used to change only name of file (without exten- + sion). + + cl change link target. If multiple files are selected, an editor + is spawn to edit paths. + + co only for *nix + change file owner. + + cg only for *nix + change file group. + + [count]cp + change file attributes (permission on *nix and properties on + Windows). If [count] is specified, it's treated as numerical + argument for non-recursive `chmod` command (of the form + [0-7]{3,4}). See "Menus and dialogs" section for controls. + + [count]C + clone file [count] times. + + [count]dd or d[count]selector + move selected file or files to trash directory (if 'trash' op- + tion is set, otherwise delete). See "Trash directory" section + below. + + [count]DD or D[count]selector + like dd and d, but omitting trash directory (even when + 'trash' option is set). + + Y, [count]yy or y[count]selector + yank selected files. + + p copy yanked files to the current directory or move the files to + the current directory if they were deleted with dd or :d[elete] + or if the files were yanked from trash directory. See "Trash + directory" section below. + + P move the last yanked files. The advantage of using P instead of + d followed by p is that P moves files only once. This isn't im- + portant in case you're moving files in the same file system + where your home directory is, but using P to move files on some + other file system (or file systems, in case you want to move + files from fs1 to fs2 and your home is on fs3) can save your + time. + + al put symbolic links with absolute paths. + + rl put symbolic links with relative paths. + + t select or unselect (tag) the current file. + + u undo last change. + + Ctrl-R redo last change. + + dp in compare view of "ofboth grouppaths" kind, makes corresponding + entry of the other pane equal to the current one. The semantics + is as follows: + - nothing done for identical entries + - if file is missing in current view, its pair gets removed + - if file is missing or differs in other view, it's replaced + - file pairs are defined by matching relative paths + File removal obeys 'trash' option. When the option is enabled, + the operation can be undone/redone (although results won't be + visible automatically). + Unlike in Vim, this operation is performed on a single line + rather than a set of adjacent changes. + + do same as dp, but applies changes in the opposite direction. + + v or V enter visual mode, clears current selection. + + [count]Ctrl-A + increment first number in file name by [count] (1 by default). + + [count]Ctrl-X + decrement first number in file name by [count] (1 by default). + + ZQ same as :quit!. + + ZZ same as :quit. + + . repeat last command-line command (not normal mode command) of + this run (does nothing right after startup or :restart command). + The command doesn't depend on command-line history and can be + used with completely disabled history. + + ( go to previous group. Groups are defined by primary sorting + key. For name and iname members of each group have same first + letter, for all other sorting keys vifm uses size, uid, ... + + ) go to next group. See ( key description above. + + { speeds up navigation to closest previous entry of the opposite + type by moving to the first file backwards when cursor is on a + directory and to the first directory backwards when cursor is on + a file. This is essentially a special case of ( that is locked + on "dirs". + + } same as {, but in forward direction. + + [c go to previous mismatched entry in directory comparison view or + do nothing. + + ]c go to next mismatched entry in directory comparison view or do + nothing. + + [d go to previous directory entry or do nothing. + + ]d go to next directory entry or do nothing. + + [r same as :siblprev. + + ]r same as :siblnext. + + [R same as :siblprev!. + + ]R same as :siblnext!. + + [s go to previous selected entry or do nothing. + + ]s go to next selected entry or do nothing. + +Using Count + You can use count with commands like yy. + + [count]yy + yank count files starting from current cursor position downward. + + Or you can use count with motions passed to y, d or D. + + d[count]j + delete (count + 1) files starting from current cursor position + upward. + +Registers + vifm supports multiple registers for temporary storing list of yanked + or deleted files. + + Registers should be specified by hitting double quote key followed by a + register name. Count is specified after register name. By default + commands use unnamed register, which has double quote as its name. + + Though all commands accept registers, most of commands ignores them + (for example H or Ctrl-U). Other commands can fill register or append + new files to it. + + Presently vifm supports ", _, a-z and A-Z characters as register names. + + As mentioned above " is unnamed register and has special meaning of the + default register. Every time when you use named registers (a-z and A- + Z) unnamed register is updated to contain same list of files as the + last used register. + + _ is black hole register. It can be used for writing, but its list is + always empty. + + Registers with names from a to z and from A to Z are named ones. Low- + ercase registers are cleared before adding new files, while uppercase + aren't and should be used to append new files to the existing file list + of appropriate lowercase register (A for a, B for b, ...). + + Registers can be changed on :empty command if they contain files under + trash directory (see "Trash directory" section below). + + Registers do not contain one file more than once. + + Example: + + "a2yy + + puts names of two files to register a (and to the unnamed register), + + "Ad + + removes one file and append its name to register a (and to the unnamed + register), + + p or "ap or "Ap + + inserts previously yanked and deleted files into current directory. + +Selectors + y, d, D, !, gu and gU commands accept selectors. You can combine them + with any of selectors below to quickly remove or yank several files. + + Most of selectors are like vi motions: j, k, gg, G, H, L, M, %, f, F, + ;, comma, ', ^, 0 and $. But there are some additional ones. + + a all files in current view. + + s selected files. + + S all files except selected. + + Examples: + + - dj - delete file under cursor and one below; + + - d2j - delete file under cursor and two below; + + - y6gg - yank all files from cursor position to 6th file in the list. + + When you pass a count to whole command and its selector they are multi- + plied. So: + + - 2d2j - delete file under cursor and four below; + + - 2dj - delete file under cursor and two below; + + - 2y6gg - yank all files from cursor position to 12th file in the + list. + +Visual Mode + Visual mode has two generic operating submodes: + + - plain selection as it is in Vim; + + - selection editing submode. + + Both modes select files in range from cursor position at which visual + mode was entered to current cursor position (let's call it "selection + region"). Each of two borders can be adjusted by swapping them via "o" + or "O" keys and updating cursor position with regular cursor motion + keys. Obviously, once initial cursor position is altered this way, + real start position becomes unavailable. + + Plain Vim-like visual mode starts with cleared selection, which is not + restored on rejecting selection ("Escape", "Ctrl-C", "v", "V"). Con- + trary to it, selection editing doesn't clear previously selected files + and restores them after reject. Accepting selection by performing an + operation on selected items (e.g. yanking them via "y") moves cursor to + the top of current selection region (not to the top most selected file + of the view). + + In turn, selection editing supports three types of editing (look at + status bar to know which one is currently active): + + - append - amend selection by selecting elements in selection region; + + - remove - amend selection by deselecting elements in selection re- + gion; + + - invert - amend selection by inverting selection of elements in se- + lection region. + + No matter how you activate selection editing it starts in "append". + One can switch type of operation (in the order given above) via "Ctrl- + G" key. + + Almost all normal mode keys work in visual mode, but instead of accept- + ing selectors they operate on selected items. + + Enter save selection and go back to normal mode not moving cursor. + + av leave visual mode if in amending mode (restores previous selec- + tion), otherwise switch to amending selection mode. + + gv restore previous visual selection. + + v, V, Ctrl-C or Escape + leave visual mode if not in amending mode, otherwise switch to + normal visual selection. + + Ctrl-G switch type of amending by round robin scheme: append -> remove + -> invert. + + : enter command line mode. Selection is cleared on leaving the + mode. + + o switch active selection bound. + + O switch active selection bound. + + gu, u make names of selected files lowercase. + + gU, U make names of selected files uppercase. + + cl change target of symbolic link(s). + + cw same as running :rename command without arguments. + +View Mode + This mode tries to imitate the less program. List of builtin shortcuts + can be found below. Shortcuts can be customized using :qmap, :qnoremap + and :qunmap command-line commands. + + Shift-Tab, Tab, q, Q, ZZ + return to normal mode. + + [count]e, [count]Ctrl-E, [count]j, [count]Ctrl-N, [count]Enter + scroll forward one line (or [count] lines). + + [count]y, [count]Ctrl-Y, [count]k, [count]Ctrl-K, [count]Ctrl-P + scroll backward one line (or [count] lines). + + [count]f, [count]Ctrl-F, [count]Ctrl-V, [count]Space + scroll forward one window (or [count] lines). + + [count]b, [count]Ctrl-B, [count]Alt-V + scroll backward one window (or [count] lines). + + [count]z + scroll forward one window (and set window to [count]). + + [count]w + scroll backward one window (and set window to [count]). + + [count]Alt-Space + scroll forward one window, but don't stop at end-of-file. + + [count]d, [count]Ctrl-D + scroll forward one half-window (and set half-window to [count]). + + [count]u, [count]Ctrl-U + scroll backward one half-window (and set half-window to + [count]). + + r, Ctrl-R, Ctrl-L + repaint screen. + + R reload view preserving scroll position. + + F toggle automatic forwarding. Roughly equivalent to periodic + file reload and scrolling to the bottom. The behaviour is simi- + lar to `tail -F` or F key in less. + + a switch to the next viewer. Does nothing for preview constructed + via %q macro. + + A switch to the previous viewer. Does nothing for preview con- + structed via %q macro. + + i toggle raw mode (ignoring of defined viewers). Does nothing for + preview constructed via %q macro. + + [count]/pattern + search forward for ([count]-th) matching line. + + [count]?pattern + search backward for ([count]-th) matching line. + + [count]n + repeat previous search (for [count]-th occurrence). + + [count]N + repeat previous search in reverse direction (for [count]-th oc- + currence). + + [count]g, [count]<, [count]Alt-< + scroll to the first line of the file (or line [count]). + + [count]G, [count]>, [count]Alt-> + scroll to the last line of the file (or line [count]). + + [count]p, [count]% + scroll to the beginning of the file (or N percent into file). + + v invoke an editor to edit the current file being viewed. The + command for editing is taken from the 'vicmd' or 'vixcmd' option + value and extended with middle line number prepended by a plus + sign and name of the current file. + + All "Ctrl-W x" keys work the same was as in Normal mode. Active mode + is automatically changed on navigating among windows. When less-like + mode activated on file preview is left using one by "Ctrl-W x" keys, + its state is stored until another file is displayed using preview (it's + possible to leave the mode, hide preview pane, do something else, then + get back to the file and show preview pane again with previously stored + state in it). + +Command line Mode + These keys are available in all submodes of the command line mode: com- + mand, search, prompt and filtering. + + Down, Up, Left, Right, Home, End and Delete are extended keys and they + are not available if vifm is compiled with --disable-extended-keys op- + tion. + + Esc, Ctrl-C + leave command line mode, cancels input. Cancelled input is + saved into appropriate history and can be recalled later. + + Ctrl-M, Enter + execute command and leave command line mode. + + Ctrl-I, Tab + complete command or its argument. + + Shift-Tab + complete in reverse order. + + Ctrl-_ stop completion and return original input. + + Ctrl-B, Left + move cursor to the left. + + Ctrl-F, Right + move cursor to the right. + + Ctrl-A, Home + go to line beginning. + + Ctrl-E, End + go to line end. + + Alt-B go to the beginning of previous word. + + Alt-F go to the end of next word. + + Ctrl-U remove characters from cursor position till the beginning of + line. + + Ctrl-K remove characters from cursor position till the end of line. + + Ctrl-H, Backspace + remove character before the cursor. + + Ctrl-D, Delete + remove character under the cursor. + + Ctrl-W remove characters from cursor position till the beginning of + previous word. + + Alt-D remove characters from cursor position till the beginning of + next word. + + Ctrl-T swap the order of current and previous character and move cursor + forward or, if cursor past the end of line, swap the order of + two last characters in the line. + + Alt-. insert last part of previous command to current cursor position. + Each next call will insert last part of older command. + + Ctrl-G edit command-line content in external editor. See "Command line + editing" section for details. + + Ctrl-N recall more recent command-line from history. + + Ctrl-P recall older command-line from history. + + Up recall more recent command-line from history, that begins as the + current command-line. + + Down recall older command-line from history, that begins as the cur- + rent command-line. + + Ctrl-] trigger abbreviation expansion. + + Ctrl-R = + insert result of evaluating an expression. Expression is to be + entered via nested command-line prompt (where this key does + nothing). Expansion of an erroneous expression is empty. + +Pasting special values + The shortcuts listed below insert specified values into current cursor + position. Last key of every shortcut references value that it inserts: + - c - [c]urrent file + - d - [d]irectory path + - e - [e]xtension of a file name + - r - [r]oot part of a file name + - t - [t]ail part of directory path + + - a - [a]utomatic filter + - m - [m]anual filter + - = - local filter, which is bound to "=" in normal mode + + Values related to filelist in current pane are available through Ctrl-X + prefix, while values from the other pane have doubled Ctrl-X key as + their prefix (doubled Ctrl-X is presumably easier to type than upper- + case letters; it's still easy to remap the keys to correspond to names + of similar macros). + + Ctrl-X c + name of the current file of the active pane. + + Ctrl-X d + path to the current directory of the active pane. + + Ctrl-X e + extension of the current file of the active pane. + + Ctrl-X r + name root of current file of the active pane. + + Ctrl-X t + the last component of path to the current directory of the ac- + tive pane. + + Ctrl-X Ctrl-X c + name of the current file of the inactive pane. + + Ctrl-X Ctrl-X d + path to the current directory of the inactive pane. + + Ctrl-X Ctrl-X e + extension of the current file of the inactive pane. + + Ctrl-X Ctrl-X r + name root of current file of the inactive pane. + + Ctrl-X Ctrl-X t + the last component of path to the current directory of the inac- + tive pane. + + + Ctrl-X a + value of implicit permanent filter (old name "automatic") of the + active pane. + + Ctrl-X m + value of explicit permanent filter (old name "manual") of the + active pane. + + Ctrl-X = + value of local filter of the active pane. + + + Ctrl-X / + last pattern from search history. + +Command line editing + vifm provides a facility to edit several kinds of data, that is usually + edited in command-line mode, in external editor (using command speci- + fied by 'vicmd' or 'vixcmd' option). This has at least two advantages + over built-in command-line mode: + - one can use full power of Vim to edit text; + - finding and reusing history entries becomes possible. + + The facility is supported by four input submodes of the command-line: + - command; + - forward search; + - backward search; + - file rename (see description of cw and cW normal mode keys). + + Editing command-line using external editor is activated by the Ctrl-G + shortcut. It's also possible to do almost the same from Normal and + Visual modes using q:, q/ and q? commands. + + Temporary file created for the purpose of editing the line has the fol- + lowing structure: + + 1. First line, which is either empty or contains text already entered + in command-line. + + 2. 2nd and all other lines with history items starting with the most + recent one. Altering this lines in any way won't change history + items stored by vifm. + + After editing application is finished the first line of the file is + taken as the result of operation, when the application returns zero + exit code. If the application returns an error (see :cquit command in + Vim), all the edits made to the file are ignored, but the initial value + of the first line is saved in appropriate history. + +More Mode + This is the mode that appears when status bar content is so big that it + doesn't fit on the screen. One can identify the mode by "-- More --" + message at the bottom. + + The following keys are handled in this mode: + + + Enter, Ctrl-J, j or Down + scroll one line down. + + Backspace, k or Up + scroll one line up. + + + d scroll one page (half of a screen) down. + + u scroll one page (half of a screen) up. + + + Space, f or PageDown + scroll down a screen. + + b or PageUp + scroll up a screen. + + + G scroll to the bottom. + + g scroll to the top. + + + q, Escape or Ctrl-C + quit the mode. + + : switch to command-line mode. + +Commands + Commands are executed with :command_name + + Commented out lines should start with the double quote symbol ("), + which may be preceded by whitespace characters intermixed with colons. + Inline comments can be added at the end of the line after double quote + symbol, only last line of a multi-line command can contain such com- + ment. Not all commands support inline comments as their syntax con- + flicts with names of registers and fields where double quotes are al- + lowed. + + Most of the commands have two forms: complete and the short one. Exam- + ple: + + :noh[lsearch] + + This means the complete command is nohlsearch, and the short one is + noh. + + Most of command-line commands completely reset selection in the current + view. However, there are several exceptions: + + - `:invert s` most likely leaves some files selected; + + - :view command; + + - :normal command (when it doesn't leave command-line mode); + + - :if and :else commands don't affect selection on successful execu- + tion. + + '|' can be used to separate commands, so you can give multiple commands + in one line. If you want to use '|' in an argument, precede it with + '\'. + + These commands see '|' as part of their arguments even when it's es- + caped: + + :[range]! + :autocmd + :cabbrev + :cmap + :cnoreabbrev + :cnoremap + :command + :dmap + :dnoremap + :filetype + :fileviewer + :filextype + :keepsel + :map + :mmap + :mnoremap + :nmap + :nnoremap + :noremap + :normal + :qmap + :qnoremap + :vmap + :vnoremap + :wincmd + :windo + :winrun + + To be able to use another command after one of these, wrap it with the + :execute command. An example: + + if filetype('.') == 'reg' | execute '!!echo regular file' | endif + + :[count] + + :number + move to the file number. + :12 would move to the 12th file in the list. + :0 move to the top of the list. + :$ move to the bottom of the list. + + :[count]command + The only builtin :[count]command are :[count]d[elete] and + :[count]y[ank]. + + :d3 would delete three files starting at the current file position + moving down. + + :3d would delete one file at the third line in the list. + + :command [args] + + :[range]!program + execute command via shell. Accepts macros. + + :[range]!command & + + same as above, but the command is run in the background using vifm's + means. + + Programs that write to stderr create error dialogs showing errors of + the command. + + Note the space before ampersand symbol, if you omit it, command will be + run in the background using job control of your shell. + + Accepts macros. + + :!! + + :[range]!!command + same as :!, but pauses before returning. + + :!! repeat the last command. + + :alink + + :[range]alink[!?] + create absolute symbolic links to files in directory of inactive + view. With "?" prompts for destination file names in an edi- + tor. "!" forces overwrite. + + :[range]alink[!] path + create absolute symbolic links to files in directory specified + by the path (absolute or relative to directory of inactive + view). + + :[range]alink[!] name1 name2... + create absolute symbolic links of files in directory of other + view giving each next link a corresponding name from the argu- + ment list. + + :[range]alink[!?] -skip ... + see "-skip parameter" section below. + + :apropos + + :apropos keyword... + create a menu of items returned by the apropos command. Select- + ing an item in the menu opens corresponding man page. By de- + fault the command relies on the external "apropos" utility, + which can be customized by altering value of the 'aproposprg' + option. See "Menus and dialogs" section for controls. + + :autocmd + + :au[tocmd] {event} {pat} {cmd} + register autocommand for the {event}, which can be: + - DirEnter - triggered after directory is changed + Event name is case insensitive. + + {pat} is a comma-separated list of modified globs patterns, + which can contain tilde or environment variables. All paths use + slash ('/') as directory separator. The pattern can start with + a '!', which negates it. Patterns that do not contain slashes + are matched against the last item of the path only (e.g. "dir" + in "/path/dir"). Literal comma can be entered by doubling it. + Two modifications to globs matching are as follows: + - * - never matches a slash (i.e., can signify single direc- + tory level) + - ** - matches any character (i.e., can match path of arbi- + trary depth) + + {cmd} is a :command or several of them separated with '|'. + + Examples of patterns: + - conf.d - matches conf.d directory anywhere + - *.d - matches directories ending with ".d" anywhere + - **.git - matches something.git, but not .git anywhere + - **/.git/** - matches /path/.git/objects, but not /path/.git + - **/.git/**/ - matches /path/.git/ only (because of trailing + slash) + - /etc/* - matches /etc/conf.d/, /etc/X11, but not + /etc/X11/fs + - /etc/**/*.d - matches /etc/conf.d, /etc/X11/conf.d, etc. + - /etc/**/* - matches /etc/ itself and any file below it + - /etc/**/** - matches /etc/ itself and any file below it + + :au[tocmd] [{event}] [{pat}] + list those autocommands that match given event-pattern combina- + tion. + {event} and {pat} can be omitted to list all autocommands. To + list any autocommands for specific pattern one can use * place- + holder in place of {event}. + + :au[tocmd]! [{event}] [{pat}] + remove autocommands that match given event-pattern combination. + Syntax is the same as for listing above. + + :apropos + repeat last :apropos command. + + :bmark + + :bmark tag1 [tag2 [tag3...]] + bookmark current directory with specified tags. + + :bmark! path tag1 [tag2 [tag3...]] + same as :bmark, but allows bookmarking specific path instead of + current directory. This is for use in vifmrc and for bookmark- + ing files. + + Path can contain macros that expand to single path (%c, %C, %d, + %D) or those that can expand to multiple paths, but contain only + one (%f, %F, %rx). The latter is done for convenience on using + the command interactively. Complex macros that include spaces + (e.g. "%c:gs/ /_") should be escaped. + + :bmarks + + :bmarks + display all bookmarks in a menu. + + :bmarks [tag1 [tag2...]] + display menu of bookmarks that include all of the specified + tags. See "Menus and dialogs" section for controls. + + :bmgo + + :bmgo [tag1 [tag2...]] + when there are more than one match acts exactly like :bmarks, + otherwise navigates to single match immediately (and fails if + there is no match). + + :cabbrev + + :ca[bbrev] + display menu of command-line mode abbreviations. See "Menus and + dialogs" section for controls. + + :ca[bbrev] lhs-prefix + display command-line mode abbreviations which left-hand side + starts with specified prefix. + + :ca[bbrev] lhs rhs + register new or overwrites existing abbreviation for command- + line mode. rhs can contain spaces and any special sequences ac- + cepted in rhs of mappings (see "Mappings" section below). Ab- + breviations are expanded non-recursively. + + :cnoreabbrev + + :cnorea[bbrev] + display menu of command-line mode abbreviations. See "Menus and + dialogs" section for controls. + + :cnorea[bbrev] lhs-prefix + display command-line mode abbreviations which left-hand side + starts with specified prefix. + + :cnorea[bbrev] lhs rhs + same as :cabbrev, but mappings in rhs are ignored during expan- + sion. + + :cd + + :cd or :cd ~ or :cd $HOME + change to home directory. + + :cd - go to the last visited directory. + + :cd ~/dir + change directory to ~/dir. + + :cd /curr/dir /other/dir + change directory of the current pane to /curr/dir and directory + of the other pane to /other/dir. Relative paths are assumed to + be relative to directory of current view. Command won't fail if + one of directories is invalid. All forms of the command accept + macros. + + :cd! /dir + same as :cd /dir /dir. + + :cds + + :cds[!] pattern string + navigate to path obtained by substituting first match in current + path. Arguments can include slashes, but starting first argu- + ment with a separator will activate below form of the command. + Specifying "!" changes directory of both panes. + + Available flags: + + - i - ignore case (the 'ignorecase' and 'smartcase' options are not + used) + + - I - don't ignore case (the 'ignorecase' and 'smartcase' options are + not used) + + :cds[!]/pattern/string/[flags] + same as above, but with :substitute-like syntax. Other punctua- + tion characters can be used as separators. + + :change + + :c[hange] + show a dialog to alter properties of files. + + :chmod + + :[range]chmod + display file attributes (permission on *nix and properties on + Windows) change dialog. + + :[range]chmod[!] arg... + only for *nix + change permissions for files. See `man 1 chmod` for arg format. + "!" means set permissions recursively. + + :chown + + :[range]chown + only for *nix + same as co key in normal mode. + + :[range]chown [user][:][group] + only for *nix + change owner and/or group of files. Operates on directories re- + cursively. + + :clone + + :[range]clone[!?] + clones files in current directory. With "?" vifm will open vi + to edit file names. "!" forces overwrite. Macros are expanded. + + :[range]clone[!] path + clones files to directory specified with the path (absolute or + relative to current directory). "!" forces overwrite. Macros + are expanded. + + :[range]clone[!] name1 name2... + clones files in current directory giving each next clone a cor- + responding name from the argument list. "!" forces overwrite. + Macros are expanded. + + :colorscheme + + :colo[rscheme]? + print current color scheme name on the status bar. + + :colo[rscheme] + display a menu with a list of available color schemes. You can + choose primary color scheme here. It is used for view if no di- + rectory specific colorscheme fits current path. It's also used + to set border color (except view titles) and colors in menus and + dialogs. See "Menus and dialogs" section for controls. + + :colo[rscheme] color_scheme_name + change primary color scheme to color_scheme_name. In case of + errors (e.g. some colors are not supported by terminal) either + nothing is changed or color scheme is reset to builtin colors to + ensure that TUI is left in a usable state. + + :colo[rscheme] color_scheme_name directory + associate directory with the color scheme. The directory argu- + ment can be either absolute or relative path when :colorscheme + command is executed from command line, but mandatory should be + an absolute path when the command is executed in scripts loaded + at startup (until vifm is completely loaded). + + :colo[rscheme] color_scheme_name color_scheme_name... + loads the first color scheme in the order given that exists and + is supported by the terminal. If none matches, current one re- + mains unchanged. For example: + + " use a separate color scheme for panes which are inside FUSE mounts + execute 'colorscheme in-fuse' &fusehome + + :comclear + + :comc[lear] + remove all user defined commands. + + :command + + :com[mand] + display a menu of user commands. See "Menus and dialogs" sec- + tion for controls. + + :com[mand] prefix + display user defined commands that start with the prefix. + + :com[mand] name action[ &] + set or redefine a user command. + Use :com[mand]! to overwrite a previously set command of the + same name. Builtin commands can't be redefined. + User commands must start with an upper or lower case letter. + Command name can't contain special symbols except for a single + trailing '?' or '!'. Numbers are allowed provided that they + don't cause parsing ambiguity (no command name prefix that pre- + cedes a digit can match an existing command unless it has a + digit in the same place), for example: + " good + :command mp3 command + " good + :command mp4 command + :command mp3! command + :command mp4? command + " bad + :command mp command + :command mp44 command + " good + :command mp4c command + + User commands are run in a shell by default (see below for syn- + tax of other options). To run a command in the background you + must mark it as a background command by adding " &" after the + command's action (e.g., `:com rm rm %f &`). + User commands of all kinds have macros expanded in them. See + "Command macros" section for more information. + + :com[mand] name /pattern + set search pattern. + + :com[mand] name =pattern + set local filter value. + + :com[mand] name filter{:filter args} + set file name filter (see :filter command description). For ex- + ample: + + " display only audio files + :command onlyaudio filter/.+.\(mp3|wav|mp3|flac|ogg|m4a|wma|ape\)$/i + " display everything except audio files + :command noaudio filter!/.+.\(mp3|wav|mp3|flac|ogg|m4a|wma|ape\)$/i + + :com[mand] name :commands + set kind of an alias for internal commands (like in a shell). + Passes range given to alias to an aliased command, so running + :%cp after + :command cp :copy %a + equals + :%copy + + :compare + + :compare [byname | bysize | bycontents | listall | listunique | + listdups | ofboth | ofone | groupids | grouppaths | skipempty]... + compare files in one or two views according to the arguments. + The default is "bycontents listall ofboth grouppaths". See + "Compare views" section below for details. Diff structure is + incompatible with alternative representations, so values of + 'lsview' and 'millerview' options are ignored. + + :copen + + :cope[n] + reopens the last visible menu that has navigation to files by + default, if any. + + :copy + + :[range]co[py][!?][ &] + copy files to directory of other view. With "?" prompts for + destination file names in an editor. "!" forces overwrite. + + :[range]co[py][!] path[ &] + copy files to directory specified with the path (absolute or + relative to directory of other view). "!" forces overwrite. + + :[range]co[py][!] name1 name2...[ &] + copy files to directory of other view giving each next file a + corresponding name from the argument list. "!" forces over- + write. + + :[range]co[py][!?] -skip ...[ &] + see "-skip parameter" section below. + + :cquit + + :cq[uit][!] + same as :quit, but also aborts directory choosing via + --choose-dir (empties output file) and returns non-zero exit + code. + + :cunabbrev + + :cuna[bbrev] lhs + unregister command-line mode abbreviation by its lhs. + + :cuna[bbrev] rhs + unregister command-line mode abbreviation by its rhs, so that + abbreviation could be removed even after expansion. + + :delbmarks + + :delbmarks + remove bookmarks from current directory. + + :delbmarks tag1 [tag2 [tag3...]] + remove set of bookmarks that include all of the specified tags. + + :delbmarks! + remove all bookmarks. + + :delbmarks! path1 [path2 [path3...]] + remove bookmarks of listed paths. + + :delcommand + + :delc[ommand] user_command + remove user defined command named user_command. + + :delete + + :[range]d[elete][!][ &] + delete selected file or files. "!" means complete removal + (omitting trash). + + :[range]d[elete][!] [reg] [count][ &] + delete selected or [count] files to the reg register. "!" means + complete removal (omitting trash). + + :delmarks + + :delm[arks]! + delete all marks. + + :delm[arks] marks ... + delete specified marks, each argument is treated as a set of + marks. + + :delsession + + :delsession + delete specified session if it was stored previously. Deleting + current session doesn't detach it. + + :display + + :di[splay] + display menu with registers content. + + :di[splay] list ... + display the contents of the numbered and named registers that + are mentioned in list (for example "az to display "", "a and "z + content). + + :dirs + + :dirs display directory stack in a menu. See "Menus and dialogs" sec- + tion for controls. + + :echo + + :ec[ho] [...] + evaluate each argument as an expression and output them sepa- + rated with a space. See help on :let command for a definition + of . + + :edit + + :[range]e[dit] [file...] + open selected or passed file(s) in editor. Macros and environ- + ment variables are expanded. + + :else + + :el[se] + execute commands until next matching :endif if all other condi- + tions didn't match. See also help on :if and :endif commands. + + :elseif + + :elsei[f] {expr1} + execute commands until next matching :elseif, :else or :endif if + conditions of previous :if and :elseif branches were evaluated + to zero. See also help on :if and :endif commands. + + :empty + + :empty permanently remove files from all existing non-empty trash di- + rectories (see "Trash directory" section below). Trash directo- + ries which are specified via %r and/or %u also get deleted com- + pletely. Also remove all operations from undolist that have no + sense after :empty and remove all records about files located + inside directories from all registers. Removal is performed as + background task with undetermined amount of work and can be + checked via :jobs menu. + + :endif + + :en[dif] + end conditional block. See also help on :if and :else commands. + + :execute + + :exe[cute] [...] + evaluate each argument as an expression and join results sepa- + rated by a space to get a single string which is then executed + as a command-line command. See help on :let command for a defi- + nition of . + + :exit + + :exi[t][!] + same as :quit. + + :file + + :f[ile][ &] + display menu of programs set for the file type of the current + file. " &" forces running associated program in background. + See "Menus and dialogs" section for controls. + + :f[ile] arg[ &] + run associated command that begins with the arg skipping opening + menu. " &" forces running associated program in background. + + :filetype + + :filet[ype] pattern-list [{descr}]def_prog[ &],[{descr}]prog2[ &],... + associate given program list to each of the patterns. Associ- + ated program (command) is used by handlers of l and Enter keys + (and also in the :file menu). If you need to insert comma into + command just double it (",,"). Space followed by an ampersand + as two last characters of a command means running of the command + in the background. Optional description can be given to each + command to ease understanding of what command will do in the + :file menu. Vifm will try the rest of the programs for an asso- + ciation when the default isn't found. When program entry + doesn't contain any of vifm macros, name of current file is ap- + pended as if program entry ended with %c macro on *nix and %"c + on Windows. On Windows path to executables containing spaces + can (and should be for correct work with such paths) be double + quoted. See "Patterns" section below for pattern definition and + "Selection" section for how selection is handled. See also "Au- + tomatic FUSE mounts" section below. Example for zip archives + and several actions: + + filetype *.zip,*.jar,*.war,*.ear + \ {Mount with fuse-zip} + \ FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR, + \ {View contents} + \ zip -sf %c | less, + \ {Extract here} + \ tar -xf %c, + + Note that on OS X when `open` is used to call an app, vifm is + unable to check whether that app is actually available. So if + automatic skipping of programs that aren't there is desirable, + `open` should be replaced with an actual command. + + :filet[ype] filename + list (in menu mode) currently registered patterns that match + specified file name. Same as ":filextype filename". + + :filextype + + :filex[type] pattern-list [{ description }] def_program,program2,... + same as :filetype, but this command is ignored if not running in + X. In X :filextype is equal to :filetype. See "Patterns" sec- + tion below for pattern definition and "Selection" section for + how selection is handled. See also "Automatic FUSE mounts" sec- + tion below. + + For example, consider the following settings (the order might + seem strange, but it's for the demonstration purpose): + + filetype *.html,*.htm + \ {View in lynx} + \ lynx + filextype *.html,*.htm + \ {Open with dwb} + \ dwb %f %i &, + filetype *.html,*.htm + \ {View in links} + \ links + filextype *.html,*.htm + \ {Open with firefox} + \ firefox %f &, + \ {Open with uzbl} + \ uzbl-browser %f %i &, + + If you're using vifm inside a terminal emulator that is running + in graphical environment (when X is used on *nix; always on Win- + dows), vifm attempts to run application in this order: + + 1. lynx + 2. dwb + 3. links + 4. firefox + 5. uzbl + + If there is no graphical environment (checked by presence of + non-empty $DISPLAY or $WAYLAND_DISPLAY environment variable on + *nix; never happens on Windows), the list will look like: + + 1. lynx + 2. links + + Just as if all :filextype commands were not there. + + The purpose of such differentiation is to allow comfortable use + of vifm with same settings in desktop environment/through remote + connection (SSH)/in native console. + + Note that on OS X $DISPLAY isn't defined unless you define it, + so :filextype should be used only if you set $DISPLAY in some + way. + + :filext[ype] filename + list (in menu mode) currently registered patterns that match + specified file name. Same as ":filetype filename". + + :fileviewer + + :filev[iewer] pattern-list command1,command2,... + register specified list of commands as viewers for each of the + patterns. Viewer is a command which output is captured and dis- + played in one of the panes of vifm after pressing "e" or running + :view command. When the command doesn't contain any of vifm + macros, name of current file is appended as if command ended + with %c macro. Comma escaping and missing commands processing + rules as for :filetype apply to this command. See "Patterns" + section below for pattern definition. Supports Lua handlers. + + Example for zip archives: + + fileviewer *.zip,*.jar,*.war,*.ear zip -sf %c, echo "No zip to preview:" + + :filev[iewer] filename + list (in menu mode) currently registered patterns that match + specified filename. + + :filter + + :filter[!] {pattern} + filter files matching the pattern out of directory listings. + '!' controls state of filter inversion after updating filter + value (see also 'cpoptions' description). Filter is matched + case sensitively on *nix and case insensitively on Windows. See + "File Filters" and "Patterns" sections. + + Example: + + " filter all files ending in .o from the filelist. + :filter /.o$/ + + + :filter[!] {empty-pattern} + same as above, but use last search pattern as pattern value. + + Example: + + :filter //I + + + :filter + reset filter (set it to an empty string) and show all files. + + :filter! + same as :invert. + + :filter? + show information on local, name and auto filters. + + :find + + :[range]fin[d] pattern + display results of find command in the menu. Searches among se- + lected files if any. Accepts macros. By default the command + relies on the external "find" utility, which can be customized + by altering value of the 'findprg' option. + + :[range]fin[d] -opt... + same as :find above, but user defines all find arguments. + Searches among selected files if any. + + :[range]fin[d] path -opt... + same as :find above, but user defines all find arguments. Ig- + nores selection and range. + + :[range]fin[d] + repeat last :find command. + + :finish + + :fini[sh] + stop sourcing a script. Can only be used in a vifm script file. + This is a quick way to skip the rest of the file. + + :goto + + :go[to] + change directory if necessary and put specified path under the + cursor. The path should be existing non-root path. Macros and + environment variables are expanded. + + :grep + + :[range]gr[ep][!] pattern + will show results of grep command in the menu. Add "!" to re- + quest inversion of search (look for lines that do not match pat- + tern). Searches among selected files if any and no range given. + Ignores binary files by default. By default the command relies + on the external "grep" utility, which can be customized by al- + tering value of the 'grepprg' option. + + :[range]gr[ep][!] -opt... + same as :grep above, but user defines all grep arguments, which + are not escaped. Searches among selected files if any. + + :[range]gr[ep][!] + repeat last :grep command. "!" of this command inverts "!" in + repeated command. + + :help + + :h[elp] + show the help file. + + :h[elp] argument + is the same as using ':h argument' in vim. Use vifm- + to get help on vifm (tab completion works). This form of the + command doesn't work when 'vimhelp' option is off. + + :hideui + + :hideui + hide interface to show previous commands' output. + + :highlight + + :hi[ghlight] + display information about all highlight groups active at the mo- + ment. + + :hi[ghlight] clear + reset all highlighting to builtin defaults and removed all file- + name-specific rules. + + :hi[ghlight] clear ( {pat1,pat2,...} | /regexp/ ) + remove specified rule. + + :hi[ghlight] ( group-name | {pat1,pat2,...} | /regexp/ ) + display information on given highlight group or file name pat- + tern of color scheme used in the active view. + + :hi[ghlight] ( group-name | {pat1,pat2,...} | /regexp/[iI] ) + cterm=style | ctermfg=color | ctermbg=color | gui=style | guifg=color | + guibg=color + set style (cterm, gui), foreground (ctermfg, guifg) and/or back- + ground (ctermbg, guibg) parameters of highlight group or file + name pattern for color scheme used in the active view. + + All style values as well as color names are case insensitive. + + Available style values (some of them can be combined): + - bold + - underline + - reverse or inverse + - standout + - italic (on unsupported systems becomes reverse) + - combine - add attributes of current group to attributes of the par- + ent in group hierarchy (see below) instead of replacing them + - none + + Available group-name values: + - Win - color of all windows (views, dialogs, menus) and default color + for their content (e.g. regular files in views) + - AuxWin - color of auxiliary areas of windows + - OtherWin - color of inactive pane + - Border - color of vertical parts of the border + - TabLine - tab line color (for 'tabscope' set to "global") + - TabLineSel - color of the tip of selected tab (regardless of 'tab- + scope') + - TopLine - top line color of the other pane + - TopLineSel - top line color of the current pane + - CmdLine - the command line/status bar color + - ErrorMsg - color of error messages in the status bar + - StatusLine - color of the line above the status bar + - JobLine - color of job line that appears above the status line + - WildMenu - color of the wild menu items + - SuggestBox - color of key suggestion box + - CurrLine - line at cursor position in active view + - OtherLine - line at cursor position in inactive view + - OddLine - color of every second entry line in a pane + - LineNr - line number column of views + - Selected - color of selected files + - Directory - color of directories + - Link - color of symbolic links in the views + - BrokenLink - color of broken symbolic links + - HardLink - color of regular files with more than one hard link + - Socket - color of sockets + - Device - color of block and character devices + - Executable - color of executable files + - Fifo - color of fifo pipes + - CmpMismatch - color of mismatched files in side-by-side comparison + by path + - CmpUnmatched - comparison file entry that has no pair in the other + pane + - CmpBlank - entry placeholder in a compare view, paired with CmpUn- + matched + - User1..User9 - 9 colors which can be used via %* 'statusline' macro + + Available colors: + - -1 or default or none - default or transparent + - black and lightblack + - red and lightred + - green and lightgreen + - yellow and lightyellow + - blue and lightblue + - magenta and lightmagenta + - cyan and lightcyan + - white and lightwhite + - 0-255 - corresponding colors from 256-color palette (for ctermfg and + ctermbg) + - #rrggbb - direct ("gui", "true", 24-bit) color in hex-notation, each + of the three compontents are in the range 0x00 to 0xff (for guifg and + guibg) + + Light versions of colors are regular colors with bold attribute set au- + tomatically in terminals that have less than 16 colors. So order of + arguments of :highlight command is important and it's better to put + "cterm" in front of others to prevent it from overwriting attributes + set by "ctermfg" or "ctermbg" arguments. + + For convenience of color scheme authors xterm-like names for 256 color + palette is also supported. The mapping is taken from + http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim + Duplicated entries were altered by adding an underscore followed by nu- + merical suffix. + + 0 Black 86 Aquamarine1 172 Orange3 + 1 Red 87 DarkSlateGray2 173 LightSalmon3_2 + 2 Green 88 DarkRed_2 174 LightPink3 + 3 Yellow 89 DeepPink4_2 175 Pink3 + 4 Blue 90 DarkMagenta 176 Plum3 + 5 Magenta 91 DarkMagenta_2 177 Violet + 6 Cyan 92 DarkViolet 178 Gold3_2 + 7 White 93 Purple 179 LightGoldenrod3 + 8 LightBlack 94 Orange4_2 180 Tan + 9 LightRed 95 LightPink4 181 MistyRose3 + 10 LightGreen 96 Plum4 182 Thistle3 + 11 LightYellow 97 MediumPurple3 183 Plum2 + 12 LightBlue 98 MediumPurple3_2 184 Yellow3_2 + 13 LightMagenta 99 SlateBlue1 185 Khaki3 + 14 LightCyan 100 Yellow4 186 LightGoldenrod2 + 15 LightWhite 101 Wheat4 187 LightYellow3 + 16 Grey0 102 Grey53 188 Grey84 + 17 NavyBlue 103 LightSlateGrey 189 LightSteelBlue1 + 18 DarkBlue 104 MediumPurple 190 Yellow2 + 19 Blue3 105 LightSlateBlue 191 DarkOliveGreen1 + 20 Blue3_2 106 Yellow4_2 192 DarkOliveG- + reen1_2 + 21 Blue1 107 DarkOliveGreen3 193 DarkSeaGreen1_2 + 22 DarkGreen 108 DarkSeaGreen 194 Honeydew2 + 23 DeepSkyBlue4 109 LightSkyBlue3 195 LightCyan1 + 24 DeepSkyBlue4_2 110 LightSkyBlue3_2 196 Red1 + 25 DeepSkyBlue4_3 111 SkyBlue2 197 DeepPink2 + 26 DodgerBlue3 112 Chartreuse2_2 198 DeepPink1 + 27 DodgerBlue2 113 DarkOliveGreen3_2 199 DeepPink1_2 + 28 Green4 114 PaleGreen3_2 200 Magenta2_2 + 29 SpringGreen4 115 DarkSeaGreen3 201 Magenta1 + 30 Turquoise4 116 DarkSlateGray3 202 OrangeRed1 + 31 DeepSkyBlue3 117 SkyBlue1 203 IndianRed1 + 32 DeepSkyBlue3_2 118 Chartreuse1 204 IndianRed1_2 + 33 DodgerBlue1 119 LightGreen_2 205 HotPink + 34 Green3 120 LightGreen_3 206 HotPink_2 + 35 SpringGreen3 121 PaleGreen1 207 MediumOrchid1_2 + 36 DarkCyan 122 Aquamarine1_2 208 DarkOrange + 37 LightSeaGreen 123 DarkSlateGray1 209 Salmon1 + 38 DeepSkyBlue2 124 Red3 210 LightCoral + 39 DeepSkyBlue1 125 DeepPink4_3 211 PaleVioletRed1 + 40 Green3_2 126 MediumVioletRed 212 Orchid2 + 41 SpringGreen3_2 127 Magenta3 213 Orchid1 + 42 SpringGreen2 128 DarkViolet_2 214 Orange1 + 43 Cyan3 129 Purple_2 215 SandyBrown + 44 DarkTurquoise 130 DarkOrange3 216 LightSalmon1 + 45 Turquoise2 131 IndianRed 217 LightPink1 + 46 Green1 132 HotPink3 218 Pink1 + 47 SpringGreen2_2 133 MediumOrchid3 219 Plum1 + 48 SpringGreen1 134 MediumOrchid 220 Gold1 + 49 MediumSpringGreen 135 MediumPurple2 221 LightGolden- + rod2_2 + 50 Cyan2 136 DarkGoldenrod 222 LightGolden- + rod2_3 + 51 Cyan1 137 LightSalmon3 223 NavajoWhite1 + 52 DarkRed 138 RosyBrown 224 MistyRose1 + 53 DeepPink4 139 Grey63 225 Thistle1 + 54 Purple4 140 MediumPurple2_2 226 Yellow1 + 55 Purple4_2 141 MediumPurple1 227 LightGoldenrod1 + 56 Purple3 142 Gold3 228 Khaki1 + 57 BlueViolet 143 DarkKhaki 229 Wheat1 + 58 Orange4 144 NavajoWhite3 230 Cornsilk1 + 59 Grey37 145 Grey69 231 Grey100 + 60 MediumPurple4 146 LightSteelBlue3 232 Grey3 + 61 SlateBlue3 147 LightSteelBlue 233 Grey7 + 62 SlateBlue3_2 148 Yellow3 234 Grey11 + 63 RoyalBlue1 149 DarkOliveGreen3_3 235 Grey15 + 64 Chartreuse4 150 DarkSeaGreen3_2 236 Grey19 + 65 DarkSeaGreen4 151 DarkSeaGreen2 237 Grey23 + 66 PaleTurquoise4 152 LightCyan3 238 Grey27 + 67 SteelBlue 153 LightSkyBlue1 239 Grey30 + 68 SteelBlue3 154 GreenYellow 240 Grey35 + 69 CornflowerBlue 155 DarkOliveGreen2 241 Grey39 + 70 Chartreuse3 156 PaleGreen1_2 242 Grey42 + 71 DarkSeaGreen4_2 157 DarkSeaGreen2_2 243 Grey46 + 72 CadetBlue 158 DarkSeaGreen1 244 Grey50 + 73 CadetBlue_2 159 PaleTurquoise1 245 Grey54 + 74 SkyBlue3 160 Red3_2 246 Grey58 + 75 SteelBlue1 161 DeepPink3 247 Grey62 + 76 Chartreuse3_2 162 DeepPink3_2 248 Grey66 + 77 PaleGreen3 163 Magenta3_2 249 Grey70 + 78 SeaGreen3 164 Magenta3_3 250 Grey74 + 79 Aquamarine3 165 Magenta2 251 Grey78 + 80 MediumTurquoise 166 DarkOrange3_2 252 Grey82 + 81 SteelBlue1_2 167 IndianRed_2 253 Grey85 + 82 Chartreuse2 168 HotPink3_2 254 Grey89 + 83 SeaGreen2 169 HotPink2 255 Grey93 + 84 SeaGreen1 170 Orchid + 85 SeaGreen1_2 171 MediumOrchid1 + + There are two colors (foreground and background) and only one bold at- + tribute. Thus single bold attribute affects both colors when "reverse" + attribute is used in vifm run inside terminal emulator. At the same + time linux native console can handle boldness of foreground and back- + ground colors independently, but for consistency with terminal emula- + tors this is available only implicitly by using light versions of col- + ors. This behaviour might be changed in the future. + + Although vifm supports 256 colors in a sense they are supported by UI + drawing library, whether you will be able to use all of them highly de- + pends on your terminal. To set up terminal properly, make sure that + $TERM in the environment you run vifm is set to name of 256-color ter- + minal (on *nixes it can also be set via X resources), e.g. + xterm-256color. One can find list of available terminal names by list- + ing /usr/lib/terminfo/. Number of colors supported by terminal with + current settings can be checked via "tput colors" command. + + In order to use 24-bit colors one needs a terminal that supports them, + corresponding terminfo record (probably ends in "-direct" like in + "xterm-direct") and $TERM pointing to it. When vifm detects direct + color support "cterm*" values are ignored for groups which have at + least one of "gui*" values set, otherwise they are used after translat- + ing via a builtin palette. + + Here is the hierarchy of highlight groups, which you need to know for + using transparency: + JobLine + SuggestBox + StatusLine + WildMenu + User1..User9 + Border + CmdLine + ErrorMsg + Win + OtherWin + AuxWin + OddLine + File name specific highlights + Directory + Link + BrokenLink + HardLink + Socket + Device + Fifo + Executable + CmpMismatch + CmpUnmatched + CmpBlank + Selected + CurrLine + LineNr (in active pane) + OtherLine + LineNr (in inactive pane) + TopLine + TopLineSel + TabLineSel (for pane tabs) + User1..User9 + TabLine + TabLineSel + User1..User9 + + "none" means default terminal color for highlight groups at the first + level of the hierarchy and transparency for all others. + + Here file name specific highlights mean those configured via globs ({}) + or regular expressions (//). At most one of them is applied per file + entry, namely the first that matches file name, hence order of :high- + light commands might be important in certain cases. + + :history + + :his[tory] + display a menu with list of visited directories. See "Menus and + dialogs" section for controls. + + :his[tory] x + x can be: + d[ir] or . show directory history. + c[md] or : show command line history. + s[earch] or / show search history and search forward on l + key. + f[search] or / show search history and search forward on l + key. + b[search] or ? show search history and search backward on l + key. + i[nput] or @ show prompt history (e.g. on one file renam- + ing). + fi[lter] or = show local filter history (see description of + the "=" normal mode command). + e[xprreg] show expression register history (see descrip- + tion of Ctrl+R = in command-line mode). + See "Menus and dialogs" section for controls. + + :histnext + + :histnext + same as . The main use case for this command is to work + around the common pain point of and being the same + ASCII character: one could alter the terminal emulator settings + to emit, for example, the `F1` keycode when Ctrl-I is pressed, + then `:noremap :histnext` in vifm, add "t" flag to the + 'cpoptions', and thus have both and working as ex- + pected. + + :histprev + + :histprev + same as . + + :if + + :if {expr1} + start conditional block. Commands are executed until next + matching :elseif, :else or :endif command if {expr1} evaluates + to non-zero, otherwise they are ignored. See also help on :else + and :endif commands. + + Example: + + if $TERM == 'screen.linux' + highlight CurrLine ctermfg=lightwhite ctermbg=lightblack + elseif $TERM == 'tmux' + highlight CurrLine cterm=reverse ctermfg=black ctermbg=white + else + highlight CurrLine cterm=bold,reverse ctermfg=black ctermbg=white + endif + + :invert + + :invert [f] + invert file name filter. + + :invert? [f] + show current filter state. + + :invert s + invert selection. + + :invert o + invert sorting order of the primary sorting key. + + :invert? o + show sorting order of the primary sorting key. + + :jobs + + :jobs display menu of current backgrounded processes. See "Menus and + dialogs" section for controls. + + :keepsel + + :keepsel [command...] + preserve selection during some :command by default. Note that + this doesn't save and restore selection to preserve it no matter + what, but precludes its clearing at the end of a command and + thus won't help if selection is cleared explicitly during opera- + tion. + + Example: + + :keepsel view + + :let + + :let $ENV_VAR = + set an environment variable. Warning: setting environment vari- + able to an empty string on Windows removes it. + + :let $ENV_VAR .= + append value to environment variable. + + :let &[l:|g:]opt = + sets option value. + + :let &[l:|g:]opt .= + append value to string option. + + :let &[l:|g:]opt += + increasing option value, adding sub-values. + + :let &[l:|g:]opt -= + decreasing option value, removing sub-values. + + Where could be a single-quoted string, double-quoted string, an + environment variable, function call or a concatanation of any of them + in any order using the '.' operator. Any whitespace is ignored. + + :locate + + :locate filename + use "locate" command to create a menu of filenames. Selecting a + file from the menu will reload the current file list in vifm to + show the selected file. By default the command relies on the + external "locate" utility (it's assumed that its database is al- + ready built), which can be customized by altering value of the + 'locateprg' option. See "Menus and dialogs" section for con- + trols. + + :locate + repeat last :locate command. + + :ls + + :ls lists windows of active terminal multiplexer (only when terminal + multiplexer is used). This is achieved by issuing proper com- + mand for active terminal multiplexer, thus the list is not han- + dled by vifm. + + :lstrash + + :lstrash + display a menu with list of files in trash. Each element of the + list is original path of a deleted file, thus the list can con- + tain duplicates. See "Menus and dialogs" section for controls. + + :mark + + :[range]ma[rk][?] x [/full/path] [filename] + Set mark x (a-zA-Z0-9) at /full/path and filename. By default + current directory is being used. If no filename was given and + /full/path is current directory then last file in [range] is + used. Using of macros is allowed. Question mark will stop com- + mand from overwriting existing marks. + + :marks + + :marks create a pop-up menu of marks. See "Menus and dialogs" section + for controls. + + :marks list ... + display the contents of the marks that are mentioned in list. + + :media + + :media only for *nix + display media management menu. See "Menus and dialogs" section + for controls. See also 'mediaprg' option. + + :messages + + :mes[sages] + shows previously given messages (up to 50). + + :mkdir + + :[line]mkdir[!] dir ... + create directories at specified paths. The [line] can be used + to pick node in a tree-view. "!" means make parent directories + as needed. Macros are expanded. + + :move + + :[range]m[ove][!?][ &] + move files to directory of other view. With "?" prompts for + destination file names in an editor. "!" forces overwrite. + + :[range]m[ove][!] path[ &] + move files to directory specified with the path (absolute or + relative to directory of other view). "!" forces overwrite. + + :[range]m[ove][!] name1 name2...[ &] + move files to directory of other view giving each next file a + corresponding name from the argument list. "!" forces over- + write. + + :[range]m[ove][!?] -skip ...[ &] + see "-skip parameter" section below. + + :nohlsearch + + :noh[lsearch] + clear selection in current pane. + + :normal + + :norm[al][!] commands + execute normal mode commands. If "!" is used, user defined map- + pings are ignored. Unfinished last command is aborted as if + or was typed. A ":" should be completed as well. + Commands can't start with a space, so put a count of 1 (one) be- + fore it. + + :only + + :on[ly] + switch to a one window view. + + :plugin + + :plugin load + loads all plugins. To be used in configuration file to manually + load plugins at an earlier point. The plugins can be loaded + only once, additional calls will do nothing. + + + :plugin blacklist {plugin} + adds {plugin} to the list of plugins to be ignored. + + :plugin whitelist {plugin} + adds {plugin} to the list of plugins to be loaded while ignoring + all other plugins. This list should normally be empty. + + :plugins + + :plugins + open plugins menu. See "Menus and dialogs" section for con- + trols. + + :popd + + :popd remove pane directories from stack. + + :pushd + + :pushd[!] /curr/dir [/other/dir] + add pane directories to stack and process arguments like :cd + command. + + :pushd exchange the top two items of the directory stack. + + :put + + :[line]pu[t][!] [reg] [ &] + put files from specified register (" by default) into current + directory. The [line] can be used to pick node in a tree-view. + "!" moves files "!" moves files from their original location in- + stead of copying them. During this operation no confirmation + dialogs will be shown, all checks are performed beforehand. + + :pwd + + :pw[d] show the present working directory. + + :qall + + :qa[ll][!] + exit vifm (add ! to skip saving changes and checking for active + backgrounded commands). + + :quit + + :q[uit][!] + if there is more than one tab, close the current one, otherwise + exit vifm (add ! to skip saving state and checking for active + backgrounded commands). + + :redraw + + :redr[aw] + redraw the screen immediately. + + :registers + + :reg[isters] + display menu with registers content. + + :reg[isters] list ... + display the contents of the numbered and named registers that + are mentioned in list (for example "az to display "", "a and "z + content). + + :regular + + :regular + + switch to regular view leaving custom view. + :rename + + :[range]rename[!] + rename files by editing their names in an editor. "!" renames + files recursively in subdirectories. See "External Renaming" + section. + + :[range]rename name1 name2... + rename each of selected files to a corresponding name. + + :restart + + :restart + free a lot of things (histories, commands, etc.), reread + vifminfo, vifmrc and session files and run startup commands + passed in the argument list, thus losing all unsaved changes + (e.g. recent history or keys mapped after starting this in- + stance). Session that wasn't yet stored gets reset. + + While many things get reset, some basic UI state and current lo- + cations are preserved, including tabs. + + :restart full + variation of :restart that makes no attempt to preserve any- + thing. + + :restore + + :[range]restore + restore file from trash directory, doesn't work outside one of + trash directories. See "Trash directory" section below. + + :rlink + + :[range]rlink[!?] + create relative symbolic links to files in directory of other + view. With "?" prompts for destination file names in an editor. + "!" forces overwrite. + + :[range]rlink[!] path + create relative symbolic links of files in directory specified + with the path (absolute or relative to directory of other view). + "!" forces overwrite. + + :[range]rlink[!] name1 name2... + create relative symbolic links of files in directory of other + view giving each next link a corresponding name from the argu- + ment list. "!" forces overwrite. + + :[range]rlink[!?] -skip ...[ &] + see "-skip parameter" section below. + + :screen + + :screen + toggle whether to use the terminal multiplexer or not. + A terminal multiplexer uses pseudo terminals to allow multiple + windows to be used in the console or in a single xterm. Start- + ing vifm from terminal multiplexer with appropriate support + turned on will cause vifm to open a new terminal multiplexer + window for each new file edited or program launched from vifm. + This requires screen version 3.9.9 or newer for the screen -X + argument or tmux (1.8 version or newer is recommended). + + :screen! + enable integration with terminal multiplexers. + + :screen? + display whether integration with terminal multiplexers is en- + abled. + + Note: the command is called screen for historical reasons (when tmux + wasn't yet supported) and might be changed in future releases, or get + an alias. + + :select + + :[range]select + select files in the given range (current file if no range is + given). + + :select {pattern} + select files that match specified pattern. Possible {pattern} + forms are described in "Patterns" section below. Trailing slash + for directories is taken into account, so `:select! */ | invert + s` selects only files. + + :select //[iI] + same as item above, but reuses last search pattern. + + :select !{external command} + select files from the list supplied by external command. Files + are matched by full paths, relative paths are converted to abso- + lute ones beforehand. + + :[range]select! [{pattern}] + same as above, but resets previously selected items before pro- + ceeding. + + :session + + :session? + print name of the current session. + + :session + detach current session without saving it. Resets v:session. + + :session name + create or load and switch to a session with the specified name. + Name can't contain slashes. Session active at the moment is + saved before the switch. Session is also automatically saved + when quiting the application in usual ways. Sets v:session. + + :session - + switch to a previous session if it still exists (wasn't removed + or detached from without saving). + + :set + + :se[t] display all options that differ from their default value. + + :se[t] all + display all options. + + :se[t] opt1=val1 opt2='val2' opt3="val3" ... + sets given options. For local options both values are set. + You can use following syntax: + - for all options - option, option? and option& + - for boolean options - nooption, invoption and option! + - for integer options - option=x, option+=x and option-=x + - for string options - option=x and option+=x + - for string list options - option=x, option+=x, option-=x and + option^=x + - for enumeration options - option=x, option+=x and option-=x + - for set options - option=x, option+=x, option-=x and op- + tion^=x + - for charset options - option=x, option+=x, option-=x and op- + tion^=x + + the meaning: + - option - turn option on (for boolean) or print its value (for + all others) + - nooption - turn option off + - invoption - invert option state + - option! - invert option state + - option? - print option value + - option& - reset option to its default value + - option=x or option:x - set option to x + - option+=x - add/append x to option + - option-=x - remove (or subtract) x from option + - option^=x - toggle x presence among values of the option + + Option name can be prepended and appended by any number of + whitespace characters. + + :setglobal + + :setg[lobal] + display all global options that differ from their default value. + + :setg[lobal] all + display all global options. + + :setg[lobal] opt1=val1 opt2='val2' opt3="val3" ... + same as :set, but changes/prints only global options or global + values of local options. Changes to the latter might be not + visible until directory is changed. + + :setlocal + + :setl[ocal] + display all local options that differ from their default value. + + :setl[ocal] all + display all local options. + + :setl[ocal] opt1=val1 opt2='val2' opt3="val3" ... + same as :set, but changes/prints only local values of local op- + tions. + + :shell + + :sh[ell][!] + start a shell in current directory. "!" suppresses spawning + dedicated window of terminal multiplexer for a shell. To make + vifm adaptive to environment it uses $SHELL if it's defined, + otherwise 'shell' value is used. + + + :siblnext + + :[count]siblnext[!] + + change directory to [count]th next sibling directory after cur- + rent path using value of global sort option of current pane. + "!" enables wrapping. + + For example, say, you're at /boot and root listing starts like + this: + + bin/ + boot/ + dev/ + ... + + Issuing :siblnext will navigate to /dev. + + + :siblprev + + :[count]siblprev[!] + same as :siblnext, but in the opposite direction. + + :sort + + :sor[t] + display dialog with different sorting methods, where one can se- + lect the primary sorting key. When 'viewcolumns' options is + empty and 'lsview' is off, changing primary sorting key will + also affect view look (in particular the second column of the + view will be changed). See "Menus and dialogs" section for con- + trols. + + :source + + :so[urce] file + read command-line commands from the file. + + :split + + :sp[lit] + switch to a two window horizontal view. + + :sp[lit]! + toggle horizontal window splitting. + + :sp[lit] path + splits the window horizontally to show both file directories. + Also changes other pane to path (absolute or relative to current + directory of active pane). + + :stop + + :st[op] + suspend vifm (same as pressing Ctrl-Z). Does nothing if this + instance isn't running in a shell. The command exists to allow + mapping to the action of Ctrl-Z. + + :substitute + + :[range]s[ubstitute]/pattern/string/[flags] + for each file in range replace a match of pattern with string. + + String can contain \0...\9 to link to capture groups (\0 - all match, + \1 - first group, etc.). + + Pattern is stored in search history. + + Available flags: + + - i - ignore case (the 'ignorecase' and 'smartcase' options are not + used) + + - I - don't ignore case (the 'ignorecase' and 'smartcase' options are + not used) + + - g - substitute all matches in each file name (each g toggles this) + + :[range]s[ubstitute]/pattern + substitute pattern with an empty string. + + :[range]s[ubstitute]//string/[flags] + use last pattern from search history. + + :[range]s[ubstitute] + repeat previous substitution command. + + :sync + + :sync [relative path] + change the other pane to the current pane directory or to some + path relative to the current directory. Using macros is al- + lowed. + + :sync! change the other pane to the current pane directory and synchro- + nize cursor position. If current pane displays custom list of + files, position before entering it is used (current one might + not make any sense). + + + :sync! [location | cursorpos | localopts | filters | filelist | tree | + all]... + change enumerated properties of the other pane to match corre- + sponding properties of the current pane. Arguments have the + following meanings: + + - location - current directory of the pane; + + - cursorpos - cursor position (doesn't make sense without "lo- + cation"); + + - localopts - all local options; + + - filters - all filters; + + - filelist - list of files for custom view (implies "loca- + tion"); + + - tree - tree structure for tree view (implies "location"); + + - all - all of the above. + + :tabclose + + :tabc[lose] + close current tab, unless it's the only one open at current + scope. + + :tabmove + + :tabm[ove] [N] + without the argument or with `$` as the argument, current tab + becomes the last tab. With the argument, current tab is moved + after the tab with the specified number. Argument of `0` moves + current tab to the first position. + + :tabname + + :tabname [name] + set, update or reset (when no argument is provided) name of the + current tab. + + :tabnew + + :tabnew [path] + create new tab. Accepts optional path for the new tab. Macros + and environment variables are expanded. + + :tabnext + + :tabn[ext] + switch to the next tab (wrapping around). + + :tabn[ext] {n} + go to the tab number {n}. Tab numeration starts with 1. + + :tabonly + + :tabo[nly] + close all tabs but the current one. Closes pane tabs only at + the active side. + + :tabprevious + + :tabp[revious] + switch to the previous tab (wrapping around). + + :tabp[revious] {n} + go to the {n}-th previous tab. Note that :tabnext handles its + argument differently. + + :touch + + :[line]touch file... + create files at specified paths. Aborts on errors. Doesn't up- + date time of existing files. The [line] can be used to pick + node in a tree-view. Macros are expanded. + + :tr + + :[range]tr/pattern/string/ + for each file in range transliterate the characters which appear + in pattern to the corresponding character in string. When + string is shorter than pattern, it's padded with its last char- + acter. + + :trashes + + :trashes + lists all valid trash directories in a menu. Only non-empty and + writable trash directories are shown. This is exactly the list + of directories that are cleared when :empty command is executed. + + :trashes? + same as :trashes, but also displays size of each trash direc- + tory. + + :tree + + :tree turn pane into tree view with current directory as its root. + The tree view is implemented on top of a custom view, but is au- + tomatically kept in sync with file system state and considers + all the filters. Thus the structure corresponds to what one + would see on visiting the directories manually. As a special + case for trees built out of custom view file-system tracking + isn't performed. + + To leave tree view go up from its root or use gh at any level of + the tree. Any command that changes directory will also do, in + particular, `:cd ..`. + + Tree structure is incompatible with alternative representations, + so values of 'lsview' and 'millerview' options are ignored. + + The "depth" argument specifies nesting level on which loading of + subdirectories won't happen (they will be folded). Values start + at 1. + + :tree! toggle current view in and out of tree mode. + + :undolist + + :undol[ist] + display list of latest changes. Use "!" to see actual commands. + See "Menus and dialogs" section for controls. + + :unlet + + :unl[et][!] $ENV_VAR1 $ENV_VAR2 ... + remove environment variables. Add ! to omit displaying of warn- + ings about nonexistent variables. + + :unselect + + :[range]unselect + unselect files in the given range (current file if no range is + given). + + :unselect {pattern} + unselect files that match specified pattern. Possible {pattern} + forms are described in "Patterns" section below. Trailing slash + for directories is taken into account, so `:unselect */` unse- + lects directories. + + :unselect !{external command} + unselect files from the list supplied by external command. + Files are matched by full paths, relative paths are converted to + absolute ones beforehand. + + :unselect //[iI] + same as item above, but reuses last search pattern. + + :version + + :ve[rsion] + show menu with version information. + + :vifm + + :vifm same as :version. + + :view + + :vie[w] + toggle on and off the quick file view (preview of file's con- + tents). See also 'quickview' option. + + :vie[w]! + turn on quick file view if it's off. + + :volumes + + :volumes + only for MS-Windows + display menu with volume list. Hitting l (or Enter) key opens + appropriate volume in the current pane. See "Menus and dialogs" + section for controls. + + :vsplit + + :vs[plit] + switch to a two window vertical view. + + :vs[plit]! + toggle window vertical splitting. + + :vs[plit] path + split the window vertically to show both file directories. And + changes other pane to path (absolute or relative to current di- + rectory of active pane). + + :wincmd + + :[count]winc[md] {arg} + same as running Ctrl-W [count] {arg}. + + :windo + + :windo [command...] + execute command for each pane (same as :winrun % command). + + :winrun + + :winrun type [command...] + execute command for pane(s), which is determined by type argu- + ment: + - ^ - top-left pane + - $ - bottom-right pane + - % - all panes + - . - current pane + - , - other pane + + :write + + :w[rite] + write current state to vifminfo and session files (if a session + is active). + + :wq + + :wq[!] same as :quit, but ! disables only the check of backgrounded + commands, while state of the application is always written. + :wqall + + :wqa[ll][!] + same as :qall, but ! disables only the check of backgrounded + commands, while state of the application is always written. + + :xall + + :xa[ll][!] + same as :qall. + + :xit + + :x[it][!] + same as :quit. + + :yank + + :[range]y[ank] [reg] [count] + will yank files to the reg register. + + :map lhs rhs + + :map lhs rhs + map lhs key sequence to rhs in normal and visual modes. + + :map! lhs rhs + map lhs key sequence to rhs in command line mode. + + + :cmap :dmap :mmap :nmap :qmap + :vmap + + :cm[ap] lhs rhs + map lhs to rhs in command line mode. + + :dm[ap] lhs rhs + map lhs to rhs in dialog modes. + + :mm[ap] lhs rhs + map lhs to rhs in menu mode. + + :nm[ap] lhs rhs + map lhs to rhs in normal mode. + + :qm[ap] lhs rhs + map lhs to rhs in view mode. + + :vm[ap] lhs rhs + map lhs to rhs in visual mode. + + + :*map + + :cm[ap] + list all maps in command line mode. + + :dm[ap] + list all maps in dialog modes. + + :mm[ap] + list all maps in menu mode. + + :nm[ap] + list all maps in normal mode. + + :qm[ap] + list all maps in view mode. + + :vm[ap] + list all maps in visual mode. + + :*map beginning + + :cm[ap] beginning + list all maps in command line mode that start with the begin- + ning. + + :dm[ap] beginning + list all maps in dialog modes that start with the beginning. + + :mm[ap] beginning + list all maps in menu mode that start with the beginning. + + :nm[ap] beginning + list all maps in normal mode that start with the beginning. + + :qm[ap] beginning + list all maps in view mode that start with the beginning. + + :vm[ap] beginning + list all maps in visual mode that start with the beginning. + + :noremap + + :no[remap] lhs rhs + map the key sequence lhs to rhs for normal and visual modes, but + don't expand user mappings in rhs. + + :no[remap]! lhs rhs + map the key sequence lhs to rhs for command line mode, but don't + expand user mappings in rhs. + + :cnoremap :dnoremap :mnoremap :nnoremap :qnoremap + :vnoremap + + :cno[remap] lhs rhs + map the key sequence lhs to rhs for command line mode, but don't + expand user mappings in rhs. + + :dn[oremap] lhs rhs + map the key sequence lhs to rhs for dialog modes, but don't ex- + pand user mappings in rhs. + + :mn[oremap] lhs rhs + map the key sequence lhs to rhs for menu mode, but don't expand + user mappings in rhs. + + :nn[oremap] lhs rhs + map the key sequence lhs to rhs for normal mode, but don't ex- + pand user mappings in rhs. + + :qn[oremap] lhs rhs + map the key sequence lhs to rhs for view mode, but don't expand + user mappings in rhs. + + :vn[oremap] lhs rhs + map the key sequence lhs to rhs for visual mode, but don't ex- + pand user mappings in rhs. + + :unmap + + :unm[ap] lhs + remove user mapping of lhs from normal and visual modes. + + :unm[ap]! lhs + remove user mapping of lhs from command line mode. + + :cunmap :dunmap :munmap :nunmap :qunmap + :vunmap + + :cu[nmap] lhs + remove user mapping of lhs from command line mode. + + :du[nmap] lhs + remove user mapping of lhs from dialog modes. + + :mu[nmap] lhs + remove user mapping of lhs from menu mode. + + :nun[map] lhs + remove user mapping of lhs from normal mode. + + :qun[map] lhs + remove user mapping of lhs from view mode. + + :vu[nmap] lhs + remove user mapping of lhs from visual mode. + +Ranges + The ranges implemented include: + 2,3 - from second to third file in the list (including it) + % - the entire directory. + . - the current position in the filelist. + $ - the end of the filelist. + 't - the mark position t. + + Examples: + + :%delete + + would delete all files in the directory. + + :2,4delete + + would delete the files in the list positions 2 through 4. + + :.,$delete + + would delete the files from the current position to the end of the + filelist. + + :3delete4 + + would delete the files in the list positions 3, 4, 5, 6. + + If a backward range is given :4,2delete - an query message is given and + user can chose what to do next. + + The builtin commands that accept a range are :d[elete] and :y[ank]. + +:command parameters + Some of the command-line commands accept parameters in the form of + `-paramname`. Arguments of such commands can be split into two groups: + parameters and positional arguments. Items from the two groups cannot + be interleaved and parameters always come first. List of parameters is + terminated implicitly by the first argument that doesn't start with a + dash ("-") or explicitly via "--" separator (needs to be a separate ar- + gument), which is just discarded. These strict rules allow arbitrary + positional arguments, such as file names that start with a dash. + + + -skip parameter + This parameter makes :copy, :move, :alink and :rlink automati- + cally skip source files that already exist at the destination + rather than refusing to perform the operation. + +Command macros + The command macros may be used in user commands. + + %a User arguments. When user arguments contain macros, they are + expanded before preforming substitution of %a. + + %c %"c The current file under the cursor. + + %C %"C The current file under the cursor in the other directory. + + %f %"f All of the selected files or the current file, but see "Selec- + tion" section below. + + %F %"F Same as %f, %"f, but for the inactive pane. + + %l %"l List of selected files. Unlike %f from above, this is only for + explicit selection (i.e., not via a range) and is empty if no + files are selected. + + %L %"L Same as %l, %"l, but for the inactive pane. + + %b %"b Same as %f %F. + + %d %"d Full path to current directory. + + %D %"D Full path to other file list directory. + + %rx %"rx + Full paths to files in the register {x}. In case of invalid + symbol in place of {x}, it's processed with the rest of the line + and default register is used. + + %m Show command output in a menu. + + %M Same as %m, but l (or Enter) key is handled like for :locate and + :find commands. + + %u Process command output as list of paths and compose custom view + out of it. + + %U Same as %u, but implies less list updates inside vifm, which is + absence of sorting at the moment. + + %Iu Same as %u, but gives up terminal before running external com- + mand. + + %IU Same as %U, but gives up terminal before running external com- + mand. + + %S Show command output in the status bar. + + %q Redirect command output to quick view, which is activated if + disabled. + + %s Execute command in horizontally split window of active terminal + multiplexer (ignored if not running inside one). + + %v Same as %s, but splits vertically. + + %n Forbid use of terminal multiplexer to run the command. + + %N Do not detach viewer from terminal session (leaves `/dev/tty` + available). + + %i Completely ignore command output. For background jobs this sup- + presses error dialogs, while still storing errors internally for + viewing via :jobs menu. + + %Pl Pipe list of files to standard input of a command. + + %Pz Same as %Pl, but separates paths by null ('\0') character. + + %pc Marks the end of the main command and the beginning of the clear + command for graphical preview, which is invoked on closing pre- + view of a file. + + %pd Marks a preview command as one that directly communicates with + the terminal. Beware that this is for things like sixel which + are self-contained sequences that depend only on current cursor + position, using this with anything else is likely to mangle ter- + minal state. + + %pu Uncached preview. Intended to be used for commands that just + send file path somewhere for preview. + + The following dimensions and coordinates are in characters: + + %px x coordinate of top-left corner of preview area. + + %py y coordinate of top-left corner of preview area. + + %pw width of preview area. + + %ph height of preview area. + + + Use %% if you need to put a percent sign in your command. + + Note that %i, %Iu, %IU, %m, %M, %n, %q, %s, %S, %u, %U and %v macros + are mutually exclusive. Only the last one of them on the command will + take effect. + + Note that %Pl and %Pz are mutually exclusive. Only the last one of + them on the command will take effect. + + You can use file name modifiers after %c, %C, %f, %F, %b, %d and %D + macros. Supported modifiers are: + + - :p - full path + + - :u - UNC name of path (e.g. "\\server" in + "\\server\share"), Windows only. Expands to current computer name + for not UNC paths. + + - :~ - relative to the home directory + + - :. - relative to current directory + + - :h - head of the file name + + - :t - tail of the file name + + - :r - root of the file name (without last extension) + + - :e - extension of the file name (last one) + + - :s?pat?sub? - substitute the first occurrence of pat with sub. + You can use any character for '?', but it must not occur in pat or + sub. + + - :gs?pat?sub? - like :s, but substitutes all occurrences of pat with + sub. + + See ':h filename-modifiers' in Vim's documentation for the detailed de- + scription. + + Using %x means expand corresponding macro escaping all characters that + have special meaning. And %"x means using of double quotes and escape + only backslash and double quote characters, which is more useful on + Windows systems. + + Position and quantity (if there is any) of %m, %M, %S or %s macros in + the command is unimportant. All their occurrences are removed from the + resulting command. + + %c and %f macros are expanded to file names only, when %C and %F are + expanded to full paths. %f and %F follow this in %b too. + + :com move mv %f %D + set the :move command to move all of the files selected in the + current directory to the other directory. + + The %a macro is replaced with any arguments given to an alias command. + All arguments are considered optional. + :com lsl !!ls -l %a - set the lsl command to execute ls -l with + or without an argument. + + :lsl + will list the directory contents of the current directory. + + :lsl filename + will list only the given filename. + + The macros can also be used in directly executing commands. ":!mv %f + %D" would move the current directory selected files to the other direc- + tory. + + Appending & to the end of a command causes it to be executed in the + background. Typically you want to run two kinds of external commands + in the background: + + - GUI applications that doesn't fork thus block vifm (:!sxiv %f &); + + - console tools that do not work with terminal (:!mv %f %D &). + + You don't want to run terminal commands, which require terminal input + or output something in background because they will mess up vifm's TUI. + Anyway, if you did run such a command, you can use Ctrl-L key to update + vifm's TUI. + + Rewriting the example command with macros given above with background- + ing: + + %m, %M, %s, %S, %u and %U macros cannot be combined with background + mark (" &") as it doesn't make much sense. + +Command backgrounding + Copy and move operation can take a lot of time to proceed. That's why + vifm supports backgrounding of this two operations. To run :copy, + :move or :delete command in the background just add " &" at the end of + a command. + + For each background operation a new thread is created. Job cancella- + tion can be requested in the :jobs menu via dd shortcut. + + You can see if command is still running in the :jobs menu. Back- + grounded commands have progress instead of process id at the line be- + ginning. + + Background operations cannot be undone. + +Cancellation + Note that cancellation works somewhat different on Windows platform due + to different mechanism of break signal propagation. One also might + need to use Ctrl-Break shortcut instead of Ctrl-C. + + There are two types of operations that can be cancelled: + + - file system operations; + + - mounting with FUSE (but not unmounting as it can cause loss of + data); + + - calls of external applications. + + Note that vifm never terminates applications, it sends SIGINT signal + and lets the application quit normally. + + When one of set of operations is cancelled (e.g. copying of 5th file of + 10 files), further operations are cancelled too. In this case undo + history will contain only actually performed operations. + + Cancelled operations are indicated by "(cancelled)" suffix appended to + information message on status bar. + + File system operations + + Currently the following commands can be cancelled: :alink, :chmod, + :chown, :clone, :copy, :delete, :mkdir, :move, :restore, :rlink, + :touch. File putting (on p/P key) can be cancelled as well. It's not + hard to see that these are mainly long-running operations. + + Cancelling commands when they are repeated for undo/redo operations is + allowed for convenience, but is not recommended as further undo/redo + operations might get blocked by side-effects of partially cancelled + group of operations. + + These commands can't be cancelled: :empty, :rename, :substitute, :tr. + + Mounting with FUSE + + It's not considered to be an error, so only notification on the status + bar is shown. + + External application calls + + Each of this operations can be cancelled: :apropos, :find, :grep, :lo- + cate. + +Selection + If there is a selection, it's stashed before proceeding further unless + file under the cursor is part of that selection. This means that when + macros are expanded for :filetype or :filextype programs, `%f` and `%F` + become equivalent to `%c` and `%C` respectively if current file is not + selected. So you run selection by running one of selected files, oth- + erwise you're running a single file even if there are other selected + entries. + + When running a selection it must not include broken symbolic links, has + to be consistent and set of file handlers must be compatible. Consis- + tency means that selection contains either only directories (including + links to them) or only files, but not their mix. + + Compatibility is a more sophisticated check, but it's defined in a nat- + ural way so that you get what you'd expect. The following properties + of selection are taken into account while checking it for compatibility + and deciding how to handle it: + + + 1. If there any files for which handler isn't defined, then all files + are opened using 'vicmd' or 'vixcmd'. + + + 2. If all handlers match the following criteria: + - backgrounded + - include `%c` and/or `%C` + - include neither `%f` nor `%F` + then each file is executed independently of the rest. + + + 3. If all handlers are equal, the common handler is executed. This + handler might ignore selection and process only file under the + cursor. + + + 4. Otherwise, an error is reported, because handlers differ and they + don't support parallel execution. + +Patterns + :highlight, :filetype, :filextype, :fileviewer commands and 'classify' + option support globs, regular expressions and mime types to match file + names or their paths. + + There are six possible ways to write a single pattern: + + 1. [!]{comma-separated-name-globs} + + 2. [!]{{comma-separated-path-globs}} + + 3. [!]/name-regular-expression/[iI] + + 4. [!]//path-regular-expression//[iI] + + 5. [!] + + 6. undecorated-pattern + + First five forms can include leading exclamation mark that negates pat- + tern matching. + + The last form is implicitly refers to one of others. :highlight does + not accept undecorated form, while :filetype, :filextype, :fileviewer, + :select, :unselect and 'classify' treat it as list of name globs. + + Path patterns receive absolute path of the file that includes its name + component as well. + + To combine several patterns (AND them), make sure you're using one of + the first five forms and write patterns one after another, like this: + {*.vifm} + Mind that if you make a mistake the whole string will be treated as the + sixth form. + + :filetype, :filextype and :fileviewer commands accept comma-separated + list of patterns instead of a single pattern, thus effectively handling + OR operation on them: + {*.vifm},{*.pdf} + Forms that accept comma-separated lists of patterns also process them + as lists of alternatives. + + Patterns with regular expressions + + Regular expression patterns are case insensitive by default, see de- + scription of commands, which might override default behaviour. + + Flags of regular expressions mean the following: + - "i" makes filter case insensitive; + - "I" makes filter case sensitive. They can be repeated multiple + times, but the later one takes precedence (e.g. "iiiI" is equivalent + to "I" and "IiIi" is the same as "i"). + + There are no implicit `^` or `$`, so make sure to specify them explic- + itly if the pattern should match the whole name or path. + + Patterns with globs + + "Globs" section below provides short overview of globs and some impor- + tant points that one needs to know about them. + + Patterns with mime-types + + Mime type matching is essentially globs matching applied to mime type + of a file instead of its name/path. Note: mime types aren't detected + on Windows. + + Examples + + Associate `evince` to PDF-files only inside `/home/user/downloads/` di- + rectory (excluding its subdirectories): + + :filextype //^/home/user/downloads/[^/]*.pdf$// evince %f + + +Regular expressions + All regular expressions are modern/extended. See `man 7 regex` for + more details on what's supported. + + The following special sequences are additionally parsed: + - `\c` forces matching ignoring case of letters + - `\C` forces matching respecting case of letters + + `\c` and `\C` have the highest priority in determining whether case is + matched or not and exist to override 'ignorecase', 'smartcase' and + `i`/`I` flags when necessary. + + If multiple sequences are present, the one which appears later takes + precedence. + + Note that unlike in Vim character classes are affected by settings and + sequences that control case sensitivity in regular expressions. + +Globs + Globs are always case insensitive as it makes sense in general case. + + `*`, `?`, `[` and `]` are treated as special symbols in the pattern. + E.g. + + :filetype * less %c + + matches all files. One can use character classes for escaping, so + + :filetype [*] less %c + + matches only one file name, the one which contains only asterisk sym- + bol. + + `*` means any number of any characters (possibly an empty substring), + with one exception: asterisk at the pattern beginning doesn't match dot + in the first position. E.g. + + :fileviewer *.zip,*.jar zip -sf %c + + associates using of `zip` program to preview all files with `zip` or + `jar` extensions as listing of their content, but `.file.zip` won't be + matched. + + `?` means any character at this position. E.g. + + :fileviewer ?.out file %c + + calls `file` tool for all files which have exactly one character before + their extension (e.g. a.out, b.out). + + Square brackets designate character class, which means that whole char- + acter class matches against any of characters listed in it. For exam- + ple + + :fileviewer *.[ch] highlight -O xterm256 -s dante --syntax c %c + + makes vifm call `highlight` program to colorize source and header files + in C language for a 256-color terminal. Equal command would be + + :fileviewer *.c,*.h highlight -O xterm256 -s dante --syntax c %c + + + Inside square brackets `^` or `!` can be used for symbol class negotia- + tion and the `-` symbol to set a range. `^` and `!` should appear + right after the opening square bracket. For example + + :filetype *.[!d]/ inspect_dir + + associates `inspect_dir` as additional handler for all directories that + have one character extension unless it's "d" letter. And + + :filetype [0-9].jpg sxiv + + associates `sxiv` picture viewer only for JPEG-files that contain sin- + gle digit in their name. + + If you need to include literal comma, which is normally separates mul- + tiple globs, double it. + +:set options + Local options + These are kind of options that are local to a specific view. So + you can set ascending sorting order for left pane and descending + order for right pane. + + In addition to being local to views, each such option also has + two values: + + - local to current directory (value associated with current + location); + + - global to current directory (value associated with the + pane). + + The idea is that current directory can be made a temporary ex- + ception to regular configuration of the view, until directory + change. Use :setlocal for that. :setglobal changes view value + not affecting settings until directory change. :set applies + changes immediately to all values. + + + 'aproposprg' + type: string + default: "apropos %a" + Specifies format for an external command to be invoked by the + :apropos command. The format supports expanding of macros, spe- + cific for a particular *prg option, and %% sequence for insert- + ing percent sign literally. This option should include the %a + macro to specify placement of arguments passed to the :apropos + command. If the macro is not used, it will be implicitly added + after a space to the value of this option. + + 'autocd' + type: boolean + default: false + When enabled unknown command-line commands are interpreted as + implicit invocation of :cd with one argument and no escaping. + Tilde is expanded, but not macros or environment variables. + + 'autochpos' + type: boolean + default: true + When disabled vifm will set cursor to the first line in the view + after :cd and :pushd commands instead of saved cursor position. + Disabling this will also make vifm clear information about cur- + sor position in the view history on :cd and :pushd commands (and + on startup if 'autochpos' is disabled in the vifmrc). l key in + the ":history ." and ":trashes" menus are treated like :cd com- + mand. This option also affects marks so that navigating to a + mark doesn't restore cursor position. + + When this option is enabled, more fine grained control over cur- + sor position is available via 'histcursor' option. + + 'columns' 'co' + type: integer + default: terminal width on startup + Terminal width in characters. + + 'caseoptions' + type: charset + default: "" + This option gives additional control over case sensitivity by + allowing overriding default behaviour to either always be case + sensitive or always be case insensitive. Possible values form + pairs of lower and upper case letters that configure specific + aspect of behaviour: + p - always ignore case of paths during completion. + P - always match case of paths during completion. + g - always ignore case of characters for f/F/;/,. + G - always match case of characters for f/F/;/,. + + At most one item of each pair takes affect, if both or more are + present, only the last one matters. When none of pair's ele- + ments are present, the behaviour is default (depends on operat- + ing system for path completion and on values of 'ignorecase' and + 'smartcase' options for file navigation). + + 'cdpath' 'cd' + type: string list + default: value of $CDPATH with commas instead of colons + Specifies locations to check on changing directory with relative + path that doesn't start with "./" or "../". When non-empty, + current directory is examined after directories listed in the + option. + + This option doesn't affect completion of :cd command. + + Example: + + set cdpath=~ + + This way ":cd bin" will switch to "~/bin" even if directory + named "bin" exists in current directory, while ":cd ./bin" com- + mand will ignore value of 'cdpath'. + + 'chaselinks' + type: boolean + default: false + When enabled path of view is always resolved to real path (with + all symbolic links expanded). + + 'classify' + type: string list + default: ":dir:/" + Specifies file name prefixes and suffixes depending on file type + or name. The format is either of: + - [{prefix}]:{filetype}:[{suffix}] + - [{prefix}]::{pattern}::[{suffix}] + Possible {pattern} forms are described in "Patterns" section + above. + + Priority rules: + - file name patterns have priority over type patterns + - file name patterns are matched in left-to-right order of + their appearance in this option + + Either {prefix} or {suffix} or both can be omitted (which is the + default for all unspecified file types), this means empty {pre- + fix} and/or {suffix}. {prefix} and {suffix} should consist of + at most eight characters. Elements are separated by commas. + Neither prefixes nor suffixes are part of file names, so they + don't affect commands which operate on file names in any way. + Comma (',') character can be inserted by doubling it. List of + file type names can be found in the description of filetype() + function. + + 'confirm' 'cf' + type: set + default: delete,permdelete + Defines which operations require confirmation: + - delete - moving files to trash (on d or :delete); + - permdelete - permanent deletion of files (on D or :delete! + command or on undo/redo operation). + + 'cpoptions' 'cpo' + type: charset + default: "fst" + Contains a sequence of single-character flags. Each flag en- + ables behaviour of older versions of vifm. Flags: + - f - when included, running :filter command results in not in- + verted (matching files are filtered out) and :filter! in in- + verted (matching files are left) filter, when omitted, meaning + of the exclamation mark changes to the opposite; + - s - when included, yy, dd and DD normal mode commands act on + selection, otherwise they operate on current file only; + - t - when included, (thus ) behave as and + switches active pane, otherwise and go forward in + the view history. It's possible to make both and to + work as expected by setting up the terminal to emit a custom se- + quence when is pressed; see :histnext for details. + + 'cvoptions' + type: set + default: + Specifies whether entering/leaving custom views triggers events + that normally happen on entering/leaving directories: + - autocmds - trigger autocommands on entering/leaving custom + views; + - localopts - reset local options on entering/leaving custom + views; + - localfilter - reset local filter on entering/leaving custom + views. + + 'deleteprg' + type: string + default: "" + Specifies program to run on files that are permanently removed. + When empty, files are removed as usual, otherwise this command + is invoked on each file by appending its name. If the command + doesn't remove files, they will remain on the file system. + + 'dirsize' + type: enumeration + default: size + Controls how size of directories is displayed in file views. + The following values are possible: + - size - size of directory (i.e., size used to store list of + files) + - nitems - number of entries in the directory (excluding . and + ..) + + Size obtained via ga/gA overwrites this setting so seeing count + of files and occasionally size of directories is possible. + + 'dotdirs' + type: set + default: nonrootparent,treeleafsparent + Controls displaying of dot directories. The following values + are possible: + - rootparent - show "../" in root directory of file system + - nonrootparent - show "../" in non-root directories of file + system + - treeleafsparent - show "../" in empty directories of tree + view + + Note that empty directories always contain "../" entry regard- + less of value of this option. "../" disappears at the moment at + least one file is created. + + 'dotfiles' + type: boolean + default: false + Whether dot files are shown in the view. Can be controlled with + z* bindings. + + 'fastrun' + type: boolean + default: false + With this option turned on you can run partially entered com- + mands with unambiguous beginning using :! (e.g. :!Te instead of + :!Terminal or :!Te). + + 'fillchars' 'fcs' + type: string list + default: "" + Sets characters used to fill borders. + + item default used for + vborder:c ' ' left, middle and right vertical bor- + ders + hborder:c '' middle horizontal border + + A null string for vborder is equivalent to a space. + + A null string for hborder omits the horizontal border. + + Example: + + set fillchars=vborder:".",hborder:"" + + 'findprg' + type: string + default: "find %s %a -print , -type d \( ! -readable -o ! -exe- + cutable \) -prune" + Specifies format for an external command to be invoked by the + :find command. The format supports expansion of macros specific + for this particular option and %% sequence for inserting percent + sign literally. The macros are: + + macro value/meaning + %s literal arguments of :find or + list of paths to search in + + %A empty or + literal arguments of :find + %a empty or + literal arguments of :find or + predicate followed by escaped arguments of :find + %p empty or + literal arguments of :find or + escaped arguments (parameters) of :find + + %u redirect output to custom view instead of showing a + menu + %U redirect output to unsorted custom view instead of + showing a menu + + Predicate in %a is "-name" on *nix and "-iname" on Windows. + + If both %u and %U are specified, %U is chosen. + + Some macros can be added implicitly: + - if %s isn't present, it's appended + - if neither of %a, %A and %p is present, %a is appended + - if neither of %s, %a, %A and %p is present, %s and %a are ap- + pended in this order + + The macros slightly change their meaning depending on format of + :find's arguments: + - if the first argument points to an existing directory, %s is + assigned all arguments while %a, %A and %p are left empty + - otherwise: + - %s is assigned a dot (".") meaning current directory or + list of selected file names, if any + - %a, %A and %p are assigned literal arguments when first + argument starts with a dash ("-"), otherwise %a gets an escaped + version of the arguments with a predicate and %p contains es- + caped version of the arguments + + Starting with Windows Server 2003 a `where` command is avail- + able. One can configure vifm to use it in the following way: + + set findprg="where /R %s %A" + + As the syntax of this command is rather limited, one can't use + :find command with selection of more than one item because the + command ignores all directory paths except for the last one. + + When using find port on Windows, another option is to setup + 'findprg' like this: + + set findprg="find %s %a" + + + 'followlinks' + type: boolean + default: true + Follow links on l or Enter. That is navigate to destination + file instead of treating the link as if it were target file. + Doesn't affects links to directories, which are always entered + (use gf key for directories). + + 'fusehome' + type: string + default: "($XDG_DATA_HOME/vifm | $VIFM)/fuse/" + Directory to be used as a root dir for FUSE mounts. Value of + the option can contain environment variables (in form "$en- + vname"), which will be expanded (prepend it with a slash to pre- + vent expansion). The value should expand to an absolute path. + + If you change this option, vifm won't remount anything. It af- + fects future mounts only. See "Automatic FUSE mounts" section + below for more information. + + 'gdefault' 'gd' + type: boolean + default: false + When on, 'g' flag is on for :substitute by default. + + 'grepprg' + type: string + default: "grep -n -H -I -r %i %a %s" + Specifies format for an external command to be invoked by the + :grep command. The format supports expanding of macros, spe- + cific for a particular *prg option, and %% sequence for insert- + ing percent sign literally. This option should include the %i + macro to specify placement of "-v" string when inversion of re- + sults is requested, %a or %A macro to specify placement of argu- + ments passed to the :grep command and the %s macro to specify + placement of list of files to search in. If some of the macros + are not used, they will be implicitly added after a space to the + value of the 'grepprg' option in the following order: %i, %a, + %s. Note that when neither %a nor %A are specified, it's %a + which is added implicitly. + + Optional %u or %U macro could be used (if both specified %U is + chosen) to force redirection to custom or unsorted custom view + respectively. + + See 'findprg' option for description of difference between %a + and %A. + + Example of setup to use ack (http://beyondgrep.com/) instead of + grep: + + set grepprg='ack -H -r %i %a %s' + + or The Silver Searcher (https://github.com/ggreer/the_sil- + ver_searcher): + + set grepprg='ag --line-numbers %i %a %s' + + + + 'histcursor' + type: set + default: startup,dirmark,direnter + Defines situations when cursor should be moved according to di- + rectory history: + - startup - on loading file lists during startup + - dirmark - after navigating to a mark that doesn't specify + file + - direnter - on opening directory from a file list + + This option has no effect when 'autochpos' is disabled. + + Note that the list is not exhaustive and there are other situa- + tions when cursor is positioned automatically. + + 'history' 'hi' + type: integer + default: 15 + Maximum number of stored items in all histories. + + 'hlsearch' 'hls' + type: boolean + default: true + Automatically select files that are search matches. + + 'iec' type: boolean + default: false + Use KiB, MiB, ... suffixes instead of K, M, ... when printing + size in human-friendly format. + + 'ignorecase' 'ic' + type: boolean + default: false + Ignore case in search patterns (:substitute, / and ? commands), + local filter (but not the rest of filters) and other things de- + tailed in the description of 'caseoptions'. + + 'incsearch' 'is' + type: boolean + default: false + When this option is set, search and view update for local filter + is be performed starting from initial cursor position each time + search pattern is changed. + + 'iooptions' + type: set + default: datasync + Controls details of file operations. The following values are + available: + - datasync - periodically synchronize writes on copying files + when 'syscalls' is set. + (This makes copying last as long as it takes to + actually write + data to the medium, which is slower than you might + expect; + however, this also prevents system hanging due to + filling memory + with file-system cache.) + - fastfilecloning - perform fast file cloning (copy-on-write), + when available (available on Linux and btrfs file system). + + 'laststatus' 'ls' + type: boolean + default: true + Controls if status bar is visible. + + 'lines' + type: integer + default: terminal height on startup + Terminal height in lines. + + 'locateprg' + type: string + default: "locate %a" + Specifies format for an external command to be invoked by the + :locate command. The format supports expanding of macros, spe- + cific for a particular *prg option, and %% sequence for insert- + ing percent sign literally. This option should include the %a + macro to specify placement of arguments passed to the :locate + command. If the macro is not used, it will be implicitly added + after a space to the value of this option. + + Optional %u or %U macro could be used (if both specified %U is + chosen) to force redirection to custom or unsorted custom view + respectively. + + 'mediaprg' + type: string + default: path to bundled script that supports udevil, udisks and + udisks2 + (using udisks2 requires python with dbus module in- + stalled) + OS X: path points to a python script that uses diskutil + {only for *nix} + Specifies command to be used to manage media devices. Used by + :media command. + + The command can be passed the following parameters: + - list -- list media + - mount {device} -- mount a device + - unmount {path} -- unmount given mount point + + The output of `list` subcommand is parsed in search of lines + that start with one of the following prefixes: + - device= - specifies device path (e.g., "/dev/sde") + - label= - specifies optional device label (e.g., "Memory + card") + - info= - specifies arbitrary text to display next to + device (by + default "[label]" is used, if label is pro- + vided) + - mount-point= - specifies a mount point (can be absent or ap- + pear more than once) + + All other lines are ignored. Each `device=` starts a new sec- + tion describing a device which should include two other possible + prefixes. + + `list` subcommand is assumed to always succeed, while exit code + of `mount` and `unmount` is taken into account to determine + whether operation was performed successfully. + + 'lsoptions' + type: string list + default: "" + scope: local + + Configures ls-like view. + + item used for + transposed filling view grid by columns rather than by + lines + + + 'lsview' + type: boolean + default: false + scope: local + When this option is set, directory view will be displayed in + multiple columns with file names similar to output of `ls -x` + command. See "ls-like view" section below for format descrip- + tion. This option has no effect if 'millerview' is on. + + 'milleroptions' + type: string list + default: "lsize:1,csize:1,rsize:1,rpreview:dirs" + scope: local + + Configures miller view. + + item default used for + lsize:num 0 left column + csize:num 1 center column (can't be disabled) + rsize:num 0 right column + rpreview:str dirs right column + + *size specifies ratios of columns. Each ratio is in the range + from 0 to 100 and values are adjusted to fit the limits. Zero + disables a column, but central (main) column can't be disabled. + + rpreview specifies what file-system objects should be previewed + in the right column and can take two values: dirs (only directo- + ries) or all. Both options don't include parent directory + (".."). + + Example of two-column mode which is useful in combination with + :view command: + + set milleroptions=lsize:1,csize:2 + + + 'millerview' + type: boolean + default: false + scope: local + When this option is set, directory view will be displayed in + multiple cascading columns. Ignores 'lsview'. + + 'mintimeoutlen' + type: integer + default: 150 + The fracture of 'timeoutlen' in milliseconds that is waited be- + tween subsequent input polls, which affects various asynchronous + operations (detecting changes made by external applications, + monitoring background jobs, redrawing UI). There are no strict + guarantees, however the higher this value is, the less is CPU + load in idle mode. + + 'number' 'nu' + type: boolean + default: false + scope: local + Print line number in front of each file name when 'lsview' op- + tion is turned off. Use 'numberwidth' to control width of line + number. Also see 'relativenumber'. + + 'numberwidth' 'nuw' + type: integer + default: 4 + scope: local + Minimal number of characters for line number field. + + 'previewoptions' + type: string list + default: "graphicsdelay:50000" + + Tweaks how previewing is done (in quick view, miller view's col- + umn and view mode). + + item default meaning + graphicsdelay:num 0 delay before drawing graphics (mi- + croseconds) + hardgraphicsclear unset redraw screen to get rid of graph- + ics + maxtreedepth:num 0 max number of levels in preview + tree + toptreestats unset show file counts before the tree + + graphicsdelay is needed if terminal requires some timeout before + it can draw graphics (otherwise it gets lost). + + hardgraphicsclear seems to be necessary to get rid of sixel + graphics in some terminals, where it otherwise lingers. This + can cause flicker on the screen due to erasure followed by re- + drawing. + + 0 for maxtreedepth means "unlimited", 1 will only show selected + directory, 2 adds its children, and so forth. + + Default value is used when item is missing from the option. + + 'previewprg' + type: string + default: "" + scope: local + + External command to be used instead of preview programs config- + ured via :fileviewer command. + + Example: + + " always show git log in preview of files inside some repository + au DirEnter '~/git-repo/**/*' setl previewprg='git log --color -- %c 2>&1' + + 'quickview' + type: boolean + default: false + Whether quick view (:view) is currently active or not. + + 'relativenumber' 'rnu' + type: boolean + default: false + scope: local + Print relative line number in front of each file name when + 'lsview' option is turned off. Use 'numberwidth' to control + width of line number. Various combinations of 'number' and + 'relativenumber' lead to such results: + + nonumber number + + norelativenumber | first | 1 first + | second | 2 second + | third | 3 third + + relativenumber | 1 first | 1 first + | 0 second |2 second + | 1 third | 1 third + + + 'rulerformat' 'ruf' + type: string + default: "%l/%S " + Determines the content of the ruler. Its minimal width is 13 + characters and it's right aligned. Following macros are sup- + ported: + %= - separation point between left and right aligned halves of + the line + %l - file number + %L - total number of files in view (including filtered out + ones) + %x - number of files excluded by filters + %0- - old name for %x macro + %P - percentage through file list (All, Top, xx% or Bot), al- + ways 3 in length + %S - number of displayed files + %= - separation point between left and right align items + %% - literal percent sign + %[ - designates beginning of an optional block + %] - designates end of an optional block + + Percent sign can be followed by optional minimum field width. + Add '-' before minimum field width if you want field to be right + aligned. + + Optional blocks are ignored unless at least one macro inside of + them is expanded to a non-empty value. + + Example: + + set rulerformat='%2l-%S%[ +%x%]' + + 'runexec' + type: boolean + default: false + Run executable file on Enter, l or Right Arrow key. Behaviour + of the last two depends on the value of the 'lsview' option. + + 'scrollbind' 'scb' + type: boolean + default: false + When this option is set, vifm will try to keep difference of + scrolling positions of two windows constant. + + 'scrolloff' 'so' + type: integer + default: 0 + Minimal number of screen lines to keep above and below the cur- + sor. If you want cursor line to always be in the middle of the + view (except at the beginning or end of the file list), set this + option to some large value (e.g. 999). + + 'sessionoptions' 'ssop' + sessionoptions ssop + type: set + default: tui,state,tabs,savedirs,dhistory + An equivalent of 'vifminfo' for sessions, uses the same values. + When both options include the same value, data from session file + has higher priority (data from vifminfo isn't necessarily com- + pletely discarded, instead it's merged with the state of a ses- + sion the same way state of multiple instances is merged on + exit). + + 'shell' 'sh' + type: string + default: $SHELL or "/bin/sh" or "cmd" (on MS-Windows) + Full path to the shell to use to run external commands. On *nix + a shell argument can be supplied. + + 'shellcmdflag' 'shcf' + type: string + default: "-c" or "/C" (for cmd.exe on MS-Windows) + Command-line option used to pass a command to 'shell'. It's + used in contexts where command comes from the user. + + Note that using this option to force interactive mode of the + shell is most likely a BAD IDEA. In general interactive host + and interactive child shell can't share the same terminal ses- + sion. You can't even run such a shell in background. Consider + writing a wrapper for your shell that preloads aliases and com- + mands without making the shell interactive and ending up using + it in a way it was not meant to be used. + + Note that this option is ignored when 'shell' is set to Power- + Shell due to the internal use of `-encodedCommand`. + + 'shortmess' 'shm' + type: charset + default: "p" + Contains a sequence of single-character flags. Each flag en- + ables shortening of some message displayed by vifm in the TUI. + Flags: + - L - display only last directory in tab line instead of full + path. + - M - shorten titles in windows of terminal multiplexers cre- + ated by vifm down to file name instead of using full path. + - T - truncate status bar messages in the middle if they are + too long to fit on the command line. "..." will appear in the + middle. + - p - use tilde shortening in view titles. + + + 'showtabline' 'stal' + type: enumeration + default: multiple + Specifies when tab line should be displayed. Possible values: + - never - never display tab line + - multiple - show tab line only when there are at least two + tabs + - always - display tab line always + + Alternatively 0, 1 and 2 Vim-like values are also accepted and + correspond to "never", "multiple" and "always" respectively. + + + 'sizefmt' + type: string list + default: "units:iec" + Configures the way size is formatted in human-friendly way. + + item value meaning + units: iec Use 1024 byte units (K or KiB, + etc.). + See 'iec' option. + si Use 1000 byte units (KB, etc.). + precision: i > 0 How many fraction digits to con- + sider. + {not set} Precision of 1 for integer part + < 10, + 0 otherwise (provides old behav- + iour). + space {present} Insert space before unit sym- + bols. + This is the default. + nospace {present} Do not insert space before unit + symbols. + + Numbers are rounded from zero. Trailing zeros are dropped. + + Example: + + set sizefmt=units:iec,precision:2,nospace + + + 'slowfs' + type: string list + default: "" + only for *nix + A list of mounter fs name beginnings (first column in /etc/mtab + or /proc/mounts) or paths prefixes for fs/directories that work + too slow for you. This option can be used to stop vifm from + making some requests to particular kinds of file systems that + can slow down file browsing. Currently this means don't check + if directory has changed, skip check if target of symbolic links + exists, assume that link target located on slow fs to be a di- + rectory (allows entering directories and navigating to files via + gf). If you set the option to "*", it means all the systems are + considered slow (useful for cygwin, where all the checks might + render vifm very slow if there are network mounts). + + Example for autofs root /mnt/autofs: + + set slowfs+=/mnt/autofs + + 'smartcase' 'scs' + type: boolean + default: false + Overrides the ignorecase option if a pattern contains at least + one upper case character. Only used when 'ignorecase' option is + enabled. + + 'sort' type: string list + default: +name on *nix and +iname on Windows + scope: local + Sets list of sorting keys (first item is primary key, second is + secondary key, etc.): + [+-]ext - extension of files and directories + [+-]fileext - extension of files only + [+-]name - name (including extension) + [+-]iname - name (including extension, ignores case) + [+-]type - file type + (dir/reg/exe/link/char/block/sock/fifo) + [+-]dir - directory grouping (directory < file) + [+-]gid - group id (*nix only) + [+-]gname - group name (*nix only) + [+-]mode - file type derived from its mode (*nix only) + [+-]perms - permissions string (*nix only) + [+-]uid - owner id (*nix only) + [+-]uname - owner name (*nix only) + [+-]nlinks - number of hard links (*nix only) + [+-]inode - inode number (*nix only) + [+-]size - size + [+-]nitems - number of items in a directory (zero for files) + [+-]groups - groups extracted via regexps from 'sortgroups' + [+-]target - symbolic link target (empty for other file + types) + [+-]atime - time accessed (e.g., read, executed) + [+-]ctime - time changed (changes in metadata, like mode) + [+-]mtime - time modified (when file contents is changed) + + Note: look for st_atime, st_ctime and st_mtime in "man 2 stat" + for more information on time keys. + + '+' means ascending sort for this key, and '-' means descending + sort. + + "dir" key is somewhat similar in this regard but it's added im- + plicitly: when "dir" is not specified, sorting behaves as if it + was the first key in the list. That's why if one wants sorting + algorithm to mix directories and files, "dir" should be appended + to sorting option, for example like this: + + set sort+=dir + + or + + set sort=-size,dir + + Value of the option is checked to include dir key and default + sorting key (name on *nix, iname on Windows). Here is what hap- + pens if one of them is missing: + + - type key is added at the beginning; + + - default key is added at the end; + + all other keys are left untouched (at most they are moved). + + This option also changes view columns according to primary sort- + ing key set, unless 'viewcolumns' option is not empty. + + 'sortnumbers' + type: boolean + default: false + scope: local + Natural sort of (version) numbers within text. + + 'sortgroups' + type: string + default: "" + scope: local + Sets comma-separated list of regular expressions for group type + of sorting. Double the comma to insert it literally. + + The regular expressions are used to extract substrings of file + names to serve as keys for sorting. It is essentially a way to + ignore uninteresting parts of file names during sorting by name. + + Each expression should contain at least one group or its value + will be considered to be always empty. Also, only the first + match of regular expression is processed. + + The first group divides list of files into sub-groups, each of + which is then sorted by substrings extracted using second regu- + lar expression and so on recursively. + + Example: + set sortgroups=-(todo|done).* + this would group files with "-done" in their names and files + with "-todo" separately. On ascending sorting, group containing + "-done" would appear before the other one. + + 'sortorder' + type: enumeration + default: ascending + Sets sort order for primary key: ascending, descending. + + 'statusline' 'stl' + type: string + default: "" + Determines the content of the status line (the line right above + command-line). Empty string means use same format like in pre- + vious versions. Following macros are supported: + + - %N - line break (increases height of the status line accord- + ingly), ignores %[ %] blocks + + - %t - file name (considering value of the 'classify' option) + + - %T - symbolic link target (empty for other filetypes) + + - %f - file name relative to current directory (considers 'clas- + sify') + + - %A - file attributes (permissions on *nix or properties on + Windows) + + - %o - file permissions in octal form on *nix (nothing on Win- + dows) + + - %u - user name or uid (if it cannot be resolved) + + - %g - group name or gid (if it cannot be resolved) + + - %s - file size in human readable format + + - %E - size of selected files in human readable format, same as + %s when no files are selected, except that it will never show + size of ../ in visual mode, since it cannot be selected + + - %d - file modification date (uses 'timefmt' option) + + - %D - path of the other pane for single-pane layout + + - %a - amount of free space available on current FS + + - %c - size of current FS + + - %z - short tips/tricks/hints that chosen randomly after one + minute period + + - %{} - evaluate arbitrary vifm expression '', e.g. + '&sort' + + - %* - resets or applies one of User1..User9 highlight groups; + reset happens when width field is 0 or not specified, one of + groups gets picked when width field is in the range from 1 to + 9 + + - all 'rulerformat' macros + + Percent sign can be followed by optional minimum field width. + Add '-' before minimum field width if you want field to be right + aligned. + + On Windows file properties include the following flags (upper + case means flag is on): + A - archive + H - hidden + I - content isn't indexed + R - readonly + S - system + C - compressed + D - directory + E - encrypted + P - reparse point (e.g. symbolic link) + Z - sparse file + + Example without colors: + + set statusline=" %t%= %A %10u:%-7g %15s %20d %{&sort} " + + Example with colors: + + highlight User1 ctermbg=yellow + highlight User2 ctermbg=blue ctermfg=white cterm=bold + set statusline="%1* %-26t %2* %= %1* %A %2* %7u:%-7g %1* %-5s %2* %d " + + + 'suggestoptions' + type: string list + default: + Controls when, for what and how suggestions are displayed. The + following values are available: + - normal - in normal mode; + - visual - in visual mode; + - view - in view mode; + - otherpane - use other pane to display suggestions, when + available; + - delay[:num] - display suggestions after a small delay (to + do not annoy if you just want to type a fast shortcut consisting + of multiple keys), num specifies the delay in ms (500 by de- + fault), 'timeoutlen' at most; + - keys - include shortcuts (commands and selectors); + - foldsubkeys - fold multiple keys with common prefix; + - marks - include marks; + - registers[:num] - include registers, at most num files (5 by + default). + + 'syncregs' + type: string + default: "" + Specifies identifier of group of instances that share registers + among each other. When several instances of vifm have this op- + tion set to identical value, they automatically synchronize con- + tents of their registers on operations which use them. + + 'syscalls' + type: boolean + default: false + When disabled, vifm will rely on external applications to per- + form file-system operations, otherwise system calls are used in- + stead (much faster and supports progress tracking). The option + should eventually be removed. Mostly *nix-like systems are af- + fected. + + 'tablabel' + type: string + default: "" + When non-empty, determines format of the main part of a single + tab's label. + + When empty, tab label is set to either tab name for named tabs + or to view title (usually current path) for unnamed tabs. + + The following macros can appear in the format (see below for + what a flag is): + + - %C - flag of a current tab + + - %N - number of the tab + + - %T - flag of a tree mode + + - %c - description of a custom view + + - %n - name of the tab + + - %p - path of the view (handles filename modifiers) + + - %t - title of the view (affected by 'shortmess' flags) + + - %% - literal percent sign + + - %[ - designates beginning of an optional block + + - %] - designates end of an optional block + + - %*, %0* - resets highlighting + + - %1-%9 - applies one of User1..User9 highlight groups + + In global tabs the view in bullets above refers to currently ac- + tive view of that tab. + + Flag macros are a special kind of macros that always expand to + an empty value and are ment to be used inside optional blocks to + control their visibility. + + Optional blocks are ignored unless at least one macro inside of + them is expanded to a non-empty value or is a set flag macro. + + " %[(%n)%] -- optional name of the tab + " %[ -- optional description of the view + " %[%T{tree}%] -- mark of tree mode + " %[{%c}%] -- description of custom view + " @ -- just an extra separator before the path + ' %] + " %p:t -- tail part of view's location + set tablabel=%[(%n)%]%[%[%T{tree}%]%[{%c}%]@%]%p:t + + 'tabprefix' + type: string + default: "[%N:" + Determines prefix of a tab's label. Formatting is done as for + 'tablabel' option. + + 'tabscope' + type: enumeration + default: global + Picks style of tabs, which defines what a single tab contains. + Possible values: + - global - tab describes complete UI of two views and how they + are arranged + - pane - tab is located "inside" a pane and manages it and + quick view + + 'tabstop' 'ts' + type: integer + default: value from curses library + Number of spaces that a Tab in the file counts for. + + 'tabsuffix' + type: string + default: "]" + Determines suffix of a tab's label. Formatting is done as for + 'tablabel' option. + + 'timefmt' + type: string + default: "%m/%d %H:%M" + Format of time in file list. See "man 1 date" or "man 3 strf- + time" for details. + + 'timeoutlen' 'tm' + type: integer + default: 1000 + The time in milliseconds that is waited for a mapped key in case + of already typed key sequence is ambiguous. + + 'title' + type: boolean + default: true when title can be restored, false otherwise + When enabled, title of the terminal or terminal multiplexer's + window is updated according to current location. Because not + all terminals support setting title, this works only if `$TERM` + value matches one of the following conditions: + - equals "xterm" or starts with "xterm-" + - equals "rxvt" or starts with "rxvt-" + - equals "screen" or starts with "screen-" + - equals "aterm" + - equals "Eterm" + + 'trash' + type: boolean + default: true + Use trash directory. See "Trash directory" section below. + + 'trashdir' + type: string + default: + on *nix: + "%r/.vifm-Trash-%u,$XDG_DATA_HOME/vifm/Trash,%r/.vifm-Trash" + or + "%r/.vifm-Trash-%u,$VIFM/Trash,%r/.vifm-Trash" + on Windows: + "%r/.vifm-Trash,$XDG_DATA_HOME/vifm/Trash" + or + "%r/.vifm-Trash,$VIFM/vifm/Trash" + List of trash directory path specifications, separated with com- + mas. Each list item either defines an absolute path to trash + directory or a path relative to a mount point root when list el- + ement starts with "%r/". Value of the option can contain envi- + ronment variables (of form "$envname"), which will be expanded + (prepend $ with a slash to prevent expansion). Environment + variables are expanded when the option is set. + + On *nix, if element ends with "%u", the mark is replaced with + real user ID and permissions are set so that only that only + owner is able to use it. + Note that even this setup is not completely secure when combined + with "%r/" and it's overall safer to keep files in home direc- + tory, but that implies cost of copying files between partitions. + + When new file gets cut (deleted) vifm traverses each element of + the option in the order of their appearance and uses first trash + directory that it was able to create or that is already + writable. + + Default value tries to use trash directory per mount point and + falls back to trash common trash directory on failure. + + Will attempt to create the directory if it does not exist. See + "Trash directory" section below. + + 'tuioptions' 'to' + type: charset + default: "psv" + Each flag configures some aspect of TUI appearance. The flags + are: + p - when included: + * file list inside a pane gets additional single character + padding on left and right sides; + * quick view and view mode get single character padding. + s - when included, left and right borders (side borders, hence + "s" character) are visible. + u - use Unicode characters in the TUI (Unicode ellipsis instead + of "..."). + v - vary width of vertical middle border to equalize view sizes. + + Each pane title contains the path of the listed directory. If + too large, the path is truncated on the left for the active pane + and on the right for the other pane. This can be modified with: + + l - truncation is always on the left. + r - truncation is always on the right. + + 'undolevels' 'ul' + type: integer + default: 100 + Maximum number of changes that can be undone. Note that here + single file operation is used as a unit, not operation, i.e. + deletion of 101 files will exceed default limit. + + 'vicmd' + type: string + default: "vim" + Command used to edit files in various contexts. Ampersand sign + at the end (regardless whether it's preceded by space or not) + means backgrounding of command. + + Background flag is ignored in certain context where vifm waits + for the editor to finish. Such contexts include any command + that spawns editor to change list of file names or a command, + with :rename being one example. `-f` is also appended to pre- + vent forking in such cases, so the command needs to handle the + flag. + + Additionally `+{num}` and `+'call cursor()'` arguments are used + to position cursor when location is known. + + 'viewcolumns' + type: string + default: "" + scope: local + Format string containing list of columns in the view. When this + option is empty, view columns to show are chosen automatically + using sorting keys (see 'sort') as a base. Value of this option + is ignored if 'lsview' is set. See "Column view" section below + for format description. + + An example of setting the options for both panes (note :windo + command): + + windo set viewcolumns=-{name}..,6{size},11{perms} + + 'vixcmd' + type: string + default: value of 'vicmd' + Same as 'vicmd', but takes precedence over it when running in- + side a graphical environment. + + 'vifminfo' + type: set + default: bookmarks,bmarks + Controls what will be saved in the $VIFM/vifminfo file. + + bmarks - named bookmarks (see :bmark command) + bookmarks - marks, except special ones like '< and '> + tui - state of the user interface (sorting, number of + windows, quick + view state, active view) + dhistory - directory history + state - file name and dot filters and terminal multiplex- + ers integration + state + cs - primary color scheme + savedirs - save last visited directory + chistory - command line history + ehistory - expression register history (see description of + Ctrl+R = + in command-line mode) + shistory - search history (/ and ? commands) + phistory - prompt history + fhistory - history of local filter (see description of the + "=" normal mode + command) + dirstack - directory stack overwrites previous stack, unless + stack of + current instance is empty + registers - registers content + tabs - global or pane tabs + options - all options that can be set with the :set command + (obsolete) + filetypes - associated programs and viewers (obsolete) + commands - user defined commands (see :command description) + (obsolete) + + 'vimhelp' + type: boolean + default: false + Use vim help format. + + 'wildmenu' 'wmnu' + type: boolean + default: false + Controls whether possible matches of completion will be shown + above the command line. + + 'wildstyle' + type: enumeration + default: bar + Picks presentation style of wild menu. Possible values: + - bar - one-line with left-to-right cursor + - popup - multi-line with top-to-bottom cursor + + 'wordchars' + type: string list + default: "1-8,14-31,33-255" (that is all non-whitespace charac- + ters) + Specifies which characters in command-line mode should be con- + sidered as part of a word. Value of the option is comma-sepa- + rated list of ranges. If both endpoints of a range match, sin- + gle endpoint is enough (e.g. "a" = "a-a"). Both endpoints are + inclusive. There are two accepted forms: character representing + itself or number encoding character according to ASCII table. + In case of ambiguous characters (dash, comma, digit) use numeric + form. Accepted characters are in the range from 0 to 255. Any + Unicode character with code greater than 255 is considered to be + part of a word. + + The option affects Alt-D, Alt-B and Alt-F, but not Ctrl-W. This + is intentionally to allow two use cases: + + - Moving by WORDS and deletion by words. + - Moving by words and deletion by WORDS. + + To get the latter use the following mapping: + + cnoremap + + Also used for abbreviations. + + 'wrap' type: boolean + default: true + Controls whether to wrap text in quick view. + + 'wrapscan' 'ws' + type: boolean + default: true + Searches wrap around end of the list. + +Mappings + Map arguments + + LHS of mappings can be preceded by arguments which take the form of + special sequences: + + + Postpone UI updates until RHS is completely processed. + + In case of builtin mapping causing conflict for a user-defined + mapping (e.g., `t` builtin to a partially typed `ta` user-de- + fined mapping), ignore the builtin mapping and wait for input + indefinitely as opposed to default behaviour of triggering the + builtin mapping after a delay defined by 'timeoutlen'. Example: + + nnoremap tw :set wrap! + nnoremap tn :set number! + nnoremap tr :set relativenumber! + + Special sequences + + Since it's not easy to enter special characters there are several spe- + cial sequences that can be used in place of them. They are: + + Enter key. + + Escape key. + + + Space key. + + Less-than character (<). + + provides a way to disable a mapping (by mapping it to ). + + Backspace key (see key conflict description below). + + + Tabulation and Shift+Tabulation keys. + + + Home/End. + + + Arrow keys. + + + PageUp/PageDown. + + + Delete key. and mean different codes, but + is more common. + + + Insert key. + + + + + + Shift + one of the keys from above, if terminal and its ter- + minfo supports it. + + ,,...,,,,,, + Control + some key (see key conflict description below). + + {only for *nix} + Control + Space. + + ,,..., + ,,..., + ,,..., {only for *nix} + ,,..., {only for *nix} + Alt + some key. + + ,,..., {only for *nix} + ,,..., {only for *nix} + ,,..., {only for *nix} + ,,..., {only for *nix} + Alt + Shift + some key. + + ,,..., {only for *nix} + ,,..., {only for *nix} + Alt + Ctrl + some key. + + - + Functional keys. + + - {only for MS-Windows} + functional keys with Control key pressed. + + - {only for MS-Windows} + functional keys with Alt key pressed. + + - {only for MS-Windows} + functional keys with Shift key pressed. + + Note that due to the way terminals process their input, several key- + board keys might be mapped to single key code, for example: + + - and ; + + - and ; + + - and and ; + + - etc. + + Most of the time they are defined consistently and don't cause sur- + prises, but and are treated differently in different envi- + ronments (although they match each other all the time), that's why they + correspond to different keys in vifm. As a consequence, if you map or be sure to repeat the mapping with the other one so that it + works in all environments. Alternatively, provide your mapping in one + form and add one of the following: + + " if mappings with in the LHS work + map + " if mappings with in the LHS work + map + + Also sometimes neither of them might work and it's key which cor- + responds to your backspace (don't mind the name). + + Whitespace + + vifm removes whitespace characters at the beginning and end of com- + mands. That's why you may want to use at the end of rhs in + mappings. For example: + + cmap man + + will put "man " in line when you hit the key in the command line + mode. + +Expression syntax + Supported expressions is a subset of what VimL provides. + + Expression syntax summary, from least to most significant: + + expr1 expr2 + expr2 || expr2 .. logical OR + + expr2 expr3 + expr3 && expr3 .. logical AND + + expr3 expr4 + expr4 == expr4 equal + expr4 != expr4 not equal + expr4 > expr4 greater than + expr4 >= expr4 greater than or equal + expr4 < expr4 smaller than + expr4 <= expr4 smaller than or equal + + expr4 expr5 + expr5 + expr5 .. number addition + expr5 - expr5 .. number subtraction + + expr5 expr6 + expr6 . expr6 .. string concatenation + + expr6 expr7 + - expr6 unary minus + + expr6 unary plus + ! expr6 logical NOT + + expr7 number number constant + "string" string constant, \ is special + 'string' string constant, ' is doubled + &option option value + $VAR environment variable + v:var builtin variable + function(expr1, ...) function call + (expr1) nested expression + + ".." indicates that the operations in this level can be concatenated. + + expr1 + ----- + expr2 || expr2 + + Arguments are converted to numbers before evaluation. + + Result is non-zero if at least one of arguments is non-zero. + + It's right associative and with short-circuiting, so sub-expressions + are evaluated from left to right until result of whole expression is + determined (i.e., until first non-zero) or end of the expression. + + expr2 + ----- + expr3 && expr3 + + Arguments are converted to numbers before evaluation. + + Result is non-zero only if both arguments are non-zero. + + It's right associative and with short-circuiting, so sub-expressions + are evaluated from left to right until result of whole expression is + determined (i.e., until first zero) or end of the expression. + + expr3 + ----- + expr4 {cmp} expr4 + + Compare two expr4 expressions, resulting in a 0 if it evaluates to + false or 1 if it evaluates to true. + + equal == + not equal != + greater than > + greater than or equal >= + smaller than < + smaller than or equal <= + + Examples: + + 'a' == 'a' == 1 + 'a' > 'b' == 1 + 'a' == 'b' == 0 + '2' > 'b' == 0 + 2 > 'b' == 1 + 2 > '1b' == 1 + 2 > '9b' == 0 + -1 == -'1' == 1 + 0 == '--1' == 1 + + expr4 + ----- + expr5 + expr5 .. number addition expr5 - expr5 .. number sub- + traction + + Examples: + + 1 + 3 - 3 == 1 + 1 + '2' == 3 + + expr5 + ----- + expr6 . expr6 .. string concatenation + + Examples: + + 'a' . 'b' == 'ab' + 'aaa' . '' . 'c' == 'aaac' + + expr6 + ----- + + - expr6 unary minus + + expr6 unary plus + ! expr6 logical NOT + + For '-' the sign of the number is changed. + For '+' the number is unchanged. + For '!' non-zero becomes zero, zero becomes one. + + A String will be converted to a Number first. + + These operations can be repeated and mixed. Examples: + + --9 == 9 + ---9 == -9 + -+9 == 9 + !-9 == 0 + !'' == 1 + !'x' == 0 + !!9 == 1 + + expr7 + ----- + + number number constant + ----- + + Decimal number. Examples: + + 0 == 0 + 0000 == 0 + 01 == 1 + 123 == 123 + 10000 == 10000 + + string + ------ + "string" string constant + + Note that double quotes are used. + + A string constant accepts these special characters: + \b backspace + \e escape + \n newline + \r return + \t tab + \\ backslash + \" double quote + + Examples: + + "\"Hello,\tWorld!\"" + "Hi,\nthere!" + + literal-string + -------------- + 'string' string constant + + Note that single quotes are used. + + This string is taken as it is. No backslashes are removed or have a + special meaning. The only exception is that two quotes stand for one + quote. + + Examples: + + 'All\slashes\are\saved.' + 'This string contains doubled single quotes ''here''' + + option + ------ + &option option value (local one is preferred, if exists) + &g:option global option value &l:option local + option value + + Examples: + + echo 'Terminal size: '.&columns.'x'.&lines + if &columns > 100 + + Any valid option name can be used here (note that "all" in ":set all" + is a pseudo option). See ":set options" section above. + + environment variable + -------------------- + $VAR environment variable + + The String value of any environment variable. When it is not defined, + the result is an empty string. + + Examples: + + 'This is my $PATH env: ' . $PATH + 'vifmrc at ' . $MYVIFMRC . ' is used.' + + builtin variable + -------------------- + v:var builtin variable + + Information exposed by vifm for use in scripting. + + v:count + count passed to : command, 0 by default. Can be used in mappings to + passthe count to a different command. + v:count1 + same as v:count, but 1 by default. + v:jobcount + number of active jobs (as can be seen in the :jobs menu). + v:session + name of the current session or empty string. + v:servername + See below. + + function call + ------------- + function(expr1, ...) function call + + See "Functions" section below. + + Examples: + + "'" . filetype('.') . "'" + filetype('.') == 'reg' + + expression nesting + ------------------ + (expr1) nested expression + + Groups any other expression of arbitrary complexity enforcing order in + which operators are applied. + + +Functions + USAGE RESULT DESCRIPTION + + chooseopt({opt}) String Queries choose parameters passed on + startup. + executable({expr}) Integer Checks whether {expr} command avail- + able. + expand({expr}) String Expands special keywords in {expr}. + extcached({cache}, {path}, {extcmd}) + String Caches output of {extcmd} per {cache} + and + {path} combination. + filetype({fnum} [, {resolve}]) + String Returns file type from position. + fnameescape({expr}) String Escapes {expr} for use in a :command. + getpanetype() String Returns type of current pane. + has({property}) Integer Checks whether instance has {prop- + erty}. + layoutis({type}) Integer Checks whether layout is of type + {type}. + paneisat({loc}) Integer Checks whether current pane is at + {loc}. + system({command}) String Executes shell command and returns + its output. + tabpagenr([{arg}]) Integer Returns number of current or last + tab. + term({command}) String Like system(), but for interactive + commands. + + chooseopt({opt}) + + Retrieves values of options related to file choosing. {opt} can be one + of: + files returns argument of --choose-files or empty string + dir returns argument of --choose-dir or empty string + cmd returns argument of --on-choose or empty string + delimiter returns argument of --delimiter or the default one (\n) + + executable({expr}) + + If {expr} is absolute or relative path, checks whether path destination + exists and refers to an executable, otherwise checks whether command + named {expr} is present in directories listed in $PATH. Checks for + various executable extensions on Windows. Returns boolean value de- + scribing result of the check. + + Example: + + " use custom default viewer script if it's available and installed + " in predefined system directory, otherwise try to find it elsewhere + if executable('/usr/local/bin/defviewer') + fileview * /usr/local/bin/defviewer %c + else + if executable('defviewer') + fileview * defviewer %c + endif + endif + + expand({expr}) + + Expands environment variables and macros in {expr} (in this order). + Returns a string. See "Command macros" section above. + + Examples: + + " percent sign + :echo expand('%%') + " the last part of directory name of the other pane + :echo expand('%D:t') + " $PATH environment variable (same as `:echo $PATH`) + :echo expand('$PATH') + " full path to the current file with backslashes + :echo expand('%c:p:gs!/!\!') + + extcached({cache}, {path}, {extcmd}) + + Caches value of {extcmd} external command automatically updating it as + necessary based on monitoring change date of a {path}. The cache is + invalidated when file or its meta-data is updated. A single path can + have multiple caches associated with it. + + {path} value is normalized, but symbolic links in it aren't resolved. + + Example: + + " display number and size of blocks actually used by a file or directory + set statusline+=" Uses: %{ extcached('uses', + expand('%c'), + expand('stat --format=%%bx%%B %c')) }" + + filetype({fnum} [, {resolve}]) + + The result is a string, which represents file type and is one of the + list: + exe executables + reg regular files + link symbolic links + broken broken symbolic links (appears only when resolving) + dir directories + char character devices + block block devices + fifo pipes + sock *nix domain sockets + ? unknown file type (should not normally happen) or + non-file (pseudo-entries in compare view) + + The result can also be an empty string in case of invalid argument. + + Parameter {fnum} can have following values: + - '.' to get type of file under the cursor in the active pane + - numerical value base 1 to get type of file on specified line num- + ber + + Optional parameter {resolve} is treated as a boolean and specifies + whether symbolic links should be resolved. + + fnameescape({expr}) + + Escapes parameter to make it suitable for use as an argument of a :com- + mand. List of escaped characters includes %, which is doubled. + + Usage example: + + " navigate to most recently modified file in current directory + execute 'goto' fnameescape(system('ls -t | head -1')) + + getpanetype() + + Retrieves string describing type of current pane. Possible return val- + ues: + regular regular file listing of some directory + custom custom file list (%u) + very-custom very custom file list (%U) + tree tree view + + has({property}) + + Allows examining internal parameters from scripts to e.g. figure out + environment in which application is running. Returns 1 if property is + true/present, otherwise 0 is returned. Currently the following proper- + ties are supported (anything else will yield 0): + unix runs in *nix-like environment (including Cygwin) + win runs on Windows + #* whether particular Lua handler exists + + Usage example: + + " skip user/group on Windows + if !has('win') + let $RIGHTS = '%10u:%-7g ' + endif + + execute 'set' 'statusline=" %t%= %A '.$RIGHTS.'%15E %20d "' + + layoutis({type}) + + Checks whether current interface layout is {type} or not, where {type} + can be: + only single-pane mode + split double-pane mode (either vertical or horizontal split) + vsplit vertical split (left and right panes) + hsplit horizontal split (top and bottom panes) + + Usage example: + + " automatically split vertically before enabling preview + :nnoremap w :if layoutis('only') | vsplit | endif | view! + + paneisat({loc}) + + Checks whether position of active pane in current layout matches one of + the following locations: + top pane reaches top border + bottom pane reaches bottom border + left pane reaches left border + right pane reaches right border + + system({command}) + + Runs the command in shell and returns its output (joined standard out- + put and standard error streams). All trailing newline characters are + stripped to allow easy appending to command output. Ctrl-C should in- + terrupt the command. + + Use this function to consume output of external commands that don't re- + quire user interaction and term() for interactive commands that make + use of terminal and are capable of handling stream redirection. + + Usage example: + + " command to enter .git/ directory of git-repository (when ran inside one) + command! cdgit :execute 'cd' fnameescape(system('git rev-parse --git-dir')) + + tabpagenr([{arg}]) + + When called without arguments returns number of current tab page base + one. + + When called with "$" as an argument returns number of the last tab page + base one, which is the same as number of tabs. + + term({command}) + + Same as system() function, but user interface is shutdown during the + execution of the command, which makes sure that external interactive + applications won't affect the way terminal is used by vifm. + + Usage example: + + " command to change directory by picking it via fzf + command! fzfcd :execute 'cd' + fnameescape(term('find -type d | fzf 2> /dev/tty')) + +Menus and dialogs + When navigating to some path from a menu there is a difference in end + location depending on whether path has trailing slash or not. Files + normally don't have trailing slashes so "file/" won't work and one can + only navigate to a file anyway. On the other hand with directories + there are two options: navigate to a directory or inside of it. To al- + low both use cases, the first one is used on paths like "dir" and the + second one for "dir/". + + Commands + + :range navigate to a menu line. + + :exi[t][!] :q[uit][!] :x[it][!] + leave menu mode. + + :noh[lsearch] + reset search match highlighting. + + :w[rite] {dest} + write all menu lines into file specified by {dest}. + + General + + j, Ctrl-N - move down. + k, Ctrl-P - move up. + Enter, l - select and exit the menu. + Ctrl-L - redraw the menu. + + Escape, Ctrl-C, ZZ, ZQ, q - quit. + + In all menus + + The following set of keys has the same meaning as in normal mode. + + Ctrl-B, Ctrl-F + Ctrl-D, Ctrl-U + Ctrl-E, Ctrl-Y + /, ? + n, N + [count]G, [count]gg + H, M, L + zb, zt, zz + + zh - scroll menu items [count] characters to the right. + zl - scroll menu items [count] characters to the left. + zH - scroll menu items half of screen width characters to the right. + zL - scroll menu items half of screen width characters to the left. + + : - enter command line mode for menus (currently only :exi[t], :q[uit], + :x[it] and :{range} are supported). + + b - interpret content of the menu as list of paths and use it to create + custom view in place of previously active pane. See "Custom views" + section below. + B - same as above, but creates unsorted view. + + v - load menu content into quickfix list of the editor (Vim compatible + by assumption) or if list doesn't have separators after file names + (colons) open each line as a file name. + + + Below is description of additional commands and reaction on selection + in some menus and dialogs. + + Apropos menu + + Selecting menu item runs man on a given topic. Menu won't be closed + automatically to allow view several pages one by one. + + Command-line mode abbreviations menu + + Type dd on an abbreviation to remove it. + + c leaves menu preserving file selection and inserts right-hand side of + selected command into command-line. + + Color scheme menu + + Selecting name of a color scheme applies it the same way as if ":col- + orscheme " was executed on the command-line. + + Commands menu + + Selecting command executes it with empty arguments (%a). + + dd on a command to remove. + + Marks menu + + Selecting mark navigates to it. + + dd on a mark to remove it. + + Bookmarks menu + + Selecting a bookmark navigates to it. + + Type dd on a bookmark to remove it. + + gf and e also work to make it more convenient to bookmark files. + + Trash (:lstrash) menu + + r on a file name to restore it from trash. + + dd deletes file under the cursor. + + Trashes (:trashes) menu + + dd empties selected trash in background. + + Directory history and Trashes menus + + Selecting directory name will change directory of the current view as + if :cd command was used. + + Directory stack menu + + Selecting directory name will rotate stack to put selected directory + pair at the top of the stack. + + File (:file) menu + + Commands from vifmrc or typed in command-line are displayed above empty + line. All commands below empty line are from .desktop files. + + c leaves menu preserving file selection and inserts command after :! in + command-line mode. + + Grep, find, locate, bookmarks and user menu with navigation (%M macro) + + gf - navigate previously active view to currently selected item. + Leaves menu mode except for grep menu. Pressing Enter key has the same + effect. + + e - open selected path in the editor, stays in menu mode. + + c - leave menu preserving file selection and insert file name after :! + in command-line mode. + + User menu without navigation (%m macro) + + c leaves menu preserving file selection and inserts whole line after :! + in command-line mode. + + Grep menu + + Selecting file (via Enter or l key) opens it in editor set by 'vicmd' + at given line number. Menu won't be closed automatically to allow + viewing more than one result. + + See above for "gf" and "e" keys description. + + Command-line history menu + + Selecting an item executes it as command-line command, search query or + local filter. + + c leaves menu preserving file selection and inserts line into command- + line of appropriate kind. + + Volumes menu + + Selecting a drive navigates previously active pane to the root of that + drive. + + Fileinfo dialog + + Enter, q - close dialog + + Sort dialog + + h, Space - switch ascending/descending. + q - close dialog + + One shortcut per sorting key (see the dialog). + + Attributes (permissions or properties) dialog + + h, Space - check/uncheck. + q - close dialog + r - (*nix only) (un)set all read bits + w - (*nix only) (un)set all write bits + x - (*nix only) (un)set all execute bits + s - (*nix only) (un)set all special (SetUID, SetGID, Sticky) bits + e - (*nix only) (un)set recursion (for directories only) + + Item states: + + - * - checked flag. + + - X - means that it has different value for files in selection. + + - d (*nix only) - (only for execute flags) means u-x+X, g-x+X or o-x+X + argument for the chmod program. If you're not on OS X and want to + remove execute permission bit from all files, but preserve it for di- + rectories, set all execute flags to 'd' and check 'Set Recursively' + flag. + + Jobs menu + + dd requests cancellation of job under cursor. The job won't be removed + from the list, but marked as being cancelled (if cancellation was suc- + cessfully requested). A message will pop up if the job has already + stopped. Note that on Windows cancelling external programs like this + might not work, because their parent shell doesn't have any windows. + + e key displays errors of selected job if any were collected. They are + displayed in a new menu, but you can get back to jobs menu by pressing + h. + + + Undolist menu + + r - reset undo position to group under the cursor. + + + Media menu + + Selecting a device either mounts (if it wasn't mounted yet) or navi- + gates to its first mount point. + + Selecting a mount point navigates to it. + + Selecting "not mounted" line causes mounting. + + Selecting any other line does nothing. + + r - reload the list. + + m - mount/unmount device (cursor should be positioned on lines under + device information). + + [ - put cursor on the previous device. + + ] - put cursor on the next device. + + + Plugins menu + + e - display log messages of selected plugin if any were collected. + They are displayed in a new menu, but you can get back to plugins menu + by pressing h. + + gf - navigate previously active view to the location of selected + plugin. Leaves menu mode. + + +Custom views + Definition + + Normally file views contain list of files from a single directory, but + sometimes it's useful to populate them with list of files that do not + belong to the same directory, which is what custom views are for. + + Presentation + + Custom views are still related to directory they were in before custom + list was loaded. Path to that directory (original directory) can be + seen in the title of a custom view. + + Files in same directory have to be named differently, this doesn't hold + for custom views thus seeing just file names might be rather confusing. + In order to give an idea where files come from and when possible, rela- + tive paths to original directory of the view is displayed, otherwise + full path is used instead. + + Custom views normally don't contain any inexistent files. + + Navigation + + Custom views have some differences related to navigation in regular + views. + + gf - acts similar to gf on symbolic links and navigates to the file at + its real + location. + + h - go to closes parent node in tree view, otherwise return to the + original directory. + + gh - return to the original directory. + + Opening ".." entry also causes return to the original directory. + + History + + Custom list exists only while it's visible, once left one can't return + to it, so there is no appearances of it in any history. + + Filters + + Only local filter affects content of the view. This is intentional, + presumably if one loads list, precisely that list should be displayed + (except for inexistent paths, which are ignored). + + Search + + Although directory names are visible in listing, they are not search- + able. Only file names are taken into account (might be changed in fu- + ture, searching whole lines seems quite reasonable). + + Sorting + + Contrary to search sorting by name works on whole visible part of file + path. + + Highlight + + Whole file name is highlighted as one entity, even if there are direc- + tory elements. + + Updates + + Reloads can occur, though they are not automatic due to files being + scattered among different places. On a reload, inexistent files are + removed and meta-data of all other files is updated. + + Once custom view forgets about the file, it won't add it back even if + it's created again. So not seeing file previously affected by an oper- + ation, which was undone is normal. + + Operations + + All operations that add files are forbidden for custom views. For ex- + ample, moving/copying/putting files into a custom view doesn't work, + because it doesn't make much sense. + + On the other hand, operations that use files of a custom view as a + source (e.g. yanking, copying, moving file from custom view, deletion) + and operations that modify names are all allowed. + +Compare views + Kinds + + :compare can produce four different results depending on arguments: + - single compare view (ofone and either listall or listdups); + - single custom view (ofone and listunique); + - two compare views (ofboth and either listall or listdups); + - two custom views (ofboth and listunique). + + The first two display files of one file system tree. Here duplicates + are files that have at least one copy in the same tree. The other two + kinds of operation compare two trees, in which duplicates are files + that are found in both trees. + + Lists of unique files are presented in custom views because there is no + file grouping to preserve as all file ids are guaranteed to be dis- + tinct. + + Creation + + Arguments passed to :compare form four categories each with its own + prefix and is responsible for particular property of operation. + + Which files to compare: + - ofboth - compares files of two panes against each other; + - ofone - compares files of the same directory. + + How files are compared: + - byname - by their name only; + - bysize - only by their size; + - bycontents - by data they contain (combination of size and hash of + small chunk of contents is used as first approximation, so don't worry + too much about large files). + + Which files to display: + - listall - all files; + - listunique - unique files only; + - listdups - only duplicated files. + + How results are grouped (has no effect if "ofone" specified): + - groupids - files considered identical are always adjacent in out- + put; + - grouppaths - file system ordering is preferred (this also enables + displaying identically named files as mismatches). + + Which files to omit: + - skipempty - ignore empty files. + + Each argument can appear multiple times, the rightmost one of the group + is considered. Arguments alter default behaviour instead of substitut- + ing it. + + Examples + + The defaults corresponds to probably the most common use case of com- + paring files in two trees with grouping by paths, so the following are + equivalent: + + :compare + :compare bycontents grouppaths + :compare bycontents listall ofboth grouppaths + + Another use case is to find duplicates in the current sub-tree: + + :compare listdups ofone + + The following command lists files that are unique to each pane: + + :compare listunique + + Look + + The view can't switch to ls-like view as it's unable to display diff- + like data. + + Comparison views have second column displaying id of the file, files + with same id are considered to be equal. The view columns configura- + tion is predefined. + + Behaviour + + When two views are being compared against each other the following + changes to the regular behaviour apply: + - views are scrolled synchronously (as if 'scrollbind' was set); + - views' cursors are synchronized; + - local filtering is disabled (its results wouldn't be meaningful); + - zd excludes groups of adjacent identical files, 1zd gives usual be- + haviour; + - sorting is permanently disabled (ordering is fixed); + - removed files hide their counter pairs; + - exiting one of the views terminates the other immediately; + - renaming files isn't blocked, but isn't taken into account and might + require regeneration of comparison; + - entries which indicate absence of equivalent file have empty names + and can be matched as such; + - when unique files of both views are listed custom views can be + empty, this absence of unique files is stated clearly. + + One compare view has similar properties (those that are applicable for + single pane). + + Files are gathered in this way: + - recursively starting at current location of the view; + - dot files are excluded if view hides them at the moment of compari- + son, file name filters are obeyed as well so you end up comparing what + you see; + - directories are not taken into account; + - symbolic links to directories are ignored. + +Startup + On startup vifm determines several variables that are used during exe- + cution. They are determined in the order they appear below. + + On *nix systems $HOME is normally present and used as is. On Windows + systems vifm tries to find correct home directory in the following or- + der: + - $HOME variable; + - $USERPROFILE variable (on Windows only); + - a combination of $HOMEDRIVE and $HOMEPATH variables (on Windows + only). + + vifm tries to find correct configuration directory by checking the fol- + lowing places: + - $VIFM variable; + - parent directory of the executable file (on Windows only); + - $HOME/.vifm directory; + - $APPDATA/Vifm directory (on Windows only); + - $XDG_CONFIG_HOME/vifm directory; + - $HOME/.config/vifm directory. + + vifm tries to find correct configuration file by checking the following + places: + - $MYVIFMRC variable; + - vifmrc in parent directory of the executable file (on Windows only); + - $VIFM/vifmrc file. + +Configure + See "Startup" section above for the explanations on $VIFM and $MYV- + IFMRC. + + The vifmrc file contains commands that will be executed on vifm + startup. There are two such files: global and local. Global one is at + {prefix}/etc/vifm/vifmrc, see $MYVIFMRC variable description for the + search algorithm used to find local vifmrc. Global vifmrc is loaded + before the local one, so that the later one can redefine anything con- + figured globally. + + Use vifmrc to set settings, mappings, filetypes etc. To use multi line + commands precede each next line with a slash (whitespace before slash + is ignored, but all spaces at the end of the lines are saved). For ex- + ample: + + set + \smartcase + + equals "setsmartcase". When + + set + \ smartcase + + equals "set smartcase". + + The $VIFM/vifminfo file contains generic state of the application. You + can control what is stored in vifminfo by setting 'vifminfo' option. + Vifm always writes this file on exit unless 'vifminfo' option is empty. + Marks, bookmarks, commands, histories, filetypes, fileviewers and reg- + isters in the file are merged with vifm configuration (which has bigger + priority). + + Generally, runtime configuration has bigger priority during merging, + but there are some exceptions: + + - directory stack stored in the file is not overwritten unless some- + thing is changed in vifm instance that performs merge; + + - each mark or bookmark is marked with a timestamp, so that newer + value is not overwritten by older one, thus no matter from where it + comes, the newer one wins; + + - all histories are marked with timestamps on storing, this means + that last instance to quit puts its elements on top of the list; + + - tabs are merged only if both current instance and stored state con- + tain exactly one tab of any kind. + + The $VIFM/scripts directory can contain shell scripts. vifm modifies + its PATH environment variable to let user run those scripts without + specifying full path. All subdirectories of the $VIFM/scripts will be + added to PATH too. Script in a subdirectory overlaps script with the + same name in all its parent directories. + + The $VIFM/colors/ and {prefix}/etc/vifm/colors/ directories contain + color schemes. Available color schemes are searched in that order, so + on name conflict the one in $VIFM/colors/ wins. + + Each color scheme should have ".vifm" extension. This wasn't the case + before and for this reason the following rules apply during lookup: + + - if there is no file with .vifm extension, all regular files are + listed; + + - otherwise only files with .vifm extension are listed (with the ex- + tension being truncated). + +Sessions + Sessions provide a way to have multiple persistent runtime configura- + tions. Think of them as second-level vifminfo files in addition to the + first-level one used by all sessions. In other words, they aren't a + replacement for vifminfo file that exists without sessions, but an ad- + dition to it. One can empty 'vifminfo' option and rely solely on ses- + sions, but in practice one might want to share some state among in- + stances in different sessions or have an "out-of-sessions" state for + tasks that don't deserve a session of their own. + + This leads to a two-level structure where data in session files has + higher priority than data in vifminfo files (where this makes sense) + following the same rules that merging of vifminfo file obeys. In addi- + tion to that, history items from session files are never ordered before + history items from vifminfo file. + + Format + + Sessions have the format of vifminfo files, they do not consist of se- + quence of command-line commands and are not meant to be sourced via + :source command. + + Storage and naming + + `$VIFM/sessions/` directory serves as a storage for sessions. Conse- + quently names should be valid filenames. The structure of the storage + is flat meaning that there are no subdirectories, that's why names of + sessions can't contain slashes. + + Usage model + + Contrary to Vim, vifm automates basic management of sessions. You can + start, switch, stop or delete a session using builtin means. + + Current session is saved at the same time vifminfo is saved (on normal + exits or explicitly on :write command) and right before switching to + another session. To avoid saving in those cases use :session command + to detach (without saving) from a session before proceeding. + + Related topics + + Commands: :session, :delsession + Options: 'sessionoptions' + Variables: v:session + +Automatic FUSE mounts + vifm has a builtin support of automated FUSE file system mounts. It is + implemented using file associations mechanism. To enable automated + mounts, one needs to use a specially formatted program line in filetype + or filextype commands. These use special macros, which differ from + macros in commands unrelated to FUSE. Currently three formats are sup- + ported: + + 1) FUSE_MOUNT This format should be used in case when all information + needed for mounting all files of a particular type is the same. E.g. + mounting of tar files don't require any file specific options. + + Format line: + FUSE_MOUNT|mounter %SOURCE_FILE %DESTINATION_DIR [%FOREGROUND] + + Example filetype command: + + :filetype FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR + + 2) FUSE_MOUNT2 This format allows one to use specially formatted files + to perform mounting and is useful for mounting remotes, for example re- + mote file systems over ftp or ssh. + + Format line: + FUSE_MOUNT2|mounter %PARAM %DESTINATION_DIR [%FOREGROUND] + + Example filetype command: + + :filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR + + Example file content: + + root@127.0.0.1:/ + + 3) FUSE_MOUNT3 + + This format is equivalent to FUSE_MOUNT, but omits unmounting. It is + useful for cases, when unmounting isn't needed, like when using AVFS. + + Example :filetype command: + + :filetype *.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz,*.deb + \ {Mount with avfs} + \ FUSE_MOUNT3|mount-avfs %DESTINATION_DIR %SOURCE_FILE + + Example `mount-avfs` helper script: + + #!/bin/sh + + dest=$1 + file=$2 + + rmdir "$dest" + ln -s "$HOME/.avfs$file#/" "$dest" + + All % macros are expanded by vifm at runtime and have the following + meaning: + - %SOURCE_FILE is replaced by full path to selected file; + - %DESTINATION_DIR is replaced by full path to mount directory, which + is created by vifm basing on the value of 'fusehome' option; + - %PARAM value is filled from the first line of file (whole line), + though in the future it can be changed to whole file content; + - %FOREGROUND means that you want to run mount command as a regular + command (required to be able to provide input for communication with + mounter in interactive way). + + %FOREGROUND is an optional macro. Other macros are not mandatory, but + mount commands likely won't work without them. + + %CLEAR is obsolete name of %FOREGROUND, which is still supported, but + might be removed in future. Its use is discouraged. + + Unlike macros elsewhere, these are recognized only if they appear at + the end of a command or are followed by a space. There is no way to + escape % either. These are historical limitations, which might be ad- + dressed in the future. + + The mounted FUSE file systems will be automatically unmounted in two + cases: + + - when vifm quits (with ZZ, :q, etc. or when killed by signal); + + - when you explicitly leave mount point going up to its parent direc- + tory (with h, Enter on "../" or ":cd ..") and other pane is not in + the same directory or its child directories. + +View look + vifm supports displaying of file list view in two different ways: + + - in a table mode, when multiple columns can be set using 'view- + columns' option (see "Column view" section below for details); + + - in a multicolumn list manner which looks almost like `ls -x` com- + mand output (see "ls-like view" section below for details). + + The look is local for each view and can be chosen by changing value of + the 'lsview' boolean option. + + Depending on view look some of keys change their meaning to allow more + natural cursor moving. This concerns mainly h, j, k, l and other simi- + lar navigation keys. + + Also some of options can be ignored if they don't affect view display- + ing in selected look. For example value of 'viewcolumns' when 'lsview' + is set. + +ls-like view + When this view look is enabled by setting 'lsview' option on, vifm will + display files in multiple columns. Number of columns depends on the + length of the longest file name present in current directory of the + view. Whole file list is automatically reflowed on directory change, + terminal or view resize. + + View looks close to output of `ls -x` command, so files are listed left + to right in rows. + + In this mode file manipulation commands (e.g. d) don't work line-wise + like they do in Vim, since such operations would be uncommon for file + manipulation tasks. Thus, for example, dd will remove only current + file. + + By default the view is filled by lines, 'lsoptions' can be used to get + filling by columns. + + Note that tree-view and compare view inhibit ls-like view. + +Column view + View columns are described by a comma-separated list of column descrip- + tions, each of which has the following format + [ '-' | '*' ] [ fw ( [ '.' tw ] | '%' ) ] '{' type | literal '}' + '.'{0,3} + where fw stands for full width, tw stands for text width, bar is logi- + cal or, square brackets denote optional parts and curly braces define + range of repetitions for a symbol that precedes them. + + So it basically consists of four parts: + 1. Optional alignment specifier + 2. Optional width specifier + 3. Mandatory column name + 4. Optional cropping specifier + + Alignment specifier + + It's an optional minus or asterisk sign as the first symbol of the + string. + + Specifies type of text alignment within a column. Three types are sup- + ported: + + - left align + + set viewcolumns=-{name} + + - right align (default) + + set viewcolumns={name} + + - dynamic align + + It's like left alignment, but when the text is bigger than the col- + umn, the alignment is made at the right (so the part of the field is + always visible). + + set viewcolumns=*{name} + + Width specifier + + It's a number followed by a percent sign, two numbers (second one + should be less than or equal to the first one) separated with a dot or + a single number. + + Specifies column width and its units. There are three size types: + + - absolute size - column width is specified in characters + + set viewcolumns=-100{name},20.15{ext} + + results in two columns with lengths of 100 and 20 and a reserved + space of five characters on the left of second column. + + - relative (percent) size - column width is specified in percents of + view width + + set viewcolumns=-80%{name},15%{ext},5%{mtime} + + results in three columns with lengths of 80/100, 15/100 and 5/100 of + view width. + + - auto size (default) - column width is automatically determined + + set viewcolumns=-{name},{ext},{mtime} + + results in three columns with length of one third of view width. + There is no size adjustment to content, since it will slow down ren- + dering. + + Columns of different sizing types can be freely mixed in one view. + Though sometimes some of columns can be seen partly or be completely + invisible if there is not enough space to display them. + + Column contents + + This is usually a sorting key surrounded with curly braces, e.g. + + {name},{ext},{mtime} + + {name} and {iname} types are the same and present both for consistency + with 'sort' option. + + Following types don't have corresponding sorting keys: + + - {root} - display name without extension (as a complement for + {ext}) + + - {fileroot} - display name without extension for anything except for + directories and symbolic links to directories (as a complement for + {fileext}) + + Empty curly braces ({}) are replaced with the default secondary column + for primary sort key. So after the next command view will be displayed + almost as if 'viewcolumns' is empty, but adding ellipsis for long file + names: + + set viewcolumns=-{name}..,6{}. + + The last kind of column value is a string literal. The literal is used + as a column value for every row. The syntax is "{#literal}", for exam- + ple: + + 3{#},{#|},{# | } + + This can be used to draw column separators. Mind that for convenience + literals have different defaults: truncation and automatically deter- + mined absolute size, which is what you usually want for them. Example: + + set viewcolumns=*{name}..,{#|},6{}. + + Cropping specifier + + It's from one to three dots after closing curly brace in column format. + + Specifies type of text truncation if it doesn't fit in the column. + Currently three types are supported: + + - truncation - text is truncated + + set viewcolumns=-{name}. + + results in truncation of names that are too long too fit in the + view. + + - adding of ellipsis - ellipsis on the left or right are added when + needed + + set viewcolumns=-{name}.. + + results in that ellipsis are added at the end of too long file + names. + + - none (default) - text can pass column boundaries + + set viewcolumns=-{name}...,{ext} + + results in that long file names can partially be written on the ext + column. + +Color schemes + The color schemes in vifm can be applied in two different ways: + + - as the primary color scheme; + + - as local to a pane color scheme. + + Both types are set using :colorscheme command, but of different forms: + + - :colorscheme color_scheme_name - for the primary color scheme; + + - :colorscheme color_scheme_name directory - for local color schemes. + + Look of different parts of the TUI (Text User Interface) is determined + in this way: + + - Border, TabLine, TabLineSel, TopLineSel, TopLine, CmdLine, Er- + rorMsg, StatusLine, JobLine, SuggestBox and WildMenu are always de- + termined by the primary color scheme; + + - CurrLine, Selected, Directory, Link, BrokenLink, Socket, Device, + Executable, Fifo, CmpMismatch, CmpUnmatched, CmpBlank, Win, AuxWin + and OtherWin are determined by primary color scheme and a set of + local color schemes, which can be empty. + + There might be a set of local color schemes because they are structured + hierarchically according to file system structure. For example, having + the following piece of file system: + + ~ + `-- bin + | + `-- my + + Two color schemes: + + # ~/.config/vifm/colors/for_bin.vifm + highlight Win cterm=none ctermfg=white ctermbg=red + highlight CurrLine cterm=none ctermfg=red ctermbg=black + + # ~/.config/vifm/colors/for_bin_my.vifm + highlight CurrLine cterm=none ctermfg=green ctermbg=black + + And these three commands in the vifmrc file: + + colorscheme Default + colorscheme for_bin ~/bin + colorscheme for_bin_my ~/bin/my + + File list will look in the following way for each level: + + - ~/ - Default color scheme + black background + cursor with blue background + + - ~/bin/ - mix of Default and for_bin color schemes + red background + cursor with black background and red foreground + + - ~/bin/my/ - mix of Default, for_bin and for_bin_my color schemes + red background + cursor with black background and green foreground + +Trash directory + vifm has support of trash directory, which is used as temporary storage + for deleted files or files that were cut. Using trash is controlled by + the 'trash' option, and exact path to the trash can be set with + 'trashdir' option. Trash directory in vifm differs from the system- + wide one by default, because of possible incompatibilities of storing + deleted files among different file managers. But one can set + 'trashdir' to "~/.local/share/Trash" to use a "standard" trash direc- + tory. + + There are two scenarios of using trash in vifm: + + 1. As a place for storing files that were cut by "d" and may be in- + serted to some other place in file system. + + 2. As a storage of files, that are deleted but not purged yet. + + The first scenario uses deletion ("d") operations to put files to trash + and put ("p") operations to restore files from trash directory. Note + that such operations move files to and from trash directory, which can + be long term operations in case of different partitions or remote + drives mounted locally. + + The second scenario uses deletion ("d") operations for moving files to + trash directory and :empty command-line command to purge all previously + deleted files. + + Deletion and put operations depend on registers, which can point to + files in trash directory. Normally, there are no nonexistent files in + registers, but vifm doesn't keep track of modifications under trash di- + rectory, so one shouldn't expect value of registers to be absolutely + correct if trash directory was modified not by operation that are meant + for it. But this won't lead to any issues with operations, since they + ignore nonexistent files. + +Client-Server + vifm supports remote execution of command-line mode commands, remote + changing of directories and expression evaluation. This is possible + using --remote and --remote-expr command-line arguments. + + To execute a command remotely combine --remote argument with -c or +. For example: + + vifm --remote -c 'cd /' + vifm --remote '+cd /' + + To change directory not using command-line mode commands one can spec- + ify paths right after --remote argument, like this: + + vifm --remote / + vifm --remote ~ + vifm --remote /usr/bin /tmp + + Evaluating expression remotely might be useful to query information + about an instance, for example its location: + + vifm --remote-expr 'expand("%d")' + + If there are several running instances, the target can be specified + with --server-name option (otherwise, the first one lexicographically + is used): + + vifm --server-name work --remote ~/work/project + + List of names of running instances can be obtained via --server-list + option. Name of the current one is available via v:servername. + + + v:servername + server name of the running vifm instance. Empty if client- + server feature is disabled. + +External Renaming + When an editor is run to edit list of file names, contents of the tem- + porary file has the following format: + + 1. Order of lines correspond to the order of files in a view. + + 2. Lines that start with a "#" are comments and are ignored. + + 3. Single backslash at the beginning of a line is ignored, so that a + file starting with a backslash will appear like "\#name". + + If an operation was rejected due to issues with file names, next time + you'll see the following in this order: + + 1. Last error (in comments). + + 2. Original file names (in comments). + + 3. Failed list of new names. + + Mind that Vim plugin will extract list of original names and show them + in a vertical split. + + You can cancel renaming by removing all non-comments from the buffer. + This also erases information about previous edits. + +Plugin + Plugin for using vifm in vim as a file selector. + + Commands: + + :EditVifm select a file or files to open in the current buffer. + :Vifm alias for :EditVifm. + :SplitVifm split buffer and select a file or files to open. + :VsplitVifm vertically split buffer and select a file or files to + open. + :DiffVifm select a file or files to compare to the current file + with + :vert diffsplit. + :TabVifm select a file or files to open in tabs. + + Each command accepts up to two arguments: left pane directory and right + pane directory. After arguments are checked, vifm process is spawned + in a special "file-picker" mode. To pick files just open them either + by pressing l, i or Enter keys, or by running :edit command. If no + files are selected, file under the cursor is opened, otherwise whole + selection is passed to the plugin and opened in vim. + + The plugin have only two settings. It's a string variable named + g:vifm_term to let user specify command to run GUI terminal. By de- + fault it's equal to 'xterm -e'. And another string variable named + g:vifm_exec, which equals "vifm" by default and specifies path to + vifm's executable. To pass arguments to vifm use g:vifm_exec_args, + which is empty by default. + + To use the plugin copy the vifm.vim file to either the system wide + vim/plugin directory or into ~/.vim/plugin. + + If you would prefer not to use the plugin and it is in the system wide + plugin directory add + + let loaded_vifm=1 + + to your ~/.vimrc file. + +Reserved + The following command names are reserved and shouldn't be used for user + commands. + + g[lobal] + v[global] + +ENVIRONMENT + VIFM Points to main configuration directory (usually ~/.con- + fig/vifm/). + + MYVIFMRC + Points to main configuration file (usually ~/.con- + fig/vifm/vifmrc). + + These environment variables are valid inside vifm and also can be used + to configure it by setting some of them before running vifm. + + When $MYVIFMRC isn't set, it's made as $VIFM/vifmrc (exception for Win- + dows: vifmrc in the same directory as vifm.exe has higher priority than + $VIFM/vifmrc). + + See "Startup" section above for more details. + + VIFM_FUSE_FILE + On execution of external commands this variable is set to the + full path of file used to initiate FUSE mount of the closest + mount point from current pane's directory up. It's not set when + outside FUSE mount point. When vifm is used inside terminal + multiplexer, it tries to set this variable as well (it doesn't + work this way on its own). + +SEE ALSO + vifm-convert-dircolors(1), vifm-pause(1) + + Website: https://vifm.info/ + Wiki: https://wiki.vifm.info/ + + Esperanto translation of the documentation by Sebastian Cyprych: + http://cyprych.neostrada.pl/tekstoj/komputiloj/vifm-help.eo.html + +AUTHOR + Vifm was written by ksteen + And currently is developed by xaizek + + + +vifm 0.12.1 21 September 2022 VIFM(1) diff --git a/config/vifm/vifmrc b/config/vifm/vifmrc new file mode 100644 index 0000000..2a1a655 --- /dev/null +++ b/config/vifm/vifmrc @@ -0,0 +1,541 @@ +" vim: filetype=vifm : +" Sample configuration file for vifm (last updated: 8 August, 2022) +" You can edit this file by hand. +" The " character at the beginning of a line comments out the line. +" Blank lines are ignored. +" The basic format for each item is shown with an example. + +" ------------------------------------------------------------------------------ +" Main settings +" ------------------------------------------------------------------------------ + +" Command used to edit files in various contexts. The default is vim. +" If you would like to use another vi clone such as Elvis or Vile +" you will need to change this setting. +if executable('nvim') + set vicmd=nvim +elseif executable('vim') + set vicmd=vim +elseif executable('elvis') + set vicmd=elvis\ -G\ termcap +elseif executable('vile') + set vicmd=vile +elseif $EDITOR != '' + echo 'Note: using `'.$EDITOR.'` as an editor' + let &vicmd = $EDITOR +endif + +" This makes vifm perform file operations on its own instead of relying on +" standard utilities like `cp`. While using `cp` and alike is a more universal +" solution, it's also much slower when processing large amounts of files and +" doesn't support progress measuring. +set syscalls + +" Trash Directory +" The default is to move files that are deleted with dd or :d to +" the trash directory. If you change this you will not be able to move +" files by deleting them and then using p to put the file in the new location. +" I recommend not changing this until you are familiar with vifm. +" This probably shouldn't be an option. +set trash + +" What should be saved automatically on restarting vifm. Drop "savedirs" +" value if you don't want vifm to remember last visited directories for you. +set vifminfo=dhistory,savedirs,chistory,state,tui,shistory, + \phistory,fhistory,dirstack,registers,bookmarks,bmarks + +" This is how many directories to store in the directory history. +set history=100 + +" Automatically resolve symbolic links on l or Enter. +set nofollowlinks + +" Natural sort of (version) numbers within text. +set sortnumbers + +set number +set relativenumber + +" Maximum number of changes that can be undone. +set undolevels=100 + +" Use Vim's format of help file (has highlighting and "hyperlinks"). +" If you would rather use a plain text help file set novimhelp. +set vimhelp + +" If you would like to run an executable file when you +" press Enter, l or Right Arrow, set this. +set norunexec + +" List of color schemes to try (picks the first one supported by the terminal) +colorscheme Default-256 Default + +" Format for displaying time in file list. For example: +" TIME_STAMP_FORMAT=%m/%d-%H:%M +" See man date or man strftime for details. +set timefmt='%Y/%m/%d %H:%M' + +" Show list of matches on tab completion in command-line mode +set wildmenu + +" Display completions in a form of popup with descriptions of the matches +set wildstyle=popup + +" Display suggestions in normal, visual and view modes for keys, marks and +" registers (at most 5 files). In other view, when available. +set suggestoptions=normal,visual,view,otherpane,keys,marks,registers + +" Ignore case in search patterns unless it contains at least one uppercase +" letter +set ignorecase +set smartcase + +" Don't highlight search results automatically +set nohlsearch + +" Use increment searching (search while typing) +set incsearch + +" Try to leave some space from cursor to upper/lower border in lists +set scrolloff=4 + +" Don't do too many requests to slow file systems +if !has('win') + set slowfs=curlftpfs +endif + +" Set custom status line look +set statusline=" Hint: %z%= %A %10u:%-7g %15s %20d " + +" ------------------------------------------------------------------------------ +" Bookmarks +" ------------------------------------------------------------------------------ + +" :mark mark /full/directory/path [filename] + +mark b ~/bin/ +mark h ~/ + +" ------------------------------------------------------------------------------ +" Commands +" ------------------------------------------------------------------------------ + +" :com[mand][!] command_name action +" +" These are some of the macros that can be used in the action part: +" %a for user arguments +" %c for current file under the cursor +" %C for current file under the cursor of inactive pane +" %f for selected file(s) +" %F for selected file(s) of inactive pane +" %b is the same as %f %F +" %d for current directory name +" %D for current directory name of inactive pane +" %r{x} for list of files in register {x} +" %m runs the command in a menu window +" %u uses command's output to build a file list +" see `:help vifm-macros` and `:help vifm-filename-modifiers` for more + +command! df df -h %m 2> /dev/null +command! diff vim -d %f %F +command! zip zip -r %c.zip %f +command! run !! ./%f +command! make !!make %a +command! mkcd :mkdir %a | cd %a +command! vgrep vim "+grep %a" +command! reload :write | restart full + +" ------------------------------------------------------------------------------ +" File types association +" ------------------------------------------------------------------------------ + +" :filetype pattern1,pattern2 defaultprogram,program2 +" :fileviewer pattern1,pattern2 consoleviewer +" +" The first entry is the default program to be used with a matching file. +" The other programs for the file type can be accessed via :file command. +" The command macros like %f, %F, %d, %D may be used in the commands. +" The %a macro is ignored. To use a % you must put %%. +" Spaces in an app name must be escaped, for example: QuickTime\ Player.app + +" For automated FUSE mounts, you must register an extension with :file[x]type +" in one of the following formats: +" +" :filetype patterns FUSE_MOUNT|mount_cmd %SOURCE_FILE %DESTINATION_DIR +" +" %SOURCE_FILE and %DESTINATION_DIR are filled in at runtime. +" +" Example: +" :filetype *.zip,*.[jwe]ar FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR +" +" :filetype patterns FUSE_MOUNT2|mount_cmd %PARAM %DESTINATION_DIR +" +" %PARAM and %DESTINATION_DIR are filled in at runtime. +" +" Example: +" :filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR +" +" %PARAM value is the first line of the matched file, example: root@127.0.0.1:/ +" +" You can also add %CLEAR if you want to clear screen before running FUSE +" program. There is also %FOREGROUND, which is useful for entering passwords. + +" Pdf +filextype {*.pdf}, zathura %c %i &, apvlv %c, xpdf %c +fileviewer {*.pdf}, pdftotext -nopgbrk %c - + +" PostScript +filextype {*.ps,*.eps,*.ps.gz}, + \ {View in zathura} + \ zathura %f, + \ {View in gv} + \ gv %c %i &, + +" Djvu +filextype {*.djvu}, + \ {View in zathura} + \ zathura %f, + \ {View in apvlv} + \ apvlv %f, + +" Audio +filetype {*.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus}, + \