Compare commits

61 Commits

Author SHA1 Message Date
Chris
a086657031 Treesitter update 2025-12-10 14:19:07 +00:00
Chris
d53821dbf7 textobjects 2025-12-10 11:47:00 +00:00
e89dbcac87 Cool stuff 2025-12-09 23:07:24 +00:00
5bf1ec232e Super keymaps 2025-12-09 22:49:24 +00:00
aded597ffe Trying stuff 2025-12-09 22:10:16 +00:00
Chris
282301e206 Plugins 2025-12-09 16:24:08 +00:00
9bd219f053 Snippets 2025-12-09 10:35:51 +00:00
0cce7837f2 God of snippets 2025-12-08 20:18:20 +00:00
Chris
f79e89d335 Snippets 2025-12-08 16:33:11 +00:00
Chris
1f5a3d19f2 Migrate map 2025-12-08 09:29:10 +00:00
dc5d2e20ff Snippets 2025-12-08 00:52:01 +00:00
256a5695ed Super keymaps 2025-12-07 18:47:34 +00:00
2a4578e1eb Better typescript 2025-11-21 19:36:05 +00:00
52ae098ac6 Add laravel maps 2025-11-16 10:01:02 +00:00
1c96d03649 Fix some things 2025-11-15 13:55:47 +00:00
Chris
344623eaf6 Hylark settings 2025-11-12 09:21:24 +00:00
f16cb91875 Stuff 2025-11-11 22:58:02 +00:00
8e2d413e0a Yazi plugin 2025-11-11 21:51:41 +00:00
2062c442b2 Fix copilot check 2025-11-10 20:58:07 +00:00
Chris
2255489fd8 Sharing config 2025-11-10 09:19:30 +00:00
a21a1a3386 More changes 2025-11-09 23:03:51 +00:00
529cfa79c8 More project specific stuff 2025-11-07 22:10:53 +00:00
f8f6d8e776 Quicker and project specific settings 2025-11-07 14:27:25 +00:00
5016dd4ee8 Add completion ignore ft 2025-10-29 20:29:38 +00:00
37b4d8a6e4 Ignore buffer 2025-10-25 14:50:02 +01:00
Chris
d44eac696f Remove 2025-10-21 09:52:22 +01:00
Chris
5c08ce032e Rename files 2025-10-21 09:50:49 +01:00
9415b1df07 More on AI 2025-10-19 13:07:29 +01:00
406e5cfe8e AI stuff 2025-10-19 10:01:51 +01:00
Chris
6a0c90bf26 Merge branch 'main' of labs.scarif.space:chris/nvim 2025-09-08 09:22:01 +01:00
Chris
7744e83086 Update snippets 2025-09-08 09:20:42 +01:00
d4ecc5aa67 Improve debugging 2025-09-08 09:19:08 +01:00
Chris
2b1d2ed5be Update snippets 2025-08-26 18:23:17 +01:00
ca6e7089fa Type 2025-08-23 12:16:33 +01:00
4f6f50cd6f Update phpactor 2025-08-13 09:04:55 +01:00
Chris
b4821e8a52 Import with extensions 2025-07-30 16:20:50 +01:00
Chris
dc0fed3735 Cleaning up 2025-07-25 12:32:22 +01:00
Chris
b72760d868 Remove go server 2025-07-24 14:34:27 +01:00
Chris
7ec52ae64a Merge branch 'main' of labs.scarif.space:chris/nvim 2025-07-24 14:31:25 +01:00
Chris
278f31d4ea Fixing lsp 2025-07-24 14:27:38 +01:00
ebb69274ba Update aider and projects 2025-07-19 11:52:57 +01:00
ff00984c4e Reordering 2025-07-01 22:44:17 +01:00
6fb67640ef Improve dashboard 2025-07-01 22:39:59 +01:00
Chris
2dc48b5b4c More aider commands 2025-06-30 09:10:05 +01:00
379f2acd55 Update aider shortcut 2025-06-26 16:46:04 +01:00
ed1f52af11 Comment out vectorcode 2025-06-20 22:16:56 +01:00
Chris
f090b1a43e More settings 2025-05-12 17:09:14 +01:00
Chris
4975f4c459 Improvements to Code companion 2025-05-12 09:04:50 +01:00
Chris
d97fdc798f Lighten line number colors 2025-05-12 09:04:50 +01:00
6f3a5a40e5 Install Aider 2025-05-11 18:22:49 +01:00
Chris
ea9ee8267a Start on insert mode 2025-05-08 07:59:46 +01:00
Chris
b8d7a1c9ab Updating debug 2025-05-07 07:58:00 +01:00
Chris
ed622165b8 Fixing some things 2025-05-06 07:18:21 +01:00
3ba111e55c Fix typo 2025-05-05 07:28:57 +01:00
c084f286a1 Merge branch 'fix-detached' 2025-05-05 07:28:04 +01:00
acccc74130 Fixing the keymap for changing model 2025-05-05 07:27:24 +01:00
c329bab9d6 Adding MCP Hub 2025-05-05 07:25:00 +01:00
Chris
6dfef7bd87 Upgrade config 2025-05-02 20:58:31 +01:00
Chris
17e642dcd3 Adding some snippets and keymaps 2025-04-29 17:22:36 +01:00
767d2595cd Delete chroma.log 2025-04-28 09:20:31 +01:00
cfb3885afd Fix closing logic 2025-04-28 08:38:30 +01:00
43 changed files with 2467 additions and 833 deletions

View File

@@ -1 +0,0 @@
AIHUBMIX_API_KEY=

View File

@@ -1,220 +0,0 @@
INFO: [15-04-2025 11:08:19] Set chroma_server_nofile to 65535
DEBUG: [15-04-2025 11:08:19] Starting component System
DEBUG: [15-04-2025 11:08:19] Starting component OpenTelemetryClient
DEBUG: [15-04-2025 11:08:19] Starting component SqliteDB
DEBUG: [15-04-2025 11:08:19] Starting component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:08:19] Starting component Posthog
DEBUG: [15-04-2025 11:08:19] Starting component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:08:19] Starting component LocalSegmentManager
DEBUG: [15-04-2025 11:08:19] Starting component LocalExecutor
DEBUG: [15-04-2025 11:08:19] Starting component SegmentAPI
DEBUG: [15-04-2025 11:08:19] Starting component SimpleAsyncRateLimitEnforcer
INFO: [15-04-2025 11:08:20] Started server process [20213]
INFO: [15-04-2025 11:08:20] Waiting for application startup.
INFO: [15-04-2025 11:08:20] Application startup complete.
INFO: [15-04-2025 11:08:20] Uvicorn running on http://localhost:54131 (Press CTRL+C to quit)
INFO: [15-04-2025 11:08:20] 127.0.0.1:54158 - "GET /api/v1/heartbeat HTTP/1.1" 200
INFO: [15-04-2025 11:08:20] 127.0.0.1:54160 - "GET /api/v2/auth/identity HTTP/1.1" 200
INFO: [15-04-2025 11:08:20] 127.0.0.1:54160 - "GET /api/v2/tenants/default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:08:20] 127.0.0.1:54160 - "GET /api/v2/tenants/default_tenant/databases/default_database?tenant=default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:08:49] Shutting down
INFO: [15-04-2025 11:08:49] Waiting for application shutdown.
DEBUG: [15-04-2025 11:08:49] Stopping component System
DEBUG: [15-04-2025 11:08:49] Stopping component SegmentAPI
DEBUG: [15-04-2025 11:08:49] Stopping component LocalExecutor
DEBUG: [15-04-2025 11:08:49] Stopping component LocalSegmentManager
DEBUG: [15-04-2025 11:08:49] Stopping component SimpleAsyncRateLimitEnforcer
DEBUG: [15-04-2025 11:08:49] Stopping component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:08:49] Stopping component Posthog
DEBUG: [15-04-2025 11:08:49] Stopping component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:08:49] Stopping component SqliteDB
DEBUG: [15-04-2025 11:08:49] Stopping component OpenTelemetryClient
INFO: [15-04-2025 11:08:49] Application shutdown complete.
INFO: [15-04-2025 11:08:49] Finished server process [20213]
INFO: [15-04-2025 11:53:31] Set chroma_server_nofile to 65535
DEBUG: [15-04-2025 11:53:31] Starting component System
DEBUG: [15-04-2025 11:53:31] Starting component OpenTelemetryClient
DEBUG: [15-04-2025 11:53:31] Starting component SqliteDB
DEBUG: [15-04-2025 11:53:31] Starting component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:53:31] Starting component Posthog
DEBUG: [15-04-2025 11:53:31] Starting component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:53:31] Starting component LocalSegmentManager
DEBUG: [15-04-2025 11:53:31] Starting component LocalExecutor
DEBUG: [15-04-2025 11:53:31] Starting component SegmentAPI
DEBUG: [15-04-2025 11:53:31] Starting component SimpleAsyncRateLimitEnforcer
INFO: [15-04-2025 11:53:31] Started server process [21405]
INFO: [15-04-2025 11:53:31] Waiting for application startup.
INFO: [15-04-2025 11:53:31] Application startup complete.
INFO: [15-04-2025 11:53:31] Uvicorn running on http://localhost:61221 (Press CTRL+C to quit)
INFO: [15-04-2025 11:53:31] 127.0.0.1:61237 - "GET /api/v1/heartbeat HTTP/1.1" 200
INFO: [15-04-2025 11:53:31] 127.0.0.1:61239 - "GET /api/v2/auth/identity HTTP/1.1" 200
INFO: [15-04-2025 11:53:31] 127.0.0.1:61239 - "GET /api/v2/tenants/default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:53:31] 127.0.0.1:61239 - "GET /api/v2/tenants/default_tenant/databases/default_database?tenant=default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "GET /api/v2/pre-flight-checks HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:48] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
DEBUG: [15-04-2025 11:53:49] Starting component PersistentLocalHnswSegment
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/add HTTP/1.1" 201
INFO: [15-04-2025 11:53:49] 127.0.0.1:61314 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/get HTTP/1.1" 200
INFO: [15-04-2025 11:53:49] Shutting down
INFO: [15-04-2025 11:53:49] Waiting for application shutdown.
DEBUG: [15-04-2025 11:53:49] Stopping component System
DEBUG: [15-04-2025 11:53:49] Stopping component SegmentAPI
DEBUG: [15-04-2025 11:53:49] Stopping component LocalExecutor
DEBUG: [15-04-2025 11:53:49] Stopping component PersistentLocalHnswSegment
DEBUG: [15-04-2025 11:53:49] Stopping component LocalSegmentManager
DEBUG: [15-04-2025 11:53:49] Stopping component SimpleAsyncRateLimitEnforcer
DEBUG: [15-04-2025 11:53:49] Stopping component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:53:49] Stopping component Posthog
DEBUG: [15-04-2025 11:53:49] Stopping component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:53:49] Stopping component SqliteDB
DEBUG: [15-04-2025 11:53:49] Stopping component OpenTelemetryClient
INFO: [15-04-2025 11:53:49] Application shutdown complete.
INFO: [15-04-2025 11:53:49] Finished server process [21405]
INFO: [15-04-2025 11:54:12] Set chroma_server_nofile to 65535
DEBUG: [15-04-2025 11:54:12] Starting component System
DEBUG: [15-04-2025 11:54:12] Starting component OpenTelemetryClient
DEBUG: [15-04-2025 11:54:12] Starting component SqliteDB
DEBUG: [15-04-2025 11:54:12] Starting component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:54:12] Starting component Posthog
DEBUG: [15-04-2025 11:54:12] Starting component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:54:12] Starting component LocalSegmentManager
DEBUG: [15-04-2025 11:54:12] Starting component LocalExecutor
DEBUG: [15-04-2025 11:54:12] Starting component SegmentAPI
DEBUG: [15-04-2025 11:54:12] Starting component SimpleAsyncRateLimitEnforcer
INFO: [15-04-2025 11:54:12] Started server process [21526]
INFO: [15-04-2025 11:54:12] Waiting for application startup.
INFO: [15-04-2025 11:54:12] Application startup complete.
INFO: [15-04-2025 11:54:12] Uvicorn running on http://localhost:61415 (Press CTRL+C to quit)
INFO: [15-04-2025 11:54:12] 127.0.0.1:61431 - "GET /api/v1/heartbeat HTTP/1.1" 200
INFO: [15-04-2025 11:54:12] 127.0.0.1:61433 - "GET /api/v2/auth/identity HTTP/1.1" 200
INFO: [15-04-2025 11:54:12] 127.0.0.1:61433 - "GET /api/v2/tenants/default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:54:12] 127.0.0.1:61433 - "GET /api/v2/tenants/default_tenant/databases/default_database?tenant=default_tenant HTTP/1.1" 200
INFO: [15-04-2025 11:54:16] 127.0.0.1:61433 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/2464dff91bf19cf59711c4ad9589d971881dee3b4724247c204882ed9a916c7 HTTP/1.1" 200
INFO: [15-04-2025 11:54:16] 127.0.0.1:61433 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/count HTTP/1.1" 200
INFO: [15-04-2025 11:54:16] 127.0.0.1:61433 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/count HTTP/1.1" 200
DEBUG: [15-04-2025 11:54:16] Starting component PersistentLocalHnswSegment
INFO: [15-04-2025 11:54:16] 127.0.0.1:61433 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/query HTTP/1.1" 200
INFO: [15-04-2025 11:54:31] Shutting down
INFO: [15-04-2025 11:54:31] Waiting for application shutdown.
DEBUG: [15-04-2025 11:54:31] Stopping component System
DEBUG: [15-04-2025 11:54:31] Stopping component SegmentAPI
DEBUG: [15-04-2025 11:54:31] Stopping component LocalExecutor
DEBUG: [15-04-2025 11:54:31] Stopping component PersistentLocalHnswSegment
DEBUG: [15-04-2025 11:54:31] Stopping component LocalSegmentManager
DEBUG: [15-04-2025 11:54:31] Stopping component SimpleAsyncRateLimitEnforcer
DEBUG: [15-04-2025 11:54:31] Stopping component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 11:54:31] Stopping component Posthog
DEBUG: [15-04-2025 11:54:31] Stopping component SimpleQuotaEnforcer
DEBUG: [15-04-2025 11:54:31] Stopping component SqliteDB
DEBUG: [15-04-2025 11:54:31] Stopping component OpenTelemetryClient
INFO: [15-04-2025 11:54:31] Application shutdown complete.
INFO: [15-04-2025 11:54:31] Finished server process [21526]
INFO: [15-04-2025 12:59:41] Set chroma_server_nofile to 65535
DEBUG: [15-04-2025 12:59:41] Starting component System
DEBUG: [15-04-2025 12:59:41] Starting component OpenTelemetryClient
DEBUG: [15-04-2025 12:59:41] Starting component SqliteDB
DEBUG: [15-04-2025 12:59:41] Starting component SimpleQuotaEnforcer
DEBUG: [15-04-2025 12:59:41] Starting component Posthog
DEBUG: [15-04-2025 12:59:41] Starting component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 12:59:41] Starting component LocalSegmentManager
DEBUG: [15-04-2025 12:59:41] Starting component LocalExecutor
DEBUG: [15-04-2025 12:59:41] Starting component SegmentAPI
DEBUG: [15-04-2025 12:59:41] Starting component SimpleAsyncRateLimitEnforcer
INFO: [15-04-2025 12:59:41] Started server process [24842]
INFO: [15-04-2025 12:59:41] Waiting for application startup.
INFO: [15-04-2025 12:59:41] Application startup complete.
INFO: [15-04-2025 12:59:41] Uvicorn running on http://localhost:62331 (Press CTRL+C to quit)
INFO: [15-04-2025 12:59:41] 127.0.0.1:62346 - "GET /api/v1/heartbeat HTTP/1.1" 200
INFO: [15-04-2025 12:59:41] 127.0.0.1:62348 - "GET /api/v2/auth/identity HTTP/1.1" 200
INFO: [15-04-2025 12:59:41] 127.0.0.1:62348 - "GET /api/v2/tenants/default_tenant HTTP/1.1" 200
INFO: [15-04-2025 12:59:41] 127.0.0.1:62348 - "GET /api/v2/tenants/default_tenant/databases/default_database?tenant=default_tenant HTTP/1.1" 200
INFO: [15-04-2025 12:59:46] 127.0.0.1:62348 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/2464dff91bf19cf59711c4ad9589d971881dee3b4724247c204882ed9a916c7 HTTP/1.1" 200
INFO: [15-04-2025 12:59:46] 127.0.0.1:62348 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/count HTTP/1.1" 200
INFO: [15-04-2025 12:59:46] 127.0.0.1:62348 - "GET /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/count HTTP/1.1" 200
DEBUG: [15-04-2025 12:59:46] Starting component PersistentLocalHnswSegment
INFO: [15-04-2025 12:59:46] 127.0.0.1:62348 - "POST /api/v2/tenants/default_tenant/databases/default_database/collections/79ccccf4-e887-41d8-b859-69da50490f8c/query HTTP/1.1" 200
INFO: [15-04-2025 12:59:49] Shutting down
INFO: [15-04-2025 12:59:49] Waiting for application shutdown.
DEBUG: [15-04-2025 12:59:49] Stopping component System
DEBUG: [15-04-2025 12:59:49] Stopping component SegmentAPI
DEBUG: [15-04-2025 12:59:49] Stopping component LocalExecutor
DEBUG: [15-04-2025 12:59:49] Stopping component PersistentLocalHnswSegment
DEBUG: [15-04-2025 12:59:49] Stopping component LocalSegmentManager
DEBUG: [15-04-2025 12:59:49] Stopping component SimpleAsyncRateLimitEnforcer
DEBUG: [15-04-2025 12:59:49] Stopping component SimpleRateLimitEnforcer
DEBUG: [15-04-2025 12:59:49] Stopping component Posthog
DEBUG: [15-04-2025 12:59:49] Stopping component SimpleQuotaEnforcer
DEBUG: [15-04-2025 12:59:49] Stopping component SqliteDB
DEBUG: [15-04-2025 12:59:49] Stopping component OpenTelemetryClient
INFO: [15-04-2025 12:59:49] Application shutdown complete.
INFO: [15-04-2025 12:59:49] Finished server process [24842]

