Compare commits

...
Sign in to create a new pull request.

29 commits

Author SHA1 Message Date
26fb9ca518
ci: nix
Some checks failed
Code Quality / changes (push) Has been cancelled
Code Quality / Lua Format Check (push) Has been cancelled
Code Quality / Lua Lint Check (push) Has been cancelled
Code Quality / Lua Type Check (push) Has been cancelled
Code Quality / Markdown Format Check (push) Has been cancelled
2026-03-04 14:12:41 -05:00
6b1ba1f056
ci: scripts + format 2026-03-04 13:50:44 -05:00
af0a44bec8
ci: migrate to nix 2026-02-23 18:14:20 -05:00
f52dd06c26
build(flake): add nix devShell
Problem: no nix dev shell existed, making it harder to get local
tooling for formatting, linting, and type checking.

Solution: add a flake with a devShell providing prettier, stylua,
selene, and lua-language-server.
2026-02-23 17:35:26 -05:00
7891879b4e
feat: blink-cmp-git integration 2026-02-20 20:18:23 -05:00
638a9e65f3
fix: use plain background for gitsigns highlights
Problem: gitsigns groups were linked to DiffAdd/DiffChange/DiffDelete,
which have tinted backgrounds that look out of place in the sign column.

Solution: define GitSignsAdd, GitSignsChange, and GitSignsDelete with
foreground-only highlights so they inherit the normal background.
2026-02-18 11:21:58 -05:00
fc03b940de
fix: format lua and highlight latex functions 2026-02-17 19:24:25 -05:00
130a1899c2 fix: recursion loading random issue 2026-02-10 13:44:36 -05:00
9ff64a7b89 misc highlight fixes 2026-02-05 00:39:22 -05:00
Barrett Ruth
b496f26e29
Merge pull request #23 from barrettruth/feat/treesitter-diff-highlights
feat: add treesitter highlights for diff files
2026-02-04 16:03:03 -05:00
f28ffed8d9 fix(ci): remove python 2026-02-04 16:01:25 -05:00
517837c9d3 feat: add treesitter highlights for diff files
Adds support for treesitter-based diff syntax highlighting:
- @diff.minus (red) and @diff.plus (green) for changed lines
- @attribute.diff (blue) for hunk headers
- @string.special.path and @variable.parameter linked to Normal
2026-02-04 15:58:07 -05:00
Barrett Ruth
c6bc4ed0db
Merge pull request #21 from barrettruth/fix/deprecation-warning
fix: add deprecation warning for setup()
2026-02-03 21:52:48 -05:00
94a373f416 fix: mark opts as intentionally unused
Some checks failed
Release / Publish to LuaRocks (push) Has been cancelled
2026-02-03 21:51:55 -05:00
2702caf352 fix: add deprecation warning for setup() 2026-02-03 21:46:43 -05:00
Barrett Ruth
79f3a3a18b
Merge pull request #20 from barrettruth/chore/add-issue-templates
chore: add issue templates
2026-02-03 21:11:09 -05:00
6559261ad5 chore: add issue templates 2026-02-03 21:07:02 -05:00
6b63011c1c format
Some checks failed
Release / Publish to LuaRocks (push) Has been cancelled
2026-02-03 20:51:56 -05:00
32c1f23f90 docs: update readme with luarocks installation 2026-02-03 20:48:46 -05:00
Barrett Ruth
d3bd65a484
Merge pull request #19 from barrettruth/refactor/remove-setup
refactor: remove unused setup function
2026-02-03 20:28:23 -05:00
270ba26bce refactor: remove unused setup function
Colorschemes load via :colorscheme command, making the setup() no-op redundant.
2026-02-03 20:12:17 -05:00
8b695453a8 remove superfluous background setting 2026-02-03 20:07:56 -05:00
b54045f31a fix: explicitly remove underline from cursor 2026-02-03 01:23:32 -05:00
2b32dda9f9 misc cleanups for diffing 2026-02-03 01:18:32 -05:00
733e04f48b feat(color): diff change 2026-02-02 15:31:46 -05:00
4e72648c2d fix: Diff* ought to hl bg 2026-02-02 00:42:11 -05:00
593ae1bc21 fix: username updated 2026-02-01 17:12:20 -05:00
95f377b8df feat: use accent color in diff text 2026-01-27 18:27:09 -05:00
f522ac7371 fix: typo 2026-01-27 18:25:58 -05:00
22 changed files with 355 additions and 153 deletions

