├── LICENSE ├── README.md ├── doc └── mini-statusline.txt └── lua └── mini └── statusline.lua /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Evgeni Chasnovski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [![GitHub license](https://badgen.net/github/license/echasnovski/mini.nvim)](https://github.com/echasnovski/mini.nvim/blob/main/LICENSE) 5 | 6 | 7 | ### Minimal and fast statusline module with opinionated default look 8 | 9 | See more details in [Features](#features) and [help file](doc/mini-statusline.txt). 10 | 11 | --- 12 | 13 | ⦿ This is a part of [mini.nvim](https://github.com/echasnovski/mini.nvim) library. Please use [this link](https://github.com/echasnovski/mini.nvim/blob/main/README.md) if you want to mention this module. 14 | 15 | ⦿ All contributions (issues, pull requests, discussions, etc.) are done inside of 'mini.nvim'. 16 | 17 | ⦿ See the repository page to learn about common design principles and configuration recipes. 18 | 19 | --- 20 | 21 | If you want to help this project grow but don't know where to start, check out [contributing guides of 'mini.nvim'](https://github.com/echasnovski/mini.nvim/blob/main/CONTRIBUTING.md) or leave a Github star for 'mini.nvim' project and/or any its standalone Git repositories. 22 | 23 | ## Demo 24 | 25 | https://user-images.githubusercontent.com/24854248/173045208-42463c8f-a2ac-488d-9d30-216891f4bb51.mp4 26 | 27 | ## Features 28 | 29 | - Define own custom statusline structure for active and inactive windows. This is done with a function which should return string appropriate for |statusline|. Its code should be similar to default one with structure: 30 | - Compute string data for every section you want to be displayed. 31 | - Combine them in groups with `MiniStatusline.combine_groups()`. 32 | - Built-in active mode indicator with colors. 33 | - Sections can hide information when window is too narrow (specific window width is configurable per section). 34 | 35 | ## Dependencies 36 | 37 | For full experience needs (still works without any of suggestions): 38 | 39 | - [Nerd font](https://www.nerdfonts.com/) and enabled ['mini.icons'](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-icons.md) module to show filetype icons. Can fall back to using [nvim-tree/nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) plugin. 40 | 41 | - Enabled ['mini.git'](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-git.md) and ['mini.diff'](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-diff.md) modules to show Git and diff related information. Can fall back to using [lewis6991/gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim) plugin. 42 | 43 | ## Installation 44 | 45 | This plugin can be installed as part of 'mini.nvim' library (**recommended**) or as a standalone Git repository. 46 | 47 | There are two branches to install from: 48 | 49 | - `main` (default, **recommended**) will have latest development version of plugin. All changes since last stable release should be perceived as being in beta testing phase (meaning they already passed alpha-testing and are moderately settled). 50 | - `stable` will be updated only upon releases with code tested during public beta-testing phase in `main` branch. 51 | 52 | Here are code snippets for some common installation methods (use only one): 53 | 54 |
55 | With mini.deps 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
Github repoBranch Code snippet
'mini.nvim' library Main Follow recommended 'mini.deps' installation
Stable
Standalone plugin Main add('echasnovski/mini.statusline')
Stable add({ source = 'echasnovski/mini.statusline', checkout = 'stable' })
78 |
79 | 80 |
81 | With folke/lazy.nvim 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |
Github repoBranch Code snippet
'mini.nvim' libraryMain { 'echasnovski/mini.nvim', version = false },
Stable { 'echasnovski/mini.nvim', version = '*' },
Standalone pluginMain { 'echasnovski/mini.statusline', version = false },
Stable { 'echasnovski/mini.statusline', version = '*' },
106 |
107 | 108 |
109 | With junegunn/vim-plug 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 |
Github repoBranch Code snippet
'mini.nvim' libraryMain Plug 'echasnovski/mini.nvim'
Stable Plug 'echasnovski/mini.nvim', { 'branch': 'stable' }
Standalone plugin Main Plug 'echasnovski/mini.statusline'
Stable Plug 'echasnovski/mini.statusline', { 'branch': 'stable' }
133 |
134 | 135 |
136 | 137 | **Important**: don't forget to call `require('mini.statusline').setup()` to enable its functionality. 138 | 139 | **Note**: if you are on Windows, there might be problems with too long file paths (like `error: unable to create file : Filename too long`). Try doing one of the following: 140 | - Enable corresponding git global config value: `git config --system core.longpaths true`. Then try to reinstall. 141 | - Install plugin in other place with shorter path. 142 | 143 | ## Default config 144 | 145 | ```lua 146 | -- No need to copy this inside `setup()`. Will be used automatically. 147 | { 148 | -- Content of statusline as functions which return statusline string. See 149 | -- `:h statusline` and code of default contents (used instead of `nil`). 150 | content = { 151 | -- Content for active window 152 | active = nil, 153 | -- Content for inactive window(s) 154 | inactive = nil, 155 | }, 156 | 157 | -- Whether to use icons by default 158 | use_icons = true, 159 | } 160 | ``` 161 | 162 | ## Similar plugins 163 | 164 | - [nvim-lualine/lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) 165 | -------------------------------------------------------------------------------- /doc/mini-statusline.txt: -------------------------------------------------------------------------------- 1 | *mini.statusline* Statusline 2 | *MiniStatusline* 3 | 4 | MIT License Copyright (c) 2021 Evgeni Chasnovski 5 | 6 | ============================================================================== 7 | 8 | Features: 9 | - Define own custom statusline structure for active and inactive windows. 10 | This is done with a function which should return string appropriate for 11 | |statusline|. Its code should be similar to default one with structure: 12 | - Compute string data for every section you want to be displayed. 13 | - Combine them in groups with |MiniStatusline.combine_groups()|. 14 | 15 | - Built-in active mode indicator with colors. 16 | 17 | - Sections can hide information when window is too narrow (specific window 18 | width is configurable per section). 19 | 20 | # Dependencies ~ 21 | 22 | Suggested dependencies (provide extra functionality, will work without them): 23 | 24 | - Nerd font (to support extra icons). 25 | 26 | - Enabled |MiniIcons| module for |MiniStatusline.section_fileinfo()|. 27 | Falls back to using 'nvim-tree/nvim-web-devicons' plugin or shows nothing. 28 | 29 | - Enabled |MiniGit| module for |MiniStatusline.section_git()|. 30 | Falls back to using 'lewis6991/gitsigns.nvim' plugin or shows nothing. 31 | 32 | - Enabled |MiniDiff| module for |MiniStatusline.section_diff()|. 33 | Falls back to using 'lewis6991/gitsigns.nvim' plugin or shows nothing. 34 | 35 | # Setup ~ 36 | 37 | This module needs a setup with `require('mini.statusline').setup({})` 38 | (replace `{}` with your `config` table). It will create global Lua table 39 | `MiniStatusline` which you can use for scripting or manually (with 40 | `:lua MiniStatusline.*`). 41 | 42 | See |MiniStatusline.config| for `config` structure and default values. For 43 | some content examples, see |MiniStatusline-example-content|. 44 | 45 | You can override runtime config settings locally to buffer inside 46 | `vim.b.ministatusline_config` which should have same structure as 47 | `MiniStatusline.config`. See |mini.nvim-buffer-local-config| for more details. 48 | 49 | # Highlight groups ~ 50 | 51 | Highlight depending on mode (second output from |MiniStatusline.section_mode|): 52 | * `MiniStatuslineModeNormal` - Normal mode. 53 | * `MiniStatuslineModeInsert` - Insert mode. 54 | * `MiniStatuslineModeVisual` - Visual mode. 55 | * `MiniStatuslineModeReplace` - Replace mode. 56 | * `MiniStatuslineModeCommand` - Command mode. 57 | * `MiniStatuslineModeOther` - other modes (like Terminal, etc.). 58 | 59 | Highlight used in default statusline: 60 | * `MiniStatuslineDevinfo` - for "dev info" group 61 | (|MiniStatusline.section_git| and |MiniStatusline.section_diagnostics|). 62 | * `MiniStatuslineFilename` - for |MiniStatusline.section_filename| section. 63 | * `MiniStatuslineFileinfo` - for |MiniStatusline.section_fileinfo| section. 64 | 65 | Other groups: 66 | * `MiniStatuslineInactive` - highliting in not focused window. 67 | 68 | To change any highlight group, modify it directly with |:highlight|. 69 | 70 | # Disabling ~ 71 | 72 | To disable (show empty statusline), set `vim.g.ministatusline_disable` 73 | (globally) or `vim.b.ministatusline_disable` (for a buffer) to `true`. 74 | Considering high number of different scenarios and customization 75 | intentions, writing exact rules for disabling module's functionality is 76 | left to user. See |mini.nvim-disabling-recipes| for common recipes. 77 | 78 | ------------------------------------------------------------------------------ 79 | *MiniStatusline-example-content* 80 | Example content 81 | 82 | # Default content ~ 83 | 84 | This function is used as default value for active content: >lua 85 | 86 | function() 87 | local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) 88 | local git = MiniStatusline.section_git({ trunc_width = 40 }) 89 | local diff = MiniStatusline.section_diff({ trunc_width = 75 }) 90 | local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 }) 91 | local lsp = MiniStatusline.section_lsp({ trunc_width = 75 }) 92 | local filename = MiniStatusline.section_filename({ trunc_width = 140 }) 93 | local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 }) 94 | local location = MiniStatusline.section_location({ trunc_width = 75 }) 95 | local search = MiniStatusline.section_searchcount({ trunc_width = 75 }) 96 | 97 | return MiniStatusline.combine_groups({ 98 | { hl = mode_hl, strings = { mode } }, 99 | { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, 100 | '%<', -- Mark general truncate point 101 | { hl = 'MiniStatuslineFilename', strings = { filename } }, 102 | '%=', -- End left alignment 103 | { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } }, 104 | { hl = mode_hl, strings = { search, location } }, 105 | }) 106 | end 107 | < 108 | # Show boolean options ~ 109 | 110 | To compute section string for boolean option use variation of this code 111 | snippet inside content function (you can modify option itself, truncation 112 | width, short and long displayed names): >lua 113 | 114 | local spell = vim.wo.spell and (MiniStatusline.is_truncated(120) and 'S' or 'SPELL') or '' 115 | < 116 | Here `x and y or z` is a common Lua way of doing ternary operator: if `x` 117 | is `true`-ish then return `y`, if not - return `z`. 118 | 119 | ------------------------------------------------------------------------------ 120 | *MiniStatusline.setup()* 121 | `MiniStatusline.setup`({config}) 122 | Module setup 123 | 124 | Parameters ~ 125 | {config} `(table|nil)` Module config table. See |MiniStatusline.config|. 126 | 127 | Usage ~ 128 | >lua 129 | require('mini.statusline').setup() -- use default config 130 | -- OR 131 | require('mini.statusline').setup({}) -- replace {} with your config table 132 | < 133 | ------------------------------------------------------------------------------ 134 | *MiniStatusline.config* 135 | `MiniStatusline.config` 136 | Module config 137 | 138 | Default values: 139 | >lua 140 | MiniStatusline.config = { 141 | -- Content of statusline as functions which return statusline string. See 142 | -- `:h statusline` and code of default contents (used instead of `nil`). 143 | content = { 144 | -- Content for active window 145 | active = nil, 146 | -- Content for inactive window(s) 147 | inactive = nil, 148 | }, 149 | 150 | -- Whether to use icons by default 151 | use_icons = true, 152 | } 153 | < 154 | ------------------------------------------------------------------------------ 155 | *MiniStatusline.active()* 156 | `MiniStatusline.active`() 157 | Compute content for active window 158 | 159 | ------------------------------------------------------------------------------ 160 | *MiniStatusline.inactive()* 161 | `MiniStatusline.inactive`() 162 | Compute content for inactive window 163 | 164 | ------------------------------------------------------------------------------ 165 | *MiniStatusline.combine_groups()* 166 | `MiniStatusline.combine_groups`({groups}) 167 | Combine groups of sections 168 | 169 | Each group can be either a string or a table with fields `hl` (group's 170 | highlight group) and `strings` (strings representing sections). 171 | 172 | General idea of this function is as follows; 173 | - String group is used as is (useful for special strings like `%<` or `%=`). 174 | - Each table group has own highlighting in `hl` field (if missing, the 175 | previous one is used) and string parts in `strings` field. Non-empty 176 | strings from `strings` are separated by one space. Non-empty groups are 177 | separated by two spaces (one for each highlighting). 178 | 179 | Parameters ~ 180 | {groups} `(table)` Array of groups. 181 | 182 | Return ~ 183 | `(string)` String suitable for 'statusline'. 184 | 185 | ------------------------------------------------------------------------------ 186 | *MiniStatusline.is_truncated()* 187 | `MiniStatusline.is_truncated`({trunc_width}) 188 | Decide whether to truncate 189 | 190 | This basically computes window width and compares it to `trunc_width`: if 191 | window is smaller then truncate; otherwise don't. Don't truncate by 192 | default. 193 | 194 | Use this to manually decide if section needs truncation or not. 195 | 196 | Parameters ~ 197 | {trunc_width} `(number|nil)` Truncation width. If `nil`, output is `false`. 198 | 199 | Return ~ 200 | `(boolean)` Whether to truncate. 201 | 202 | ------------------------------------------------------------------------------ 203 | *MiniStatusline.section_mode()* 204 | `MiniStatusline.section_mode`({args}) 205 | Section for Vim |mode()| 206 | 207 | Short output is returned if window width is lower than `args.trunc_width`. 208 | 209 | Parameters ~ 210 | {args} `(table)` Section arguments. 211 | 212 | Return ~ 213 | `(...)` Section string and mode's highlight group. 214 | 215 | ------------------------------------------------------------------------------ 216 | *MiniStatusline.section_git()* 217 | `MiniStatusline.section_git`({args}) 218 | Section for Git information 219 | 220 | Shows Git summary from |MiniGit| (should be set up; recommended). To tweak 221 | formatting of what data is shown, modify buffer-local summary string directly 222 | as described in |MiniGit-examples|. 223 | 224 | If 'mini.git' is not set up, section falls back on 'lewis6991/gitsigns' data 225 | or showing empty string. 226 | 227 | Empty string is returned if window width is lower than `args.trunc_width`. 228 | 229 | Parameters ~ 230 | {args} `(table)` Section arguments. Use `args.icon` to supply your own icon. 231 | 232 | Return ~ 233 | `(string)` Section string. 234 | 235 | ------------------------------------------------------------------------------ 236 | *MiniStatusline.section_diff()* 237 | `MiniStatusline.section_diff`({args}) 238 | Section for diff information 239 | 240 | Shows diff summary from |MiniDiff| (should be set up; recommended). To tweak 241 | formatting of what data is shown, modify buffer-local summary string directly 242 | as described in |MiniDiff-diff-summary|. 243 | 244 | If 'mini.diff' is not set up, section falls back on 'lewis6991/gitsigns' data 245 | or showing empty string. 246 | 247 | Empty string is returned if window width is lower than `args.trunc_width`. 248 | 249 | Parameters ~ 250 | {args} `(table)` Section arguments. Use `args.icon` to supply your own icon. 251 | 252 | Return ~ 253 | `(string)` Section string. 254 | 255 | ------------------------------------------------------------------------------ 256 | *MiniStatusline.section_diagnostics()* 257 | `MiniStatusline.section_diagnostics`({args}) 258 | Section for Neovim's builtin diagnostics 259 | 260 | Shows nothing if diagnostics is disabled, no diagnostic is set, or for short 261 | output. Otherwise uses |vim.diagnostic.get()| to compute and show number of 262 | errors ('E'), warnings ('W'), information ('I'), and hints ('H'). 263 | 264 | Short output is returned if window width is lower than `args.trunc_width`. 265 | 266 | Parameters ~ 267 | {args} `(table)` Section arguments. Use `args.icon` to supply your own icon. 268 | Use `args.signs` to use custom signs per severity level name. For example: >lua 269 | 270 | { ERROR = '!', WARN = '?', INFO = '@', HINT = '*' } 271 | < 272 | Return ~ 273 | `(string)` Section string. 274 | 275 | ------------------------------------------------------------------------------ 276 | *MiniStatusline.section_lsp()* 277 | `MiniStatusline.section_lsp`({args}) 278 | Section for attached LSP servers 279 | 280 | Shows number of LSP servers (each as separate "+" character) attached to 281 | current buffer or nothing if none is attached. 282 | Nothing is shown if window width is lower than `args.trunc_width`. 283 | 284 | Parameters ~ 285 | {args} `(table)` Section arguments. Use `args.icon` to supply your own icon. 286 | 287 | Return ~ 288 | `(string)` Section string. 289 | 290 | ------------------------------------------------------------------------------ 291 | *MiniStatusline.section_filename()* 292 | `MiniStatusline.section_filename`({args}) 293 | Section for file name 294 | 295 | Show full file name or relative in short output. 296 | 297 | Short output is returned if window width is lower than `args.trunc_width`. 298 | 299 | Parameters ~ 300 | {args} `(table)` Section arguments. 301 | 302 | Return ~ 303 | `(string)` Section string. 304 | 305 | ------------------------------------------------------------------------------ 306 | *MiniStatusline.section_fileinfo()* 307 | `MiniStatusline.section_fileinfo`({args}) 308 | Section for file information 309 | 310 | Shows 'filetype', 'fileencoding' / 'encoding', 'fileformat', and buffer size. 311 | Short output has only non-empty 'filetype' and is returned if window width is 312 | lower than `args.trunc_width` or buffer is not normal (as per 'buftype'). 313 | 314 | Buffer size is computed based on current text, not file's saved version. 315 | 316 | If `config.use_icons` is true and icon provider is present (see 317 | "Dependencies" section in |mini.statusline|), shows icon near the filetype. 318 | 319 | Parameters ~ 320 | {args} `(table)` Section arguments. 321 | 322 | Return ~ 323 | `(string)` Section string. 324 | 325 | ------------------------------------------------------------------------------ 326 | *MiniStatusline.section_location()* 327 | `MiniStatusline.section_location`({args}) 328 | Section for location inside buffer 329 | 330 | Show location inside buffer in the form: 331 | - Normal: `'||'` 332 | - Short: `''` 333 | 334 | Short output is returned if window width is lower than `args.trunc_width`. 335 | 336 | Parameters ~ 337 | {args} `(table)` Section arguments. 338 | 339 | Return ~ 340 | `(string)` Section string. 341 | 342 | ------------------------------------------------------------------------------ 343 | *MiniStatusline.section_searchcount()* 344 | `MiniStatusline.section_searchcount`({args}) 345 | Section for current search count 346 | 347 | Show the current status of |searchcount()|. Empty output is returned if 348 | window width is lower than `args.trunc_width`, search highlighting is not 349 | on (see |v:hlsearch|), or if number of search result is 0. 350 | 351 | `args.options` is forwarded to |searchcount()|. By default it recomputes 352 | data on every call which can be computationally expensive (although still 353 | usually on 0.1 ms order of magnitude). To prevent this, supply 354 | `args.options = { recompute = false }`. 355 | 356 | Parameters ~ 357 | {args} `(table)` Section arguments. 358 | 359 | Return ~ 360 | `(string)` Section string. 361 | 362 | 363 | vim:tw=78:ts=8:noet:ft=help:norl: -------------------------------------------------------------------------------- /lua/mini/statusline.lua: -------------------------------------------------------------------------------- 1 | --- *mini.statusline* Statusline 2 | --- *MiniStatusline* 3 | --- 4 | --- MIT License Copyright (c) 2021 Evgeni Chasnovski 5 | --- 6 | --- ============================================================================== 7 | --- 8 | --- Features: 9 | --- - Define own custom statusline structure for active and inactive windows. 10 | --- This is done with a function which should return string appropriate for 11 | --- |statusline|. Its code should be similar to default one with structure: 12 | --- - Compute string data for every section you want to be displayed. 13 | --- - Combine them in groups with |MiniStatusline.combine_groups()|. 14 | --- 15 | --- - Built-in active mode indicator with colors. 16 | --- 17 | --- - Sections can hide information when window is too narrow (specific window 18 | --- width is configurable per section). 19 | --- 20 | --- # Dependencies ~ 21 | --- 22 | --- Suggested dependencies (provide extra functionality, will work without them): 23 | --- 24 | --- - Nerd font (to support extra icons). 25 | --- 26 | --- - Enabled |MiniIcons| module for |MiniStatusline.section_fileinfo()|. 27 | --- Falls back to using 'nvim-tree/nvim-web-devicons' plugin or shows nothing. 28 | --- 29 | --- - Enabled |MiniGit| module for |MiniStatusline.section_git()|. 30 | --- Falls back to using 'lewis6991/gitsigns.nvim' plugin or shows nothing. 31 | --- 32 | --- - Enabled |MiniDiff| module for |MiniStatusline.section_diff()|. 33 | --- Falls back to using 'lewis6991/gitsigns.nvim' plugin or shows nothing. 34 | --- 35 | --- # Setup ~ 36 | --- 37 | --- This module needs a setup with `require('mini.statusline').setup({})` 38 | --- (replace `{}` with your `config` table). It will create global Lua table 39 | --- `MiniStatusline` which you can use for scripting or manually (with 40 | --- `:lua MiniStatusline.*`). 41 | --- 42 | --- See |MiniStatusline.config| for `config` structure and default values. For 43 | --- some content examples, see |MiniStatusline-example-content|. 44 | --- 45 | --- You can override runtime config settings locally to buffer inside 46 | --- `vim.b.ministatusline_config` which should have same structure as 47 | --- `MiniStatusline.config`. See |mini.nvim-buffer-local-config| for more details. 48 | --- 49 | --- # Highlight groups ~ 50 | --- 51 | --- Highlight depending on mode (second output from |MiniStatusline.section_mode|): 52 | --- * `MiniStatuslineModeNormal` - Normal mode. 53 | --- * `MiniStatuslineModeInsert` - Insert mode. 54 | --- * `MiniStatuslineModeVisual` - Visual mode. 55 | --- * `MiniStatuslineModeReplace` - Replace mode. 56 | --- * `MiniStatuslineModeCommand` - Command mode. 57 | --- * `MiniStatuslineModeOther` - other modes (like Terminal, etc.). 58 | --- 59 | --- Highlight used in default statusline: 60 | --- * `MiniStatuslineDevinfo` - for "dev info" group 61 | --- (|MiniStatusline.section_git| and |MiniStatusline.section_diagnostics|). 62 | --- * `MiniStatuslineFilename` - for |MiniStatusline.section_filename| section. 63 | --- * `MiniStatuslineFileinfo` - for |MiniStatusline.section_fileinfo| section. 64 | --- 65 | --- Other groups: 66 | --- * `MiniStatuslineInactive` - highliting in not focused window. 67 | --- 68 | --- To change any highlight group, modify it directly with |:highlight|. 69 | --- 70 | --- # Disabling ~ 71 | --- 72 | --- To disable (show empty statusline), set `vim.g.ministatusline_disable` 73 | --- (globally) or `vim.b.ministatusline_disable` (for a buffer) to `true`. 74 | --- Considering high number of different scenarios and customization 75 | --- intentions, writing exact rules for disabling module's functionality is 76 | --- left to user. See |mini.nvim-disabling-recipes| for common recipes. 77 | 78 | --- Example content 79 | --- 80 | --- # Default content ~ 81 | --- 82 | --- This function is used as default value for active content: >lua 83 | --- 84 | --- function() 85 | --- local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) 86 | --- local git = MiniStatusline.section_git({ trunc_width = 40 }) 87 | --- local diff = MiniStatusline.section_diff({ trunc_width = 75 }) 88 | --- local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 }) 89 | --- local lsp = MiniStatusline.section_lsp({ trunc_width = 75 }) 90 | --- local filename = MiniStatusline.section_filename({ trunc_width = 140 }) 91 | --- local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 }) 92 | --- local location = MiniStatusline.section_location({ trunc_width = 75 }) 93 | --- local search = MiniStatusline.section_searchcount({ trunc_width = 75 }) 94 | --- 95 | --- return MiniStatusline.combine_groups({ 96 | --- { hl = mode_hl, strings = { mode } }, 97 | --- { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, 98 | --- '%<', -- Mark general truncate point 99 | --- { hl = 'MiniStatuslineFilename', strings = { filename } }, 100 | --- '%=', -- End left alignment 101 | --- { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } }, 102 | --- { hl = mode_hl, strings = { search, location } }, 103 | --- }) 104 | --- end 105 | --- < 106 | --- # Show boolean options ~ 107 | --- 108 | --- To compute section string for boolean option use variation of this code 109 | --- snippet inside content function (you can modify option itself, truncation 110 | --- width, short and long displayed names): >lua 111 | --- 112 | --- local spell = vim.wo.spell and (MiniStatusline.is_truncated(120) and 'S' or 'SPELL') or '' 113 | --- < 114 | --- Here `x and y or z` is a common Lua way of doing ternary operator: if `x` 115 | --- is `true`-ish then return `y`, if not - return `z`. 116 | ---@tag MiniStatusline-example-content 117 | 118 | ---@alias __statusline_args table Section arguments. 119 | ---@alias __statusline_section string Section string. 120 | 121 | -- Module definition ========================================================== 122 | local MiniStatusline = {} 123 | local H = {} 124 | 125 | --- Module setup 126 | --- 127 | ---@param config table|nil Module config table. See |MiniStatusline.config|. 128 | --- 129 | ---@usage >lua 130 | --- require('mini.statusline').setup() -- use default config 131 | --- -- OR 132 | --- require('mini.statusline').setup({}) -- replace {} with your config table 133 | --- < 134 | MiniStatusline.setup = function(config) 135 | -- TODO: Remove after Neovim=0.8 support is dropped 136 | if vim.fn.has('nvim-0.9') == 0 then 137 | vim.notify( 138 | '(mini.statusline) Neovim<0.9 is soft deprecated (module works but not supported).' 139 | .. ' It will be deprecated after next "mini.nvim" release (module might not work).' 140 | .. ' Please update your Neovim version.' 141 | ) 142 | end 143 | 144 | -- Export module 145 | _G.MiniStatusline = MiniStatusline 146 | 147 | -- Setup config 148 | config = H.setup_config(config) 149 | 150 | -- Apply config 151 | H.apply_config(config) 152 | 153 | -- Define behavior 154 | H.create_autocommands() 155 | 156 | -- - Disable built-in statusline in Quickfix window 157 | vim.g.qf_disable_statusline = 1 158 | 159 | -- Create default highlighting 160 | H.create_default_hl() 161 | end 162 | 163 | --- Module config 164 | --- 165 | --- Default values: 166 | ---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section) 167 | MiniStatusline.config = { 168 | -- Content of statusline as functions which return statusline string. See 169 | -- `:h statusline` and code of default contents (used instead of `nil`). 170 | content = { 171 | -- Content for active window 172 | active = nil, 173 | -- Content for inactive window(s) 174 | inactive = nil, 175 | }, 176 | 177 | -- Whether to use icons by default 178 | use_icons = true, 179 | } 180 | --minidoc_afterlines_end 181 | 182 | -- Module functionality ======================================================= 183 | --- Compute content for active window 184 | MiniStatusline.active = function() 185 | if H.is_disabled() then return '' end 186 | return (H.get_config().content.active or H.default_content_active)() 187 | end 188 | 189 | --- Compute content for inactive window 190 | MiniStatusline.inactive = function() 191 | if H.is_disabled() then return '' end 192 | return (H.get_config().content.inactive or H.default_content_inactive)() 193 | end 194 | 195 | --- Combine groups of sections 196 | --- 197 | --- Each group can be either a string or a table with fields `hl` (group's 198 | --- highlight group) and `strings` (strings representing sections). 199 | --- 200 | --- General idea of this function is as follows; 201 | --- - String group is used as is (useful for special strings like `%<` or `%=`). 202 | --- - Each table group has own highlighting in `hl` field (if missing, the 203 | --- previous one is used) and string parts in `strings` field. Non-empty 204 | --- strings from `strings` are separated by one space. Non-empty groups are 205 | --- separated by two spaces (one for each highlighting). 206 | --- 207 | ---@param groups table Array of groups. 208 | --- 209 | ---@return string String suitable for 'statusline'. 210 | MiniStatusline.combine_groups = function(groups) 211 | local parts = vim.tbl_map(function(s) 212 | if type(s) == 'string' then return s end 213 | if type(s) ~= 'table' then return '' end 214 | 215 | local string_arr = vim.tbl_filter(function(x) return type(x) == 'string' and x ~= '' end, s.strings or {}) 216 | local str = table.concat(string_arr, ' ') 217 | 218 | -- Use previous highlight group 219 | if s.hl == nil then return ' ' .. str .. ' ' end 220 | 221 | -- Allow using this highlight group later 222 | if str:len() == 0 then return '%#' .. s.hl .. '#' end 223 | 224 | return string.format('%%#%s# %s ', s.hl, str) 225 | end, groups) 226 | 227 | return table.concat(parts, '') 228 | end 229 | 230 | --- Decide whether to truncate 231 | --- 232 | --- This basically computes window width and compares it to `trunc_width`: if 233 | --- window is smaller then truncate; otherwise don't. Don't truncate by 234 | --- default. 235 | --- 236 | --- Use this to manually decide if section needs truncation or not. 237 | --- 238 | ---@param trunc_width number|nil Truncation width. If `nil`, output is `false`. 239 | --- 240 | ---@return boolean Whether to truncate. 241 | MiniStatusline.is_truncated = function(trunc_width) 242 | -- Use -1 to default to 'not truncated' 243 | local cur_width = vim.o.laststatus == 3 and vim.o.columns or vim.api.nvim_win_get_width(0) 244 | return cur_width < (trunc_width or -1) 245 | end 246 | 247 | -- Sections =================================================================== 248 | -- Functions should return output text without whitespace on sides. 249 | -- Return empty string to omit section. 250 | 251 | --- Section for Vim |mode()| 252 | --- 253 | --- Short output is returned if window width is lower than `args.trunc_width`. 254 | --- 255 | ---@param args __statusline_args 256 | --- 257 | ---@return ... Section string and mode's highlight group. 258 | MiniStatusline.section_mode = function(args) 259 | local mode_info = H.modes[vim.fn.mode()] 260 | 261 | local mode = MiniStatusline.is_truncated(args.trunc_width) and mode_info.short or mode_info.long 262 | 263 | return mode, mode_info.hl 264 | end 265 | 266 | --- Section for Git information 267 | --- 268 | --- Shows Git summary from |MiniGit| (should be set up; recommended). To tweak 269 | --- formatting of what data is shown, modify buffer-local summary string directly 270 | --- as described in |MiniGit-examples|. 271 | --- 272 | --- If 'mini.git' is not set up, section falls back on 'lewis6991/gitsigns' data 273 | --- or showing empty string. 274 | --- 275 | --- Empty string is returned if window width is lower than `args.trunc_width`. 276 | --- 277 | ---@param args __statusline_args Use `args.icon` to supply your own icon. 278 | --- 279 | ---@return __statusline_section 280 | MiniStatusline.section_git = function(args) 281 | if MiniStatusline.is_truncated(args.trunc_width) then return '' end 282 | 283 | local summary = vim.b.minigit_summary_string or vim.b.gitsigns_head 284 | if summary == nil then return '' end 285 | 286 | local use_icons = H.use_icons or H.get_config().use_icons 287 | local icon = args.icon or (use_icons and '' or 'Git') 288 | return icon .. ' ' .. (summary == '' and '-' or summary) 289 | end 290 | 291 | --- Section for diff information 292 | --- 293 | --- Shows diff summary from |MiniDiff| (should be set up; recommended). To tweak 294 | --- formatting of what data is shown, modify buffer-local summary string directly 295 | --- as described in |MiniDiff-diff-summary|. 296 | --- 297 | --- If 'mini.diff' is not set up, section falls back on 'lewis6991/gitsigns' data 298 | --- or showing empty string. 299 | --- 300 | --- Empty string is returned if window width is lower than `args.trunc_width`. 301 | --- 302 | ---@param args __statusline_args Use `args.icon` to supply your own icon. 303 | --- 304 | ---@return __statusline_section 305 | MiniStatusline.section_diff = function(args) 306 | if MiniStatusline.is_truncated(args.trunc_width) then return '' end 307 | 308 | local summary = vim.b.minidiff_summary_string or vim.b.gitsigns_status 309 | if summary == nil then return '' end 310 | 311 | local use_icons = H.use_icons or H.get_config().use_icons 312 | local icon = args.icon or (use_icons and '' or 'Diff') 313 | return icon .. ' ' .. (summary == '' and '-' or summary) 314 | end 315 | 316 | --- Section for Neovim's builtin diagnostics 317 | --- 318 | --- Shows nothing if diagnostics is disabled, no diagnostic is set, or for short 319 | --- output. Otherwise uses |vim.diagnostic.get()| to compute and show number of 320 | --- errors ('E'), warnings ('W'), information ('I'), and hints ('H'). 321 | --- 322 | --- Short output is returned if window width is lower than `args.trunc_width`. 323 | --- 324 | ---@param args __statusline_args Use `args.icon` to supply your own icon. 325 | --- Use `args.signs` to use custom signs per severity level name. For example: >lua 326 | --- 327 | --- { ERROR = '!', WARN = '?', INFO = '@', HINT = '*' } 328 | --- < 329 | ---@return __statusline_section 330 | MiniStatusline.section_diagnostics = function(args) 331 | if MiniStatusline.is_truncated(args.trunc_width) then return '' end 332 | 333 | -- Construct string parts. NOTE: call `diagnostic_is_disabled()` *after* 334 | -- check for present `count` to not source `vim.diagnostic` on startup. 335 | local count = H.diagnostic_counts[vim.api.nvim_get_current_buf()] 336 | if count == nil or H.diagnostic_is_disabled() then return '' end 337 | 338 | local severity, signs, t = vim.diagnostic.severity, args.signs or {}, {} 339 | for _, level in ipairs(H.diagnostic_levels) do 340 | local n = count[severity[level.name]] or 0 341 | -- Add level info only if diagnostic is present 342 | if n > 0 then table.insert(t, ' ' .. (signs[level.name] or level.sign) .. n) end 343 | end 344 | if #t == 0 then return '' end 345 | 346 | local use_icons = H.use_icons or H.get_config().use_icons 347 | local icon = args.icon or (use_icons and '' or 'Diag') 348 | return icon .. table.concat(t, '') 349 | end 350 | 351 | --- Section for attached LSP servers 352 | --- 353 | --- Shows number of LSP servers (each as separate "+" character) attached to 354 | --- current buffer or nothing if none is attached. 355 | --- Nothing is shown if window width is lower than `args.trunc_width`. 356 | --- 357 | ---@param args __statusline_args Use `args.icon` to supply your own icon. 358 | --- 359 | ---@return __statusline_section 360 | MiniStatusline.section_lsp = function(args) 361 | if MiniStatusline.is_truncated(args.trunc_width) then return '' end 362 | 363 | local attached = H.attached_lsp[vim.api.nvim_get_current_buf()] or '' 364 | if attached == '' then return '' end 365 | 366 | local use_icons = H.use_icons or H.get_config().use_icons 367 | local icon = args.icon or (use_icons and '󰰎' or 'LSP') 368 | return icon .. ' ' .. attached 369 | end 370 | 371 | --- Section for file name 372 | --- 373 | --- Show full file name or relative in short output. 374 | --- 375 | --- Short output is returned if window width is lower than `args.trunc_width`. 376 | --- 377 | ---@param args __statusline_args 378 | --- 379 | ---@return __statusline_section 380 | MiniStatusline.section_filename = function(args) 381 | -- In terminal always use plain name 382 | if vim.bo.buftype == 'terminal' then 383 | return '%t' 384 | elseif MiniStatusline.is_truncated(args.trunc_width) then 385 | -- File name with 'truncate', 'modified', 'readonly' flags 386 | -- Use relative path if truncated 387 | return '%f%m%r' 388 | else 389 | -- Use fullpath if not truncated 390 | return '%F%m%r' 391 | end 392 | end 393 | 394 | --- Section for file information 395 | --- 396 | --- Shows 'filetype', 'fileencoding' / 'encoding', 'fileformat', and buffer size. 397 | --- Short output has only non-empty 'filetype' and is returned if window width is 398 | --- lower than `args.trunc_width` or buffer is not normal (as per 'buftype'). 399 | --- 400 | --- Buffer size is computed based on current text, not file's saved version. 401 | --- 402 | --- If `config.use_icons` is true and icon provider is present (see 403 | --- "Dependencies" section in |mini.statusline|), shows icon near the filetype. 404 | --- 405 | ---@param args __statusline_args 406 | --- 407 | ---@return __statusline_section 408 | MiniStatusline.section_fileinfo = function(args) 409 | local filetype = vim.bo.filetype 410 | 411 | -- Add filetype icon 412 | H.ensure_get_icon() 413 | if H.get_icon ~= nil and filetype ~= '' then filetype = H.get_icon(filetype) .. ' ' .. filetype end 414 | 415 | -- Construct output string if truncated or buffer is not normal 416 | if MiniStatusline.is_truncated(args.trunc_width) or vim.bo.buftype ~= '' then return filetype end 417 | 418 | -- Construct output string with extra file info 419 | local encoding = vim.bo.fileencoding or vim.bo.encoding 420 | local format = vim.bo.fileformat 421 | local size = H.get_filesize() 422 | 423 | return string.format('%s%s%s[%s] %s', filetype, filetype == '' and '' or ' ', encoding, format, size) 424 | end 425 | 426 | --- Section for location inside buffer 427 | --- 428 | --- Show location inside buffer in the form: 429 | --- - Normal: `'||'` 430 | --- - Short: `''` 431 | --- 432 | --- Short output is returned if window width is lower than `args.trunc_width`. 433 | --- 434 | ---@param args __statusline_args 435 | --- 436 | ---@return __statusline_section 437 | MiniStatusline.section_location = function(args) 438 | -- Use virtual column number to allow update when past last column 439 | if MiniStatusline.is_truncated(args.trunc_width) then return '%l│%2v' end 440 | 441 | -- Use `virtcol()` to correctly handle multi-byte characters 442 | return '%l|%L│%2v|%-2{virtcol("$") - 1}' 443 | end 444 | 445 | --- Section for current search count 446 | --- 447 | --- Show the current status of |searchcount()|. Empty output is returned if 448 | --- window width is lower than `args.trunc_width`, search highlighting is not 449 | --- on (see |v:hlsearch|), or if number of search result is 0. 450 | --- 451 | --- `args.options` is forwarded to |searchcount()|. By default it recomputes 452 | --- data on every call which can be computationally expensive (although still 453 | --- usually on 0.1 ms order of magnitude). To prevent this, supply 454 | --- `args.options = { recompute = false }`. 455 | --- 456 | ---@param args __statusline_args 457 | --- 458 | ---@return __statusline_section 459 | MiniStatusline.section_searchcount = function(args) 460 | if vim.v.hlsearch == 0 or MiniStatusline.is_truncated(args.trunc_width) then return '' end 461 | -- `searchcount()` can return errors because it is evaluated very often in 462 | -- statusline. For example, when typing `/` followed by `\(`, it gives E54. 463 | local ok, s_count = pcall(vim.fn.searchcount, (args or {}).options or { recompute = true }) 464 | if not ok or s_count.current == nil or s_count.total == 0 then return '' end 465 | 466 | if s_count.incomplete == 1 then return '?/?' end 467 | 468 | local too_many = '>' .. s_count.maxcount 469 | local current = s_count.current > s_count.maxcount and too_many or s_count.current 470 | local total = s_count.total > s_count.maxcount and too_many or s_count.total 471 | return current .. '/' .. total 472 | end 473 | 474 | -- Helper data ================================================================ 475 | -- Module default config 476 | H.default_config = vim.deepcopy(MiniStatusline.config) 477 | 478 | -- Showed diagnostic levels 479 | H.diagnostic_levels = { 480 | { name = 'ERROR', sign = 'E' }, 481 | { name = 'WARN', sign = 'W' }, 482 | { name = 'INFO', sign = 'I' }, 483 | { name = 'HINT', sign = 'H' }, 484 | } 485 | 486 | -- Diagnostic counts per buffer id 487 | H.diagnostic_counts = {} 488 | 489 | -- String representation of attached LSP clients per buffer id 490 | H.attached_lsp = {} 491 | 492 | -- Helper functionality ======================================================= 493 | -- Settings ------------------------------------------------------------------- 494 | H.setup_config = function(config) 495 | H.check_type('config', config, 'table', true) 496 | config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {}) 497 | 498 | H.check_type('content', config.content, 'table') 499 | H.check_type('content.active', config.content.active, 'function', true) 500 | H.check_type('content.inactive', config.content.inactive, 'function', true) 501 | 502 | H.check_type('use_icons', config.use_icons, 'boolean') 503 | 504 | return config 505 | end 506 | 507 | H.apply_config = function(config) 508 | MiniStatusline.config = config 509 | 510 | -- Set statusline globally and dynamically decide which content to use 511 | vim.go.statusline = 512 | '%{%(nvim_get_current_win()==#g:actual_curwin || &laststatus==3) ? v:lua.MiniStatusline.active() : v:lua.MiniStatusline.inactive()%}' 513 | end 514 | 515 | H.create_autocommands = function() 516 | local gr = vim.api.nvim_create_augroup('MiniStatusline', {}) 517 | 518 | local au = function(event, pattern, callback, desc) 519 | vim.api.nvim_create_autocmd(event, { group = gr, pattern = pattern, callback = callback, desc = desc }) 520 | end 521 | 522 | -- Use `schedule_wrap()` because at `LspDetach` server is still present 523 | local track_lsp = vim.schedule_wrap(function(data) 524 | H.attached_lsp[data.buf] = vim.api.nvim_buf_is_valid(data.buf) and H.compute_attached_lsp(data.buf) or nil 525 | vim.cmd('redrawstatus') 526 | end) 527 | au({ 'LspAttach', 'LspDetach' }, '*', track_lsp, 'Track LSP clients') 528 | 529 | -- Use `schedule_wrap()` because `redrawstatus` might error on `:bwipeout` 530 | -- See: https://github.com/neovim/neovim/issues/32349 531 | local track_diagnostics = vim.schedule_wrap(function(data) 532 | H.diagnostic_counts[data.buf] = vim.api.nvim_buf_is_valid(data.buf) and H.get_diagnostic_count(data.buf) or nil 533 | vim.cmd('redrawstatus') 534 | end) 535 | au('DiagnosticChanged', '*', track_diagnostics, 'Track diagnostics') 536 | 537 | au('ColorScheme', '*', H.create_default_hl, 'Ensure colors') 538 | end 539 | 540 | --stylua: ignore 541 | H.create_default_hl = function() 542 | local set_default_hl = function(name, data) 543 | data.default = true 544 | vim.api.nvim_set_hl(0, name, data) 545 | end 546 | 547 | set_default_hl('MiniStatuslineModeNormal', { link = 'Cursor' }) 548 | set_default_hl('MiniStatuslineModeInsert', { link = 'DiffChange' }) 549 | set_default_hl('MiniStatuslineModeVisual', { link = 'DiffAdd' }) 550 | set_default_hl('MiniStatuslineModeReplace', { link = 'DiffDelete' }) 551 | set_default_hl('MiniStatuslineModeCommand', { link = 'DiffText' }) 552 | set_default_hl('MiniStatuslineModeOther', { link = 'IncSearch' }) 553 | 554 | set_default_hl('MiniStatuslineDevinfo', { link = 'StatusLine' }) 555 | set_default_hl('MiniStatuslineFilename', { link = 'StatusLineNC' }) 556 | set_default_hl('MiniStatuslineFileinfo', { link = 'StatusLine' }) 557 | set_default_hl('MiniStatuslineInactive', { link = 'StatusLineNC' }) 558 | end 559 | 560 | H.is_disabled = function() return vim.g.ministatusline_disable == true or vim.b.ministatusline_disable == true end 561 | 562 | H.get_config = function(config) 563 | return vim.tbl_deep_extend('force', MiniStatusline.config, vim.b.ministatusline_config or {}, config or {}) 564 | end 565 | 566 | -- Mode ----------------------------------------------------------------------- 567 | -- Custom `^V` and `^S` symbols to make this file appropriate for copy-paste 568 | -- (otherwise those symbols are not displayed). 569 | local CTRL_S = vim.api.nvim_replace_termcodes('', true, true, true) 570 | local CTRL_V = vim.api.nvim_replace_termcodes('', true, true, true) 571 | 572 | -- stylua: ignore start 573 | H.modes = setmetatable({ 574 | ['n'] = { long = 'Normal', short = 'N', hl = 'MiniStatuslineModeNormal' }, 575 | ['v'] = { long = 'Visual', short = 'V', hl = 'MiniStatuslineModeVisual' }, 576 | ['V'] = { long = 'V-Line', short = 'V-L', hl = 'MiniStatuslineModeVisual' }, 577 | [CTRL_V] = { long = 'V-Block', short = 'V-B', hl = 'MiniStatuslineModeVisual' }, 578 | ['s'] = { long = 'Select', short = 'S', hl = 'MiniStatuslineModeVisual' }, 579 | ['S'] = { long = 'S-Line', short = 'S-L', hl = 'MiniStatuslineModeVisual' }, 580 | [CTRL_S] = { long = 'S-Block', short = 'S-B', hl = 'MiniStatuslineModeVisual' }, 581 | ['i'] = { long = 'Insert', short = 'I', hl = 'MiniStatuslineModeInsert' }, 582 | ['R'] = { long = 'Replace', short = 'R', hl = 'MiniStatuslineModeReplace' }, 583 | ['c'] = { long = 'Command', short = 'C', hl = 'MiniStatuslineModeCommand' }, 584 | ['r'] = { long = 'Prompt', short = 'P', hl = 'MiniStatuslineModeOther' }, 585 | ['!'] = { long = 'Shell', short = 'Sh', hl = 'MiniStatuslineModeOther' }, 586 | ['t'] = { long = 'Terminal', short = 'T', hl = 'MiniStatuslineModeOther' }, 587 | }, { 588 | -- By default return 'Unknown' but this shouldn't be needed 589 | __index = function() 590 | return { long = 'Unknown', short = 'U', hl = '%#MiniStatuslineModeOther#' } 591 | end, 592 | }) 593 | -- stylua: ignore end 594 | 595 | -- Default content ------------------------------------------------------------ 596 | --stylua: ignore 597 | H.default_content_active = function() 598 | H.use_icons = H.get_config().use_icons 599 | local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 }) 600 | local git = MiniStatusline.section_git({ trunc_width = 40 }) 601 | local diff = MiniStatusline.section_diff({ trunc_width = 75 }) 602 | local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 }) 603 | local lsp = MiniStatusline.section_lsp({ trunc_width = 75 }) 604 | local filename = MiniStatusline.section_filename({ trunc_width = 140 }) 605 | local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 }) 606 | local location = MiniStatusline.section_location({ trunc_width = 75 }) 607 | local search = MiniStatusline.section_searchcount({ trunc_width = 75 }) 608 | H.use_icons = nil 609 | 610 | -- Usage of `MiniStatusline.combine_groups()` ensures highlighting and 611 | -- correct padding with spaces between groups (accounts for 'missing' 612 | -- sections, etc.) 613 | return MiniStatusline.combine_groups({ 614 | { hl = mode_hl, strings = { mode } }, 615 | { hl = 'MiniStatuslineDevinfo', strings = { git, diff, diagnostics, lsp } }, 616 | '%<', -- Mark general truncate point 617 | { hl = 'MiniStatuslineFilename', strings = { filename } }, 618 | '%=', -- End left alignment 619 | { hl = 'MiniStatuslineFileinfo', strings = { fileinfo } }, 620 | { hl = mode_hl, strings = { search, location } }, 621 | }) 622 | end 623 | 624 | H.default_content_inactive = function() return '%#MiniStatuslineInactive#%F%=' end 625 | 626 | -- LSP ------------------------------------------------------------------------ 627 | H.compute_attached_lsp = function(buf_id) return string.rep('+', vim.tbl_count(H.get_buf_lsp_clients(buf_id))) end 628 | 629 | H.get_buf_lsp_clients = function(buf_id) return vim.lsp.get_clients({ bufnr = buf_id }) end 630 | -- NOTE: Use `has('nvim-0.xx')` instead of directly checking presence of target 631 | -- function to avoid loading `vim.xxx` modules at `require('mini.statusline')`. 632 | -- This visibly improves startup time. 633 | if vim.fn.has('nvim-0.10') == 0 then 634 | H.get_buf_lsp_clients = function(buf_id) return vim.lsp.buf_get_clients(buf_id) end 635 | end 636 | 637 | -- Diagnostics ---------------------------------------------------------------- 638 | H.get_diagnostic_count = function(buf_id) return vim.diagnostic.count(buf_id) end 639 | if vim.fn.has('nvim-0.10') == 0 then 640 | H.get_diagnostic_count = function(buf_id) 641 | local res = {} 642 | for _, d in ipairs(vim.diagnostic.get(buf_id)) do 643 | res[d.severity] = (res[d.severity] or 0) + 1 644 | end 645 | return res 646 | end 647 | end 648 | 649 | H.diagnostic_is_disabled = function() return not vim.diagnostic.is_enabled({ bufnr = 0 }) end 650 | if vim.fn.has('nvim-0.10') == 0 then 651 | if vim.fn.has('nvim-0.9') == 1 then 652 | H.diagnostic_is_disabled = function() return vim.diagnostic.is_disabled(0) end 653 | else 654 | H.diagnostic_is_disabled = function() return false end 655 | end 656 | end 657 | 658 | -- Utilities ------------------------------------------------------------------ 659 | H.error = function(msg) error('(mini.statusline) ' .. msg, 0) end 660 | 661 | H.check_type = function(name, val, ref, allow_nil) 662 | if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end 663 | H.error(string.format('`%s` should be %s, not %s', name, ref, type(val))) 664 | end 665 | 666 | H.get_filesize = function() 667 | local size = math.max(vim.fn.line2byte(vim.fn.line('$') + 1) - 1, 0) 668 | if size < 1024 then 669 | return string.format('%dB', size) 670 | elseif size < 1048576 then 671 | return string.format('%.2fKiB', size / 1024) 672 | else 673 | return string.format('%.2fMiB', size / 1048576) 674 | end 675 | end 676 | 677 | H.ensure_get_icon = function() 678 | if not (H.use_icons or H.get_config().use_icons) then 679 | -- Show no icon 680 | H.get_icon = nil 681 | elseif H.get_icon ~= nil then 682 | -- Cache only once 683 | return 684 | elseif _G.MiniIcons ~= nil then 685 | -- Prefer 'mini.icons' 686 | H.get_icon = function(filetype) return (_G.MiniIcons.get('filetype', filetype)) end 687 | else 688 | -- Try falling back to 'nvim-web-devicons' 689 | local has_devicons, devicons = pcall(require, 'nvim-web-devicons') 690 | if not has_devicons then return end 691 | H.get_icon = function() return (devicons.get_icon(vim.fn.expand('%:t'), nil, { default = true })) end 692 | end 693 | end 694 | 695 | return MiniStatusline 696 | --------------------------------------------------------------------------------