View File

@@ -11,9 +11,36 @@ require 'opt'
require 'keymap' require 'keymap'
require 'autocmd' require 'autocmd'
require 'lazy_init' require 'lazy_init'
require 'visuals'
require 'projects'
require('helpers').edit_cf('v', '/init.lua') require('helpers').edit_cf('v', '/init.lua')
--[[
TODO: Neovim configurations I want to add:
- [x] Clearer line numbers (weirdly not as simple as it sounds)
- [ ] Debugging keymap that works like PHPStorm
- [ ] Improve snippet expansion (and get rid of that stupid #endsection snippet)
- [ ] Better organising of buffers when opening side panels (like AI chat and test summary)
- [ ] Close test panel when opening debugger and vice versa using edgy
- [ ] Close terminal from inside terminal buffer
- [ ] Get shift key bindings working inside tmux
- [ ] Fix ctrl+shift+a keybinding for AI actions
- [ ] Get VectorCode working
- [ ] Add LSP symbols for Pest tests
- [ ] More prompts
- [ ] Give AI better context and tools for working with Hylark
- [ ] Figure out AI workspaces
- [ ] Figure out agentic workflow
- [ ] Figure out a better way to add relevant buffers to AI
- [ ] Better inline AI assistant
- [ ] Keymap to copy visual selection to chat
- [ ] Better register management
- [ ] Figure out debug expressions
- [ ] Better keymaps for debug movements
- [ ] Chat history
]]
-- " Auto-Commands --- {{{ -- " Auto-Commands --- {{{
-- --
-- augroup modes -- augroup modes

View File

@@ -26,6 +26,14 @@ vim.api.nvim_create_autocmd('InsertLeave', {
command = 'silent! wa', -- Save all files when leaving insert mode command = 'silent! wa', -- Save all files when leaving insert mode
}) })
vim.api.nvim_create_autocmd('SwapExists', {
desc = 'Always choose to delete the swap file, files are saved automatically',
group = vim.api.nvim_create_augroup('NoSwaps', { clear = true }),
callback = function(args)
vim.cmd "let v:swapchoice = 'd'"
end,
})
-- vim.api.nvim_create_autocmd('TextChanged', { -- vim.api.nvim_create_autocmd('TextChanged', {
-- group = autosave_group, -- group = autosave_group,
-- pattern = '*', -- pattern = '*',
@@ -67,19 +75,22 @@ vim.api.nvim_create_autocmd({ 'User' }, {
end, end,
}) })
vim.api.nvim_create_autocmd('BufEnter', { -- vim.api.nvim_create_autocmd('BufEnter', {
callback = function(event) -- callback = function(event)
local windows = vim.api.nvim_list_wins() -- local windows = vim.api.nvim_list_wins()
--
for _, window in ipairs(windows) do -- for _, window in ipairs(windows) do
local bufnr = vim.api.nvim_win_get_buf(window) -- local bufnr = vim.api.nvim_win_get_buf(window)
if vim.api.nvim_get_option_value('buflisted', { buf = bufnr }) then -- local ft = vim.api.nvim_get_option_value('filetype', { buf = bufnr })
return -- if vim.api.nvim_get_option_value('buflisted', { buf = bufnr })
end -- or ft == 'oil'
end -- or ft == 'snacks_dashboard' then
vim.cmd 'qa' -- return
end, -- end
}) -- end
-- vim.cmd 'qa'
-- end,
-- })
local modes_group = vim.api.nvim_create_augroup('modes', { clear = true }) local modes_group = vim.api.nvim_create_augroup('modes', { clear = true })
vim.api.nvim_create_autocmd('FocusLost', { vim.api.nvim_create_autocmd('FocusLost', {
@@ -105,4 +116,33 @@ vim.api.nvim_create_autocmd('BufWritePost', {
end, end,
}) })
vim.api.nvim_create_autocmd('FileType', {
pattern = {
'bash',
'c',
'diff',
'html',
'lua',
'luadoc',
'markdown',
'markdown_inline',
'query',
'vim',
'vimdoc',
'php',
'javascript',
'typescript',
'json',
},
callback = function()
-- syntax highlighting, provided by Neovim
vim.treesitter.start()
-- folds, provided by Neovim
vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
vim.wo.foldmethod = 'expr'
-- indentation, provided by nvim-treesitter
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
end,
})
require('helpers').edit_cf('a', '/lua/autocmd.lua') require('helpers').edit_cf('a', '/lua/autocmd.lua')

View File

@@ -9,7 +9,50 @@ helpers.edit_cf = function(map, path)
end, { desc = 'Edit ' .. path .. ' in a new tab' }) end, { desc = 'Edit ' .. path .. ' in a new tab' })
end end
helpers.map = function(keys, func, opts, mode)
mode = mode or 'n'
vim.keymap.set(mode, keys, func, opts)
end
helpers.edit_cf('h', '/lua/helpers.lua') helpers.edit_cf('h', '/lua/helpers.lua')
---@param opts? { cmd?: string }
helpers.open_term = function(opts)
opts = opts or { cmd = '' }
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_option_value('bufhidden', 'wipe', { buf = buf })
vim.api.nvim_set_option_value('modifiable', false, { buf = buf })
local height = math.ceil(vim.o.lines * 0.9)
local width = math.ceil(vim.o.columns * 0.9)
local win = vim.api.nvim_open_win(buf, true, {
style = 'minimal',
relative = 'editor',
width = width,
height = height,
row = math.ceil((vim.o.lines - height) / 2),
col = math.ceil((vim.o.columns - width) / 2),
border = 'single',
})
vim.api.nvim_set_current_win(win)
vim.fn.jobstart(opts.cmd, {
term = true,
on_exit = function(_, _, _)
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
end
end,
})
vim.cmd.startinsert()
end
helpers.has_copilot = function()
return vim.fn.getenv('COPILOT_API_KEY') ~= vim.NIL
end
return helpers return helpers
-- nnoremap <Leader>ev :tabedit $MYVIMRC<CR> -- nnoremap <Leader>ev :tabedit $MYVIMRC<CR>

View File

@@ -1,6 +1,8 @@
-- [[ Basic Keymaps ]] -- Basic Keymaps
-- See `:help vim.keymap.set()` -- See `:help vim.keymap.set()`
local helpers = require 'helpers'
-- Swap : and ; around -- Swap : and ; around
vim.keymap.set({ 'n', 'v' }, ':', ';') vim.keymap.set({ 'n', 'v' }, ':', ';')
vim.keymap.set({ 'n', 'v' }, ';', ':') vim.keymap.set({ 'n', 'v' }, ';', ':')
@@ -12,6 +14,10 @@ vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
-- Diagnostic keymaps -- Diagnostic keymaps
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
vim.keymap.set({ 'n', 'v' }, 'c', '"zc', { desc = 'Change without copying to clipboard' })
vim.keymap.set({ 'n', 'v' }, 'x', '"zx', { desc = 'Cut without copying to clipboard' })
vim.keymap.set('v', 'p', '"zdP', { desc = 'Paste over selection without yanking replaced text' })
-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which -- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
-- is not what someone will guess without a bit more experience. -- is not what someone will guess without a bit more experience.
@@ -20,19 +26,130 @@ vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagn
-- or just use <C-\><C-n> to exit terminal mode -- or just use <C-\><C-n> to exit terminal mode
vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' }) vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
vim.keymap.set('n', '<Leader>c', function()
vim.treesitter.inspect_tree()
end, { desc = 'Treesitter' })
-- vim.keymap.set('n', '<C-S-D>', function()
-- local node = vim.treesitter.get_node {}
-- local range = { vim.treesitter.get_node_range(node) }
-- vim.api.nvim_win_set_cursor(0, { range[3] + 1, range[4] - 1 })
-- vim.fn.setpos("'x", { 0, range[1] + 1, range[2] + 1, 0 })
-- vim.cmd.normal 'v`x'
-- end, { desc = 'Select surrounding treesitter node' })
vim.keymap.set('v', '<C-S-D>', function()
local start = vim.api.nvim_win_get_cursor(0)
local start_row, start_column
if start[2] == 0 then
start_row = start[1] - 1
start_column = 0
else
start_row = start[1]
start_column = start[2] - 1
end
vim.api.nvim_win_set_cursor(0, { start_row, start_column })
local node = vim.treesitter.get_node {}
local range = { vim.treesitter.get_node_range(node) }
vim.api.nvim_win_set_cursor(0, { range[3] + 1, range[4] - 1 })
vim.fn.setpos("'x", { 0, range[1] + 1, range[2] + 1, 0 })
vim.cmd.normal 'i'
vim.cmd.normal 'v`x'
end, { desc = 'Select surrounding treesitter node' })
local swappable_nodes = { 'argument', 'array_element_initializer', 'simple_parameter', 'string', 'integer', 'member_call_expression', 'method_declaration' }
local function closest_swappable_node(node)
while node and not vim.list_contains(swappable_nodes, node:type()) and (not node:next_named_sibling() or not node:prev_named_sibling()) do
node = node:parent()
end
return node
end
vim.keymap.set({ 'n' }, '<C-S-h>', function()
local node = closest_swappable_node(vim.treesitter.get_node())
if not node then
return
end
local prev_node = node:prev_named_sibling()
while prev_node and not vim.list_contains(swappable_nodes, prev_node:type()) do
prev_node = prev_node:prev_named_sibling()
end
if prev_node == nil then
return
end
require('nvim-treesitter.ts_utils').swap_nodes(node, prev_node, 0, true)
end, { desc = 'Swap with node to the left' })
vim.keymap.set({ 'n' }, '<C-S-l>', function()
local node = closest_swappable_node(vim.treesitter.get_node())
if not node then
return
end
local next_node = node:next_named_sibling()
while next_node and not vim.list_contains(swappable_nodes, next_node:type()) do
next_node = next_node:next_named_sibling()
end
if next_node == nil then
return
end
require('nvim-treesitter.ts_utils').swap_nodes(node, next_node, 0, true)
end, { desc = 'Swap with node to the right' })
vim.keymap.set('n', '<C-S-j>', 'ddp', { desc = 'Move line down' })
vim.keymap.set('n', '<C-S-k>', 'ddkP', { desc = 'Move line up' })
vim.keymap.set('v', '<C-S-j>', 'do<Esc>p`[v`]', { desc = 'Move selection down' })
vim.keymap.set('v', '<C-S-k>', 'dkO<Esc>p`[v`]', { desc = 'Move selection up' })
-- Keybinds to make split navigation easier. -- Keybinds to make split navigation easier.
-- Use CTRL+<hjkl> to switch between windows -- Use CTRL+<hjkl> to switch between windows
-- --
-- See `:help wincmd` for a list of all window commands -- See `:help wincmd` for a list of all window commands
local function win_or_treesj(dir_cmd, desc)
return function()
local cur = vim.api.nvim_get_current_win()
vim.cmd('wincmd ' .. dir_cmd)
if vim.api.nvim_get_current_win() == cur then
local ok, treesj = pcall(require, 'treesj')
if ok and type(treesj.toggle) == 'function' then
treesj.toggle()
end
end
end, { desc = desc }
end
vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' }) vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' }) vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' }) vim.keymap.set('n', '<C-j>', (win_or_treesj)('j', 'Move focus to the lower window or treesj.toggle()'))
vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' }) vim.keymap.set('n', '<C-k>', (win_or_treesj)('k', 'Move focus to the upper window or treesj.toggle()'))
vim.keymap.set('n', '<C-S-h>', '<C-w>H', { desc = 'Move window to the left' }) vim.keymap.set({ 'i' }, '<C-J>', function()
vim.keymap.set('n', '<C-S-l>', '<C-w>L', { desc = 'Move window to the right' }) local ls = require 'luasnip'
vim.keymap.set('n', '<C-S-j>', '<C-w>J', { desc = 'Move window to the lower' }) if ls.choice_active() then
vim.keymap.set('n', '<C-S-k>', '<C-w>K', { desc = 'Move window to the upper' }) ls.change_choice(1)
end
end, { desc = 'Toggle snippet choice', silent = true })
vim.keymap.set({ 'i' }, '<C-k>', function()
local ls = require 'luasnip'
if ls.choice_active() then
ls.change_choice(-1)
end
end, { desc = 'Toggle snippet choice', silent = true })
vim.keymap.set({ 'i', 's' }, '<C-L>', function()
local ls = require 'luasnip'
if ls.expandable() then
ls.expand()
elseif ls.in_snippet() then
ls.jump(1)
end
end, { desc = 'Expand snippet', silent = true })
vim.keymap.set({ 'i', 's' }, '<C-H>', function()
local ls = require 'luasnip'
if ls.in_snippet() then
ls.jump(-1)
end
end, { desc = 'Go back a snippet slot', silent = true })
vim.keymap.set('n', '<Leader>.', '<Cmd>tabnext<CR>', { desc = 'Next tab' })
vim.keymap.set('n', '<Leader>,', '<Cmd>tabprevious<CR>', { desc = 'Previous tab' })
-- Overriding CTRL mappings because some of them are stupid -- Overriding CTRL mappings because some of them are stupid
vim.keymap.set({ 'n', 'v', 'c', 'i' }, '<C-S-B>', '<CMD>Git blame<CR>', { desc = 'Git blame' }) vim.keymap.set({ 'n', 'v', 'c', 'i' }, '<C-S-B>', '<CMD>Git blame<CR>', { desc = 'Git blame' })
@@ -53,7 +170,7 @@ vim.keymap.set({ 'n', 'v', 'c', 'i' }, '<C-S-P>', function()
hidden = true, hidden = true,
} }
end, { desc = 'Find all files' }) end, { desc = 'Find all files' })
vim.keymap.set({ 'n', 'v', 'c', 'i' }, '<C-F>', function() vim.keymap.set({ 'n', 'v', 'c', 'i' }, '<C-f>', function()
require('telescope.builtin').live_grep { require('telescope.builtin').live_grep {
hidden = true, hidden = true,
} }
@@ -86,27 +203,48 @@ vim.keymap.set('n', '<Leader>{', 'mzF[`a<CR><Esc>``%i<CR><Esc>`z', { desc = 'Ind
vim.keymap.set('n', '<Leader>}', 'mzF[`a<CR><Esc>``%i<CR><Esc>`zvi[:s/,\\s*/,\\r/g<CR>vi[=<Esc>`z:nohlsearch<CR>', { desc = 'Indent an array some other way?' }) vim.keymap.set('n', '<Leader>}', 'mzF[`a<CR><Esc>``%i<CR><Esc>`zvi[:s/,\\s*/,\\r/g<CR>vi[=<Esc>`z:nohlsearch<CR>', { desc = 'Indent an array some other way?' })
-- Git mappings -- Git mappings
vim.keymap.set('n', '<Leader>gaf', '<CMD>Git add %<CR>', { desc = 'Git add current file' })
vim.keymap.set('n', '<Leader>gaa', '<CMD>Git add --all<CR>', { desc = 'Git add all unstaged changes' })
vim.keymap.set('n', '<Leader>gap', '<CMD>Git add --patch --all<CR>', { desc = 'Git add all unstaged changes interactively' })
vim.keymap.set('n', '<Leader>gb', '<CMD>Git blame<CR>', { desc = 'Git blame' }) vim.keymap.set('n', '<Leader>gb', '<CMD>Git blame<CR>', { desc = 'Git blame' })
vim.keymap.set('n', '<Leader>gcm', '<CMD>Git commit -v<CR>', { desc = 'Git commit' })
vim.keymap.set('n', '<Leader>gp', '<CMD>Git push<CR>', { desc = 'Git push' })
vim.keymap.set('n', '<Leader>gup', '<CMD>Git pull --rebase<CR>', { desc = 'Git pull --rebase' })
vim.keymap.set('n', '<Leader>gsb', '<CMD>Git status<CR>', { desc = 'Git status' })
vim.keymap.set('n', '<Leader>gd', '<CMD>Git diff<CR>', { desc = 'Git diff' }) vim.keymap.set('n', '<Leader>gd', '<CMD>Git diff<CR>', { desc = 'Git diff' })
vim.keymap.set('n', '<Leader>gdc', '<CMD>Git diff --cached<CR>', { desc = 'Git diff' }) vim.keymap.set('n', '<Leader>gdc', '<CMD>Git diff --cached<CR>', { desc = 'Git diff' })
vim.keymap.set('n', '<Leader>gl', '<CMD>Git log<CR>', { desc = 'Git log' }) vim.keymap.set('n', '<Leader>G', function()
vim.keymap.set('n', '<Leader>gun', '<CMD>Git reset -- %<CR>', { desc = 'Git unstage file' }) helpers.open_term { cmd = 'lazygit' }
vim.keymap.set('n', '<Leader>gco', '<CMD>Git checkout -- %<CR>', { desc = 'Git checkout' }) end, { desc = 'Git' })
vim.keymap.set('n', '<Leader>G', '<CMD>Git', { desc = 'Git' })
vim.keymap.set('n', '<Leader>gsta', '<CMD>Git stash push<CR>', { desc = 'Git stash' }) -- Add keymaps for diff mode
vim.keymap.set('n', '<Leader>gstA', '<CMD>Git stash apply<CR>', { desc = 'Git stash apply' }) vim.api.nvim_create_autocmd('BufEnter', {
vim.keymap.set('n', '<Leader>gstp', '<CMD>Git stash pop<CR>', { desc = 'Git stash pop' }) callback = function()
if vim.wo.diff then
-- Keymaps for navigating hunks
vim.api.nvim_buf_set_keymap(0, 'n', '<Tab>', ']c', { noremap = true, silent = true, desc = 'Next hunk in diff mode' })
vim.api.nvim_buf_set_keymap(0, 'n', '<S-Tab>', '[c', { noremap = true, silent = true, desc = 'Previous hunk in diff mode' })
-- Keymaps for resolving conflicts
vim.api.nvim_buf_set_keymap(0, 'n', '<leader>dl', ':diffget LOCAL<CR>', { noremap = true, silent = true, desc = 'Get LOCAL changes' })
vim.api.nvim_buf_set_keymap(0, 'n', '<leader>dr', ':diffget REMOTE<CR>', { noremap = true, silent = true, desc = 'Get REMOTE changes' })
end
end,
})
-- AI mappings -- AI mappings
vim.keymap.set('v', '<Leader>ae', '<CMD>CodeCompanion<CR>', { desc = 'Edit selection with AI' }) -- vim.keymap.set('v', '<Leader>ae', '<CMD>CodeCompanion<CR>', { desc = 'Edit selection with AI' })
vim.keymap.set('n', '<Leader>ac', '<CMD>CodeCompanionCmd<CR>', { desc = 'Run Neovim commands with AI' }) -- vim.keymap.set('n', '<Leader>ac', '<CMD>CodeCompanionCmd<CR>', { desc = 'Run Neovim commands with AI' })
vim.api.nvim_create_autocmd('FileType', {
pattern = 'codecompanion',
callback = function()
vim.keymap.set('i', '<Enter>', function()
require('codecompanion').last_chat():submit()
end, { buffer = true, desc = 'Use enter to send the message' })
vim.keymap.set('i', '<S-Enter>', '<Enter>', { buffer = true, desc = 'Use shift enter to start a new line' })
vim.keymap.set('n', '<Enter>', 'G', { buffer = true, desc = 'Use enter in normal mode to go to the end of the chat' })
local models = { vim.env.DEFAULT_AI_MODEL, vim.env.REASONING_MODEL, vim.env.FAST_MODEL }
-- Loop through models and create keymaps for each
for i, model in ipairs(models) do
vim.keymap.set('n', '<C-' .. i .. '>', 'mzggj0W"_C' .. model .. '<Esc>`z', { desc = 'Switch to ' .. model })
vim.keymap.set('i', '<C-' .. i .. '>', '<Esc>mzggj0W"_C' .. model .. '<Esc>`za', { desc = 'Switch to ' .. model })
end
end,
})
-- Search mappings -- Search mappings
vim.keymap.set('n', '<Leader>sGb', '<CMD>Telescope git_branches<CR>', { desc = 'Search git branches' }) vim.keymap.set('n', '<Leader>sGb', '<CMD>Telescope git_branches<CR>', { desc = 'Search git branches' })
@@ -125,54 +263,95 @@ local function open_test()
require('neotest').output_panel.open() require('neotest').output_panel.open()
end end
-- Testing -- Testing
local test_maps = { -- local test_maps = {
{ -- {
keys = { '<F12>', '<Leader>tn' }, -- keys = { '<F12>', '<Leader>tn' },
action = function() -- action = function()
require('neotest').run.run() -- require('neotest').run.run()
open_test() -- open_test()
end, -- end,
desc = 'Run nearest test', -- desc = 'Run nearest test',
}, -- },
{ -- {
keys = { '<F9>', '<Leader>ta' }, -- keys = { '<F9>', '<Leader>ta' },
action = function() -- action = function()
require('neotest').run.run { suite = true } -- require('neotest').run.run { suite = true }
open_test() -- open_test()
end, -- end,
desc = 'Run all tests in the project', -- desc = 'Run all tests in the project',
}, -- },
{ -- {
keys = { '<F11>', '<Leader>tp' }, -- keys = { '<F11>', '<Leader>tp' },
action = function() -- action = function()
require('neotest').run.run_last() -- require('neotest').run.run_last()
open_test() -- open_test()
end, -- end,
desc = 'Run previous test again', -- desc = 'Run previous test again',
}, -- },
{ -- {
keys = { '<F10>', '<Leader>td' }, -- keys = { '<F10>', '<Leader>td' },
action = function() -- action = function()
require('neotest').run.run_last { strategy = 'dap' } -- local dap = require 'dap'
require('neotest').summary.open() -- Note: Doesn't call open_test() like the others -- if dap.session() == nil then
end, -- dap.continue()
desc = 'Run last test with debugger', -- end
}, -- require('dapui').open()
} -- local neotest = require 'neotest'
-- local bufnr = vim.api.nvim_get_current_buf()
-- local row = vim.api.nvim_win_get_cursor(0)[1] - 1
--
-- local adapters = neotest.state.adapter_ids()
-- local found = false
--
-- for _, adapter_id in ipairs(adapters) do
-- local tree = neotest.state.positions(adapter_id, { buffer = bufnr })
-- if tree then
-- local nearest = require('neotest.lib.positions').nearest(tree, row)
-- if nearest and nearest:data().type ~= 'file' then
-- neotest.run.run()
-- found = true
-- break
-- end
-- end
-- end
--
-- if not found then
-- neotest.run.run_last()
-- end
-- end,
-- desc = 'Run last test with debugger',
-- },
-- }
--
-- for _, map_info in ipairs(test_maps) do
-- for _, key in ipairs(map_info.keys) do
-- vim.keymap.set('n', key, map_info.action, { desc = map_info.desc })
-- end
-- end
-- vim.keymap.set('n', '<Leader>tf', function()
-- require('neotest').run.run(vim.fn.expand '%')
-- open_test()
-- end, { desc = 'Run all tests in the current file' })
-- vim.keymap.set('n', '<Leader>tc', function()
-- require('neotest').summary.close()
-- require('neotest').output_panel.close()
-- end, { desc = 'Close test panels' })
for _, map_info in ipairs(test_maps) do -- vim.keymap.set('i', '<Tab>', function()
for _, key in ipairs(map_info.keys) do -- local copilot = require 'copilot.suggestion'
vim.keymap.set('n', key, map_info.action, { desc = map_info.desc }) -- local ls = require 'luasnip'
end -- if copilot.is_visible() then
end -- vim.api.nvim_echo({{'Accepting copilot suggestion'}}, false, {})
vim.keymap.set('n', '<Leader>tf', function() -- copilot.accept()
require('neotest').run.run(vim.fn.expand '%') -- copilot.dismiss()
open_test() -- elseif ls.jumpable(1) then
end, { desc = 'Run all tests in the current file' }) -- vim.api.nvim_echo({{'Jumping in snippet'}}, false, {})
vim.keymap.set('n', '<Leader>tc', function() -- ls.jump()
require('neotest').summary.close() -- else
require('neotest').output_panel.close() -- vim.api.nvim_echo({{'Inserting tab'}}, false, {})
end, { desc = 'Close test panels' }) -- vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<Tab>', true, true, true), 'n', true)
-- end
-- end, { desc = 'Luasnip accept copilot or jump forward' })
-- Leaving this commented out, I will try the format command instead -- Leaving this commented out, I will try the format command instead
-- "A command to properly indent json code -- "A command to properly indent json code
@@ -182,8 +361,11 @@ end, { desc = 'Close test panels' })
-- directory if the file does not exist -- directory if the file does not exist
vim.keymap.set('n', '<Leader>es', function() vim.keymap.set('n', '<Leader>es', function()
local ft = vim.bo.filetype local ft = vim.bo.filetype
if ft == 'vue' then
ft = 'javascript'
end
local snippets_dir = vim.fn.stdpath 'config' .. '/lua/snippets' local snippets_dir = vim.fn.stdpath 'config' .. '/lua/snippets'
local snippets_file = snippets_dir .. '/' .. ft .. '.json' local snippets_file = snippets_dir .. '/' .. ft .. '.lua'
vim.cmd('tabedit ' .. snippets_file) vim.cmd('tabedit ' .. snippets_file)
end, { desc = 'Edit snippets file' }) end, { desc = 'Edit snippets file' })

View File

@@ -0,0 +1,72 @@
-- AI code completion
if vim.fn.getenv 'COPILOT_API_KEY' ~= vim.NIL then
return {
'zbirenbaum/copilot.lua',
event = 'InsertEnter',
config = function()
require('copilot').setup {
suggestion = {
enabled = true,
auto_trigger = true,
keymap = {
accept = '<A-a>',
},
},
filetypes = {
yaml = true,
markdown = true,
gitcommit = true,
gitrebase = true,
},
}
end,
}
end
return {
'milanglacier/minuet-ai.nvim',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
require('minuet').setup {
virtualtext = {
auto_trigger_ft = { '*' },
auto_trigger_ignore_ft = { 'help', 'TelescopePrompt', 'codecompanion', 'snacks_input' },
keymap = {
accept = '<A-A>',
accept_line = '<A-a>',
-- accept n lines (prompts for number)
-- e.g. "A-z 2 CR" will accept 2 lines
accept_n_lines = '<A-z>',
-- Cycle to prev completion item, or manually invoke completion
prev = '<A-[>',
-- Cycle to next completion item, or manually invoke completion
next = '<A-]>',
dismiss = '<A-e>',
},
},
provider = 'openai_compatible',
request_timeout = 3,
throttle = 500, -- Increase to reduce costs and avoid rate limits
debounce = 400, -- Increase to reduce costs and avoid rate limits
n_completions = 1,
before_cursor_filter_length = 10,
provider_options = {
openai_compatible = {
api_key = 'COMPLETION_OPENAI_API_KEY',
end_point = vim.env.COMPLETION_OPENAI_API_BASE .. '/v1/chat/completions',
model = vim.env.COMPLETION_MODEL,
name = 'Openrouter',
optional = {
max_tokens = 300,
top_p = 0.9,
provider = {
-- Prioritize throughput for faster completion
sort = 'throughput',
},
},
},
},
}
end,
}

67
lua/plugins/aider.lua Normal file
View File

@@ -0,0 +1,67 @@
require('helpers').edit_cf('pa', '/lua/plugins/aider.lua')
local change_model_function = function(model)
return function()
require('nvim_aider').api.send_command('/model', model)
end
end
return {
'GeorgesAlkhouri/nvim-aider',
cmd = 'Aider',
keys = {
{ '<leader>a/', '<cmd>Aider toggle<cr>', desc = 'Toggle Aider' },
{ '<leader>as', '<cmd>Aider send<cr>', desc = 'Send to Aider', mode = { 'n', 'v' } },
{ '<leader>ac', '<cmd>Aider command<cr>', desc = 'Aider Commands' },
{ '<leader>ab', '<cmd>Aider buffer<cr>', desc = 'Send Buffer' },
{ '<leader>a+', '<cmd>Aider add<cr>', desc = 'Add File' },
{ '<leader>a-', '<cmd>Aider drop<cr>', desc = 'Drop File' },
{ '<leader>ar', '<cmd>Aider add readonly<cr>', desc = 'Add Read-Only' },
{ '<leader>aR', '<cmd>Aider reset<cr>', desc = 'Reset Session' },
-- Example nvim-tree.lua integration if needed
{ '<leader>a+', '<cmd>AiderTreeAddFile<cr>', desc = 'Add File from Tree to Aider', ft = 'NvimTree' },
{ '<leader>a-', '<cmd>AiderTreeDropFile<cr>', desc = 'Drop File from Tree from Aider', ft = 'NvimTree' },
{ '<leader>am4', change_model_function 'gpt-4.1', desc = 'Switch aider model to GPT-4.1' },
{ '<leader>amo', change_model_function 'openai/o4-mini', desc = 'Switch aider model to o4-mini' },
{ '<leader>amg', change_model_function 'openai/gemini-2.5-pro', desc = 'Switch aider model to Gemini 2.5 Pro' },
{ '<leader>ams', change_model_function 'openai/claude-sonnet-4', desc = 'Switch aider model to Claude Sonnet 4' },
},
dependencies = {
'folke/snacks.nvim',
--- The below dependencies are optional
'catppuccin/nvim',
'nvim-tree/nvim-tree.lua',
--- Neo-tree integration
{
'nvim-neo-tree/neo-tree.nvim',
opts = function(_, opts)
-- Example mapping configuration (already set by default)
-- opts.window = {
-- mappings = {
-- ["+"] = { "nvim_aider_add", desc = "add to aider" },
-- ["-"] = { "nvim_aider_drop", desc = "drop from aider" }
-- ["="] = { "nvim_aider_add_read_only", desc = "add read-only to aider" }
-- }
-- }
require('nvim_aider.neo_tree').setup(opts)
end,
},
},
config = function()
require('nvim_aider').setup {
aider_cmd = 'aider',
args = {
'--config=$HOME/.config/aider/aider.yaml',
'--env-file=$(pwd)/aider.env',
'--watch',
'--architect',
},
auto_reload = true,
win = {
wo = { winbar = 'Aider' },
style = 'nvim_aider',
position = 'bottom',
},
}
end,
}

View File

@@ -2,7 +2,7 @@
-- https://github.com/windwp/nvim-autopairs -- https://github.com/windwp/nvim-autopairs
return { return {
"windwp/nvim-autopairs", 'windwp/nvim-autopairs',
event = "InsertEnter", event = 'InsertEnter',
opts = {}, opts = {},
} }

View File

@@ -1,75 +0,0 @@
return {}
-- require('helpers').edit_cf('pa', '/lua/plugins/avante.lua')
--
-- return {
-- 'yetone/avante.nvim',
-- event = 'VeryLazy',
-- version = false, -- Never set this value to "*"! Never!
-- opts = {
-- -- add any opts here
-- -- for example
-- provider = 'aihubmix',
-- -- cursor_applying_provider = 'aihubmix_llama_versatile',
-- aihubmix = {
-- -- model = 'claude-3-7-sonnet-20250219',
-- model = 'DeepSeek-V3',
-- },
-- openai = {
-- endpoint = 'https://api.openai.com/v1',
-- model = 'gpt-4o', -- your desired model (or use gpt-4o, etc.)
-- timeout = 30000, -- Timeout in milliseconds, increase this for reasoning models
-- temperature = 0,
-- max_completion_tokens = 8192, -- Increase this to include reasoning tokens (for reasoning models)
-- --reasoning_effort = "medium", -- low|medium|high, only used for reasoning models
-- },
-- vendors = {
-- aihubmix_llama_versatile = {
-- __inherited_from = 'openai',
-- api_key_name = 'AIHUBMIX_API_KEY',
-- endpoint = 'https://aihubmix.com/v1',
-- model = 'llama-3.3-70b-versatile',
-- },
-- },
-- },
-- -- if you want to build from source then do `make BUILD_FROM_SOURCE=true`
-- build = 'make',
-- -- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows
-- dependencies = {
-- 'nvim-treesitter/nvim-treesitter',
-- 'stevearc/dressing.nvim',
-- 'nvim-lua/plenary.nvim',
-- 'MunifTanjim/nui.nvim',
-- --- The below dependencies are optional,
-- 'echasnovski/mini.pick', -- for file_selector provider mini.pick
-- 'nvim-telescope/telescope.nvim', -- for file_selector provider telescope
-- 'hrsh7th/nvim-cmp', -- autocompletion for avante commands and mentions
-- 'ibhagwan/fzf-lua', -- for file_selector provider fzf
-- 'nvim-tree/nvim-web-devicons', -- or echasnovski/mini.icons
-- 'zbirenbaum/copilot.lua', -- for providers='copilot'
-- {
-- -- support for image pasting
-- 'HakonHarnes/img-clip.nvim',
-- event = 'VeryLazy',
-- opts = {
-- -- recommended settings
-- default = {
-- embed_image_as_base64 = false,
-- prompt_for_file_name = false,
-- drag_and_drop = {
-- insert_mode = true,
-- },
-- -- required for Windows users
-- use_absolute_path = true,
-- },
-- },
-- },
-- {
-- -- Make sure to set this up properly if you have lazy=true
-- 'MeanderingProgrammer/render-markdown.nvim',
-- opts = {
-- file_types = { 'markdown', 'Avante' },
-- },
-- ft = { 'markdown', 'Avante' },
-- },
-- },
-- }

View File

@@ -4,10 +4,7 @@ return {
event = 'VimEnter', event = 'VimEnter',
version = '1.*', version = '1.*',
dependencies = { dependencies = {
-- Compatibility for Avante with Blink (it typically only works with cmp) -- 'L3MON4D3/LuaSnip',
-- 'Kaiser-Yang/blink-cmp-avante',
-- Snippet Engine
'L3MON4D3/LuaSnip',
'folke/lazydev.nvim', 'folke/lazydev.nvim',
}, },
--- @module 'blink.cmp' --- @module 'blink.cmp'
@@ -36,6 +33,7 @@ return {
-- --
-- See :h blink-cmp-config-keymap for defining your own keymap -- See :h blink-cmp-config-keymap for defining your own keymap
preset = 'enter', preset = 'enter',
['<C-K>'] = false,
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
@@ -50,11 +48,11 @@ return {
completion = { completion = {
-- By default, you may press `<c-space>` to show the documentation. -- By default, you may press `<c-space>` to show the documentation.
-- Optionally, set `auto_show = true` to show the documentation after a delay. -- Optionally, set `auto_show = true` to show the documentation after a delay.
documentation = { auto_show = true, auto_show_delay_ms = 500 }, documentation = { auto_show = true, auto_show_delay_ms = 200 },
}, },
sources = { sources = {
default = { 'codecompanion', 'lsp', 'path', 'snippets', 'lazydev' }, default = { 'lsp', 'path', 'snippets', 'lazydev' },
providers = { providers = {
lazydev = { module = 'lazydev.integrations.blink', score_offset = 100 }, lazydev = { module = 'lazydev.integrations.blink', score_offset = 100 },
-- avante = { module = 'blink-cmp-avante', name = 'Avante', opts = {} }, -- avante = { module = 'blink-cmp-avante', name = 'Avante', opts = {} },
@@ -64,7 +62,7 @@ return {
}, },
}, },
snippets = { preset = 'luasnip' }, -- snippets = { preset = 'luasnip' },
-- Blink.cmp includes an optional, recommended rust fuzzy matcher, -- Blink.cmp includes an optional, recommended rust fuzzy matcher,
-- which automatically downloads a prebuilt binary when enabled. -- which automatically downloads a prebuilt binary when enabled.

View File

@@ -1,86 +1,339 @@
require('helpers').edit_cf('pa', '/lua/plugins/codecompanion.lua')
return { return {
'olimorris/codecompanion.nvim', 'olimorris/codecompanion.nvim',
opts = function(_, opts) config = function()
opts.adapters = { require('codecompanion').setup {
gpt = function() adapters = {
http = {
default = function()
if (require('helpers').has_copilot()) then
return require('codecompanion.adapters').extend('copilot', { return require('codecompanion.adapters').extend('copilot', {
schema = { schema = {
model = { model = {
default = 'gpt-4o', default = vim.env.DEFAULT_AI_MODEL,
}, },
max_tokens = { max_tokens = {
default = 1000000, default = 1000000,
}, },
},
})
end,
flash = function()
return require('codecompanion.adapters').extend('copilot', {
schema = {
model = {
default = 'gemini-2.0-flash',
},
max_tokens = {
default = 1000000,
},
},
})
end,
gemini = function()
return require('codecompanion.adapters').extend('copilot', {
schema = {
model = {
default = 'gemini-2.5-pro',
},
max_tokens = {
default = 1000000,
},
},
})
end,
sonnet = function()
return require('codecompanion.adapters').extend('copilot', {
schema = {
model = {
default = 'claude-3.7-sonnet',
},
max_tokens = {
default = 1000000,
},
},
})
end,
} }
})
opts.display = { end
return require('codecompanion.adapters').extend('openai_compatible', {
env = {
url = vim.env.DEFAULT_OPENAI_API_BASE,
api_key = vim.env.DEFAULT_OPENAI_API_KEY,
chat_url = '/v1/chat/completions',
models_endpoint = '/v1/models',
},
schema = {
model = {
default = vim.env.DEFAULT_AI_MODEL,
},
max_tokens = {
default = 1000000,
},
},
})
end,
},
},
display = {
chat = { chat = {
show_settings = true, show_settings = true,
start_in_insert_mode = false,
}, },
} },
strategies = {
opts.strategies = {
chat = { chat = {
adapter = 'gemini', adapter = 'default',
slash_commands = { slash_commands = {
codebase = require('vectorcode.integrations').codecompanion.chat.make_slash_command(), -- codebase = require('vectorcode.integrations').codecompanion.chat.make_slash_command(),
}, },
tools = { tools = {
vectorcode = { -- vectorcode = {
description = 'Run VectorCode to retrieve the project context.', -- description = 'Run VectorCode to retrieve the project context.',
callback = require('vectorcode.integrations').codecompanion.chat.make_tool(), -- callback = require('vectorcode.integrations').codecompanion.chat.make_tool(),
-- },
['cmd_runner'] = {
opts = {
requires_approval = false,
},
},
},
roles = {
---@type string|fun(adapter: CodeCompanion.Adapter): string
llm = function(adapter)
return 'CodeCompanion (' .. adapter.formatted_name .. ': ' .. adapter.parameters.model .. ')'
end,
},
keymaps = {
send = {
modes = { n = '<C-s>', i = '<C-s>' },
},
close = {
modes = { n = '<C-c>', i = '<C-c>' },
}, },
}, },
}, },
inline = { inline = {
adapter = 'flash', adapter = {
name = 'default',
model = vim.env.FAST_MODEL,
},
},
cmd = {
adapter = {
name = 'default',
model = vim.env.FAST_MODEL,
},
},
},
extensions = {
mcphub = {
callback = 'mcphub.extensions.codecompanion',
opts = {
show_result_in_chat = true,
make_vars = true,
make_slash_commands = true,
},
},
},
system_prompt = function(opts)
local language = opts.language or 'English'
return string.format(
[[You are an AI programming assistant named "CodeCompanion". You are currently plugged into the Neovim text editor on a user's machine.
Your core tasks include:
- Answering general programming questions.
- Explaining how the code in a Neovim buffer works.
- Reviewing the selected code from a Neovim buffer.
- Generating unit tests for the selected code.
- Proposing fixes for problems in the selected code.
- Scaffolding code for a new workspace.
- Finding relevant code to the user's query.
- Proposing fixes for test failures.
- Answering questions about Neovim.
- Running tools.
You must:
- Follow the user's requirements carefully and to the letter.
- Keep your answers short and impersonal, especially if the user's context is outside your core tasks.
- Minimize additional prose unless clarification is needed.
- Use Markdown formatting in your answers.
- Include the programming language name at the start of each Markdown code block.
- Avoid including line numbers in code blocks.
- Avoid wrapping the whole response in triple backticks.
- Only return code that's directly relevant to the task at hand. You may omit code that isnt necessary for the solution.
- Avoid using H1, H2 or H3 headers in your responses as these are reserved for the user.
- Use actual line breaks in your responses; only use "\n" when you want a literal backslash followed by 'n'.
- All non-code text responses must be written in the %s language indicated.
- Multiple, different tools can be called as part of the same response.
- Use full path names when using tools to read and modify files.
When given a task:
1. Think step-by-step and, unless the user requests otherwise or the task is very simple, describe your plan in detailed pseudocode.
2. Output the final code in a single code block, ensuring that only relevant code is included.
3. End your response with a short suggestion for the next user turn that directly supports continuing the conversation.
4. Provide exactly one complete reply per conversation turn.
5. If necessary, execute multiple tools in a single turn.]],
language
)
end,
prompt_library = {
['Code Expert'] = {
strategy = 'chat',
description = 'Get some special advice from an LLM.',
opts = {
mapping = '<Leader>ce',
modes = { 'v' },
short_name = 'expert',
auto_submit = true,
stop_context_insertion = true,
user_prompt = true,
},
prompts = {
{
role = 'system',
content = function(context)
return 'I want you to act as a senior'
.. context.filetype
.. 'developer I will ask you specific questions and I want you to return concise explanations and codeblock examples.'
end,
},
{
role = 'user',
content = function(context)
local text = require('codecompanion.helpers.actions').get_code(context.start_line, context.end_line)
return 'I have the following code:\n\n```' .. context.filetype .. '\n' .. text .. '\n```\n\n'
end,
opts = {
contains_code = true,
},
},
},
},
['Games Master'] = {
strategy = 'chat',
description = 'A personal Games Master Assistant.',
opts = {
user_prompt = false,
},
prompts = {
{
role = 'system',
content = [[
You are a personal Games Master Assistant. You are currently plugged in to the Neovim text editor on a user's machine.
Your core tasks include:
- Crafting engaging role playing sessions
- Building immersive and authentic worlds
- Creating compelling characters for the players to interact with and drive the story
- Reviewing session summaries and building on them
- Providing advice on how to bring sessions to life
- Create exciting encounters to challenge the players
- Encounters can be combat, social, or exploration based
- There should always be a story reason for the encounter
- Combine player character backgrounds and motivations into the world
- Build tension and drama into the game
- Ensure each session provides opportunities for the players to engage with and drive the story
You must:
- Follow the user's requirements carefully and to the letter.
- Keep answers focused on the task at hand.
- Provide original ideas and suggestions.
- Use Markdown formatting in your answers.
- Use actual line breaks instead of '\n' in your response to begin new lines.
- Use '\n' only when you want a literal backslash followed by a character 'n'.
- All responses must be written in English.
- Multiple, different tools can be called as part of the same response.
- Help sessions be fast paced and fun.
- Ensure there are multiple soltuions to each problem.
- Avoid railroading the players.
When given a task:
1. Consider the existing world and characters. Use tools to gather information that may be relevant.
2. Provide exactly one complete reply per conversation turn.
3. If necessary, execute multiple tools in a single turn.
]],
},
{
role = 'user',
content = '',
},
},
},
['PHPStan Fixer'] = {
strategy = 'workflow',
description = 'Use a workflow to fix PHPStan errors until there are none left.',
opts = {
short_name = 'phpstan',
},
prompts = {
{
{
name = 'Run PHPStan',
role = 'user',
opts = { auto_submit = false },
content = function()
-- Enable turbo mode!!!
vim.g.codecompanion_auto_tool_mode = true
return [[PHPStan is a static analysis tool for PHP. It is currently reporting errors in the code. Your task is to fix these errors and run PHPStan again until there are no errors left.
First of all use the @cmd_runner tool to run the `composer type-check` command. This will run PHPStan and output type errors in the code.]]
end,
},
},
{
{
name = 'Fetch files',
role = 'user',
opts = { auto_submit = false },
content = function()
-- Enable turbo mode!!!
vim.g.codecompanion_auto_tool_mode = true
return 'PHPStan has reported errors. Look at the output and see where the files are reported. Use the @mcp tool to read all the offending files so you can implement the fixes.'
end,
},
},
{
{
name = 'Fix errors and run',
role = 'user',
opts = { auto_submit = false },
content = function()
-- Enable turbo mode!!!
vim.g.codecompanion_auto_tool_mode = true
return [[### Instructions
Now you have the errors and the appropriate context you can fix the errors.
### Steps to Follow
You are required to analyse the PHPStan errors and write code to fix them.
Reason through the errors and write out the possible causes and fixes for each.
1. Then use the @mcp tool to update the files with the fixes. When editing files use the full path name including the project name /Users/chris/Code/Sites/hylark/
2. After editing the files use the @cmd_runner tool again to run the `composer type-check` command to see if any errors remain.
We'll repeat this cycle until there are no errors. Ensure no deviations from these steps.
### Tips for fixing PHPStan errors
- Do not ignore the errors
- Use Webmozart Assert library to narrow types
- Most errors are due to missing docblocks or calling methods/parameters on types that PHPStan cannot infer
- Use fully qualified namespaces for classes in doc blocks
- The code is working so fixes should not change the behaviour of the code
- There are some custom types in this project that help define types
- closure<T> creates T|Closure(): T, you can add a second argument to specify the depth so closure<T, 2> creates T|Closure(): T|Closure(): (Closure(): T). This is useful because GraphQL queries can return closures.
- promise<T> creates T|SyncPromise<T>, as with closure, you can add a second argument for depth. You can also add a third argument if T is an array to allow adding promises to each value, so promise<array{a: int}, 1, 1> will create array{a: int}|SyncPromise<array{a: int}>|array{a: SyncPromise<int>}|SyncPromise<array{a: SyncPromise<int>}>. This is useful because GraphQL queries can return promises and arrays of promises.
- GraphQL schema types (these should only be used in the Query classes)
- GArgs<T> will look at the GraphQL schema and create an array type for the arguments of a field on one of the root types (Query or Mutation)
- GArgs<TType, TField> will create a type for the arguments of a field on a type
- GType<T> will create an type for a specific GraphQL type, input, interface, or enum
- GVal<T> will create a type for the return value of a field on one of the root types (Query or Mutation)
- GVal<TType, TField> will create a type for the return value of a field on a type
- pick<T, TKeys> will create an array from T with only the keys in TKeys (e.g. pick<array{a: int, b: int, c: int}, 'a'|'b'> will create array{a: int, b: int})
- except<T, TKeys> works like pick only it excludes the keys in TKeys (e.g. except<array{a: int, b: int, c: int}, 'a'|'b'> will create array{c: int})
- union<T, U> creates a union array of T and U (e.g. union<array{a: int}, array{b: int}> will create array{a: int, b: int})]]
end,
},
},
{
{
name = 'Repeat On Failure',
role = 'user',
opts = { auto_submit = false },
-- Scope this prompt to the cmd_runner tool
condition = function()
return _G.codecompanion_current_tool == 'cmd_runner'
end,
-- Repeat until the tests pass, as indicated by the testing flag
-- which the cmd_runner tool sets on the chat buffer
repeat_until = function(chat)
-- Check if the last message in the chat buffer contains "[ERROR] found"
local messages = chat.messages
local last_message = messages[#messages]
if last_message and last_message.role == 'assistant' then
local content = last_message.content
return not content:find '[ERROR] found'
end
return true
end,
content = 'PHPStan is still reporting errors. Edit the code to fix the errors and run PHPStan again.',
},
},
},
},
}, },
} }
end, end,
dependencies = { dependencies = {
'nvim-lua/plenary.nvim', 'nvim-lua/plenary.nvim',
'nvim-treesitter/nvim-treesitter', 'nvim-treesitter/nvim-treesitter',
'Davidyz/VectorCode', -- 'Davidyz/VectorCode',
'ravitemer/mcphub.nvim',
}, },
} }

View File

@@ -12,13 +12,14 @@ return { -- Autoformat
desc = '[F]ormat buffer', desc = '[F]ormat buffer',
}, },
}, },
opts = { config = function()
require('conform').setup({
notify_on_error = false, notify_on_error = false,
format_on_save = function(bufnr) format_on_save = function(bufnr)
-- Disable "format_on_save lsp_fallback" for languages that don't -- Disable "format_on_save lsp_fallback" for languages that don't
-- have a well standardized coding style. You can add additional -- have a well standardized coding style. You can add additional
-- languages here or re-enable it for the disabled ones. -- languages here or re-enable it for the disabled ones.
local disable_filetypes = { c = true, cpp = true } local disable_filetypes = { c = true, cpp = true, vue = true, js = true }
if disable_filetypes[vim.bo[bufnr].filetype] then if disable_filetypes[vim.bo[bufnr].filetype] then
return nil return nil
else else
@@ -30,11 +31,14 @@ return { -- Autoformat
end, end,
formatters_by_ft = { formatters_by_ft = {
lua = { 'stylua' }, lua = { 'stylua' },
php = { 'pint' },
-- Conform can also run multiple formatters sequentially -- Conform can also run multiple formatters sequentially
-- python = { "isort", "black" }, -- python = { "isort", "black" },
-- --
-- You can use 'stop_after_first' to run the first available formatter from the list -- You can use 'stop_after_first' to run the first available formatter from the list
-- javascript = { "prettierd", "prettier", stop_after_first = true }, -- javascript = { "prettierd", "prettier", stop_after_first = true },
}, },
}, log_level = vim.log.levels.DEBUG
})
end
} }

View File

@@ -1,3 +0,0 @@
return {
'github/copilot.vim',
}

View File

@@ -73,7 +73,7 @@ return {
function() function()
require('dapui').toggle() require('dapui').toggle()
end, end,
desc = 'Debug: See last session result.', desc = 'Debug: Toggle UI',
}, },
}, },
config = function() config = function()
@@ -87,7 +87,28 @@ return {
-- You can provide additional configuration to the handlers, -- You can provide additional configuration to the handlers,
-- see mason-nvim-dap README for more information -- see mason-nvim-dap README for more information
handlers = {}, handlers = {
function(config)
require('mason-nvim-dap').default_setup(config)
end,
php = function(config)
config.configurations = {
{
type = 'php',
request = 'launch',
name = 'Listen for XDebug',
port = 9003,
log = true,
-- pathMappings = {
-- ['/var/www/html/'] = vim.fn.getcwd() .. '/',
-- },
hostname = '0.0.0.0',
},
}
require('mason-nvim-dap').default_setup(config)
end,
},
-- You'll need to check that you have the required things installed -- You'll need to check that you have the required things installed
-- online, please don't ask me how to install them :) -- online, please don't ask me how to install them :)
@@ -100,7 +121,9 @@ return {
dap.adapters.php = { dap.adapters.php = {
type = 'executable', type = 'executable',
command = 'node', command = 'node',
args = { '/Users/chris/.local/src/vscode-php-debug/out/phpDebug.js' }, args = {
vim.fn.expand '$MASON/packages/php-debug-adapter/extension/out/phpDebug.js',
},
} }
dap.configurations.php = { dap.configurations.php = {
@@ -110,9 +133,9 @@ return {
name = 'Listen for XDebug', name = 'Listen for XDebug',
port = 9003, port = 9003,
log = true, log = true,
pathMappings = { -- pathMappings = {
['/var/www/html/'] = vim.fn.getcwd() .. '/', -- ['/var/www/html/'] = vim.fn.getcwd() .. '/',
}, -- },
hostname = '0.0.0.0', hostname = '0.0.0.0',
}, },
} }
@@ -126,29 +149,73 @@ return {
icons = { expanded = '', collapsed = '', current_frame = '*' }, icons = { expanded = '', collapsed = '', current_frame = '*' },
controls = { controls = {
icons = { icons = {
pause = '', pause = '',
play = '', play = '',
step_into = '', step_into = '󰆹',
step_over = '', step_over = '󰆷',
step_out = '', step_out = '󰆸',
step_back = 'b', step_back = '',
run_last = '▶▶', run_last = '',
terminate = '', terminate = '',
disconnect = '', disconnect = '',
},
},
element_mappings = {
stacks = {
open = '<CR>',
expand = 'o',
}, },
}, },
} }
-- Change breakpoint icons -- Change breakpoint icons
-- vim.api.nvim_set_hl(0, 'DapBreak', { fg = '#e51400' }) vim.api.nvim_set_hl(0, 'DapBreak', { fg = '#e51400' })
-- vim.api.nvim_set_hl(0, 'DapStop', { fg = '#ffcc00' }) vim.api.nvim_set_hl(0, 'DapStop', { fg = '#ffcc00' })
-- local breakpoint_icons = vim.g.have_nerd_font local breakpoint_icons = vim.g.have_nerd_font
-- and { Breakpoint = '', BreakpointCondition = '', BreakpointRejected = '', LogPoint = '', Stopped = '' } and { Breakpoint = '', BreakpointCondition = '', BreakpointRejected = '', LogPoint = '', Stopped = '' }
-- or { Breakpoint = '●', BreakpointCondition = '⊜', BreakpointRejected = '⊘', LogPoint = '◆', Stopped = '⭔' } or { Breakpoint = '', BreakpointCondition = '', BreakpointRejected = '', LogPoint = '', Stopped = '' }
-- for type, icon in pairs(breakpoint_icons) do for type, icon in pairs(breakpoint_icons) do
-- local tp = 'Dap' .. type local tp = 'Dap' .. type
-- local hl = (type == 'Stopped') and 'DapStop' or 'DapBreak' local hl = (type == 'Stopped') and 'DapStop' or 'DapBreak'
-- vim.fn.sign_define(tp, { text = icon, texthl = hl, numhl = hl }) vim.fn.sign_define(tp, { text = icon, texthl = hl, numhl = hl })
end
local function get_php_ini_dir()
local handle = io.popen 'php --ini 2>/dev/null'
if not handle then
return nil
end
local result = handle:read '*a'
handle:close()
local dir = result:match 'Scan for additional .ini files in:%s+([^\n]+)'
if dir and dir:find '%(none%)' == nil then
return vim.trim(dir)
end
return nil
end
local function enable_xdebug()
local ini_dir = get_php_ini_dir()
if not ini_dir then
return
end
os.execute(string.format('mv "%s/20-xdebug.ini.disabled" "%s/20-xdebug.ini" 2>/dev/null', ini_dir, ini_dir))
end
local function disable_xdebug()
local ini_dir = get_php_ini_dir()
if not ini_dir then
return
end
os.execute(string.format('mv "%s/20-xdebug.ini" "%s/20-xdebug.ini.disabled" 2>/dev/null', ini_dir, ini_dir))
end
dap.listeners.after.event_initialized['xdebug_enable'] = enable_xdebug
dap.listeners.before.event_terminated['xdebug_disable'] = disable_xdebug
dap.listeners.before.event_exited['xdebug_disable'] = disable_xdebug
-- dap.listeners.after.event_output['neotest_display'] = function(_, body)
-- require('neotest').output.open { enter = true, last = true }
-- end -- end
dap.listeners.after.event_initialized['dapui_config'] = dapui.open dap.listeners.after.event_initialized['dapui_config'] = dapui.open

