{
  "@class (LuaDoc)": {
    "body": [
      "---@class (exact) ${1:class_name}",
      "---@field ${2:field_name} string"
    ],
    "description": "https://github.com/LuaLS/lua-language-server/wiki/Annotations#class",
    "prefix": "@class (LuaDoc)"
  },
  "@type (LuaDoc)": {
    "body": "---@type ${1:string}",
    "prefix": "@type (LuaDoc)"
  },
  "Record (type)": {
    "body": "---@type table<string, string>",
    "prefix": "Record (type)"
  },
  "count occurrences in string": {
    "body": "local _, count = ${1:str}:gsub(\"${2:find}\", \"\")",
    "prefix": "count occurrences in string"
  },
  "export module": {
    "body": [
      "local M = {}",
      "--------------------------------------------------------------------------------",
      "",
      "$0--------------------------------------------------------------------------------",
      "return M"
    ],
    "prefix": "export module"
  },
  "find all in string": {
    "body": [
      "local ${1:matches} = {}",
      "for match in ${2:str}:gmatch(${3:pattern}) do",
      "\ttable.insert(${1:matches}, match)",
      "end"
    ],
    "prefix": "find all in string"
  },
  "for each (list)": {
    "body": [
      "for _, ${1:v} in pairs(${2:table}) do",
      "\t$0",
      "end"
    ],
    "prefix": "for each (list)"
  },
  "for each line (of file)": {
    "body": [
      "for line in io.lines(${1:filepath}) do",
      "\t$0",
      "end"
    ],
    "prefix": [
      "for each line (file)",
      "read file (as lines)"
    ]
  },
  "home": {
    "body": "os.getenv(\"HOME\")",
    "prefix": "home"
  },
  "if .. then .. else": {
    "body": [
      "if ${1:true} then",
      "\t$2",
      "else",
      "\t$0",
      "end"
    ],
    "filetype": "lua",
    "prefix": "if .. then .. else"
  },
  "nodiscard": {
    "body": "---@nodiscard",
    "description": "Luadoc Annotation that a function's return value should not be discarded. https://github.com/LuaLS/lua-language-server/wiki/Annotations#nodiscard",
    "prefix": "nodiscard"
  },
  "path of this file": {
    "body": "local pathOfThisFile = debug.getinfo(1).source:sub(2)",
    "prefix": "path of this file"
  },
  "path separator (os-independent)": {
    "body": "local osPathSep = package.config:sub(1, 1)",
    "prefix": "path separator (os-independent)"
  },
  "pcall": {
    "body": [
      "local success = pcall(${1:func})",
      "if not success then",
      "\t$0",
      "\treturn",
      "end"
    ],
    "prefix": [
      "try",
      "pcall"
    ]
  },
  "read file": {
    "body": [
      "---@param filePath string",
      "---@return string? -- content or error message",
      "---@return boolean success",
      "local function readFile(filePath)",
      "\tlocal file, err = io.open(filePath, \"r\")",
      "\tif not file then return err, false end",
      "\tlocal content = file:read(\"*a\")",
      "\tfile:close()",
      "\treturn content, true",
      "end"
    ],
    "prefix": "read file"
  },
  "redirect (metatable __index)": {
    "body": [
      "setmetatable(M, {",
      "\t__index = function(_, key)",
      "\t\treturn function(...)",
      "\t\t\trequire(${1:moduleToRedirectTo})[key](...)",
      "\t\tend",
      "\tend,",
      "})"
    ],
    "prefix": "redirect (metatable __index)"
  },
  "round number": {
    "body": "local roundedNum = tonumber(string.format(\"%.${1:decimals}f\", exactNum))",
    "prefix": "round number"
  },
  "safe require": {
    "body": [
      "local ok, ${1:module} = require(\"${1:module}\")",
      "if not (ok and ${1:module}) then return end",
      "${1:module}.$0"
    ],
    "prefix": "safe require"
  },
  "sort (table)": {
    "body": "table.sort(${1:table}, function(a, b) return ${2:a} > ${3:b} end)",
    "prefix": "sort (table)"
  },
  "split (gmatch)": {
    "body": [
      "local acc = {}",
      "for part in ${1:str}:gmatch(\"(.-)\" .. ${2:delimiter}) do",
      "\ttable.insert(acc, part)",
      "end"
    ],
    "filetype": "lua",
    "prefix": "split (gmatch)"
  },
  "ternary": {
    "body": "${1:condition} and ${2:value1} or ${3:value2}",
    "prefix": "ternary"
  },
  "trim trailing line break": {
    "body": ":gsub(\"\\n$\", \"\")",
    "prefix": "trim"
  },
  "write file": {
    "body": [
      "---@param str string",
      "---@param filePath string",
      "---@return string|nil -- error message",
      "local function overwriteFile(filePath, str)",
      "\tlocal file, _ = io.open(filePath, \"w\")",
      "\tif not file then return end",
      "\tfile:write(str)",
      "\tfile:close()",
      "end"
    ],
    "description": "Overwriting file, for appending use `a` instead of `w`.",
    "prefix": "write file"
  },
  "Create Auto Command": {
    "prefix": "autocmd",
    "body": [
      "vim.api.nvim_create_autocmd(\"${1:event}\", {",
      "  group = vim.api.nvim_create_augroup(\"${2:group}\", { clear = true }),",
      "  callback = function(ev)",
      "    ${0}",
      "  end",
      "})"
    ]
  },
  "Create Auto Command Group": {
    "prefix": "augroup",
    "body": [
      "vim.api.nvim_create_augroup(\"${1:group}\", { clear = true })$0"
    ]
  },
  "Current Win": {
    "prefix": "win",
    "body": "local win = vim.api.nvim_get_current_win()\n$0"
  },
  "Current Buf": {
    "prefix": "buf",
    "body": "local buf = vim.api.nvim_get_current_buf()\n$0"
  },
  "Buf Valid": {
    "prefix": "bufvalid",
    "body": "vim.api.nvim_buf_is_valid(${1:buf})"
  },
  "Win Valid": {
    "prefix": "winvalid",
    "body": "vim.api.nvim_win_is_valid(${1:win})"
  },
  "Win Call": {
    "prefix": "wincall",
    "body": [
      "vim.api.nvim_win_call(${1:win}, function(win)",
      "  ${0}",
      "end)"
    ]
  },
  "Buf Call": {
    "prefix": "bufcall",
    "body": [
      "vim.api.nvim_buf_call(${1:buf}, function(buf)",
      "  ${0}",
      "end)"
    ]
  },
  "Schedule": {
    "prefix": "schedule",
    "body": [
      "vim.schedule(function()",
      "  ${0}",
      "end)"
    ]
  },
  "Table Deep Extend": {
    "prefix": "deepextend",
    "body": "vim.tbl_deep_extend(\"force\", ${1:table}, ${2:table})$0"
  },
  "Table Filter": {
    "prefix": "filter",
    "body": [
      "vim.tbl_filter(function()",
      "  $0",
      "end, ${1:table})"
    ]
  },
  "Table Map": {
    "prefix": "map",
    "body": [
      "vim.tbl_map(function()",
      "  $0",
      "end, ${1:table})"
    ]
  },
  "Table Values": {
    "prefix": "values",
    "body": "vim.tbl_values(${1:table})"
  },
  "Table Keys": {
    "prefix": "keys",
    "body": "vim.tbl_keys(${1:table})"
  }
}
