NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
complete.c File Reference

Notmuch Auto-Completion. More...

#include "config.h"
#include <notmuch.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "complete/lib.h"
#include "editor/lib.h"
#include "index/lib.h"
+ Include dependency graph for complete.c:

Go to the source code of this file.

Functions

static void nm_complete_data_init (struct CompletionData *cd, const char *pt)
 Reset the completion state for a tag lookup.
 
static int complete_all_nm_tags_fresh (struct CompletionData *cd)
 Query notmuch directly for a fresh tag list.
 
int complete_all_nm_tags (struct CompletionData *cd, const char *pt)
 Pass a list of Notmuch tags to the completion code.
 
bool mutt_nm_query_complete (struct CompletionData *cd, struct Buffer *buf, int numtabs)
 Complete to the nearest notmuch tag.
 
bool mutt_nm_tag_complete (struct CompletionData *cd, struct Buffer *buf, int numtabs)
 Complete to the nearest notmuch tag.
 
enum FunctionRetval complete_nm_query (struct EnterWindowData *wdata, int op)
 Complete a Notmuch Query - Implements CompleteOps::complete() -.
 
enum FunctionRetval complete_nm_tag (struct EnterWindowData *wdata, int op)
 Complete a Notmuch Tag - Implements CompleteOps::complete() -.
 

Variables

const struct CompleteOps CompleteNmQueryOps
 Auto-Completion of NmQuerys.
 
const struct CompleteOps CompleteNmTagOps
 Auto-Completion of NmTags.
 

Detailed Description

Notmuch Auto-Completion.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file complete.c.

Function Documentation

◆ nm_complete_data_init()

static void nm_complete_data_init ( struct CompletionData * cd,
const char * pt )
static

Reset the completion state for a tag lookup.

Parameters
cdCompletion Data
ptUser input being completed

Definition at line 49 of file complete.c.

50{
52 mutt_str_copy(cd->user_typed, pt, sizeof(cd->user_typed));
53 memset(cd->match_list, 0, cd->match_list_len * sizeof(const char *));
54 memset(cd->completed, 0, sizeof(cd->completed));
55 cd->num_matched = 0;
56 cd->free_match_strings = true;
57}
void completion_data_free_match_strings(struct CompletionData *cd)
Free the Completion strings.
Definition data.c:38
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition string.c:587
int match_list_len
Enough space for all of the config items.
Definition data.h:37
bool free_match_strings
Should the strings in match_list be freed?
Definition data.h:38
char user_typed[1024]
Initial string that starts completion.
Definition data.h:33
char completed[256]
Completed string (command or variable)
Definition data.h:35
int num_matched
Number of matches for completion.
Definition data.h:34
const char ** match_list
Matching strings.
Definition data.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ complete_all_nm_tags_fresh()

static int complete_all_nm_tags_fresh ( struct CompletionData * cd)
static

Query notmuch directly for a fresh tag list.

Parameters
cdCompletion Data
Return values
0Success
-1Error

Definition at line 65 of file complete.c.

66{
67 int rc = -1;
68 struct Mailbox *m_cur = get_current_mailbox();
69 notmuch_database_t *db = NULL;
70 notmuch_tags_t *tags = NULL;
71 const char *db_filename = nm_db_get_filename(m_cur);
72
73#if !LIBNOTMUCH_CHECK_VERSION(5, 4, 0)
74 if (!db_filename)
75 db_filename = cs_subset_string(NeoMutt->sub, "folder");
76#endif
77
78 if (!(db = nm_db_do_open(db_filename, false, false)) ||
79 !(tags = notmuch_database_get_all_tags(db)))
80 {
81 goto done;
82 }
83
84 while (notmuch_tags_valid(tags))
85 {
86 const char *tag = notmuch_tags_get(tags);
87
88 /* Keep a private copy because notmuch owns the iterator storage. */
89 if (*tag && candidate(cd, cd->user_typed, tag, cd->completed, sizeof(cd->completed)))
90 cd->match_list[cd->num_matched - 1] = mutt_str_dup(tag);
91
92 notmuch_tags_move_to_next(tags);
93 }
94
95 rc = 0;
96
97done:
98 if (tags)
99 notmuch_tags_destroy(tags);
100 if (db)
101 nm_db_free(db);
102
103 return rc;
104}
bool candidate(struct CompletionData *cd, char *user, const char *src, char *dest, size_t dlen)
Helper function for completion.
Definition helpers.c:79
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition index.c:725
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
notmuch_database_t * nm_db_do_open(const char *filename, bool writable, bool verbose)
Open a Notmuch database.
Definition db.c:116
const char * nm_db_get_filename(struct Mailbox *m)
Get the filename of the Notmuch database.
Definition db.c:63
void nm_db_free(notmuch_database_t *db)
Decoupled way to close a Notmuch database.
Definition db.c:262
A mailbox.
Definition mailbox.h:81
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ complete_all_nm_tags()

int complete_all_nm_tags ( struct CompletionData * cd,
const char * pt )

Pass a list of Notmuch tags to the completion code.

Parameters
cdCompletion Data
ptUser input being completed
Return values
0Success
-1Error

Definition at line 113 of file complete.c.

114{
115 int rc = -1;
116
117 nm_complete_data_init(cd, pt);
119 if (rc == 0)
120 {
123 }
124
125 return rc;
126}
void matches_ensure_morespace(struct CompletionData *cd, int new_size)
Allocate more space for auto-completion.
Definition helpers.c:54
static void nm_complete_data_init(struct CompletionData *cd, const char *pt)
Reset the completion state for a tag lookup.
Definition complete.c:49
static int complete_all_nm_tags_fresh(struct CompletionData *cd)
Query notmuch directly for a fresh tag list.
Definition complete.c:65
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_nm_query_complete()

bool mutt_nm_query_complete ( struct CompletionData * cd,
struct Buffer * buf,
int numtabs )

Complete to the nearest notmuch tag.

Parameters
cdCompletion Data
bufBuffer for the result
numtabsNumber of times the user has hit 'tab'
Return values
trueSuccess, a match
falseError, no match

Complete the last "tag:"-prefixed string.

Definition at line 138 of file complete.c.

139{
140 char *pt = buf->data;
141 int spaces;
142
143 SKIPWS(pt);
144 spaces = pt - buf->data;
145
146 pt = (char *) buf_rfind(buf, "tag:");
147 if (pt)
148 {
149 pt += 4;
150 if (numtabs == 1)
151 {
152 /* First TAB. Collect all the matches */
153 complete_all_nm_tags(cd, pt);
154
155 /* All matches are stored. Longest non-ambiguous string is ""
156 * i.e. don't change 'buf'. Fake successful return this time. */
157 if (cd->user_typed[0] == '\0')
158 return true;
159 }
160
161 if ((cd->completed[0] == '\0') && (cd->user_typed[0] != '\0'))
162 return false;
163
164 /* cd->num_matched will _always_ be at least 1 since the initial
165 * user-typed string is always stored */
166 if ((numtabs == 1) && (cd->num_matched == 2))
167 {
168 snprintf(cd->completed, sizeof(cd->completed), "%s", NONULL(cd->match_list[0]));
169 }
170 else if ((numtabs > 1) && (cd->num_matched > 2))
171 {
172 /* cycle through all the matches */
173 snprintf(cd->completed, sizeof(cd->completed), "%s",
174 NONULL(cd->match_list[(numtabs - 2) % cd->num_matched]));
175 }
176
177 /* return the completed query */
178 strncpy(pt, cd->completed, buf->data + buf->dsize - pt - spaces);
179 }
180 else
181 {
182 return false;
183 }
184
185 return true;
186}
const char * buf_rfind(const struct Buffer *buf, const char *str)
Find last instance of a substring.
Definition buffer.c:805
int complete_all_nm_tags(struct CompletionData *cd, const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition complete.c:113
#define NONULL(x)
Definition string2.h:44
#define SKIPWS(ch)
Definition string2.h:52
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_nm_tag_complete()

bool mutt_nm_tag_complete ( struct CompletionData * cd,
struct Buffer * buf,
int numtabs )

Complete to the nearest notmuch tag.

Parameters
cdCompletion Data
bufBuffer for the result
numtabsNumber of times the user has hit 'tab'
Return values
trueSuccess, a match
falseError, no match

Complete the nearest "+" or "-" -prefixed string previous to pos.

Definition at line 198 of file complete.c.

199{
200 if (!buf)
201 return false;
202
203 char *pt = buf->data;
204
205 /* Only examine the last token */
206 char *last_space = strrchr(buf->data, ' ');
207 if (last_space)
208 pt = (last_space + 1);
209
210 /* Skip the +/- */
211 if ((pt[0] == '+') || (pt[0] == '-'))
212 pt++;
213
214 if (numtabs == 1)
215 {
216 /* First TAB. Collect all the matches */
217 complete_all_nm_tags(cd, pt);
218
219 /* All matches are stored. Longest non-ambiguous string is ""
220 * i.e. don't change 'buf'. Fake successful return this time. */
221 if (cd->user_typed[0] == '\0')
222 return true;
223 }
224
225 if ((cd->completed[0] == '\0') && (cd->user_typed[0] != '\0'))
226 return false;
227
228 /* cd->num_matched will _always_ be at least 1 since the initial
229 * user-typed string is always stored */
230 if ((numtabs == 1) && (cd->num_matched == 2))
231 {
232 snprintf(cd->completed, sizeof(cd->completed), "%s", NONULL(cd->match_list[0]));
233 }
234 else if ((numtabs > 1) && (cd->num_matched > 2))
235 {
236 /* cycle through all the matches */
237 snprintf(cd->completed, sizeof(cd->completed), "%s",
238 NONULL(cd->match_list[(numtabs - 2) % cd->num_matched]));
239 }
240
241 /* return the completed query */
242 strncpy(pt, cd->completed, buf->data + buf->dsize - pt);
243
244 return true;
245}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ CompleteNmQueryOps

const struct CompleteOps CompleteNmQueryOps
Initial value:
= {
.complete = complete_nm_query,
}
enum FunctionRetval complete_nm_query(struct EnterWindowData *wdata, int op)
Complete a Notmuch Query - Implements CompleteOps::complete() -.
Definition complete.c:250

Auto-Completion of NmQuerys.

Definition at line 284 of file complete.c.

284 {
285 .complete = complete_nm_query,
286};

◆ CompleteNmTagOps

const struct CompleteOps CompleteNmTagOps
Initial value:
= {
.complete = complete_nm_tag,
}
enum FunctionRetval complete_nm_tag(struct EnterWindowData *wdata, int op)
Complete a Notmuch Tag - Implements CompleteOps::complete() -.
Definition complete.c:267

Auto-Completion of NmTags.

Definition at line 291 of file complete.c.

291 {
292 .complete = complete_nm_tag,
293};