View File

@@ -4,9 +4,10 @@ return {
event = { 'BufReadPre', 'BufNewFile' }, event = { 'BufReadPre', 'BufNewFile' },
config = function() config = function()
local lint = require 'lint' local lint = require 'lint'
lint.linters_by_ft = { -- lint.linters_by_ft = {
markdown = { 'markdownlint' }, -- markdown = { 'markdownlint' },
} -- }
lint.linters_by_ft['markdown'] = nil
lint.linters_by_ft['javascript'] = nil lint.linters_by_ft['javascript'] = nil
lint.linters_by_ft['vue'] = nil lint.linters_by_ft['vue'] = nil
lint.linters_by_ft['html'] = nil lint.linters_by_ft['html'] = nil

View File

@@ -4,98 +4,38 @@ require('helpers').edit_cf('pl', '/lua/plugins/lsp.lua')
return { return {
'neovim/nvim-lspconfig', 'neovim/nvim-lspconfig',
dependencies = { dependencies = {
-- Automatically install LSPs and related tools to stdpath for Neovim
-- Mason must be loaded before its dependents so we need to set it up here.
-- NOTE: `opts = {}` is the same as calling `require('mason').setup({})`
{ 'williamboman/mason.nvim', opts = {} }, { 'williamboman/mason.nvim', opts = {} },
'williamboman/mason-lspconfig.nvim', 'williamboman/mason-lspconfig.nvim',
'WhoIsSethDaniel/mason-tool-installer.nvim', 'WhoIsSethDaniel/mason-tool-installer.nvim',
-- Useful status updates for LSP.
{ 'j-hui/fidget.nvim', opts = {} }, { 'j-hui/fidget.nvim', opts = {} },
-- Allows extra capabilities provided by blink.cmp
'saghen/blink.cmp', 'saghen/blink.cmp',
'folke/lazydev.nvim', 'folke/lazydev.nvim',
}, },
build = function()
vim.fn.system 'composer global require jetbrains/phpstorm-stubs friendsofphp/php-cs-fixer'
end,
config = function() config = function()
-- Brief aside: **What is LSP?**
--
-- LSP is an initialism you've probably heard, but might not understand what it is.
--
-- LSP stands for Language Server Protocol. It's a protocol that helps editors
-- and language tooling communicate in a standardized fashion.
--
-- In general, you have a "server" which is some tool built to understand a particular
-- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers
-- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone
-- processes that communicate with some "client" - in this case, Neovim!
--
-- LSP provides Neovim with features like:
-- - Go to definition
-- - Find references
-- - Autocompletion
-- - Symbol Search
-- - and more!
--
-- Thus, Language Servers are external tools that must be installed separately from
-- Neovim. This is where `mason` and related plugins come into play.
--
-- If you're wondering about lsp vs treesitter, you can check out the wonderfully
-- and elegantly composed help section, `:help lsp-vs-treesitter`
-- This function gets run when an LSP attaches to a particular buffer. -- This function gets run when an LSP attaches to a particular buffer.
-- That is to say, every time a new file is opened that is associated with -- That is to say, every time a new file is opened that is associated with
-- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this
-- function will be executed to configure the current buffer -- function will be executed to configure the current buffer
vim.api.nvim_create_autocmd('LspAttach', { vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), group = vim.api.nvim_create_augroup('lsp-attach', { clear = true }),
callback = function(event) callback = function(event)
-- NOTE: Remember that Lua is a real programming language, and as such it is possible
-- to define small helper and utility functions so you don't have to repeat yourself.
--
-- In this case, we create a function that lets us more easily define mappings specific
-- for LSP related items. It sets the mode, buffer and description for us each time.
local map = function(keys, func, desc, mode) local map = function(keys, func, desc, mode)
mode = mode or 'n' require('helpers').map(keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }, mode)
vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc })
end end
-- Rename the variable under your cursor.
-- Most Language Servers support renaming across files, etc.
map('grn', vim.lsp.buf.rename, '[R]e[n]ame') map('grn', vim.lsp.buf.rename, '[R]e[n]ame')
-- Execute a code action, usually your cursor needs to be on top of an error
-- or a suggestion from your LSP for this to activate.
map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' }) map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' })
-- Find references for the word under your cursor.
map('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') map('grr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
-- Jump to the implementation of the word under your cursor.
-- Useful when your language has ways of declaring types without an actual implementation.
map('gri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') map('gri', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation')
-- Jump to the definition of the word under your cursor.
-- This is where a variable was first declared, or where a function is defined, etc.
-- To jump back, press <C-t>.
map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') map('grd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition')
-- WARN: This is not Goto Definition, this is Goto Declaration.
-- For example, in C this would take you to the header.
map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
-- Fuzzy find all the symbols in your current document.
-- Symbols are things like variables, functions, types, etc.
map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols') map('gO', require('telescope.builtin').lsp_document_symbols, 'Open Document Symbols')
-- Fuzzy find all the symbols in your current workspace.
-- Similar to document symbols, except searches over your entire project.
map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols') map('gW', require('telescope.builtin').lsp_dynamic_workspace_symbols, 'Open Workspace Symbols')
-- Jump to the type of the word under your cursor.
-- Useful when you're not sure what type a variable is and you want to see
-- the definition of its *type*, not where it was *defined*.
map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition') map('grt', require('telescope.builtin').lsp_type_definitions, '[G]oto [T]ype Definition')
-- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10) -- This function resolves a difference between neovim nightly (version 0.11) and stable (version 0.10)
@@ -118,7 +58,7 @@ return {
-- When you move your cursor, the highlights will be cleared (the second autocommand). -- When you move your cursor, the highlights will be cleared (the second autocommand).
local client = vim.lsp.get_client_by_id(event.data.client_id) local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_documentHighlight, event.buf) then
local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) local highlight_augroup = vim.api.nvim_create_augroup('lsp-highlight', { clear = false })
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
buffer = event.buf, buffer = event.buf,
group = highlight_augroup, group = highlight_augroup,
@@ -132,18 +72,14 @@ return {
}) })
vim.api.nvim_create_autocmd('LspDetach', { vim.api.nvim_create_autocmd('LspDetach', {
group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }), group = vim.api.nvim_create_augroup('lsp-detach', { clear = true }),
callback = function(event2) callback = function(event2)
vim.lsp.buf.clear_references() vim.lsp.buf.clear_references()
vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf } vim.api.nvim_clear_autocmds { group = 'lsp-highlight', buffer = event2.buf }
end, end,
}) })
end end
-- The following code creates a keymap to toggle inlay hints in your
-- code, if the language server you are using supports them
--
-- This may be unwanted, since they displace some of your code
if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then if client and client_supports_method(client, vim.lsp.protocol.Methods.textDocument_inlayHint, event.buf) then
map('<leader>th', function() map('<leader>th', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf }) vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf })
@@ -152,8 +88,6 @@ return {
end, end,
}) })
-- Diagnostic Config
-- See :help vim.diagnostic.Opts
vim.diagnostic.config { vim.diagnostic.config {
severity_sort = true, severity_sort = true,
float = { border = 'rounded', source = 'if_many' }, float = { border = 'rounded', source = 'if_many' },
@@ -181,14 +115,7 @@ return {
}, },
} }
-- LSP servers and clients are able to communicate to each other what features they support.
-- By default, Neovim doesn't support everything that is in the LSP specification.
-- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities.
-- So, we create new capabilities with blink.cmp, and then broadcast that to the servers.
local capabilities = require('blink.cmp').get_lsp_capabilities()
-- Enable the following language servers -- Enable the following language servers
-- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
-- --
-- Add any additional override configuration in the following tables. Available keys are: -- Add any additional override configuration in the following tables. Available keys are:
-- - cmd (table): Override the default command used to start the server -- - cmd (table): Override the default command used to start the server
@@ -198,93 +125,92 @@ return {
-- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/
local mason_registry = require 'mason-registry' local mason_registry = require 'mason-registry'
local vue_language_server_path = mason_registry.get_package('vue-language-server'):get_install_path() .. '/node_modules/@vue/language-server' local vue_language_server_path = vim.fn.expand '$MASON/packages/vue-language-server/node_modules/@vue/language-server'
local servers = { local servers = {
-- clangd = {}, clangd = {},
-- gopls = {}, pyright = {},
-- pyright = {}, rust_analyzer = {},
-- rust_analyzer = {},
-- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
--
-- Some languages (like typescript) have entire language plugins that can be useful:
-- https://github.com/pmizio/typescript-tools.nvim
--
-- But for many setups, the LSP (`ts_ls`) will work just fine
-- ts_ls = {},
--
lua_ls = { lua_ls = {
-- cmd = { ... },
-- filetypes = { ... },
-- capabilities = {},
settings = { settings = {
Lua = { Lua = {
completion = { completion = {
callSnippet = 'Replace', callSnippet = 'Replace',
}, },
-- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings
-- diagnostics = { disable = { 'missing-fields' } },
}, },
}, },
}, },
ts_ls = { phpactor = {},
init_options = { vtsls = {
plugins = { settings = {
vtsls = {
tsserver = {
globalPlugins = {
{ {
name = '@vue/typescript-plugin', name = '@vue/typescript-plugin',
location = vue_language_server_path, location = vue_language_server_path,
languages = { 'vue' }, languages = { 'vue' },
configNamespace = 'typescript',
},
},
},
},
javascript = {
preferences = {
importModuleSpecifierPreference = 'non-relative',
importModuleSpecifierEnding = 'js',
}, },
}, },
}, },
filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue' }, filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue' },
}, },
['vue-language-server'] = {
on_init = function(client)
client.handlers['tsserver/request'] = function(_, result, context)
local clients = vim.lsp.get_clients { bufnr = context.bufnr, name = 'vtsls' }
if #clients == 0 then
vim.notify('Could not find `vtsls` lsp client, `vue-language-server` would not work without it.', vim.log.levels.ERROR)
return
end
local ts_client = clients[1]
volar = { local param = unpack(result)
on_attach = function(client, bufnr) local id, command, payload = unpack(param)
client.server_capabilities.documentFormattingProvider = false ts_client:exec_cmd({
end, title = 'vue_request_forward', -- You can give title anything as it's used to represent a command in the UI, `:h Client:exec_cmd`
command = 'typescript.tsserverRequest',
arguments = {
command,
payload,
}, },
}, { bufnr = context.bufnr }, function(_, r)
phpactor = { local response_data = { { id, r.body } }
on_attach = function(client, bufnr) ---@diagnostic disable-next-line: param-type-mismatch
client.server_capabilities.documentFormattingProvider = false client:notify('tsserver/response', response_data)
end)
end
end, end,
}, },
} }
-- Ensure the servers and tools above are installed
--
-- To check the current status of installed tools and/or manually install
-- other tools, you can run
-- :Mason
--
-- You can press `g?` for help in this menu.
--
-- `mason` had to be setup earlier: to configure its options see the
-- `dependencies` table for `nvim-lspconfig` above.
--
-- You can add other tools here that you want Mason to install
-- for you, so that they are available from within Neovim.
local ensure_installed = vim.tbl_keys(servers or {}) local ensure_installed = vim.tbl_keys(servers or {})
vim.list_extend(ensure_installed, { vim.list_extend(ensure_installed, {
'stylua', -- Used to format Lua code 'stylua', -- Used to format Lua code
}) })
-- LSP servers and clients are able to communicate to each other what features they support.
-- By default, Neovim doesn't support everything that is in the LSP specification.
-- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities.
-- So, we create new capabilities with blink.cmp, and then broadcast that to the servers.
local capabilities = require('blink.cmp').get_lsp_capabilities()
for name, cfg in pairs(servers) do
cfg.capabilities = vim.tbl_deep_extend('force', {}, capabilities, cfg.capabilities or {})
vim.lsp.config(name, cfg) -- new Neovim 0.11 API
end
require('mason-tool-installer').setup { ensure_installed = ensure_installed } require('mason-tool-installer').setup { ensure_installed = ensure_installed }
require('mason-lspconfig').setup { require('mason').setup {}
ensure_installed = {}, -- explicitly set to an empty table (Kickstart populates installs via mason-tool-installer) require('mason-lspconfig').setup {}
automatic_installation = false,
handlers = {
function(server_name)
local server = servers[server_name] or {}
-- This handles overriding only values explicitly passed
-- by the server configuration above. Useful when disabling
-- certain features of an LSP (for example, turning off formatting for ts_ls)
server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {})
require('lspconfig')[server_name].setup(server)
end,
},
}
end, end,
} }

