breadcrumbs.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. local M = {}
  2. -- local Log = require "lvim.core.log"
  3. local icons = lvim.icons.kind
  4. M.config = function()
  5. lvim.builtin.breadcrumbs = {
  6. active = true,
  7. on_config_done = nil,
  8. winbar_filetype_exclude = {
  9. "help",
  10. "startify",
  11. "dashboard",
  12. "lazy",
  13. "neo-tree",
  14. "neogitstatus",
  15. "NvimTree",
  16. "Trouble",
  17. "alpha",
  18. "lir",
  19. "Outline",
  20. "spectre_panel",
  21. "toggleterm",
  22. "DressingSelect",
  23. "Jaq",
  24. "harpoon",
  25. "dap-repl",
  26. "dap-terminal",
  27. "dapui_console",
  28. "dapui_hover",
  29. "lab",
  30. "notify",
  31. "noice",
  32. "neotest-summary",
  33. "",
  34. },
  35. options = {
  36. icons = {
  37. Array = icons.Array .. " ",
  38. Boolean = icons.Boolean .. " ",
  39. Class = icons.Class .. " ",
  40. Color = icons.Color .. " ",
  41. Constant = icons.Constant .. " ",
  42. Constructor = icons.Constructor .. " ",
  43. Enum = icons.Enum .. " ",
  44. EnumMember = icons.EnumMember .. " ",
  45. Event = icons.Event .. " ",
  46. Field = icons.Field .. " ",
  47. File = icons.File .. " ",
  48. Folder = icons.Folder .. " ",
  49. Function = icons.Function .. " ",
  50. Interface = icons.Interface .. " ",
  51. Key = icons.Key .. " ",
  52. Keyword = icons.Keyword .. " ",
  53. Method = icons.Method .. " ",
  54. Module = icons.Module .. " ",
  55. Namespace = icons.Namespace .. " ",
  56. Null = icons.Null .. " ",
  57. Number = icons.Number .. " ",
  58. Object = icons.Object .. " ",
  59. Operator = icons.Operator .. " ",
  60. Package = icons.Package .. " ",
  61. Property = icons.Property .. " ",
  62. Reference = icons.Reference .. " ",
  63. Snippet = icons.Snippet .. " ",
  64. String = icons.String .. " ",
  65. Struct = icons.Struct .. " ",
  66. Text = icons.Text .. " ",
  67. TypeParameter = icons.TypeParameter .. " ",
  68. Unit = icons.Unit .. " ",
  69. Value = icons.Value .. " ",
  70. Variable = icons.Variable .. " ",
  71. },
  72. highlight = true,
  73. separator = " " .. lvim.icons.ui.ChevronRight .. " ",
  74. depth_limit = 0,
  75. depth_limit_indicator = "..",
  76. },
  77. }
  78. end
  79. M.setup = function()
  80. local status_ok, navic = pcall(require, "nvim-navic")
  81. if not status_ok then
  82. return
  83. end
  84. M.create_winbar()
  85. navic.setup(lvim.builtin.breadcrumbs.options)
  86. if lvim.builtin.breadcrumbs.on_config_done then
  87. lvim.builtin.breadcrumbs.on_config_done()
  88. end
  89. end
  90. local function isempty(s)
  91. return s == nil or s == ""
  92. end
  93. M.get_filename = function()
  94. local filename = vim.fn.expand "%:t"
  95. local extension = vim.fn.expand "%:e"
  96. if not isempty(filename) then
  97. local file_icon, hl_group
  98. local devicons_ok, devicons = pcall(require, "nvim-web-devicons")
  99. if lvim.use_icons and devicons_ok then
  100. file_icon, hl_group = devicons.get_icon(filename, extension, { default = true })
  101. if isempty(file_icon) then
  102. file_icon = lvim.icons.kind.File
  103. end
  104. else
  105. file_icon = ""
  106. hl_group = "Normal"
  107. end
  108. local buf_ft = vim.bo.filetype
  109. if buf_ft == "dapui_breakpoints" then
  110. file_icon = lvim.icons.ui.Bug
  111. end
  112. if buf_ft == "dapui_stacks" then
  113. file_icon = lvim.icons.ui.Stacks
  114. end
  115. if buf_ft == "dapui_scopes" then
  116. file_icon = lvim.icons.ui.Scopes
  117. end
  118. if buf_ft == "dapui_watches" then
  119. file_icon = lvim.icons.ui.Watches
  120. end
  121. -- if buf_ft == "dapui_console" then
  122. -- file_icon = lvim.icons.ui.DebugConsole
  123. -- end
  124. local navic_text = vim.api.nvim_get_hl_by_name("Normal", true) -- FIXME
  125. -- local navic_text = vim.api.nvim_get_hl(0, { name = "Normal", create = false })
  126. vim.api.nvim_set_hl(0, "Winbar", { fg = navic_text.foreground })
  127. return " " .. "%#" .. hl_group .. "#" .. file_icon .. "%*" .. " " .. "%#Winbar#" .. filename .. "%*"
  128. end
  129. end
  130. local get_gps = function()
  131. local status_gps_ok, gps = pcall(require, "nvim-navic")
  132. if not status_gps_ok then
  133. return ""
  134. end
  135. local status_ok, gps_location = pcall(gps.get_location, {})
  136. if not status_ok then
  137. return ""
  138. end
  139. if not gps.is_available() or gps_location == "error" then
  140. return ""
  141. end
  142. if not require("lvim.utils.functions").isempty(gps_location) then
  143. return "%#NavicSeparator#" .. lvim.icons.ui.ChevronRight .. "%* " .. gps_location
  144. else
  145. return ""
  146. end
  147. end
  148. local excludes = function()
  149. return vim.tbl_contains(lvim.builtin.breadcrumbs.winbar_filetype_exclude or {}, vim.bo.filetype)
  150. end
  151. M.get_winbar = function()
  152. if excludes() then
  153. return
  154. end
  155. local value = M.get_filename()
  156. local gps_added = false
  157. if not isempty(value) then
  158. local gps_value = get_gps()
  159. value = value .. " " .. gps_value
  160. if not isempty(gps_value) then
  161. gps_added = true
  162. end
  163. end
  164. if not isempty(value) and vim.api.nvim_get_option_value("mod", { buf = 0 }) then
  165. -- TODO: replace with circle
  166. local mod = "%#LspCodeLens#" .. lvim.icons.ui.Circle .. "%*"
  167. if gps_added then
  168. value = value .. " " .. mod
  169. else
  170. value = value .. mod
  171. end
  172. end
  173. local num_tabs = #vim.api.nvim_list_tabpages()
  174. if num_tabs > 1 and not isempty(value) then
  175. local tabpage_number = tostring(vim.api.nvim_tabpage_get_number(0))
  176. value = value .. "%=" .. tabpage_number .. "/" .. tostring(num_tabs)
  177. end
  178. local status_ok, _ = pcall(vim.api.nvim_set_option_value, "winbar", value, { scope = "local" })
  179. if not status_ok then
  180. return
  181. end
  182. end
  183. M.create_winbar = function()
  184. vim.api.nvim_create_augroup("_winbar", {})
  185. vim.api.nvim_create_autocmd({
  186. "CursorHoldI",
  187. "CursorHold",
  188. "BufWinEnter",
  189. "BufFilePost",
  190. "InsertEnter",
  191. "BufWritePost",
  192. "TabClosed",
  193. "TabEnter",
  194. }, {
  195. group = "_winbar",
  196. callback = function()
  197. if lvim.builtin.breadcrumbs.active then
  198. local status_ok, _ = pcall(vim.api.nvim_buf_get_var, 0, "lsp_floating_window")
  199. if not status_ok then
  200. -- TODO:
  201. require("lvim.core.breadcrumbs").get_winbar()
  202. end
  203. end
  204. end,
  205. })
  206. end
  207. return M