chore(nvim): reinitialize with working config
Some checks are pending
Check Lua Formatting in MyRepo / Stylua Check (push) Waiting to run
Some checks are pending
Check Lua Formatting in MyRepo / Stylua Check (push) Waiting to run
This commit is contained in:
commit
02e26b00b7
98 changed files with 5274 additions and 0 deletions
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Executable file
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Any bug report not following this template will be immediately closed. Thanks -->
|
||||
|
||||
## Describe the bug
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
## To Reproduce
|
||||
<!-- Steps to reproduce the behavior. -->
|
||||
1. ...
|
||||
|
||||
## Desktop
|
||||
<!-- please complete the following information. -->
|
||||
- OS:
|
||||
- Terminal:
|
||||
|
||||
## Neovim Version
|
||||
<!-- Output of running `:version` from inside of neovim. -->
|
||||
|
||||
```
|
||||
```
|
||||
30
.github/workflows/stylua.yaml
vendored
Normal file
30
.github/workflows/stylua.yaml
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
# Check Lua Formatting
|
||||
name: Check Lua Formatting in MyRepo
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
stylua-check:
|
||||
name: Stylua Check
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Stylua Check
|
||||
uses: JohnnyMorganz/stylua-action@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: latest
|
||||
args: --check .
|
||||
7
.gitignore
vendored
Executable file
7
.gitignore
vendored
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
tags
|
||||
test.sh
|
||||
.luarc.json
|
||||
nvim
|
||||
lazy-lock.json
|
||||
.DS_Store
|
||||
|
||||
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
13
.idea/inspectionProfiles/Project_Default.xml
Normal file
13
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="dict.database" />
|
||||
<option value="search_engine" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
.idea/misc.xml
Normal file
7
.idea/misc.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.11" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
10
.stylua.toml
Executable file
10
.stylua.toml
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
call_parentheses = "Always"
|
||||
quote_style = "AutoPreferSingle"
|
||||
collapse_simple_statement = "Never"
|
||||
|
||||
[sort_requires]
|
||||
enabled = false
|
||||
19
LICENSE.md
Executable file
19
LICENSE.md
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
159
README.md
Executable file
159
README.md
Executable file
|
|
@ -0,0 +1,159 @@
|
|||
# kickstart.nvim
|
||||
|
||||
https://github.com/kdheepak/kickstart.nvim/assets/1813121/f3ff9a2b-c31f-44df-a4fa-8a0d7b17cf7b
|
||||
|
||||
### Introduction
|
||||
|
||||
A starting point for Neovim that is:
|
||||
|
||||
* Small
|
||||
* Single-file (with examples of moving to multi-file)
|
||||
* Documented
|
||||
* Modular
|
||||
|
||||
This repo is meant to be used by **YOU** to begin your Neovim journey; remove the things you don't use and add what you miss.
|
||||
|
||||
Kickstart.nvim targets *only* the latest ['stable'](https://github.com/neovim/neovim/releases/tag/stable) and latest ['nightly'](https://github.com/neovim/neovim/releases/tag/nightly) of Neovim. If you are experiencing issues, please make sure you have the latest versions.
|
||||
|
||||
Distribution Alternatives:
|
||||
- [LazyVim](https://www.lazyvim.org/): A delightful distribution maintained by @folke (the author of lazy.nvim, the package manager used here)
|
||||
|
||||
### Installation
|
||||
|
||||
> **NOTE**
|
||||
> [Backup](#FAQ) your previous configuration (if any exists)
|
||||
|
||||
Requirements:
|
||||
* Make sure to review the readmes of the plugins if you are experiencing errors. In particular:
|
||||
* [ripgrep](https://github.com/BurntSushi/ripgrep#installation) is required for multiple [telescope](https://github.com/nvim-telescope/telescope.nvim#suggested-dependencies) pickers.
|
||||
* See [Windows Installation](#Windows-Installation) if you have trouble with `telescope-fzf-native`
|
||||
|
||||
Neovim's configurations are located under the following paths, depending on your OS:
|
||||
|
||||
| OS | PATH |
|
||||
| :- | :--- |
|
||||
| Linux | `$XDG_CONFIG_HOME/nvim`, `~/.config/nvim` |
|
||||
| MacOS | `$XDG_CONFIG_HOME/nvim`, '~/.config/nvim` |
|
||||
| Windows | `%userprofile%\AppData\Local\nvim\` |
|
||||
|
||||
Clone kickstart.nvim:
|
||||
|
||||
```sh
|
||||
# on Linux and Mac
|
||||
git clone https://github.com/nvim-lua/kickstart.nvim.git "${XDG_CONFIG_HOME:-$HOME/.config}"/nvim
|
||||
# on Windows
|
||||
git clone https://github.com/nvim-lua/kickstart.nvim.git %userprofile%\AppData\Local\nvim\
|
||||
```
|
||||
|
||||
### Post Installation
|
||||
|
||||
Run the following command and then **you are ready to go**!
|
||||
|
||||
```sh
|
||||
nvim --headless "+Lazy! sync" +qa
|
||||
```
|
||||
|
||||
### Recommended Steps
|
||||
|
||||
[Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo (so that you have your own copy that you can modify) and then installing you can install to your machine using the methods above.
|
||||
|
||||
> **NOTE**
|
||||
> Your fork's url will be something like this: `https://github.com/<your_github_username>/kickstart.nvim.git`
|
||||
|
||||
### Configuration And Extension
|
||||
|
||||
* Inside of your copy, feel free to modify any file you like! It's your copy!
|
||||
* Feel free to change any of the default options in `init.lua` to better suit your needs.
|
||||
* For adding plugins, there are 3 primary options:
|
||||
* Add new configuration in `lua/custom/plugins/*` files, which will be auto sourced using `lazy.nvim` (uncomment the line importing the `custom/plugins` directory in the `init.lua` file to enable this)
|
||||
* Modify `init.lua` with additional plugins.
|
||||
* Include the `lua/kickstart/plugins/*` files in your configuration.
|
||||
|
||||
You can also merge updates/changes from the repo back into your fork, to keep up-to-date with any changes for the default configuration.
|
||||
|
||||
#### Example: Adding an autopairs plugin
|
||||
|
||||
In the file: `lua/custom/plugins/autopairs.lua`, add:
|
||||
|
||||
```lua
|
||||
-- File: lua/custom/plugins/autopairs.lua
|
||||
|
||||
return {
|
||||
"windwp/nvim-autopairs",
|
||||
-- Optional dependency
|
||||
dependencies = { 'hrsh7th/nvim-cmp' },
|
||||
config = function()
|
||||
require("nvim-autopairs").setup {}
|
||||
-- If you want to automatically add `(` after selecting a function or method
|
||||
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
|
||||
local cmp = require('cmp')
|
||||
cmp.event:on(
|
||||
'confirm_done',
|
||||
cmp_autopairs.on_confirm_done()
|
||||
)
|
||||
end,
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
This will automatically install [windwp/nvim-autopairs](https://github.com/windwp/nvim-autopairs) and enable it on startup. For more information, see documentation for [lazy.nvim](https://github.com/folke/lazy.nvim).
|
||||
|
||||
#### Example: Adding a file tree plugin
|
||||
|
||||
In the file: `lua/custom/plugins/filetree.lua`, add:
|
||||
|
||||
```lua
|
||||
-- Unless you are still migrating, remove the deprecated commands from v1.x
|
||||
vim.cmd([[ let g:neo_tree_remove_legacy_commands = 1 ]])
|
||||
|
||||
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",
|
||||
},
|
||||
config = function ()
|
||||
require('neo-tree').setup {}
|
||||
end,
|
||||
}
|
||||
```
|
||||
|
||||
This will install the tree plugin and add the command `:Neotree` for you. You can explore the documentation at [neo-tree.nvim](https://github.com/nvim-neo-tree/neo-tree.nvim) for more information.
|
||||
|
||||
### Contribution
|
||||
|
||||
Pull-requests are welcome. The goal of this repo is not to create a Neovim configuration framework, but to offer a starting template that shows, by example, available features in Neovim. Some things that will not be included:
|
||||
|
||||
* Custom language server configuration (null-ls templates)
|
||||
* Theming beyond a default colorscheme necessary for LSP highlight groups
|
||||
|
||||
Each PR, especially those which increase the line count, should have a description as to why the PR is necessary.
|
||||
|
||||
### FAQ
|
||||
|
||||
* What should I do if I already have a pre-existing neovim configuration?
|
||||
* You should back it up, then delete all files associated with it.
|
||||
* This includes your existing init.lua and the neovim files in `~/.local` which can be deleted with `rm -rf ~/.local/share/nvim/`
|
||||
* You may also want to look at the [migration guide for lazy.nvim](https://github.com/folke/lazy.nvim#-migration-guide)
|
||||
* What if I want to "uninstall" this configuration:
|
||||
* See [lazy.nvim uninstall](https://github.com/folke/lazy.nvim#-uninstalling) information
|
||||
* Are there any cool videos about this plugin?
|
||||
* Current iteration of kickstart (coming soon)
|
||||
* Here is one about the previous iteration of kickstart: [video introduction to Kickstart.nvim](https://youtu.be/stqUbv-5u2s). Note the install via init.lua no longer works as specified. Please follow the install instructions in this file instead as they're up to date.
|
||||
|
||||
### Windows Installation
|
||||
|
||||
Installation may require installing build tools, and updating the run command for `telescope-fzf-native`
|
||||
|
||||
See `telescope-fzf-native` documentation for [more details](https://github.com/nvim-telescope/telescope-fzf-native.nvim#installation)
|
||||
|
||||
This requires:
|
||||
|
||||
- Install CMake, and the Microsoft C++ Build Tools on Windows
|
||||
|
||||
```lua
|
||||
{'nvim-telescope/telescope-fzf-native.nvim', build = 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' }
|
||||
```
|
||||
|
||||
66
after/queries/go/highlights.scm
Normal file
66
after/queries/go/highlights.scm
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
;; Custom highlights for Go
|
||||
;; Place this in: ~/.config/nvim/after/queries/go/highlights.scm
|
||||
|
||||
;; Highlight struct field names
|
||||
(field_declaration
|
||||
name: (field_identifier) @struct.field)
|
||||
|
||||
;; Highlight function receivers in method declarations
|
||||
(parameter_declaration
|
||||
name: (identifier) @function.receiver
|
||||
type: (pointer_type (type_identifier))) ;; Pointer receivers
|
||||
|
||||
(parameter_declaration
|
||||
name: (identifier) @function.receiver
|
||||
type: (type_identifier)) ;; Value receivers
|
||||
|
||||
;; Highlight type parameters (Go 1.18+ Generics)
|
||||
; (type_parameter
|
||||
; name: (type_identifier) @type.parameter)
|
||||
|
||||
;; Better highlight for method calls
|
||||
(selector_expression
|
||||
field: (field_identifier) @method.call)
|
||||
|
||||
;; Improved context highlighting for function parameters
|
||||
(function_declaration
|
||||
name: (identifier) @function.name
|
||||
parameters: (parameter_list
|
||||
(parameter_declaration
|
||||
name: (identifier) @function.parameter)))
|
||||
|
||||
;; Interface method names (fixed issue with invalid method_spec)
|
||||
; (interface_type
|
||||
; (field
|
||||
; name: (field_identifier) @interface.method)) ;; Interface methods
|
||||
|
||||
;; Highlight builtin functions
|
||||
((identifier) @function.builtin
|
||||
(#any-of? @function.builtin "append" "cap" "close" "complex" "copy" "delete"
|
||||
"imag" "len" "make" "new" "panic" "print" "println"
|
||||
"real" "recover"))
|
||||
|
||||
;; Constants in ALL_CAPS (common Go convention)
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||
|
||||
;; Error variables (by Go convention, starting with "Err")
|
||||
((identifier) @variable.error
|
||||
(#match? @variable.error "^Err[A-Z]\\w*"))
|
||||
|
||||
;; Type declaration highlighting
|
||||
(type_spec
|
||||
name: (type_identifier) @type.definition)
|
||||
|
||||
;; Enhance composite literal highlighting
|
||||
(composite_literal
|
||||
type: (_) @composite.type)
|
||||
|
||||
;; Go build tags
|
||||
(comment) @preproc.build
|
||||
(#match? @preproc.build "^//go:build")
|
||||
|
||||
;; Go generate directives
|
||||
(comment) @preproc.generate
|
||||
(#match? @preproc.generate "^//go:generate")
|
||||
|
||||
99
after/queries/go/textobjects.scm
Normal file
99
after/queries/go/textobjects.scm
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
;; extends
|
||||
; Custom text objects for Go
|
||||
; Place this in: ~/.config/nvim/after/queries/go/textobjects.scm
|
||||
|
||||
; Function text objects
|
||||
(function_declaration) @function.outer
|
||||
|
||||
(function_declaration
|
||||
body: (block) @function.inner)
|
||||
|
||||
; Method text objects
|
||||
(method_declaration) @function.outer
|
||||
|
||||
(method_declaration
|
||||
body: (block) @function.inner)
|
||||
|
||||
; Function literal (closure) text objects
|
||||
(func_literal) @function.outer
|
||||
|
||||
(func_literal
|
||||
body: (block) @function.inner)
|
||||
|
||||
; Class text objects (structs, interfaces)
|
||||
(type_declaration) @class.outer
|
||||
|
||||
; (struct_type
|
||||
; "{" "}" @class.inner)
|
||||
|
||||
(interface_type
|
||||
"{" "}" @class.inner)
|
||||
|
||||
; Parameter text objects
|
||||
(parameter_list) @parameter.outer
|
||||
|
||||
(parameter_list
|
||||
"(" . (_) @_start (_)? @_end . ")"
|
||||
(#make-range! "parameter.inner" @_start @_end))
|
||||
|
||||
; Argument text objects
|
||||
(argument_list) @parameter.outer
|
||||
|
||||
(argument_list
|
||||
"(" . (_) @_start (_)? @_end . ")"
|
||||
(#make-range! "parameter.inner" @_start @_end))
|
||||
|
||||
; Comment text objects
|
||||
(comment) @comment.outer
|
||||
|
||||
; Block text objects
|
||||
(block) @block.outer
|
||||
|
||||
(block
|
||||
"{" . (_) @_start (_)? @_end . "}"
|
||||
(#make-range! "block.inner" @_start @_end))
|
||||
|
||||
; Statement text objects
|
||||
; (simple_statement) @statement.outer
|
||||
(expression_statement) @statement.outer
|
||||
(if_statement) @statement.outer
|
||||
(for_statement) @statement.outer
|
||||
; (switch_statement) @statement.outer
|
||||
(select_statement) @statement.outer
|
||||
(return_statement) @statement.outer
|
||||
(defer_statement) @statement.outer
|
||||
(go_statement) @statement.outer
|
||||
|
||||
; Conditional text objects
|
||||
(if_statement) @conditional.outer
|
||||
|
||||
; (if_statement
|
||||
; body: (block) @conditional.inner)
|
||||
|
||||
; Loop text objects
|
||||
(for_statement) @loop.outer
|
||||
|
||||
(for_statement
|
||||
body: (block) @loop.inner)
|
||||
|
||||
; Call text objects
|
||||
(call_expression) @call.outer
|
||||
|
||||
(call_expression
|
||||
arguments: (argument_list) @call.inner)
|
||||
|
||||
; Assignment text objects
|
||||
(assignment_statement) @assignment.outer
|
||||
(short_var_declaration) @assignment.outer
|
||||
|
||||
; Import text objects
|
||||
(import_declaration) @import.outer
|
||||
|
||||
(import_spec_list) @import.inner
|
||||
|
||||
; Package text objects
|
||||
(package_clause) @package.outer
|
||||
|
||||
; Attribute/field text objects
|
||||
(field_declaration) @attribute.outer
|
||||
|
||||
15
after/queries/markdown/textobjects.scm
Normal file
15
after/queries/markdown/textobjects.scm
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
; (atx_heading
|
||||
; heading_content: (_) @class.inner) @class.outer
|
||||
;
|
||||
; (setext_heading
|
||||
; heading_content: (_) @class.inner) @class.outer
|
||||
;
|
||||
; (thematic_break) @class.outer
|
||||
|
||||
(fenced_code_block (code_fence_content) @block.inner) @block.outer
|
||||
|
||||
[
|
||||
(paragraph)
|
||||
(list)
|
||||
] @block.outer
|
||||
|
||||
13
after/queries/markdown_inline/highlights.scm
Normal file
13
after/queries/markdown_inline/highlights.scm
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
;extends
|
||||
|
||||
[
|
||||
(shortcut_link)
|
||||
] @nospell
|
||||
|
||||
(strikethrough
|
||||
(emphasis_delimiter)
|
||||
(strikethrough
|
||||
(emphasis_delimiter)
|
||||
(emphasis_delimiter))
|
||||
(emphasis_delimiter))@markup.doublestrikethrough
|
||||
|
||||
12
after/queries/norg/injections.scm
Normal file
12
after/queries/norg/injections.scm
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
; Injection for code blocks
|
||||
(ranged_verbatim_tag (tag_name) @_tagname (tag_parameters .(tag_param) @injection.language) (ranged_verbatim_tag_content) @injection.content (#any-of? @_tagname "code" "embed"))
|
||||
(ranged_verbatim_tag (tag_name) @_tagname (tag_parameters)? (ranged_verbatim_tag_content) @injection.content (#eq? @_tagname "math") (#set! injection.language "latex"))
|
||||
|
||||
(
|
||||
(inline_math) @injection.content
|
||||
(#offset! @injection.content 0 1 0 -1)
|
||||
(#set! injection.language "latex")
|
||||
)
|
||||
|
||||
(ranged_verbatim_tag (tag_name) @_tagname (ranged_verbatim_tag_content) @injection.content (#eq? @_tagname "document.meta") (#set! injection.language "norg_meta"))
|
||||
|
||||
12
after/queries/python/highlights.scm
Normal file
12
after/queries/python/highlights.scm
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
;extends
|
||||
(
|
||||
(comment) @comment
|
||||
(#match? @comment "^\\#\\|")
|
||||
) @text.literal
|
||||
|
||||
|
||||
(
|
||||
(comment) @content
|
||||
(#match? @content "^\\# ?\\%\\%")
|
||||
) @class.outer @text.literal
|
||||
|
||||
7
after/queries/python/textobjects.scm
Normal file
7
after/queries/python/textobjects.scm
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
;extends
|
||||
|
||||
(
|
||||
(comment) @content1
|
||||
(#match? @content1 "^\\# ?\\%\\%")
|
||||
) @class.inner
|
||||
|
||||
50
after/queries/r/textobjects.scm
Normal file
50
after/queries/r/textobjects.scm
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
; block
|
||||
; call
|
||||
(call) @call.outer
|
||||
|
||||
(arguments) @call.inner
|
||||
|
||||
; class
|
||||
; comment
|
||||
(comment) @comment.outer
|
||||
|
||||
; conditional
|
||||
(if_statement
|
||||
condition: (_)? @conditional.inner) @conditional.outer
|
||||
|
||||
; function
|
||||
[
|
||||
(function_definition)
|
||||
] @function.outer
|
||||
|
||||
(function_definition
|
||||
[
|
||||
(call)
|
||||
(binary_operator)
|
||||
] @function.inner) @function.outer
|
||||
|
||||
|
||||
; loop
|
||||
[
|
||||
(while_statement)
|
||||
(for_statement)
|
||||
(repeat_statement)
|
||||
] @loop.outer
|
||||
|
||||
(while_statement
|
||||
body: (_) @loop.inner)
|
||||
|
||||
(repeat_statement
|
||||
body: (_) @loop.inner)
|
||||
|
||||
(for_statement
|
||||
body: (_) @loop.inner)
|
||||
|
||||
; statement
|
||||
|
||||
(program
|
||||
(_) @statement.outer)
|
||||
|
||||
; number
|
||||
(float) @number.inner
|
||||
|
||||
15
after/queries/rust/injections.scm
Normal file
15
after/queries/rust/injections.scm
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
;extends
|
||||
(macro_invocation
|
||||
(scoped_identifier
|
||||
path: (identifier) @path (#eq? @path "sqlx")
|
||||
name: (identifier) @name (#match? @name "^query.*")
|
||||
)
|
||||
|
||||
(token_tree
|
||||
(raw_string_literal) @injection.content
|
||||
(#set! injection.language "sql")
|
||||
(#set! injection.include-children)
|
||||
)
|
||||
(#offset! @injection.content 0 3 0 -2)
|
||||
)
|
||||
|
||||
196
ftplugin/c.lua
Normal file
196
ftplugin/c.lua
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
-- Indentation settings
|
||||
vim.bo.expandtab = true -- Use spaces instead of tabs
|
||||
vim.bo.tabstop = 4 -- Number of spaces per tab
|
||||
vim.bo.shiftwidth = 4 -- Number of spaces for autoindent
|
||||
vim.bo.softtabstop = 4 -- Number of spaces for editing
|
||||
vim.bo.formatoptions = vim.bo.formatoptions:gsub('o', '') -- Remove 'o'
|
||||
|
||||
-- Format on save using Conform
|
||||
local augroup = vim.api.nvim_create_augroup('CFormat', { clear = true })
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
group = augroup,
|
||||
pattern = '*.c',
|
||||
callback = function()
|
||||
if vim.fn.exists(':ConformFormat') == 2 then
|
||||
vim.cmd('ConformFormat')
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local function cmake_build_dir(name)
|
||||
local dir = vim.fn.getcwd() .. '/' .. (name or 'build')
|
||||
if vim.fn.isdirectory(dir) == 0 then
|
||||
vim.fn.mkdir(dir, 'p')
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
local function cmake_configure(build_dir, extra_args)
|
||||
local args = extra_args or ''
|
||||
local bin_dir = vim.fn.getcwd() .. '/bin'
|
||||
vim.fn.mkdir(bin_dir, 'p')
|
||||
local out_args =
|
||||
' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' .. vim.fn.shellescape(bin_dir) .. ' -DCMAKE_LIBRARY_OUTPUT_DIRECTORY='
|
||||
.. vim.fn.shellescape(bin_dir)
|
||||
.. ' -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY='
|
||||
.. vim.fn.shellescape(bin_dir)
|
||||
vim.cmd('!cmake -S . -B ' .. vim.fn.fnameescape(build_dir) .. out_args .. ' ' .. args)
|
||||
end
|
||||
|
||||
local function cmake_build(build_dir)
|
||||
vim.cmd('!cmake --build ' .. vim.fn.fnameescape(build_dir))
|
||||
end
|
||||
|
||||
local function cmake_ctest(build_dir)
|
||||
vim.cmd('!ctest --test-dir ' .. vim.fn.fnameescape(build_dir) .. ' --output-on-failure')
|
||||
end
|
||||
|
||||
local function toggle_debugger_repl()
|
||||
local dbg = vim.__c_dbg_term
|
||||
if dbg and dbg.is_open and dbg:is_open() then
|
||||
dbg:close()
|
||||
return
|
||||
end
|
||||
|
||||
local ok_term, term_mod = pcall(require, 'toggleterm.terminal')
|
||||
if not ok_term then
|
||||
return
|
||||
end
|
||||
|
||||
local cmd
|
||||
if vim.fn.has('mac') == 1 then
|
||||
cmd = 'lldb'
|
||||
else
|
||||
cmd = 'gdb'
|
||||
end
|
||||
|
||||
if not vim.__c_dbg_term then
|
||||
vim.__c_dbg_term = term_mod.Terminal:new({
|
||||
cmd = cmd,
|
||||
direction = 'vertical',
|
||||
size = function()
|
||||
return math.floor(vim.o.columns * 0.4)
|
||||
end,
|
||||
hidden = true,
|
||||
on_open = function(term)
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 'n', 'q', '<cmd>close<CR>', { noremap = true, silent = true })
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 't', '<Esc><Esc>', '<C-\\><C-n>', { noremap = true, silent = true })
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
vim.__c_dbg_term:open()
|
||||
vim.cmd('wincmd p')
|
||||
end
|
||||
|
||||
local opts = { buffer = true, silent = true }
|
||||
|
||||
local function switch_source_header()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local function edit_file(fname)
|
||||
if not fname or fname == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('edit ' .. vim.fn.fnameescape(fname))
|
||||
end
|
||||
|
||||
local clangd
|
||||
for _, client in ipairs(vim.lsp.get_clients({ bufnr = bufnr })) do
|
||||
if client.name == 'clangd' then
|
||||
clangd = client
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if clangd then
|
||||
clangd.request('textDocument/switchSourceHeader', { uri = vim.uri_from_bufnr(bufnr) }, function(err, result)
|
||||
if err then
|
||||
vim.notify('clangd: switchSourceHeader failed', vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
if not result then
|
||||
vim.notify('No corresponding header/source found', vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
vim.schedule(function()
|
||||
edit_file(vim.uri_to_fname(result))
|
||||
end)
|
||||
end, bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
local file = vim.api.nvim_buf_get_name(bufnr)
|
||||
if file == '' then
|
||||
return
|
||||
end
|
||||
|
||||
local root = file:gsub('%.[^%.]+$', '')
|
||||
local ext = vim.fn.fnamemodify(file, ':e')
|
||||
local candidates
|
||||
|
||||
if ext == 'h' or ext == 'hpp' or ext == 'hh' or ext == 'hxx' then
|
||||
candidates = { 'c', 'cpp', 'cc', 'cxx' }
|
||||
elseif ext == 'c' then
|
||||
candidates = { 'h' }
|
||||
else
|
||||
candidates = { 'h', 'hpp', 'hh', 'hxx' }
|
||||
end
|
||||
|
||||
for _, e in ipairs(candidates) do
|
||||
local cand = root .. '.' .. e
|
||||
if vim.fn.filereadable(cand) == 1 then
|
||||
edit_file(cand)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
vim.notify('No corresponding header/source found', vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
local function memory_profile_command(run_cmd)
|
||||
if vim.fn.has('mac') == 1 then
|
||||
return 'leaks --atExit -- ' .. run_cmd
|
||||
end
|
||||
return 'valgrind --leak-check=full --track-origins=yes ' .. run_cmd
|
||||
end
|
||||
|
||||
vim.keymap.set('n', '<leader>cb', function()
|
||||
local build_dir = cmake_build_dir('build')
|
||||
cmake_configure(build_dir)
|
||||
cmake_build(build_dir)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Build' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>ct', function()
|
||||
local build_dir = cmake_build_dir('build')
|
||||
cmake_ctest(build_dir)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Test' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>ch', switch_source_header, vim.tbl_extend('force', opts, { desc = 'C: Switch header/source' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cg', toggle_debugger_repl, vim.tbl_extend('force', opts, { desc = 'C: Toggle debugger REPL' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cm', function()
|
||||
local cmd = vim.fn.input('Memory profile run: ', './bin/')
|
||||
if cmd == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('!' .. memory_profile_command(cmd))
|
||||
end, vim.tbl_extend('force', opts, { desc = 'C: Memory profile (leaks/valgrind)' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rr', toggle_debugger_repl, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Toggle' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rf', function()
|
||||
local cmd = vim.fn.input('Run: ', './bin/')
|
||||
if cmd == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('!' .. cmd)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Run' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Ri', function()
|
||||
local dbg = vim.__c_dbg_term
|
||||
if dbg and dbg.send and dbg.is_open and dbg:is_open() then
|
||||
dbg:send('\x03')
|
||||
end
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Interrupt' }))
|
||||
|
||||
256
ftplugin/cpp.lua
Normal file
256
ftplugin/cpp.lua
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
vim.opt_local.cinoptions = vim.opt_local.cinoptions + '0{1' -- Places opening brace on the same line as function signature
|
||||
vim.opt_local.smartindent = true -- Automatically adds indentation where needed
|
||||
vim.opt_local.tabstop = 4 -- Set tab stop to 4 spaces
|
||||
vim.opt_local.shiftwidth = 4 -- Set shift width to 4 spaces
|
||||
vim.opt_local.softtabstop = 4 -- Use spaces instead of tabs
|
||||
|
||||
vim.api.nvim_create_user_command('RunCpp', function(opts)
|
||||
vim.cmd('w') -- Save the current file
|
||||
local filename = vim.fn.expand('%') -- Get current file name
|
||||
local output = 'bin/' .. vim.fn.expand('%:r'):match('([^/]+)$') .. '.out' -- Output file with .out extension
|
||||
|
||||
-- Use provided compiler or default to 'clang++'
|
||||
local compiler = opts.args ~= '' and opts.args or 'clang++'
|
||||
|
||||
-- Ensure the output directory exists
|
||||
vim.fn.mkdir('bin', 'p')
|
||||
|
||||
-- Compile and run the C++ code
|
||||
vim.cmd('!' .. compiler .. ' ' .. filename .. ' -o ' .. output .. ' && ./' .. output)
|
||||
end, { nargs = '?' }) -- Accepts one optional argument for the compiler
|
||||
|
||||
local function cmake_build_dir(name)
|
||||
local dir = vim.fn.getcwd() .. '/' .. (name or 'build')
|
||||
if vim.fn.isdirectory(dir) == 0 then
|
||||
vim.fn.mkdir(dir, 'p')
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
local function cmake_configure(build_dir, extra_args)
|
||||
local args = extra_args or ''
|
||||
local bin_dir = vim.fn.getcwd() .. '/bin'
|
||||
vim.fn.mkdir(bin_dir, 'p')
|
||||
local out_args =
|
||||
' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' .. vim.fn.shellescape(bin_dir) .. ' -DCMAKE_LIBRARY_OUTPUT_DIRECTORY='
|
||||
.. vim.fn.shellescape(bin_dir)
|
||||
.. ' -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY='
|
||||
.. vim.fn.shellescape(bin_dir)
|
||||
vim.cmd('!cmake -S . -B ' .. vim.fn.fnameescape(build_dir) .. out_args .. ' ' .. args)
|
||||
end
|
||||
|
||||
local function cmake_build(build_dir, extra_args)
|
||||
local args = extra_args or ''
|
||||
vim.cmd('!cmake --build ' .. vim.fn.fnameescape(build_dir) .. ' ' .. args)
|
||||
end
|
||||
|
||||
local function cmake_ctest(build_dir)
|
||||
vim.cmd('!ctest --test-dir ' .. vim.fn.fnameescape(build_dir) .. ' --output-on-failure')
|
||||
end
|
||||
|
||||
local function select_cmake_preset()
|
||||
local lines = vim.fn.systemlist('cmake --list-presets')
|
||||
local presets = {}
|
||||
for _, line in ipairs(lines) do
|
||||
local name = line:match('^%s*"([^"]+)"')
|
||||
if name then
|
||||
table.insert(presets, name)
|
||||
end
|
||||
end
|
||||
if #presets == 0 then
|
||||
return
|
||||
end
|
||||
vim.ui.select(presets, { prompt = 'CMake preset' }, function(choice)
|
||||
if choice then
|
||||
vim.g.cmake_preset = choice
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function cmake_configure_with_preset()
|
||||
local preset = vim.g.cmake_preset
|
||||
if preset and preset ~= '' then
|
||||
vim.cmd('!cmake --preset ' .. preset)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function cmake_build_with_preset()
|
||||
local preset = vim.g.cmake_preset
|
||||
if preset and preset ~= '' then
|
||||
vim.cmd('!cmake --build --preset ' .. preset)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function toggle_debugger_repl()
|
||||
local dbg = vim.__cpp_dbg_term
|
||||
if dbg and dbg.is_open and dbg:is_open() then
|
||||
dbg:close()
|
||||
return
|
||||
end
|
||||
|
||||
local ok_term, term_mod = pcall(require, 'toggleterm.terminal')
|
||||
if not ok_term then
|
||||
return
|
||||
end
|
||||
|
||||
local cmd
|
||||
if vim.fn.has('mac') == 1 then
|
||||
cmd = 'lldb'
|
||||
else
|
||||
cmd = 'gdb'
|
||||
end
|
||||
|
||||
if not vim.__cpp_dbg_term then
|
||||
vim.__cpp_dbg_term = term_mod.Terminal:new({
|
||||
cmd = cmd,
|
||||
direction = 'vertical',
|
||||
size = function()
|
||||
return math.floor(vim.o.columns * 0.4)
|
||||
end,
|
||||
hidden = true,
|
||||
on_open = function(term)
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 'n', 'q', '<cmd>close<CR>', { noremap = true, silent = true })
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 't', '<Esc><Esc>', '<C-\\><C-n>', { noremap = true, silent = true })
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
vim.__cpp_dbg_term:open()
|
||||
vim.cmd('wincmd p')
|
||||
end
|
||||
|
||||
local opts = { buffer = true, silent = true }
|
||||
|
||||
local function switch_source_header()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local function edit_file(fname)
|
||||
if not fname or fname == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('edit ' .. vim.fn.fnameescape(fname))
|
||||
end
|
||||
|
||||
local clangd
|
||||
for _, client in ipairs(vim.lsp.get_clients({ bufnr = bufnr })) do
|
||||
if client.name == 'clangd' then
|
||||
clangd = client
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if clangd then
|
||||
clangd.request('textDocument/switchSourceHeader', { uri = vim.uri_from_bufnr(bufnr) }, function(err, result)
|
||||
if err then
|
||||
vim.notify('clangd: switchSourceHeader failed', vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
if not result then
|
||||
vim.notify('No corresponding header/source found', vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
vim.schedule(function()
|
||||
edit_file(vim.uri_to_fname(result))
|
||||
end)
|
||||
end, bufnr)
|
||||
return
|
||||
end
|
||||
|
||||
local file = vim.api.nvim_buf_get_name(bufnr)
|
||||
if file == '' then
|
||||
return
|
||||
end
|
||||
|
||||
local root = file:gsub('%.[^%.]+$', '')
|
||||
local ext = vim.fn.fnamemodify(file, ':e')
|
||||
local candidates
|
||||
|
||||
if ext == 'h' or ext == 'hpp' or ext == 'hh' or ext == 'hxx' then
|
||||
candidates = { 'cpp', 'cc', 'cxx', 'c' }
|
||||
elseif ext == 'c' then
|
||||
candidates = { 'h' }
|
||||
else
|
||||
candidates = { 'h', 'hpp', 'hh', 'hxx' }
|
||||
end
|
||||
|
||||
for _, e in ipairs(candidates) do
|
||||
local cand = root .. '.' .. e
|
||||
if vim.fn.filereadable(cand) == 1 then
|
||||
edit_file(cand)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
vim.notify('No corresponding header/source found', vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
local function memory_profile_command(run_cmd)
|
||||
if vim.fn.has('mac') == 1 then
|
||||
return 'leaks --atExit -- ' .. run_cmd
|
||||
end
|
||||
return 'valgrind --leak-check=full --track-origins=yes ' .. run_cmd
|
||||
end
|
||||
|
||||
vim.keymap.set('n', '<leader>cS', select_cmake_preset, vim.tbl_extend('force', opts, { desc = 'CMake: Select preset' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cb', function()
|
||||
if cmake_configure_with_preset() then
|
||||
cmake_build_with_preset()
|
||||
return
|
||||
end
|
||||
local build_dir = cmake_build_dir('build')
|
||||
cmake_configure(build_dir)
|
||||
cmake_build(build_dir)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Build' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>ct', function()
|
||||
local build_dir = cmake_build_dir('build')
|
||||
cmake_ctest(build_dir)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Test' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cr', function()
|
||||
local cmd = vim.fn.input('Run command: ', './')
|
||||
if cmd == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('!' .. cmd)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Run (prompt)' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>ch', switch_source_header, vim.tbl_extend('force', opts, { desc = 'C++: Switch header/source' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cg', toggle_debugger_repl, vim.tbl_extend('force', opts, { desc = 'C++: Toggle debugger REPL' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>cm', function()
|
||||
local cmd = vim.fn.input('Memory profile run: ', './bin/')
|
||||
if cmd == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('!' .. memory_profile_command(cmd))
|
||||
end, vim.tbl_extend('force', opts, { desc = 'C++: Memory profile (leaks/valgrind)' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rr', toggle_debugger_repl, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Toggle' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rf', function()
|
||||
local cmd = vim.fn.input('Run: ', './bin/')
|
||||
if cmd == '' then
|
||||
return
|
||||
end
|
||||
vim.cmd('!' .. cmd)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Run' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Ri', function()
|
||||
local dbg = vim.__cpp_dbg_term
|
||||
if dbg and dbg.send and dbg.is_open and dbg:is_open() then
|
||||
dbg:send('\x03')
|
||||
end
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Interrupt' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>ca', function()
|
||||
local build_dir = cmake_build_dir('build-asan')
|
||||
local flags = "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS='-fsanitize=address -fno-omit-frame-pointer' -DCMAKE_CXX_FLAGS='-fsanitize=address -fno-omit-frame-pointer'"
|
||||
cmake_configure(build_dir, flags)
|
||||
cmake_build(build_dir)
|
||||
end, vim.tbl_extend('force', opts, { desc = 'CMake: Build (ASan)' }))
|
||||
1
ftplugin/crontab.lua
Normal file
1
ftplugin/crontab.lua
Normal file
|
|
@ -0,0 +1 @@
|
|||
vim.opt_local.fixeol = false
|
||||
2
ftplugin/dockerfile.lua
Normal file
2
ftplugin/dockerfile.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
vim.opt_local.expandtab = true
|
||||
vim.opt_local.shiftwidth = 2
|
||||
35
ftplugin/go.lua
Normal file
35
ftplugin/go.lua
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
-- Set buffer-local options for Go files
|
||||
vim.bo.expandtab = true -- Use spaces instead of tabs
|
||||
vim.opt_local.shiftwidth = 4 -- Indent width
|
||||
vim.opt_local.tabstop = 4 -- Tab width
|
||||
vim.opt_local.softtabstop = 4 -- Soft tab width for alignment
|
||||
|
||||
vim.bo.commentstring = '// %s' -- Comment format for Go
|
||||
vim.opt_local.comments = 's1:/*,mb:*,ex:*/,://'
|
||||
|
||||
-- Define a buffer-local key mapping to trigger Go debugging
|
||||
vim.keymap.set('n', '<leader>dd', function()
|
||||
require('dap-go').debug_test()
|
||||
end, { buffer = 0, desc = 'Debug Go Test' }) -- Buffer-local key mapping
|
||||
|
||||
-- Load nvim-dap-go and set up configurations
|
||||
require('dap-go').setup()
|
||||
|
||||
-- Go DAP configuration
|
||||
local dap = require('dap')
|
||||
|
||||
-- Define Go DAP configurations
|
||||
dap.configurations.go = {
|
||||
{
|
||||
type = 'go',
|
||||
name = 'Launch File',
|
||||
request = 'launch',
|
||||
program = '${file}',
|
||||
},
|
||||
{
|
||||
type = 'go',
|
||||
name = 'Launch Package',
|
||||
request = 'launch',
|
||||
program = '${workspaceFolder}',
|
||||
},
|
||||
}
|
||||
16
ftplugin/json.lua
Normal file
16
ftplugin/json.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Use 2 spaces for indentation
|
||||
vim.bo.shiftwidth = 2
|
||||
vim.bo.tabstop = 2
|
||||
vim.bo.expandtab = true
|
||||
|
||||
vim.bo.textwidth = 100
|
||||
vim.wo.wrap = false
|
||||
|
||||
-- Enable spell-check for JSON comments
|
||||
vim.wo.spell = true
|
||||
|
||||
-- Enable Folding for JSON
|
||||
vim.wo.foldmethod = 'syntax'
|
||||
|
||||
-- Set conceal level for better JSON readability (e.g., hiding quotes)
|
||||
vim.wo.conceallevel = 2
|
||||
163
ftplugin/julia.lua
Normal file
163
ftplugin/julia.lua
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
local ok_conform, conform = pcall(require, 'conform')
|
||||
if ok_conform then
|
||||
conform.formatters = conform.formatters or {}
|
||||
conform.formatters_by_ft = conform.formatters_by_ft or {}
|
||||
|
||||
conform.formatters_by_ft.julia = { 'juliaformatter' }
|
||||
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
if vim.api.nvim_buf_line_count(0) > 2000 then
|
||||
return
|
||||
end
|
||||
conform.format({ timeout_ms = 2000, lsp_fallback = false })
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
if not vim.g.julia_repl_setup_done then
|
||||
vim.g.julia_repl_setup_done = true
|
||||
|
||||
local ok_toggleterm, toggleterm_terminal = pcall(require, 'toggleterm.terminal')
|
||||
if not ok_toggleterm then
|
||||
return
|
||||
end
|
||||
|
||||
local Terminal = toggleterm_terminal.Terminal
|
||||
|
||||
local function get_startup_commands()
|
||||
return [[
|
||||
ENV["JULIA_NOVERSIONS"] = "yes"
|
||||
try
|
||||
using Revise
|
||||
catch
|
||||
end
|
||||
println("\033[2J\033[H")
|
||||
]]
|
||||
end
|
||||
|
||||
local function new_julia_terminal()
|
||||
return Terminal:new({
|
||||
cmd = 'julia --banner=no',
|
||||
direction = 'vertical',
|
||||
size = 80,
|
||||
hidden = true,
|
||||
on_open = function(term)
|
||||
vim.defer_fn(function()
|
||||
term:send(get_startup_commands())
|
||||
end, 100)
|
||||
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 'n', 'q', '<cmd>close<CR>', { noremap = true, silent = true })
|
||||
vim.api.nvim_buf_set_keymap(term.bufnr, 't', '<Esc>', '<C-\\><C-n>', { noremap = true, silent = true })
|
||||
|
||||
local win = term.window or vim.api.nvim_get_current_win()
|
||||
vim.api.nvim_set_option_value('signcolumn', 'no', { win = win })
|
||||
vim.api.nvim_set_option_value('number', false, { win = win })
|
||||
vim.api.nvim_set_option_value('relativenumber', false, { win = win })
|
||||
end,
|
||||
on_exit = function(_)
|
||||
vim.cmd('stopinsert')
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
vim.__julia_repl_terminal = new_julia_terminal()
|
||||
|
||||
vim.api.nvim_create_user_command('JuliaREPL', function()
|
||||
local julia = vim.__julia_repl_terminal
|
||||
if not julia then
|
||||
vim.__julia_repl_terminal = new_julia_terminal()
|
||||
julia = vim.__julia_repl_terminal
|
||||
end
|
||||
|
||||
if julia:is_open() then
|
||||
julia:close()
|
||||
else
|
||||
julia:open()
|
||||
vim.cmd('wincmd p')
|
||||
end
|
||||
end, {})
|
||||
|
||||
vim.keymap.set('n', '<leader>Rr', '<cmd>JuliaREPL<CR>', { noremap = true, silent = true, desc = 'Run/REPL: Toggle' })
|
||||
end
|
||||
|
||||
local function send_to_julia(code)
|
||||
local julia = vim.__julia_repl_terminal
|
||||
if not julia then
|
||||
return
|
||||
end
|
||||
|
||||
if not julia:is_open() then
|
||||
julia:open()
|
||||
vim.defer_fn(function()
|
||||
julia:send(code)
|
||||
vim.cmd('wincmd p')
|
||||
end, 200)
|
||||
else
|
||||
julia:send(code)
|
||||
vim.cmd('wincmd p')
|
||||
end
|
||||
end
|
||||
|
||||
local function get_cell_content()
|
||||
local cur_line = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||
local start_line, end_line = cur_line, cur_line
|
||||
|
||||
while start_line > 1 and not lines[start_line - 1]:match('^#%%') and not lines[start_line - 1]:match('^##') do
|
||||
start_line = start_line - 1
|
||||
end
|
||||
|
||||
while end_line < #lines and not lines[end_line + 1]:match('^#%%') and not lines[end_line + 1]:match('^##') do
|
||||
end_line = end_line + 1
|
||||
end
|
||||
|
||||
return table.concat(vim.api.nvim_buf_get_lines(0, start_line - 1, end_line, false), '\n')
|
||||
end
|
||||
|
||||
local opts = { buffer = true, silent = true }
|
||||
|
||||
vim.keymap.set('n', '<leader>Rf', function()
|
||||
send_to_julia('using Revise\nincludet("' .. vim.fn.expand('%:p') .. '")\n')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Run file' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rl', function()
|
||||
send_to_julia(vim.api.nvim_get_current_line() .. '\n')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Send line' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rc', function()
|
||||
send_to_julia(get_cell_content() .. '\n')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Send cell' }))
|
||||
|
||||
vim.keymap.set('v', '<leader>Rs', function()
|
||||
local start_pos = vim.fn.getpos("'<")[2]
|
||||
local end_pos = vim.fn.getpos("'>")[2]
|
||||
local code = table.concat(vim.api.nvim_buf_get_lines(0, start_pos - 1, end_pos, false), '\n')
|
||||
send_to_julia(code .. '\n')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Send selection' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Ri', function()
|
||||
send_to_julia('\x03')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Interrupt' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>jb', function()
|
||||
send_to_julia('using BenchmarkTools\n@btime ' .. vim.api.nvim_get_current_line() .. '\n')
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Julia: Benchmark line' }))
|
||||
|
||||
vim.keymap.set('n', '<leader>Rx', function()
|
||||
local julia = vim.__julia_repl_terminal
|
||||
if julia then
|
||||
pcall(function()
|
||||
julia:shutdown()
|
||||
end)
|
||||
end
|
||||
vim.__julia_repl_terminal = Terminal:new({
|
||||
cmd = 'julia --banner=no',
|
||||
direction = 'vertical',
|
||||
size = 80,
|
||||
hidden = true,
|
||||
})
|
||||
end, vim.tbl_extend('force', opts, { desc = 'Run/REPL: Restart' }))
|
||||
|
||||
vim.g.julia_ftplugin_migrated = true
|
||||
9
ftplugin/lua.lua
Normal file
9
ftplugin/lua.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
vim.opt.expandtab = true
|
||||
vim.opt.shiftwidth = 2
|
||||
vim.opt.tabstop = 2
|
||||
vim.opt.softtabstop = 2
|
||||
|
||||
vim.opt_local.formatoptions:remove('o')
|
||||
|
||||
vim.opt_local.commentstring = '-- %s'
|
||||
vim.opt_local.colorcolumn = '120'
|
||||
24
ftplugin/make.lua
Normal file
24
ftplugin/make.lua
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-- Use tabs for indentation (Makefiles require tabs in rules)
|
||||
vim.bo.expandtab = false
|
||||
vim.bo.shiftwidth = 4
|
||||
vim.bo.tabstop = 4
|
||||
vim.bo.softtabstop = 4
|
||||
|
||||
-- Show trailing spaces and tabs explicitly for visibility
|
||||
vim.wo.list = true
|
||||
vim.opt.listchars:append({ tab = '→ ', trail = '·' })
|
||||
|
||||
-- Disable automatic comment continuation
|
||||
vim.opt_local.formatoptions:remove('o')
|
||||
|
||||
-- Highlight spaces before tabs (helps detect incorrect indentation)
|
||||
vim.cmd([[ match Error /^\s\+\t/ ]])
|
||||
|
||||
-- Enable line numbers for better navigation
|
||||
vim.wo.number = true
|
||||
|
||||
-- Disable spell checking for Makefiles
|
||||
vim.wo.spell = false
|
||||
|
||||
-- Set conceal level to 0 (Makefiles don't need concealment)
|
||||
vim.wo.conceallevel = 0
|
||||
101
ftplugin/markdown.lua
Normal file
101
ftplugin/markdown.lua
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
vim.opt_local.textwidth = 80
|
||||
vim.opt_local.wrap = true
|
||||
vim.opt_local.linebreak = true
|
||||
|
||||
-- Update PATH to include TeX binaries
|
||||
vim.env.PATH = vim.env.PATH .. ':/Library/TeX/texbin'
|
||||
|
||||
local function ensure_directory_exists(path)
|
||||
if not vim.fn.isdirectory(path) then
|
||||
vim.fn.mkdir(path, 'p')
|
||||
end
|
||||
end
|
||||
|
||||
local function generate_pdf_paths(filename)
|
||||
local base_dir = vim.fn.fnamemodify(filename, ':h')
|
||||
local target_dir = base_dir:gsub('/src$', '/pdf')
|
||||
local output_file = vim.fn.fnamemodify(filename, ':t:r') .. '.pdf'
|
||||
local output_path = target_dir .. '/' .. output_file
|
||||
|
||||
ensure_directory_exists(target_dir)
|
||||
|
||||
return target_dir, output_file, output_path
|
||||
end
|
||||
|
||||
local function build_pdf(filename, output_path)
|
||||
local command = string.format('buildnote %s %s', vim.fn.shellescape(filename), vim.fn.shellescape(output_path))
|
||||
return vim.fn.systemlist(command)
|
||||
end
|
||||
|
||||
local function open_pdf_in_zathura(pdf_path)
|
||||
local zathura_running = vim.fn.systemlist('pgrep -f "zathura ' .. vim.fn.shellescape(pdf_path) .. '"')
|
||||
|
||||
if #zathura_running == 0 then
|
||||
vim.fn.jobstart({ 'zathura', pdf_path }, { detach = true, stdout = 'null', stderr = 'null' })
|
||||
print('Opening PDF in Zathura: ' .. pdf_path)
|
||||
else
|
||||
print('Zathura is already running for this file.')
|
||||
end
|
||||
end
|
||||
|
||||
local function close_zathura()
|
||||
local _, _, output_path = generate_pdf_paths(vim.fn.expand('%:p'))
|
||||
vim.fn.system({ 'pkill', '-f', 'zathura ' .. output_path })
|
||||
end
|
||||
|
||||
vim.keymap.set('n', '<leader>Rv', function()
|
||||
local filename = vim.fn.expand('%:p')
|
||||
local _, _, output_path = generate_pdf_paths(filename)
|
||||
|
||||
local result = build_pdf(filename, output_path)
|
||||
|
||||
if #result == 0 then
|
||||
print('Error: Could not generate PDF.')
|
||||
return
|
||||
end
|
||||
|
||||
open_pdf_in_zathura(output_path)
|
||||
end, {
|
||||
desc = 'View output PDF in Zathura',
|
||||
noremap = true,
|
||||
silent = true,
|
||||
})
|
||||
|
||||
vim.keymap.set('n', '<leader>Rc', close_zathura, {
|
||||
desc = 'Close Zathura instance for the current PDF',
|
||||
noremap = true,
|
||||
silent = true,
|
||||
})
|
||||
|
||||
vim.keymap.set('n', '<leader>Rb', function()
|
||||
local filename = vim.fn.expand('%:p')
|
||||
local _, _, output_path = generate_pdf_paths(filename)
|
||||
|
||||
local result = build_pdf(filename, output_path)
|
||||
|
||||
if #result == 0 then
|
||||
print('Error: Could not generate PDF.')
|
||||
return
|
||||
end
|
||||
|
||||
print('PDF generated at: ' .. output_path)
|
||||
end, {
|
||||
desc = 'Build PDF',
|
||||
noremap = true,
|
||||
silent = true,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('BufWritePost', {
|
||||
pattern = '*note-*.md',
|
||||
callback = function()
|
||||
local filename = vim.fn.expand('%:p')
|
||||
local _, _, output_path = generate_pdf_paths(filename)
|
||||
|
||||
if vim.fn.filereadable(filename) == 1 then
|
||||
local command = string.format('buildnote %s %s', vim.fn.shellescape(filename), vim.fn.shellescape(output_path))
|
||||
vim.cmd('silent !' .. command)
|
||||
else
|
||||
print('Error: File ' .. filename .. ' does not exist.')
|
||||
end
|
||||
end,
|
||||
})
|
||||
4
ftplugin/ocaml.lua
Normal file
4
ftplugin/ocaml.lua
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
vim.opt.shiftwidth = 2
|
||||
|
||||
-- vim.keymap.set('n', '<space>cp', require('ocaml.mappings').dune_promote_file, { buffer = 0 })
|
||||
--
|
||||
145
ftplugin/python.lua
Normal file
145
ftplugin/python.lua
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
-- Set buffer-local options for Python files
|
||||
vim.opt_local.expandtab = true -- Use spaces instead of tabs
|
||||
vim.opt_local.commentstring = '# %s' -- Python comment format
|
||||
vim.opt_local.shiftwidth = 4 -- Indent width
|
||||
vim.opt_local.tabstop = 4 -- Tab width
|
||||
vim.opt_local.softtabstop = 4 -- Soft tab width for alignment
|
||||
vim.opt_local.fileformat = 'unix' -- Use Unix line endings
|
||||
vim.opt_local.textwidth = 79 -- Maximum text width
|
||||
vim.opt_local.colorcolumn = '80' -- Highlight column 80
|
||||
|
||||
local dap = require('dap')
|
||||
|
||||
local function get_python_path()
|
||||
local cwd = vim.fn.getcwd()
|
||||
if vim.env.VIRTUAL_ENV then
|
||||
return vim.env.VIRTUAL_ENV .. '/bin/python' -- Use virtual environment if set
|
||||
elseif vim.fn.executable(cwd .. '/venv/bin/python') == 1 then
|
||||
return cwd .. '/venv/bin/python' -- Use project-specific venv
|
||||
elseif vim.fn.executable(cwd .. '/.venv/bin/python') == 1 then
|
||||
return cwd .. '/.venv/bin/python' -- Use hidden project venv
|
||||
else
|
||||
return 'python' -- Fallback to system Python
|
||||
end
|
||||
end
|
||||
|
||||
local function get_ipython_cmd()
|
||||
local cwd = vim.fn.getcwd()
|
||||
local venv = vim.env.VIRTUAL_ENV
|
||||
if not venv then
|
||||
if vim.fn.isdirectory(cwd .. '/.venv') == 1 then
|
||||
venv = cwd .. '/.venv'
|
||||
elseif vim.fn.isdirectory(cwd .. '/venv') == 1 then
|
||||
venv = cwd .. '/venv'
|
||||
end
|
||||
end
|
||||
|
||||
if venv and vim.fn.executable(venv .. '/bin/ipython') == 1 then
|
||||
return vim.fn.shellescape(venv .. '/bin/ipython')
|
||||
end
|
||||
|
||||
local py = get_python_path()
|
||||
if py:find('/') then
|
||||
py = vim.fn.shellescape(py)
|
||||
end
|
||||
return py .. ' -m IPython'
|
||||
end
|
||||
|
||||
local function get_ipython_argv()
|
||||
local cwd = vim.fn.getcwd()
|
||||
local venv = vim.env.VIRTUAL_ENV
|
||||
if not venv then
|
||||
if vim.fn.isdirectory(cwd .. '/.venv') == 1 then
|
||||
venv = cwd .. '/.venv'
|
||||
elseif vim.fn.isdirectory(cwd .. '/venv') == 1 then
|
||||
venv = cwd .. '/venv'
|
||||
end
|
||||
end
|
||||
|
||||
if venv and vim.fn.executable(venv .. '/bin/ipython') == 1 then
|
||||
return { venv .. '/bin/ipython' }
|
||||
end
|
||||
|
||||
return { get_python_path(), '-m', 'IPython' }
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
group = vim.api.nvim_create_augroup('lsp_attach_disable_ruff_hover', { clear = true }),
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
if client and client.name == 'ruff' then
|
||||
client.server_capabilities.hoverProvider = false
|
||||
end
|
||||
end,
|
||||
desc = 'Disable hover capability from Ruff',
|
||||
})
|
||||
|
||||
require('dap-python').setup(get_python_path())
|
||||
|
||||
dap.configurations.python = {
|
||||
{
|
||||
type = 'python',
|
||||
request = 'launch',
|
||||
name = 'Launch Program',
|
||||
program = '${file}',
|
||||
console = 'integratedTerminal',
|
||||
},
|
||||
{
|
||||
type = 'python',
|
||||
request = 'launch',
|
||||
name = 'Profile Memory',
|
||||
program = '${file}',
|
||||
args = { '--profile-memory' },
|
||||
},
|
||||
}
|
||||
|
||||
vim.keymap.set('n', '<leader>Rr', function()
|
||||
local screen_width_percentage = 25
|
||||
local function find_terminal_buffer()
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_is_loaded(bufnr) and vim.bo[bufnr].buftype == 'terminal' and vim.b[bufnr].python_repl == true then
|
||||
return bufnr
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function toggle_terminal_window(bufnr)
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
||||
vim.api.nvim_win_hide(win)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
vim.cmd('vsplit')
|
||||
vim.api.nvim_win_set_buf(0, bufnr)
|
||||
vim.cmd.wincmd('L')
|
||||
vim.api.nvim_win_set_width(0, math.floor(vim.o.columns / (100 / screen_width_percentage)))
|
||||
end
|
||||
|
||||
local function create_terminal()
|
||||
vim.cmd('vnew')
|
||||
vim.cmd.wincmd('L')
|
||||
|
||||
vim.api.nvim_win_set_width(0, math.floor(vim.o.columns / (100 / screen_width_percentage)))
|
||||
|
||||
vim.b.python_repl = true
|
||||
local job_id = vim.fn.termopen(get_ipython_argv())
|
||||
if job_id and job_id > 0 then
|
||||
vim.g.slime_default_config = { jobid = job_id }
|
||||
end
|
||||
vim.cmd('startinsert')
|
||||
end
|
||||
|
||||
local term_bufnr = find_terminal_buffer()
|
||||
if term_bufnr then
|
||||
local job_id = vim.b[term_bufnr].terminal_job_id
|
||||
if job_id and job_id > 0 then
|
||||
vim.g.slime_default_config = { jobid = job_id }
|
||||
end
|
||||
toggle_terminal_window(term_bufnr)
|
||||
else
|
||||
create_terminal()
|
||||
end
|
||||
end, { desc = 'Run/REPL: Toggle Python REPL' })
|
||||
60
ftplugin/rust.lua
Normal file
60
ftplugin/rust.lua
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
-- Set buffer-local options for Rust files
|
||||
vim.opt_local.expandtab = true -- Use spaces instead of tabs
|
||||
vim.opt_local.autoindent = true -- Maintain indentation levels
|
||||
vim.opt_local.smartindent = true -- Smart indentation
|
||||
vim.opt_local.shiftwidth = 4 -- Indent width
|
||||
vim.opt_local.tabstop = 4 -- Tab width
|
||||
vim.opt_local.softtabstop = 4 -- Soft tab width for alignment
|
||||
vim.opt_local.textwidth = 80 -- Maximum text width
|
||||
vim.opt_local.colorcolumn = '80' -- Highlight column 80
|
||||
|
||||
vim.keymap.set('n', '<leader>Rf', '<CMD>Cargo run<CR>', { desc = 'Run/REPL: Run (Cargo)', noremap = true, buffer = 0 })
|
||||
vim.keymap.set('n', '<leader>Rb', '<CMD>Cargo check<CR>', { desc = 'Run/REPL: Build/Check (Cargo)', noremap = true, buffer = 0 })
|
||||
|
||||
local dap = require('dap')
|
||||
local rust_tools = require('rust-tools')
|
||||
local mason_registry = require('mason-registry')
|
||||
|
||||
local function get_codelldb_paths()
|
||||
local codelldb_package = mason_registry.get_package('codelldb')
|
||||
if not codelldb_package:is_installed() then
|
||||
vim.notify('codelldb is not installed. Please install it via mason.nvim.', vim.log.levels.ERROR)
|
||||
return nil, nil
|
||||
end
|
||||
local codelldb_path = codelldb_package:get_install_path()
|
||||
local adapter = codelldb_path .. '/extension/adapter/codelldb'
|
||||
local lib = codelldb_path .. '/extension/lldb/lib/liblldb.so'
|
||||
return adapter, lib
|
||||
end
|
||||
|
||||
local codelldb_adapter, codelldb_lib = get_codelldb_paths()
|
||||
if codelldb_adapter and codelldb_lib then
|
||||
rust_tools.setup({
|
||||
tools = {
|
||||
autosethints = true,
|
||||
inlay_hints = {
|
||||
show_parameter_hints = true,
|
||||
parameter_hints_prefix = '<- ',
|
||||
other_hints_prefix = '=> ',
|
||||
},
|
||||
},
|
||||
server = {
|
||||
on_attach = function(_, bufnr)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>dR', '<cmd>RustDebuggables<CR>', { noremap = true, silent = true })
|
||||
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>RustHoverActions<CR>', { noremap = true, silent = true })
|
||||
end,
|
||||
},
|
||||
dap = {
|
||||
adapter = require('rust-tools.dap').get_codelldb_adapter(codelldb_adapter, codelldb_lib),
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
dap.configurations.rust = {
|
||||
{
|
||||
type = 'rust',
|
||||
request = 'launch',
|
||||
name = 'Launch Program',
|
||||
program = '${workspaceFolder}/target/debug/${workspaceFolderBasename}',
|
||||
},
|
||||
}
|
||||
5
ftplugin/sh.lua
Normal file
5
ftplugin/sh.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
vim.opt_local.expandtab = false
|
||||
vim.opt_local.shiftwidth = 2
|
||||
vim.opt_local.softtabstop = 2
|
||||
vim.opt_local.tabstop = 2
|
||||
vim.opt_local.textwidth = 80
|
||||
1
ftplugin/sql.lua
Normal file
1
ftplugin/sql.lua
Normal file
|
|
@ -0,0 +1 @@
|
|||
vim.opt_local.commentstring = '-- %s'
|
||||
17
ftplugin/yaml.lua
Normal file
17
ftplugin/yaml.lua
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
-- Set indentation for YAML files
|
||||
vim.bo.shiftwidth = 2
|
||||
vim.bo.tabstop = 2
|
||||
vim.bo.expandtab = true
|
||||
|
||||
-- Set text width to 80 to auto-break lines when formatting
|
||||
vim.bo.textwidth = 80
|
||||
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, false)[1] or ''
|
||||
if first_line ~= '---' then
|
||||
vim.api.nvim_buf_set_lines(0, 0, 0, false, { '---' })
|
||||
end
|
||||
end,
|
||||
})
|
||||
26
init.lua
Executable file
26
init.lua
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
-- Install package manager
|
||||
-- https://github.com/folke/lazy.nvim
|
||||
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
|
||||
if not vim.loop.fs_stat(lazypath) then
|
||||
vim.fn.system({
|
||||
'git',
|
||||
'clone',
|
||||
'--filter=blob:none',
|
||||
'https://github.com/folke/lazy.nvim.git',
|
||||
'--branch=stable', -- latest stable release
|
||||
lazypath,
|
||||
})
|
||||
end
|
||||
vim.opt.rtp:prepend(vim.env.LAZY or lazypath)
|
||||
|
||||
vim.cmd('filetype plugin on')
|
||||
|
||||
vim.g.mapleader = ' '
|
||||
vim.g.maplocalleader = ' '
|
||||
|
||||
require('config.lazy')
|
||||
require('config.autocmds')
|
||||
require('config.options')
|
||||
require('config.mappings')
|
||||
require('config.utils')
|
||||
require('config.themes')
|
||||
67
lua/config/autocmds.lua
Executable file
67
lua/config/autocmds.lua
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
-- Auto-format on save
|
||||
vim.cmd([[
|
||||
augroup FormatOnSave
|
||||
autocmd!
|
||||
autocmd BufWritePre * lua vim.lsp.buf.format({ async = false })
|
||||
augroup END
|
||||
]])
|
||||
|
||||
-- Augroup for Highlight on yank
|
||||
vim.cmd([[
|
||||
augroup YankHighlight
|
||||
autocmd!
|
||||
autocmd TextYankPost * lua vim.hl.on_yank()
|
||||
augroup END
|
||||
]])
|
||||
|
||||
-- Remove trailing whitespace
|
||||
vim.cmd([[
|
||||
augroup RemoveTrailingWhitespace
|
||||
autocmd!
|
||||
autocmd BufWritePre * %s/\s\+$//e
|
||||
augroup END
|
||||
]])
|
||||
|
||||
-- Append newline at EOF, excluding YAML files
|
||||
vim.cmd([[
|
||||
augroup append_newline_at_eof
|
||||
autocmd!
|
||||
autocmd BufWritePre * silent! if !empty(getline('$')) && getline('$') !~# '\n$' && &filetype != 'yaml' | call append(line('$'), '') | endif
|
||||
augroup END
|
||||
]])
|
||||
|
||||
local function augroup(name)
|
||||
return vim.api.nvim_create_augroup('lazyvim_' .. name, { clear = true })
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd('VimEnter', {
|
||||
group = augroup('autoupdate'),
|
||||
callback = function()
|
||||
if require('lazy.status').has_updates() then
|
||||
require('lazy').update({ show = false })
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('User', {
|
||||
pattern = 'LazyCheck',
|
||||
-- pattern = "LazyVimStarted",
|
||||
desc = 'Update lazy.nvim plugins',
|
||||
callback = function()
|
||||
vim.schedule(function()
|
||||
require('lazy').sync({ wait = false, show = false })
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('TermOpen', {
|
||||
pattern = '*',
|
||||
group = vim.api.nvim_create_augroup('custom-term-open', { clear = true }),
|
||||
desc = 'Automatically start insert mode in terminal buffers',
|
||||
callback = function()
|
||||
vim.cmd('startinsert')
|
||||
vim.cmd('setlocal nonumber norelativenumber')
|
||||
vim.cmd('normal! G')
|
||||
vim.cmd('tnoremap <esc><esc> <c-\\><c-n>')
|
||||
end,
|
||||
})
|
||||
37
lua/config/lazy.lua
Executable file
37
lua/config/lazy.lua
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
local opts = {
|
||||
git = { log = { '--since=3 days ago' } },
|
||||
ui = { custom_keys = { false } },
|
||||
colors = { themes = { 'monokai' } },
|
||||
checker = {
|
||||
enabled = true,
|
||||
-- notify = false,
|
||||
},
|
||||
performance = {
|
||||
rtp = {
|
||||
disabled_plugins = {
|
||||
'gzip',
|
||||
'tarPlugin',
|
||||
'tohtml',
|
||||
'tutor',
|
||||
'zipPlugin',
|
||||
},
|
||||
},
|
||||
},
|
||||
change_detection = {
|
||||
notify = false,
|
||||
},
|
||||
rocks = { enabled=false },
|
||||
}
|
||||
|
||||
require('lazy').setup({
|
||||
-- Git related plugins
|
||||
'tpope/vim-fugitive',
|
||||
'tpope/vim-rhubarb',
|
||||
|
||||
-- Detect tabstop and shiftwidth automatically
|
||||
-- 'tpope/vim-sleuth',
|
||||
{
|
||||
import = 'custom.plugins',
|
||||
exclude = 'custom.plugins.mason',
|
||||
},
|
||||
}, opts)
|
||||
162
lua/config/mappings.lua
Executable file
162
lua/config/mappings.lua
Executable file
|
|
@ -0,0 +1,162 @@
|
|||
local utils = require('config.utils')
|
||||
|
||||
-- Basic Keymaps
|
||||
-- Keymaps for better default experience
|
||||
-- See `:help vim.keymap.set()`
|
||||
vim.keymap.set({ 'n', 'v' }, '<Space>', '<Nop>', { silent = true })
|
||||
-- vim.keymap.set('n', '<leader>pv', vim.cmd.Ex, { desc = "[P]roject [V]iew" })
|
||||
vim.keymap.set('n', '<C-c>', '<ESC><ESC>', { silent = true })
|
||||
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>', { silent = true })
|
||||
|
||||
-- Remap for dealing with word wrap
|
||||
vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
|
||||
vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
|
||||
|
||||
-- Move lines
|
||||
vim.keymap.set('v', 'J', ":m '>+1<CR>gv=gv", { silent = true })
|
||||
vim.keymap.set('v', 'K', ":m '<-2<CR>gv=gv", { silent = true })
|
||||
vim.keymap.set('n', '>', '>gv', { silent = true })
|
||||
vim.keymap.set('n', '<', '<gv', { silent = true })
|
||||
|
||||
-- Miscellaneous Navigation Keymaps
|
||||
vim.keymap.set('n', 'J', 'mzj`z')
|
||||
vim.keymap.set('n', '<c-d>', '<C-d>zz', { desc = 'Half Page Jumping Up' })
|
||||
vim.keymap.set('n', '<c-u>', '<C-u>zz', { desc = 'Half Page Jumping Down' })
|
||||
vim.keymap.set('n', 'n', 'nzzzv', { noremap = true, silent = true })
|
||||
vim.keymap.set('n', 'N', 'Nzzzv', { noremap = true, silent = true })
|
||||
|
||||
vim.keymap.set('n', '<leader>n', function()
|
||||
vim.o.hlsearch = not vim.o.hlsearch
|
||||
end, { desc = 'Toggle Search Highlight' })
|
||||
|
||||
vim.api.nvim_set_keymap('n', 'gp', '<Nop>', { noremap = true, silent = true })
|
||||
vim.keymap.set('n', '<C-k>', '<cmd>cnext<CR>zz')
|
||||
vim.keymap.set('n', '<C-j>', '<cmd>cprev<CR>zz')
|
||||
vim.keymap.set('n', ']q', '<cmd>lnext<CR>zz', { desc = 'Location List Next' })
|
||||
vim.keymap.set('n', '[q', '<cmd>lprev<CR>zz', { desc = 'Location List Prev' })
|
||||
|
||||
-- Buffer Navigation Keymaps
|
||||
vim.keymap.set('n', '<leader>bn', '<cmd>bnext<CR>zz', { desc = 'Quick Nav Buf Next' })
|
||||
vim.keymap.set('n', '<leader>bp', '<cmd>bprev<CR>zz', { desc = 'Quick Nav Buf Prev' })
|
||||
vim.keymap.set('n', '<leader>bd', '<cmd>bdelete<CR>', { desc = 'Quick Nav Buf Delete' })
|
||||
vim.keymap.set('n', '<leader>bs', '<cmd>split<CR>', { desc = 'Openn Buf Horizontal Split' })
|
||||
vim.keymap.set('n', '<leader>bv', '<cmd>vsp<CR>', { desc = 'Open Buf Vertical Split' })
|
||||
-- vim.keymap.set('n', '<leader>bt', function()
|
||||
-- vim.cmd.vnew()
|
||||
-- vim.cmd.term()
|
||||
-- vim.cmd.wincmd('J')
|
||||
-- vim.api.nvim_win_set_height(0, 15)
|
||||
-- end, { desc = 'Open Buf in Terminal' })
|
||||
|
||||
-- -- open terminal for R and Python
|
||||
-- vim.keymap.set('n', '<leader>bR', '<cmd>terminal R<CR>', { desc = 'Open R Terminal' })
|
||||
-- vim.keymap.set('n', '<leader>bP', '<cmd>terminal python<CR>', { desc = 'Open Python Terminal' })
|
||||
|
||||
-- Editing Keymaps
|
||||
vim.keymap.set('x', '<leader>p', [["_dP"]], { desc = 'Paste without register' })
|
||||
vim.keymap.set({ 'n', 'v' }, '<leader>D', [["_d"]], { desc = 'Delete without register' })
|
||||
vim.keymap.set({ 'n', 'v' }, '<leader>y', '"+y', { desc = 'Copy to + register' })
|
||||
vim.keymap.set('n', '<leader>Y', '"+Y')
|
||||
-- replace current word in current scope
|
||||
vim.keymap.set(
|
||||
'n',
|
||||
'<leader>rw',
|
||||
':%s/\\<<C-r><C-w>\\>/<C-r><C-w>/gI<Left><Left><Left>',
|
||||
{ desc = '[R]eplace Current [W]ord in Current Scope' }
|
||||
)
|
||||
-- replace current word in file scope
|
||||
vim.keymap.set(
|
||||
'n',
|
||||
'<leader>rW',
|
||||
':%s/\\<<C-r><C-w>\\>/<C-r><C-w>/gI<Left><Left><Left>',
|
||||
{ desc = '[R]eplace Current [W]ord in File Scope' }
|
||||
)
|
||||
|
||||
-- Open vertical split pane
|
||||
|
||||
-- File Management Keymaps
|
||||
vim.keymap.set('n', '<C-f>', '<cmd>silent !tmux neww $HOME/.local/bin/tmux_sessionizer<CR>', { desc = 'Open Session' })
|
||||
vim.keymap.set('n', '<leader>fx', '<cmd>!chmod +x %<CR>', { desc = 'Set Current File to Executable', silent = true })
|
||||
|
||||
-- Telescope Keymaps
|
||||
-- See `:help telescope.builtin`
|
||||
local builtin = require('telescope.builtin')
|
||||
vim.keymap.set('n', '<leader>?', builtin.oldfiles, { desc = '[?] Find recently opened files' })
|
||||
vim.keymap.set('n', '<leader><space>', builtin.buffers, { desc = '[ ] Find existing buffers' })
|
||||
vim.keymap.set('n', '<leader>/', function()
|
||||
builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown({ winblend = 10, previewer = false }))
|
||||
end, { desc = '[/] Fuzzily search in current buffer' })
|
||||
vim.keymap.set('n', '<leader>gf', builtin.git_files, { desc = 'Search [G]it [F]iles' })
|
||||
vim.keymap.set('n', '<leader>gb', builtin.git_branches, { desc = 'Search [G]it [B]ranches' })
|
||||
vim.keymap.set('n', '<leader>gc', builtin.git_commits, { desc = 'Search [G]it [C]ommits' })
|
||||
vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
|
||||
|
||||
vim.keymap.set({ 'n', 'v' }, '<leader>sh', function()
|
||||
local query = utils.get_search_query()
|
||||
builtin.help_tags({ search = query, initial_mode = 'insert', default_text = query })
|
||||
end, { desc = '[S]earch [H]elp' })
|
||||
vim.keymap.set({ 'n', 'v' }, '<leader>sw', function()
|
||||
local query = utils.get_search_query()
|
||||
builtin.grep_string({ search = query, initial_mode = 'insert', default_text = query })
|
||||
end, { desc = '[S]earch current [W]ord' })
|
||||
vim.keymap.set('n', '<leader>sp', function()
|
||||
builtin.grep_string({ search = vim.fn.input('Grep Search > ') })
|
||||
end, { desc = '[S]earch [P]roject' })
|
||||
vim.keymap.set('n', '<leader>sG', builtin.live_grep, { desc = '[S]earch by [G]rep' })
|
||||
vim.keymap.set('n', '<leader>sg', ':LiveGrepGitRoot<cr>', { desc = '[S]earch by [G]rep on Git Root' })
|
||||
vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' })
|
||||
vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = '[S]earch [R]esume' })
|
||||
|
||||
-- Telescope config files
|
||||
vim.keymap.set('n', '<leader>fc', function()
|
||||
builtin.find_files({
|
||||
cwd = vim.fn.stdpath('config'),
|
||||
find_command = {
|
||||
'fd',
|
||||
'--type',
|
||||
'f',
|
||||
'--exclude',
|
||||
'README.md',
|
||||
'--exclude',
|
||||
'LICENSE.md',
|
||||
'--exclude',
|
||||
'init.lua',
|
||||
},
|
||||
})
|
||||
end, { desc = '[F]ind [C]onfig Files' })
|
||||
|
||||
vim.keymap.set('n', '<leader>fp', function()
|
||||
builtin.find_files({
|
||||
cwd = vim.fs.joinpath(vim.fn.stdpath('data'), 'lazy'),
|
||||
})
|
||||
end, { desc = '[F]ind [P]lugin Files' })
|
||||
|
||||
-- local runner = require("quarto.runner")
|
||||
-- vim.keymap.set('n', '<leader>qrc', runner.run_cell, { desc = '[R]un [C]ell', silent = true })
|
||||
-- vim.keymap.set('n', '<leader>qra', runner.run_above, { desc = '[R]un cell and [A]bove', silent = true })
|
||||
-- vim.keymap.set('n', "<leader>qrA", runner.run_all, { desc = "run all cells", silent = true })
|
||||
-- vim.keymap.set('n', "<leader>qrl", runner.run_line, { desc = "run line", silent = true })
|
||||
-- vim.keymap.set('v', '<leader>qr', runner.run_range, { desc = "run visual range", silent = true })
|
||||
-- vim.keymap.set('n', '<leader>qRA', function()
|
||||
-- runner.run_all(true)
|
||||
-- end, { desc = "run all cells of all languages", silent = true })
|
||||
|
||||
-- Refactoring Keymaps
|
||||
-- vim.keymap.set({ "x" }, "<leader>re", [[<Esc><Cmd>lua require('refactoring').refactor('Extract Function')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Extract Function" })
|
||||
-- vim.keymap.set(
|
||||
-- { "x" },
|
||||
-- "<leader>rf", [[<Esc><Cmd>lua require('refactoring').refactor('Extract Function To File')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Extract Function To File" }
|
||||
--)
|
||||
-- vim.keymap.set({ "x" }, "<leader>rv", [[<Esc><Cmd>lua require('refactoring').refactor('Extract Variable')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Extract Variable" })
|
||||
-- vim.keymap.set({ "n" }, "<leader>rI", [[<Cmd>lua require('refactoring').refactor('Inline Variable')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Inline Variable" })
|
||||
-- vim.keymap.set({ "n", "x" }, "<leader>ri", [[<Esc><Cmd>lua require('refactoring').refactor('Inline Variable')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Inline Variable" })
|
||||
--
|
||||
-- vim.keymap.set({ "n" }, "<leader>rb", [[<Esc><Cmd>lua require('refactoring').refactor('Extract Block')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Extract Block" })
|
||||
-- vim.keymap.set({ "n" }, "<leader>rbf", [[<Esc><Cmd>lua require('refactoring').refactor('Extract Block To File')<CR>]],
|
||||
-- { noremap = true, silent = true, expr = false, desc = "Extract Block To File" })
|
||||
141
lua/config/options.lua
Executable file
141
lua/config/options.lua
Executable file
|
|
@ -0,0 +1,141 @@
|
|||
local opt = vim.opt
|
||||
local g = vim.g
|
||||
|
||||
g.ftplugin_migrated_all = true
|
||||
|
||||
local opts = {
|
||||
-- Change cursor in insert mode
|
||||
guicursor = '',
|
||||
|
||||
-- set terminal tab title
|
||||
title = true,
|
||||
titlelen = 0,
|
||||
-- titlestring = 'nvim %t (%-15.25F)%a%r%m',
|
||||
titlestring = 'nvim %t (%-15.25f)%a%r%m',
|
||||
|
||||
-- Make line numbers default
|
||||
relativenumber = true,
|
||||
|
||||
--Enable noshowmode
|
||||
showmode = false,
|
||||
|
||||
-- Enable lazy redraw
|
||||
lazyredraw = true,
|
||||
|
||||
-- Enable break indent
|
||||
breakindent = true,
|
||||
|
||||
-- Indent Configuration
|
||||
tabstop = 4,
|
||||
softtabstop = 4,
|
||||
shiftwidth = 4,
|
||||
expandtab = true,
|
||||
|
||||
-- Disable line wrap
|
||||
wrap = false,
|
||||
|
||||
-- Save undo history
|
||||
swapfile = false,
|
||||
backup = false,
|
||||
undodir = vim.fn.stdpath('data') .. '/site/undodir',
|
||||
undofile = true,
|
||||
|
||||
-- Searching Configuration
|
||||
hlsearch = false,
|
||||
incsearch = true,
|
||||
|
||||
-- Case-insensitive searching UNLESS \C or capital in search
|
||||
ignorecase = true,
|
||||
smartcase = true,
|
||||
|
||||
-- Decrease update time
|
||||
updatetime = 50,
|
||||
timeoutlen = 300,
|
||||
|
||||
-- Set completeopt to have a better completion experience
|
||||
completeopt = 'menuone,noselect',
|
||||
|
||||
-- NOTE: You should make sure your terminal supports this
|
||||
termguicolors = true,
|
||||
scrolloff = 10,
|
||||
pyxversion = 3,
|
||||
|
||||
-- Sets how neovim will display certain whitespace characters in the editor.
|
||||
-- See :help 'list'
|
||||
-- and :help 'listchars'
|
||||
list = true,
|
||||
listchars = { tab = ' ', trail = '·', nbsp = '␣' },
|
||||
|
||||
-- Preview substitutions live, as you type!
|
||||
inccommand = 'split',
|
||||
}
|
||||
|
||||
for k, v in pairs(opts) do
|
||||
opt[k] = v
|
||||
end
|
||||
|
||||
local win_local = {
|
||||
signcolumn = 'yes',
|
||||
number = true,
|
||||
}
|
||||
|
||||
for k, v in pairs(win_local) do
|
||||
vim.wo[k] = v
|
||||
end
|
||||
|
||||
-- Disable built-in plugins
|
||||
local disabled_built_ins = {
|
||||
'2html_plugin',
|
||||
'getscript',
|
||||
'getscriptPlugin',
|
||||
'gzip',
|
||||
'logipat',
|
||||
'matchit',
|
||||
-- "netrw",
|
||||
'netrwFileHandlers',
|
||||
'loaded_remote_plugins',
|
||||
'loaded_tutor_mode_plugin',
|
||||
-- "netrwPlugin",
|
||||
-- "netrwSettings",
|
||||
'rrhelper',
|
||||
'spellfile_plugin',
|
||||
'tar',
|
||||
'tarPlugin',
|
||||
'vimball',
|
||||
'vimballPlugin',
|
||||
'zip',
|
||||
'zipPlugin',
|
||||
'matchparen',
|
||||
}
|
||||
|
||||
for _, plugin in pairs(disabled_built_ins) do
|
||||
g['loaded_' .. plugin] = 1
|
||||
end
|
||||
|
||||
-- Improve Neovim startup
|
||||
local global_let_opts = {
|
||||
loaded_python_provider = 0,
|
||||
loaded_python3_provider = 0,
|
||||
python_host_skip_check = 1,
|
||||
python3_host_skip_check = 1,
|
||||
python3_host_prog = '/usr/local/bin/python3',
|
||||
EditorConfig_core_mode = 'external_command',
|
||||
matchparen_timeout = 20,
|
||||
matchparen_insert_timeout = 20,
|
||||
}
|
||||
|
||||
for k, v in pairs(global_let_opts) do
|
||||
g[k] = v
|
||||
end
|
||||
|
||||
opt.formatoptions = 'l'
|
||||
opt.formatoptions = opt.formatoptions
|
||||
- 'a' -- Auto formatting is BAD.
|
||||
- 't' -- Don't auto format my code. I got linters for that.
|
||||
+ 'c' -- In general, I like it when comments respect textwidth
|
||||
- 'o' -- O and o, don't continue comments
|
||||
+ 'r' -- But do continue when pressing enter.
|
||||
+ 'n' -- Indent past the formatlistpat, not underneath it.
|
||||
+ 'j' -- Auto-remove comments if possible.
|
||||
- '2' -- I'm not in gradeschool anymore
|
||||
opt.iskeyword:append('_')
|
||||
0
lua/config/themes.lua
Executable file
0
lua/config/themes.lua
Executable file
23
lua/config/utils.lua
Executable file
23
lua/config/utils.lua
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
-- Function to get the current visual selection
|
||||
local function get_visual_selection()
|
||||
vim.cmd('noau normal! "vy"')
|
||||
local text = vim.fn.getreg('v')
|
||||
-- optional: clear register v
|
||||
-- vim.fn.setreg('v', '')
|
||||
|
||||
text = text:gsub('\n$', '') -- remove trailing newline
|
||||
return text
|
||||
end
|
||||
|
||||
-- Function to get the current search query
|
||||
local function get_search_query()
|
||||
local word_under_cursor = vim.fn.expand('<cword>')
|
||||
local visual_selection = get_visual_selection() -- call local function directly
|
||||
|
||||
return visual_selection ~= '' and visual_selection or word_under_cursor
|
||||
end
|
||||
|
||||
return {
|
||||
get_visual_selection = get_visual_selection,
|
||||
get_search_query = get_search_query,
|
||||
}
|
||||
17
lua/custom/plugins/atac.lua
Executable file
17
lua/custom/plugins/atac.lua
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
return {
|
||||
'NachoNievaG/atac.nvim',
|
||||
dependencies = { 'akinsho/toggleterm.nvim' },
|
||||
config = function()
|
||||
require('toggleterm').setup({
|
||||
open_mapping = [[<c-\>]],
|
||||
hide_numbers = true,
|
||||
shade_terminals = true,
|
||||
start_in_insert = true,
|
||||
persist_size = true,
|
||||
close_on_exit = true,
|
||||
})
|
||||
require('atac').setup({
|
||||
dir = '~/Documents/projects/', -- By default, the dir will be set as /tmp/atac
|
||||
})
|
||||
end,
|
||||
}
|
||||
66
lua/custom/plugins/auto-dark-mode.lua
Executable file
66
lua/custom/plugins/auto-dark-mode.lua
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
-- Define the function to set custom highlights for both themes
|
||||
local function set_lsp_highlights(mode)
|
||||
local hl = vim.api.nvim_set_hl
|
||||
|
||||
-- Shared diagnostic groups
|
||||
local diagnostic_groups = {
|
||||
'DiagnosticVirtualTextError',
|
||||
'DiagnosticVirtualTextWarn',
|
||||
'DiagnosticVirtualTextInfo',
|
||||
'DiagnosticVirtualTextHint',
|
||||
'DiagnosticUnderlineError',
|
||||
'DiagnosticUnderlineWarn',
|
||||
'DiagnosticUnderlineInfo',
|
||||
'DiagnosticUnderlineHint',
|
||||
}
|
||||
|
||||
if mode == 'dark' then
|
||||
local fg = 'NONE'
|
||||
local bg = '#272822'
|
||||
local comment = '#75715e'
|
||||
local line_nr = '#90908a'
|
||||
|
||||
for _, group in ipairs(diagnostic_groups) do
|
||||
hl(0, group, { fg = fg, bg = bg, underline = false })
|
||||
end
|
||||
|
||||
hl(0, 'TreesitterContext', { bg = bg })
|
||||
hl(0, 'TreesitterContextLineNumber', { fg = line_nr })
|
||||
hl(0, 'TreesitterContextSeparator', { fg = comment })
|
||||
elseif mode == 'light' then
|
||||
local bg = '#fdf6e3'
|
||||
local fg = '#657b83'
|
||||
local comment = '#586e75'
|
||||
|
||||
hl(0, 'LspDocumentHighlight', { bg = bg, fg = fg, underline = false })
|
||||
hl(0, 'DiagnosticVirtualTextError', { fg = '#dc322f' })
|
||||
hl(0, 'DiagnosticVirtualTextWarn', { fg = '#b58900' })
|
||||
hl(0, 'DiagnosticVirtualTextInfo', { fg = '#268bd2' })
|
||||
hl(0, 'DiagnosticVirtualTextHint', { fg = '#2aa198' })
|
||||
|
||||
hl(0, 'TreesitterContext', { bg = 'NONE' })
|
||||
hl(0, 'TreesitterContextLineNumber', { fg = comment })
|
||||
hl(0, 'TreesitterContextSeparator', { fg = comment })
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
'f-person/auto-dark-mode.nvim',
|
||||
opts = {
|
||||
update_interval = 2000,
|
||||
set_dark_mode = function()
|
||||
vim.api.nvim_set_option_value('background', 'dark', {})
|
||||
vim.cmd('colorscheme monokai_soda')
|
||||
|
||||
-- Apply custom highlight settings for Monokai
|
||||
set_lsp_highlights('dark')
|
||||
end,
|
||||
set_light_mode = function()
|
||||
vim.api.nvim_set_option_value('background', 'light', {})
|
||||
vim.cmd('colorscheme solarized')
|
||||
|
||||
-- Apply custom highlight settings for Solarized
|
||||
set_lsp_highlights('light')
|
||||
end,
|
||||
},
|
||||
}
|
||||
12
lua/custom/plugins/autopairs.lua
Executable file
12
lua/custom/plugins/autopairs.lua
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
return {
|
||||
'windwp/nvim-autopairs',
|
||||
dependencies = { 'hrsh7th/nvim-cmp' },
|
||||
event = 'InsertEnter',
|
||||
config = function()
|
||||
require('nvim-autopairs').setup({})
|
||||
-- If you want to automatically add `(` after selecting a function or method
|
||||
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
|
||||
local cmp = require('cmp')
|
||||
cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done())
|
||||
end,
|
||||
}
|
||||
143
lua/custom/plugins/cmp.lua
Executable file
143
lua/custom/plugins/cmp.lua
Executable file
|
|
@ -0,0 +1,143 @@
|
|||
return {
|
||||
'hrsh7th/nvim-cmp',
|
||||
event = { 'InsertEnter', 'CmdlineEnter' },
|
||||
dependencies = {
|
||||
-- Core snippet engine and integration
|
||||
{ 'L3MON4D3/LuaSnip' },
|
||||
{ 'saadparwaiz1/cmp_luasnip' },
|
||||
|
||||
-- LSP support
|
||||
{ 'hrsh7th/cmp-nvim-lsp' },
|
||||
|
||||
-- Predefined snippets, lazy-loaded
|
||||
{ 'rafamadriz/friendly-snippets' },
|
||||
|
||||
-- Additional sources
|
||||
{ 'hrsh7th/cmp-path' },
|
||||
{ 'hrsh7th/cmp-buffer' }, -- Will be filtered later
|
||||
|
||||
-- Cmdline & git
|
||||
{ 'hrsh7th/cmp-cmdline' },
|
||||
{ 'petertriho/cmp-git', ft = { 'gitcommit' } },
|
||||
|
||||
-- UI enhancement
|
||||
{ 'onsails/lspkind-nvim' },
|
||||
},
|
||||
config = function()
|
||||
local cmp = require('cmp')
|
||||
local luasnip = require('luasnip')
|
||||
local lspkind = require('lspkind')
|
||||
|
||||
-- Load only selected snippets
|
||||
require('luasnip.loaders.from_vscode').lazy_load({})
|
||||
|
||||
vim.opt.completeopt = { 'menu', 'menuone', 'noselect' }
|
||||
|
||||
luasnip.config.setup({
|
||||
history = true,
|
||||
updateevents = 'TextChanged,TextChangedI',
|
||||
})
|
||||
|
||||
-- Precompute mappings for insert and command mode
|
||||
local insert_mappings = {
|
||||
['<C-n>'] = cmp.mapping.select_next_item(),
|
||||
['<C-p>'] = cmp.mapping.select_prev_item(),
|
||||
['<C-b>'] = cmp.mapping.scroll_docs(-4),
|
||||
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
||||
['<Tab>'] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expand_or_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { 'i', 's', 'c' }),
|
||||
['<S-Tab>'] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
elseif luasnip.jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { 'i', 's', 'c' }),
|
||||
['<CR>'] = cmp.mapping.confirm({ select = false }),
|
||||
}
|
||||
|
||||
local insert_sources = {
|
||||
{ name = 'nvim_lsp', priority = 1000 },
|
||||
{ name = 'luasnip', priority = 900 },
|
||||
{ name = 'path', priority = 750 },
|
||||
{ name = 'buffer', priority = 500, keyword_length = 5, max_item_count = 50 },
|
||||
}
|
||||
|
||||
cmp.setup({
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
luasnip.lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
mapping = insert_mappings,
|
||||
sources = insert_sources,
|
||||
formatting = {
|
||||
fields = { 'abbr', 'kind', 'menu' },
|
||||
expandable_indicator = false,
|
||||
format = function(entry, vim_item)
|
||||
if entry.source.name == 'nvim_lsp' then
|
||||
return lspkind.cmp_format({
|
||||
mode = 'symbol_text',
|
||||
maxwidth = 50,
|
||||
ellipsis_char = '...',
|
||||
menu = {
|
||||
nvim_lsp = '[LSP]',
|
||||
luasnip = '[Snip]',
|
||||
buffer = '[Buffer]',
|
||||
path = '[Path]',
|
||||
},
|
||||
})(entry, vim_item)
|
||||
end
|
||||
return vim_item
|
||||
end,
|
||||
},
|
||||
window = {
|
||||
completion = cmp.config.window.bordered(),
|
||||
documentation = cmp.config.window.bordered(),
|
||||
},
|
||||
performance = {
|
||||
filtering_context_budget = 5,
|
||||
async_budget = 5,
|
||||
confirm_resolve_timeout = 100,
|
||||
max_view_entries = 20,
|
||||
debounce = 60,
|
||||
throttle = 30,
|
||||
fetching_timeout = 200,
|
||||
},
|
||||
})
|
||||
|
||||
-- Cmdline setup
|
||||
cmp.setup.cmdline({ '/', '?' }, {
|
||||
mapping = insert_mappings,
|
||||
sources = { { name = 'buffer', keyword_length = 5 } },
|
||||
})
|
||||
|
||||
cmp.setup.cmdline(':', {
|
||||
mapping = insert_mappings,
|
||||
sources = { { name = 'path' }, { name = 'cmdline' } },
|
||||
window = {
|
||||
documentation = cmp.config.window.bordered({
|
||||
winhighlight = 'Normal:Normal,FloatBorder:FloatBorder,CursorLine:Visual,Search:None',
|
||||
border = 'rounded',
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
-- Git commit
|
||||
cmp.setup.filetype('gitcommit', {
|
||||
sources = {
|
||||
{ name = 'git', priority = 900 },
|
||||
{ name = 'buffer', keyword_length = 5 },
|
||||
},
|
||||
})
|
||||
end,
|
||||
}
|
||||
4
lua/custom/plugins/comments.lua
Executable file
4
lua/custom/plugins/comments.lua
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
return {
|
||||
'numToStr/Comment.nvim',
|
||||
opts = {},
|
||||
}
|
||||
28
lua/custom/plugins/context.lua
Normal file
28
lua/custom/plugins/context.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
return {
|
||||
'nvim-treesitter/nvim-treesitter-context',
|
||||
event = 'BufReadPost',
|
||||
config = function()
|
||||
require('treesitter-context').setup({
|
||||
max_lines = 3,
|
||||
multiwindow = false,
|
||||
multiline_threshold = 1,
|
||||
trim_scope = 'inner',
|
||||
mode = 'cursor', -- faster than 'cursor'
|
||||
separator = '─',
|
||||
on_attach = function(buf)
|
||||
-- disable for large files
|
||||
if vim.api.nvim_buf_line_count(buf) > 3000 then
|
||||
return false
|
||||
end
|
||||
-- disable for specific filetypes
|
||||
local disabled = { 'markdown', 'text', 'help', 'json', 'yaml' }
|
||||
if vim.tbl_contains(disabled, vim.bo[buf].filetype) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set('n', '<leader>uc', '<cmd>TSContext toggle<cr>')
|
||||
end,
|
||||
}
|
||||
43
lua/custom/plugins/copilot-chat.lua
Normal file
43
lua/custom/plugins/copilot-chat.lua
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
-- Copilot Chat (UI + prompts for Copilot)
|
||||
return {
|
||||
'CopilotC-Nvim/CopilotChat.nvim',
|
||||
cmd = {
|
||||
'CopilotChat',
|
||||
'CopilotChatClose',
|
||||
'CopilotChatExplain',
|
||||
'CopilotChatReview',
|
||||
'CopilotChatTests',
|
||||
'CopilotChatRefactor',
|
||||
'CopilotChatOptimize',
|
||||
'CopilotChatDocs',
|
||||
'CopilotChatToggle',
|
||||
},
|
||||
keys = {
|
||||
{ '<leader>C', '<cmd>CopilotChat<cr>', desc = 'Open CopilotChat' },
|
||||
{ '<leader>Cq', '<cmd>CopilotChatClose<cr>', desc = 'Close CopilotChat' },
|
||||
{ '<leader>Ce', '<cmd>CopilotChatExplain<cr>', desc = 'Explain code', mode = { 'n', 'v' } },
|
||||
{ '<leader>Cr', '<cmd>CopilotChatReview<cr>', desc = 'Review code', mode = { 'n', 'v' } },
|
||||
{ '<leader>Ct', '<cmd>CopilotChatTests<cr>', desc = 'Generate tests', mode = { 'n', 'v' } },
|
||||
{ '<leader>Cf', '<cmd>CopilotChatRefactor<cr>', desc = 'Refactor code', mode = { 'n', 'v' } },
|
||||
{ '<leader>Co', '<cmd>CopilotChatOptimize<cr>', desc = 'Optimize code', mode = { 'n', 'v' } },
|
||||
{ '<leader>Cd', '<cmd>CopilotChatDocs<cr>', desc = 'Generate docs', mode = { 'n', 'v' } },
|
||||
{ '<leader>Cp', '<cmd>CopilotChatToggle<cr>', desc = 'Toggle CopilotChat' },
|
||||
},
|
||||
build = 'make tiktoken',
|
||||
opts = {
|
||||
debug = false,
|
||||
show_help = true,
|
||||
prompts = {
|
||||
Explain = 'Please explain how the following code works.',
|
||||
Review = 'Please review the following code and provide suggestions for improvement.',
|
||||
Tests = 'Please explain how the selected code works, then generate unit tests for it.',
|
||||
Refactor = 'Please refactor the following code to improve its clarity and readability.',
|
||||
Optimize = 'Please optimize the following code for efficiency and performance.',
|
||||
Docs = 'Please generate documentation for the following code.',
|
||||
},
|
||||
},
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
'zbirenbaum/copilot.lua', -- make sure copilot is available
|
||||
},
|
||||
}
|
||||
18
lua/custom/plugins/copilot.lua
Executable file
18
lua/custom/plugins/copilot.lua
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
-- GitHub Copilot base plugin
|
||||
return {
|
||||
'zbirenbaum/copilot.lua',
|
||||
cmd = 'Copilot',
|
||||
event = 'InsertEnter',
|
||||
opts = {
|
||||
node_cmd = vim.fn.executable('node') == 1 and vim.fn.exepath('node') or 'node',
|
||||
suggestion = {
|
||||
auto_trigger = true,
|
||||
keymap = {
|
||||
accept_word = '<M-u>',
|
||||
accept_line = '<M-i>',
|
||||
-- next = '<M-[>',
|
||||
-- previous = '<M-]>',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
17
lua/custom/plugins/dadbod.lua
Executable file
17
lua/custom/plugins/dadbod.lua
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
return {
|
||||
'kristijanhusak/vim-dadbod-ui',
|
||||
dependencies = {
|
||||
{ 'tpope/vim-dadbod', lazy = true },
|
||||
{ 'kristijanhusak/vim-dadbod-completion', ft = { 'sql', 'mysql', 'plsql' }, lazy = true }, -- Optional
|
||||
},
|
||||
cmd = {
|
||||
'DBUI',
|
||||
'DBUIToggle',
|
||||
'DBUIAddConnection',
|
||||
'DBUIFindBuffer',
|
||||
},
|
||||
init = function()
|
||||
-- Your DBUI configuration
|
||||
vim.g.db_ui_use_nerd_fonts = 1
|
||||
end,
|
||||
}
|
||||
204
lua/custom/plugins/dap.lua
Executable file
204
lua/custom/plugins/dap.lua
Executable file
|
|
@ -0,0 +1,204 @@
|
|||
return {
|
||||
-- Define language plugins at top level to prevent luarocks installation
|
||||
{
|
||||
'mfussenegger/nvim-dap-python',
|
||||
ft = 'python',
|
||||
rocks = { enabled = false },
|
||||
},
|
||||
{
|
||||
'leoluz/nvim-dap-go',
|
||||
ft = 'go',
|
||||
rocks = { enabled = false },
|
||||
},
|
||||
{
|
||||
'mfussenegger/nvim-dap',
|
||||
dependencies = {
|
||||
'rcarriga/nvim-dap-ui',
|
||||
'nvim-neotest/nvim-nio',
|
||||
{ 'thehamsta/nvim-dap-virtual-text', opts = {} },
|
||||
'mfussenegger/nvim-dap-python',
|
||||
'leoluz/nvim-dap-go',
|
||||
'jay-babu/mason-nvim-dap.nvim',
|
||||
},
|
||||
config = function()
|
||||
local dap = require('dap')
|
||||
local dapui = require('dapui')
|
||||
|
||||
dapui.setup()
|
||||
|
||||
-- Mason handles debugger installation and configuration
|
||||
require('mason-nvim-dap').setup({
|
||||
automatic_installation = true,
|
||||
ensure_installed = { 'codelldb', 'python', 'delve' },
|
||||
handlers = {},
|
||||
})
|
||||
|
||||
-- Python setup with proper path detection
|
||||
local function get_python_path()
|
||||
-- Check if we're in a virtual environment
|
||||
local venv = os.getenv('VIRTUAL_ENV')
|
||||
if venv then
|
||||
local venv_python = venv .. '/bin/python'
|
||||
if vim.fn.executable(venv_python) == 1 then
|
||||
return venv_python
|
||||
end
|
||||
end
|
||||
|
||||
-- Fall back to system python3 or python
|
||||
local python3 = vim.fn.exepath('python3')
|
||||
if python3 ~= '' then
|
||||
return python3
|
||||
end
|
||||
|
||||
local python = vim.fn.exepath('python')
|
||||
if python ~= '' then
|
||||
return python
|
||||
end
|
||||
|
||||
-- Last resort - use system default
|
||||
return 'python3'
|
||||
end
|
||||
|
||||
require('dap-python').setup(get_python_path())
|
||||
|
||||
-- Go setup (helper does the heavy lifting)
|
||||
require('dap-go').setup()
|
||||
|
||||
-- C/C++ configurations
|
||||
dap.configurations.c = {
|
||||
{
|
||||
name = 'Launch',
|
||||
type = 'codelldb',
|
||||
request = 'launch',
|
||||
program = function()
|
||||
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
|
||||
end,
|
||||
cwd = '${workspaceFolder}',
|
||||
stopOnEntry = false,
|
||||
},
|
||||
{
|
||||
name = 'Launch with ASan',
|
||||
type = 'codelldb',
|
||||
request = 'launch',
|
||||
program = function()
|
||||
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
|
||||
end,
|
||||
cwd = '${workspaceFolder}',
|
||||
stopOnEntry = false,
|
||||
env = { ASAN_OPTIONS = 'detect_leaks=1' },
|
||||
},
|
||||
}
|
||||
dap.configurations.cpp = dap.configurations.c
|
||||
|
||||
-- Rust configuration
|
||||
dap.configurations.rust = {
|
||||
{
|
||||
name = 'Launch',
|
||||
type = 'codelldb',
|
||||
request = 'launch',
|
||||
program = function()
|
||||
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/target/debug/', 'file')
|
||||
end,
|
||||
cwd = '${workspaceFolder}',
|
||||
stopOnEntry = false,
|
||||
},
|
||||
}
|
||||
|
||||
-- Zig configuration
|
||||
dap.configurations.zig = {
|
||||
{
|
||||
name = 'Launch',
|
||||
type = 'codelldb',
|
||||
request = 'launch',
|
||||
program = function()
|
||||
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/zig-out/bin/', 'file')
|
||||
end,
|
||||
cwd = '${workspaceFolder}',
|
||||
stopOnEntry = false,
|
||||
},
|
||||
}
|
||||
|
||||
-- Auto-open/close UI
|
||||
dap.listeners.after.event_initialized['dapui_config'] = dapui.open
|
||||
dap.listeners.before.event_terminated['dapui_config'] = dapui.close
|
||||
dap.listeners.before.event_exited['dapui_config'] = dapui.close
|
||||
|
||||
-- Breakpoint signs
|
||||
vim.fn.sign_define('DapBreakpoint', { text = '🔴', texthl = '', linehl = '', numhl = '' })
|
||||
vim.fn.sign_define('DapStopped', { text = '➡️', texthl = '', linehl = 'debugPC', numhl = '' })
|
||||
end,
|
||||
keys = {
|
||||
{
|
||||
'<leader>dc',
|
||||
function()
|
||||
require('dap').continue()
|
||||
end,
|
||||
desc = 'Debug: Continue',
|
||||
},
|
||||
{
|
||||
'<leader>ds',
|
||||
function()
|
||||
require('dap').step_over()
|
||||
end,
|
||||
desc = 'Debug: Step Over',
|
||||
},
|
||||
{
|
||||
'<leader>di',
|
||||
function()
|
||||
require('dap').step_into()
|
||||
end,
|
||||
desc = 'Debug: Step Into',
|
||||
},
|
||||
{
|
||||
'<leader>do',
|
||||
function()
|
||||
require('dap').step_out()
|
||||
end,
|
||||
desc = 'Debug: Step Out',
|
||||
},
|
||||
{
|
||||
'<leader>db',
|
||||
function()
|
||||
require('dap').toggle_breakpoint()
|
||||
end,
|
||||
desc = 'Debug: Toggle Breakpoint',
|
||||
},
|
||||
{
|
||||
'<leader>dB',
|
||||
function()
|
||||
require('dap').set_breakpoint(vim.fn.input('Breakpoint condition: '))
|
||||
end,
|
||||
desc = 'Debug: Conditional Breakpoint',
|
||||
},
|
||||
{
|
||||
'<leader>dr',
|
||||
function()
|
||||
require('dap').repl.toggle()
|
||||
end,
|
||||
desc = 'Debug: Toggle REPL',
|
||||
},
|
||||
{
|
||||
'<leader>dl',
|
||||
function()
|
||||
require('dap').run_last()
|
||||
end,
|
||||
desc = 'Debug: Run Last',
|
||||
},
|
||||
{
|
||||
'<leader>du',
|
||||
function()
|
||||
require('dapui').toggle()
|
||||
end,
|
||||
desc = 'Debug: Toggle UI',
|
||||
},
|
||||
{
|
||||
'<leader>dt',
|
||||
function()
|
||||
require('dap').terminate()
|
||||
end,
|
||||
desc = 'Debug: Terminate',
|
||||
},
|
||||
},
|
||||
ft = { 'python', 'go', 'rust', 'c', 'cpp', 'zig' },
|
||||
},
|
||||
}
|
||||
6
lua/custom/plugins/diffview.lua
Executable file
6
lua/custom/plugins/diffview.lua
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
return {
|
||||
'sindrets/diffview.nvim',
|
||||
dependencies = { 'nvim-lua/plenary.nvim' },
|
||||
opts = {},
|
||||
}
|
||||
|
||||
88
lua/custom/plugins/formatting.lua
Executable file
88
lua/custom/plugins/formatting.lua
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
return {
|
||||
'stevearc/conform.nvim',
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
'WhoIsSethDaniel/mason-tool-installer.nvim',
|
||||
},
|
||||
event = { 'BufReadPre', 'BufNewFile' },
|
||||
opts = {
|
||||
formatters = {
|
||||
juliaformatter = {
|
||||
command = 'julia',
|
||||
args = {
|
||||
'--project=' .. vim.fn.expand('~/.julia/environments/nvim-format'),
|
||||
'--startup-file=no',
|
||||
'--history-file=no',
|
||||
'-e',
|
||||
[[
|
||||
using JuliaFormatter
|
||||
print(format_text(read(stdin, String)))
|
||||
]],
|
||||
},
|
||||
stdin = true,
|
||||
},
|
||||
},
|
||||
formatters_by_ft = {
|
||||
python = {
|
||||
'ruff_fix',
|
||||
'ruff_format',
|
||||
'ruff_organize_imports',
|
||||
},
|
||||
yaml = { 'yamlfmt' },
|
||||
sh = { 'shfmt' },
|
||||
sql = { 'sqlfluff' },
|
||||
lua = { 'stylua' },
|
||||
json = { 'jq' },
|
||||
julia = { 'juliaformatter' }, -- keep JuliaFormatter here
|
||||
markdown = { 'prettierd', 'prettier' },
|
||||
html = { 'prettierd' },
|
||||
css = { 'prettierd' },
|
||||
javascript = { 'prettierd' },
|
||||
typescript = { 'prettierd' },
|
||||
},
|
||||
|
||||
-- Fallback setup
|
||||
format_on_save = function(bufnr)
|
||||
if vim.bo[bufnr].filetype == 'julia' then
|
||||
return
|
||||
end
|
||||
return {
|
||||
timeout_ms = 2000,
|
||||
lsp_fallback = true,
|
||||
}
|
||||
end,
|
||||
|
||||
notify_on_error = true,
|
||||
async = true,
|
||||
},
|
||||
|
||||
config = function(_, opts)
|
||||
-- Setup Conform
|
||||
require('conform').setup(opts)
|
||||
|
||||
-- Auto-install formatters via Mason
|
||||
local all_formatters = {}
|
||||
for _, formatters in pairs(opts.formatters_by_ft) do
|
||||
for _, f in ipairs(formatters) do
|
||||
all_formatters[f] = true
|
||||
end
|
||||
end
|
||||
|
||||
local exclude = {
|
||||
ruff_fix = true,
|
||||
ruff_format = true,
|
||||
ruff_organize_imports = true,
|
||||
juliaformatter = true, -- exclude JuliaFormatter from Mason (install via Julia)
|
||||
}
|
||||
|
||||
local tools = vim.tbl_filter(function(tool)
|
||||
return not exclude[tool]
|
||||
end, vim.tbl_keys(all_formatters))
|
||||
|
||||
require('mason-tool-installer').setup({
|
||||
ensure_installed = tools,
|
||||
auto_update = false,
|
||||
run_on_start = true,
|
||||
})
|
||||
end,
|
||||
}
|
||||
46
lua/custom/plugins/fugitive.lua
Executable file
46
lua/custom/plugins/fugitive.lua
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
return {
|
||||
'tpope/vim-fugitive',
|
||||
config = function()
|
||||
-- General key mappings for Fugitive
|
||||
vim.keymap.set('n', '<leader>gs', vim.cmd.Git, { desc = 'Open Git status' })
|
||||
|
||||
-- Create an autocommand group for Fugitive-specific settings
|
||||
local fugitive_augroup = vim.api.nvim_create_augroup('fugitive', { clear = true })
|
||||
|
||||
-- Set up autocommands for Fugitive buffers
|
||||
vim.api.nvim_create_autocmd('BufWinEnter', {
|
||||
group = fugitive_augroup,
|
||||
pattern = '*',
|
||||
callback = function()
|
||||
if vim.bo.filetype ~= 'fugitive' then
|
||||
return
|
||||
end
|
||||
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local opts = { buffer = bufnr, remap = false }
|
||||
|
||||
-- Key mappings specific to Fugitive buffers
|
||||
vim.keymap.set('n', '<leader>gp', function()
|
||||
vim.cmd.Git('push')
|
||||
end, opts)
|
||||
vim.keymap.set('n', '<leader>gP', function()
|
||||
vim.cmd.Git('pull --rebase')
|
||||
end, opts)
|
||||
vim.keymap.set('n', '<leader>gU', ':Git push -u origin ', opts)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Additional key mappings for resolving Git conflicts
|
||||
vim.keymap.set('n', 'gu', '<cmd>diffget //2<CR>', { desc = 'Get diff for version 2' })
|
||||
vim.keymap.set('n', 'gh', '<cmd>diffget //3<CR>', { desc = 'Get diff for version 3' })
|
||||
|
||||
-- Create a custom user command for Git operations
|
||||
vim.api.nvim_create_user_command('Git', function(params)
|
||||
vim.cmd('Git ' .. params.args)
|
||||
end, { nargs = '*' })
|
||||
end,
|
||||
cond = function()
|
||||
-- Conditional loading based on the presence of a Git repository
|
||||
return vim.fn.isdirectory('.git') == 1
|
||||
end,
|
||||
}
|
||||
45
lua/custom/plugins/gitsigns.lua
Executable file
45
lua/custom/plugins/gitsigns.lua
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
return {
|
||||
'lewis6991/gitsigns.nvim',
|
||||
opts = {
|
||||
-- Git sign characters
|
||||
signs = {
|
||||
add = { text = '+' },
|
||||
change = { text = '~' },
|
||||
delete = { text = '_' },
|
||||
topdelete = { text = '‾' },
|
||||
changedelete = { text = '~' },
|
||||
},
|
||||
-- Function called when plugin attaches to a buffer
|
||||
on_attach = function(bufnr)
|
||||
-- Always show the sign column
|
||||
vim.opt.signcolumn = 'yes'
|
||||
|
||||
-- Keybindings
|
||||
local gs = require('gitsigns')
|
||||
vim.keymap.set('n', '<leader>hp', gs.preview_hunk, {
|
||||
buffer = bufnr,
|
||||
desc = 'Preview git hunk',
|
||||
})
|
||||
|
||||
vim.keymap.set({ 'n', 'v' }, ']c', function()
|
||||
if vim.wo.diff then
|
||||
return ']c'
|
||||
end
|
||||
vim.schedule(function()
|
||||
gs.next_hunk()
|
||||
end)
|
||||
return '<Ignore>'
|
||||
end, { expr = true, buffer = bufnr, desc = 'Jump to next hunk' })
|
||||
|
||||
vim.keymap.set({ 'n', 'v' }, '[c', function()
|
||||
if vim.wo.diff then
|
||||
return '[c'
|
||||
end
|
||||
vim.schedule(function()
|
||||
gs.prev_hunk()
|
||||
end)
|
||||
return '<Ignore>'
|
||||
end, { expr = true, buffer = bufnr, desc = 'Jump to previous hunk' })
|
||||
end,
|
||||
},
|
||||
}
|
||||
102
lua/custom/plugins/harpoon.lua
Executable file
102
lua/custom/plugins/harpoon.lua
Executable file
|
|
@ -0,0 +1,102 @@
|
|||
return {
|
||||
'theprimeagen/harpoon',
|
||||
branch = 'harpoon2',
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
-- 'nvim-telescope/telescope.nvim',
|
||||
},
|
||||
config = function()
|
||||
local harpoon = require('harpoon')
|
||||
-- local actions = require('telescope.actions')
|
||||
-- local action_state = require('telescope.actions.state')
|
||||
-- local conf = require('telescope.config').values
|
||||
|
||||
harpoon:setup({
|
||||
settings = {
|
||||
save_on_toggle = true,
|
||||
sync_on_ui_close = true,
|
||||
key = function()
|
||||
return vim.loop.cwd() or 'global'
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
-- Telescope integration
|
||||
-- local function toggle_telescope()
|
||||
-- local list = harpoon:list()
|
||||
-- local file_paths = {}
|
||||
--
|
||||
-- for _, item in ipairs(list.items) do
|
||||
-- table.insert(file_paths, item.value)
|
||||
-- end
|
||||
--
|
||||
-- require('telescope.pickers')
|
||||
-- .new({}, {
|
||||
-- prompt_title = 'Harpoon',
|
||||
-- finder = require('telescope.finders').new_table({
|
||||
-- results = file_paths,
|
||||
-- }),
|
||||
-- previewer = false,
|
||||
-- sorter = conf.generic_sorter({}),
|
||||
-- layout_config = {
|
||||
-- width = 0.5,
|
||||
-- height = 0.5,
|
||||
-- prompt_position = 'top',
|
||||
-- },
|
||||
-- layout_strategy = 'vertical',
|
||||
-- attach_mappings = function(prompt_bufnr, map)
|
||||
-- map('i', '<C-d>', function()
|
||||
-- local selection = action_state.get_selected_entry()
|
||||
-- if not selection then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- local target = selection[1]
|
||||
-- for _, item in ipairs(harpoon:list().items) do
|
||||
-- if item.value == target then
|
||||
-- harpoon:list():remove(item)
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
-- actions.close(prompt_bufnr)
|
||||
-- toggle_telescope()
|
||||
-- end)
|
||||
-- return true
|
||||
-- end,
|
||||
-- })
|
||||
-- :find()
|
||||
-- end
|
||||
|
||||
vim.keymap.set('n', '<leader>a', function()
|
||||
if vim.fn.expand('%:p'):sub(1, 6) == 'oil://' then
|
||||
return
|
||||
end
|
||||
|
||||
harpoon:list():add()
|
||||
end, { desc = 'Harpoon: Add file to list (if not already present)' })
|
||||
|
||||
vim.keymap.set('n', '<C-e>', function()
|
||||
harpoon.ui:toggle_quick_menu(harpoon:list())
|
||||
end, { desc = 'Harpoon: Toggle quick menu' })
|
||||
|
||||
vim.keymap.set('n', '<C-h>', function()
|
||||
harpoon:list():select(1)
|
||||
end)
|
||||
vim.keymap.set('n', '<C-j>', function()
|
||||
harpoon:list():select(2)
|
||||
end)
|
||||
vim.keymap.set('n', '<C-k>', function()
|
||||
harpoon:list():select(3)
|
||||
end)
|
||||
vim.keymap.set('n', '<C-l>', function()
|
||||
harpoon:list():select(4)
|
||||
end)
|
||||
|
||||
vim.keymap.set('n', '<C-h>', function()
|
||||
harpoon:list():prev()
|
||||
end)
|
||||
vim.keymap.set('n', '<C-l>', function()
|
||||
harpoon:list():next()
|
||||
end)
|
||||
end,
|
||||
}
|
||||
104
lua/custom/plugins/images.lua
Normal file
104
lua/custom/plugins/images.lua
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
return {
|
||||
-- {
|
||||
-- 'vhyrro/luarocks.nvim',
|
||||
-- priority = 1001,
|
||||
-- opts = {
|
||||
-- rocks = { 'magick' },
|
||||
-- },
|
||||
-- event = 'VeryLazy', -- Adjust this based on your needs
|
||||
-- },
|
||||
-- {
|
||||
-- 'willothy/wezterm.nvim',
|
||||
-- config = true,
|
||||
-- event = 'BufWinEnter', -- Or another appropriate event
|
||||
-- },
|
||||
-- {
|
||||
-- '3rd/image.nvim',
|
||||
-- enabled = true,
|
||||
-- commit = 'deb158d',
|
||||
-- dev = false,
|
||||
-- ft = { 'markdown', 'quarto', 'vimwiki' },
|
||||
-- config = function()
|
||||
-- local image = require 'image'
|
||||
-- image.setup {
|
||||
-- backend = 'wezterm',
|
||||
-- integrations = {
|
||||
-- markdown = {
|
||||
-- enabled = true,
|
||||
-- only_render_image_at_cursor = true,
|
||||
-- filetypes = { 'markdown', 'vimwiki', 'quarto' },
|
||||
-- },
|
||||
-- },
|
||||
-- editor_only_render_when_focused = false,
|
||||
-- window_overlap_clear_enabled = true,
|
||||
-- tmux_show_only_in_active_window = true,
|
||||
-- window_overlap_clear_ft_ignore = { 'cmp_menu', 'cmp_docs', 'scrollview', 'scrollview_sign' },
|
||||
-- max_width = nil,
|
||||
-- max_height = nil,
|
||||
-- max_width_window_percentage = nil,
|
||||
-- max_height_window_percentage = 30,
|
||||
-- kitty_method = 'normal',
|
||||
-- }
|
||||
--
|
||||
-- local function clear_all_images()
|
||||
-- local bufnr = vim.api.nvim_get_current_buf()
|
||||
-- local images = image.get_images { buffer = bufnr }
|
||||
-- for _, img in ipairs(images) do
|
||||
-- img:clear()
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local function get_image_at_cursor(buf)
|
||||
-- local images = image.get_images { buffer = buf }
|
||||
-- local row = vim.api.nvim_win_get_cursor(0)[1] - 1
|
||||
-- for _, img in ipairs(images) do
|
||||
-- if img.geometry ~= nil and img.geometry.y == row then
|
||||
-- local og_max_height = img.global_state.options.max_height_window_percentage
|
||||
-- img.global_state.options.max_height_window_percentage = nil
|
||||
-- return img, og_max_height
|
||||
-- end
|
||||
-- end
|
||||
-- return nil
|
||||
-- end
|
||||
--
|
||||
-- local create_preview_window = function(img, og_max_height)
|
||||
-- local buf = vim.api.nvim_create_buf(false, true)
|
||||
-- local win_width = vim.api.nvim_get_option_value('columns', {})
|
||||
-- local win_height = vim.api.nvim_get_option_value('lines', {})
|
||||
-- local win = vim.api.nvim_open_win(buf, true, {
|
||||
-- relative = 'editor',
|
||||
-- style = 'minimal',
|
||||
-- width = win_width,
|
||||
-- height = win_height,
|
||||
-- row = 0,
|
||||
-- col = 0,
|
||||
-- zindex = 1000,
|
||||
-- })
|
||||
-- vim.keymap.set('n', 'q', function()
|
||||
-- vim.api.nvim_win_close(win, true)
|
||||
-- img.global_state.options.max_height_window_percentage = og_max_height
|
||||
-- end, { buffer = buf })
|
||||
-- return { buf = buf, win = win }
|
||||
-- end
|
||||
--
|
||||
-- local handle_zoom = function(bufnr)
|
||||
-- local img, og_max_height = get_image_at_cursor(bufnr)
|
||||
-- if img == nil then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- local preview = create_preview_window(img, og_max_height)
|
||||
-- image.hijack_buffer(img.path, preview.win, preview.buf)
|
||||
-- end
|
||||
--
|
||||
-- vim.keymap.set('n', '<leader>io', function()
|
||||
-- local bufnr = vim.api.nvim_get_current_buf()
|
||||
-- handle_zoom(bufnr)
|
||||
-- end, { buffer = true, desc = 'image [o]pen' })
|
||||
--
|
||||
-- vim.keymap.set('n', '<leader>ic', clear_all_images, { desc = 'image [c]lear' })
|
||||
-- end,
|
||||
-- },
|
||||
--
|
||||
}
|
||||
|
||||
24
lua/custom/plugins/indent.lua
Executable file
24
lua/custom/plugins/indent.lua
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
local highlight = {
|
||||
'Whitespace',
|
||||
'Function',
|
||||
}
|
||||
|
||||
return {
|
||||
-- Add indentation guides even on blank lines
|
||||
'lukas-reineke/indent-blankline.nvim',
|
||||
main = 'ibl',
|
||||
opts = {
|
||||
indent = {
|
||||
highlight = highlight,
|
||||
char = '┆',
|
||||
},
|
||||
whitespace = {
|
||||
highlight = highlight,
|
||||
remove_blankline_trail = true,
|
||||
},
|
||||
scope = {
|
||||
enabled = true,
|
||||
exclude = { language = { 'vim', 'lua', 'go', 'python', 'rust', 'sh', 'json', 'yaml', 'toml', 'markdown' } },
|
||||
},
|
||||
},
|
||||
}
|
||||
67
lua/custom/plugins/jupytext.lua
Normal file
67
lua/custom/plugins/jupytext.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
return {
|
||||
'goerz/jupytext.vim',
|
||||
lazy = false,
|
||||
config = function()
|
||||
vim.g.jupytext_fmt = 'py:percent'
|
||||
vim.g.jupytext_enable = 1
|
||||
vim.g.jupytext_pairing = 1
|
||||
|
||||
local jupytext_bin = vim.fn.exepath('jupytext')
|
||||
if jupytext_bin ~= nil and jupytext_bin ~= '' then
|
||||
vim.g.jupytext_command = jupytext_bin
|
||||
else
|
||||
local preferred_python3 = '/opt/homebrew/bin/python3'
|
||||
local python3_bin = preferred_python3
|
||||
if vim.fn.executable(preferred_python3) ~= 1 then
|
||||
python3_bin = vim.fn.exepath('python3')
|
||||
end
|
||||
|
||||
if python3_bin ~= nil and python3_bin ~= '' then
|
||||
vim.g.jupytext_command = python3_bin .. ' -m jupytext'
|
||||
else
|
||||
vim.schedule(function()
|
||||
vim.notify('Jupytext: no `jupytext` or `python3` found in PATH. Install jupytext (e.g. `/opt/homebrew/bin/python3 -m pip install --user jupytext`) or set `vim.g.jupytext_command`.', vim.log.levels.WARN)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local jupytext_group = vim.api.nvim_create_augroup('custom_jupytext', { clear = true })
|
||||
|
||||
vim.api.nvim_create_autocmd('BufWritePost', {
|
||||
group = jupytext_group,
|
||||
pattern = '*.py',
|
||||
callback = function()
|
||||
local ipynb_file = vim.fn.expand('%:r') .. '.ipynb'
|
||||
if vim.fn.filereadable(ipynb_file) == 1 then
|
||||
vim.cmd('silent! Jupytext --sync')
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('BufWritePost', {
|
||||
group = jupytext_group,
|
||||
pattern = '*.ipynb',
|
||||
callback = function()
|
||||
local py_file = vim.fn.expand('%:r') .. '.py'
|
||||
if vim.fn.filereadable(py_file) == 1 then
|
||||
vim.cmd('silent! Jupytext --sync')
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile' }, {
|
||||
group = jupytext_group,
|
||||
pattern = '*.ipynb',
|
||||
callback = function()
|
||||
local py_file = vim.fn.expand('%:r') .. '.py'
|
||||
if vim.fn.filereadable(py_file) == 0 then
|
||||
vim.cmd('silent! Jupytext --to py:percent')
|
||||
end
|
||||
|
||||
if vim.fn.filereadable(py_file) == 1 then
|
||||
vim.cmd('silent! edit ' .. vim.fn.fnameescape(py_file))
|
||||
end
|
||||
end,
|
||||
})
|
||||
end,
|
||||
}
|
||||
74
lua/custom/plugins/linting.lua
Executable file
74
lua/custom/plugins/linting.lua
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
return {
|
||||
'mfussenegger/nvim-lint',
|
||||
dependencies = { 'WhoIsSethDaniel/mason-tool-installer.nvim' },
|
||||
event = { 'BufReadPre', 'BufNewFile' },
|
||||
opts = {
|
||||
linters_by_ft = {
|
||||
python = { 'ruff', 'mypy' },
|
||||
go = { 'golangcilint' },
|
||||
yaml = { 'yamllint' },
|
||||
markdown = { 'markdownlint' },
|
||||
sh = { 'shellcheck' },
|
||||
lua = { 'luacheck' },
|
||||
sql = { 'sqlfluff' },
|
||||
},
|
||||
mason_to_lint = {
|
||||
golangcilint = { 'golangci-lint' },
|
||||
},
|
||||
},
|
||||
config = function(_, opts)
|
||||
local lint = require('lint')
|
||||
lint.linters_by_ft = opts.linters_by_ft
|
||||
|
||||
-- Flatten linters and map to Mason package names
|
||||
local all_linters = {}
|
||||
for _, ft_linters in pairs(opts.linters_by_ft) do
|
||||
for _, l in ipairs(ft_linters) do
|
||||
local tool = opts.mason_to_lint[l] or { l }
|
||||
-- Handle both table and string values
|
||||
if type(tool) == 'table' then
|
||||
for _, t in ipairs(tool) do
|
||||
if t ~= '' then
|
||||
table.insert(all_linters, t)
|
||||
end
|
||||
end
|
||||
elseif tool ~= '' then
|
||||
table.insert(all_linters, tool)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Deduplicate tools
|
||||
local tools_set = {}
|
||||
for _, t in ipairs(all_linters) do
|
||||
tools_set[t] = true
|
||||
end
|
||||
local tools = vim.tbl_keys(tools_set)
|
||||
|
||||
print('Ensuring installation of linters: ' .. table.concat(tools, ', '))
|
||||
|
||||
-- Setup mason-tool-installer safely
|
||||
require('mason-tool-installer').setup({
|
||||
ensure_installed = tools,
|
||||
auto_update = false,
|
||||
run_on_start = true,
|
||||
start_delay = 3000,
|
||||
})
|
||||
|
||||
-- Autocommand group for linting
|
||||
local augroup = vim.api.nvim_create_augroup('LintAutogroup', { clear = true })
|
||||
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
|
||||
group = augroup,
|
||||
callback = function()
|
||||
local ft = vim.bo.filetype
|
||||
local available = lint.linters_by_ft[ft]
|
||||
if available and #available > 0 then
|
||||
local ok, err = pcall(lint.try_lint)
|
||||
if not ok then
|
||||
vim.notify('[nvim-lint] Error running linter: ' .. err, vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
end,
|
||||
}
|
||||
552
lua/custom/plugins/lsp-config.lua
Executable file
552
lua/custom/plugins/lsp-config.lua
Executable file
|
|
@ -0,0 +1,552 @@
|
|||
return {
|
||||
'neovim/nvim-lspconfig',
|
||||
event = { 'BufReadPre', 'BufNewFile' },
|
||||
dependencies = {
|
||||
-- Mason core
|
||||
{ 'williamboman/mason.nvim', build = ':MasonUpdate', cmd = 'Mason', config = true },
|
||||
'williamboman/mason-lspconfig.nvim',
|
||||
'WhoIsSethDaniel/mason-tool-installer.nvim',
|
||||
|
||||
-- Lua dev
|
||||
{ 'folke/neodev.nvim', ft = 'lua', config = true },
|
||||
|
||||
-- LSP UI & UX
|
||||
{ 'j-hui/fidget.nvim', opts = {}, event = 'LspAttach' },
|
||||
{ 'ray-x/lsp_signature.nvim', event = 'LspAttach' },
|
||||
|
||||
-- Treesitter
|
||||
{
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
build = ':TSUpdate',
|
||||
event = 'BufReadPost',
|
||||
opts = {
|
||||
highlight = { enable = true },
|
||||
indent = { enable = true },
|
||||
ensure_installed = {
|
||||
'bash',
|
||||
'c',
|
||||
'cpp',
|
||||
'go',
|
||||
'html',
|
||||
'julia',
|
||||
'lua',
|
||||
'markdown',
|
||||
'python',
|
||||
'rust',
|
||||
'sql',
|
||||
'vim',
|
||||
'vimdoc',
|
||||
'yaml',
|
||||
'zig',
|
||||
},
|
||||
},
|
||||
config = true,
|
||||
},
|
||||
{ 'nvim-treesitter/nvim-treesitter-textobjects', event = 'BufReadPost' },
|
||||
|
||||
-- Python venv selector
|
||||
{
|
||||
'linux-cultist/venv-selector.nvim',
|
||||
ft = 'python',
|
||||
opts = { auto_activate = true },
|
||||
config = true,
|
||||
},
|
||||
|
||||
-- JSON Schema support
|
||||
{ 'b0o/schemastore.nvim', ft = { 'json', 'yaml' } },
|
||||
},
|
||||
|
||||
config = function()
|
||||
require('neodev').setup()
|
||||
|
||||
-- Enhanced capabilities for LSP servers
|
||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
local has_cmp, cmp_nvim_lsp = pcall(require, 'cmp_nvim_lsp')
|
||||
if has_cmp then
|
||||
capabilities = cmp_nvim_lsp.default_capabilities(capabilities)
|
||||
end
|
||||
capabilities.offsetEncoding = { 'utf-8' }
|
||||
|
||||
-- Disable dynamicRegistration to silence yamlls warning
|
||||
capabilities.workspace = capabilities.workspace or {}
|
||||
capabilities.workspace.didChangeConfiguration = capabilities.workspace.didChangeConfiguration or {}
|
||||
capabilities.workspace.didChangeConfiguration.dynamicRegistration = false
|
||||
|
||||
local function path_exists(p)
|
||||
return p and p ~= '' and vim.uv.fs_stat(p) ~= nil
|
||||
end
|
||||
|
||||
local function mason_bin(name)
|
||||
local p = vim.fs.joinpath(vim.fn.stdpath('data'), 'mason', 'bin', name)
|
||||
if path_exists(p) then
|
||||
return p
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
local function julia_bin()
|
||||
local home = vim.env.HOME or ''
|
||||
local candidates = {
|
||||
vim.fn.exepath('julia'),
|
||||
vim.fs.joinpath(home, '.juliaup', 'bin', 'julia'),
|
||||
'/opt/homebrew/bin/julia',
|
||||
'/usr/local/bin/julia',
|
||||
}
|
||||
for _, p in ipairs(candidates) do
|
||||
if path_exists(p) then
|
||||
return p
|
||||
end
|
||||
end
|
||||
return 'julia'
|
||||
end
|
||||
|
||||
-- Servers that should provide formatting
|
||||
local format_enabled_servers = {
|
||||
bashls = true,
|
||||
clangd = true,
|
||||
gopls = true,
|
||||
html = true,
|
||||
htmx = true,
|
||||
jsonls = true,
|
||||
lua_ls = true,
|
||||
marksman = true,
|
||||
pyright = true,
|
||||
ruff = true,
|
||||
rust_analyzer = true,
|
||||
taplo = true,
|
||||
texlab = true,
|
||||
yamlls = true,
|
||||
zls = true,
|
||||
}
|
||||
|
||||
-- Default on_attach function
|
||||
local on_attach = function(client, bufnr)
|
||||
-- Enable formatting only for supported servers
|
||||
if not format_enabled_servers[client.name] then
|
||||
client.server_capabilities.documentFormattingProvider = false
|
||||
client.server_capabilities.documentRangeFormattingProvider = false
|
||||
end
|
||||
|
||||
vim.bo[bufnr].omnifunc = 'v:lua.vim.lsp.omnifunc'
|
||||
|
||||
-- LSP signature help
|
||||
require('lsp_signature').on_attach({
|
||||
hint_enable = false,
|
||||
handler_opts = { border = 'rounded' },
|
||||
}, bufnr)
|
||||
|
||||
-- Keymap helper
|
||||
local function map(keys, func, desc, modes)
|
||||
modes = modes or 'n'
|
||||
vim.keymap.set(modes, keys, func, {
|
||||
buffer = bufnr,
|
||||
desc = desc and 'LSP: ' .. desc or nil,
|
||||
})
|
||||
end
|
||||
|
||||
-- Lazy-load Telescope for LSP
|
||||
local function telescope_builtin(name)
|
||||
return function(...)
|
||||
require('lazy').load({ plugins = { 'telescope.nvim' } })
|
||||
return require('telescope.builtin')[name](...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Navigation
|
||||
map('gd', telescope_builtin('lsp_definitions'), '[G]oto [D]efinition')
|
||||
map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
|
||||
map('gr', telescope_builtin('lsp_references'), '[G]oto [R]eferences')
|
||||
map('gI', telescope_builtin('lsp_implementations'), '[G]oto [I]mplementation')
|
||||
map('<leader>lT', telescope_builtin('lsp_type_definitions'), '[T]ype Definition')
|
||||
map('<leader>ls', telescope_builtin('lsp_document_symbols'), '[D]ocument [S]ymbols')
|
||||
map('<leader>lS', telescope_builtin('lsp_dynamic_workspace_symbols'), '[W]orkspace [S]ymbols')
|
||||
|
||||
-- Diagnostics
|
||||
map('<leader>ld', vim.diagnostic.open_float, 'Show line [E]rrors')
|
||||
map('[d', vim.diagnostic.get_prev, 'Previous Diagnostic')
|
||||
map(']d', vim.diagnostic.get_next, 'Next Diagnostic')
|
||||
|
||||
-- Code Actions & Refactoring
|
||||
map('<leader>lr', vim.lsp.buf.rename, 'Rename')
|
||||
map('<leader>la', vim.lsp.buf.code_action, 'Code Action', { 'n', 'v' })
|
||||
|
||||
-- Documentation
|
||||
map('K', vim.lsp.buf.hover, 'Hover Documentation')
|
||||
map('<C-k>', vim.lsp.buf.signature_help, 'Signature Documentation')
|
||||
|
||||
-- Document highlight
|
||||
if client.server_capabilities.documentHighlightProvider then
|
||||
local highlight_group = vim.api.nvim_create_augroup('lsp_document_highlight', { clear = true })
|
||||
local visual_bg = vim.fn.synIDattr(vim.fn.hlID('Visual'), 'bg') or '#3e4452'
|
||||
|
||||
vim.api.nvim_set_hl(0, 'LspReferenceText', { bg = visual_bg })
|
||||
vim.api.nvim_set_hl(0, 'LspReferenceRead', { bg = visual_bg })
|
||||
vim.api.nvim_set_hl(0, 'LspReferenceWrite', { bg = visual_bg })
|
||||
vim.o.updatetime = math.max(vim.o.updatetime, 500)
|
||||
|
||||
local function toggle_lsp_highlight(enable)
|
||||
if enable then
|
||||
vim.api.nvim_create_autocmd('CursorHold', {
|
||||
group = highlight_group,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if client and client.server_capabilities.documentHighlightProvider then
|
||||
vim.lsp.buf.document_highlight()
|
||||
end
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('CursorMoved', {
|
||||
group = highlight_group,
|
||||
buffer = bufnr,
|
||||
callback = vim.lsp.buf.clear_references,
|
||||
})
|
||||
else
|
||||
vim.api.nvim_clear_autocmds({ group = highlight_group, buffer = bufnr })
|
||||
vim.lsp.buf.clear_references()
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_create_user_command(bufnr, 'LspToggleHighlight', function()
|
||||
local enabled = vim.b.lsp_highlight_enabled or false
|
||||
toggle_lsp_highlight(not enabled)
|
||||
vim.b.lsp_highlight_enabled = not enabled
|
||||
print('LSP document highlights ' .. (enabled and 'disabled' or 'enabled'))
|
||||
end, {})
|
||||
|
||||
toggle_lsp_highlight(true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Default LSP configuration
|
||||
local default_config = {
|
||||
capabilities = capabilities,
|
||||
on_attach = on_attach,
|
||||
autostart = true,
|
||||
}
|
||||
|
||||
local julia_cmd = julia_bin()
|
||||
local julia_ls_project = vim.fn.expand('~/.julia/environments/nvim-lsp')
|
||||
|
||||
-- Server-specific configurations
|
||||
local servers = {
|
||||
bashls = {
|
||||
filetypes = { 'sh', 'bash', 'zsh' },
|
||||
},
|
||||
|
||||
html = {
|
||||
filetypes = { 'html', 'htmldjango' },
|
||||
init_options = {
|
||||
configurationSection = { 'html', 'css', 'javascript' },
|
||||
embeddedLanguages = {
|
||||
css = true,
|
||||
javascript = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
htmx = {
|
||||
cmd = { 'htmx-lsp' },
|
||||
filetypes = { 'html', 'htmx' },
|
||||
},
|
||||
|
||||
gopls = {
|
||||
settings = {
|
||||
gopls = {
|
||||
gofumpt = true,
|
||||
staticcheck = true,
|
||||
completeUnimported = true,
|
||||
usePlaceholders = true,
|
||||
analyses = { unusedparams = true },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
clangd = {
|
||||
cmd = {
|
||||
'clangd',
|
||||
'--background-index',
|
||||
'--clang-tidy',
|
||||
'--header-insertion=iwyu',
|
||||
'--completion-style=detailed',
|
||||
'--header-insertion-decorators',
|
||||
'--query-driver=/usr/bin/clang,/usr/bin/clang++',
|
||||
'--enable-config',
|
||||
},
|
||||
settings = {
|
||||
formatting = true,
|
||||
inlayHints = {
|
||||
designators = true,
|
||||
enabled = true,
|
||||
parameterNames = true,
|
||||
deducedTypes = true,
|
||||
},
|
||||
},
|
||||
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'h', 'hpp', 'hxx' },
|
||||
},
|
||||
|
||||
marksman = {
|
||||
filetypes = { 'markdown' },
|
||||
settings = {
|
||||
marksman = {
|
||||
extensions = { 'mdx' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
jsonls = {
|
||||
cmd = { 'vscode-json-language-server', '--stdio' },
|
||||
settings = {
|
||||
json = {
|
||||
validate = { enable = true },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
julials = {
|
||||
filetypes = { 'julia' },
|
||||
cmd = {
|
||||
julia_cmd,
|
||||
'--project=' .. julia_ls_project,
|
||||
'--startup-file=no',
|
||||
'--history-file=no',
|
||||
'-e',
|
||||
[[
|
||||
using Logging
|
||||
using LanguageServer
|
||||
using SymbolServer
|
||||
|
||||
global_logger(ConsoleLogger(stderr, Logging.Warn))
|
||||
|
||||
function project_path()
|
||||
try
|
||||
return LanguageServer.find_project_path(pwd())
|
||||
catch
|
||||
return pwd()
|
||||
end
|
||||
end
|
||||
|
||||
depot_path = get(ENV, "JULIA_DEPOT_PATH", "")
|
||||
|
||||
server = LanguageServer.LanguageServerInstance(
|
||||
stdin,
|
||||
stdout,
|
||||
something(project_path(), pwd()),
|
||||
depot_path,
|
||||
)
|
||||
|
||||
server.runlinter = true
|
||||
run(server)
|
||||
]],
|
||||
},
|
||||
settings = {
|
||||
julia = {
|
||||
lint = {
|
||||
run = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
on_attach(client, bufnr)
|
||||
-- Julia must never format via LSP
|
||||
client.server_capabilities.documentFormattingProvider = false
|
||||
client.server_capabilities.documentRangeFormattingProvider = false
|
||||
end,
|
||||
},
|
||||
|
||||
pyright = {
|
||||
settings = {
|
||||
python = {
|
||||
analysis = {
|
||||
autoSearchPaths = true,
|
||||
diagnosticMode = 'workspace',
|
||||
useLibraryCodeForTypes = true,
|
||||
typeCheckingMode = 'none',
|
||||
reportGeneralTypeIssues = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
ruff = {
|
||||
filetypes = { 'python' },
|
||||
on_init = function()
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
group = vim.api.nvim_create_augroup('lsp_attach_disable_ruff_hover', { clear = true }),
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
if client and client.name == 'ruff' then
|
||||
-- Disable Ruff hover
|
||||
client.server_capabilities.hoverProvider = false
|
||||
end
|
||||
end,
|
||||
desc = 'LSP: Disable hover capability from Ruff',
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
rust_analyzer = {
|
||||
settings = {
|
||||
['rust-analyzer'] = {
|
||||
imports = { granularity = { group = 'module' }, prefix = 'self' },
|
||||
cargo = { buildScripts = { enable = true } },
|
||||
procMacro = { enable = true },
|
||||
checkOnSave = { command = 'clippy' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
taplo = {
|
||||
filetypes = { 'toml' },
|
||||
},
|
||||
|
||||
yamlls = {
|
||||
settings = {
|
||||
yaml = {
|
||||
schemaStore = { enable = true },
|
||||
validate = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
texlab = {
|
||||
filetypes = { 'tex', 'plaintex', 'bib', 'cls', 'sty' },
|
||||
settings = {
|
||||
texlab = {
|
||||
build = {
|
||||
onSave = false,
|
||||
},
|
||||
diagnostics = {
|
||||
ignoredPatterns = {
|
||||
'^Overfull \\\\hbox',
|
||||
'^Underfull \\\\hbox',
|
||||
'^Package.*Warning',
|
||||
},
|
||||
},
|
||||
auxDirectory = 'output',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
lua_ls = {
|
||||
cmd = { mason_bin('lua-language-server') },
|
||||
settings = {
|
||||
Lua = {
|
||||
workspace = { checkThirdParty = false },
|
||||
telemetry = { enable = false },
|
||||
diagnostics = { globals = { 'vim' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
sqls = {
|
||||
filetypes = { 'sql', 'mysql', 'plsql', 'postgresql' },
|
||||
settings = {
|
||||
sql = {
|
||||
connections = {
|
||||
{
|
||||
driver = 'sqlite3',
|
||||
dataSourceName = 'file::memory:?cache=shared',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
on_init = function(client)
|
||||
local root_dir = client.config.root_dir or vim.fn.getcwd()
|
||||
local db_files = vim.fn.globpath(root_dir, '*.db', false, true)
|
||||
vim.list_extend(db_files, vim.fn.globpath(root_dir, '*.sqlite', false, true))
|
||||
|
||||
if #db_files > 0 then
|
||||
local connections = {}
|
||||
for _, path in ipairs(db_files) do
|
||||
table.insert(connections, {
|
||||
driver = 'sqlite3',
|
||||
dataSourceName = vim.fn.fnamemodify(path, ':p'),
|
||||
})
|
||||
end
|
||||
client.config.settings.sql.connections = connections
|
||||
client.notify('workspace/didChangeConfiguration', { settings = client.config.settings })
|
||||
end
|
||||
end,
|
||||
},
|
||||
|
||||
zls = {
|
||||
filetypes = { 'zig' },
|
||||
},
|
||||
}
|
||||
|
||||
-- Use Mason to ensure servers are installed
|
||||
local ensure_installed = vim.tbl_keys(servers)
|
||||
ensure_installed = vim.tbl_filter(function(name)
|
||||
return name ~= 'julials'
|
||||
end, ensure_installed)
|
||||
|
||||
require('mason-lspconfig').setup({
|
||||
ensure_installed = ensure_installed,
|
||||
automatic_enable = false,
|
||||
})
|
||||
|
||||
local function get_lspconfig_defaults(server_name)
|
||||
local ok, cfg = pcall(require, 'lspconfig.configs.' .. server_name)
|
||||
if ok and cfg and cfg.default_config then
|
||||
local defaults = vim.deepcopy(cfg.default_config)
|
||||
if type(defaults.root_dir) == 'function' then
|
||||
local orig_root_dir = defaults.root_dir
|
||||
defaults.root_dir = function(bufnr, on_dir)
|
||||
local fname = bufnr
|
||||
if type(bufnr) == 'number' then
|
||||
fname = vim.api.nvim_buf_get_name(bufnr)
|
||||
if fname == '' or type(fname) ~= 'string' or fname:match('^%w+://') then
|
||||
fname = vim.fn.getcwd()
|
||||
end
|
||||
end
|
||||
|
||||
local root = orig_root_dir(fname)
|
||||
if type(on_dir) == 'function' then
|
||||
on_dir(root)
|
||||
return
|
||||
end
|
||||
return root
|
||||
end
|
||||
end
|
||||
return defaults
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Setup and enable LSP servers
|
||||
for server_name, config in pairs(servers) do
|
||||
if config then
|
||||
local lspconfig_defaults = get_lspconfig_defaults(server_name)
|
||||
|
||||
-- Merge default config with server-specific config
|
||||
local merged_config = vim.tbl_deep_extend('force', lspconfig_defaults, default_config, config)
|
||||
|
||||
-- Configure and enable the server
|
||||
vim.lsp.config(server_name, merged_config)
|
||||
vim.lsp.enable(server_name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Diagnostics configuration
|
||||
vim.diagnostic.config({
|
||||
underline = true,
|
||||
severity_sort = true,
|
||||
signs = {
|
||||
text = {
|
||||
[vim.diagnostic.severity.ERROR] = 'E',
|
||||
[vim.diagnostic.severity.WARN] = 'W',
|
||||
[vim.diagnostic.severity.HINT] = 'H',
|
||||
[vim.diagnostic.severity.INFO] = 'I',
|
||||
},
|
||||
linehl = {
|
||||
[vim.diagnostic.severity.ERROR] = 'ErrorMsg',
|
||||
},
|
||||
numhl = {
|
||||
[vim.diagnostic.severity.WARN] = 'WarningMsg',
|
||||
},
|
||||
},
|
||||
virtual_text = { spacing = 2, prefix = '●' },
|
||||
float = { source = 'if_many', border = 'rounded' },
|
||||
})
|
||||
end,
|
||||
}
|
||||
36
lua/custom/plugins/lualine.lua
Executable file
36
lua/custom/plugins/lualine.lua
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
return {
|
||||
'nvim-lualine/lualine.nvim',
|
||||
dependencies = { 'nvim-tree/nvim-web-devicons', 'tpope/vim-fugitive' },
|
||||
config = function()
|
||||
require('lualine').setup({
|
||||
options = {
|
||||
theme = 'auto',
|
||||
icons_enabled = true,
|
||||
component_separators = '|',
|
||||
section_separators = '',
|
||||
},
|
||||
sections = {
|
||||
lualine_a = {
|
||||
{
|
||||
'buffers',
|
||||
show_modified_status = true,
|
||||
symbols = { modified = '●', alternate_file = '#', directory = '' },
|
||||
},
|
||||
},
|
||||
lualine_b = {
|
||||
{ 'mode', icons_enabled = true },
|
||||
},
|
||||
lualine_c = {
|
||||
'branch',
|
||||
{ 'diff', colored = false, symbols = { added = ' ', modified = ' ', removed = ' ' } },
|
||||
},
|
||||
lualine_x = {
|
||||
'encoding',
|
||||
{ 'fileformat', symbols = { unix = ' ', mac = ' ', dos = ' ' } },
|
||||
'filetype',
|
||||
},
|
||||
},
|
||||
extensions = { 'fugitive', 'nvim-tree' },
|
||||
})
|
||||
end,
|
||||
}
|
||||
8
lua/custom/plugins/marks.lua
Executable file
8
lua/custom/plugins/marks.lua
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
return {
|
||||
'chentoast/marks.nvim',
|
||||
opts = {
|
||||
default_mappings = true,
|
||||
default_view = 'vertical',
|
||||
},
|
||||
}
|
||||
|
||||
8
lua/custom/plugins/monokai.lua
Executable file
8
lua/custom/plugins/monokai.lua
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
return {
|
||||
'tanvirtin/monokai.nvim',
|
||||
priority = 1000,
|
||||
config = function()
|
||||
|
||||
end,
|
||||
}
|
||||
|
||||
36
lua/custom/plugins/neogen.lua
Executable file
36
lua/custom/plugins/neogen.lua
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
return {
|
||||
'danymat/neogen',
|
||||
dependencies = {
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
'L3MON4D3/LuaSnip',
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
'<leader>nf',
|
||||
function()
|
||||
require('neogen').generate({ type = 'func' })
|
||||
end,
|
||||
desc = 'Generate function documentation',
|
||||
},
|
||||
{
|
||||
'<leader>nt',
|
||||
function()
|
||||
require('neogen').generate({ type = 'type' })
|
||||
end,
|
||||
desc = 'Generate type documentation',
|
||||
},
|
||||
},
|
||||
config = function()
|
||||
require('neogen').setup({
|
||||
enabled = true,
|
||||
snippet_engine = 'luasnip', -- Using LuaSnip as the snippet engine
|
||||
})
|
||||
end,
|
||||
cond = function()
|
||||
-- Only load if Treesitter is installed and available
|
||||
return vim.fn.exists(':TSInstall') == 2
|
||||
end,
|
||||
-- Uncomment next line if you want to follow only stable versions
|
||||
-- version = "*"
|
||||
}
|
||||
|
||||
137
lua/custom/plugins/neotest.lua
Normal file
137
lua/custom/plugins/neotest.lua
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
return {
|
||||
{
|
||||
'nvim-neotest/neotest',
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
'nvim-neotest/nvim-nio',
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
'nvim-neotest/neotest-python',
|
||||
'alfaix/neotest-gtest',
|
||||
'andythigpen/nvim-coverage',
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
'<leader>tn',
|
||||
function()
|
||||
local neotest = require('neotest')
|
||||
neotest.summary.open({ enter = false })
|
||||
neotest.run.run()
|
||||
end,
|
||||
desc = 'Test: Run nearest',
|
||||
},
|
||||
{
|
||||
'<leader>tf',
|
||||
function()
|
||||
local neotest = require('neotest')
|
||||
neotest.summary.open({ enter = false })
|
||||
neotest.run.run(vim.fn.expand('%'))
|
||||
end,
|
||||
desc = 'Test: Run file',
|
||||
},
|
||||
{
|
||||
'<leader>ta',
|
||||
function()
|
||||
local neotest = require('neotest')
|
||||
neotest.summary.open({ enter = false })
|
||||
neotest.run.run(vim.fn.getcwd())
|
||||
end,
|
||||
desc = 'Test: Run all (cwd)',
|
||||
},
|
||||
{
|
||||
'<leader>td',
|
||||
function()
|
||||
local neotest = require('neotest')
|
||||
neotest.summary.open({ enter = false })
|
||||
neotest.run.run({ strategy = 'dap' })
|
||||
end,
|
||||
desc = 'Test: Debug nearest',
|
||||
},
|
||||
{
|
||||
'<leader>tx',
|
||||
function()
|
||||
require('neotest').run.stop()
|
||||
end,
|
||||
desc = 'Test: Stop',
|
||||
},
|
||||
{
|
||||
'<leader>ts',
|
||||
function()
|
||||
require('neotest').summary.toggle()
|
||||
end,
|
||||
desc = 'Test: Toggle summary',
|
||||
},
|
||||
{
|
||||
'<leader>to',
|
||||
function()
|
||||
require('neotest').output.open({ enter = true, auto_close = false })
|
||||
end,
|
||||
desc = 'Test: Show output',
|
||||
},
|
||||
{
|
||||
'<leader>tw',
|
||||
function()
|
||||
require('neotest').watch.toggle(vim.fn.expand('%'))
|
||||
end,
|
||||
desc = 'Test: Watch file',
|
||||
},
|
||||
{
|
||||
']t',
|
||||
function()
|
||||
require('neotest').jump.next({ status = 'failed' })
|
||||
end,
|
||||
desc = 'Test: Next failed',
|
||||
},
|
||||
{
|
||||
'[t',
|
||||
function()
|
||||
require('neotest').jump.prev({ status = 'failed' })
|
||||
end,
|
||||
desc = 'Test: Prev failed',
|
||||
},
|
||||
{
|
||||
'<leader>tC',
|
||||
function()
|
||||
local ok, coverage = pcall(require, 'coverage')
|
||||
if ok then
|
||||
coverage.toggle()
|
||||
end
|
||||
end,
|
||||
desc = 'Test: Toggle coverage',
|
||||
},
|
||||
{
|
||||
'<leader>tL',
|
||||
function()
|
||||
local ok, coverage = pcall(require, 'coverage')
|
||||
if ok then
|
||||
coverage.load(true)
|
||||
end
|
||||
end,
|
||||
desc = 'Test: Load coverage',
|
||||
},
|
||||
},
|
||||
config = function()
|
||||
local neotest = require('neotest')
|
||||
|
||||
neotest.setup({
|
||||
adapters = {
|
||||
require('neotest-python')({
|
||||
runner = 'pytest',
|
||||
dap = { justMyCode = false },
|
||||
}),
|
||||
require('neotest-gtest').setup({
|
||||
debug_adapter = 'codelldb',
|
||||
}),
|
||||
},
|
||||
output = { open_on_run = false },
|
||||
summary = { open = 'botright vsplit | vertical resize 60' },
|
||||
})
|
||||
|
||||
local ok_cov, coverage = pcall(require, 'coverage')
|
||||
if ok_cov then
|
||||
coverage.setup({
|
||||
auto_reload = true,
|
||||
})
|
||||
end
|
||||
end,
|
||||
},
|
||||
}
|
||||
50
lua/custom/plugins/notify.lua
Normal file
50
lua/custom/plugins/notify.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
return {
|
||||
'rcarriga/nvim-notify',
|
||||
opts = {
|
||||
timeout = 5000,
|
||||
stages = 'static',
|
||||
},
|
||||
config = function(_, opts)
|
||||
local notify = require('notify')
|
||||
notify.setup(opts)
|
||||
|
||||
-- Override vim.notify to filter out noisy LSP messages
|
||||
local original_notify = vim.notify
|
||||
vim.notify = function(msg, level, notify_opts)
|
||||
-- Suppress Node.js warnings
|
||||
if type(msg) == 'string' and msg:match('ExperimentalWarning: SQLite') then
|
||||
return
|
||||
end
|
||||
if type(msg) == 'string' and msg:match('DeprecationWarning.*punycode') then
|
||||
return
|
||||
end
|
||||
|
||||
-- Suppress copilot errors (harmless race conditions)
|
||||
if type(msg) == 'string' and msg:match('Cannot find request.*whilst attempting to cancel') then
|
||||
return
|
||||
end
|
||||
if type(msg) == 'string' and msg:match('AbortError: The operation was aborted') then
|
||||
return
|
||||
end
|
||||
if type(msg) == 'string' and msg:match('rate limit exceeded') then
|
||||
return
|
||||
end
|
||||
if type(msg) == 'string' and msg:match('Rate limited by server') then
|
||||
return
|
||||
end
|
||||
|
||||
-- Suppress bashls parsing/formatting errors
|
||||
if type(msg) == 'string' and msg:match('Error while parsing file://') then
|
||||
return
|
||||
end
|
||||
if type(msg) == 'string' and msg:match('Error while formatting.*Shfmt') then
|
||||
return
|
||||
end
|
||||
|
||||
original_notify(msg, level, notify_opts)
|
||||
end
|
||||
|
||||
-- Set as default notifier
|
||||
vim.notify = notify
|
||||
end,
|
||||
}
|
||||
74
lua/custom/plugins/oil.lua
Executable file
74
lua/custom/plugins/oil.lua
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
return {
|
||||
'stevearc/oil.nvim',
|
||||
dependencies = {
|
||||
'nvim-tree/nvim-web-devicons', -- optional, for file icons
|
||||
},
|
||||
config = function()
|
||||
local oil = require('oil')
|
||||
|
||||
oil.setup({
|
||||
columns = {
|
||||
'icon',
|
||||
-- 'permissions',
|
||||
},
|
||||
keymaps = {
|
||||
['C-h'] = false,
|
||||
['M-h'] = 'actions.select_split',
|
||||
},
|
||||
view_options = {
|
||||
show_hidden = true,
|
||||
},
|
||||
float = {
|
||||
padding = 2,
|
||||
max_width = 80,
|
||||
max_height = 30,
|
||||
border = 'rounded',
|
||||
win_options = {
|
||||
winblend = 0,
|
||||
},
|
||||
relative = 'editor',
|
||||
},
|
||||
})
|
||||
|
||||
-- Monokai-like highlights
|
||||
vim.api.nvim_set_hl(0, 'OilDir', { fg = '#A6E22E' })
|
||||
vim.api.nvim_set_hl(0, 'OilFile', { fg = '#D3D0C8' })
|
||||
vim.api.nvim_set_hl(0, 'OilHiddenFile', { fg = '#75715E' })
|
||||
vim.api.nvim_set_hl(0, 'OilProgress', { fg = '#66D9EF' })
|
||||
vim.api.nvim_set_hl(0, 'OilSymlink', { fg = '#F92672' })
|
||||
|
||||
-- Oil keymaps
|
||||
vim.keymap.set('n', '<leader>e', '<CMD>Oil<CR>', { noremap = true, silent = true, desc = 'Open parent directory' })
|
||||
vim.keymap.set('n', '<leader>E', function()
|
||||
oil.toggle_float()
|
||||
end, { noremap = true, silent = true, desc = 'Toggle oil floating window' })
|
||||
|
||||
-- Add selected file in oil.nvim to Harpoon
|
||||
-- same keymapping as if in a buffer
|
||||
vim.keymap.set('n', '<leader>a', function()
|
||||
local ok_harpoon, harpoon = pcall(require, 'harpoon')
|
||||
if not ok_harpoon then
|
||||
vim.notify('Harpoon not found', vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
local entry = oil.get_cursor_entry()
|
||||
if not entry or not entry.name then
|
||||
vim.notify('No valid entry selected in Oil', vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
|
||||
local full_path = oil.get_current_dir() .. entry.name
|
||||
local stat = vim.loop.fs_stat(full_path)
|
||||
if not stat or stat.type ~= 'file' then
|
||||
vim.notify('Selected entry is not a file: ' .. full_path, vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
|
||||
harpoon:list():add({
|
||||
value = entry.name,
|
||||
context = { filename = entry.name, cwd = oil.get_current_dir() or 'global' },
|
||||
})
|
||||
end, { desc = 'Add selected file in oil.nvim to Harpoon' })
|
||||
end,
|
||||
}
|
||||
12
lua/custom/plugins/refactoring.lua
Executable file
12
lua/custom/plugins/refactoring.lua
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
return {
|
||||
{
|
||||
'ThePrimeagen/refactoring.nvim',
|
||||
event = 'VeryLazy',
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
},
|
||||
lazy = true,
|
||||
opts = {},
|
||||
},
|
||||
}
|
||||
10
lua/custom/plugins/render-markdown.lua
Executable file
10
lua/custom/plugins/render-markdown.lua
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
return {
|
||||
'MeanderingProgrammer/render-markdown.nvim',
|
||||
ft = { 'markdown' },
|
||||
dependencies = {
|
||||
'nvim-tree/nvim-web-devicons',
|
||||
},
|
||||
opts = {
|
||||
-- Put any overrides here only if you need them.
|
||||
},
|
||||
}
|
||||
5
lua/custom/plugins/schemastore.lua
Executable file
5
lua/custom/plugins/schemastore.lua
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
'b0o/schemastore.nvim',
|
||||
ft = { 'josn', 'jsonc', 'json5', 'yaml', 'toml' },
|
||||
event = 'VeryLazy',
|
||||
}
|
||||
40
lua/custom/plugins/slime.lua
Executable file
40
lua/custom/plugins/slime.lua
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
return {
|
||||
'jpalardy/vim-slime',
|
||||
ft = { 'python' },
|
||||
keys = {
|
||||
{ '<leader>RC', '<cmd>SlimeConfig<cr>', desc = 'Slime Config' },
|
||||
{
|
||||
'<leader>RS',
|
||||
function()
|
||||
if require('custom.user.ipython_utils').is_ipython_open() then
|
||||
if vim.fn.mode() == 'v' then
|
||||
-- Visual mode mapping
|
||||
vim.cmd("<cmd><C-u>'<,'>SlimeSend<CR>")
|
||||
else
|
||||
-- Normal mode mapping: Execute the <Plug>SlimeSendCell and move to the next cell delimiter
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<Plug>SlimeSendCell', true, true, true), 'm', true)
|
||||
vim.cmd('normal! /^# %%\\<CR>')
|
||||
end
|
||||
else
|
||||
vim.notify('No IPython REPL found. Open an IPython terminal first.', vim.log.levels.WARN)
|
||||
end
|
||||
end,
|
||||
mode = { 'n', 'v' },
|
||||
},
|
||||
},
|
||||
init = function()
|
||||
vim.g.slime_target = 'neovim'
|
||||
vim.g.slime_no_mappings = true
|
||||
end,
|
||||
config = function()
|
||||
-- Slime configuration
|
||||
vim.g.slime_cell_delimiter = '# %%'
|
||||
vim.g.slime_bracketed_paste = 1
|
||||
vim.g.slime_paste_file = os.getenv('HOME') .. '/.slime_paste'
|
||||
vim.g.slime_input_pid = false
|
||||
vim.g.slime_suggest_default = true
|
||||
vim.g.slime_menu_config = false
|
||||
vim.g.slime_neovim_ignore_unlisted = false
|
||||
vim.g.slime_python_ipython = 0
|
||||
end,
|
||||
}
|
||||
42
lua/custom/plugins/snippets.lua
Executable file
42
lua/custom/plugins/snippets.lua
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
return {
|
||||
{
|
||||
'L3MON4D3/LuaSnip',
|
||||
version = 'v2.*', -- Follows the latest major release version 2
|
||||
build = 'make install_jsregexp', -- Optional: install JavaScript-based regular expressions
|
||||
|
||||
dependencies = { 'rafamadriz/friendly-snippets' },
|
||||
|
||||
config = function()
|
||||
local luasnip = require('luasnip')
|
||||
|
||||
-- Extend filetypes with specific snippets
|
||||
luasnip.filetype_extend('javascript', { 'jsdoc' })
|
||||
luasnip.filetype_extend('python', { 'google' })
|
||||
|
||||
-- Key mappings for LuaSnip
|
||||
vim.keymap.set({ 'i' }, '<C-s>e', function()
|
||||
if luasnip.expand_or_jumpable() then
|
||||
luasnip.expand()
|
||||
end
|
||||
end, { silent = true, desc = 'Expand snippet' })
|
||||
|
||||
vim.keymap.set({ 'i', 's' }, '<C-s>;', function()
|
||||
if luasnip.jumpable(1) then
|
||||
luasnip.jump(1)
|
||||
end
|
||||
end, { silent = true, desc = 'Jump forward in snippet' })
|
||||
|
||||
vim.keymap.set({ 'i', 's' }, '<C-s>,', function()
|
||||
if luasnip.jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
end
|
||||
end, { silent = true, desc = 'Jump backward in snippet' })
|
||||
|
||||
vim.keymap.set({ 'i', 's' }, '<C-s>', function()
|
||||
if luasnip.choice_active() then
|
||||
luasnip.change_choice(1)
|
||||
end
|
||||
end, { silent = true, desc = 'Cycle through snippet choices' })
|
||||
end,
|
||||
},
|
||||
}
|
||||
7
lua/custom/plugins/solarized.lua
Executable file
7
lua/custom/plugins/solarized.lua
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
return {
|
||||
'shaunsingh/solarized.nvim',
|
||||
event = 'VeryLazy',
|
||||
config = function()
|
||||
vim.g.solarized_variant = 'light'
|
||||
end,
|
||||
}
|
||||
5
lua/custom/plugins/surround.lua
Executable file
5
lua/custom/plugins/surround.lua
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
'tpope/vim-surround',
|
||||
event = { 'BufRead', 'BufNewFile' },
|
||||
config = function() end,
|
||||
}
|
||||
44
lua/custom/plugins/telescope-undo.lua
Executable file
44
lua/custom/plugins/telescope-undo.lua
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
return {
|
||||
-- "debugloop/telescope-undo.nvim",
|
||||
-- dependencies = { -- note how they're inverted to above example
|
||||
-- {
|
||||
-- "nvim-telescope/telescope.nvim",
|
||||
-- dependencies = { "nvim-lua/plenary.nvim" },
|
||||
-- },
|
||||
-- },
|
||||
-- keys = {
|
||||
-- { -- lazy style key map
|
||||
-- "<leader>u", "<cmd>Telescope undo<cr>", desc = "undo history",
|
||||
-- },
|
||||
-- },
|
||||
-- opts = {
|
||||
-- extensions = {
|
||||
-- undo = {
|
||||
-- mapping = {
|
||||
-- i = {
|
||||
-- ["<cr>"] = require("telescope-undo.actions").yank_additions,
|
||||
-- ["<c-d>"] = require("telescope-undo.actions").yank_deletions,
|
||||
-- ["<c-r>"] = require("telescope-undo.actions").restore,
|
||||
-- },
|
||||
-- n = {
|
||||
-- ["y"] = require("telescope-undo.actions").yank_additions,
|
||||
-- ["Y"] = require("telescope-undo.actions").yank_deletions,
|
||||
-- ["u"] = require("telescope-undo.actions").restore,
|
||||
-- },
|
||||
-- },
|
||||
-- side_by_side = true,
|
||||
-- layout_strategy = "vertical",
|
||||
-- layout_config = {
|
||||
-- preview_height = 0.8,
|
||||
-- },
|
||||
-- },
|
||||
-- },
|
||||
-- },
|
||||
-- config = function(_, opts)
|
||||
-- -- Calling telescope's setup from multiple specs does not hurt, it will happily merge the
|
||||
-- -- configs for us. We won't use data, as everything is in it's own namespace (telescope
|
||||
-- -- defaults, as well as each extension).
|
||||
-- require("telescope").setup(opts)
|
||||
-- require("telescope").load_extension("undo")
|
||||
-- end,
|
||||
}
|
||||
96
lua/custom/plugins/telescope.lua
Executable file
96
lua/custom/plugins/telescope.lua
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
return {
|
||||
-- Fuzzy Finder (files, LSP, etc.)
|
||||
'nvim-telescope/telescope.nvim',
|
||||
cmd = 'Telescope',
|
||||
version = '*',
|
||||
dependencies = {
|
||||
'nvim-lua/plenary.nvim',
|
||||
'debugloop/telescope-undo.nvim', -- Undo history extension
|
||||
{
|
||||
'nvim-telescope/telescope-fzf-native.nvim',
|
||||
build = 'make',
|
||||
config = function()
|
||||
require('telescope').setup({
|
||||
extensions = {
|
||||
fzf = {},
|
||||
},
|
||||
})
|
||||
require('telescope').load_extension('fzf')
|
||||
end,
|
||||
cond = function()
|
||||
return vim.fn.executable('make') == 1
|
||||
end,
|
||||
},
|
||||
'nvim-tree/nvim-web-devicons', -- Optional: Icons for UI
|
||||
'mbbill/undotree', -- Undotree dependency
|
||||
-- 'b0o/schemastore.nvim', -- YAML schema support
|
||||
},
|
||||
config = function()
|
||||
local telescope = require('telescope')
|
||||
|
||||
-- Configure Telescope
|
||||
telescope.setup({
|
||||
defaults = {
|
||||
-- prompt_prefix = '🔍 ',
|
||||
sorting_strategy = 'descending',
|
||||
layout_strategy = 'flex',
|
||||
mappings = {
|
||||
i = {
|
||||
['<C-u>'] = false, -- Disable Ctrl+u clearing input
|
||||
['<C-d>'] = false, -- Disable Ctrl+d clearing input
|
||||
},
|
||||
},
|
||||
-- Attach the global mapping for centering the cursor on selection
|
||||
attach_mappings = function(prompt_bufnr, _)
|
||||
local actions = require('telescope.actions')
|
||||
|
||||
-- When selecting a result, center it in the middle of the screen
|
||||
actions.select_default:replace(function()
|
||||
local line = actions.state.get_selected_entry().lnum
|
||||
vim.api.nvim_win_set_cursor(0, { line, 0 })
|
||||
vim.cmd('normal! zz') -- This centers the line in the middle of the screen
|
||||
actions.close(prompt_bufnr) -- Close the Telescope window
|
||||
end)
|
||||
|
||||
return true
|
||||
end,
|
||||
},
|
||||
extensions = {
|
||||
undo = {
|
||||
use_delta = true, -- Use delta for better diff visualization
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Load the undo extension for Telescope
|
||||
telescope.load_extension('undo')
|
||||
|
||||
-- Load yaml schemas for Telescope
|
||||
-- telescope.load_extension('yaml_schema')
|
||||
|
||||
-- Function to find git root directory
|
||||
local function find_git_root()
|
||||
local current_file = vim.api.nvim_buf_get_name(0)
|
||||
local current_dir = current_file ~= '' and vim.fn.fnamemodify(current_file, ':h') or vim.fn.getcwd()
|
||||
local git_root =
|
||||
vim.fn.systemlist('git -C ' .. vim.fn.escape(current_dir, ' ') .. ' rev-parse --show-toplevel')[1]
|
||||
|
||||
if vim.v.shell_error ~= 0 then
|
||||
print('Not a git repository, searching in current directory.')
|
||||
return vim.fn.getcwd()
|
||||
end
|
||||
return git_root
|
||||
end
|
||||
|
||||
-- Function for live_grep within the Git root
|
||||
local function live_grep_git_root()
|
||||
local git_root = find_git_root()
|
||||
if git_root then
|
||||
require('telescope.builtin').live_grep({ search_dirs = { git_root } })
|
||||
end
|
||||
end
|
||||
|
||||
-- Command to trigger live_grep_git_root
|
||||
vim.api.nvim_create_user_command('LiveGrepGitRoot', live_grep_git_root, { desc = 'Live grep in Git root' })
|
||||
end,
|
||||
}
|
||||
11
lua/custom/plugins/terminal.lua
Executable file
11
lua/custom/plugins/terminal.lua
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
return {
|
||||
{
|
||||
'floaterminal',
|
||||
dir = vim.fn.stdpath('config') .. '/lua/plugins',
|
||||
config = function()
|
||||
require('plugins.floaterminal').setup({
|
||||
title = 'Terminal',
|
||||
})
|
||||
end,
|
||||
},
|
||||
}
|
||||
7
lua/custom/plugins/todo-notes.lua
Executable file
7
lua/custom/plugins/todo-notes.lua
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
-- Highlight todo, notes, etc in comments
|
||||
return {
|
||||
'folke/todo-comments.nvim',
|
||||
event = 'VimEnter',
|
||||
dependencies = { 'nvim-lua/plenary.nvim' },
|
||||
opts = { signs = false },
|
||||
}
|
||||
106
lua/custom/plugins/tree-sitter.lua
Executable file
106
lua/custom/plugins/tree-sitter.lua
Executable file
|
|
@ -0,0 +1,106 @@
|
|||
return {
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
branch = 'master',
|
||||
version = false, -- last release is too old and doesn't work on Windows
|
||||
build = ':TSUpdate',
|
||||
event = { 'VeryLazy' },
|
||||
lazy = vim.fn.argc(-1) == 0, -- load treesitter early when opening a file from the cmdline
|
||||
init = function(plugin)
|
||||
-- PERF: add nvim-treesitter queries to the rtp and its custom query predicates early
|
||||
require('lazy.core.loader').add_to_rtp(plugin)
|
||||
require('nvim-treesitter.query_predicates')
|
||||
end,
|
||||
cmd = { 'TSUpdateSync', 'TSUpdate', 'TSInstall' },
|
||||
keys = {
|
||||
{ '<c-space>', desc = 'Increment Selection' },
|
||||
{ '<bs>', desc = 'Decrement Selection', mode = 'x' },
|
||||
},
|
||||
opts_extend = { 'ensure_installed' },
|
||||
---@type TSConfig
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
opts = {
|
||||
highlight = { enable = true },
|
||||
indent = { enable = true },
|
||||
ensure_installed = {
|
||||
'bash',
|
||||
'c',
|
||||
'html',
|
||||
'javascript',
|
||||
'jsdoc',
|
||||
'json',
|
||||
'jsonc',
|
||||
'lua',
|
||||
'luadoc',
|
||||
'markdown',
|
||||
'markdown_inline',
|
||||
'python',
|
||||
'query',
|
||||
'toml',
|
||||
'vim',
|
||||
'vimdoc',
|
||||
'yaml',
|
||||
'sql',
|
||||
'zig',
|
||||
},
|
||||
incremental_selection = {
|
||||
enable = true,
|
||||
keymaps = {
|
||||
init_selection = 'gnn',
|
||||
node_incremental = 'grn',
|
||||
scope_incremental = 'grc',
|
||||
node_decremental = 'grm',
|
||||
},
|
||||
},
|
||||
textobjects = {
|
||||
select = {
|
||||
enable = true,
|
||||
lookahead = true,
|
||||
keymaps = {
|
||||
['aa'] = '@parameter.outer',
|
||||
['ia'] = '@parameter.inner',
|
||||
['af'] = '@function.outer',
|
||||
['if'] = '@function.inner',
|
||||
['ac'] = '@class.outer',
|
||||
['ic'] = '@class.inner',
|
||||
},
|
||||
},
|
||||
move = {
|
||||
enable = true,
|
||||
set_jumps = true,
|
||||
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',
|
||||
},
|
||||
},
|
||||
swap = {
|
||||
enable = true,
|
||||
swap_next = {
|
||||
['<leader>i'] = '@parameter.inner',
|
||||
},
|
||||
swap_previous = {
|
||||
['<leader>I'] = '@parameter.inner',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
---@param opts TSConfig
|
||||
config = function(_, opts)
|
||||
-- Ensure no duplicates in the ensure_installed list
|
||||
if type(opts.ensure_installed) == 'table' then
|
||||
opts.ensure_installed = vim.tbl_deep_extend('force', {}, opts.ensure_installed)
|
||||
end
|
||||
require('nvim-treesitter.configs').setup(opts)
|
||||
end,
|
||||
}
|
||||
39
lua/custom/plugins/trouble.lua
Executable file
39
lua/custom/plugins/trouble.lua
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
return {
|
||||
'folke/trouble.nvim',
|
||||
version = '*',
|
||||
opts = {}, -- for default options, refer to the configuration section for custom setup.
|
||||
cmd = 'Trouble',
|
||||
event = 'LspAttach',
|
||||
keys = {
|
||||
{
|
||||
'<leader>xx',
|
||||
'<cmd>Trouble diagnostics toggle<cr>',
|
||||
desc = 'Diagnostics (Trouble)',
|
||||
},
|
||||
{
|
||||
'<leader>xX',
|
||||
'<cmd>Trouble diagnostics toggle filter.buf=0<cr>',
|
||||
desc = 'Buffer Diagnostics (Trouble)',
|
||||
},
|
||||
{
|
||||
'<leader>xs',
|
||||
'<cmd>Trouble symbols toggle focus=false<cr>',
|
||||
desc = 'Symbols (Trouble)',
|
||||
},
|
||||
{
|
||||
'<leader>xl',
|
||||
'<cmd>Trouble lsp toggle focus=false win.position=right<cr>',
|
||||
desc = 'LSP Definitions / references / ... (Trouble)',
|
||||
},
|
||||
{
|
||||
'<leader>xL',
|
||||
'<cmd>Trouble loclist toggle<cr>',
|
||||
desc = 'Location List (Trouble)',
|
||||
},
|
||||
{
|
||||
'<leader>xQ',
|
||||
'<cmd>Trouble qflist toggle<cr>',
|
||||
desc = 'Quickfix List (Trouble)',
|
||||
},
|
||||
},
|
||||
}
|
||||
9
lua/custom/plugins/undotree.lua
Executable file
9
lua/custom/plugins/undotree.lua
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
return {
|
||||
'mbbill/undotree',
|
||||
config = function()
|
||||
-- Set Undotree to open on the right side
|
||||
vim.g.undotree_WindowLayout = 4
|
||||
|
||||
vim.keymap.set('n', '<leader>u', vim.cmd.UndotreeToggle, { desc = '[U]ndotree' })
|
||||
end,
|
||||
}
|
||||
29
lua/custom/plugins/venv-selector.lua
Executable file
29
lua/custom/plugins/venv-selector.lua
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
return {
|
||||
'linux-cultist/venv-selector.nvim',
|
||||
cmd = 'VenvSelect',
|
||||
dependencies = {
|
||||
'neovim/nvim-lspconfig',
|
||||
'nvim-telescope/telescope.nvim',
|
||||
-- Remove nvim-dap-python from here - it's defined separately
|
||||
},
|
||||
opts = {
|
||||
settings = {
|
||||
options = {
|
||||
activate_venv_in_terminal = true,
|
||||
notify_user_on_venv_activation = true,
|
||||
debug = true,
|
||||
},
|
||||
search = {
|
||||
pyenv = {
|
||||
command = 'fd python$ -E "*lib*" -E "*init*" ${PYENV_ROOT}/versions/*.*.*/envs',
|
||||
on_telescope_result_callback = function(filename)
|
||||
return filename:gsub(os.getenv('HOME'), '~'):gsub('/bin/python', '')
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
keys = {
|
||||
{ ',v', '<cmd>VenvSelect<cr>', desc = 'Select Virtual Environment' },
|
||||
},
|
||||
}
|
||||
187
lua/custom/plugins/vimtex.lua
Executable file
187
lua/custom/plugins/vimtex.lua
Executable file
|
|
@ -0,0 +1,187 @@
|
|||
return {
|
||||
'lervag/vimtex',
|
||||
ft = { 'tex', 'latex', 'cls', 'sty', 'bib' },
|
||||
lazy = false,
|
||||
init = function()
|
||||
-- macOS PDF viewer - Skim is better than Zathura on macOS
|
||||
vim.g.vimtex_view_method = 'skim'
|
||||
vim.g.vimtex_view_skim_sync = 1
|
||||
vim.g.vimtex_view_skim_activate = 1
|
||||
vim.g.vimtex_view_skim_reading_bar = 0
|
||||
vim.g.vimtex_view_skim_preserve_state = 1
|
||||
-- Alternative: use system default PDF viewer
|
||||
-- vim.g.vimtex_view_method = 'general'
|
||||
-- vim.g.vimtex_view_general_viewer = 'open'
|
||||
|
||||
-- Compiler
|
||||
vim.g.vimtex_compiler_method = 'latexmk'
|
||||
vim.g.vimtex_compiler_latexmk_engines = {
|
||||
_ = '-pdf -xelatex -synctex=1 -interaction=nonstopmode',
|
||||
}
|
||||
vim.g.vimtex_compiler_latexmk = {
|
||||
build_dir = 'output',
|
||||
aux_dir = 'output',
|
||||
callback = 1,
|
||||
continuous = 1,
|
||||
executable = 'latexmk',
|
||||
options = {
|
||||
-- '-pdf',
|
||||
'-verbose',
|
||||
'-file-line-error',
|
||||
-- '-synctex=1',
|
||||
'-interaction=nonstopmode',
|
||||
-- '-xelatex',
|
||||
'-shell-escape',
|
||||
'-outdir=output',
|
||||
'-auxdir=output',
|
||||
},
|
||||
}
|
||||
|
||||
-- Disable problematic default mappings
|
||||
vim.g.vimtex_mappings_disable = {
|
||||
['n'] = { 'K' },
|
||||
['x'] = { 'K' },
|
||||
}
|
||||
|
||||
-- Quickfix
|
||||
vim.g.vimtex_quickfix_method = vim.fn.executable('pplatex') == 1 and 'pplatex' or 'latexlog'
|
||||
vim.g.vimtex_quickfix_mode = 2
|
||||
vim.g.vimtex_quickfix_open_on_warning = 0
|
||||
vim.g.vimtex_quickfix_ignore_filters = {
|
||||
'Underfull \\hbox',
|
||||
'Overfull \\hbox',
|
||||
'LaTeX Warning: .+ float specifier changed to',
|
||||
'LaTeX hooks Warning',
|
||||
'Package hyperref Warning: Token not allowed in a PDF string',
|
||||
'Package fontspec Warning',
|
||||
'Package everypage Warning',
|
||||
'Package microtype Warning',
|
||||
'LaTeX Warning: Command \\. invalid in math mode',
|
||||
'Package babel Warning',
|
||||
'Package biblatex Warning',
|
||||
}
|
||||
|
||||
-- Folding
|
||||
vim.g.vimtex_fold_enabled = 1
|
||||
vim.g.vimtex_fold_types = {
|
||||
envs = { whitelist = { 'figure', 'table', 'equation', 'align' } },
|
||||
sections = { parse_levels = 1 },
|
||||
}
|
||||
|
||||
-- Syntax
|
||||
vim.g.vimtex_syntax_enabled = 1
|
||||
vim.g.vimtex_syntax_conceal = {
|
||||
accents = 0,
|
||||
ligatures = 0,
|
||||
cites = 1,
|
||||
fancy = 0,
|
||||
spacing = 0,
|
||||
greek = 1,
|
||||
math_bounds = 0,
|
||||
math_delimiters = 0,
|
||||
math_fracs = 0,
|
||||
math_super_sub = 1,
|
||||
math_symbols = 1,
|
||||
sections = 0,
|
||||
}
|
||||
end,
|
||||
|
||||
config = function()
|
||||
-- Auto-create output dir
|
||||
vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, {
|
||||
pattern = { '*.tex', '*.latex' },
|
||||
callback = function()
|
||||
if vim.bo.filetype == 'tex' or vim.bo.filetype == 'latex' then
|
||||
local output_dir = vim.fn.expand('%:p:h') .. '/output'
|
||||
if vim.fn.isdirectory(output_dir) == 0 then
|
||||
vim.fn.mkdir(output_dir, 'p')
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Toggle continuous compilation function
|
||||
_G.vimtex_toggle_continuous = function()
|
||||
if vim.g.vimtex_compiler_latexmk.continuous == 1 then
|
||||
vim.g.vimtex_compiler_latexmk.continuous = 0
|
||||
print('Continuous compilation OFF')
|
||||
vim.cmd('VimtexStop')
|
||||
else
|
||||
vim.g.vimtex_compiler_latexmk.continuous = 1
|
||||
print('Continuous compilation ON')
|
||||
vim.cmd('VimtexCompile')
|
||||
end
|
||||
end
|
||||
|
||||
-- Function to close Skim for current PDF
|
||||
local function close_skim()
|
||||
local file_name = vim.fn.expand('%:t:r')
|
||||
if file_name ~= '' then
|
||||
local pdf_name = file_name .. '.pdf'
|
||||
-- AppleScript to close Skim window for specific PDF
|
||||
local script = string.format(
|
||||
[[
|
||||
tell application "System Events"
|
||||
if (name of processes) contains "Skim" then
|
||||
tell application "Skim"
|
||||
set theWindows to every window whose name contains "%s"
|
||||
repeat with theWindow in theWindows
|
||||
close theWindow
|
||||
end repeat
|
||||
end tell
|
||||
end if
|
||||
end tell
|
||||
]],
|
||||
pdf_name
|
||||
)
|
||||
vim.fn.system({ 'osascript', '-e', script })
|
||||
end
|
||||
end
|
||||
|
||||
-- Auto-close Skim when LaTeX buffer is deleted or closed
|
||||
vim.api.nvim_create_autocmd({ 'BufDelete', 'BufWipeout' }, {
|
||||
pattern = { '*.tex', '*.latex' },
|
||||
callback = function()
|
||||
close_skim()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Also close when Neovim exits
|
||||
vim.api.nvim_create_autocmd('VimLeave', {
|
||||
pattern = { '*.tex', '*.latex' },
|
||||
callback = function()
|
||||
close_skim()
|
||||
end,
|
||||
})
|
||||
end,
|
||||
|
||||
-- Use VimTeX's standard keymaps - only add minimal custom ones
|
||||
keys = {
|
||||
-- Standard VimTeX mappings (these are the defaults, just making them explicit)
|
||||
{ '<localleader>ll', '<cmd>VimtexCompile<cr>', desc = 'VimTeX: Compile', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lv', '<cmd>VimtexView<cr>', desc = 'VimTeX: View PDF', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>ls', '<cmd>VimtexStop<cr>', desc = 'VimTeX: Stop', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lS', '<cmd>VimtexStopAll<cr>', desc = 'VimTeX: Stop All', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lc', '<cmd>VimtexClean<cr>', desc = 'VimTeX: Clean', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lC', '<cmd>VimtexClean!<cr>', desc = 'VimTeX: Clean All', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lq', '<cmd>VimtexErrors<cr>', desc = 'VimTeX: Errors', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lk', '<cmd>VimtexLog<cr>', desc = 'VimTeX: Log', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>li', '<cmd>VimtexInfo<cr>', desc = 'VimTeX: Info', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lI', '<cmd>VimtexInfoFull<cr>', desc = 'VimTeX: Info Full', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lt', '<cmd>VimtexTocToggle<cr>', desc = 'VimTeX: TOC Toggle', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lT', '<cmd>VimtexTocOpen<cr>', desc = 'VimTeX: TOC Open', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lw', '<cmd>VimtexCountWords<cr>', desc = 'VimTeX: Count Words', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lW', '<cmd>VimtexCountLetters<cr>', desc = 'VimTeX: Count Letters', ft = { 'tex', 'latex' } },
|
||||
{ '<localleader>lm', '<cmd>VimtexImapsList<cr>', desc = 'VimTeX: Imaps List', ft = { 'tex', 'latex' } },
|
||||
|
||||
-- Only one custom mapping for continuous compilation toggle
|
||||
{
|
||||
'<localleader>lR',
|
||||
function()
|
||||
_G.vimtex_toggle_continuous()
|
||||
end,
|
||||
desc = 'VimTeX: Toggle Continuous',
|
||||
ft = { 'tex', 'latex' },
|
||||
},
|
||||
},
|
||||
}
|
||||
6
lua/custom/plugins/wezterm.lua
Normal file
6
lua/custom/plugins/wezterm.lua
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
return {
|
||||
'willothy/wezterm.nvim',
|
||||
opts = {
|
||||
create_commands = false
|
||||
}
|
||||
}
|
||||
62
lua/custom/plugins/which-key.lua
Executable file
62
lua/custom/plugins/which-key.lua
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
return {
|
||||
'folke/which-key.nvim',
|
||||
event = 'VimEnter', -- Sets the loading event to 'VimEnter'
|
||||
icons = {
|
||||
mappings = true,
|
||||
keys = {
|
||||
Up = '<Up> ',
|
||||
Down = '<Down> ',
|
||||
Left = '<Left> ',
|
||||
Right = '<Right> ',
|
||||
C = '<C-…> ',
|
||||
M = '<M-…> ',
|
||||
D = '<D-…> ',
|
||||
S = '<S-…> ',
|
||||
CR = '<CR> ',
|
||||
Esc = '<Esc> ',
|
||||
ScrollWheelDown = '<ScrollWheelDown> ',
|
||||
ScrollWheelUp = '<ScrollWheelUp> ',
|
||||
NL = '<NL> ',
|
||||
BS = '<BS> ',
|
||||
Space = '<Space> ',
|
||||
Tab = '<Tab> ',
|
||||
F1 = '<F1>',
|
||||
F2 = '<F2>',
|
||||
F3 = '<F3>',
|
||||
F4 = '<F4>',
|
||||
F5 = '<F5>',
|
||||
F6 = '<F6>',
|
||||
F7 = '<F7>',
|
||||
F8 = '<F8>',
|
||||
F9 = '<F9>',
|
||||
F10 = '<F10>',
|
||||
F11 = '<F11>',
|
||||
F12 = '<F12>',
|
||||
},
|
||||
},
|
||||
opts = {
|
||||
preset = 'helix', -- I like helix because I can still see the text, but others: modernm, classic
|
||||
spec = {
|
||||
{ '<leader>a', group = 'Harpoon', mode = { 'n', 'x' } },
|
||||
{ '<leader>b', group = '[B]uffer' },
|
||||
{ '<leader>c', group = '[C]ode/C++', mode = { 'n', 'x' } },
|
||||
{ '<leader>C', group = '[C]opilot', mode = {'n', 'x'} },
|
||||
{ '<leader>d', group = '[D]ebug' },
|
||||
{ '<leader>e', group = '[E]xplorer' },
|
||||
{ '<leader>f', group = '[F]iles' },
|
||||
{ '<leader>g', group = '[G]it' },
|
||||
{ '<leader>h', group = 'Git [H]unk', mode = { 'n', 'v' } },
|
||||
{ '<leader>j', group = '[J]ulia', mode = { 'n', 'x' } },
|
||||
{ '<leader>l', group = '[L]SP' },
|
||||
{ '<leader>p', group = '[P]aste', mode = { 'n', 'x' } },
|
||||
{ '<leader>R', group = '[R]un/REPL', mode = { 'n', 'x' } },
|
||||
{ '<leader>r', group = '[R]eplace' },
|
||||
{ '<leader>s', group = '[S]earch' },
|
||||
{ '<leader>t', group = '[T]est' },
|
||||
{ '<leader>u', group = '[U]I' },
|
||||
{ '<leader>w', group = '[W]orkspace' },
|
||||
{ '<leader>x', group = 'Trouble' },
|
||||
{ '<leader>z', group = '[Z]en' },
|
||||
},
|
||||
},
|
||||
}
|
||||
20
lua/custom/plugins/worktree.lua
Normal file
20
lua/custom/plugins/worktree.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
return {
|
||||
'ThePrimeagen/git-worktree.nvim',
|
||||
config = function()
|
||||
require('git-worktree').setup()
|
||||
require('telescope').load_extension('git_worktree')
|
||||
|
||||
vim.keymap.set(
|
||||
'n',
|
||||
'<leader>ga',
|
||||
"<cmd>lua require('telescope').extensions.git_worktree.git_worktree()<CR>",
|
||||
{ desc = 'Git Worktrees' }
|
||||
)
|
||||
vim.keymap.set(
|
||||
'n',
|
||||
'<leader>gn',
|
||||
"<cmd>lua require('telescope').extensions.git_worktree.create_git_worktree()<CR>",
|
||||
{ desc = 'New Git Worktree' }
|
||||
)
|
||||
end,
|
||||
}
|
||||
42
lua/custom/plugins/zen-mode.lua
Executable file
42
lua/custom/plugins/zen-mode.lua
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
return {
|
||||
'folke/zen-mode.nvim',
|
||||
command = 'ZenMode',
|
||||
opts = {
|
||||
window = {
|
||||
backdrop = 0.95, -- Transparency level for the zen mode window
|
||||
width = 0.80, -- 80% of the total editor width
|
||||
height = 1, -- Full height
|
||||
options = {
|
||||
signcolumn = 'no', -- Hide signcolumn in zen mode
|
||||
number = true, -- Disable line numbers
|
||||
relativenumber = true, -- Disable relative numbers
|
||||
},
|
||||
},
|
||||
plugins = {
|
||||
wezterm = {
|
||||
enabled = true,
|
||||
font = '+2', -- Increase font size in WezTerm by 2
|
||||
},
|
||||
},
|
||||
on_open = function()
|
||||
-- Configure Neovim options when Zen Mode opens
|
||||
vim.opt.ruler = false -- Hide ruler
|
||||
vim.opt.showcmd = false -- Hide command feedback
|
||||
vim.opt.laststatus = 0 -- Hide status line
|
||||
end,
|
||||
on_close = function()
|
||||
-- Restore Neovim options when Zen Mode closes
|
||||
vim.opt.ruler = true -- Show ruler
|
||||
vim.opt.showcmd = true -- Show command feedback
|
||||
vim.opt.laststatus = 2 -- Show status line
|
||||
end,
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
'<leader>zz',
|
||||
'<cmd>ZenMode<CR>',
|
||||
desc = 'Toggle Zen Mode',
|
||||
silent = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
26
lua/custom/snippets/go.lua
Normal file
26
lua/custom/snippets/go.lua
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
local ls = require('luasnip')
|
||||
|
||||
local s = ls.snippet
|
||||
local i = ls.insert_node
|
||||
local t = ls.text_node
|
||||
|
||||
local fmt = require('luasnip.extras.fmt').fmt
|
||||
|
||||
ls.add_snippets('go', {
|
||||
s('ee', {
|
||||
t({ 'panic(' }),
|
||||
i(1, 'err'),
|
||||
t({ ')' }),
|
||||
}),
|
||||
s(
|
||||
'ei',
|
||||
fmt(
|
||||
[[
|
||||
if err != nil {{
|
||||
panic({})
|
||||
}}
|
||||
]],
|
||||
{ i(1, 'err') }
|
||||
)
|
||||
),
|
||||
})
|
||||
20
lua/custom/snippets/lua.lua
Normal file
20
lua/custom/snippets/lua.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
local ls = require 'luasnip'
|
||||
|
||||
local s = ls.snippet
|
||||
local i = ls.insert_node
|
||||
local t = ls.text_node
|
||||
|
||||
ls.add_snippets('lua', {
|
||||
s('lr', {
|
||||
t 'local ',
|
||||
i(1, 'module'),
|
||||
t ' = require("',
|
||||
i(2, 'module'),
|
||||
t '")',
|
||||
}),
|
||||
s('pr', {
|
||||
t 'print(',
|
||||
i(1, 'text'),
|
||||
t ')',
|
||||
}),
|
||||
})
|
||||
51
lua/custom/snippets/pyhton.lua
Normal file
51
lua/custom/snippets/pyhton.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
local ls = require('luasnip')
|
||||
|
||||
local s = ls.snippet
|
||||
local i = ls.insert_node
|
||||
local t = ls.text_node
|
||||
local d = ls.dynamic_node
|
||||
local sn = ls.snippet_node
|
||||
|
||||
-- Helper to parse function args and create insert nodes
|
||||
local function generate_arg_docs()
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local args = line:match('def%s+[%w_]+%((.*)%)')
|
||||
if not args then
|
||||
return sn(nil, { t('Args:') })
|
||||
end
|
||||
|
||||
local nodes = { t('Args:') }
|
||||
local index = 1
|
||||
|
||||
for arg in args:gmatch('[^,%s]+') do
|
||||
table.insert(nodes, t({ '', ' ' .. arg .. ': ' }))
|
||||
table.insert(nodes, i(index))
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
return sn(nil, nodes)
|
||||
end
|
||||
|
||||
-- Add Python snippets
|
||||
ls.add_snippets('python', {
|
||||
s('log', {
|
||||
t({ 'LOG.' }),
|
||||
i(1, 'level'),
|
||||
t({ '(' }),
|
||||
i(2, 'message'),
|
||||
t({ ')' }),
|
||||
}),
|
||||
|
||||
s('#!', {
|
||||
t({ '#!/usr/bin/env python' }),
|
||||
}),
|
||||
|
||||
-- Docstring with Args (interactive) and Returns
|
||||
s('doc', {
|
||||
t({ '"""' }),
|
||||
d(1, generate_arg_docs, {}),
|
||||
t({ '', '', 'Returns:', ' ' }),
|
||||
i(2, 'return_value_description'),
|
||||
t({ '', '"""' }),
|
||||
}),
|
||||
})
|
||||
2
lua/custom/user/init.lua
Normal file
2
lua/custom/user/init.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
-- Load user-created modules
|
||||
require('custom.user.ipython_utils')
|
||||
24
lua/custom/user/ipython_utils.lua
Normal file
24
lua/custom/user/ipython_utils.lua
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
local M = {}
|
||||
|
||||
-- Function to check if an IPython REPL is open in Neovim panes
|
||||
function M.is_ipython_open()
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_is_loaded(bufnr) and vim.api.nvim_get_option_value('buftype', { buf = bufnr }) == 'terminal' then
|
||||
if vim.b[bufnr].python_repl == true then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Get first few lines to check if it's an IPython REPL
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, 10, false)
|
||||
for _, line in ipairs(lines) do
|
||||
-- Specific checks for IPython
|
||||
if line:match('IPython') or line:match('In %[%d+%]:') or line:match('In %[') then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return M
|
||||
76
lua/kickstart/plugins/autoformat.lua
Executable file
76
lua/kickstart/plugins/autoformat.lua
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
-- autoformat.lua
|
||||
--
|
||||
-- Use your language server to automatically format your code on save.
|
||||
-- Adds additional commands as well to manage the behavior
|
||||
|
||||
return {
|
||||
'neovim/nvim-lspconfig',
|
||||
config = function()
|
||||
-- Switch for controlling whether you want autoformatting.
|
||||
-- Use :KickstartFormatToggle to toggle autoformatting on or off
|
||||
local format_is_enabled = true
|
||||
vim.api.nvim_create_user_command('KickstartFormatToggle', function()
|
||||
format_is_enabled = not format_is_enabled
|
||||
print('Setting autoformatting to: ' .. tostring(format_is_enabled))
|
||||
end, {})
|
||||
|
||||
-- Create an augroup that is used for managing our formatting autocmds.
|
||||
-- We need one augroup per client to make sure that multiple clients
|
||||
-- can attach to the same buffer without interfering with each other.
|
||||
local _augroups = {}
|
||||
local get_augroup = function(client)
|
||||
if not _augroups[client.id] then
|
||||
local group_name = 'kickstart-lsp-format-' .. client.name
|
||||
local id = vim.api.nvim_create_augroup(group_name, { clear = true })
|
||||
_augroups[client.id] = id
|
||||
end
|
||||
|
||||
return _augroups[client.id]
|
||||
end
|
||||
|
||||
-- Whenever an LSP attaches to a buffer, we will run this function.
|
||||
--
|
||||
-- See `:help LspAttach` for more information about this autocmd event.
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
group = vim.api.nvim_create_augroup('kickstart-lsp-attach-format', { clear = true }),
|
||||
-- This is where we attach the autoformatting for reasonable clients
|
||||
callback = function(args)
|
||||
local client_id = args.data.client_id
|
||||
local client = vim.lsp.get_client_by_id(client_id)
|
||||
local bufnr = args.buf
|
||||
if not client then
|
||||
return
|
||||
end
|
||||
-- Only attach to clients that support document formatting
|
||||
if not client.server_capabilities.documentFormattingProvider then
|
||||
return
|
||||
end
|
||||
|
||||
-- Tsserver usually works poorly. Sorry you work with bad languages
|
||||
-- You can remove this line if you know what you're doing :)
|
||||
if client.name == 'tsserver' then
|
||||
return
|
||||
end
|
||||
|
||||
-- Create an autocmd that will run *before* we save the buffer.
|
||||
-- Run the formatting command for the LSP that has just attached.
|
||||
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||
group = get_augroup(client),
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if not format_is_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
vim.lsp.buf.format({
|
||||
async = false,
|
||||
filter = function(c)
|
||||
return c.id == client.id
|
||||
end,
|
||||
})
|
||||
end,
|
||||
})
|
||||
end,
|
||||
})
|
||||
end,
|
||||
}
|
||||
88
lua/kickstart/plugins/debug.lua
Executable file
88
lua/kickstart/plugins/debug.lua
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
-- debug.lua
|
||||
--
|
||||
-- Shows how to use the DAP plugin to debug your code.
|
||||
--
|
||||
-- Primarily focused on configuring the debugger for Go, but can
|
||||
-- be extended to other languages as well. That's why it's called
|
||||
-- kickstart.nvim and not kitchen-sink.nvim ;)
|
||||
|
||||
return {
|
||||
-- NOTE: Yes, you can install new plugins here!
|
||||
'mfussenegger/nvim-dap',
|
||||
-- NOTE: And you can specify dependencies as well
|
||||
dependencies = {
|
||||
-- Creates a beautiful debugger UI
|
||||
'rcarriga/nvim-dap-ui',
|
||||
|
||||
-- Installs the debug adapters for you
|
||||
'williamboman/mason.nvim',
|
||||
'jay-babu/mason-nvim-dap.nvim',
|
||||
|
||||
-- Add your own debuggers here
|
||||
'leoluz/nvim-dap-go',
|
||||
},
|
||||
config = function()
|
||||
local dap = require('dap')
|
||||
local dapui = require('dapui')
|
||||
|
||||
require('mason-nvim-dap').setup({
|
||||
-- Makes a best effort to setup the various debuggers with
|
||||
-- reasonable debug configurations
|
||||
automatic_installation = true,
|
||||
automatic_setup = true,
|
||||
|
||||
-- You can provide additional configuration to the handlers,
|
||||
-- see mason-nvim-dap README for more information
|
||||
handlers = {},
|
||||
|
||||
-- You'll need to check that you have the required things installed
|
||||
-- online, please don't ask me how to install them :)
|
||||
ensure_installed = {
|
||||
-- Update this to ensure that you have the debuggers for the langs you want
|
||||
'delve',
|
||||
},
|
||||
})
|
||||
|
||||
-- Basic debugging keymaps, feel free to change to your liking!
|
||||
vim.keymap.set('n', '<F5>', dap.continue, { desc = 'Debug: Start/Continue' })
|
||||
vim.keymap.set('n', '<F1>', dap.step_into, { desc = 'Debug: Step Into' })
|
||||
vim.keymap.set('n', '<F2>', dap.step_over, { desc = 'Debug: Step Over' })
|
||||
vim.keymap.set('n', '<F3>', dap.step_out, { desc = 'Debug: Step Out' })
|
||||
vim.keymap.set('n', '<leader>b', dap.toggle_breakpoint, { desc = 'Debug: Toggle Breakpoint' })
|
||||
vim.keymap.set('n', '<leader>B', function()
|
||||
dap.set_breakpoint(vim.fn.input('Breakpoint condition: '))
|
||||
end, { desc = 'Debug: Set Breakpoint' })
|
||||
|
||||
-- Dap UI setup
|
||||
-- For more information, see |:help nvim-dap-ui|
|
||||
dapui.setup({
|
||||
-- Set icons to characters that are more likely to work in every terminal.
|
||||
-- Feel free to remove or use ones that you like more! :)
|
||||
-- Don't feel like these are good choices.
|
||||
icons = { expanded = '▾', collapsed = '▸', current_frame = '*' },
|
||||
controls = {
|
||||
icons = {
|
||||
pause = '⏸',
|
||||
play = '▶',
|
||||
step_into = '⏎',
|
||||
step_over = '⏭',
|
||||
step_out = '⏮',
|
||||
step_back = 'b',
|
||||
run_last = '▶▶',
|
||||
terminate = '⏹',
|
||||
disconnect = '⏏',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
|
||||
vim.keymap.set('n', '<F7>', dapui.toggle, { desc = 'Debug: See last session result.' })
|
||||
|
||||
dap.listeners.after.event_initialized['dapui_config'] = dapui.open
|
||||
dap.listeners.before.event_terminated['dapui_config'] = dapui.close
|
||||
dap.listeners.before.event_exited['dapui_config'] = dapui.close
|
||||
|
||||
-- Install golang specific config
|
||||
require('dap-go').setup()
|
||||
end,
|
||||
}
|
||||
126
lua/plugins/floaterminal.lua
Executable file
126
lua/plugins/floaterminal.lua
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
local M = {}
|
||||
|
||||
-- State to manage the floating terminal
|
||||
M.state = {
|
||||
floating = {
|
||||
buf = -1,
|
||||
win = -1,
|
||||
},
|
||||
}
|
||||
|
||||
-- Helper function to validate a window
|
||||
local function is_valid_window(win)
|
||||
return win and vim.api.nvim_win_is_valid(win)
|
||||
end
|
||||
|
||||
-- Helper function to validate a buffer
|
||||
local function is_valid_buffer(buf)
|
||||
return buf and vim.api.nvim_buf_is_valid(buf)
|
||||
end
|
||||
|
||||
-- Create or update the floating terminal
|
||||
local function create_floating_terminal(opts)
|
||||
opts = opts or {}
|
||||
|
||||
-- Calculate dimensions and position
|
||||
local width = opts.width or math.floor(vim.o.columns * 0.8)
|
||||
local height = opts.height or math.floor(vim.o.lines * 0.8)
|
||||
local col = math.floor((vim.o.columns - width) / 2)
|
||||
local row = math.floor((vim.o.lines - height) / 2)
|
||||
|
||||
-- Ensure buffer is valid or create a new one
|
||||
local buf = is_valid_buffer(opts.buf) and opts.buf or vim.api.nvim_create_buf(false, true)
|
||||
|
||||
-- Window configuration
|
||||
local win_config = {
|
||||
relative = 'editor',
|
||||
width = width,
|
||||
height = height,
|
||||
col = col,
|
||||
row = row,
|
||||
style = 'minimal',
|
||||
border = opts.border or 'rounded',
|
||||
title = opts.title or 'Terminal',
|
||||
title_pos = 'center',
|
||||
}
|
||||
|
||||
-- Create the floating window
|
||||
local ok, win = pcall(vim.api.nvim_open_win, buf, true, win_config)
|
||||
if not ok then
|
||||
vim.notify('Failed to create floating window: ' .. win, vim.log.levels.ERROR)
|
||||
return nil
|
||||
end
|
||||
|
||||
return { buf = buf, win = win }
|
||||
end
|
||||
|
||||
-- Toggle the floating terminal
|
||||
function M.toggle_terminal(opts)
|
||||
opts = opts or {}
|
||||
|
||||
if not is_valid_window(M.state.floating.win) then
|
||||
-- Create and initialize the floating terminal
|
||||
M.state.floating = create_floating_terminal({
|
||||
buf = M.state.floating.buf,
|
||||
width = opts.width,
|
||||
height = opts.height,
|
||||
border = opts.border,
|
||||
title = opts.title,
|
||||
})
|
||||
|
||||
if M.state.floating and is_valid_buffer(M.state.floating.buf) then
|
||||
-- Ensure the buffer is a terminal
|
||||
local buf = M.state.floating.buf
|
||||
if vim.bo[buf].buftype ~= 'terminal' then
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
vim.cmd('startinsert')
|
||||
vim.fn.termopen(os.getenv('SHELL') or 'sh')
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Close the floating window
|
||||
pcall(vim.api.nvim_win_close, M.state.floating.win, true)
|
||||
M.state.floating.win = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup function to initialize the module
|
||||
function M.setup(opts)
|
||||
opts = opts or {}
|
||||
|
||||
-- Create a user command for toggling the terminal
|
||||
vim.api.nvim_create_user_command('FloatTermToggle', function()
|
||||
M.toggle_terminal(opts)
|
||||
end, {})
|
||||
|
||||
-- Apply key mappings
|
||||
M.keys(opts.mapping)
|
||||
end
|
||||
|
||||
-- Apply key mappings
|
||||
function M.keys(mapping)
|
||||
local default_keymap = {
|
||||
['<leader>ft'] = {
|
||||
mode = { 'n', 't' },
|
||||
cmd = '<CMD>FloatTermToggle<CR>',
|
||||
options = { noremap = true, silent = true, desc = 'Toggle floating terminal' },
|
||||
},
|
||||
}
|
||||
|
||||
-- Use custom or default mappings
|
||||
local keymaps = mapping or default_keymap
|
||||
|
||||
for key, map in pairs(keymaps) do
|
||||
if map.desc then
|
||||
map.options = vim.tbl_extend('force', map.options or {}, { desc = map.desc })
|
||||
end
|
||||
|
||||
for _, mode in ipairs(map.mode) do
|
||||
pcall(vim.keymap.del, mode, key)
|
||||
end
|
||||
|
||||
vim.keymap.set(map.mode, key, map.cmd, map.options)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Loading…
Reference in a new issue