├── .gitignore ├── LICENSE ├── README.md ├── bat ├── config └── themes │ └── tokyonight_night.tmTheme ├── bigquery └── bigqueryrc ├── dlv └── config.yml ├── ergodox ├── README.md └── ergodox-keyboard-config.hex ├── espanso ├── config │ └── default.yml ├── match │ └── base.yml └── media │ ├── hfy.jpeg │ ├── middle.gif │ └── tlm.jpg ├── gh └── config.yml ├── ghostty └── config ├── git ├── config ├── git-ignore-for-home-dir └── ignore ├── jetbrains └── ideavimrc ├── latexmk └── latexmkrc ├── nvim ├── .neoconf.json ├── LICENSE ├── README.md ├── init.lua ├── lua │ ├── autocmds.lua │ ├── icons.lua │ ├── keyboard-bindings-mappings.lua │ ├── options.lua │ ├── plugins │ │ ├── chatgpt.lua │ │ ├── formatting.lua │ │ ├── gitsigns.lua │ │ ├── go.lua │ │ ├── lib.lua │ │ ├── lspconfig.lua │ │ ├── lualine.lua │ │ ├── mason.lua │ │ ├── mini.lua │ │ ├── neotest.lua │ │ ├── nvim-cmp.lua │ │ ├── nvim-tree.lua │ │ ├── tabular.lua │ │ ├── telescope.lua │ │ ├── tmux.lua │ │ ├── todo-comments.lua │ │ ├── tokyonight.lua │ │ ├── treesitter.lua │ │ ├── trouble.lua │ │ ├── vim-asterisk.lua │ │ ├── vim-surround.lua │ │ └── vimtex.lua │ ├── setup-plugins.lua │ └── util.lua └── stylua.toml ├── obsidian └── .vimrc ├── ripgrep └── ripgreprc ├── setup ├── install-brew-and-apps.sh ├── mac-system-config.sh └── set-up-zsh.sh ├── tmux ├── init_tmux_window.zsh └── tmux.conf └── zsh ├── .zshenv ├── .zshrc ├── brew.zsh ├── functions ├── bigquery ├── kk ├── kube ├── pod-logs ├── pod-port-forward-grpc ├── pod-port-forward-http ├── pod-sync ├── pr-comments └── toiletpresence ├── fzf.zsh ├── history.zsh ├── keybindings.zsh ├── scripts ├── extract ├── holla ├── mk ├── tmux-quick-monorepo └── tmux-quick-repo ├── theme.zsh └── vi-mode.zsh /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*/ 3 | 4 | !bat/**/* 5 | !bigquery/**/* 6 | !dlv/**/* 7 | !ergodox/**/* 8 | !espanso/**/* 9 | !fonts/**/* 10 | !gh/**/* 11 | !ghostty/**/* 12 | !git/**/* 13 | !jetbrains/**/* 14 | !latexmk/**/* 15 | !lazygit/config.yml 16 | !nvim/**/* 17 | !obsidian/**/* 18 | !ripgrep/**/* 19 | !setup/**/* 20 | !tmux/**/* 21 | !yomichan/**/* 22 | !zsh/**/* 23 | 24 | gh/hosts.yml 25 | nvim/lazy-lock.json 26 | dlv/.dbg_history 27 | espanso/match/local.yml 28 | 29 | **/.DS_Store 30 | **/*.log 31 | **/*.spl 32 | **/*.add 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Roger Guldbrandsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dotfiles (macOS) 2 | 3 | Works best for macOS (silicon). 4 | 5 | ## Setup steps from a fresh install 6 | 7 | ### Create a Git repo of home directory 8 | 9 | Open Terminal (for now) and run `git init` in the home directory, so you can go back in time if you mess up. 10 | You'll be prompted to install Xcode command line tools. Accept. Wait. 11 | 12 | Once that's done set up the git repo in home with (replace with appropriate email): 13 | 14 | ``` 15 | git config --global user.name "kinbiko" 16 | git config --global user.email "your@email.com" 17 | 18 | # Try `git init` in the home directory again. 19 | cd 20 | git init 21 | 22 | # Use `config/git/gitignore-for-home-dir` as the `.gitignore` for this repo: 23 | curl https://raw.githubusercontent.com/kinbiko/dotfiles/master/config/git/git-ignore-for-home-dir > .gitignore 24 | git add . 25 | git commit -m 'Initial commit' 26 | ``` 27 | 28 | ### Start getting access 29 | 30 | Set up the password manager, and install a better browser. 31 | 32 | ### Fetch and use this repo 33 | 34 | Set up SSH keys in GitHub following [the official instructions](https://docs.github.com/en/authentication/connecting-to-github-with-ssh). 35 | 36 | Clone this repo: 37 | 38 | ```sh 39 | git clone git@github.com:kinbiko/dotfiles.git ~/.config 40 | ``` 41 | 42 | Set up zsh: `setup/set-up-zsh.sh` 43 | 44 | If you close your current shell and open a new one, it should look pretty (and have a few extra features). 45 | That said, most software is not yet installed. 46 | 47 | ### Install software 48 | 49 | Install `brew` and install packages with `setup/install-brew-and-apps.sh`. 50 | 51 | You can now close Terminal and use a better one. 52 | 53 | ### Post-install software configuration 54 | 55 | #### Alfred 56 | 57 | - Disable spotlight cmd + space shortcut in keyboard -> shortuts -> spotlight 58 | - Set Alfred shortcut to `cmd + space` 59 | - Add a theme to Alfred. 60 | - Set up [the Jisho.org workflow](https://github.com/kinbiko/jisho-alfred). 61 | - Set up clipboard history. Map to `cmd + p` (who prints these days anyway?) 62 | 63 | #### Japanese language learning 64 | 65 | - Set up Yomitan 66 | - Set up Anki 67 | 68 | ## System preferences 69 | 70 | Run `setup/mac-system-config.sh` 71 | 72 | Do the rest manually for now, until I figure out the command-line commands to run for all of these. 73 | 74 | 1. Set up the Mac dock: 75 | 1. Move it to the left-hand side 76 | 1. Make icons much smaller 77 | 1. Pretty decent zoom 78 | 1. Don't animate opening apps 79 | 1. Don't show recent application in dock 80 | 1. Automatically hide and show dock (to get back some screen real estate) 81 | 1. Remove most apps from the dock. 82 | 1. Set system-wide theme. 83 | 1. Automatically hide the menu bar. 84 | 1. Keep track of 'none' recent items. 85 | 1. Revert scroll direction 86 | 1. Trackpad: 87 | 1. Lookup and data detectors -> tap with three fingers 88 | 1. Disable tap to click 89 | 1. Accessibility (this is where the good bits are): 90 | 1. System voice to fast, and start speaking with `CMD + ESC` 91 | 1. Zoom with ctrl + scroll 92 | 1. Pointer control -> trackpad- > 3-finger drag 93 | 1. Change language with alt + space, and have only two input sources: 94 | 1. American English 95 | 1. Hiragana 96 | 1. Keyboard: 97 | 1. Turn caps lock into ctrl 98 | -------------------------------------------------------------------------------- /bat/config: -------------------------------------------------------------------------------- 1 | --theme="tokyonight_night" 2 | -------------------------------------------------------------------------------- /bat/themes/tokyonight_night.tmTheme: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | author 5 | Folke Lemaitre (http://github.com/folke) 6 | colorSpaceName 7 | sRGB 8 | name 9 | TokyoNight 10 | semanticClass 11 | enki.theme.tokyo 12 | settings 13 | 14 | 15 | settings 16 | 17 | activeGuide 18 | #363b54 19 | background 20 | #1a1b26 21 | caret 22 | #DBC08A 23 | findHighlight 24 | #ffa300 25 | findHighlightForeground 26 | #000000 27 | foreground 28 | #c0caf5 29 | guide 30 | #4f4f5e40 31 | gutterForeground 32 | #3b415caa 33 | inactiveSelection 34 | #282833 35 | invisibles 36 | #4f4f5e 37 | lineHighlight 38 | #00000030 39 | selection 40 | #9D599D40 41 | selectionBorder 42 | #9D599D 43 | shadow 44 | #00000010 45 | stackGuide 46 | #4f4f5e60 47 | tagsOptions 48 | underline 49 | 50 | 51 | 52 | name 53 | Italics - Comments, Storage, Keyword Flow, Vue attributes, Decorators 54 | scope 55 | comment, meta.var.expr storage.type, keyword.control.flow, meta.directive.vue punctuation.separator.key-value.html, meta.directive.vue entity.other.attribute-name.html, tag.decorator.js entity.name.tag.js, tag.decorator.js punctuation.definition.tag.js, storage.modifier 56 | settings 57 | 58 | fontStyle 59 | italic 60 | 61 | 62 | 63 | name 64 | Comment 65 | scope 66 | comment, comment.block.documentation, punctuation.definition.comment 67 | settings 68 | 69 | foreground 70 | #565f89 71 | 72 | 73 | 74 | name 75 | Comment Doc 76 | scope 77 | comment.block.documentation variable, comment.block.documentation storage, comment.block.documentation punctuation, comment.block.documentation keyword, comment.block.documentation support, comment.block.documentation markup, comment.block.documentation markup.inline.raw.string.markdown, keyword.other.phpdoc.php 78 | settings 79 | 80 | foreground 81 | #565f89 82 | 83 | 84 | 85 | name 86 | Number, Boolean, Undefined, Null 87 | scope 88 | variable.other.constant, punctuation.definition.constant, constant.language, constant.numeric, support.constant 89 | settings 90 | 91 | foreground 92 | #ff9e64 93 | 94 | 95 | 96 | name 97 | String, Symbols, Markup Heading 98 | scope 99 | string, constant.other.symbol, constant.other.key, markup.heading, meta.attribute-selector 100 | settings 101 | 102 | fontStyle 103 | 104 | foreground 105 | #9ece6a 106 | 107 | 108 | 109 | name 110 | Colors 111 | scope 112 | constant.other.color, constant.other.color.rgb-value.hex punctuation.definition.constant 113 | settings 114 | 115 | foreground 116 | #9aa5ce 117 | 118 | 119 | 120 | name 121 | Invalid 122 | scope 123 | invalid, invalid.illegal 124 | settings 125 | 126 | foreground 127 | #f7768e 128 | 129 | 130 | 131 | name 132 | Invalid deprecated 133 | scope 134 | invalid.deprecated 135 | settings 136 | 137 | foreground 138 | #bb9af7 139 | 140 | 141 | 142 | name 143 | Storage Type 144 | scope 145 | storage.type 146 | settings 147 | 148 | foreground 149 | #bb9af7 150 | 151 | 152 | 153 | name 154 | Storage - modifier, var, const, let 155 | scope 156 | meta.var.expr storage.type, storage.modifier 157 | settings 158 | 159 | foreground 160 | #9d7cd8 161 | 162 | 163 | 164 | name 165 | Interpolation 166 | scope 167 | punctuation.definition.template-expression, punctuation.section.embedded 168 | settings 169 | 170 | foreground 171 | #7dcfff 172 | 173 | 174 | 175 | name 176 | Spread 177 | scope 178 | keyword.operator.spread, keyword.operator.rest 179 | settings 180 | 181 | fontStyle 182 | bold 183 | foreground 184 | #f7768e 185 | 186 | 187 | 188 | name 189 | Operator, Misc 190 | scope 191 | keyword.operator, keyword.control.as, keyword.other, keyword.operator.bitwise.shift, punctuation, punctuation.definition.constant.markdown, punctuation.definition.string, punctuation.support.type.property-name, text.html.vue-html meta.tag, punctuation.definition.keyword, punctuation.terminator.rule, punctuation.definition.entity, punctuation.definition.tag, punctuation.separator.inheritance.php, punctuation.definition.tag.html, keyword.other.template, keyword.other.substitution, entity.name.operator, text.html.vue meta.tag.block.any.html, text.html.vue meta.tag.inline.any.html, text.html.vue meta.tag.other.html, text.html.twig meta.tag.inline.any.html, text.html.twig meta.tag.block.any.html, text.html.twig meta.tag.structure.any.html, text.html.twig meta.tag.any.html 192 | settings 193 | 194 | foreground 195 | #89ddff 196 | 197 | 198 | 199 | name 200 | Import, Export, From, Default 201 | scope 202 | keyword.control.import, keyword.control.export, keyword.control.from, keyword.control.default, meta.import keyword.other 203 | settings 204 | 205 | foreground 206 | #7dcfff 207 | 208 | 209 | 210 | name 211 | Keyword 212 | scope 213 | keyword, keyword.control, keyword.other.important 214 | settings 215 | 216 | foreground 217 | #bb9af7 218 | 219 | 220 | 221 | name 222 | Keyword SQL 223 | scope 224 | keyword.other.DML 225 | settings 226 | 227 | foreground 228 | #7dcfff 229 | 230 | 231 | 232 | name 233 | Keyword Operator Logical, Arrow, Ternary, Comparison 234 | scope 235 | keyword.operator.logical, storage.type.function, keyword.operator.bitwise, keyword.operator.ternary, keyword.operator.comparison, keyword.operator.relational, keyword.operator.or.regexp 236 | settings 237 | 238 | foreground 239 | #bb9af7 240 | 241 | 242 | 243 | name 244 | Tag 245 | scope 246 | entity.name.tag, entity.name.tag support.class.component, meta.tag 247 | settings 248 | 249 | foreground 250 | #f7768e 251 | 252 | 253 | 254 | name 255 | Tag Punctuation 256 | scope 257 | punctuation.definition.tag, punctuation.definition.tag.html, punctuation.definition.tag.begin.html, punctuation.definition.tag.end.html 258 | settings 259 | 260 | foreground 261 | #ba3c97 262 | 263 | 264 | 265 | name 266 | Blade 267 | scope 268 | keyword.blade, entity.name.function.blade 269 | settings 270 | 271 | foreground 272 | #7aa2f7 273 | 274 | 275 | 276 | name 277 | PHP - Embedded Tag 278 | scope 279 | punctuation.section.embedded.begin.php, punctuation.section.embedded.end.php 280 | settings 281 | 282 | foreground 283 | #0db9d7 284 | 285 | 286 | 287 | name 288 | Smarty - Twig tag - Blade 289 | scope 290 | punctuation.definition.variable.smarty, punctuation.section.embedded.begin.smarty, punctuation.section.embedded.end.smarty, meta.tag.template.value.twig, punctuation.section.tag.twig, meta.tag.expression.twig, punctuation.definition.tag.expression.twig, punctuation.definition.tag.output.twig, variable.parameter.smarty 291 | settings 292 | 293 | foreground 294 | #7DCFFF 295 | 296 | 297 | 298 | name 299 | Smarty - Twig variable - function 300 | scope 301 | variable.other.property.twig, support.function.twig, meta.function-call.twig, keyword.control.twig, keyword.control.smarty, keyword.operator.other.twig, keyword.operator.comparison.twig, support.function.functions.twig, support.function.functions.twig, keyword.operator.assignment.twig, support.function.filters.twig, support.function.built-in.smarty, keyword.operator.smarty, text.blade text.html.blade custom.compiler.blade.php punctuation.section.embedded.php entity.name.tag.block.any.html, text.blade text.html.blade custom.compiler.blade.php punctuation.section.embedded.php constant.other.inline-data.html, text.blade text.html.blade custom.compiler.blade.php support.function constant.other.inline-data.html 302 | settings 303 | 304 | foreground 305 | #0db9d7 306 | 307 | 308 | 309 | name 310 | Globals - PHP Constants etc 311 | scope 312 | constant.other.php, variable.other.global.safer, variable.other.global.safer punctuation.definition.variable, variable.other.global, variable.other.global punctuation.definition.variable, constant.other 313 | settings 314 | 315 | foreground 316 | #e0af68 317 | 318 | 319 | 320 | name 321 | Variables 322 | scope 323 | variable, support.variable, string constant.other.placeholder 324 | settings 325 | 326 | foreground 327 | #c0caf5 328 | 329 | 330 | 331 | name 332 | Object Variable 333 | scope 334 | variable.other.object, support.module.node 335 | settings 336 | 337 | foreground 338 | #c0caf5 339 | 340 | 341 | 342 | name 343 | Object Key 344 | scope 345 | meta.object-literal.key, meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js, string.alias.graphql, string.unquoted.graphql, string.unquoted.alias.graphql, meta.field.declaration.ts variable.object.property 346 | settings 347 | 348 | foreground 349 | #73daca 350 | 351 | 352 | 353 | name 354 | Object Property 355 | scope 356 | variable.other.property, support.variable.property, support.variable.property.dom, meta.function-call variable.other.object.property, variable.language.prototype, meta.property.object, variable.other.member 357 | settings 358 | 359 | foreground 360 | #7dcfff 361 | 362 | 363 | 364 | name 365 | Object Property 366 | scope 367 | variable.other.object.property 368 | settings 369 | 370 | foreground 371 | #c0caf5 372 | 373 | 374 | 375 | name 376 | Object Literal Member lvl 3 (Vue Prop Validation) 377 | scope 378 | meta.objectliteral meta.object.member meta.objectliteral meta.object.member meta.objectliteral meta.object.member meta.object-literal.key 379 | settings 380 | 381 | foreground 382 | #41a6b5 383 | 384 | 385 | 386 | name 387 | C-related Block Level Variables 388 | scope 389 | source.cpp meta.block variable.other 390 | settings 391 | 392 | foreground 393 | #f7768e 394 | 395 | 396 | 397 | name 398 | Other Variable 399 | scope 400 | support.other.variable 401 | settings 402 | 403 | foreground 404 | #f7768e 405 | 406 | 407 | 408 | name 409 | Methods 410 | scope 411 | meta.class-method.js entity.name.function.js, entity.name.method.js, variable.function.constructor, keyword.other.special-method, storage.type.cs 412 | settings 413 | 414 | foreground 415 | #7aa2f7 416 | 417 | 418 | 419 | name 420 | Function Definition 421 | scope 422 | entity.name.function, meta.function-call, meta.function-call entity.name.function, variable.function, meta.definition.method entity.name.function, meta.object-literal entity.name.function 423 | settings 424 | 425 | foreground 426 | #7aa2f7 427 | 428 | 429 | 430 | name 431 | Function Argument 432 | scope 433 | variable.parameter.function.language.special, variable.parameter, meta.function.parameters punctuation.definition.variable, meta.function.parameter variable 434 | settings 435 | 436 | foreground 437 | #e0af68 438 | 439 | 440 | 441 | name 442 | Constant, Tag Attribute 443 | scope 444 | keyword.other.type.php, storage.type.php, constant.character, constant.escape, keyword.other.unit 445 | settings 446 | 447 | foreground 448 | #bb9af7 449 | 450 | 451 | 452 | name 453 | Variable Definition 454 | scope 455 | meta.definition.variable variable.other.constant, meta.definition.variable variable.other.readwrite, variable.other.declaration 456 | settings 457 | 458 | foreground 459 | #bb9af7 460 | 461 | 462 | 463 | name 464 | Inherited Class 465 | scope 466 | entity.other.inherited-class 467 | settings 468 | 469 | fontStyle 470 | 471 | foreground 472 | #bb9af7 473 | 474 | 475 | 476 | name 477 | Class, Support, DOM, etc 478 | scope 479 | support.class, support.type, variable.other.readwrite.alias, support.orther.namespace.use.php, meta.use.php, support.other.namespace.php, support.type.sys-types, support.variable.dom, support.constant.math, support.type.object.module, support.constant.json, entity.name.namespace, meta.import.qualifier, entity.name.class 480 | settings 481 | 482 | foreground 483 | #0db9d7 484 | 485 | 486 | 487 | name 488 | Class Name 489 | scope 490 | entity.name 491 | settings 492 | 493 | foreground 494 | #c0caf5 495 | 496 | 497 | 498 | name 499 | Support Function 500 | scope 501 | support.function 502 | settings 503 | 504 | foreground 505 | #0db9d7 506 | 507 | 508 | 509 | name 510 | CSS Class and Support 511 | scope 512 | source.css support.type.property-name, source.sass support.type.property-name, source.scss support.type.property-name, source.less support.type.property-name, source.stylus support.type.property-name, source.postcss support.type.property-name, support.type.property-name.css, support.type.vendored.property-name, support.type.map.key 513 | settings 514 | 515 | foreground 516 | #7aa2f7 517 | 518 | 519 | 520 | name 521 | CSS Font 522 | scope 523 | support.constant.font-name, meta.definition.variable 524 | settings 525 | 526 | foreground 527 | #9ece6a 528 | 529 | 530 | 531 | name 532 | CSS Class 533 | scope 534 | entity.other.attribute-name.class, meta.at-rule.mixin.scss entity.name.function.scss 535 | settings 536 | 537 | foreground 538 | #9ece6a 539 | 540 | 541 | 542 | name 543 | CSS ID 544 | scope 545 | entity.other.attribute-name.id 546 | settings 547 | 548 | foreground 549 | #fc7b7b 550 | 551 | 552 | 553 | name 554 | CSS Tag 555 | scope 556 | entity.name.tag.css, entity.name.tag.reference, entity.name.tag.scss 557 | settings 558 | 559 | foreground 560 | #0db9d7 561 | 562 | 563 | 564 | name 565 | CSS Tag Reference 566 | scope 567 | entity.name.tag.reference 568 | settings 569 | 570 | foreground 571 | #e0af68 572 | 573 | 574 | 575 | name 576 | CSS Property Separator 577 | scope 578 | meta.property-list punctuation.separator.key-value 579 | settings 580 | 581 | foreground 582 | #9abdf5 583 | 584 | 585 | 586 | name 587 | CSS Punctuation 588 | scope 589 | meta.property-list, punctuation.definition.entity.css 590 | settings 591 | 592 | foreground 593 | #e0af68 594 | 595 | 596 | 597 | name 598 | SCSS @ 599 | scope 600 | meta.at-rule.mixin keyword.control.at-rule.mixin, meta.at-rule.include entity.name.function.scss, meta.at-rule.include keyword.control.at-rule.include 601 | settings 602 | 603 | foreground 604 | #bb9af7 605 | 606 | 607 | 608 | name 609 | SCSS Mixins, Extends, Include Keyword 610 | scope 611 | keyword.control.at-rule.include punctuation.definition.keyword, keyword.control.at-rule.mixin punctuation.definition.keyword, meta.at-rule.include keyword.control.at-rule.include, keyword.control.at-rule.extend punctuation.definition.keyword, meta.at-rule.extend keyword.control.at-rule.extend, entity.other.attribute-name.placeholder.css punctuation.definition.entity.css, meta.at-rule.media keyword.control.at-rule.media, meta.at-rule.mixin keyword.control.at-rule.mixin, meta.at-rule.function keyword.control.at-rule.function, keyword.control punctuation.definition.keyword, meta.at-rule.import.scss entity.other.attribute-name.placeholder.scss punctuation.definition.entity.scss, meta.at-rule.import.scss keyword.control.at-rule.import.scss 612 | settings 613 | 614 | foreground 615 | #9d7cd8 616 | 617 | 618 | 619 | name 620 | SCSS Include Mixin Argument 621 | scope 622 | meta.property-list meta.at-rule.include 623 | settings 624 | 625 | foreground 626 | #c0caf5 627 | 628 | 629 | 630 | name 631 | CSS value 632 | scope 633 | support.constant.property-value 634 | settings 635 | 636 | foreground 637 | #ff9e64 638 | 639 | 640 | 641 | name 642 | Sub-methods 643 | scope 644 | entity.name.module.js, variable.import.parameter.js, variable.other.class.js 645 | settings 646 | 647 | foreground 648 | #c0caf5 649 | 650 | 651 | 652 | name 653 | Language methods 654 | scope 655 | variable.language 656 | settings 657 | 658 | foreground 659 | #f7768e 660 | 661 | 662 | 663 | name 664 | Variable punctuation 665 | scope 666 | variable.other punctuation.definition.variable 667 | settings 668 | 669 | foreground 670 | #c0caf5 671 | 672 | 673 | 674 | name 675 | Keyword this with Punctuation, ES7 Bind Operator 676 | scope 677 | source.js constant.other.object.key.js string.unquoted.label.js, variable.language.this punctuation.definition.variable, keyword.other.this 678 | settings 679 | 680 | foreground 681 | #f7768e 682 | 683 | 684 | 685 | name 686 | HTML Attributes 687 | scope 688 | entity.other.attribute-name, text.html.basic entity.other.attribute-name.html, text.html.basic entity.other.attribute-name, text.blade entity.other.attribute-name.class, text.html.smarty entity.other.attribute-name.class 689 | settings 690 | 691 | foreground 692 | #bb9af7 693 | 694 | 695 | 696 | name 697 | Vue Template attributes 698 | scope 699 | meta.directive.vue punctuation.separator.key-value.html, meta.directive.vue entity.other.attribute-name.html 700 | settings 701 | 702 | foreground 703 | #bb9af7 704 | 705 | 706 | 707 | name 708 | Vue Template attribute separator 709 | scope 710 | meta.directive.vue punctuation.separator.key-value.html 711 | settings 712 | 713 | foreground 714 | #89ddff 715 | 716 | 717 | 718 | name 719 | CSS IDs 720 | scope 721 | source.sass keyword.control 722 | settings 723 | 724 | foreground 725 | #7aa2f7 726 | 727 | 728 | 729 | name 730 | CSS psuedo selectors 731 | scope 732 | entity.other.attribute-name.pseudo-class, entity.other.attribute-name.pseudo-element, entity.other.attribute-name.placeholder, meta.property-list meta.property-value 733 | settings 734 | 735 | foreground 736 | #bb9af7 737 | 738 | 739 | 740 | name 741 | Inserted 742 | scope 743 | markup.inserted 744 | settings 745 | 746 | foreground 747 | #449dab 748 | 749 | 750 | 751 | name 752 | Deleted 753 | scope 754 | markup.deleted 755 | settings 756 | 757 | foreground 758 | #914c54 759 | 760 | 761 | 762 | name 763 | Changed 764 | scope 765 | markup.changed 766 | settings 767 | 768 | foreground 769 | #6183bb 770 | 771 | 772 | 773 | name 774 | Regular Expressions 775 | scope 776 | string.regexp 777 | settings 778 | 779 | foreground 780 | #b4f9f8 781 | 782 | 783 | 784 | name 785 | Regular Expressions - Punctuation 786 | scope 787 | punctuation.definition.group 788 | settings 789 | 790 | foreground 791 | #f7768e 792 | 793 | 794 | 795 | name 796 | Regular Expressions - Character Class 797 | scope 798 | constant.other.character-class.regexp 799 | settings 800 | 801 | foreground 802 | #bb9af7 803 | 804 | 805 | 806 | name 807 | Regular Expressions - Character Class Set 808 | scope 809 | constant.other.character-class.set.regexp, punctuation.definition.character-class.regexp 810 | settings 811 | 812 | foreground 813 | #e0af68 814 | 815 | 816 | 817 | name 818 | Regular Expressions - Quantifier 819 | scope 820 | keyword.operator.quantifier.regexp 821 | settings 822 | 823 | foreground 824 | #89ddff 825 | 826 | 827 | 828 | name 829 | Regular Expressions - Backslash 830 | scope 831 | constant.character.escape.backslash 832 | settings 833 | 834 | foreground 835 | #c0caf5 836 | 837 | 838 | 839 | name 840 | Escape Characters 841 | scope 842 | constant.character.escape 843 | settings 844 | 845 | foreground 846 | #89ddff 847 | 848 | 849 | 850 | name 851 | Decorators 852 | scope 853 | tag.decorator.js entity.name.tag.js, tag.decorator.js punctuation.definition.tag.js 854 | settings 855 | 856 | foreground 857 | #7aa2f7 858 | 859 | 860 | 861 | name 862 | CSS Units 863 | scope 864 | keyword.other.unit 865 | settings 866 | 867 | foreground 868 | #f7768e 869 | 870 | 871 | 872 | name 873 | JSON Key - Level 0 874 | scope 875 | source.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json string.quoted.double.json 876 | settings 877 | 878 | foreground 879 | #7aa2f7 880 | 881 | 882 | 883 | name 884 | JSON Key - Level 1 885 | scope 886 | source.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.quoted.double.json 887 | settings 888 | 889 | foreground 890 | #0db9d7 891 | 892 | 893 | 894 | name 895 | JSON Key - Level 2 896 | scope 897 | source.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.quoted.double.json 898 | settings 899 | 900 | foreground 901 | #7dcfff 902 | 903 | 904 | 905 | name 906 | JSON Key - Level 3 907 | scope 908 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.quoted.double.json 909 | settings 910 | 911 | foreground 912 | #bb9af7 913 | 914 | 915 | 916 | name 917 | JSON Key - Level 4 918 | scope 919 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json string.quoted.double.json 920 | settings 921 | 922 | foreground 923 | #e0af68 924 | 925 | 926 | 927 | name 928 | JSON Key - Level 5 929 | scope 930 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json string.quoted.double.json 931 | settings 932 | 933 | foreground 934 | #0db9d7 935 | 936 | 937 | 938 | name 939 | JSON Key - Level 6 940 | scope 941 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json string.quoted.double.json 942 | settings 943 | 944 | foreground 945 | #73daca 946 | 947 | 948 | 949 | name 950 | JSON Key - Level 7 951 | scope 952 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json 953 | settings 954 | 955 | foreground 956 | #f7768e 957 | 958 | 959 | 960 | name 961 | JSON Key - Level 8 962 | scope 963 | source.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.value.json meta.sequence.json meta.mapping.key.json string.quoted.double.json punctuation.definition.string.end.json 964 | settings 965 | 966 | foreground 967 | #9ece6a 968 | 969 | 970 | 971 | name 972 | JSON Key - value 973 | scope 974 | source.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json, source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json 975 | settings 976 | 977 | foreground 978 | #9ece6a 979 | 980 | 981 | 982 | name 983 | Plain Punctuation 984 | scope 985 | punctuation.definition.list_item.markdown 986 | settings 987 | 988 | foreground 989 | #9abdf5 990 | 991 | 992 | 993 | name 994 | Block Punctuation 995 | scope 996 | meta.block, meta.brace, punctuation.definition.block, punctuation.definition.use, punctuation.definition.group.shell, punctuation.definition.class, punctuation.definition.begin.bracket, punctuation.definition.end.bracket, punctuation.definition.parameters, punctuation.definition.arguments, punctuation.definition.dictionary, punctuation.definition.array, punctuation.section 997 | settings 998 | 999 | foreground 1000 | #9abdf5 1001 | 1002 | 1003 | 1004 | name 1005 | Markdown - Plain 1006 | scope 1007 | meta.jsx.children, meta.embedded.block 1008 | settings 1009 | 1010 | foreground 1011 | #c0caf5 1012 | 1013 | 1014 | 1015 | name 1016 | HTML text 1017 | scope 1018 | text.html 1019 | settings 1020 | 1021 | foreground 1022 | #9aa5ce 1023 | 1024 | 1025 | 1026 | name 1027 | Markdown - Markup Raw Inline 1028 | scope 1029 | text.html.markdown markup.inline.raw.markdown 1030 | settings 1031 | 1032 | foreground 1033 | #bb9af7 1034 | 1035 | 1036 | 1037 | name 1038 | Markdown - Markup Raw Inline Punctuation 1039 | scope 1040 | text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown 1041 | settings 1042 | 1043 | foreground 1044 | #4E5579 1045 | 1046 | 1047 | 1048 | name 1049 | Markdown - Heading 1 1050 | scope 1051 | heading.1.markdown entity.name, heading.1.markdown punctuation.definition.heading.markdown 1052 | settings 1053 | 1054 | fontStyle 1055 | bold 1056 | foreground 1057 | #89ddff 1058 | 1059 | 1060 | 1061 | name 1062 | Markdown - Heading 2 1063 | scope 1064 | heading.2.markdown entity.name, heading.2.markdown punctuation.definition.heading.markdown 1065 | settings 1066 | 1067 | fontStyle 1068 | bold 1069 | foreground 1070 | #61bdf2 1071 | 1072 | 1073 | 1074 | name 1075 | Markdown - Heading 3 1076 | scope 1077 | heading.3.markdown entity.name, heading.3.markdown punctuation.definition.heading.markdown 1078 | settings 1079 | 1080 | fontStyle 1081 | bold 1082 | foreground 1083 | #7aa2f7 1084 | 1085 | 1086 | 1087 | name 1088 | Markdown - Heading 4 1089 | scope 1090 | heading.4.markdown entity.name, heading.4.markdown punctuation.definition.heading.markdown 1091 | settings 1092 | 1093 | fontStyle 1094 | bold 1095 | foreground 1096 | #6d91de 1097 | 1098 | 1099 | 1100 | name 1101 | Markdown - Heading 5 1102 | scope 1103 | heading.5.markdown entity.name, heading.5.markdown punctuation.definition.heading.markdown 1104 | settings 1105 | 1106 | fontStyle 1107 | bold 1108 | foreground 1109 | #9aa5ce 1110 | 1111 | 1112 | 1113 | name 1114 | Markdown - Heading 6 1115 | scope 1116 | heading.6.markdown entity.name, heading.6.markdown punctuation.definition.heading.markdown 1117 | settings 1118 | 1119 | fontStyle 1120 | bold 1121 | foreground 1122 | #747ca1 1123 | 1124 | 1125 | 1126 | name 1127 | Markup - Italic 1128 | scope 1129 | markup.italic, markup.italic punctuation 1130 | settings 1131 | 1132 | fontStyle 1133 | italic 1134 | foreground 1135 | #c0caf5 1136 | 1137 | 1138 | 1139 | name 1140 | Markup - Bold 1141 | scope 1142 | markup.bold, markup.bold punctuation 1143 | settings 1144 | 1145 | fontStyle 1146 | bold 1147 | foreground 1148 | #c0caf5 1149 | 1150 | 1151 | 1152 | name 1153 | Markup - Bold-Italic 1154 | scope 1155 | markup.bold markup.italic, markup.bold markup.italic punctuation 1156 | settings 1157 | 1158 | fontStyle 1159 | bold italic 1160 | foreground 1161 | #c0caf5 1162 | 1163 | 1164 | 1165 | name 1166 | Markup - Underline 1167 | scope 1168 | markup.underline, markup.underline punctuation 1169 | settings 1170 | 1171 | fontStyle 1172 | underline 1173 | 1174 | 1175 | 1176 | name 1177 | Markdown - Blockquote 1178 | scope 1179 | markup.quote punctuation.definition.blockquote.markdown 1180 | settings 1181 | 1182 | foreground 1183 | #4e5579 1184 | 1185 | 1186 | 1187 | name 1188 | Markup - Quote 1189 | scope 1190 | markup.quote 1191 | settings 1192 | 1193 | fontStyle 1194 | italic 1195 | 1196 | 1197 | 1198 | name 1199 | Markdown - Link 1200 | scope 1201 | string.other.link, markup.underline.link, constant.other.reference.link.markdown, string.other.link.description.title.markdown 1202 | settings 1203 | 1204 | foreground 1205 | #73daca 1206 | 1207 | 1208 | 1209 | name 1210 | Markdown - Fenced Code Block 1211 | scope 1212 | markup.fenced_code.block.markdown, markup.inline.raw.string.markdown, variable.language.fenced.markdown 1213 | settings 1214 | 1215 | foreground 1216 | #89ddff 1217 | 1218 | 1219 | 1220 | name 1221 | Markdown - Separator 1222 | scope 1223 | meta.separator 1224 | settings 1225 | 1226 | fontStyle 1227 | bold 1228 | foreground 1229 | #444b6a 1230 | 1231 | 1232 | 1233 | name 1234 | Markup - Table 1235 | scope 1236 | markup.table 1237 | settings 1238 | 1239 | foreground 1240 | #c0cefc 1241 | 1242 | 1243 | 1244 | name 1245 | Token - Info 1246 | scope 1247 | token.info-token 1248 | settings 1249 | 1250 | foreground 1251 | #0db9d7 1252 | 1253 | 1254 | 1255 | name 1256 | Token - Warn 1257 | scope 1258 | token.warn-token 1259 | settings 1260 | 1261 | foreground 1262 | #ffdb69 1263 | 1264 | 1265 | 1266 | name 1267 | Token - Error 1268 | scope 1269 | token.error-token 1270 | settings 1271 | 1272 | foreground 1273 | #db4b4b 1274 | 1275 | 1276 | 1277 | name 1278 | Token - Debug 1279 | scope 1280 | token.debug-token 1281 | settings 1282 | 1283 | foreground 1284 | #b267e6 1285 | 1286 | 1287 | 1288 | name 1289 | Apache Tag 1290 | scope 1291 | entity.tag.apacheconf 1292 | settings 1293 | 1294 | foreground 1295 | #f7768e 1296 | 1297 | 1298 | 1299 | name 1300 | Preprocessor 1301 | scope 1302 | meta.preprocessor 1303 | settings 1304 | 1305 | foreground 1306 | #73daca 1307 | 1308 | 1309 | 1310 | name 1311 | ENV value 1312 | scope 1313 | source.env 1314 | settings 1315 | 1316 | foreground 1317 | #7aa2f7 1318 | 1319 | 1320 | 1321 | uuid 1322 | 06f855e3-9fb7-4fb1-b790-aef06065f34e 1323 | 1324 | 1325 | -------------------------------------------------------------------------------- /bigquery/bigqueryrc: -------------------------------------------------------------------------------- 1 | #--apilog=stderr 2 | --format=prettyjson 3 | 4 | [query] 5 | --use_legacy_sql=false 6 | --max_rows=1000 7 | 8 | # Stop if attempting to bill for more than 20GB. 9 | --maximum_bytes_billed=20000000000 10 | -------------------------------------------------------------------------------- /dlv/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration file for the delve debugger. 2 | 3 | # This is the default configuration file. Available options are provided, but disabled. 4 | # Delete the leading hash mark to enable an item. 5 | 6 | # Uncomment the following line and set your preferred ANSI color for source 7 | # line numbers in the (list) command. The default is 34 (dark blue). See 8 | # https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit 9 | # source-list-line-color: "\x1b[34m" 10 | 11 | # Uncomment the following lines to change the colors used by syntax highlighting. 12 | # source-list-keyword-color: "\x1b[0m" 13 | # source-list-string-color: "\x1b[92m" 14 | # source-list-number-color: "\x1b[0m" 15 | # source-list-comment-color: "\x1b[95m" 16 | # source-list-arrow-color: "\x1b[93m" 17 | 18 | # Uncomment to change the number of lines printed above and below cursor when 19 | # listing source code. 20 | source-list-line-count: 15 21 | 22 | # Provided aliases will be added to the default aliases for a given command. 23 | aliases: 24 | # command: ["alias1", "alias2"] 25 | 26 | # Define sources path substitution rules. Can be used to rewrite a source path stored 27 | # in program's debug information, if the sources were moved to a different place 28 | # between compilation and debugging. 29 | # Note that substitution rules will not be used for paths passed to "break" and "trace" 30 | # commands. 31 | substitute-path: 32 | # - {from: path, to: path} 33 | 34 | # Maximum number of elements loaded from an array. 35 | max-array-values: 10 36 | 37 | # Maximum loaded string length. 38 | max-string-len: 120 39 | 40 | # Output evaluation. 41 | max-variable-recurse: 2 42 | 43 | # Uncomment the following line to make the whatis command also print the DWARF location expression of its argument. 44 | # show-location-expr: true 45 | 46 | # Allow user to specify output syntax flavor of assembly, one of this list "intel"(default), "gnu", "go". 47 | # disassemble-flavor: intel 48 | 49 | # List of directories to use when searching for separate debug info files. 50 | debug-info-directories: ["/usr/lib/debug/.build-id"] 51 | -------------------------------------------------------------------------------- /ergodox/README.md: -------------------------------------------------------------------------------- 1 | # Ergodox online configurations and comments 2 | 3 | This is a list of all my Ergodox configurations as they are online. 4 | Unfortunately, simply storing the config isn't enough to modify it later on. 5 | 6 | ### Remember: 7 | 8 | 9 | 10 | - When selecting `"` in the online utility, because of my keyboard mapping this will actually be `@` 11 | - "non-US `\`" is actually `` ` ``. 12 | - `` ` `` is actually `\` 13 | - `\` is actually `#` 14 | 15 | Maybe it's easier to switch to a US English keyboard layout? 16 | 17 | ### Structure 18 | 19 | The heading of each of the below sections links to the corresponding version of my Ergodox config. 20 | 21 | Below the heading are some frustrations with the current layout and ideas for the next version. 22 | 23 | ## [Version 1](https://configure.ergodox-ez.com/ergodox-ez/layouts/gaAw4/latest/1) 24 | 25 | - Get rid of numbers along the top entirely. I rarely hit the right one, and it's probably easier for me to hit two modes to get it into a mode where the numpad becomes available. Then I won't be as tempted to use the top row for programming buttons like `!"\$%^&\*()\_+=-` etc. 26 | - Make layer 1 + caps lock do backspace. 27 | - Add mouse button clicks 28 | - The lights doesn't appear to work with this one. I think I chose glow, which might not match what my keyboard is capable of. 29 | - Caps lock becomes CTRL when held or escape when not held 30 | - big button []{} goes away in favour of second layer 31 | - left 'enter' is layer 2 32 | - Clean up weird stuff in layer 0 33 | 34 | ## [Version 2](https://configure.ergodox-ez.com/ergodox-ez/layouts/XbMwy/latest/2) 35 | 36 | - This layout has no way of doing minus or equals 37 | 38 | ## [Version 3](https://configure.ergodox-ez.com/ergodox-ez/layouts/40E5n/latest/1) 39 | 40 | - This layout has no way of hitting plus and underscore. 41 | - Need to be able to turn off the colours, so it's not distracting to other people. 42 | 43 | ## [Version 4](https://configure.ergodox-ez.com/ergodox-ez/layouts/Rjr55/latest/0) 44 | 45 | - No way of toggling or weakening the colours between layers. 46 | 47 | ## [Version 5](https://configure.ergodox-ez.com/ergodox-ez/layouts/JaQLB/latest/2) 48 | 49 | - Need to remap "Go to definition" and "Pop" in vim or make `[]` easier to hit in combination with space 50 | - Touch time for tap vs. press is far too short 51 | - Would be good to have quotes on the bottom left row, then brackets above that, the funky symbols above that again. 52 | - Make layer 1 arrow keys be `hjkl`. Mouse clicks can be the remaining thumb button on the left. 53 | - Switch `&` and `*` 54 | 55 | ## [Version 6](https://configure.ergodox-ez.com/ergodox-ez/layouts/9DKbW/latest/1) 56 | 57 | - `CTRL + ESC` thing is still a bit awkward when trying to quickly `CTRL+a` in TMUX for instance. Might be best to only have it as CTRL. 58 | - Having `@` and `~` right next to each other can lead to awkward executions of a register when I want to change the capitalisation of a character in vim 59 | - It's a bit awkward reaching the most common numbers right now. Consider moving numbers to half above the `hjkl` keys and half below. 60 | - Also, let's make the number rows `01234`, `56789` as `1` and `0` are used together a lot. 61 | - Need to get `^` back to an easier position to hit. 62 | 63 | ## [Version 7](https://configure.ergodox-ez.com/ergodox-ez/layouts/bv5gg/latest/0) 64 | 65 | - Add red/green/refactor backlight buttons 66 | - Make `` ` `` and `\` easier to reach. Maybe instead of `-` and `=` on the big keys on the LHS which I never use. 67 | 68 | ## [Version 8](https://configure.ergodox-ez.com/ergodox-ez/layouts/x9Jqo/latest/0) 69 | 70 | - Make hitting `ctrl+tab` easier 71 | - Left 'enter' key is never used. 72 | - Make layer 1 caps lock be ESC 73 | - Re-map the RHS bottom row arrow keys to something more useful, as I keep using layer 1 + `hjkl` anyway for arrows 74 | - mouse movement 75 | - expose `F1-F12` keys 76 | 77 | ## [Version 9](https://configure.ergodox-ez.com/ergodox-ez/layouts/Jwj5m/latest/1) 78 | 79 | - Re-enable modifier keys in other levels so that the order in which modifier keys and layer shifting keys are hit doesn't matter. 80 | - Set up a layer change button on both sides of the keyboard so that using the mouse movement keys becomes one-handed if necessary. 81 | - Set up a Windows gaming layer. 82 | 83 | ## [Version 10](https://configure.ergodox-ez.com/ergodox-ez/layouts/53oKe/latest/3) 84 | 85 | - Re-enable modifier keys in other levels so that the order in which modifier keys and layer shifting keys are hit doesn't matter. 86 | - Set up a layer change button on both sides of the keyboard so that using the mouse movement keys becomes one-handed if necessary. 87 | - Make the mouse more usable by tweaking the advanced mouse config settings. Ideally, consistent movement without inertia, but perhaps a bit faster. 88 | - Replace the windows layer with an excalidraw layer instead. 89 | 90 | ## [Version 11](https://configure.zsa.io/ergodox-ez/layouts/ZDnb5/latest/0) 91 | 92 | - Make mouse movements more precise, remove unused layer and some keys. 93 | 94 | ## [Version 12](https://configure.zsa.io/ergodox-ez/layouts/A0r90/latest/0) 95 | 96 | - [x] Scroll speed is way too fast, after some initial very slowness. 97 | - [x] Can't hit any of the Anki answer keys (`1234`) with my left hand, which makes it awkward when I'm using a pen in my right hand. I should probably solve this with an Anki plugin though. 98 | - [x] Make layer 1 (symbols)'s "caps lock" be `ctrl+alt`, so I can use this for yabai window management. 99 | - [x] `[]{}()` could be `[{(]})` instead? (`close - open = 3` always for easy muscle memory) 100 | 101 | ## [Version 13](https://configure.zsa.io/ergodox-ez/layouts/oyvow/latest/1) 102 | 103 | - [x] Make max mouse scroll speed faster. 104 | 105 | ## [Version 14]() 106 | 107 | - [x] Fix broken ctrl key 108 | 109 | ## [Version 15](https://configure.zsa.io/ergodox-ez/layouts/M4BLo/latest/0) 110 | 111 | - Consider moving some of the "related" symbol keys further apart, so I experience fewer off-by-1 errors in my left hand. E.g. 112 | - [ ] `&` and `*` 113 | - [ ] `\` and `|` 114 | - [ ] `$` and `%` -- They're not really related, but I always hit the wrong one 115 | -------------------------------------------------------------------------------- /espanso/config/default.yml: -------------------------------------------------------------------------------- 1 | # espanso configuration file 2 | 3 | # For a complete introduction, visit the official docs at: https://espanso.org/docs/ 4 | 5 | # You can use this file to define the global configuration options for espanso. 6 | # These are the parameters that will be used by default on every application, 7 | # but you can also override them on a per-application basis. 8 | 9 | # To make customization easier, this file contains some of the commonly used 10 | # parameters. Feel free to uncomment and tune them to fit your needs! 11 | 12 | # --- Toggle key 13 | 14 | # Customize the key used to disable and enable espanso (when double tapped) 15 | # Available options: CTRL, SHIFT, ALT, CMD, OFF 16 | # You can also specify the key variant, such as LEFT_CTRL, RIGHT_SHIFT, etc... 17 | # toggle_key: ALT 18 | # You can also disable the toggle key completely with 19 | # toggle_key: OFF 20 | 21 | # --- Injection Backend 22 | 23 | # Espanso supports multiple ways of injecting text into applications. Each of 24 | # them has its quirks, therefore you may want to change it if you are having problems. 25 | # By default, espanso uses the "Auto" backend which should work well in most cases, 26 | # but you may want to try the "Clipboard" or "Inject" backend in case of issues. 27 | # backend: Clipboard 28 | 29 | # --- Auto-restart 30 | 31 | # Enable/disable the config auto-reload after a file change is detected. 32 | # auto_restart: false 33 | 34 | # --- Clipboard threshold 35 | 36 | # Because injecting long texts char-by-char is a slow operation, espanso automatically 37 | # uses the clipboard if the text is longer than 'clipboard_threshold' characters. 38 | # clipboard_threshold: 100 39 | 40 | # For a list of all the available options, visit the official docs at: https://espanso.org/docs/ 41 | 42 | # By default this is alt+space, which collides with my keyboard input toggle 43 | search_shortcut: off 44 | 45 | # ensure espanso is seen but not heard 46 | search_trigger: off 47 | show_icon: false 48 | show_notifications: false 49 | -------------------------------------------------------------------------------- /espanso/match/base.yml: -------------------------------------------------------------------------------- 1 | # For a complete introduction, visit the official docs at: https://espanso.org/docs/ 2 | matches: 3 | - trigger: "a\\\\" 4 | label: "Markdown Link" 5 | replace: "[$|$]({{clipboard}})" 6 | vars: 7 | - name: "clipboard" 8 | type: "clipboard" 9 | 10 | # Furigana (for GitHub / Obsidian) 11 | - trigger: "fg\\\\" 12 | replace: "$|$" 13 | 14 | # Other symbols 15 | - trigger: "<--" 16 | replace: "⇽" 17 | word: true 18 | - trigger: "-->" 19 | replace: "⇾" 20 | word: true 21 | - trigger: "green\\\\" 22 | replace: "🟢" 23 | - trigger: "yellow\\\\" 24 | replace: "🟡" 25 | - trigger: "red\\\\" 26 | replace: "🔴" 27 | 28 | # Typos 29 | - trigger: "saerch" 30 | replace: "search" 31 | propagate_case: true 32 | - trigger: "pythong" 33 | replace: "python" 34 | propagate_case: true 35 | - trigger: "assocaited" 36 | replace: "associated" 37 | propagate_case: true 38 | word: true 39 | - trigger: "shiping" 40 | replace: "shipping" 41 | propagate_case: true 42 | word: true 43 | - trigger: "langauge" 44 | replace: "language" 45 | propagate_case: true 46 | word: true 47 | 48 | # Better communication 49 | - trigger: "inflammable" 50 | replace: "flammable" 51 | word: true 52 | 53 | # Capitalisation of brands (that aren't also parts of a URL) 54 | - trigger: "latex" 55 | replace: "LaTeX" 56 | word: true 57 | 58 | # Dates 59 | - trigger: "today\\\\" 60 | replace: "{{current_date}}" 61 | vars: 62 | - name: current_date 63 | type: date 64 | params: 65 | format: "%Y-%m-%d" 66 | - trigger: "tomorrow\\\\" 67 | replace: "{{tomorrow}}" 68 | vars: 69 | - name: tomorrow 70 | type: date 71 | params: 72 | format: "%Y-%m-%d" 73 | offset: 86400 74 | 75 | # These are just better words 76 | - trigger: "dentures" 77 | replace: "substiteeth" 78 | word: true 79 | - trigger: "forecast" 80 | replace: "prophecy" 81 | word: true 82 | - trigger: "jetski" 83 | replace: "boatercycle" 84 | word: true 85 | - trigger: "hemorrhoids" 86 | replace: "assteroids" 87 | word: true 88 | - trigger: "astronomer" 89 | replace: "skyintist" 90 | word: true 91 | - trigger: "step-dad" 92 | replace: "faux pa" 93 | word: true 94 | - trigger: "toothbrush" 95 | replace: "teethbrush" 96 | word: true 97 | - trigger: "butt dial" 98 | replace: "booty call" 99 | word: true 100 | - trigger: "dad bod" 101 | replace: "father figure" 102 | word: true 103 | - trigger: "narwhal" 104 | replace: "tunacorn" 105 | word: true 106 | - trigger: "mailman" 107 | replace: "mailmale" 108 | word: true 109 | - trigger: "american football" 110 | replace: "hand egg" 111 | word: true 112 | - trigger: "veterinarian" 113 | replace: "dogtor" 114 | word: true 115 | - trigger: "murder of crows" 116 | replace: "cawcawphony" 117 | word: true 118 | - trigger: "fire truck" 119 | replace: "water truck" 120 | word: true 121 | - trigger: "machine gun" 122 | replace: "rooty tooty fast 'n shooty" 123 | word: true 124 | - trigger: "airport" 125 | replace: "plane station" 126 | word: true 127 | 128 | # Memes 129 | - trigger: "cowsay\\\\" 130 | replace: "{{cowsay}}" 131 | vars: 132 | - name: cowsay 133 | type: shell 134 | params: 135 | cmd: "cowsay 'Moo!'" 136 | 137 | - trigger: "middle\\\\" 138 | image_path: "$CONFIG/media/middle.gif" 139 | - trigger: "hfy\\\\" 140 | image_path: "$CONFIG/media/hfy.jpeg" 141 | - trigger: "tlm\\\\" 142 | image_path: "$CONFIG/media/tlm.jpg" 143 | -------------------------------------------------------------------------------- /espanso/media/hfy.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinbiko/dotfiles/bde6b8eee78f7c93721ffce573386c68c8f46114/espanso/media/hfy.jpeg -------------------------------------------------------------------------------- /espanso/media/middle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinbiko/dotfiles/bde6b8eee78f7c93721ffce573386c68c8f46114/espanso/media/middle.gif -------------------------------------------------------------------------------- /espanso/media/tlm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinbiko/dotfiles/bde6b8eee78f7c93721ffce573386c68c8f46114/espanso/media/tlm.jpg -------------------------------------------------------------------------------- /gh/config.yml: -------------------------------------------------------------------------------- 1 | version: "1" 2 | # What protocol to use when performing git operations. Supported values: ssh, https 3 | git_protocol: https 4 | # What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment. 5 | editor: 6 | # When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled 7 | prompt: enabled 8 | # A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager. 9 | pager: bat 10 | # Aliases allow you to create nicknames for gh commands 11 | aliases: 12 | # The path to a unix socket through which send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport. 13 | http_unix_socket: 14 | # What web browser gh should use when opening URLs. If blank, will refer to environment. 15 | browser: 16 | version: "1" 17 | -------------------------------------------------------------------------------- /ghostty/config: -------------------------------------------------------------------------------- 1 | # This is the configuration file for Ghostty. 2 | # 3 | # This template file has been automatically created at the following 4 | # path since Ghostty couldn't find any existing config files on your system: 5 | # 6 | # /Users/kinbiko/Library/Application Support/com.mitchellh.ghostty/config 7 | # 8 | # The template does not set any default options, since Ghostty ships 9 | # with sensible defaults for all options. Users should only need to set 10 | # options that they want to change from the default. 11 | # 12 | # Run `ghostty +show-config --default --docs` to view a list of 13 | # all available config options and their default values. 14 | # 15 | # Additionally, each config option is also explained in detail 16 | # on Ghostty's website, at https://ghostty.org/docs/config. 17 | 18 | # Config syntax crash course 19 | # ========================== 20 | # # The config file consists of simple key-value pairs, 21 | # # separated by equals signs. 22 | # font-family = Iosevka 23 | # window-padding-x = 2 24 | # 25 | # # Spacing around the equals sign does not matter. 26 | # # All of these are identical: 27 | # key=value 28 | # key= value 29 | # key =value 30 | # key = value 31 | # 32 | # # Any line beginning with a # is a comment. It's not possible to put 33 | # # a comment after a config option, since it would be interpreted as a 34 | # # part of the value. For example, this will have a value of "#123abc": 35 | # background = #123abc 36 | # 37 | # # Empty values are used to reset config keys to default. 38 | # key = 39 | # 40 | # # Some config options have unique syntaxes for their value, 41 | # # which is explained in the docs for that config option. 42 | # # Just for example: 43 | # resize-overlay-duration = 4s 200ms 44 | 45 | theme = dark:catppuccin-frappe,light:catppuccin-latte 46 | -------------------------------------------------------------------------------- /git/config: -------------------------------------------------------------------------------- 1 | # vim: set syntax=toml: 2 | [delta "villsau"] 3 | # original author: https://github.com/torarnv 4 | # Edited. 5 | # Theme for delta when doing diffs 6 | dark = true 7 | file-style = omit 8 | hunk-header-decoration-style = omit 9 | hunk-header-file-style = magenta 10 | hunk-header-line-number-style = magenta 11 | hunk-header-style = file line-number syntax 12 | line-numbers = true 13 | minus-emph-style = bold red 52 14 | minus-empty-line-marker-style = normal "#9f0001" 15 | minus-non-emph-style = dim red 16 | minus-style = bold red 17 | plus-emph-style = bold green 22 18 | plus-empty-line-marker-style = normal "#002800" 19 | plus-non-emph-style = dim green 20 | plus-style = bold green 21 | whitespace-error-style = reverse red 22 | zero-style = dim syntax 23 | 24 | [include] 25 | # Let a local gitconfig override with machine specific config 26 | path = ~/.local.gitconfig 27 | 28 | [core] 29 | pager = delta 30 | quotepath = off # Show filenames in UTF-8 31 | 32 | [user] 33 | name = kinbiko 34 | 35 | [pull] 36 | rebase = true 37 | 38 | [init] 39 | defaultBranch = main 40 | 41 | [interactive] 42 | diffFilter = delta --color-only 43 | 44 | [delta] 45 | features = villsau 46 | navigate = true # use n and N to move between diff sections 47 | light = false # set to true if you're in a terminal w/ a light background color (e.g. the default macOS terminal) 48 | line-numbers = true 49 | 50 | [merge] 51 | conflictstyle = merge 52 | 53 | [diff] 54 | colorMoved = default 55 | [rerere] 56 | enabled = true 57 | -------------------------------------------------------------------------------- /git/git-ignore-for-home-dir: -------------------------------------------------------------------------------- 1 | .Trash/ 2 | .cache/ 3 | .local/ 4 | .local/share/nvim/shada/main.shada 5 | .npm/ 6 | .zsh_history 7 | .zsh_sessions/ 8 | .zcompdump* 9 | 10 | Applications/ 11 | Desktop/ 12 | Documents/ 13 | Downloads/ 14 | Library/ 15 | Movies/ 16 | Music/ 17 | Pictures/ 18 | Public/ 19 | go/ 20 | repos/ 21 | .viminfo 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /git/ignore: -------------------------------------------------------------------------------- 1 | # Ctags generated 2 | tags 3 | 4 | # Don't commit secrets 5 | .env.* 6 | .envrc.* 7 | !.env.sample 8 | !.envrc.sample 9 | 10 | # Work around OSX' bad design decision. 11 | .DS_Store 12 | 13 | # Don't ever want to commit editor config 14 | .idea/ 15 | 16 | # I sometimes take notes in files like these 17 | memo.md 18 | notes.md 19 | TODO.md 20 | out.txt 21 | out.json 22 | a.json 23 | out.jsonl 24 | a.jsonl 25 | 26 | # If I choose to save a session with :mksession 27 | Session.vim 28 | 29 | # This is obviously not necessary for normal git use, 30 | # but adding it here to ignore files under .git/ when 31 | # using ripgrep which respects git ignored files. 32 | .git/ 33 | 34 | # Go coverage reports 35 | cover.cov 36 | -------------------------------------------------------------------------------- /jetbrains/ideavimrc: -------------------------------------------------------------------------------- 1 | " Enable tpope surround syntax 2 | set surround 3 | 4 | "{{{ Searching 5 | set incsearch "search as chars are entered 6 | set hlsearch "highlight matches 7 | set ignorecase "Case insensitive search 8 | set smartcase "except when explicitly using capital letters 9 | "}}} 10 | 11 | set number "Display line numbers 12 | set relativenumber "Linenumbers are relative to current line 13 | 14 | set timeoutlen=300 ttimeoutlen=0 15 | 16 | "{{{ Mappings 17 | let mapleader = ' ' 18 | " does not work, local leader is hardcoded below, but leaving here for intent 19 | let maplocalleader = ',' 20 | 21 | " | Normal | Clear current search-highlight 22 | nnoremap , :nohlsearch 23 | 24 | " v | Normal | Open .ideavimrc 25 | nnoremap ,v :e ~/repos/dotfiles/ideavimrc 26 | 27 | " Jump back and forth between tags 28 | nnoremap ] :action GotoDeclaration 29 | nnoremap [ :action Back 30 | 31 | " Copy and paste from within brackets 32 | nnoremap gb yib 33 | nnoremap gp vibpyib 34 | 35 | " Create a blank line above/below current line 36 | nnoremap j ok 37 | nnoremap k Oj 38 | 39 | " Put `final` at the beginning of the current line 40 | nnoremap f Ifinal 41 | 42 | " Increment/Decrement the next number on this line 43 | nnoremap + 44 | nnoremap - 45 | 46 | " Convenience key for getting to command mode 47 | nnoremap ; : 48 | 49 | " Move to the next/previous completely empty line in buffer 50 | nnoremap { 51 | onoremap { 52 | vnoremap { 53 | nnoremap } 54 | onoremap } 55 | vnoremap } 56 | 57 | " Fuzzy find file by filename in the current project 58 | nnoremap ? :action SearchEverywhere 59 | 60 | " Move to the first/last non-blank character on this line 61 | map H ^ 62 | map L $ 63 | 64 | " Execute the last played macro 65 | nmap Q @@ 66 | 67 | " Surround current word with next character 68 | nmap S vawS 69 | 70 | " Move up/down one line, moving to wrapped lines if applicable 71 | nnoremap j gj 72 | nnoremap k gk 73 | 74 | " Enter normal mode 75 | inoremap jk 76 | inoremap ,= := 77 | 78 | " Do nothing. 79 | nnoremap s :w 80 | nnoremap t 81 | nnoremap 82 | 83 | "}}} 84 | 85 | -------------------------------------------------------------------------------- /latexmk/latexmkrc: -------------------------------------------------------------------------------- 1 | $pdflatex = 'pdflatex -synctex=1 -interaction=nonstopmode'; 2 | $pdf_previewer = 'open -a Skim'; 3 | $recorder = 1; 4 | $continuously_watch = 1; 5 | -------------------------------------------------------------------------------- /nvim/.neoconf.json: -------------------------------------------------------------------------------- 1 | { 2 | "neodev": { 3 | "library": { 4 | "enabled": true, 5 | "plugins": true 6 | } 7 | }, 8 | "neoconf": { 9 | "plugins": { 10 | "lua_ls": { 11 | "enabled": true 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /nvim/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /nvim/README.md: -------------------------------------------------------------------------------- 1 | # Neovim config 2 | 3 | This Neovim config is inspired by [LazyVim](https://github.com/LazyVim/LazyVim). 4 | The state before I discovered LazyVim is [this commit](https://github.com/kinbiko/dotfiles/tree/12a0b753d3b05ca3c762a2dd9ece873cdb2b2b8c). 5 | -------------------------------------------------------------------------------- /nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- The order of these files matters 2 | require("options") 3 | require("setup-plugins") 4 | require("autocmds") 5 | require("keyboard-bindings-mappings") -- a longer name makes it easier to find with Telescope 6 | 7 | local function set_colorscheme() 8 | local handle = io.popen("defaults read -g AppleInterfaceStyle 2>/dev/null") 9 | local result = handle:read("*a") -- NOTE: result is empty unless dark. 10 | handle:close() 11 | 12 | local theme = (result:match("Dark") and "tokyonight-night") or "tokyonight-day" 13 | vim.cmd.colorscheme(theme) 14 | end 15 | 16 | set_colorscheme() 17 | vim.api.nvim_create_autocmd("FocusGained", { pattern = "*", callback = set_colorscheme }) 18 | -------------------------------------------------------------------------------- /nvim/lua/autocmds.lua: -------------------------------------------------------------------------------- 1 | local function augroup(name) 2 | return vim.api.nvim_create_augroup("kinbiko_" .. name, { clear = true }) 3 | end 4 | 5 | -- Check if we need to reload the file when it changed 6 | vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave" }, { 7 | group = augroup("checktime"), 8 | command = "checktime", 9 | }) 10 | 11 | -- Highlight on yank 12 | vim.api.nvim_create_autocmd("TextYankPost", { 13 | group = augroup("highlight_yank"), 14 | callback = function() 15 | vim.highlight.on_yank() 16 | end, 17 | }) 18 | 19 | -- go to last loc when opening a buffer 20 | vim.api.nvim_create_autocmd("BufReadPost", { 21 | group = augroup("last_loc"), 22 | callback = function() 23 | local mark = vim.api.nvim_buf_get_mark(0, '"') 24 | local lcount = vim.api.nvim_buf_line_count(0) 25 | if mark[1] > 0 and mark[1] <= lcount then 26 | pcall(vim.api.nvim_win_set_cursor, 0, mark) 27 | end 28 | end, 29 | }) 30 | 31 | -- close some filetypes with 32 | vim.api.nvim_create_autocmd("FileType", { 33 | group = augroup("close_with_q"), 34 | pattern = { 35 | "PlenaryTestPopup", 36 | "help", 37 | "lspinfo", 38 | "man", 39 | "notify", 40 | "qf", 41 | "spectre_panel", 42 | "startuptime", 43 | "tsplayground", 44 | "neotest-output", 45 | "checkhealth", 46 | "neotest-summary", 47 | "neotest-output-panel", 48 | }, 49 | callback = function(event) 50 | vim.bo[event.buf].buflisted = false 51 | vim.keymap.set("n", "q", "close", { buffer = event.buf, silent = true }) 52 | end, 53 | }) 54 | -------------------------------------------------------------------------------- /nvim/lua/icons.lua: -------------------------------------------------------------------------------- 1 | -- icons used by other plugins 2 | return { 3 | diagnostics = { 4 | Error = " ", 5 | Warn = " ", 6 | Hint = " ", 7 | Info = " ", 8 | }, 9 | git = { 10 | added = " ", 11 | modified = " ", 12 | removed = " ", 13 | }, 14 | kinds = { 15 | Array = " ", 16 | Boolean = " ", 17 | Class = " ", 18 | Color = " ", 19 | Constant = " ", 20 | Constructor = " ", 21 | Copilot = " ", 22 | Enum = " ", 23 | EnumMember = " ", 24 | Event = " ", 25 | Field = " ", 26 | File = " ", 27 | Folder = " ", 28 | Function = " ", 29 | Interface = " ", 30 | Key = " ", 31 | Keyword = " ", 32 | Method = " ", 33 | Module = " ", 34 | Namespace = " ", 35 | Null = " ", 36 | Number = " ", 37 | Object = " ", 38 | Operator = " ", 39 | Package = " ", 40 | Property = " ", 41 | Reference = " ", 42 | Snippet = " ", 43 | String = " ", 44 | Struct = " ", 45 | Text = " ", 46 | TypeParameter = " ", 47 | Unit = " ", 48 | Value = " ", 49 | Variable = " ", 50 | }, 51 | } 52 | -------------------------------------------------------------------------------- /nvim/lua/keyboard-bindings-mappings.lua: -------------------------------------------------------------------------------- 1 | local i = "i" 2 | local n = "n" 3 | local o = "o" 4 | local v = "v" 5 | local x = "x" 6 | 7 | local map = function(mode, lhs, rhs, opts) 8 | opts = opts or { silent = true, remap = false } 9 | vim.keymap.set(mode, lhs, rhs, opts) 10 | end 11 | 12 | -- better up/down 13 | map({ n, x }, "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) 14 | map({ n, x }, "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) 15 | 16 | -- Move to window using the hjkl keys 17 | map(n, "", "h", { desc = "Go to left window", remap = true }) 18 | map(n, "", "j", { desc = "Go to lower window", remap = true }) 19 | map(n, "", "k", { desc = "Go to upper window", remap = true }) 20 | map(n, "", "l", { desc = "Go to right window", remap = true }) 21 | 22 | map(n, "bb", "e #", { desc = "Switch to Other Buffer" }) 23 | 24 | -- When writing long things in text, it's nice to be able to undo more partially. 25 | map(i, ",", ",u") 26 | map(i, ".", ".u") 27 | map(i, ";", ";u") 28 | map(i, "?", "?u") 29 | map(i, ":", ":u") 30 | 31 | -- Make arrow key navigation more useful 32 | -- Note to the reader: I've programmed a second layer on my ergodox keyboard to 33 | -- map hjkl to the arrow keys. So even when I do use the arrow keys my fingers 34 | -- don't leave the home row. 35 | map(n, "", ":keepjumps normal {zz") -- Previous paragraph 36 | map(n, "", ":keepjumps normal }zz") -- Next paragraph 37 | map(v, "", "{zz") -- Previous paragraph 38 | map(v, "", "}zz") -- Next paragraph 39 | map(n, "0", "^") -- Make 0 take me to the first non-blank character of the line. 40 | map(n, "'", "`") -- Make jumping to a mark more precise than just the beginning of the line in normal mode 41 | map(o, "'", "`") -- Make jumping to a mark more precise than just the beginning of the line when awaiting an operator 42 | 43 | map(n, "", [[lua require('tmux').move_left()]]) 44 | map(n, "", [[lua require('tmux').move_down()]]) 45 | map(n, "", [[lua require('tmux').move_up()]]) 46 | map(n, "", [[lua require('tmux').move_right()]]) 47 | 48 | map(n, "s", "w") -- Quick-save the current buffer 49 | 50 | map(n, "gd", "Telescope lsp_definitions", { desc = "Go to definition" }) 51 | map(n, "gr", "Telescope lsp_references", { desc = "Find references" }) 52 | map(n, "gI", "Telescope lsp_implementations", { desc = "Find implementations" }) -- Go-to implementation 53 | map(n, "", "gd", { silent = true }) -- Go to definition 54 | map(n, "", "", { silent = true }) -- Pop back up 55 | map(n, "n", "nzz") -- Make forward search results always appear in the middle of the screen 56 | map(n, "N", "Nzz") -- Make backward search results always appear in the middle of the screen 57 | map(n, "", "noh") -- Clear search results 58 | 59 | -- NOTE: Resist the temptation to rewrite ":" to "" as these mappings require a closing . 60 | -- Also trying to silence it prevents the command mode from being visible. 61 | map(n, ";", ":", { remap = true }) -- Conveniently enter command mode 62 | 63 | map(v, "Y", '"*y') -- Copy to the system clipboard 64 | map(v, ">", ">gv") -- indent lines and remember the selection 65 | map(v, "L", ">gv") -- indent lines and remember the selection 66 | map(v, "<", "") -- Easy access to normal mode from insert mode 70 | map(n, "", "cclose") -- Close the quickfix window 71 | map(n, "gk", ':!kokodoko % =line(".")') -- Fetch link to current line in GitHub 72 | map(v, "gk", [[:!kokodoko % =line("'<")-=line("'>")u]]) -- Fetch link to selected lines in GitHub 73 | 74 | map(n, "S", "ysiw", { silent = true, remap = true }) -- Surround the current word with the following character 75 | map("", "*", "(asterisk-z*)zz") -- Make * mark the current word and n will go forward 76 | map("", "#", "(asterisk-z#)zz") -- Make # mark the current work and n will go backward 77 | 78 | map("n", "+", "", { desc = "Increment" }) 79 | map("n", "-", "", { desc = "Decrement" }) 80 | -------------------------------------------------------------------------------- /nvim/lua/options.lua: -------------------------------------------------------------------------------- 1 | vim.cmd.lang("en_US.UTF-8") -- Setting this explicitly means I can copy Japanese to the clipboard without mojibake 2 | 3 | -- Don't put these in keymaps.lua as they get loaded too late for plugins to know what the leaders are. 4 | vim.g.mapleader = " " -- This is already the LazyVim default, but explicitly stating again for clarity. 5 | vim.g.maplocalleader = "," -- This is ' ' by default as LazyVim has it defined. 6 | 7 | vim.g.netrw_dirhistmax = 0 -- Disable the netrw history file which is otherwise added to ~/.vim/.netrwhist 8 | vim.g.markdown_recommended_style = 0 -- Fix markdown indentation settings 9 | 10 | local o = vim.opt 11 | 12 | -- Allow for directives in sourcecode to adjust vim settings, e.g. 13 | -- # vim: syntax=toml: 14 | -- in git config files etc. 15 | o.modeline = true 16 | 17 | o.autowrite = true -- Make No write since last change stfu 18 | o.completeopt = "menu,menuone,noselect" 19 | o.conceallevel = 3 -- Hide * markup for bold and italic 20 | o.confirm = true -- Confirm to save changes before exiting modified buffer 21 | o.cursorline = false -- Disable highlighting of current line 22 | o.expandtab = true -- Use spaces instead of tabs 23 | o.fillchars = { vert = "│", eob = " ", diff = " ", fold = " " } -- Define the window border characters for splits etc. 24 | o.formatoptions = "jcroqlnt" -- tcqj 25 | o.grepformat = "%f:%l:%c:%m" 26 | o.grepprg = "rg --vimgrep" 27 | o.hidden = true -- Allows you to hide a buffer without saving it 28 | o.ignorecase = true -- Ignore case 29 | o.inccommand = "nosplit" -- preview incremental substitute 30 | o.laststatus = 0 31 | o.list = false -- Don't show "shadow" symbols for whitespace since I've got formatters for basically all the files I open. 32 | o.number = true -- Print line number 33 | o.pumblend = 10 -- Popup blend 34 | o.pumheight = 10 -- Maximum number of entries in a popup 35 | o.relativenumber = true -- Relative line numbers 36 | o.scrolloff = 8 -- Number of lines from vertical edge to start scroll 37 | o.sessionoptions = { "buffers", "curdir", "tabpages", "winsize" } 38 | o.shiftround = true -- Round indent 39 | o.shiftwidth = 2 -- Size of an indent 40 | o.shortmess:append({ W = true, I = true, c = true, C = true }) 41 | o.showmode = false -- Dont show mode since we have a statusline 42 | o.sidescroll = 6 -- Number of columns to scroll at a time 43 | o.sidescrolloff = 15 -- Number of lines from horizontal edge to start scroll 44 | o.signcolumn = "yes" -- Always show the signcolumn, otherwise it would shift the text each time 45 | o.smartcase = true -- Don't ignore case with capitals 46 | o.smartindent = true -- Insert indents automatically 47 | o.softtabstop = 2 -- spaces per tab key press in insert mode. Also on backspace 48 | o.spelllang = { "en" } 49 | o.splitbelow = true -- Put new windows below current 50 | o.splitright = true -- Put new windows right of current 51 | o.swapfile = false -- Disable swap files 52 | o.tabstop = 2 -- Number of columns per tab character 53 | o.termguicolors = true -- True color support 54 | o.timeoutlen = 300 55 | o.ttimeoutlen = 0 -- Ensure that there's no delay between esc-ing and the next command executing 56 | o.undolevels = 10000 57 | o.updatetime = 200 -- Save swap file and trigger CursorHold 58 | o.wildmode = "longest:full,full" -- Command-line completion mode 59 | o.winminwidth = 5 -- Minimum window width 60 | o.wrap = false -- Disable line wrap 61 | -------------------------------------------------------------------------------- /nvim/lua/plugins/chatgpt.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "jackMort/ChatGPT.nvim", 4 | cond = os.getenv("OPENAI_API_KEY") ~= nil, 5 | event = "VeryLazy", 6 | config = function() 7 | local chatgpt = require("chatgpt") 8 | chatgpt.setup({ 9 | popup_layout = { 10 | center = { 11 | width = "90%", 12 | height = "80%", 13 | }, 14 | }, 15 | edit_with_instructions = { 16 | diff = true, 17 | }, 18 | openai_params = { 19 | max_tokens = 4096, -- default is 300 20 | }, 21 | }) 22 | 23 | local map = function(lhs, rhs) 24 | vim.keymap.set("n", lhs, rhs, { silent = true, remap = false }) 25 | vim.keymap.set("v", lhs, rhs, { silent = true, remap = false }) 26 | end 27 | 28 | map("ce", chatgpt.edit_with_instructions) 29 | map("co", chatgpt.openChat) 30 | map("cc", chatgpt.complete_code) 31 | map("ct", "ChatGPTRun translate") 32 | map("cj", "ChatGPTRun translate japanese") 33 | vim.keymap.set("i", "", chatgpt.complete_code, { silent = true, remap = false }) 34 | end, 35 | dependencies = { 36 | "MunifTanjim/nui.nvim", 37 | "nvim-lua/plenary.nvim", 38 | "folke/trouble.nvim", 39 | "nvim-telescope/telescope.nvim", 40 | }, 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /nvim/lua/plugins/formatting.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "stevearc/conform.nvim", 4 | opts = {}, 5 | config = function() 6 | require("conform").setup({ 7 | format_on_save = { 8 | -- These options will be passed to conform.format() 9 | timeout_ms = 500, 10 | lsp_fallback = true, 11 | }, 12 | -- Conform will run multiple formatters sequentially 13 | -- Use a sub-list to run only the first available formatter 14 | formatters_by_ft = { 15 | bash = { "shfmt" }, 16 | go = { "goimports", "gci", "gofmt", "gofumpt", stop_after_first = true }, 17 | javascript = { "prettier" }, 18 | json = { "prettier" }, 19 | lua = { "stylua" }, 20 | markdown = { "prettier" }, 21 | proto = { "buf" }, 22 | python = { "black" }, 23 | yaml = { "prettier" }, 24 | }, 25 | }) 26 | end, 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /nvim/lua/plugins/gitsigns.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "lewis6991/gitsigns.nvim", 4 | event = { "BufReadPre", "BufNewFile" }, 5 | opts = { 6 | signs = { 7 | add = { text = "新" }, 8 | change = { text = "∂" }, 9 | delete = { text = "消" }, -- the line below has been deleted 10 | topdelete = { text = "‾" }, -- something has been deleted from the top of the file 11 | changedelete = { text = "▎" }, 12 | untracked = { text = "?" }, 13 | }, 14 | on_attach = function(buffer) 15 | vim.keymap.set("n", "gu", package.loaded.gitsigns.reset_hunk, { buffer = buffer, desc = "Undo hunk" }) 16 | vim.keymap.set("n", "gb", package.loaded.gitsigns.blame_line, { buffer = buffer, desc = "Git Blame" }) 17 | end, 18 | }, 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /nvim/lua/plugins/go.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "fatih/vim-go", 4 | ft = { "go", "gomod" }, 5 | lazy = true, 6 | keys = { 7 | { "gaf", "GoAlt", desc = "Open Alternative File" }, 8 | { "gat", "GoAddTag", desc = "Add Struct Tags" }, 9 | { "gfs", "GoFillStruct", desc = "Fill Struct" }, 10 | { "gr", "GoRename", desc = "Rename identifier under the cursor" }, 11 | 12 | { "gtt", "GoTest", desc = "Run tests in package" }, 13 | { "gtr", "GoTestFunc", desc = "Run closest test function" }, 14 | { "gtf", "GoTestFile", desc = "Run tests in current file" }, 15 | 16 | { "gtcc", "GoCoverageToggle", desc = "Toggle test coverage overlay" }, 17 | { "gtcb", "GoCoverageBrowser", desc = "Show test coverage in a browser" }, 18 | 19 | { "gi", "GoImports", desc = "Format and organize imports" }, 20 | { "gp", "GoPlay", desc = "Share snippet in go.play" }, 21 | { "gw", "GoDefStack", desc = "Where am I in the godef stack?" }, 22 | 23 | { "gbt", "GoBuildTags ", desc = "Add the given build tag(s) to various commands" }, 24 | }, 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /nvim/lua/plugins/lib.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- ui components 3 | { "MunifTanjim/nui.nvim", lazy = true }, 4 | -- library used by other plugins 5 | { "nvim-lua/plenary.nvim", lazy = true }, 6 | -- Make vim-surround things repeatable with . 7 | { "tpope/vim-repeat", event = "VeryLazy" }, 8 | } 9 | -------------------------------------------------------------------------------- /nvim/lua/plugins/lspconfig.lua: -------------------------------------------------------------------------------- 1 | local Util = require("lazy.core.util") 2 | 3 | _opts = nil 4 | 5 | function enabled() 6 | return _opts and _opts.autoformat 7 | end 8 | 9 | local function lsp_get_config(server) 10 | local configs = require("lspconfig.configs") 11 | return rawget(configs, server) 12 | end 13 | 14 | ---@param server string 15 | ---@param cond fun( root_dir, config): boolean 16 | local function lsp_disable(server, cond) 17 | local util = require("lspconfig.util") 18 | local def = lsp_get_config(server) 19 | def.document_config.on_new_config = util.add_hook_before(def.document_config.on_new_config, function(config, root_dir) 20 | if cond(root_dir, config) then 21 | config.enabled = false 22 | end 23 | end) 24 | end 25 | 26 | function toggle() 27 | if vim.b.autoformat == false then 28 | vim.b.autoformat = nil 29 | _opts.autoformat = true 30 | else 31 | _opts.autoformat = not _opts.autoformat 32 | end 33 | if _opts.autoformat then 34 | Util.info("Enabled format on save", { title = "Format" }) 35 | else 36 | Util.warn("Disabled format on save", { title = "Format" }) 37 | end 38 | end 39 | 40 | ---@param opts? {force?:boolean} 41 | function format(opts) 42 | local buf = vim.api.nvim_get_current_buf() 43 | if vim.b.autoformat == false and not (opts and opts.force) then 44 | return 45 | end 46 | 47 | local formatters = get_formatters(buf) 48 | local client_ids = vim.tbl_map(function(client) 49 | return client.id 50 | end, formatters.active) 51 | 52 | if #client_ids == 0 then 53 | return 54 | end 55 | 56 | if _opts.format_notify then 57 | notify(formatters) 58 | end 59 | 60 | vim.lsp.buf.format(vim.tbl_deep_extend("force", { 61 | bufnr = buf, 62 | filter = function(client) 63 | return vim.tbl_contains(client_ids, client.id) 64 | end, 65 | }, require("util").opts("nvim-lspconfig").format or {})) 66 | end 67 | 68 | ---@param formatters LazyVimFormatters 69 | function notify(formatters) 70 | local lines = { "# Active:" } 71 | 72 | for _, client in ipairs(formatters.active) do 73 | local line = "- **" .. client.name .. "**" 74 | table.insert(lines, line) 75 | end 76 | 77 | if #formatters.available > 0 then 78 | table.insert(lines, "") 79 | table.insert(lines, "# Disabled:") 80 | for _, client in ipairs(formatters.available) do 81 | table.insert(lines, "- **" .. client.name .. "**") 82 | end 83 | end 84 | 85 | vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO, { 86 | title = "Formatting", 87 | on_open = function(win) 88 | vim.api.nvim_win_set_option(win, "conceallevel", 3) 89 | vim.api.nvim_win_set_option(win, "spell", false) 90 | local buf = vim.api.nvim_win_get_buf(win) 91 | vim.treesitter.start(buf, "markdown") 92 | end, 93 | }) 94 | end 95 | 96 | -- Gets all lsp clients that support formatting. 97 | function get_formatters(bufnr) 98 | local ft = vim.bo[bufnr].filetype 99 | 100 | ---@class LazyVimFormatters 101 | local ret = { 102 | ---@type lsp.Client[] 103 | active = {}, 104 | ---@type lsp.Client[] 105 | available = {}, 106 | } 107 | 108 | ---@type lsp.Client[] 109 | local clients = vim.lsp.get_active_clients({ bufnr = bufnr }) 110 | for _, client in ipairs(clients) do 111 | if supports_format(client) then 112 | table.insert(ret.available, client) 113 | end 114 | end 115 | 116 | return ret 117 | end 118 | 119 | -- Gets all lsp clients that support formatting 120 | -- and have not disabled it in their client config 121 | ---@param client lsp.Client 122 | function supports_format(client) 123 | if 124 | client.config 125 | and client.config.capabilities 126 | and client.config.capabilities.documentFormattingProvider == false 127 | then 128 | return false 129 | end 130 | return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting") 131 | end 132 | 133 | ---@param opts PluginLspOpts 134 | function setup(opts) 135 | _opts = opts 136 | vim.api.nvim_create_autocmd("BufWritePre", { 137 | group = vim.api.nvim_create_augroup("LazyVimFormat", {}), 138 | callback = function() 139 | if enabled() then 140 | format() 141 | end 142 | end, 143 | }) 144 | end 145 | 146 | ---@return (LazyKeys|{has?:string})[] 147 | local get = function() 148 | return { 149 | { "K", vim.lsp.buf.hover, desc = "Hover" }, 150 | { "gK", vim.lsp.buf.signature_help, desc = "Signature Help", has = "signatureHelp" }, 151 | { "ca", vim.lsp.buf.code_action, desc = "Code Action", mode = { "n", "v" }, has = "codeAction" }, 152 | { "cr", vim.lsp.buf.rename, desc = "Rename", has = "rename" }, 153 | } 154 | end 155 | 156 | local on_attach = function(client, buffer) 157 | local Keys = require("lazy.core.handler.keys") 158 | local keymaps = {} ---@type table 159 | 160 | for _, value in ipairs(get()) do 161 | local keys = Keys.parse(value) 162 | if keys[2] == vim.NIL or keys[2] == false then 163 | keymaps[keys.id] = nil 164 | else 165 | keymaps[keys.id] = keys 166 | end 167 | end 168 | 169 | for _, keys in pairs(keymaps) do 170 | if not keys.has or client.server_capabilities[keys.has .. "Provider"] then 171 | local opts = Keys.opts(keys) 172 | ---@diagnostic disable-next-line: no-unknown 173 | opts.has = nil 174 | opts.silent = opts.silent ~= false 175 | opts.buffer = buffer 176 | if keys[2] then 177 | vim.keymap.set(keys.mode or "n", keys[1], keys[2], opts) 178 | end 179 | end 180 | end 181 | end 182 | 183 | return { 184 | { 185 | "neovim/nvim-lspconfig", 186 | event = { "BufReadPre", "BufNewFile" }, 187 | dependencies = { 188 | { "folke/neoconf.nvim", cmd = "Neoconf", config = true }, 189 | { "folke/neodev.nvim", opts = {} }, 190 | "mason.nvim", 191 | "williamboman/mason-lspconfig.nvim", 192 | "hrsh7th/cmp-nvim-lsp", 193 | "jose-elias-alvarez/typescript.nvim", 194 | "b0o/SchemaStore.nvim", 195 | version = false, -- last release is way too old 196 | }, 197 | ---@class PluginLspOpts 198 | opts = { 199 | -- options for vim.diagnostic.config() 200 | diagnostics = { 201 | underline = true, 202 | update_in_insert = false, 203 | virtual_text = { 204 | spacing = 4, 205 | source = "if_many", 206 | prefix = "●", 207 | -- this will set set the prefix to a function that returns the diagnostics icon based on the severity 208 | -- this only works on a recent 0.10.0 build. Will be set to "●" when not supported 209 | -- prefix = "icons", 210 | }, 211 | severity_sort = true, 212 | }, 213 | -- Enable this to enable the builtin LSP inlay hints on Neovim >= 0.10.0 214 | -- Be aware that you also will need to properly configure your LSP server to 215 | -- provide the inlay hints. 216 | inlay_hints = { 217 | enabled = false, 218 | }, 219 | -- add any global capabilities here 220 | capabilities = {}, 221 | -- Automatically format on save 222 | autoformat = true, 223 | -- Enable this to show formatters used in a notification 224 | -- Useful for debugging formatter issues 225 | format_notify = false, 226 | -- options for vim.lsp.buf.format 227 | -- `bufnr` and `filter` is handled by the LazyVim formatter, 228 | -- but can be also overridden when specified 229 | format = { 230 | formatting_options = nil, 231 | timeout_ms = nil, 232 | }, 233 | -- LSP Server Settings 234 | ---@type lspconfig.options 235 | servers = { 236 | lua_ls = { 237 | -- mason = false, -- set to false if you don't want this server to be installed with mason 238 | settings = { 239 | Lua = { 240 | workspace = { 241 | checkThirdParty = false, 242 | }, 243 | completion = { 244 | callSnippet = "Replace", 245 | }, 246 | }, 247 | }, 248 | }, 249 | ts_ls = { 250 | settings = { 251 | typescript = { 252 | format = { 253 | indentSize = vim.o.shiftwidth, 254 | convertTabsToSpaces = vim.o.expandtab, 255 | tabSize = vim.o.tabstop, 256 | }, 257 | }, 258 | javascript = { 259 | format = { 260 | indentSize = vim.o.shiftwidth, 261 | convertTabsToSpaces = vim.o.expandtab, 262 | tabSize = vim.o.tabstop, 263 | }, 264 | }, 265 | completions = { 266 | completeFunctionCalls = true, 267 | }, 268 | }, 269 | }, 270 | eslint = { 271 | settings = { 272 | -- helps eslint find the eslintrc when it's placed in a subfolder instead of the cwd root 273 | workingDirectory = { mode = "auto" }, 274 | }, 275 | }, 276 | jsonls = { 277 | -- lazy-load schemastore when needed 278 | on_new_config = function(new_config) 279 | new_config.settings.json.schemas = new_config.settings.json.schemas or {} 280 | vim.list_extend(new_config.settings.json.schemas, require("schemastore").json.schemas()) 281 | end, 282 | settings = { 283 | json = { 284 | format = { 285 | enable = true, 286 | }, 287 | validate = { enable = true }, 288 | }, 289 | }, 290 | }, 291 | gopls = { 292 | settings = { 293 | gopls = { 294 | semanticTokens = true, 295 | }, 296 | }, 297 | }, 298 | }, 299 | -- you can do any additional lsp server setup here 300 | -- return true if you don't want this server to be setup with lspconfig 301 | ---@type table 302 | setup = { 303 | ts_ls = function(_, opts) 304 | require("util").on_attach(function(client, buffer) 305 | if client.name == "ts_ls" then 306 | -- stylua: ignore 307 | vim.keymap.set("n", "co", "TypescriptOrganizeImports", 308 | { buffer = buffer, desc = "Organize Imports" }) 309 | -- stylua: ignore 310 | vim.keymap.set("n", "cR", "TypescriptRenameFile", 311 | { desc = "Rename File", buffer = buffer }) 312 | end 313 | end) 314 | require("typescript").setup({ server = opts }) 315 | return true 316 | end, 317 | 318 | eslint = function() 319 | vim.api.nvim_create_autocmd("BufWritePre", { 320 | callback = function(event) 321 | if not enabled() then 322 | -- exit early if autoformat is not enabled 323 | return 324 | end 325 | 326 | local client = vim.lsp.get_active_clients({ bufnr = event.buf, name = "eslint" })[1] 327 | if client then 328 | local diag = vim.diagnostic.get(event.buf, { namespace = vim.lsp.diagnostic.get_namespace(client.id) }) 329 | if #diag > 0 then 330 | vim.cmd("EslintFixAll") 331 | end 332 | end 333 | end, 334 | }) 335 | end, 336 | gopls = function() 337 | -- workaround for gopls not supporting semantictokensprovider 338 | -- https://github.com/golang/go/issues/54531#issuecomment-1464982242 339 | require("util").on_attach(function(client, _) 340 | if client.name == "gopls" then 341 | if not client.server_capabilities.semanticTokensProvider then 342 | local semantic = client.config.capabilities.textDocument.semanticTokens 343 | client.server_capabilities.semanticTokensProvider = { 344 | full = true, 345 | legend = { 346 | tokenTypes = semantic.tokenTypes, 347 | tokenModifiers = semantic.tokenModifiers, 348 | }, 349 | range = true, 350 | } 351 | end 352 | end 353 | end) 354 | -- end workaround 355 | end, 356 | }, 357 | }, 358 | ---@param opts PluginLspOpts 359 | config = function(_, opts) 360 | local utils = require("util") 361 | -- setup autoformat 362 | setup(opts) 363 | -- setup formatting and keymaps 364 | utils.on_attach(function(client, buffer) 365 | on_attach(client, buffer) 366 | end) 367 | 368 | -- diagnostics 369 | for name, icon in pairs(require("icons").diagnostics) do 370 | name = "DiagnosticSign" .. name 371 | vim.fn.sign_define(name, { text = icon, texthl = name, numhl = "" }) 372 | end 373 | 374 | if opts.inlay_hints.enabled and vim.lsp.buf.inlay_hint then 375 | utils.on_attach(function(client, buffer) 376 | if client.server_capabilities.inlayHintProvider then 377 | vim.lsp.buf.inlay_hint(buffer, true) 378 | end 379 | end) 380 | end 381 | 382 | if type(opts.diagnostics.virtual_text) == "table" and opts.diagnostics.virtual_text.prefix == "icons" then 383 | opts.diagnostics.virtual_text.prefix = vim.fn.has("nvim-0.10.0") == 0 and "●" 384 | or function(diagnostic) 385 | local icons = require("icons").diagnostics 386 | for d, icon in pairs(icons) do 387 | if diagnostic.severity == vim.diagnostic.severity[d:upper()] then 388 | return icon 389 | end 390 | end 391 | end 392 | end 393 | 394 | vim.diagnostic.config(vim.deepcopy(opts.diagnostics)) 395 | 396 | local servers = opts.servers 397 | local capabilities = vim.tbl_deep_extend( 398 | "force", 399 | {}, 400 | vim.lsp.protocol.make_client_capabilities(), 401 | require("cmp_nvim_lsp").default_capabilities(), 402 | opts.capabilities or {} 403 | ) 404 | 405 | local function setup(server) 406 | local server_opts = vim.tbl_deep_extend("force", { 407 | capabilities = vim.deepcopy(capabilities), 408 | }, servers[server] or {}) 409 | 410 | if opts.setup[server] then 411 | if opts.setup[server](server, server_opts) then 412 | return 413 | end 414 | elseif opts.setup["*"] then 415 | if opts.setup["*"](server, server_opts) then 416 | return 417 | end 418 | end 419 | require("lspconfig")[server].setup(server_opts) 420 | end 421 | 422 | -- get all the servers that are available thourgh mason-lspconfig 423 | local have_mason, mlsp = pcall(require, "mason-lspconfig") 424 | local all_mslp_servers = {} 425 | if have_mason then 426 | all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package) 427 | end 428 | 429 | local ensure_installed = {} ---@type string[] 430 | for server, server_opts in pairs(servers) do 431 | if server_opts then 432 | server_opts = server_opts == true and {} or server_opts 433 | -- run manual setup if mason=false or if this is a server that cannot be installed with mason-lspconfig 434 | if server_opts.mason == false or not vim.tbl_contains(all_mslp_servers, server) then 435 | setup(server) 436 | else 437 | ensure_installed[#ensure_installed + 1] = server 438 | end 439 | end 440 | end 441 | 442 | if have_mason then 443 | mlsp.setup({ ensure_installed = ensure_installed, handlers = { setup } }) 444 | end 445 | 446 | if lsp_get_config("denols") and lsp_get_config("ts_ls") then 447 | local is_deno = require("lspconfig.util").root_pattern("deno.json", "deno.jsonc") 448 | lsp_disable("ts_ls", is_deno) 449 | lsp_disable("denols", function(root_dir) 450 | return not is_deno(root_dir) 451 | end) 452 | end 453 | end, 454 | }, 455 | } 456 | -------------------------------------------------------------------------------- /nvim/lua/plugins/lualine.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "nvim-lualine/lualine.nvim", 4 | event = "VeryLazy", 5 | opts = function() 6 | local icons = require("icons") 7 | 8 | return { 9 | options = { 10 | globalstatus = true, 11 | disabled_filetypes = { statusline = { "dashboard" } }, 12 | }, 13 | sections = { 14 | lualine_a = { "mode" }, 15 | lualine_b = { "branch" }, 16 | lualine_c = { 17 | { "filetype", icon_only = true, separator = "", padding = { left = 1, right = 0 } }, 18 | { "filename", path = 1, symbols = { modified = "", readonly = "", unnamed = "" } }, 19 | }, 20 | lualine_x = { 21 | { 22 | "diagnostics", 23 | symbols = { 24 | error = icons.diagnostics.Error, 25 | warn = icons.diagnostics.Warn, 26 | info = icons.diagnostics.Info, 27 | hint = icons.diagnostics.Hint, 28 | }, 29 | }, 30 | { 31 | "diff", 32 | symbols = { 33 | added = icons.git.added, 34 | modified = icons.git.modified, 35 | removed = icons.git.removed, 36 | }, 37 | }, 38 | }, 39 | lualine_y = {}, 40 | lualine_z = { 41 | function() 42 | return " " .. os.date("%R") 43 | end, 44 | }, 45 | }, 46 | } 47 | end, 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /nvim/lua/plugins/mason.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "williamboman/mason.nvim", 4 | cmd = "Mason", 5 | keys = { { "cm", "Mason", desc = "Mason" } }, 6 | opts = { 7 | ensure_installed = { 8 | "black", 9 | "buf", 10 | "delve", 11 | "gci", 12 | "gofumpt", 13 | "js-debug-adapter", 14 | "prettier", 15 | "prettierd", 16 | "shfmt", 17 | "stylua", 18 | }, 19 | }, 20 | ---@param opts MasonSettings | {ensure_installed: string[]} 21 | config = function(_, opts) 22 | require("mason").setup(opts) 23 | local mr = require("mason-registry") 24 | local function ensure_installed() 25 | for _, tool in ipairs(opts.ensure_installed) do 26 | local p = mr.get_package(tool) 27 | if not p:is_installed() then 28 | p:install() 29 | end 30 | end 31 | end 32 | if mr.refresh then 33 | mr.refresh(ensure_installed) 34 | else 35 | ensure_installed() 36 | end 37 | end, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /nvim/lua/plugins/mini.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- auto pairs 3 | { 4 | "echasnovski/mini.pairs", 5 | event = "VeryLazy", 6 | opts = {}, 7 | }, 8 | 9 | { 10 | "echasnovski/mini.comment", 11 | event = "VeryLazy", 12 | dependencies = { 13 | "nvim-treesitter", 14 | "JoosepAlviste/nvim-ts-context-commentstring", -- comments using the correct syntax in files with multiple languages like svelte or vue 15 | }, 16 | 17 | opts = { 18 | options = { 19 | custom_commentstring = function() 20 | return require("ts_context_commentstring.internal").calculate_commentstring() or vim.bo.commentstring 21 | end, 22 | }, 23 | }, 24 | }, 25 | 26 | -- active indent guide and indent text objects 27 | { 28 | "echasnovski/mini.indentscope", 29 | version = false, -- wait till new 0.7.0 release to put it back on semver 30 | event = { "BufReadPre", "BufNewFile" }, 31 | opts = { 32 | -- symbol = "▏", 33 | symbol = "│", 34 | options = { try_as_border = true }, 35 | }, 36 | init = function() 37 | vim.api.nvim_create_autocmd("FileType", { 38 | pattern = { 39 | "help", 40 | "dashboard", 41 | "Trouble", 42 | "lazy", 43 | "mason", 44 | "notify", 45 | "toggleterm", 46 | "lazyterm", 47 | }, 48 | callback = function() 49 | vim.b.miniindentscope_disable = true 50 | end, 51 | }) 52 | end, 53 | }, 54 | 55 | { 56 | -- better text-objects 57 | "echasnovski/mini.ai", 58 | -- keys = { 59 | -- { "a", mode = { "x", "o" } }, 60 | -- { "i", mode = { "x", "o" } }, 61 | -- }, 62 | event = "VeryLazy", 63 | dependencies = { "nvim-treesitter-textobjects" }, 64 | opts = function() 65 | local ai = require("mini.ai") 66 | return { 67 | n_lines = 500, 68 | custom_textobjects = { 69 | o = ai.gen_spec.treesitter({ 70 | a = { "@block.outer", "@conditional.outer", "@loop.outer" }, 71 | i = { "@block.inner", "@conditional.inner", "@loop.inner" }, 72 | }, {}), 73 | f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}), 74 | c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}), 75 | }, 76 | } 77 | end, 78 | config = function(_, opts) 79 | require("mini.ai").setup(opts) 80 | -- register all text objects with which-key 81 | ---@type table 82 | local i = { 83 | [" "] = "Whitespace", 84 | ['"'] = 'Balanced "', 85 | ["'"] = "Balanced '", 86 | ["`"] = "Balanced `", 87 | ["("] = "Balanced (", 88 | [")"] = "Balanced ) including white-space", 89 | [">"] = "Balanced > including white-space", 90 | [""] = "Balanced <", 91 | ["]"] = "Balanced ] including white-space", 92 | ["["] = "Balanced [", 93 | ["}"] = "Balanced } including white-space", 94 | ["{"] = "Balanced {", 95 | ["?"] = "User Prompt", 96 | _ = "Underscore", 97 | a = "Argument", 98 | b = "Balanced ), ], }", 99 | c = "Class", 100 | f = "Function", 101 | o = "Block, conditional, loop", 102 | q = "Quote `, \", '", 103 | t = "Tag", 104 | } 105 | local a = vim.deepcopy(i) 106 | for k, v in pairs(a) do 107 | a[k] = v:gsub(" including.*", "") 108 | end 109 | 110 | local ic = vim.deepcopy(i) 111 | local ac = vim.deepcopy(a) 112 | for key, name in pairs({ n = "Next", l = "Last" }) do 113 | i[key] = vim.tbl_extend("force", { name = "Inside " .. name .. " textobject" }, ic) 114 | a[key] = vim.tbl_extend("force", { name = "Around " .. name .. " textobject" }, ac) 115 | end 116 | end, 117 | }, 118 | { "echasnovski/mini.icons", version = false }, 119 | } 120 | -------------------------------------------------------------------------------- /nvim/lua/plugins/neotest.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "nvim-neotest/neotest", 4 | dependencies = { 5 | "antoinemadec/FixCursorHold.nvim", 6 | "marilari88/neotest-vitest", 7 | "nvim-lua/plenary.nvim", 8 | "nvim-neotest/neotest-go", 9 | "nvim-neotest/neotest-jest", 10 | "nvim-neotest/nvim-nio", 11 | "nvim-treesitter/nvim-treesitter", 12 | }, 13 | opts = { 14 | -- Can be a list of adapters like what neotest expects, 15 | -- or a list of adapter names, 16 | -- or a table of adapter names, mapped to adapter configs. 17 | -- The adapter will then be automatically loaded with the config. 18 | adapters = { 19 | "neotest-jest", 20 | "neotest-vitest", 21 | ["neotest-go"] = { 22 | args = { "-v", "-count=1", "-timeout=30s" }, 23 | }, 24 | }, 25 | -- Example for loading neotest-go with a custom config 26 | -- adapters = { 27 | -- ["neotest-go"] = { 28 | -- args = { "-tags=integration" }, 29 | -- }, 30 | -- }, 31 | status = { virtual_text = true }, 32 | output = { open_on_run = true }, 33 | quickfix = { 34 | open = function() 35 | vim.cmd("Trouble quickfix") 36 | end, 37 | }, 38 | }, 39 | config = function(_, opts) 40 | local neotest_ns = vim.api.nvim_create_namespace("neotest") 41 | vim.diagnostic.config({ 42 | virtual_text = { 43 | format = function(diagnostic) 44 | -- Replace newline and tab characters with space for more compact diagnostics 45 | local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "") 46 | return message 47 | end, 48 | }, 49 | }, neotest_ns) 50 | 51 | if opts.adapters then 52 | local adapters = {} 53 | for name, config in pairs(opts.adapters or {}) do 54 | if type(name) == "number" then 55 | if type(config) == "string" then 56 | config = require(config) 57 | end 58 | adapters[#adapters + 1] = config 59 | elseif config ~= false then 60 | local adapter = require(name) 61 | if type(config) == "table" and not vim.tbl_isempty(config) then 62 | local meta = getmetatable(adapter) 63 | if adapter.setup then 64 | adapter.setup(config) 65 | elseif meta and meta.__call then 66 | adapter(config) 67 | else 68 | error("Adapter " .. name .. " does not support setup") 69 | end 70 | end 71 | adapters[#adapters + 1] = adapter 72 | end 73 | end 74 | opts.adapters = adapters 75 | end 76 | 77 | require("neotest").setup(opts) 78 | end, 79 | -- stylua: ignore 80 | keys = { 81 | { "tt", function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "Run File" }, 82 | { "tT", function() require("neotest").run.run(vim.loop.cwd()) end, desc = "Run All Test Files" }, 83 | { "tr", function() require("neotest").run.run() end, desc = "Run Nearest" }, 84 | { "ts", function() require("neotest").summary.toggle() end, desc = "Toggle Summary" }, 85 | { "to", function() require("neotest").output.open({ enter = true, auto_close = true }) end, desc = "Show Output" }, 86 | { "tO", function() require("neotest").output_panel.toggle() end, desc = "Toggle Output Panel" }, 87 | { "tS", function() require("neotest").run.stop() end, desc = "Stop" }, 88 | }, 89 | }, 90 | } 91 | -------------------------------------------------------------------------------- /nvim/lua/plugins/nvim-cmp.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- auto completion 3 | { 4 | "hrsh7th/nvim-cmp", 5 | version = false, -- last release is way too old 6 | event = "InsertEnter", 7 | dependencies = { 8 | "L3MON4D3/LuaSnip", 9 | "hrsh7th/cmp-nvim-lsp", 10 | "saadparwaiz1/cmp_luasnip", 11 | }, 12 | opts = function() 13 | vim.api.nvim_set_hl(0, "CmpGhostText", { link = "Comment", default = true }) 14 | local cmp = require("cmp") 15 | return { 16 | completion = { 17 | completeopt = "menu,menuone,noinsert", 18 | }, 19 | snippet = { 20 | expand = function(args) 21 | require("luasnip").lsp_expand(args.body) 22 | end, 23 | }, 24 | mapping = cmp.mapping.preset.insert({ 25 | [""] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), 26 | [""] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), 27 | [""] = cmp.mapping.scroll_docs(-4), 28 | [""] = cmp.mapping.scroll_docs(4), 29 | [""] = cmp.mapping.complete(), 30 | [""] = cmp.mapping.abort(), 31 | [""] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. 32 | [""] = cmp.mapping.confirm({ 33 | behavior = cmp.ConfirmBehavior.Replace, 34 | select = true, 35 | }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. 36 | }), 37 | sources = cmp.config.sources({ 38 | { name = "nvim_lsp" }, 39 | { name = "luasnip" }, 40 | }), 41 | experimental = { 42 | ghost_text = { 43 | hl_group = "CmpGhostText", 44 | }, 45 | }, 46 | sorting = { 47 | priority_weight = 2, 48 | comparators = { 49 | -- Below is the default comparitor list and order for nvim-cmp 50 | cmp.config.compare.offset, 51 | -- cmp.config.compare.scopes, --this is commented in nvim-cmp too 52 | cmp.config.compare.exact, 53 | cmp.config.compare.score, 54 | cmp.config.compare.recently_used, 55 | cmp.config.compare.locality, 56 | cmp.config.compare.kind, 57 | cmp.config.compare.sort_text, 58 | cmp.config.compare.length, 59 | cmp.config.compare.order, 60 | }, 61 | }, 62 | } 63 | end, 64 | }, 65 | } 66 | -------------------------------------------------------------------------------- /nvim/lua/plugins/nvim-tree.lua: -------------------------------------------------------------------------------- 1 | local function on_attach_nvim_tree(bufnr) 2 | local api = require("nvim-tree.api") 3 | 4 | local map = function(lhs, rhs, description) 5 | vim.keymap.set("n", lhs, rhs, { silent = true, buffer = bufnr, desc = description }) 6 | end 7 | 8 | map("", api.node.open.edit, "Open") 9 | map("", api.node.open.no_window_picker, "Open: No Window Picker") 10 | map("C", api.tree.change_root_to_node, "CD") 11 | map("|", api.node.open.vertical, "Open: Vertical Split") 12 | map("-", api.node.open.horizontal, "Open: Horizontal Split") 13 | map("u", api.node.navigate.parent, "Parent Directory") 14 | map("x", api.node.navigate.parent_close, "Close Directory") 15 | map("", api.node.open.preview, "Open Preview") 16 | map("hg", api.tree.toggle_gitignore_filter, "Toggle Git Ignore") 17 | map("hd", api.tree.toggle_hidden_filter, "Toggle Dotfiles") 18 | map("hh", api.tree.toggle_custom_filter, "Toggle Hidden") 19 | map("R", api.tree.reload, "Refresh") 20 | map("n", api.fs.create, "Create") 21 | map("d", api.fs.remove, "Delete") 22 | map("r", api.fs.rename, "Rename") 23 | map("x", api.fs.cut, "Cut") 24 | map("yy", api.fs.copy.node, "Copy") 25 | map("p", api.fs.paste, "Paste") 26 | map("yn", api.fs.copy.filename, "Copy Name") 27 | map("yr", api.fs.copy.relative_path, "Copy Relative Path") 28 | map("ya", api.fs.copy.absolute_path, "Copy Absolute Path") 29 | map("[", api.node.navigate.diagnostics.prev, "Prev Diagnostic") 30 | map("]", api.node.navigate.diagnostics.next, "Next Diagnostic") 31 | map("(", api.node.navigate.git.prev, "Prev Git") 32 | map(")", api.node.navigate.git.next, "Next Git") 33 | map("q", api.tree.close, "Close") 34 | map("X", api.tree.collapse_all, "Collapse") 35 | map("E", api.tree.expand_all, "Expand All") 36 | map("s", api.tree.search_node, "Search") 37 | map("", api.node.show_info_popup, "Info") 38 | map("?", api.tree.toggle_help, "Help") 39 | -- Unmapped bindings, and their default value: 40 | -- map('-', api.tree.change_root_to_parent, 'Up') 41 | -- map('D', api.fs.trash, 'Trash') 42 | -- map('o', api.node.open.edit, 'Open') 43 | -- map('<2-LeftMouse>', api.node.open.edit, 'Open') 44 | -- map('', api.node.open.replace_tree_buffer, 'Open: In Place') 45 | -- map('', api.node.open.tab, 'Open: New Tab') 46 | -- map('<', api.node.navigate.sibling.prev, 'Previous Sibling') 47 | -- map('>', api.node.navigate.sibling.next, 'Next Sibling') 48 | -- map('K', api.node.navigate.sibling.first, 'First Sibling') 49 | -- map('J', api.node.navigate.sibling.last, 'Last Sibling') 50 | -- map('', api.fs.rename_sub, 'Rename: Omit Filename') 51 | -- map('s', api.node.run.system, 'Run System') 52 | -- map('f', api.live_filter.start, 'Filter') 53 | -- map('F', api.live_filter.clear, 'Clean Filter') 54 | -- map('.', api.node.run.cmd, 'Run Command') 55 | -- map('m', api.marks.toggle, 'Toggle Bookmark') 56 | -- map('bmv', api.marks.bulk.move, 'Move Bookmarked') 57 | end 58 | 59 | return { 60 | { 61 | "kyazdani42/nvim-tree.lua", 62 | dependencies = "nvim-tree/nvim-web-devicons", 63 | keys = { 64 | { "", "NvimTreeToggle" }, 65 | { "f", "NvimTreeFindFileToggle" }, 66 | }, 67 | config = function() 68 | require("nvim-tree").setup({ 69 | auto_reload_on_write = true, 70 | create_in_closed_folder = false, 71 | disable_netrw = true, 72 | hijack_cursor = true, 73 | hijack_netrw = true, 74 | hijack_unnamed_buffer_when_opening = false, 75 | open_on_tab = false, 76 | ignore_buf_on_tab_change = {}, 77 | sort_by = "name", 78 | root_dirs = {}, 79 | prefer_startup_root = false, 80 | sync_root_with_cwd = false, 81 | reload_on_bufenter = false, 82 | respect_buf_cwd = false, 83 | on_attach = on_attach_nvim_tree, 84 | view = { 85 | adaptive_size = false, 86 | centralize_selection = true, 87 | width = 30, 88 | side = "left", 89 | preserve_window_proportions = false, 90 | number = false, 91 | relativenumber = false, 92 | signcolumn = "yes", 93 | float = { 94 | enable = false, -- This feature is actually kind a cool, but gives an error 50% of the time. 95 | open_win_config = { 96 | relative = "editor", 97 | border = "rounded", 98 | width = 30, 99 | height = 10, 100 | row = 10, 101 | col = 40, 102 | }, 103 | }, 104 | }, 105 | renderer = { 106 | add_trailing = false, 107 | group_empty = true, 108 | highlight_git = false, 109 | full_name = true, -- floats the whole name if it doesn't fit in the nvim-tree window. 110 | highlight_opened_files = "all", 111 | root_folder_modifier = ":~", 112 | indent_width = 2, 113 | indent_markers = { 114 | enable = true, 115 | inline_arrows = true, 116 | icons = { 117 | corner = "└", 118 | edge = "│", 119 | item = "│", 120 | bottom = "─", 121 | none = " ", 122 | }, 123 | }, 124 | icons = { 125 | webdev_colors = true, 126 | git_placement = "before", 127 | padding = " ", 128 | symlink_arrow = " ➛ ", 129 | show = { 130 | file = true, 131 | folder = true, 132 | folder_arrow = true, 133 | git = true, 134 | }, 135 | glyphs = { 136 | default = "", 137 | symlink = "", 138 | bookmark = "", 139 | folder = { 140 | arrow_closed = "", 141 | arrow_open = "", 142 | default = "", 143 | open = "", 144 | empty = "", 145 | empty_open = "", 146 | symlink = "", 147 | symlink_open = "", 148 | }, 149 | git = { 150 | unstaged = "✗", 151 | staged = "✓", 152 | unmerged = "", 153 | renamed = "➜", 154 | untracked = "★", 155 | deleted = "", 156 | ignored = "◌", 157 | }, 158 | }, 159 | }, 160 | special_files = { "go.mod", "go.sum" }, 161 | symlink_destination = true, 162 | }, 163 | hijack_directories = { 164 | enable = true, 165 | auto_open = true, 166 | }, 167 | update_focused_file = { 168 | enable = false, 169 | update_root = false, 170 | ignore_list = {}, 171 | }, 172 | system_open = { 173 | cmd = "", 174 | args = {}, 175 | }, 176 | diagnostics = { 177 | enable = true, 178 | show_on_dirs = true, 179 | debounce_delay = 50, 180 | icons = { 181 | hint = "", 182 | info = "", 183 | warning = "", 184 | error = "", 185 | }, 186 | }, 187 | filters = { 188 | dotfiles = false, 189 | custom = {}, 190 | exclude = {}, 191 | }, 192 | filesystem_watchers = { 193 | enable = true, 194 | debounce_delay = 50, 195 | }, 196 | git = { 197 | enable = true, 198 | ignore = true, 199 | show_on_dirs = true, 200 | timeout = 400, 201 | }, 202 | actions = { 203 | use_system_clipboard = true, 204 | change_dir = { 205 | enable = true, 206 | global = false, 207 | restrict_above_cwd = false, 208 | }, 209 | expand_all = { 210 | max_folder_discovery = 300, 211 | exclude = {}, 212 | }, 213 | file_popup = { 214 | open_win_config = { 215 | col = 1, 216 | row = 1, 217 | relative = "cursor", 218 | border = "shadow", 219 | style = "minimal", 220 | }, 221 | }, 222 | open_file = { 223 | quit_on_open = false, 224 | resize_window = true, 225 | window_picker = { 226 | enable = true, 227 | chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 228 | exclude = { 229 | filetype = { "notify", "packer", "qf", "diff", "fugitive", "fugitiveblame" }, 230 | buftype = { "nofile", "terminal", "help" }, 231 | }, 232 | }, 233 | }, 234 | remove_file = { 235 | close_window = true, 236 | }, 237 | }, 238 | trash = { 239 | cmd = "gio trash", 240 | require_confirm = true, 241 | }, 242 | live_filter = { 243 | prefix = "[FILTER]: ", 244 | always_show_folders = false, 245 | }, 246 | log = { 247 | enable = false, 248 | truncate = false, 249 | types = { 250 | all = false, 251 | config = false, 252 | copy_paste = false, 253 | dev = false, 254 | diagnostics = false, 255 | git = false, 256 | profile = false, 257 | watcher = false, 258 | }, 259 | }, 260 | }) 261 | end, 262 | }, 263 | } 264 | -------------------------------------------------------------------------------- /nvim/lua/plugins/tabular.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "godlygeek/tabular" }, -- Easily align text vertically by character 3 | } 4 | -------------------------------------------------------------------------------- /nvim/lua/plugins/telescope.lua: -------------------------------------------------------------------------------- 1 | local Util = require("util") 2 | 3 | return { 4 | { 5 | "nvim-telescope/telescope.nvim", 6 | commit = vim.fn.has("nvim-0.9.0") == 0 and "057ee0f8783" or nil, 7 | cmd = "Telescope", 8 | version = false, -- telescope did only one release, so use HEAD for now 9 | keys = { 10 | { ",", "Telescope buffers show_all_buffers=true", desc = "Switch Buffer" }, 11 | { "/", Util.telescope("live_grep"), desc = "Grep (root dir)" }, 12 | { ":", "Telescope command_history", desc = "Command History" }, 13 | { "", Util.telescope("files"), desc = "Find Files (root dir)" }, 14 | -- find 15 | { "fb", "Telescope buffers", desc = "Buffers" }, 16 | { "ff", Util.telescope("files"), desc = "Find Files (root dir)" }, 17 | { "fF", Util.telescope("files", { cwd = false }), desc = "Find Files (cwd)" }, 18 | { "fr", "Telescope oldfiles", desc = "Recent" }, 19 | { "fR", Util.telescope("oldfiles", { cwd = vim.loop.cwd() }), desc = "Recent (cwd)" }, 20 | -- git 21 | { "gc", "Telescope git_commits", desc = "commits" }, 22 | { "gs", "Telescope git_status", desc = "status" }, 23 | -- search 24 | { "sa", "Telescope autocommands", desc = "Auto Commands" }, 25 | { "sb", "Telescope current_buffer_fuzzy_find", desc = "Buffer" }, 26 | { "sc", "Telescope command_history", desc = "Command History" }, 27 | { "sC", "Telescope commands", desc = "Commands" }, 28 | { "sd", "Telescope diagnostics bufnr=0", desc = "Document diagnostics" }, 29 | { "sD", "Telescope diagnostics", desc = "Workspace diagnostics" }, 30 | { "sg", Util.telescope("live_grep"), desc = "Grep (root dir)" }, 31 | { "sG", Util.telescope("live_grep", { cwd = false }), desc = "Grep (cwd)" }, 32 | { "sh", "Telescope help_tags", desc = "Help Pages" }, 33 | { "sH", "Telescope highlights", desc = "Search Highlight Groups" }, 34 | { "sk", "Telescope keymaps", desc = "Key Maps" }, 35 | { "sM", "Telescope man_pages", desc = "Man Pages" }, 36 | { "sm", "Telescope marks", desc = "Jump to Mark" }, 37 | { "so", "Telescope vim_options", desc = "Options" }, 38 | { "sR", "Telescope resume", desc = "Resume" }, 39 | { "sw", Util.telescope("grep_string"), desc = "Word (root dir)" }, 40 | { "sW", Util.telescope("grep_string", { cwd = false }), desc = "Word (cwd)" }, 41 | { "uC", Util.telescope("colorscheme", { enable_preview = true }), desc = "Colorscheme with preview" }, 42 | { 43 | "ss", 44 | Util.telescope("lsp_document_symbols", { 45 | symbols = { 46 | "Class", 47 | "Function", 48 | "Method", 49 | "Constructor", 50 | "Interface", 51 | "Module", 52 | "Struct", 53 | "Trait", 54 | "Field", 55 | "Property", 56 | }, 57 | }), 58 | desc = "Goto Symbol", 59 | }, 60 | { 61 | "sS", 62 | Util.telescope("lsp_dynamic_workspace_symbols", { 63 | symbols = { 64 | "Class", 65 | "Function", 66 | "Method", 67 | "Constructor", 68 | "Interface", 69 | "Module", 70 | "Struct", 71 | "Trait", 72 | "Field", 73 | "Property", 74 | }, 75 | }), 76 | desc = "Goto Symbol (Workspace)", 77 | }, 78 | }, 79 | opts = { 80 | defaults = { 81 | path_display = { "shorten" }, 82 | prompt_prefix = " ", 83 | selection_caret = " ", 84 | mappings = { 85 | i = { 86 | [""] = function(...) 87 | return require("trouble.providers.telescope").open_with_trouble(...) 88 | end, 89 | [""] = function(...) 90 | return require("trouble.providers.telescope").open_selected_with_trouble(...) 91 | end, 92 | [""] = function() 93 | local action_state = require("telescope.actions.state") 94 | local line = action_state.get_current_line() 95 | Util.telescope("find_files", { no_ignore = true, default_text = line })() 96 | end, 97 | [""] = function() 98 | local action_state = require("telescope.actions.state") 99 | local line = action_state.get_current_line() 100 | Util.telescope("find_files", { hidden = true, default_text = line })() 101 | end, 102 | [""] = function(...) 103 | return require("telescope.actions").cycle_history_next(...) 104 | end, 105 | [""] = function(...) 106 | return require("telescope.actions").cycle_history_prev(...) 107 | end, 108 | [""] = function(...) 109 | return require("telescope.actions").preview_scrolling_down(...) 110 | end, 111 | [""] = function(...) 112 | return require("telescope.actions").preview_scrolling_up(...) 113 | end, 114 | }, 115 | n = { 116 | ["q"] = function(...) 117 | return require("telescope.actions").close(...) 118 | end, 119 | }, 120 | }, 121 | }, 122 | }, 123 | }, 124 | } 125 | -------------------------------------------------------------------------------- /nvim/lua/plugins/tmux.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "nathom/tmux.nvim" }, -- Move smoothly between vim and tmux winows 3 | } 4 | -------------------------------------------------------------------------------- /nvim/lua/plugins/todo-comments.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- highlight and easily find TODO comments 3 | { 4 | "folke/todo-comments.nvim", 5 | cmd = { "TodoTrouble", "TodoTelescope" }, 6 | event = { "BufReadPost", "BufNewFile" }, 7 | config = true, 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /nvim/lua/plugins/tokyonight.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "folke/tokyonight.nvim", 4 | lazy = true, 5 | opts = { style = "night", transparent = true }, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /nvim/lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | local load_textobjects = false 2 | 3 | return { 4 | { 5 | "nvim-treesitter/nvim-treesitter", 6 | version = false, -- last release is way too old and doesn't work on Windows 7 | build = ":TSUpdate", 8 | event = { "BufReadPost", "BufNewFile" }, 9 | dependencies = { 10 | { 11 | "nvim-treesitter/nvim-treesitter-textobjects", 12 | init = function() 13 | -- disable rtp plugin, as we only need its queries for mini.ai 14 | -- In case other textobject modules are enabled, we will load them 15 | -- once nvim-treesitter is loaded 16 | require("lazy.core.loader").disable_rtp_plugin("nvim-treesitter-textobjects") 17 | load_textobjects = true 18 | end, 19 | }, 20 | }, 21 | cmd = { "TSUpdateSync" }, 22 | keys = { 23 | { "", desc = "Increment selection" }, 24 | { "", desc = "Decrement selection", mode = "x" }, 25 | }, 26 | ---@type TSConfig 27 | opts = { 28 | highlight = { enable = true }, 29 | indent = { enable = true }, 30 | ensure_installed = { 31 | "bash", 32 | "c", 33 | "css", 34 | "csv", 35 | "cue", 36 | "diff", 37 | "dockerfile", 38 | "git_config", 39 | "git_rebase", 40 | "gitattributes", 41 | "gitcommit", 42 | "gitignore", 43 | "go", 44 | "gomod", 45 | "gosum", 46 | "gowork", 47 | "html", 48 | "javascript", 49 | "jq", 50 | "json", 51 | "json5", 52 | "jsonc", 53 | "latex", 54 | "lua", 55 | "luadoc", 56 | "luap", 57 | "markdown", 58 | "markdown_inline", 59 | "php", 60 | "proto", 61 | "python", 62 | "query", 63 | "regex", 64 | "ruby", 65 | "rust", 66 | "sql", 67 | "terraform", 68 | "tsx", 69 | "typescript", 70 | "vim", 71 | "vimdoc", 72 | "xml", 73 | "yaml", 74 | }, 75 | incremental_selection = { 76 | enable = true, 77 | keymaps = { 78 | init_selection = "", 79 | node_incremental = "", 80 | scope_incremental = false, 81 | node_decremental = "", 82 | }, 83 | }, 84 | }, 85 | ---@param opts TSConfig 86 | config = function(_, opts) 87 | if type(opts.ensure_installed) == "table" then 88 | ---@type table 89 | local added = {} 90 | opts.ensure_installed = vim.tbl_filter(function(lang) 91 | if added[lang] then 92 | return false 93 | end 94 | added[lang] = true 95 | return true 96 | end, opts.ensure_installed) 97 | end 98 | require("nvim-treesitter.configs").setup(opts) 99 | 100 | if load_textobjects then 101 | -- PERF: no need to load the plugin, if we only need its queries for mini.ai 102 | if opts.textobjects then 103 | for _, mod in ipairs({ "move", "select", "swap", "lsp_interop" }) do 104 | if opts.textobjects[mod] and opts.textobjects[mod].enable then 105 | local Loader = require("lazy.core.loader") 106 | Loader.disabled_rtp_plugins["nvim-treesitter-textobjects"] = nil 107 | local plugin = require("lazy.core.config").plugins["nvim-treesitter-textobjects"] 108 | require("lazy.core.loader").source_runtime(plugin.dir, "plugin") 109 | break 110 | end 111 | end 112 | end 113 | end 114 | end, 115 | }, 116 | } 117 | -------------------------------------------------------------------------------- /nvim/lua/plugins/trouble.lua: -------------------------------------------------------------------------------- 1 | return { 2 | -- better diagnostics list and others 3 | { 4 | "folke/trouble.nvim", 5 | cmd = { "TroubleToggle", "Trouble" }, 6 | opts = { use_diagnostic_signs = true }, 7 | keys = { 8 | { "xx", "Trouble diagnostics", desc = "Diagnostics" }, 9 | { "xt", "Trouble todo", desc = "TODOs" }, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /nvim/lua/plugins/vim-asterisk.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "haya14busa/vim-asterisk" }, -- Make * and # stay on the first element before iterating 3 | } 4 | -------------------------------------------------------------------------------- /nvim/lua/plugins/vim-surround.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { "tpope/vim-surround" }, -- ysiw syntax for surrounding 3 | } 4 | -------------------------------------------------------------------------------- /nvim/lua/plugins/vimtex.lua: -------------------------------------------------------------------------------- 1 | return { 2 | { 3 | "lervag/vimtex", -- latex plugin 4 | lazy = false, -- docs say to not load lazily, but undo if slow to start 5 | init = function() 6 | vim.g.vimtex_view_method = "skim" 7 | vim.g.vimtex_compiler_method = "latexmk" 8 | end, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /nvim/lua/setup-plugins.lua: -------------------------------------------------------------------------------- 1 | -- Define the location where to install lazy.nvim. 2 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 3 | -- If there's nothing currently in this path, then clone lazy.nvim into this directory. 4 | if not vim.loop.fs_stat(lazypath) then 5 | -- bootstrap lazy.nvim 6 | vim.fn.system({ 7 | "git", 8 | "clone", 9 | "--filter=blob:none", 10 | "https://github.com/folke/lazy.nvim.git", 11 | "--branch=stable", 12 | lazypath, 13 | }) 14 | end 15 | -- Add the lazy.nvim directory to the runtimepath. 16 | -- XXX: When would vim.env.LAZY be set? 17 | vim.opt.rtp:prepend(vim.env.LAZY or lazypath) 18 | 19 | require("lazy").setup({ 20 | spec = { 21 | { "folke/lazy.nvim", version = "*" }, -- manage itself 22 | { import = "plugins" }, 23 | }, 24 | change_detection = { 25 | notify = false, 26 | }, 27 | performance = { 28 | rtp = { 29 | disabled_plugins = { 30 | "gzip", 31 | "netrwPlugin", 32 | "tarPlugin", 33 | "tohtml", 34 | "tutor", 35 | "zipPlugin", 36 | }, 37 | }, 38 | }, 39 | }) 40 | -------------------------------------------------------------------------------- /nvim/lua/util.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | ---@param on_attach fun(client, buffer) 4 | function M.on_attach(on_attach) 5 | local callback = function(args) 6 | local client = vim.lsp.get_client_by_id(args.data.client_id) 7 | on_attach(client, args.buf) 8 | end 9 | vim.api.nvim_create_autocmd("LspAttach", { callback = callback }) 10 | end 11 | 12 | ---@param name string 13 | function M.opts(name) 14 | local plugin = require("lazy.core.config").plugins[name] 15 | if not plugin then 16 | return {} 17 | end 18 | local Plugin = require("lazy.core.plugin") 19 | return Plugin.values(plugin, "opts", false) 20 | end 21 | 22 | -- returns the root directory based on: 23 | -- * lsp workspace folders 24 | -- * lsp root_dir 25 | -- * root pattern of filename of the current buffer 26 | -- * root pattern of cwd 27 | ---@return string 28 | function M.get_root() 29 | ---@type string? 30 | local path = vim.api.nvim_buf_get_name(0) 31 | path = path ~= "" and vim.loop.fs_realpath(path) or nil 32 | ---@type string[] 33 | local roots = {} 34 | if path then 35 | for _, client in pairs(vim.lsp.get_active_clients({ bufnr = 0 })) do 36 | local workspace = client.config.workspace_folders 37 | local paths = workspace and vim.tbl_map(function(ws) 38 | return vim.uri_to_fname(ws.uri) 39 | end, workspace) or client.config.root_dir and { client.config.root_dir } or {} 40 | for _, p in ipairs(paths) do 41 | local r = vim.loop.fs_realpath(p) or "no-real-path-found" 42 | if path:find(r, 1, true) then 43 | roots[#roots + 1] = r 44 | end 45 | end 46 | end 47 | end 48 | table.sort(roots, function(a, b) 49 | return #a > #b 50 | end) 51 | ---@type string? 52 | local root = roots[1] 53 | if not root then 54 | path = path and vim.fs.dirname(path) or vim.loop.cwd() 55 | ---@type string? 56 | root = vim.fs.find({ ".git", "lua" }, { path = path, upward = true })[1] 57 | root = root and vim.fs.dirname(root) or vim.loop.cwd() 58 | end 59 | ---@cast root string 60 | return root 61 | end 62 | 63 | -- this will return a function that calls telescope. 64 | -- cwd will default to lazyvim.util.get_root 65 | -- for `files`, git_files or find_files will be chosen depending on .git 66 | function M.telescope(builtin, opts) 67 | local params = { builtin = builtin, opts = opts } 68 | return function() 69 | builtin = params.builtin 70 | opts = vim.tbl_deep_extend("force", { cwd = M.get_root() }, params.opts or {}) 71 | if builtin == "files" then 72 | if vim.loop.fs_stat((opts.cwd or vim.loop.cwd()) .. "/.git") then 73 | opts.show_untracked = true 74 | builtin = "git_files" 75 | else 76 | builtin = "find_files" 77 | end 78 | end 79 | require("telescope.builtin")[builtin](opts) 80 | end 81 | end 82 | 83 | return M 84 | -------------------------------------------------------------------------------- /nvim/stylua.toml: -------------------------------------------------------------------------------- 1 | indent_type = "Spaces" 2 | indent_width = 2 3 | column_width = 120 -------------------------------------------------------------------------------- /obsidian/.vimrc: -------------------------------------------------------------------------------- 1 | " Have j and k navigate visual lines rather than logical ones 2 | nmap j gj 3 | nmap k gk 4 | 5 | nmap { 6 | nmap } 7 | 8 | nmap 0 ^ 9 | 10 | nmap + 11 | nmap - 12 | 13 | nmap ; : 14 | 15 | nmap Q @@ 16 | 17 | imap jk 18 | 19 | vmap p "_dP 20 | 21 | exmap surround_wiki surround [[ ]] 22 | exmap surround_double_quotes surround " " 23 | exmap surround_single_quotes surround ' ' 24 | exmap surround_brackets surround ( ) 25 | exmap surround_square_brackets surround [ ] 26 | exmap surround_curly_brackets surround { } 27 | exmap surround_backticks surround ` ` 28 | exmap surround_latex surround $ $ 29 | exmap surround_latex_paragraph surround $$ $$ 30 | 31 | " NOTE: must use 'map' and not 'nmap' 32 | map [[ :surround_wiki 33 | nunmap S 34 | vunmap S 35 | 36 | map s 37 | 38 | map S" :surround_double_quotes 39 | map S' :surround_single_quotes 40 | map Sb :surround_brackets 41 | map S( :surround_brackets 42 | map S) :surround_brackets 43 | map S[ :surround_square_brackets 44 | map S[ :surround_square_brackets 45 | map S{ :surround_curly_brackets 46 | map S} :surround_curly_brackets 47 | map SB :surround_curly_brackets 48 | map S` :surround_backticks 49 | map Sl :surround_latex 50 | map SL :surround_latex_paragraph 51 | -------------------------------------------------------------------------------- /ripgrep/ripgreprc: -------------------------------------------------------------------------------- 1 | # Don't let ripgrep vomit really long lines to my terminal, and show a preview. 2 | --max-columns=250 3 | --max-columns-preview 4 | 5 | # Add custom types in order to easily filter (-tweb) or filter out (-Tweb) 6 | # NOTE: This only works with the name of the file itself, not the file path. 7 | # E.g. whatever/mocks/mything.go won't be matched. 8 | --type-add 9 | web:*.{html,css,js,jsx,tsx,ts,json,svelte}* 10 | --type-add 11 | test:*{Test,test,mock,spec}* 12 | 13 | # or 14 | --glob 15 | !git/* 16 | 17 | # Be smart about case-sensitivity. Only care if I include a capital letter 18 | --smart-case 19 | -------------------------------------------------------------------------------- /setup/install-brew-and-apps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Install brew 4 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 5 | 6 | # Install the pretty font that's defined in the alacritty config 7 | brew tap homebrew/cask-fonts 8 | brew install font-sauce-code-pro-nerd-font 9 | 10 | # Install system-wide snippet engine 11 | brew tap espanso/espanso 12 | brew install espanso 13 | 14 | # Command line tools 15 | brew install bat # cat but pretty 16 | brew install btop # top but prettier 17 | brew install curses # Required for fpp 18 | brew install fd # Opinionated alternative to 'find'. 19 | brew install fpp # Open URLs visible in the terminal with the keyboard 20 | brew install fzf # Fuzzy finder. Vim plugin doesn't install to path, nor sets up shell keybindings 21 | brew install gh # GitHub CLI 22 | brew install git-delta # Even better git diffs 23 | brew install go # Go programming language 24 | brew install gpg # For PGP signing 25 | brew install grpcurl # For making gRPC requests from the command line 26 | brew install jq # Query JSON 27 | brew install ncurses # Pretty terminal stuff -- needed for tmux-256color 28 | brew install --HEAD neovim # Editor 29 | brew install pinentry-mac # Lets you enter passwords with a TUI when signing git commits 30 | brew install rg # Super fast grep-like application, used by FZF and telescope.nvim 31 | brew install skim # PDF viewer with auto-refresh functionality for writing LaTeX 32 | brew install tmux # Terminal multiplexer 33 | brew install tree # Show folders and files easily 34 | brew install up # Incrementally build long pipes 35 | brew install urlview # Required for fpp 36 | brew install zoxide # Fast directory switching 37 | 38 | # basic unix utils as you expect them to work 39 | brew install coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt grep 40 | 41 | # UI Apps 42 | brew install alfred # Productivity heaven 43 | brew install anki # Flashcards 44 | brew install obsidian # Second brain 45 | brew install qlmarkdown # Let finder's Preview understand Markdown files 46 | 47 | go install github.com/kinbiko/kokodoko/cmd/kokodoko@latest # Required by neovim bindings 48 | go install github.com/kinbiko/jisho-alfred@latest # Required by the Jisho.org Alfred workflow 49 | 50 | # Optional 51 | go install github.com/kinbiko/mokku/cmd/mokku@latest 52 | go install github.com/kinbiko/semver/cmd/upversion@latest 53 | 54 | "$(brew --prefix)/opt/ncurses/bin/infocmp" tmux-256color >|~/tmux-256color.info 55 | tic -xe tmux-256color ~/tmux-256color.info 56 | infocmp tmux-256color | head 57 | -------------------------------------------------------------------------------- /setup/mac-system-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Make key repeat super fast. Stolen from: 4 | # https://apple.stackexchange.com/a/83923 5 | defaults write -g InitialKeyRepeat -int 10 # normal minimum is 15 (225 ms) 6 | defaults write -g KeyRepeat -int 1 # normal minimum is 2 (30 ms) 7 | 8 | # Hide fluffy directories from finder that I can't delete 9 | chflags hidden Applications Movies Music Pictures Public 10 | 11 | # Make Anki-Connect work well even when not in foreground 12 | defaults write net.ankiweb.dtop NSAppSleepDisabled -bool true 13 | defaults write net.ichi2.anki NSAppSleepDisabled -bool true 14 | defaults write org.qt-project.Qt.QtWebEngineCore NSAppSleepDisabled -bool true 15 | -------------------------------------------------------------------------------- /setup/set-up-zsh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | source "~/.config/zsh/.zshenv" 4 | # .zshenv contains $XDG_CONFIG_HOME so link only after this environment 5 | # variable is available 6 | ln -s "$XDG_CONFIG_HOME/zsh/.zshenv" ~/.zshenv 7 | 8 | # Single quotes here is correct. Want to refer to the variable name in zsh, not 9 | # the value it has at the time of install. 10 | echo 'source $XDG_CONFIG_HOME/zsh/.zshrc' >~/.zshrc 11 | -------------------------------------------------------------------------------- /tmux/init_tmux_window.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # vim: set ft=sh: 3 | 4 | function init_tmux_window() { 5 | local session="$1" 6 | local name="$2" 7 | local org="$3" 8 | local repo="$4" 9 | 10 | # Create the session if it doesn't exist 11 | if ! tmux has-session -t "$session" 2>/dev/null; then 12 | tmux new-session -d -s "$session" 13 | # If it's the session is being created then instead of creating a new 14 | # window we should rename the default one 15 | tmux rename-window -t "$session:0" "$name" 16 | fi 17 | 18 | # Create the window if it doesn't exist 19 | if ! tmux list-windows -t "$session" | grep -q "$name"; then 20 | tmux new-window -t "$session" -n "$name" 21 | fi 22 | 23 | tmux send-keys -t "$session:$name" "mkdir \"$session\"" Enter 24 | tmux send-keys -t "$session:$name" "cd \"$session\"" Enter 25 | tmux send-keys -t "$session:$name" "gh repo clone $org/$repo" Enter 26 | tmux send-keys -t "$session:$name" "cd $repo" Enter 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | set -g default-terminal "tmux-256color" 2 | set -sa terminal-overrides ",alacritty:RGB" 3 | 4 | setw -g xterm-keys on # Allow ctrl, shift, and alt keys to work as expected. 5 | 6 | # Time to wait after 'esc' to determine if it's a function or meta key 7 | # sequence. Not having this makes vim really annoying to use, as getting into 8 | # normal mode takes forever. 9 | set -s escape-time 0 10 | 11 | # Make it so you don't have to hit the prefix every time you run a tmux 12 | # command, and allow multiple tmux commands in quick succession 13 | # (default was 500ms). Useful for resizing panes 14 | set -sg repeat-time 600 15 | 16 | # Allow focus events from the terminal to bubble through to tmux. 17 | # E.g. clicking on a pane 18 | set -s focus-events on 19 | 20 | set -g prefix C-a # Change the prefix from the default ctrl+b to ctrl+a 21 | 22 | setw -qg utf8 on # Expect UTF-8 23 | 24 | # The maximum number of lines held in window history. 25 | # I.e. scrolling up and down a tmux pane 26 | set -g history-limit 25000 # boost history 27 | 28 | # Usually, having windows be 1-indexed would make more sense, since most keyboards are 1234567890 29 | # Mine is 01234 30 | # 56789 31 | set -g base-index 0 32 | setw -g pane-base-index 0 33 | 34 | set -g allow-rename off # After renaming the window, don't automatically rename it again 35 | set -g renumber-windows on # Renumber windows when a window is closed 36 | 37 | set -g status off # Don't need any status bars 38 | set -g status-position top # But when I rename panes I want to look to the top of the screen 39 | 40 | # Closing a session/window/whatever doesn't exit out of tmux, but moves to another session. 41 | set -g detach-on-destroy off 42 | 43 | # New windows should have the same path as current window 44 | bind c new-window -c "#{pane_current_path}" 45 | 46 | # Pane navigation 47 | bind -r h select-pane -L 48 | bind -r j select-pane -D 49 | bind -r k select-pane -U 50 | bind -r l select-pane -R 51 | 52 | # Pane resizing 53 | bind -r H resize-pane -L 1 54 | bind -r J resize-pane -D 1 55 | bind -r K resize-pane -U 1 56 | bind -r L resize-pane -R 1 57 | 58 | # Pane splitting 59 | bind - split-window -v -c '#{pane_current_path}' 60 | bind _ split-window -h -c '#{pane_current_path}' 61 | 62 | # allow vim bindings to work as expected in tmux menus etc. 63 | bind -T choice-mode-vi h send-keys -X tree-collapse 64 | bind -T choice-mode-vi l send-keys -X tree-expand 65 | run -b 'tmux bind -T choice-mode-vi K send-keys -X start-of-list 2> /dev/null' 66 | run -b 'tmux bind -T choice-mode-vi J send-keys -X end-of-list 2> /dev/null' 67 | bind -T choice-mode-vi H send-keys -X tree-collapse-all 68 | bind -T choice-mode-vi L send-keys -X tree-expand-all 69 | bind -T choice-mode-vi Escape send-keys -X cancel 70 | bind -T copy-mode-vi v send-keys -X begin-selection 71 | bind -T copy-mode-vi C-v send-keys -X rectangle-toggle 72 | bind -T copy-mode-vi y send-keys -X copy-selection 73 | bind -T copy-mode-vi Escape send-keys -X cancel 74 | bind -T copy-mode-vi H send-keys -X start-of-line 75 | bind -T copy-mode-vi L send-keys -X end-of-line 76 | 77 | bind p paste-buffer # Paste most recent copied buffer 78 | 79 | # Checks to see if we're in vim or fzf 80 | is_vim="ps -o tty= -o state= -o comm= | grep -iqE '^#{s|/dev/||:pane_tty} +[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" 81 | is_fzf="ps -o tty= -o state= -o comm= | grep -iqE '^#{s|/dev/||:pane_tty} +[^TXZ ]+ +(\\S+\\/)?fzf$'" 82 | 83 | # If it's vim, then move within vim windows. Otherwise move within tmux panes 84 | # If it's fzf, move up or down the fzf options with ctrl+j and ctrl+k 85 | bind -n C-h run "($is_vim && tmux send-keys C-h) || tmux select-pane -L" 86 | bind -n C-j run "($is_vim && tmux send-keys C-j) || ($is_fzf && tmux send-keys C-j) || tmux select-pane -D" 87 | bind -n C-k run "($is_vim && tmux send-keys C-k) || ($is_fzf && tmux send-keys C-k) || tmux select-pane -U" 88 | bind -n C-l run "($is_vim && tmux send-keys C-l) || tmux select-pane -R" 89 | 90 | setw -g mouse on # Enable mouse support (e.g. scrolling) 91 | 92 | # Simplified version of https://github.com/tmux-plugins/tmux-urlview 93 | bind "u" capture-pane -J \; save-buffer "/tmp/tmux-buffer" \; delete-buffer \; split-window -l 10 "urlview '/tmp/tmux-buffer'" 94 | 95 | bind -r s run-shell "tmux neww ~/.config/zsh/scripts/tmux-quick-repo" 96 | bind -r S run-shell "tmux neww ~/.config/zsh/scripts/tmux-quick-monorepo" 97 | -------------------------------------------------------------------------------- /zsh/.zshenv: -------------------------------------------------------------------------------- 1 | # This file is run for *every* zsh shell (login and interactive agnostic) 2 | # E.g. commands executed from within vim or scripts in Alfred etc. will also 3 | # benefit from this file. 4 | 5 | export EDITOR='nvim' 6 | export XDG_CONFIG_HOME="$HOME/.config" 7 | export BIGQUERYRC="$XDG_CONFIG_HOME/bigquery/bigqueryrc" 8 | export RIPGREP_CONFIG_PATH="$XDG_CONFIG_HOME/ripgrep/ripgreprc" 9 | export LANG=en_US.UTF-8 10 | 11 | alias dcd="docker compose down" 12 | alias dcu="docker compose up" 13 | alias effyou="git push -f" 14 | alias fetch="git fetch -p" 15 | alias g="git" 16 | alias ga="git add -A" 17 | alias glint="golangci-lint" 18 | alias gorammit="git commit --amend --no-edit" 19 | alias gorram="git commit --amend --no-edit" 20 | alias gorramit="git commit --amend --no-edit" 21 | alias gorrammit="git commit --amend --no-edit" 22 | alias gs="git status" 23 | alias gtr="go test -race" 24 | alias pull="git pull" 25 | alias push="git push" 26 | alias tf="terraform" 27 | alias v="nvim" 28 | alias vim="nvim" 29 | alias vimdiff="nvim -d" 30 | -------------------------------------------------------------------------------- /zsh/.zshrc: -------------------------------------------------------------------------------- 1 | # This file is run for interactive shells only. 2 | 3 | typeset -U path PATH # Unique-ify the path 4 | 5 | # Unable to load these in zshenv because it can't find the go binary yet 6 | export GOPATH="$(go env GOPATH)" 7 | export GOBIN="$GOPATH/bin" 8 | 9 | export QUICK_TMUX_REPOS="$HOME/repos $HOME/.config" 10 | export QUICK_TMUX_MONOREPOS="" 11 | 12 | path+=("$GOBIN" "$HOME/scripts" "$XDG_CONFIG_HOME/zsh/scripts") 13 | 14 | fpath+="$XDG_CONFIG_HOME/zsh/functions" 15 | autoload \ 16 | bigquery \ 17 | kk \ 18 | kube \ 19 | pod-logs \ 20 | pod-port-forward-grpc \ 21 | pod-port-forward-http \ 22 | pod-sync \ 23 | pr-comments \ 24 | toiletpresence \ 25 | 26 | # Wait 10 ms for additional key sequences. 27 | # Allows you to enter normal mode in zsh faster than the default 0.4s 28 | export KEYTIMEOUT=1 29 | 30 | # This makes copy and pasting in the shell be the same as the system clipboard 31 | clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; } 32 | clippaste() { pbpaste; } 33 | 34 | # Docs: https://zsh.sourceforge.io/Doc/Release/Options.html 35 | setopt AUTO_PARAM_SLASH # Tab completing directory appends a slash 36 | setopt INTERACTIVE_COMMENTS # Allow comments even in interactive shells. 37 | setopt NO_CLOBBER # Don't overwrite files with > redirects. Use >| to force 38 | setopt MAGIC_EQUAL_SUBST # Auto-complete paths in arguments 39 | 40 | source "$XDG_CONFIG_HOME/zsh/vi-mode.zsh" # Doesn't work well if it's not first 41 | 42 | source "$XDG_CONFIG_HOME/zsh/brew.zsh" 43 | source "$XDG_CONFIG_HOME/zsh/fzf.zsh" 44 | source "$XDG_CONFIG_HOME/zsh/history.zsh" 45 | source "$XDG_CONFIG_HOME/zsh/keybindings.zsh" 46 | source "$XDG_CONFIG_HOME/zsh/theme.zsh" 47 | 48 | alias add="clear; git add -p" 49 | alias caler="clear" 50 | alias cat="bat" 51 | alias claer="clear" 52 | alias clar="clear" 53 | alias clare="clear" 54 | alias cler="clear" 55 | alias dot="cd $XDG_CONFIG_HOME" 56 | alias gd="clear; git diff" 57 | alias gdc="clear; git diff --cached" 58 | alias gdno="git diff --name-only" 59 | alias gitroot='cd $(git rev-parse --show-toplevel)' 60 | alias glog='git log --graph --pretty=format:'\''%Cred%h%Creset %Cgreen(%cr)%Creset%Cblue[%an]%Creset %s%Creset%C(yellow)%d%Creset'\'' --abbrev-commit --date=relative' 61 | alias htop="btop" 62 | alias iedit='gh issue edit $(gh issue list | fzf | cut -f 1)' # Shorthand for editing an issue after first listing available issues 63 | alias jq="jq -Sr" 64 | alias la='ls -lAh' 65 | alias lear="clear" 66 | alias pingu="ping google.com" 67 | alias q="exit" 68 | alias rg='clear; rg' 69 | alias sd="z" 70 | alias sdi="zi" 71 | alias ta="tmux new-session -A -s kinbiko" # New session or attach if it already exists 72 | alias top="btop" 73 | 74 | eval "$(nodenv init -)" 75 | eval "$(zoxide init zsh)" 76 | eval "$(direnv hook zsh)" 77 | -------------------------------------------------------------------------------- /zsh/brew.zsh: -------------------------------------------------------------------------------- 1 | # Run brew commands without forcing an update first. 2 | export HOMEBREW_NO_AUTO_UPDATE=1 3 | # Get homebrew to back off when I'm just trying to install / upgrade one thing 4 | # and there are other things installed that have newer versions. 5 | export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 6 | 7 | # Set up completion for programs that define these under site-functions 8 | if type brew &>/dev/null; then 9 | FPATH=$(brew --prefix)/share/zsh/site-functions:$FPATH 10 | 11 | autoload -Uz compinit 12 | compinit 13 | fi 14 | -------------------------------------------------------------------------------- /zsh/functions/bigquery: -------------------------------------------------------------------------------- 1 | # Create a directory to store input queries and their corresponding output. 2 | local _querydirname="$HOME/.cache/bigquery-history" 3 | [ -d $_querydirname ] || mkdir -p $_querydirname 4 | 5 | # Prep a record of each query and their response for debugging/caching purposes 6 | local _datetime="$(date -uI'seconds')" 7 | local _queryfilename="$_querydirname/$_datetime-query.sql" 8 | local _resultfilename="$_querydirname/$_datetime-result.json" 9 | 10 | # Prep the query, letting the user modify a "base" query with their editor of choice 11 | if [[ -f $LAST_BIGQUERY_QUERY ]]; then 12 | cat $LAST_BIGQUERY_QUERY >$_queryfilename 13 | else 14 | local _project_name="$(gcloud config get-value project)" 15 | echo 'SELECT * FROM `'"$_project_name"'.database.table` LIMIT 10;' >$_queryfilename 16 | fi 17 | command "$EDITOR" "$_queryfilename" 18 | 19 | # Make the bigquery query, and save the result. For convenience keep track of 20 | # the result in an environment variable called $LAST_BIGQUERY_RESULT. 21 | command bq "query" "$(<$_queryfilename)" >$_resultfilename 22 | export LAST_BIGQUERY_RESULT=$_resultfilename 23 | export LAST_BIGQUERY_QUERY=$_queryfilename 24 | 25 | # Prepare the next command for execution in a way that it 26 | # can be later retrieved from the history without causing a 27 | # new request. 28 | print -z 'cat $LAST_BIGQUERY_RESULT | jq -r '"'.'" 29 | -------------------------------------------------------------------------------- /zsh/functions/kk: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | # The following kubernetes command was stolen from @eqyiel, and further modified. 3 | # Onto @eqyiel the glory 4 | _kk__ls() { 5 | kubectl -n $GCP_PROJECT_ID get pods | tail -n +2 6 | } 7 | 8 | _kk__pod() { 9 | _kk__ls | fzf | cut -f1 -d' ' 10 | } 11 | 12 | _kk__cpod() { 13 | _kk__pod | tr -d '\n' | pbcopy 14 | } 15 | 16 | _kk__describe() { 17 | tmp_file=$(mktemp) 18 | kubectl -n $GCP_PROJECT_ID describe pod $(_kk__pod) >| $tmp_file 19 | nvim $tmp_file 20 | } 21 | 22 | _kk__logs() { 23 | kubectl -n $GCP_PROJECT_ID logs $(_kk__pod) --follow 24 | } 25 | 26 | _kk__logsj() { 27 | _kk__logs | jq -R '.ts |= (. + 32400 | todateiso8601)' 28 | } 29 | 30 | kk() { 31 | if [ $# -eq 0 ]; then 32 | echo "Usage:" 33 | echo " kk " 34 | return 1 35 | fi 36 | local cmdname=$1; shift 37 | if type "_kk__$cmdname" >/dev/null 2>&1; then 38 | "_kk__$cmdname" "$@" 39 | else 40 | echo "Unknown command $cmdname" 41 | return 1 42 | fi 43 | } 44 | 45 | kk $@ 46 | -------------------------------------------------------------------------------- /zsh/functions/kube: -------------------------------------------------------------------------------- 1 | kubectl $@ -n $GCP_PROJECT_ID 2 | -------------------------------------------------------------------------------- /zsh/functions/pod-logs: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | if [[ -z "${PR_NUM+x}" ]]; then 4 | PR_NUM=$(gh pr view --json number | jq -R '.number') 5 | fi 6 | if [[ -z "${PRRC_POD+x}" ]]; then 7 | PRRC_POD=$(kubectl -n $GCP_PROJECT_ID get pods | grep "pr$PR_NUM" | cut -d ' ' -f1) 8 | fi 9 | 10 | 11 | kubectl -n $GCP_PROJECT_ID logs $PRRC_POD --follow | jq -R '. as $line | try (.ts |= (. + 32400 | todateiso8601)) catch $line' 12 | -------------------------------------------------------------------------------- /zsh/functions/pod-port-forward-grpc: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | if [[ -z "${PR_NUM+x}" ]]; then 4 | PR_NUM=$(gh pr view --json number | jq '.number') 5 | fi 6 | if [[ -z "${PRRC_POD+x}" ]]; then 7 | PRRC_POD=$(kubectl -n $GCP_PROJECT_ID get pods | grep "pr$PR_NUM" | cut -d ' ' -f1) 8 | fi 9 | if [[ -z "${GRPC_PORT+x}" ]]; then 10 | echo "Please set GRPC_PORT in the environment" 11 | return 12 | fi 13 | 14 | kubectl -n $GCP_PROJECT_ID port-forward $PRRC_POD $GRPC_PORT':'$GRPC_PORT 15 | -------------------------------------------------------------------------------- /zsh/functions/pod-port-forward-http: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | if [[ -z "${PR_NUM+x}" ]]; then 4 | PR_NUM=$(gh pr view --json number | jq '.number') 5 | fi 6 | if [[ -z "${PRRC_POD+x}" ]]; then 7 | PRRC_POD=$(kubectl -n $GCP_PROJECT_ID get pods | grep "pr$PR_NUM" | cut -d ' ' -f1) 8 | fi 9 | if [[ -z "${HTTP_PORT+x}" ]]; then 10 | echo "Please set HTTP_PORT in the environment" 11 | return 12 | fi 13 | 14 | kubectl -n $GCP_PROJECT_ID port-forward $PRRC_POD $HTTP_PORT':'$HTTP_PORT 15 | -------------------------------------------------------------------------------- /zsh/functions/pod-sync: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | PR_NUM=$(gh pr view --json number | jq '.number') 3 | PRRC_POD=$(kubectl -n $GCP_PROJECT_ID get pods | grep "pr$PR_NUM" | cut -d ' ' -f1) 4 | 5 | echo 'shell vars synced:' 6 | 7 | echo ' $PR_NUM = '"$PR_NUM" 8 | echo '$PRRC_POD = '"$PRRC_POD" 9 | -------------------------------------------------------------------------------- /zsh/functions/pr-comments: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | # depends on jq and github.com/kinbiko/gh-pr-comments being installed on the PATH 3 | 4 | if [[ -z "${PR_NUM+x}" ]]; then 5 | PR_NUM=$(gh pr view --json number | jq '.number') 6 | fi 7 | 8 | OWNER_AND_REPO=$(git remote -v | cut -d':' -f2 | cut -d'.' -f1 | uniq) 9 | 10 | gh api \ 11 | -H "Accept: application/vnd.github+json" \ 12 | -H "X-GitHub-Api-Version: 2022-11-28" \ 13 | /repos/$OWNER_AND_REPO/pulls/$PR_NUM/comments | jq | gh-pr-comments 14 | -------------------------------------------------------------------------------- /zsh/functions/toiletpresence: -------------------------------------------------------------------------------- 1 | # I don't like this particular tool (telepresence) very much. 2 | # Hence the name of the function. 3 | 4 | # I can't believe this is necessary :( 5 | sudo dscacheutil -flushcache 6 | sudo killall -HUP mDNSResponder 7 | 8 | sudo telepresence quit 9 | sudo telepresence connect --mapped-namespaces $GCP_PROJECT_ID 10 | -------------------------------------------------------------------------------- /zsh/fzf.zsh: -------------------------------------------------------------------------------- 1 | export FZF_DEFAULT_COMMAND='rg --files-with-matches --hidden .' 2 | export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" 3 | export FZF_CTRL_T_OPTS='--preview "bat --color=always --style=numbers --line-range=:500 {}"' 4 | 5 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh 6 | 7 | function checkout() { 8 | local git_branches pr_num_title_branch view branch num 9 | 10 | git_branches=$(git branch) 11 | pr_num_title_branch=$(gh pr list --json 'title,number,headRefName' | jq '.[] | {number: .number|tostring, title, headRefName} | .number + "\t" + .title + "\t" + .headRefName') 12 | view="$git_branches\n$pr_num_title_branch" 13 | branch=$(echo $view | fzf --prompt="Select a branch: ") 14 | 15 | if [[ -n "$branch" ]]; then 16 | num=$(echo "$branch" | cut -f 1) 17 | if [[ $num =~ ^[0-9]+$ ]] ; then 18 | gh pr checkout $num 19 | else 20 | git checkout $(echo $branch | xargs) 21 | fi 22 | fi 23 | } 24 | -------------------------------------------------------------------------------- /zsh/history.zsh: -------------------------------------------------------------------------------- 1 | SAVEHIST=10000 # Number of commands to keep in history file 2 | HISTSIZE=10000 # Number of lines the shell keeps in one session 3 | HISTFILE=~/.zsh_history # History file location 4 | 5 | # Docs: https://zsh.sourceforge.io/Guide/zshguide02.html section: 2.5.5: History options 6 | setopt APPEND_HISTORY # Append history instead of overwriting 7 | setopt HIST_EXPIRE_DUPS_FIRST # Delete duplicates first when HISTFILE size exceeds HISTSIZE 8 | setopt HIST_VERIFY # Expand history references (e.g. !!) instead of running right away 9 | setopt SHARE_HISTORY # share command history data across sessions 10 | setopt EXTENDED_HISTORY # Write datetime and duration to history. List with 'history -Di' 11 | setopt HIST_ALLOW_CLOBBER # Let the history auto insert >| when using clobbering redirection 12 | setopt HIST_IGNORE_SPACE # Don't append commands that start with space to the history 13 | setopt HIST_NO_STORE # Don't store 'history' or 'fc' commands in history 14 | -------------------------------------------------------------------------------- /zsh/keybindings.zsh: -------------------------------------------------------------------------------- 1 | # [Shift-Tab] - move through the completion menu backwards 2 | if [[ -n "${terminfo[kcbt]}" ]]; then 3 | bindkey -M viins "${terminfo[kcbt]}" reverse-menu-complete 4 | bindkey -M vicmd "${terminfo[kcbt]}" reverse-menu-complete 5 | fi 6 | 7 | bindkey '\C-v' edit-command-line 8 | 9 | # Undo the zle completion, e.g. history expansion 10 | bindkey '^u' undo 11 | -------------------------------------------------------------------------------- /zsh/scripts/extract: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | # extract can decompress most compressed files, assuming the correct tool is installed. 3 | # Cred to DevRant user Jilano: https://devrant.com/users/Jilano 4 | if [[ -f "$1" ]]; then 5 | case "$1" in 6 | *.tar.bz2) tar xvjf "$1" ;; 7 | *.tar.gz) tar xvzf "$1" ;; 8 | *.bz2) bunzip2 "$1" ;; 9 | *.rar) unrar x "$1" ;; 10 | *.gz) gunzip "$1" ;; 11 | *.tar) tar xvf "$1" ;; 12 | *.tbz2) tar xvjf "$1" ;; 13 | *.tgz) tar xvzf "$1" ;; 14 | *.zip) unzip "$1" ;; 15 | *.Z) uncompress "$1" ;; 16 | *.7z) 7z x "$1" ;; 17 | *) 18 | echo "No idea how to extract this filetype" 19 | exit 2 20 | ;; 21 | esac 22 | else 23 | echo "'$1' is not a valid file!" 24 | exit 1 25 | fi 26 | -------------------------------------------------------------------------------- /zsh/scripts/holla: -------------------------------------------------------------------------------- 1 | gh pr checks --watch 2 | say "Continuous integration jobs complete." 3 | -------------------------------------------------------------------------------- /zsh/scripts/mk: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | # Find the most immediate Makefile and run make commands without complaining about not finding the Makefile in the current dir. 4 | 5 | gitroot="$(git rev-parse --show-toplevel)" 6 | 7 | dir=$(pwd) 8 | while [[ "$dir" != "$gitroot" ]]; do 9 | if [[ -e "$dir/Makefile" ]]; then 10 | cd "$dir" || exit 1 11 | break 12 | fi 13 | dir=$(dirname "$dir") 14 | done 15 | 16 | make -C "$dir" "$@" 17 | ret_code=$? 18 | 19 | # Navigate back to the original directory, silently. 20 | cd - >/dev/null 2>&1 || exit 21 | 22 | exit $ret_code 23 | -------------------------------------------------------------------------------- /zsh/scripts/tmux-quick-monorepo: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | # Allow opening a session by name for a non-fzf shorthand for a session opened 4 | # regularly. 5 | if [[ $# -eq 1 ]]; then 6 | selected=$1 7 | else 8 | selected=$(find $QUICK_TMUX_MONOREPOS -mindepth 1 -maxdepth 1 -type d | fzf) 9 | fi 10 | 11 | # If selected directory is empty, exit the script 12 | if [[ -z $selected ]]; then 13 | exit 0 14 | fi 15 | 16 | # Extract the base name of the selected directory and replace any dots with 17 | # underscores so that it's a valid session name in TMUX 18 | selected_name=$(basename "$selected" | tr . _) 19 | 20 | # Check if tmux is already running 21 | tmux_running=$(pgrep tmux) 22 | 23 | # If not inside a tmux session and tmux is not running, create a new session 24 | # with selected directory 25 | if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then 26 | tmux new-session -s $selected_name -c $selected 27 | exit 0 28 | fi 29 | 30 | # If a tmux session with the selected name doesn't exist, create a new detached 31 | # session with selected directory 32 | if ! tmux has-session -t=$selected_name 2>/dev/null; then 33 | tmux new-session -ds $selected_name -c $selected 34 | fi 35 | 36 | # Switch to the tmux session with the selected name 37 | tmux switch-client -t $selected_name 38 | -------------------------------------------------------------------------------- /zsh/scripts/tmux-quick-repo: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | # Allow opening a session by name for a non-fzf shorthand for a session opened 4 | # regularly. 5 | if [[ $# -eq 1 ]]; then 6 | selected=$1 7 | else 8 | selected=$(find $QUICK_TMUX_REPOS -mindepth 1 -maxdepth 1 -type d | fzf) 9 | fi 10 | 11 | # If selected directory is empty, exit the script 12 | if [[ -z $selected ]]; then 13 | exit 0 14 | fi 15 | 16 | # Extract the base name of the selected directory and replace any dots with 17 | # underscores so that it's a valid session name in TMUX 18 | selected_name=$(basename "$selected" | tr . _) 19 | 20 | # Check if tmux is already running 21 | tmux_running=$(pgrep tmux) 22 | 23 | # If not inside a tmux session and tmux is not running, create a new session 24 | # with selected directory 25 | if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then 26 | tmux new-session -s $selected_name -c $selected 27 | exit 0 28 | fi 29 | 30 | # If a tmux session with the selected name doesn't exist, create a new detached 31 | # session with selected directory 32 | if ! tmux has-session -t=$selected_name 2>/dev/null; then 33 | tmux new-session -ds $selected_name -c $selected 34 | fi 35 | 36 | # Switch to the tmux session with the selected name 37 | tmux switch-client -t $selected_name 38 | -------------------------------------------------------------------------------- /zsh/theme.zsh: -------------------------------------------------------------------------------- 1 | setopt PROMPT_SUBST # Make substitutions in prompt strings, allowing for coloring. 2 | 3 | # ls colors 4 | autoload -U colors && colors 5 | 6 | # Enable ls colors 7 | export LSCOLORS="Gxfxcxdxbxegedabagacad" 8 | 9 | function colorize() { 10 | echo "%{$fg[$2]%}$1%{$reset_color%}" 11 | } 12 | function colorize_bold() { 13 | echo "%{$fg_bold[$2]%}$1%{$reset_color%}" 14 | } 15 | 16 | function git_info() { 17 | if ! GIT_OPTIONAL_LOCKS=0 command git rev-parse --git-dir &> /dev/null; then 18 | return 0 19 | fi 20 | 21 | local is_dirty=$(GIT_OPTIONAL_LOCKS=0 command git diff --quiet && git diff --cached --quiet) 22 | if [[ -n $is_dirty ]]; then 23 | local color="yellow" 24 | else 25 | local color="green" 26 | fi 27 | 28 | local branch=$(GIT_OPTIONAL_LOCKS=0 command git symbolic-ref --short HEAD 2> /dev/null || echo "<>") 29 | echo "$(colorize "⎇ ${branch}" $color)" 30 | } 31 | 32 | local current_dir="$(colorize_bold "%3~" "cyan")" 33 | local return_status_symbols="%(?..%? 💀)" 34 | local return_status_indicator=$(colorize "${return_status_symbols}" "red") 35 | local lambda_prompt="$(colorize_bold "»" "red")" 36 | if [[ -n "$TMUX" ]]; then 37 | lambda_prompt="$(colorize_bold "λ" "white")" 38 | fi 39 | 40 | # Main prompt 41 | PS1='${current_dir} $(git_info) ${return_status_indicator} 42 | ${lambda_prompt} ' 43 | 44 | #local current_time='$(date "+%Y-%m-%dT%H:%M:%S")' 45 | #RPS1="$(colorize "${current_time}" "white")" 46 | 47 | # This shows up when a command runs longer than one line 48 | PS2=$(colorize_bold "︙" "black") 49 | 50 | # Colorize completions using default `ls` colors. 51 | zstyle ':completion:*' list-colors '' 52 | -------------------------------------------------------------------------------- /zsh/vi-mode.zsh: -------------------------------------------------------------------------------- 1 | # Stolen from oh-my-zsh's official plugin 2 | # Control whether to force a redraw on each mode change. 3 | # 4 | # Resetting the prompt on every mode change can cause lag when switching modes. 5 | # This is especially true if the prompt does things like checking git status. 6 | # 7 | # Set to "true" to force the prompt to reset on each mode change. 8 | # Unset or set to any other value to do the opposite. 9 | # 10 | # The default is not to reset, unless we're showing the mode in RPS1. 11 | typeset -g VI_MODE_RESET_PROMPT_ON_MODE_CHANGE 12 | # Control whether to change the cursor style on mode change. 13 | # 14 | # Set to "true" to change the cursor on each mode change. 15 | # Unset or set to any other value to do the opposite. 16 | typeset -g VI_MODE_SET_CURSOR 17 | 18 | typeset -g VI_KEYMAP=main 19 | 20 | function _vi-mode-set-cursor-shape-for-keymap() { 21 | [[ "$VI_MODE_SET_CURSOR" = true ]] || return 22 | 23 | # https://vt100.net/docs/vt510-rm/DECSCUSR 24 | local _shape=0 25 | case "${1:-${VI_KEYMAP:-main}}" in 26 | main) _shape=6 ;; # vi insert: line 27 | viins) _shape=6 ;; # vi insert: line 28 | isearch) _shape=6 ;; # inc search: line 29 | command) _shape=6 ;; # read a command name 30 | vicmd) _shape=2 ;; # vi cmd: block 31 | visual) _shape=2 ;; # vi visual mode: block 32 | viopp) _shape=0 ;; # vi operation pending: blinking block 33 | *) _shape=0 ;; 34 | esac 35 | printf $'\e[%d q' "${_shape}" 36 | } 37 | 38 | # Updates editor information when the keymap changes. 39 | function zle-keymap-select() { 40 | # update keymap variable for the prompt 41 | typeset -g VI_KEYMAP=$KEYMAP 42 | 43 | if [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]]; then 44 | zle reset-prompt 45 | zle -R 46 | fi 47 | _vi-mode-set-cursor-shape-for-keymap "${VI_KEYMAP}" 48 | } 49 | zle -N zle-keymap-select 50 | 51 | # These "echoti" statements were originally set in lib/key-bindings.zsh 52 | # Not sure the best way to extend without overriding. 53 | function zle-line-init() { 54 | local prev_vi_keymap 55 | prev_vi_keymap="${VI_KEYMAP:-}" 56 | typeset -g VI_KEYMAP=main 57 | [[ "$prev_vi_keymap" != 'main' ]] && [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]] && zle reset-prompt 58 | (( ! ${+terminfo[smkx]} )) || echoti smkx 59 | _vi-mode-set-cursor-shape-for-keymap "${VI_KEYMAP}" 60 | } 61 | zle -N zle-line-init 62 | 63 | function zle-line-finish() { 64 | typeset -g VI_KEYMAP=main 65 | (( ! ${+terminfo[rmkx]} )) || echoti rmkx 66 | _vi-mode-set-cursor-shape-for-keymap default 67 | } 68 | zle -N zle-line-finish 69 | 70 | bindkey -v 71 | 72 | # allow vv to edit the command line (standard behaviour) 73 | autoload -Uz edit-command-line 74 | zle -N edit-command-line 75 | bindkey -M vicmd 'vv' edit-command-line 76 | 77 | # allow ctrl-p, ctrl-n for navigate history (standard behaviour) 78 | bindkey '^P' up-history 79 | bindkey '^N' down-history 80 | 81 | # allow ctrl-h, ctrl-w, ctrl-? for char and word deletion (standard behaviour) 82 | bindkey '^?' backward-delete-char 83 | bindkey '^h' backward-delete-char 84 | bindkey '^w' backward-kill-word 85 | 86 | # allow ctrl-r and ctrl-s to search the history 87 | bindkey '^r' history-incremental-search-backward 88 | bindkey '^s' history-incremental-search-forward 89 | 90 | # allow ctrl-a and ctrl-e to move to beginning/end of line 91 | bindkey '^a' beginning-of-line 92 | bindkey '^e' end-of-line 93 | 94 | function wrap_clipboard_widgets() { 95 | # NB: Assume we are the first wrapper and that we only wrap native widgets 96 | # See zsh-autosuggestions.zsh for a more generic and more robust wrapper 97 | local verb="$1" 98 | shift 99 | 100 | local widget 101 | local wrapped_name 102 | for widget in "$@"; do 103 | wrapped_name="_zsh-vi-${verb}-${widget}" 104 | if [ "${verb}" = copy ]; then 105 | eval " 106 | function ${wrapped_name}() { 107 | zle .${widget} 108 | printf %s \"\${CUTBUFFER}\" | clipcopy 2>/dev/null || true 109 | } 110 | " 111 | else 112 | eval " 113 | function ${wrapped_name}() { 114 | CUTBUFFER=\"\$(clippaste 2>/dev/null || echo \$CUTBUFFER)\" 115 | zle .${widget} 116 | } 117 | " 118 | fi 119 | zle -N "${widget}" "${wrapped_name}" 120 | done 121 | } 122 | 123 | wrap_clipboard_widgets copy vi-yank vi-yank-eol vi-backward-kill-word vi-change-whole-line vi-delete vi-delete-char 124 | wrap_clipboard_widgets paste vi-put-{before,after} 125 | unfunction wrap_clipboard_widgets 126 | --------------------------------------------------------------------------------