78
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View file

@ -0,0 +1,78 @@
name: Bug Report
description: Report a bug
title: 'bug: '
labels: [bug]
body:
- type: checkboxes
attributes:
label: Prerequisites
options:
- label:
I have searched [existing
issues](https://github.com/barrettruth/midnight.nvim/issues)
required: true
- label: I have updated to the latest version
required: true
- type: textarea
attributes:
label: 'Neovim version'
description: 'Output of `nvim --version`'
render: text
validations:
required: true
- type: input
attributes:
label: 'Operating system'
placeholder: 'e.g. Arch Linux, macOS 15, Ubuntu 24.04'
validations:
required: true
- type: textarea
attributes:
label: Description
description: What happened? What did you expect?
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Minimal steps to trigger the bug
value: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: 'Health check'
description: 'Output of `:checkhealth midnight`'
render: text
- type: textarea
attributes:
label: Minimal reproduction
description: |
Save the script below as `repro.lua`, edit if needed, and run:
```
nvim -u repro.lua
```
Confirm the bug reproduces with this config before submitting.
render: lua
value: |
vim.env.LAZY_STDPATH = '.repro'
load(vim.fn.system('curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua'))()
require('lazy.nvim').setup({
spec = {
{
'barrett-ruth/midnight.nvim',
opts = {},
},
},
})
validations:
required: true

5
.github/ISSUE_TEMPLATE/config.yaml vendored Normal file
View file

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Questions
url: https://github.com/barrettruth/midnight.nvim/discussions
about: Ask questions and discuss ideas

View file

@ -0,0 +1,30 @@
name: Feature Request
description: Suggest a feature
title: 'feat: '
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Prerequisites
options:
- label:
I have searched [existing
issues](https://github.com/barrettruth/midnight.nvim/issues)
required: true
- type: textarea
attributes:
label: Problem
description: What problem does this solve?
validations:
required: true
- type: textarea
attributes:
label: Proposed solution
validations:
required: true
- type: textarea
attributes:
label: Alternatives considered

View file

@ -11,7 +11,6 @@ jobs:
runs-on: ubuntu-latest
outputs:
lua: ${{ steps.changes.outputs.lua }}
python: ${{ steps.changes.outputs.python }}
markdown: ${{ steps.changes.outputs.markdown }}
steps:
- uses: actions/checkout@v4
@ -25,10 +24,7 @@ jobs:
- '*.lua'
- '.luarc.json'
- '*.toml'
python:
- 'scripts/**/*.py'
- 'pyproject.toml'
- 'uv.lock'
- 'vim.yaml'
markdown:
- '*.md'
@ -39,11 +35,8 @@ jobs:
if: ${{ needs.changes.outputs.lua == 'true' }}
steps:
- uses: actions/checkout@v4
- uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: 2.1.0
args: --check .
- uses: cachix/install-nix-action@v31
- run: nix develop --command stylua --check .
lua-lint:
name: Lua Lint Check
@ -52,11 +45,8 @@ jobs:
if: ${{ needs.changes.outputs.lua == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Lint with Selene
uses: NTBBloodbath/selene-action@v1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --display-style quiet .
- uses: cachix/install-nix-action@v31
- run: nix develop --command selene --display-style quiet .
lua-typecheck:
name: Lua Type Check
@ -72,48 +62,6 @@ jobs:
directories: lua
configpath: .luarc.json
python-format:
name: Python Format Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.python == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install ruff
run: uv tool install ruff
- name: Check Python formatting with ruff
run: ruff format --check .
python-lint:
name: Python Lint Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.python == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install ruff
run: uv tool install ruff
- name: Lint Python files with ruff
run: ruff check .
python-typecheck:
name: Python Type Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.python == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install dependencies with mypy
run: uv sync --dev
- name: Type check Python files with mypy
run: uv run mypy .
markdown-format:
name: Markdown Format Check
runs-on: ubuntu-latest
@ -121,15 +69,5 @@ jobs:
if: ${{ needs.changes.outputs.markdown == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 8
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install prettier
run: pnpm add -g prettier@3.1.0
- name: Check markdown formatting with prettier
run: prettier --check .
- uses: cachix/install-nix-action@v31
- run: nix develop --command prettier --check .

3
.gitignore vendored
View file

@ -8,3 +8,6 @@ venv/
CLAUDE.md
__pycache__
node_modules/
.direnv/
.envrc

View file

@ -1,8 +1,9 @@
{
"runtime.version": "Lua 5.1",
"runtime.version": "LuaJIT",
"runtime.path": ["lua/?.lua", "lua/?/init.lua"],
"diagnostics.globals": ["vim"],
"workspace.library": ["$VIMRUNTIME/lua", "${3rd}/luv/library"],
"workspace.checkThirdParty": false,
"workspace.ignoreDir": [".direnv"],
"completion.callSnippet": "Replace"
}

View file

@ -9,26 +9,6 @@ repos:
files: \.lua$
pass_filenames: true
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.3
hooks:
- id: ruff-format
name: ruff (format)
files: \.py$
- id: ruff
name: ruff (lint imports)
args: ['--fix', '--select=I']
files: \.py$
- repo: local
hooks:
- id: mypy
name: mypy (type check)
entry: uv run mypy
language: system
args: ['.']
pass_filenames: false
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:

1
.styluaignore Normal file
View file

@ -0,0 +1 @@
.direnv/

View file

@ -1,24 +1,25 @@
# midnight.nvim
neovim theme for code, not colors.
Neovim theme for code, not colors.
![Image](https://github.com/user-attachments/assets/9abb5126-15d7-4de4-ad6d-ec35975fec03)
## Installation
Install with any package manager of your choice. For example, with
[lazy.nvim](https://github.com/folke/lazy.nvim):
Install using your package manager of choice or via
[luarocks](https://luarocks.org/modules/barrettruth/midnight.nvim):
```lua
{
'barrett-ruth/midnight.nvim',
config = function()
vim.cmd.colorscheme('midnight')
end,
}
```
luarocks install midnight.nvim
```
## Plugin Integration
Then set the colorscheme:
```lua
vim.cmd.colorscheme('midnight')
```
## Plugin Integrations
- [treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
- [fzf-lua](https://github.com/ibhagwan/fzf-lua)
@ -29,7 +30,7 @@ Install with any package manager of your choice. For example, with
## Motivation
I find existing colorschemes to generally be excessively colorful and
distracting, rather than informative. I wrote midnight.nvim to focus on code
distracting rather than informative. I wrote midnight.nvim to focus on code
structure, specifically for competitive programming and workplace software
development environments. I included highlighting of constants (e.g. strings,
numbers, booleans) and language keywords to emphasize the maximally important

View file

@ -1,2 +1 @@
vim.o.background = 'light'
require('midnight').load()

View file

@ -1,2 +1 @@
vim.o.background = 'dark'
require('midnight').load()

View file

@ -16,7 +16,7 @@ INSTALLATION *midnight-installation*
>lua
{
'barrett-ruth/midnight.nvim',
'barrettruth/midnight.nvim',
config = function()
vim.cmd.colorscheme('midnight')
end,

43
flake.lock generated Normal file
View file

@ -0,0 +1,43 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1771423170,
"narHash": "sha256-K7Dg9TQ0mOcAtWTO/FX/FaprtWQ8BmEXTpLIaNRhEwU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "bcc4a9d9533c033d806a46b37dc444f9b0da49dd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

33
flake.nix Normal file
View file

@ -0,0 +1,33 @@
{
description = "midnight.nvim a dark colorscheme for Neovim";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
systems.url = "github:nix-systems/default";
};
outputs =
{
nixpkgs,
systems,
...
}:
let
forEachSystem =
f: nixpkgs.lib.genAttrs (import systems) (system: f nixpkgs.legacyPackages.${system});
in
{
formatter = forEachSystem (pkgs: pkgs.nixfmt-tree);
devShells = forEachSystem (pkgs: {
default = pkgs.mkShell {
packages = [
pkgs.prettier
pkgs.stylua
pkgs.selene
pkgs.lua-language-server
];
};
});
};
}

View file

@ -1,16 +1,14 @@
local M = {}
---@class MidnightConfig
---@field [string] any
---@param opts? MidnightConfig
---@return nil
function M.setup(opts)
opts = opts or {}
end
local loading = false
---@return nil
function M.load()
if loading then
return
end
loading = true
if vim.g.colors_name then
vim.cmd('hi clear')
end
@ -24,6 +22,21 @@ function M.load()
local theme = require('midnight.theme')
theme.apply()
loading = false
end
---@deprecated Use `vim.cmd('colorscheme midnight')` instead
function M.setup(_opts)
vim.deprecate(
'require("midnight").setup()',
'vim.cmd("colorscheme midnight")',
'v0.1.0',
'midnight.nvim',
false
)
M.load()
end
return M

View file

@ -1,5 +1,22 @@
local M = {}
---@param hex string
---@param bg_hex string
---@param alpha number
---@return string
function M.blend(hex, bg_hex, alpha)
local function parse(h)
h = h:gsub('#', '')
return tonumber(h:sub(1, 2), 16), tonumber(h:sub(3, 4), 16), tonumber(h:sub(5, 6), 16)
end
local r, g, b = parse(hex)
local bg_r, bg_g, bg_b = parse(bg_hex)
local blend_r = math.floor(r * alpha + bg_r * (1 - alpha))
local blend_g = math.floor(g * alpha + bg_g * (1 - alpha))
local blend_b = math.floor(b * alpha + bg_b * (1 - alpha))
return string.format('#%02x%02x%02x', blend_r, blend_g, blend_b)
end
---@class Palette
---@field foreground string
---@field red string
@ -31,6 +48,9 @@ local M = {}
---@field light_cyan? string
---@field light_white? string
---@field medium_emphasis? string
---@field diff_add? string
---@field diff_delete? string
---@field diff_change? string
---@type Palette
M.midnight = {
@ -59,6 +79,15 @@ M.midnight = {
dark_grey = '#222222',
medium_emphasis = '#999999',
-- Diff backgrounds: base color blended at 40% with visual bg (#121212)
-- Generated via: M.blend(base_color, '#121212', 0.4)
-- diff_add = M.blend('#98c379', '#121212', 0.4) -- green
-- diff_delete = M.blend('#ff6b6b', '#121212', 0.4) -- red
-- diff_change = M.blend('#7aa2f7', '#121212', 0.4) -- blue
diff_add = '#0c2f1e',
diff_delete = '#291f27',
diff_change = '#3a4a6d',
}
---@type Palette
@ -88,6 +117,12 @@ M.daylight = {
dark_grey = '#ebebeb',
medium_emphasis = '#666666',
-- Diff backgrounds: base color blended at 40% with visual bg (#f5f5f5)
-- Generated via: M.blend(base_color, '#f5f5f5', 0.4)
diff_add = '#a5c5ab',
diff_delete = '#e2a1b2',
diff_change = '#a9b7e5',
}
---@return Palette

View file

@ -65,7 +65,7 @@ function M.apply()
hi('NonText', { fg = cs.grey }, { 'SpecialKey' })
hi('LineNr', { fg = cs.light_black }, { 'SignColumn' })
hi('CursorLine', { bg = cs.dark_grey }, { 'ColorColumn', 'Folded', 'Visual' })
hi('CursorLine', { bg = cs.dark_grey, underline = false }, { 'ColorColumn', 'Folded', 'Visual' })
hi('CursorLineNr', { fg = cs.medium_emphasis })
hi('Conceal', { fg = cs.light_black, bg = cs.foreground })
@ -121,9 +121,13 @@ function M.apply()
hi('@variable', { none = true })
hi('Pmenu', { bg = cs.dark_grey }, { 'PmenuSbar' })
hi('Pmenu', { fg = cs.background, bg = cs.foreground }, { 'PmenuSbar' })
hi('PmenuSel', { bg = cs.med_grey })
hi('PmenuThumb', { bg = cs.grey })
hi('BlinkCmpMenu', { fg = cs.background, bg = cs.foreground })
hi('BlinkCmpMenuBorder', { fg = cs.background, bg = cs.foreground })
hi('BlinkCmpDoc', { fg = cs.background, bg = cs.foreground })
hi('BlinkCmpDocBorder', { fg = cs.background, bg = cs.foreground })
hi('LspInlayHint', { fg = cs.light_black })
hi('LspSignatureActiveParameter', { underline = true, italic = true })
@ -145,18 +149,32 @@ function M.apply()
hi('gitCommitSummary', { fg = cs.background })
hi('@attribute.diff', { fg = cs.background })
hi('DiffAdd', { fg = cs.green }, { '@text.diff.add', 'diffAdded' })
hi('DiffDelete', { fg = cs.red }, { '@text.diff.delete', 'diffRemoved' })
hi('DiffChange', { fg = cs.yellow })
hi('@attribute.diff', { fg = cs.blue })
hi('@diff.minus', { fg = cs.red })
hi('@diff.plus', { fg = cs.green })
hi('@diff.delta', { fg = cs.blue })
hi('@punctuation.special.diff', { fg = cs.blue })
link('Normal', { '@string.special.path', '@variable.parameter' })
hi('DiffAdd', { bg = cs.diff_add, fg = cs.green }, { '@text.diff.add', 'diffAdded' })
hi('DiffDelete', { bg = cs.diff_delete, fg = cs.red }, { '@text.diff.delete', 'diffRemoved' })
hi('DiffChange', { bg = cs.diff_change, fg = cs.blue })
hi('DiffText', { bg = cs.blue, fg = cs.foreground })
hi('DiffsDiffAdd', { bg = cs.diff_add })
hi('DiffsDiffDelete', { bg = cs.diff_delete })
hi('DiffsDiffChange', { bg = cs.diff_change })
hi('DiffsDiffText', { bg = cs.blue })
hi('@constructor.lua', { fg = cs.background })
hi('@markup.heading.gitcommit', { none = true })
hi('@function.latex', { fg = cs.blue })
hi('GitSignsCurrentLineBlame', { italic = true, fg = cs.light_black })
link('DiffAdd', 'GitSignsAdd')
link('DiffChange', 'GitSignsChange')
link('DiffDelete', 'GitSignsDelete')
hi('GitSignsAdd', { fg = cs.green })
hi('GitSignsChange', { fg = cs.blue })
hi('GitSignsDelete', { fg = cs.red })
link('Search', 'HighlightUndo')
@ -165,6 +183,23 @@ function M.apply()
hi('CmpItemAbbr', { fg = cs.background })
hi('CmpItemAbbrMatch', { fg = cs.background, bold = true })
hi('CmpItemAbbrMatchFuzzy', { fg = cs.background, bold = true })
hi('BlinkCmpLabelMatch', { fg = cs.green })
hi('BlinkCmpGhostText', { fg = cs.light_black })
hi('BlinkCmpGitKindMR', { fg = cs.magenta })
hi('BlinkCmpGitKindPR', { fg = cs.magenta })
hi('BlinkCmpGitKindIssue', { fg = cs.magenta })
hi('BlinkCmpGitKindCommit', { fg = cs.magenta })
hi('BlinkCmpGitKindMention', { fg = cs.magenta })
hi('BlinkCmpGitKindIconMR', { fg = cs.magenta })
hi('BlinkCmpGitKindIconPR', { fg = cs.magenta })
hi('BlinkCmpGitKindIconIssue', { fg = cs.magenta })
hi('BlinkCmpGitKindIconCommit', { fg = cs.magenta })
hi('BlinkCmpGitKindIconMention', { fg = cs.magenta })
hi('BlinkCmpGitLabelMRId', { fg = cs.magenta })
hi('BlinkCmpGitLabelPRId', { fg = cs.magenta })
hi('BlinkCmpGitLabelIssueId', { fg = cs.magenta })
hi('BlinkCmpGitLabelCommitId', { fg = cs.magenta })
hi('BlinkCmpGitLabelMentionId', { fg = cs.magenta })
hi('CmpItemAbbrDeprecated', { fg = cs.light_black, strikethrough = true })
hi('CmpItemMenu', { fg = cs.light_black })

View file

@ -2,5 +2,5 @@ rockspec_format = '3.0'
package = 'midnight.nvim'
version = 'scm-1'
source = { url = 'git://github.com/barrett-ruth/midnight.nvim' }
source = { url = 'git://github.com/barrettruth/midnight.nvim' }
build = { type = 'builtin' }

9
scripts/ci.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
set -eu
nix develop --command stylua --check .
git ls-files '*.lua' | xargs nix develop --command selene --display-style quiet
nix develop --command prettier --check .
nix fmt
git diff --exit-code -- '*.nix'
nix develop --command lua-language-server --check . --checklevel=Warning

View file

@ -1 +1,4 @@
std = 'vim'
[lints]
bad_string_escape = 'allow'

View file

@ -1,30 +0,0 @@
[selene]
base = "lua51"
name = "vim"
[vim]
any = true
[jit]
any = true
[assert]
any = true
[describe]
any = true
[it]
any = true
[before_each]
any = true
[after_each]
any = true
[spy]
any = true
[stub]
any = true

26
vim.yaml Normal file
View file

@ -0,0 +1,26 @@
---
base: lua51
name: vim
lua_versions:
- luajit
globals:
vim:
any: true
jit:
any: true
assert:
any: true
describe:
any: true
it:
any: true
before_each:
any: true
after_each:
any: true
spy:
any: true
stub:
any: true
bit:
any: true