xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit 7a9d78d7ce119d8f3b5dbb8e540b779df03b519d

Add vifm.color.{count,gui,new()}
vifm.color.count - number of available colors
vifm.color.gui - whether GUI colors are in use
vifm.color.new() - creates a color description
Author: xaizek
Author date (UTC): 2026-06-05 22:35
Committer name: xaizek
Committer date (UTC): 2026-06-06 10:00
Parent(s): 07a8364f00bfb003da4bc05910212fdd881724d0
Signing key: 99DC5E4DB05F6BE2
Tree: 3efb4c2526aaa94777a4746288d540fa9f712266
File Lines added Lines deleted
ChangeLog.LuaAPI 4 0
HACKING.md 1 0
data/vim/doc/app/vifm-lua.txt 55 1
src/Makefile.am 1 0
src/Makefile.in 51 43
src/Makefile.win 5 4
src/lua/vifm.c 5 0
src/lua/vifm_color.c 228 0
src/lua/vifm_color.h 6 6
src/tags.c 5 0
tests/lua/api_color.c 124 0
File ChangeLog.LuaAPI changed (mode: 100644) (index 1d672c160..4e6f5502a)
... ... documented in the regular ChangeLog.
15 15 Added vifm.redraw() which requests a UI redraw. Thanks to Steven Added vifm.redraw() which requests a UI redraw. Thanks to Steven
16 16 Xu (stevenxxiu). Xu (stevenxxiu).
17 17
18 Added vifm.color with vifm.color.count (number of available colors),
19 vifm.color.gui (whether GUI colors are in use) and
20 vifm.color.new() (creates a color description).
21
18 22 Added "specs" field to vifm.menus.loadcustom() which allows specifying Added "specs" field to vifm.menus.loadcustom() which allows specifying
19 23 targets for navigation menus independently of whether and how they appear targets for navigation menus independently of whether and how they appear
20 24 in the menu. in the menu.
File HACKING.md changed (mode: 100644) (index bcfc383f9..20f6e79e1)
... ... of changes of each kind.
142 142 | | |-- vifm.c - implementation of `vifm` | | |-- vifm.c - implementation of `vifm`
143 143 | | |-- vifm_abbrevs.c - implementation of `vifm.abbrevs` | | |-- vifm_abbrevs.c - implementation of `vifm.abbrevs`
144 144 | | |-- vifm_cmds.c - implementation of `vifm.cmds` | | |-- vifm_cmds.c - implementation of `vifm.cmds`
145 | | |-- vifm_color.c - implementation of `vifm.color`
145 146 | | |-- vifm_events.c - implementation of `vifm.events` | | |-- vifm_events.c - implementation of `vifm.events`
146 147 | | |-- vifm_handlers.c - implementation of `vifm.addhandler` | | |-- vifm_handlers.c - implementation of `vifm.addhandler`
147 148 | | |-- vifm_tabs.c - implementation of `vifm.tabs` | | |-- vifm_tabs.c - implementation of `vifm.tabs`
File data/vim/doc/app/vifm-lua.txt changed (mode: 100644) (index bc3582181..e48bdf7f7)
1 *vifm-lua.txt* For Vifm version 1.0 Last change: 2026 June 3
1 *vifm-lua.txt* For Vifm version 1.0 Last change: 2026 June 6
2 2
3 3 Email for bugs and suggestions: <xaizek@posteo.net> Email for bugs and suggestions: <xaizek@posteo.net>
4 4
 
... ... Current API version: v0.2.0
21 21 |vifm-l_vifm| `vifm` global table. |vifm-l_vifm| `vifm` global table.
22 22 |vifm-l_vifm.abbrevs| `vifm.abbrevs` global table. |vifm-l_vifm.abbrevs| `vifm.abbrevs` global table.
23 23 |vifm-l_vifm.cmds| `vifm.cmds` global table. |vifm-l_vifm.cmds| `vifm.cmds` global table.
24 |vifm-l_vifm.color| `vifm.color` global table.
24 25 |vifm-l_vifm.events| `vifm.events` global table. |vifm-l_vifm.events| `vifm.events` global table.
25 26 |vifm-l_vifm.fs| `vifm.fs` global table. |vifm-l_vifm.fs| `vifm.fs` global table.
26 27 |vifm-l_vifm.keys| `vifm.keys` global table. |vifm-l_vifm.keys| `vifm.keys` global table.
 
... ... Current API version: v0.2.0
32 33 |vifm-l_vifm.sessions| `vifm.sessions` global table. |vifm-l_vifm.sessions| `vifm.sessions` global table.
33 34 |vifm-l_vifm.tabs| `vifm.tabs` global table. |vifm-l_vifm.tabs| `vifm.tabs` global table.
34 35 |vifm-l_vifm.version| `vifm.version` global table. |vifm-l_vifm.version| `vifm.version` global table.
36 |vifm-l_VifmColor| `VifmColor` type.
35 37 |vifm-l_VifmEntry| `VifmEntry` type. |vifm-l_VifmEntry| `VifmEntry` type.
36 38 |vifm-l_VifmJob| `VifmJob` type. |vifm-l_VifmJob| `VifmJob` type.
37 39 |vifm-l_VifmTab| `VifmTab` type. |vifm-l_VifmTab| `VifmTab` type.
 
