Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions lua/nvim-dap-envfile.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local utils = require("utils")

local notify_opts = {
title = "nvim-dap-envfile",
icon = "",
Expand Down Expand Up @@ -79,15 +81,25 @@ function M.load_env_file(path)
local env = {} ---@type table<string,string>
local file = io.open(path, "r")
if not file then
vim.notify("Can't load file: " .. path, vim.log.levels.ERROR, notify_opts)
return env
end

for line in file:lines() do
---@type string, string
local key, value = line:match("^%s*([%w_]+)%s*=%s*(.+)%s*$")
if key and value then
-- remove quotes
env[key] = value:gsub('^"(.*)"$', "%1"):gsub("^'(.*)'$", "%1")
local key, value = utils.str_split_once(line, "=")

if value then
value = vim.trim(value)

if vim.startswith(value, '"') then
value = utils.parse_double(value)
elseif vim.startswith(value, "'") then
value = utils.parse_single(value)
end

env[key] = value
else
vim.notify('Unexpected format for "' .. key .. '"', vim.log.levels.WARN, notify_opts)
end
end

Expand Down
43 changes: 43 additions & 0 deletions lua/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
local M = {}

--- Splits a string into two parts at the first occurrence of a separator.
---
--- @param str string The input string to split.
--- @param sep string The separator to split on, plain text.
--- @return string left The part before the first separator
--- @return string|nil right The part after the first separator, or nil if not found.
function M.str_split_once(str, sep)
local pos = string.find(str, sep, 1, true) -- plain search
if not pos then
return str, nil
end
return str:sub(1, pos - 1), str:sub(pos + #sep)
end

---@param str string String in double quotes to parse.
---@return string
function M.parse_double(str)
if not vim.startswith(str, '"') or not vim.endswith(str, '"') then
return str
end

str = vim.fn.strcharpart(str, 1, #str - 2)
str = str:gsub('\\"', '"'):gsub("\\n", "\n"):gsub("\\\\", "\\"):gsub("\\t", "\t")

return str
end

---@param str string String in single quotes to parse.
---@return string
function M.parse_single(str)
if not vim.startswith(str, "'") or not vim.endswith(str, "'") then
return str
end

str = vim.fn.strcharpart(str, 1, #str - 2)
str = str:gsub("\\'", "'")

return str
end

return M
44 changes: 44 additions & 0 deletions tests/nvim-dap-envfile/load_env_file_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
local M = require("nvim-dap-envfile")
local path = M.expand_path_vars("${fileDirname}/tests/nvim-dap-envfile/test.env")

describe("load_env_file", function()
it("loads basic values", function()
local got = M.load_env_file(path)
assert.equal(got.basic, "value")
end)

it("trims spaces", function()
local got = M.load_env_file(path)
assert.equal(got.with_spaces, "value")
end)

it("trims double quotes", function()
local got = M.load_env_file(path)
assert.equal(got.double_quotes, "value")
end)

it("trims spaces, then double quotes", function()
local got = M.load_env_file(path)
assert.equal(got.double_quotes_spaces, "value")
end)

it("trims single quotes", function()
local got = M.load_env_file(path)
assert.equal(got.single_quotes, "value")
end)

it("handles double escape", function()
local got = M.load_env_file(path)
assert.equal(got.double_escape, '"value"')
end)

it("handles single escape", function()
local got = M.load_env_file(path)
assert.equal(got.single_escape, "'value'")
end)

it("handles special characters", function()
local got = M.load_env_file(path)
assert.equal(got.double_special, '\n\t"\\')
end)
end)
12 changes: 12 additions & 0 deletions tests/nvim-dap-envfile/test.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
basic=value

with_spaces= value

double_quotes="value"
double_quotes_spaces= "value"
single_quotes='value'

double_special="\n\t\"\\"

double_escape="\"value\""
single_escape='\'value\''