Skip to content
Merged
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ Why fluo? Because it's simply cool!

![flow-multiple-terminal](https://github.com/user-attachments/assets/9d1f367a-7a9d-478d-9fe0-a67bd33eca1a)

## Variants

Flow colorscheme family offers two variants:

- `default`: is the original version of the colorscheme providing a wide range of colors.
This variant is recommended for people that likes selected colors for every semantic syntax in the UI.

- `mono`: the mono variant desaturates all syntax colors to metallic grey shades with a cool blue
hue, while mapping keywords and operators to the selected fluo accent color. Diagnostics also use
fluo shades. This variant is recommended for people that want a super focusing environment where
the accent color draws attention to what matters most.

To variant can be selected by loading the colorscheme with the specific name:

```lua
vim.cmd("colorscheme flow")
```

Or:

```lua
vim.cmd("colorscheme flow-mono")
```

## Palette

Flow uses a palette of nine HSL-based colors, chosen to create a cohesive and visually appealing
Expand Down Expand Up @@ -92,7 +116,7 @@ return {
},
},
ui = {
borders = "inverse", -- "theme" | "inverse" | "fluo" | "none"
borders = "none", -- "light" | "dark" | "none"
aggressive_spell = false, -- true | false
},
},
Expand Down
1 change: 1 addition & 0 deletions colors/flow-mono.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require("flow").load("mono")
2 changes: 1 addition & 1 deletion colors/flow.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
require("flow").load()
require("flow").load("classic")
30 changes: 29 additions & 1 deletion doc/flow.nvim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Table of Contents *flow.nvim-table-of-contents*

1. 🌊 Flow |flow.nvim-🌊-flow|
- Showcase |flow.nvim-🌊-flow-showcase|
- Variants |flow.nvim-🌊-flow-variants|
- Palette |flow.nvim-🌊-flow-palette|
- Requirements |flow.nvim-🌊-flow-requirements|
- Installation |flow.nvim-🌊-flow-installation|
Expand All @@ -31,6 +32,33 @@ Why fluo? Because it’s simply cool!
SHOWCASE *flow.nvim-🌊-flow-showcase*


VARIANTS *flow.nvim-🌊-flow-variants*

Flow colorscheme family offers two variants:

- `default`: is the original version of the colorscheme providing a wide range
of colors. This variant is recommended for people that likes selected colors
for every semantic syntax in the UI.

- `mono`: the mono variant desaturates all syntax colors to metallic grey shades
with a cool blue hue, while mapping keywords and operators to the selected
fluo accent color. Diagnostics also use fluo shades. This variant is
recommended for people that want a super focusing environment where the
accent color draws attention to what matters most.

The variant can be selected by loading the colorscheme with the specific name:

>lua
vim.cmd("colorscheme flow")
<

Or:

>lua
vim.cmd("colorscheme flow-mono")
<


PALETTE *flow.nvim-🌊-flow-palette*

Flow uses a palette of nine HSL-based colors, chosen to create a cohesive and
Expand Down Expand Up @@ -114,7 +142,7 @@ DEFAULT ~
},
},
ui = {
borders = "inverse", -- "theme" | "inverse" | "fluo" | "none"
borders = "none", -- "light" | "dark" | "none"
aggressive_spell = false, -- true | false
},
},
Expand Down
122 changes: 83 additions & 39 deletions lua/flow/colors.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
local M = {}

M.colors = nil

M._color_names =
{ "orange", "yellow", "red", "purple", "blue", "light_blue", "sky_blue", "cyan", "green" }
local palette = require("flow.palette")

local M = {
--- Names of the colors used in the colorscheme.
names = {
"blue",
"cyan",
"green",
"light_blue",
"orange",
"purple",
"red",
"sky_blue",
"yellow",
},

colors = nil,
}

--- Setup the colorscheme colors based on the options and palette.
--- @param opts FlowConfig: The options to setup the colorscheme.
--- @return table: The colors used by the colorscheme.
function M.setup(opts)
local default_palette = require("flow.palette").get(opts or {})
--- @param config FlowConfig The configuration options to setup the colorscheme.
--- @return table The colors used by the colorscheme.
function M.setup(config)
config = config or {}

opts = opts or {}
local default_palette = palette.get(config)

-- Get the configured fluo color (with fallback to default)
local fluo_color = (opts.colors and opts.colors.fluo) or "pink"
local fluo_color = (config.colors and config.colors.fluo) or "pink"

local colors = {
-- Core colors
-- Core colors.
transparent = default_palette.transparent,
black = default_palette.black,
white = default_palette.white,
Expand All @@ -32,20 +44,25 @@ function M.setup(opts)
to_check = default_palette.fluo.green.default,
}

M._apply_opts(default_palette, colors, opts)
M._apply_opts(default_palette, colors, config)

for _, key in ipairs(M._color_names) do
for _, key in ipairs(M.names) do
-- Set the specific mode of the colors.
colors[key] = default_palette[key][opts.colors.mode]
colors[key] = default_palette[key][config.colors.mode]
-- Store all the color variations. These variables are used for hi that
-- requires contrasts with the current theme, like git.
-- require contrasts with the current theme, like git.
local Key = key:gsub("^%l", string.upper)
colors[Key] = default_palette[key]
end

-- Yellow is perceptually too light for light backgrounds, use the dark shade instead.
if config.theme.style ~= "dark" then
colors.yellow = colors.Yellow.dark
end

-- Comments - use lighter grey for light theme
colors.comment = opts.theme.style == "dark" and colors.grey[7] -- Dark theme: 50% lightness
or colors.grey[4] -- Light theme: inverts to 65% lightness (less dark)
colors.comment = config.theme.style == "dark" and colors.grey[7] -- Dark theme: 50% lightness
or colors.grey[6] -- Light theme: darker grey for readability against light background

