Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Shadow on editor edge that randomly appears #1575

Open
3 tasks done
Ajaymamtora opened this issue Oct 5, 2024 · 1 comment
Open
3 tasks done

BUG: Shadow on editor edge that randomly appears #1575

Ajaymamtora opened this issue Oct 5, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@Ajaymamtora
Copy link

Did you check docs and existing issues?

  • I have read all the docs.
  • I have searched the existing issues.
  • I have searched the existing discussions.

Neovim Version (nvim -v)

NVIM v0.10.2 Build type: Release LuaJIT 2.1.1713484068 Run "nvim -V1 -v" for more info

Operating System / Version

macos 15.0

Describe the Bug

theres a drop shadow along the edge which flickers when used with edgy.nvim

Screenshots, Traceback

image

Steps to Reproduce

Not actually sure what causes it, think its a win highlight and removing local highlights does nothing.

Expected Behavior

No drop shadow

Your Configuration

local M = {}

local git_utils = require("utils.git")

function M.set_neo_tree_root(new_root)
  if new_root then
    local neo_tree_loaded, _ = pcall(require, "neo-tree")
    if neo_tree_loaded then
      local manager = require("neo-tree.sources.manager")
      local renderer = require("neo-tree.ui.renderer")

      -- Check if the root has changed
      local current_state = manager.get_state("filesystem")
      if current_state and current_state.path == new_root then
        -- Root hasn't changed, no need to update
        return
      end

      -- Update the root for all tabs
      for _, tabpage in ipairs(vim.api.nvim_list_tabpages()) do
        local state = manager.get_state("filesystem", tabpage)
        if state and state.path ~= new_root then
          state.path = new_root
          state.dirty = true
        end
      end

      -- Refresh Neo-tree if it's visible in the current tab
      local current_tabpage = vim.api.nvim_get_current_tabpage()
      local state = manager.get_state("filesystem", current_tabpage)
      if state and renderer.window_exists(state) and state.path ~= new_root then
        manager.navigate("filesystem", new_root)
      end

      vim.g.cached_lsp_root = new_root
      print("Neo-tree root set to: " .. new_root)
    else
      print("Neo-tree is not loaded")
    end
  end
end

local augroup = vim.api.nvim_create_augroup("TabGroupSwitch", { clear = true })
vim.api.nvim_create_autocmd("TabEnter", {
  group = augroup,
  callback = function()
    vim.schedule(function()
      if vim.g.cached_lsp_root then
        M.set_neo_tree_root(vim.g.cached_lsp_root)
      end
    end)
  end,
})