... ... Parameters:~
915 917 Return:~ Return:~
916 918 `true` on success. `true` on success.
917 919
920 --------------------------------------------------------------------------------
921 *vifm-l_vifm.color*
922
923 This global `vifm.color` table exposes UI-related information and functions.
924 It contains the following items:
925
926 color.count (integer) *vifm-l_vifm.color.count*
927 Number of available colors.
928
929 color.gui (boolean) *vifm-l_vifm.color.gui*
930 Indicates whether GUI/RGB/24-bit colors are in use.
931
932 color.new({info}) *vifm-l_vifm.color.new()*
933 Creates a new instance of |vifm-l_VifmColor|.
934
935 Possible fields of {info} (see |vifm-:highlight| for their meaning):
936 - "ctermfg" (integer or string) (optional)
937 - "ctermbg" (integer or string) (optional)
938 - "cterm" (array of strings) (optional)
939 - "guifg" (string) (optional)
940 - "guibg" (string) (optional)
941 - "gui" (array of strings) (optional)
942
943 Fields that are not provided retain their default values which correspond to a
944 transparent cterm color with no attributes (not even "combine" attribute, so
945 the attributes of lower highlight groups are lost).
946
947 Parameters:~
948 {info} Table with information about the color.
949
950 Return:~
951 On success: an instance of |vifm-l_VifmColor|.
952 On error: `nil` and a string describing the error.
953
918 954 -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
919 955 *vifm-l_vifm.events* *vifm-l_vifm.events*
920 956
 
... ... Parameters:~
1315 1351 Return:~ Return:~
1316 1352 `true` if the version is equal or more recent than the specified one. `true` if the version is equal or more recent than the specified one.
1317 1353
1354 --------------------------------------------------------------------------------
1355 *vifm-l_VifmColor*
1356
1357 Instances of this type are returned by:
1358 * |vifm-l_vifm.color.new()|
1359
1360 This type represents a combination of foreground color, background color and
1361 attributes for both cterm and GUI variants. The data of each instance is fixed
1362 on construction and is not exposed in any way because it is meant to be consumed
1363 by Vifm while drawing TUI.
1364
1318 1365 -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1319 1366 *vifm-l_VifmEntry* *vifm-l_VifmEntry*
1320 1367
 
... ... vifm.cmds.add({cmd}) |vifm-l_vifm.cmds.add()|
1692 1739 vifm.cmds.command({cmd}) |vifm-l_vifm.cmds.command()| vifm.cmds.command({cmd}) |vifm-l_vifm.cmds.command()|
1693 1740 vifm.cmds.delcommand({name}) |vifm-l_vifm.cmds.delcommand()| vifm.cmds.delcommand({name}) |vifm-l_vifm.cmds.delcommand()|
1694 1741
1742 vifm.color (table) |vifm-l_vifm.color|
1743 vifm.color.count (integer) |vifm-l_vifm.color.count|
1744 vifm.color.gui (boolean) |vifm-l_vifm.color.gui|
1745 vifm.color.new({info}) |vifm-l_vifm.color.new()|
1746
1695 1747 vifm.events (table) |vifm-l_vifm.events| vifm.events (table) |vifm-l_vifm.events|
1696 1748 vifm.events.listen({event}) |vifm-l_vifm.events.listen()| vifm.events.listen({event}) |vifm-l_vifm.events.listen()|
1697 1749
 
