]> git.r.bdr.sh - rbdr/oleoboard.nvim/blob - lua/oleoboard/board.lua
11b90db9f83c859d5846c698bb1c86849c311ff2
[rbdr/oleoboard.nvim] / lua / oleoboard / board.lua
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, 1)
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