summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2024-09-08 15:37:03 -0400
committerpommicket <pommicket@gmail.com>2024-09-08 15:37:03 -0400
commitfd1e2b3d3ccd26fb5bd9d7cbced04f673cfd19ba (patch)
treea045f5d5f44c63a603e4c56f53d5f986c3973488
parentc4ab62a68f81fda1365bab9e5200f27a6a986bae (diff)
Customizable data directories
-rw-r--r--Makefile20
-rw-r--r--README.md8
-rw-r--r--control2
-rw-r--r--main.c146
-rw-r--r--ted.h2
-rw-r--r--windows_installer/ted/ted.vdproj6
6 files changed, 127 insertions, 57 deletions
diff --git a/Makefile b/Makefile
index 50861cd..7a01a86 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,19 @@
+# where to put ted's files
+# GLOBAL_DATA_DIR = files shared between all users (e.g. default ted.cfg)
+# LOCAL_DATA_DIR = user-specific files
+# either one can start with ~ for home directory.
+# these are currently ignored for debug builds.
+GLOBAL_DATA_DIR?=/usr/share/ted
+LOCAL_DATA_DIR?=~/.local/share/ted
+INSTALL_BIN_DIR?=/usr/bin
+
ALL_CFLAGS=$(CFLAGS) -Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -std=gnu11 \
-Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough -Wno-format-truncation -Wno-unknown-warning-option \
- -Ipcre2
+ -Ipcre2 -DTED_GLOBAL_DATA_DIR='"$(GLOBAL_DATA_DIR)"' -DTED_LOCAL_DATA_DIR='"$(LOCAL_DATA_DIR)"'
LIBS=-lSDL2 -lGL -lm libpcre2-32.a libpcre2-8.a
RELEASE_CFLAGS=$(ALL_CFLAGS) -O3
PROFILE_CFLAGS=$(ALL_CFLAGS) -O3 -g -DPROFILE=1
-# if you change the directories below, ted won't work.
-# we don't yet have support for using different data directories
-GLOBAL_DATA_DIR=/usr/share/ted
-LOCAL_DATA_DIR=/home/`logname`/.local/share/ted
-INSTALL_BIN_DIR=/usr/bin
+
debug-build: ted compile_commands.json
ted: debug/ted
@# note: needed so cp doesn't fail if `ted` is busy
@@ -33,8 +38,7 @@ install: release
@[ -w `dirname $(GLOBAL_DATA_DIR)` ] || { echo "You need permission to write to $(GLOBAL_DATA_DIR). Try running with sudo/as root." && exit 1; }
@[ -w `dirname $(INSTALL_BIN_DIR)` ] || { echo "You need permission to write to $(INSTALL_BIN_DIR). Try running with sudo/as root." && exit 1; }
- mkdir -p $(GLOBAL_DATA_DIR) $(LOCAL_DATA_DIR)
- chown `logname`:`logname` $(LOCAL_DATA_DIR)
+ mkdir -p $(GLOBAL_DATA_DIR)
cp -r assets $(GLOBAL_DATA_DIR)
cp -r themes $(GLOBAL_DATA_DIR)
install -m 644 ted.cfg $(GLOBAL_DATA_DIR)
diff --git a/README.md b/README.md
index 06422a9..68cac35 100644
--- a/README.md
+++ b/README.md
@@ -292,6 +292,14 @@ sudo apt install clang libsdl2-dev cmake imagemagick
Then run `make -j8 release` to build or `sudo make install -j8` to build and install.
You can also run `make -j8 ted.deb` to build the .deb installer.
+This installs ted for all users. If you just want to install it for yourself (or you don't have superuser access), you can do so
+with
+
+```bash
+mkdir -p ~/.local/bin ~/.local/share
+GLOBAL_DATA_DIR='~/.local/share/ted-data' LOCAL_DATA_DIR='~/.local/share/ted' INSTALL_BIN_DIR='~/.local/bin' make install -j8
+```
+
On Windows, install Microsoft Visual Studio 2022, then find and add vcvarsall.bat to your PATH
(most likely lives at `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build`).
Also, install the [Visual Studio Installer Projects extension](https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects)
diff --git a/control b/control
index 9525107..49091d0 100644
--- a/control
+++ b/control
@@ -1,5 +1,5 @@
Package: ted
-Version: 2.7.2
+Version: 2.7.3
Section: text
Priority: optional
Architecture: amd64
diff --git a/main.c b/main.c
index 723b748..bace6b8 100644
--- a/main.c
+++ b/main.c
@@ -2,22 +2,43 @@
FUTURE FEATURES:
- more tests
- prepare rename support
-- autodetect indentation (tabs vs spaces)
- custom file/build command associations
- config variables
- bind key to series of commands
- convert macro to command list
- plugins?
- - built-in plugins
+ - built-in plugins:
- "remove file..." menu
- auto-close brackets
- with macros we can really test performance of buffer_insert_text_at_pos, etc. (which should ideally be fast)
-- manual directory
+- better manual
- restart LSP server automatically?
- LSP request timeout
- reflow command
*/
+/*
+macros defining ted data directory locations.
+the first character can be interpreted specially if it is one of the following:
+ ~ home directory
+ ^ user's AppData\Local directory (Windows only)
+ @ directory containing ted executable
+*/
+#ifndef TED_GLOBAL_DATA_DIR
+#if _WIN32
+ #define TED_GLOBAL_DATA_DIR "@"
+#else
+ #define TED_GLOBAL_DATA_DIR "/usr/share/ted"
+#endif
+#endif
+#ifndef TED_LOCAL_DATA_DIR
+#if _WIN32
+ #define TED_LOCAL_DATA_DIR "^/ted"
+#else
+ #define TED_LOCAL_DATA_DIR "~/.local/share/ted"
+#endif
+#endif
+
#include "ted-internal.h"
#include <locale.h>
@@ -369,38 +390,94 @@ int main(int argc, char **argv) {
os_get_cwd(ted->start_cwd, sizeof ted->start_cwd);
{ // get local and global data directory
-#if _WIN32
- wchar_t *appdata = NULL;
+ #if _WIN32
+ char *appdata = NULL;
+ wchar_t *appdata_wide = NULL;
KNOWNFOLDERID id = FOLDERID_LocalAppData;
- if (SHGetKnownFolderPath(&id, 0, NULL, &appdata) == S_OK) {
- strbuf_printf(ted->local_data_dir, "%ls%cted", appdata, PATH_SEPARATOR);
- CoTaskMemFree(appdata);
+ if (SHGetKnownFolderPath(&id, 0, NULL, &appdata_wide) == S_OK) {
+ size_t sz = wcslen(appdata_wide) * 4 + 1;
+ appdata = malloc(sz);
+ snprintf(appdata, sz, "%ls", appdata_wide);
+ CoTaskMemFree(appdata_wide); appdata_wide = NULL;
}
id = FOLDERID_Profile;
- wchar_t *home = NULL;
- if (SHGetKnownFolderPath(&id, 0, NULL, &home) == S_OK) {
- strbuf_printf(ted->home, "%ls", home);
- CoTaskMemFree(home);
+ wchar_t *home_wide = NULL;
+ if (SHGetKnownFolderPath(&id, 0, NULL, &home_wide) == S_OK) {
+ strbuf_printf(ted->home, "%ls", home_wide);
+ CoTaskMemFree(home_wide);
}
-
- // on Windows, the global data directory is just the directory where the executable is.
WCHAR executable_wide_path[TED_PATH_MAX] = {0};
- char executable_path[TED_PATH_MAX] = {0};
+ char executable_dir[TED_PATH_MAX] = {0};
if (GetModuleFileNameW(NULL, executable_wide_path, sizeof executable_wide_path - 1) > 0) {
- WideCharToMultiByte(CP_UTF8, 0, executable_wide_path, -1, executable_path, sizeof executable_path, NULL, NULL);
- char *last_backslash = strrchr(executable_path, '\\');
+ WideCharToMultiByte(CP_UTF8, 0, executable_wide_path, -1, executable_dir, sizeof executable_dir, NULL, NULL);
+ char *last_backslash = strrchr(executable_dir, '\\');
if (last_backslash) {
*last_backslash = '\0';
- strbuf_cpy(ted->global_data_dir, executable_path);
}
}
-#else
+ #elif __unix__
char *home = getenv("HOME");
strbuf_printf(ted->home, "%s", home);
- strbuf_printf(ted->local_data_dir, "%s/.local/share/ted", home);
- strbuf_printf(ted->global_data_dir, "/usr/share/ted");
-#endif
-
+ char executable_dir[TED_PATH_MAX] = {0};
+ ssize_t len = readlink("/proc/self/exe", executable_dir, sizeof executable_dir - 1);
+ if (len == -1) {
+ // some posix systems don't have /proc/self/exe. oh well.
+ } else {
+ executable_dir[len] = '\0';
+ char *last_slash = strrchr(executable_dir, '/');
+ if (last_slash) {
+ *last_slash = '\0';
+ // if we started in the directory where the executable is located,
+ // we're probably debugging ted, so search the start cwd for ted.cfg, etc.
+ ted->search_start_cwd = streq(ted->start_cwd, executable_dir);
+ }
+ }
+ #else
+ #error "unrecognized OS"
+ #endif
+ // replace special characters at start of data dirs
+ typedef struct {
+ const char *src;
+ char *dest;
+ size_t size;
+ } DataDir;
+ DataDir data_dirs[] = {
+ {.src = TED_LOCAL_DATA_DIR, .dest = ted->local_data_dir, .size = sizeof ted->local_data_dir},
+ {.src = TED_GLOBAL_DATA_DIR, .dest = ted->global_data_dir, .size = sizeof ted->global_data_dir},
+ };
+ for (size_t i = 0; i < arr_count(data_dirs); i++) {
+ const char *src = data_dirs[i].src;
+ char *dest = data_dirs[i].dest;
+ size_t size = data_dirs[i].size;
+ if (!src[0] || !strchr(ALL_PATH_SEPARATORS, src[1])) goto absolute_path;
+ switch (src[0]) {
+ case '~':
+ str_printf(dest, size, "%s%s", ted->home, src + 1);
+ break;
+ #if _WIN32
+ case '^':
+ str_printf(dest, size, "%s%s", appdata, src + 1);
+ break;
+ #endif
+ case '@':
+ str_printf(dest, size, "%s%s", executable_dir, src + 1);
+ break;
+ default:
+ absolute_path:
+ if (!path_is_absolute(src)) {
+ die("Data directory %s is not an absolute path", src);
+ }
+ str_cpy(dest, size, src);
+ }
+ // ensure we always use the same path separator
+ for (int c = 0; dest[c]; c++) {
+ if (strchr(ALL_PATH_SEPARATORS, dest[c]))
+ dest[c] = PATH_SEPARATOR;
+ }
+ }
+ if (fs_path_type(ted->global_data_dir) == FS_NON_EXISTENT) {
+ die("Couldn't open ted data directory at %s", ted->global_data_dir);
+ }
if (fs_path_type(ted->local_data_dir) == FS_NON_EXISTENT)
fs_mkdir(ted->local_data_dir);
@@ -424,29 +501,10 @@ int main(int argc, char **argv) {
os_get_cwd(ted->cwd, sizeof ted->cwd);
}
- { // check if this is the installed version of ted (as opposed to just running it from the directory with the source)
- #if _WIN32
- // never search cwd; we'll search the executable directory anyways
- #else
- char executable_path[TED_PATH_MAX] = {0};
- const char *cwd = ted->cwd;
- ssize_t len = readlink("/proc/self/exe", executable_path, sizeof executable_path - 1);
- if (len == -1) {
- // some posix systems don't have /proc/self/exe. oh well.
- } else {
- executable_path[len] = '\0';
- char *last_slash = strrchr(executable_path, '/');
- if (last_slash) {
- *last_slash = '\0';
- ted->search_start_cwd = streq(cwd, executable_path);
- }
- }
- #endif
- }
- #if TED_FORCE_SEARCH_CWD
+ #if TED_FORCE_SEARCH_START_CWD
// override whether or not we are in the executable's directory
// (for testing on Unix systems without /proc)
- ted->search_cwd = true;
+ ted->search_start_cwd = true;
#endif
PROFILE_TIME(misc_end)
diff --git a/ted.h b/ted.h
index d95d158..d11c9b7 100644
--- a/ted.h
+++ b/ted.h
@@ -22,7 +22,7 @@ extern "C" {
#include "command.h"
/// Version number
-#define TED_VERSION "2.7.2"
+#define TED_VERSION "2.7.3"
/// Maximum path size ted handles.
#define TED_PATH_MAX 1024
/// Config filename
diff --git a/windows_installer/ted/ted.vdproj b/windows_installer/ted/ted.vdproj
index fe1ecda..aac4438 100644
--- a/windows_installer/ted/ted.vdproj
+++ b/windows_installer/ted/ted.vdproj
@@ -620,15 +620,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:ted"
- "ProductCode" = "8:{952FA867-111C-443C-9AFB-DA084083F038}"
- "PackageCode" = "8:{BBBD2CF3-16E0-47E6-B64F-C1C73261D9F2}"
+ "ProductCode" = "8:{54706FEE-3070-4909-A56B-1FCFE6EB66C3}"
+ "PackageCode" = "8:{BFB90C03-ECC1-4511-9D2A-C6FEAB445A37}"
"UpgradeCode" = "8:{844F6C2B-DF3B-4A81-9BD5-603401BBA651}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:FALSE"
"InstallAllUsers" = "11:FALSE"
- "ProductVersion" = "8:24.07.1801"
+ "ProductVersion" = "8:24.09.0800"
"Manufacturer" = "8:ted"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"