... ... vifm.version.api.minor (integer) |vifm-l_vifm.version.api.minor|
1743 1795 vifm.version.api.patch (integer) |vifm-l_vifm.version.api.patch| vifm.version.api.patch (integer) |vifm-l_vifm.version.api.patch|
1744 1796 vifm.version.app.str (string) |vifm-l_vifm.version.app.str| vifm.version.app.str (string) |vifm-l_vifm.version.app.str|
1745 1797
1798 VifmColor (type) |vifm-l_VifmColor|
1799
1746 1800 VifmEntry (type) |vifm-l_VifmEntry| VifmEntry (type) |vifm-l_VifmEntry|
1747 1801 VifmEntry.atime (integer) |vifm-l_VifmEntry.atime| VifmEntry.atime (integer) |vifm-l_VifmEntry.atime|
1748 1802 VifmEntry.classify (table) |vifm-l_VifmEntry.classify| VifmEntry.classify (table) |vifm-l_VifmEntry.classify|
File src/Makefile.am changed (mode: 100644) (index d60af48b6..0369015eb)
... ... vifm_SOURCES = \
194 194 lua/vifm.c lua/vifm.h \ lua/vifm.c lua/vifm.h \
195 195 lua/vifm_abbrevs.c lua/vifm_abbrevs.h \ lua/vifm_abbrevs.c lua/vifm_abbrevs.h \
196 196 lua/vifm_cmds.c lua/vifm_cmds.h \ lua/vifm_cmds.c lua/vifm_cmds.h \
197 lua/vifm_color.c lua/vifm_color.h \
197 198 lua/vifm_events.c lua/vifm_events.h \ lua/vifm_events.c lua/vifm_events.h \
198 199 lua/vifm_fs.c lua/vifm_fs.h \ lua/vifm_fs.c lua/vifm_fs.h \
199 200 lua/vifm_handlers.c lua/vifm_handlers.h \ lua/vifm_handlers.c lua/vifm_handlers.h \
File src/Makefile.in changed (mode: 100644) (index 77cd95ca5..264f7d514)
... ... am_vifm_OBJECTS = cfg/config.$(OBJEXT) cfg/info.$(OBJEXT) \
168 168 lua/lua/lvm.$(OBJEXT) lua/lua/lzio.$(OBJEXT) \ lua/lua/lvm.$(OBJEXT) lua/lua/lzio.$(OBJEXT) \
169 169 lua/common.$(OBJEXT) lua/vifm.$(OBJEXT) \ lua/common.$(OBJEXT) lua/vifm.$(OBJEXT) \
170 170 lua/vifm_abbrevs.$(OBJEXT) lua/vifm_cmds.$(OBJEXT) \ lua/vifm_abbrevs.$(OBJEXT) lua/vifm_cmds.$(OBJEXT) \
171 lua/vifm_events.$(OBJEXT) lua/vifm_fs.$(OBJEXT) \
172 lua/vifm_handlers.$(OBJEXT) lua/vifm_keys.$(OBJEXT) \
173 lua/vifm_tabs.$(OBJEXT) lua/vifm_viewcolumns.$(OBJEXT) \
174 lua/vifmentry.$(OBJEXT) lua/vifmjob.$(OBJEXT) \
175 lua/vifmtab.$(OBJEXT) lua/vifmview.$(OBJEXT) \
176 lua/vlua.$(OBJEXT) lua/vlua_cbacks.$(OBJEXT) \
177 lua/vlua_state.$(OBJEXT) menus/apropos_menu.$(OBJEXT) \
178 menus/bmarks_menu.$(OBJEXT) menus/cabbrevs_menu.$(OBJEXT) \
179 menus/chistory_menu.$(OBJEXT) menus/colorscheme_menu.$(OBJEXT) \
180 menus/commands_menu.$(OBJEXT) menus/dirhistory_menu.$(OBJEXT) \
181 menus/dirstack_menu.$(OBJEXT) menus/filetypes_menu.$(OBJEXT) \
182 menus/find_menu.$(OBJEXT) menus/grep_menu.$(OBJEXT) \
183 menus/history_menu.$(OBJEXT) menus/jobs_menu.$(OBJEXT) \
184 menus/locate_menu.$(OBJEXT) menus/trash_menu.$(OBJEXT) \
185 menus/trashes_menu.$(OBJEXT) menus/map_menu.$(OBJEXT) \
186 menus/marks_menu.$(OBJEXT) menus/media_menu.$(OBJEXT) \
187 menus/menus.$(OBJEXT) menus/plugins_menu.$(OBJEXT) \
188 menus/registers_menu.$(OBJEXT) menus/undolist_menu.$(OBJEXT) \
189 menus/users_menu.$(OBJEXT) menus/vifm_menu.$(OBJEXT) \
171 lua/vifm_color.$(OBJEXT) lua/vifm_events.$(OBJEXT) \
172 lua/vifm_fs.$(OBJEXT) lua/vifm_handlers.$(OBJEXT) \
173 lua/vifm_keys.$(OBJEXT) lua/vifm_tabs.$(OBJEXT) \
174 lua/vifm_viewcolumns.$(OBJEXT) lua/vifmentry.$(OBJEXT) \
175 lua/vifmjob.$(OBJEXT) lua/vifmtab.$(OBJEXT) \
176 lua/vifmview.$(OBJEXT) lua/vlua.$(OBJEXT) \
177 lua/vlua_cbacks.$(OBJEXT) lua/vlua_state.$(OBJEXT) \
178 menus/apropos_menu.$(OBJEXT) menus/bmarks_menu.$(OBJEXT) \
179 menus/cabbrevs_menu.$(OBJEXT) menus/chistory_menu.$(OBJEXT) \
180 menus/colorscheme_menu.$(OBJEXT) menus/commands_menu.$(OBJEXT) \
181 menus/dirhistory_menu.$(OBJEXT) menus/dirstack_menu.$(OBJEXT) \
182 menus/filetypes_menu.$(OBJEXT) menus/find_menu.$(OBJEXT) \
183 menus/grep_menu.$(OBJEXT) menus/history_menu.$(OBJEXT) \
184 menus/jobs_menu.$(OBJEXT) menus/locate_menu.$(OBJEXT) \
185 menus/trash_menu.$(OBJEXT) menus/trashes_menu.$(OBJEXT) \
186 menus/map_menu.$(OBJEXT) menus/marks_menu.$(OBJEXT) \
187 menus/media_menu.$(OBJEXT) menus/menus.$(OBJEXT) \
188 menus/plugins_menu.$(OBJEXT) menus/registers_menu.$(OBJEXT) \
189 menus/undolist_menu.$(OBJEXT) menus/users_menu.$(OBJEXT) \
190 menus/vifm_menu.$(OBJEXT) \
190 191 modes/dialogs/attr_dialog_nix.$(OBJEXT) \ modes/dialogs/attr_dialog_nix.$(OBJEXT) \
191 192 modes/dialogs/change_dialog.$(OBJEXT) \ modes/dialogs/change_dialog.$(OBJEXT) \
192 193 modes/dialogs/msg_dialog.$(OBJEXT) \ modes/dialogs/msg_dialog.$(OBJEXT) \
 
... ... am__depfiles_remade = ./$(DEPDIR)/args.Po ./$(DEPDIR)/background.Po \
319 320 io/private/$(DEPDIR)/ionotif.Po \ io/private/$(DEPDIR)/ionotif.Po \
320 321 io/private/$(DEPDIR)/traverser.Po lua/$(DEPDIR)/common.Po \ io/private/$(DEPDIR)/traverser.Po lua/$(DEPDIR)/common.Po \
321 322 lua/$(DEPDIR)/vifm.Po lua/$(DEPDIR)/vifm_abbrevs.Po \ lua/$(DEPDIR)/vifm.Po lua/$(DEPDIR)/vifm_abbrevs.Po \
322 lua/$(DEPDIR)/vifm_cmds.Po lua/$(DEPDIR)/vifm_events.Po \
323 lua/$(DEPDIR)/vifm_fs.Po lua/$(DEPDIR)/vifm_handlers.Po \
324 lua/$(DEPDIR)/vifm_keys.Po lua/$(DEPDIR)/vifm_tabs.Po \
325 lua/$(DEPDIR)/vifm_viewcolumns.Po lua/$(DEPDIR)/vifmentry.Po \
326 lua/$(DEPDIR)/vifmjob.Po lua/$(DEPDIR)/vifmtab.Po \
327 lua/$(DEPDIR)/vifmview.Po lua/$(DEPDIR)/vlua.Po \
328 lua/$(DEPDIR)/vlua_cbacks.Po lua/$(DEPDIR)/vlua_state.Po \
329 lua/lua/$(DEPDIR)/lapi.Po lua/lua/$(DEPDIR)/lauxlib.Po \
330 lua/lua/$(DEPDIR)/lbaselib.Po lua/lua/$(DEPDIR)/lcode.Po \
331 lua/lua/$(DEPDIR)/lcorolib.Po lua/lua/$(DEPDIR)/lctype.Po \
332 lua/lua/$(DEPDIR)/ldblib.Po lua/lua/$(DEPDIR)/ldebug.Po \
333 lua/lua/$(DEPDIR)/ldo.Po lua/lua/$(DEPDIR)/ldump.Po \
334 lua/lua/$(DEPDIR)/lfunc.Po lua/lua/$(DEPDIR)/lgc.Po \
335 lua/lua/$(DEPDIR)/linit.Po lua/lua/$(DEPDIR)/liolib.Po \
336 lua/lua/$(DEPDIR)/llex.Po lua/lua/$(DEPDIR)/lmathlib.Po \
337 lua/lua/$(DEPDIR)/lmem.Po lua/lua/$(DEPDIR)/loadlib.Po \
338 lua/lua/$(DEPDIR)/lobject.Po lua/lua/$(DEPDIR)/lopcodes.Po \
339 lua/lua/$(DEPDIR)/loslib.Po lua/lua/$(DEPDIR)/lparser.Po \
340 lua/lua/$(DEPDIR)/lstate.Po lua/lua/$(DEPDIR)/lstring.Po \
341 lua/lua/$(DEPDIR)/lstrlib.Po lua/lua/$(DEPDIR)/ltable.Po \
342 lua/lua/$(DEPDIR)/ltablib.Po lua/lua/$(DEPDIR)/ltm.Po \
343 lua/lua/$(DEPDIR)/lundump.Po lua/lua/$(DEPDIR)/lutf8lib.Po \
344 lua/lua/$(DEPDIR)/lvm.Po lua/lua/$(DEPDIR)/lzio.Po \
345 menus/$(DEPDIR)/apropos_menu.Po menus/$(DEPDIR)/bmarks_menu.Po \
323 lua/$(DEPDIR)/vifm_cmds.Po lua/$(DEPDIR)/vifm_color.Po \
324 lua/$(DEPDIR)/vifm_events.Po lua/$(DEPDIR)/vifm_fs.Po \
325 lua/$(DEPDIR)/vifm_handlers.Po lua/$(DEPDIR)/vifm_keys.Po \
326 lua/$(DEPDIR)/vifm_tabs.Po lua/$(DEPDIR)/vifm_viewcolumns.Po \
327 lua/$(DEPDIR)/vifmentry.Po lua/$(DEPDIR)/vifmjob.Po \
328 lua/$(DEPDIR)/vifmtab.Po lua/$(DEPDIR)/vifmview.Po \
329 lua/$(DEPDIR)/vlua.Po lua/$(DEPDIR)/vlua_cbacks.Po \
330 lua/$(DEPDIR)/vlua_state.Po lua/lua/$(DEPDIR)/lapi.Po \
331 lua/lua/$(DEPDIR)/lauxlib.Po lua/lua/$(DEPDIR)/lbaselib.Po \
332 lua/lua/$(DEPDIR)/lcode.Po lua/lua/$(DEPDIR)/lcorolib.Po \
333 lua/lua/$(DEPDIR)/lctype.Po lua/lua/$(DEPDIR)/ldblib.Po \
334 lua/lua/$(DEPDIR)/ldebug.Po lua/lua/$(DEPDIR)/ldo.Po \
335 lua/lua/$(DEPDIR)/ldump.Po lua/lua/$(DEPDIR)/lfunc.Po \
336 lua/lua/$(DEPDIR)/lgc.Po lua/lua/$(DEPDIR)/linit.Po \
337 lua/lua/$(DEPDIR)/liolib.Po lua/lua/$(DEPDIR)/llex.Po \
338 lua/lua/$(DEPDIR)/lmathlib.Po lua/lua/$(DEPDIR)/lmem.Po \
339 lua/lua/$(DEPDIR)/loadlib.Po lua/lua/$(DEPDIR)/lobject.Po \
340 lua/lua/$(DEPDIR)/lopcodes.Po lua/lua/$(DEPDIR)/loslib.Po \
341 lua/lua/$(DEPDIR)/lparser.Po lua/lua/$(DEPDIR)/lstate.Po \
342 lua/lua/$(DEPDIR)/lstring.Po lua/lua/$(DEPDIR)/lstrlib.Po \
343 lua/lua/$(DEPDIR)/ltable.Po lua/lua/$(DEPDIR)/ltablib.Po \
344 lua/lua/$(DEPDIR)/ltm.Po lua/lua/$(DEPDIR)/lundump.Po \
345 lua/lua/$(DEPDIR)/lutf8lib.Po lua/lua/$(DEPDIR)/lvm.Po \
346 lua/lua/$(DEPDIR)/lzio.Po menus/$(DEPDIR)/apropos_menu.Po \
347 menus/$(DEPDIR)/bmarks_menu.Po \
346 348 menus/$(DEPDIR)/cabbrevs_menu.Po \ menus/$(DEPDIR)/cabbrevs_menu.Po \
347 349 menus/$(DEPDIR)/chistory_menu.Po \ menus/$(DEPDIR)/chistory_menu.Po \
348 350 menus/$(DEPDIR)/colorscheme_menu.Po \ menus/$(DEPDIR)/colorscheme_menu.Po \
 
