Author: Manos Pitsidianakis [manos@pitsidianak.is]
Hash: 4b959f5c4f20ff02a75ef708d975d8a1307b99e5
Timestamp: Wed, 07 Aug 2024 12:51:25 +0000 (1 month ago)

+225 -220 +/-12 browse
Remove pcre feature/dependency
Remove pcre feature/dependency

Crate regex is used by default in builds, so there's no need for an
optional libpcre2 dependency

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
1diff --git a/.cargo/config.toml b/.cargo/config.toml
2deleted file mode 100644
3index f0ad4ff..0000000
4--- a/.cargo/config.toml
5+++ /dev/null
6 @@ -1,2 +0,0 @@
7- [env]
8- PCRE2_SYS_STATIC = "1"
9 diff --git a/BUILD.md b/BUILD.md
10index 942166d..e564309 100644
11--- a/BUILD.md
12+++ b/BUILD.md
13 @@ -28,10 +28,6 @@ Some functionality is held behind "feature gates", or compile-time flags. The fo
14 - `jmap` provides support for connecting to a jmap server and use it as a mail backend (on by default)
15 - `sqlite3` provides support for builting fast search indexes in local sqlite3 databases (on by default)
16 - `cli-docs` includes the manpage documentation compiled by either `mandoc` or `man` binary to plain text in `meli`'s command line. Embedded documentation can be viewed with the subcommand `meli man [PAGE]` (on by default).
17- - `regexp` provides experimental support for theming some e-mail fields based
18- on regular expressions.
19- It uses the `pcre2` library.
20- Since it's actual use in the code is very limited, it is not recommended to use this (off by default).
21 - `static` and `*-static` bundle C libraries in dependencies so that you don't need them installed in your system (on by default).
22
23 Though not a feature, the presence of the environment variable `UNICODE_REGENERATE_TABLES` in compile-time of the `melib` crate will force the regeneration of unicode tables.
24 diff --git a/Cargo.lock b/Cargo.lock
25index 658b502..b927dba 100644
26--- a/Cargo.lock
27+++ b/Cargo.lock
28 @@ -325,7 +325,6 @@ version = "1.0.83"
29 source = "registry+https://github.com/rust-lang/crates.io-index"
30 checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
31 dependencies = [
32- "jobserver",
33 "libc",
34 ]
35
36 @@ -1096,15 +1095,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
37 checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
38
39 [[package]]
40- name = "jobserver"
41- version = "0.1.26"
42- source = "registry+https://github.com/rust-lang/crates.io-index"
43- checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
44- dependencies = [
45- "libc",
46- ]
47-
48- [[package]]
49 name = "js-sys"
50 version = "0.3.64"
51 source = "registry+https://github.com/rust-lang/crates.io-index"
52 @@ -1292,7 +1282,6 @@ dependencies = [
53 "melib",
54 "nix",
55 "notify-rust",
56- "pcre2",
57 "predicates",
58 "proc-macro2",
59 "quote",
60 @@ -1595,29 +1584,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
61 checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
62
63 [[package]]
64- name = "pcre2"
65- version = "0.2.4"
66- source = "registry+https://github.com/rust-lang/crates.io-index"
67- checksum = "486aca7e74edb8cab09a48d461177f450a5cca3b55e61d139f7552190e2bbcf5"
68- dependencies = [
69- "libc",
70- "log",
71- "pcre2-sys",
72- "thread_local",
73- ]
74-
75- [[package]]
76- name = "pcre2-sys"
77- version = "0.2.6"
78- source = "registry+https://github.com/rust-lang/crates.io-index"
79- checksum = "ae234f441970dbd52d4e29bee70f3b56ca83040081cb2b55b7df772b16e0b06e"
80- dependencies = [
81- "cc",
82- "libc",
83- "pkg-config",
84- ]
85-
86- [[package]]
87 name = "percent-encoding"
88 version = "2.3.0"
89 source = "registry+https://github.com/rust-lang/crates.io-index"
90 diff --git a/meli/Cargo.toml b/meli/Cargo.toml
91index 34cfc54..1532baa 100644
92--- a/meli/Cargo.toml
93+++ b/meli/Cargo.toml
94 @@ -46,12 +46,6 @@ termion = { version = "1.5.1", default-features = false }
95 toml = { version = "0.8", default-features = false, features = ["display","preserve_order","parse"] }
96 xdg = { version = "2.1.0" }
97
98- [dependencies.pcre2]
99- # An [env] entry in .cargo/config.toml should force a static build instead of
100- # looking for a system library.
101- version = "0.2.3"
102- optional = true
103-
104 [features]
105 default = ["sqlite3", "notmuch", "smtp", "dbus-notifications", "gpgme", "cli-docs", "jmap", "static"]
106 notmuch = ["melib/notmuch"]
107 @@ -59,7 +53,6 @@ jmap = ["melib/jmap"]
108 sqlite3 = ["melib/sqlite3"]
109 smtp = ["melib/smtp"]
110 smtp-trace = ["smtp", "melib/smtp-trace"]
111- regexp = ["dep:pcre2"]
112 dbus-notifications = ["dep:notify-rust"]
113 cli-docs = ["dep:flate2"]
114 svgscreenshot = ["dep:svg_crate"]
115 diff --git a/meli/src/conf/data_types/mod.rs b/meli/src/conf/data_types/mod.rs
116index c9a7e34..e657d7c 100644
117--- a/meli/src/conf/data_types/mod.rs
118+++ b/meli/src/conf/data_types/mod.rs
119 @@ -21,6 +21,7 @@
120 // SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
121
122 pub mod dotaddressable;
123+ pub mod regex_pattern;
124
125 use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
126
127 diff --git a/meli/src/conf/data_types/regex_pattern.rs b/meli/src/conf/data_types/regex_pattern.rs
128new file mode 100644
129index 0000000..0d27b4f
130--- /dev/null
131+++ b/meli/src/conf/data_types/regex_pattern.rs
132 @@ -0,0 +1,215 @@
133+ //
134+ // meli
135+ //
136+ // Copyright 2024 Emmanouil Pitsidianakis <manos@pitsidianak.is>
137+ //
138+ // This file is part of meli.
139+ //
140+ // meli is free software: you can redistribute it and/or modify
141+ // it under the terms of the GNU General Public License as published by
142+ // the Free Software Foundation, either version 3 of the License, or
143+ // (at your option) any later version.
144+ //
145+ // meli is distributed in the hope that it will be useful,
146+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
147+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
148+ // GNU General Public License for more details.
149+ //
150+ // You should have received a copy of the GNU General Public License
151+ // along with meli. If not, see <http://www.gnu.org/licenses/>.
152+ //
153+ // SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
154+
155+ use melib::error::{Result, WrapResultIntoError};
156+ use serde::{Deserialize, Deserializer};
157+
158+ const fn lf_val() -> u8 {
159+ b'\n'
160+ }
161+
162+ #[derive(Debug, Clone)]
163+ pub enum RegexValue {
164+ Default {
165+ pattern: regex::Regex,
166+ },
167+ Builder {
168+ pattern: regex::Regex,
169+ options: RegexOptions,
170+ },
171+ }
172+
173+ impl RegexValue {
174+ pub fn new_with_options(pattern: &str, o: RegexOptions) -> Result<Self> {
175+ let mut b = regex::RegexBuilder::new(pattern);
176+ b.unicode(o.unicode)
177+ .case_insensitive(o.case_insensitive)
178+ .multi_line(o.multi_line)
179+ .dot_matches_new_line(o.dot_matches_new_line)
180+ .crlf(o.crlf)
181+ .line_terminator(o.line_terminator)
182+ .swap_greed(o.swap_greed)
183+ .ignore_whitespace(o.ignore_whitespace)
184+ .octal(o.octal);
185+ if let Some(v) = o.size_limit {
186+ b.size_limit(v);
187+ }
188+ let pattern = b
189+ .build()
190+ .wrap_err(|| format!("Could not compile regular expression `{}`", pattern))?;
191+ Ok(Self::Builder {
192+ pattern,
193+ options: o,
194+ })
195+ }
196+
197+ pub fn find_iter<'w, 's>(&'w self, s: &'s str) -> FindIter<'w, 's> {
198+ let (Self::Default { pattern } | Self::Builder { pattern, .. }) = self;
199+ FindIter {
200+ iter: pattern.find_iter(s),
201+ char_indices: s.char_indices(),
202+ char_offset: 0,
203+ }
204+ }
205+ }
206+
207+ #[derive(Clone, Copy, Serialize, Deserialize, Debug)]
208+ pub struct RegexOptions {
209+ #[serde(default = "crate::conf::true_val")]
210+ unicode: bool,
211+ #[serde(default = "crate::conf::false_val")]
212+ case_insensitive: bool,
213+ #[serde(default = "crate::conf::false_val")]
214+ multi_line: bool,
215+ #[serde(default = "crate::conf::false_val")]
216+ dot_matches_new_line: bool,
217+ #[serde(default = "crate::conf::false_val")]
218+ crlf: bool,
219+ #[serde(default = "lf_val")]
220+ line_terminator: u8,
221+ #[serde(default = "crate::conf::false_val")]
222+ swap_greed: bool,
223+ #[serde(default = "crate::conf::false_val")]
224+ ignore_whitespace: bool,
225+ #[serde(default = "crate::conf::false_val")]
226+ octal: bool,
227+ #[serde(default, skip_serializing_if = "Option::is_none")]
228+ size_limit: Option<usize>,
229+ }
230+
231+ impl Default for RegexOptions {
232+ fn default() -> Self {
233+ Self {
234+ unicode: true,
235+ case_insensitive: false,
236+ multi_line: false,
237+ dot_matches_new_line: false,
238+ crlf: false,
239+ line_terminator: b'\n',
240+ swap_greed: false,
241+ ignore_whitespace: false,
242+ octal: false,
243+ size_limit: None,
244+ }
245+ }
246+ }
247+
248+ impl<'de> Deserialize<'de> for RegexValue {
249+ fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
250+ where
251+ D: Deserializer<'de>,
252+ {
253+ // [ref:FIXME]: clippy false positive, remove when resolved.
254+ #![allow(clippy::collection_is_never_read)]
255+
256+ #[derive(Deserialize)]
257+ #[serde(untagged)]
258+ enum Inner<'a> {
259+ Default {
260+ pattern: &'a str,
261+ },
262+ Builder {
263+ pattern: &'a str,
264+ #[serde(flatten)]
265+ o: RegexOptions,
266+ },
267+ }
268+ let s = <Inner>::deserialize(deserializer);
269+ Ok(
270+ match s.map_err(|err| {
271+ serde::de::Error::custom(format!(
272+ r#"expected one of "true", "false", "ask", found `{}`"#,
273+ err
274+ ))
275+ })? {
276+ Inner::Default { pattern } => Self::Default {
277+ pattern: regex::Regex::new(pattern).map_err(|err| {
278+ serde::de::Error::custom(format!(
279+ "Could not compile regular expression `{}`: {}",
280+ pattern, err
281+ ))
282+ })?,
283+ },
284+ Inner::Builder { pattern, o } => {
285+ let mut b = regex::RegexBuilder::new(pattern);
286+ b.unicode(o.unicode)
287+ .case_insensitive(o.case_insensitive)
288+ .multi_line(o.multi_line)
289+ .dot_matches_new_line(o.dot_matches_new_line)
290+ .crlf(o.crlf)
291+ .line_terminator(o.line_terminator)
292+ .swap_greed(o.swap_greed)
293+ .ignore_whitespace(o.ignore_whitespace)
294+ .octal(o.octal);
295+ if let Some(v) = o.size_limit {
296+ b.size_limit(v);
297+ }
298+ let pattern = b.build().map_err(|err| {
299+ serde::de::Error::custom(format!(
300+ "Could not compile regular expression `{}`: {}",
301+ pattern, err
302+ ))
303+ })?;
304+ Self::Builder {
305+ pattern,
306+ options: o,
307+ }
308+ }
309+ },
310+ )
311+ }
312+ }
313+
314+ pub struct FindIter<'r, 's> {
315+ iter: regex::Matches<'r, 's>,
316+ char_indices: std::str::CharIndices<'s>,
317+ char_offset: usize,
318+ }
319+
320+ impl<'r, 's> Iterator for FindIter<'r, 's> {
321+ type Item = (usize, usize);
322+
323+ fn next(&mut self) -> Option<Self::Item> {
324+ let next_byte_offset = self.iter.next()?;
325+
326+ let mut next_char_index = self.char_indices.next()?;
327+
328+ while next_byte_offset.start() < next_char_index.0 {
329+ self.char_offset += 1;
330+ next_char_index = self.char_indices.next()?;
331+ }
332+ let start = self.char_offset;
333+
334+ while next_byte_offset.end()
335+ > self
336+ .char_indices
337+ .next()
338+ .map(|(v, _)| v)
339+ .unwrap_or_else(|| next_byte_offset.end())
340+ {
341+ self.char_offset += 1;
342+ }
343+ let end = self.char_offset + 1;
344+
345+ Some((start, end))
346+ }
347+ }
348 diff --git a/meli/src/conf/themes.rs b/meli/src/conf/themes.rs
349index a5832bd..606a50b 100644
350--- a/meli/src/conf/themes.rs
351+++ b/meli/src/conf/themes.rs
352 @@ -43,6 +43,7 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
353 use smallvec::SmallVec;
354
355 use crate::{
356+ conf::data_types::regex_pattern::{RegexOptions, RegexValue},
357 terminal::{Attr, Color},
358 Context,
359 };
360 @@ -520,30 +521,23 @@ pub struct Themes {
361 pub struct Theme {
362 color_aliases: IndexMap<Cow<'static, str>, ThemeValue<Color>>,
363 attr_aliases: IndexMap<Cow<'static, str>, ThemeValue<Attr>>,
364- #[cfg(feature = "regexp")]
365 text_format_regexps: IndexMap<Cow<'static, str>, SmallVec<[TextFormatterSetting; 32]>>,
366 pub keys: IndexMap<Cow<'static, str>, ThemeAttributeInner>,
367 }
368
369- #[cfg(feature = "regexp")]
370 pub use regexp::text_format_regexps;
371- #[cfg(feature = "regexp")]
372 use regexp::*;
373
374- #[cfg(feature = "regexp")]
375 mod regexp {
376 use super::*;
377- use crate::terminal::FormatTag;
378+ use crate::{conf::data_types::regex_pattern::RegexValue, terminal::FormatTag};
379
380 pub(super) const DEFAULT_TEXT_FORMATTER_KEYS: &[&str] =
381 &["pager.envelope.body", "listing.from", "listing.subject"];
382
383- #[derive(Clone)]
384- pub struct RegexpWrapper(pub pcre2::bytes::Regex);
385-
386 #[derive(Clone, Debug)]
387 pub(super) struct TextFormatterSetting {
388- pub(super) regexp: RegexpWrapper,
389+ pub(super) regexp: RegexValue,
390 pub(super) fg: Option<ThemeValue<Color>>,
391 pub(super) bg: Option<ThemeValue<Color>>,
392 pub(super) attrs: Option<ThemeValue<Attr>>,
393 @@ -552,108 +546,10 @@ mod regexp {
394
395 #[derive(Clone, Debug)]
396 pub struct TextFormatter<'r> {
397- pub regexp: &'r RegexpWrapper,
398+ pub regexp: &'r RegexValue,
399 pub tag: FormatTag,
400 }
401
402- impl Default for RegexpWrapper {
403- fn default() -> Self {
404- Self(pcre2::bytes::Regex::new("").unwrap())
405- }
406- }
407-
408- impl std::fmt::Debug for RegexpWrapper {
409- fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
410- std::fmt::Debug::fmt(self.0.as_str(), fmt)
411- }
412- }
413-
414- impl std::hash::Hash for RegexpWrapper {
415- fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
416- self.0.as_str().hash(state)
417- }
418- }
419-
420- impl Eq for RegexpWrapper {}
421-
422- impl PartialEq for RegexpWrapper {
423- fn eq(&self, other: &Self) -> bool {
424- self.0.as_str().eq(other.0.as_str())
425- }
426- }
427-
428- impl RegexpWrapper {
429- pub(super) fn new(
430- pattern: &str,
431- caseless: bool,
432- dotall: bool,
433- extended: bool,
434- multi_line: bool,
435- ucp: bool,
436- jit_if_available: bool,
437- ) -> std::result::Result<Self, pcre2::Error> {
438- Ok(Self(
439- pcre2::bytes::RegexBuilder::new()
440- .caseless(caseless)
441- .dotall(dotall)
442- .extended(extended)
443- .multi_line(multi_line)
444- .ucp(ucp)
445- .jit_if_available(jit_if_available)
446- .build(pattern)?,
447- ))
448- }
449-
450- pub fn find_iter<'w, 's>(&'w self, s: &'s str) -> FindIter<'w, 's> {
451- FindIter {
452- pcre_iter: self.0.find_iter(s.as_bytes()),
453- char_indices: s.char_indices(),
454- char_offset: 0,
455- }
456- }
457- }
458-
459- pub struct FindIter<'r, 's> {
460- pcre_iter: pcre2::bytes::Matches<'r, 's>,
461- char_indices: std::str::CharIndices<'s>,
462- char_offset: usize,
463- }
464-
465- impl<'r, 's> Iterator for FindIter<'r, 's> {
466- type Item = (usize, usize);
467-
468- fn next(&mut self) -> Option<Self::Item> {
469- loop {
470- let next_byte_offset = self.pcre_iter.next()?;
471- if next_byte_offset.is_err() {
472- continue;
473- }
474- let next_byte_offset = next_byte_offset.unwrap();
475-
476- let mut next_char_index = self.char_indices.next()?;
477-
478- while next_byte_offset.start() < next_char_index.0 {
479- self.char_offset += 1;
480- next_char_index = self.char_indices.next()?;
481- }
482- let start = self.char_offset;
483-
484- while next_byte_offset.end()
485- > self
486- .char_indices
487- .next()
488- .map(|(v, _)| v)
489- .unwrap_or_else(|| next_byte_offset.end())
490- {
491- self.char_offset += 1;
492- }
493- let end = self.char_offset + 1;
494-
495- return Some((start, end));
496- }
497- }
498- }
499-
500 #[inline(always)]
501 pub fn text_format_regexps<'ctx>(
502 context: &'ctx Context,
503 @@ -775,14 +671,6 @@ impl<'de> Deserialize<'de> for Themes {
504 where
505 D: Deserializer<'de>,
506 {
507- #[cfg(feature = "regexp")]
508- const fn false_val() -> bool {
509- false
510- }
511- #[cfg(feature = "regexp")]
512- const fn true_val() -> bool {
513- true
514- }
515 #[derive(Deserialize)]
516 struct ThemesOptions {
517 #[serde(default)]
518 @@ -798,27 +686,15 @@ impl<'de> Deserialize<'de> for Themes {
519 color_aliases: IndexMap<Cow<'static, str>, ThemeValue<Color>>,
520 #[serde(default)]
521 attr_aliases: IndexMap<Cow<'static, str>, ThemeValue<Attr>>,
522- #[cfg(feature = "regexp")]
523 #[serde(default)]
524 text_format_regexps: IndexMap<Cow<'static, str>, IndexMap<String, RegexpOptions>>,
525 #[serde(flatten, default)]
526 keys: IndexMap<Cow<'static, str>, ThemeAttributeInnerOptions>,
527 }
528- #[cfg(feature = "regexp")]
529 #[derive(Default, Deserialize)]
530 struct RegexpOptions {
531- #[serde(default = "false_val")]
532- caseless: bool,
533- #[serde(default = "false_val")]
534- dotall: bool,
535- #[serde(default = "false_val")]
536- extended: bool,
537- #[serde(default = "false_val")]
538- multi_line: bool,
539- #[serde(default = "true_val")]
540- ucp: bool,
541- #[serde(default = "false_val")]
542- jit_if_available: bool,
543+ #[serde(flatten)]
544+ o: RegexOptions,
545 #[serde(default)]
546 priority: u8,
547 #[serde(flatten)]
548 @@ -867,19 +743,10 @@ impl<'de> Deserialize<'de> for Themes {
549 }
550 ret.light.color_aliases = s.light.color_aliases;
551 ret.light.attr_aliases = s.light.attr_aliases;
552- #[cfg(feature = "regexp")]
553 for (k, v) in s.light.text_format_regexps {
554 let mut acc = SmallVec::new();
555 for (rs, v) in v {
556- match RegexpWrapper::new(
557- &rs,
558- v.caseless,
559- v.dotall,
560- v.extended,
561- v.multi_line,
562- v.ucp,
563- v.jit_if_available,
564- ) {
565+ match RegexValue::new_with_options(&rs, v.o) {
566 Ok(regexp) => {
567 acc.push(TextFormatterSetting {
568 regexp,
569 @@ -922,19 +789,10 @@ impl<'de> Deserialize<'de> for Themes {
570 }
571 ret.dark.color_aliases = s.dark.color_aliases;
572 ret.dark.attr_aliases = s.dark.attr_aliases;
573- #[cfg(feature = "regexp")]
574 for (k, v) in s.dark.text_format_regexps {
575 let mut acc = SmallVec::new();
576 for (rs, v) in v {
577- match RegexpWrapper::new(
578- &rs,
579- v.caseless,
580- v.dotall,
581- v.extended,
582- v.multi_line,
583- v.ucp,
584- v.jit_if_available,
585- ) {
586+ match RegexValue::new_with_options(&rs, v.o) {
587 Ok(regexp) => {
588 acc.push(TextFormatterSetting {
589 regexp,
590 @@ -980,19 +838,10 @@ impl<'de> Deserialize<'de> for Themes {
591 }
592 t.color_aliases = theme.color_aliases;
593 t.attr_aliases = theme.attr_aliases;
594- #[cfg(feature = "regexp")]
595 for (k, v) in theme.text_format_regexps {
596 let mut acc = SmallVec::new();
597 for (rs, v) in v {
598- match RegexpWrapper::new(
599- &rs,
600- v.caseless,
601- v.dotall,
602- v.extended,
603- v.multi_line,
604- v.ucp,
605- v.jit_if_available,
606- ) {
607+ match RegexValue::new_with_options(&rs, v.o) {
608 Ok(regexp) => {
609 acc.push(TextFormatterSetting {
610 regexp,
611 @@ -1126,7 +975,6 @@ impl Themes {
612 }
613 }))
614 .collect::<SmallVec<[(Option<_>, &'_ str, &'_ str, &'_ str); 128]>>();
615- #[cfg(feature = "regexp")]
616 {
617 for (key, v) in &theme.text_format_regexps {
618 if !regexp::DEFAULT_TEXT_FORMATTER_KEYS.contains(&key.as_ref()) {
619 @@ -1759,7 +1607,6 @@ impl Default for Themes {
620 keys: light,
621 attr_aliases: Default::default(),
622 color_aliases: Default::default(),
623- #[cfg(feature = "regexp")]
624 text_format_regexps: DEFAULT_TEXT_FORMATTER_KEYS
625 .iter()
626 .map(|&k| (k.into(), SmallVec::new()))
627 @@ -1769,7 +1616,6 @@ impl Default for Themes {
628 keys: dark,
629 attr_aliases: Default::default(),
630 color_aliases: Default::default(),
631- #[cfg(feature = "regexp")]
632 text_format_regexps: DEFAULT_TEXT_FORMATTER_KEYS
633 .iter()
634 .map(|&k| (k.into(), SmallVec::new()))
635 diff --git a/meli/src/mail/listing/compact.rs b/meli/src/mail/listing/compact.rs
636index e9d8d1a..5c5be5f 100644
637--- a/meli/src/mail/listing/compact.rs
638+++ b/meli/src/mail/listing/compact.rs
639 @@ -1221,7 +1221,6 @@ impl CompactListing {
640 .set_attrs(row_attr.attrs)
641 .set_ch(' ');
642 }
643- #[cfg(feature = "regexp")]
644 {
645 for text_formatter in crate::conf::text_format_regexps(context, "listing.from") {
646 let t = columns[2].grid_mut().insert_tag(text_formatter.tag);
647 @@ -1280,7 +1279,6 @@ impl CompactListing {
648 None,
649 None,
650 ));
651- #[cfg(feature = "regexp")]
652 {
653 for text_formatter in
654 crate::conf::text_format_regexps(context, "listing.subject")
655 diff --git a/meli/src/mail/listing/plain.rs b/meli/src/mail/listing/plain.rs
656index 558e895..8dffae8 100644
657--- a/meli/src/mail/listing/plain.rs
658+++ b/meli/src/mail/listing/plain.rs
659 @@ -931,7 +931,6 @@ impl PlainListing {
660 None,
661 None,
662 );
663- #[cfg(feature = "regexp")]
664 {
665 for text_formatter in crate::conf::text_format_regexps(context, "listing.from")
666 {
667 @@ -1004,7 +1003,6 @@ impl PlainListing {
668 None,
669 None,
670 ));
671- #[cfg(feature = "regexp")]
672 {
673 for text_formatter in
674 crate::conf::text_format_regexps(context, "listing.subject")
675 @@ -1212,7 +1210,6 @@ impl PlainListing {
676 None,
677 None,
678 ));
679- #[cfg(feature = "regexp")]
680 {
681 for text_formatter in crate::conf::text_format_regexps(context, "listing.subject") {
682 let t = columns[4].grid_mut().insert_tag(text_formatter.tag);
683 diff --git a/meli/src/mail/listing/thread.rs b/meli/src/mail/listing/thread.rs
684index b32c4ac..862f4e3 100644
685--- a/meli/src/mail/listing/thread.rs
686+++ b/meli/src/mail/listing/thread.rs
687 @@ -987,7 +987,6 @@ impl ThreadListing {
688 None,
689 None,
690 );
691- #[cfg(feature = "regexp")]
692 {
693 for text_formatter in crate::conf::text_format_regexps(context, "listing.from")
694 {
695 @@ -1060,7 +1059,6 @@ impl ThreadListing {
696 None,
697 None,
698 ));
699- #[cfg(feature = "regexp")]
700 {
701 for text_formatter in
702 crate::conf::text_format_regexps(context, "listing.subject")
703 diff --git a/meli/src/subcommands.rs b/meli/src/subcommands.rs
704index efdecb2..be36097 100644
705--- a/meli/src/subcommands.rs
706+++ b/meli/src/subcommands.rs
707 @@ -115,8 +115,6 @@ pub fn compiled_with() -> Result<()> {
708 println!("sqlite3");
709 #[cfg(feature = "smtp")]
710 println!("smtp");
711- #[cfg(feature = "regexp")]
712- println!("regexp");
713 #[cfg(feature = "dbus-notifications")]
714 println!("dbus-notifications");
715 #[cfg(feature = "cli-docs")]
716 diff --git a/meli/src/utilities/pager.rs b/meli/src/utilities/pager.rs
717index 3532462..ca4ea4d 100644
718--- a/meli/src/utilities/pager.rs
719+++ b/meli/src/utilities/pager.rs
720 @@ -393,7 +393,6 @@ impl Pager {
721 }
722
723 {
724- #[cfg(feature = "regexp")]
725 {
726 let area3 = area;
727 for text_formatter in