Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #222 from feline-nvim/develop
Browse files Browse the repository at this point in the history
v1.0
  • Loading branch information
famiu authored Feb 13, 2022
2 parents e54e0cc + a318fbe commit 7ddd3f0
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 30 deletions.
58 changes: 58 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,18 @@ end

If you omit the provider value, it will be set to an empty string. A component with no provider or an empty provider may be useful for things like [applying a highlight to section gaps](#highlight-section-gaps) or just having an icon or separator as a component.

#### Component name

A component can optionally be given a name. While the component is not required to have a name and the name is mostly useless, it can be used to check if the component has been [truncated](#truncation). To give a component a name, just set its `name` value to a `string`, shown below:

```
local my_component = {
name = 'a_unique_name'
}
```

Two components inside the `active` or `inactive` table cannot share the same name, so make sure to give all components unique names.

#### Truncation

Feline has an automatic smart truncation system where components can be automatically truncated if the statusline doesn't fit within the window. It can be useful if you want to make better use of screen space. It also allows you to better manage which providers are truncated, how they are truncated and in which order they are truncated.
Expand Down Expand Up @@ -228,6 +240,10 @@ local high_priority_component = {

Priority can also be set to a negative number, which can be used to make a component be truncated earlier than the ones with default priority.

##### Check if component is truncated or hidden

If you give a component a `name`, you can check if that component has been truncated or hidden by Feline's smart truncation system through the utility functions, `require('feline').is_component_truncated` and `require('feline').is_component_hidden`. Both of these functions take two arguments, `winid` which is the window id of the window for which the component's truncation is being checked, the second is the `name` of the component. `is_component_truncated` returns `true` if a component has been truncated or hidden, and `is_component_hidden` returns `true` only if a component has been hidden.

#### Conditionally enable components

The `enabled` value of a component can be a boolean or function. This value determines if the component is enabled or not. If false, the component is not shown in the statusline. For example:
Expand Down Expand Up @@ -464,6 +480,37 @@ Now that you know about the components table and how Feline components work, you

- `preset` - Set it to use a preconfigured statusline. Currently it can be equal to either `default` for the default statusline or `noicon` for the default statusline without icons. You don't have to put any of the other values if you use a preset, but if you do, your settings will override the preset's settings. To see more info such as how to modify a preset to build a statusline, see: [Modifying an existing preset](#3.-modifying-an-existing-preset)
- `components` - The [components table](#components).
- `conditional_components` - An array-like table containing conditionally enabled components tables, each element of the table must be a components table with an additional key, `condition`, which would be a function without arguments that returns a boolean value. If the function returns `true` for a certain window, then that components table will be used for the statusline of that window instead of the default components table. If multiple conditional components match a certain window, the first one in the table will be used. An example usage of this option is shown below:

```lua
conditional_components = {
{
-- Only use this components table for the 2nd window
condition = function()
return vim.api.nvim_win_get_number(0) == 2
end,
active = {
-- Components used for active window
},
inactive = {
-- Components used for inactive windows
},
},
{
-- Only use this components table for buffers of filetype 'lua'
condition = function()
return vim.api.nvim_buf_get_option(0, 'filetype') == 'lua'
end,
active = {
-- Components used for active window
},
inactive = {
-- Components used for inactive windows
},
}
}
```

- `custom_providers` - A table containing user-defined [provider functions](#component-providers). For example:

```lua
Expand Down Expand Up @@ -657,6 +704,17 @@ The `file_info` provider has some special provider options that can be passed th

<br>Default: `'base-only'`

### File Type

The file type provider has the following options:

- `filetype_icon` (boolean): Whether the file type icon is shown alongside the file type.
Default: `false`
- `colored_icon` (boolean): Determines whether file icon should use color inherited from `nvim-web-devicons`.<br>
Default: `true`
- `case` (string): The case of the file type string. Possible values are: `'uppercase'`, `'titlecase'` and `'lowercase'`.<br>
Default: `'uppercase'`

### Git

The git providers all require [gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim/), make sure you have it installed when you use those providers, otherwise they'll have no output.
Expand Down
81 changes: 81 additions & 0 deletions doc/feline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,28 @@ with no provider or an empty provider may be useful for things like
|feline-applying-a-highlight-to-section-gaps| or just having an icon or
separator as a component.

*feline-Component-name*

Component name A component can optionally be given a
name. While the component is not
required to have a name and the name is
mostly useless, it can be used to check
if the component has been
|feline-truncated|. To give a component
a name, just set its `name` value to a
`string`, shown below:


>
local my_component = {
name = 'a_unique_name'
}
<


Two components inside the `active` or `inactive` table cannot share the same
name, so make sure to give all components unique names.

*feline-Truncation*

Truncation Feline has an automatic smart truncation
Expand Down Expand Up @@ -332,6 +354,18 @@ are truncated later on. For example:
Priority can also be set to a negative number, which can be used to make a
component be truncated earlier than the ones with default priority.

CHECK IF COMPONENT IS TRUNCATED OR HIDDEN

If you give a component a `name`, you can check if that component has been
truncated or hidden by Feline’s smart truncation system through the utility
functions, `require('feline').is_component_truncated` and
`require('feline').is_component_hidden`. Both of these functions take two
arguments, `winid` which is the window id of the window for which the
component’s truncation is being checked, the second is the `name` of the
component. `is_component_truncated` returns `true` if a component has been
truncated or hidden, and `is_component_hidden` returns `true` only if a
component has been hidden.

*feline-Conditionally-enable-components*

Conditionally enable components The `enabled` value of a component can
Expand Down Expand Up @@ -646,6 +680,40 @@ listed below:

- `preset` - Set it to use a preconfigured statusline. Currently it can be equal to either `default` for the default statusline or `noicon` for the default statusline without icons. You don’t have to put any of the other values if you use a preset, but if you do, your settings will override the preset’s settings. To see more info such as how to modify a preset to build a statusline, see: |feline-modifying-an-existing-preset|
- `components` - The |feline-components-table|.
- `conditional_components` - An array-like table containing conditionally enabled components tables, each element of the table must be a components table with an additional key, `condition`, which would be a function without arguments that returns a boolean value. If the function returns `true` for a certain window, then that components table will be used for the statusline of that window instead of the default components table. If multiple conditional components match a certain window, the first one in the table will be used. An example usage of this option is shown below:


>
conditional_components = {
{
-- Only use this components table for the 2nd window
condition = function()
return vim.api.nvim_win_get_number(0) == 2
end,
active = {
-- Components used for active window
},
inactive = {
-- Components used for inactive windows
},
},
{
-- Only use this components table for buffers of filetype 'lua'
condition = function()
return vim.api.nvim_buf_get_option(0, 'filetype') == 'lua'
end,
active = {
-- Components used for active window
},
inactive = {
-- Components used for inactive windows
},
}
}
<



- `custom_providers` - A table containing user-defined |feline-provider-functions|. For example:


Expand Down Expand Up @@ -884,6 +952,19 @@ through the provider `opts`:
<br>Default: `'base-only'`


FILE TYPE ~

The file type provider has the following options:


- `filetype_icon` (boolean): Whether the file type icon is shown alongside the file type.
Default: `false`
- `colored_icon` (boolean): Determines whether file icon should use color inherited from `nvim-web-devicons`.<br>
Default: `true`
- `case` (string): The case of the file type string. Possible values are: `'uppercase'`, `'titlecase'` and `'lowercase'`.<br>
Default: `'uppercase'`


GIT ~

The git providers all require gitsigns.nvim
Expand Down
3 changes: 3 additions & 0 deletions lua/feline/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ return {
components = {
type = 'table',
},
conditional_components = {
type = 'table',
},
preset = {
type = 'string',
},
Expand Down
75 changes: 69 additions & 6 deletions lua/feline/generator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ local feline = require('feline')
local M = {
-- Cached highlights
highlights = {},
-- Used to check if a certain component is truncated
component_truncated = {},
-- Used to check if a certain component is hidden
component_hidden = {},
}

-- Return true if any pattern in tbl matches provided value
Expand Down Expand Up @@ -320,6 +324,7 @@ end
-- Wrapper around parse_component that handles any errors that happen while parsing the components
-- and points to the location of the component in case of any errors
local function parse_component_handle_errors(
winid,
component,
use_short_provider,
statusline_type,
Expand All @@ -331,10 +336,11 @@ local function parse_component_handle_errors(
if not ok then
api.nvim_err_writeln(
string.format(
"Feline: error while processing component number %d on section %d of type '%s': %s",
"Feline: error while processing component number %d on section %d of type '%s' for window %d: %s",
component_number,
component_section,
statusline_type,
winid,
result
)
)
Expand All @@ -358,10 +364,35 @@ end

-- Generate statusline by parsing all components and return a string
function M.generate_statusline(is_active)
if not feline.components or is_disabled() then
local components
local winid = api.nvim_get_current_win()

M.component_truncated[winid] = {}
M.component_hidden[winid] = {}

if is_disabled() then
return ''
end

-- If a condition for one of the conditional components is satisfied, use those components
if feline.conditional_components then
for _, v in ipairs(feline.conditional_components) do
if v.condition() then
components = v
break
end
end
end

-- If none of the conditional components match, use the default components
if not components then
if feline.components then
components = feline.components
else
return ''
end
end

local statusline_type

if is_active and not is_forced_inactive() then
Expand All @@ -370,7 +401,7 @@ function M.generate_statusline(is_active)
statusline_type = 'inactive'
end

local sections = feline.components[statusline_type]
local sections = components[statusline_type]

if not sections then
return ''
Expand All @@ -388,8 +419,23 @@ function M.generate_statusline(is_active)
component_widths[i] = {}

for j, component in ipairs(section) do
local component_str = parse_component_handle_errors(component, false, statusline_type, i, j)
if component.name then
if M.component_truncated[winid][component.name] ~= nil then
api.nvim_err_writeln(
string.format(
'Feline: error while parsing components for window %d: '
.. "Multiple components with name '%s'",
winid,
component.name
)
)
return ''
end
M.component_truncated[winid][component.name] = false
M.component_hidden[winid][component.name] = false
end

local component_str = parse_component_handle_errors(winid, component, false, statusline_type, i, j)
local component_width = get_component_width(component_str)

component_strs[i][j] = component_str
Expand Down Expand Up @@ -421,7 +467,14 @@ function M.generate_statusline(is_active)
local component = sections[section][number]

if component.short_provider then
local component_str = parse_component_handle_errors(component, true, statusline_type, section, number)
local component_str = parse_component_handle_errors(
winid,
component,
true,
statusline_type,
section,
number
)

local component_width = get_component_width(component_str)

Expand All @@ -435,6 +488,10 @@ function M.generate_statusline(is_active)
statusline_width = statusline_width - width_difference
component_strs[section][number] = component_str
component_widths[section][number] = component_width

if component.name then
M.component_truncated[winid][component.name] = true
end
end
end

Expand All @@ -449,11 +506,17 @@ function M.generate_statusline(is_active)
if statusline_width > window_width then
for _, indices in ipairs(component_indices) do
local section, number = indices[1], indices[2]
local component = sections[section][number]

if sections[section][number].truncate_hide then
if component.truncate_hide then
statusline_width = statusline_width - component_widths[section][number]
component_strs[section][number] = ''
component_widths[section][number] = 0

if component.name then
M.component_truncated[winid][component.name] = true
M.component_hidden[winid][component.name] = true
end
end

if statusline_width <= window_width then
Expand Down
22 changes: 22 additions & 0 deletions lua/feline/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,26 @@ function M.use_theme(name_or_tbl)
M.reset_highlights()
end

-- Check if component with `name` in the statusline of window `winid` is truncated or hidden
function M.is_component_truncated(winid, name)
if gen.component_truncated[winid][name] == nil then
api.nvim_err_writeln(string.format("Component with name '%s' not found", name))
return
end

return gen.component_truncated[winid][name]
end

-- Check if component with `name` in the statusline of window `winid` is hidden
function M.is_component_hidden(winid, name)
if gen.component_hidden[winid][name] == nil then
api.nvim_err_writeln(string.format("Component with name '%s' not found", name))
return
end

return gen.component_hidden[winid][name]
end

-- Setup Feline using the provided configuration options
function M.setup(config)
-- Check if Neovim version is 0.5 or greater
Expand Down Expand Up @@ -189,6 +209,8 @@ function M.setup(config)
M.use_preset(preset)
end

M.conditional_components = config.conditional_components

-- Ensures custom quickfix statusline isn't loaded
g.qf_disable_statusline = true

Expand Down
Loading

0 comments on commit 7ddd3f0

Please sign in to comment.