summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-02-01 04:04:55 -0800
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-02-01 04:04:55 -0800
commit8160ad061328dfd40696b1c36c8aa911062cf8a4 (patch)
tree422adf3c58a020bdb01e8a0699fb9f7d083b852f
parentf7e64e9c6a7dd22d16ac15adf4f86714b5b993ef (diff)
downloadmpv-iptv-menu-8160ad061328dfd40696b1c36c8aa911062cf8a4.tar.gz
mpv-iptv-menu-8160ad061328dfd40696b1c36c8aa911062cf8a4.tar.xz
move string seek/transform operations to util
-rw-r--r--rt.lua143
-rw-r--r--util.lua102
2 files changed, 131 insertions, 114 deletions
diff --git a/rt.lua b/rt.lua
index da6c238..6b2c09d 100644
--- a/rt.lua
+++ b/rt.lua
@@ -535,173 +535,88 @@ function rt.open_option_info(opt)
end
end
-function rt.search_text_insert_char(ev)
- if ev.event ~= 'down' and ev.event ~= 'repeat' then
+local function search_text_transform(f, ...)
+ local menu = state:menu()
+ local str, pos = f(menu.search_text, menu.search_cursor, ...)
+ if not str then
return
end
- local menu = state:menu()
- menu:set_search_text(
- menu.search_text:sub(1, menu.search_cursor - 1) ..
- ev.key_text ..
- menu.search_text:sub(menu.search_cursor),
- menu.search_cursor + #ev.key_text)
+ menu:set_search_text(str, pos)
osd:dirty()
end
-function rt.search_text_del_prev_char()
- local menu = state:menu()
- if menu.search_cursor <= 1 then
+function rt.search_text_insert_char(ev)
+ if ev.event ~= 'down' and ev.event ~= 'repeat' then
return
end
- local pos = util.utf8_seek(menu.search_text, menu.search_cursor, -1)
- menu:set_search_text(
- menu.search_text:sub(1, pos - 1) ..
- menu.search_text:sub(menu.search_cursor),
- pos)
- osd:dirty()
+ search_text_transform(util.str_insert_char, ev.key_text)
end
-function rt.search_text_del_next_char()
- local menu = state:menu()
- if menu.search_cursor > #menu.search_text then
- return
- end
+function rt.search_text_del_prev_char()
+ search_text_transform(util.str_del_prev_char)
+end
- menu:set_search_text(
- menu.search_text:sub(1, menu.search_cursor - 1) ..
- menu.search_text:sub(util.utf8_seek(
- menu.search_text, menu.search_cursor, 1)))
- osd:dirty()
+function rt.search_text_del_next_char()
+ search_text_transform(util.str_del_next_char)
end
function rt.search_text_del_prev_word()
- local menu = state:menu()
- if menu.search_cursor <= 1 then
- return
- end
-
- local pos = menu.search_text:sub(1, menu.search_cursor - 1):match(
- '()%S*%s*$')
- menu:set_search_text(
- menu.search_text:sub(1, pos - 1) ..
- menu.search_text:sub(menu.search_cursor),
- pos)
- osd:dirty()
+ search_text_transform(util.str_del_prev_word)
end
function rt.search_text_del_next_word()
- local menu = state:menu()
- if menu.search_cursor > #menu.search_text then
- return
- end
-
- local pos = menu.search_text:match('%s*%S*()', menu.search_cursor)
- menu:set_search_text(
- menu.search_text:sub(1, menu.search_cursor - 1) ..
- menu.search_text:sub(pos))
- osd:dirty()
+ search_text_transform(util.str_del_next_word)
end
function rt.search_text_del_to_start()
- local menu = state:menu()
- if menu.search_cursor <= 1 then
- return
- end
-
- menu:set_search_text(menu.search_text:sub(menu.search_cursor), 1)
- osd:dirty()
+ search_text_transform(util.str_del_to_start)
end
function rt.search_text_del_to_end()
- local menu = state:menu()
- if menu.search_cursor > #menu.search_text then
- return
- end
-
- menu:set_search_text(menu.search_text:sub(1, menu.search_cursor - 1))
- osd:dirty()
+ search_text_transform(util.str_del_to_end)
end
function rt.search_text_transpose_chars()
- local menu = state:menu()
- if menu.search_cursor <= 1 then
- return
- end
-
- local pos = util.utf8_seek(menu.search_text, menu.search_cursor, 1)
- local cp2 = util.utf8_seek(menu.search_text, pos, -1)
- if cp2 <= 1 then
- return
- end
- local cp1 = util.utf8_seek(menu.search_text, cp2, -1)
-
- menu:set_search_text(
- menu.search_text:sub(1, cp1 - 1) ..
- menu.search_text:sub(cp2, pos - 1) ..
- menu.search_text:sub(cp1, cp2 - 1) ..
- menu.search_text:sub(pos),
- pos)
- osd:dirty()
+ search_text_transform(util.str_transpose_chars)
end
function rt.search_text_transpose_words()
- local menu = state:menu()
- if menu.search_cursor <= 1 then
- return
- end
-
- local pos = menu.search_text:match('%s*%S*()', menu.search_cursor)
- local pre, w1, sp, w2 = menu.search_text:sub(1, pos - 1):match(
- '^(.-)(%S+)(%s+)(%S+%s*)$')
- if not pre then
- return
- end
-
- menu:set_search_text(
- pre .. w2 .. sp .. w1 .. menu.search_text:sub(pos),
- pos)
- osd:dirty()
+ search_text_transform(util.str_transpose_words)
end
-local function set_search_cursor(pos)
+local function search_cursor_move(f)
+ local menu = state:menu()
+ local pos = f(menu.search_text, menu.search_cursor)
+
if state:menu():set_search_cursor(pos) then
osd:dirty()
end
end
function rt.search_cursor_prev_char()
- local menu = state:menu()
- set_search_cursor(util.utf8_seek(
- menu.search_text, menu.search_cursor, -1))
+ search_cursor_move(util.str_seek_prev_char)
end
function rt.search_cursor_next_char()
- local menu = state:menu()
- set_search_cursor(util.utf8_seek(
- menu.search_text, menu.search_cursor, 1))
+ search_cursor_move(util.str_seek_next_char)
end
function rt.search_cursor_prev_word()
- local menu = state:menu()
- set_search_cursor(
- menu.search_text:sub(1, menu.search_cursor - 1):match(
- '()%S*%s*$'))
+ search_cursor_move(util.str_seek_prev_word)
end
function rt.search_cursor_next_word()
- local menu = state:menu()
- set_search_cursor(
- menu.search_text:match('%s*%S*()', menu.search_cursor))
+ search_cursor_move(util.str_seek_next_word)
end
function rt.search_cursor_start()
- set_search_cursor(1)
+ search_cursor_move(function() return 1 end)
end
function rt.search_cursor_end()
- set_search_cursor(#state:menu().search_text + 1)
+ search_cursor_move(function(str) return #str + 1 end)
end
function rt.start_search()
diff --git a/util.lua b/util.lua
index 04e1bf6..99bba7b 100644
--- a/util.lua
+++ b/util.lua
@@ -125,4 +125,106 @@ function util.stable_kmerge(t, u, k)
return res
end
+function util.str_seek_prev_char(str, pos)
+ return util.utf8_seek(str, pos, -1)
+end
+
+function util.str_seek_next_char(str, pos)
+ return util.utf8_seek(str, pos, 1)
+end
+
+function util.str_seek_prev_word(str, pos)
+ return str:sub(1, pos - 1):match('()%S*%s*$')
+end
+
+function util.str_seek_next_word(str, pos)
+ return str:match('%s*%S*()', pos)
+end
+
+function util.str_insert_char(str, pos, ch)
+ return str:sub(1, pos - 1) .. ch .. str:sub(pos), pos + #ch
+end
+
+function util.str_del_prev_char(str, pos)
+ if pos <= 1 then
+ return
+ end
+
+ local npos = util.utf8_seek(str, pos, -1)
+ return str:sub(1, npos - 1) .. str:sub(pos), npos
+end
+
+function util.str_del_next_char(str, pos)
+ if pos > #str then
+ return
+ end
+
+ return str:sub(1, pos - 1) .. str:sub(util.utf8_seek(str, pos, 1)), pos
+end
+
+function util.str_del_prev_word(str, pos)
+ if pos <= 1 then
+ return
+ end
+
+ local npos = str:sub(1, pos - 1):match('()%S*%s*$')
+ return str:sub(1, npos - 1) .. str:sub(pos), npos
+end
+
+function util.str_del_next_word(str, pos)
+ if pos > #str then
+ return
+ end
+
+ return str:sub(1, pos - 1) .. str:sub(str:match('%s*%S*()', pos)), pos
+end
+
+function util.str_del_to_start(str, pos)
+ if pos <= 1 then
+ return
+ end
+
+ return str:sub(pos), 1
+end
+
+function util.str_del_to_end(str, pos)
+ if pos > #str then
+ return
+ end
+
+ return str:sub(1, pos - 1), pos
+end
+
+function util.str_transpose_chars(str, pos)
+ if pos <= 1 then
+ return
+ end
+
+ local npos = util.utf8_seek(str, pos, 1)
+ local cp2 = util.utf8_seek(str, npos, -1)
+ if cp2 <= 1 then
+ return
+ end
+ local cp1 = util.utf8_seek(str, cp2, -1)
+
+ return str:sub(1, cp1 - 1) .. str:sub(cp2, npos - 1) ..
+ str:sub(cp1, cp2 - 1) .. str:sub(npos),
+ npos
+end
+
+function util.str_transpose_words(str, pos)
+ if pos <= 1 then
+ return
+ end
+
+ local npos = str:match('%s*%S*()', pos)
+ local pre, w1, sp, w2 = str:sub(1, npos - 1):match(
+ '^(.-)(%S+)(%s+)(%S+%s*)$')
+ if not pre then
+ return
+ end
+
+ return pre .. w2 .. sp .. w1 .. str:sub(npos), npos
+end
+
return util