@@ -13,26 +13,11 @@ local utils = {}
13
13
--- @field file OrgApiFile
14
14
--- @field filename string
15
15
--- @field headline ? OrgApiHeadline
16
+ --- @field title ? string
16
17
17
- --- Fetches entrys from OrgApi and extracts the relevant information
18
- --- @param opts any
18
+ --- @param file_results { file : OrgApiFile , filename : string } []
19
19
--- @return OrgEntry[]
20
- utils .get_entries = function (opts )
21
- --- @type { file : OrgApiFile , filename : string } []
22
- local file_results = vim .tbl_map (function (file )
23
- return { file = file , filename = file .filename }
24
- end , orgmode .load ())
25
-
26
- if not opts .archived then
27
- file_results = vim .tbl_filter (function (entry )
28
- return not entry .file .is_archive_file
29
- end , file_results )
30
- end
31
-
32
- if opts .max_depth == 0 then
33
- return file_results
34
- end
35
-
20
+ local function index_headlines (file_results , opts )
36
21
local results = {}
37
22
for _ , file_entry in ipairs (file_results ) do
38
23
for _ , headline in ipairs (file_entry .file .headlines ) do
@@ -43,6 +28,7 @@ utils.get_entries = function(opts)
43
28
file = file_entry .file ,
44
29
filename = file_entry .filename ,
45
30
headline = headline ,
31
+ title = nil ,
46
32
}
47
33
table.insert (results , entry )
48
34
end
@@ -52,11 +38,58 @@ utils.get_entries = function(opts)
52
38
return results
53
39
end
54
40
41
+ --- @param file_results { file : OrgApiFile , filename : string } []
42
+ --- @return OrgEntry[]
43
+ local function index_orgfiles (file_results , opts )
44
+ local results = {}
45
+ for _ , file_entry in ipairs (file_results ) do
46
+ local entry = {
47
+ file = file_entry .file ,
48
+ filename = file_entry .filename ,
49
+ -- not beautiful to access a private property, but this is the only way to get the title
50
+ --- @diagnostic disable-next-line : invisible , undefined-field
51
+ title = file_entry .file ._file :get_directive (' TITLE' ) or nil ,
52
+ headline = nil ,
53
+ }
54
+ table.insert (results , entry )
55
+ end
56
+ return results
57
+ end
58
+
59
+ --- Fetches entrys from OrgApi and extracts the relevant information
60
+ --- @param opts any
61
+ --- @return OrgEntry[]
62
+ utils .get_entries = function (opts )
63
+ --- @type { file : OrgApiFile , filename : string , last_used : number } []
64
+ local file_results = vim .tbl_map (function (file )
65
+ return { file = file , filename = file .filename }
66
+ end , orgmode .load ())
67
+
68
+ if not opts .archived then
69
+ file_results = vim .tbl_filter (function (entry )
70
+ return not entry .file .is_archive_file
71
+ end , file_results )
72
+ end
73
+
74
+ if opts .state and opts .state .current and opts .state .current .max_depth == 0 then
75
+ return index_orgfiles (file_results , opts )
76
+ end
77
+
78
+ return index_headlines (file_results , opts )
79
+ end
80
+
55
81
--- Entry-Maker for Telescope
56
82
--- @param opts any
57
83
--- @return fun ( entry : OrgEntry ): MatchEntry
58
84
utils .make_entry = function (opts )
59
- local displayer = entry_display .create ({
85
+ local orgfile_displayer = entry_display .create ({
86
+ separator = ' ' ,
87
+ items = {
88
+ { remaining = true },
89
+ },
90
+ })
91
+
92
+ local headline_displayer = entry_display .create ({
60
93
separator = ' ' ,
61
94
items = {
62
95
{ width = vim .F .if_nil (opts .location_width , 20 ) },
@@ -67,27 +100,32 @@ utils.make_entry = function(opts)
67
100
68
101
--- @param entry MatchEntry
69
102
local function make_display (entry )
70
- return displayer ({ entry .location , entry .tags .. ' ' .. entry .line })
103
+ if opts .state and opts .state .current and opts .state .current .max_depth == 0 then
104
+ return orgfile_displayer ({ entry .line })
105
+ else
106
+ return headline_displayer ({ entry .location , entry .tags .. ' ' .. entry .line })
107
+ end
71
108
end
72
109
73
110
return function (entry )
74
- local headline = entry .headline
75
-
76
111
local lnum = nil
77
112
local location = vim .fn .fnamemodify (entry .filename , ' :t' )
78
- local line = ' '
113
+ local line = entry . title or location
79
114
local tags = ' '
115
+ local ordinal = line
80
116
117
+ local headline = entry .headline
81
118
if headline then
82
119
lnum = headline .position .start_line
83
120
location = string.format (' %s:%i' , location , lnum )
84
121
line = string.format (' %s %s' , string.rep (' *' , headline .level ), headline .title )
122
+ ordinal = tags .. ' ' .. line .. ' ' .. location
85
123
tags = table.concat (headline .all_tags , ' :' )
86
124
end
87
125
88
126
return {
89
127
value = entry ,
90
- ordinal = location .. ' ' .. tags .. ' ' .. line ,
128
+ ordinal = ordinal ,
91
129
filename = entry .filename ,
92
130
lnum = lnum ,
93
131
display = make_display ,
@@ -103,20 +141,31 @@ utils.gen_depth_toggle = function(opts)
103
141
local current_picker = action_state .get_current_picker (prompt_bufnr )
104
142
local status = state .get_status (prompt_bufnr )
105
143
106
- if status ._ot_current_depth == nil and status ._ot_next_depth == nil then
107
- -- uninitialized state - initialize with "show files only"
144
+ -- FIXME: the state get's sometimes nil when the initalization has already been run
145
+ -- In this case, a toggle is "dropped" (keypress does not change the state).
146
+ -- Can we avoid that by initializing the state in the higher order function?
147
+ -- Idea: We can try to do it as before, but pass the prompt_bufnr with the opts.
148
+ if status ._ot_state == nil then
149
+ -- uninitialized state - initialize with orgfiles
108
150
-- Because when this function is called the first time, it is triggered
109
- -- by the users and we search over headings by default, we set the state
151
+ -- by the users and we search over headlines by default, we set the state
110
152
-- for the first toggle already here.
111
- status ._ot_current_depth = 0
112
- status ._ot_next_depth = opts .max_depth
153
+ -- _ot_ is used as our plugin-specific namespace in the action status
154
+ -- (ot - orgmode telescope)
155
+ status ._ot_state = { current = opts .state .orgfiles , next = opts .state .headlines }
113
156
else
114
157
-- initalized state - swap to next state
115
- status ._ot_current_depth , status ._ot_next_depth = status ._ot_next_depth , status ._ot_current_depth
158
+ status ._ot_state . current , status ._ot_state . next = status ._ot_state . next , status ._ot_state . current
116
159
end
117
160
118
161
-- opts is used as a channel to communicate the depth state to the get_entries function
119
- opts .max_depth = status ._ot_current_depth
162
+ opts .state .current = status ._ot_state .current
163
+
164
+ -- the caller may not have defined a prompt title - then we don't adjust it
165
+ if opts .state .current .prompt_title then
166
+ current_picker .layout .prompt .border :change_title (status ._ot_state .current .prompt_title )
167
+ end
168
+
120
169
local new_finder = finders .new_table ({
121
170
results = utils .get_entries (opts ),
122
171
entry_maker = opts .entry_maker or utils .make_entry (opts ),
0 commit comments