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

Notmuch Auto-Completion. More...

#include "config.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 48 of file complete.c.

49{
51 mutt_str_copy(cd->user_typed, pt, sizeof(cd->user_typed));
52 memset(cd->match_list, 0, cd->match_list_len * sizeof(const char *));
53 memset(cd->completed, 0, sizeof(cd->completed));
54 cd->num_matched = 0;
55 cd->free_match_strings = true;
56}
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:586
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 64 of file complete.c.

65{
66 int rc = -1;
67 struct Mailbox *m_cur = get_current_mailbox();
68 notmuch_database_t *db = NULL;
69 notmuch_tags_t *tags = NULL;
70 const char *db_filename = nm_db_get_filename(m_cur);
71
72#if !LIBNOTMUCH_CHECK_VERSION(5, 4, 0)
73 if (!db_filename)
74 db_filename = cs_subset_string(NeoMutt->sub, "folder");
75#endif
76
77 if (!(db = nm_db_do_open(db_filename, false, false)) ||
78 !(tags = notmuch_database_get_all_tags(db)))
79 {
80 goto done;
81 }
82
83 while (notmuch_tags_valid(tags))
84 {
85 const char *tag = notmuch_tags_get(tags);
86
87 /* Keep a private copy because notmuch owns the iterator storage. */
88 if (*tag && candidate(cd, cd->user_typed, tag, cd->completed, sizeof(cd->completed)))
89 cd->match_list[cd->num_matched - 1] = mutt_str_dup(tag);
90
91 notmuch_tags_move_to_next(tags);
92 }
93
94 rc = 0;
95
96done:
97 if (tags)
98 notmuch_tags_destroy(tags);
99 if (db)
100 nm_db_free(db);
101
102 return rc;
103}
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:726
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 112 of file complete.c.

113{
114 int rc = -1;
115
116 nm_complete_data_init(cd, pt);
118 if (rc == 0)
119 {
122 }
123
124 return rc;
125}
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:48
static int complete_all_nm_tags_fresh(struct CompletionData *cd)
Query notmuch directly for a fresh tag list.
Definition complete.c:64
+ 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 137 of file complete.c.

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

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

Auto-Completion of NmQuerys.

Definition at line 283 of file complete.c.

283 {
284 .complete = complete_nm_query,
285};

◆ 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:266

Auto-Completion of NmTags.

Definition at line 290 of file complete.c.

290 {
291 .complete = complete_nm_tag,
292};