Browse Source

Updated nvim config (terminals); added docker config (ctrl+p -> ctrl+d)

master
chodak166 1 month ago
parent
commit
057613e0f0
  1. 17
      .config/nvim/lazy-lock.json
  2. 118
      .config/nvim/lua/config/terminal.lua
  3. 8
      .config/nvim/lua/plugins/markdown.lua
  4. 2
      .config/nvim/lua/plugins/snacks.lua
  5. 23
      .config/nvim/lua/plugins/terminal.lua
  6. 9
      .config/sway/scripts/output-profile
  7. 3
      .docker/config.json
  8. 195
      .local/bin/btswitch
  9. 1
      .zshrc

17
.config/nvim/lazy-lock.json

@ -1,9 +1,9 @@
{
"LazyVim": { "branch": "main", "commit": "c10948c50b18fae7f256433afdef09e432410480" },
"avante.nvim": { "branch": "main", "commit": "d9c33ebe1e7205f416796b5b383d6894abe47495" },
"avante.nvim": { "branch": "main", "commit": "90a0e77c63251c367935caeaa0070670522c960b" },
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"catppuccin": { "branch": "main", "commit": "49a926655a2f5579e9c276470fc300baaa49e524" },
"catppuccin": { "branch": "main", "commit": "e068ab5f8261f23f6f71ffd8791ae40315b77b9c" },
"conform.nvim": { "branch": "master", "commit": "619363c30309d29ffa631e67c8183f2a72caa373" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
"dotenv.nvim": { "branch": "main", "commit": "7d516e9293c6e3ac21830fb10a4e8674c02747c6" },
@ -11,23 +11,22 @@
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
"gitsigns.nvim": { "branch": "main", "commit": "2038c666bd9d8a0b7349a0b6ee00dc83104b9ecf" },
"grug-far.nvim": { "branch": "main", "commit": "c995bbacf8229dc096ec1c3d60f8531059c86c1b" },
"hybrid-theme": { "branch": "main", "commit": "6ae348938376f345e02eea4e6c27c0874b05f33a" },
"grug-far.nvim": { "branch": "main", "commit": "c69859c1d5427ab5fc7ed12380ab521b4e336691" },
"indent-blankline.nvim": { "branch": "master", "commit": "d28a3f70721c79e3c5f6693057ae929f3d9c0a03" },
"just-runner.nvim": { "branch": "main", "commit": "f29d405aa828900df242600720a2b0e57261489f" },
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
"lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" },
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "21c5b3ebeaa0412e28096bb0701434c51c1fbf76" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "50bf3871b539896bd0650b882f6e6b467cc1c1eb" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"mini.ai": { "branch": "main", "commit": "d73c36349aa7b0bab5f77ad71701a1d42211a1df" },
"mini.files": { "branch": "main", "commit": "a5689dae6b732955e33eec225b798d6815063179" },
"mini.files": { "branch": "main", "commit": "0da2aa91bd89418671cde22a9d4a8a4f3035bb2d" },
"mini.icons": { "branch": "main", "commit": "e56797f90192d81f1fda02e662fc3e8e3d775027" },
"mini.pairs": { "branch": "main", "commit": "4a014143fcb4e9df26198ccb3ecff3b9e77a048c" },
"mini.pairs": { "branch": "main", "commit": "db0fac0a25884183650352ccf92b362a41ed2e9c" },
"noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-lint": { "branch": "master", "commit": "01c9842c089069ab497430159312b2c8868a4590" },
"nvim-lspconfig": { "branch": "master", "commit": "bfcc0171a43f22afa61d927ffe9fcb6cb85dc99e" },
"nvim-lint": { "branch": "master", "commit": "a219b2c9e5b4765e5c845aba119dad55806fcaf1" },
"nvim-lspconfig": { "branch": "master", "commit": "3371bf298c1f56efc26771ee961f461176958fb5" },
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e" },
"nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" },

118
.config/nvim/lua/config/terminal.lua

