Skip to content

Commit 49a4219

Browse files
committed
Merge branch 'telescope' into dev
* telescope: Also make picker height flex by content Collect all widths info in one loop Make picker width adaptive by content length Add new select ui option "telescope" Set "kind" option in ui.select
2 parents 9d7669f + 5df54f6 commit 49a4219

File tree

6 files changed

+172
-2
lines changed

6 files changed

+172
-2
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ CHANGES
1919
allow to use ad-hoc groups instead of ordinary added groups. This is useful
2020
to setup different mappings for another set of groups.
2121

22+
* Add another selection UI type `telescope` which opens a telescope.nvim picker.
23+
2224
* Add `cycle_filetype_links` option; to define certain filetypes to share other types' groups.
2325

2426
* Change the phased search for multibyte character, fix a problem when cword is equal to cchar.

autoload/cycle/conflict.vim

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@ let s:funcs = {}
22
let s:loaders = {}
33

44

5+
" Select UI Loaders: {{{
6+
7+
function! s:loaders.telescope() abort " {{{
8+
if has('nvim') && exists(':Telescope') == 2
9+
function! s:TelescopeConflictSelect(...) abort
10+
return luaeval('require("vim_cycle.telescope").conflict_select(unpack(_A))', a:000)
11+
endfunction
12+
let s:funcs['telescope'] = function('s:TelescopeConflictSelect')
13+
else
14+
let s:funcs['telescope'] = 'unavailable'
15+
endif
16+
endfunction " }}}
17+
18+
519
function! s:loaders.ui_select() abort " {{{
620
if has('nvim') && luaeval('vim.ui.select')->type() == v:t_func
721
function! s:LuaConflictSelect(...) abort
@@ -32,6 +46,8 @@ function! s:loaders._test() abort " {{{
3246
let s:funcs['_test'] = function('cycle#test#conflict_ui')
3347
endfunction " }}}
3448

49+
" }}}
50+
3551

3652
function! cycle#conflict#ui(options, ctx) abort " {{{
3753
let pref = get(g:, 'cycle_conflict_ui', '')
@@ -40,7 +56,7 @@ function! cycle#conflict#ui(options, ctx) abort " {{{
4056
return s:funcs[pref](a:options, a:ctx)
4157
endif
4258

43-
let prefs = sort(['ui.select', 'inputlist', 'confirm', '_test'], {a, b -> b == pref})
59+
let prefs = sort(['telescope', 'ui.select', 'inputlist', 'confirm', '_test'], {a, b -> b == pref})
4460

4561
for key in prefs
4662
if !has_key(s:funcs, key)

autoload/cycle/select.vim

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ let s:hint_pad = 4
55

66
" Select UI Loaders: {{{
77

8+
function! s:loaders.telescope() abort " {{{
9+
if has('nvim') && exists(':Telescope') == 2
10+
function! s:TelescopeSelect(...) abort
11+
return luaeval('require("vim_cycle.telescope").select(unpack(_A))', a:000)
12+
endfunction
13+
let s:funcs['telescope'] = function('s:TelescopeSelect')
14+
else
15+
let s:funcs['telescope'] = 'unavailable'
16+
endif
17+
endfunction " }}}
18+
19+
820
function! s:loaders.ui_select() abort " {{{
921
if has('nvim') && luaeval('vim.ui.select')->type() == v:t_func
1022
function! s:LuaSelect(...) abort
@@ -45,7 +57,7 @@ function! cycle#select#ui(options, ctx) abort " {{{
4557
return s:funcs[pref](a:options, a:ctx)
4658
endif
4759

48-
let prefs = sort(['ui.select', 'inputlist', 'confirm', '_test'], {a, b -> b == pref})
60+
let prefs = sort(['telescope', 'ui.select', 'inputlist', 'confirm', '_test'], {a, b -> b == pref})
4961

5062
for key in prefs
5163
if !has_key(s:funcs, key)

doc/cycle.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ g:cycle_select_ui (default: "") ~
160160

161161
Can be set to one of the following:
162162

163+
telescope Use |telesope.nvim| picker.
164+
163165
ui.select Use nvim's |vim.ui.select()|.
164166

165167
inputlist Use Vim's |inputlist()|, input number and Enter to select.

lua/vim_cycle/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ local make_select_options = function(options)
2626
local format_str = string.format("%%-%dS" .. hint_pad .. " %%-%dS", max_length, max_hint_length)
2727

