Compare commits
48 Commits
main
...
dev_01_ini
| Author | SHA1 | Date |
|---|---|---|
|
|
7581bcf9fa | 1 year ago |
|
|
079befc8c0 | 1 year ago |
|
|
520b3c6ca2 | 3 years ago |
|
|
6e9f295331 | 2 years ago |
|
|
002bebba41 | 2 years ago |
|
|
7071c2c983 | 2 years ago |
|
|
e075b9fac3 | 2 years ago |
|
|
70b8952fb1 | 2 years ago |
|
|
51d44eccb6 | 2 years ago |
|
|
9091f905f1 | 2 years ago |
|
|
e4a8443c39 | 2 years ago |
|
|
e8e34cd240 | 2 years ago |
|
|
2fc0d8a669 | 2 years ago |
|
|
57f0011d41 | 2 years ago |
|
|
ff0387644e | 2 years ago |
|
|
79f3aa8120 | 2 years ago |
|
|
fe74c748d7 | 2 years ago |
|
|
4cd100ec1f | 2 years ago |
|
|
65cf545b95 | 2 years ago |
|
|
88276e4050 | 2 years ago |
|
|
1887345eab | 2 years ago |
|
|
31da710a57 | 2 years ago |
|
|
7bcd2f471b | 3 years ago |
|
|
76fb435bce | 3 years ago |
|
|
545db10376 | 3 years ago |
|
|
5abc6affd7 | 3 years ago |
|
|
a52399bf8a | 3 years ago |
|
|
d3ebe8db18 | 3 years ago |
|
|
a86ea3b1f4 | 3 years ago |
|
|
2cf8d7e4bf | 3 years ago |
|
|
39ec6308c5 | 3 years ago |
|
|
6c1542dda3 | 3 years ago |
|
|
87809eaa6b | 3 years ago |
|
|
8aaaa14676 | 3 years ago |
|
|
4876b40295 | 3 years ago |
|
|
95e07fabda | 3 years ago |
|
|
524a46720c | 3 years ago |
|
|
562da7e184 | 3 years ago |
|
|
5a549794b6 | 3 years ago |
|
|
a0fbe7e891 | 3 years ago |
|
|
1bf43d13ac | 3 years ago |
|
|
50f5bdcf96 | 3 years ago |
|
|
07b1e0730e | 3 years ago |
|
|
32296d4a92 | 3 years ago |
|
|
13764d56dd | 3 years ago |
|
|
09d64c7cb5 | 3 years ago |
|
|
107d627d57 | 3 years ago |
|
|
8f2e6a8453 | 3 years ago |
497 changed files with 49037 additions and 1 deletions
@ -0,0 +1,11 @@ |
|||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
|
charset = utf-8 |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.nix] |
||||
|
ident_style = space |
||||
|
ident_size = 2 |
||||
@ -0,0 +1 @@ |
|||||
|
use flake |
||||
@ -0,0 +1,3 @@ |
|||||
|
nixos/hosts/*/secrets/*.yaml diff=sopsdiffer |
||||
|
nixos/common/secrets/*.yaml diff=sopsdiffer |
||||
|
nix linguist-generated=true |
||||
@ -0,0 +1,4 @@ |
|||||
|
.direnv |
||||
|
result* |
||||
|
*.qcow2 |
||||
|
.nixie |
||||
@ -0,0 +1,26 @@ |
|||||
|
{ |
||||
|
"main": { |
||||
|
"enabled": 1, |
||||
|
"type": 1, |
||||
|
"hidden": false, |
||||
|
"description": "Build main branch", |
||||
|
"flake": "github:misterio77/nix-config/main", |
||||
|
"checkinterval": 60, |
||||
|
"schedulingshares": 10, |
||||
|
"enableemail": false, |
||||
|
"emailoverride": "", |
||||
|
"keepnr": 2 |
||||
|
}, |
||||
|
"next": { |
||||
|
"enabled": 1, |
||||
|
"type": 1, |
||||
|
"hidden": false, |
||||
|
"description": "Build next branch", |
||||
|
"flake": "github:misterio77/nix-config/next", |
||||
|
"checkinterval": 60, |
||||
|
"schedulingshares": 5, |
||||
|
"enableemail": false, |
||||
|
"emailoverride": "", |
||||
|
"keepnr": 1 |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
keys: |
||||
|
# Users |
||||
|
- &users: |
||||
|
- &misterio 7088C7421873E0DB97FF17C2245CAB70B4C225E9 |
||||
|
# Hosts |
||||
|
- &hosts: |
||||
|
- &atlas age1hm5lf4qk84r4wh00atn6hpts7mpdx80adq26wht2e5qh9ewvhyaszfv82d |
||||
|
- &merope age1709qfrwglm75v5x8lpuhryt83k6p6c90npplzzec6a5w8ct93ejscpqpc3 |
||||
|
- &pleione age1j9ld6ey62hqd33xkyd2fg9362k6xhm5gavsrpsfalwpcs8smxfdqpk84a2 |
||||
|
- &maia age1dn7pkareh83k8el2yt4dmdfdzn7f45fuc785cnnxgzf3h4r5gqhqd4l93h |
||||
|
- &alcyone age1uxvuygmvwpfjrd9d3ulg6ln8dgvaw4l2c90mw0tr72qg3n8vd9ns3dm000 |
||||
|
- &celaeno age1gxhy9eq38xfplay0kvkeyvsg96g0c4p6rkhajkrj8nc9dswdzqhssgvns0 |
||||
|
- &electra age1n06f4dcslh8xq686z2fa9ddr3yg5yzj87p727896xsm8xvusdv6qan0grl |
||||
|
|
||||
|
creation_rules: |
||||
|
- path_regex: hosts/celaeno/secrets.ya?ml$ |
||||
|
key_groups: |
||||
|
- age: |
||||
|
- *celaeno |
||||
|
pgp: |
||||
|
- *misterio |
||||
|
- path_regex: hosts/alcyone/secrets.ya?ml$ |
||||
|
key_groups: |
||||
|
- age: |
||||
|
- *alcyone |
||||
|
pgp: |
||||
|
- *misterio |
||||
|
- path_regex: hosts/merope/secrets.ya?ml$ |
||||
|
key_groups: |
||||
|
- age: |
||||
|
- *merope |
||||
|
pgp: |
||||
|
- *misterio |
||||
|
|
||||
|
- path_regex: hosts/common/secrets.ya?ml$ |
||||
|
key_groups: |
||||
|
- age: |
||||
|
- *atlas |
||||
|
- *merope |
||||
|
- *pleione |
||||
|
- *maia |
||||
|
- *alcyone |
||||
|
- *celaeno |
||||
|
- *electra |
||||
|
pgp: |
||||
|
- *misterio |
||||
@ -0,0 +1,7 @@ |
|||||
|
Copyright (c) 2021 Gabriel Fontes |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||
@ -1,2 +1,142 @@ |
|||||
# nix-config |
[](https://builtwithnix.org) |
||||
|
[](https://hydra.m7.rs/jobset/nix-config/main#tabs-jobs) |
||||
|
|
||||
|
# My NixOS configurations |
||||
|
|
||||
|
Here's my NixOS/home-manager config files. Requires [Nix flakes](https://nixos.wiki/wiki/Flakes). |
||||
|
|
||||
|
Looking for something simpler to start out with flakes? Try [my starter config repo](https://github.com/Misterio77/nix-starter-config). |
||||
|
|
||||
|
**Highlights**: |
||||
|
|
||||
|
- Multiple **NixOS configurations**, including **desktop**, **laptop**, **server** |
||||
|
- **Opt-in persistence** through impermanence + blank snapshotting |
||||
|
- **Encrypted** single **BTRFS** partition |
||||
|
- Fully **declarative** **self-hosted** stuff |
||||
|
- Deployment **secrets** using **sops-nix** |
||||
|
- **Mesh networked** hosts with **tailscale** and **headscale** |
||||
|
- Flexible **Home Manager** Configs through **feature flags** |
||||
|
- Extensively configured wayland environments (**sway** and **hyprland**) and editor (**neovim**) |
||||
|
- **Declarative** **themes** and **wallpapers** with **nix-colors** |
||||
|
- **Hydra CI/CD server and binary cache** that uses the **desktops as remote builders** |
||||
|
|
||||
|
## Structure |
||||
|
|
||||
|
- `flake.nix`: Entrypoint for hosts and home configurations. Also exposes a |
||||
|
devshell for boostrapping (`nix develop` or `nix-shell`). |
||||
|
- `lib`: A few lib functions for making my flake cleaner |
||||
|
- `hosts`: NixOS Configurations, accessible via `nixos-rebuild --flake`. |
||||
|
- `common`: Shared configurations consumed by the machine-specific ones. |
||||
|
- `global`: Configurations that are globally applied to all my machines. |
||||
|
- `optional`: Opt-in configurations my machines can use. |
||||
|
- `atlas`: Desktop PC - 32GB RAM, R5 3600x, RX 5700XT | Hyprland |
||||
|
- `pleione`: Lenovo Ideapad 3 - 8GB RAM, R7 5700u | Hyprland |
||||
|
- `maia`: Secondary Desktop PC - 16GB RAM, i5 6600, GTX 970 | Server |
||||
|
- `merope`: Raspberry Pi 4 - 8GB RAM | Server |
||||
|
- `celaeno`: Oracle Could VPS (Ampere) - 24GB RAM & 4vCPUs | Server |
||||
|
- `alcyone`: Vultr VPS - 1GB RAM & 1 vCPU | Server |
||||
|
- `home`: My Home-manager configuration, acessible via `home-manager --flake` |
||||
|
- Each directory here is a "feature" each hm configuration can toggle, thus |
||||
|
customizing my setup for each machine (be it a server, desktop, laptop, |
||||
|
anything really). |
||||
|
- `modules`: A few actual modules (with options) I haven't upstreamed yet. |
||||
|
- `overlay`: Patches and version overrides for some packages. Accessible via |
||||
|
`nix build`. |
||||
|
- `pkgs`: My custom packages. Also accessible via `nix build`. You can compose |
||||
|
these into your own configuration by using my flake's overlay, or consume them through NUR. |
||||
|
- `templates`: A couple project templates for different languages. Accessible |
||||
|
via `nix init`. |
||||
|
|
||||
|
|
||||
|
## About the installation |
||||
|
|
||||
|
All my computers use a single btrfs (encrypted on all except headless systems) |
||||
|
partition, with subvolumes for `/nix`, a `/persist` directory (which I opt in |
||||
|
using `impermanence`), swap file, and a root subvolume (cleared on every boot). |
||||
|
|
||||
|
Home-manager is used in a standalone way, and because of opt-in persistence is |
||||
|
activated on every boot with `loginShellInit`. |
||||
|
|
||||
|
|
||||
|
## How to bootstrap |
||||
|
|
||||
|
All you need is nix (any version). Run: |
||||
|
``` |
||||
|
nix-shell |
||||
|
``` |
||||
|
|
||||
|
If you already have nix 2.4+, git, and have already enabled `flakes` and |
||||
|
`nix-command`, you can also use the non-legacy command: |
||||
|
``` |
||||
|
nix develop |
||||
|
``` |
||||
|
|
||||
|
`nixos-rebuild --flake .` To build system configurations |
||||
|
|
||||
|
`home-manager --flake .` To build user configurations |
||||
|
|
||||
|
`nix build` (or shell or run) To build and use packages |
||||
|
|
||||
|
`sops` To manage secrets |
||||
|
|
||||
|
|
||||
|
## Secrets |
||||
|
|
||||
|
For deployment secrets (such as user passwords and server service secrets), I'm |
||||
|
using the awesome [`sops-nix`](https://github.com/Mic92/sops-nix). All secrets |
||||
|
are encrypted with my personal PGP key (stored on a YubiKey), as well as the |
||||
|
relevant systems's SSH host keys. |
||||
|
|
||||
|
On my desktop and laptop, I use `pass` for managing passwords, which are |
||||
|
encrypted using (you bet) my PGP key. This same key is also used for mail |
||||
|
signing, as well as for SSH'ing around. |
||||
|
|
||||
|
## Tooling and applications I use |
||||
|
|
||||
|
Most relevant user apps daily drivers: |
||||
|
|
||||
|
- hyprland + swayidle + swaylock |
||||
|
- waybar |
||||
|
- neovim |
||||
|
- fish + starship |
||||
|
- kitty |
||||
|
- qutebrowser |
||||
|
- neomutt + mbsync |
||||
|
- khal + khard + todoman + vdirsyncer |
||||
|
- gpg + pass |
||||
|
- tailscale |
||||
|
- podman |
||||
|
- zathura |
||||
|
- wofi |
||||
|
- bat + fd + rg |
||||
|
- kdeconnect |
||||
|
- sublime-music |
||||
|
|
||||
|
Some of the services I host: |
||||
|
|
||||
|
- hydra |
||||
|
- navidrome |
||||
|
- deluge |
||||
|
- prometheus |
||||
|
- websites (such as https://m7.rs) |
||||
|
- minecraft |
||||
|
- headscale |
||||
|
|
||||
|
Nixy stuff: |
||||
|
|
||||
|
- nix-colors |
||||
|
- sops-nix |
||||
|
- impermanence |
||||
|
- home-manager |
||||
|
- deploy-rs |
||||
|
- and NixOS and nix itself, of course :) |
||||
|
|
||||
|
Let me know if you have any questions about them :) |
||||
|
|
||||
|
## Unixpornish stuff |
||||
|
 |
||||
|
 |
||||
|
|
||||
|
That's how my hyprland desktop setup look like (as of 2022 July). |
||||
|
|
||||
|
|
||||
|
|||||
@ -0,0 +1,16 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
export NIX_SSHOPTS="-A" |
||||
|
|
||||
|
build_remote=false |
||||
|
|
||||
|
hosts="$1" |
||||
|
shift |
||||
|
|
||||
|
if [ -z "$hosts" ]; then |
||||
|
echo "No hosts to deploy" |
||||
|
exit 2 |
||||
|
fi |
||||
|
|
||||
|
for host in ${hosts//,/ }; do |
||||
|
nixos-rebuild --flake .\#$host switch --target-host $host --use-remote-sudo --use-substitutes $@ |
||||
|
done |
||||
@ -0,0 +1,215 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
|
||||
|
# this is a simple config for herbstluftwm |
||||
|
|
||||
|
hc() { |
||||
|
herbstclient "$@" |
||||
|
} |
||||
|
|
||||
|
hc emit_hook reload |
||||
|
|
||||
|
xsetroot -solid '#5A8E3A' |
||||
|
|
||||
|
# remove all existing keybindings |
||||
|
hc keyunbind --all |
||||
|
|
||||
|
# keybindings |
||||
|
# if you have a super key you will be much happier with Mod set to Mod4 |
||||
|
#Mod=Mod1 # Use alt as the main modifier |
||||
|
Mod=Mod4 # Use the super key as the main modifier |
||||
|
|
||||
|
hc keybind $Mod-Shift-q close |
||||
|
hc keybind $Mod-Shift-e quit |
||||
|
hc keybind $Mod-Shift-r reload |
||||
|
hc keybind $Mod-Shift-c close |
||||
|
hc keybind $Mod-Return spawn "alacritty" # use your $TERMINAL with xterm as fallback |
||||
|
|
||||
|
# basic movement in tiling and floating mode |
||||
|
# focusing clients |
||||
|
hc keybind $Mod-Left focus left |
||||
|
hc keybind $Mod-Down focus down |
||||
|
hc keybind $Mod-Up focus up |
||||
|
hc keybind $Mod-Right focus right |
||||
|
hc keybind $Mod-h focus left |
||||
|
hc keybind $Mod-j focus down |
||||
|
hc keybind $Mod-k focus up |
||||
|
hc keybind $Mod-l focus right |
||||
|
|
||||
|
# moving clients in tiling and floating mode |
||||
|
hc keybind $Mod-Shift-Left shift left |
||||
|
hc keybind $Mod-Shift-Down shift down |
||||
|
hc keybind $Mod-Shift-Up shift up |
||||
|
hc keybind $Mod-Shift-Right shift right |
||||
|
hc keybind $Mod-Shift-h shift left |
||||
|
hc keybind $Mod-Shift-j shift down |
||||
|
hc keybind $Mod-Shift-k shift up |
||||
|
hc keybind $Mod-Shift-l shift right |
||||
|
|
||||
|
# splitting frames |
||||
|
# create an empty frame at the specified direction |
||||
|
hc keybind $Mod-u split bottom 0.5 |
||||
|
hc keybind $Mod-o split right 0.5 |
||||
|
# let the current frame explode into subframes |
||||
|
hc keybind $Mod-Control-space split explode |
||||
|
|
||||
|
# resizing frames and floating clients |
||||
|
resizestep=0.02 |
||||
|
hc keybind $Mod-Control-h resize left +$resizestep |
||||
|
hc keybind $Mod-Control-j resize down +$resizestep |
||||
|
hc keybind $Mod-Control-k resize up +$resizestep |
||||
|
hc keybind $Mod-Control-l resize right +$resizestep |
||||
|
hc keybind $Mod-Control-Left resize left +$resizestep |
||||
|
hc keybind $Mod-Control-Down resize down +$resizestep |
||||
|
hc keybind $Mod-Control-Up resize up +$resizestep |
||||
|
hc keybind $Mod-Control-Right resize right +$resizestep |
||||
|
|
||||
|
# tags |
||||
|
tag_names=( {1..9} ) |
||||
|
tag_keys=( {1..9} 0 ) |
||||
|
|
||||
|
hc rename default "${tag_names[0]}" || true |
||||
|
for i in "${!tag_names[@]}" ; do |
||||
|
hc add "${tag_names[$i]}" |
||||
|
key="${tag_keys[$i]}" |
||||
|
if [ -n "$key" ] ; then |
||||
|
hc keybind "$Mod-$key" use_index "$i" |
||||
|
hc keybind "$Mod-Shift-$key" move_index "$i" |
||||
|
fi |
||||
|
done |
||||
|
|
||||
|
# cycle through tags |
||||
|
hc keybind $Mod-period use_index +1 --skip-visible |
||||
|
hc keybind $Mod-comma use_index -1 --skip-visible |
||||
|
|
||||
|
# layouting |
||||
|
hc keybind $Mod-e rotate |
||||
|
hc keybind $Mod-r remove |
||||
|
hc keybind $Mod-s floating toggle |
||||
|
hc keybind $Mod-f fullscreen toggle |
||||
|
hc keybind $Mod-Shift-f set_attr clients.focus.floating toggle |
||||
|
hc keybind $Mod-Shift-d set_attr clients.focus.decorated toggle |
||||
|
hc keybind $Mod-Shift-m set_attr clients.focus.minimized true |
||||
|
hc keybind $Mod-Control-m jumpto last-minimized |
||||
|
hc keybind $Mod-p pseudotile toggle |
||||
|
# The following cycles through the available layouts within a frame, but skips |
||||
|
# layouts, if the layout change wouldn't affect the actual window positions. |
||||
|
# I.e. if there are two windows within a frame, the grid layout is skipped. |
||||
|
hc keybind $Mod-space \ |
||||
|
or , and . compare tags.focus.curframe_wcount = 2 \ |
||||
|
. cycle_layout +1 vertical horizontal max vertical grid \ |
||||
|
, cycle_layout +1 |
||||
|
|
||||
|
# mouseover |
||||
|
hc mouseunbind --all |
||||
|
hc mousebind $Mod-Button1 move |
||||
|
hc mousebind $Mod-Button2 zoom |
||||
|
hc mousebind $Mod-Button3 resize |
||||
|
|
||||
|
# focus |
||||
|
hc keybind $Mod-BackSpace cycle_monitor |
||||
|
hc keybind $Mod-Tab cycle_all +1 |
||||
|
hc keybind $Mod-Shift-Tab cycle_all -1 |
||||
|
hc keybind $Mod-c cycle |
||||
|
hc keybind $Mod-i jumpto urgent |
||||
|
|
||||
|
# theme |
||||
|
hc attr theme.tiling.reset 1 |
||||
|
hc attr theme.floating.reset 1 |
||||
|
hc set frame_border_active_color '#222222cc' |
||||
|
hc set frame_border_normal_color '#101010cc' |
||||
|
hc set frame_bg_normal_color '#565656aa' |
||||
|
hc set frame_bg_active_color '#345F0Caa' |
||||
|
hc set frame_border_width 1 |
||||
|
hc set always_show_frame on |
||||
|
hc set frame_bg_transparent on |
||||
|
hc set frame_transparent_width 5 |
||||
|
hc set frame_gap 4 |
||||
|
|
||||
|
hc attr theme.title_height 15 |
||||
|
hc attr theme.title_when always |
||||
|
hc attr theme.title_font 'Dejavu Sans:pixelsize=12' # example using Xft |
||||
|
# hc attr theme.title_font '-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*' |
||||
|
hc attr theme.title_depth 3 # space below the title's baseline |
||||
|
hc attr theme.active.color '#345F0Cef' |
||||
|
hc attr theme.title_color '#ffffff' |
||||
|
hc attr theme.normal.color '#323232dd' |
||||
|
hc attr theme.urgent.color '#7811A1dd' |
||||
|
hc attr theme.tab_color '#1F1F1Fdd' |
||||
|
hc attr theme.active.tab_color '#2B4F0Add' |
||||
|
hc attr theme.active.tab_outer_color '#6C8257dd' |
||||
|
hc attr theme.active.tab_title_color '#ababab' |
||||
|
hc attr theme.normal.title_color '#898989' |
||||
|
hc attr theme.inner_width 1 |
||||
|
hc attr theme.inner_color black |
||||
|
hc attr theme.border_width 3 |
||||
|
hc attr theme.floating.border_width 4 |
||||
|
hc attr theme.floating.outer_width 1 |
||||
|
hc attr theme.floating.outer_color black |
||||
|
hc attr theme.active.inner_color '#789161' |
||||
|
hc attr theme.urgent.inner_color '#9A65B0' |
||||
|
hc attr theme.normal.inner_color '#606060' |
||||
|
# copy inner color to outer_color |
||||
|
for state in active urgent normal ; do |
||||
|
hc substitute C theme.${state}.inner_color \ |
||||
|
attr theme.${state}.outer_color C |
||||
|
done |
||||
|
hc attr theme.tiling.outer_width 1 |
||||
|
hc attr theme.background_color '#141414' |
||||
|
|
||||
|
hc set window_gap 0 |
||||
|
hc set frame_padding 0 |
||||
|
hc set smart_window_surroundings off |
||||
|
hc set smart_frame_surroundings on |
||||
|
hc set mouse_recenter_gap 0 |
||||
|
|
||||
|
# rules |
||||
|
hc unrule -F |
||||
|
#hc rule class=XTerm tag=3 # move all xterms to tag 3 |
||||
|
hc rule focus=on # normally focus new clients |
||||
|
hc rule floatplacement=smart |
||||
|
#hc rule focus=off # normally do not focus new clients |
||||
|
# give focus to most common terminals |
||||
|
#hc rule class~'(.*[Rr]xvt.*|.*[Tt]erm|Konsole)' focus=on |
||||
|
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(DIALOG|UTILITY|SPLASH)' floating=on |
||||
|
hc rule windowtype='_NET_WM_WINDOW_TYPE_DIALOG' focus=on |
||||
|
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(NOTIFICATION|DOCK|DESKTOP)' manage=off |
||||
|
hc rule fixedsize floating=on |
||||
|
|
||||
|
hc rule class=Steam tag=8 |
||||
|
hc rule class=Lutris tag=8 |
||||
|
hc rule class=Signal tag=9 |
||||
|
hc rule class=thunderbird tag=9 |
||||
|
|
||||
|
hc set tree_style '╾│ ├└╼─┐' |
||||
|
|
||||
|
# unlock, just to be sure |
||||
|
hc unlock |
||||
|
|
||||
|
# do multi monitor setup here, e.g.: |
||||
|
# hc set_monitors 1280x1024+0+0 1280x1024+1280+0 |
||||
|
# or simply: |
||||
|
# hc detect_monitors |
||||
|
|
||||
|
# find the panel |
||||
|
panel=~/.config/herbstluftwm/panel.sh |
||||
|
[ -x "$panel" ] || panel=/etc/xdg/herbstluftwm/panel.sh |
||||
|
for monitor in $(hc list_monitors | cut -d: -f1) ; do |
||||
|
# start it on each monitor |
||||
|
"$panel" "$monitor" & |
||||
|
done |
||||
|
|
||||
|
hc keybind $Mod-d spawn ~/.config/polybar/scripts/launcher.sh |
||||
|
|
||||
|
hc keybind $Mod-minus spawn ~/.config/herbstluftwm/scripts/scratchpad.sh "hlwmScratch1" "st -n hlwmScratch1" |
||||
|
hc keybind $Mod-Alt-minus spawn ~/.config/herbstluftwm/scripts/scratchpad.sh "hlwmScratch2" "st -n hlwmScratch2" |
||||
|
# put this somewhere after 'hc unrule -F' line |
||||
|
hc rule instance~hlwmScratch.* floating=on floatplacement=center # float all instances which contains 'hlwmScratch' |
||||
|
|
||||
|
# screenshot |
||||
|
hc keybind Release-$Mod-Shift-p spawn scrot |
||||
|
|
||||
|
# autostart |
||||
|
hc spawn flameshot |
||||
|
hc spawn redshift-gtk |
||||
|
|
||||
|
~/.config/polybar/launch.sh |
||||
@ -0,0 +1,63 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
|
||||
|
# a i3-like scratchpad for arbitrary applications. |
||||
|
# |
||||
|
# this lets a new monitor called "scratchpad" appear in from the top into the |
||||
|
# current monitor. There the "scratchpad" will be shown (it will be created if |
||||
|
# it doesn't exist yet). If the monitor already exists it is scrolled out of |
||||
|
# the screen and removed again. |
||||
|
# |
||||
|
# Warning: this uses much resources because herbstclient is forked for each |
||||
|
# animation step. |
||||
|
# |
||||
|
# If a tag name is supplied, this is used instead of the scratchpad |
||||
|
|
||||
|
tag="${1:-scratchpad}" |
||||
|
hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} |
||||
|
|
||||
|
mrect=( $(hc monitor_rect "" ) ) |
||||
|
|
||||
|
width=${mrect[2]} |
||||
|
height=${mrect[3]} |
||||
|
|
||||
|
rect=( |
||||
|
$((width/2)) |
||||
|
$((height/2)) |
||||
|
$((${mrect[0]}+(width/4))) |
||||
|
$((${mrect[1]}+(height/4))) |
||||
|
) |
||||
|
|
||||
|
hc chain , add "$tag" , set_attr tags.by-name."$tag".at_end true |
||||
|
|
||||
|
monitor=scratchpad |
||||
|
|
||||
|
exists=false |
||||
|
if ! hc add_monitor $(printf "%dx%d%+d%+d" "${rect[@]}") \ |
||||
|
"$tag" $monitor 2> /dev/null ; then |
||||
|
exists=true |
||||
|
else |
||||
|
# remember which monitor was focused previously |
||||
|
hc chain \ |
||||
|
, new_attr string monitors.by-name."$monitor".my_prev_focus \ |
||||
|
, substitute M monitors.focus.index \ |
||||
|
set_attr monitors.by-name."$monitor".my_prev_focus M |
||||
|
fi |
||||
|
|
||||
|
show() { |
||||
|
hc lock |
||||
|
hc raise_monitor "$monitor" |
||||
|
hc focus_monitor "$monitor" |
||||
|
hc unlock |
||||
|
hc lock_tag "$monitor" |
||||
|
} |
||||
|
|
||||
|
hide() { |
||||
|
# if q3terminal still is focused, then focus the previously focused monitor |
||||
|
# (that mon which was focused when starting q3terminal) |
||||
|
hc substitute M monitors.by-name."$monitor".my_prev_focus \ |
||||
|
and + compare monitors.focus.name = "$monitor" \ |
||||
|
+ focus_monitor M |
||||
|
hc remove_monitor "$monitor" |
||||
|
} |
||||
|
|
||||
|
[ $exists = true ] && hide || show |
||||
@ -0,0 +1,46 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
set -e |
||||
|
# |
||||
|
# dependencies: |
||||
|
# |
||||
|
# - rofi |
||||
|
|
||||
|
# offer a window menu offering possible actions on that window like |
||||
|
# moving to a different tag or toggling its fullscreen state |
||||
|
|
||||
|
action_list() { |
||||
|
local a="$1" |
||||
|
"$a" "Close" herbstclient close |
||||
|
"$a" "Toggle fullscreen" herbstclient fullscreen toggle |
||||
|
"$a" "Toggle pseudotile" herbstclient pseudotile toggle |
||||
|
for tag in $(herbstclient complete 1 move) ; do |
||||
|
"$a" "Move to tag $tag" herbstclient move "$tag" |
||||
|
done |
||||
|
} |
||||
|
|
||||
|
print_menu() { |
||||
|
echo "$1" |
||||
|
} |
||||
|
|
||||
|
title=$(herbstclient attr clients.focus.title) |
||||
|
title=${title//&/&} |
||||
|
rofiflags=( |
||||
|
-p "herbstclient:" |
||||
|
-mesg "<i>$title</i>" |
||||
|
-columns 3 |
||||
|
-location 2 |
||||
|
-width 100 |
||||
|
-no-custom |
||||
|
) |
||||
|
result=$(action_list print_menu | rofi -i -dmenu -m -2 "${rofiflags[@]}") |
||||
|
[ $? -ne 0 ] && exit 0 |
||||
|
|
||||
|
exec_entry() { |
||||
|
if [ "$1" = "$result" ] ; then |
||||
|
shift |
||||
|
"$@" |
||||
|
exit 0 |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
action_list exec_entry |
||||
@ -0,0 +1 @@ |
|||||
|
lazy-lock.json |
||||
@ -0,0 +1,10 @@ |
|||||
|
set guifont=MesloLGL\ Nerd\ Font\ Mono,all-the-icons,file-icons:h11:#e-subpixelantialias:#h-full |
||||
|
set conceallevel=0 |
||||
|
let g:neovide_scroll_animation_length = 0 |
||||
|
let g:neovide_cursor_animation_length = 0 |
||||
|
let g:neovide_cursor_trail_size = 0 |
||||
|
let g:neovide_remember_window_size = v:false |
||||
|
|
||||
|
# vscode-neovim workaround: https://github.com/vscode-neovim/vscode-neovim/wiki/Plugins |
||||
|
highlight QuickScopePrimary guifg='#afff5f' gui=underline ctermfg=155 cterm=underline |
||||
|
highlight QuickScopeSecondary guifg='#5fffff' gui=underline ctermfg=81 cterm=underline |
||||
@ -0,0 +1 @@ |
|||||
|
require 'core' |
||||
@ -0,0 +1,37 @@ |
|||||
|
-- Autocommands |
||||
|
local autocmd = vim.api.nvim_create_autocmd |
||||
|
--local augroup = vim.api.nvim_create_augroup |
||||
|
--autocmd('VimEnter', { |
||||
|
-- group = augroup('start_screen', { clear = true }), |
||||
|
-- once = true, |
||||
|
-- callback = function() |
||||
|
-- require('start').start() |
||||
|
-- end, |
||||
|
--}) |
||||
|
--local misc_aucmds = augroup('misc_aucmds', { clear = true }) |
||||
|
--autocmd('BufWinEnter', { group = misc_aucmds, command = 'checktime' }) |
||||
|
--autocmd('TextYankPost', { |
||||
|
-- group = misc_aucmds, |
||||
|
-- callback = function() |
||||
|
-- vim.highlight.on_yank() |
||||
|
-- end, |
||||
|
--}) |
||||
|
--autocmd('FileType', { group = misc_aucmds, pattern = 'qf', command = 'set nobuflisted' }) |
||||
|
--vim.cmd [[silent! autocmd! FileExplorer *]] |
||||
|
--autocmd('BufEnter', { |
||||
|
-- pattern = '*', |
||||
|
-- callback = function(args) |
||||
|
-- local file_info = vim.loop.fs_stat(args.file) |
||||
|
-- if file_info and file_info.type == 'directory' then |
||||
|
-- require('neo-tree').setup {} |
||||
|
-- vim.cmd('Neotree position=current ' .. args.file) |
||||
|
-- end |
||||
|
-- end, |
||||
|
--}) |
||||
|
autocmd('BufReadPre', { |
||||
|
group = misc_aucmds, |
||||
|
callback = function() |
||||
|
require 'core.plugins.coding.lsp-zero' |
||||
|
end, |
||||
|
once = true, |
||||
|
}) |
||||
@ -0,0 +1,200 @@ |
|||||
|
---@type LazyVimConfig |
||||
|
local M = {} |
||||
|
|
||||
|
M.lazy_version = ">=9.1.0" |
||||
|
|
||||
|
---@class LazyVimConfig |
||||
|
local defaults = { |
||||
|
-- colorscheme can be a string like `catppuccin` or a function that will load the colorscheme |
||||
|
---@type string|fun() |
||||
|
colorscheme = function() |
||||
|
require("tokyonight").load() |
||||
|
end, |
||||
|
-- load the default settings |
||||
|
defaults = { |
||||
|
autocmds = true, -- lazyvim.config.autocmds |
||||
|
keymaps = true, -- lazyvim.config.keymaps |
||||
|
-- lazyvim.config.options can't be configured here since that's loaded before lazyvim setup |
||||
|
-- if you want to disable loading options, add `package.loaded["lazyvim.config.options"] = true` to the top of your init.lua |
||||
|
}, |
||||
|
-- icons used by other plugins |
||||
|
icons = { |
||||
|
dap = { |
||||
|
Stopped = { " ", "DiagnosticWarn", "DapStoppedLine" }, |
||||
|
Breakpoint = " ", |
||||
|
BreakpointCondition = " ", |
||||
|
BreakpointRejected = { " ", "DiagnosticError" }, |
||||
|
LogPoint = ".>", |
||||
|
}, |
||||
|
diagnostics = { |
||||
|
Error = " ", |
||||
|
Warn = " ", |
||||
|
Hint = " ", |
||||
|
Info = " ", |
||||
|
}, |
||||
|
git = { |
||||
|
added = " ", |
||||
|
modified = " ", |
||||
|
removed = " ", |
||||
|
}, |
||||
|
kinds = { |
||||
|
Array = " ", |
||||
|
Boolean = " ", |
||||
|
Class = " ", |
||||
|
Color = " ", |
||||
|
Constant = " ", |
||||
|
Constructor = " ", |
||||
|
Copilot = " ", |
||||
|
Enum = " ", |
||||
|
EnumMember = " ", |
||||
|
Event = " ", |
||||
|
Field = " ", |
||||
|
File = " ", |
||||
|
Folder = " ", |
||||
|
Function = " ", |
||||
|
Interface = " ", |
||||
|
Key = " ", |
||||
|
Keyword = " ", |
||||
|
Method = " ", |
||||
|
Module = " ", |
||||
|
Namespace = " ", |
||||
|
Null = " ", |
||||
|
Number = " ", |
||||
|
Object = " ", |
||||
|
Operator = " ", |
||||
|
Package = " ", |
||||
|
Property = " ", |
||||
|
Reference = " ", |
||||
|
Snippet = " ", |
||||
|
String = " ", |
||||
|
Struct = " ", |
||||
|
Text = " ", |
||||
|
TypeParameter = " ", |
||||
|
Unit = " ", |
||||
|
Value = " ", |
||||
|
Variable = " ", |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
M.renames = { |
||||
|
["windwp/nvim-spectre"] = "nvim-pack/nvim-spectre", |
||||
|
} |
||||
|
|
||||
|
---@type LazyVimConfig |
||||
|
local options |
||||
|
|
||||
|
---@param opts? LazyVimConfig |
||||
|
function M.setup(opts) |
||||
|
options = vim.tbl_deep_extend("force", defaults, opts or {}) |
||||
|
if not M.has() then |
||||
|
require("lazy.core.util").error( |
||||
|
"**LazyVim** needs **lazy.nvim** version " |
||||
|
.. M.lazy_version |
||||
|
.. " to work properly.\n" |
||||
|
.. "Please upgrade **lazy.nvim**", |
||||
|
{ title = "LazyVim" } |
||||
|
) |
||||
|
error("Exiting") |
||||
|
end |
||||
|
|
||||
|
if vim.fn.argc(-1) == 0 then |
||||
|
-- autocmds and keymaps can wait to load |
||||
|
vim.api.nvim_create_autocmd("User", { |
||||
|
group = vim.api.nvim_create_augroup("LazyVim", { clear = true }), |
||||
|
pattern = "VeryLazy", |
||||
|
callback = function() |
||||
|
M.load("autocmds") |
||||
|
M.load("keymaps") |
||||
|
end, |
||||
|
}) |
||||
|
else |
||||
|
-- load them now so they affect the opened buffers |
||||
|
M.load("autocmds") |
||||
|
M.load("keymaps") |
||||
|
end |
||||
|
|
||||
|
require("lazy.core.util").try(function() |
||||
|
if type(M.colorscheme) == "function" then |
||||
|
M.colorscheme() |
||||
|
else |
||||
|
vim.cmd.colorscheme(M.colorscheme) |
||||
|
end |
||||
|
end, { |
||||
|
msg = "Could not load your colorscheme", |
||||
|
on_error = function(msg) |
||||
|
require("lazy.core.util").error(msg) |
||||
|
vim.cmd.colorscheme("habamax") |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
---@param range? string |
||||
|
function M.has(range) |
||||
|
local Semver = require("lazy.manage.semver") |
||||
|
return Semver.range(range or M.lazy_version):matches(require("lazy.core.config").version or "0.0.0") |
||||
|
end |
||||
|
|
||||
|
---@param name "autocmds" | "options" | "keymaps" |
||||
|
function M.load(name) |
||||
|
local Util = require("lazy.core.util") |
||||
|
local function _load(mod) |
||||
|
Util.try(function() |
||||
|
require(mod) |
||||
|
end, { |
||||
|
msg = "Failed loading " .. mod, |
||||
|
on_error = function(msg) |
||||
|
local info = require("lazy.core.cache").find(mod) |
||||
|
if info == nil or (type(info) == "table" and #info == 0) then |
||||
|
return |
||||
|
end |
||||
|
Util.error(msg) |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
-- always load lazyvim, then user file |
||||
|
if M.defaults[name] or name == "options" then |
||||
|
_load("core.config." .. name) |
||||
|
end |
||||
|
_load("config." .. name) |
||||
|
if vim.bo.filetype == "lazy" then |
||||
|
-- HACK: LazyVim may have overwritten options of the Lazy ui, so reset this here |
||||
|
vim.cmd([[do VimResized]]) |
||||
|
end |
||||
|
local pattern = "pfke" .. name:sub(1, 1):upper() .. name:sub(2) |
||||
|
vim.api.nvim_exec_autocmds("User", { pattern = pattern, modeline = false }) |
||||
|
end |
||||
|
|
||||
|
M.did_init = false |
||||
|
function M.init() |
||||
|
if not M.did_init then |
||||
|
M.did_init = true |
||||
|
-- delay notifications till vim.notify was replaced or after 500ms |
||||
|
require("core.util").lazy_notify() |
||||
|
|
||||
|
-- load options here, before lazy init while sourcing plugin modules |
||||
|
-- this is needed to make sure options will be correctly applied |
||||
|
-- after installing missing plugins |
||||
|
require("core.config").load("options") |
||||
|
local Plugin = require("lazy.core.plugin") |
||||
|
local add = Plugin.Spec.add |
||||
|
Plugin.Spec.add = function(self, plugin, ...) |
||||
|
if type(plugin) == "table" and M.renames[plugin[1]] then |
||||
|
plugin[1] = M.renames[plugin[1]] |
||||
|
end |
||||
|
return add(self, plugin, ...) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
setmetatable(M, { |
||||
|
__index = function(_, key) |
||||
|
if options == nil then |
||||
|
return vim.deepcopy(defaults)[key] |
||||
|
end |
||||
|
---@cast options LazyVimConfig |
||||
|
return options[key] |
||||
|
end, |
||||
|
}) |
||||
|
|
||||
|
return M |
||||
@ -0,0 +1,53 @@ |
|||||
|
-- Keybindings |
||||
|
local silent = { silent = true, noremap = true } |
||||
|
|
||||
|
-- Quit, close buffers, etc. |
||||
|
vim.keymap.set('n', '<leader>q', '<cmd>qa<cr>', silent) |
||||
|
vim.keymap.set('n', '<leader>x', '<cmd>x!<cr>', silent) |
||||
|
vim.keymap.set('n', '<leader>d', '<cmd>BufDel<cr>', { silent = true, nowait = true, noremap = true }) |
||||
|
|
||||
|
-- Save buffer |
||||
|
vim.keymap.set('i', '<c-s>', '<esc><cmd>w<cr>a', silent) |
||||
|
vim.keymap.set('n', '<leader>w', '<cmd>w<cr>', silent) |
||||
|
|
||||
|
-- Yank to clipboard |
||||
|
vim.keymap.set('n', 'y+', '<cmd>set opfunc=util#clipboard_yank<cr>g@', silent) |
||||
|
vim.keymap.set('v', 'y+', '<cmd>set opfunc=util#clipboard_yank<cr>g@', silent) |
||||
|
|
||||
|
-- movement |
||||
|
-- scroll half screen down and center |
||||
|
vim.keymap.set('n', '<c-u>', '<c-u>zz', silent) |
||||
|
vim.keymap.set('n', '<c-d>', '<c-d>zz', silent) |
||||
|
-- indent line and move one line down |
||||
|
vim.keymap.set('n', '==', '==j', silent) |
||||
|
|
||||
|
-- Window movement |
||||
|
vim.keymap.set('n', '<c-h>', '<c-w>h', silent) |
||||
|
vim.keymap.set('n', '<c-j>', '<c-w>j', silent) |
||||
|
vim.keymap.set('n', '<c-k>', '<c-w>k', silent) |
||||
|
vim.keymap.set('n', '<c-l>', '<c-w>l', silent) |
||||
|
|
||||
|
-- Tab movement |
||||
|
vim.keymap.set('n', '<a-Left>', '<cmd>tabpre<cr>', silent) |
||||
|
vim.keymap.set('n', '<a-Right>', '<cmd>tabnext<cr>', silent) |
||||
|
|
||||
|
-- search |
||||
|
vim.keymap.set('n', '<Esc><Esc>', '<cmd>nohlsearch<cr>', { silent = true, nowait = true, noremap = true }) |
||||
|
|
||||
|
-- Make relative line jumps store jumplist locations |
||||
|
vim.keymap.set('n', 'k', function() |
||||
|
if vim.v.count > 1 then |
||||
|
return [[m']] .. vim.v.count .. 'k' |
||||
|
end |
||||
|
|
||||
|
return 'k' |
||||
|
end, { expr = true, silent = true }) |
||||
|
|
||||
|
vim.keymap.set('n', 'j', function() |
||||
|
if vim.v.count > 1 then |
||||
|
return [[m']] .. vim.v.count .. 'j' |
||||
|
end |
||||
|
|
||||
|
return 'j' |
||||
|
end, { expr = true, silent = true }) |
||||
|
|
||||
@ -0,0 +1,73 @@ |
|||||
|
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' |
||||
|
if not vim.loop.fs_stat(lazypath) then |
||||
|
-- bootstrap lazy.nvim |
||||
|
-- stylua: ignore |
||||
|
vim.fn.system({ 'git', 'clone', '--filter=blob:none', '--branch=stable', 'https://github.com/folke/lazy.nvim.git', lazypath }) |
||||
|
end |
||||
|
vim.opt.runtimepath:prepend(lazypath) |
||||
|
-- Leader/local leader - lazy.nvim needs these set first |
||||
|
vim.g.mapleader = [[,]] |
||||
|
vim.g.maplocalleader = [[,]] |
||||
|
|
||||
|
require('lazy').setup({ |
||||
|
spec = { |
||||
|
{ import = "core.plugins.coding" }, |
||||
|
{ import = "core.plugins.coding.dap" }, |
||||
|
{ import = "core.plugins.coding.test" }, |
||||
|
{ import = "core.plugins.editor" }, |
||||
|
{ import = "core.plugins.ui" }, |
||||
|
{ import = "core.plugins.util" }, |
||||
|
}, |
||||
|
defaults = { |
||||
|
-- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. |
||||
|
-- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. |
||||
|
lazy = false, |
||||
|
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning, |
||||
|
-- have outdated releases, which may break your Neovim install. |
||||
|
version = false, -- always use the latest git commit |
||||
|
-- version = "*", -- try installing the latest stable version for plugins that support semver |
||||
|
}, |
||||
|
install = { |
||||
|
missing = true, |
||||
|
colorscheme = { "tokyonight-night", "carbonfox" }, |
||||
|
}, |
||||
|
checker = { |
||||
|
enabled = true, -- automatically check for plugin updates |
||||
|
concurrency = nil, ---@type number? set to 1 to check for updates very slowly |
||||
|
notify = false, -- get a notification when new updates are found |
||||
|
frequency = 3600, -- check for updates every hour |
||||
|
}, |
||||
|
change_detection = { |
||||
|
enabled = false, |
||||
|
notify = false, |
||||
|
}, |
||||
|
performance = { |
||||
|
cache = { |
||||
|
enabled = true, |
||||
|
}, |
||||
|
reset_packpath = true, -- reset the package path to improve startup time |
||||
|
rtp = { |
||||
|
disabled_plugins = { |
||||
|
'gzip', |
||||
|
--'matchit', |
||||
|
--'matchparen', |
||||
|
--'netrwPlugin', |
||||
|
'tarPlugin', |
||||
|
'tohtml', |
||||
|
'tutor', |
||||
|
'zipPlugin', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
-- lazy can generate helptags from the headings in markdown readme files, |
||||
|
-- so :help works even for plugins that don't have vim docs. |
||||
|
-- when the readme opens with :help it will be correctly displayed as markdown |
||||
|
readme = { |
||||
|
enabled = true, |
||||
|
root = vim.fn.stdpath("state") .. "/lazy/readme", |
||||
|
files = { "README.md", "lua/**/README.md" }, |
||||
|
-- only generate markdown helptags for plugins that dont have docs |
||||
|
skip_if_doc_exists = true, |
||||
|
}, |
||||
|
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things |
||||
|
}) |
||||
@ -0,0 +1,98 @@ |
|||||
|
-- Settings |
||||
|
vim.opt.backup = false -- creates a backup file |
||||
|
vim.opt.clipboard = "unnamedplus" -- allows neovim to access the system clipboard |
||||
|
vim.opt.cmdheight = 1 -- more space in the neovim command line for displaying messages |
||||
|
vim.opt.completeopt = { "menuone", "noselect" } -- mostly just for cmp |
||||
|
vim.opt.conceallevel = 0 -- so that `` is visible in markdown files |
||||
|
vim.opt.fileencoding = "utf-8" -- the encoding written to a file |
||||
|
vim.opt.hlsearch = true -- highlight all matches on previous search pattern |
||||
|
vim.opt.ignorecase = true -- ignore case in search patterns |
||||
|
vim.opt.smartcase = true -- smart case |
||||
|
vim.opt.wrapscan = true -- loop search back to beginning |
||||
|
vim.opt.smartindent = true -- make indenting smarter again |
||||
|
vim.opt.splitbelow = true -- force all horizontal splits to go below current window |
||||
|
vim.opt.splitright = true -- force all vertical splits to go to the right of current window |
||||
|
vim.opt.swapfile = false -- creates a swapfile |
||||
|
vim.opt.termguicolors = true -- set term gui colors (most terminals support this) |
||||
|
vim.opt.timeoutlen = 1000 -- time to wait for a mapped sequence to complete (in milliseconds) |
||||
|
vim.opt.undofile = true -- enable persistent undo |
||||
|
vim.opt.updatetime = 300 -- faster completion (4000ms default) |
||||
|
vim.opt.writebackup = false -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited |
||||
|
vim.opt.expandtab = true -- convert tabs to spaces |
||||
|
vim.opt.shiftwidth = 4 -- the number of spaces inserted for each indentation |
||||
|
vim.opt.tabstop = 4 -- insert 4 spaces for a tab |
||||
|
--vim.opt.cursorline = true -- highlight the current line |
||||
|
vim.opt.relativenumber = true -- set numbered lines |
||||
|
vim.opt.laststatus = 3 -- only the last window will always have a status line |
||||
|
vim.opt.showcmd = false -- hide (partial) command in the last line of the screen (for performance) |
||||
|
vim.opt.numberwidth = 4 -- minimal number of columns to use for the line number {default 4} |
||||
|
--vim.opt.signcolumn = "yes:3" -- always show the sign column, otherwise it would shift the text each time |
||||
|
vim.opt.wrap = false -- display lines as one long line |
||||
|
vim.opt.scrolloff = 8 -- minimal number of screen lines to keep above and below the cursor |
||||
|
vim.opt.sidescrolloff = 8 -- minimal number of screen columns to keep to the left and right of the cursor if wrap is `false` |
||||
|
--vim.opt.whichwrap:append("<,>,[,],h,l") -- keys allowed to move to the previous/next line when the beginning/end of line is reached |
||||
|
--vim.opt.iskeyword:append("-") -- treats words with `-` as single words |
||||
|
vim.opt.formatoptions:remove({ "c", "r", "o" }) -- This is a sequence of letters which describes how automatic formatting is to be done |
||||
|
vim.opt.linebreak = true -- Enable line breaks |
||||
|
--vim.opt.colorcolumn = "120" -- side column |
||||
|
vim.opt.wildmenu=true -- completion of commands |
||||
|
vim.opt.wildignorecase=true -- case insensitive completion |
||||
|
vim.opt.wildmode = "longest,full,full" -- how the completion is done |
||||
|
vim.opt.wildignore = ".git,.hg,.svn,*.pyc,*.o,*.out,*.jpg,*.jpeg,*.png,*.gif,*.zip,**/tmp/**,*.DS_Store,**/node_modules/**,**/bower_modules/**" |
||||
|
-- |
||||
|
vim.opt.textwidth = 100 |
||||
|
vim.opt.inccommand = 'nosplit' |
||||
|
-- vim.opt.lazyredraw = true |
||||
|
vim.opt.showmatch = true |
||||
|
vim.opt.softtabstop = 0 |
||||
|
vim.opt.number = true |
||||
|
vim.opt.smartindent = true |
||||
|
vim.opt.showmode = false |
||||
|
vim.opt.shada = [['20,<50,s10,h,/100]] |
||||
|
vim.opt.hidden = true |
||||
|
|
||||
|
|
||||
|
-- flag meaning when present |
||||
|
-- f use "(3 of 5)" instead of "(file 3 of 5)" |
||||
|
-- i use "[noeol]" instead of "[Incomplete last line]" |
||||
|
-- l use "999L, 888B" instead of "999 lines, 888 bytes" |
||||
|
-- m use "[+]" instead of "[Modified]" |
||||
|
-- n use "[New]" instead of "[New File]" |
||||
|
-- r use "[RO]" instead of "[readonly]" |
||||
|
-- w use "[w]" instead of "written" for file write message and "[a]" instead of "appended" for ':w >> file' command |
||||
|
-- x use "[dos]" instead of "[dos format]", "[unix]" instead of "[unix format]" and "[mac]" instead of "[mac format]" |
||||
|
-- a all of the above abbreviations |
||||
|
-- o overwrite message for writing a file with subsequent message for reading a file (useful for ":wn" or when 'autowrite' on) |
||||
|
-- O message for reading a file overwrites any previous message; also for quickfix message (e.g., ":cn") |
||||
|
-- s don't give "search hit BOTTOM, continuing at TOP" or "search hit TOP, continuing at BOTTOM" messages; when using the search count do not show "W" after the count message (see S below) |
||||
|
-- t truncate file message at the start if it is too long to fit on the command-line, "<" will appear in the left most column; ignored in Ex mode |
||||
|
-- T truncate other messages in the middle if they are too long to fit on the command line; "..." will appear in the middle; ignored in Ex mode |
||||
|
-- W don't give "written" or "[w]" when writing a file A don't give the "ATTENTION" message when an existing swap file is found |
||||
|
-- I don't give the intro message when starting Vim, see |:intro| |
||||
|
-- c don't give |ins-completion-menu| messages; for example, "-- XXX completion (YYY)", "match 1 of 2", "The only match", "Pattern not found", "Back at original", etc. |
||||
|
-- C don't give messages while scanning for ins-completion items, for instance "scanning tags" |
||||
|
-- q use "recording" instead of "recording @a" |
||||
|
-- F don't give the file info when editing a file, like `:silent` was used for the command |
||||
|
-- S do not show search count message when searching, e.g. "[1/5]" |
||||
|
--= "fixtToOFWs" |
||||
|
vim.opt.shortmess = vim.opt.shortmess + { |
||||
|
s = true, |
||||
|
} |
||||
|
|
||||
|
vim.opt.joinspaces = false |
||||
|
vim.opt.guicursor = [[n-v-c:block,i-ci-ve:ver25,r-cr:hor20,o:hor50]] |
||||
|
vim.opt.updatetime = 100 |
||||
|
vim.opt.conceallevel = 2 |
||||
|
vim.opt.concealcursor = 'nc' |
||||
|
vim.opt.previewheight = 5 |
||||
|
vim.opt.undofile = true |
||||
|
vim.opt.synmaxcol = 500 |
||||
|
vim.opt.display = 'msgsep' |
||||
|
vim.opt.modeline = false |
||||
|
vim.opt.mouse = 'nivh' |
||||
|
vim.opt.cmdheight = 0 |
||||
|
vim.opt.splitbelow = true |
||||
|
vim.opt.splitright = true |
||||
|
vim.opt.timeoutlen = 400 |
||||
|
vim.opt.fillchars = [[vert:│,horiz:─,eob: ]] |
||||
|
vim.opt.switchbuf = 'useopen,uselast' |
||||
@ -0,0 +1,4 @@ |
|||||
|
require "core.config.options" |
||||
|
require "core.config.keymaps" |
||||
|
require "core.config.lazy" |
||||
|
require "core.config.autocmds" |
||||
@ -0,0 +1,133 @@ |
|||||
|
return { |
||||
|
-- copilot |
||||
|
{ |
||||
|
"zbirenbaum/copilot.lua", |
||||
|
cmd = "Copilot", |
||||
|
build = ":Copilot auth", |
||||
|
opts = { |
||||
|
suggestion = { |
||||
|
enabled = true, |
||||
|
auto_trigger = false, |
||||
|
debounce = 75, |
||||
|
keymap = { |
||||
|
accept = "<C-l>", |
||||
|
accept_word = false, |
||||
|
accept_line = false, |
||||
|
next = "<C-n>", |
||||
|
prev = "<C-p>", |
||||
|
dismiss = "<C-A-l>", |
||||
|
}, |
||||
|
}, |
||||
|
panel = { enabled = false }, |
||||
|
filetypes = { |
||||
|
bash = true, |
||||
|
c = true, |
||||
|
clojure = true, |
||||
|
cmake = true, |
||||
|
cpp = true, |
||||
|
css = true, |
||||
|
gdb = true, |
||||
|
go = true, |
||||
|
html = true, |
||||
|
java = true, |
||||
|
javascript = true, |
||||
|
json = true, |
||||
|
lua = true, |
||||
|
make = true, |
||||
|
perl = true, |
||||
|
python = true, |
||||
|
ruby = true, |
||||
|
rust = true, |
||||
|
scala = true, |
||||
|
sh = true, |
||||
|
svg = true, |
||||
|
typescript = true, |
||||
|
xml = true, |
||||
|
["*"] = false, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
"nvim-lualine/lualine.nvim", |
||||
|
optional = true, |
||||
|
event = "VeryLazy", |
||||
|
opts = function(_, opts) |
||||
|
local Util = require("core.util") |
||||
|
local colors = { |
||||
|
[""] = Util.fg("Special"), |
||||
|
["Normal"] = Util.fg("Special"), |
||||
|
["Warning"] = Util.fg("DiagnosticError"), |
||||
|
["InProgress"] = Util.fg("DiagnosticWarn"), |
||||
|
} |
||||
|
opts.sections = opts.sections or {} |
||||
|
opts.sections.lualine_x = opts.sections.lualine_x or {} |
||||
|
table.insert(opts.sections.lualine_x, 2, { |
||||
|
function() |
||||
|
local icon = require("core.config").icons.kinds.Copilot |
||||
|
local status = require("copilot.api").status.data |
||||
|
return icon .. (status.message or "") |
||||
|
end, |
||||
|
cond = function() |
||||
|
local ok, clients = pcall(vim.lsp.get_active_clients, { name = "copilot", bufnr = 0 }) |
||||
|
return ok and #clients > 0 |
||||
|
end, |
||||
|
color = function() |
||||
|
if not package.loaded["copilot"] then |
||||
|
return |
||||
|
end |
||||
|
local status = require("copilot.api").status.data |
||||
|
return colors[status.status] or colors[""] |
||||
|
end, |
||||
|
}) |
||||
|
end, |
||||
|
}, |
||||
|
|
||||
|
-- copilot cmp source |
||||
|
{ |
||||
|
"nvim-cmp", |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"zbirenbaum/copilot-cmp", |
||||
|
dependencies = "copilot.lua", |
||||
|
opts = {}, |
||||
|
config = function(_, opts) |
||||
|
local copilot_cmp = require("copilot_cmp") |
||||
|
copilot_cmp.setup(opts) |
||||
|
-- attach cmp source whenever copilot attaches |
||||
|
-- fixes lazy-loading issues with the copilot cmp source |
||||
|
require("core.util").on_attach(function(client) |
||||
|
if client.name == "copilot" then |
||||
|
--copilot_cmp._on_insert_enter({}) |
||||
|
end |
||||
|
end) |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
-- @param opts cmp.ConfigSchema |
||||
|
opts = function(_, opts) |
||||
|
local cmp = require("cmp") |
||||
|
|
||||
|
opts.sources = opts.sources or {} |
||||
|
table.insert(opts.sources, 1, { name = "copilot", group_index = 2 }) |
||||
|
|
||||
|
opts.sorting = { |
||||
|
priority_weight = 2, |
||||
|
comparators = { |
||||
|
require("copilot_cmp.comparators").prioritize, |
||||
|
|
||||
|
-- Below is the default comparitor list and order for nvim-cmp |
||||
|
cmp.config.compare.offset, |
||||
|
-- cmp.config.compare.scopes, --this is commented in nvim-cmp too |
||||
|
cmp.config.compare.exact, |
||||
|
cmp.config.compare.score, |
||||
|
cmp.config.compare.recently_used, |
||||
|
cmp.config.compare.locality, |
||||
|
cmp.config.compare.kind, |
||||
|
cmp.config.compare.sort_text, |
||||
|
cmp.config.compare.length, |
||||
|
cmp.config.compare.order, |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,104 @@ |
|||||
|
return { |
||||
|
"mfussenegger/nvim-dap", |
||||
|
|
||||
|
dependencies = { |
||||
|
|
||||
|
-- fancy UI for the debugger |
||||
|
{ |
||||
|
"rcarriga/nvim-dap-ui", |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>du", function() require("dapui").toggle({ }) end, desc = "Dap UI" }, |
||||
|
{ "<leader>de", function() require("dapui").eval() end, desc = "Eval", mode = {"n", "v"} }, |
||||
|
}, |
||||
|
opts = {}, |
||||
|
config = function(_, opts) |
||||
|
local dap = require("dap") |
||||
|
local dapui = require("dapui") |
||||
|
dapui.setup(opts) |
||||
|
dap.listeners.after.event_initialized["dapui_config"] = function() |
||||
|
dapui.open({}) |
||||
|
end |
||||
|
dap.listeners.before.event_terminated["dapui_config"] = function() |
||||
|
dapui.close({}) |
||||
|
end |
||||
|
dap.listeners.before.event_exited["dapui_config"] = function() |
||||
|
dapui.close({}) |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
|
||||
|
-- virtual text for the debugger |
||||
|
{ |
||||
|
"theHamsta/nvim-dap-virtual-text", |
||||
|
opts = {}, |
||||
|
}, |
||||
|
|
||||
|
-- which key integration |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>d"] = { name = "+debug" }, |
||||
|
["<leader>da"] = { name = "+adapters" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
-- mason.nvim integration |
||||
|
{ |
||||
|
"jay-babu/mason-nvim-dap.nvim", |
||||
|
dependencies = "mason.nvim", |
||||
|
cmd = { "DapInstall", "DapUninstall" }, |
||||
|
opts = { |
||||
|
-- Makes a best effort to setup the various debuggers with |
||||
|
-- reasonable debug configurations |
||||
|
automatic_installation = true, |
||||
|
|
||||
|
-- You can provide additional configuration to the handlers, |
||||
|
-- see mason-nvim-dap README for more information |
||||
|
handlers = {}, |
||||
|
|
||||
|
-- You'll need to check that you have the required things installed |
||||
|
-- online, please don't ask me how to install them :) |
||||
|
ensure_installed = { |
||||
|
-- Update this to ensure that you have the debuggers for the langs you want |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>dB", function() require("dap").set_breakpoint(vim.fn.input('Breakpoint condition: ')) end, desc = "Breakpoint Condition" }, |
||||
|
{ "<leader>db", function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint" }, |
||||
|
{ "<leader>dc", function() require("dap").continue() end, desc = "Continue" }, |
||||
|
{ "<leader>dC", function() require("dap").run_to_cursor() end, desc = "Run to Cursor" }, |
||||
|
{ "<leader>dg", function() require("dap").goto_() end, desc = "Go to line (no execute)" }, |
||||
|
{ "<leader>di", function() require("dap").step_into() end, desc = "Step Into" }, |
||||
|
{ "<leader>dj", function() require("dap").down() end, desc = "Down" }, |
||||
|
{ "<leader>dk", function() require("dap").up() end, desc = "Up" }, |
||||
|
{ "<leader>dl", function() require("dap").run_last() end, desc = "Run Last" }, |
||||
|
{ "<leader>do", function() require("dap").step_out() end, desc = "Step Out" }, |
||||
|
{ "<leader>dO", function() require("dap").step_over() end, desc = "Step Over" }, |
||||
|
{ "<leader>dp", function() require("dap").pause() end, desc = "Pause" }, |
||||
|
{ "<leader>dr", function() require("dap").repl.toggle() end, desc = "Toggle REPL" }, |
||||
|
{ "<leader>ds", function() require("dap").session() end, desc = "Session" }, |
||||
|
{ "<leader>dt", function() require("dap").terminate() end, desc = "Terminate" }, |
||||
|
{ "<leader>dw", function() require("dap.ui.widgets").hover() end, desc = "Widgets" }, |
||||
|
}, |
||||
|
|
||||
|
config = function() |
||||
|
local Config = require("core.config") |
||||
|
vim.api.nvim_set_hl(0, "DapStoppedLine", { default = true, link = "Visual" }) |
||||
|
|
||||
|
for name, sign in pairs(Config.icons.dap) do |
||||
|
sign = type(sign) == "table" and sign or { sign } |
||||
|
vim.fn.sign_define( |
||||
|
"Dap" .. name, |
||||
|
{ text = sign[1], texthl = sign[2] or "DiagnosticInfo", linehl = sign[3], numhl = sign[3] } |
||||
|
) |
||||
|
end |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
return { |
||||
|
"mfussenegger/nvim-dap", |
||||
|
|
||||
|
dependencies = { |
||||
|
{ |
||||
|
"jbyuki/one-small-step-for-vimkind", |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>daL", function() require("osv").launch({ port = 8086 }) end, desc = "Adapter Lua Server" }, |
||||
|
{ "<leader>dal", function() require("osv").run_this() end, desc = "Adapter Lua" }, |
||||
|
}, |
||||
|
config = function() |
||||
|
local dap = require("dap") |
||||
|
dap.adapters.nlua = function(callback, config) |
||||
|
callback({ type = "server", host = config.host or "127.0.0.1", port = config.port or 8086 }) |
||||
|
end |
||||
|
dap.configurations.lua = { |
||||
|
{ |
||||
|
type = "nlua", |
||||
|
request = "attach", |
||||
|
name = "Attach to running Neovim instance", |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
-- Standalone UI for nvim-lsp progress |
||||
|
return { |
||||
|
'j-hui/fidget.nvim', |
||||
|
version = "legacy", |
||||
|
} |
||||
@ -0,0 +1,110 @@ |
|||||
|
-- lsp-zero |
||||
|
return { |
||||
|
'VonHeikemen/lsp-zero.nvim', |
||||
|
branch = 'v3.x', |
||||
|
dependencies = { |
||||
|
-- LSP Support |
||||
|
{ |
||||
|
'neovim/nvim-lspconfig', -- Required |
||||
|
event = { "BufReadPre", "BufNewFile" }, |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"SmiteshP/nvim-navbuddy", |
||||
|
dependencies = { |
||||
|
"SmiteshP/nvim-navic", |
||||
|
"MunifTanjim/nui.nvim" |
||||
|
}, |
||||
|
opts = { lsp = { auto_attach = true } } |
||||
|
}, |
||||
|
{ "folke/neoconf.nvim", cmd = "Neoconf", config = true }, |
||||
|
{ "folke/neodev.nvim", opts = {} }, |
||||
|
}, |
||||
|
}, |
||||
|
{ -- Optional |
||||
|
'williamboman/mason.nvim', |
||||
|
build = ":MasonUpdate", |
||||
|
}, |
||||
|
{ |
||||
|
'williamboman/mason-lspconfig.nvim', -- Optional |
||||
|
opts = { |
||||
|
automatic_installation = true, |
||||
|
} |
||||
|
}, |
||||
|
{'simrat39/rust-tools.nvim'}, |
||||
|
|
||||
|
-- Autocompletion |
||||
|
{'hrsh7th/nvim-cmp'}, -- Required |
||||
|
{ |
||||
|
'hrsh7th/cmp-nvim-lsp', -- Required |
||||
|
cond = function() |
||||
|
return require("core.util").has("nvim-cmp") |
||||
|
end, |
||||
|
}, |
||||
|
{'L3MON4D3/LuaSnip'}, -- Required |
||||
|
{'hrsh7th/cmp-path'}, -- gives completions based on the filesystem |
||||
|
{'hrsh7th/cmp-buffer'}, -- provides suggestions based on the current file |
||||
|
{'saadparwaiz1/cmp_luasnip'}, -- it shows snippets loaded by luasnip |
||||
|
{'rafamadriz/friendly-snippets'}, -- external collection of snippets |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
local lsp = require('lsp-zero') |
||||
|
lsp.extend_lspconfig() |
||||
|
|
||||
|
require("mason").setup() |
||||
|
require("mason-lspconfig").setup() |
||||
|
require("mason-lspconfig").setup_handlers { |
||||
|
-- The first entry (without a key) will be the default handler |
||||
|
-- and will be called for each installed server that doesn't have |
||||
|
-- a dedicated handler. |
||||
|
function (server_name) -- default handler (optional) |
||||
|
require("lspconfig")[server_name].setup {} |
||||
|
end, |
||||
|
-- Next, you can provide a dedicated handler for specific servers. |
||||
|
-- For example, a handler override for the `rust_analyzer`: |
||||
|
["rust_analyzer"] = function () |
||||
|
require("rust-tools").setup {} |
||||
|
end, |
||||
|
} |
||||
|
|
||||
|
lsp.preset({}) |
||||
|
|
||||
|
lsp.on_attach(function(_, bufnr) |
||||
|
lsp.default_keymaps({buffer = bufnr}) |
||||
|
end) |
||||
|
|
||||
|
-- (Optional) Configure lua language server for neovim |
||||
|
require('lspconfig').lua_ls.setup(lsp.nvim_lua_ls()) |
||||
|
|
||||
|
lsp.setup() |
||||
|
|
||||
|
local capabilities = vim.lsp.protocol.make_client_capabilities() |
||||
|
capabilities.offsetEncoding = { "utf-16" } |
||||
|
require("lspconfig").clangd.setup({ capabilities = capabilities }) |
||||
|
|
||||
|
local Util = require("core.util") |
||||
|
-- setup autoformat |
||||
|
--require("core.plugins.coding.lsp.format").setup(opts) |
||||
|
-- setup formatting and keymaps |
||||
|
--Util.on_attach(function(client, buffer) |
||||
|
--require("core.plugins.coding.lsp.keymaps").on_attach(client, buffer) |
||||
|
--end) |
||||
|
|
||||
|
local cmp = require('cmp') |
||||
|
local cmp_action = require('lsp-zero').cmp_action() |
||||
|
|
||||
|
require('luasnip.loaders.from_vscode').lazy_load() |
||||
|
|
||||
|
cmp.setup({ |
||||
|
sources = { |
||||
|
{name = 'path'}, |
||||
|
{name = 'nvim_lsp'}, |
||||
|
{name = 'buffer', keyword_length = 3}, |
||||
|
{name = 'luasnip', keyword_length = 2}, |
||||
|
}, |
||||
|
mapping = { |
||||
|
['<C-f>'] = cmp_action.luasnip_jump_forward(), |
||||
|
['<C-b>'] = cmp_action.luasnip_jump_backward(), |
||||
|
} |
||||
|
}) |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,152 @@ |
|||||
|
local Util = require("lazy.core.util") |
||||
|
|
||||
|
local M = {} |
||||
|
|
||||
|
---@type PluginLspOpts |
||||
|
M.opts = nil |
||||
|
|
||||
|
function M.enabled() |
||||
|
return M.opts.autoformat |
||||
|
end |
||||
|
|
||||
|
function M.toggle() |
||||
|
if vim.b.autoformat == false then |
||||
|
vim.b.autoformat = nil |
||||
|
M.opts.autoformat = true |
||||
|
else |
||||
|
M.opts.autoformat = not M.opts.autoformat |
||||
|
end |
||||
|
if M.opts.autoformat then |
||||
|
Util.info("Enabled format on save", { title = "Format" }) |
||||
|
else |
||||
|
Util.warn("Disabled format on save", { title = "Format" }) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
---@param opts? {force?:boolean} |
||||
|
function M.format(opts) |
||||
|
local buf = vim.api.nvim_get_current_buf() |
||||
|
if vim.b.autoformat == false and not (opts and opts.force) then |
||||
|
return |
||||
|
end |
||||
|
|
||||
|
local formatters = M.get_formatters(buf) |
||||
|
local client_ids = vim.tbl_map(function(client) |
||||
|
return client.id |
||||
|
end, formatters.active) |
||||
|
|
||||
|
if #client_ids == 0 then |
||||
|
return |
||||
|
end |
||||
|
|
||||
|
if M.opts.format_notify then |
||||
|
M.notify(formatters) |
||||
|
end |
||||
|
|
||||
|
vim.lsp.buf.format(vim.tbl_deep_extend("force", { |
||||
|
bufnr = buf, |
||||
|
filter = function(client) |
||||
|
return vim.tbl_contains(client_ids, client.id) |
||||
|
end, |
||||
|
}, require("core.util").opts("nvim-lspconfig").format or {})) |
||||
|
end |
||||
|
|
||||
|
---@param formatters LazyVimFormatters |
||||
|
function M.notify(formatters) |
||||
|
local lines = { "# Active:" } |
||||
|
|
||||
|
for _, client in ipairs(formatters.active) do |
||||
|
local line = "- **" .. client.name .. "**" |
||||
|
if client.name == "null-ls" then |
||||
|
line = line |
||||
|
.. " (" |
||||
|
.. table.concat( |
||||
|
vim.tbl_map(function(f) |
||||
|
return "`" .. f.name .. "`" |
||||
|
end, formatters.null_ls), |
||||
|
", " |
||||
|
) |
||||
|
.. ")" |
||||
|
end |
||||
|
table.insert(lines, line) |
||||
|
end |
||||
|
|
||||
|
if #formatters.available > 0 then |
||||
|
table.insert(lines, "") |
||||
|
table.insert(lines, "# Disabled:") |
||||
|
for _, client in ipairs(formatters.available) do |
||||
|
table.insert(lines, "- **" .. client.name .. "**") |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO, { |
||||
|
title = "Formatting", |
||||
|
on_open = function(win) |
||||
|
vim.api.nvim_win_set_option(win, "conceallevel", 3) |
||||
|
vim.api.nvim_win_set_option(win, "spell", false) |
||||
|
local buf = vim.api.nvim_win_get_buf(win) |
||||
|
vim.treesitter.start(buf, "markdown") |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
-- Gets all lsp clients that support formatting. |
||||
|
-- When a null-ls formatter is available for the current filetype, |
||||
|
-- only null-ls formatters are returned. |
||||
|
function M.get_formatters(bufnr) |
||||
|
local ft = vim.bo[bufnr].filetype |
||||
|
-- check if we have any null-ls formatters for the current filetype |
||||
|
local null_ls = package.loaded["null-ls"] and require("null-ls.sources").get_available(ft, "NULL_LS_FORMATTING") or {} |
||||
|
|
||||
|
---@class LazyVimFormatters |
||||
|
local ret = { |
||||
|
---@type lsp.Client[] |
||||
|
active = {}, |
||||
|
---@type lsp.Client[] |
||||
|
available = {}, |
||||
|
null_ls = null_ls, |
||||
|
} |
||||
|
|
||||
|
---@type lsp.Client[] |
||||
|
local clients = vim.lsp.get_active_clients({ bufnr = bufnr }) |
||||
|
for _, client in ipairs(clients) do |
||||
|
if M.supports_format(client) then |
||||
|
if (#null_ls > 0 and client.name == "null-ls") or #null_ls == 0 then |
||||
|
table.insert(ret.active, client) |
||||
|
else |
||||
|
table.insert(ret.available, client) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return ret |
||||
|
end |
||||
|
|
||||
|
-- Gets all lsp clients that support formatting |
||||
|
-- and have not disabled it in their client config |
||||
|
---@param client lsp.Client |
||||
|
function M.supports_format(client) |
||||
|
if |
||||
|
client.config |
||||
|
and client.config.capabilities |
||||
|
and client.config.capabilities.documentFormattingProvider == false |
||||
|
then |
||||
|
return false |
||||
|
end |
||||
|
return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting") |
||||
|
end |
||||
|
|
||||
|
---@param opts PluginLspOpts |
||||
|
function M.setup(opts) |
||||
|
M.opts = opts |
||||
|
vim.api.nvim_create_autocmd("BufWritePre", { |
||||
|
group = vim.api.nvim_create_augroup("LazyVimFormat", {}), |
||||
|
callback = function() |
||||
|
if M.opts.autoformat then |
||||
|
M.format() |
||||
|
end |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
return M |
||||
@ -0,0 +1,101 @@ |
|||||
|
local M = {} |
||||
|
|
||||
|
---@type PluginLspKeys |
||||
|
M._keys = nil |
||||
|
|
||||
|
---@return (LazyKeys|{has?:string})[] |
||||
|
function M.get() |
||||
|
local format = function() |
||||
|
require("core.plugins.coding.lsp.format").format({ force = true }) |
||||
|
end |
||||
|
if not M._keys then |
||||
|
---@class PluginLspKeys |
||||
|
-- stylua: ignore |
||||
|
M._keys = { |
||||
|
{ "<leader>cd", vim.diagnostic.open_float, desc = "Line Diagnostics" }, |
||||
|
{ "<leader>cl", "<cmd>LspInfo<cr>", desc = "Lsp Info" }, |
||||
|
{ "gd", "<cmd>Telescope lsp_definitions<cr>", desc = "Goto Definition", has = "definition" }, |
||||
|
{ "gr", "<cmd>Telescope lsp_references<cr>", desc = "References" }, |
||||
|
{ "gD", vim.lsp.buf.declaration, desc = "Goto Declaration" }, |
||||
|
{ "gI", "<cmd>Telescope lsp_implementations<cr>", desc = "Goto Implementation" }, |
||||
|
{ "gy", "<cmd>Telescope lsp_type_definitions<cr>", desc = "Goto T[y]pe Definition" }, |
||||
|
{ "K", vim.lsp.buf.hover, desc = "Hover" }, |
||||
|
{ "gK", vim.lsp.buf.signature_help, desc = "Signature Help", has = "signatureHelp" }, |
||||
|
{ "<c-k>", vim.lsp.buf.signature_help, mode = "i", desc = "Signature Help", has = "signatureHelp" }, |
||||
|
{ "]d", M.diagnostic_goto(true), desc = "Next Diagnostic" }, |
||||
|
{ "[d", M.diagnostic_goto(false), desc = "Prev Diagnostic" }, |
||||
|
{ "]e", M.diagnostic_goto(true, "ERROR"), desc = "Next Error" }, |
||||
|
{ "[e", M.diagnostic_goto(false, "ERROR"), desc = "Prev Error" }, |
||||
|
{ "]w", M.diagnostic_goto(true, "WARN"), desc = "Next Warning" }, |
||||
|
{ "[w", M.diagnostic_goto(false, "WARN"), desc = "Prev Warning" }, |
||||
|
{ "<leader>cf", format, desc = "Format Document", has = "documentFormatting" }, |
||||
|
{ "<leader>cf", format, desc = "Format Range", mode = "v", has = "documentRangeFormatting" }, |
||||
|
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Code Action", mode = { "n", "v" }, has = "codeAction" }, |
||||
|
{ |
||||
|
"<leader>cA", |
||||
|
function() |
||||
|
vim.lsp.buf.code_action({ |
||||
|
context = { |
||||
|
only = { |
||||
|
"source", |
||||
|
}, |
||||
|
diagnostics = {}, |
||||
|
}, |
||||
|
}) |
||||
|
end, |
||||
|
desc = "Source Action", |
||||
|
has = "codeAction", |
||||
|
} |
||||
|
} |
||||
|
if require("core.util").has("inc-rename.nvim") then |
||||
|
M._keys[#M._keys + 1] = { |
||||
|
"<leader>cr", |
||||
|
function() |
||||
|
local inc_rename = require("inc_rename") |
||||
|
return ":" .. inc_rename.config.cmd_name .. " " .. vim.fn.expand("<cword>") |
||||
|
end, |
||||
|
expr = true, |
||||
|
desc = "Rename", |
||||
|
has = "rename", |
||||
|
} |
||||
|
else |
||||
|
M._keys[#M._keys + 1] = { "<leader>cr", vim.lsp.buf.rename, desc = "Rename", has = "rename" } |
||||
|
end |
||||
|
end |
||||
|
return M._keys |
||||
|
end |
||||
|
|
||||
|
function M.on_attach(client, buffer) |
||||
|
local Keys = require("lazy.core.handler.keys") |
||||
|
local keymaps = {} ---@type table<string,LazyKeys|{has?:string}> |
||||
|
|
||||
|
for _, value in ipairs(M.get()) do |
||||
|
local keys = Keys.parse(value) |
||||
|
if keys[2] == vim.NIL or keys[2] == false then |
||||
|
keymaps[keys.id] = nil |
||||
|
else |
||||
|
keymaps[keys.id] = keys |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
for _, keys in pairs(keymaps) do |
||||
|
if not keys.has or client.server_capabilities[keys.has .. "Provider"] then |
||||
|
local opts = Keys.opts(keys) |
||||
|
---@diagnostic disable-next-line: no-unknown |
||||
|
opts.has = nil |
||||
|
opts.silent = opts.silent ~= false |
||||
|
opts.buffer = buffer |
||||
|
vim.keymap.set(keys.mode or "n", keys[1], keys[2], opts) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
function M.diagnostic_goto(next, severity) |
||||
|
local go = next and vim.diagnostic.goto_next or vim.diagnostic.goto_prev |
||||
|
severity = severity and vim.diagnostic.severity[severity] or nil |
||||
|
return function() |
||||
|
go({ severity = severity }) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return M |
||||
@ -0,0 +1,15 @@ |
|||||
|
-- comments |
||||
|
return { |
||||
|
"echasnovski/mini.comment", |
||||
|
dependencies = { |
||||
|
"JoosepAlviste/nvim-ts-context-commentstring" |
||||
|
}, |
||||
|
event = "VeryLazy", |
||||
|
opts = { |
||||
|
options = { |
||||
|
custom_commentstring = function() |
||||
|
return require("ts_context_commentstring.internal").calculate_commentstring() or vim.bo.commentstring |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
return { |
||||
|
'TimUntersberger/neogit', |
||||
|
dependencies = { |
||||
|
'nvim-lua/plenary.nvim', |
||||
|
}, |
||||
|
opts = {}, |
||||
|
--keys = { |
||||
|
-- { "<leader>gn", "<cmd>Neogit<cr>", desc = "Neogit" }, |
||||
|
--} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
-- formatters |
||||
|
return { |
||||
|
"jose-elias-alvarez/null-ls.nvim", |
||||
|
event = { "BufReadPre", "BufNewFile" }, |
||||
|
dependencies = { "mason.nvim" }, |
||||
|
opts = function() |
||||
|
local nls = require("null-ls") |
||||
|
return { |
||||
|
root_dir = require("null-ls.utils").root_pattern(".null-ls-root", ".neoconf.json", "Makefile", ".git"), |
||||
|
sources = { |
||||
|
nls.builtins.formatting.fish_indent, |
||||
|
nls.builtins.diagnostics.fish, |
||||
|
nls.builtins.formatting.stylua, |
||||
|
nls.builtins.formatting.shfmt, |
||||
|
nls.builtins.formatting.prettierd, |
||||
|
-- nls.builtins.diagnostics.flake8, |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
-- auto completion |
||||
|
return { |
||||
|
"hrsh7th/nvim-cmp", |
||||
|
version = false, -- last release is way too old |
||||
|
event = "InsertEnter", |
||||
|
priority = 1000, |
||||
|
lazy = false, |
||||
|
dependencies = { |
||||
|
"hrsh7th/cmp-nvim-lsp", |
||||
|
"hrsh7th/cmp-buffer", |
||||
|
"hrsh7th/cmp-path", |
||||
|
"saadparwaiz1/cmp_luasnip", |
||||
|
}, |
||||
|
opts = function() |
||||
|
local cmp = require("cmp") |
||||
|
return { |
||||
|
completion = { |
||||
|
completeopt = "menu,menuone,noinsert", |
||||
|
}, |
||||
|
snippet = { |
||||
|
expand = function(args) |
||||
|
require("luasnip").lsp_expand(args.body) |
||||
|
end, |
||||
|
}, |
||||
|
mapping = cmp.mapping.preset.insert({ |
||||
|
["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), |
||||
|
["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), |
||||
|
["<C-b>"] = cmp.mapping.scroll_docs(-4), |
||||
|
["<C-f>"] = cmp.mapping.scroll_docs(4), |
||||
|
["<C-Space>"] = cmp.mapping.complete(), |
||||
|
["<C-e>"] = cmp.mapping.abort(), |
||||
|
["<CR>"] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. |
||||
|
["<S-CR>"] = cmp.mapping.confirm({ |
||||
|
behavior = cmp.ConfirmBehavior.Replace, |
||||
|
select = true, |
||||
|
}), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. |
||||
|
}), |
||||
|
sources = cmp.config.sources({ |
||||
|
{ name = "nvim_lsp" }, |
||||
|
{ name = "luasnip" }, |
||||
|
{ name = "buffer" }, |
||||
|
{ name = "path" }, |
||||
|
}), |
||||
|
formatting = { |
||||
|
format = function(_, item) |
||||
|
local icons = require("core.config").icons.kinds |
||||
|
if icons[item.kind] then |
||||
|
item.kind = icons[item.kind] .. item.kind |
||||
|
end |
||||
|
return item |
||||
|
end, |
||||
|
}, |
||||
|
experimental = { |
||||
|
ghost_text = { |
||||
|
hl_group = "LspCodeLens", |
||||
|
}, |
||||
|
}, |
||||
|
-- sorting = { |
||||
|
-- priority_weight = 2, |
||||
|
-- comparators = { |
||||
|
-- require("copilot_cmp.comparators").prioritize, |
||||
|
-- |
||||
|
-- -- Below is the default comparitor list and order for nvim-cmp |
||||
|
-- cmp.config.compare.offset, |
||||
|
-- -- cmp.config.compare.scopes, --this is commented in nvim-cmp too |
||||
|
-- cmp.config.compare.exact, |
||||
|
-- cmp.config.compare.score, |
||||
|
-- cmp.config.compare.recently_used, |
||||
|
-- cmp.config.compare.locality, |
||||
|
-- cmp.config.compare.kind, |
||||
|
-- cmp.config.compare.sort_text, |
||||
|
-- cmp.config.compare.length, |
||||
|
-- cmp.config.compare.order, |
||||
|
-- }, |
||||
|
-- } |
||||
|
} |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
return { |
||||
|
'haringsrob/nvim_context_vt', |
||||
|
opts = { |
||||
|
min_rows = 5, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
return { |
||||
|
{ |
||||
|
"nvim-neotest/neotest", |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>T"] = { name = "+test" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
opts = { |
||||
|
-- Can be a list of adapters like what neotest expects, |
||||
|
-- or a list of adapter names, |
||||
|
-- or a table of adapter names, mapped to adapter configs. |
||||
|
-- The adapter will then be automatically loaded with the config. |
||||
|
adapters = {}, |
||||
|
-- Example for loading neotest-go with a custom config |
||||
|
-- adapters = { |
||||
|
-- ["neotest-go"] = { |
||||
|
-- args = { "-tags=integration" }, |
||||
|
-- }, |
||||
|
-- }, |
||||
|
status = { virtual_text = true }, |
||||
|
output = { open_on_run = true }, |
||||
|
quickfix = { |
||||
|
open = function() |
||||
|
if require("lazyvim.util").has("trouble.nvim") then |
||||
|
vim.cmd("Trouble quickfix") |
||||
|
else |
||||
|
vim.cmd("copen") |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
local neotest_ns = vim.api.nvim_create_namespace("neotest") |
||||
|
vim.diagnostic.config({ |
||||
|
virtual_text = { |
||||
|
format = function(diagnostic) |
||||
|
-- Replace newline and tab characters with space for more compact diagnostics |
||||
|
local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "") |
||||
|
return message |
||||
|
end, |
||||
|
}, |
||||
|
}, neotest_ns) |
||||
|
|
||||
|
if opts.adapters then |
||||
|
local adapters = {} |
||||
|
for name, config in pairs(opts.adapters or {}) do |
||||
|
if type(name) == "number" then |
||||
|
if type(config) == "string" then |
||||
|
config = require(config) |
||||
|
end |
||||
|
adapters[#adapters + 1] = config |
||||
|
elseif config ~= false then |
||||
|
local adapter = require(name) |
||||
|
if type(config) == "table" and not vim.tbl_isempty(config) then |
||||
|
local meta = getmetatable(adapter) |
||||
|
if adapter.setup then |
||||
|
adapter.setup(config) |
||||
|
elseif meta and meta.__call then |
||||
|
adapter(config) |
||||
|
else |
||||
|
error("Adapter " .. name .. " does not support setup") |
||||
|
end |
||||
|
end |
||||
|
adapters[#adapters + 1] = adapter |
||||
|
end |
||||
|
end |
||||
|
opts.adapters = adapters |
||||
|
end |
||||
|
|
||||
|
require("neotest").setup(opts) |
||||
|
end, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>tt", function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "Run File" }, |
||||
|
{ "<leader>tT", function() require("neotest").run.run(vim.loop.cwd()) end, desc = "Run All Test Files" }, |
||||
|
{ "<leader>tr", function() require("neotest").run.run() end, desc = "Run Nearest" }, |
||||
|
{ "<leader>ts", function() require("neotest").summary.toggle() end, desc = "Toggle Summary" }, |
||||
|
{ "<leader>to", function() require("neotest").output.open({ enter = true, auto_close = true }) end, desc = "Show Output" }, |
||||
|
{ "<leader>tO", function() require("neotest").output_panel.toggle() end, desc = "Toggle Output Panel" }, |
||||
|
{ "<leader>tS", function() require("neotest").run.stop() end, desc = "Stop" }, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
"mfussenegger/nvim-dap", |
||||
|
optional = true, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>td", function() require("neotest").run.run({strategy = "dap"}) end, desc = "Debug Nearest" }, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
return { |
||||
|
{ |
||||
|
"nvim-treesitter/nvim-treesitter", |
||||
|
version = false, -- last release is way too old and doesn't work on Windows |
||||
|
build = ":TSUpdate", |
||||
|
event = { "BufReadPost", "BufNewFile" }, |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"nvim-treesitter/nvim-treesitter-textobjects", |
||||
|
init = function() |
||||
|
-- PERF: no need to load the plugin, if we only need its queries for mini.ai |
||||
|
local plugin = require("lazy.core.config").spec.plugins["nvim-treesitter"] |
||||
|
local opts = require("lazy.core.plugin").values(plugin, "opts", false) |
||||
|
local enabled = false |
||||
|
if opts.textobjects then |
||||
|
for _, mod in ipairs({ "move", "select", "swap", "lsp_interop" }) do |
||||
|
if opts.textobjects[mod] and opts.textobjects[mod].enable then |
||||
|
enabled = true |
||||
|
break |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
if not enabled then |
||||
|
require("lazy.core.loader").disable_rtp_plugin("nvim-treesitter-textobjects") |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
"mrjones2014/nvim-ts-rainbow", |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<c-space>", desc = "Increment selection" }, |
||||
|
{ "<bs>", desc = "Decrement selection", mode = "x" }, |
||||
|
}, |
||||
|
-- @type TSConfig |
||||
|
opts = { |
||||
|
highlight = { enable = true }, |
||||
|
indent = { enable = true }, |
||||
|
ensure_installed = { |
||||
|
"bash", |
||||
|
"c", |
||||
|
"html", |
||||
|
"javascript", |
||||
|
"json", |
||||
|
"lua", |
||||
|
"luadoc", |
||||
|
"luap", |
||||
|
"markdown", |
||||
|
"markdown_inline", |
||||
|
"python", |
||||
|
"rust", |
||||
|
"query", |
||||
|
"regex", |
||||
|
"tsx", |
||||
|
"typescript", |
||||
|
"vim", |
||||
|
"vimdoc", |
||||
|
"yaml", |
||||
|
}, |
||||
|
incremental_selection = { |
||||
|
enable = true, |
||||
|
keymaps = { |
||||
|
init_selection = "<C-space>", |
||||
|
node_incremental = "<C-space>", |
||||
|
scope_incremental = false, |
||||
|
node_decremental = "<bs>", |
||||
|
}, |
||||
|
}, |
||||
|
rainbow = { |
||||
|
enable = true, |
||||
|
-- disable = { "jsx", "cpp" }, list of languages you want to disable the plugin for |
||||
|
extended_mode = true, -- Also highlight non-bracket delimiters like html tags, boolean or table: lang -> boolean |
||||
|
max_file_lines = nil, -- Do not enable for files with more than n lines, int |
||||
|
-- colors = {}, -- table of hex strings |
||||
|
-- termcolors = {} -- table of colour name strings |
||||
|
}, |
||||
|
}, |
||||
|
-- @param opts TSConfig |
||||
|
config = function(_, opts) |
||||
|
if type(opts.ensure_installed) == "table" then |
||||
|
---@type table<string, boolean> |
||||
|
local added = {} |
||||
|
opts.ensure_installed = vim.tbl_filter(function(lang) |
||||
|
if added[lang] then |
||||
|
return false |
||||
|
end |
||||
|
added[lang] = true |
||||
|
return true |
||||
|
end, opts.ensure_installed) |
||||
|
end |
||||
|
require("nvim-treesitter.configs").setup(opts) |
||||
|
end, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
-- better diagnostics list and others |
||||
|
return { |
||||
|
"folke/trouble.nvim", |
||||
|
cmd = { "TroubleToggle", "Trouble" }, |
||||
|
opts = { use_diagnostic_signs = true }, |
||||
|
keys = { |
||||
|
{ "<leader>xx", "<cmd>TroubleToggle document_diagnostics<cr>", desc = "Document Diagnostics (Trouble)" }, |
||||
|
{ "<leader>xX", "<cmd>TroubleToggle workspace_diagnostics<cr>", desc = "Workspace Diagnostics (Trouble)" }, |
||||
|
{ "<leader>xL", "<cmd>TroubleToggle loclist<cr>", desc = "Location List (Trouble)" }, |
||||
|
{ "<leader>xQ", "<cmd>TroubleToggle quickfix<cr>", desc = "Quickfix List (Trouble)" }, |
||||
|
{ |
||||
|
"[q", |
||||
|
function() |
||||
|
if require("trouble").is_open() then |
||||
|
require("trouble").previous({ skip_groups = true, jump = true }) |
||||
|
else |
||||
|
local ok, err = pcall(vim.cmd.cprev) |
||||
|
if not ok then |
||||
|
vim.notify(err, vim.log.levels.ERROR) |
||||
|
end |
||||
|
end |
||||
|
end, |
||||
|
desc = "Previous trouble/quickfix item", |
||||
|
}, |
||||
|
{ |
||||
|
"]q", |
||||
|
function() |
||||
|
if require("trouble").is_open() then |
||||
|
require("trouble").next({ skip_groups = true, jump = true }) |
||||
|
else |
||||
|
local ok, err = pcall(vim.cmd.cnext) |
||||
|
if not ok then |
||||
|
vim.notify(err, vim.log.levels.ERROR) |
||||
|
end |
||||
|
end |
||||
|
end, |
||||
|
desc = "Next trouble/quickfix item", |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
-- A lot of people have mappings like jk or jj to escape insert mode. |
||||
|
-- The problem with this mappings is that whenever you type a j, neovim |
||||
|
-- wait about 100-500ms (depending on your timeoutlen) to see, if you |
||||
|
-- type a j or a k because these are mapped. Only after that time the j |
||||
|
-- will be inserted. Then you always get a delay when typing a j |
||||
|
return { |
||||
|
"max397574/better-escape.nvim", |
||||
|
config = function() |
||||
|
require("better_escape").setup { |
||||
|
default_mappings = true, |
||||
|
mappings = { |
||||
|
i = { |
||||
|
j = { |
||||
|
j = "<Esc>", |
||||
|
J = "<Esc>j", |
||||
|
h = "<Esc>h"; |
||||
|
H = "<Esc>2b"; |
||||
|
l = "<Esc>l", |
||||
|
L = "<Esc>w", |
||||
|
K = "<Esc>k", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
-- scrollbar with minimap |
||||
|
return { |
||||
|
'gorbit99/codewindow.nvim', |
||||
|
version = '*', |
||||
|
config = function(_, opts) |
||||
|
local codewindow = require('codewindow') |
||||
|
codewindow.setup(opts) |
||||
|
codewindow.apply_default_keybinds() |
||||
|
end, |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>um"] = { name = "+minimap" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
opts = { |
||||
|
active_in_terminals = false, -- Should the minimap activate for terminal buffers |
||||
|
auto_enable = true, -- Automatically open the minimap when entering a (non-excluded) buffer (accepts a table of filetypes) |
||||
|
exclude_filetypes = { 'help', 'neo-tree' }, -- Choose certain filetypes to not show minimap on |
||||
|
max_minimap_height = nil, -- The maximum height the minimap can take (including borders) |
||||
|
max_lines = 5000, -- If auto_enable is true, don't open the minimap for buffers which have more than this many lines. |
||||
|
minimap_width = 20, -- The width of the text part of the minimap |
||||
|
use_lsp = true, -- Use the builtin LSP to show errors and warnings |
||||
|
use_treesitter = true, -- Use nvim-treesitter to highlight the code |
||||
|
use_git = true, -- Show small dots to indicate git additions and deletions |
||||
|
width_multiplier = 4, -- How many characters one dot represents |
||||
|
z_index = 1, -- The z-index the floating window will be on |
||||
|
show_cursor = true, -- Show the cursor position in the minimap |
||||
|
screen_bounds = 'lines', -- How the visible area is displayed, "lines": lines above and below, "background": background color |
||||
|
window_border = 'single', -- The border style of the floating window (accepts all usual options) |
||||
|
relative = 'win', -- What will be the minimap be placed relative to, "win": the current window, "editor": the entire editor |
||||
|
events = { 'TextChanged', 'InsertLeave', 'DiagnosticChanged', 'FileWritePost' }, -- Events that update the code window |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<leader>umo", function() require("codewindow").open_minimap() end, desc = "open the minimap" }, |
||||
|
{ "<leader>umc", function() require("codewindow").close_minimap() end, desc = "close the minimap" }, |
||||
|
{ "<leader>umt", function() require("codewindow").open_minimap() end, desc = "toggle the minimap" }, |
||||
|
{ "<leader>umf", function() require("codewindow").open_minimap() end, desc = "focus/unfocus the minimap" }, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
-- Create Color Code in neovim. |
||||
|
-- Use the colorful sliders to easily generate any desired color! |
||||
|
return { |
||||
|
"ziontee113/color-picker.nvim", |
||||
|
opts = { |
||||
|
auto_enable = true, |
||||
|
lsp = true, |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<leader>up", "<Cmd>PickColor<CR>", desc = "Pick color" }, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
return { |
||||
|
-- nightfox |
||||
|
{ |
||||
|
'EdenEast/nightfox.nvim', |
||||
|
lazy = false, -- make sure we load this during startup if it is your main colorscheme |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = {}, |
||||
|
-- config = function() |
||||
|
-- vim.opt.termguicolors = true |
||||
|
-- vim.opt.background = 'dark' |
||||
|
-- |
||||
|
-- vim.cmd [[colorscheme carbonfox]] |
||||
|
-- end |
||||
|
}, |
||||
|
|
||||
|
-- catppuccin |
||||
|
{ |
||||
|
"catppuccin/nvim", |
||||
|
name = "catppuccin", |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = { |
||||
|
integrations = { |
||||
|
alpha = true, |
||||
|
cmp = true, |
||||
|
gitsigns = true, |
||||
|
illuminate = true, |
||||
|
indent_blankline = { enabled = true }, |
||||
|
lsp_trouble = true, |
||||
|
mini = true, |
||||
|
native_lsp = { |
||||
|
enabled = true, |
||||
|
underlines = { |
||||
|
errors = { "undercurl" }, |
||||
|
hints = { "undercurl" }, |
||||
|
warnings = { "undercurl" }, |
||||
|
information = { "undercurl" }, |
||||
|
}, |
||||
|
}, |
||||
|
navic = { enabled = true }, |
||||
|
neotest = true, |
||||
|
noice = true, |
||||
|
notify = true, |
||||
|
nvimtree = true, |
||||
|
semantic_tokens = true, |
||||
|
telescope = true, |
||||
|
treesitter = true, |
||||
|
which_key = true, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
-- Gruvbox Material is a modified version of Gruvbox, the contrast is adjusted to be softer in order to protect developers' eyes. |
||||
|
{ |
||||
|
"sainnhe/gruvbox-material", |
||||
|
lazy = false, -- make sure we load this during startup if it is your main colorscheme |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = {}, |
||||
|
}, |
||||
|
|
||||
|
-- This color scheme is based on Monokai Pro, the contrast is adjusted to be a bit lower while keeping the colors vivid enough. |
||||
|
{ |
||||
|
"sainnhe/sonokai", |
||||
|
lazy = false, -- make sure we load this during startup if it is your main colorscheme |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = {}, |
||||
|
config = function() |
||||
|
vim.opt.termguicolors = true |
||||
|
vim.cmd("let g:sonokai_style = 'espresso'") |
||||
|
vim.cmd("let g:sonokai_better_performance = 1") |
||||
|
vim.cmd("let g:sonokai_current_word = 'underline'") |
||||
|
vim.cmd("colorscheme sonokai") |
||||
|
end |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
"sainnhe/everforest", |
||||
|
lazy = false, -- make sure we load this during startup if it is your main colorscheme |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = {}, |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
"sainnhe/edge", |
||||
|
lazy = false, -- make sure we load this during startup if it is your main colorscheme |
||||
|
priority = 1000, -- make sure to load this before all the other start plugins |
||||
|
opts = {}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,173 @@ |
|||||
|
-- Compter.nvim provides an easy way to customize and power the ability of <C-a> and <C-x>. |
||||
|
return { |
||||
|
"RutaTang/compter.nvim", |
||||
|
opts = { |
||||
|
templates = { |
||||
|
{ |
||||
|
pattern = [[-\?\d\+]], |
||||
|
priority = 0, |
||||
|
increase = function(content) |
||||
|
content = tonumber(content) |
||||
|
return content + 1, true |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
content = tonumber(content) |
||||
|
return content - 1, true |
||||
|
end, |
||||
|
}, |
||||
|
-- for lowercase alphabet |
||||
|
{ |
||||
|
pattern = [[\l]], |
||||
|
priority = 0, |
||||
|
increase = function(content) |
||||
|
local ansiCode = string.byte(content) + 1 |
||||
|
if ansiCode > string.byte("z") then |
||||
|
ansiCode = string.byte("a") |
||||
|
end |
||||
|
local char = string.char(ansiCode) |
||||
|
return char, true |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local ansiCode = string.byte(content) - 1 |
||||
|
if ansiCode < string.byte("a") then |
||||
|
ansiCode = string.byte("z") |
||||
|
end |
||||
|
local char = string.char(ansiCode) |
||||
|
return char, true |
||||
|
end, |
||||
|
}, |
||||
|
-- for uppercase alphabet |
||||
|
{ |
||||
|
pattern = [[\u]], |
||||
|
priority = 0, |
||||
|
increase = function(content) |
||||
|
local ansiCode = string.byte(content) + 1 |
||||
|
if ansiCode > string.byte("Z") then |
||||
|
ansiCode = string.byte("A") |
||||
|
end |
||||
|
local char = string.char(ansiCode) |
||||
|
return char, true |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local ansiCode = string.byte(content) - 1 |
||||
|
if ansiCode < string.byte("A") then |
||||
|
ansiCode = string.byte("Z") |
||||
|
end |
||||
|
local char = string.char(ansiCode) |
||||
|
return char, true |
||||
|
end, |
||||
|
}, |
||||
|
-- for date format: dd/mm/YYYY |
||||
|
{ |
||||
|
pattern = [[\d\{2}/\d\{2}/\d\{4}]], |
||||
|
priority = 100, |
||||
|
increase = function(content) |
||||
|
local ts = vim.fn.strptime("%d/%m/%Y", content) |
||||
|
if ts == 0 then |
||||
|
return content, false |
||||
|
else |
||||
|
ts = ts + 24 * 60 * 60 |
||||
|
return vim.fn.strftime("%d/%m/%Y", ts), true |
||||
|
end |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local ts = vim.fn.strptime("%d/%m/%Y", content) |
||||
|
if ts == 0 then |
||||
|
return content, false |
||||
|
else |
||||
|
ts = ts - 24 * 60 * 60 |
||||
|
return vim.fn.strftime("%d/%m/%Y", ts), true |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
-- for date format: YYYY/mm/dd |
||||
|
{ |
||||
|
pattern = [[\d\{4}/\d\{2}/\d\{2}]], |
||||
|
priority = 100, |
||||
|
increase = function(content) |
||||
|
local ts = vim.fn.strptime("%Y/%m/%d", content) |
||||
|
if ts == 0 then |
||||
|
return content, false |
||||
|
else |
||||
|
ts = ts + 24 * 60 * 60 |
||||
|
return vim.fn.strftime("%Y/%m/%d", ts), true |
||||
|
end |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local ts = vim.fn.strptime("%Y/%m/%d", content) |
||||
|
if ts == 0 then |
||||
|
return content, false |
||||
|
else |
||||
|
ts = ts - 24 * 60 * 60 |
||||
|
return vim.fn.strftime("%Y/%m/%d", ts), true |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
-- for circle degree |
||||
|
{ |
||||
|
pattern = [[\d\{1,3}°]], |
||||
|
priority = 0, |
||||
|
increase = function(content) |
||||
|
local l = tonumber(content:sub(1, -3)) + 1 |
||||
|
if l >= 360 then |
||||
|
l = 0 |
||||
|
end |
||||
|
return string.format("%d°", l), true |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local l = tonumber(content:sub(1, -3)) - 1 |
||||
|
if l < 0 then |
||||
|
l = 359 |
||||
|
end |
||||
|
return string.format("%d°", l), true |
||||
|
end, |
||||
|
}, |
||||
|
-- for boolean |
||||
|
{ |
||||
|
pattern = [[\<\(true\|false\|TRUE\|FALSE\|True\|False\)\>]], |
||||
|
priority = 100, |
||||
|
increase = function(content) |
||||
|
local switch = { |
||||
|
["true"] = "false", |
||||
|
["false"] = "true", |
||||
|
["True"] = "False", |
||||
|
["False"] = "True", |
||||
|
["TRUE"] = "FALSE", |
||||
|
["FALSE"] = "TRUE", |
||||
|
} |
||||
|
return switch[content], true |
||||
|
end, |
||||
|
decrease = function(content) |
||||
|
local switch = { |
||||
|
["true"] = "false", |
||||
|
["false"] = "true", |
||||
|
["True"] = "False", |
||||
|
["False"] = "True", |
||||
|
["TRUE"] = "FALSE", |
||||
|
["FALSE"] = "TRUE", |
||||
|
} |
||||
|
return switch[content], true |
||||
|
end, |
||||
|
}, |
||||
|
|
||||
|
-- example template |
||||
|
--{ |
||||
|
-- pattern = [[-\?\d\+]], |
||||
|
-- priority = 0, |
||||
|
-- increase = function(content) |
||||
|
-- content = tonumber(content) |
||||
|
-- return content + 1, true |
||||
|
-- end, |
||||
|
-- decrease = function(content) |
||||
|
-- content = tonumber(content) |
||||
|
-- return content - 1, true |
||||
|
-- end, |
||||
|
--}, |
||||
|
-- more templates |
||||
|
}, |
||||
|
fallback = true, |
||||
|
}, |
||||
|
-- config = function() |
||||
|
-- require("compter").setup({}) |
||||
|
-- end, |
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
-- Flatten allows you to open files from a neovim terminal buffer in your current neovim instance instead of a nested one:w |
||||
|
return { |
||||
|
'willothy/flatten.nvim', |
||||
|
opts = { |
||||
|
window = { open = 'alternate' }, |
||||
|
callbacks = { |
||||
|
should_block = function(argv) |
||||
|
-- Note that argv contains all the parts of the CLI command, including |
||||
|
-- Neovim's path, commands, options and files. |
||||
|
-- See: :help v:argv |
||||
|
|
||||
|
-- In this case, we would block if we find the `-b` flag |
||||
|
-- This allows you to use `nvim -b file1` instead of `nvim --cmd 'let g:flatten_wait=1' file1` |
||||
|
return vim.tbl_contains(argv, "-b") |
||||
|
|
||||
|
-- Alternatively, we can block if we find the diff-mode option |
||||
|
-- return vim.tbl_contains(argv, "-d") |
||||
|
end, |
||||
|
post_open = function(_bufnr, winnr, _ft, is_blocking) |
||||
|
if is_blocking then |
||||
|
require('toggleterm').toggle(0) |
||||
|
else |
||||
|
vim.api.nvim_set_current_win(winnr) |
||||
|
end |
||||
|
|
||||
|
-- If the file is a git commit, create one-shot autocmd to delete its buffer on write |
||||
|
-- If you just want the toggleable terminal integration, ignore this bit |
||||
|
if ft == "gitcommit" then |
||||
|
vim.api.nvim_create_autocmd( |
||||
|
"BufWritePost", |
||||
|
{ |
||||
|
buffer = bufnr, |
||||
|
once = true, |
||||
|
callback = function() |
||||
|
-- This is a bit of a hack, but if you run bufdelete immediately |
||||
|
-- the shell can occasionally freeze |
||||
|
vim.defer_fn( |
||||
|
function() |
||||
|
vim.api.nvim_buf_delete(bufnr, {}) |
||||
|
end, |
||||
|
50 |
||||
|
) |
||||
|
end |
||||
|
} |
||||
|
) |
||||
|
end |
||||
|
end, |
||||
|
block_end = function() |
||||
|
-- After blocking ends (for a git commit, etc), reopen the terminal |
||||
|
require("toggleterm").toggle(0) |
||||
|
end |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
-- easily jump to any location and enhanced f/t motions for Leap |
||||
|
return { |
||||
|
"ggandor/flit.nvim", |
||||
|
keys = function() |
||||
|
---@type LazyKeys[] |
||||
|
local ret = {} |
||||
|
for _, key in ipairs({ "f", "F", "t", "T" }) do |
||||
|
ret[#ret + 1] = { key, mode = { "n", "x", "o" }, desc = key } |
||||
|
end |
||||
|
return ret |
||||
|
end, |
||||
|
opts = { labeled_modes = "nx" }, |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
-- git signs |
||||
|
return { |
||||
|
"lewis6991/gitsigns.nvim", |
||||
|
event = { "BufReadPre", "BufNewFile" }, |
||||
|
opts = { |
||||
|
signs = { |
||||
|
add = { text = "▎" }, |
||||
|
change = { text = "▎" }, |
||||
|
delete = { text = "" }, |
||||
|
topdelete = { text = "" }, |
||||
|
changedelete = { text = "▎" }, |
||||
|
untracked = { text = "▎" }, |
||||
|
}, |
||||
|
on_attach = function(buffer) |
||||
|
local gs = package.loaded.gitsigns |
||||
|
|
||||
|
local function map(mode, l, r, desc) |
||||
|
vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc }) |
||||
|
end |
||||
|
|
||||
|
-- stylua: ignore start |
||||
|
--map("n", "]h", gs.next_hunk, "Next Hunk") |
||||
|
--map("n", "[h", gs.prev_hunk, "Prev Hunk") |
||||
|
--map({ "n", "v" }, "<leader>ghs", ":Gitsigns stage_hunk<CR>", "Stage Hunk") |
||||
|
--map({ "n", "v" }, "<leader>ghr", ":Gitsigns reset_hunk<CR>", "Reset Hunk") |
||||
|
--map("n", "<leader>ghS", gs.stage_buffer, "Stage Buffer") |
||||
|
--map("n", "<leader>ghu", gs.undo_stage_hunk, "Undo Stage Hunk") |
||||
|
--map("n", "<leader>ghR", gs.reset_buffer, "Reset Buffer") |
||||
|
--map("n", "<leader>ghp", gs.preview_hunk, "Preview Hunk") |
||||
|
--map("n", "<leader>ghb", function() gs.blame_line({ full = true }) end, "Blame Line") |
||||
|
--map("n", "<leader>ghd", gs.diffthis, "Diff This") |
||||
|
--map("n", "<leader>ghD", function() gs.diffthis("~") end, "Diff This ~") |
||||
|
--map({ "o", "x" }, "ih", ":<C-U>Gitsigns select_hunk<CR>", "GitSigns Select Hunk") |
||||
|
end, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
-- Automagically close the unedited buffers in your bufferlist when it becomes too long. |
||||
|
-- The "edited" buffers remain untouched. For a buffer to be considered edited it is enough |
||||
|
-- to enter insert mode once or modify it in any way. |
||||
|
return { |
||||
|
'axkirillov/hbac.nvim', |
||||
|
dependencies = { |
||||
|
-- these are optional, add them, if you want the telescope module |
||||
|
'nvim-telescope/telescope.nvim', |
||||
|
'nvim-lua/plenary.nvim', |
||||
|
'nvim-tree/nvim-web-devicons' |
||||
|
}, |
||||
|
config = function () |
||||
|
require("hbac").setup() |
||||
|
end |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
return { |
||||
|
'kevinhwang91/nvim-hlslens', |
||||
|
opts = { |
||||
|
-- If calm_down is true, clear all lens and highlighting When the cursor is out of the position range of the matched instance or any texts are changed |
||||
|
calm_down = false, |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "n", [[<Cmd>execute('normal! ' . v:count1 . 'n')<CR><Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search next", noremap = true, silent = true, }, |
||||
|
{ "N", [[<Cmd>execute('normal! ' . v:count1 . 'N')<CR><Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search prev", noremap = true, silent = true, }, |
||||
|
{ "*", [[*<Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search next", noremap = true, silent = true, }, |
||||
|
{ "#", [[#<Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search prev", noremap = true, silent = true, }, |
||||
|
{ "g*", [[g*<Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search next (less strict)", noremap = true, silent = true, }, |
||||
|
{ "g#", [[g#<Cmd>lua require('hlslens').start()<CR>]], desc = "hlslens: search prev (less strict)", noremap = true, silent = true, }, |
||||
|
}, |
||||
|
config = function() |
||||
|
require'hlslens'.setup() |
||||
|
|
||||
|
-- run `:nohlsearch` and export results to quickfix |
||||
|
-- if Neovim is 0.8.0 before, remap yourself. |
||||
|
vim.keymap.set({'n', 'x'}, '<Leader>L', function() |
||||
|
vim.schedule(function() |
||||
|
if require('hlslens').exportLastSearchToQuickfix() then |
||||
|
vim.cmd('cw') |
||||
|
end |
||||
|
end) |
||||
|
return ':noh<CR>' |
||||
|
end, {expr = true, desc = 'hlslens: send to quickfix'}) |
||||
|
|
||||
|
-- integration with vim-visual-multi |
||||
|
vim.cmd([[ |
||||
|
aug VMlens |
||||
|
au! |
||||
|
au User visual_multi_start lua require('core.plugins.hlslens.init.lua').start() |
||||
|
au User visual_multi_exit lua require('core.plugins.hlslens.init.lua').exit() |
||||
|
aug END |
||||
|
]]) |
||||
|
end |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
-- Leap is a general-purpose motion plugin for Neovim |
||||
|
return { |
||||
|
"ggandor/leap.nvim", |
||||
|
keys = { |
||||
|
{ "s", mode = { "n", "x", "o" }, desc = "Leap forward to" }, |
||||
|
{ "S", mode = { "n", "x", "o" }, desc = "Leap backward to" }, |
||||
|
{ "gs", mode = { "n", "x", "o" }, desc = "Leap from windows" }, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
local leap = require("leap") |
||||
|
for k, v in pairs(opts) do |
||||
|
leap.opts[k] = v |
||||
|
end |
||||
|
leap.add_default_mappings(true) |
||||
|
vim.keymap.del({ "x", "o" }, "x") |
||||
|
vim.keymap.del({ "x", "o" }, "X") |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
-- better text-objects |
||||
|
return { |
||||
|
"echasnovski/mini.ai", |
||||
|
-- keys = { |
||||
|
-- { "a", mode = { "x", "o" } }, |
||||
|
-- { "i", mode = { "x", "o" } }, |
||||
|
-- }, |
||||
|
event = "VeryLazy", |
||||
|
dependencies = { "nvim-treesitter-textobjects" }, |
||||
|
opts = function() |
||||
|
local ai = require("mini.ai") |
||||
|
return { |
||||
|
n_lines = 500, |
||||
|
custom_textobjects = { |
||||
|
o = ai.gen_spec.treesitter({ |
||||
|
a = { "@block.outer", "@conditional.outer", "@loop.outer" }, |
||||
|
i = { "@block.inner", "@conditional.inner", "@loop.inner" }, |
||||
|
}, {}), |
||||
|
f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}), |
||||
|
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}), |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
config = function(_, opts) |
||||
|
require("mini.ai").setup(opts) |
||||
|
-- register all text objects with which-key |
||||
|
if require("core.util").has("which-key.nvim") then |
||||
|
---@type table<string, string|table> |
||||
|
local i = { |
||||
|
[" "] = "Whitespace", |
||||
|
['"'] = 'Balanced "', |
||||
|
["'"] = "Balanced '", |
||||
|
["`"] = "Balanced `", |
||||
|
["("] = "Balanced (", |
||||
|
[")"] = "Balanced ) including white-space", |
||||
|
[">"] = "Balanced > including white-space", |
||||
|
["<lt>"] = "Balanced <", |
||||
|
["]"] = "Balanced ] including white-space", |
||||
|
["["] = "Balanced [", |
||||
|
["}"] = "Balanced } including white-space", |
||||
|
["{"] = "Balanced {", |
||||
|
["?"] = "User Prompt", |
||||
|
_ = "Underscore", |
||||
|
a = "Argument", |
||||
|
b = "Balanced ), ], }", |
||||
|
c = "Class", |
||||
|
f = "Function", |
||||
|
o = "Block, conditional, loop", |
||||
|
q = "Quote `, \", '", |
||||
|
t = "Tag", |
||||
|
} |
||||
|
local a = vim.deepcopy(i) |
||||
|
for k, v in pairs(a) do |
||||
|
a[k] = v:gsub(" including.*", "") |
||||
|
end |
||||
|
|
||||
|
local ic = vim.deepcopy(i) |
||||
|
local ac = vim.deepcopy(a) |
||||
|
for key, name in pairs({ n = "Next", l = "Last" }) do |
||||
|
i[key] = vim.tbl_extend("force", { name = "Inside " .. name .. " textobject" }, ic) |
||||
|
a[key] = vim.tbl_extend("force", { name = "Around " .. name .. " textobject" }, ac) |
||||
|
end |
||||
|
require("which-key").register({ |
||||
|
mode = { "o", "x" }, |
||||
|
i = i, |
||||
|
a = a, |
||||
|
}) |
||||
|
end |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
-- buffer remove |
||||
|
return { |
||||
|
"echasnovski/mini.bufremove", |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>bd", function() require("mini.bufremove").delete(0, false) end, desc = "Delete Buffer" }, |
||||
|
{ "<leader>bD", function() require("mini.bufremove").delete(0, true) end, desc = "Delete Buffer (Force)" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
return { |
||||
|
'echasnovski/mini.cursorword', |
||||
|
version = '*', |
||||
|
opts = { }, |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
-- move text blocks/selections/... |
||||
|
return { |
||||
|
'booperlv/nvim-gomove', |
||||
|
version = '*', |
||||
|
enabled = true, |
||||
|
opts = { |
||||
|
-- whether or not to map default key bindings, (true/false) |
||||
|
map_defaults = true, |
||||
|
-- whether or not to reindent lines moved vertically (true/false) |
||||
|
reindent = false, |
||||
|
-- whether or not to undojoin same direction moves (true/false) |
||||
|
undojoin = true, |
||||
|
-- whether to not to move past end column when moving blocks horizontally, (true/false) |
||||
|
move_past_end_col = false, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
-- auto pairs |
||||
|
return { |
||||
|
"echasnovski/mini.pairs", |
||||
|
event = "VeryLazy", |
||||
|
opts = {}, |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
local Util = require("core.util") |
||||
|
|
||||
|
-- Neo-tree is a Neovim plugin to browse the file system and other tree like structures |
||||
|
return { |
||||
|
'nvim-neo-tree/neo-tree.nvim', |
||||
|
branch = 'v2.x', |
||||
|
lazy = false, |
||||
|
cmd = "Neotree", |
||||
|
keys = { |
||||
|
{ "<leader>fe", function() require("neo-tree.command").execute({ toggle = true, dir = Util.get_root() }) end, desc = "Explorer NeoTree (root dir)", }, |
||||
|
{ "<leader>FE", function() require("neo-tree.command").execute({ toggle = true, dir = vim.loop.cwd() }) end, desc = "Explorer NeoTree (cwd)", }, |
||||
|
{ "<leader>e", "<leader>fe", desc = "Explorer NeoTree (root dir)", remap = true }, |
||||
|
{ "<leader>E", "<leader>FE", desc = "Explorer NeoTree (cwd)", remap = true }, |
||||
|
}, |
||||
|
deactivate = function() |
||||
|
vim.cmd([[Neotree close]]) |
||||
|
end, |
||||
|
init = function() |
||||
|
vim.g.neo_tree_remove_legacy_commands = true |
||||
|
|
||||
|
if vim.fn.argc() == 1 then |
||||
|
local stat = vim.loop.fs_stat(vim.fn.argv(0)) |
||||
|
if stat and stat.type == "directory" then |
||||
|
require("neo-tree") |
||||
|
end |
||||
|
end |
||||
|
end, |
||||
|
opts = { |
||||
|
sources = { "filesystem", "buffers", "git_status", "document_symbols" }, |
||||
|
open_files_do_not_replace_types = { "terminal", "Trouble", "qf", "Outline" }, |
||||
|
filesystem = { |
||||
|
bind_to_cwd = false, |
||||
|
follow_current_file = true, |
||||
|
use_libuv_file_watcher = true, |
||||
|
filtered_items = { |
||||
|
visible = false, |
||||
|
hide_dotfiles = false, |
||||
|
hide_gitignored = false, |
||||
|
hide_hidden = false, |
||||
|
}, |
||||
|
}, |
||||
|
window = { |
||||
|
mappings = { |
||||
|
["<space>"] = "none", |
||||
|
}, |
||||
|
}, |
||||
|
default_component_configs = { |
||||
|
indent = { |
||||
|
with_expanders = true, -- if nil and file nesting is enabled, will enable expanders |
||||
|
expander_collapsed = "", |
||||
|
expander_expanded = "", |
||||
|
expander_highlight = "NeoTreeExpander", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
require("neo-tree").setup(opts) |
||||
|
vim.api.nvim_create_autocmd("TermClose", { |
||||
|
pattern = "*lazygit", |
||||
|
callback = function() |
||||
|
if package.loaded["neo-tree.sources.git_status"] then |
||||
|
require("neo-tree.sources.git_status").refresh() |
||||
|
end |
||||
|
end, |
||||
|
}) |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
return { |
||||
|
'ecthelionvi/NeoColumn.nvim', |
||||
|
opts = { |
||||
|
NeoColumn = "120", |
||||
|
always_on = true, |
||||
|
excluded_ft = { "help", "text", "markdown", "NeoTree" }, |
||||
|
custom_NeoColumn = { |
||||
|
ruby = "120", |
||||
|
java = { "180", "200"}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
-- NeoComposer is a Neovim plugin that streamlines macro management and execution with a |
||||
|
-- customizable Status Line Component and Telescope Extension |
||||
|
return { |
||||
|
{ |
||||
|
"ecthelionvi/NeoComposer.nvim", |
||||
|
dependencies = { |
||||
|
"kkharji/sqlite.lua", |
||||
|
}, |
||||
|
opts = { |
||||
|
notify = true, |
||||
|
delay_timer = 200, |
||||
|
colors = { |
||||
|
bg = "#16161e", |
||||
|
fg = "#ff9e64", |
||||
|
red = "#ec5f67", |
||||
|
blue = "#5fb3b3", |
||||
|
green = "#99c794", |
||||
|
}, |
||||
|
keymaps = { |
||||
|
play_macro = "Q", |
||||
|
yank_macro = "yq", |
||||
|
stop_macro = "cq", |
||||
|
toggle_record = "q", |
||||
|
cycle_next = "<m-n>", |
||||
|
cycle_prev = "<m-p>", |
||||
|
toggle_macro_menu = "<m-q>", |
||||
|
}, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
require('telescope').load_extension('macros') |
||||
|
require("NeoComposer").setup(opts) |
||||
|
end, |
||||
|
}, |
||||
|
{ |
||||
|
"nvim-lualine/lualine.nvim", |
||||
|
opts = { |
||||
|
sections = { |
||||
|
lualine_c = { |
||||
|
-- { require('NeoComposer.ui').status_recording }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
-- Plugin um Message zu unterdrücken und zu filtern |
||||
|
-- wie z.b. die "Search hit bottom without match |
||||
|
-- config siehe: https://www.reddit.com/r/neovim/comments/12lf0ke/does_anyone_have_a_cmdheight0_setup_without/ |
||||
|
-- noicer ui |
||||
|
return { |
||||
|
"folke/noice.nvim", |
||||
|
event = "VeryLazy", |
||||
|
dependencies = { |
||||
|
-- which key integration |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
--opts = function(_, opts) |
||||
|
-- if require("core.util").has("noice.nvim") then |
||||
|
-- opts.defaults["<leader>sn"] = { name = "+noice" } |
||||
|
-- end |
||||
|
--end, |
||||
|
}, |
||||
|
}, |
||||
|
opts = { |
||||
|
lsp = { |
||||
|
override = { |
||||
|
["vim.lsp.util.convert_input_to_markdown_lines"] = true, |
||||
|
["vim.lsp.util.stylize_markdown"] = true, |
||||
|
["cmp.entry.get_documentation"] = true, |
||||
|
}, |
||||
|
}, |
||||
|
messages = { |
||||
|
view_search = false, --"virtualtext", -- no search found count messages |
||||
|
}, |
||||
|
routes = { |
||||
|
{ |
||||
|
filter = { |
||||
|
event = "msg_show", |
||||
|
any = { |
||||
|
{ find = "%d+L, %d+B" }, |
||||
|
{ find = "; after #%d+" }, |
||||
|
{ find = "; before #%d+" }, |
||||
|
}, |
||||
|
}, |
||||
|
view = "mini", |
||||
|
}, |
||||
|
}, |
||||
|
presets = { |
||||
|
bottom_search = true, |
||||
|
command_palette = true, |
||||
|
long_message_to_split = true, |
||||
|
inc_rename = true, |
||||
|
}, |
||||
|
}, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<S-Enter>", function() require("noice").redirect(vim.fn.getcmdline()) end, mode = "c", desc = "Redirect Cmdline" }, |
||||
|
{ "<leader>snl", function() require("noice").cmd("last") end, desc = "Noice Last Message" }, |
||||
|
{ "<leader>snh", function() require("noice").cmd("history") end, desc = "Noice History" }, |
||||
|
{ "<leader>sna", function() require("noice").cmd("all") end, desc = "Noice All" }, |
||||
|
{ "<leader>snd", function() require("noice").cmd("dismiss") end, desc = "Dismiss All" }, |
||||
|
{ "<c-f>", function() if not require("noice.lsp").scroll(4) then return "<c-f>" end end, silent = true, expr = true, desc = "Scroll forward", mode = {"i", "n", "s"} }, |
||||
|
{ "<c-b>", function() if not require("noice.lsp").scroll(-4) then return "<c-b>" end end, silent = true, expr = true, desc = "Scroll backward", mode = {"i", "n", "s"}}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
return { |
||||
|
'brenoprata10/nvim-highlight-colors', |
||||
|
opts = { }, |
||||
|
keys = { |
||||
|
{ "<leader>uo", function() require("nvim-highlight-colors").turnOff() end, desc = "highlight-colors off" }, |
||||
|
{ "<leader>ul", function() require("nvim-highlight-colors").turnOn() end, desc = "highlight-colors on" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
return { "sitiom/nvim-numbertoggle" } |
||||
@ -0,0 +1,10 @@ |
|||||
|
-- search/replace in multiple files |
||||
|
return { |
||||
|
"nvim-pack/nvim-spectre", |
||||
|
cmd = "Spectre", |
||||
|
opts = { open_cmd = "noswapfile vnew" }, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>sr", function() require("spectre").open() end, desc = "Replace in files (Spectre)" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
-- surround |
||||
|
return { |
||||
|
"kylechui/nvim-surround", |
||||
|
version = "*", -- Use for stability; omit to use `main` branch for the latest features |
||||
|
event = "VeryLazy", |
||||
|
config = function() |
||||
|
require("nvim-surround").setup({ |
||||
|
keymaps = { |
||||
|
visual = "Y", |
||||
|
}, |
||||
|
}) |
||||
|
end |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
return { |
||||
|
'stevearc/oil.nvim', |
||||
|
opts = {}, |
||||
|
-- Optional dependencies |
||||
|
dependencies = { "nvim-tree/nvim-web-devicons" }, |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
-- An always-on highlight for a unique character in every word on a line to help you use f, F and family. |
||||
|
return { |
||||
|
'unblevable/quick-scope', |
||||
|
cond = not vim.g.vscode |
||||
|
} |
||||
@ -0,0 +1,122 @@ |
|||||
|
local Util = require("core.util") |
||||
|
|
||||
|
-- fuzzy finder |
||||
|
return { |
||||
|
"nvim-telescope/telescope.nvim", |
||||
|
commit = vim.fn.has("nvim-0.9.0") == 0 and "057ee0f8783" or nil, |
||||
|
cmd = "Telescope", |
||||
|
version = false, -- telescope did only one release, so use HEAD for now |
||||
|
keys = { |
||||
|
{ "<leader>,", "<cmd>Telescope buffers show_all_buffers=true<cr>", desc = "Switch Buffer" }, |
||||
|
{ "<leader>/", Util.telescope("live_grep"), desc = "Grep (root dir)" }, |
||||
|
{ "<leader>:", "<cmd>Telescope command_history<cr>", desc = "Command History" }, |
||||
|
{ "<leader><space>", Util.telescope("files"), desc = "Find Files (root dir)" }, |
||||
|
-- find |
||||
|
{ "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Buffers" }, |
||||
|
{ "<leader>ff", Util.telescope("files"), desc = "Find Files (root dir)" }, |
||||
|
{ "<leader>fF", Util.telescope("files", { cwd = false }), desc = "Find Files (cwd)" }, |
||||
|
{ "<leader>fr", "<cmd>Telescope oldfiles<cr>", desc = "Recent" }, |
||||
|
{ "<leader>fR", Util.telescope("oldfiles", { cwd = vim.loop.cwd() }), desc = "Recent (cwd)" }, |
||||
|
-- git |
||||
|
--{ "<leader>gc", "<cmd>Telescope git_commits<CR>", desc = "commits" }, |
||||
|
--{ "<leader>gs", "<cmd>Telescope git_status<CR>", desc = "status" }, |
||||
|
-- search |
||||
|
{ "<leader>sa", "<cmd>Telescope autocommands<cr>", desc = "Auto Commands" }, |
||||
|
{ "<leader>sb", "<cmd>Telescope current_buffer_fuzzy_find<cr>", desc = "Buffer" }, |
||||
|
{ "<leader>sc", "<cmd>Telescope command_history<cr>", desc = "Command History" }, |
||||
|
{ "<leader>sC", "<cmd>Telescope commands<cr>", desc = "Commands" }, |
||||
|
{ "<leader>sd", "<cmd>Telescope diagnostics bufnr=0<cr>", desc = "Document diagnostics" }, |
||||
|
{ "<leader>sD", "<cmd>Telescope diagnostics<cr>", desc = "Workspace diagnostics" }, |
||||
|
{ "<leader>sg", Util.telescope("live_grep"), desc = "Grep (root dir)" }, |
||||
|
{ "<leader>sG", Util.telescope("live_grep", { cwd = false }), desc = "Grep (cwd)" }, |
||||
|
{ "<leader>sh", "<cmd>Telescope help_tags<cr>", desc = "Help Pages" }, |
||||
|
{ "<leader>sH", "<cmd>Telescope highlights<cr>", desc = "Search Highlight Groups" }, |
||||
|
{ "<leader>sk", "<cmd>Telescope keymaps<cr>", desc = "Key Maps" }, |
||||
|
{ "<leader>sM", "<cmd>Telescope man_pages<cr>", desc = "Man Pages" }, |
||||
|
{ "<leader>sm", "<cmd>Telescope marks<cr>", desc = "Jump to Mark" }, |
||||
|
{ "<leader>so", "<cmd>Telescope vim_options<cr>", desc = "Options" }, |
||||
|
{ "<leader>sR", "<cmd>Telescope resume<cr>", desc = "Resume" }, |
||||
|
{ "<leader>sw", Util.telescope("grep_string"), desc = "Word (root dir)" }, |
||||
|
{ "<leader>sW", Util.telescope("grep_string", { cwd = false }), desc = "Word (cwd)" }, |
||||
|
{ "<leader>uC", Util.telescope("colorscheme", { enable_preview = true }), desc = "Colorscheme with preview" }, |
||||
|
{ |
||||
|
"<leader>ss", |
||||
|
Util.telescope("lsp_document_symbols", { |
||||
|
symbols = { |
||||
|
"Class", |
||||
|
"Function", |
||||
|
"Method", |
||||
|
"Constructor", |
||||
|
"Interface", |
||||
|
"Module", |
||||
|
"Struct", |
||||
|
"Trait", |
||||
|
"Field", |
||||
|
"Property", |
||||
|
}, |
||||
|
}), |
||||
|
desc = "Goto Symbol", |
||||
|
}, |
||||
|
{ |
||||
|
"<leader>sS", |
||||
|
Util.telescope("lsp_dynamic_workspace_symbols", { |
||||
|
symbols = { |
||||
|
"Class", |
||||
|
"Function", |
||||
|
"Method", |
||||
|
"Constructor", |
||||
|
"Interface", |
||||
|
"Module", |
||||
|
"Struct", |
||||
|
"Trait", |
||||
|
"Field", |
||||
|
"Property", |
||||
|
}, |
||||
|
}), |
||||
|
desc = "Goto Symbol (Workspace)", |
||||
|
}, |
||||
|
}, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
prompt_prefix = " ", |
||||
|
selection_caret = " ", |
||||
|
mappings = { |
||||
|
i = { |
||||
|
["<c-t>"] = function(...) |
||||
|
return require("trouble.providers.telescope").open_with_trouble(...) |
||||
|
end, |
||||
|
["<a-t>"] = function(...) |
||||
|
return require("trouble.providers.telescope").open_selected_with_trouble(...) |
||||
|
end, |
||||
|
["<a-i>"] = function() |
||||
|
local action_state = require("telescope.actions.state") |
||||
|
local line = action_state.get_current_line() |
||||
|
Util.telescope("find_files", { no_ignore = true, default_text = line })() |
||||
|
end, |
||||
|
["<a-h>"] = function() |
||||
|
local action_state = require("telescope.actions.state") |
||||
|
local line = action_state.get_current_line() |
||||
|
Util.telescope("find_files", { hidden = true, default_text = line })() |
||||
|
end, |
||||
|
["<C-Down>"] = function(...) |
||||
|
return require("telescope.actions").cycle_history_next(...) |
||||
|
end, |
||||
|
["<C-Up>"] = function(...) |
||||
|
return require("telescope.actions").cycle_history_prev(...) |
||||
|
end, |
||||
|
["<C-f>"] = function(...) |
||||
|
return require("telescope.actions").preview_scrolling_down(...) |
||||
|
end, |
||||
|
["<C-b>"] = function(...) |
||||
|
return require("telescope.actions").preview_scrolling_up(...) |
||||
|
end, |
||||
|
}, |
||||
|
n = { |
||||
|
["q"] = function(...) |
||||
|
return require("telescope.actions").close(...) |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
-- todo comments |
||||
|
return { |
||||
|
"folke/todo-comments.nvim", |
||||
|
cmd = { "TodoTrouble", "TodoTelescope" }, |
||||
|
event = { "BufReadPost", "BufNewFile" }, |
||||
|
config = true, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "]t", function() require("todo-comments").jump_next() end, desc = "Next todo comment" }, |
||||
|
{ "[t", function() require("todo-comments").jump_prev() end, desc = "Previous todo comment" }, |
||||
|
{ "<leader>xt", "<cmd>TodoTrouble<cr>", desc = "Todo (Trouble)" }, |
||||
|
{ "<leader>xT", "<cmd>TodoTrouble keywords=TODO,FIX,FIXME<cr>", desc = "Todo/Fix/Fixme (Trouble)" }, |
||||
|
{ "<leader>st", "<cmd>TodoTelescope<cr>", desc = "Todo" }, |
||||
|
{ "<leader>sT", "<cmd>TodoTelescope keywords=TODO,FIX,FIXME<cr>", desc = "Todo/Fix/Fixme" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
return { |
||||
|
'akinsho/toggleterm.nvim', |
||||
|
version = "*", |
||||
|
lazy = false, |
||||
|
priority = 1001, |
||||
|
opts = { |
||||
|
open_mapping = [[<c-\>]], |
||||
|
direction = 'float', |
||||
|
shade_terminals = true, |
||||
|
float_opts = { |
||||
|
border = "curved", |
||||
|
} |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<esc>", [[<c-\><c-n>]], mode = 't', desc = "Enter free movement" }, |
||||
|
--{ "jk", [[<C-\><C-n>]], mode = 't', desc = "" }, |
||||
|
{ "<C-h>", [[<Cmd>wincmd h<CR>]], mode = 't', desc = "Leave"} , |
||||
|
{ "<C-j>", [[<Cmd>wincmd j<CR>]], mode = 't', desc = "Leave" }, |
||||
|
{ "<C-k>", [[<Cmd>wincmd k<CR>]], mode = 't', desc = "Leave" }, |
||||
|
{ "<C-l>", [[<Cmd>wincmd l<CR>]], mode = 't', desc = "Leave" }, |
||||
|
{ "<C-w>", [[<C-\><C-n><C-w>]], mode = 't', desc = "Leave" }, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
require('toggleterm').setup(opts) |
||||
|
-- |
||||
|
local Terminal = require('toggleterm.terminal').Terminal |
||||
|
|
||||
|
local htop = Terminal:new({ cmd = "htop", direction = "horizontal", hidden = true }) |
||||
|
function _htop_toggle() |
||||
|
htop:toggle() |
||||
|
end |
||||
|
|
||||
|
local lazygit = Terminal:new({ cmd = "lazygit", dir = "git_dir", hidden = true }) |
||||
|
function _lazygit_toggle() |
||||
|
lazygit:toggle() |
||||
|
end |
||||
|
|
||||
|
vim.api.nvim_set_keymap("n", "<leader>tf", "<cmd>ToggleTerm direction=float<CR>", { desc = "Toggle floating terminal", noremap = true, silent = true }) |
||||
|
vim.api.nvim_set_keymap("n", "<leader>th", "<cmd>ToggleTerm direction=horizontal size=10<CR>", { desc = "Toggle horizontal terminal", noremap = true, silent = true }) |
||||
|
vim.api.nvim_set_keymap("n", "<leader>tv", "<cmd>ToggleTerm direction=vertical size=80<CR>", { desc = "Toggle vertical terminal", noremap = true, silent = true }) |
||||
|
|
||||
|
vim.api.nvim_set_keymap("n", "<leader>tg", "<cmd>lua _lazygit_toggle()<CR>", {noremap = true, silent = true}) |
||||
|
vim.api.nvim_set_keymap("n", "<leader>tt", "<cmd>lua _htop_toggle()<CR>", {noremap = true, silent = true}) |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
-- highlight words under cursor |
||||
|
return { |
||||
|
"RRethy/vim-illuminate", |
||||
|
event = { "BufReadPost", "BufNewFile" }, |
||||
|
enabled = false, |
||||
|
opts = { |
||||
|
delay = 200, |
||||
|
large_file_cutoff = 2000, |
||||
|
large_file_overrides = { |
||||
|
providers = { "lsp" }, |
||||
|
}, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
require("illuminate").configure(opts) |
||||
|
|
||||
|
local function map(key, dir, buffer) |
||||
|
vim.keymap.set("n", key, function() |
||||
|
require("illuminate")["goto_" .. dir .. "_reference"](false) |
||||
|
end, { desc = dir:sub(1, 1):upper() .. dir:sub(2) .. " Reference", buffer = buffer }) |
||||
|
end |
||||
|
|
||||
|
map("]]", "next") |
||||
|
map("[[", "prev") |
||||
|
|
||||
|
-- also set it after loading ftplugins, since a lot overwrite [[ and ]] |
||||
|
vim.api.nvim_create_autocmd("FileType", { |
||||
|
callback = function() |
||||
|
local buffer = vim.api.nvim_get_current_buf() |
||||
|
map("]]", "next", buffer) |
||||
|
map("[[", "prev", buffer) |
||||
|
end, |
||||
|
}) |
||||
|
end, |
||||
|
keys = { |
||||
|
{ "]]", desc = "Next Reference" }, |
||||
|
{ "[[", desc = "Prev Reference" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
-- match-up is a plugin that lets you highlight, navigate, and operate on sets of matching text |
||||
|
-- (a.1) jump between matching words |
||||
|
-- (a.2) jump to open & close words |
||||
|
-- (a.3) jump inside (z%) |
||||
|
-- (b.1) full set of text objects |
||||
|
-- (b.2) delete surrounding matched words |
||||
|
-- (c.1) highlight (), [], & {} |
||||
|
-- (c.2) highlight all matching words |
||||
|
-- (c.3) display matches off-screen |
||||
|
-- (c.4) show where you are (breadcrumbs) |
||||
|
-- (d.1) (neovim) tree-sitter integration |
||||
|
return { |
||||
|
'andymass/vim-matchup', |
||||
|
config = function() |
||||
|
local g = vim.g |
||||
|
g.matchup_matchparen_deferred = 1 |
||||
|
g.matchup_matchparen_deferred_show_delay = 100 |
||||
|
g.matchup_matchparen_hi_surround_always = 1 |
||||
|
g.matchup_override_vimtex = 1 |
||||
|
g.matchup_delim_start_plaintext = 0 |
||||
|
g.matchup_transmute_enabled = 0 |
||||
|
end, |
||||
|
event = 'User ActuallyEditing', |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
return { |
||||
|
'mg979/vim-visual-multi', |
||||
|
config = function() |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
-- The aim of yanky.nvim is to improve yank and put functionalities for Neovim |
||||
|
return { |
||||
|
"gbprod/yanky.nvim", |
||||
|
dependencies = { |
||||
|
"kkharji/sqlite.lua", |
||||
|
}, |
||||
|
opts = { |
||||
|
highlight = { |
||||
|
on_put = true, |
||||
|
on_yank = true, |
||||
|
timer = 500, |
||||
|
}, |
||||
|
ring = { |
||||
|
history_length = 100, |
||||
|
storage = "sqlite", |
||||
|
sync_with_numbered_registers = true, |
||||
|
cancel_event = "update", |
||||
|
ignore_registers = { "_" }, |
||||
|
}, |
||||
|
system_clipboard = { |
||||
|
sync_with_ring = true, |
||||
|
}, |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "p", "<Plug>(YankyPutAfter)", desc = "Yanky put after", }, |
||||
|
{ "P", "<Plug>(YankyPutBefore)", desc = "Yanky put before", }, |
||||
|
{ "gp", "<Plug>(YankyPutGPutAfter)", desc = "Yanky put after and leave cursor after", }, |
||||
|
{ "gP", "<Plug>(YankyPutGPutBefore)", desc = "Yanky put before and leave cursor after", }, |
||||
|
{ "<c-n>", "<Plug>(YankyCycleForward)", desc = "Yanky-ring fore", }, |
||||
|
{ "<c-p>", "<Plug>(YankyCycleBackward)", desc = "Yanky-ring back", }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
-- dashboard |
||||
|
return { |
||||
|
"goolord/alpha-nvim", |
||||
|
event = "VimEnter", |
||||
|
enabled = false, |
||||
|
opts = function() |
||||
|
local dashboard = require("alpha.themes.dashboard") |
||||
|
local logo = [[ |
||||
|
█████╗ █████╗ ██╗ ██╗ █████╗ |
||||
|
██║ █║ ██═══╝ ██║██╦╝ ██═══╝ |
||||
|
█████║ ████╗ ████╦╝ ████╗ |
||||
|
██╔══╝ ██╔═╝ ██║██╗ ██╔═╝ |
||||
|
██║ ██║ ██║ ██╗ █████╗ |
||||
|
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝ |
||||
|
]] |
||||
|
|
||||
|
dashboard.section.header.val = vim.split(logo, "\n") |
||||
|
dashboard.section.buttons.val = { |
||||
|
dashboard.button("f", " " .. " Find file", ":Telescope find_files <CR>"), |
||||
|
dashboard.button("n", " " .. " New file", ":ene <BAR> startinsert <CR>"), |
||||
|
dashboard.button("r", " " .. " Recent files", ":Telescope oldfiles <CR>"), |
||||
|
dashboard.button("g", " " .. " Find text", ":Telescope live_grep <CR>"), |
||||
|
dashboard.button("c", " " .. " Config", ":e $MYVIMRC <CR>"), |
||||
|
dashboard.button("s", " " .. " Restore Session", [[:lua require("persistence").load() <cr>]]), |
||||
|
dashboard.button("l", " " .. " Lazy", ":Lazy<CR>"), |
||||
|
dashboard.button("q", " " .. " Quit", ":qa<CR>"), |
||||
|
} |
||||
|
for _, button in ipairs(dashboard.section.buttons.val) do |
||||
|
button.opts.hl = "AlphaButtons" |
||||
|
button.opts.hl_shortcut = "AlphaShortcut" |
||||
|
end |
||||
|
dashboard.section.header.opts.hl = "AlphaHeader" |
||||
|
dashboard.section.buttons.opts.hl = "AlphaButtons" |
||||
|
dashboard.section.footer.opts.hl = "AlphaFooter" |
||||
|
dashboard.opts.layout[1].val = 8 |
||||
|
return dashboard |
||||
|
end, |
||||
|
config = function(_, dashboard) |
||||
|
-- close Lazy and re-open when the dashboard is ready |
||||
|
if vim.o.filetype == "lazy" then |
||||
|
vim.cmd.close() |
||||
|
vim.api.nvim_create_autocmd("User", { |
||||
|
pattern = "AlphaReady", |
||||
|
callback = function() |
||||
|
require("lazy").show() |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
require("alpha").setup(dashboard.opts) |
||||
|
|
||||
|
vim.api.nvim_create_autocmd("User", { |
||||
|
pattern = "VimStarted", |
||||
|
callback = function() |
||||
|
local stats = require("lazy").stats() |
||||
|
local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100) |
||||
|
dashboard.section.footer.val = "⚡ Neovim loaded " .. stats.count .. " plugins in " .. ms .. "ms" |
||||
|
pcall(vim.cmd.AlphaRedraw) |
||||
|
end, |
||||
|
}) |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
-- bufferline |
||||
|
return { |
||||
|
"akinsho/bufferline.nvim", |
||||
|
event = "VeryLazy", |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>bs"] = { name = "+sort" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
'famiu/bufdelete.nvim', |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<leader>bsd", function() require("bufferline").sort_by("directory") end, desc = "sort by directory" }, |
||||
|
{ "<leader>bse", function() require("bufferline").sort_by("extension") end, desc = "sort by extension" }, |
||||
|
{ "<leader>bst", function() require("bufferline").sort_by("tabs") end, desc = "sort by tabs" }, |
||||
|
{ "<leader>bp", "<Cmd>BufferLineTogglePin<CR>", desc = "Toggle pin" }, |
||||
|
{ "<leader>bP", "<Cmd>BufferLineGroupClose ungrouped<CR>", desc = "Delete non-pinned buffers" }, |
||||
|
{ "<leader>br", "<Cmd>BufferLineCloseRight<CR>", desc = "Close all to the right" }, |
||||
|
{ "<leader>bl", "<Cmd>BufferLineCloseLeft<CR>", desc = "Close all to the left" }, |
||||
|
{ "<A-left>", "<Cmd>BufferLineCyclePrev<CR>", desc = "Prev Tab" }, |
||||
|
{ "<A-right>", "<Cmd>BufferLineCycleNext<CR>", desc = "Next Tab" }, |
||||
|
{ "<C-A-left>", "<Cmd>BufferLineMovePrev<CR>", desc = "Move current buffer forward" }, |
||||
|
{ "<C-A-right>", "<Cmd>BufferLineMoveNext<CR>", desc = "Move current buffer backwards" }, |
||||
|
{ "<A-1>", function() require("bufferline").go_to(1, true) end, desc = "Goto buffer 1" }, |
||||
|
{ "<A-2>", function() require("bufferline").go_to(2, true) end, desc = "Goto buffer 2" }, |
||||
|
{ "<A-3>", function() require("bufferline").go_to(3, true) end, desc = "Goto buffer 3" }, |
||||
|
{ "<A-4>", function() require("bufferline").go_to(4, true) end, desc = "Goto buffer 4" }, |
||||
|
{ "<A-5>", function() require("bufferline").go_to(5, true) end, desc = "Goto buffer 5" }, |
||||
|
{ "<A-6>", function() require("bufferline").go_to(6, true) end, desc = "Goto buffer 6" }, |
||||
|
{ "<A-7>", function() require("bufferline").go_to(7, true) end, desc = "Goto buffer 7" }, |
||||
|
{ "<A-8>", function() require("bufferline").go_to(8, true) end, desc = "Goto buffer 8" }, |
||||
|
{ "<A-9>", function() require("bufferline").go_to(9, true) end, desc = "Goto buffer 9" }, |
||||
|
{ "<A-0>", function() require("bufferline").go_to(0, true) end, desc = "Goto buffer 0" }, |
||||
|
{ "<A-ß>", function() require("bufferline").go_to(-1, true) end, desc = "Goto last visible buffer" }, |
||||
|
{ "<C-Del>", function() require("bufdelete").bufdelete(0, true) end, desc = "delete current buffer" }, |
||||
|
}, |
||||
|
opts = { |
||||
|
options = { |
||||
|
-- stylua: ignore |
||||
|
close_command = function(n) require("mini.bufremove").delete(n, false) end, |
||||
|
-- stylua: ignore |
||||
|
right_mouse_command = function(n) require("mini.bufremove").delete(n, false) end, |
||||
|
diagnostics = "nvim_lsp", |
||||
|
always_show_bufferline = true, |
||||
|
diagnostics_indicator = function(_, _, diag) |
||||
|
local icons = require("core.config").icons.diagnostics |
||||
|
local ret = (diag.error and icons.Error .. diag.error .. " " or "") |
||||
|
.. (diag.warning and icons.Warn .. diag.warning or "") |
||||
|
return vim.trim(ret) |
||||
|
end, |
||||
|
offsets = { |
||||
|
{ |
||||
|
filetype = "neo-tree", |
||||
|
text = "Neo-tree", |
||||
|
highlight = "Directory", |
||||
|
text_align = "left", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
return { |
||||
|
"nvim-zh/colorful-winsep.nvim", |
||||
|
config = true, |
||||
|
event = { "WinNew" }, |
||||
|
opts = {} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
-- better vim.ui |
||||
|
-- ui hooks |
||||
|
return { |
||||
|
"stevearc/dressing.nvim", |
||||
|
lazy = true, |
||||
|
init = function() |
||||
|
---@diagnostic disable-next-line: duplicate-set-field |
||||
|
vim.ui.select = function(...) |
||||
|
require("lazy").load({ plugins = { "dressing.nvim" } }) |
||||
|
return vim.ui.select(...) |
||||
|
end |
||||
|
---@diagnostic disable-next-line: duplicate-set-field |
||||
|
vim.ui.input = function(...) |
||||
|
require("lazy").load({ plugins = { "dressing.nvim" } }) |
||||
|
return vim.ui.input(...) |
||||
|
end |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,158 @@ |
|||||
|
-- A Neovim plugin to easily create and manage predefined window layouts, bringing a new edge to your workflow |
||||
|
return { |
||||
|
-- edgy |
||||
|
{ |
||||
|
"folke/edgy.nvim", |
||||
|
event = "VeryLazy", |
||||
|
enabled = false, |
||||
|
keys = { |
||||
|
{ |
||||
|
"<leader>ue", |
||||
|
function() |
||||
|
require("edgy").toggle() |
||||
|
end, |
||||
|
desc = "Edgy Toggle", |
||||
|
}, |
||||
|
-- stylua: ignore |
||||
|
{ "<leader>uE", function() require("edgy").select() end, desc = "Edgy Select Window" }, |
||||
|
}, |
||||
|
opts = { |
||||
|
bottom = { |
||||
|
{ |
||||
|
ft = "toggleterm", |
||||
|
size = { height = 0.4 }, |
||||
|
filter = function(buf, win) |
||||
|
return vim.api.nvim_win_get_config(win).relative == "" |
||||
|
end, |
||||
|
}, |
||||
|
{ |
||||
|
ft = "noice", |
||||
|
size = { height = 0.4 }, |
||||
|
filter = function(buf, win) |
||||
|
return vim.api.nvim_win_get_config(win).relative == "" |
||||
|
end, |
||||
|
}, |
||||
|
{ |
||||
|
ft = "lazyterm", |
||||
|
title = "LazyTerm", |
||||
|
size = { height = 0.4 }, |
||||
|
filter = function(buf) |
||||
|
return not vim.b[buf].lazyterm_cmd |
||||
|
end, |
||||
|
}, |
||||
|
"Trouble", |
||||
|
{ ft = "qf", title = "QuickFix" }, |
||||
|
{ |
||||
|
ft = "help", |
||||
|
size = { height = 20 }, |
||||
|
-- don't open help files in edgy that we're editing |
||||
|
filter = function(buf) |
||||
|
return vim.bo[buf].buftype == "help" |
||||
|
end, |
||||
|
}, |
||||
|
{ ft = "spectre_panel", size = { height = 0.4 } }, |
||||
|
{ title = "Neotest Output", ft = "neotest-output-panel", size = { height = 15 } }, |
||||
|
}, |
||||
|
left = { |
||||
|
{ |
||||
|
title = "Neo-Tree", |
||||
|
ft = "neo-tree", |
||||
|
filter = function(buf) |
||||
|
return vim.b[buf].neo_tree_source == "filesystem" |
||||
|
end, |
||||
|
pinned = true, |
||||
|
open = function() |
||||
|
vim.api.nvim_input("<esc><space>e") |
||||
|
end, |
||||
|
size = { height = 0.5 }, |
||||
|
}, |
||||
|
{ title = "Neotest Summary", ft = "neotest-summary" }, |
||||
|
{ |
||||
|
title = "Neo-Tree Git", |
||||
|
ft = "neo-tree", |
||||
|
filter = function(buf) |
||||
|
return vim.b[buf].neo_tree_source == "git_status" |
||||
|
end, |
||||
|
pinned = true, |
||||
|
open = "Neotree position=right git_status", |
||||
|
}, |
||||
|
{ |
||||
|
title = "Neo-Tree Buffers", |
||||
|
ft = "neo-tree", |
||||
|
filter = function(buf) |
||||
|
return vim.b[buf].neo_tree_source == "buffers" |
||||
|
end, |
||||
|
pinned = true, |
||||
|
open = "Neotree position=top buffers", |
||||
|
}, |
||||
|
{ |
||||
|
ft = "Outline", |
||||
|
pinned = true, |
||||
|
open = "SymbolsOutline", |
||||
|
}, |
||||
|
"neo-tree", |
||||
|
}, |
||||
|
keys = { |
||||
|
-- increase width |
||||
|
["<c-Right>"] = function(win) |
||||
|
win:resize("width", 2) |
||||
|
end, |
||||
|
-- decrease width |
||||
|
["<c-Left>"] = function(win) |
||||
|
win:resize("width", -2) |
||||
|
end, |
||||
|
-- increase height |
||||
|
["<c-Up>"] = function(win) |
||||
|
win:resize("height", 2) |
||||
|
end, |
||||
|
-- decrease height |
||||
|
["<c-Down>"] = function(win) |
||||
|
win:resize("height", -2) |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
-- prevent neo-tree from opening files in edgy windows |
||||
|
{ |
||||
|
"nvim-neo-tree/neo-tree.nvim", |
||||
|
optional = true, |
||||
|
opts = function(_, opts) |
||||
|
opts.open_files_do_not_replace_types = opts.open_files_do_not_replace_types |
||||
|
or { "terminal", "Trouble", "qf", "Outline" } |
||||
|
table.insert(opts.open_files_do_not_replace_types, "edgy") |
||||
|
end, |
||||
|
}, |
||||
|
|
||||
|
-- Fix bufferline offsets when edgy is loaded |
||||
|
{ |
||||
|
"akinsho/bufferline.nvim", |
||||
|
optional = true, |
||||
|
opts = function() |
||||
|
local Offset = require("bufferline.offset") |
||||
|
if not Offset.edgy then |
||||
|
local get = Offset.get |
||||
|
Offset.get = function() |
||||
|
if package.loaded.edgy then |
||||
|
local layout = require("edgy.config").layout |
||||
|
local ret = { left = "", left_size = 0, right = "", right_size = 0 } |
||||
|
for _, pos in ipairs({ "left", "right" }) do |
||||
|
local sb = layout[pos] |
||||
|
if sb and #sb.wins > 0 then |
||||
|
local title = " Sidebar" .. string.rep(" ", sb.bounds.width - 8) |
||||
|
ret[pos] = "%#EdgyTitle#" .. title .. "%*" .. "%#WinSeparator#│%*" |
||||
|
ret[pos .. "_size"] = sb.bounds.width |
||||
|
end |
||||
|
end |
||||
|
ret.total_size = ret.left_size + ret.right_size |
||||
|
if ret.total_size > 0 then |
||||
|
return ret |
||||
|
end |
||||
|
end |
||||
|
return get() |
||||
|
end |
||||
|
Offset.edgy = true |
||||
|
end |
||||
|
end, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
return { |
||||
|
'anuvyklack/hydra.nvim', |
||||
|
lazy = false, |
||||
|
dependencies = { |
||||
|
"mrjones2014/smart-splits.nvim", |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>w"] = { name = "+windows" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
-- WinShift lets you freely rearrange your window layouts by letting you move any |
||||
|
-- window in any direction. Further, it doesn't only let you move around windows, |
||||
|
-- but also lets you form new columns and rows by moving into windows horizontally |
||||
|
-- or vertically respectively |
||||
|
'sindrets/winshift.nvim', |
||||
|
opts = { |
||||
|
highlight_moving_win = true, -- Highlight the window being moved |
||||
|
focused_hl_group = "Visual", -- The highlight group used for the moving window |
||||
|
moving_win_options = { |
||||
|
-- These are local options applied to the moving window while it's |
||||
|
-- being moved. They are unset when you leave Win-Move mode. |
||||
|
wrap = false, |
||||
|
cursorline = false, |
||||
|
cursorcolumn = false, |
||||
|
colorcolumn = "", |
||||
|
}, |
||||
|
keymaps = { |
||||
|
disable_defaults = true, -- Disable the default keymaps |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
config = function() |
||||
|
-- TODO autom. über alle lua-files iterieren |
||||
|
require('core.plugins.ui.hydra.hydra_for_colorscheme') |
||||
|
require('core.plugins.ui.hydra.hydra_for_git') |
||||
|
require('core.plugins.ui.hydra.hydra_for_motion') |
||||
|
require('core.plugins.ui.hydra.hydra_for_windows') |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,94 @@ |
|||||
|
local Hydra = require('hydra') |
||||
|
|
||||
|
local window_hint = [[ |
||||
|
Colorschemes |
||||
|
------------ |
||||
|
f o r e s t ^ ^ box-material |
||||
|
e ┌──^─^────────^─^──┐ g ┌──^─^────────^─^──┐ |
||||
|
v │ _q_ hart _Q_ │ r │ _w_ hart _W_ │ |
||||
|
e │ _a_ medium _A_ │ u │ _s_ medium _S_ │ |
||||
|
r │ _y_ soft _Y_ │ v │ _x_ soft _X_ │ |
||||
|
└──^─^────────^─^──┘ └──^─^────────^─^──┘ |
||||
|
s o n o k a i |
||||
|
┌─^─^───────────^─^──────────┐ |
||||
|
│ _e_ default _E_ shusia │ |
||||
|
│ _d_ atlantis _D_ maia │ |
||||
|
│ _c_ andromeda _C_ espresso │ |
||||
|
└─^─^───────────^─^──────────┘ |
||||
|
e d g e ^ ^ n i g h t f o x |
||||
|
┌──^─^────────^─^─┐ ┌──^─^───────────────^─^──┐ |
||||
|
│ _r_ aura ^ ^ │ │ _t_ night-/dayfox _T_ │ |
||||
|
│ _f_ default _F_ │ │ _g_ nord-/dawnfox _G_ │ |
||||
|
│ _v_ neon ^ ^ │ │ _b_ dusk-/terafox _B_ │ |
||||
|
└──^─^────────^─^─┘ │ _n_ carbonfox ^ ^ │ |
||||
|
^ ^ ^ ^ └──────^─^───────────^─^──┘ |
||||
|
]] |
||||
|
|
||||
|
local function set_colorscheme(colorscheme, background, contrast) |
||||
|
vim.cmd(string.format("set background=%s", background)) |
||||
|
vim.cmd(string.format("let g:%s_background = '%s'", colorscheme, contrast)) |
||||
|
vim.cmd(string.format("let g:%s_better_performance = 1", colorscheme)) |
||||
|
vim.cmd(string.format("let g:%s_current_word = 'underline'", colorscheme)) |
||||
|
-- replace _ with - because 'gruvbox_material' is configured with underscore, but its name is '-' |
||||
|
vim.cmd(string.format("colorscheme %s", colorscheme):gsub("_", "-")) |
||||
|
end |
||||
|
|
||||
|
local function set_colorscheme_wstyle(colorscheme, background, style) |
||||
|
vim.cmd(string.format("set background=%s", background)) |
||||
|
vim.cmd(string.format("let g:%s_style = '%s'", colorscheme, style)) |
||||
|
vim.cmd(string.format("let g:%s_better_performance = 1", colorscheme)) |
||||
|
vim.cmd(string.format("let g:%s_current_word = 'underline'", colorscheme)) |
||||
|
vim.cmd(string.format("colorscheme %s", colorscheme):gsub("_", "-")) |
||||
|
end |
||||
|
|
||||
|
Hydra({ |
||||
|
name = 'Colorschemes', |
||||
|
hint = window_hint, |
||||
|
config = { |
||||
|
invoke_on_body = true, |
||||
|
hint = { |
||||
|
border = 'rounded', |
||||
|
offset = -1, |
||||
|
position = 'middle-right', |
||||
|
} |
||||
|
}, |
||||
|
mode = 'n', |
||||
|
body = '<leader>uc', |
||||
|
heads = { |
||||
|
{ 'q', function() set_colorscheme('everforest', 'dark', 'hard') end, { desc = "Everforest dark / hard" }, }, |
||||
|
{ 'a', function() set_colorscheme('everforest', 'dark', 'medium') end, { desc = "Everforest dark / medium" }, }, |
||||
|
{ 'y', function() set_colorscheme('everforest', 'dark', 'soft') end, { desc = "Everforest dark / soft" }, }, |
||||
|
{ 'Q', function() set_colorscheme('everforest', 'light', 'hard') end, { desc = "Everforest light / hard" }, }, |
||||
|
{ 'A', function() set_colorscheme('everforest', 'light', 'medium') end, { desc = "Everforest light / medium" }, }, |
||||
|
{ 'Y', function() set_colorscheme('everforest', 'light', 'soft') end, { desc = "Everforest light / soft" }, }, |
||||
|
|
||||
|
{ 'w', function() set_colorscheme('gruvbox_material', 'dark', 'hard') end, { desc = "Gruvbox-Material dark / hard" }, }, |
||||
|
{ 's', function() set_colorscheme('gruvbox_material', 'dark', 'medium') end, { desc = "Gruvbox-Material dark / medium" }, }, |
||||
|
{ 'x', function() set_colorscheme('gruvbox_material', 'dark', 'soft') end, { desc = "Gruvbox-Material dark / soft" }, }, |
||||
|
{ 'W', function() set_colorscheme('gruvbox_material', 'light', 'hard') end, { desc = "Gruvbox-Material light / hard" }, }, |
||||
|
{ 'S', function() set_colorscheme('gruvbox_material', 'light', 'medium') end, { desc = "Gruvbox-Material light / medium" }, }, |
||||
|
{ 'X', function() set_colorscheme('gruvbox_material', 'light', 'soft') end, { desc = "Gruvbox-Material light / soft" }, }, |
||||
|
|
||||
|
{ 'e', function() set_colorscheme_wstyle('sonokai', 'dark', 'default') end, { desc = "Sonokai: Default" }, }, |
||||
|
{ 'd', function() set_colorscheme_wstyle('sonokai', 'dark', 'atlantis') end, { desc = "Sonokai: Atlantis" }, }, |
||||
|
{ 'c', function() set_colorscheme_wstyle('sonokai', 'dark', 'andromeda') end, { desc = "Sonokai: Andromeda" }, }, |
||||
|
{ 'E', function() set_colorscheme_wstyle('sonokai', 'dark', 'shusia') end, { desc = "Sonokai: Shusia" }, }, |
||||
|
{ 'D', function() set_colorscheme_wstyle('sonokai', 'dark', 'maia') end, { desc = "Sonokai: Maia" }, }, |
||||
|
{ 'C', function() set_colorscheme_wstyle('sonokai', 'dark', 'espresso') end, { desc = "Sonokai: Espresso" }, }, |
||||
|
|
||||
|
{ 'r', function() set_colorscheme_wstyle('edge', 'dark', 'aura') end, { desc = "Edge: Atlantis" }, }, |
||||
|
{ 'f', function() set_colorscheme_wstyle('edge', 'dark', 'default') end, { desc = "Edge: Default" }, }, |
||||
|
{ 'F', function() set_colorscheme_wstyle('edge', 'light', 'default') end, { desc = "Edge: light" }, }, |
||||
|
{ 'v', function() set_colorscheme_wstyle('edge', 'dark', 'neon') end, { desc = "Edge: Andromeda" }, }, |
||||
|
|
||||
|
{ 't', function() vim.cmd("colorscheme nightfox") end, { desc = "Nightfox: Nightfox" }, }, |
||||
|
{ 'T', function() vim.cmd("colorscheme dayfox") end, { desc = "Nightfox: Dayfox" }, }, |
||||
|
{ 'g', function() vim.cmd("colorscheme nordfox") end, { desc = "Nightfox: Nordfox" }, }, |
||||
|
{ 'G', function() vim.cmd("colorscheme dawnfox") end, { desc = "Nightfox: Dawnfox" }, }, |
||||
|
{ 'b', function() vim.cmd("colorscheme duskfox") end, { desc = "Nightfox: Duskfox" }, }, |
||||
|
{ 'B', function() vim.cmd("colorscheme terafox") end, { desc = "Nightfox: Terafox" }, }, |
||||
|
{ 'n', function() vim.cmd("colorscheme carbonfox") end, { desc = "Nightfox: Carbonfox" }, }, |
||||
|
|
||||
|
{ '<Esc>', nil, { exit = true, desc = false }} |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,94 @@ |
|||||
|
local Hydra = require('hydra') |
||||
|
|
||||
|
local gitsigns = require('gitsigns') |
||||
|
local telescope = require('telescope.builtin') |
||||
|
|
||||
|
local hint = [[ |
||||
|
_n_/_N_: next/prev hunk _b_/_B_: blame light/full _1_: show buf commits _d_: show deleted |
||||
|
_s_/_u_: stage/unstage hunk ^ ^ ^ ^ _2_: show commits _t_: toggle line blame |
||||
|
_p_/_P_: preview/inline hunk _/_ ^ ^: show base file _3_: show branches _l_: toggle no hl |
||||
|
_S_ ^ ^: stage buffer _?_ ^ ^: diff _4_: show files _L_: toggle line hl |
||||
|
_r_/_R_: reset hunk/buffer ^ ^ ^ ^ _5_: show status _w_: toggle word diff |
||||
|
^ ^ ^ ^ ^ ^ ^ ^ _6_: show stash _v_: toggle gitsigns |
||||
|
^ |
||||
|
^ ^ ^ ^ _<Enter>_: Neogit _<Esc>_: exit |
||||
|
]] |
||||
|
|
||||
|
Hydra({ |
||||
|
name = 'Git', |
||||
|
hint = hint, |
||||
|
config = { |
||||
|
buffer = bufnr, |
||||
|
color = 'pink', |
||||
|
invoke_on_body = true, |
||||
|
hint = { |
||||
|
border = 'rounded' |
||||
|
}, |
||||
|
on_enter = function() |
||||
|
vim.cmd 'mkview' |
||||
|
vim.cmd 'silent! %foldopen!' |
||||
|
vim.bo.modifiable = true |
||||
|
gitsigns.toggle_signs(true) |
||||
|
gitsigns.toggle_linehl(true) |
||||
|
gitsigns.toggle_deleted(true) |
||||
|
end, |
||||
|
on_exit = function() |
||||
|
local cursor_pos = vim.api.nvim_win_get_cursor(0) |
||||
|
vim.cmd 'loadview' |
||||
|
vim.api.nvim_win_set_cursor(0, cursor_pos) |
||||
|
vim.cmd 'normal zv' |
||||
|
gitsigns.toggle_signs(false) |
||||
|
gitsigns.toggle_linehl(false) |
||||
|
gitsigns.toggle_deleted(false) |
||||
|
end, |
||||
|
}, |
||||
|
mode = {'n','x'}, |
||||
|
body = '<leader>g', |
||||
|
heads = { |
||||
|
{ 'n', |
||||
|
function() |
||||
|
if vim.wo.diff then return ']c' end |
||||
|
vim.schedule(function() gitsigns.next_hunk() end) |
||||
|
return '<Ignore>' |
||||
|
end, |
||||
|
{ expr = true, desc = 'next hunk' } }, |
||||
|
{ 'N', |
||||
|
function() |
||||
|
if vim.wo.diff then return '[c' end |
||||
|
vim.schedule(function() gitsigns.prev_hunk() end) |
||||
|
return '<Ignore>' |
||||
|
end, |
||||
|
{ expr = true, desc = 'prev hunk' } }, |
||||
|
{ 'p', gitsigns.preview_hunk, { desc = 'preview hunk' } }, |
||||
|
{ 'P', gitsigns.preview_hunk_inline, { desc = 'preview hunk inline' } }, |
||||
|
|
||||
|
{ 's', gitsigns.stage_hunk, { silent = true, desc = 'stage hunk' } }, |
||||
|
{ 'u', gitsigns.undo_stage_hunk, { desc = 'undo last stage' } }, |
||||
|
|
||||
|
{ 'r', gitsigns.reset_hunk, { desc = 'reset hunk' } }, |
||||
|
{ 'S', gitsigns.stage_buffer, { desc = 'stage buffer' } }, |
||||
|
{ 'R', gitsigns.reset_buffer, { exit = true, desc = 'reset buffer' } }, |
||||
|
|
||||
|
{ 'b', gitsigns.blame_line, { desc = 'blame' } }, |
||||
|
{ 'B', function() gitsigns.blame_line{ full = true } end, { desc = 'blame show full' } }, |
||||
|
{ '/', gitsigns.show, { exit = true, desc = 'show base file' } }, -- show the base of the file |
||||
|
{ '?', gitsigns.diffthis, { desc = 'diff' } }, |
||||
|
|
||||
|
{ 'd', gitsigns.toggle_deleted, { desc = 'toggle deleted' } }, |
||||
|
{ 't', gitsigns.toggle_current_line_blame, { desc = 'toggle line blame' } }, |
||||
|
{ 'l', gitsigns.toggle_numhl, { desc = 'toggle num hl' } }, |
||||
|
{ 'L', gitsigns.toggle_linehl, { desc = 'toggle line hl' } }, |
||||
|
{ 'w', gitsigns.toggle_word_diff, { desc = 'toggle word diff' } }, |
||||
|
{ 'v', gitsigns.toggle_signs, { desc = 'toggle gitsigns' } }, |
||||
|
|
||||
|
{ '1', telescope.git_bcommits, { exit_before = true, desc = 'show buf commits' } }, |
||||
|
{ '2', telescope.git_commits, { exit_before = true, desc = 'show commits' } }, |
||||
|
{ '3', telescope.git_branches, { exit_before = true, desc = 'show branches' } }, |
||||
|
{ '4', telescope.git_files, { exit_before = true, desc = 'show files' } }, |
||||
|
{ '5', telescope.git_status, { exit_before = true, desc = 'show status' } }, |
||||
|
{ '6', telescope.git_stash, { exit_before = true, desc = 'show stash' } }, |
||||
|
|
||||
|
{ '<Enter>', '<Cmd>Neogit<CR>', { exit = true, desc = 'Neogit' } }, |
||||
|
{ '<Esc>', nil, { exit = true, nowait = true, desc = 'exit' } }, |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,104 @@ |
|||||
|
local Hydra = require('hydra') |
||||
|
local splits = require('smart-splits') |
||||
|
|
||||
|
local cmd = require('hydra.keymap-util').cmd |
||||
|
local pcmd = require('hydra.keymap-util').pcmd |
||||
|
|
||||
|
|
||||
|
--Hydra({ |
||||
|
-- name = 'Movement', |
||||
|
-- config = { |
||||
|
-- color = 'pink', |
||||
|
-- }, |
||||
|
-- mode = 'n', |
||||
|
-- body = '<leader>m', |
||||
|
-- heads = { |
||||
|
-- { 'h', '5zh' }, |
||||
|
-- { 'l', '5zl', { desc = '←/→' } }, |
||||
|
-- { 'H', 'zH' }, |
||||
|
-- { 'L', 'zL', { desc = 'half screen ←/→' } }, |
||||
|
-- } |
||||
|
--}) |
||||
|
|
||||
|
local hint = [[ |
||||
|
Char^ ^ ^ ^ Page^ ^ ^ ^ ^ Split |
||||
|
^-^-^-^-^-^ ----^-^-^-^---^- ^^--------------- |
||||
|
^ ^ _k_ ^ ^ |
||||
|
_h_ ^ ^ _l_ |
||||
|
^ ^ _j_ ^ ^ |
||||
|
|
||||
|
^ ^ _K_ ^ ^ ⇈ |
||||
|
_H_ ^ ^ _L_ ⇇ ⇉ |
||||
|
^ ^ _J_ ^ ^ ⇊ |
||||
|
|
||||
|
|
||||
|
|
||||
|
^ ^ _-_ ^ ^ ↰ |
||||
|
_\^_ ^ ^ _$_ ↶ ↷ |
||||
|
^ ^ _+_ ^ ^ ↲ |
||||
|
|
||||
|
^ ^ ^ ^ ^ ^ ^ ^ ^ ^^ ^ ^ _o_: remain only |
||||
|
|
||||
|
zl zh |
||||
|
zL zH |
||||
|
|
||||
|
]] |
||||
|
-- <c-u> |
||||
|
-- <c-d> |
||||
|
|
||||
|
Hydra({ |
||||
|
name = 'Motion', |
||||
|
hint = hint, |
||||
|
config = { |
||||
|
invoke_on_body = true, |
||||
|
hint = { |
||||
|
border = 'rounded', |
||||
|
offset = -1 |
||||
|
} |
||||
|
}, |
||||
|
mode = 'n', |
||||
|
body = '<leader>m', |
||||
|
heads = { |
||||
|
{ 'h', 'h' }, |
||||
|
{ 'j', 'j' }, |
||||
|
{ 'k', 'k' }, |
||||
|
{ 'l', 'l' }, |
||||
|
|
||||
|
{ 'H', 'zh' }, |
||||
|
{ 'J', '<c-d>' }, |
||||
|
{ 'K', '<c-u>' }, |
||||
|
{ 'L', 'zl' }, |
||||
|
|
||||
|
{ '-', '-' }, |
||||
|
{ '^', '^' }, |
||||
|
{ '+', '+' }, |
||||
|
{ '$', '$' }, |
||||
|
|
||||
|
{ '<C-h>', function() splits.resize_left(2) end }, |
||||
|
{ '<C-j>', function() splits.resize_down(2) end }, |
||||
|
{ '<C-k>', function() splits.resize_up(2) end }, |
||||
|
{ '<C-l>', function() splits.resize_right(2) end }, |
||||
|
{ '=', '<C-w>=', { desc = 'equalize'} }, |
||||
|
|
||||
|
{ 's', pcmd('split', 'E36') }, |
||||
|
{ '<C-s>', pcmd('split', 'E36'), { desc = false } }, |
||||
|
{ 'v', pcmd('vsplit', 'E36') }, |
||||
|
{ '<C-v>', pcmd('vsplit', 'E36'), { desc = false } }, |
||||
|
|
||||
|
{ 'w', '<C-w>w', { exit = true, desc = false } }, |
||||
|
{ '<C-w>', '<C-w>w', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'z', cmd 'WindowsMaximaze', { exit = true, desc = 'maximize' } }, |
||||
|
{ '<C-z>', cmd 'WindowsMaximaze', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'o', '<C-w>o', { exit = true, desc = 'remain only' } }, |
||||
|
{ '<C-o>', '<C-w>o', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'c', pcmd('close', 'E444') }, |
||||
|
{ 'q', pcmd('close', 'E444'), { desc = 'close window' } }, |
||||
|
{ '<C-c>', pcmd('close', 'E444'), { desc = false } }, |
||||
|
{ '<C-q>', pcmd('close', 'E444'), { desc = false } }, |
||||
|
|
||||
|
{ '<Esc>', nil, { exit = true, desc = false }} |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,67 @@ |
|||||
|
local Hydra = require('hydra') |
||||
|
local splits = require('smart-splits') |
||||
|
|
||||
|
local cmd = require('hydra.keymap-util').cmd |
||||
|
local pcmd = require('hydra.keymap-util').pcmd |
||||
|
|
||||
|
local window_hint = [[ |
||||
|
^^^^^^^^^^^^ Move ^^ Size ^^ ^^ Split |
||||
|
^^^^^^^^^^^^------------- ^^-----------^^ ^^--------------- |
||||
|
^ ^ _k_ ^ ^ ^ ^ _K_ ^ ^ ^ _<C-k>_ ^ _s_: horizontally |
||||
|
_h_ ^ ^ _l_ _H_ ^ ^ _L_ _<C-h>_ _<C-l>_ _v_: vertically |
||||
|
^ ^ _j_ ^ ^ ^ ^ _J_ ^ ^ ^ _<C-j>_ ^ _q_, _c_: close |
||||
|
focus^^^^^^ window^^^^^^ ^_=_: equalize^ _z_: maximize |
||||
|
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^^ ^ ^ _o_: remain only |
||||
|
]] |
||||
|
|
||||
|
Hydra({ |
||||
|
name = 'Windows', |
||||
|
hint = window_hint, |
||||
|
config = { |
||||
|
invoke_on_body = true, |
||||
|
hint = { |
||||
|
border = 'rounded', |
||||
|
offset = -1 |
||||
|
} |
||||
|
}, |
||||
|
mode = 'n', |
||||
|
body = '<leader>ww', |
||||
|
heads = { |
||||
|
{ 'h', '<C-w>h' }, |
||||
|
{ 'j', '<C-w>j' }, |
||||
|
{ 'k', pcmd('wincmd k', 'E11', 'close') }, |
||||
|
{ 'l', '<C-w>l' }, |
||||
|
|
||||
|
{ 'H', cmd 'WinShift left' }, |
||||
|
{ 'J', cmd 'WinShift down' }, |
||||
|
{ 'K', cmd 'WinShift up' }, |
||||
|
{ 'L', cmd 'WinShift right' }, |
||||
|
|
||||
|
{ '<C-h>', function() splits.resize_left(2) end }, |
||||
|
{ '<C-j>', function() splits.resize_down(2) end }, |
||||
|
{ '<C-k>', function() splits.resize_up(2) end }, |
||||
|
{ '<C-l>', function() splits.resize_right(2) end }, |
||||
|
{ '=', '<C-w>=', { desc = 'equalize'} }, |
||||
|
|
||||
|
{ 's', pcmd('split', 'E36') }, |
||||
|
{ '<C-s>', pcmd('split', 'E36'), { desc = false } }, |
||||
|
{ 'v', pcmd('vsplit', 'E36') }, |
||||
|
{ '<C-v>', pcmd('vsplit', 'E36'), { desc = false } }, |
||||
|
|
||||
|
{ 'w', '<C-w>w', { exit = true, desc = false } }, |
||||
|
{ '<C-w>', '<C-w>w', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'z', cmd 'WindowsMaximaze', { exit = true, desc = 'maximize' } }, |
||||
|
{ '<C-z>', cmd 'WindowsMaximaze', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'o', '<C-w>o', { exit = true, desc = 'remain only' } }, |
||||
|
{ '<C-o>', '<C-w>o', { exit = true, desc = false } }, |
||||
|
|
||||
|
{ 'c', pcmd('close', 'E444') }, |
||||
|
{ 'q', pcmd('close', 'E444'), { desc = 'close window' } }, |
||||
|
{ '<C-c>', pcmd('close', 'E444'), { desc = false } }, |
||||
|
{ '<C-q>', pcmd('close', 'E444'), { desc = false } }, |
||||
|
|
||||
|
{ '<Esc>', nil, { exit = true, desc = false }} |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,34 @@ |
|||||
|
-- indent guides for Neovim |
||||
|
return { |
||||
|
"lukas-reineke/indent-blankline.nvim", |
||||
|
event = { "BufReadPost", "BufNewFile" }, |
||||
|
opts = { |
||||
|
-- char = "▏", |
||||
|
char = "│", |
||||
|
filetype_exclude = { |
||||
|
"help", |
||||
|
"alpha", |
||||
|
"dashboard", |
||||
|
"neo-tree", |
||||
|
"Trouble", |
||||
|
"lazy", |
||||
|
"mason", |
||||
|
"notify", |
||||
|
"toggleterm", |
||||
|
"lazyterm", |
||||
|
}, |
||||
|
show_end_of_line = true, |
||||
|
space_char_blankline = " ", |
||||
|
show_trailing_blankline_indent = false, |
||||
|
show_current_context = false, |
||||
|
show_current_context_start = true, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
require("ibl").setup { indent = { highlight = highlight } } |
||||
|
end, |
||||
|
init = function() |
||||
|
vim.opt.list = true |
||||
|
vim.opt.listchars:append "space:⋅" |
||||
|
vim.opt.listchars:append "eol:↴" |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
-- statusline |
||||
|
return { |
||||
|
"nvim-lualine/lualine.nvim", |
||||
|
event = "VeryLazy", |
||||
|
lazy = false, |
||||
|
opts = function() |
||||
|
local icons = require("core.config").icons |
||||
|
local Util = require("core.util") |
||||
|
|
||||
|
return { |
||||
|
options = { |
||||
|
theme = "auto", |
||||
|
globalstatus = true, |
||||
|
disabled_filetypes = { statusline = { "dashboard", "alpha" } }, |
||||
|
}, |
||||
|
sections = { |
||||
|
lualine_a = { "mode" }, |
||||
|
lualine_b = { "branch" }, |
||||
|
lualine_c = { |
||||
|
{ |
||||
|
"diagnostics", |
||||
|
symbols = { |
||||
|
error = icons.diagnostics.Error, |
||||
|
warn = icons.diagnostics.Warn, |
||||
|
info = icons.diagnostics.Info, |
||||
|
hint = icons.diagnostics.Hint, |
||||
|
}, |
||||
|
}, |
||||
|
{ "filetype", icon_only = true, separator = "", padding = { left = 1, right = 0 } }, |
||||
|
{ "filename", path = 1, symbols = { modified = " ", readonly = "", unnamed = "" } }, |
||||
|
-- stylua: ignore |
||||
|
{ |
||||
|
function() return require("nvim-navic").get_location() end, |
||||
|
cond = function() return package.loaded["nvim-navic"] and require("nvim-navic").is_available() end, |
||||
|
}, |
||||
|
}, |
||||
|
lualine_x = { |
||||
|
-- stylua: ignore |
||||
|
{ |
||||
|
function() return require("noice").api.status.command.get() end, |
||||
|
cond = function() return package.loaded["noice"] and require("noice").api.status.command.has() end, |
||||
|
color = Util.fg("Statement"), |
||||
|
}, |
||||
|
-- stylua: ignore |
||||
|
{ |
||||
|
function() return require("noice").api.status.mode.get() end, |
||||
|
cond = function() return package.loaded["noice"] and require("noice").api.status.mode.has() end, |
||||
|
color = Util.fg("Constant"), |
||||
|
}, |
||||
|
-- stylua: ignore |
||||
|
{ |
||||
|
function() return " " .. require("dap").status() end, |
||||
|
cond = function () return package.loaded["dap"] and require("dap").status() ~= "" end, |
||||
|
color = Util.fg("Debug"), |
||||
|
}, |
||||
|
{ require("lazy.status").updates, cond = require("lazy.status").has_updates, color = Util.fg("Special") }, |
||||
|
{ |
||||
|
"diff", |
||||
|
symbols = { |
||||
|
added = icons.git.added, |
||||
|
modified = icons.git.modified, |
||||
|
removed = icons.git.removed, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
lualine_y = { |
||||
|
{ "progress", separator = " ", padding = { left = 1, right = 0 } }, |
||||
|
{ "location", padding = { left = 0, right = 1 } }, |
||||
|
}, |
||||
|
lualine_z = { |
||||
|
function() |
||||
|
return " " .. os.date("%R") |
||||
|
end, |
||||
|
}, |
||||
|
}, |
||||
|
extensions = { "neo-tree", "lazy" }, |
||||
|
} |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
return { |
||||
|
'chentoast/marks.nvim', |
||||
|
opts = { |
||||
|
-- whether to map keybinds or not. default true |
||||
|
default_mappings = true, |
||||
|
-- which builtin marks to show. default {} |
||||
|
builtin_marks = { ".", "<", ">", "^" }, |
||||
|
-- whether movements cycle back to the beginning/end of buffer. default true |
||||
|
cyclic = true, |
||||
|
-- whether the shada file is updated after modifying uppercase marks. default false |
||||
|
force_write_shada = false, |
||||
|
-- how often (in ms) to redraw signs/recompute mark positions. |
||||
|
-- higher values will have better performance but may cause visual lag, |
||||
|
-- while lower values may cause performance penalties. default 150. |
||||
|
refresh_interval = 250, |
||||
|
-- sign priorities for each type of mark - builtin marks, uppercase marks, lowercase |
||||
|
-- marks, and bookmarks. |
||||
|
-- can be either a table with all/none of the keys, or a single number, in which case |
||||
|
-- the priority applies to all marks. |
||||
|
-- default 10. |
||||
|
sign_priority = { lower=10, upper=15, builtin=8, bookmark=20 }, |
||||
|
-- disables mark tracking for specific filetypes. default {} |
||||
|
excluded_filetypes = {}, |
||||
|
-- marks.nvim allows you to configure up to 10 bookmark groups, each with its own |
||||
|
-- sign/virttext. Bookmarks can be used to group together positions and quickly move |
||||
|
-- across multiple buffers. default sign is '!@#$%^&*()' (from 0 to 9), and |
||||
|
-- default virt_text is "". |
||||
|
bookmark_0 = { |
||||
|
sign = "⚑", |
||||
|
virt_text = "hello world" |
||||
|
}, |
||||
|
mappings = { |
||||
|
--next = "m>", |
||||
|
--prev = "m<", |
||||
|
--preview = false, |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
return { |
||||
|
-- animations |
||||
|
{ |
||||
|
"echasnovski/mini.animate", |
||||
|
event = "VeryLazy", |
||||
|
enabled = false, |
||||
|
opts = function() |
||||
|
-- don't use animate when scrolling with the mouse |
||||
|
local mouse_scrolled = false |
||||
|
for _, scroll in ipairs({ "Up", "Down" }) do |
||||
|
local key = "<ScrollWheel" .. scroll .. ">" |
||||
|
vim.keymap.set({ "", "i" }, key, function() |
||||
|
mouse_scrolled = true |
||||
|
return key |
||||
|
end, { expr = true }) |
||||
|
end |
||||
|
|
||||
|
local animate = require("mini.animate") |
||||
|
return { |
||||
|
resize = { |
||||
|
timing = animate.gen_timing.linear({ duration = 100, unit = "total" }), |
||||
|
}, |
||||
|
scroll = { |
||||
|
timing = animate.gen_timing.linear({ duration = 150, unit = "total" }), |
||||
|
subscroll = animate.gen_subscroll.equal({ |
||||
|
predicate = function(total_scroll) |
||||
|
if mouse_scrolled then |
||||
|
mouse_scrolled = false |
||||
|
return false |
||||
|
end |
||||
|
return total_scroll > 1 |
||||
|
end, |
||||
|
}), |
||||
|
}, |
||||
|
} |
||||
|
end, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
-- active indent guide and indent text objects |
||||
|
-- Visualize scope with animated vertical context line |
||||
|
return { |
||||
|
"echasnovski/mini.indentscope", |
||||
|
version = false, -- wait till new 0.7.0 release to put it back on semver |
||||
|
event = { "BufReadPre", "BufNewFile" }, |
||||
|
opts = { |
||||
|
-- symbol = "▏", |
||||
|
symbol = "│", |
||||
|
options = { try_as_border = true }, |
||||
|
}, |
||||
|
init = function() |
||||
|
vim.api.nvim_create_autocmd("FileType", { |
||||
|
pattern = { |
||||
|
"help", |
||||
|
"alpha", |
||||
|
"dashboard", |
||||
|
"neo-tree", |
||||
|
"Trouble", |
||||
|
"lazy", |
||||
|
"mason", |
||||
|
"notify", |
||||
|
"toggleterm", |
||||
|
"lazyterm", |
||||
|
}, |
||||
|
callback = function() |
||||
|
vim.b.miniindentscope_disable = true |
||||
|
end, |
||||
|
}) |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
return { |
||||
|
'MunifTanjim/nui.nvim' |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
return { |
||||
|
'yaocccc/nvim-foldsign', |
||||
|
opts = { |
||||
|
offset = -2, |
||||
|
foldsigns = { |
||||
|
open = '-', -- mark the beginning of a fold |
||||
|
close = '+', -- show a closed fold |
||||
|
seps = { '│', '┃' }, -- open fold middle marker |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
-- lsp symbol navigation for lualine |
||||
|
return { |
||||
|
"SmiteshP/nvim-navic", |
||||
|
lazy = true, |
||||
|
init = function() |
||||
|
vim.g.navic_silence = true |
||||
|
require("core.util").on_attach(function(client, buffer) |
||||
|
if client.server_capabilities.documentSymbolProvider then |
||||
|
require("nvim-navic").attach(client, buffer) |
||||
|
end |
||||
|
end) |
||||
|
end, |
||||
|
opts = function() |
||||
|
return { |
||||
|
separator = " ", |
||||
|
highlight = true, |
||||
|
depth_limit = 5, |
||||
|
icons = require("core.config").icons.kinds, |
||||
|
} |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
-- Better `vim.notify()` |
||||
|
return { |
||||
|
"rcarriga/nvim-notify", |
||||
|
keys = { |
||||
|
{ |
||||
|
"<leader>un", |
||||
|
function() |
||||
|
require("notify").dismiss({ silent = true, pending = true }) |
||||
|
end, |
||||
|
desc = "Dismiss all Notifications", |
||||
|
}, |
||||
|
}, |
||||
|
opts = { |
||||
|
timeout = 3000, |
||||
|
max_height = function() |
||||
|
return math.floor(vim.o.lines * 0.75) |
||||
|
end, |
||||
|
max_width = function() |
||||
|
return math.floor(vim.o.columns * 0.75) |
||||
|
end, |
||||
|
}, |
||||
|
init = function() |
||||
|
-- when noice is not enabled, install notify on VeryLazy |
||||
|
local Util = require("core.util") |
||||
|
if not Util.has("noice.nvim") then |
||||
|
Util.on_very_lazy(function() |
||||
|
vim.notify = require("notify") |
||||
|
end) |
||||
|
end |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
-- icons |
||||
|
return { "nvim-tree/nvim-web-devicons", lazy = true } |
||||
@ -0,0 +1,19 @@ |
|||||
|
return { |
||||
|
"folke/twilight.nvim", |
||||
|
dependencies = { |
||||
|
{ |
||||
|
"folke/which-key.nvim", |
||||
|
optional = true, |
||||
|
opts = { |
||||
|
defaults = { |
||||
|
["<leader>ut"] = { name = "+twilight" }, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
keys = { |
||||
|
{ "<leader>utt", "<Cmd>Twilight<CR>", desc = "Twilight toggle" }, |
||||
|
{ "<leader>ute", "<Cmd>TwilightEnable<CR>", desc = "Twilight enable" }, |
||||
|
{ "<leader>utd", "<Cmd>TwilightDisable<CR>", desc = "Twilight disable" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,114 @@ |
|||||
|
-- WhichKey is a lua plugin for Neovim 0.5 that displays a popup with possible key bindings of the command you started typing |
||||
|
return { |
||||
|
"folke/which-key.nvim", |
||||
|
event = "VeryLazy", |
||||
|
priority = 900, -- make sure to load this before all the other start plugins |
||||
|
opts = { |
||||
|
plugins = { spelling = true }, |
||||
|
defaults = { |
||||
|
mode = { "n", "v" }, |
||||
|
["g"] = { name = "+goto" }, |
||||
|
["gz"] = { name = "+surround" }, |
||||
|
["]"] = { name = "+next" }, |
||||
|
["["] = { name = "+prev" }, |
||||
|
["<leader><tab>"] = { name = "+tabs" }, |
||||
|
["<leader>b"] = { name = "+buffer" }, |
||||
|
["<leader>c"] = { name = "+code" }, |
||||
|
["<leader>f"] = { name = "+file/find" }, |
||||
|
--["<leader>g"] = { name = "+git" }, |
||||
|
--["<leader>gh"] = { name = "+hunks" }, |
||||
|
["<leader>q"] = { name = "+quit/session" }, |
||||
|
["<leader>s"] = { name = "+search" }, |
||||
|
["<leader>sn"] = { name = "+noice" }, |
||||
|
["<leader>u"] = { name = "+ui" }, |
||||
|
["<leader>w"] = { name = "+windows" }, |
||||
|
["<leader>x"] = { name = "+diagnostics/quickfix" }, |
||||
|
}, |
||||
|
}, |
||||
|
config = function(_, opts) |
||||
|
local wk = require("which-key") |
||||
|
wk.setup(opts) |
||||
|
wk.register(opts.defaults) |
||||
|
end, |
||||
|
-- init = function() |
||||
|
-- vim.o.timeout = true |
||||
|
-- vim.o.timeoutlen = 300 |
||||
|
-- end, |
||||
|
-- config = function() |
||||
|
-- local wk = require("which-key") |
||||
|
-- |
||||
|
-- wk.setup { |
||||
|
-- plugins = { |
||||
|
-- marks = true, -- shows a list of your marks on ' and ` |
||||
|
-- registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode |
||||
|
-- spelling = { |
||||
|
-- enabled = false, -- enabling this will show WhichKey when pressing z= to select spelling suggestions |
||||
|
-- suggestions = 20, -- how many suggestions should be shown in the list? |
||||
|
-- }, |
||||
|
-- -- the presets plugin, adds help for a bunch of default keybindings in Neovim |
||||
|
-- -- No actual key bindings are created |
||||
|
-- presets = { |
||||
|
-- operators = true, -- adds help for operators like d, y, ... and registers them for motion / text object completion |
||||
|
-- motions = rue, -- adds help for motions |
||||
|
-- text_objects = true, -- help for text objects triggered after entering an operator |
||||
|
-- windows = true, -- default bindings on <c-w> |
||||
|
-- nav = true, -- misc bindings to work with windows |
||||
|
-- z = true, -- bindings for folds, spelling and others prefixed with z |
||||
|
-- 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", |
||||
|
-- }, |
||||
|
-- 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 = "single", -- none, single, double, shadow |
||||
|
-- position = "bottom", -- bottom, top |
||||
|
-- margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left] |
||||
|
-- padding = { 2, 2, 2, 2 }, -- extra window padding [top, right, bottom, left] |
||||
|
-- winblend = 0 |
||||
|
-- }, |
||||
|
-- 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 help message on the command line when the popup is visible |
||||
|
-- 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 specify a list manually |
||||
|
-- triggers_blacklist = { |
||||
|
-- -- list of mode / prefixes that should never be hooked by WhichKey |
||||
|
-- -- this is mostly relevant for key maps that start with a native binding |
||||
|
-- -- most people should not need to change this |
||||
|
-- i = { "j", "k" }, |
||||
|
-- v = { "j", "k" }, |
||||
|
-- }, |
||||
|
-- -- disable the WhichKey popup for certain buf types and file types. |
||||
|
-- -- Disabled by deafult for Telescope |
||||
|
-- disable = { |
||||
|
-- buftypes = {}, |
||||
|
-- filetypes = { "TelescopePrompt" }, |
||||
|
-- }, |
||||
|
-- } |
||||
|
-- end, |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,12 @@ |
|||||
|
-- session management |
||||
|
return { |
||||
|
"folke/persistence.nvim", |
||||
|
event = "BufReadPre", |
||||
|
opts = { options = { "buffers", "curdir", "tabpages", "winsize", "help", "globals", "skiprtp" } }, |
||||
|
-- stylua: ignore |
||||
|
keys = { |
||||
|
{ "<leader>qs", function() require("persistence").load() end, desc = "Restore Session" }, |
||||
|
{ "<leader>ql", function() require("persistence").load({ last = true }) end, desc = "Restore Last Session" }, |
||||
|
{ "<leader>qd", function() require("persistence").stop() end, desc = "Don't Save Current Session" }, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
return { |
||||
|
"nvim-lua/plenary.nvim" |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,2 @@ |
|||||
|
-- makes some plugins dot-repeatable like leap |
||||
|
return { "tpope/vim-repeat", event = "VeryLazy" } |
||||
@ -0,0 +1,8 @@ |
|||||
|
-- measure startuptime |
||||
|
return { |
||||
|
"dstein64/vim-startuptime", |
||||
|
cmd = "StartupTime", |
||||
|
config = function() |
||||
|
vim.g.startuptime_tries = 10 |
||||
|
end, |
||||
|
} |
||||
@ -0,0 +1,311 @@ |
|||||
|
--[[ |
||||
|
@title lua-profiler |
||||
|
@version 1.1 |
||||
|
@description Code profiling for Lua based code; |
||||
|
The output is a report file (text) and optionally to a console or other logger. |
||||
|
|
||||
|
The initial reason for this project was to reduce misinterpretations of code profiling |
||||
|
caused by the lengthy measurement time of the 'ProFi' profiler v1.3; |
||||
|
and then to remove the self-profiler functions from the output report. |
||||
|
|
||||
|
The profiler code has been substantially rewritten to remove dependence to the 'OO' |
||||
|
class definitions, and repetitions in code; |
||||
|
thus this profiler has a smaller code footprint and reduced execution time up to ~900% faster. |
||||
|
|
||||
|
The second purpose was to allow slight customisation of the output report, |
||||
|
which I have parametrised the output report and rewritten. |
||||
|
|
||||
|
Caveats: I didn't include an 'inspection' function that ProFi had, also the RAM |
||||
|
output is gone. Please configure the profiler output in top of the code, particularly the |
||||
|
location of the profiler source file (if not in the 'main' root source directory). |
||||
|
|
||||
|
@authors Charles Mallah |
||||
|
@copyright (c) 2018-2020 Charles Mallah |
||||
|
@license MIT license |
||||
|
|
||||
|
@sample Output will be generated like this, all output here is ordered by time (seconds): |
||||
|
`> TOTAL TIME = 0.030000 s |
||||
|
`-------------------------------------------------------------------------------------- |
||||
|
`| FILE : FUNCTION : LINE : TIME : % : # | |
||||
|
`-------------------------------------------------------------------------------------- |
||||
|
`| map : new : 301 : 0.1330 : 52.2 : 2 | |
||||
|
`| map : unpackTileLayer : 197 : 0.0970 : 38.0 : 36 | |
||||
|
`| engine : loadAtlas : 512 : 0.0780 : 30.6 : 1 | |
||||
|
`| map : init : 292 : 0.0780 : 30.6 : 1 | |
||||
|
`| map : setTile : 38 : 0.0500 : 19.6 : 20963| |
||||
|
`| engine : new : 157 : 0.0220 : 8.6 : 1 | |
||||
|
`| map : unpackObjectLayer : 281 : 0.0190 : 7.5 : 2 | |
||||
|
`-------------------------------------------------------------------------------------- |
||||
|
`| ui : sizeCharLimit : 328 : ~ : ~ : 2 | |
||||
|
`| modules/profiler : stop : 192 : ~ : ~ : 1 | |
||||
|
`| ui : sizeWidthToScreenWidthHalf : 301 : ~ : ~ : 4 | |
||||
|
`| map : setRectGridTo : 255 : ~ : ~ : 7 | |
||||
|
`| ui : sizeWidthToScreenWidth : 295 : ~ : ~ : 11 | |
||||
|
`| character : warp : 32 : ~ : ~ : 15 | |
||||
|
`| panels : Anon : 0 : ~ : ~ : 1 | |
||||
|
`-------------------------------------------------------------------------------------- |
||||
|
|
||||
|
The partition splits the notable code that is running the slowest, all other code is running |
||||
|
too fast to determine anything specific, instead of displaying "0.0000" the script will tidy |
||||
|
this up as "~". Table headers % and # refer to percentage total time, and function call count. |
||||
|
|
||||
|
@example Print a profile report of a code block |
||||
|
`local profiler = require("profiler") |
||||
|
`profiler.start() |
||||
|
`-- Code block and/or called functions to profile -- |
||||
|
`profiler.stop() |
||||
|
`profiler.report("profiler.log") |
||||
|
|
||||
|
@example Profile a code block and allow mirror print to a custom print function |
||||
|
`local profiler = require("profiler") |
||||
|
`function exampleConsolePrint() |
||||
|
` -- Custom function in your code-base to print to file or console -- |
||||
|
`end |
||||
|
`profiler.attachPrintFunction(exampleConsolePrint, true) |
||||
|
`profiler.start() |
||||
|
`-- Code block and/or called functions to profile -- |
||||
|
`profiler.stop() |
||||
|
`profiler.report("profiler.log") -- exampleConsolePrint will now be called from this |
||||
|
|
||||
|
@example Override a configuration parameter programmatically; insert your override values into a |
||||
|
new table using the matched key names: |
||||
|
|
||||
|
`local overrides = { |
||||
|
` fW = 100, -- Change the file column to 100 characters (from 20) |
||||
|
` fnW = 120, -- Change the function column to 120 characters (from 28) |
||||
|
` } |
||||
|
`profiler.configuration(overrides) |
||||
|
]] |
||||
|
|
||||
|
--[[ Configuration ]]-- |
||||
|
|
||||
|
local config = { |
||||
|
outputFile = "profiler.lua", -- Name of this profiler (to remove itself from reports) |
||||
|
emptyToThis = "~", -- Rows with no time are set to this value |
||||
|
fW = 20, -- Width of the file column |
||||
|
fnW = 28, -- Width of the function name column |
||||
|
lW = 7, -- Width of the line column |
||||
|
tW = 7, -- Width of the time taken column |
||||
|
rW = 6, -- Width of the relative percentage column |
||||
|
cW = 5, -- Width of the call count column |
||||
|
reportSaved = "> Report saved to: ", -- Text for the file output confirmation |
||||
|
} |
||||
|
|
||||
|
--[[ Locals ]]-- |
||||
|
|
||||
|
local module = {} |
||||
|
local getTime = os.clock |
||||
|
local string, debug, table = string, debug, table |
||||
|
local reportCache = {} |
||||
|
local allReports = {} |
||||
|
local reportCount = 0 |
||||
|
local startTime = 0 |
||||
|
local stopTime = 0 |
||||
|
local printFun = nil |
||||
|
local verbosePrint = false |
||||
|
|
||||
|
local outputHeader, formatHeader, outputTitle, formatOutput, formatTotalTime |
||||
|
local formatFunLine, formatFunTime, formatFunRelative, formatFunCount, divider, nilTime |
||||
|
|
||||
|
local function deepCopy(input) |
||||
|
if type(input) == "table" then |
||||
|
local output = {} |
||||
|
for i, o in next, input, nil do |
||||
|
output[deepCopy(i)] = deepCopy(o) |
||||
|
end |
||||
|
return output |
||||
|
else |
||||
|
return input |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
local function charRepetition(n, character) |
||||
|
local s = "" |
||||
|
character = character or " " |
||||
|
for _ = 1, n do |
||||
|
s = s..character |
||||
|
end |
||||
|
return s |
||||
|
end |
||||
|
|
||||
|
local function singleSearchReturn(inputString, search) |
||||
|
for _ in string.gmatch(inputString, search) do -- luacheck: ignore |
||||
|
return true |
||||
|
end |
||||
|
return false |
||||
|
end |
||||
|
|
||||
|
local function rebuildColumnPatterns() |
||||
|
local c = config |
||||
|
local str = "s: %-" |
||||
|
outputHeader = "| %-"..c.fW..str..c.fnW..str..c.lW..str..c.tW..str..c.rW..str..c.cW.."s|\n" |
||||
|
formatHeader = string.format(outputHeader, "FILE", "FUNCTION", "LINE", "TIME", "%", "#") |
||||
|
outputTitle = "%-"..c.fW.."."..c.fW..str..c.fnW.."."..c.fnW..str..c.lW.."s" |
||||
|
formatOutput = "| %s: %-"..c.tW..str..c.rW..str..c.cW.."s|\n" |
||||
|
formatTotalTime = "Total time: %f s\n" |
||||
|
formatFunLine = "%"..(c.lW - 2).."i" |
||||
|
formatFunTime = "%04.4f" |
||||
|
formatFunRelative = "%03.1f" |
||||
|
formatFunCount = "%"..(c.cW - 1).."i" |
||||
|
divider = charRepetition(#formatHeader - 1, "-").."\n" |
||||
|
-- nilTime = "0."..charRepetition(c.tW - 3, "0") |
||||
|
nilTime = "0.0000" |
||||
|
end |
||||
|
|
||||
|
local function functionReport(information) |
||||
|
local src = information.short_src |
||||
|
if not src then |
||||
|
src = "<C>" |
||||
|
elseif string.sub(src, #src - 3, #src) == ".lua" then |
||||
|
src = string.sub(src, 1, #src - 4) |
||||
|
end |
||||
|
local name = information.name |
||||
|
if not name then |
||||
|
name = "Anon" |
||||
|
elseif string.sub(name, #name - 1, #name) == "_l" then |
||||
|
name = string.sub(name, 1, #name - 2) |
||||
|
end |
||||
|
local title = string.format(outputTitle, src, name, |
||||
|
string.format(formatFunLine, information.linedefined or 0)) |
||||
|
local report = reportCache[title] |
||||
|
if not report then |
||||
|
report = { |
||||
|
title = string.format(outputTitle, src, name, |
||||
|
string.format(formatFunLine, information.linedefined or 0)), |
||||
|
count = 0, timer = 0, |
||||
|
} |
||||
|
reportCache[title] = report |
||||
|
reportCount = reportCount + 1 |
||||
|
allReports[reportCount] = report |
||||
|
end |
||||
|
return report |
||||
|
end |
||||
|
|
||||
|
local onDebugHook = function(hookType) |
||||
|
local information = debug.getinfo(2, "nS") |
||||
|
if hookType == "call" then |
||||
|
local funcReport = functionReport(information) |
||||
|
funcReport.callTime = getTime() |
||||
|
funcReport.count = funcReport.count + 1 |
||||
|
elseif hookType == "return" then |
||||
|
local funcReport = functionReport(information) |
||||
|
if funcReport.callTime and funcReport.count > 0 then |
||||
|
funcReport.timer = funcReport.timer + (getTime() - funcReport.callTime) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
--[[ Functions ]]-- |
||||
|
|
||||
|
--[[Attach a print function to the profiler, to receive a single string parameter |
||||
|
@param fn (function) <required> |
||||
|
@param verbose (boolean) <default: false> |
||||
|
]] |
||||
|
function module.attachPrintFunction(fn, verbose) |
||||
|
printFun = fn |
||||
|
verbosePrint = verbose or false |
||||
|
end |
||||
|
|
||||
|
--[[Start the profiling |
||||
|
]] |
||||
|
function module.start() |
||||
|
if not outputHeader then |
||||
|
rebuildColumnPatterns() |
||||
|
end |
||||
|
reportCache = {} |
||||
|
allReports = {} |
||||
|
reportCount = 0 |
||||
|
startTime = getTime() |
||||
|
stopTime = nil |
||||
|
debug.sethook(onDebugHook, "cr", 0) |
||||
|
end |
||||
|
|
||||
|
--[[Stop profiling |
||||
|
]] |
||||
|
function module.stop() |
||||
|
stopTime = getTime() |
||||
|
debug.sethook() |
||||
|
end |
||||
|
|
||||
|
--[[Writes the profile report to file (will stop profiling if not stopped already) |
||||
|
@param filename (string) <default: "profiler.log"> [File will be created and overwritten] |
||||
|
]] |
||||
|
function module.report(filename) |
||||
|
if not stopTime then |
||||
|
module.stop() |
||||
|
end |
||||
|
filename = filename or "profiler.log" |
||||
|
table.sort(allReports, function(a, b) return a.timer > b.timer end) |
||||
|
local fileWriter = io.open(filename, "w+") |
||||
|
local divide = false |
||||
|
local totalTime = stopTime - startTime |
||||
|
local totalTimeOutput = "> "..string.format(formatTotalTime, totalTime) |
||||
|
fileWriter:write(totalTimeOutput) |
||||
|
if printFun ~= nil then |
||||
|
printFun(totalTimeOutput) |
||||
|
end |
||||
|
fileWriter:write(divider) |
||||
|
fileWriter:write(formatHeader) |
||||
|
fileWriter:write(divider) |
||||
|
for i = 1, reportCount do |
||||
|
local funcReport = allReports[i] |
||||
|
if funcReport.count > 0 and funcReport.timer <= totalTime then |
||||
|
local printThis = true |
||||
|
if config.outputFile ~= "" then |
||||
|
if singleSearchReturn(funcReport.title, config.outputFile) then |
||||
|
printThis = false |
||||
|
end |
||||
|
end |
||||
|
if printThis then -- Remove lines that are not needed |
||||
|
if singleSearchReturn(funcReport.title, "[[C]]") then |
||||
|
printThis = false |
||||
|
end |
||||
|
end |
||||
|
if printThis then |
||||
|
local count = string.format(formatFunCount, funcReport.count) |
||||
|
local timer = string.format(formatFunTime, funcReport.timer) |
||||
|
local relTime = string.format(formatFunRelative, (funcReport.timer / totalTime) * 100) |
||||
|
if not divide and timer == nilTime then |
||||
|
fileWriter:write(divider) |
||||
|
divide = true |
||||
|
end |
||||
|
if timer == nilTime then |
||||
|
timer = config.emptyToThis |
||||
|
relTime = config.emptyToThis |
||||
|
end |
||||
|
-- Build final line |
||||
|
local output = string.format(formatOutput, funcReport.title, timer, relTime, count) |
||||
|
fileWriter:write(output) |
||||
|
-- This is a verbose print to the attached print function |
||||
|
if printFun ~= nil and verbosePrint then |
||||
|
printFun(output) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
fileWriter:write(divider) |
||||
|
fileWriter:close() |
||||
|
if printFun ~= nil then |
||||
|
printFun(config.reportSaved.."'"..filename.."'") |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
--[[Modify the configuration of this module programmatically; |
||||
|
Provide a table with keys that share the same name as the configuration parameters: |
||||
|
@param overrides (table) <required> [Each key is from a valid name, the value is the override] |
||||
|
@unpack config |
||||
|
]] |
||||
|
function module.configuration(overrides) |
||||
|
local safe = deepCopy(overrides) |
||||
|
for k, v in pairs(safe) do |
||||
|
if config[k] == nil then |
||||
|
print("error: override field '"..k.."' not found (configuration)") |
||||
|
else |
||||
|
config[k] = v |
||||
|
end |
||||
|
end |
||||
|
rebuildColumnPatterns() |
||||
|
end |
||||
|
|
||||
|
--[[ End ]]-- |
||||
|
return module |
||||
@ -0,0 +1,254 @@ |
|||||
|
-- TODO: Could almost certainly make this a lot faster, especially by using Luv more directly in the |
||||
|
-- MRU logic, making make_sections() construct the full table of strings first and then call |
||||
|
-- set_lines only once (still need to deal with highlights), maybe making file info fill in async |
||||
|
local utils = require 'utils' |
||||
|
|
||||
|
local counter = 15 |
||||
|
local offset = 5 |
||||
|
|
||||
|
local regex = vim.regex |
||||
|
local path_skip_list = { |
||||
|
regex 'runtime/doc/.*\\.txt', |
||||
|
regex '/.git/', |
||||
|
regex(vim.fn.escape(vim.fn.fnamemodify(vim.fn.resolve(os.getenv 'VIMRUNTIME'), ':p'), '\\') .. 'doc/.*\\.txt'), |
||||
|
} |
||||
|
|
||||
|
local function skip(path) |
||||
|
local n = #path_skip_list |
||||
|
for i = 1, n do |
||||
|
if path_skip_list[i]:match_str(path) then |
||||
|
return true |
||||
|
end |
||||
|
end |
||||
|
return false |
||||
|
end |
||||
|
|
||||
|
local function recent_files() |
||||
|
local oldfiles = {} |
||||
|
local f_mod = vim.fn.fnamemodify |
||||
|
local f_esc = vim.fn.fnameescape |
||||
|
local f_stat = vim.loop.fs_stat |
||||
|
local unfiltered_oldfiles = vim.v.oldfiles |
||||
|
for _, file in ipairs(unfiltered_oldfiles) do |
||||
|
if #oldfiles >= counter then |
||||
|
break |
||||
|
end |
||||
|
|
||||
|
local absolute_path = f_mod(file, ':p') |
||||
|
local path_info = f_stat(absolute_path) |
||||
|
if path_info and path_info.type ~= 'directory' and not skip(absolute_path) then |
||||
|
local escaped_path = f_esc(absolute_path) |
||||
|
oldfiles[#oldfiles + 1] = { |
||||
|
key = tostring(#oldfiles), |
||||
|
cmd = 'edit ' .. escaped_path, |
||||
|
-- disp = cap_path_length(f_mod(absolute_path, ':~:.')), --get_icon(escaped_path, f_mod(escaped_path, ':e'), { default = true }) .. ' ' .. cap_path_length( f_mod(absolute_path, ':~:.')), |
||||
|
disp = utils.display_path(file), |
||||
|
editing = true, |
||||
|
} |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return oldfiles |
||||
|
end |
||||
|
|
||||
|
local commands = { |
||||
|
{ key = 'e', disp = ' New file', cmd = 'ene | startinsert', editing = true }, |
||||
|
{ key = 'u', disp = ' Update plugins', cmd = 'Lazy sync' }, |
||||
|
{ key = 'b', disp = ' File Browser', cmd = 'Telescope file_browser' }, |
||||
|
{ key = 'r', disp = ' Recent files', cmd = 'Telescope oldfiles' }, |
||||
|
{ key = 's', disp = ' Start Prosession', cmd = 'Prosession .', editing = true }, |
||||
|
{ key = 'g', disp = ' NeoGit', cmd = 'Neogit' }, |
||||
|
{ key = 't', disp = '⏱ Time startup', cmd = 'Lazy profile' }, |
||||
|
{ key = 'q', disp = ' Quit', cmd = 'qa' }, |
||||
|
} |
||||
|
|
||||
|
-- TODO: Maybe make the show functions unevaluated and run async? Would require rewriting using LUV |
||||
|
-- functions, which isn't a bad idea anyway |
||||
|
local sections = { |
||||
|
{ title = 'Commands', show = commands }, |
||||
|
{ title = 'Recent Files', show = recent_files() }, |
||||
|
} |
||||
|
|
||||
|
local boundaries = {} |
||||
|
local keybindings = {} |
||||
|
|
||||
|
local function longest_elems() |
||||
|
local longest_title = 0 |
||||
|
local longest_item = 0 |
||||
|
for _, section in ipairs(sections) do |
||||
|
local title_len = string.len(section.title) |
||||
|
if title_len > longest_title then |
||||
|
longest_title = title_len |
||||
|
end |
||||
|
for _, item in ipairs(section.show) do |
||||
|
local item_len = string.len(item.disp) |
||||
|
if item_len > longest_item then |
||||
|
longest_item = item_len |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return longest_title, longest_item |
||||
|
end |
||||
|
|
||||
|
local function make_sections() |
||||
|
boundaries = {} |
||||
|
keybindings = {} |
||||
|
local set_lines = vim.api.nvim_buf_set_lines |
||||
|
local highlight = vim.api.nvim_buf_add_highlight |
||||
|
local win_width = vim.fn.winwidth(0) |
||||
|
local linenr = 2 |
||||
|
set_lines(0, 0, 0, false, { '', '' }) |
||||
|
local longest_title, longest_item = longest_elems() |
||||
|
local title_indent = bit.arshift(win_width - longest_title, 1) |
||||
|
local section_indent = bit.arshift(win_width - longest_item - 4, 1) |
||||
|
offset = section_indent + 2 |
||||
|
local section_padding = string.rep(' ', section_indent) |
||||
|
for _, section in ipairs(sections) do |
||||
|
if next(section.show) ~= nil then |
||||
|
local section_title_indent = title_indent + bit.arshift(longest_title - string.len(section.title), 1) |
||||
|
local title_padding = string.rep(' ', section_title_indent) |
||||
|
set_lines(0, linenr, linenr, false, { title_padding .. section.title, '' }) |
||||
|
highlight(0, -1, 'SpecialComment', linenr, 1, -1) |
||||
|
linenr = linenr + 1 |
||||
|
local size = 1 |
||||
|
for _, item in ipairs(section.show) do |
||||
|
local key = item.key |
||||
|
local key_len |
||||
|
if type(key) == 'string' then |
||||
|
key_len = string.len(key) |
||||
|
else |
||||
|
key_len = (key < 10) and 1 or 2 |
||||
|
end |
||||
|
|
||||
|
local key_padding = (key_len == 1) and ' ' or ' ' |
||||
|
set_lines( |
||||
|
0, |
||||
|
linenr + size, |
||||
|
linenr + size, |
||||
|
false, |
||||
|
{ string.format('%s(%s)%s%s', section_padding, key, key_padding, item.disp) } |
||||
|
) |
||||
|
highlight(0, -1, 'StartifyBracket', linenr + size, section_indent, section_indent + 1) |
||||
|
highlight(0, -1, 'StartifyNumber', linenr + size, section_indent + 1, section_indent + 1 + key_len) |
||||
|
highlight(0, -1, 'StartifyBracket', linenr + size, section_indent + 1 + key_len, section_indent + 2 + key_len) |
||||
|
keybindings[#keybindings + 1] = { key = key, cmd = item.cmd, editing = item.editing } |
||||
|
size = size + 1 |
||||
|
end |
||||
|
|
||||
|
set_lines(0, -1, -1, false, { '', '' }) |
||||
|
boundaries[#boundaries + 1] = { linenr + 1, linenr + size } |
||||
|
linenr = linenr + size + 2 |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
return keybindings |
||||
|
end |
||||
|
|
||||
|
local function move_cursor(d) |
||||
|
local curr_line = vim.fn.line '.' |
||||
|
for idx, range in ipairs(boundaries) do |
||||
|
if range[1] <= curr_line and range[2] >= curr_line then |
||||
|
if range[1] >= curr_line + d then |
||||
|
if idx > 1 then |
||||
|
vim.fn.cursor(boundaries[idx - 1][2], offset) |
||||
|
end |
||||
|
elseif range[2] < curr_line + d then |
||||
|
if idx < #boundaries then |
||||
|
vim.fn.cursor(boundaries[idx + 1][1] + 1, offset) |
||||
|
end |
||||
|
else |
||||
|
vim.fn.cursor(curr_line + d, offset) |
||||
|
end |
||||
|
|
||||
|
return |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
local function handle_j() |
||||
|
move_cursor(1) |
||||
|
end |
||||
|
|
||||
|
local function handle_k() |
||||
|
move_cursor(-1) |
||||
|
end |
||||
|
|
||||
|
local function do_binding(binding) |
||||
|
if binding.editing then |
||||
|
vim.api.nvim_exec_autocmds('User', { pattern = 'ActuallyEditing' }) |
||||
|
end |
||||
|
|
||||
|
vim.cmd(binding.cmd) |
||||
|
end |
||||
|
|
||||
|
local function handle_key(key) |
||||
|
for _, binding in ipairs(keybindings) do |
||||
|
if binding.key == key then |
||||
|
do_binding(binding) |
||||
|
return |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
local function handle_cr() |
||||
|
local line_num = vim.fn.line '.' |
||||
|
local curr_line = vim.api.nvim_buf_get_lines(0, line_num - 1, line_num, false)[1] |
||||
|
local key = string.match(curr_line, '%(([^%]]*)%)') |
||||
|
handle_key(key) |
||||
|
end |
||||
|
|
||||
|
local function setup_keys() |
||||
|
-- First, the nav keys |
||||
|
local map = vim.api.nvim_buf_set_keymap |
||||
|
map(0, 'n', 'h', '<NOP>', { noremap = true, silent = true }) |
||||
|
map(0, 'n', 'l', '<NOP>', { noremap = true, silent = true }) |
||||
|
map(0, 'n', 'j', '', { noremap = true, silent = true, callback = handle_j }) |
||||
|
map(0, 'n', 'k', '', { noremap = true, silent = true, callback = handle_k }) |
||||
|
map(0, 'n', '<cr>', '', { noremap = true, silent = true, callback = handle_cr }) |
||||
|
|
||||
|
-- Then, the defined keybindings |
||||
|
for _, binding in ipairs(keybindings) do |
||||
|
map(0, 'n', tostring(binding.key), '', { |
||||
|
noremap = true, |
||||
|
silent = true, |
||||
|
callback = function() |
||||
|
do_binding(binding) |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
local function start_screen() |
||||
|
if vim.fn.argc() ~= 0 or vim.fn.line2byte '$' ~= -1 or vim.o.insertmode or not vim.o.modifiable then |
||||
|
vim.api.nvim_exec_autocmds('User', { pattern = 'ActuallyEditing' }) |
||||
|
return |
||||
|
end |
||||
|
|
||||
|
vim.o.eventignore = 'all' |
||||
|
vim.opt_local.bufhidden = 'wipe' |
||||
|
vim.opt_local.colorcolumn = '' |
||||
|
vim.opt_local.foldcolumn = '0' |
||||
|
vim.opt_local.matchpairs = '' |
||||
|
vim.opt_local.buflisted = false |
||||
|
vim.opt_local.cursorcolumn = false |
||||
|
vim.opt_local.cursorline = false |
||||
|
vim.opt_local.list = false |
||||
|
vim.opt_local.number = false |
||||
|
vim.opt_local.relativenumber = false |
||||
|
vim.opt_local.spell = false |
||||
|
vim.opt_local.swapfile = false |
||||
|
vim.opt_local.signcolumn = 'no' |
||||
|
vim.opt_local.synmaxcol = 0 |
||||
|
vim.opt_local.statusline = '' |
||||
|
vim.opt_local.filetype = 'startify' |
||||
|
|
||||
|
-- vim.cmd [[noautocmd silent! setlocal bufhidden=wipe colorcolumn= foldcolumn=0 matchpairs= nobuflisted nocursorcolumn nocursorline nolist nonumber norelativenumber nospell noswapfile signcolumn=no synmaxcol& statusline= filetype=startify]] |
||||
|
make_sections() |
||||
|
vim.opt_local.modifiable = false |
||||
|
vim.opt_local.modified = false |
||||
|
vim.api.nvim_win_set_cursor(0, { 5, offset - 1 }) |
||||
|
setup_keys() |
||||
|
vim.o.eventignore = '' |
||||
|
end |
||||
|
return { start = start_screen, handle_j = handle_j, handle_k = handle_k, handle_cr = handle_cr } |
||||
@ -0,0 +1,190 @@ |
|||||
|
local get_mode = vim.api.nvim_get_mode |
||||
|
local get_icon_color = require('nvim-web-devicons').get_icon_color |
||||
|
local get_current_win = vim.api.nvim_get_current_win |
||||
|
|
||||
|
local bg_color = '#222222' |
||||
|
local fg_color = '#e9e9e9' |
||||
|
|
||||
|
local function setup_colors() |
||||
|
if vim.g.colors_name ~= 'nazgul' then |
||||
|
local statusline_hl = vim.api.nvim_get_hl(0, { name = 'Statusline', link = false }) |
||||
|
bg_color = statusline_hl.bg |
||||
|
fg_color = statusline_hl.fg |
||||
|
end |
||||
|
|
||||
|
local set_hl = vim.api.nvim_set_hl |
||||
|
set_hl(0, 'Statusline', { fg = fg_color, bg = bg_color }) |
||||
|
set_hl(0, 'StatuslineSeparator', { fg = bg_color }) |
||||
|
set_hl(0, 'StatuslineNormal', { bg = bg_color, fg = fg_color }) |
||||
|
set_hl(0, 'StatuslineVC', { bg = bg_color, fg = '#a9a9a9' }) |
||||
|
set_hl(0, 'StatuslineNormalAccent', { bg = '#403834', bold = true, fg = fg_color }) |
||||
|
set_hl(0, 'StatuslineInsertAccent', { fg = fg_color, bold = true, bg = '#726b67' }) |
||||
|
set_hl(0, 'StatuslineReplaceAccent', { fg = fg_color, bold = true, bg = '#afaf00' }) |
||||
|
set_hl(0, 'StatuslineConfirmAccent', { fg = fg_color, bold = true, bg = '#83adad' }) |
||||
|
set_hl(0, 'StatuslineTerminalAccent', { fg = fg_color, bold = true, bg = '#6f6f6f' }) |
||||
|
set_hl(0, 'StatuslineMiscAccent', { fg = fg_color, bold = true, bg = '#948d89' }) |
||||
|
set_hl(0, 'StatuslineLSPInfo', { fg = '#a9a9a9', bold = true, bg = bg_color }) |
||||
|
|
||||
|
-- Diagnostics |
||||
|
local error_hl = vim.api.nvim_get_hl(0, { name = 'DiagnosticError', link = false }) |
||||
|
set_hl(0, 'StatuslineDiagnosticError', { fg = error_hl.fg, bg = bg_color }) |
||||
|
local warning_hl = vim.api.nvim_get_hl(0, { name = 'DiagnosticWarning', link = false }) |
||||
|
set_hl(0, 'StatuslineDiagnosticWarning', { fg = warning_hl.fg, bg = bg_color }) |
||||
|
local info_hl = vim.api.nvim_get_hl(0, { name = 'DiagnosticInfo', link = false }) |
||||
|
set_hl(0, 'StatuslineDiagnosticInfo', { fg = info_hl.fg, bg = bg_color }) |
||||
|
local hint_hl = vim.api.nvim_get_hl(0, { name = 'DiagnosticHint', link = false }) |
||||
|
set_hl(0, 'StatuslineDiagnosticHint', { fg = hint_hl.fg, bg = bg_color }) |
||||
|
end |
||||
|
|
||||
|
vim.api.nvim_create_autocmd('ColorScheme', { pattern = '*', callback = setup_colors }) |
||||
|
setup_colors() |
||||
|
|
||||
|
local function vcs() |
||||
|
local branch_sign = '' |
||||
|
local git_info = vim.b.gitsigns_status_dict |
||||
|
if not git_info or git_info.head == '' then |
||||
|
return '[ no vcs ]' |
||||
|
end |
||||
|
local added = git_info.added and ('+' .. git_info.added .. ' ') or '' |
||||
|
local modified = git_info.changed and ('~' .. git_info.changed .. ' ') or '' |
||||
|
local removed = git_info.removed and ('-' .. git_info.removed .. ' ') or '' |
||||
|
local pad = ((added ~= '') or (removed ~= '') or (modified ~= '')) and ' ' or '' |
||||
|
local diff_str = string.format('%s%s%s%s', added, removed, modified, pad) |
||||
|
return string.format('%s%s %s ', diff_str, branch_sign, git_info.head) |
||||
|
end |
||||
|
|
||||
|
local mode_table = { |
||||
|
n = 'Normal', |
||||
|
no = 'N·Operator Pending', |
||||
|
v = 'Visual', |
||||
|
V = 'V·Line', |
||||
|
['^V'] = 'V·Block', |
||||
|
s = 'Select', |
||||
|
S = 'S·Line', |
||||
|
['^S'] = 'S·Block', |
||||
|
i = 'Insert', |
||||
|
ic = 'Insert', |
||||
|
R = 'Replace', |
||||
|
Rv = 'V·Replace', |
||||
|
c = 'Command', |
||||
|
cv = 'Vim Ex', |
||||
|
ce = 'Ex', |
||||
|
r = 'Prompt', |
||||
|
rm = 'More', |
||||
|
['r?'] = 'Confirm', |
||||
|
['!'] = 'Shell', |
||||
|
t = 'Terminal', |
||||
|
} |
||||
|
|
||||
|
local function mode_name(mode) |
||||
|
return string.upper(mode_table[mode] or 'V-Block') |
||||
|
end |
||||
|
|
||||
|
local function update_colors(mode) |
||||
|
local mode_color = 'StatuslineMiscAccent' |
||||
|
if mode == 'n' then |
||||
|
mode_color = 'StatuslineNormalAccent' |
||||
|
elseif mode == 'i' or mode == 'ic' then |
||||
|
mode_color = 'StatuslineInsertAccent' |
||||
|
elseif mode == 'R' then |
||||
|
mode_color = 'StatuslineReplaceAccent' |
||||
|
elseif mode == 'c' then |
||||
|
mode_color = 'StatuslineConfirmAccent' |
||||
|
elseif mode == 't' then |
||||
|
mode_color = 'StatuslineTerminalAccent' |
||||
|
else |
||||
|
mode_color = 'StatuslineMiscAccent' |
||||
|
end |
||||
|
|
||||
|
return mode_color |
||||
|
end |
||||
|
|
||||
|
local function get_paste() |
||||
|
return vim.o.paste and 'PASTE ' or '' |
||||
|
end |
||||
|
|
||||
|
local function get_readonly_space() |
||||
|
return ((vim.o.paste and vim.bo.readonly) and ' ' or '') and '%r' .. (vim.bo.readonly and ' ' or '') |
||||
|
end |
||||
|
|
||||
|
-- Copied from @akinsho's config |
||||
|
local error_icon = '' -- '✗' |
||||
|
local warning_icon = '' |
||||
|
local info_icon = '' -- |
||||
|
local hint_icon = '⚑' -- ⚑ |
||||
|
local function diagnostics() |
||||
|
local errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }) |
||||
|
local warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }) |
||||
|
local hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT }) |
||||
|
local info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO }) |
||||
|
local components = {} |
||||
|
if errors > 0 then |
||||
|
components[#components + 1] = '%#StatuslineDiagnosticError#' .. error_icon .. ' ' .. errors |
||||
|
end |
||||
|
|
||||
|
if warnings > 0 then |
||||
|
components[#components + 1] = '%#StatuslineDiagnosticWarning#' .. warning_icon .. ' ' .. warnings |
||||
|
end |
||||
|
|
||||
|
if hints > 0 then |
||||
|
components[#components + 1] = '%#StatuslineDiagnosticHint#' .. hint_icon .. ' ' .. hints |
||||
|
end |
||||
|
|
||||
|
if info > 0 then |
||||
|
components[#components + 1] = '%#StatuslineDiagnosticInfo#' .. info_icon .. ' ' .. info |
||||
|
end |
||||
|
|
||||
|
return table.concat(components, ' ') |
||||
|
end |
||||
|
|
||||
|
local function lsp_servers() |
||||
|
local names = {} |
||||
|
for _, server in pairs(vim.lsp.get_active_clients { bufnr = 0 }) do |
||||
|
table.insert(names, server.name) |
||||
|
end |
||||
|
if #names == 0 then |
||||
|
return '' |
||||
|
end |
||||
|
|
||||
|
return '[ ' .. table.concat(names, ' ') .. ' ]' |
||||
|
end |
||||
|
|
||||
|
local function filetype_icon() |
||||
|
local fname = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(0), ':t') |
||||
|
local ft = vim.bo.filetype |
||||
|
local icon, color = get_icon_color(fname, vim.fn.fnamemodify(fname, ':e'), { default = true }) |
||||
|
vim.api.nvim_set_hl(0, 'StatuslineFiletype', { fg = color, bg = bg_color }) |
||||
|
return icon, ft |
||||
|
end |
||||
|
|
||||
|
local statusline_format = |
||||
|
'%%#%s# %s %%<%%#StatuslineFilenameNoMod# %s%s%%<%%=%%#StatuslineFiletype#%s%%#Statusline#%s%s%s%s%%=%%#StatuslineVC#%s' |
||||
|
|
||||
|
local statuslines = {} |
||||
|
local function status() |
||||
|
setup_colors() |
||||
|
local win_id = vim.g.statusline_winid |
||||
|
if win_id == get_current_win() or statuslines[win_id] == nil then |
||||
|
local mode = get_mode().mode |
||||
|
local mode_color = update_colors(mode) |
||||
|
local ft_icon, ft_name = filetype_icon() |
||||
|
local lsp_info = lsp_servers() |
||||
|
statuslines[win_id] = string.format( |
||||
|
statusline_format, |
||||
|
mode_color, |
||||
|
mode_name(mode), |
||||
|
get_paste(), |
||||
|
get_readonly_space(), |
||||
|
ft_icon, |
||||
|
(ft_name ~= '') and (' ' .. ft_name) or '', |
||||
|
(ft_name ~= '' and lsp_info ~= '') and ' · ' or '', |
||||
|
lsp_info, |
||||
|
(lsp_info ~= '') and ' ' or '', |
||||
|
vcs() |
||||
|
) |
||||
|
end |
||||
|
|
||||
|
return statuslines[win_id] |
||||
|
end |
||||
|
|
||||
|
return { status = status } |
||||
@ -0,0 +1,252 @@ |
|||||
|
local Util = require("lazy.core.util") |
||||
|
|
||||
|
local M = {} |
||||
|
|
||||
|
M.root_patterns = { ".git", "lua" } |
||||
|
|
||||
|
---@param on_attach fun(client, buffer) |
||||
|
function M.on_attach(on_attach) |
||||
|
vim.api.nvim_create_autocmd("LspAttach", { |
||||
|
callback = function(args) |
||||
|
local buffer = args.buf |
||||
|
local client = vim.lsp.get_client_by_id(args.data.client_id) |
||||
|
on_attach(client, buffer) |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
---@param plugin string |
||||
|
function M.has(plugin) |
||||
|
return require("lazy.core.config").plugins[plugin] ~= nil |
||||
|
end |
||||
|
|
||||
|
function M.fg(name) |
||||
|
---@type {foreground?:number}? |
||||
|
local hl = vim.api.nvim_get_hl and vim.api.nvim_get_hl(0, { name = name }) or vim.api.nvim_get_hl_by_name(name, true) |
||||
|
local fg = hl and hl.fg or hl.foreground |
||||
|
return fg and { fg = string.format("#%06x", fg) } |
||||
|
end |
||||
|
|
||||
|
---@param fn fun() |
||||
|
function M.on_very_lazy(fn) |
||||
|
vim.api.nvim_create_autocmd("User", { |
||||
|
pattern = "VeryLazy", |
||||
|
callback = function() |
||||
|
fn() |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
---@param name string |
||||
|
function M.opts(name) |
||||
|
local plugin = require("lazy.core.config").plugins[name] |
||||
|
if not plugin then |
||||
|
return {} |
||||
|
end |
||||
|
local Plugin = require("lazy.core.plugin") |
||||
|
return Plugin.values(plugin, "opts", false) |
||||
|
end |
||||
|
|
||||
|
-- returns the root directory based on: |
||||
|
-- * lsp workspace folders |
||||
|
-- * lsp root_dir |
||||
|
-- * root pattern of filename of the current buffer |
||||
|
-- * root pattern of cwd |
||||
|
---@return string |
||||
|
function M.get_root() |
||||
|
---@type string? |
||||
|
local path = vim.api.nvim_buf_get_name(0) |
||||
|
path = path ~= "" and vim.loop.fs_realpath(path) or nil |
||||
|
---@type string[] |
||||
|
local roots = {} |
||||
|
if path then |
||||
|
for _, client in pairs(vim.lsp.get_active_clients({ bufnr = 0 })) do |
||||
|
local workspace = client.config.workspace_folders |
||||
|
local paths = workspace and vim.tbl_map(function(ws) |
||||
|
return vim.uri_to_fname(ws.uri) |
||||
|
end, workspace) or client.config.root_dir and { client.config.root_dir } or {} |
||||
|
for _, p in ipairs(paths) do |
||||
|
local r = vim.loop.fs_realpath(p) |
||||
|
if path:find(r, 1, true) then |
||||
|
roots[#roots + 1] = r |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
table.sort(roots, function(a, b) |
||||
|
return #a > #b |
||||
|
end) |
||||
|
---@type string? |
||||
|
local root = roots[1] |
||||
|
if not root then |
||||
|
path = path and vim.fs.dirname(path) or vim.loop.cwd() |
||||
|
---@type string? |
||||
|
root = vim.fs.find(M.root_patterns, { path = path, upward = true })[1] |
||||
|
root = root and vim.fs.dirname(root) or vim.loop.cwd() |
||||
|
end |
||||
|
---@cast root string |
||||
|
return root |
||||
|
end |
||||
|
|
||||
|
-- this will return a function that calls telescope. |
||||
|
-- cwd will default to lazyvim.util.get_root |
||||
|
-- for `files`, git_files or find_files will be chosen depending on .git |
||||
|
function M.telescope(builtin, opts) |
||||
|
local params = { builtin = builtin, opts = opts } |
||||
|
return function() |
||||
|
builtin = params.builtin |
||||
|
opts = params.opts |
||||
|
opts = vim.tbl_deep_extend("force", { cwd = M.get_root() }, opts or {}) |
||||
|
if builtin == "files" then |
||||
|
if vim.loop.fs_stat((opts.cwd or vim.loop.cwd()) .. "/.git") then |
||||
|
opts.show_untracked = true |
||||
|
builtin = "git_files" |
||||
|
else |
||||
|
builtin = "find_files" |
||||
|
end |
||||
|
end |
||||
|
if opts.cwd and opts.cwd ~= vim.loop.cwd() then |
||||
|
opts.attach_mappings = function(_, map) |
||||
|
map("i", "<a-c>", function() |
||||
|
local action_state = require("telescope.actions.state") |
||||
|
local line = action_state.get_current_line() |
||||
|
M.telescope( |
||||
|
params.builtin, |
||||
|
vim.tbl_deep_extend("force", {}, params.opts or {}, { cwd = false, default_text = line }) |
||||
|
)() |
||||
|
end) |
||||
|
return true |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
require("telescope.builtin")[builtin](opts) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
---@type table<string,LazyFloat> |
||||
|
local terminals = {} |
||||
|
|
||||
|
-- Opens a floating terminal (interactive by default) |
||||
|
---@param cmd? string[]|string |
||||
|
---@param opts? LazyCmdOptions|{interactive?:boolean, esc_esc?:false} |
||||
|
function M.float_term(cmd, opts) |
||||
|
opts = vim.tbl_deep_extend("force", { |
||||
|
ft = "lazyterm", |
||||
|
size = { width = 0.9, height = 0.9 }, |
||||
|
}, opts or {}, { persistent = true }) |
||||
|
---@cast opts LazyCmdOptions|{interactive?:boolean, esc_esc?:false} |
||||
|
|
||||
|
local termkey = vim.inspect({ cmd = cmd or "shell", cwd = opts.cwd, env = opts.env }) |
||||
|
|
||||
|
if terminals[termkey] and terminals[termkey]:buf_valid() then |
||||
|
terminals[termkey]:toggle() |
||||
|
else |
||||
|
terminals[termkey] = require("lazy.util").float_term(cmd, opts) |
||||
|
local buf = terminals[termkey].buf |
||||
|
vim.b[buf].lazyterm_cmd = cmd |
||||
|
if opts.esc_esc == false then |
||||
|
vim.keymap.set("t", "<esc>", "<esc>", { buffer = buf, nowait = true }) |
||||
|
end |
||||
|
vim.api.nvim_create_autocmd("BufEnter", { |
||||
|
buffer = buf, |
||||
|
callback = function() |
||||
|
vim.cmd.startinsert() |
||||
|
end, |
||||
|
}) |
||||
|
end |
||||
|
|
||||
|
return terminals[termkey] |
||||
|
end |
||||
|
|
||||
|
---@param silent boolean? |
||||
|
---@param values? {[1]:any, [2]:any} |
||||
|
function M.toggle(option, silent, values) |
||||
|
if values then |
||||
|
if vim.opt_local[option]:get() == values[1] then |
||||
|
vim.opt_local[option] = values[2] |
||||
|
else |
||||
|
vim.opt_local[option] = values[1] |
||||
|
end |
||||
|
return Util.info("Set " .. option .. " to " .. vim.opt_local[option]:get(), { title = "Option" }) |
||||
|
end |
||||
|
vim.opt_local[option] = not vim.opt_local[option]:get() |
||||
|
if not silent then |
||||
|
if vim.opt_local[option]:get() then |
||||
|
Util.info("Enabled " .. option, { title = "Option" }) |
||||
|
else |
||||
|
Util.warn("Disabled " .. option, { title = "Option" }) |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
local enabled = true |
||||
|
function M.toggle_diagnostics() |
||||
|
enabled = not enabled |
||||
|
if enabled then |
||||
|
vim.diagnostic.enable() |
||||
|
Util.info("Enabled diagnostics", { title = "Diagnostics" }) |
||||
|
else |
||||
|
vim.diagnostic.disable() |
||||
|
Util.warn("Disabled diagnostics", { title = "Diagnostics" }) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
function M.deprecate(old, new) |
||||
|
Util.warn(("`%s` is deprecated. Please use `%s` instead"):format(old, new), { title = "LazyVim" }) |
||||
|
end |
||||
|
|
||||
|
-- delay notifications till vim.notify was replaced or after 500ms |
||||
|
function M.lazy_notify() |
||||
|
local notifs = {} |
||||
|
local function temp(...) |
||||
|
table.insert(notifs, vim.F.pack_len(...)) |
||||
|
end |
||||
|
|
||||
|
local orig = vim.notify |
||||
|
vim.notify = temp |
||||
|
|
||||
|
local timer = vim.loop.new_timer() |
||||
|
local check = vim.loop.new_check() |
||||
|
|
||||
|
local replay = function() |
||||
|
timer:stop() |
||||
|
check:stop() |
||||
|
if vim.notify == temp then |
||||
|
vim.notify = orig -- put back the original notify if needed |
||||
|
end |
||||
|
vim.schedule(function() |
||||
|
---@diagnostic disable-next-line: no-unknown |
||||
|
for _, notif in ipairs(notifs) do |
||||
|
vim.notify(vim.F.unpack_len(notif)) |
||||
|
end |
||||
|
end) |
||||
|
end |
||||
|
|
||||
|
-- wait till vim.notify has been replaced |
||||
|
check:start(function() |
||||
|
if vim.notify ~= temp then |
||||
|
replay() |
||||
|
end |
||||
|
end) |
||||
|
-- or if it took more than 500ms, then something went wrong |
||||
|
timer:start(500, 0, replay) |
||||
|
end |
||||
|
|
||||
|
function M.lsp_get_config(server) |
||||
|
local configs = require("lspconfig.configs") |
||||
|
return rawget(configs, server) |
||||
|
end |
||||
|
|
||||
|
---@param server string |
||||
|
---@param cond fun( root_dir, config): boolean |
||||
|
function M.lsp_disable(server, cond) |
||||
|
local util = require("lspconfig.util") |
||||
|
local def = M.lsp_get_config(server) |
||||
|
def.document_config.on_new_config = util.add_hook_before(def.document_config.on_new_config, function(config, root_dir) |
||||
|
if cond(root_dir, config) then |
||||
|
config.enabled = false |
||||
|
end |
||||
|
end) |
||||
|
end |
||||
|
|
||||
|
return M |
||||
@ -0,0 +1,26 @@ |
|||||
|
local icons = require 'nvim-web-devicons' |
||||
|
local get_icon = icons.get_icon |
||||
|
local f_mod = vim.fn.fnamemodify |
||||
|
local f_esc = vim.fn.fnameescape |
||||
|
local pshorten = vim.fn.pathshorten |
||||
|
|
||||
|
local function cap_path_length(path) |
||||
|
if string.len(path) > 50 then |
||||
|
path = pshorten(path) |
||||
|
end |
||||
|
|
||||
|
return path |
||||
|
end |
||||
|
|
||||
|
local function display_path(path) |
||||
|
local absolute_path = f_mod(path, ':p') |
||||
|
local escaped_path = f_esc(absolute_path) |
||||
|
return get_icon(escaped_path, f_mod(escaped_path, ':e'), { default = true }) |
||||
|
.. ' ' |
||||
|
.. cap_path_length(f_mod(absolute_path, ':~:.')) |
||||
|
end |
||||
|
|
||||
|
return { |
||||
|
cap_path_length = cap_path_length, |
||||
|
display_path = display_path, |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue