@@ -3,6 +3,7 @@ local utf8 = require('window-picker.utf-8')
33--- @class FloatingBigLetterHint
44--- @field win { width : number , height : number } window options
55--- @field windows number[] list of window ids
6+ --- @field prefix_windows number[][] list of window ids for the prefix characters
67local M = {}
78
89local border = {
@@ -30,6 +31,7 @@ function M:new()
3031 height = 8 ,
3132 },
3233 windows = {},
34+ prefix_windows = { {}, {}, {}, {} },
3335 }
3436
3537 setmetatable (o , self )
4042
4143function M :set_config (config )
4244 self .chars = config .chars
45+ self .create_chars = config .create_chars
4346 local font = config .picker_config .floating_big_letter .font
4447
4548 if type (font ) == ' string' then
@@ -51,13 +54,25 @@ function M:set_config(config)
5154 end
5255end
5356
54- function M :_get_float_win_pos (window )
57+ local positioning_params = {
58+ m = { 0.5 , 0.5 , 0.5 , 0.5 , ' NW' }, -- Middle
59+ h = { 0 , 0 , 0.5 , 0.5 , ' NW' }, -- Middle-left
60+ j = { 0.5 , 0.5 , 1 , 0 , ' SW' }, -- Bottom-middle
61+ k = { 0.5 , 0.5 , 0 , 0 , ' NW' }, -- Top-middle
62+ l = { 1 , 0 , 0.5 , 0.5 , ' NE' }, -- Middle-right
63+ }
64+ local create_win_positions = { ' h' , ' j' , ' k' , ' l' }
65+
66+ function M :_get_float_win_pos (window , position )
67+ position = position or ' m'
5568 local width = vim .api .nvim_win_get_width (window )
5669 local height = vim .api .nvim_win_get_height (window )
70+ local params = positioning_params [position ]
5771
5872 local point = {
59- x = ((width - self .win .width ) / 2 ),
60- y = ((height - self .win .height ) / 2 ),
73+ x = width * params [1 ] - self .win .width * params [2 ],
74+ y = height * params [3 ] - self .win .height * params [4 ],
75+ anchor = params [5 ],
6176 }
6277
6378 return point
@@ -79,7 +94,7 @@ function M._add_big_char_margin(lines)
7994 -- bottom padding
8095 table.insert (lines , # lines + 1 , ' ' )
8196
82- -- left & right padding
97+ -- left & right paddin
8398
8499 for _ , line in ipairs (lines ) do
85100 local new_line = string.format (
@@ -95,8 +110,8 @@ function M._add_big_char_margin(lines)
95110 return centered_lines
96111end
97112
98- function M :_show_letter_in_window (window , char )
99- local point = self :_get_float_win_pos (window )
113+ function M :_show_letter_in_window (window , char , position )
114+ local point = self :_get_float_win_pos (window , position )
100115
101116 local lines = self ._add_big_char_margin (vim .split (char , ' \n ' ))
102117
@@ -107,37 +122,67 @@ function M:_show_letter_in_window(window, char)
107122 local window_id = vim .api .nvim_open_win (buffer_id , false , {
108123 relative = ' win' ,
109124 win = window ,
110- focusable = true ,
125+ focusable = false ,
111126 row = point .y ,
112127 col = point .x ,
113128 width = width ,
114129 height = height ,
115130 style = ' minimal' ,
116131 border = border ,
132+ anchor = point .anchor ,
117133 })
118134
119135 vim .api .nvim_buf_set_lines (buffer_id , 0 , 0 , true , lines )
120136
121137 return window_id
122138end
123139
124- function M :draw (windows )
140+ function M :draw (windows , or_create )
125141 for index , window in ipairs (windows ) do
126- local char = self .chars [index ]
127- local big_char = self .big_chars [char :lower ()]
128- local window_id = self :_show_letter_in_window (window , big_char )
129- table.insert (self .windows , window_id )
142+ do
143+ local char = self .chars [index ]
144+ local big_char = self .big_chars [char :lower ()]
145+ local window_id = self :_show_letter_in_window (window , big_char )
146+ table.insert (self .windows , window_id )
147+ end
148+
149+ if or_create then
150+ for i = 1 , 4 do
151+ local char = self .create_chars [i ]
152+ local big_char = self .big_chars [char :lower ()]
153+ local dir = create_win_positions [i ]
154+ local window_id =
155+ self :_show_letter_in_window (window , big_char , dir )
156+ table.insert (self .prefix_windows [i ], window_id )
157+ end
158+ end
130159 end
131160end
132161
133- function M : clear ( )
134- for _ , window in ipairs (self . windows ) do
162+ local function clear_list_of_windows ( windows )
163+ for _ , window in ipairs (windows ) do
135164 if vim .api .nvim_win_is_valid (window ) then
136165 local buffer = vim .api .nvim_win_get_buf (window )
137166 vim .api .nvim_win_close (window , true )
138167 vim .api .nvim_buf_delete (buffer , { force = true })
139168 end
140169 end
170+ end
171+
172+ function M :clear_prefixes (index )
173+ for prefix , windows in ipairs (self .prefix_windows ) do
174+ -- Clear all prefixes except the one that was chosen
175+ if prefix ~= index then
176+ clear_list_of_windows (windows )
177+ self .prefix_windows [prefix ] = {}
178+ end
179+ end
180+ end
181+
182+ function M :clear ()
183+ clear_list_of_windows (self .windows )
184+
185+ self :clear_prefixes ()
141186
142187 self .windows = {}
143188end
0 commit comments