aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vis-lua.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/vis-lua.c b/vis-lua.c
index da875e2..bb97a33 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -11,6 +11,7 @@
* @license ISC
* @release RELEASE
*/
+#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -416,6 +417,11 @@ static void *obj_ref_check(lua_State *L, int idx, const char *type) {
return obj;
}
+static void *obj_ref_check_containerof(lua_State *L, int idx, const char *type, size_t offset) {
+ void *obj = obj_ref_check(L, idx, type);
+ return obj ? ((char*)obj-offset) : obj;
+}
+
static void *obj_lightref_new(lua_State *L, void *addr, const char *type) {
if (!addr)
return NULL;
@@ -1425,6 +1431,10 @@ static const struct luaL_Reg window_cursor_funcs[] = {
* File state.
* @tfield bool modified whether the file contains unsaved changes
*/
+/***
+ * File marks.
+ * @field marks array to access the marks of this file by single letter name
+ */
static int file_index(lua_State *L) {
File *file = obj_ref_check(L, 1, "vis.file");
if (!file) {
@@ -1473,6 +1483,11 @@ static int file_index(lua_State *L) {
lua_pushboolean(L, text_modified(file->text));
return 1;
}
+
+ if (strcmp(key, "marks") == 0) {
+ obj_ref_new(L, file->marks, "vis.file.marks");
+ return 1;
+ }
}
return index_common(L);
@@ -1751,6 +1766,53 @@ static const struct luaL_Reg file_lines_funcs[] = {
{ NULL, NULL },
};
+static int file_marks_index(lua_State *L) {
+ File *file = obj_ref_check_containerof(L, 1, "vis.file.marks", offsetof(File, marks));
+ if (!file)
+ goto err;
+ const char *symbol = luaL_checkstring(L, 2);
+ if (!symbol || strlen(symbol) != 1)
+ goto err;
+ enum VisMark mark = vis_mark_from(NULL /* XXX */, symbol[0]);
+ if (mark == VIS_MARK_INVALID)
+ goto err;
+ size_t pos = text_mark_get(file->text, file->marks[mark]);
+ if (pos == EPOS)
+ goto err;
+ lua_pushunsigned(L, pos);
+ return 1;
+err:
+ lua_pushnil(L);
+ return 1;
+}
+
+static int file_marks_newindex(lua_State *L) {
+ File *file = obj_ref_check_containerof(L, 1, "vis.file.marks", offsetof(File, marks));
+ if (!file)
+ return 0;
+ const char *symbol = luaL_checkstring(L, 2);
+ if (!symbol || strlen(symbol) != 1)
+ return 0;
+ enum VisMark mark = vis_mark_from(NULL /* XXX */, symbol[0]);
+ size_t pos = luaL_checkunsigned(L, 3);
+ if (mark < LENGTH(file->marks))
+ file->marks[mark] = text_mark_set(file->text, pos);
+ return 0;
+}
+
+static int file_marks_len(lua_State *L) {
+ File *file = obj_ref_check_containerof(L, 1, "vis.file.marks", offsetof(File, marks));
+ lua_pushunsigned(L, file ? LENGTH(file->marks) : 0);
+ return 1;
+}
+
+static const struct luaL_Reg file_marks_funcs[] = {
+ { "__index", file_marks_index },
+ { "__newindex", file_marks_newindex },
+ { "__len", file_marks_len },
+ { NULL, NULL },
+};
+
/***
* The user interface.
*
@@ -2034,6 +2096,8 @@ void vis_lua_init(Vis *vis) {
}
obj_type_new(L, "vis.file.mark");
+ obj_type_new(L, "vis.file.marks");
+ luaL_setfuncs(L, file_marks_funcs, 0);
obj_type_new(L, "vis.window.cursor");
luaL_setfuncs(L, window_cursor_funcs, 0);
@@ -2209,6 +2273,7 @@ void vis_lua_file_close(Vis *vis, File *file) {
obj_ref_new(L, file, "vis.file");
pcall(vis, L, 1, 0);
}
+ obj_ref_free(L, file->marks);
obj_ref_free(L, file->text);
obj_ref_free(L, file);
lua_pop(L, 1);