-- +----------------------------------------------------------------------------------------+
-- | Sidebar (e.g., NERDTree, Telescope, Quickfix) | <- Sidebar
Expand Down Expand Up @@ -74,16 +91,29 @@ function M.setup(opts)
colors.fg_sidebar = default_palette.grey[8]
colors.bg_sidebar = colors.bg

local is_transparent = opts.theme.transparent == true
local is_transparent = config.theme.transparent == true

-- Gutter: used for line numbers, signs, and fold column.
colors.fg_gutter = colors.grey[5]
colors.bg_gutter = (is_transparent and default_palette.transparent) or colors.bg

--
-- -- CursorLine background.
--
-- -- Visual selection background.
-- visual_bg = {
-- dark = hsl_to_hex(fluo_hue_value, 90, 23), -- For dark theme
-- light = hsl_to_hex(fluo_hue_value, 90, 77), -- For light theme
-- },
--

-- -- Float window colors.
-- float_bg = {
-- dark = hsl_to_hex(203, 20, 18), -- For dark theme
-- light = hsl_to_hex(203, 20, 82), -- For light theme
-- },
-- Float: used for visual elements that are floating and triggered by the user.
colors.fg_float = colors.grey[8]
colors.bg_float = opts.theme.style == "dark" and default_palette.float_bg.dark
or default_palette.float_bg.light
colors.bg_float = default_palette.grey[2]

-- Popups: use for completion menu and all visual components that appears autonomously.
colors.fg_popup = default_palette.grey[9]
Expand All @@ -97,9 +127,12 @@ function M.setup(opts)
colors.fg_highlight = colors.grey[6]
colors.bg_highlight = colors.grey[2]

-- visual_bg = {
-- dark = hsl_to_hex(fluo_hue_value, 90, 23), -- For dark theme
-- light = hsl_to_hex(fluo_hue_value, 90, 77), -- For light theme
-- },
-- Visual - uses configured fluo color
colors.bg_visual = opts.theme.style == "dark" and default_palette.visual_bg.dark
or default_palette.visual_bg.light
colors.bg_visual = config.theme.style == "dark" and colors.Fluo.dark or colors.Fluo.light
colors.fg_visual = colors.grey[2]

-- Git
Expand All @@ -111,7 +144,7 @@ function M.setup(opts)
untracked = colors.sky_blue, -- New untracked files
}

local is_dark = opts.theme.style == "dark"
local is_dark = config.theme.style == "dark"
colors.diff = {
add = not is_dark and colors.Green.very_light or colors.Green.very_dark,
delete = not is_dark and colors.Red.very_light or colors.Red.very_dark,
Expand All @@ -132,6 +165,11 @@ function M.setup(opts)
colors.fixme = is_dark and colors.Red.default or colors.Red.dark -- FIXME comments
colors.hack = is_dark and colors.Yellow.default or colors.Yellow.dark -- HACK comments

-- Apply monochrome transformation if enabled
if config.variant == "mono" then
require("flow.mono").apply(colors, config)
end

M.colors = colors

return colors
Expand All @@ -154,43 +192,49 @@ function M._swap(t, a, b)
t[a], t[b] = t[b], t[a]
end

--- @param opts FlowConfig
function M._apply_opts(default_palette, colors, opts)
if opts.colors.fluo then
colors.fluo = default_palette.fluo[opts.colors.fluo].default
colors.Fluo = default_palette.fluo[opts.colors.fluo]
--- @param default_palette table
--- @param colors table
--- @param config FlowConfig
function M._apply_opts(default_palette, colors, config)
if config.colors.fluo then
colors.fluo = default_palette.fluo[config.colors.fluo].default
colors.Fluo = default_palette.fluo[config.colors.fluo]
end

-- Apply changes if the theme is not dark.
-- HACK: this has to be executed before all changes that involves white, black, and grey.
if opts.theme.style ~= "dark" then
if config.theme.style ~= "dark" then
M._invert_colors_for_theme(colors)
end

-- If high contrast the darkest color is swap for the next color and the
-- lightest color is swap for the color before.
if opts.theme.contrast == "high" then
if config.theme.contrast == "high" then
M._invert_colors_for_contrast(colors)
end

colors.bg = (opts.theme.transparent and default_palette.transparent) or default_palette.grey[3] -- used for theme background
colors.fg = (opts.theme.style == "dark" and colors.grey[8]) or colors.grey[8]
colors.bg = (config.theme.transparent and default_palette.transparent) or default_palette.grey[3] -- used for theme background
colors.fg = (config.theme.style == "dark" and colors.grey[8]) or colors.grey[8]

-- Borders
if opts.ui.borders == "none" then
if config.ui.borders == "none" then
colors.fg_border = colors.bg -- Match background to make borders invisible
colors.fg_vsplit = colors.grey[2]
elseif opts.ui.borders == "light" then
elseif config.ui.borders == "light" then
colors.fg_border = colors.grey[4]
colors.fg_vsplit = colors.grey[4]
else -- dark (default)
colors.fg_border = colors.grey[1]
colors.fg_vsplit = colors.grey[1]
end

-- cursorline_bg = {
-- dark = hsl_to_hex(fluo_hue_value, 20, 13), -- For dark theme
-- light = hsl_to_hex(fluo_hue_value, 20, 87), -- For light theme
-- },
-- CursorLine background - uses configured fluo color
colors.bg_cursorline = opts.theme.style == "dark" and default_palette.cursorline_bg.dark
or default_palette.cursorline_bg.light
colors.bg_cursorline = config.theme.style == "dark" and colors.Fluo.very_dark
or colors.Fluo.very_light

-- NOTE bg_border is currently not used.
colors.bg_border = colors.grey[7]
Expand Down
Loading