Merge main

This commit is contained in:
Patrick Stevens
2024-10-19 22:30:32 +01:00
20 changed files with 1007 additions and 346 deletions

View File

@@ -1,6 +1,8 @@
{
pkgs,
config,
username,
dotnet,
...
}: {
nixpkgs.config.allowUnfree = true;
@@ -8,6 +10,23 @@
../hardware/capybara.nix
];
hardware.graphics = {
enable = true;
};
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
modesetting.enable = true;
powerManagement.enable = false;
# I don't have a Turing GPU
powerManagement.finegrained = false;
open = false;
nvidiaSettings = true;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.useOSProber = true;
@@ -38,16 +57,16 @@
};
environment.systemPackages = [
pkgs.git
pkgs.vim
pkgs.wget
pkgs.tmux
pkgs.home-manager
pkgs.firefox
pkgs.steam-run
];
environment.loginShellInit = ''
[[ "$(tty)" == /dev/tty1 ]] && sway
[[ "$(tty)" == /dev/tty1 ]] && sway --unsupported-gpu
'';
services.openssh.enable = true;

View File

@@ -1,5 +1,6 @@
{
nixpkgs,
machinename,
username,
mbsync,
dotnet,
@@ -58,7 +59,12 @@
extraConfig = {
commit.gpgsign = true;
gpg.program = "${nixpkgs.gnupg}/bin/gpg";
user.signingkey = "7C97D679CF3BC4F9";
user.signingkey =
if machinename == "darwin" || machinename == "earthworm"
then "7C97D679CF3BC4F9"
else if machinename == "capybara"
then "AE90453E879DBCFA"
else throw "unrecognised machine name!";
core = {
autocrlf = "input";
};
@@ -129,6 +135,15 @@
in {
enable = true;
plugins = [
{
plugin = nixpkgs.vimPlugins.nvim-web-devicons;
}
{
plugin = nixpkgs.vimPlugins.mini-nvim;
}
{
plugin = nixpkgs.vimPlugins.satellite-nvim;
}
{
plugin = nixpkgs.vimPlugins.nvim-lightbulb;
type = "lua";
@@ -235,6 +250,7 @@
vimdiffAlias = true;
withPython3 = true;
extraPython3Packages = ps: [
ps.pip
ps.pynvim
ps.pynvim-pp
ps.pyyaml
@@ -242,56 +258,78 @@
];
withRuby = true;
extraLuaConfig = builtins.readFile ./nvim/build-utils.lua + "\n" + builtins.readFile ./nvim/dotnet.lua + "\n" + builtins.readFile ./nvim/init.lua + "\n" + builtins.readFile ./nvim/python.lua;
extraLuaConfig = builtins.readFile ./nvim/build-utils.lua + "\n" + (builtins.replaceStrings ["_CURL_"] ["${nixpkgs.curl}/bin/curl"] (builtins.readFile ./nvim/dotnet.lua)) + "\n" + builtins.readFile ./nvim/init.lua + "\n" + builtins.readFile ./nvim/python.lua;
};
home.packages = [
nixpkgs.difftastic
nixpkgs.syncthing
nixpkgs.nodePackages_latest.dockerfile-language-server-nodejs
nixpkgs.nodePackages_latest.bash-language-server
nixpkgs.nodePackages_latest.vscode-json-languageserver
nixpkgs.nodePackages_latest.vscode-langservers-extracted
nixpkgs.hadolint
nixpkgs.ltex-ls
nixpkgs.yaml-language-server
nixpkgs.csharp-ls
nixpkgs.netcoredbg
nixpkgs.nil
nixpkgs.fsautocomplete
nixpkgs.keepassxc
nixpkgs.wget
nixpkgs.yt-dlp
nixpkgs.cmake
nixpkgs.gnumake
nixpkgs.gcc
nixpkgs.lldb
nixpkgs.hledger
nixpkgs.hledger-web
dotnet
nixpkgs.jitsi-meet
nixpkgs.elan
nixpkgs.coreutils-prefixed
nixpkgs.shellcheck
nixpkgs.universal-ctags
nixpkgs.asciinema
nixpkgs.git-lfs
nixpkgs.imagemagick
nixpkgs.nixpkgs-fmt
nixpkgs.lnav
nixpkgs.age
nixpkgs.nodejs
nixpkgs.nodePackages.pyright
nixpkgs.woodpecker-agent
nixpkgs.lynx
nixpkgs.alejandra
nixpkgs.ffmpeg
nixpkgs.bat
nixpkgs.pandoc
nixpkgs.fd
nixpkgs.sumneko-lua-language-server
nixpkgs.gnupg
];
home.packages =
[
nixpkgs.jq
nixpkgs.difftastic
nixpkgs.syncthing
nixpkgs.nodePackages_latest.dockerfile-language-server-nodejs
nixpkgs.nodePackages_latest.bash-language-server
nixpkgs.nodePackages_latest.vscode-json-languageserver
nixpkgs.nodePackages_latest.vscode-langservers-extracted
nixpkgs.hadolint
nixpkgs.yaml-language-server
nixpkgs.csharp-ls
nixpkgs.netcoredbg
nixpkgs.nil
nixpkgs.fsautocomplete
nixpkgs.keepassxc
nixpkgs.wget
nixpkgs.yt-dlp
nixpkgs.cmake
nixpkgs.gnumake
nixpkgs.gcc
nixpkgs.lldb
nixpkgs.hledger
nixpkgs.hledger-web
dotnet
nixpkgs.elan
nixpkgs.coreutils-prefixed
nixpkgs.shellcheck
nixpkgs.universal-ctags
nixpkgs.asciinema
nixpkgs.git-lfs
nixpkgs.imagemagick
nixpkgs.nixpkgs-fmt
nixpkgs.lnav
nixpkgs.age
nixpkgs.nodejs
nixpkgs.pyright
nixpkgs.woodpecker-agent
nixpkgs.lynx
nixpkgs.alejandra
nixpkgs.ffmpeg
nixpkgs.bat
nixpkgs.pandoc
nixpkgs.fd
nixpkgs.sumneko-lua-language-server
nixpkgs.gnupg
nixpkgs.gh
nixpkgs.clang-tools
nixpkgs.deno
nixpkgs.yazi
]
++ (
if nixpkgs.stdenv.isLinux
then [
nixpkgs.protonmail-bridge
nixpkgs.pinentry
nixpkgs.signal-desktop
]
else []
)
++ (
if machinename == "capybara"
then [
nixpkgs.steam-run
nixpkgs.discord
nixpkgs.anki-bin
]
else []
);
home.file.".ideavimrc".source = ./ideavimrc;
home.file.".config/yt-dlp/config".source = ./youtube-dl.conf;

View File

@@ -4,7 +4,7 @@
dotnet,
...
}: {
home.packages = [nixpkgs.firefox-wayland nixpkgs.wl-clipboard];
home.packages = [nixpkgs.firefox-wayland nixpkgs.wl-clipboard nixpkgs.jetbrains.rider];
nixpkgs.config.firefox = {
speechSynthesisSupport = true;
};
@@ -22,6 +22,11 @@
'';
};
services.gpg-agent = {
enable = nixpkgs.stdenv.isLinux;
pinentryPackage = nixpkgs.pinentry-qt;
};
services.swayidle = {enable = true;};
services.cbatticon = {
lowLevelPercent = 20;

View File

@@ -75,7 +75,7 @@ in {
# Run `./mail/mutt-oauth2.py /path/to/secret --authorize --verbose` once manually,
# and that will populate /path/to/secret.
# I've left it unencrypted here; the original uses GPG to store it encrypted at rest.
passwordCommand = ''${pkgs.python3}/bin/python ${./mail/mutt-oauth2.py} ${secretsPath}/gmail.txt'';
passwordCommand = ''${pkgs.python3}/bin/python ${./mail/mutt-oauth2.py} ${secretsPath}/gmail.txt 2>/tmp/gmail-passcmd.2.txt'';
realName = "Patrick Stevens";
};
@@ -149,7 +149,10 @@ in {
port = 1025; # 8126; if using hydroxide
tls = {enable = false;};
};
userName = address;
userName =
if pkgs.stdenv.isLinux
then builtins.head (pkgs.lib.strings.splitString "@" address)
else address;
};
programs.mbsync = {

View File

@@ -73,13 +73,14 @@ function RegisterSolution(sln_path)
end
local whichkey = require("which-key")
whichkey.register({
s = {
name = ".NET solution",
b = { BuildDotNetSolution, "Build .NET solution" },
t = { TestDotNetSolution, "Test .NET solution" },
whichkey.add({
{
"<localleader>s",
desc = ".NET solution",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
{ "<localleader>sb", BuildDotNetSolution, desc = "Build .NET solution" },
{ "<localleader>st", TestDotNetSolution, desc = "Test .NET solution" },
}, { buffer = vim.api.nvim_get_current_buf() })
end
local function find_nearest_slns()
@@ -153,8 +154,612 @@ vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, {
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "fsharp", "cs" },
pattern = { "fsharp", "cs", "fsharp_project" },
callback = function()
FindAndRegisterSolution(false)
end,
})
-- For what I'm sure are reasons, Lua appears to have nothing in its standard library
---@generic K
---@generic V1
---@generic V2
---@param tbl table<K, V1>
---@param f fun(V1): V2
---@return table<K, V2>
local function map(tbl, f)
local t = {}
for k, v in pairs(tbl) do
t[k] = f(v)
end
return t
end
---@generic K
---@generic V
---@param tbl table<K, V>
---@param f fun(V1): nil
local function iter(tbl, f)
for _, v in pairs(tbl) do
f(v)
end
end
---@generic K
---@generic V
---@param tbl table<K, V>
---@param predicate fun(V): boolean
---@return boolean, V
local function find(tbl, predicate)
for _, v in pairs(tbl) do
if predicate(v) then
return true, v
end
end
return false, nil
end
---@class (exact) NuGetVersion
---@field major number
---@field minor number
---@field patch number
---@field suffix? string
local NuGetVersion = {}
---@param v NuGetVersion
---@nodiscard
---@return string
local function nuGetVersionToString(v)
local s = tostring(v.major) .. "." .. tostring(v.minor) .. "." .. tostring(v.patch)
if v.suffix then
return s .. v.suffix
else
return s
end
end
local function get_all_variables()
local variables = {}
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for _, line in ipairs(lines) do
local var_name, var_value = line:match("<(%w+)>([^<]+)</(%w+)>")
if var_name and var_value then
variables[var_name] = var_value
end
end
return variables
end
local function resolve_variable(version, variables)
if version:match("^%$%((.+)%)$") then
local var_name = version:match("^%$%((.+)%)$")
return variables[var_name] or nil
end
return nil
end
---@param v string
---@nodiscard
---@return NuGetVersion
local function parse_version(v)
local variables = get_all_variables()
local major, minor, patch, pre = v:match("(%d+)%.(%d+)%.(%d+)(.*)$")
if major == nil then
local resolved = resolve_variable(v, variables)
if resolved ~= nil then
return parse_version(resolved)
end
end
-- TODO: why does this type-check if you remove the field names?
return {
major = tonumber(major) or 0,
minor = tonumber(minor) or 0,
patch = tonumber(patch) or 0,
suffix = pre or nil,
}
end
---@param a NuGetVersion
---@param b NuGetVersion
---@nodiscard
---@return boolean
local function compare_versions(a, b)
if a.major ~= b.major then
return a.major < b.major
elseif a.minor ~= b.minor then
return a.minor < b.minor
elseif a.patch ~= b.patch then
return a.patch < b.patch
elseif a.suffix and not b.suffix then
return false
elseif not a.suffix and b.suffix then
return true
else
return a.suffix < b.suffix
end
end
---@param url string
---@nodiscard
local function curl_sync(url)
local command = string.format("_CURL_ --silent --compressed --fail '%s'", url)
local response = vim.fn.system(command)
if vim.v.shell_error ~= 0 then
print("Failed to fetch " .. url)
return nil
end
local success, decoded = pcall(vim.fn.json_decode, response)
if not success then
print("Failed to decode JSON from curl at " .. url)
return nil
end
return decoded
end
---@param url string
---@param callback fun(table): nil
---@return nil
local function curl(url, callback)
local stdout = vim.uv.new_pipe(false)
local stdout_text = ""
local handle
handle, _ = vim.uv.spawn(
"_CURL_",
{ args = { "--silent", "--compressed", "--fail", url }, stdio = { nil, stdout, nil } },
vim.schedule_wrap(function(code, _)
stdout:read_stop()
stdout:close()
if handle and not handle:is_closing() then
handle:close()
end
if code ~= 0 then
print("Failed to fetch " .. url)
end
local success, decoded = pcall(vim.fn.json_decode, stdout_text)
if not success then
print("Failed to decode JSON from curl at " .. url .. "\n" .. stdout_text)
end
callback(decoded)
end)
)
vim.uv.read_start(stdout, function(err, data)
assert(not err, err)
if data then
stdout_text = stdout_text .. data
end
end)
end
local _nugetIndex
local _packageBaseAddress
---@param callback fun(): nil
local function populate_nuget_api(callback)
if _nugetIndex ~= nil then
callback()
end
local url = string.format("https://api.nuget.org/v3/index.json")
local function handle(decoded)
local default_nuget_reg = "https://api.nuget.org/v3/registration5-semver1/"
local default_base_address = "https://api.nuget.org/v3-flatcontainer/"
if not decoded then
print("Failed to fetch NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
_packageBaseAddress = default_base_address
else
local resources = decoded["resources"]
if resources == nil then
print("Failed to parse: " .. decoded .. tostring(decoded))
for k, v in pairs(decoded) do
print(k .. ": " .. tostring(v))
end
callback()
return
end
local resourceSuccess, regUrl = find(resources, function(o)
return o["@type"] == "RegistrationsBaseUrl/3.6.0"
end)
if not resourceSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
else
_nugetIndex = regUrl["@id"]
end
local baseAddrSuccess, baseAddrUrl = find(resources, function(o)
return o["@type"] == "PackageBaseAddress/3.0.0"
end)
if not baseAddrSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_packageBaseAddress = default_base_address
else
_packageBaseAddress = baseAddrUrl["@id"]
end
end
callback()
end
curl(url, handle)
end
---@return nil
local function populate_nuget_api_sync()
if _nugetIndex ~= nil then
return
end
local url = string.format("https://api.nuget.org/v3/index.json")
local decoded = curl_sync(url)
local default_nuget_reg = "https://api.nuget.org/v3/registration5-semver1/"
local default_base_address = "https://api.nuget.org/v3-flatcontainer/"
if not decoded then
print("Failed to fetch NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
_packageBaseAddress = default_base_address
else
local resources = decoded["resources"]
local resourceSuccess, regUrl = find(resources, function(o)
return o["@type"] == "RegistrationsBaseUrl/3.6.0"
end)
if not resourceSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
else
_nugetIndex = regUrl["@id"]
end
local baseAddrSuccess, baseAddrUrl = find(resources, function(o)
return o["@type"] == "PackageBaseAddress/3.0.0"
end)
if not baseAddrSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_packageBaseAddress = default_base_address
else
_packageBaseAddress = baseAddrUrl["@id"]
end
end
end
---@return nil
---@param callback fun(nugetIndex: string): nil
local function get_nuget_index(callback)
populate_nuget_api(function()
callback(_nugetIndex)
end)
end
---@return nil
---@param callback fun(packageBaseIndex: string): nil
local function get_package_base_addr(callback)
populate_nuget_api(function()
callback(_packageBaseAddress)
end)
end
---@return string
local function get_package_base_addr_sync()
populate_nuget_api_sync()
return _packageBaseAddress
end
local _package_versions_cache = {}
---@param package_name string
---@return NuGetVersion[]
local function get_package_versions_sync(package_name)
if _package_versions_cache[package_name] ~= nil then
return _package_versions_cache[package_name]
end
local base = get_package_base_addr_sync()
local url = base .. string.format("%s/index.json", package_name:lower())
local decoded = curl_sync(url)
if not decoded then
print("Failed to fetch package versions")
return {}
end
local versions = map(decoded.versions, parse_version)
table.sort(versions, function(a, b)
return compare_versions(b, a)
end)
_package_versions_cache[package_name] = versions
return versions
end
---@param package_name string
---@param callback fun(v: NuGetVersion[]): nil
---@return nil
local function get_package_versions(package_name, callback)
if _package_versions_cache[package_name] ~= nil then
callback(_package_versions_cache[package_name])
end
local function handle(base)
local url = base .. string.format("%s/index.json", package_name:lower())
local function handle2(decoded)
if not decoded then
print("Failed to fetch package versions")
callback({})
end
local versions = map(decoded.versions, parse_version)
table.sort(versions, function(a, b)
return compare_versions(b, a)
end)
_package_versions_cache[package_name] = versions
callback(versions)
end
curl(url, handle2)
end
get_package_base_addr(handle)
end
---@param version NuGetVersion
---@return nil
local function update_package_version(version)
local line = vim.api.nvim_get_current_line()
local new_line = line:gsub('Version="[^"]+"', string.format('Version="%s"', nuGetVersionToString(version)))
vim.api.nvim_set_current_line(new_line)
end
-- A map from package to { packageWeDependOn: version }.
--- @type table<string, table<string, string>>
local _package_dependency_cache = {}
---@param package_name string
---@param version NuGetVersion
---@param callback fun(result: table<string, string>): nil
---@return nil
local function get_package_dependencies(package_name, version, callback)
local key = package_name .. "@" .. nuGetVersionToString(version)
local cache_hit = _package_dependency_cache[key]
if cache_hit ~= nil then
callback(cache_hit)
return
end
local function handle1(index)
local url = index .. string.format("%s/%s.json", package_name:lower(), nuGetVersionToString(version):lower())
local function handle(response)
if not response then
print(
"Failed to get dependencies of "
.. package_name
.. " at version "
.. version
.. " : unsuccessful response to "
.. url
)
return
end
local entry_url = response["catalogEntry"]
local function handle2(catalog_entry)
if not catalog_entry then
print(
"Failed to get dependencies of "
.. package_name
.. " at version "
.. version
.. " : unsuccessful response to "
.. entry_url
)
return
end
local result = {}
if catalog_entry["dependencyGroups"] then
iter(catalog_entry["dependencyGroups"], function(grp)
if grp["dependencies"] then
for _, dep in pairs(grp["dependencies"]) do
result[dep["id"]] = dep["range"]
end
end
end)
end
_package_dependency_cache[key] = result
callback(result)
end
curl(entry_url, handle2)
end
curl(url, handle)
end
get_nuget_index(handle1)
end
---@return table<string, NuGetVersion>
---@nodiscard
local function get_all_package_references()
local packages = {}
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for _, line in ipairs(lines) do
local package_name = line:match('PackageReference Include="([^"]+)"')
or line:match('PackageReference Update="([^"]+)"')
local version = line:match('Version="([^"]+)"')
if package_name and version then
if not packages[package_name] then
packages[package_name] = {}
end
table.insert(packages[package_name], parse_version(version))
end
end
return packages
end
function ClearNuGetDependencyCache()
for k, _ in pairs(_package_dependency_cache) do
_package_dependency_cache[k] = nil
end
end
vim.api.nvim_create_user_command("ClearNuGetDependencyCache", ClearNuGetDependencyCache, {})
function PrintNuGetDependencyCache()
for k, v in pairs(_package_dependency_cache) do
print(k .. ":")
for dep, ver in pairs(v) do
print(" " .. dep .. ": " .. ver)
end
end
end
vim.api.nvim_create_user_command("PrintNuGetDependencyCache", PrintNuGetDependencyCache, {})
local function prefetch_dependencies()
local packages = get_all_package_references()
local function process_package(package_name, versions, callback)
local count = #versions
for _, version in ipairs(versions) do
vim.schedule(function()
get_package_dependencies(package_name, version, function(_)
count = count - 1
if count == 0 then
callback()
end
end)
end)
end
end
local total_packages = 0
for _ in pairs(packages) do
total_packages = total_packages + 1
end
local processed_packages = 0
for package_name, versions in pairs(packages) do
process_package(package_name, versions, function()
local function handle(package_versions)
if package_versions then
process_package(package_name, package_versions, function()
processed_packages = processed_packages + 1
if processed_packages == total_packages then
print("All dependencies prefetched")
end
end)
else
processed_packages = processed_packages + 1
if processed_packages == total_packages then
print("All dependencies prefetched")
end
end
end
get_package_versions(package_name, handle)
end)
end
end
---@param v1 NuGetVersion
---@param v2 NuGetVersion
---@return boolean
---@nodiscard
local function nuget_versions_equal(v1, v2)
return v1.major == v2.major and v1.minor == v2.minor and v1.patch == v2.patch and v1.suffix == v2.suffix
end
vim.api.nvim_create_autocmd("FileType", {
pattern = { "fsharp_project", "csharp_project", "xml" },
callback = function()
function UpdateNuGetVersion()
local line = vim.api.nvim_get_current_line()
local package_name = line:match('PackageReference Include="([^"]+)"')
or line:match('PackageReference Update="([^"]+)"')
if not package_name then
print("No package reference found on the current line")
return
end
local current_version = parse_version(line:match('Version="([^"]+)"'))
if not current_version then
print("oh no!")
end
local package_versions = get_package_versions_sync(package_name)
if #package_versions == 0 then
print("No versions found for the package")
return
end
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local previewers = require("telescope.previewers")
pickers
.new({}, {
prompt_title = string.format("Select version for %s", package_name),
finder = finders.new_table({
results = package_versions,
entry_maker = function(entry)
local val = nuGetVersionToString(entry)
local display_value = val
if current_version and nuget_versions_equal(entry, current_version) then
display_value = "[CURRENT] " .. val
end
return {
value = entry,
display = display_value,
ordinal = entry,
}
end,
}),
previewer = previewers.new_buffer_previewer({
define_preview = function(self, entry, _)
local bufnr = self.state.bufnr
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "Loading..." })
get_package_dependencies(package_name, entry.value, function(package_dependencies)
if not package_dependencies then
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "No dependencies found" })
return
end
local display = {}
table.insert(
display,
"Dependencies for "
.. package_name
.. " at version "
.. nuGetVersionToString(entry.value)
.. ":"
)
for dep, range in pairs(package_dependencies) do
table.insert(display, dep .. ": " .. range)
end
local ok, err = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, display)
if not ok then
-- If we can't set lines, the window's probably gone. Ignore.
return
end
end)
end,
}),
attach_mappings = function(_, mapping)
mapping("i", "<CR>", function(prompt_bufnr)
local selection = require("telescope.actions.state").get_selected_entry()
require("telescope.actions").close(prompt_bufnr)
update_package_version(selection.value)
end)
return true
end,
})
:find()
end
local whichkey = require("which-key")
whichkey.add({
{ "<localleader>n", desc = "NuGet" },
{ "<localleader>nu", UpdateNuGetVersion, desc = "Upgrade NuGet versions" },
}, { buffer = vim.api.nvim_get_current_buf() })
vim.schedule(prefetch_dependencies)
end,
})

View File

@@ -169,8 +169,6 @@ function DisplayAllMappingsWithTelescope()
local function accumulate(tree)
tree:walk(function(node)
-- Note: we could (if desired) view all groups, because the `node.mapping` table looks like this:
-- { prefix = "g", group = true, keys = {...}}
if node.mapping then
local mapping = node.mapping
if not mapping.group then
@@ -224,73 +222,69 @@ function ToggleSpell()
vim.cmd("setlocal spell!")
end
whichkey.register({
[vim.api.nvim_get_var("maplocalleader")] = {
DisplayAllMappingsWithTelescope,
"View all mappings",
whichkey.add({
{
"<localleader><localleader>",
function()
require("which-key").show({ global = false })
end,
desc = "View all mappings",
},
m = {
p = { MarkdownPreview, "Preview Markdown in Lynx" },
d = { RemoveCarriageReturn, "Delete carriage returns from file" },
},
["j"] = {
FormatJson,
"Auto-format JSON",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.register({
g = {
{ "<localleader>mp", MarkdownPreview, desc = "Preview Markdown in Lynx" },
{ "<localleader>md", RemoveCarriageReturn, desc = "Delete carriage returns from file" },
{ "<localleader>j", FormatJson, desc = "Auto-format JSON" },
})
whichkey.add({
{
"<leader>g",
function()
require("telescope.builtin").grep_string()
end,
"Find instances of text under cursor",
desc = "Find instances of text under cursor",
},
h = {
name = "Find historical...",
f = {
function()
require("telescope.builtin").oldfiles()
end,
"List previously open files",
},
c = {
function()
require("telescope.builtin").command_history()
end,
"List previously run commands",
},
s = {
function()
require("telescope.builtin").search_history()
end,
"List previously run searches",
},
{ "<leader>h", desc = "Find historical..." },
{
"<leader>hf",
function()
require("telescope.builtin").oldfiles()
end,
desc = "List previously open files",
},
m = {
{
"<leader>hc",
function()
require("telescope.builtin").command_history()
end,
desc = "List previously run commands",
},
{
"<leader>hs",
function()
require("telescope.builtin").search_history()
end,
desc = "List previously run searches",
},
{
"<leader>m",
function()
require("telescope.builtin").marks()
end,
"List marks",
desc = "List marks",
},
["cd"] = {
ChangeToCurrentDirectory,
"Switch CWD to the directory of the open buffer",
},
["ss"] = {
ToggleSpell,
"Toggle spell-checker on or off",
},
[vim.api.nvim_get_var("mapleader")] = {
{ "<leader>cd", ChangeToCurrentDirectory, desc = "Switch CWD to the directory of the open buffer" },
{ "<leader>ss", ToggleSpell, desc = "Toggle spell-checker on or off" },
{
"<leader><leader>",
function()
require("telescope.builtin").find_files()
end,
"Find files by name",
desc = "Find files by name",
},
}, { prefix = vim.api.nvim_get_var("mapleader") })
vim.api.nvim_create_autocmd({"BufRead","BufNewFile"}, {
pattern = {"Directory.Build.props", "*.fsproj", "*.csproj"},
callback = function()
vim.bo.filetype = "xml"
end,
})
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = { "Directory.Build.props", "*.fsproj", "*.csproj" },
callback = function()
vim.bo.filetype = "xml"
end,
})

View File

@@ -59,7 +59,7 @@ local function BuildFSharpProjects(projects)
end
if not projects then
projects = vim.fn['fsharp#getLoadedProjects']()
projects = vim.fn["fsharp#getLoadedProjects"]()
end
if projects then
local total_projects = 0
@@ -90,7 +90,7 @@ vim.api.nvim_create_user_command("BuildFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = vim.fn['fsharp#getLoadedProjects'](),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -156,7 +156,7 @@ vim.api.nvim_create_user_command("RunFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = vim.fn['fsharp#getLoadedProjects'](),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -185,7 +185,7 @@ vim.api.nvim_create_user_command("PublishFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = vim.fn['fsharp#getLoadedProjects'](),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -206,28 +206,19 @@ vim.api.nvim_create_autocmd("FileType", {
callback = function()
local status, whichkey = pcall(require, "which-key")
if status then
whichkey.register({
f = {
name = "F#",
t = { ":call fsharp#showTooltip()<CR>", "Show F# Tooltip" },
["si"] = { ":call fsharp#toggleFsi()<CR>", "Toggle FSI (F# Interactive)" },
["sl"] = { ":call fsharp#sendLineToFsi()<cr>", "Send line to FSI (F# Interactive)" },
r = {
name = "Run F# project",
d = { ":RunFSharpProject Debug", "Run F# project in debug configuration" },
r = { ":RunFSharpProject Release", "Run F# project in release configuration" },
},
p = {
":PublishFSharpProject",
"Publish F# project",
},
b = {
"Build F# project",
a = { BuildFSharpProjects, "Build all projects" },
s = { ":BuildFSharpProject", "Build specified project" },
},
},
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
whichkey.add({
{ "<localleader>f", desc = "F#" },
{ "<localleader>ft", ":call fsharp#showTooltip()<CR>", desc = "Show F# Tooltip" },
{ "<localleader>fsi", ":call fsharp#toggleFsi()<CR>", desc = "Toggle FSI (F# Interactive)" },
{ "<localleader>fsl", ":call fsharp#sendLineToFsi()<cr>", desc = "Send line to FSI (F# Interactive)" },
{ "<localleader>fr", desc = "Run F# project" },
{ "<localleader>frd", ":RunFSharpProject Debug", desc = "Run F# project in debug configuration" },
{ "<localleader>frr", ":RunFSharpProject Release", desc = "Run F# project in release configuration" },
{ "<localleader>fp", ":PublishFSharpProject", desc = "Publish F# project" },
{ "<localleader>fb", desc = "Build F# project" },
{ "<localleader>fba", BuildFSharpProjects, desc = "Build all projects" },
{ "<localleader>fbs", ":BuildFSharpProject", desc = "Build specified project" },
}, { buffer = vim.api.nvim_get_current_buf() })
else
vim.api.nvim_set_keymap("n", "<localleader>ft", ":call fsharp#showTooltip()<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<localleader>fsi", ":call fsharp#toggleFsi()<CR>", { noremap = true })

View File

@@ -2,16 +2,16 @@ require("lspconfig")["leanls"].setup({})
require("lean").setup({})
require("which-key").register({
l = {
i = { "<Cmd>LeanInfoviewToggle<CR>", "Toggle Lean info view" },
p = { "<Cmd>LeanInfoviewPinTogglePause<CR>", "Pause Lean info view" },
s = { "<Cmd>LeanSorryFill<CR>", "Fill open goals with sorry" },
w = { "<Cmd>LeanInfoviewEnableWidgets<CR>", "Enable Lean widgets" },
W = { "<Cmd>LeanInfoviewDisableWidgets<CR>", "Disable Lean widgets" },
["?"] = {
"<Cmd>LeanAbbreviationsReverseLookup<CR>",
"Show what Lean abbreviation produces the symbol under the cursor",
},
require("which-key").add({
{ "<localleader>l", desc = "Lean" },
{ "<localleader>li", "<Cmd>LeanInfoviewToggle<CR>", desc = "Toggle Lean info view" },
{ "<localleader>lp", "<Cmd>LeanInfoviewPinTogglePause<CR>", desc = "Pause Lean info view" },
{ "<localleader>ls", "<Cmd>LeanSorryFill<CR>", desc = "Fill open goals with sorry" },
{ "<localleader>lw", "<Cmd>LeanInfoviewEnableWidgets<CR>", desc = "Enable Lean widgets" },
{ "<localleader>lW", "<Cmd>LeanInfoviewDisableWidgets<CR>", desc = "Disable Lean widgets" },
{
"<localleader>l?",
"<Cmd>LeanAbbreviationsReverseLookup<CR>",
desc = "Show what Lean abbreviation produces the symbol under the cursor",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
})

View File

@@ -13,6 +13,8 @@ local schemas = {
["https://json.schemastore.org/dotnet-tools.json"] = "dotnet-tools.json",
}
require("lspconfig")["clangd"].setup({})
require("lspconfig")["yamlls"].setup({
settings = {
yaml = {
@@ -41,15 +43,18 @@ require("lspconfig")["jsonls"].setup({
},
})
require("lspconfig")["denols"].setup({})
require("lspconfig")["bashls"].setup({})
require("lspconfig")["dockerls"].setup({})
require("lspconfig")["html"].setup({
capabilities = capabilities,
})
require("lspconfig")["ltex"].setup({})
require("lspconfig")["lua_ls"].setup({
on_init = function(client)
if not client.workspace_folders then
return
end
local path = client.workspace_folders[1].name
if vim.uv.fs_stat(path .. "/.luarc.json") or vim.loop.fs_stat(path .. "/.luarc.jsonc") then
return
@@ -116,15 +121,13 @@ end
do
local whichkey_status, whichkey = pcall(require, "which-key")
if whichkey_status then
whichkey.register({
l = {
name = "loclist-related commands",
p = { vim.diagnostic.goto_prev, "Go to previous entry in loclist" },
n = { vim.diagnostic.goto_next, "Go to next entry in loclist" },
l = { ToggleLocList, "Toggle loclist" },
f = { vim.diagnostic.open_float, "Open current loclist entry in floating window" },
},
}, { prefix = vim.api.nvim_get_var("mapleader") })
whichkey.add({
{ "<leader>l", desc = "loclist-related commands" },
{ "<leader>lp", vim.diagnostic.goto_prev, desc = "Go to previous entry in loclist" },
{ "<leader>ln", vim.diagnostic.goto_next, desc = "Go to next entry in loclist" },
{ "<leader>ll", ToggleLocList, desc = "Toggle loclist" },
{ "<leader>lf", vim.diagnostic.open_float, desc = "Open current loclist entry in floating window" },
})
else
vim.keymap.set("n", "<leader>lp", vim.diagnostic.goto_prev)
vim.keymap.set("n", "<leader>ln", vim.diagnostic.goto_next)
@@ -144,48 +147,44 @@ vim.api.nvim_create_autocmd("LspAttach", {
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
whichkey.register({
g = {
name = "Go-to related commands",
D = { vim.lsp.buf.declaration, "Go to declaration" },
d = { vim.lsp.buf.definition, "Go to definition" },
i = { vim.lsp.buf.implementation, "Go to implementation" },
r = {
function()
require("telescope.builtin").lsp_references()
end,
"Find references",
},
whichkey.add({
{ "g", desc = "Go-to related commands" },
{ "gD", vim.lsp.buf.declaration, desc = "Go to declaration" },
{ "gd", vim.lsp.buf.definition, desc = "Go to definition" },
{ "gi", vim.lsp.buf.implementation, desc = "Go to implementation" },
{
"gr",
function()
require("telescope.builtin").lsp_references()
end,
desc = "Find references",
},
K = { vim.lsp.buf.hover, "Display information about symbol under cursor" },
{ "gK", vim.lsp.buf.hover, desc = "Display information about symbol under cursor" },
})
whichkey.register({
["<C-k>"] = { vim.lsp.buf.signature_help, "Display signature information about symbol under cursor" },
whichkey.add({
{ "<C-k>", vim.lsp.buf.signature_help, desc = "Display signature information about symbol under cursor" },
})
whichkey.register({
w = {
a = { vim.lsp.buf.add_workspace_folder, "Add a path to the workspace folders list" },
r = { vim.lsp.buf.add_workspace_folder, "Remove a path from the workspace folders list" },
l = {
function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end,
"Show the workspace folders list",
},
whichkey.add({
{ "<leader>w", desc = "Workspace-related commands" },
{ "<leader>wa", vim.lsp.buf.add_workspace_folder, desc = "Add a path to the workspace folders list" },
{ "<leader>wr", vim.lsp.buf.add_workspace_folder, desc = "Remove a path from the workspace folders list" },
{
"<leader>wl",
function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end,
desc = "Show the workspace folders list",
},
f = {
{
"<leader>f",
function()
vim.lsp.buf.format({ async = true })
end,
"Autoformat",
desc = "Autoformat",
},
c = {
a = { vim.lsp.buf.code_action, "Select a code action" },
},
r = {
n = { vim.lsp.buf.rename, "Rename variable" },
},
D = { vim.lsp.buf.type_definition, "Go to type definition" },
}, { prefix = vim.api.nvim_get_var("mapleader") })
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Select a code action" },
{ "<leader>rn", vim.lsp.buf.rename, desc = "Rename variable" },
{ "<leader>D", vim.lsp.buf.type_definition, desc = "Go to type definition" },
})
end,
})

View File

@@ -2,14 +2,10 @@ require("dap-python").setup("%PYTHONENV%/bin/python")
do
local whichkey = require("which-key")
whichkey.register({
['pd'] = {
"Debugger-related commands",
t = {
"Tests",
f = { require("dap-python").test_class, "Run Python tests in the current file" },
c = { require("dap-python").test_method, "Run the Python test under the cursor" },
},
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.add({
{ "<localleader>pd", desc = "Debugger-related commands" },
{ "<localleader>pdt", desc = "Tests" },
{ "<localleader>pdtf", require("dap-python").test_class, desc = "Run Python tests in the current file" },
{ "<localleader>pdtc", require("dap-python").test_method, desc = "Run the Python test under the cursor" },
})
end

View File

@@ -30,37 +30,36 @@ dap.configurations.cs = {
do
local whichkey = require("which-key")
whichkey.register({
d = {
name = "Debugger-related commands",
o = { dap.step_over, "Step over" },
i = { dap.step_into, "Step into" },
c = { dap.continue, "Continue" },
C = { dap.run_last, "Run with last debug configuration" },
b = { dap.toggle_breakpoint, "Toggle breakpoint" },
r = { dap.repl.open, "Open debug repl" },
v = {
name = "Commands to view debugger state",
v = {
function()
dap_ui.hover()
end,
"View value of expression under cursor",
},
s = {
function()
dap_ui.sidebar(dap_ui.scopes).open()
end,
"View values of all variables in all scopes",
},
f = {
function()
dap_ui.sidebar(dap_ui.frames).open()
end,
"View stack frames",
},
},
t = { dap.terminate, "Terminate/stop/end debug session" },
whichkey.add({
{ "<localleader>d", desc = "Debugger-related commands" },
{ "<localleader>do", dap.step_over, desc = "Step over" },
{ "<localleader>di", dap.step_into, desc = "Step into" },
{ "<localleader>dc", dap.continue, desc = "Continue" },
{ "<localleader>dC", dap.run_last, desc = "Run with last debug configuration" },
{ "<localleader>db", dap.toggle_breakpoint, desc = "Toggle breakpoint" },
{ "<localleader>dr", dap.repl.open, desc = "Open debug repl" },
{ "<localleader>dv", desc = "Commands to view debugger state" },
{
"<localleader>dvv",
function()
dap_ui.hover()
end,
desc = "View value of expression under cursor",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
{
"<localleader>dvs",
function()
dap_ui.sidebar(dap_ui.scopes).open()
end,
desc = "View values of all variables in all scopes",
},
{
"<localleader>dvf",
function()
dap_ui.sidebar(dap_ui.frames).open()
end,
desc = "View stack frames",
},
{ "<localleader>dt", dap.terminate, desc = "Terminate/stop/end debug session" },
})
end

View File

@@ -55,12 +55,10 @@ end
do
local whichkey = require("which-key")
whichkey.register({
['pt'] = {
"Run Python tests",
f = { RunPythonTestsInFile, "Run Python tests in the current file" },
a = { RunAllPythonTests, "Run all Python tests" },
c = { RunPythonTestAtCursor, "Run the Python test under the cursor" },
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.add({
{ "<localleader>pt", desc = "Run Python tests" },
{ "<localleader>ptf", RunPythonTestsInFile, desc = "Run Python tests in the current file" },
{ "<localleader>pta", RunAllPythonTests, desc = "Run all Python tests" },
{ "<localleader>ptc", RunPythonTestAtCursor, desc = "Run the Python test under the cursor" },
})
end

View File

@@ -1,5 +1,8 @@
require("tokyonight").setup({
style = "night",
on_colors = function(colors)
colors.border = "#565f89"
end,
})
vim.cmd([[colorscheme tokyonight]])

View File

@@ -84,17 +84,16 @@ end
do
local whichkey = require("which-key")
whichkey.register({
['pv'] = {
name = "Python virtual environment-related commands",
c = { CreateVenv, "Create virtual environment" },
l = { SelectVenv, "Load virtual environment" },
o = {
function()
vim.cmd("VenvSelect")
end,
"Choose (override) new virtual environment",
},
whichkey.add({
{ "<localleader>pv", desc = "Python virtual environment-related commands" },
{ "<localleader>pvc", CreateVenv, desc = "Create virtual environment" },
{ "<localleader>pvl", SelectVenv, desc = "Load virtual environment" },
{
"<localleader>pvo",
function()
vim.cmd("VenvSelect")
end,
desc = "Choose (override) new virtual environment",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
})
end

View File

@@ -18,67 +18,19 @@ require("which-key").setup({
g = true, -- bindings for prefixed with g
},
},
-- add operators that will trigger motion and text object completion
-- to enable all native operators, set the preset / operators plugin above
operators = { gc = "Comments" },
key_labels = {
-- override the label used to display some keys. It doesn't effect WK in any other way.
-- For example:
-- ["<space>"] = "SPC",
-- ["<cr>"] = "RET",
-- ["<tab>"] = "TAB",
},
motions = {
count = true,
},
icons = {
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
separator = "", -- symbol used between a key and it's label
group = "+", -- symbol prepended to a group
},
popup_mappings = {
scroll_down = "<c-d>", -- binding to scroll down inside the popup
scroll_up = "<c-u>", -- binding to scroll up inside the popup
},
window = {
border = "none", -- none, single, double, shadow
position = "bottom", -- bottom, top
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
zindex = 1000, -- positive value to position WhichKey above other floating windows.
},
layout = {
height = { min = 4, max = 25 }, -- min and max height of the columns
width = { min = 20, max = 50 }, -- min and max width of the columns
spacing = 3, -- spacing between columns
align = "left", -- align columns left, center or right
},
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
show_help = true, -- show a help message in the command line for using WhichKey
show_keys = true, -- show the currently pressed key and its label as a message in the command line
triggers = "auto", -- automatically setup triggers
-- triggers = {"<leader>"} -- or specifiy a list manually
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
triggers_nowait = {
-- marks
"`",
"'",
"g`",
"g'",
-- registers
'"',
"<c-r>",
-- spelling
"z=",
},
triggers_blacklist = {
-- list of mode / prefixes that should never be hooked by WhichKey
-- this is mostly relevant for keymaps that start with a native binding
i = { "j", "k" },
v = { "j", "k" },
},
-- disable the WhichKey popup for certain buf types and file types.
-- Disabled by default for Telescope
disable = {