From 5f5daf1047dffa41ba0ef4c92405e0ee128fc18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 10 Mar 2026 20:47:24 +0100 Subject: [PATCH] vim again, and tmux too --- default-machine-config.nix | 2 + hosts/kili/configuration.nix | 4 + no current target | 1 - programs/default.nix | 39 ++------- programs/fish/default.nix | 2 + programs/kitty/default.nix | 6 +- programs/niri/default.nix | 2 +- programs/nvim/config.lua | 132 ++++------------------------- programs/nvim/default.nix | 55 +++++++++++- programs/nvim/editor-hax.py | 119 ++++++++++++++++++++++++++ programs/nvim/keys.nix | 48 ++++------- programs/nvim/options.nix | 4 + programs/nvim/plugins.nix | 44 ++++------ programs/tmux/default.nix | 68 +++++++++++---- programs/xdg.nix | 156 +++++++++++++++++++++++++++++++++++ 15 files changed, 451 insertions(+), 231 deletions(-) delete mode 100644 no current target create mode 100755 programs/nvim/editor-hax.py create mode 100644 programs/xdg.nix diff --git a/default-machine-config.nix b/default-machine-config.nix index 3f05995..913d7f1 100644 --- a/default-machine-config.nix +++ b/default-machine-config.nix @@ -12,6 +12,8 @@ (inputs.self + /programs) ]; + xdg.mime.enable = lib.mkForce false; + system.stateVersion = "26.05"; services.resolved.enable = false; diff --git a/hosts/kili/configuration.nix b/hosts/kili/configuration.nix index 07db5ef..cd5b820 100644 --- a/hosts/kili/configuration.nix +++ b/hosts/kili/configuration.nix @@ -52,6 +52,7 @@ extraGroups = [ "networkmanager" "wheel" + "docker" ]; packages = with pkgs; [ ]; }; @@ -62,6 +63,7 @@ # $ nix search wget environment.systemPackages = with pkgs; [ gcc + docker firefox kitty @@ -93,6 +95,8 @@ rr ]; + virtualisation.docker.enable = true; + services.xserver.enable = true; services.displayManager.gdm.enable = true; services.desktopManager.gnome.enable = true; diff --git a/no current target b/no current target deleted file mode 100644 index 19fa523..0000000 --- a/no current target +++ /dev/null @@ -1 +0,0 @@ -Ptmux;_Ga=d,d=a,q=2\\ \ No newline at end of file diff --git a/programs/default.nix b/programs/default.nix index 5cab805..2d14e5e 100644 --- a/programs/default.nix +++ b/programs/default.nix @@ -1,4 +1,5 @@ -_: { +{ ... }@inputs: +{ imports = [ ./nvim ./fish @@ -10,6 +11,7 @@ _: { ./niri ./zed ./firefox + ./xdg.nix ]; custom.program.graphcial-packages = { @@ -25,6 +27,9 @@ _: { bind.dnsutils mpv vlc + libreoffice-qt + hunspell + hunspellDicts.en_US ]; }; }; @@ -223,36 +228,4 @@ _: { }; }; - custom.program.homedirs = { - home-config = - { config, ... }: - { - home.file = { - "dl".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.download}"; - "doc".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.documents}"; - }; - }; - }; - - custom.program.xdg = { - home-config = - { config, ... }: - { - xdg = { - enable = true; - - configHome = "${config.home.homeDirectory}/.config"; - userDirs = { - enable = true; - documents = "${config.home.homeDirectory}/Documents"; - desktop = "${config.home.homeDirectory}/Documents"; - download = "${config.home.homeDirectory}/Downloads"; - music = "${config.home.homeDirectory}/Documents/personal/music"; - pictures = "${config.home.homeDirectory}/Documents/personal/pictures"; - }; - - mime.enable = true; - }; - }; - }; } diff --git a/programs/fish/default.nix b/programs/fish/default.nix index 1c489c1..ece1740 100644 --- a/programs/fish/default.nix +++ b/programs/fish/default.nix @@ -185,6 +185,8 @@ _: { bind -M insert \cV beginning-of-line bind -M insert \f end-of-line + bind \cl 'clear; commandline -f repaint' + set -g sponge_successful_exit_codes 0 set -g sponge_allow_previously_successful false set -g sponge_delay 10 diff --git a/programs/kitty/default.nix b/programs/kitty/default.nix index 4cff031..05b44c7 100644 --- a/programs/kitty/default.nix +++ b/programs/kitty/default.nix @@ -9,7 +9,7 @@ _: { enable = true; font = { name = "Maple Mono NF"; - size = 13.0; + size = 11.0; package = pkgs.jetbrains-mono; }; @@ -49,6 +49,10 @@ _: { "ctrl+0" = "change_font_size all 0"; # "ctrl+/" = "send_text all "; "super+~" = "no_op"; + + # required for vim!! + # terminals map ctrl+i to tab. I want them to do different things in vim. + "ctrl+i" = "send_text all \\x01"; }; extraConfig = '' diff --git a/programs/niri/default.nix b/programs/niri/default.nix index 8afa33f..04ae0f6 100644 --- a/programs/niri/default.nix +++ b/programs/niri/default.nix @@ -309,7 +309,7 @@ _: { action.spawn = noctalia "sessionMenu toggle"; }; - "Mod+O" = { + "Mod+P" = { hotkey-overlay.title = "Run an Application"; action.spawn = noctalia "launcher toggle"; }; diff --git a/programs/nvim/config.lua b/programs/nvim/config.lua index 0507bae..fa9219b 100644 --- a/programs/nvim/config.lua +++ b/programs/nvim/config.lua @@ -19,134 +19,32 @@ local esc = vim.api.nvim_replace_termcodes( ) local api = require('Comment.api') -vim.keymap.set("n", "", ":lua require('Comment.api').toggle.linewise.current() j", { remap = true }) +vim.keymap.set("n", "", ":lua require('Comment.api').toggle.linewise.current()j", { remap = true }) vim.keymap.set("i", "", ":lua require('Comment.api').toggle.linewise.current()", { remap = true }) vim.keymap.set("x", "", function() vim.api.nvim_feedkeys(esc, 'nx', false) api.toggle.linewise(vim.fn.visualmode()) end, { remap = true }) -vim.keymap.set('n', 'gr', (function() builtin.lsp_references({jump_type="vsplit"}) end), {}) -vim.keymap.set('n', 'gd', (function() builtin.lsp_definitions({jump_type="vsplit"}) end), {}) -vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {}) -local barbar_state = require("barbar.state") -function find_windows_with_buffer(bufnum) - windows = {} - local window_list = vim.api.nvim_list_wins() +-- vim.keymap.set('n', 'gr', (function() builtin.lsp_references({jump_type="vsplit"}) end), {}) +-- vim.keymap.set('n', 'gd', (function() builtin.lsp_definitions({jump_type="vsplit"}) end), {}) +-- vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {}) +-- vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {}) - for _, window in ipairs(window_list) do - local win_info = vim.fn.getwininfo(window) - if win_info ~= nil then - for _, buf in ipairs(win_info) do - if buf.bufnr == bufnum then - table.insert(windows, window) - end - end - end - end - return windows -end - -function num_useful_windows() - local window_list = vim.api.nvim_tabpage_list_wins(0) - local num = 0 - - for _, window in ipairs(window_list) do - local win_info = vim.fn.getwininfo(window) - - if win_info ~= nil then - for _, win_info in ipairs(win_info) do - if buf_is_useful(win_info.bufnr) then - num = num + 1 - end - end - end - end - - return num -end - -function buf_is_useful(bufnr) - local bufname = vim.api.nvim_buf_get_name(bufnr) - - -- if the window's buffer has no name, it's not useful - if bufname == '' then - return false - end - - -- print("bufname: ", bufname) - - -- if the window's buffer is read only, it's not useful - local readonly = vim.api.nvim_buf_get_option(bufnr, 'readonly') - if readonly then - -- print("=readonly") - return false - end - - -- -- if the buffer is not listed, it's not useful - local listed = vim.api.nvim_buf_get_option(bufnr, 'buflisted') - if not listed then - -- print("=unlisted") - return false - end - - local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype') - if buftype == "quickfix" then - -- print("=readonly") - return false - end - - local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) - if #lines > 1 or (#lines == 1 and #lines[1] > 0) then - return true -- If the buffer has content, return false - else - return false - end - - -- the window contains a useful buffer - return true -end - -function quit_window(window) - vim.api.nvim_win_call(window, function() - vim.cmd "quit" - end) -end - -vim.api.nvim_create_user_command('CloseBuffer', function (opts) - if num_useful_windows() > 1 then - vim.cmd { - cmd = "quit", - bang = opts.bang, - } - else - vim.cmd { - cmd = "BufferDelete", - bang = opts.bang, - } - if not buf_is_useful(vim.api.nvim_get_current_buf()) then - vim.cmd { - cmd = "quit", - bang = opts.bang, - } - end - end -end, { desc = "Close Current Buffer", bang = true, }) - -local function close_floating() - for _, win in ipairs(vim.api.nvim_list_wins()) do - local config = vim.api.nvim_win_get_config(win) - if config.relative ~= "" then - vim.api.nvim_win_close(win, false) - end - end -end - -vim.keymap.set("n", "", close_floating, { desc = "Close floats, clear highlights" }) +-- local function close_floating() +-- for _, win in ipairs(vim.api.nvim_list_wins()) do +-- local config = vim.api.nvim_win_get_config(win) +-- if config.relative ~= "" then +-- vim.api.nvim_win_close(win, false) +-- end +-- end +-- end +-- +-- vim.keymap.set("n", "", close_floating, { desc = "Close floats, clear highlights" }) local builtin = require('telescope.builtin') diff --git a/programs/nvim/default.nix b/programs/nvim/default.nix index e733593..b2bfdbf 100644 --- a/programs/nvim/default.nix +++ b/programs/nvim/default.nix @@ -1,15 +1,64 @@ _: { custom.program.nvim.requirements = [ "cli" ]; custom.program.nvim.home-config = - { pkgs, flakes, ... }: { - + pkgs, + flakes, + lib, + ... + }: + let + nvim_mime_types = [ + "application/x-zerosize" + "text/english" + "text/plain" + "text/x-makefile" + "text/x-c++hdr" + "text/x-c++src" + "text/x-chdr" + "text/x-csrc" + "text/x-java" + "text/x-moc" + "text/x-pascal" + "text/x-tcl" + "text/x-tex" + "application/x-shellscript" + "text/x-c" + "text/x-c++" + ]; + desktop-entry-name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanvim"; + desktop-entry = pkgs.makeDesktopItem { + name = desktop-entry-name; + desktopName = "neovim"; + exec = "${./editor-hax.py} %F"; + tryExec = "${./editor-hax.py}"; + terminal = false; + type = "Application"; + categories = [ + "Utility" + "TextEditor" + ]; + icon = "terminal"; + mimeTypes = nvim_mime_types; + }; + in + { home = { sessionVariables = { EDITOR = "nvim"; }; }; + home.file.".local/share/applications/${desktop-entry-name}.desktop" = { + source = "${desktop-entry}/share/applications/${desktop-entry-name}.desktop"; + }; + + xdg.mimeApps.associations.added = lib.mergeAttrsList ( + map (mime: { + ${mime} = [ "${desktop-entry-name}.desktop" ]; + }) nvim_mime_types + ); + imports = [ flakes.nixvim.homeModules.nixvim ./options.nix @@ -98,7 +147,9 @@ _: { # lspconfig.noteslsp.setup{} # '' + (builtins.readFile ./config.lua); + extraConfigLuaPost = '' + ''; }; }; } diff --git a/programs/nvim/editor-hax.py b/programs/nvim/editor-hax.py new file mode 100755 index 0000000..a35f59e --- /dev/null +++ b/programs/nvim/editor-hax.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +import subprocess +import os +import sys +import re +from urllib.parse import urlsplit + +extract_line_regex = re.compile(r"(.*?)(?::([0-9]+))?(?::([0-9]+))?(:)?$") + +main_editor = "nvim" +editors = [main_editor, "vim", "vi"] +real_editor = os.environ.get("REAL_EDITOR", None) +editor_command = main_editor +if real_editor is not None: + editors.append(real_editor) + editor_command = real_editor + +def run(cmd, only_stdout=True): + res = subprocess.run(cmd, capture_output=True, text=True, shell=True) + if only_stdout: + return str(res.stdout) + else: + return res + +def find_pane(window): + for editor in editors: + pane = run(f"tmux list-panes -a -f '#{{&&:#{{==:#{{window_id}},{window}}},#{{==:#{{pane_current_command}},{editor}}}}}' -F '#{{pane_id}}'").strip(); + if pane != "": + return pane + +def create_pane(args): + run(f'tmux split-window -h -P -F "#{{pane_id}}" {editor_command} {args}') + +def find_or_create_pane(window, args): + if pane := find_pane(window): + # exit copy mode so we don't send these commands directly to tmux + run(f"tmux send-keys -t {pane} -X cancel") + # Escape for some reason doesn't get sent as the escape key if it shows up next to any other keys??? + run(f"tmux send-keys -t {pane} Escape") + + # note the space, this tells nvim not to save it in history + run(f"tmux send-keys -t {pane} \": drop {args}\" Enter") + run(f"tmux select-pane -t {pane} -Z") + else: + create_pane(args) + +def split_line(filename): + mtch = extract_line_regex.match(filename) + file = mtch.group(1) + line = mtch.group(2) + column = mtch.group(3) + + url = urlsplit(line) + if url.scheme == "file" and url.path != file: + file = url.path + + file = os.path.abspath(file) + + print(f"opening {file}:{line}:{column}") + return file, line, column + +def join_line(filename, maybe_line, maybe_column): + assert not (maybe_line is None and maybe_column is not None) + + if maybe_line is None: + return filename + + if maybe_column is None: + maybe_column = "0" + + return f"+normal!{maybe_line}G{maybe_column} {filename}" + +def trim(arg): + if arg.startswith("\"") and not arg.endswith("\""): + arg = arg.lstrip("\"") + if arg.endswith("\"") and not arg.startswith("\""): + arg = arg.rstrip("\"") + return arg.strip() + +def editor_hax(filename): + args = split_line(trim(filename)) + current_window = run("tmux display-message -p \"#{window_id}\"").strip(); + find_or_create_pane(current_window, join_line(*args)) + +def xdg_open(arg): + subprocess.run(f"xdg-open {trim(arg)}", shell=True) + +def xdg_open_proxy(*args): + for arg in args: + try: + _file, line, _column = split_line(arg) + if line is not None: + editor_hax(arg) + else: + xdg_open(arg) + except: + xdg_open(arg) + + +def usage(): + print(f"usage: {sys.argv[0]} filename:(line):(column)") + print(" Opens a file with line number and colum in the editor in another pane of the current tmux window") + print(f"usage: {sys.argv[0]} xdg-open-proxy filename:(line):(column)") + print(" Calls xdg-open on the given parameters. However, if any part contains a line number and or column, opens in nvim like editor-hax") + exit(1) + +if __name__ == "__main__": + if len(sys.argv) < 2: + usage() + elif sys.argv[1] == "xdg-open-proxy": + if len(sys.argv) < 3: + usage() + else: + xdg_open_proxy(*sys.argv[1:]) + elif len(sys.argv) > 2: + usage() + else: + editor_hax(sys.argv[1]) + diff --git a/programs/nvim/keys.nix b/programs/nvim/keys.nix index 0080355..679ecbd 100644 --- a/programs/nvim/keys.nix +++ b/programs/nvim/keys.nix @@ -17,39 +17,23 @@ in # splitting (map "n" "s" "vertical sb") - # closing - (map "n" "w" "BufferClose") # single buffer - (map "n" "cb" "BufferClose") # single buffer - - (map "n" "ct" "CloseBuffer") # buffer or extra tab - (map "n" "q" "CloseBuffer") # buffer or extra tab - - (map "n" "co" "silent! BufferCloseAllButVisible") # other buffers - (map "n" "cl" "silent! BufferCloseBuffersLeft") # other buffers (left) - (map "n" "cr" "silent! BufferCloseBuffersRight") # other buffers (right) - - # moving - (map "n" "mL" "BufferMovePrevious") # left - (map "n" "mr" "BufferMoveNext") # right - (map "n" "m0" "BufferMoveStart") # start - (map "n" "m$" "BufferMoveEnd") # end - - (map "n" "jb" "BufferPick") # jump to tab - # jumplist - # (map "n" "" "") - # (map "n" "" "") + (map "" "" "") # note: C-a is actually C-i, remapped through kitty. (luamap "n" "r" "${telescope}.jumplist()") + (luamap "n" "R" "${telescope}.loclist()") # pickers (luamap "n" "" "${telescope}.find_files()") (luamap "n" "f" "${telescope}.live_grep()") (luamap "n" "t" "${telescope}.lsp_document_symbols()") (luamap "n" "T" "${telescope}.lsp_dynamic_workspace_symbols()") + (luamap "n" "/" "${telescope}.current_buffer_fuzzy_find()") # last used pickers/searches - (luamap "n" "h" "${telescope}.pickers()") + (luamap "n" "p" "${telescope}.pickers()") + (luamap "n" "m" "${telescope}.search_history()") # open buffers (luamap "n" "b" "${telescope}.buffers({sort_mru = true})") + (luamap "n" "" "${telescope}.buffers({sort_mru = true})") # diagnostics (map "n" "d" "Trouble diagnostics toggle filter.buf=0") @@ -69,26 +53,25 @@ in # expand macro (map "n" "em" "RustLsp expandMacro") - # easier quitting etc - (map "ca" "W" "w") - (map "ca" "X" "x") - - (map "ca" "Q" "CloseBuffer") - (map "ca" "q" "CloseBuffer") - # navigation (map "" "" "") (map "" "" "") (map "" "" "") (map "" "" "") - (map "" "" "") + (map "" "h" "") + (map "" "l" "") + (map "" "k" "") + (map "" "j" "") + + # close buffer + (map "" "c" "bd") # { # key = "/"; # action = "lua require('spectre').open_file_search({select_word=true})"; # } - (map "n" "t" "Neotree toggle") + # (map "n" "t" "Neotree toggle") # tab for indent/dedent (map "n" "" ">>_") @@ -98,6 +81,9 @@ in (map "v" "" "" = "cmp.mapping.complete()"; "" = "cmp.mapping.confirm({ select = true })"; "" = '' - function() - if cmp.visible_docs() then - cmp.close_docs() + function(fallback) + if cmp.visible() then + if cmp.visible_docs() then + cmp.close_docs() + else + cmp.open_docs() + end else - cmp.open_docs() + fallback() end end ''; @@ -270,7 +269,7 @@ in }; auto-session = { - enable = true; + enable = false; settings = { auto_save_enabled = true; auto_restore_enabled = true; @@ -288,7 +287,7 @@ in }; neo-tree = { - enable = true; + enable = false; settings = { close_if_last_window = true; enable_git_status = false; @@ -660,7 +659,7 @@ in return wilder.renderer_mux({ [':'] = popupmenu_renderer, ['/'] = wildmenu_renderer, - substitute = wildmenu_renderer, + substitute = wildmenu_enderer, }) end)() ''; @@ -695,7 +694,7 @@ in ]; defaults = { path_display = [ "smart" ]; - layout_strategy = "horizontal"; + layout_strategy = "flex"; layout_config = { width = 0.99; height = 0.99; @@ -709,15 +708,6 @@ in enable = true; }; - # tabs - barbar = { - enable = true; - settings = { - options.diagnostics = "nvim_lsp"; - focus_on_close = "previous"; - }; - }; - # for lsp/cmp inside markdown code blocks otter = { enable = true; diff --git a/programs/tmux/default.nix b/programs/tmux/default.nix index 8d18280..dc6d148 100644 --- a/programs/tmux/default.nix +++ b/programs/tmux/default.nix @@ -35,6 +35,8 @@ _: { # unbind every single normal keybinding unbind-key -a + set -g status-left "#{?client_prefix,#[bg=colour2],#[bg=colour1]}#[fg=colour0] #S " + # for special characters to work right # like # set-window-option -g xterm-keys on @@ -93,18 +95,30 @@ _: { bind j select-pane -D bind k select-pane -U bind l select-pane -R + bind Left select-pane -L + bind Down select-pane -D + bind Up select-pane -U + bind Right select-pane -R bind L split-window -h -c "#{pane_current_path}" bind J split-window -v -c "#{pane_current_path}" bind H split-window -h -b -c "#{pane_current_path}" bind K split-window -v -b -c "#{pane_current_path}" + bind S-Left split-window -h -c "#{pane_current_path}" + bind S-Down split-window -v -c "#{pane_current_path}" + bind S-Up split-window -h -b -c "#{pane_current_path}" + bind S-Right split-window -v -b -c "#{pane_current_path}" + bind-key -r -T prefix M-h resize-pane -L 5 + bind-key -r -T prefix M-j resize-pane -D 5 + bind-key -r -T prefix M-k resize-pane -U 5 + bind-key -r -T prefix M-l resize-pane -R 5 bind x swap-pane -D # double-click ^k (or lshift with kanata) for previous pane like ^w in vim bind -r ^k select-pane -l bind-key q confirm-before -p "kill-pane #P? (y/n)" kill-pane - bind-key o choose-tree -wZ - bind-key O choose-tree -sZ + # bind-key o choose-tree -wZ + # bind-key O choose-tree -sZ # get back command mode and some other basics... bind : command-prompt @@ -148,23 +162,41 @@ _: { bind d select-pane -l \; send-keys [ + # f: file search + # unbound: git files + # g: git hashes + # u: urls + # C-d: numbers + # M-i: ips + # include line and column numbers in file search + # rebind `f` so we can reuse it here + bind-key -T prefix C-f command-prompt { find-window -Z "%%" } + # jyn is so sorry, and so am I now + # https://github.com/jyn514/dotfiles/blob/65be3c004113290f41f858f4d7f1a6799fabab19/config/tmux.conf#L203-L212 + # see `search-regex.sh` for wtf this means + # TODO: include shell variable names + bind-key f copy-mode \; send-keys -X search-backward '(^|/|\<|[[:space:]"])((\.|\.\.)|[[:alnum:]~_"-]*)((/[][[:alnum:]_.#$%&+=@"-]+)+([/ "]|\.([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?)|[][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)(:[0-9]+)?)|(/[][[:alnum:]_.#$%&+=@"-]+){2,}([/ "]|\.([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?)|[][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)(:[0-9]+)?)?|(\.|\.\.)/([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?))' + # urls + bind-key u copy-mode \; send-keys -X search-backward '(https?://|git@|git://|ssh://|ftp://|file:///)[[:alnum:]?=%/_.:,;~@!#$&*+-]*' + # hashes + bind-key g copy-mode \; send-keys -X search-backward '[[:<:]]([0-9a-f]{7,40}|[[:alnum:]]{52}|[0-9a-f]{64})[[:>:]]' + # ips + bind-key M-i copy-mode \; send-keys -X search-backward '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' + + bind-key -T copy-mode-vi o send-keys -X copy-pipe \ + 'cd #{pane_current_path}; xargs -I {} echo "echo {}" | bash | xargs ${../nvim/editor-hax.py} xdg-open-proxy' \; \ + if -F "#{alternate_on}" { send-keys -X cancel } + # save the buffer, then open an editor in the current pane + bind-key -T copy-mode-vi O send-keys -X copy-pipe-and-cancel \ + 'tmux send-keys "C-q"; xargs -I {} tmux send-keys "vim {}"; tmux send-keys "C-m"' + # search for the highlighted text + bind-key -T copy-mode-vi s send-keys -X copy-pipe \ + "cd #{pane_current_path}; xargs -I {} open 'https://www.google.com/search?q={}'" \; \ + if -F "#{alternate_on}" { send-keys -X cancel } + # save buffer and retype into the shell + bind-key -T copy-mode-vi Tab send-keys -X copy-selection-and-cancel \; paste-buffer -p + ''; }; - # bind-key -T root DoubleClick1Pane run-shell "cd '#{pane_current_path}'; echo '#{mouse_line}' | ${pkgs.writeScriptBin "open-file" '' - # open_file () { - # input=`cat` - # link=$(echo "$input" | grep -Po '[^ \\]*/[^ \\]*\.[^ \\]*\:[0-9]+' | sed 's/\:/|/g') - # - # if [ ! -z "$link" ]; then - # echo "LINK = $link" - # vim_proc=$(pgrep vim | xargs pwdx | grep $(pwd -P) | awk '{print $1}' | sed 's/\:*$//g' | xargs -I{} find /run/user/1000 -depth -maxdepth 1 -name "nvim.{}.0") - # - # nvim --server "$vim_proc" --remote-send ":e $link" - # fi - # } - # - # open_file 2>&1 >> ~/open-file.log - # - # ''}/bin/open-file" }; } diff --git a/programs/xdg.nix b/programs/xdg.nix new file mode 100644 index 0000000..7339c2a --- /dev/null +++ b/programs/xdg.nix @@ -0,0 +1,156 @@ +{ ... }@inputs: +let + browsers = [ + "firefox.desktop" + ]; + + defaultApps = { + text = [ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanvim.desktop" + ]; + image = [ "org.gnome.Loupe.desktop" ]; + audio = [ "mpv.desktop" ]; + video = [ "mpv.desktop" ]; + directory = [ + "nautilus.desktop" + "org.gnome.Nautilus.desktop" + ]; + mail = [ ] ++ browsers; + calendar = [ ] ++ browsers; + browser = [ ] ++ browsers; + office = [ "libreoffice.desktop" ]; + pdf = [ ] ++ browsers; + ebook = [ ]; + magnet = [ ]; + signal = [ "signal.desktop" ]; + }; + + mimeMap = { + text = [ + "text/plain" + "text/english" + "application/x-zerosize" + "text/x-makefile" + "text/x-c++hdr" + "text/x-c++src" + "text/x-chdr" + "text/x-csrc" + "text/x-java" + "text/x-moc" + "text/x-pascal" + "text/x-tcl" + "text/x-tex" + "application/x-shellscript" + "text/x-c" + "text/x-c++" + ]; + image = [ + "image/bmp" + "image/gif" + "image/jpeg" + "image/jpg" + "image/png" + "image/svg+xml" + "image/tiff" + "image/vnd.microsoft.icon" + "image/webp" + ]; + audio = [ + "audio/aac" + "audio/mpeg" + "audio/ogg" + "audio/opus" + "audio/wav" + "audio/webm" + "audio/x-matroska" + ]; + video = [ + "video/mp2t" + "video/mp4" + "video/mpeg" + "video/ogg" + "video/webm" + "video/x-flv" + "video/x-matroska" + "video/x-msvideo" + ]; + directory = [ "inode/directory" ]; + mail = [ "x-scheme-handler/mailto" ]; + calendar = [ + "text/calendar" + "x-scheme-handler/webcal" + ]; + browser = [ + "text/html" + "x-scheme-handler/about" + "x-scheme-handler/http" + "x-scheme-handler/https" + "x-scheme-handler/unknown" + ]; + office = [ + "application/vnd.oasis.opendocument.text" + "application/vnd.oasis.opendocument.spreadsheet" + "application/vnd.oasis.opendocument.presentation" + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + "application/vnd.openxmlformats-officedocument.presentationml.presentation" + "application/msword" + "application/vnd.ms-excel" + "application/vnd.ms-powerpoint" + "application/rtf" + ]; + pdf = [ "application/pdf" ]; + ebook = [ "application/epub+zip" ]; + magnet = [ "x-scheme-handler/magnet" ]; + signal = [ "signal.desktop" ]; + }; + + associations = + with inputs.lib; + with builtins; + listToAttrs ( + flatten (mapAttrsToList (key: map (type: attrsets.nameValuePair type defaultApps."${key}")) mimeMap) + ); + removedAssociations = { + "text/plain" = "dev.zed.Zed.desktop"; + "application/x-zerosize" = "dev.zed.Zed.desktop"; + }; +in +{ + custom.program.homedirs = { + home-config = + { config, ... }: + { + xdg = { + enable = true; + mime.enable = true; + configHome = "${config.home.homeDirectory}/.config"; + userDirs = { + enable = true; + documents = "${config.home.homeDirectory}/Documents"; + desktop = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + music = "${config.home.homeDirectory}/Documents/personal/music"; + pictures = "${config.home.homeDirectory}/Documents/personal/pictures"; + }; + configFile."mimeapps.list".force = true; + mimeApps = { + enable = true; + associations.added = associations; + associations.removed = removedAssociations; + defaultApplications = associations; + }; + }; + }; + }; + + xdg = { + mime = { + enable = true; + defaultApplications = associations; + addedAssociations = associations; + inherit removedAssociations; + }; + }; + +}