local t=vim.cmd local z=vim.fn local R={}R.getOS=function()local t=io.popen("\117\110\097\109\101 -\115")if t==nil then vim.notify("\069\114\114\111\114 \119\104\105\108\101 \111\112\101\110\105\110\103 \104\097\110\100\108\101\114",vim.log.levels.ERROR)return end local z=t:read("\042\097")t:close()z=z:gsub("\037\115\043","")if z=="\068\097\114\119\105\110"then return"\068\097\114\119\105\110"elseif z=="\076\105\110\117\120"then return"\076\105\110\117\120"else return end end R.isNeovimVersionsatisfied=function(t)return t<=tonumber((vim.version()).minor)end R.isExecutableAvailable=function(t)return vim.fn.executable(t)==1 end R.notify=function(t,z,R)local A={title=R,timeout=2000}vim.api.nvim_notify(t,z,A)end R.isNotEmpty=function(t)return t~=nil and t~=""end R.path_exists=function(t)return vim.loop.fs_stat(t)end R.project_files=function()local t=vim.loop.cwd().."\047\046\103\105\116"if R.path_exists(t)then return"\084\101\108\101\115\099\111\112\101 \103\105\116\095\102\105\108\101\115"else return"\084\101\108\101\115\099\111\112\101 \102\105\110\100\095\102\105\108\101\115"end end R.toggle_qf=function()local A=z.getwininfo()local V=false for t,z in pairs(A)do if z.quickfix==1 then V=true end end if V==true then t("\099\099\108\111\115\101")return end if R.isNotEmpty(z.getqflist())then t("\099\111\112\101\110")end end R.toggle_colorcolumn=function()local t=vim.api.nvim_get_option_value("\099\111\108\111\114\099\111\108\117\109\110",{})if t==""then R.notify("\069\110\097\098\108\101 \099\111\108\111\099\111\108\117\109\110",1,"\102\117\110\099\116\105\111\110\115\046\108\117\097")vim.api.nvim_set_option_value("\099\111\108\111\114\099\111\108\117\109\110","\055\057",{})else R.notify("\068\105\115\097\098\108\101 \099\111\108\111\099\111\108\117\109\110",1,"\102\117\110\099\116\105\111\110\115\046\108\117\097")vim.api.nvim_set_option_value("\099\111\108\111\114\099\111\108\117\109\110","",{})end end R.escapePair=function()local t={"\041","\093";"\125";"\062","\'";"\"";"\096";"\044"}local z=vim.api.nvim_get_current_line()local R,A=unpack(vim.api.nvim_win_get_cursor(0))local V=z:sub(A+1,-1)local Z=#V+1 local v=nil for t,z in ipairs(t)do local R,A=V:find(z)if R and R<Z then Z=R v=t end end if v then vim.api.nvim_win_set_cursor(0,{R,A+Z})else vim.api.nvim_win_set_cursor(0,{R,A+1})end end function R.get_listed_buffers()local t={}local z=0 for R=1,vim.fn.bufnr("\036"),1 do if vim.fn.buflisted(R)==1 then z=z+1 t[z]=R end end return t end function R.map(t,z,R,A)A=A or{}vim.keymap.set(t,z,R,A)end function R.on_attach(t)vim.api.nvim_create_autocmd("\076\115\112\065\116\116\097\099\104",{callback=function(z)local R=z.buf local A=vim.lsp.get_client_by_id(z.data.client_id)t(A,R)end})end return R
local cmd = vim.cmd
local fn = vim.fn

local M = {}

-- Check if running on Darwin or Linux
M.getOS = function()
  local handle = io.popen 'uname -s'
  if handle == nil then
    vim.notify('Error while opening handler', vim.log.levels.ERROR)
    return
  end
  local uname = handle:read '*a'
  handle:close()
  uname = uname:gsub('%s+', '')
  if uname == 'Darwin' then
    return 'Darwin'
  elseif uname == 'Linux' then
    return 'Linux'
  else
    return
  end
end

--- Check if the minimum Neovim version is satisfied
--- Expects only the minor version, e.g. "9" for 0.9.1
---@param version number
---@return boolean
M.isNeovimVersionsatisfied = function(version)
  return version <= tonumber(vim.version().minor)
end

---checks if a command is available
---@param command string
---@return boolean
M.isExecutableAvailable = function(command)
  return vim.fn.executable(command) == 1
end

M.notify = function(message, level, title)
  local notify_options = {
    title = title,
    timeout = 2000,
  }
  vim.api.nvim_notify(message, level, notify_options)
end

-- Check if a variable is not empty nor nil
M.isNotEmpty = function(s)
  return s ~= nil and s ~= ''
end

--- Check if path exists
M.path_exists = function(path)
  return vim.loop.fs_stat(path)
end

-- Return telescope files command
M.project_files = function()
  local path = vim.loop.cwd() .. '/.git'
  if M.path_exists(path) then
    return 'Telescope git_files'
  else
    return 'Telescope find_files'
  end
end

-- toggle quickfixlist
M.toggle_qf = function()
  local windows = fn.getwininfo()
  local qf_exists = false
  for _, win in pairs(windows) do
    if win['quickfix'] == 1 then
      qf_exists = true
    end
  end
  if qf_exists == true then
    cmd 'cclose'
    return
  end
  if M.isNotEmpty(fn.getqflist()) then
    cmd 'copen'
  end
end

-- toggle colorcolumn
M.toggle_colorcolumn = function()
  local value = vim.api.nvim_get_option_value('colorcolumn', {})
  if value == '' then
    M.notify('Enable colocolumn', 1, 'functions.lua')
    vim.api.nvim_set_option_value('colorcolumn', '79', {})
  else
    M.notify('Disable colocolumn', 1, 'functions.lua')
    vim.api.nvim_set_option_value('colorcolumn', '', {})
  end
end

-- move over a closing element in insert mode
M.escapePair = function()
  local closers = { ')', ']', '}', '>', "'", '"', '`', ',' }
  local line = vim.api.nvim_get_current_line()
  local row, col = unpack(vim.api.nvim_win_get_cursor(0))
  local after = line:sub(col + 1, -1)
  local closer_col = #after + 1
  local closer_i = nil
  for i, closer in ipairs(closers) do
    local cur_index, _ = after:find(closer)
    if cur_index and (cur_index < closer_col) then
      closer_col = cur_index
      closer_i = i
    end
  end
  if closer_i then
    vim.api.nvim_win_set_cursor(0, { row, col + closer_col })
  else
    vim.api.nvim_win_set_cursor(0, { row, col + 1 })
  end
end

-- @author kikito
-- @see https://codereview.stackexchange.com/questions/268130/get-list-of-buffers-from-current-neovim-instance
-- currently not used
function M.get_listed_buffers()
  local buffers = {}
  local len = 0
  for buffer = 1, vim.fn.bufnr '$' do
    if vim.fn.buflisted(buffer) == 1 then
      len = len + 1
      buffers[len] = buffer
    end
  end

  return buffers
end

function M.map(mode, l, r, opts)
  opts = opts or {}
  vim.keymap.set(mode, l, r, opts)
end

---@param on_attach fun(client, buffer)
function M.on_attach(on_attach)
  vim.api.nvim_create_autocmd('LspAttach', {
    callback = function(args)
      local buffer = args.buf
      local client = vim.lsp.get_client_by_id(args.data.client_id)
      on_attach(client, buffer)
    end,
  })
end

return M