View File

@@ -25,16 +25,36 @@ return {
require('mini.pairs').setup() require('mini.pairs').setup()
-- require('mini.jump').setup() require('mini.jump').setup {
mappings = {
repeat_jump = ':',
},
}
require('mini.jump2d').setup() local MiniJump2d = require 'mini.jump2d'
MiniJump2d.setup {
spotter = MiniJump2d.gen_spotter.union(
MiniJump2d.gen_spotter.pattern('[([{][^$]', 'end'),
MiniJump2d.gen_spotter.pattern('%$.', 'end'),
MiniJump2d.gen_spotter.pattern('->.', 'end'),
MiniJump2d.gen_spotter.pattern('^%s*%S', 'end')
),
mappings = {
start_jumping = 'S',
},
allowed_lines = {
blank = false,
cursor_at = false,
fold = false,
},
}
require('mini.splitjoin').setup() require('mini.splitjoin').setup()
require('mini.map').setup() require('mini.map').setup()
-- Simple and easy statusline. -- Simple and easy statusline.
-- You could remove this setup call if you don't like it, -- You could remove this setup call i you don't like it,
-- and try some other statusline plugin -- and try some other statusline plugin
local statusline = require 'mini.statusline' local statusline = require 'mini.statusline'
-- set use_icons to true if you have a Nerd Font -- set use_icons to true if you have a Nerd Font

View File

@@ -1,39 +0,0 @@
-- Neo-tree is a Neovim plugin to browse the file system
-- https://github.com/nvim-neo-tree/neo-tree.nvim
return {
'nvim-neo-tree/neo-tree.nvim',
version = '*',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-tree/nvim-web-devicons', -- not strictly required, but recommended
'MunifTanjim/nui.nvim',
},
cmd = 'Neotree',
keys = {
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
},
opts = function(_, opts)
local function on_move(data)
Snacks.rename.on_rename_file(data.source, data.destination)
end
local events = require("neo-tree.events")
opts.event_handlers = opts.event_handlers or {}
vim.list_extend(opts.event_handlers, {
{ event = events.FILE_MOVED, handler = on_move },
{ event = events.FILE_RENAMED, handler = on_move },
})
opts.filesystem = {
window = {
mappings = {
['\\'] = 'close_window',
},
},
filtered_items = {
hide_dotfiles = false,
},
}
end,
}