... ... vifm_SOURCES = \
921 923 lua/vifm.c lua/vifm.h \ lua/vifm.c lua/vifm.h \
922 924 lua/vifm_abbrevs.c lua/vifm_abbrevs.h \ lua/vifm_abbrevs.c lua/vifm_abbrevs.h \
923 925 lua/vifm_cmds.c lua/vifm_cmds.h \ lua/vifm_cmds.c lua/vifm_cmds.h \
926 lua/vifm_color.c lua/vifm_color.h \
924 927 lua/vifm_events.c lua/vifm_events.h \ lua/vifm_events.c lua/vifm_events.h \
925 928 lua/vifm_fs.c lua/vifm_fs.h \ lua/vifm_fs.c lua/vifm_fs.h \
926 929 lua/vifm_handlers.c lua/vifm_handlers.h \ lua/vifm_handlers.c lua/vifm_handlers.h \
 
... ... lua/vifm_abbrevs.$(OBJEXT): lua/$(am__dirstamp) \
1375 1378 lua/$(DEPDIR)/$(am__dirstamp) lua/$(DEPDIR)/$(am__dirstamp)
1376 1379 lua/vifm_cmds.$(OBJEXT): lua/$(am__dirstamp) \ lua/vifm_cmds.$(OBJEXT): lua/$(am__dirstamp) \
1377 1380 lua/$(DEPDIR)/$(am__dirstamp) lua/$(DEPDIR)/$(am__dirstamp)
1381 lua/vifm_color.$(OBJEXT): lua/$(am__dirstamp) \
1382 lua/$(DEPDIR)/$(am__dirstamp)
1378 1383 lua/vifm_events.$(OBJEXT): lua/$(am__dirstamp) \ lua/vifm_events.$(OBJEXT): lua/$(am__dirstamp) \
1379 1384 lua/$(DEPDIR)/$(am__dirstamp) lua/$(DEPDIR)/$(am__dirstamp)
1380 1385 lua/vifm_fs.$(OBJEXT): lua/$(am__dirstamp) \ lua/vifm_fs.$(OBJEXT): lua/$(am__dirstamp) \
 
... ... distclean-compile:
1770 1775 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm.Po@am__quote@ # am--include-marker
1771 1776 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_abbrevs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_abbrevs.Po@am__quote@ # am--include-marker
1772 1777 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_cmds.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_cmds.Po@am__quote@ # am--include-marker
1778 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_color.Po@am__quote@ # am--include-marker
1773 1779 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_events.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_events.Po@am__quote@ # am--include-marker
1774 1780 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_fs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_fs.Po@am__quote@ # am--include-marker
1775 1781 @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_handlers.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@lua/$(DEPDIR)/vifm_handlers.Po@am__quote@ # am--include-marker
 
... ... distclean: distclean-am
2839 2845 -rm -f lua/$(DEPDIR)/vifm.Po -rm -f lua/$(DEPDIR)/vifm.Po
2840 2846 -rm -f lua/$(DEPDIR)/vifm_abbrevs.Po -rm -f lua/$(DEPDIR)/vifm_abbrevs.Po
2841 2847 -rm -f lua/$(DEPDIR)/vifm_cmds.Po -rm -f lua/$(DEPDIR)/vifm_cmds.Po
2848 -rm -f lua/$(DEPDIR)/vifm_color.Po
2842 2849 -rm -f lua/$(DEPDIR)/vifm_events.Po -rm -f lua/$(DEPDIR)/vifm_events.Po
2843 2850 -rm -f lua/$(DEPDIR)/vifm_fs.Po -rm -f lua/$(DEPDIR)/vifm_fs.Po
2844 2851 -rm -f lua/$(DEPDIR)/vifm_handlers.Po -rm -f lua/$(DEPDIR)/vifm_handlers.Po
 
... ... maintainer-clean: maintainer-clean-am
3109 3116 -rm -f lua/$(DEPDIR)/vifm.Po -rm -f lua/$(DEPDIR)/vifm.Po
3110 3117 -rm -f lua/$(DEPDIR)/vifm_abbrevs.Po -rm -f lua/$(DEPDIR)/vifm_abbrevs.Po
3111 3118 -rm -f lua/$(DEPDIR)/vifm_cmds.Po -rm -f lua/$(DEPDIR)/vifm_cmds.Po
3119 -rm -f lua/$(DEPDIR)/vifm_color.Po
3112 3120 -rm -f lua/$(DEPDIR)/vifm_events.Po -rm -f lua/$(DEPDIR)/vifm_events.Po
3113 3121 -rm -f lua/$(DEPDIR)/vifm_fs.Po -rm -f lua/$(DEPDIR)/vifm_fs.Po
3114 3122 -rm -f lua/$(DEPDIR)/vifm_handlers.Po -rm -f lua/$(DEPDIR)/vifm_handlers.Po
File src/Makefile.win changed (mode: 100644) (index 99df410de..a11c988af)
... ... lua := lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c \
56 56 lzio.c lzio.c
57 57 lua := $(addprefix lua/, $(lua)) lua := $(addprefix lua/, $(lua))
58 58 lua := $(addprefix lua/, $(lua) common.c vifm.c vifm_abbrevs.c vifm_cmds.c \ lua := $(addprefix lua/, $(lua) common.c vifm.c vifm_abbrevs.c vifm_cmds.c \
59 vifm_events.c vifm_fs.c vifm_handlers.c \
60 vifm_keys.c vifm_tabs.c vifm_viewcolumns.c \
61 vifmentry.c vifmjob.c vifmtab.c vifmview.c \
62 vlua.c vlua_cbacks.c vlua_state.c)
59 vifm_color.c vifm_events.c vifm_fs.c \
60 vifm_handlers.c vifm_keys.c vifm_tabs.c \
61 vifm_viewcolumns.c vifmentry.c vifmjob.c \
62 vifmtab.c vifmview.c vlua.c vlua_cbacks.c \
63 vlua_state.c)
63 64
64 65 menus := apropos_menu.c bmarks_menu.c cabbrevs_menu.c chistory_menu.c \ menus := apropos_menu.c bmarks_menu.c cabbrevs_menu.c chistory_menu.c \
65 66 colorscheme_menu.c commands_menu.c dirhistory_menu.c dirstack_menu.c \ colorscheme_menu.c commands_menu.c dirhistory_menu.c dirstack_menu.c \
File src/lua/vifm.c changed (mode: 100644) (index 73f706251..a232ee4a5)
41 41 #include "common.h" #include "common.h"
42 42 #include "vifm_abbrevs.h" #include "vifm_abbrevs.h"
43 43 #include "vifm_cmds.h" #include "vifm_cmds.h"
44 #include "vifm_color.h"
44 45 #include "vifm_events.h" #include "vifm_events.h"
45 46 #include "vifm_fs.h" #include "vifm_fs.h"
46 47 #include "vifm_handlers.h" #include "vifm_handlers.h"
 
