forked from nvim-lualine/lualine.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcosmicink.lua
More file actions
613 lines (555 loc) · 15.9 KB
/
cosmicink.lua
File metadata and controls
613 lines (555 loc) · 15.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
-- CosmicInk config for lualine
-- Author: Yeeloman
-- MIT license, see LICENSE for more details.
-- Main configuration for setting up lualine.nvim statusline plugin
-- Default Theme Colors: Define a set of base colors for your theme
local colors = {
BG = '#16181b', -- Dark background
FG = '#c5c4c4', -- Light foreground for contrast
YELLOW = '#e8b75f', -- Vibrant yellow
CYAN = '#00bcd4', -- Soft cyan
DARKBLUE = '#2b3e50', -- Deep blue
GREEN = '#00e676', -- Bright green
ORANGE = '#ff7733', -- Warm orange
VIOLET = '#7a3ba8', -- Strong violet
MAGENTA = '#d360aa', -- Deep magenta
BLUE = '#4f9cff', -- Light-medium blue
RED = '#ff3344', -- Strong red
}
-- Function to get the color associated with the current mode in Vim
local function get_mode_color()
-- Define a table mapping modes to their associated colors
local mode_color = {
n = colors.DARKBLUE,
i = colors.VIOLET,
v = colors.RED,
[''] = colors.BLUE,
V = colors.RED,
c = colors.MAGENTA,
no = colors.RED,
s = colors.ORANGE,
S = colors.ORANGE,
[''] = colors.ORANGE,
ic = colors.YELLOW,
R = colors.ORANGE,
Rv = colors.ORANGE,
cv = colors.RED,
ce = colors.RED,
r = colors.CYAN,
rm = colors.CYAN,
['r?'] = colors.CYAN,
['!'] = colors.RED,
t = colors.RED,
}
-- Return the opposite color, or fallback to foreground color
return mode_color[vim.fn.mode()]
end
-- Function to get the opposite color of a given mode color
local function get_opposite_color(mode_color)
-- Define a table mapping colors to their opposite color
local opposite_colors = {
[colors.RED] = colors.CYAN,
[colors.BLUE] = colors.ORANGE,
[colors.GREEN] = colors.MAGENTA,
[colors.MAGENTA] = colors.DARKBLUE,
[colors.ORANGE] = colors.BLUE,
[colors.CYAN] = colors.YELLOW,
[colors.VIOLET] = colors.GREEN,
[colors.YELLOW] = colors.RED,
[colors.DARKBLUE] = colors.VIOLET,
}
-- Return the opposite color, or fallback to foreground color
return opposite_colors[mode_color] or colors.FG
end
-- Function to get an animated color (randomly chosen from available colors)
local function get_animated_color(mode_color)
-- Define a list of all available colors
local all_colors = {
colors.RED,
colors.BLUE,
colors.GREEN,
colors.MAGENTA,
colors.ORANGE,
colors.CYAN,
colors.VIOLET,
colors.YELLOW,
colors.DARKBLUE,
}
-- Create a list of possible opposite colors (excluding the current mode color)
local possible_opposites = {}
for _, color in ipairs(all_colors) do
if color ~= mode_color then
table.insert(possible_opposites, color)
end
end
-- Randomly select an opposite color
if #possible_opposites > 0 then
local random_index = math.random(1, #possible_opposites)
return possible_opposites[random_index]
else
return colors.FG -- Default to foreground color if no opposite found
end
end
-- Function to interpolate between two colors for a smooth transition
local function interpolate_color(color1, color2, step)
-- Blend two colors based on the given step factor (0.0 -> color1, 1.0 -> color2)
local blend = function(c1, c2, stp)
return math.floor(c1 + (c2 - c1) * stp)
end
-- Extract the RGB values of both colors (in hex)
local r1, g1, b1 = tonumber(color1:sub(2, 3), 16), tonumber(color1:sub(4, 5), 16), tonumber(color1:sub(6, 7), 16)
local r2, g2, b2 = tonumber(color2:sub(2, 3), 16), tonumber(color2:sub(4, 5), 16), tonumber(color2:sub(6, 7), 16)
-- Calculate the new RGB values for the blended color
local r = blend(r1, r2, step)
local g = blend(g1, g2, step)
local b = blend(b1, b2, step)
-- Return the blended color in hex format
return string.format('#%02X%02X%02X', r, g, b)
end
-- Function to get a middle color by interpolating between mode color and its opposite
local function get_middle_color(color_step)
-- Set default value for color_step if not provided
color_step = color_step or 0.5 -- If color_step is nil, default to 0.5
local color1 = get_mode_color() -- Get the current mode color
local color2 = get_opposite_color(color1) -- Get the opposite color
-- Return an interpolated color between the two (based on the color_step value)
return interpolate_color(color1, color2, color_step)
end
-- Condition: Check if the buffer is not empty
-- This checks whether the current file's name is non-empty.
-- If the file is open (i.e., has a name), it returns true, meaning the buffer is not empty.
-- local function buffer_not_empty()
-- return vim.fn.empty(vim.fn.expand('%:t')) ~= 1 -- 'expand('%:t')' gets the file name
-- end
-- Condition: Hide in width (only show the statusline when the window width is greater than 80)
-- This ensures that the statusline will only appear if the current window width exceeds 80 characters.
local function hide_in_width()
return vim.fn.winwidth(0) > 80 -- 'winwidth(0)' returns the current window width
end
-- Condition: Check if the current workspace is inside a Git repository
-- This function checks if the current file is inside a Git repository by looking for a `.git` directory
-- in the current file's path. Returns true if the file is in a Git workspace.
-- local function check_git_workspace()
-- local filepath = vim.fn.expand('%:p:h') -- Get the current file's directory
-- local gitdir = vim.fn.finddir('.git', filepath .. ';') -- Search for a `.git` directory in the file path
-- return gitdir and #gitdir > 0 and #gitdir < #filepath -- Returns true if a `.git` directory is found
-- end
-- -- Set random seed based on current time for randomness
math.randomseed(os.time())
-- Icon sets for random selection
local icon_sets = {
stars = { '★', '☆', '✧', '✦', '✶', '✷', '✸', '✹' }, -- Set of star-like icons
runes = {
'✠',
'⛧',
'𖤐',
'ᛟ',
'ᚨ',
'ᚱ',
'ᚷ',
'ᚠ',
'ᛉ',
'ᛊ',
'ᛏ',
'☠',
'☾',
'♰',
'✟',
'☽',
'⚚',
'🜏',
}, -- Set of rune-like symbols
hearts = { '❤', '♥', '♡', '❦', '❧' }, -- Set of heart-shaped icons
waves = { '≈', '∿', '≋', '≀', '⌀', '≣', '⌇' }, -- Set of wave-like symbols
crosses = { '☨', '✟', '♰', '♱', '⛨', '' }, -- Set of cross-like symbols
}
-- Function to select a random icon from a given set
local function get_random_icon(icons)
return icons[math.random(#icons)] -- Returns a random icon from the set
end
-- Function to shuffle the elements in a table
local function shuffle_table(tbl)
local n = #tbl
while n > 1 do
local k = math.random(n)
tbl[n], tbl[k] = tbl[k], tbl[n] -- Swap elements
n = n - 1 -- Decrease the size of the unsorted portion
end
end
-- Create a list of all icon sets to allow for random selection from any set
local icon_sets_list = {}
for _, icons in pairs(icon_sets) do
table.insert(icon_sets_list, icons) -- Add each icon set to the list
end
shuffle_table(icon_sets_list) -- Shuffle the icon sets list
-- Function to reverse the order of elements in a table
local function reverse_table(tbl)
local reversed = {}
for i = #tbl, 1, -1 do
table.insert(reversed, tbl[i]) -- Insert elements in reverse order
end
return reversed
end
-- Create a reversed list of icon sets
local reversed_icon_sets = reverse_table(icon_sets_list)
-- Function to create a separator component based on side (left/right) and optional mode color
local function create_separator(side, use_mode_color)
return {
function()
return side == 'left' and '' or '' -- Choose separator symbol based on side
end,
color = function()
-- Set color based on mode or opposite color
local color = use_mode_color and get_mode_color() or get_opposite_color(get_mode_color())
return {
fg = color,
}
end,
padding = {
left = 0,
},
}
end
-- Function to create a mode-based component (e.g., statusline)
-- with optional content, icon, and colors
local function create_mode_based_component(content, icon, color_fg, color_bg)
return {
content,
icon = icon,
color = function()
local mode_color = get_mode_color()
local opposite_color = get_opposite_color(mode_color)
return {
fg = color_fg or colors.FG,
bg = color_bg or opposite_color,
gui = 'bold',
}
end,
}
end
-- -- Function to get the current mode indicator as a single character
local function mode()
-- Map of modes to their respective shorthand indicators
local mode_map = {
n = 'N', -- Normal mode
i = 'I', -- Insert mode
v = 'V', -- Visual mode
[''] = 'V', -- Visual block mode
V = 'V', -- Visual line mode
c = 'C', -- Command-line mode
no = 'N', -- NInsert mode
s = 'S', -- Select mode
S = 'S', -- Select line mode
ic = 'I', -- Insert mode (completion)
R = 'R', -- Replace mode
Rv = 'R', -- Virtual Replace mode
cv = 'C', -- Command-line mode
ce = 'C', -- Ex mode
r = 'R', -- Prompt mode
rm = 'M', -- More mode
['r?'] = '?', -- Confirm mode
['!'] = '!', -- Shell mode
t = 'T', -- Terminal mode
}
-- Return the mode shorthand or [UNKNOWN] if no match
return mode_map[vim.fn.mode()] or '[UNKNOWN]'
end
-- Config
local config = {
options = {
component_separators = '',
section_separators = '',
theme = {
normal = {
c = {
fg = colors.FG,
bg = colors.BG,
},
},
inactive = {
c = {
fg = colors.FG,
bg = colors.BG,
},
}, -- Simplified inactive theme
},
disabled_filetypes = {
'neo-tree',
'undotree',
'sagaoutline',
'diff',
},
},
sections = {
lualine_a = {},
lualine_b = {},
lualine_c = {},
lualine_x = {},
lualine_y = {},
lualine_z = {},
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = {
{
'location',
color = function()
return {
fg = colors.FG,
gui = 'bold',
}
end,
},
},
lualine_x = {
{
'filename',
color = function()
return {
fg = colors.FG,
gui = 'bold,italic',
}
end,
},
},
lualine_y = {},
lualine_z = {},
},
}
-- Helper functions
local function ins_left(component)
table.insert(config.sections.lualine_c, component)
end
local function ins_right(component)
table.insert(config.sections.lualine_x, component)
end
-- LEFT
ins_left {
mode,
color = function()
local mode_color = get_mode_color()
return {
fg = colors.BG,
bg = mode_color,
gui = 'bold',
}
end,
padding = { left = 1, right = 1 },
}
ins_left(create_separator('left', true))
ins_left {
function()
return vim.fn.fnamemodify(vim.fn.getcwd(), ':t')
end,
icon = ' ',
color = function()
local virtual_env = vim.env.VIRTUAL_ENV
if virtual_env then
return {
fg = get_mode_color(),
gui = 'bold,strikethrough',
}
else
return {
fg = get_mode_color(),
gui = 'bold',
}
end
end,
}
ins_left(create_separator('right'))
ins_left(create_mode_based_component('filename', nil, colors.BG))
ins_left(create_separator('left'))
ins_left {
function()
return ''
end,
color = function()
return {
fg = get_middle_color(),
}
end,
cond = hide_in_width,
}
ins_left {
function()
local git_status = vim.b.gitsigns_status_dict
if git_status then
return string.format('+%d ~%d -%d', git_status.added or 0, git_status.changed or 0, git_status.removed or 0)
end
return ''
end,
-- icon = ' ',
color = {
fg = colors.YELLOW,
gui = 'bold',
},
cond = hide_in_width,
}
for _, icons in pairs(icon_sets_list) do
ins_left {
function()
return get_random_icon(icons)
end,
color = function()
return {
fg = get_animated_color(),
}
end,
cond = hide_in_width,
}
end
ins_left {
'searchcount',
color = {
fg = colors.GREEN,
gui = 'bold',
},
}
-- RIGHT
ins_right {
function()
local reg = vim.fn.reg_recording()
return reg ~= '' and '[' .. reg .. ']' or ''
end,
color = {
fg = '#ff3344',
gui = 'bold',
},
cond = function()
return vim.fn.reg_recording() ~= ''
end,
}
ins_right {
'selectioncount',
color = {
fg = colors.GREEN,
gui = 'bold',
},
}
for _, icons in ipairs(reversed_icon_sets) do
ins_right {
function()
return get_random_icon(icons)
end,
color = function()
return {
fg = get_animated_color(),
}
end,
cond = hide_in_width,
}
end
ins_right {
function()
local msg = 'No Active Lsp'
local buf_ft = vim.api.nvim_buf_get_option(0, 'filetype')
local clients = vim.lsp.get_clients()
if next(clients) == nil then
return msg
end
local lsp_short_names = {
pyright = 'py',
tsserver = 'ts',
rust_analyzer = 'rs',
lua_ls = 'lua',
clangd = 'c++',
bashls = 'sh',
jsonls = 'json',
html = 'html',
cssls = 'css',
tailwindcss = 'tw',
dockerls = 'docker',
sqlls = 'sql',
yamlls = 'yml',
}
for _, client in ipairs(clients) do
local filetypes = client.config.filetypes
if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then
return lsp_short_names[client.name] or client.name:sub(1, 2)
end
end
return msg
end,
icon = ' ',
color = {
fg = colors.YELLOW,
gui = 'bold',
},
}
ins_right {
function()
return ''
end,
color = function()
return { fg = get_middle_color() }
end,
cond = hide_in_width,
}
ins_right(create_separator('right'))
ins_right(create_mode_based_component('location', nil, colors.BG))
ins_right(create_separator('left'))
ins_right {
'branch',
icon = ' ',
--[[ Truncates and formats Git branch names for display in lualine:
First segment: Uppercase, truncated to 1 character.
Middle segments: Lowercase, truncated to 1 character.
Last segment: Unchanged.
Separator: › between truncated segments and the last segment.
Example Input/Output:
Branch Name Output
backend/setup/tailwind Bs›tailwind
feature/add-ui Fa›add-ui
main main
]]
fmt = function(branch)
if branch == '' or branch == nil then
return 'No Repo'
end
-- Function to truncate a segment to a specified length
local function truncate_segment(segment, max_length)
if #segment > max_length then
return segment:sub(1, max_length)
end
return segment
end
-- Split the branch name by '/'
local segments = {}
for segment in branch:gmatch('[^/]+') do
table.insert(segments, segment)
end
-- Truncate all segments except the last one
for i = 1, #segments - 1 do
segments[i] = truncate_segment(segments[i], 1) -- Truncate to 1 character
end
-- If there's only one segment (no '/'), return it as-is
if #segments == 1 then
return segments[1]
end
-- Capitalize the first segment and lowercase the rest (except the last one)
segments[1] = segments[1]:upper() -- First segment uppercase
for i = 2, #segments - 1 do
segments[i] = segments[i]:lower() -- Other segments lowercase
end
-- Combine the first segments with no separator and add '›' before the last segment
local truncated_branch = table.concat(segments, '', 1, #segments - 1) .. '›' .. segments[#segments]
-- Ensure the final result doesn't exceed a maximum length
local max_total_length = 15
if #truncated_branch > max_total_length then
truncated_branch = truncated_branch:sub(1, max_total_length) .. '…'
end
return truncated_branch
end,
color = function()
local mode_color = get_mode_color()
return {
fg = mode_color,
gui = 'bold',
}
end,
}
ins_right(create_separator('right'))
ins_right(create_mode_based_component('progress', nil, colors.BG))
require('lualine').setup(config)