I'm Famiu (IPA pronunciation: fαmjʊ), I'm currently a student and like to contribute to Open Source projects in my free time.
- E-mail: [email protected]
- Element/Matrix: @moonglade:matrix.org
A minimal, stylish and customizable statusline for Neovim written in Lua
License: GNU General Public License v3.0
I'm Famiu (IPA pronunciation: fαmjʊ), I'm currently a student and like to contribute to Open Source projects in my free time.
Hi @famiu great plugin :D . Been using it for a while now , galaxyline had a separate section for shortline , how do I do this with feline?
For example some components arent visible if the buffer's width is small
Neovim version
NVIM v0.6.0-dev+210-g6751d6254
Feline version
ee74b0c
Describe the bug
When opening a file, feline crashes.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expected it to not crash.
Does this error occur in the minimal init file?
No it does not.
Additional context
I do my config in a weird way(see below for my feline config file), and that may be the issue.
feline.lua
^ Try loading this file in nvim and see if the problem occurs then.
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Unreasonable rendering of too long components.
For example:
-- config:
local cur_function = {
provider = function()
return vim.fn["nvim_treesitter#statusline"](90)
end,
enabled = function()
return vim.NIL ~= vim.fn["nvim_treesitter#statusline"](90)
end,
left_sep = ' ',
hl = {
fg = colors.yellow
}
}
local components = {
left = {
active = {
comps.vi_mode.left,
comps.file.info,
cur_function,
-- .......
},
inactive = {
comps.file.info
}
},
-- .........
}
require'feline'.setup {
-- .....
components = components,
-- ....
}
but if the component too long , it work like that:
comps.vi_mode.left
, comps.file.info
was truncated.
and now i solve it by a status line mark %<
provider = function()
return "%<" .. vim.fn["nvim_treesitter#statusline"](90)
end
However, display function name is more usefully than function signature
Describe the solution you'd like
A clear and concise description of what you want to happen. I hope it can truncate.
Therefore, i hope we can cut off the tail rather than the head of component, like that :
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Easy goal: cut off the tail for some component.
Future hope:
It just an idea without detail.
I hope each component can set 3 properties: max_size
, min_size
, truncate_level
. For the too long component, it can truncate the low level component to min_size.
Additional context
Add any other context or screenshots about the feature request here.
Neovim version
Both 0.6 nightly and 0.5 release:
NVIM v0.6.0-dev+63-ga8c3d50fa
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
NVIM v0.5.0
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Feline version
4c04c967691d028b4056f726735db329039cdff2
This was happening since the first version of feline
I used, this isn't a new issue.
Describe the bug
Feline causes the neovim spash screen to disappear, for clarity I'm referring to the opening screen with the neovim version, etc:
~ NVIM v0.5.0
~
~ Nvim is open source and freely distributable
~ https://neovim.io/#chat
~
~ type :help nvim<Enter> if you are new!
~ type :checkhealth<Enter> to optimize Nvim
~ type :q<Enter> to exit
~ type :help<Enter> for help
~
~ Help poor children in Uganda!
~ type :help iccf<Enter> for information
To Reproduce
Run feline as the only plugin and it should reproduce, it even happens when lazy loading to with packer on VimEnter
:
use { 'famiu/feline.nvim',
requires = { 'kyazdani42/nvim-web-devicons' },
config = "require'plugin.feline'",
event = 'VimEnter'
}
Expected behavior
Keep the splash screen.
Does this error occur in the minimal init file?
Yes, the issue is reproducible with minimal_init.lua
.
Additional context
Most fancy status line plugins I tried have the same issue, for exmaple galaxyline issue #107, gitsigns
used to have a similar problem, perhaps gitsigns issue #238 will provide a clue how to fix it?
It would be great to have a whitespace provider like in galaxyline
It is a very useful feature and I feel its complex enough for it be included as a provider.
Great plugin.
I am trying to set my highlights via my colorscheme. Since feline only defines highlights on demand (afaict), any I define get clobbered.
I am using Lush, so it's actually not that big a deal to just import the theme data into feline and do it but given I can set the name, maybe you could check if the given name exists before defining it?
I can see a few ways to do this:
Check via vim.fn.hlexists()
-- Add highlight of component
local function add_component_highlight(name, fg, bg, style)
local hlname = 'StatusComponent' .. name
-- check via vim.fn.hlexists,
-- may incur some viml bridge cost so perhaps checking
-- and memoising the result into highlights[hlname] so future
-- checks are speedy?
if highlights[hlname] or (vim.fn.hlexists(hlname) == 1) then
-- i.e highlights[hlname] = "externally_defined"
return hlname
else
cmd(string.format('highlight %s gui=%s guifg=%s guibg=%s', hlname, style, fg, bg))
highlights[hlname] = true
return hlname
end
end
Allow for the hl
option be a string or function that returns a string
If hl
is a string, just apply the highlight given
components.left.active[1] = {
provider = 'file_type',
hl = "MyFileTypeGroup"
}
components.left.active[1] = {
provider = 'file_type',
hl = function() return "MyFileTypeGroup" end
}
local function parse_hl(hl)
if hl == {} then return defhl end
-- maybe prefix with StatusComponent, but probably just leave as given
-- since the user is being explicit about what they want and can namespace
-- the group themselves if they want
if type(hl) == "string" then return hl end
Don't generate a highlight group if no data is given
components.left.active[1] = {
provider = 'file_type',
hl = {
-- this will generate the group, with the
-- name StatusComponentMyGroup fg = red
fg = "red",
name = "MyGroup"
}
}
components.left.active[1] = {
provider = 'file_type',
hl = {
-- this will not redefine the group
name = "MyGroup"
}
}
I can submit a PR if you have a preferred method, probably #2 is neatest?
(I like the name.)
With newest version from master branch, I got following error message.
Highlight group 'Normal' has no background highlight.
Please provide an RGB hex value or highlight group with a background value for 'background_colour' option
Defaulting to #000000
Neovim version
NVIM v0.6.0-dev+262-g643cb8a6e
Feline version
0506b42
Describe the bug
It appears that all inactive statuslines use the current buffer for buffer options. For example, if there is one 'Lua' buffer and another 'Rust' buffer, and you are showing the vim.bo.ft
in the inactive statusline, it will show whichever file you are currently in on the inactive statusline rather than the inactive buffer's filetype.
To Reproduce
Steps to reproduce the behavior:
require('feline').setup(
{
components =
{
active =
{
-- Left
{},
-- Middle
{},
-- Right
{},
},
inactive =
{
-- Left
{},
-- Right
{{provider = function() return vim.bo.ft end}},
},
},
force_inactive =
{
bufnames = {},
buftypes = {'help', 'prompt', 'terminal'},
filetypes =
{
'dbui',
'diff',
'help',
'NvimTree',
'packer',
'peekaboo',
'qf',
'undotree',
'vista',
'vista_markdown',
},
},
})
foo.lua
file, then open foo.rs
in a new split.foo.lua
shows "rust" when in the Rust file, and the Rust file shows "Lua" when in the Lua file.Expected behavior
Use each inactive buffer separately as reference point for vim.bo
when generating status line.
Does this error occur in the minimal init file?
No, because the minimal file doesn't have a config scheme like this.
Provide modified minimal_init.lua
All that is needed is the minimal feline
setup command provided above.
NvimTree
buffer also is affected by the inactive statusline issue.Hey, thanks for the great statusline plugin!
I noticed that the git_diff_changed
icon is of a completely different style compared to the others. Here's a screenshot using the minimal init (thank you for that one btw, extremely handy):
It's the exact same icon I see over at
feline.nvim/lua/feline/providers/git.lua
Line 51 in fbd31ae
I use Fira Code Retina in Neovim v0.6.0-dev+1689-gdce50312e.
Neovim version
NVIM v0.5.0
Build type: Release
LuaJIT 2.0.5
Feline version
8c809b2 (latest as of now)
Describe the bug
Statusline is updated only in current window, so inactive statusline isn't updated. This is a problem because in the inactive part i put the window number (return value of vim.fn.winnr()
) to make easier to jump between windows with a keybinding (space+number). When deleting a window, for example, window numbers aren't updated, making navigation between windows difficult.
To Reproduce
<C-w>v
)<C-w>v
)<C-w>w
)<C-w>c
)If you jump to window 2 and come back to window 1 you'll see the number updated.
Expected behavior
Inactive windows should be updated.
I have some components that are only displayed on certain conditions and I don't want their separators to show if the component provider returns the empty string.
Right now, I could call the provider function again inside the separator function or set a variable, but both feel messy and unnecessary. It would be nice if the separator table could have a key omit_empty
which, if true, would cause the separator to be ignored in this case, e.g.:
config.components.active[2] = {
{
provider = 'lsp_clients_running',
hl = { fg = 'green' },
right_sep = { str = ' ', omit_empty = true },
},
{
provider = 'lsp_clients_exited_ok',
hl = { fg = 'lavender' },
right_sep = { str = ' ', omit_empty = true },
},
{
provider = 'lsp_clients_exited_err',
hl = { fg = 'red' },
right_sep = { str = ' ', omit_empty = true },
},
-- ...
}
My current solution (ugly, inefficient):
{
provider = 'lsp_clients_running',
hl = { fg = 'green' },
right_sep = function()
return {
str = user_lsp_status.clients_running() == '' and '' or ' '
}
end
},
{
provider = 'lsp_clients_exited_ok',
hl = { fg = 'lavender' },
right_sep = function()
return {
str = user_lsp_status.clients_exited_ok() == '' and '' or ' '
}
end
},
{
provider = 'lsp_clients_exited_err',
hl = { fg = 'red' },
right_sep = function()
return {
str = user_lsp_status.clients_exited_err() == '' and '' or ' '
}
end
},
-- ...
I was thinking of adding named components to Feline's. So basically, components could have an extra name
value, which could be used to access them directly from the components table without having to remember their index. It'd also help prevent code duplication in the plugin since noicons
preset is basically the default
preset with a few changes, we'd be able to just directly use the default
preset and make a few modifications to it using the component names to prevent code duplication. It'd also allow people to easily modify components without having to remember the index.
The problem is, I haven't found a single way to implement them that isn't horribly ineffecient (eg: something that doesn't involve searching every component whenever a name is used for access). I tried caching the names and using metatables for access but even then it isn't foolproof since newindex
only works for values that already don't exist, and using a proxy table prevents the table from being iterated using ipairs
, which is something that the statusline generator needs to do. Thoughts on it would be appreciated.
Neovim version
NVIM v0.5.0-dev+384f9870f
Feline version
ac91701f5a133f5c4eb763c604faa559c3afb587
Describe the bug
Can't load the plugin without nvim-web-devicons
To Reproduce
Install the plugin without nvim-web-devicons
Expected behavior
No load issues
Does this error occur in the minimal init file?
Probably not, because the minimal file contains it as dependency.
Screenshots
E5108: Error executing lua ...k/packer/start/feline.nvim/lua/feline/providers/file.lua:91: module 'nvim-web-devicons' not found:
no field package.preload['nvim-web-devicons']
no file './nvim-web-devicons.lua'
no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/luajit-2.1.0-beta3/nvim-web-devicons.lua'
no file '/usr/local/share/lua/5.1/nvim-web-devicons.lua'
no file '/usr/local/share/lua/5.1/nvim-web-devicons/init.lua'
no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/lua/5.1/nvim-web-devicons.lua'
no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/lua/5.1/nvim-web-devicons/init.lua'
no file '/Users/fladson/.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/nvim-web-devicons.lua'
no file '/Users/fladson/.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/nvim-web-devicons/init.lua'
no file '/Users/fladson/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/nvim-web-devicons.lua'
no file '/Users/fladson/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/nvim-web-devicons/init.lua'
no file './nvim-web-devicons.so'
no file '/usr/local/lib/lua/5.1/nvim-web-devicons.so'
no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/lib/lua/5.1/nvim-web-devicons.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
no file '/Users/fladson/.cache/nvim/packer_hererocks/2.1.0-beta3/lib/lua/5.1/nvim-web-devicons.so'
because the statusline is evaluated in the current window and buffer with %!
, every function, whether it is a provider, hl, icon, or separator, should have a handler to its original window, otherwise, doing something like
FileName = {
provider = function(component, winid),
return vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winid))
end,
hl = function()
if vim.bo.modified then return {fg = 'magenta', style = 'bold', name = 'StatusFileNameModified'}
else return {fg = 'purple', style = 'bold', name = 'StatusFileName'}
end
end
}
will not work, in the sense that the current buffer modified status will affect all the statuslines that display the FileName
component.
A workaround would be to set every field of the component from within the provider function, like this:
FileName = {
provider = function(component, winid),
if vim.bo[winid].modified then component.hl = {fg = 'magenta', style = 'bold', name = 'StatusFileNameModified'}
else component.hl = {fg = 'purple', style = 'bold', name = 'StatusFileName'}
end
return vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winid))
end,
}
but I think it's not very elegant, considering the plugin phylosophy. Also, the README.md should be clearer about functions being evaluated in the current window context (%!
)
Using a function in a table of separators is difficult. As far as I can can tell it appears to be explicitly disallowed here, at least as the first element:
feline.nvim/lua/feline/generator.lua
Line 135 in f659ae8
And it's not possible for a function to return a table of separators.
I can bodge things by having a table which has an empty string as the first element followed by functions, but this feels wrong.
Have I missed something, or is there room for improvement here?
Neovim version
NVIM v0.5.0-dev+1449-gbdf3df402
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-11 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include
Features: +acl +iconv +tui
Feline version
9977073d8f5c064785ff6b44aad30cbc6d887da0
Describe the bug
When quickfix window is activated, the statusline is not affected by feline. No active/inactive configuration is applied to statusline.
To Reproduce
Just call :copen
Neovim version
NVIM v0.5.0-dev+1414-g8cdffd42d-dirty
Build type: Gentoo
Lua 5.1
Compilation: /usr/bin/x86_64-pc-linux-gnu-gcc -O2 -pipe -march=native -mtune=native -fomit-frame-pointer -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/portage/portage/app-editors/neovim-9999/work/neovim-9999_build/config -I/home/portage/portage/app-editors/neovim-9999/work/neovim-9999/src -I/usr/include -I/home/portage/portage/app-editors/neovim-9999/work/neovim-9999_build/src/nvim/auto -I/home/portage/portage/app-editors/neovim-9999/work/neovim-9999_build/include
Compiled by portage@localhost
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "/etc/vim/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Feline version
9977073d8f5c064785ff6b44aad30cbc6d887da0
Describe the bug
Statusline is empty when using default feline theme
To Reproduce
Follow installation steps from readme
Expected behavior
Feline statusline not empty
Does this error occur in the minimal init file?
No.
Provide modified minimal_init.lua
I'm using paq instead of packer, here's minimal config when feline doesn't work
vim.cmd 'packadd paq-nvim'
local paq = require('paq-nvim').paq
paq 'famiu/feline.nvim'
require('feline').setup()
I'm loving this plugin! The documentation is excellent.
Currently, it seems like the circle
icon is the only option to show that a file is modified. What do you think about adding a configuration option to allow the circle
to be overwritten?
Not sure how you'd prefer to implement it, but I'd be happy to update the provider. I was thinking of adding a component option like file_modified_icon
, but then the component
table gets polluted just for file_info
.
Galaxyline and Lualine seem similar. I'd love to know at a glance how they differ from Feline
Some buffers really don't need a status line (e.g. NvimTree). It'd be a useful complement to force_inactive
to be able to specify buffers for which the whole statusline is completely hidden.
Would it be possible to have something like this?
custom_components = {
{
condition = table similar to force_inactives
components = active/inactive component table
},
{
condition = table similar to force_inactives
components = active/inactive component table
}, ...
}
This way, it is possible to differentiate between the statusline of inactive regular buffers and statusline of sidebar plugins.
But also will give full control on active/inactive statusline for every filetype.
At the moment it is possible to achieve this behavior by working on top of the provided interface, but I think having this built in would be a cool addition.
alternatively, exposing a function require('feline').create_statusline(component_list)
would be useful to manually create WinEnter
WinLeave
autocommands
Colored file icons would be nice to have, similar to galaxyline.
ref. This is how galaxyline does it .
Recently, I've been thinking of changing the format in which components are defined, which would obviously be a breaking change, though I plan to deprecate the current format first before removing it outright in order to give people a chance to switch.
Before, the component table had the left, mid and right tables inside of it and each of those tables had an 'active' table and an 'inactive' table inside of them. The new format would instead have the 'active' table and 'inactive' table directly inside the component table, with a variable amount of sections for the active and inactive statusline. So you're not limited to the 3 sections (left, mid and right) but instead can have 4 or even more sections. Another benefit is that it allows grouping active and inactive statusline elements together. Here's what it'd look like in code:
components = {
-- active statusline
active = {
-- left section
{
-- first component
{
-- insert component code here
},
-- second component
{
-- insert component code here
}
},
-- mid section
{
-- insert code for section components here
-- similarly to what was shown above in the code for the left section
},
-- right section
{
-- insert code for section components here
-- similarly to what was shown above in the code for the left section
}
},
-- inactive statusline
inactive = {
-- insert sections and section components here
-- similarly to what was shown above in the code for the active statusline
}
}
I feel like this change to the component table layout will make configuration simpler and more organized, while also adding flexibility. But I'm not 100% sure if I should implement it yet since this is going to be a breaking change. So I'd like other opinions on it if possible.
Is your feature request related to a problem? Please describe.
I would like to disable feline in all windows of nvim-dap-ui.
Describe the solution you'd like
I would like for feline to treat wildcard characters in the setup function properly:
disable = { filetypes = { "dapui*" } }
Feline seems to occasionally show the inactive statusline on the active window. It seems to happen randomly and I didn't find a pattern to it yet, but it only happens when I switch tabs through mouseclick using barbar.nvim. Need to find the cause of this.
Is your feature request related to a problem? Please describe.
express line can display messages from LSP which can be quite useful (https://github.com/tjdevries/express_line.nvim/blob/master/lua/el/plugins/lsp_status.lua).
Describe the solution you'd like
Add the same support (new provider) to feline.
Describe alternatives you've considered
I can imagine that being quite common use case eventually so having it provided (optionally) by plugin can help many users.
Additional context
Great looking plugin! I have tried galaxy line and had many problems, feline worked of the bat, thanks!
Neovim version
NVIM v0.5.0
Build type: Release
LuaJIT 2.0.5
Compilation: /usr/bin/cc -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -DNDEBUG -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/build/neovim/src/neovim-0.5.0/build/config -I/build/neovim/src/neovim-0.5.0/src -I/usr/include -I/build/neovim/src/neovim-0.5.0/build/src/nvim/auto -I/build/neovim/src/neovim-0.5.0/build/include
Compiled by builduser
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Feline version
v0.1.1
Describe the bug
I keep getting this error message every time I open neovim
, and feline
fails to load.
Error:
E5113: Error while calling lua chunk: ...acker/start/feline.nvim/lua/feline/providers/vi_mode.lua:45: attempt to index field 'vi_mode_colors' (a nil value)
To Reproduce
Open neovim
with a custom feline
config
Expected behavior
feline
should load correctly
Does this error occur in the minimal init file?
Yes, it occurs
Provide modified minimal_init.lua
-- Minimal init file to run Feline with the most basic functionality
-- Run from Feline top-level directory using:
-- nvim --noplugin -u minimal_init.lua
local function load_plugins()
local packer = require('packer')
local use = packer.use
packer.reset()
packer.init {
package_root = '/tmp/nvim/site/pack',
git = {
clone_timeout = -1
}
}
use 'wbthomason/packer.nvim'
use {
'famiu/feline.nvim',
requires = {
{
'lewis6991/gitsigns.nvim',
requires = { 'nvim-lua/plenary.nvim' },
config = function()
require('gitsigns').setup()
end
},
'kyazdani42/nvim-web-devicons'
}
}
packer.sync()
end
_G.load_config = function()
vim.opt.termguicolors = true
-- Replace this part of the config with whatever Feline configuration you're using
local lsp = require("feline.providers.lsp")
local vi_mode_utils = require("feline.providers.vi_mode")
local utils = require("utils")
local onedark_colours = utils.all_colours.onedark_colours
local nord_colours = utils.all_colours.nord_colours
--
-- COLOURS
--
local vi_mode_colors = {
['NORMAL'] = onedark_colours.green,
['OP'] = onedark_colours.green,
['INSERT'] = onedark_colours.red,
['VISUAL'] = onedark_colours.skyblue,
['BLOCK'] = onedark_colours.skyblue,
['REPLACE'] = onedark_colours.violet,
['V-REPLACE'] = onedark_colours.violet,
['ENTER'] = onedark_colours.cyan,
['MORE'] = onedark_colours.cyan,
['SELECT'] = onedark_colours.orange,
['COMMAND'] = onedark_colours.green,
['SHELL'] = onedark_colours.green,
['TERM'] = onedark_colours.green,
['NONE'] = onedark_colours.yellow
}
local components = {
active = {},
inactive = {}
}
-- left -> active[1]
-- mid -> active[2]
-- right -> active[3]
table.insert(components.active, {})
table.insert(components.active, {})
table.insert(components.active, {})
-- left -> active[1]
-- mid -> active[2]
-- right -> active[3]
table.insert(components.inactive, {})
table.insert(components.inactive, {})
table.insert(components.inactive, {})
--
-- LEFT COMPONENTS
--
table.insert(components.active[1], {
provider = "git_branch",
icon = " ",
hl = {
fg = "black",
bg = vi_mode_utils.get_mode_color(),
style = "bold"
},
right_sep = {
str = "right_filled",
hl = {
bg = nord_colours.nord3,
fg = vi_mode_utils.get_mode_color(),
style = "bold"
}
}
})
table.insert(components.active[1], {
provider = "git_diff_added",
hl = {
fg = "green",
bg = nord_colours.nord3
}
})
table.insert(components.active[1], {
provider = "git_diff_changed",
hl = {
fg = "orange",
bg = nord_colours.nord3
}
})
table.insert(components.active[1], {
provider = "git_diff_removed",
hl = {
fg = "red",
bg = nord_colours.nord3
},
right_sep = {
str = "right_filled",
hl = {
fg = nord_colours.nord3
}
}
})
table.insert(components.inactive[1], {
provider = " ",
icon = "",
})
--
-- MIDDLE COMPONENTS
--
table.insert(components.active[2], {
provider = "file_info",
icon = "",
type = "relative",
left_sep = "left"
})
table.insert(components.active[2], {
provider = "@"
})
table.insert(components.active[2], {
provider = "position",
left_sep = " ",
right_sep = "right",
})
table.insert(components.inactive[2], {
provider = "file_info",
icon = "",
type = "relative",
left_sep = "left",
right_sep = "right"
})
--
-- RIGHT COMPONENTS
--
table.insert(components.active[3], {
provider = "diagnostic_errors",
enabled = function() return lsp.diagnostics_exist("Error") end,
icon = "✖ ",
hl = { fg = "#FF0000" },
right_sep = " "
})
table.insert(components.active[3], {
provider = "diagnostic_warnings",
enabled = function() return lsp.diagnostics_exist("Warning") end,
icon = " ",
hl = { fg = "#F0F722" },
right_sep = " "
})
table.insert(components.active[3], {
provider = "diagnostic_info",
enabled = function() return lsp.diagnostics_exist("Information") end,
icon = " ",
hl = { fg = "#1176DB" },
right_sep = " "
})
table.insert(components.active[3], {
provider = "diagnostic_hints",
enabled = function() return lsp.diagnostics_exist("Hint") end,
icon = "ℍ ",
hl = { fg = "#C678DD" },
right_sep = " "
})
table.insert(components.active[3], {
provider = "file_encoding",
left_sep = {"left", " "},
right_sep = " ",
})
table.insert(components.active[3], {
provider = vim.bo.fileformat:upper(),
left_sep = {"left", " "},
right_sep = " ",
})
table.insert(components.active[3], {
provider = utils.get_buf_indentation_style,
left_sep = {"left", " "},
right_sep = " "
})
table.insert(components.active[3], {
provider = utils.get_asyncrun_running,
hl = {fg = nord_colours.nord4, bg = nord_colours.nord3, style = "bold"},
left_sep = {str = "left_filled", hl = {fg = nord_colours.nord3}}
})
table.insert(components.active[3], {
provider = utils.get_python_venv,
hl = {
fg = nord_colours.nord3,
bg = nord_colours.nord9,
style = "bold"
},
left_sep = {
{str = "left_filled", hl = {fg = nord_colours.nord9, bg = nord_colours.nord3}},
},
})
local colours = onedark_colours
colours.bg = nord_colours.nord1
colours.fg = "#D0D0D0"
require("feline").setup({
components = components,
colors = colours,
force_inactive = {
filetypes = {
"NvimTree",
"packer",
"startify",
"fugitive",
"fugitiveblame",
"dashboard"
},
buftypes = {
"terminal"
},
bufnames = {}
},
vi_mode_colors = vi_mode_colors
})
end
local install_path = '/tmp/nvim/site/pack/packer/start/packer.nvim'
vim.opt.packpath = {'/tmp/nvim/site'}
if vim.fn.isdirectory(install_path) == 0 then
vim.fn.system({'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path})
end
load_plugins()
vim.api.nvim_command('autocmd User PackerComplete ++once lua load_config()')
Additional context
The configuration used to work fine until I moved to v0.1.1
Neovim version
NVIM v0.5.0
Build type: Release
LuaJIT 2.1.0-beta3
Compilation:
Compiled by nixbld
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "
/nix/store/920i9s2jc9nvm8zqp8f214apf9wbm34p-neovim-unwrapped-0.5.0/share/nvim
"
Run :checkhealth for more info
Feline version
v0.1
Describe the bug
The plugin can not be initialised and used unless you have nvim-web-devicons
installed since this commit 6961f91
I beleive the correct course of action is to gate that code to ensure it doesn't execute unless the module is require-able.
To Reproduce
Install feline and open Neovim without nvim-web-devicons
installed.
In the line above, the number of percent should be padded to 2, not 3. The number can never hit 100%, so it's either of the form 5
or 50
. Together with the percentage sign we get 5%
or 50%
, which is now of the same length as Top
and Bot
, the other two possible outputs.
I was thinking that it'd be nice to have a config showcase section in the README like galaxyline does. So it would be nice if people could post their own configs and screenshots of their statusline in this thread
i want to show python virtual environment on feline (if virtual env is activated).
also is there any way to show lsp's status?
some times we start editing a file then if we try to save it it shows read only can you add a read only tag in feline that would be great
First of all, thank you so much for sharing this plugin with the Neovim community. I wanted to try out galaxyline.nvim, but I found it very hard to configure. With this plugin, I just copy-pasted one of the included configs and changed it till I like it. It's the perfect combination of power and ease of use. So thanks.
Now for my issue. Consider the following screenshot:
Those two splits clearly contain different files, but they are both named init.lua
, so the default file_info
provider shows them as the same (because it uses expand("%:t")
instead of expand("%")
). To be clear, I like this as the default, because the status line would get cluttered very quickly if it used the fully qualified path by default. But I am wondering if you have any ideas for how to avoid this in my personal config. I'm thinking like only show the tail (%:t
) normally, but if there are two buffers that have the same filename, add on the names of their parent folders until they are unique. For example, projects/example1/init.lua
and projects/example2/init.lua
would show only example1/init.lua
and example2/init.lua
, but example1/lua/init.lua
and example2/lua/init.lua
would have to show their entire paths because going up one level wouldn't make them unique.
Do you have any idea how to go about doing this?
Possibly tangentially related: #6
Neovim version
NVIM v0.6.0-dev+221-g47f99d664
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/config -I/home/mon/.local/cache/paru/clone/neovim-git/src/neovim-git/src -I/usr/include -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/src/nvim/auto -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/include
Compiled by mon@artix-pc
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Feline version
3278e3f
Describe the bug
After trying one of the configurations given in the README.md, I get a warning message relating to the deprecated component style. It seemed simple enough to implement, so I simply replaced
local components = {
left = {
active = {
comps.vi_mode.left,
comps.file.info,
comps.lsp.name,
comps.diagnos.err,
comps.diagnos.warn,
comps.diagnos.hint,
comps.diagnos.info
},
inactive = {
comps.vi_mode.left,
comps.file.info
}
},
mid = {
active = {},
inactive = {}
},
right = {
active = {
comps.git.add,
comps.git.change,
comps.git.remove,
comps.file.os,
comps.git.branch,
comps.line_percentage,
comps.scroll_bar,
comps.vi_mode.right
},
inactive = {}
}
}
with:
local components = {
active = {
left = {
comps.vi_mode.left,
comps.file.info,
comps.lsp.name,
comps.diagnos.err,
comps.diagnos.warn,
comps.diagnos.hint,
comps.diagnos.info
},
right = {
comps.git.add,
comps.git.change,
comps.git.remove,
comps.file.os,
comps.git.branch,
comps.line_percentage,
comps.scroll_bar,
comps.vi_mode.right
}
},
inactive = {
left = {
comps.vi_mode.left,
comps.file.info
},
}
}
Yet... Nothing was displaying on the status bar, it was simply just a bar of a solid color.
Expected behavior
The exact same bar, except I wouldn't get the warning.
Does this error occur in the minimal init file?
Yes.
Provide modified minimal_init.lua
https://termbin.com/6lx2
Screenshots
https://imgur.com/a/olG43Jy
I like the name
Is your feature request related to a problem? Please describe.
Hi, thanks for the plugin. I am currently trying to give different highlight to the filename depending if the file is modified. However, unlike provider which takes in winid
as an argument, it seems like highlight function changes the highlighting globally for all statusbars for the buffers.
Describe the solution you'd like
I wish the highlight function can take in a winid as well, so that I am only modifying the statusbar for one particular buffer.
Describe alternatives you've considered
So inorder to achieve the different coloring, I use the vim.bo.modified
. Here is my code.
table.insert(components.active, {})
table.insert(components.active, {})
table.insert(components.inactive, {})
table.insert(components.inactive, {})
local split = function(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t = {}
for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
table.insert(t, str)
end
return t
end
local ins_left = function(component)
table.insert(components.active[1], component)
end
local ins_right = function(component)
table.insert(components.active[#components.active], component)
end
local short_ins_left = function(component)
table.insert(components.inactive[1], component)
end
local short_ins_right = function(component)
table.insert(components.inactive[#components.active], component)
end
local file_path = {
provider = function(_, winid)
local filepath = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winid)), ":~:.")
local splitpath = split(filepath, "/")
splitpath[#splitpath] = ""
filepath = table.concat(splitpath, "/")
return filepath
end,
hl = function()
local res = {
fg = colors.yellow,
style = "bold",
}
if vim.bo.modifiable and vim.bo.modified then
res.fg = colors.red
end
return res
end,
}
ins_left(file_path)
local file_name = {
provider = function(_, winid)
return fn.fnamemodify(vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winid)), ":t")
end,
hl = function()
local res = {
fg = colors.fg,
style = "bold",
}
if vim.bo.modifiable and vim.bo.modified then
res.fg = colors.red
end
return res
end,
icon = "",
}
ins_left(file_name)
short_ins_left(file_path)
short_ins_left(file_name)
However, this code not only modify the current buffer statusline, it also modifies other buffers as well. I think this can be solved with vim.bo[bufnr].modified
, hence I wish there is an option for winid
.
Additional context
Before modifying feline.lua buffer.
After modifying feline.lua buffer.
After jumping to galaxyline buffer and jumping back to feline.lua
So the inactive buffer gets updated when trigger events happen, and the inactive buffer will be red when the active buffer is modified.
I don't know why, but it just blinks once and then disappears.
My config can be found here.
In fact, I just use
require'feline'.setup()
When I run :checkhealth
, feline works on new buffer until Running healthchecks...
disappears. Then feline also disappears.
Neovim version
NVIM v0.6.0-dev+227-gc1f573fbc
Feline version
5d152e2
Describe the bug
I don't know what I'm doing
To Reproduce
Steps to reproduce the behavior:
components.active[3][1] = { provider = function() local timer = vim.loop.new_timer() timer:start(0,1000,vim.schedule_wrap(function() return(os.date("%d %b %Y %H:%M:%S")) end)) end, }
:luafile %
.Expected behavior
I expected it to print the time in the bottom right in the bar. What am I doing wrong?
Does this error occur in the minimal init file?
Yes it does
Additional context
It's using an inline custom component, so maybe there's a parsing error with it?
Is your feature request related to a problem? Please describe.
Users define LSP signs. These signs usually shows up in the sign column and other related LSP UI. Would be nice to have feline use these defined signs by default.
Describe the solution you'd like
Have an options similar to trouble called use_lsp_diagnostic_signs
where it gets the defined signs and use it as default icon.
Describe alternatives you've considered
No alternative at the moment. Users need to set the symbols manually to be similar to the LSP defined signs.
Additional context
Example configuration from Trouble https://github.com/folke/trouble.nvim#setup
use_lsp_diagnostic_signs = false -- enabling this will use the signs defined in your lsp client
Is it possible to set a different highlighting for a component's icon?
If not I think it would be great if their highlighting were configurable just like how the separators are configured. I.e. something like this:
table.insert(components.right.active, {
provider = 'git_branch',
hl = { bg = 'line_bg' },
icon = {
str = ' '
hi = {fg = 'orange'}
}
})
Is your feature request related to a problem? Please describe.
Not really a problem, but it can get really annoying.
Here you can see how the elements shift when the position element changes its width
Describe the solution you'd like
The components should have a fixed width and it shouldn't be affected by others components. I think that the only components that need modification are the position and probably the progress bar. Because all of the other things in the statusline are static, they never change, like the filename (they can change but not every time you move through the file). The components making the whole statusline to shift are the position ones, since they can change its width when you move through the file.
Describe alternatives you've considered
One example where this does not happen is lualine. The elements don't shift when they change its width.
Compare the two, and I think you can see how annoying it can get to have the statusline changing its position when you move through the file. However this is not a big deal, it's not like me or most people are staring at the statusline the whole time, but nonetheless it would be nice if this doesn't happen.
Neovim version
NVIM v0.5.0
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/lib/ccache/bin/cc -fstack-clash-protection -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -g -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/builddir/neovim-0.5.0/build/config -I/builddir/neovim-0.5.0/src -I/usr/include -I/builddir/neovim-0.5.0/build/src/nvim/auto -I/builddir/neovim-0.5.0/build/include
Compiled by void-buildslave@a-hel-fi
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Feline version
Up-to-date master
branch
Describe the bug
When setting opts
for file_info
provider, the file icon doesn't appear, even though icon
is not set to anything.
To Reproduce
Setting file_info
with opts
. For example:
require('feline').setup {
components = {
active = {
{
{
provider = {
name = 'file_info',
opts = {
-- Set anything here
type = 'unique'
}
},
-- Don't set icon
hl = { fg = '#61afef', style = 'bold'},
right_sep = ' '
}
},
{}, {}
},
inactive = {}
}
}
Expected behavior
There is a file icon appear before the file name (the same as normally setting provider = 'file_info'
)
Does this error occur in the minimal init file?
Yes
Provide modified minimal_init.lua
See the reproduce part above
Screenshots
Additional context
I've only used feline.nvim
for a day, so if this is the intentional behavior, sorry for a stupid bug report :)
Neovim version
NVIM v0.6.0-dev+284-gc2a65921d
Build type: RelWithDebInfo
LuaJIT 2.0.5
Compilation: /usr/bin/cc -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/config -I/home/mon/.local/cache/paru/clone/neovim-git/src/neovim-git/src -I/usr/include -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/src/nvim/auto -I/home/mon/.local/cache/paru/clone/neovim-git/src/build/include
Compiled by mon@artix-pc
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info
Feline version
Newest version via PlugUpdate
Describe the bug
Essentially, upon including the disable
table into the setup function (i happen to have the force_inactive
table as well), then quitting and restarting; I receive an error:
E5108: Error executing lua vim/shared.lua:183: t: expected table, got nil
stack traceback:
vim/shared.lua:183: in function 'tbl_contains'
.../share/nvim/plugged/feline.nvim/lua/feline/generator.lua:35: in function 'is_disabled'
.../share/nvim/plugged/feline.nvim/lua/feline/generator.lua:259: in function <.../share/nvim/plugged/feline.nvim/lua/feline/generator.lua:256>
To Reproduce
disable = {
filetypes = {
'NvimTree'
}
}
Expected behavior
It'd allow me to disable the statusline for that specific filetype
Does this error occur in the minimal init file?
Yes.
Provide modified minimal_init.lua
https://termbin.com/pfpw
and here's colors.lua if needed:
https://termbin.com/gpfe
Neovim version
The output of nvim --version
.
0.5 release
Feline version
cd
to the directory containing Feline and use git rev-parse HEAD
, and put the output of that here.
cfc0ecf
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Does this error occur in the minimal init file?
Use the following commands to download the minimal init file provided by Feline:
curl -fLO https://raw.githubusercontent.com/famiu/feline.nvim/master/minimal_init.lua
Modify the file to your needs (if necessary), then load Neovim using:
nvim -u minimal_init.lua
And check if your issue still occurs.
Provide modified minimal_init.lua
If you modified the minimal_init.lua that Feline provides by default in order to fit your configuration, put it here. Otherwise ignore this part.
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
Add any other context about the problem here (eg: other plugins that may conflict with this plugin, configuration options that you think might cause the issue, etc.).
I'm willing to give this another shot. But first, we'd have to plan how truncation actually works. How do we decide when to truncate, which components to truncate, and where to truncate the components, and how do we allow the provider to affect the truncation? We need to plan out a good blueprint for truncation before we can implement it, so I'd like the input of as many people as possible.
@ram02z you seemed to have ideas for truncation as well, I'd be interested in hearing them out again. @Melkster how would you want truncation to work?
Neovim version
NVIM v0.5.0
Build type: Release
LuaJIT 2.1.0-beta3
Compilation: clang -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -O2 -DNDEBUG -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/tmp/neovim-20210702-14987-rep9di/neovim-0.5.0/build/config -I/tmp/neovim-20210702-14987-rep9di/neovim-0.5.0/src -I/usr/local/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/usr/local/opt/gettext/include -I/tmp/neovim-20210702-14987-rep9di/neovim-0.5.0/build/src/nvim/auto -I/tmp/neovim-20210702-14987-rep9di/neovim-0.5.0/build/include
Compiled by brew@BigSur
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/local/Cellar/neovim/0.5.0/share/nvim"
Feline version
Current master.
Describe the bug
E5108: Error executing lua ...k/packer/start/feline.nvim/lua/feline/providers/file.lua:97: module 'nvim-web-devicons' not found:
no field package.preload['nvim-web-devicons']No cache entry
To Reproduce
Steps to reproduce the behavior:
I don't have web-devicons installed. Just use the basic setup {}
.
Expected behavior
Should work without devicons installed since it's optional.
I wondered if anyone has come up with a nice way of toggling colors with feline.nvim when changing their color scheme/theme?
Right now I have a hacked up method that reloads my feline config when the theme changes (via an autocommand), including loading of colors. But this only seems to work a couple of times before stopping altogether:
For reference, my relevant code is:
--statusline.lua file
local M = {}
-- Load the correct colour palette
local function load_colors()
local colors = require('themes')
if vim.g.theme == 'onedark' then
return colors.onedark
else
return colors.onelight
end
end
-- Setup our feline statusline
function M.__load()
M.colors = load_colors()
-- Set our components here
-- Omitted from this example but included a link below!
require('feline').setup({
preset = 'noicon',
default_fg = M.colors.fg,
default_bg = M.colors.bg,
vi_mode_colors = M.vi_mode_colors,
components = M.components,
properties = M.properties
})
end
return M
--autocmds.lua file
if pcall(require, 'feline') then
utils.augroup({refresh_statusline_colors = {{'ColorScheme', '*', "lua require('plugins.configs.statusline').__load()"}}})
end
My full feline config can be found here, FYI.
I recently found this issue on the Neovim repo and it got me thinking if we should switch to Semantic Versioning for Feline. It'd give users better control over what features they want at a certain time and also prevent users from accidentally installing breaking changes. But I'm wondering if that'll be worth the extra work it comes with. I'd like other thoughts on this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.