Coverage Report

Created: 2023-09-25 07:17

/src/neomutt/browser/complete.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * Browser Auto-Completion
4
 *
5
 * @authors
6
 * Copyright (C) 2023 Richard Russon <rich@flatcap.org>
7
 *
8
 * @copyright
9
 * This program is free software: you can redistribute it and/or modify it under
10
 * the terms of the GNU General Public License as published by the Free Software
11
 * Foundation, either version 2 of the License, or (at your option) any later
12
 * version.
13
 *
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17
 * details.
18
 *
19
 * You should have received a copy of the GNU General Public License along with
20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
/**
24
 * @page browser_complete Browser Auto-Completion
25
 *
26
 * Browser Auto-Completion
27
 */
28
29
#include "config.h"
30
#include <stddef.h>
31
#include <stdbool.h>
32
#include <string.h>
33
#include "mutt/lib.h"
34
#include "core/lib.h"
35
#include "gui/lib.h"
36
#include "lib.h"
37
#include "complete/lib.h"
38
#include "editor/lib.h"
39
#include "history/lib.h"
40
#include "mutt_mailbox.h"
41
#include "muttlib.h"
42
43
/**
44
 * complete_file_mbox - Complete a Mailbox - Implements ::complete_function_t - @ingroup complete_api
45
 */
46
int complete_file_mbox(struct EnterWindowData *wdata, int op)
47
0
{
48
0
  if (!wdata)
49
0
    return FR_NO_ACTION;
50
51
0
  struct FileCompletionData *cdata = wdata->cdata;
52
53
0
  if (op == OP_EDITOR_MAILBOX_CYCLE)
54
0
  {
55
0
    wdata->first = true; /* clear input if user types a real key later */
56
0
    buf_mb_wcstombs(wdata->buffer, wdata->state->wbuf, wdata->state->curpos);
57
0
    mutt_mailbox_next(cdata->mailbox, wdata->buffer);
58
59
0
    wdata->state->curpos = wdata->state->lastchar = mutt_mb_mbstowcs(
60
0
        &wdata->state->wbuf, &wdata->state->wbuflen, 0, buf_string(wdata->buffer));
61
0
    return FR_SUCCESS;
62
0
  }
63
64
0
  if ((op != OP_EDITOR_COMPLETE) && (op != OP_EDITOR_COMPLETE_QUERY))
65
0
    return FR_NO_ACTION;
66
67
0
  int rc = FR_SUCCESS;
68
0
  buf_mb_wcstombs(wdata->buffer, wdata->state->wbuf, wdata->state->curpos);
69
70
  /* see if the path has changed from the last time */
71
0
  if ((!wdata->tempbuf && !wdata->state->lastchar) ||
72
0
      (wdata->tempbuf && (wdata->templen == wdata->state->lastchar) &&
73
0
       (memcmp(wdata->tempbuf, wdata->state->wbuf,
74
0
               wdata->state->lastchar * sizeof(wchar_t)) == 0)))
75
0
  {
76
0
    SelectFileFlags flags = MUTT_SEL_NO_FLAGS;
77
0
    if (wdata->hclass == HC_MBOX)
78
0
      flags |= MUTT_SEL_FOLDER;
79
0
    if (cdata->multiple)
80
0
      flags |= MUTT_SEL_MULTI;
81
82
0
    dlg_browser(wdata->buffer, flags, cdata->mailbox, cdata->files, cdata->numfiles);
83
0
    if (!buf_is_empty(wdata->buffer))
84
0
    {
85
0
      buf_pretty_mailbox(wdata->buffer);
86
0
      if (!wdata->pass)
87
0
        mutt_hist_add(wdata->hclass, buf_string(wdata->buffer), true);
88
0
      wdata->done = true;
89
0
      return FR_SUCCESS;
90
0
    }
91
92
    /* file selection cancelled */
93
0
    return FR_CONTINUE;
94
0
  }
95
96
0
  if (mutt_complete(wdata->cd, wdata->buffer) == 0)
97
0
  {
98
0
    wdata->templen = wdata->state->lastchar;
99
0
    mutt_mem_realloc(&wdata->tempbuf, wdata->templen * sizeof(wchar_t));
100
0
    memcpy(wdata->tempbuf, wdata->state->wbuf, wdata->templen * sizeof(wchar_t));
101
0
  }
102
0
  else
103
0
  {
104
0
    return FR_ERROR; // let the user know that nothing matched
105
0
  }
106
0
  replace_part(wdata->state, 0, buf_string(wdata->buffer));
107
0
  return rc;
108
0
}
109
110
/**
111
 * complete_file_simple - Complete a filename - Implements ::complete_function_t - @ingroup complete_api
112
 */
113
int complete_file_simple(struct EnterWindowData *wdata, int op)
114
0
{
115
0
  if (!wdata || ((op != OP_EDITOR_COMPLETE) && (op != OP_EDITOR_COMPLETE_QUERY)))
116
0
    return FR_NO_ACTION;
117
118
0
  int rc = FR_SUCCESS;
119
0
  size_t i;
120
0
  for (i = wdata->state->curpos;
121
0
       (i > 0) && !mutt_mb_is_shell_char(wdata->state->wbuf[i - 1]); i--)
122
0
  {
123
0
  }
124
0
  buf_mb_wcstombs(wdata->buffer, wdata->state->wbuf + i, wdata->state->curpos - i);
125
0
  if (wdata->tempbuf && (wdata->templen == (wdata->state->lastchar - i)) &&
126
0
      (memcmp(wdata->tempbuf, wdata->state->wbuf + i,
127
0
              (wdata->state->lastchar - i) * sizeof(wchar_t)) == 0))
128
0
  {
129
0
    dlg_browser(wdata->buffer, MUTT_SEL_NO_FLAGS, NULL, NULL, NULL);
130
0
    if (buf_is_empty(wdata->buffer))
131
0
      replace_part(wdata->state, i, buf_string(wdata->buffer));
132
0
    return FR_CONTINUE;
133
0
  }
134
135
0
  if (mutt_complete(wdata->cd, wdata->buffer) == 0)
136
0
  {
137
0
    wdata->templen = wdata->state->lastchar - i;
138
0
    mutt_mem_realloc(&wdata->tempbuf, wdata->templen * sizeof(wchar_t));
139
0
    memcpy(wdata->tempbuf, wdata->state->wbuf + i, wdata->templen * sizeof(wchar_t));
140
0
  }
141
0
  else
142
0
  {
143
0
    rc = FR_ERROR;
144
0
  }
145
146
0
  replace_part(wdata->state, i, buf_string(wdata->buffer));
147
0
  return rc;
148
0
}
149
150
/**
151
 * CompleteFileOps - Auto-Completion of Files
152
 */
153
const struct CompleteOps CompleteFileOps = {
154
  .complete = complete_file_simple,
155
};
156
157
/**
158
 * CompleteMailboxOps - Auto-Completion of Files / Mailboxes
159
 */
160
const struct CompleteOps CompleteMailboxOps = {
161
  .complete = complete_file_mbox,
162
};