diff --git a/README.md b/README.md index bcee2ac8..ca09e5b8 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Plugin | Description [`selectionhighlight`](plugins/selectionhighlight.lua?raw=1) | Highlights regions of code that match the current selection *([screenshot](https://user-images.githubusercontent.com/3920290/80710883-5f597c80-8ae7-11ea-97f0-76dfacc08439.png))* [`sort`](plugins/sort.lua?raw=1) | Sorts selected lines alphabetically [`spellcheck`](plugins/spellcheck.lua?raw=1) | Underlines misspelt words *([screenshot](https://user-images.githubusercontent.com/3920290/79923973-9caa7400-842e-11ea-85d4-7a196a91ca50.png))* *— note: on Windows a [`words.txt`](https://github.com/dwyl/english-words/blob/master/words.txt) dictionary file must be placed beside the exe* +[`stateful_switch`](plugins/stateful_switch.lua?raw=1) | Improved switching between split panes which are displaying the same text file [`tabnumbers`](plugins/tabnumbers.lua?raw=1) | Displays tab numbers from 1–9 next to their names *([screenshot](https://user-images.githubusercontent.com/16415678/101285362-007a8500-37e5-11eb-869b-c10eb9d9d902.png)) [`theme16`](https://github.com/monolifed/theme16)* | Theme manager with base16 themes [`titleize`](plugins/titleize.lua?raw=1) | Titleizes selected string (`hello world` => `Hello World`) diff --git a/plugins/stateful_switch.lua b/plugins/stateful_switch.lua new file mode 100644 index 00000000..16767ee0 --- /dev/null +++ b/plugins/stateful_switch.lua @@ -0,0 +1,106 @@ +local core = require "core" +local command = require "core.command" +local keymap = require "core.keymap" + + +-- Keeps the line and column number where cursor was while switching +-- between split panes. It is useful when working on a large +-- text file in multiple panes. + + +local function new_weak_table() + return setmetatable({ }, { __mode = "v" }) +end + + +local function dv() + return core.active_view +end + + +local view_states = { } + + +local function find_in_view_state(view_state, node, idx) + for k, v in pairs(view_state) do + if v.node == node and v.idx == idx then + return k + end + end + + return -1 +end + + +local function save_view_state() + local node = core.root_view:get_active_node() + local idx = node:get_view_idx(dv()) + if dv().doc == nil then + return + end + + local line, col = dv().doc:get_selection(false) + + local ind = find_in_view_state(view_states, node, idx) + + local state = new_weak_table() + state.node = node + state.idx = idx + state.line = line + state.col = col + + if ind > -1 then + view_states[ind] = nil + end + + table.insert(view_states, state) +end + + +local function restore_view_state() + local node = core.root_view:get_active_node() + local idx = node:get_view_idx(dv()) + + local ind = find_in_view_state(view_states, node, idx) + if ind > -1 then + local state = view_states[ind] + local line = state.line + local col = state.col + + dv().doc:set_selection(line, col) + dv():scroll_to_line(line, true) + end +end + + +for _, dir in ipairs { "left", "right", "up", "down" } do + command.add(nil, { + ["stateful-switch:switch-to-" .. dir] = function () + save_view_state() + command.perform("root:switch-to-" .. dir) + restore_view_state() + end + }) +end + + +for _, dir in ipairs { "previous", "next" } do + command.add(nil, { + ["stateful-switch:switch-to-" .. dir .. "-tab"] = function () + save_view_state() + command.perform("root:switch-to-" .. dir .. "-tab") + restore_view_state() + end + }) +end + + +keymap.add({ + ["alt+j"] = "stateful-switch:switch-to-left", + ["alt+l"] = "stateful-switch:switch-to-right", + ["alt+i"] = "stateful-switch:switch-to-up", + ["alt+k"] = "stateful-switch:switch-to-down", + ["ctrl+tab"] = "stateful-switch:switch-to-next-tab", + ["ctrl+shift+tab"] = "stateful-switch:switch-to-previous-tab" +}) +