View File

@@ -1,21 +0,0 @@
return {
"nvim-neotest/neotest",
lazy = true,
dependencies = {
"nvim-neotest/nvim-nio",
"nvim-lua/plenary.nvim",
"antoinemadec/FixCursorHold.nvim",
"nvim-treesitter/nvim-treesitter",
-- Adapters
'V13Axel/neotest-pest',
-- "olimorris/neotest-phpunit",
},
config = function()
require('neotest').setup({
adapters = {
require('neotest-pest'),
-- require('neotest-phpunit'),
}
})
end
}

View File

@@ -1,7 +1,7 @@
-- Filesystem manager -- Filesystem manager
require('helpers').edit_cf('po', '/lua/plugins/oil.lua') -- require('helpers').edit_cf('po', '/lua/plugins/oil.lua')
--
vim.keymap.set('n', '-', '<CMD>Oil<CR>', { desc = 'Open parent directory' }) -- vim.keymap.set('n', '-', '<CMD>Oil<CR>', { desc = 'Open parent directory' })
return { return {
'stevearc/oil.nvim', 'stevearc/oil.nvim',
@@ -13,6 +13,7 @@ return {
}, },
keymaps = { keymaps = {
['<C-p>'] = false, ['<C-p>'] = false,
['-'] = false,
}, },
}, },
-- Optional dependencies -- Optional dependencies

