aboutsummaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorGuldoman <giulio.lettieri@gmail.com>2024-10-22 18:31:45 +0200
committerGitHub <noreply@github.com>2024-10-22 12:31:45 -0400
commitd48605887511e6ca4f6d9a239a53c19c6f98f255 (patch)
treea6332c1821b1186b9f6b6eff5680034bf14dd92f /data
parentd925da47fa80c627933a9f4fc535d61872978c52 (diff)
downloadlite-xl-d48605887511e6ca4f6d9a239a53c19c6f98f255.tar.gz
lite-xl-d48605887511e6ca4f6d9a239a53c19c6f98f255.zip
Add support for relative `require`s (#1634)
Diffstat (limited to 'data')
-rw-r--r--data/core/doc/init.lua4
-rw-r--r--data/core/start.lua65
2 files changed, 67 insertions, 2 deletions
diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua
index ec9d46bc..3999937f 100644
--- a/data/core/doc/init.lua
+++ b/data/core/doc/init.lua
@@ -1,6 +1,6 @@
local Object = require "core.object"
-local Highlighter = require "core.doc.highlighter"
-local translate = require "core.doc.translate"
+local Highlighter = require ".highlighter"
+local translate = require ".translate"
local core = require "core"
local syntax = require "core.syntax"
local config = require "core.config"
diff --git a/data/core/start.lua b/data/core/start.lua
index bfa74810..439f1cbc 100644
--- a/data/core/start.lua
+++ b/data/core/start.lua
@@ -46,6 +46,71 @@ end }
table.pack = table.pack or pack or function(...) return {...} end
table.unpack = table.unpack or unpack
+local lua_require = require
+local require_stack = { "" }
+---Loads the given module, returns any value returned by the searcher (`true` when `nil`).
+---Besides that value, also returns as a second result the loader data returned by the searcher,
+---which indicates how `require` found the module.
+---(For instance, if the module came from a file, this loader data is the file path.)
+---
+---This is a variant that also supports relative imports.
+---
+---For example `require ".b"` will require `b` in the same path of the current
+---file.
+---This also supports multiple levels traversal. For example `require "...b"`
+---will require `b` from two levels above the current one.
+---This method has a few caveats: it uses the last `require` call to get the
+---current "path", so this only works if the relative `require` is called inside
+---its parent `require`.
+---Calling a relative `require` in a function called outside the parent
+---`require`, will result in the wrong "path" being used.
+---
+---It's possible to save the current "path" with `get_current_require_path`
+---called inside the parent `require`, and use its return value to populate
+---future requires.
+---@see get_current_require_path
+---@param modname string
+---@return unknown
+---@return unknown loaderdata
+function require(modname, ...)
+ if modname then
+ local level, rel_path = string.match(modname, "^(%.*)(.*)")
+ level = #(level or "")
+ if level > 0 then
+ if #require_stack == 0 then
+ return error("Require stack underflowed.")
+ else
+ local base_path = require_stack[#require_stack]
+ while level > 1 do
+ base_path = string.match(base_path, "^(.*)%.") or ""
+ level = level - 1
+ end
+ modname = base_path
+ if #base_path > 0 then
+ modname = modname .. "."
+ end
+ modname = modname .. rel_path
+ end
+ end
+ end
+
+ table.insert(require_stack, modname)
+ local ok, result, loaderdata = pcall(lua_require, modname, ...)
+ table.remove(require_stack)
+
+ if not ok then
+ return error(result)
+ end
+ return result, loaderdata
+end
+
+---Returns the current `require` path.
+---@see require for details and caveats
+---@return string
+function get_current_require_path()
+ return require_stack[#require_stack]
+end
+
bit32 = bit32 or require "core.bit"
require "core.utf8string"