M.neo_tree = function()
  local icons = require("core.ui.icons")

  -- Helper function to check if a path is excluded
  local function is_path_excluded(path, exclusions)
    for _, exclusion in ipairs(exclusions) do
      -- Trim whitespace and remove trailing slash if present
      local pattern = exclusion:match("^%s*(.-)%s*/?$")
      -- Escape all special regex characters
      pattern = pattern:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
      -- Replace escaped '*' with '.-' for wildcard matching
      pattern = pattern:gsub("%%%*", ".-")

      -- Check if the pattern matches the full path (for absolute path patterns)
      if pattern:sub(1, 2) == "%/" then
        if path:match("^" .. pattern .. "$") then
          return true
        end
      else
        -- For relative patterns, match against path segments
        local segments = {}
        for segment in path:gmatch("[^/]+") do
          table.insert(segments, segment)
        end

        -- Check if the pattern matches any complete segment
        for i = #segments, 1, -1 do
          if segments[i]:match("^" .. pattern .. "$") then
            return true
          end
        end
      end
    end
    return false
  end

  local windows_bindings = {
    ["zO"] = "expand_all_nodes",
    ["zC"] = "close_all_nodes",
    ["zZ"] = "toggle_auto_expand_width",
    ["zz"] = {
      "toggle_node",
    },
    ["<C-w>s"] = "open_split",
    ["<C-w>v"] = "open_vsplit",
    ["<C-w>T"] = "open_tabnew",
    ["<C-w>p"] = "open_with_window_picker",
    ["<M-y>"] = "copy_path_from_content_root",
    ["e"] = false,
    ["z"] = false,
    ["<Leader>"] = false,
    ["<M-u>"] = "refresh",
    ["<M-f>"] = "live_grep_at_path",
    ["<M-d>"] = "diffview_node",
    ["<M-g>"] = "lazy_git_at_path",
    ["<M-e>"] = "explorer_at_path",
    ["<M-o>"] = "telescope_find_and_open_file",
    ["<M-r>"] = "grug_replace",
    ["<M-t>"] = "open_in_terminal",
    ["E"] = "toggle_exclude_item",
    ["[g"] = "prev_git_modified",
    ["]g"] = "next_git_modified",
    ["_"] = "reset_root_to_lsp_common",
  }
  local user_exclusions = require("neoconf").get("exclusions")
  local permanent_exclusions = require("utils.files").lua_converted_exclusion_patterns

  local function custom_renderer(config, node, state)
    local name = node.name
    local path = node:get_id()

    -- Check if the node is excluded or filtered
    local is_user_excluded = is_path_excluded(path, user_exclusions)
    local is_permanent_excluded = is_path_excluded(path, permanent_exclusions)
    local is_filtered = node.filtered_by and next(node.filtered_by) ~= nil

    -- Apply custom highlight if excluded or filtered
    if is_permanent_excluded then
      return {
        {
          text = name,
          highlight = "NeoTreePermanentExcludedFileName",
        },
      }
    elseif is_user_excluded or is_filtered then
      return {
        {
          text = name,
          highlight = "NeoTreeExcludedFileName",
        },
      }
    end

    -- Use the default renderer for non-excluded and non-filtered nodes
    local default_renderer = require("neo-tree.sources.common.components").name
    local default_result = default_renderer(config, node, state)

    -- Ensure we're returning a table to prevent potential issues
    if type(default_result) ~= "table" then
      return { { text = tostring(default_result), highlight = "NeoTreeFileName" } }
    end

    return default_result
  end

  -- Update the toggle_exclude_item function
  local function toggle_exclude_item(state)
    local node = state.tree:get_node()
    local path = node:get_id()

    local is_permanent_excluded = is_path_excluded(path, permanent_exclusions)

    if is_permanent_excluded then
      vim.notify("Permanent exclusion found at " .. tostring(path), vim.log.levels.WARN)
      return
    end

    require("utils.settings").toggle_string_in_table(path, "exclusions")

    print("Toggle exclude item at " .. tostring(path))

    pcall(function()
      vim.cmd("Neotree close")
    end)
    vim.defer_fn(function()
      require("neoconf.settings").refresh()
      pcall(function()
        vim.cmd("Lazy reload neo-tree.nvim")
      end)
    end, 100)
  end

  local event_handlers = {
    {
      event = "vim_buffer_changed",
      handler = function(_)
        vim.schedule(function()
          if vim.g.cached_lsp_root then
            M.set_neo_tree_root(vim.g.cached_lsp_root)
          end
        end)
      end,
    },
    {
      event = "neo_tree_buffer_enter",
      handler = function(_)
        vim.schedule(function()
          vim.wo.statuscolumn = " "
        end)
      end,
    },
    {
      event = "neo_tree_window_before_open",
      handler = function(_) end,
    },
    {
      event = "neo_tree_window_after_close",
      handler = function(args)
        if args.position == "left" or args.position == "right" then
          vim.cmd("wincmd =")
        end
      end,
    },
    {
      event = "neo_tree_window_after_open",
      handler = function(args)
        if args.position == "left" or args.position == "right" then
          vim.cmd("wincmd =")
        end
        vim.schedule(function()
          vim.wo.statuscolumn = " "
          --       vim.g.minianimate_disable = false
        end)
      end,
    },
    {
      event = "file_opened",
      handler = function(file_path)
        -- auto close
        require("neo-tree.command").execute({ action = "close" })
      end,
    },
    {
      event = "neo_tree_buffer_leave",
      handler = function()
        local shown_buffers = {}
        for _, win in ipairs(vim.api.nvim_list_wins()) do
          shown_buffers[vim.api.nvim_win_get_buf(win)] = true
        end
        for _, buf in ipairs(vim.api.nvim_list_bufs()) do
          if
            not shown_buffers[buf]
            and vim.api.nvim_buf_get_option(buf, "buftype") == "nofile"
            and vim.api.nvim_buf_get_option(buf, "filetype") == "neo-tree"
          then
            vim.api.nvim_buf_delete(buf, {})
          end
        end
      end,
    },
  }

  local filesystem_commands = {
    telescope_find_and_open_file = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()

      -- Check if the path is a file or a directory
      local is_file = vim.fn.filereadable(path) == 1

      -- If it's a file, get the parent directory
      if is_file then
        path = vim.fn.fnamemodify(path, ":h")
      end

      require("utils.telescope_utils").find_files({
        paths = {
          path,
        },
        cwd = path,
      })
      print("Searching for files in " .. tostring(path))
    end,

    copy_path_from_content_root = function(state)
      local node = state.tree:get_node()
      local absolute_path = node:get_id()

      vim.ui.select({ "Absolute Path", "Relative Path" }, {
        prompt = "Select path type to copy:",
        format_item = function(item)
          return item
        end,
      }, function(choice)
        local result

        if choice == "Absolute Path" then
          result = absolute_path
        else
          -- Get the git root directory
          local git_root = vim.fn.systemlist(
            "git -C " .. vim.fn.escape(vim.fn.fnamemodify(absolute_path, ":h"), " ") .. " rev-parse --show-toplevel"
          )[1]

          if git_root and git_root ~= "" then
            -- File is in a git repository
            result = vim.fn.fnamemodify(absolute_path, ":p"):gsub(git_root .. "/", "")
          else
            -- File is not in a git repository, use full path
            result = vim.fn.fnamemodify(absolute_path, ":p")
          end
        end

        -- Copy the result to the clipboard
        vim.fn.setreg("+", result)

        -- Print a message to confirm the action
        print("Copied to clipboard: " .. result)
      end)
    end,

    live_grep_at_path = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()

      local exclusions = require("utils.files").get_rg_exclusions()
      require("telescope").extensions.egrepify.search_given_files({ exclusions = exclusions, search_dirs = { path } })
      print("Searching in " .. tostring(path))
    end,

    lazy_git_at_path = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()

      -- Use git_utils to find the closest Git directory
      local git_dir = git_utils.get_closest_git_dir_to(path)

      if git_dir then
        require("lazygit").lazygit(git_dir)
        print("Lazygit opened at " .. tostring(git_dir))
      else
        print("No Git repository found. Using the original path.")
        require("lazygit").lazygit(path)
        print("Lazygit opened at " .. tostring(path))
      end
    end,

    explorer_at_path = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()

      require("yazi").yazi(nil, path)
      print("Opening explorer at " .. tostring(path))
    end,

    diffview_node = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()

      -- Ensure we have a valid path
      if not path then
        print("Error: Unable to get path from node")
        return
      end

      -- Get the full absolute path
      local full_path = vim.fn.fnamemodify(path, ":p")

      -- Check if the path exists
      if vim.fn.isdirectory(full_path) == 1 or vim.fn.filereadable(full_path) == 1 then
        -- Construct the DiffviewFileHistory command
        local cmd = string.format("DiffviewFileHistory %s", vim.fn.fnameescape(full_path))

        -- Execute the Diffview command
        vim.cmd(cmd)

        print("Opening Diffview File History for: " .. full_path)
      else
        print("Path does not exist or is not accessible: " .. full_path)
      end
    end,

    grug_replace = function(state)
      local node = state.tree:get_node()
      local path = node:get_id()
      vim.cmd(":Neotree close")

      -- Check if the path is a file or directory
      local is_single = false
      local is_file = vim.fn.filereadable(path) == 1
      local is_directory = vim.fn.isdirectory(path) == 1

      if is_file then
        is_single = true
      elseif is_directory then
        is_single = false
      end

      require("utils.search_utils").grug_search({
        default_text = "",
        paths = { path },
        single_file_mode = is_single,
      })
      print("Replacing in " .. (is_single and "file: " or "directory: ") .. tostring(path))
    end,

    open_in_terminal = function(state)
      local toggleterm = require("toggleterm")
      local node = state.tree:get_node()
      local path = node:get_id()

      -- Use vim.fn.shellescape to properly escape the path
      local escaped_path = vim.fn.shellescape(path)

      -- Construct the command
      local cmd = string.format("cd %s", escaped_path)

      -- Use the toggleterm API to execute the command
      toggleterm.exec(cmd, 99)

      -- Focus the terminal
      require("utils.terminal").focus_main_term()
      -- Enter insert mode
      vim.schedule(function()
        vim.cmd("startinsert")
      end)

      print("Opening terminal in " .. tostring(path))
    end,

    toggle_exclude_item = toggle_exclude_item,

    reset_root_to_lsp_common = require("utils.lsp").set_neo_tree_dir_to_lsp_common_root,
  }

  local full_opts = {
    hide_root_node = true,
    retain_hidden_root_indent = true,
    sort_case_insensitive = true,
    open_files_do_not_replace_types = { "terminal", "Trouble", "qf", "edgy", "neo-tree" },
    use_popups_for_input = false,
    popup_border_style = "single",
    enable_git_status = false,
    enable_diagnostics = false,
    auto_clean_after_session_restore = true,
    sources = {
      "filesystem",
      -- "buffers",
      -- "git_status",
      --"document_symbols",
    },
    event_handlers = event_handlers,
    source_selector = {
      winbar = true,
      separator = "",
      content_layout = "center",
      sources = {
        {
          source = "filesystem",
          display_name = icons.common.folder .. " DIR  ",
        },
        -- {
        --   source = "buffers",
        --   display_name = icons.common.buffer .. " BUF  ",
        -- },
        -- {
        --   source = "git_status",
        --   display_name = icons.common.git .. " GIT  ",
        -- },
        --        {
        --         source = "document_symbols",
        --        display_name = icons.lsp.Module .. " DOC  ",
        --     },
      },
    },
    default_component_configs = {
      container = {
        enable_character_fade = true,
      },
      indent = {
        with_markers = false,
        with_expanders = true,
        expander_collapsed = "",
        expander_expanded = "",
      },
      icon = {
        folder_closed = icons.common.folder_close,
        folder_open = icons.common.folder_open,
        folder_empty = icons.common.folder_empty,
        highlight = "NeoTreeFileIcon",
      },
      modified = {
        symbol = icons.common.dot,
      },
      git_status = {
        symbols = icons.git_status,
        align = "right",
      },
      name = {
        use_git_status_colors = false,
        highlight = "NeoTreeFileName",
      },
    },
    window = {
      position = "left",
      width = 40,
    },
    filesystem = {
      components = {
        name = custom_renderer,
      },
      window = {
        mappings = windows_bindings,
      },
      commands = filesystem_commands,
      bind_to_cwd = false,
      -- netrw disabled, opening a directory opens neo-tree
      -- in whatever position is specified in window.position
      -- "open_current",  -- netrw disabled, opening a directory opens within the
      -- window like netrw would, regardless of window.position
      -- "disabled",    -- netrw left alone, neo-tree does not handle opening dirs
      -- hijack_netrw_behavior = "disabled",
      follow_current_file = {
        enabled = true,
        leave_dirs_open = true,
      },
      filtered_items = {
        hide_dotfiles = false,
        hide_gitignored = true,
        hide_by_name = {
          ".git",
          ".idea",
          ".DS_Store",
        },
        always_show = {
          ".nvim.json",
        },
        show_hidden_count = false,
        never_show = {
          ".DS_Store",
        },
      },
      use_libuv_file_watcher = not _G.__os.is_windows,
    },
    diagnostics = {
      autopreview = false,
      autopreview_config = {},
      autopreview_event = "neo_tree_buffer_enter",
      bind_to_cwd = true,
      diag_sort_function = "severity",
      follow_behavior = {
        always_focus_file = true,
        expand_followed = true,
        collapse_others = true,
      },
      follow_current_file = false,
      group_dirs_and_files = true,
      group_empty_dirs = true,
      show_unloaded = true,
    },
    git_status = {
      indent = {
        padding = 0,
      },
    },
    -- nesting_rules = require("neotree-file-nesting-config").nesting_rules,
  }
  return full_opts
end

M.neo_tree_setup = function()
  require("neo-tree").setup(M.neo_tree())
end

return M
@Ajaymamtora Ajaymamtora added the bug Something isn't working label Oct 5, 2024
@Ajaymamtora
Copy link
Author

It appears after a short delay on open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant