]>
Commit | Line | Data |
---|---|---|
c0539eea RBR |
1 | ------------------------------------------------------------------------------- |
2 | -- Tools to deal with the board | |
3 | ------------------------------------------------------------------------------- | |
4 | local Board = { | |
5 | saved_state = nil, | |
6 | } | |
7 | ||
8 | local Util = require('oleoboard.util') | |
9 | ||
10 | ------------------------------------------------------------------------------- | |
11 | -- Internal Functions | |
12 | ------------------------------------------------------------------------------- | |
13 | local function get_directories(parent_path) | |
14 | ||
15 | local directories = {} | |
16 | local directory_iterator = vim.loop.fs_scandir(parent_path) | |
17 | ||
18 | if directory_iterator then | |
19 | while true do | |
20 | local name, type = vim.loop.fs_scandir_next(directory_iterator) | |
21 | if not name then break end | |
22 | if type == "directory" then | |
23 | table.insert(directories, parent_path .. '/' .. name) | |
24 | end | |
25 | end | |
26 | else | |
27 | vim.api.nvim_err_writeln('Could not read directory ' .. parent_path) | |
28 | end | |
29 | ||
30 | return directories | |
31 | end | |
32 | ||
33 | local function save_state() | |
34 | ||
35 | local config_dir = vim.fn.stdpath('config') | |
36 | local session_file = config_dir .. '/oleoboard.saved' | |
37 | vim.cmd('mks! ' .. session_file) | |
38 | ||
39 | Board.saved_state = session_file | |
40 | end | |
41 | ||
42 | local function close_all_buffers() | |
43 | for _, window in ipairs(vim.api.nvim_list_wins()) do | |
44 | if window ~= vim.api.nvim_get_current_win() then | |
45 | vim.api.nvim_win_close(window, false) | |
46 | end | |
47 | end | |
48 | end | |
49 | ||
50 | local function restore_state() | |
51 | if Board.saved_state then | |
52 | ||
53 | local config_dir = vim.fn.stdpath('config') | |
54 | local session_file = config_dir .. '/oleoboard.saved' | |
55 | if vim.fn.filereadable(session_file) == 1 then | |
56 | vim.cmd('source ' .. session_file) | |
57 | vim.fn.delete(session_file) | |
58 | end | |
59 | ||
60 | Board.saved_state = nil | |
61 | end | |
62 | end | |
63 | ||
64 | local function find_left_neighbor(windows, current_window) | |
65 | ||
66 | local left_window = nil | |
67 | ||
68 | for _, window in ipairs(windows) do | |
69 | local window_position = vim.api.nvim_win_get_position(window) | |
70 | local current_position = vim.api.nvim_win_get_position(current_window) | |
71 | if Util.is_left_of(current_position, window_position) then | |
72 | if left_window then | |
73 | local candidate_position = vim.api.nvim_win_get_position(left_window) | |
74 | if Util.is_right_of(candidate_position, window_position) then | |
75 | left_window = window | |
76 | end | |
77 | else | |
78 | left_window = window | |
79 | end | |
80 | end | |
81 | end | |
82 | ||
83 | return left_window | |
84 | end | |
85 | ||
86 | local function find_right_neighbor(windows, current_window) | |
87 | ||
88 | local right_window = nil | |
89 | ||
90 | for _, window in ipairs(windows) do | |
91 | local window_position = vim.api.nvim_win_get_position(window) | |
92 | local current_position = vim.api.nvim_win_get_position(current_window) | |
93 | if Util.is_right_of(current_position, window_position) then | |
94 | right_window = window | |
95 | break | |
96 | end | |
97 | end | |
98 | ||
99 | return right_window | |
100 | end | |
101 | ||
102 | ------------------------------------------------------------------------------- | |
103 | -- Public Interface | |
104 | ------------------------------------------------------------------------------- | |
105 | ||
106 | --- Toggles the board | |
107 | function Board.toggle(directory) | |
108 | if Board.saved_state then | |
109 | Board.close() | |
110 | else | |
111 | Board.open(directory) | |
112 | end | |
113 | end | |
114 | ||
115 | --- Opens the board | |
116 | function Board.open(directory) | |
117 | if not directory or directory == '' then | |
118 | directory = vim.fn.getcwd() | |
119 | end | |
120 | ||
121 | local directories = get_directories(directory) | |
122 | if #directories > 0 then | |
123 | save_state() | |
124 | close_all_buffers() | |
125 | vim.api.nvim_command('enew') | |
126 | ||
127 | for i, directory in ipairs(directories) do | |
128 | if i > 1 then | |
129 | vim.api.nvim_command('vsplit') | |
130 | end | |
131 | vim.api.nvim_command('edit ' .. directory) | |
132 | vim.api.nvim_buf_set_var(0, 'is_oleoboard_column', true) | |
133 | end | |
134 | end | |
135 | end | |
136 | ||
137 | --- Closes the board | |
138 | function Board.close() | |
139 | for _, window in ipairs(vim.api.nvim_list_wins()) do | |
140 | local buffer = vim.api.nvim_win_get_buf(window) | |
141 | local ok, is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, buffer, 'is_oleoboard_column') | |
142 | if ok and is_oleoboard_column then | |
143 | vim.api.nvim_buf_delete(buffer, {force = true}) | |
144 | end | |
145 | end | |
146 | ||
147 | restore_state() | |
148 | end | |
149 | ||
150 | --- Moves the entry under the cursor to the right | |
151 | function Board.move_entry_right() | |
152 | ||
153 | local current_window = vim.api.nvim_get_current_win() | |
154 | local windows = vim.api.nvim_tabpage_list_wins(0) | |
155 | local right_window = nil | |
156 | ||
157 | right_window = find_right_neighbor(windows, current_window) | |
158 | ||
159 | if right_window then | |
160 | local buffer = vim.api.nvim_win_get_buf(right_window) | |
161 | local ok, is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, buffer, 'is_oleoboard_column') | |
162 | if ok and is_oleoboard_column then | |
163 | vim.cmd('normal! dd') | |
164 | vim.api.nvim_set_current_win(right_window) | |
165 | vim.cmd('normal! G') | |
166 | vim.cmd('normal! p') | |
167 | end | |
168 | end | |
169 | end | |
170 | ||
171 | --- Moves the entry under the cursor to the left | |
172 | function Board.move_entry_left() | |
173 | ||
174 | local current_window = vim.api.nvim_get_current_win() | |
175 | local windows = vim.api.nvim_tabpage_list_wins(0) | |
176 | local left_window = nil | |
177 | ||
178 | left_window = find_left_neighbor(windows, current_window) | |
179 | ||
180 | if left_window then | |
181 | local buffer = vim.api.nvim_win_get_buf(left_window) | |
182 | local ok, is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, buffer, 'is_oleoboard_column') | |
183 | if ok and is_oleoboard_column then | |
184 | vim.cmd('normal! dd') | |
185 | vim.api.nvim_set_current_win(left_window) | |
186 | vim.cmd('normal! G') | |
187 | vim.cmd('normal! p') | |
188 | end | |
189 | end | |
190 | end | |
191 | ||
192 | --- Moves the active column to the right | |
193 | function Board.move_column_right() | |
194 | local current_window = vim.api.nvim_get_current_win() | |
195 | local windows = vim.api.nvim_tabpage_list_wins(0) | |
196 | local right_window = find_right_neighbor(windows, current_window) | |
197 | ||
198 | if right_window then | |
199 | local right_buffer = vim.api.nvim_win_get_buf(right_window) | |
200 | local current_buffer = vim.api.nvim_win_get_buf(current_window) | |
201 | local right_ok, right_is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, right_buffer, 'is_oleoboard_column') | |
202 | local current_ok, current_is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, current_buffer, 'is_oleoboard_column') | |
203 | if right_ok and right_is_oleoboard_column and current_ok and current_is_oleoboard_column then | |
204 | vim.api.nvim_win_set_buf(right_window, current_buffer) | |
205 | vim.api.nvim_win_set_buf(current_window, right_buffer) | |
206 | vim.api.nvim_set_current_win(right_window) | |
207 | end | |
208 | end | |
209 | end | |
210 | ||
211 | --- Moves the active column to the left | |
212 | function Board.move_column_left() | |
213 | local current_window = vim.api.nvim_get_current_win() | |
214 | local windows = vim.api.nvim_tabpage_list_wins(0) | |
215 | local left_window = find_left_neighbor(windows, current_window) | |
216 | ||
217 | if left_window then | |
218 | local left_buffer = vim.api.nvim_win_get_buf(left_window) | |
219 | local current_buffer = vim.api.nvim_win_get_buf(current_window) | |
220 | local left_ok, left_is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, left_buffer, 'is_oleoboard_column') | |
221 | local current_ok, current_is_oleoboard_column = pcall(vim.api.nvim_buf_get_var, current_buffer, 'is_oleoboard_column') | |
222 | if left_ok and left_is_oleoboard_column and current_ok and current_is_oleoboard_column then | |
223 | vim.api.nvim_win_set_buf(left_window, current_buffer) | |
224 | vim.api.nvim_win_set_buf(current_window, left_buffer) | |
225 | vim.api.nvim_set_current_win(left_window) | |
226 | end | |
227 | end | |
228 | end | |
229 | ||
230 | return Board |