NeoMutt  2024-04-25-1-g3de005
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 "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "complete/lib.h"
#include "editor/lib.h"
#include "index/lib.h"
#include "notmuch/lib.h"
+ Include dependency graph for complete.c:

Go to the source code of this file.

Functions

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.
 
int complete_nm_query (struct EnterWindowData *wdata, int op)
 Complete a Notmuch Query - Implements CompleteOps::complete() -.
 
int 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

◆ 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
ptList of all Notmuch tags
Return values
0Success
-1Error

Definition at line 48 of file complete.c.

49{
50 struct Mailbox *m_cur = get_current_mailbox();
51 int tag_count_1 = 0;
52 int tag_count_2 = 0;
53 int rc = -1;
54
55 mutt_str_copy(cd->user_typed, pt, sizeof(cd->user_typed));
56 memset(cd->match_list, 0, cd->match_list_len);
57 memset(cd->completed, 0, sizeof(cd->completed));
58 cd->free_match_strings = true;
59
60 nm_db_longrun_init(m_cur, false);
61
62 /* Work out how many tags there are. */
63 if ((nm_get_all_tags(m_cur, NULL, &tag_count_1) != 0) || (tag_count_1 == 0))
64 goto done;
65
66 /* Get all the tags. */
67 const char **nm_tags = mutt_mem_calloc(tag_count_1, sizeof(char *));
68 if ((nm_get_all_tags(m_cur, nm_tags, &tag_count_2) != 0) || (tag_count_1 != tag_count_2))
69 {
71 goto done;
72 }
73
74 /* Put them into the completion machinery. */
75 for (int i = 0; i < tag_count_1; i++)
76 {
77 if (!candidate(cd, cd->user_typed, nm_tags[i], cd->completed, sizeof(cd->completed)))
78 FREE(&nm_tags[i]);
79 }
80
83 rc = 0;
84
85done:
86 FREE(&nm_tags);
87 nm_db_longrun_done(m_cur);
88 return rc;
89}
void matches_ensure_morespace(struct CompletionData *cd, int new_size)
Allocate more space for auto-completion.
Definition: helpers.c:54
bool candidate(struct CompletionData *cd, char *user, const char *src, char *dest, size_t dlen)
Helper function for completion.
Definition: helpers.c:78
void completion_data_free_match_strings(struct CompletionData *cd)
Free the Completion strings.
Definition: data.c:38
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:715
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:45
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
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:575
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: db.c:378
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: db.c:363
int nm_get_all_tags(struct Mailbox *m, const char **tag_list, int *tag_count)
Fill a list with all notmuch tags.
Definition: notmuch.c:1979
int match_list_len
Enough space for all of the config items.
Definition: data.h:38
bool free_match_strings
Should the strings in match_list be freed?
Definition: data.h:39
char user_typed[1024]
Initial string that starts completion.
Definition: data.h:34
char completed[256]
Completed string (command or variable)
Definition: data.h:36
int num_matched
Number of matches for completion.
Definition: data.h:35
const char ** match_list
Matching strings.
Definition: data.h:37
A mailbox.
Definition: mailbox.h:79
+ 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 101 of file complete.c.

102{
103 char *pt = buf->data;
104 int spaces;
105
106 SKIPWS(pt);
107 spaces = pt - buf->data;
108
109 pt = (char *) buf_rfind(buf, "tag:");
110 if (pt)
111 {
112 pt += 4;
113 if (numtabs == 1)
114 {
115 /* First TAB. Collect all the matches */
116 complete_all_nm_tags(cd, pt);
117
118 /* All matches are stored. Longest non-ambiguous string is ""
119 * i.e. don't change 'buf'. Fake successful return this time. */
120 if (cd->user_typed[0] == '\0')
121 return true;
122 }
123
124 if ((cd->completed[0] == '\0') && (cd->user_typed[0] != '\0'))
125 return false;
126
127 /* cd->num_matched will _always_ be at least 1 since the initial
128 * user-typed string is always stored */
129 if ((numtabs == 1) && (cd->num_matched == 2))
130 {
131 snprintf(cd->completed, sizeof(cd->completed), "%s", cd->match_list[0]);
132 }
133 else if ((numtabs > 1) && (cd->num_matched > 2))
134 {
135 /* cycle through all the matches */
136 snprintf(cd->completed, sizeof(cd->completed), "%s",
137 cd->match_list[(numtabs - 2) % cd->num_matched]);
138 }
139
140 /* return the completed query */
141 strncpy(pt, cd->completed, buf->data + buf->dsize - pt - spaces);
142 }
143 else
144 {
145 return false;
146 }
147
148 return true;
149}
const char * buf_rfind(const struct Buffer *buf, const char *str)
Find last instance of a substring.
Definition: buffer.c:796
int complete_all_nm_tags(struct CompletionData *cd, const char *pt)
Pass a list of Notmuch tags to the completion code.
Definition: complete.c:48
#define SKIPWS(ch)
Definition: string2.h:45
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 161 of file complete.c.

162{
163 if (!buf)
164 return false;
165
166 char *pt = buf->data;
167
168 /* Only examine the last token */
169 char *last_space = strrchr(buf->data, ' ');
170 if (last_space)
171 pt = (last_space + 1);
172
173 /* Skip the +/- */
174 if ((pt[0] == '+') || (pt[0] == '-'))
175 pt++;
176
177 if (numtabs == 1)
178 {
179 /* First TAB. Collect all the matches */
180 complete_all_nm_tags(cd, pt);
181
182 /* All matches are stored. Longest non-ambiguous string is ""
183 * i.e. don't change 'buf'. Fake successful return this time. */
184 if (cd->user_typed[0] == '\0')
185 return true;
186 }
187
188 if ((cd->completed[0] == '\0') && (cd->user_typed[0] != '\0'))
189 return false;
190
191 /* cd->num_matched will _always_ be at least 1 since the initial
192 * user-typed string is always stored */
193 if ((numtabs == 1) && (cd->num_matched == 2))
194 {
195 snprintf(cd->completed, sizeof(cd->completed), "%s", cd->match_list[0]);
196 }
197 else if ((numtabs > 1) && (cd->num_matched > 2))
198 {
199 /* cycle through all the matches */
200 snprintf(cd->completed, sizeof(cd->completed), "%s",
201 cd->match_list[(numtabs - 2) % cd->num_matched]);
202 }
203
204 /* return the completed query */
205 strncpy(pt, cd->completed, buf->data + buf->dsize - pt);
206
207 return true;
208}
+ 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,
}
int complete_nm_query(struct EnterWindowData *wdata, int op)
Complete a Notmuch Query - Implements CompleteOps::complete() -.
Definition: complete.c:213

Auto-Completion of NmQuerys.

Definition at line 247 of file complete.c.

◆ CompleteNmTagOps

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

Auto-Completion of NmTags.

Definition at line 254 of file complete.c.