aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/option.c
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2020-11-25 12:15:55 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2020-11-25 12:15:55 +0100
commit72d29847d61358322caf3415404ca3a37c438dee (patch)
tree40e0bdd0717b73c4876a0686bd190f1c6b64fa91 /src/nvim/option.c
parentd285fa73da7ce2cb9abfbbb423eb8506e7202411 (diff)
downloadrneovim-72d29847d61358322caf3415404ca3a37c438dee.tar.gz
rneovim-72d29847d61358322caf3415404ca3a37c438dee.tar.bz2
rneovim-72d29847d61358322caf3415404ca3a37c438dee.zip
runtime: extract 'runtimepath' and 'packpath' logic to its own file
No code changes, except for added ILOG for the calculated startup path
Diffstat (limited to 'src/nvim/option.c')
-rw-r--r--src/nvim/option.c305
1 files changed, 9 insertions, 296 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 0a91687352..8f2cd4546b 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -56,6 +56,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
+#include "nvim/runtime.h"
#include "nvim/keymap.h"
#include "nvim/garray.h"
#include "nvim/cursor_shape.h"
@@ -337,301 +338,6 @@ static char_u SHM_ALL[] = {
# include "option.c.generated.h"
#endif
-/// Append string with escaped commas
-static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- size_t shift = 0;
- for (size_t i = 0; i < len; i++) {
- if (src[i] == ',') {
- dest[i + shift++] = '\\';
- }
- dest[i + shift] = src[i];
- }
- return &dest[len + shift];
-}
-
-/// Compute length of a ENV_SEPCHAR-separated value, doubled and with some
-/// suffixes
-///
-/// @param[in] val ENV_SEPCHAR-separated array value.
-/// @param[in] common_suf_len Length of the common suffix which is appended to
-/// each item in the array, twice.
-/// @param[in] single_suf_len Length of the suffix which is appended to each
-/// item in the array once.
-///
-/// @return Length of the ENV_SEPCHAR-separated string array that contains each
-/// item in the original array twice with suffixes with given length
-/// (common_suf is present after each new item, single_suf is present
-/// after half of the new items) and with commas after each item, commas
-/// inside the values are escaped.
-static inline size_t compute_double_env_sep_len(const char *const val,
- const size_t common_suf_len,
- const size_t single_suf_len)
- FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
-{
- if (val == NULL || *val == NUL) {
- return 0;
- }
- size_t ret = 0;
- const void *iter = NULL;
- do {
- size_t dir_len;
- const char *dir;
- iter = vim_env_iter(ENV_SEPCHAR, val, iter, &dir, &dir_len);
- if (dir != NULL && dir_len > 0) {
- ret += ((dir_len + memcnt(dir, ',', dir_len) + common_suf_len
- + !after_pathsep(dir, dir + dir_len)) * 2
- + single_suf_len);
- }
- } while (iter != NULL);
- return ret;
-}
-
-#define NVIM_SIZE (sizeof("nvim") - 1)
-
-/// Add directories to a ENV_SEPCHAR-separated array from a colon-separated one
-///
-/// Commas are escaped in process. To each item PATHSEP "nvim" is appended in
-/// addition to suf1 and suf2.
-///
-/// @param[in,out] dest Destination comma-separated array.
-/// @param[in] val Source ENV_SEPCHAR-separated array.
-/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it
-/// directory separator is appended. Suffix must not contain
-/// commas.
-/// @param[in] len1 Length of the suf1.
-/// @param[in] suf2 If not NULL, another suffix appended to destination. Again
-/// with directory separator behind. Suffix must not contain
-/// commas.
-/// @param[in] len2 Length of the suf2.
-/// @param[in] forward If true, iterate over val in forward direction.
-/// Otherwise in reverse.
-///
-/// @return (dest + appended_characters_length)
-static inline char *add_env_sep_dirs(char *dest, const char *const val,
- const char *const suf1, const size_t len1,
- const char *const suf2, const size_t len2,
- const bool forward)
- FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1)
-{
- if (val == NULL || *val == NUL) {
- return dest;
- }
- const void *iter = NULL;
- do {
- size_t dir_len;
- const char *dir;
- iter = (forward ? vim_env_iter : vim_env_iter_rev)(ENV_SEPCHAR, val, iter,
- &dir, &dir_len);
- if (dir != NULL && dir_len > 0) {
- dest = strcpy_comma_escaped(dest, dir, dir_len);
- if (!after_pathsep(dest - 1, dest)) {
- *dest++ = PATHSEP;
- }
- memmove(dest, "nvim", NVIM_SIZE);
- dest += NVIM_SIZE;
- if (suf1 != NULL) {
- *dest++ = PATHSEP;
- memmove(dest, suf1, len1);
- dest += len1;
- if (suf2 != NULL) {
- *dest++ = PATHSEP;
- memmove(dest, suf2, len2);
- dest += len2;
- }
- }
- *dest++ = ',';
- }
- } while (iter != NULL);
- return dest;
-}
-
-/// Adds directory `dest` to a comma-separated list of directories.
-///
-/// Commas in the added directory are escaped.
-///
-/// Windows: Appends "nvim-data" instead of "nvim" if `type` is kXDGDataHome.
-///
-/// @see get_xdg_home
-///
-/// @param[in,out] dest Destination comma-separated array.
-/// @param[in] dir Directory to append.
-/// @param[in] type Decides whether to append "nvim" (Win: or "nvim-data").
-/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it
-/// directory separator is appended. Suffix must not contain
-/// commas.
-/// @param[in] len1 Length of the suf1.
-/// @param[in] suf2 If not NULL, another suffix appended to destination. Again
-/// with directory separator behind. Suffix must not contain
-/// commas.
-/// @param[in] len2 Length of the suf2.
-/// @param[in] forward If true, iterate over val in forward direction.
-/// Otherwise in reverse.
-///
-/// @return (dest + appended_characters_length)
-static inline char *add_dir(char *dest, const char *const dir,
- const size_t dir_len, const XDGVarType type,
- const char *const suf1, const size_t len1,
- const char *const suf2, const size_t len2)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (dir == NULL || dir_len == 0) {
- return dest;
- }
- dest = strcpy_comma_escaped(dest, dir, dir_len);
- bool append_nvim = (type == kXDGDataHome || type == kXDGConfigHome);
- if (append_nvim) {
- if (!after_pathsep(dest - 1, dest)) {
- *dest++ = PATHSEP;
- }
-#if defined(WIN32)
- size_t size = (type == kXDGDataHome ? sizeof("nvim-data") - 1 : NVIM_SIZE);
- memmove(dest, (type == kXDGDataHome ? "nvim-data" : "nvim"), size);
- dest += size;
-#else
- memmove(dest, "nvim", NVIM_SIZE);
- dest += NVIM_SIZE;
-#endif
- if (suf1 != NULL) {
- *dest++ = PATHSEP;
- memmove(dest, suf1, len1);
- dest += len1;
- if (suf2 != NULL) {
- *dest++ = PATHSEP;
- memmove(dest, suf2, len2);
- dest += len2;
- }
- }
- }
- *dest++ = ',';
- return dest;
-}
-
-char *get_lib_dir(void)
-{
- // TODO(bfredl): too fragile? Ideally default_lib_dir would be made empty
- // in an appimage build
- if (strlen(default_lib_dir) != 0
- && os_isdir((const char_u *)default_lib_dir)) {
- return xstrdup(default_lib_dir);
- }
-
- // Find library path relative to the nvim binary: ../lib/nvim/
- char exe_name[MAXPATHL];
- vim_get_prefix_from_exepath(exe_name);
- if (append_path(exe_name, "lib" _PATHSEPSTR "nvim", MAXPATHL) == OK) {
- return xstrdup(exe_name);
- }
- return NULL;
-}
-
-/// Sets &runtimepath to default value.
-///
-/// Windows: Uses "…/nvim-data" for kXDGDataHome to avoid storing
-/// configuration and data files in the same path. #4403
-///
-/// If "clean_arg" is true, Nvim was started with --clean.
-static void set_runtimepath_default(bool clean_arg)
-{
- size_t rtp_size = 0;
- char *const data_home = clean_arg
- ? NULL
- : stdpaths_get_xdg_var(kXDGDataHome);
- char *const config_home = clean_arg
- ? NULL
- : stdpaths_get_xdg_var(kXDGConfigHome);
- char *const vimruntime = vim_getenv("VIMRUNTIME");
- char *const libdir = get_lib_dir();
- char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs);
- char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
-#define SITE_SIZE (sizeof("site") - 1)
-#define AFTER_SIZE (sizeof("after") - 1)
- size_t data_len = 0;
- size_t config_len = 0;
- size_t vimruntime_len = 0;
- size_t libdir_len = 0;
- if (data_home != NULL) {
- data_len = strlen(data_home);
- if (data_len != 0) {
-#if defined(WIN32)
- size_t nvim_size = (sizeof("nvim-data") - 1);
-#else
- size_t nvim_size = NVIM_SIZE;
-#endif
- rtp_size += ((data_len + memcnt(data_home, ',', data_len)
- + nvim_size + 1 + SITE_SIZE + 1
- + !after_pathsep(data_home, data_home + data_len)) * 2
- + AFTER_SIZE + 1);
- }
- }
- if (config_home != NULL) {
- config_len = strlen(config_home);
- if (config_len != 0) {
- rtp_size += ((config_len + memcnt(config_home, ',', config_len)
- + NVIM_SIZE + 1
- + !after_pathsep(config_home, config_home + config_len)) * 2
- + AFTER_SIZE + 1);
- }
- }
- if (vimruntime != NULL) {
- vimruntime_len = strlen(vimruntime);
- if (vimruntime_len != 0) {
- rtp_size += vimruntime_len + memcnt(vimruntime, ',', vimruntime_len) + 1;
- }
- }
- if (libdir != NULL) {
- libdir_len = strlen(libdir);
- if (libdir_len != 0) {
- rtp_size += libdir_len + memcnt(libdir, ',', libdir_len) + 1;
- }
- }
- rtp_size += compute_double_env_sep_len(data_dirs,
- NVIM_SIZE + 1 + SITE_SIZE + 1,
- AFTER_SIZE + 1);
- rtp_size += compute_double_env_sep_len(config_dirs, NVIM_SIZE + 1,
- AFTER_SIZE + 1);
- if (rtp_size == 0) {
- return;
- }
- char *const rtp = xmalloc(rtp_size);
- char *rtp_cur = rtp;
- rtp_cur = add_dir(rtp_cur, config_home, config_len, kXDGConfigHome,
- NULL, 0, NULL, 0);
- rtp_cur = add_env_sep_dirs(rtp_cur, config_dirs, NULL, 0, NULL, 0, true);
- rtp_cur = add_dir(rtp_cur, data_home, data_len, kXDGDataHome,
- "site", SITE_SIZE, NULL, 0);
- rtp_cur = add_env_sep_dirs(rtp_cur, data_dirs, "site", SITE_SIZE, NULL, 0,
- true);
- rtp_cur = add_dir(rtp_cur, vimruntime, vimruntime_len, kXDGNone,
- NULL, 0, NULL, 0);
- rtp_cur = add_dir(rtp_cur, libdir, libdir_len, kXDGNone, NULL, 0, NULL, 0);
- rtp_cur = add_env_sep_dirs(rtp_cur, data_dirs, "site", SITE_SIZE,
- "after", AFTER_SIZE, false);
- rtp_cur = add_dir(rtp_cur, data_home, data_len, kXDGDataHome,
- "site", SITE_SIZE, "after", AFTER_SIZE);
- rtp_cur = add_env_sep_dirs(rtp_cur, config_dirs, "after", AFTER_SIZE, NULL, 0,
- false);
- rtp_cur = add_dir(rtp_cur, config_home, config_len, kXDGConfigHome,
- "after", AFTER_SIZE, NULL, 0);
- // Strip trailing comma.
- rtp_cur[-1] = NUL;
- assert((size_t) (rtp_cur - rtp) == rtp_size);
-#undef SITE_SIZE
-#undef AFTER_SIZE
- set_string_default("runtimepath", rtp, true);
- // Make a copy of 'rtp' for 'packpath'
- set_string_default("packpath", rtp, false);
- xfree(data_dirs);
- xfree(config_dirs);
- xfree(data_home);
- xfree(config_home);
- xfree(vimruntime);
- xfree(libdir);
-}
-
-#undef NVIM_SIZE
-
/// Initialize the options, first part.
///
/// Called only once from main(), just after creating the first buffer.
@@ -779,7 +485,14 @@ void set_init_1(bool clean_arg)
true);
// Set default for &runtimepath. All necessary expansions are performed in
// this function.
- set_runtimepath_default(clean_arg);
+ char *rtp = runtimepath_default(clean_arg);
+ if (rtp) {
+ ILOG("startup runtimepart/packpath value: %s", rtp);
+ set_string_default("runtimepath", rtp, true);
+ // Make a copy of 'rtp' for 'packpath'
+ set_string_default("packpath", rtp, false);
+ rtp = NULL; // ownership taken
+ }
/*
* Set all the options (except the terminal options) to their default