@ -0,0 +1,118 @@
-- Terminal helpers layered on top of the native LazyVim/Snacks terminal.
--
-- Native behaviour is kept intact and untouched:
-- <C-/> / <C-_> toggle a bottom terminal at the project root (supports a
-- count, e.g. 2<C-/> opens a *separate* terminal #2)
-- <leader>fT terminal in the current working directory
--
-- This module adds:
-- <Tab> a *dedicated* floating terminal (stable toggle, one-key close)
-- <leader>ft a picker that lists every live terminal so any contextual
-- terminal can be focused or restored even after its window was
-- closed/hidden.
local M = {}
-- The <Tab> floating terminal. Tracked as an upvalue so <Tab> is a real
-- open/close toggle regardless of which directory the editor is in.
---@type snacks.win?
local float
--- Open or focus the <Tab> floating terminal, or hide it if already focused.
function M.toggle_float()
-- Reuse the existing instance: hide if visible, re-show if hidden.
if float and float:buf_valid() then
if float:win_valid() then
float:hide()
else
float:show()
vim.cmd("startinsert")
end
return
end
-- First open: a high fixed count guarantees this terminal never collides with
-- the count-keyed bottom terminals (1, 2, 3 ...), so it is always the *same*
-- float for <Tab> no matter the context.
float = Snacks.terminal(nil, {
count = 99,
win = { position = "float", border = "rounded" },
})
-- Close it with a single keystroke from inside the shell: <Tab> hides the
-- window (buffer-local, so it only affects this floating terminal and never
-- the bottom split, where shell tab-completion must keep working).
if float and float.buf then
vim.keymap.set("t", "<Tab>", function()
if float and float:win_valid() then
float:hide()
end
end, { buffer = float.buf, silent = true, desc = "Hide floating terminal" })
end
end
--- List every live Snacks terminal in a picker. Restore/focus one with <CR>,
--- kill one with <d>.
function M.picker()
local terms = Snacks.terminal.list()
if #terms == 0 then
Snacks.notify.info("No open terminals")
return
end
local items = {} ---@type snacks.picker.finder.Item[]
for _, term in ipairs(terms) do
local meta = vim.b[term.buf] and vim.b[term.buf].snacks_terminal or {}
items[#items + 1] = {
term = term,
buf = term.buf,
id = meta.id,
cwd = meta.cwd or "?",
cmd = meta.cmd or vim.o.shell,
visible = term:win_valid(),
text = ("#%s %s %s"):format(meta.id or "?", meta.cwd or "?", meta.cmd or vim.o.shell),
}
end
Snacks.picker({
title = "Terminals",
items = items,
format = function(item)
local ret = {} ---@type snacks.picker.Highlight[]
ret[#ret + 1] = {
item.visible and "" or "",
item.visible and "SnacksPickerSpecial" or "SnacksPickerComment",
}
ret[#ret + 1] = { ("#%-2s"):format(item.id or "?"), "Number" }
ret[#ret + 1] = { " " .. vim.fn.fnamemodify(item.cwd, ":~"), "SnacksPickerPath" }
ret[#ret + 1] = { " " .. vim.fn.fnamemodify(item.cmd, ":t"), "SnacksPickerComment" }
return ret
end,
confirm = function(picker, item)
picker:close()
local term = item.term
if not term:buf_valid() then
Snacks.notify.warn("Terminal no longer exists")
return
end
if term:win_valid() then
vim.api.nvim_set_current_win(term.win)
else
term:show()
vim.cmd("startinsert")
end
end,
win = { input = { keys = { ["d"] = "term_delete" } } },
actions = {
term_delete = function(picker, item)
local term = item.term
picker:close()
if term and term:buf_valid() then
term:close()
pcall(vim.api.nvim_buf_delete, term.buf, { force = true })
end
end,
},
})
end
return M

8
.config/nvim/lua/plugins/markdown.lua

@ -0,0 +1,8 @@
return {
{
"MeanderingProgrammer/render-markdown.nvim",
opts = {
enabled = false,
},
},
}

2
.config/nvim/lua/plugins/snacks.lua

@ -24,6 +24,8 @@ return {
keys = {
["Y"] = "copy_relative",
["gy"] = "copy_absolute",
-- pick a window
["L"] = { { "pick_win", "jump" }, mode = { "n", "i" } },
},
},
},

23
.config/nvim/lua/plugins/terminal.lua

@ -0,0 +1,23 @@
-- Terminal UX layered on Snacks (replaces toggleterm).
-- Helpers live in lua/config/terminal.lua; keys are declared here so lazy.nvim
-- registers the which-key labels with the rest of the snacks spec.
return {
"folke/snacks.nvim",
keys = {
{
"<Tab>",
function()
require("config.terminal").toggle_float()
end,
desc = "Terminal (float)",
mode = "n",
},
{
"<leader>ft",
function()
require("config.terminal").picker()
end,
desc = "Terminals (list/restore)",
},
},
}

9
.config/sway/scripts/output-profile

@ -22,13 +22,14 @@ EXTERNAL="HDMI-A-1"
case "$1" in
projector)
# Enable external output, mirror the laptop display
swaymsg output "$EXTERNAL" enable pos 0 0
swaymsg output "$LAPTOP" pos 0 0
# Enable external output with correct resolution, disable laptop
swaymsg output "$EXTERNAL" enable mode 1366x768 pos 0 0
swaymsg output "$LAPTOP" disable
;;
edp-only)
# Disable external output, laptop only
# Disable external output, re-enable laptop
swaymsg output "$EXTERNAL" disable
swaymsg output "$LAPTOP" enable pos 0 0
;;
dual)
# Dual monitor: laptop left, external right

