Skip to content
chinise edited this page Dec 9, 2023 · 8 revisions

One of the features of lir.nvim is that it allows you to easily define and map your own actions.

NOTE: Feel free to add your own actions!

home()

local function home()
  vim.cmd('edit ' .. vim.fn.expand('$HOME'))
end

gomi()

Use b4b4r07/gomi

local function gomi()
  local ctx = lir.get_context()

  local marked_items = ctx:get_marked_items()
  if #marked_items == 0 then
    utils.error('Please mark one or more.')
    return
  end

  local path_list = vim.tbl_map(function(items)
    return esc_path(items.fullpath)
  end, marked_items)

  if vim.fn.confirm("Delete files?", "&Yes\n&No", 2) ~= 1 then
    return
  end
  vim.fn.system('gomi ' .. vim.fn.join(path_list))
  actions.reload()
end

nop()

local function nop()
end

goto_git_root()

local function goto_git_root()
  local dir = require'lspconfig.util'.find_git_ancestor(vim.fn.getcwd())
  if dir == nil or dir == "" then
    return
  end
  vim.cmd ('e ' .. dir)
end

rename_and_jump()

local function rename_and_jump()
  local ctx = lir.get_context()
  local old = string.gsub(ctx:current_value(), '/$', '')
  local new = vim.fn.input('Rename: ', old)
  if new == '' or new == old then
    return
  end

  if new == '.' or new == '..' or string.match(new, '[/\\]') then
    utils.error('Invalid name: ' .. new)
    return
  end

  if not vim.loop.fs_rename(ctx.dir .. old, ctx.dir .. new) then
    utils.error('Rename failed')
  end

  actions.reload()

  local lnum = lir.get_context():indexof(new)
  if lnum then
    vim.cmd(tostring(lnum))
  end
end

input_newfile()

  • If the input value ends with '/', the directory will be created and
  • If the input value contains '/', and the directory does not exist, it will be created recursively
  • If the input file name does not contain '.' or '/', check if it is a directory.
  • If the first string is '.' and show_hidden_files is false, set it to true and display it again.
local lir = require('lir')
local utils = lir.utils
local config = lir.config
local Path = require('plenary.path')

local function lcd(path)
  vim.cmd(string.format(':lcd %s', path))
end

local no_confirm_patterns = {
  '^LICENSE$',
  '^Makefile$'
}

local need_confirm = function(filename)
  for _, pattern in ipairs(no_confirm_patterns) do
    if filename:match(pattern) then
      return false
    end
  end
  return true
end

local function input_newfile()
  local save_curdir = vim.fn.getcwd()
  lcd(lir.get_context().dir)
  local name = vim.fn.input('New file: ', '', 'file')
  lcd(save_curdir)

  if name == '' then
    return
  end

  if name == '.' or name == '..' then
    utils.error('Invalid file name: ' .. name)
    return
  end

  -- If I need to check, I will.
  if need_confirm(name) then
    -- '.' is not included or '/' is not included, then
    -- I may have entered it as a directory, I'll check.
    if not name:match('%.') and not name:match('/') then
      if vim.fn.confirm("Directory?", "&No\n&Yes", 1) == 2 then
        name = name .. '/'
      end
    end
  end

  local path = Path:new(lir.get_context().dir .. name)
  if string.match(name, '/$') then
    -- mkdir
    name = name:gsub('/$', '')
    path:mkdir({
      parents = true,
      mode = tonumber('700', 8),
      exists_ok = false
    })
  else
    -- touch
    path:touch({
      parents = true,
      mode = tonumber('644', 8),
    })
  end

  -- If the first character is '.' and show_hidden_files is false, set it to true
  if name:match([[^%.]]) and not config.values.show_hidden_files then
    config.values.show_hidden_files = true
  end

  actions.reload()

  -- Jump to a line in the parent directory of the file you created.
  local lnum = lir.get_context():indexof(name:match('^[^/]+'))
  if lnum then
    vim.cmd(tostring(lnum))
  end
end

telescope fd_lir

local pickers = require('telescope.pickers')
local finders = require('telescope.finders')
local conf = require('telescope.config').values
local actions = require('telescope.actions')
local action_state = require "telescope.actions.state"
local utils = require "telescope.utils"

return function()
  local cwd
  local is_lir = vim.bo.filetype == 'lir'
  if is_lir then
    cwd = vim.fn.expand('%:p')
  else
    -- もし、git のディレクトリだったら、 root を使う
    cwd = vim.fn.getcwd()
    local output = utils.get_os_command_output({'git', 'rev-parse', '--show-toplevel'}, cwd)
    if output[1] and not vim.tbl_isempty(output) then
      cwd = output[1]
    end
  end

  pickers.new({}, {
    prompt_title = 'lir fd',
    finder = finders.new_oneshot_job(
      {'fd', '--color=never', '--type', 'directory'},
      {
        cwd = cwd
      }
    ),
    sorter = conf.generic_sorter({}),
    previewer = conf.file_previewer({
      -- depth = 1
    }),
    attach_mappings = function(prompt_bufnr, _)
      actions.select_default:replace(function()
        local entry = action_state.get_selected_entry()
        actions.close(prompt_bufnr)
        if is_lir then
          vim.cmd('e ' .. cwd .. '/' .. entry.value)
          return
        else
        end
        require'lir.float'.init(cwd .. '/' .. entry.value)
      end)

      return true
    end,
  }):find()
end

telescope fnamemodify

local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local conf = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local lir = require("lir")

local find_git_ancestor = require("lspconfig.util").find_git_ancestor

local fnamemodify = function(mods)
  return function(path)
    return vim.fn.fnamemodify(path, mods)
  end
end

local git_fnamemodify = function(mods)
  mods = vim.F.if_nil(mods, ':p')
  return function(path)
    local root = find_git_ancestor(path)
    if root == nil then
      return nil
    end

    path = vim.fn.fnamemodify(path, mods)
    return path:sub(#root + 2)
  end
end

local fnamemods = {
  fnamemodify(":p:t"),
  git_fnamemodify(),
  git_fnamemodify(":p:h"),
  git_fnamemodify(":p:h:h"),
  fnamemodify(":p"),
  fnamemodify(":p:h"),
  fnamemodify(":p:h:h"),
}

return function()
  local ctx = lir.get_context()
  local cur_path = ctx:current().fullpath
  local results = {}
  for _, mod in ipairs(fnamemods) do
    local res = mod(cur_path)
    if res and res ~= "" then
      table.insert(results, res)
    end
  end

  pickers.new({}, {
    prompt_title = "Paths",
    finder = finders.new_table({
      results = results,
      entry_maker = function(entry)
        return {
          value = entry,
          display = entry,
          ordinal = entry,
        }
      end,
    }),
    sorter = conf.generic_sorter({}),
    attach_mappings = function(prompt_bufnr, _)
      actions.select_default:replace(function()
        local entry = action_state.get_selected_entry()
        actions.close(prompt_bufnr)

        vim.fn.setreg(vim.v.register, entry.value)
      end)

      return true
    end,
  }):find()
end

filename_command()

Populates command line with filename for ease of running command on files.

Inspired by vim-vinegar

local lir = require'lir'

local function filename_command()
  local full_path, _ = lir.get_context():current().fullpath:gsub("//", "/"):gsub("\\\\", "\\")
  local pwd = vim.fn.getcwd()
  local final_path = full_path

  if full_path:sub(1, pwd:len()) == pwd then
    final_path = "."..full_path:sub(pwd:len()+1)
  end

  if final_path:find(' ') then
    final_path = '"'..final_path..'"'
  end

  vim.api.nvim_input(string.format(": %s<C-b>", final_path))
end