34
lua/plugins/quicker.lua Normal file
View File

@@ -0,0 +1,34 @@
vim.keymap.set("n", "<leader>q", function()
require("quicker").toggle()
end, { desc = "Toggle quickfix" })
vim.keymap.set("n", "<leader>l", function()
require("quicker").toggle({ loclist = true })
end, { desc = "Toggle loclist" })
return {
'stevearc/quicker.nvim',
ft = 'qf',
---@module "quicker"
---@type quicker.SetupOptions
opts = {},
config = function()
require('quicker').setup({
keys = {
{
">",
function()
require("quicker").expand({ before = 2, after = 2, add_to_existing = true })
end,
desc = "Expand quickfix context",
},
{
"<",
function()
require("quicker").collapse()
end,
desc = "Collapse quickfix context",
},
},
})
end,
}

View File

@@ -8,7 +8,58 @@ return {
-- or leave it empty to use the default settings -- or leave it empty to use the default settings
-- refer to the configuration section below -- refer to the configuration section below
bigfile = { enabled = true }, bigfile = { enabled = true },
dashboard = { enabled = true }, dashboard = {
enabled = true,
preset = {
keys = {
{ icon = '', key = 'f', desc = 'Find File', action = ":lua Snacks.dashboard.pick('files')" },
{ icon = '', key = 'n', desc = 'New File', action = ':ene | startinsert' },
{ icon = '', key = 'g', desc = 'Find Text', action = ":lua Snacks.dashboard.pick('live_grep')" },
{ icon = '', key = 'r', desc = 'Recent Files', action = ":lua Snacks.dashboard.pick('oldfiles')" },
{ icon = '', key = 'c', desc = 'Config', action = ":lua Snacks.dashboard.pick('files', {cwd = vim.fn.stdpath('config')})" },
-- { icon = " ", key = "s", desc = "Restore Session", section = "session" },
{ icon = '󰒲 ', key = 'L', desc = 'Lazy', action = ':Lazy', enabled = package.loaded.lazy ~= nil },
{ icon = '', key = 'q', desc = 'Quit', action = ':qa' },
},
},
sections = {
{ section = 'header' },
{ section = 'keys', gap = 1, padding = 1 },
{
pane = 2,
icon = '',
title = 'Projects',
section = 'projects',
indent = 2,
padding = 1,
session = false,
dirs = function()
return {
vim.fn.expand '~/Code/Sites/runcats',
vim.fn.expand '~/Code/Sites/moovaza',
vim.fn.expand '~/Code/Sites/tuxtoolkit',
vim.fn.expand '~/Code/Sites/chrisstarling',
vim.fn.stdpath 'config',
}
end,
},
{ pane = 2, icon = '', title = 'Recent Files', section = 'recent_files', indent = 2, padding = 1 },
{
pane = 2,
icon = '',
title = 'Git Status',
section = 'terminal',
enabled = function()
return Snacks.git.get_root() ~= nil
end,
cmd = 'git status --short --branch --renames',
height = 5,
padding = 1,
ttl = 5 * 60,
indent = 3,
},
},
},
indent = { enabled = true }, indent = { enabled = true },
input = { enabled = true }, input = { enabled = true },
notifier = { enabled = true }, notifier = { enabled = true },

View File

@@ -11,21 +11,16 @@ return {
return 'make install_jsregexp' return 'make install_jsregexp'
end)(), end)(),
config = function() config = function()
local ls = require 'luasnip'
ls.filetype_extend('vue', { 'javascript' })
local snippets_dir = vim.fn.stdpath 'config' .. '/lua/snippets' local snippets_dir = vim.fn.stdpath 'config' .. '/lua/snippets'
require('luasnip.loaders.from_vscode').lazy_load { require('luasnip.loaders.from_lua').load {
paths = { snippets_dir }, paths = { snippets_dir },
} }
ls.setup {
update_events = 'TextChanged,TextChangedI',
enable_autosnippets = true,
}
end, end,
dependencies = {
-- `friendly-snippets` contains a variety of premade snippets.
-- See the README about individual language/framework/plugin snippets:
-- https://github.com/rafamadriz/friendly-snippets
{
'rafamadriz/friendly-snippets',
config = function()
require('luasnip.loaders.from_vscode').lazy_load()
end,
},
},
opts = {}, opts = {},
} }

6
lua/plugins/suda.lua Normal file
View File

@@ -0,0 +1,6 @@
return {
'lambdalisue/vim-suda',
config = function()
vim.g.suda_smart_edit = 1
end,
}

View File

@@ -73,6 +73,9 @@ return {
['<C-k>'] = 'move_selection_previous', ['<C-k>'] = 'move_selection_previous',
}, },
}, },
file_ignore_patterns = {
'.obsidian',
},
}, },
} }

View File

@@ -1,7 +1,7 @@
-- Highlight todo, notes, etc in comments -- Highlight todo, notes, etc in comments
return { return {
"folke/todo-comments.nvim", 'folke/todo-comments.nvim',
event = "VimEnter", event = 'VimEnter',
dependencies = { "nvim-lua/plenary.nvim" }, dependencies = { 'nvim-lua/plenary.nvim' },
opts = { signs = false }, opts = { signs = false },
} }

View File

@@ -0,0 +1,153 @@
-- Highlight, edit, and navigate code
return {
-- 'nvim-treesitter/nvim-treesitter-textobjects',
-- lazy = true,
-- branch = 'main',
-- dependencies = {
-- 'nvim-treesitter/nvim-treesitter',
-- },
-- config = function()
-- -- configuration
-- require('nvim-treesitter-textobjects').setup {
-- select = {
-- lookahead = true,
-- selection_modes = {
-- ['@parameter.outer'] = 'v', -- charwise
-- ['@function.outer'] = 'V', -- linewise
-- ['@class.outer'] = 'V', -- blockwise
-- },
-- include_surrounding_whitespace = false,
-- },
-- move = {
-- set_jumps = true,
-- },
-- }
-- for keys, query in
-- {
-- -- or you use the queries from supported languages with textobjects.scm
-- ['af'] = '@function.outer',
-- ['if'] = '@function.inner',
-- ['aC'] = '@class.outer',
-- ['iC'] = '@class.inner',
-- ['ay'] = '@conditional.outer',
-- ['iy'] = '@conditional.inner',
-- ['aj'] = '@loop.outer',
-- ['ij'] = '@loop.inner',
-- ['is'] = '@statement.inner',
-- ['as'] = '@statement.outer',
-- ['ac'] = '@comment.outer',
-- ['ic'] = '@comment.inner',
-- ['ap'] = '@comment.parameter',
-- ['ip'] = '@comment.parameter',
-- ['an'] = '@local.scope',
-- }
-- do
-- vim.keymap.set({ 'n', 'x', 'o' }, keys, function()
-- require('nvim-treesitter-textobjects.select').select_textobject(query, 'textobjects')
-- end)
-- end
-- for keys, query in
-- {
-- -- or you use the queries from supported languages with textobjects.scm
-- [']'] = '@function.outer',
-- ['o'] = { '@loop.inner', '@loop.outer' },
-- ['n'] = '@local.scope',
-- ['y'] = '@conditional.outer',
-- ['e'] = '@statement.outer',
-- ['/'] = '@comment.outer',
-- }
-- do
-- vim.keymap.set({ 'n', 'x', 'o' }, ']' .. keys, function()
-- require('nvim-treesitter-textobjects.move').goto_next_start(query, 'textobjects')
-- end)
-- vim.keymap.set({ 'n', 'x', 'o' }, '[' .. keys, function()
-- require('nvim-treesitter-textobjects.move').goto_previous_start(query, 'textobjects')
-- end)
-- end
-- -- require('nvim-treesitter.configs').setup {
-- -- incremental_selection = {
-- -- enable = true,
-- -- keymaps = {
-- -- -- mappings for incremental selection (visual mappings)
-- -- init_selection = '<C-S-D>', -- maps in normal mode to init the node/scope selection
-- -- node_incremental = '<C-S-D>', -- increment to the upper named parent
-- -- scope_incremental = '<C-S-U>', -- increment to the upper scope (as defined in locals.scm)
-- -- node_decremental = '<C-S-S>', -- decrement to the previous node
-- -- },
-- -- },
-- -- textobjects = {
-- -- -- syntax-aware textobjects
-- -- enable = true,
-- -- keymaps = {
-- -- ['iL'] = {
-- -- -- you can define your own textobjects directly here
-- -- go = '(function_definition) @function',
-- -- },
-- -- -- or you use the queries from supported languages with textobjects.scm
-- -- ['af'] = '@function.outer',
-- -- ['if'] = '@function.inner',
-- -- ['aC'] = '@class.outer',
-- -- ['iC'] = '@class.inner',
-- -- ['ay'] = '@conditional.outer',
-- -- ['iy'] = '@conditional.inner',
-- -- ['aj'] = '@loop.outer',
-- -- ['ij'] = '@loop.inner',
-- -- ['is'] = '@statement.inner',
-- -- ['as'] = '@statement.outer',
-- -- ['ac'] = '@comment.outer',
-- -- ['ic'] = '@comment.inner',
-- -- ['ap'] = '@comment.parameter',
-- -- ['ip'] = '@comment.parameter',
-- -- },
-- -- move = {
-- -- enable = true,
-- -- set_jumps = true, -- whether to set jumps in the jumplist
-- -- goto_next_start = {
-- -- [']m'] = '@function.outer',
-- -- [']]'] = '@class.outer',
-- -- },
-- -- goto_next_end = {
-- -- [']M'] = '@function.outer',
-- -- [']['] = '@class.outer',
-- -- },
-- -- goto_previous_start = {
-- -- ['[m'] = '@function.outer',
-- -- ['[['] = '@class.outer',
-- -- },
-- -- goto_previous_end = {
-- -- ['[M'] = '@function.outer',
-- -- ['[]'] = '@class.outer',
-- -- },
-- -- },
-- -- select = {
-- -- enable = true,
-- -- keymaps = {
-- -- -- You can use the capture groups defined in textobjects.scm
-- -- ['af'] = '@function.outer',
-- -- ['if'] = '@function.inner',
-- -- ['ac'] = '@class.outer',
-- -- ['ic'] = '@class.inner',
-- -- -- Or you can define your own textobjects like this
-- -- ['iF'] = {
-- -- python = '(function_definition) @function',
-- -- cpp = '(function_definition) @function',
-- -- c = '(function_definition) @function',
-- -- java = '(method_declaration) @function',
-- -- go = '(method_declaration) @function',
-- -- },
-- -- },
-- -- },
-- -- },
-- -- }
-- end,
-- opts = {},
-- -- There are additional nvim-treesitter modules that you can use to interact
-- -- with nvim-treesitter. You should go explore a few and see what interests you:
-- --
-- -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod`
-- -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context
-- -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects
}

View File

@@ -2,10 +2,11 @@
return { return {
'nvim-treesitter/nvim-treesitter', 'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate', build = ':TSUpdate',
main = 'nvim-treesitter.configs', -- Sets main module to use for opts branch = 'main',
-- [[ Configure Treesitter ]] See `:help nvim-treesitter` -- [[ Configure Treesitter ]] See `:help nvim-treesitter`
opts = { config = function()
ensure_installed = { require('nvim-treesitter').setup {}
require('nvim-treesitter').install {
'bash', 'bash',
'c', 'c',
'diff', 'diff',
@@ -17,18 +18,13 @@ return {
'query', 'query',
'vim', 'vim',
'vimdoc', 'vimdoc',
}, 'php',
-- Autoinstall languages that are not installed 'javascript',
auto_install = true, 'typescript',
highlight = { 'json',
enable = true, }
-- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. end,
-- If you are experiencing weird indenting issues, add the language to opts = {},
-- the list of additional_vim_regex_highlighting and disabled languages for indent.
additional_vim_regex_highlighting = { 'ruby' },
},
indent = { enable = true, disable = { 'ruby' } },
},
-- There are additional nvim-treesitter modules that you can use to interact -- There are additional nvim-treesitter modules that you can use to interact
-- with nvim-treesitter. You should go explore a few and see what interests you: -- with nvim-treesitter. You should go explore a few and see what interests you:
-- --

10
lua/plugins/treesj.lua Normal file
View File

@@ -0,0 +1,10 @@
return {
'Wansmer/treesj',
lazy = true,
dependencies = { 'nvim-treesitter/nvim-treesitter' }, -- if you install parsers with `nvim-treesitter`
config = function()
require('treesj').setup({
use_default_keymaps = false,
})
end,
}

View File

@@ -1,11 +0,0 @@
require('helpers').edit_cf('pv', '/lua/plugins/vectorcode.lua')
return {
'Davidyz/VectorCode',
version = '*', -- optional, depending on whether you're on nightly or release
dependencies = { 'nvim-lua/plenary.nvim' },
build = 'pipx upgrade vectorcode',
cmd = 'VectorCode', -- if you're lazy-loading VectorCode
opts = {
async_backend = 'lsp',
},
}

View File

@@ -1,8 +0,0 @@
if vim.loop.os_uname().sysname == 'Darwin' then
return {
'wakatime/vim-wakatime',
lazy = false,
}
else
return {}
end

32
lua/plugins/yazi.lua Normal file
View File

@@ -0,0 +1,32 @@
---@type LazySpec
return {
'mikavilpas/yazi.nvim',
version = '*', -- use the latest stable version
event = 'VeryLazy',
dependencies = {
{ 'nvim-lua/plenary.nvim', lazy = true },
},
keys = {
-- 👇 in this section, choose your own keymappings!
{
'-',
mode = { 'n', 'v' },
'<cmd>Yazi<cr>',
desc = 'Open yazi at the current file',
},
{
-- Open in the current working directory
'\\',
'<cmd>Yazi cwd<cr>',
desc = "Open the file manager in nvim's working directory",
},
},
---@type YaziConfig | {}
opts = {
-- if you want to open yazi instead of netrw, see below for more info
open_for_directories = false,
keymaps = {
show_help = '<f1>',
},
},
}

294
lua/projects.lua Normal file
View File

@@ -0,0 +1,294 @@
-- Project specific settings
local M = {}
-- Helper to create mappings
local helpers = require 'helpers'
local map = helpers.map
-- Get the last folder name from a path
local function project_name_from_cwd(cwd)
return vim.fn.fnamemodify(cwd, ':t')
end
local function command_with_dir(dir, cmd)
if dir then
return '!cd ' .. dir .. ' && ' .. cmd
end
return '!' .. cmd
end
local function make_laravel_file(dir, cmd)
local cwd = vim.fn.getcwd()
if dir then
vim.fn.chdir(dir)
end
vim.ui.input({ prompt = 'Make: ' .. cmd }, function(input)
if input == nil then
vim.fn.chdir(cwd)
return
end
local output = vim.system({ 'vendor/bin/sail', 'artisan', 'make:' .. cmd, input }):wait().stdout
local new_file = output:match '%[([%w%./]+)%]'
if new_file ~= nil then
vim.cmd('edit ' .. new_file)
end
vim.fn.chdir(cwd)
end)
end
local function get_scope_from_file(filename)
local ext = filename:match '%.(%w+)$'
local base_name = filename:match '^(%w+)%.?%w*$'
local extensionSuffixes = {
php = { 'Controller', 'Repository', 'StoreRequest', 'UpdateRequest', 'Request', 'Resource', 'Test', 'Observer', 'Policy', 'Seeder', 'Factory' },
['[jt]s'] = { 'Service' },
}
for suffix_type, _ in pairs(extensionSuffixes) do
if ext:match(suffix_type) then
local suffixes = extensionSuffixes[suffix_type]
for _, suffix in ipairs(suffixes) do
local scope = base_name:match('^(%w+)' .. suffix .. '$')
if scope then
return scope
end
end
end
end
return base_name
end
local function navigate_using_suffix(suffix)
local scope = get_scope_from_file(vim.fn.expand '%:t')
local file_name = scope .. suffix
local file_path = vim.system({ 'git', 'ls-files', file_name, '**/' .. file_name }):wait().stdout
if file_path ~= '' then
vim.cmd('edit ' .. file_path)
else
vim.notify('File ' .. file_name .. ' not found in git ls-files', vim.log.levels.ERROR)
end
end
local function create_navigation_maps(maps)
for key, suffix_and_name in pairs(maps) do
map('<Leader>n' .. key, function()
navigate_using_suffix(suffix_and_name[1])
end, { desc = 'Navigate to relevant ' .. suffix_and_name[2] })
end
end
local function create_bookmark(key, bookmark)
map('<Leader>b' .. key, function()
vim.cmd('edit ' .. bookmark)
end, { desc = 'Navigate to ' .. bookmark })
end
local function create_bookmark_maps(maps)
for key, bookmark in pairs(maps) do
create_bookmark(key, bookmark)
end
end
local function laravel_bookmarks_with_dir(dir)
create_bookmark_maps {
['e'] = dir .. '/.env',
['l'] = dir .. '/storage/logs/laravel.log',
['w'] = dir .. '/routes/web.php',
['a'] = dir .. '/routes/api.php',
['m'] = dir .. '/database/migrations',
['dc'] = dir .. '/app/Core/',
['dd'] = dir .. '/app/Data/',
['dE'] = dir .. '/app/Enums/',
['de'] = dir .. '/app/Events/',
['dh'] = dir .. '/app/Http/',
['dj'] = dir .. '/app/Jobs/',
['dl'] = dir .. '/app/Listeners/',
['dM'] = dir .. '/app/Mail/',
['dm'] = dir .. '/app/Models/',
['dn'] = dir .. '/app/Notifications/',
['do'] = dir .. '/app/Observers/',
['dp'] = dir .. '/app/Providers/',
['pa'] = dir .. '/app/Providers/AppServiceProvider.php',
['pe'] = dir .. '/app/Providers/EventServiceProvider.php',
['cA'] = dir .. '/config/app.php',
['ca'] = dir .. '/config/auth.php',
['cb'] = dir .. '/config/broadcasting.php',
['cd'] = dir .. '/config/database.php',
['cf'] = dir .. '/config/filesystems.php',
['ch'] = dir .. '/config/filesystems.php',
['cl'] = dir .. '/config/logging.php',
['cm'] = dir .. '/config/mail.php',
['cq'] = dir .. '/config/queue.php',
['cS'] = dir .. '/config/services.php',
['cs'] = dir .. '/config/session.php',
}
end
local function laravel_keymaps(dir)
map('sl ', command_with_dir(dir, 'vendor/bin/sail '), { desc = 'Run sail command' }, 'c')
map('art ', command_with_dir(dir, 'php artisan '), { desc = 'Run artisan command' }, 'c')
map('sart ', command_with_dir(dir, 'vendor/bin/sail artisan '), { desc = 'Run artisan command with sail' }, 'c')
map('cmp ', command_with_dir(dir, 'composer '), { desc = 'Run composer script' }, 'c')
map('<Leader>pm', ':' .. command_with_dir(dir, 'vendor/bin/sail artisan migrate<CR>'))
map('<Leader>pr', ':' .. command_with_dir(dir, 'vendor/bin/sail artisan migrate:rollback<CR>'))
map('<Leader>pM', ':' .. command_with_dir(dir, 'vendor/bin/sail artisan make:'))
create_navigation_maps {
['m'] = { '.php', 'model' },
['c'] = { 'Controller.php', 'controller' },
['p'] = { 'Policy.php', 'policy' },
['R'] = { 'Resource.php', 'resource' },
['r'] = { 'Request.php', 'request' },
['t'] = { 'Test.php', 'test file' },
}
if dir == nil then
dir = ''
end
laravel_bookmarks_with_dir(dir)
end
local function laravel_makes(dir)
for key, name in pairs {
c = 'controller',
d = 'data',
e = 'event',
f = 'factory',
j = 'job',
l = 'listener',
ma = 'mail',
mi = 'migration',
mo = 'model',
mw = 'middleware',
n = 'notification',
o = 'observer',
pi = 'model --pivot',
po = 'policy',
pr = 'provider',
t = 'test --pest',
v = 'view',
x = 'exception',
} do
map('<Leader>m' .. key, function()
make_laravel_file(dir, name)
end, { desc = 'Make and navigate to relevant ' .. name })
end
end
-- Define per-project configuration here.
-- Keys are folder names (last segment of your cwd).
local PROJECTS = {
-- Example: a repo folder
['runcats'] = function(dir)
-- local dump_buf = vim.api.nvim_create_buf(false, true)
-- vim.api.nvim_set_option_value('bufhidden', 'hide', { buf = dump_buf })
-- vim.api.nvim_set_option_value('modifiable', false, { buf = dump_buf })
--
-- vim.fn.jobstart('cd server && sail artisan dump-server', {
-- term = true,
-- })
-- map('<leader>dd', function()
-- local height = math.ceil(vim.o.lines * 0.8)
-- local width = math.ceil(vim.o.columns * 0.8)
-- vim.api.nvim_open_win(dump_buf, true, {
-- style = 'minimal',
-- relative = 'editor',
-- width = width,
-- height = height,
-- row = math.ceil((vim.o.lines - height) / 2),
-- col = math.ceil((vim.o.columns - width) / 2),
-- border = 'single',
-- })
--
-- vim.cmd.startinsert()
-- end, { desc = 'Open the dump-server window' })
map(
'<leader>pl',
':cexpr system("cd server && vendor/bin/phpstan analyse --no-progress --error-format=raw --memory-limit=2G -vv") <CR>',
{ desc = 'Run lint' }
)
map('<leader>pd', function()
helpers.open_term { cmd = 'lazysql mysql://root@localhost:3306/runcats' }
end, { desc = 'Open database manager' })
map('s ', '!cd server && ', { desc = 'Run command in server directory' }, 'c')
map('c ', '!cd client && ', { desc = 'Run command in client directory' }, 'c')
laravel_keymaps 'server'
laravel_makes 'server'
map('yrn ', '!cd client && yarn ', { desc = 'Run yarn script' }, 'c')
map('<Leader>pt', ':!cd server && php artisan typescript:transform --format<CR>', { desc = 'Compile typescript' })
require('conform').formatters.pint = {
append_args = {
'--config=' .. dir .. '/server/pint.json',
},
}
create_bookmark('E', dir .. '/client/src/types/api/endpointMap.d.ts')
create_bookmark('q', dir .. '/client/quasar.config.ts')
create_bookmark('db', dir .. '/client/src/boot')
create_bookmark('ds', dir .. '/client/src/stores')
create_bookmark('dS', dir .. '/client/src/services')
end,
['hylark'] = function(dir)
map('<leader>pl', ':cexpr system("vendor/bin/phpstan analyse --no-progress --error-format=raw --memory-limit=2G -vv") <CR>', { desc = 'Run lint' })
map('<leader>pd', function()
helpers.open_term { cmd = 'lazysql pgsql://homestead:password@localhost:5432/homestead' }
end, { desc = 'Open database manager' })
laravel_keymaps()
laravel_makes()
map('yrn ', '!cd frontend && yarn ', { desc = 'Run yarn script' }, 'c')
map('<Leader>pm', ':vendor/bin/sail composer migrate<CR>')
end,
default = function() end,
}
local last_applied = nil
function M.apply(cwd)
local dir = cwd or vim.fn.getcwd()
local name = project_name_from_cwd(dir)
if last_applied == name then
return
end
last_applied = name
local setup = PROJECTS[name] or PROJECTS.default
if type(setup) == 'function' then
setup(dir)
vim.notify(('Project config loaded: %s'):format(name), vim.log.levels.INFO, { title = 'projects.lua' })
end
end
-- Apply on startup and when the working directory changes
do
local grp = vim.api.nvim_create_augroup('ProjectConfig', { clear = true })
vim.api.nvim_create_autocmd('VimEnter', {
group = grp,
callback = function()
M.apply()
end,
})
vim.api.nvim_create_autocmd('DirChanged', {
group = grp,
callback = function(args)
-- args.file is the new cwd for DirChanged
M.apply(args and args.file or nil)
end,
})
end
-- Optional command to manually re-apply
vim.api.nvim_create_user_command('ProjectReload', function()
last_applied = nil
M.apply()
end, {})
-- Keep your helper line
require('helpers').edit_cf('w', '/lua/projects.lua')

View File

@@ -1 +0,0 @@
{}

1
lua/snippets/all.lua Normal file
View File

@@ -0,0 +1 @@
return {}

View File

@@ -1,9 +0,0 @@
{
"Log function": {
"prefix": "du",
"body": [
"console.log($0);"
],
"description": "Log variable"
}
}

View File

@@ -0,0 +1,45 @@
local ls = require 'luasnip'
local s = ls.snippet
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
return {
s('du', { t 'console.log(', i(0), t ');' }),
s('vue', {
t { '<template>', '' },
t { '', '</template>', '', '', '<script setup>', '' },
i(0),
t { '', '</script>', '', '', '<style scoped>', '', '.o-share-page {', '}', '', '</style>' },
}),
s('fun', {
t 'function ',
i(1),
t '(',
i(2),
t ') {',
t { '', ' ' },
i(0),
t { '', '}' },
}),
s('afun', {
t 'async function ',
i(1),
t '(',
i(2),
t ') {',
t { '', ' ' },
i(0),
t { '', '}' },
}),
s('()', {
t '() => {',
t { '', ' ' },
i(0),
t { '', '}' },
}),
}

View File

@@ -1,26 +0,0 @@
{
"name": "example-snippets",
"contributes": {
"snippets": [
{
"language": [
"all"
],
"path": "./snippets/all.json"
},
{
"language": [
"php"
],
"path": "./php.json"
},
{
"language": [
"javascript",
"vue"
],
"path": "./javascript-vue.json"
}
]
}
}

View File

@@ -1,17 +0,0 @@
{
"Create doc block": {
"prefix": "/**",
"body": [
"/**",
" * $0",
" */"
]
},
"Dump function": {
"prefix": "du",
"body": [
"dump($0);"
],
"description": "Dump variable"
}
}

600
lua/snippets/php.lua Normal file
View File

@@ -0,0 +1,600 @@
local ls = require 'luasnip'
local s = ls.snippet
local sn = ls.snippet_node
local fn = ls.function_node
local ms = ls.multi_snippet
local t = ls.text_node
local c = ls.choice_node
local i = ls.insert_node
local f = ls.function_node
local d = ls.dynamic_node
local fmt = require('luasnip.extras.fmt').fmt
local rep = require('luasnip.extras').rep
local extend_decorator = require 'luasnip.util.extend_decorator'
local fmta = extend_decorator.apply(fmt, { delimiters = '#~' })
local utils = require 'snippets.snip_utils'
local tr = utils.tr
local etr = utils.etr
local atr = utils.atr
local ctr = utils.ctr
local bs = utils.bs
local function psr_namespace()
local path = vim.fn.expand '%'
-- Get the directory of the path
local dir = vim.fs.dirname(path)
-- Loop through parent directories to find composer.json
while dir ~= '/' and dir ~= nil do
local composer_json_path = dir .. '/composer.json'
if vim.fn.filereadable(composer_json_path) == 1 then
break
end
dir = vim.fs.dirname(dir)
end
-- If no composer.json found, return empty string
if dir == '/' or dir == nil then
return ''
end
-- Decode composer.json and get PSR-4 autoload mappings
local composer = vim.json.decode(vim.iter(vim.fn.readfile(dir .. '/composer.json')):join '')
local psr4 = composer['autoload'] and composer['autoload']['psr-4']
-- If no PSR-4 mappings, return empty string
if not psr4 then
return ''
end
-- Get the relative path from the composer.json directory
local relative_path = path:sub(#dir + 2)
-- Loop through PSR-4 mappings
for namespace, map in pairs(psr4) do
-- Check if the relative path matches the mapping
if relative_path:match('^' .. map:gsub('/', '%%/')) then
-- Extract the suffix of the path after the mapping, removing the filename
local suffix = relative_path:sub(#map + 1):match '^(.*)/[^/]+%.php$' or ''
local trimmed = namespace:gsub('\\$', '')
return trimmed .. (suffix ~= '' and ('\\' .. suffix:gsub('/', '\\')) or '')
end
end
end
local function class_name(args, snip)
local filename = snip.env.TM_FILENAME or ''
return filename:match '([^%.]+)' or 'ClassName'
end
return {
---------------
-- DEBUGGING --
---------------
s(etr('du ', 'Dump a variable to the dump server'), fmta('dump(#~);', { i(0) })),
bs(atr('du ', 'Dump a variable to the dump server'), fmta('dump(#~)', { i(0) })),
s(etr('r ', 'ray'), fmta('ray(#~);', { i(0) })),
bs(atr('r ', 'ray'), fmta('ray(#~)', { i(0) })),
s(etr('dt ', 'Dump PHPStan type definition'), fmta('\\PhpStan\\dumpType(#~);', { i(0) })),
s(
etr('ql ', 'Log all queries'),
fmta(
[[
\Illuminate\Support\Facades\DB::listen(function (\Illuminate\Database\Events\QueryExecuted $e) {
dump($e->sql, $e->bindings);
});
#~
]],
{ i(0) }
)
),
--------------
-- COMMENTS --
--------------
s(etr('/**', 'Docblock comment'), {
c(1, {
sn(
nil,
fmta(
[[
/**
* #~
*/
]],
{ i(1) }
)
),
sn(nil, fmta('/** #~ */', { i(1) })),
}),
}),
s(etr('@v', '@var docblock'), fmta('/** @var #~ $#~ */', { i(1), i(0) })),
s(ctr('@v', '@var docblock'), fmta('@var #~ $#~', { i(1), i(0) })),
s(ctr('* @pr', 'Class property docblock'), fmta('* @property #~ $#~', { i(1), i(0) })),
s(ctr('* @pb', 'Class boolean property docblock'), fmta('* @property bool $#~', { i(0) })),
s(ctr('* @pi', 'Class int property docblock'), fmta('* @property int $#~', { i(0) })),
s(ctr('* @ps', 'Class string property docblock'), fmta('* @property string $#~', { i(0) })),
s(ctr('* @pc', 'Class collection property docblock'), fmta('* @property \\Illuminate\\Database\\Eloquent\\Collection<#~> $#~', { i(1), i(0) })),
s(ctr('* @pd', 'Class date property docblock'), fmta('* @property \\Illuminate\\Support\\Carbon $#~', { i(0) })),
s(
etr('@pm', 'Model magic properties docblock'),
fmta(
[[
/**
* @property int $id
* #~
* @property \Illuminate\Support\Carbon $created_at
* @property \Illuminate\Support\Carbon $updated_at
*
* Relationships
* #~
*/
]],
{ i(1), i(0) }
)
),
------------
-- SYNTAX --
------------
s(
etr('if ', 'if block'),
fmta(
[[
if (#~) {
#~
}
]],
{ i(1), i(0) }
)
),
s(
etr('fe ', 'foreach block'),
fmta(
[[
foreach (#~ as #~) {
#~
}
]],
{ i(1), i(2), i(0) }
)
),
s(etr('foreach', 'foreach block'), fmta('fe', {})),
s(
etr('for ', 'for block'),
fmta(
[[
for (#~; #~; #~) {
#~
}
]],
{ i(1, '$i'), i(2), i(3, '$i++'), i(0) }
)
),
s(etr('return ', 'Add semicolon after return'), fmta('return #~;', { i(0) })),
s(atr(' use ', 'Add use to function'), fmta(' use (#~)', { i(0) })),
s(etr('rt ', 'return alias'), fmta('return #~;', { i(0) })),
bs(etr('fn ', 'Shorthand function block'), {
c(1, {
sn(nil, fmta('fn (#~) => #~', { i(1), i(2) })),
sn(
nil,
fmta(
[[
function (#~) {
#~
}
]],
{ i(1), i(2) }
)
),
}),
}),
bs(etr('fun ', 'Shorthand function block'), {
c(1, {
sn(
nil,
fmta(
[[
function (#~) {
#~
}
]],
{ i(1), i(2) }
)
),
sn(
nil,
fmta(
[[
function (#~) use (#~) {
#~
}
]],
{ i(1), i(2), i(3) }
)
),
}),
}),
s(
etr('con', 'Constructor function block'),
c(1, {
sn(
nil,
fmta(
[[
public function __construct(#~)
{
#~
}
]],
{ i(1), i(2) }
)
),
sn(
nil,
fmta(
[[
public function __construct(
#~
) {
#~
}
]],
{ i(1), i(2) }
)
),
})
),
bs(atr('function', 'Shorthand function block'), fmta('fun', {})),
bs(atr('s%$', 'string type parameter'), fmta('string $#~', { i(0, 'var') })),
bs(atr('i%$', 'int type parameter'), fmta('int $#~', { i(0, 'var') })),
bs(atr('b%$', 'bool type parameter'), fmta('bool $#~', { i(0, 'var') })),
bs(atr('a%$', 'array type parameter'), fmta('array $#~', { i(0, 'var') })),
s(atr('$ ', 'Expand $this->'), fmta('$this->#~', { i(0) })),
bs(etr('am ', 'array_map function'), {
c(1, {
sn(nil, fmta('array_map(fn (#~) => #~, #~)', { i(2), i(3), i(1) })),
sn(
nil,
fmta(
[[
array_map(function (#~) {
#~
}, #~)
]],
{ i(2), i(0), i(1) }
)
),
}),
}),
bs(etr('array_map', 'array_map function'), fmta('am', {})),
bs(etr('af ', 'array_filter function'), {
c(1, {
sn(nil, fmta('array_filter(#~, fn (#~) => #~)', { i(1), i(2), i(3) })),
sn(
nil,
fmta(
[[
array_filter(#~, function (#~) {
#~
})
]],
{ i(1), i(2), i(0) }
)
),
}),
}),
bs(etr('array_filter', 'array_filter function'), fmta('af', {})),
s(
etr('php', 'php class'),
fmta(
[[
<?php
declare(strict_types=1);
namespace #~;
class #~
{
public function __construct()
{
#~
}
}
]],
{ f(psr_namespace, {}), f(class_name, {}), i(0) }
)
),
s(
etr('met', 'public class method'),
fmta(
[[
public function #~(#~)
{
#~
}
]],
{ i(1), i(2), i(0) }
)
),
s(
etr('pmet', 'protected class method'),
fmta(
[[
protected function #~(#~)
{
#~
}
]],
{ i(1), i(2), i(0) }
)
),
s(
etr('smet', 'public static class method'),
fmta(
[[
public static function #~(#~)
{
#~
}
]],
{ i(1), i(2), i(0) }
)
),
s(
etr('spmet', 'protected static class method'),
fmta(
[[
protected static function #~(#~)
{
#~
}
]],
{ i(1), i(2), i(0) }
)
),
-------------
-- PROJECT --
-------------
s(
etr('test', 'Create a test function'),
fmta(
[[
test(#~ function () {
#~
})
]],
{ i(1), i(0) }
)
),
s(etr('nn ', 'Assert not null'), fmta('Assert::notNull(#~)', { i(0) })),
-------------
-- LARAVEL --
-------------
s(
etr('bt', 'belongsTo Laravel relationship method'),
c(0, {
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\#~, $this>
*/
public function #~(): BelongsTo
{
return $this->belongsTo(#~::class);
}
]],
{ rep(1), i(0), i(1) }
)
),
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\#~, $this>
*/
public function #~(): BelongsTo
{
return $this->belongsTo(#~::class, #~);
}
]],
{ rep(1), i(2), i(1), i(0) }
)
),
})
),
s(
etr('hm', 'hasMany Laravel relationship method'),
c(0, {
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\#~, $this>
*/
public function #~(): HasMany
{
return $this->hasOne(#~::class);
}
]],
{ rep(1), i(0), i(1) }
)
),
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\#~, $this>
*/
public function #~(): HasMany
{
return $this->hasOne(#~::class, #~);
}
]],
{ rep(1), i(2), i(1), i(0) }
)
),
})
),
s(
etr('ho', 'hasOne Laravel relationship method'),
c(0, {
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\#~, $this>
*/
public function #~(): HasOne
{
return $this->hasOne(#~::class);
}
]],
{ rep(1), i(0), i(1) }
)
),
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne<\App\Models\#~, $this>
*/
public function #~(): HasOne
{
return $this->hasOne(#~::class, #~);
}
]],
{ rep(1), i(2), i(1), i(0) }
)
),
})
),
s(
etr('bm', 'belongsToMany Laravel relationship method'),
c(0, {
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<\App\Models\#~, $this>
*/
public function #~(): BelongsToMany
{
return $this->belongsToMany(#~::class, #~);
}
]],
{ rep(1), i(2), i(1), i(0) }
)
),
sn(
nil,
fmta(
[[
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<\App\Models\#~, $this>
*/
public function #~(): BelongsToMany
{
return $this->belongsToMany(#~::class, #~, #~);
}
]],
{ rep(1), i(2), i(1), i(3), i(0) }
)
),
})
),
s(
atr('->wr', 'Eloquent where method'),
c(0, {
sn(nil, fmta("->where('#~', #~)", { i(1), i(0) })),
sn(nil, fmta('->where(fn ($query) => #~)', { i(0) })),
sn(
nil,
fmta(
[[
->where(function ($query) {
#~
})
]],
{ i(0) }
)
),
sn(
nil,
fmta(
[[
->where(function ($query) use (#~) {
#~
})
]],
{ i(1), i(0) }
)
),
})
),
s(atr('->wi', 'Eloquent where in method'), fmta("->whereIn('#~', #~)", { i(1), i(0) })),
s(atr('->wn', 'Eloquent where not in method'), fmta("->whereNotIn('#~', #~)", { i(1), i(0) })),
s(
atr('->wh', 'Eloquent where has method'),
c(0, {
sn(nil, fmta("->whereHas('#~')", { i(1) })),
sn(nil, fmta("->whereHas('#~', fn ($query) => #~)", { i(1), i(0) })),
sn(
nil,
fmta(
[[
->whereHas('#~', function ($query) {
#~
})
]],
{ i(1), i(0) }
)
),
sn(
nil,
fmta(
[[
->whereHas('#~', function ($query) use (#~) {
#~
})
]],
{ i(1), i(2), i(0) }
)
),
})
),
s(
atr('->we', 'Eloquent where exists method'),
c(0, {
sn(nil, fmta('->whereExists(fn ($query) => #~)', { i(0) })),
sn(
nil,
fmta(
[[
->whereExists(function ($query) {
#~
})
]],
{ i(0) }
)
),
sn(
nil,
fmta(
[[
->whereExists(function ($query) use (#~) {
#~
})
]],
{ i(1), i(0) }
)
),
})
),
}

136
lua/snippets/snip_utils.lua Normal file
View File

@@ -0,0 +1,136 @@
local ls = require 'luasnip'
local s = ls.snippet
local sn = ls.snippet_node
local fn = ls.function_node
local ms = ls.multi_snippet
local t = ls.text_node
local c = ls.choice_node
local i = ls.insert_node
local f = ls.function_node
local d = ls.dynamic_node
local fmt = require('luasnip.extras.fmt').fmt
local rep = require('luasnip.extras').rep
local line_begin = require('luasnip.extras.conditions').line_begin
local extend_decorator = require 'luasnip.util.extend_decorator'
local fmta = extend_decorator.apply(fmt, { delimiters = '#~' })
local utils = {}
--- Check if the trigger is at the beginning of a line
---@param line_to_cursor string
---@param matched_trigger string
---@return boolean
utils.line_begin = function(line_to_cursor, matched_trigger)
return line_to_cursor:sub(1, -(#matched_trigger + 1)):match '^%s*$'
end
--- Check if the trigger is on an empty line
---@param _ string
---@param matched_trigger string
---@return boolean
utils.empty_line = function(_, matched_trigger)
return vim.api.nvim_get_current_line():match('^%s*' .. vim.pesc(matched_trigger) .. '$')
end
--- Check if the trigger is at the start of a file
---@param line_to_cursor string
---@param matched_trigger string
---@return boolean
utils.file_begin = function(line_to_cursor, matched_trigger)
local line_number = vim.fn.line '.'
return line_number == 1 and line_begin(line_to_cursor, matched_trigger)
end
--- Check if the trigger is inside a string
---@return boolean
utils.in_string = function()
local node_type = vim.treesitter.get_node():type()
return node_type == 'string_content' or node_type == 'string'
end
--- Check if the trigger is inside a comment
---@return boolean
utils.in_comment = function()
local node_type = vim.treesitter.get_node():type()
return node_type == 'comment'
end
--- Check if the trigger is not inside a string or a comment
---@return boolean
utils.not_in_string_or_comment = function()
return (not utils.in_string()) and (not utils.in_comment())
end
--- Create a basic auto expand trigger
---@param trigger string
---@param description? string
---@param options? table
---@return table
utils.tr = function(trigger, description, options)
return vim.tbl_extend('force', {
trig = trigger,
desc = description,
snippetType = 'autosnippet',
}, options or {})
end
--- Create a trigger for an empty line snippet
---@param trigger string
---@param description? string
---@param options? table
---@return table
utils.etr = function(trigger, description, options)
return utils.tr(trigger, description, vim.tbl_extend('force', { condition = utils.empty_line }, options or {}))
end
--- Create a trigger for a comment trigger
---@param trigger string
---@param description? string
---@param options? table
---@return table
utils.ctr = function(trigger, description, options)
return utils.tr(trigger, description, vim.tbl_extend('force', { condition = utils.in_comment }, options or {}))
end
--- Create a trigger for a snippet to expand anywhere outside a string/comment
---@param trigger string
---@param description? string
---@param options? table
---@return table
utils.atr = function(trigger, description, options)
return utils.tr(
trigger,
description,
vim.tbl_extend('force', {
regTrig = true,
wordTrig = false,
condition = utils.not_in_string_or_comment,
}, options or {})
)
end
--- Create a snippet that will expand anywhere but in the middle of a word
---@param trigger any
---@param nodes any
---@param options? any
---@return table
utils.bs = function(trigger, nodes, options)
local btrigger
if type(trigger) == 'string' then
btrigger = utils.atr('([^%w_-])' .. trigger)
else
btrigger = vim.tbl_extend('keep', utils.atr('([^%w_-])' .. trigger.trig), trigger)
end
return ms(
{
trigger,
btrigger,
},
vim.list_extend({ fn(function(args, snip)
return snip.captures[1] or ''
end) }, nodes),
options
)
end
return utils

8
lua/visuals.lua Normal file
View File

@@ -0,0 +1,8 @@
require('helpers').edit_cf('c', '/lua/visuals.lua')
local line_number_color = '#5d6487'
vim.cmd('highlight LineNr guifg=' .. line_number_color)
vim.cmd('highlight LineNrAbove guifg=' .. line_number_color)
vim.cmd('highlight LineNrBelow guifg=' .. line_number_color)
vim.api.nvim_set_hl(0, "CopilotSuggestion", { fg = "#888888", italic = true })