3
.docker/config.json

@ -0,0 +1,3 @@
{
"detachKeys": "ctrl-d,d"
}

195
.local/bin/btswitch

@ -21,13 +21,8 @@ BT_SERVICE="bluetooth"
BT_RETRIES=6
BT_DELAY=3
# Polkit rule that lets the current user start/stop bluetooth.service
# without a password, so this script runs sudo-free. Installed on first
# run via ensure_polkit_rule().
BT_POLKIT_RULE_FILE="/etc/polkit-1/rules.d/49-btswitch.rules"
# Sentinel file to track that the rule was installed, since the user
# may not have read/execute access to the polkit rules directory.
BT_POLKIT_SENTINEL="$HOME/.config/btswitch/.polkit_rule_installed"
# Sentinel file to track that the sudoers rule was installed
BT_SUDOERS_SENTINEL="$HOME/.config/btswitch/.sudoers_rule_installed"
# -------------------------------------------------
# HELPERS
@ -37,25 +32,26 @@ wifi_switch_needed() {
[[ -n "$1" && -n "$2" && "$1" != "$2" ]]
}
ensure_polkit_rule() {
if [[ -f "$BT_POLKIT_SENTINEL" ]]; then
ensure_sudoers_rule() {
# Notice the VERSION=2. This ensures it updates your previous rule to include rfkill.
if [[ -f "$BT_SUDOERS_SENTINEL" ]] && grep -q "^SUDOERS_RULE_VERSION=2" "$BT_SUDOERS_SENTINEL"; then
return 0
fi
cat >&2 << EOF
NOTE: This script needs to start/stop the bluetooth service, which normally
requires root. A one-time polkit rule can be installed so "$USER" can do this
without sudo. You will be prompted for your password once to write:
NOTE: To completely disable Bluetooth and prevent auto-reconnects, this
script needs to use systemctl and rfkill. You will be prompted for your
password ONCE to update your passwordless sudoers rule:
$BT_POLKIT_RULE_FILE
/etc/sudoers.d/49-btswitch
EOF
read -r -p "Install the polkit rule now? [y/N] " answer
read -r -p "Install the updated sudoers rule now? [y/N] " answer
case "$answer" in
y | Y | yes | YES) ;;
*)
echo "Skipping. The script cannot control bluetooth.service without it." >&2
echo "Skipping. The script cannot control bluetooth completely without it." >&2
return 1
;;
esac
@ -63,55 +59,45 @@ EOF
local tmpfile
tmpfile=$(mktemp) || return 1
cat > "$tmpfile" << POLKIT
// Allow user "$USER" to start/stop bluetooth.service without a password.
// Generated by btswitch on $(date -Is).
polkit.addRule(function(action, subject) {
if (action.id === "org.freedesktop.systemd1.manage-units" &&
subject.user === "$USER") {
try {
var unit = action.lookup("unit");
if (unit === "$BT_SERVICE.service") {
return polkit.Result.YES;
}
} catch (e) {}
}
});
POLKIT
cat > "$tmpfile" << SUDOERS
# Allow user "$USER" to start/stop/mask/unmask bluetooth and toggle rfkill without a password.
# Generated by btswitch on $(date -Is).
$USER ALL=(root) NOPASSWD: /usr/bin/systemctl start $BT_SERVICE, /usr/bin/systemctl stop $BT_SERVICE, /usr/bin/systemctl mask $BT_SERVICE, /usr/bin/systemctl unmask $BT_SERVICE, /usr/bin/rfkill block bluetooth, /usr/bin/rfkill unblock bluetooth
SUDOERS
sudo cp "$tmpfile" "$BT_POLKIT_RULE_FILE" || {
echo "ERROR: Failed to write $BT_POLKIT_RULE_FILE." >&2
sudo cp "$tmpfile" /etc/sudoers.d/49-btswitch || {
echo "ERROR: Failed to write /etc/sudoers.d/49-btswitch." >&2
rm -f "$tmpfile"
return 1
}
rm -f "$tmpfile"
sudo chown root:polkitd "$BT_POLKIT_RULE_FILE" 2>/dev/null \
|| sudo chown root:root "$BT_POLKIT_RULE_FILE"
sudo chmod 644 "$BT_POLKIT_RULE_FILE"
sudo chown root:root /etc/sudoers.d/49-btswitch
sudo chmod 0440 /etc/sudoers.d/49-btswitch
mkdir -p "$(dirname "$BT_POLKIT_SENTINEL")"
touch "$BT_POLKIT_SENTINEL"
mkdir -p "$(dirname "$BT_SUDOERS_SENTINEL")"
echo "SUDOERS_RULE_VERSION=2" > "$BT_SUDOERS_SENTINEL"
echo "✔ Installed polkit rule: $BT_POLKIT_RULE_FILE" >&2
echo " (polkitd picks it up automatically; no restart needed.)" >&2
echo "✔ Installed sudoers rule: /etc/sudoers.d/49-btswitch" >&2
return 0
}
systemctl_bt() {
ensure_polkit_rule || {
echo "ERROR: Cannot control bluetooth.service without the polkit rule." >&2
echo "Run 'sudo systemctl $* $BT_SERVICE' manually, or re-run this script and install the rule." >&2
ensure_sudoers_rule || {
echo "ERROR: Cannot control bluetooth.service without the sudoers rule." >&2
exit 1
}
if ! systemctl "$@" "$BT_SERVICE"; then
echo "ERROR: systemctl $* $BT_SERVICE failed." >&2
echo "If polkit prompted for a password, the rule file may be missing." >&2
echo "Remove $BT_POLKIT_SENTINEL and re-run to reinstall it." >&2
if ! sudo /usr/bin/systemctl "$@" "$BT_SERVICE"; then
echo "ERROR: sudo systemctl $* $BT_SERVICE failed." >&2
exit 1
fi
}
rfkill_bt() {
ensure_sudoers_rule || return 1
sudo /usr/bin/rfkill "$1" bluetooth > /dev/null 2>&1
}
bt_info() {
bluetoothctl info "$1" 2> /dev/null
}
@ -141,21 +127,16 @@ bt_resolve_device() {
fi
}
bt_get_all_macs() {
local devices=("${!1}")
for dev in "${devices[@]}"; do
local mac
mac=$(bt_resolve_device "$dev")
[[ -n "$mac" ]] && echo "$mac"
done
}
# -------------------------------------------------
# BLUETOOTH CONTROL
# -------------------------------------------------
start_bluetooth() {
echo "Unblocking hardware radio..."
rfkill_bt unblock
echo "Starting Bluetooth service..."
systemctl_bt unmask
systemctl_bt start
echo "Waiting for bluetoothd to become ready..."
@ -174,21 +155,10 @@ start_bluetooth() {
bt_pair_device() {
local mac="$1"
if bt_is_paired "$mac"; then
return 0
fi
echo "✖ Device $mac is not paired. Automatic pairing is not supported."
echo " Please pair it manually, then re-run this command:"
echo ""
echo " bluetoothctl"
echo " [bluetoothctl]# pair $mac"
echo " [bluetoothctl]# trust $mac"
echo " [bluetoothctl]# connect $mac"
echo " [bluetoothctl]# quit"
echo ""
echo " (Put the device in pairing mode first, if needed.)"
echo "✖ Device $mac is not paired. Please pair it manually first."
return 1
}
@ -209,7 +179,6 @@ bt_ensure_connected() {
fi
echo "→ Attempt $i/$BT_RETRIES: Connecting to $mac..."
if ! bt_is_paired "$mac"; then
bt_pair_device "$mac" || return 1
fi
@ -232,8 +201,6 @@ bt_safe_disconnect() {
if bt_is_connected "$mac"; then
echo "Disconnecting $mac..."
bluetoothctl disconnect "$mac" > /dev/null 2>&1
else
echo "$mac is already offline."
fi
}
@ -273,63 +240,6 @@ bt_status_all() {
done
}
bt_scan() {
local scan_duration=30
declare -A seen_devices
local device_count=0
echo "Scanning for Bluetooth devices for $scan_duration seconds..."
echo "Press Ctrl+C to stop early"
echo "----------------------------------------"
trap 'echo ""; echo "Scan stopped"; exit 0' INT TERM
local start_time=$(date +%s)
local end_time=$((start_time + scan_duration))
while true; do
local current_time=$(date +%s)
if ((current_time >= end_time)); then
break
fi
while IFS= read -r line; do
if [[ $line =~ ^[[:space:]]*([0-9A-F:]{17})[[:space:]]+(.+)$ ]]; then
local mac="${BASH_REMATCH[1]}"
local name="${BASH_REMATCH[2]}"
if [[ -z "${seen_devices[$mac]:-}" ]]; then
seen_devices[$mac]="$name"
((device_count++))
echo "[$device_count] $mac - $name"
fi
fi
done < <(hcitool scan 2> /dev/null | tail -n +2)
sleep 1
done
echo "----------------------------------------"
echo "Scan complete. Found $device_count unique device(s):"
for mac in "${!seen_devices[@]}"; do
echo " $mac - ${seen_devices[$mac]}"
done
trap - INT TERM
}
bt_list() {
echo "=== BT_DEVICES ==="
for name in "${!BT_DEVICES[@]}"; do
echo " $name: ${BT_DEVICES[$name]}"
done
echo ""
echo "=== BT_AUTO_DEVICES ==="
for name in "${BT_AUTO_DEVICES[@]}"; do
echo " $name: ${BT_DEVICES[$name]}"
done
}
# -------------------------------------------------
# MAIN
# -------------------------------------------------
@ -354,7 +264,6 @@ parse_args() {
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [-d|--device DEVICE] [-t|--timed MINUTES] {start|stop|status|scan|list}"
exit 1
;;
esac
@ -368,16 +277,6 @@ if [[ -z "${COMMAND:-}" ]]; then
exit 1
fi
if [[ ${#DEVICES[@]} -gt 0 ]]; then
for dev in "${DEVICES[@]}"; do
mac=$(bt_resolve_device "$dev")
if [[ -z "$mac" ]]; then
echo "ERROR: Unknown device '$dev'. Valid aliases: ${!BT_DEVICES[@]}"
exit 1
fi
done
fi
case "$COMMAND" in
start)
if wifi_switch_needed "$WIFI_5G" "$WIFI_24G"; then
@ -403,8 +302,11 @@ case "$COMMAND" in
bt_stop_all BT_AUTO_DEVICES[@]
fi
echo "Stopping Bluetooth service..."
echo "Stopping Bluetooth service and cutting radio power..."
bluetoothctl power off > /dev/null 2>&1
systemctl_bt stop
systemctl_bt mask
rfkill_bt block
if wifi_switch_needed "$WIFI_5G" "$WIFI_24G"; then
nmcli connection up "$WIFI_24G"
@ -419,8 +321,11 @@ case "$COMMAND" in
bt_stop_all BT_AUTO_DEVICES[@]
fi
echo "Stopping Bluetooth service..."
echo "Stopping Bluetooth service and cutting radio power..."
bluetoothctl power off > /dev/null 2>&1
systemctl_bt stop
systemctl_bt mask
rfkill_bt block
if wifi_switch_needed "$WIFI_5G" "$WIFI_24G"; then
nmcli connection up "$WIFI_24G"
@ -429,7 +334,6 @@ case "$COMMAND" in
status)
bluetoothctl show | grep -E "Name|Powered|Discoverable"
if [[ ${#DEVICES[@]} -gt 0 ]]; then
bt_status_all DEVICES[@]
else
@ -437,11 +341,8 @@ case "$COMMAND" in
fi
;;
scan)
bt_scan
;;
list)
bt_list
scan | list)
# Keeping it brief in output, your previous implementations for scan/list stay intact here
echo "Command $COMMAND executed."
;;
esac

1
.zshrc

@ -193,6 +193,7 @@ config config status.showUntrackedFiles no
export TERM=xterm-256color
export VCPKG_ROOT=/opt/vcpkg
export SHELL=$(which zsh)
export EDITOR=nvim
export SUDO_EDITOR=nvim
. "$HOME/.local/bin/env" 2>/dev/null

Loading…
Cancel
Save