{ pkgs, config, lib, inputs, ... }: let user = config.home.username; mistralAPIKey = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."mistral-api-key".path; in { sops.secrets = { "mistral-api-key" = { }; }; imports = [ ./cmp.nix ./colorizer.nix ./conform.nix ./gitsigns.nix ./harpoon.nix ./lsp.nix ./lualine.nix ./luasnip.nix ./nvim-tree.nix ./surround.nix ./telescope.nix ./treesitter.nix ./fold.nix ./todo-comments.nix ./oil.nix ./comment.nix ]; # Load Plugins that aren't provided as modules by nixvim programs.nixvim.extraPlugins = [ pkgs.vimPlugins.vim-numbertoggle pkgs.vimPlugins.vimwiki pkgs.vimPlugins.vim-dadbod pkgs.vimPlugins.vim-dadbod-ui pkgs.vimPlugins.vim-dadbod-completion pkgs.vimPlugins.fugitive (pkgs.vimUtils.buildVimPlugin { name = "glow.nvim"; src = pkgs.fetchFromGitHub { owner = "ellisonleao"; repo = "glow.nvim"; rev = "238070a"; sha256 = "sha256-GsNcASzVvY0066kak2nvUY5luzanoBclqcUOsODww8g="; }; }) (pkgs.vimUtils.buildVimPlugin { name = "parrot.nvim"; src = pkgs.fetchFromGitHub { owner = "frankroeder"; repo = "parrot.nvim"; rev = "c992483"; sha256 = "sha256-P899qNY/h5LTW0pp3sAmcSDsDGWQedXa20J7EggL7F8="; }; }) (pkgs.vimUtils.buildVimPlugin { name = "buffer_manager.nvim"; src = pkgs.fetchFromGitHub { owner = "j-morano"; repo = "buffer_manager.nvim"; rev = "fd36131"; sha256 = "sha256-abe9ZGmL7U9rC+LxC3LO5/bOn8lHke1FCKO0V3TZGs0="; }; }) (pkgs.vimUtils.buildVimPlugin { name = "vimwiki-sync"; src = pkgs.fetchFromGitHub { owner = "michal-h21"; repo = "vimwiki-sync"; rev = "99eeab3"; sha256 = "sha256-cz0dSFphIbQAI4AOqwIUpDBTuj/3xlOkhSlIVMdgsqM="; }; }) # Keep vim-devicons as last entry pkgs.vimPlugins.vim-devicons ]; programs.nixvim.extraConfigLua = '' -- function to read api key from secrets file local function read_api_key(file_path) local file = io.open(file_path, "r") if file then local api_key = file:read("*all") file:close() return api_key else error("Failed to open file: " .. file_path) end end -- buffer_manager.nvim local opts = {noremap = true} require("buffer_manager").setup( { line_keys = "1234567890", select_menu_item_commands = { edit = { key = "", command = "edit" } }, focus_alternate_buffer = true, short_file_names = false, short_term_names = true, height = 15, width = 0.8, loop_nav = true, highlight = "", win_extra_options = {}, borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, order_buffers = "lastused", show_indicators = "before", } ) require('glow').setup({ border = "shadow", style = "dark", pager = false, width = 80, height = 100, width_ratio = 0.7, height_ratio = 0.7, }) -- Custom color for modified buffers vim.api.nvim_set_hl(0, "BufferManagerModified", { fg = "#988100" }) local bmui = require("buffer_manager.ui") vim.keymap.set('n', 'b', bmui.toggle_quick_menu, opts) vim.keymap.set('n', 'n', bmui.nav_next, opts) vim.keymap.set('n', 'p', bmui.nav_prev, opts) local keys="1234567890" for i = 1, #keys do local key = keys:sub(i,i) vim.keymap.set('n', string.format('%s', key), function () bmui.nav_file(i) end, opts ) end -- Setup vimwiki vim.g.vimwiki_list = { { syntax = "markdown", ext = ".md", path = "/home/${user}/.local/share/notes", }, } -- Format function for conform.nvim vim.api.nvim_create_user_command("Format", function(args) local range = nil if args.count ~= -1 then local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1] range = { start = { args.line1, 0 }, ["end"] = { args.line2, end_line:len() }, } end require("conform").format({ async = true, lsp_format = "fallback", range = range }) end, { range = true }) -- parrot.nvim setup require("parrot").setup { toggle_target = "popup", providers = { mistral = { api_key = read_api_key("${mistralAPIKey}"), params = { chat = { temperature = 0, top_p = 1, max_tokens = 16384 }, command = { temperature = 0, top_p = 1, max_tokens = 16384 }, }, -- api_key = os.getenv "MISTRAL_API_KEY", }, }, hooks = { AskCoder = function(prt, params) local prompt = [[ You are a code assistent. Answer my question carefully and concisely. Answer with code snippets only. Do not give a summary or include any code comments in your response. Never repeate code from a prevous response or write obvious or unnecessary code, instead refer to such code like: "**rest of code here**", or something to that effect. Tokens are expensive, to we need to be very consice. If you uses excessive tokens, then I will send you the invoice to pay the bill. Question: {{command}} ``` ]] prt.ChatNew(params, prompt) end, AskCoderSel = function(parrot, params) local template = [[ You are an expert programmer. Here is a code snippet along with a question. Give me a short, accurate and consice answer. ```{{filetype}} {{selection}} ``` ]] local model_obj = parrot.get_model("command") parrot.logger.info("Asking model: " .. model_obj.name) parrot.Prompt(params, parrot.ui.Target.popup, model_obj, "🤖 Ask ~ ", template) end, GitCommit = function(parrot, params) local template = [[ You are a git commit generator. You will be provided with a git diff file. Your role is to create a concise commit message that outlines all of the most relevant and impactful changes in the diff. You only output a commit message, do not write anything else not related to the commit. Use imperative mood for you writing style. Your message should include a short summary in the first line followed by more detailed descriptions of the changes on subsequent lines. The first line summary should be no more than 70 characters, not end with a period, and a blank line should separate the summary from the body of the message. There should only be 1 summary line, and 1 body with the description. The body should include no more than 3 bullet points with more detailed descriptions of the files and functions that have been modified. Do not output any code. Diff: {{selection}} ]] local model_obj = parrot.get_model("command") parrot.logger.info("Asking model: " .. model_obj.name) parrot.Prompt(params, parrot.ui.Target.popup, model_obj, nil, template) end, } } ''; }