From 87ea788dee6e4aae2eaf3575ab14f38a61d883f7 Mon Sep 17 00:00:00 2001 From: ray Date: Mon, 12 Jan 2026 22:08:43 +0000 Subject: [PATCH] Implement custom tabline with configurable path shortening Add a custom tabline function to enhance path display in Neovim. Users can configure the number of full parent directories and the length of shortened directory names for better context and manageability. --- LOG.md | 1 + MIGRATION_PLAN.md | 6 ++++ README.md | 31 +++++++++++++++++ lua/settings.lua | 20 +++++++++++ lua/utils.lua | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+) diff --git a/LOG.md b/LOG.md index 4716ef8..6222096 100644 --- a/LOG.md +++ b/LOG.md @@ -9,6 +9,7 @@ Authoritative notes for the Neovim migration. Use this alongside `MIGRATION_PLAN Record every decision here with a short rationale. Append new entries; do not rewrite history. +- 2025-01-12: **Custom Tabline Function**: Implemented configurable custom tabline to replace Neovim's hardcoded path shortening (e.g., `a/p/file.txt`). Function in `lua/utils.lua` allows controlling: (1) number of full parent directories via `utils.tabline_full_parents` (default: 1), and (2) shortening length via `utils.tabline_shorten_length` (default: 3 characters). Example: with defaults, `/path/to/my/project/src/file.txt` becomes `pat/to/my/project/src/file.txt`. User preference for seeing enough context in shortened paths while keeping tab width manageable. - 2025-12-06: PHP LSP = `intelephense` (good PHP ecosystem support; integrates includePaths). - 2025-12-06: Enable Markdown LSP = `marksman` (lightweight, good MD features). - 2025-12-06: Use legacy `listchars` and `showbreak` values (preserve muscle memory). diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md index 56fe7d0..001dc84 100644 --- a/MIGRATION_PLAN.md +++ b/MIGRATION_PLAN.md @@ -336,6 +336,12 @@ Source of truth for the step-by-step rebuild. Keep this concise and up to date. - [x] Persistent folds (via UFO) -- no need, this is no longer required. - [x] Note: UFO handles folding; no explicit persistence mechanism needed +## Phase 10.6 — Custom tabline function +- [x] Implement custom tabline with configurable path shortening (`lua/utils.lua`) +- [x] Configure tabline in `lua/settings.lua` with `utils.tabline_full_parents` +- [x] Document tabline configuration in `README.md` +- [x] Show N parent directories in full, shorten earlier paths to first letter + ## Phase 11 — Colorscheme: Modern Paper Tonic ## Phase 11.1 — Confirm scope and priorities diff --git a/README.md b/README.md index 3cfde91..763fdc7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,37 @@ Living reference for session management, keymaps, commands, and plugin-specific features in this config. +## Configuration Options + +### Tabline Display + +Custom tabline shows intelligent path shortening with two configurable options. + +**Location:** `lua/settings.lua` (configured via `utils.tabline_full_parents` and `utils.tabline_shorten_length`) + +**Configuration Options:** + +1. **`utils.tabline_full_parents`** (default: `1`) - Number of parent directories to show in full +2. **`utils.tabline_shorten_length`** (default: `3`) - Number of characters to show for shortened directories + +**Examples:** + +With `full_parents = 1, shorten_length = 3`: +- `/path/to/my/project/src/file.txt` → `pat/to/my/project/src/file.txt` + +With `full_parents = 2, shorten_length = 3`: +- `/path/to/my/project/src/file.txt` → `pat/to/my/project/src/file.txt` + +With `full_parents = 1, shorten_length = 1`: +- `/path/to/my/project/src/file.txt` → `p/t/m/project/src/file.txt` + +With `full_parents = 0, shorten_length = 3`: +- `/path/to/my/project/src/file.txt` → `pat/to/my/pro/src/file.txt` + +The last N parent directories are shown in full, earlier directories are shortened to the specified number of characters. The filename itself is always shown in full. + +**To customize:** Edit `utils.tabline_full_parents` and `utils.tabline_shorten_length` values in `lua/settings.lua` + ## Working Directory Behavior The working directory (`:pwd`) is locked to the directory where you opened Neovim and does NOT change when switching files: diff --git a/lua/settings.lua b/lua/settings.lua index 19f96fe..8f2cc40 100644 --- a/lua/settings.lua +++ b/lua/settings.lua @@ -16,6 +16,26 @@ vim.opt.autochdir = false -- Keep working directory at project root vim.opt.exrc = true -- Load .nvim.lua from project root vim.opt.secure = true -- Prompt before loading untrusted files +-- Custom tabline configuration +-- Load utils module for custom tabline function +local utils = require('utils') + +-- Configure number of parent directories to show in full (default: 1) +-- Examples: +-- 1: /path/to/my/project/src/file.txt → pat/to/my/project/src/file.txt +-- 2: /path/to/my/project/src/file.txt → pat/to/my/project/src/file.txt +utils.tabline_full_parents = 1 + +-- Configure number of characters to show for shortened directories (default: 3) +-- Examples: +-- 3: /path/to/my → pat/to/my +-- 1: /path/to/my → p/t/m +utils.tabline_shorten_length = 4 + +-- Use custom tabline function +vim.opt.tabline = '%!v:lua.require("utils").custom_tabline()' +vim.opt.showtabline = 1 -- Show tabline only when there are 2+ tabs + -- Phase 3.2: non-plugin settings (legacy values where specified) -- Completion UI for nvim-cmp vim.opt.completeopt = { "menu", "menuone", "noselect" } diff --git a/lua/utils.lua b/lua/utils.lua index 419cde8..00d090c 100644 --- a/lua/utils.lua +++ b/lua/utils.lua @@ -6,5 +6,94 @@ function M.safe_require(name) return nil end +-- Number of parent directories to show in full in the tabline +-- The rest will be shortened according to tabline_shorten_length +-- Example: with full_parents = 1, /path/to/my/project/src/file.txt becomes pat/to/my/project/src/file.txt +-- Example: with full_parents = 2, it becomes pat/to/my/project/src/file.txt +M.tabline_full_parents = 1 + +-- Number of characters to show for shortened directory names in the tabline +-- Example: with shorten_length = 3, /path/to/my becomes pat/to/my +-- Example: with shorten_length = 1, /path/to/my becomes p/t/m +M.tabline_shorten_length = 3 + +-- Custom tabline function +-- Shows configurable number of full parent directories, shortens the rest +function M.custom_tabline() + local tabline = '' + local num_tabs = vim.fn.tabpagenr('$') + + for i = 1, num_tabs do + local buflist = vim.fn.tabpagebuflist(i) + local winnr = vim.fn.tabpagewinnr(i) + local bufnr = buflist[winnr] + local bufname = vim.fn.bufname(bufnr) + local bufmodified = vim.fn.getbufvar(bufnr, "&modified") + + -- Highlight for the tab + if i == vim.fn.tabpagenr() then + tabline = tabline .. '%#TabLineSel#' + else + tabline = tabline .. '%#TabLine#' + end + + -- Tab number + tabline = tabline .. ' ' .. i .. ' ' + + -- Format the filename with smart path shortening + local filename + if bufname == '' then + filename = '[No Name]' + else + -- Get the full path relative to cwd if possible + local path = vim.fn.fnamemodify(bufname, ':~:.') + + -- Split path into components + local parts = vim.split(path, '/', { plain = true }) + + if #parts > M.tabline_full_parents + 1 then + -- We have enough parts to do smart shortening + local result = {} + + -- Shorten the leading directories (all but the last full_parents + filename) + local num_to_shorten = #parts - M.tabline_full_parents - 1 + for j = 1, num_to_shorten do + table.insert(result, parts[j]:sub(1, M.tabline_shorten_length)) + end + + -- Add the full parent directories + for j = num_to_shorten + 1, #parts - 1 do + table.insert(result, parts[j]) + end + + -- Add the filename + table.insert(result, parts[#parts]) + + filename = table.concat(result, '/') + else + -- Path is short enough, just use it as-is + filename = path + end + end + + -- Add modified flag + if bufmodified == 1 then + filename = filename .. ' [+]' + end + + tabline = tabline .. filename .. ' ' + end + + -- Fill the rest with TabLineFill + tabline = tabline .. '%#TabLineFill#%T' + + -- Right-align: show tab page count if more than one tab + if num_tabs > 1 then + tabline = tabline .. '%=%#TabLine# ' .. num_tabs .. ' tabs ' + end + + return tabline +end + return M