2828
local select_options = {
29+
kind = 'vim-cycle',
2930
prompt = 'Cycle to:',
3031
format_item = function(opt)
3132
local group

lua/vim_cycle/telescope.lua

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
local strings = require 'plenary.strings'
2+
local pickers = require 'telescope.pickers'
3+
local finders = require 'telescope.finders'
4+
local conf = require('telescope.config').values
5+
local actions = require 'telescope.actions'
6+
local action_state = require 'telescope.actions.state'
7+
local themes = require 'telescope.themes'
8+
local make_entry = require 'telescope.make_entry'
9+
local entry_display = require 'telescope.pickers.entry_display'
10+
11+
local hint_pad_size = 2
12+
local content_width = 0
13+
local items_size = 0
14+
local picker_padding = 6
15+
16+
local M = {}
17+
18+
local flex_width = function(self, max_columns, max_lines)
19+
local width = content_width + picker_padding * 2
20+
width = math.max(width, 20)
21+
width = math.min(width, math.floor(max_columns * 0.9))
22+
return width
23+
end
24+
25+
local flex_height = function(self, max_columns, max_lines)
26+
local height = items_size + picker_padding
27+
height = math.max(height, 10)
28+
height = math.min(height, math.floor(max_lines * 0.9))
29+
return height
30+
end
31+
32+
local defaults = themes.get_cursor{
33+
layout_config = {
34+
width = flex_width,
35+
height = flex_height,
36+
},
37+
}
38+
39+
local config = vim.tbl_extend('force', {}, defaults)
40+
41+
M.setup = function(opts)
42+
config = vim.tbl_deep_extend('force', defaults, opts or {})
43+
end
44+
45+
function picker(type, items, ctx)
46+
local opts = config
47+
48+
local title = ''
49+
local callback = ''
50+
if type == 'select' then
51+
title = 'Cycle'
52+
callback = ctx.sid .. 'on_select'
53+
elseif type == 'conflict' then
54+
title = 'Conflict'
55+
callback = ctx.sid .. 'on_resolve_conflict'
56+
end
57+
58+
local widths = {
59+
text = 0,
60+
hint = 0,
61+
group_name = 0,
62+
}
63+
for idx, item in ipairs(items) do
64+
widths.text = math.max(widths.text , strings.strdisplaywidth(item.text))
65+
widths.hint = math.max(widths.hint, strings.strdisplaywidth(item.hint))
66+
widths.group_name = math.max(widths.group_name, strings.strdisplaywidth(item.group_name))
67+
end
68+
content_width = widths.text + widths.hint + widths.group_name + (widths.hint > 0 and hint_pad_size or 0) + (widths.group_name > 0 and 2 or 0)
69+
items_size = #items
70+
71+
local displayer = entry_display.create {
72+
separator = ' ',
73+
items = {
74+
{ width = widths.text },
75+
{ width = widths.hint > 0 and hint_pad_size or 1 },
76+
{ width = widths.hint },
77+
{ remaining = true },
78+
},
79+
}
80+
81+
local make_display = function(entry)
82+
local v = entry.value
83+
local group_name = v.group_name
84+
if #group_name > 0 then
85+
group_name = string.format('(%s)', group_name)
86+
end
87+
return displayer {
88+
{ v.text },
89+
'',
90+
{ v.hint, 'TelescopeResultsFunction' },
91+
{ group_name, 'TelescopeResultsComment' },
92+
}
93+
end
94+
95+
local entry_maker = function(entry)
96+
return make_entry.set_default_entry_mt({
97+
value = entry,
98+
ordinal = entry.text,
99+
display = make_display,
100+
}, opts)
101+
end
102+
103+
pickers
104+
.new(opts, {
105+
prompt_title = title,
106+
finder = finders.new_table {
107+
results = items,
108+
entry_maker = entry_maker,
109+
},
110+
sorter = conf.generic_sorter(opts),
111+
attach_mappings = function(prompt_bufnr, map)
112+
actions.select_default:replace(function()
113+
actions.close(prompt_bufnr)
114+
local selection = action_state.get_selected_entry()
115+
116+
if selection then
117+
vim.call(callback, selection.index, ctx)
118+
return
119+
end
120+
end)
121+
122+
return true
123+
end,
124+
})
125+
:find()
126+
127+
end
128+
129+
M.select = function(items, ctx)
130+
picker('select', items, ctx)
131+
end
132+
133+
M.conflict_select = function(items, ctx)
134+
picker('conflict', items, ctx)
135+
end
136+
137+
return M

0 commit comments

Comments
 (0)