... ... vifm_init(lua_State *lua)
179 180 vifm_cmds_init(lua); vifm_cmds_init(lua);
180 181 lua_setfield(lua, -2, "cmds"); lua_setfield(lua, -2, "cmds");
181 182
183 /* Setup vifm.color. */
184 vifm_color_init(lua);
185 lua_setfield(lua, -2, "color");
186
182 187 /* Setup vifm.events. */ /* Setup vifm.events. */
183 188 vifm_events_init(lua); vifm_events_init(lua);
184 189 lua_setfield(lua, -2, "events"); lua_setfield(lua, -2, "events");
File src/lua/vifm_color.c added (mode: 100644) (index 000000000..7c19f3b38)
1 /* vifm
2 * Copyright (C) 2026 xaizek.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "vifm_color.h"
20
21 #include <curses.h> /* COLORS */
22
23 #include <string.h> /* memset() */
24
25 #include "../ui/colors.h"
26 #include "../status.h"
27 #include "lua/lauxlib.h"
28 #include "lua/lua.h"
29 #include "api.h"
30 #include "common.h"
31
32 static int VLUA_API(color_new)(lua_State *lua);
33 static int parse_cterm_color(lua_State *lua, int is_fg, col_attr_t *color);
34 static int parse_gui_color(lua_State *lua, int is_fg, col_attr_t *color);
35 static int parse_attrs(lua_State *lua, int is_gui, col_attr_t *color);
36 static int parse_attr_list(lua_State *lua, int *combine_attrs);
37
38 VLUA_DECLARE_SAFE(color_new);
39
40 /* Functions of the `vifm.color` table. */
41 static const luaL_Reg vifm_color_methods[] = {
42 { "new", VLUA_REF(color_new) },
43 { NULL, NULL }
44 };
45
46 void
47 vifm_color_init(lua_State *lua)
48 {
49 vlua_cmn_make_metatable(lua, "VifmColor");
50 lua_pop(lua, 1); /* VifmColor metatable */
51
52 luaL_newlib(lua, vifm_color_methods);
53
54 lua_pushinteger(lua, COLORS);
55 lua_setfield(lua, -2, "count");
56
57 lua_pushboolean(lua, curr_stats.direct_color);
58 lua_setfield(lua, -2, "gui");
59 }
60
61 /* Member of `vifm.color` that creates an instance of VifmColor or returns a
62 * pair of `nil` and an error string. */
63 static int
64 VLUA_API(color_new)(lua_State *lua)
65 {
66 luaL_checktype(lua, 1, LUA_TTABLE);
67
68 col_attr_t *color = lua_newuserdatauv(lua, sizeof(*color), /*nuvalue=*/0);
69 memset(color, 0, sizeof(*color));
70 color->fg = -1;
71 color->bg = -1;
72
73 if(parse_cterm_color(lua, /*is_fg=*/0, color) != 0 ||
74 parse_cterm_color(lua, /*is_fg=*/1, color) != 0 ||
75 parse_gui_color(lua, /*is_fg=*/0, color) != 0 ||
76 parse_gui_color(lua, /*is_fg=*/1, color) != 0 ||
77 parse_attrs(lua, /*is_gui=*/0, color) != 0 ||
78 parse_attrs(lua, /*is_gui=*/1, color) != 0)
79 {
80 return 2;
81 }
82
83 lua_copy(lua, 2, -1);
84 luaL_getmetatable(lua, "VifmColor");
85 lua_setmetatable(lua, -2);
86 return 1;
87 }
88
89 /* Parses value of "ctermfg" or "ctermbg" field when it's present. Returns zero
90 * on success, otherwise leaves `nil` and an error string on Lua's stack. */
91 static int
92 parse_cterm_color(lua_State *lua, int is_fg, col_attr_t *color)
93 {
94 const char *field = (is_fg ? "ctermfg" : "ctermbg");
95 short *value = (is_fg ? &color->fg : &color->bg);
96
97 /* vlua_cmn_check_opt_field() doesn't allow handling two types. */
98 const int type = lua_getfield(lua, 1, field);
99 if(type == LUA_TNIL)
100 {
101 return 0;
102 }
103
104 if(type != LUA_TNUMBER && type != LUA_TSTRING)
105 {
106 return luaL_error(lua, "`%s` value is of wrong type: %s", field,
107 lua_typename(lua, type));
108 }
109
110 const char *str = lua_tostring(lua, -1);
111 *value = cols_parse_value(str, is_fg, &color->attr);
112 if(*value >= -1)
113 {
114 return 0;
115 }
116
117 lua_pushnil(lua);
118 lua_pushfstring(lua, "Bad value of '%s' field: '%s'", field, str);
119 return 1;
120 }
121
122 /* Parses value of "guifg" or "guibg" field when it's present. Returns zero on
123 * success, otherwise leaves `nil` and an error string on Lua's stack. */
124 static int
125 parse_gui_color(lua_State *lua, int is_fg, col_attr_t *color)
126 {
127 const char *field = (is_fg ? "guifg" : "guibg");
128
129 if(!vlua_cmn_check_opt_field(lua, 1, field, LUA_TSTRING))
130 {
131 return 0;
132 }
133
134 const char *str = lua_tostring(lua, -1);
135 int value;
136 if(cols_parse_gui_value(str, &value) == 0)
137 {
138 if(is_fg)
139 {
140 color->gui_fg = value;
141 }
142 else
143 {
144 color->gui_bg = value;
145 }
146
147 cs_color_enable_gui(color);
148 return 0;
149 }
150
151 lua_pushnil(lua);
152 lua_pushfstring(lua, "Bad value of '%s' field: '%s'", field, str);
153 return 1;
154 }
155
156 /* Parses value of "gui" or "cterm" field when it's present. Returns zero on
157 * success, otherwise leaves `nil` and an error string on Lua's stack. */
158 static int
159 parse_attrs(lua_State *lua, int is_gui, col_attr_t *color)
160 {
161 const char *field = (is_gui ? "gui" : "cterm");
162 int *value = (is_gui ? &color->gui_attr : &color->attr);
163
164 if(!vlua_cmn_check_opt_field(lua, 1, field, LUA_TTABLE))
165 {
166 return 0;
167 }
168
169 int combine_attrs;
170 *value = parse_attr_list(lua, &combine_attrs);
171 if(*value == -1)
172 {
173 lua_pushnil(lua);
174 lua_pushfstring(lua, "Bad value of '%s' field", field);
175 return 1;
176 }
177
178 if(is_gui)
179 {
180 color->combine_gui_attrs = combine_attrs;
181 cs_color_enable_gui(color);
182 }
183 else
184 {
185 if(curr_stats.exec_env_type == EET_LINUX_NATIVE &&
186 (*value & (A_BOLD | A_REVERSE)) == (A_BOLD | A_REVERSE))
187 {
188 *value |= A_BLINK;
189 }
190
191 color->combine_attrs = combine_attrs;
192 }
193
194 return 0;
195 }
196
197 /* Parses an array of strings that represent attributes. Returns parsed result
198 * or -1 on error. *combine_attrs is always assigned to. */
199 static int
200 parse_attr_list(lua_State *lua, int *combine_attrs)
201 {
202 int attrs = 0;
203 *combine_attrs = 0;
204
205 lua_pushnil(lua); /* first key */
206 while(lua_next(lua, -2) != 0)
207 {
208 if(lua_type(lua, -1) != LUA_TSTRING)
209 {
210 lua_pop(lua, 2); /* item's value, item's key */
211 return -1;
212 }
213
214 const char *attr = lua_tostring(lua, -1);
215 if(cols_parse_attr(attr, &attrs, combine_attrs) != 0)
216 {
217 lua_pop(lua, 2); /* item's value, item's key */
218 return -1;
219 }
220
221 lua_pop(lua, 1); /* item's value */
222 }
223
224 return attrs;
225 }
226
227 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
228 /* vim: set cinoptions+=t0 : */
File src/lua/vifm_color.h copied from file src/lua/vifm.h (similarity 77%) (mode: 100644) (index 6fcdd31d4..e45434982)
1 1 /* vifm /* vifm
2 * Copyright (C) 2023 xaizek.
2 * Copyright (C) 2026 xaizek.
3 3 * *
4 4 * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
5 5 * it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
 
16 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 17 */ */
18 18
19 #ifndef VIFM__LUA__VIFM_H__
20 #define VIFM__LUA__VIFM_H__
19 #ifndef VIFM__LUA__VIFM_COLOR_H__
20 #define VIFM__LUA__VIFM_COLOR_H__
21 21
22 22 struct lua_State; struct lua_State;
23 23
24 /* Produces `vifm` table. Puts the table on the top of the stack. */
25 void vifm_init(struct lua_State *lua);
24 /* Produces `vifm.color` table. Puts the table on the top of the stack. */
25 void vifm_color_init(struct lua_State *lua);
26 26
27 #endif /* VIFM__LUA__VIFM_H__ */
27 #endif /* VIFM__LUA__VIFM_COLOR_H__ */
28 28
29 29 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
30 30 /* vim: set cinoptions+=t0 filetype=c : */ /* vim: set cinoptions+=t0 filetype=c : */
File src/tags.c changed (mode: 100644) (index bd91de5eb..0c3c81559)
... ... const char *tags[] = {
709 709 "vifm-jobcount-variable", "vifm-jobcount-variable",
710 710 "vifm-k", "vifm-k",
711 711 "vifm-l", "vifm-l",
712 "vifm-l_VifmColor",
712 713 "vifm-l_VifmEntry", "vifm-l_VifmEntry",
713 714 "vifm-l_VifmEntry.atime", "vifm-l_VifmEntry.atime",
714 715 "vifm-l_VifmEntry.classify", "vifm-l_VifmEntry.classify",
 
... ... const char *tags[] = {
764 765 "vifm-l_vifm.cmds.add()", "vifm-l_vifm.cmds.add()",
765 766 "vifm-l_vifm.cmds.command()", "vifm-l_vifm.cmds.command()",
766 767 "vifm-l_vifm.cmds.delcommand()", "vifm-l_vifm.cmds.delcommand()",
768 "vifm-l_vifm.color",
769 "vifm-l_vifm.color.count",
770 "vifm-l_vifm.color.gui",
771 "vifm-l_vifm.color.new()",
767 772 "vifm-l_vifm.currview()", "vifm-l_vifm.currview()",
768 773 "vifm-l_vifm.errordialog()", "vifm-l_vifm.errordialog()",
769 774 "vifm-l_vifm.escape()", "vifm-l_vifm.escape()",
File tests/lua/api_color.c added (mode: 100644) (index 000000000..a5af392ec)
1 #include <stic.h>
2
3 #include "../../src/cfg/config.h"
4 #include "../../src/compat/os.h"
5 #include "../../src/lua/vlua.h"
6 #include "../../src/ui/statusbar.h"
7 #include "../../src/ops.h"
8 #include "../../src/status.h"
9
10 #include <test-utils.h>
11
12 #include "asserts.h"
13
14 static vlua_t *vlua;
15
16 SETUP()
17 {
18 vlua = vlua_init();
19 }
20
21 TEARDOWN()
22 {
23 vlua_finish(vlua);
24 }
25
26 TEST(color_fields)
27 {
28 /* With uninitialized curses these may produce unexpected output, so just
29 * checking for presence and types. */
30 GLUA_ENDS(vlua, "number", "print(type(vifm.color.count))");
31 GLUA_ENDS(vlua, "boolean", "print(type(vifm.color.gui))");
32 }
33
34 TEST(color_new_bad_cterm_colors)
35 {
36 /* Bad type. */
37 BLUA_ENDS(vlua, ": `ctermfg` value is of wrong type: table",
38 "vifm.color.new { ctermfg = {} }");
39 BLUA_ENDS(vlua, ": `ctermbg` value is of wrong type: table",
40 "vifm.color.new { ctermbg = {} }");
41
42 /* Bad string value. */
43 GLUA_EQ(vlua, "nil\tBad value of 'ctermfg' field: 'bad'",
44 "print(vifm.color.new { ctermfg = 'bad' })");
45 GLUA_EQ(vlua, "nil\tBad value of 'ctermbg' field: 'bad'",
46 "print(vifm.color.new { ctermbg = 'bad' })");
47
48 /* Bad numerical value. */
49 GLUA_EQ(vlua, "nil\tBad value of 'ctermfg' field: '-5'",
50 "print(vifm.color.new { ctermfg = -5 })");
51 GLUA_EQ(vlua, "nil\tBad value of 'ctermbg' field: '-5'",
52 "print(vifm.color.new { ctermbg = -5 })");
53 }
54
55 TEST(color_new_bad_gui_colors)
56 {
57 /* Bad type. */
58 BLUA_ENDS(vlua, ": `guifg` value must be a string",
59 "vifm.color.new { guifg = {} }");
60 BLUA_ENDS(vlua, ": `guibg` value must be a string",
61 "vifm.color.new { guibg = {} }");
62
63 /* Bad string value. */
64 GLUA_EQ(vlua, "nil\tBad value of 'guifg' field: 'bad'",
65 "print(vifm.color.new { guifg = 'bad' })");
66 GLUA_EQ(vlua, "nil\tBad value of 'guibg' field: 'bad'",
67 "print(vifm.color.new { guibg = 'bad' })");
68 }
69
70 TEST(color_new_bad_attrs)
71 {
72 /* Bad field type. */
73 BLUA_ENDS(vlua, ": `cterm` value must be a table",
74 "vifm.color.new { cterm = 10 }");
75 BLUA_ENDS(vlua, ": `gui` value must be a table",
76 "vifm.color.new { gui = 10 }");
77
78 /* Bad element type. */
79 BLUA_ENDS(vlua, ": Bad value of 'cterm' field",
80 "assert(vifm.color.new { cterm = { 10 } })");
81 BLUA_ENDS(vlua, ": Bad value of 'gui' field",
82 "assert(vifm.color.new { gui = { 10 } })");
83
84 /* Bad string value. */
85 BLUA_ENDS(vlua, ": Bad value of 'cterm' field",
86 "assert(vifm.color.new { cterm = { 'bad' } })");
87 BLUA_ENDS(vlua, ": Bad value of 'gui' field",
88 "assert(vifm.color.new { gui = { 'bad' } })");
89 }
90
91 TEST(color_new_good)
92 {
93 GLUA_STARTS(vlua, "VifmColor: ", "print(vifm.color.new {})");
94
95 /* cterm colors */
96 GLUA_STARTS(vlua, "VifmColor: ",
97 "print(vifm.color.new {"
98 " ctermfg = 'white',"
99 " ctermbg = 'black',"
100 "})");
101 /* Testing numerical values other than -1 requires mocking COLORS. */
102 GLUA_STARTS(vlua, "VifmColor: ",
103 "print(vifm.color.new {"
104 " ctermfg = -1,"
105 " ctermbg = -1,"
106 "})");
107
108 /* gui colors */
109 GLUA_STARTS(vlua, "VifmColor: ",
110 "print(vifm.color.new {"
111 " guifg = '#000000',"
112 " guibg = '#FFffFF',"
113 "})");
114
115 /* attributes */
116 GLUA_STARTS(vlua, "VifmColor: ",
117 "print(vifm.color.new {"
118 " cterm = { 'combine', 'none', 'bold' },"
119 " gui = { },"
120 "})");
121 }
122
123 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
124 /* vim: set cinoptions+=t0 : */
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master