Remove ui crate

Merge ui crate with root crate.

In preparation for uploading `meli` as a separate crate on crates.io.

Workspace crates will need to be published as well and having a separate
`ui` crate and binary perhaps doesn't make sense anymore.
memfd
Manos Pitsidianakis 2020-02-04 15:52:12 +02:00
parent 6fcc792b83
commit 8b6ea8de9a
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
69 changed files with 320 additions and 892 deletions

62
Cargo.lock generated
View File

@ -236,15 +236,6 @@ dependencies = [
"libdbus-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "debug_printer"
version = "0.0.1"
dependencies = [
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"melib 0.4.1",
"ui 0.4.1",
]
[[package]]
name = "dirs"
version = "1.0.5"
@ -743,13 +734,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "meli"
version = "0.4.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"melib 0.4.1",
"nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
"notify-rust 3.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rmpv 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ui 0.4.1",
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"text_processing 0.4.1",
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg-utils 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1839,37 +1850,6 @@ name = "try-lock"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ui"
version = "0.4.1"
dependencies = [
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
"linkify 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"melib 0.4.1",
"nix 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
"notify-rust 3.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rmpv 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"text_processing 0.4.1",
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg-utils 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicase"
version = "2.6.0"

View File

@ -14,21 +14,44 @@ crossbeam = "0.7.2"
signal-hook = "0.1.12"
signal-hook-registry = "1.2.0"
nix = "0.16.1"
melib = { path = "melib", version = "*" }
ui = { path = "ui", version = "*" }
melib = { path = "melib", version = "0.4.1" }
serde = "1.0.71"
serde_derive = "1.0.71"
serde_json = "1.0"
toml = "0.5.3"
fnv = "1.0.3" # >:c
linkify = "0.3.1" # >:c
xdg-utils = "0.3.0"
nom = "3.2.0"
notify = "4.0.1" # >:c
notify-rust = "^3" # >:c
termion = "1.5.1"
bincode = "1.2.0"
uuid = { version = "0.7.4", features = ["serde", "v4"] }
unicode-segmentation = "1.2.1" # >:c
text_processing = { path = "text_processing", version = "0.4.1" }
libc = {version = "0.2.59", features = ["extra_traits",]}
rusqlite = {version = "0.20.0", optional =true }
rmp = "^0.8"
rmpv = { version = "^0.4.2", features=["with-serde",] }
rmp-serde = "^0.14.0"
smallvec = { version = "1.1.0", features = ["serde", ] }
[profile.release]
lto = true
debug = false
[workspace]
members = ["melib", "ui", "debug_printer", "testing", "text_processing"]
members = ["melib", "testing", "text_processing"]
[features]
default = []
notmuch = ["melib/notmuch_backend", "ui/notmuch"]
default = ["sqlite3"]
notmuch = ["melib/notmuch_backend", ]
jmap = ["melib/jmap_backend",]
sqlite3 = ["rusqlite"]
# Print tracing logs as meli runs in stderr
# enable for debug tracing logs: build with --features=debug-tracing
debug-tracing = ["melib/debug-tracing", "ui/debug-tracing"]
debug-tracing = ["melib/debug-tracing", ]

View File

@ -46,17 +46,18 @@ GREEN ?= `[ -z $${NO_COLOR+x} ] && tput setaf 2 || echo ""`
help:
@echo "For a quick start, build and install locally:\n ${BOLD}${GREEN}PREFIX=~/.local make install${ANSI_RESET}\n"
@echo "Available subcommands:"
@echo " - ${BOLD}install${ANSI_RESET} (installs binary and documentation)"
@echo " - ${BOLD}meli${ANSI_RESET} (builds meli with optimizations in \$$CARGO_TARGET_DIR)"
@echo " - ${BOLD}install${ANSI_RESET} (installs binary in \$$BINDIR and documentation to \$$MANDIR)"
@echo " - ${BOLD}uninstall${ANSI_RESET}"
@echo "Secondary subcommands:"
@echo " - ${BOLD}clean${ANSI_RESET} (cleans build artifacts)"
@echo " - ${BOLD}check-deps${ANSI_RESET} (checks dependencies)"
@echo " - ${BOLD}install-bin${ANSI_RESET} (installs binary to BINDIR)"
@echo " - ${BOLD}install-doc${ANSI_RESET} (installs manpages to MANDIR)"
@echo " - ${BOLD}install-bin${ANSI_RESET} (installs binary to \$$BINDIR)"
@echo " - ${BOLD}install-doc${ANSI_RESET} (installs manpages to \$$MANDIR)"
@echo " - ${BOLD}help${ANSI_RESET} (prints this information)"
@echo " - ${BOLD}dist${ANSI_RESET} (creates release tarball named meli-"${VERSION}".tar.gz)"
@echo " - ${BOLD}deb-dist${ANSI_RESET} (builds debian package)"
@echo " - ${BOLD}dist${ANSI_RESET} (creates release tarball named meli-"${VERSION}".tar.gz in this directory)"
@echo " - ${BOLD}deb-dist${ANSI_RESET} (builds debian package in the parent directory)"
@echo " - ${BOLD}distclean${ANSI_RESET} (cleans distribution build artifacts)"
@echo "\nENVIRONMENT variables of interest:"
@echo "* PREFIX = ${UNDERLINE}${PREFIX}${ANSI_RESET}"

View File

@ -1,17 +0,0 @@
[package]
name = "debug_printer"
version = "0.0.1" #:version
authors = ["Manos Pitsidianakis <el13635@mail.ntua.gr>"]
workspace = ".."
edition = "2018"
[lib]
name = "debugprinter"
crate-type = ["dylib"]
path = "src/lib.rs"
[dependencies]
libc = {version = "0.2.55", features = ["extra_traits",] }
melib = { path = "../melib", version = "*" }
ui = { path = "../ui", version = "*" }

View File

@ -1,44 +0,0 @@
extern crate libc;
extern crate melib;
use melib::Envelope;
use std::ffi::CString;
use std::os::raw::c_char;
#[no_mangle]
pub extern "C" fn print_envelope(ptr: *const Envelope) -> *const c_char {
unsafe {
assert!(!ptr.is_null(), "Null pointer in print_envelope");
//println!("got addr {}", p as u64);
//unsafe { CString::new("blah".to_string()).unwrap().as_ptr() }
let s = CString::new(format!("{:?}", *ptr)).unwrap();
drop(ptr);
let p = s.as_ptr();
std::mem::forget(s);
p
}
}
#[no_mangle]
pub extern "C" fn get_empty_envelope() -> *mut Envelope {
let mut ret = Envelope::default();
let ptr = std::ptr::NonNull::new(&mut ret as *mut Envelope)
.expect("Envelope::default() has a NULL pointer?");
let ptr = ptr.as_ptr();
std::mem::forget(ret);
ptr
}
#[no_mangle]
pub extern "C" fn destroy_cstring(ptr: *mut c_char) {
unsafe {
let slice = CString::from_raw(ptr);
drop(slice);
}
}
#[no_mangle]
pub extern "C" fn envelope_size() -> libc::size_t {
std::mem::size_of::<Envelope>()
}

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2019 Manos Pitsidianakis
*

View File

@ -21,24 +21,74 @@
//!
//! This crate contains the frontend stuff of the application. The application entry way on
//! `src/bin.rs` creates an event loop and passes input to the `ui` module.
//! `src/bin.rs` creates an event loop and passes input to a thread.
//!
//! The mail handling stuff is done in the `melib` crate which includes all backend needs. The
//! split is done to theoretically be able to create different frontends with the same innards.
//!
use std::alloc::System;
use std::collections::VecDeque;
use std::path::{Path, PathBuf};
extern crate notify_rust;
extern crate text_processing;
use text_processing::*;
extern crate xdg_utils;
#[macro_use]
extern crate serde_derive;
extern crate linkify;
extern crate uuid;
extern crate fnv;
extern crate termion;
#[macro_use]
extern crate nom;
extern crate serde_json;
extern crate smallvec;
#[global_allocator]
static GLOBAL: System = System;
// Re export to put crates in the documentation's start page.
pub use melib;
pub use ui;
#[macro_use]
extern crate melib;
use melib::*;
use ui::*;
mod unix;
use unix::*;
#[macro_use]
pub mod types;
use crate::types::*;
#[macro_use]
pub mod terminal;
use crate::terminal::*;
#[macro_use]
pub mod execute;
use crate::execute::*;
pub mod state;
use crate::state::*;
pub mod components;
use crate::components::*;
#[macro_use]
pub mod conf;
use crate::conf::*;
pub mod workers;
use crate::workers::*;
#[cfg(feature = "sqlite3")]
pub mod sqlite3;
pub mod cache;
pub mod mailcap;
pub mod plugins;
use nix;
use std::os::raw::c_int;
@ -152,15 +202,12 @@ fn run_app() -> Result<()> {
args.version = true;
}
"--print-loaded-themes" => {
let s = ui::conf::FileSettings::new()?;
let s = conf::FileSettings::new()?;
print!("{}", s.terminal.themes.to_string());
return Ok(());
}
"--print-default-theme" => {
print!(
"{}",
ui::conf::Theme::default().key_to_string("dark", false)
);
print!("{}", conf::Theme::default().key_to_string("dark", false));
return Ok(());
}
e => match prev {
@ -215,7 +262,7 @@ fn run_app() -> Result<()> {
};
if let Some(config_path) = args.test_config.as_ref() {
ui::conf::FileSettings::validate(config_path)?;
conf::FileSettings::validate(config_path)?;
return Ok(());
}
@ -235,7 +282,7 @@ fn run_app() -> Result<()> {
if config_path.exists() {
return Err(MeliError::new(format!("File `{}` already exists.\nMaybe you meant to specify another path with --create-config=PATH", config_path.display())));
}
ui::conf::create_config_file(&config_path)?;
conf::create_config_file(&config_path)?;
return Ok(());
}
@ -268,19 +315,17 @@ fn run_app() -> Result<()> {
let status_bar = Box::new(StatusBar::new(window));
state.register_component(status_bar);
let xdg_notifications = Box::new(ui::components::notifications::XDGNotifications::new());
let xdg_notifications = Box::new(components::notifications::XDGNotifications::new());
state.register_component(xdg_notifications);
state.register_component(Box::new(
ui::components::notifications::NotificationFilter {},
));
state.register_component(Box::new(components::notifications::NotificationFilter {}));
/* Keep track of the input mode. See ui::UIMode for details */
/* Keep track of the input mode. See UIMode for details */
'main: loop {
state.render();
'inner: loop {
/* Check if any components have sent reply events to State. */
let events: ui::smallvec::SmallVec<[UIEvent; 8]> = state.context.replies();
let events: smallvec::SmallVec<[UIEvent; 8]> = state.context.replies();
for e in events {
state.rcv_event(e);
}

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Search queries.
*/
use melib::parsec::*;
use melib::UnixTimestamp;
use melib::{
@ -27,6 +29,7 @@ use melib::{
thread::{SortField, SortOrder},
Result,
};
use std::borrow::Cow;
use std::sync::{Arc, RwLock};
pub use query_parser::query;
@ -334,7 +337,6 @@ pub mod query_parser {
pub fn query_to_imap(q: &Query) -> String {
fn rec(q: &Query, s: &mut String) {
use crate::sqlite3::escape_double_quote;
match q {
Subject(t) => {
s.push_str(" SUBJECT \"");
@ -440,3 +442,12 @@ pub fn imap_search(
panic!("Could not downcast ImapType backend. BUG");
}
}
#[inline(always)]
pub fn escape_double_quote(w: &str) -> Cow<str> {
if w.contains('"') {
Cow::from(w.replace('"', "\"\""))
} else {
Cow::from(w)
}
}

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -19,11 +19,11 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
Components are ways to handle application data. They can draw on the terminal and receive events, but also do other stuff as well. (For example, see the `notifications` module.)
See the `Component` Trait for more details.
*/
/*! Components visual and logical separations of application interfaces.
*
* They can draw on the terminal and receive events, but also do other stuff as well. (For example, see the `notifications` module.)
* See the `Component` Trait for more details.
*/
use super::*;
@ -32,9 +32,6 @@ pub use crate::mail::*;
pub mod notifications;
pub mod indexer;
pub use self::indexer::*;
pub mod utilities;
pub use self::utilities::*;

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -74,6 +74,7 @@ pub(super) struct EntryStrings {
}
#[macro_export]
/// Creates a comma separated list `String` out of an `Address` iterable.
macro_rules! address_list {
(($name:expr) as comma_sep_list) => {{
let mut ret: String =

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2019 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2020 Manos Pitsidianakis
*

View File

@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Configuration logic and `config.toml` interfaces. */
extern crate bincode;
extern crate serde;
extern crate toml;
@ -637,7 +639,7 @@ pub fn create_config_file(p: &Path) -> Result<()> {
.create_new(true)
.open(p)
.expect("Could not create config file.");
file.write_all(include_bytes!("../../sample-config"))
file.write_all(include_bytes!("../sample-config"))
.expect("Could not write to config file.");
println!("Written example configuration to {}", p.display());
let metadata = file.metadata()?;
@ -649,6 +651,7 @@ pub fn create_config_file(p: &Path) -> Result<()> {
}
mod pp {
//! Preprocess configuration files by unfolding `include` macros.
use melib::{
error::{MeliError, Result},
parsec::*,
@ -656,6 +659,7 @@ mod pp {
use std::io::Read;
use std::path::{Path, PathBuf};
/// Try to parse line into a path to be included.
fn include_directive<'a>() -> impl Parser<'a, Option<&'a str>> {
move |input: &'a str| {
enum State {
@ -712,6 +716,7 @@ mod pp {
}
}
/// Expands `include` macros in path.
fn pp_helper(path: &Path, level: u8) -> Result<String> {
if level > 7 {
return Err(MeliError::new(format!("Maximum recursion limit reached while unfolding include directives in {}. Have you included a config file within itself?", path.display())));
@ -752,6 +757,8 @@ mod pp {
Ok(ret)
}
/// Expands `include` macros in configuration file and other configuration files (eg. themes)
/// in the filesystem.
pub fn pp<P: AsRef<Path>>(path: P) -> Result<String> {
let p_buf: PathBuf = if path.as_ref().is_relative() {
path.as_ref().canonicalize()?

View File

@ -1106,10 +1106,9 @@ impl Account {
#[cfg(not(feature = "sqlite3"))]
{
let mut ret = SmallVec::new();
let envelopes = self.collection.envelopes.clone().read();
let envelopes = envelopes.unwrap();
let envelopes = self.collection.envelopes.read().unwrap();
for env_hash in self.folders[folder_hash].as_result()?.envelopes {
for &env_hash in &self.folders[&folder_hash].as_result()?.envelopes {
let envelope = &envelopes[&env_hash];
if envelope.subject().contains(&search_term) {
ret.push(env_hash);
@ -1127,7 +1126,7 @@ impl Account {
ret.push(env_hash);
}
}
ret
Ok(ret)
}
}
}

View File

@ -18,6 +18,8 @@
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
//! Configuration for composing email.
use super::default_vals::{false_val, none, true_val};
/// Settings for writing and sending new e-mail

View File

@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
//! Settings for the pager function.
use super::default_vals::*;
use super::deserializers::*;
use melib::ToggleFlag;

View File

@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
//! E-mail tag configuration and {de,}serializing.
use crate::terminal::Color;
use serde::{Deserialize, Deserializer};
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};

View File

@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
//! Settings for terminal display
use super::deserializers::non_empty_string;
use super::Theme;
use super::ToggleFlag;

View File

@ -19,6 +19,15 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
//! Application themes.
//!
//! * An attribute is a triple of foreground color, background color and terminal attribute `ThemeValue`s.
//! * A `ThemeValue<T>` is either an actual value or the key name of another value to which it depends. The value is either `Color` or `Attr`.
//! * `ThemeAttributeInner` is an attribute triplet.
//! * `ThemeAttribute` is an attribute triplet with the links resolved.
//!
//! On startup a [DFS](https://en.wikipedia.org/wiki/Depth-first_search) is performed to see if there are any cycles in the link graph.
use crate::terminal::{Attr, Color};
use crate::Context;
use melib::{MeliError, Result};
@ -187,6 +196,7 @@ const DEFAULT_KEYS: &'static [&'static str] = &[
"mail.listing.thread_snooze_flag",
];
/// `ThemeAttributeInner` but with the links resolved.
#[derive(Debug, PartialEq, Eq, Clone, Default, Copy, Serialize, Deserialize)]
pub struct ThemeAttribute {
pub fg: Color,
@ -194,6 +204,7 @@ pub struct ThemeAttribute {
pub attrs: Attr,
}
/// Holds {fore,back}ground color and terminal attribute values.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ThemeAttributeInner {
#[serde(default)]
@ -205,6 +216,7 @@ pub struct ThemeAttributeInner {
}
#[derive(Debug, Clone)]
/// Holds either an actual value or refers to the key name of the attribute that holds the value.
pub enum ThemeValue<T> {
Value(T),
Link(Cow<'static, str>),

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -19,7 +19,7 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! A parser module for user commands passed through the Ex mode.
/*! A parser module for user commands passed through the Execute mode.
*/
use melib::backends::FolderOperation;
pub use melib::thread::{SortField, SortOrder};

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2019 Manos Pitsidianakis
*

View File

@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Find mailcap entries to execute attachments.
*/
use crate::split_command;
use crate::state::Context;
use crate::types::{create_temp_file, ForkType, UIEvent};

View File

@ -19,6 +19,8 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Plugins are executed by meli and communication is done by `messagepack` IPC.
*/
use melib::error::{MeliError, Result};
use std::collections::HashMap;
use std::io::Write;

View File

@ -19,9 +19,10 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Use an sqlite3 database for fast searching.
*/
use smallvec::SmallVec;
use crate::cache::query;
use crate::cache::Query::{self, *};
use crate::cache::{escape_double_quote, query, Query::{self, *}};
use crate::melib::parsec::Parser;
use melib::{
backends::MailBackend,
@ -31,20 +32,10 @@ use melib::{
MeliError, Result, ERROR,
};
use rusqlite::{params, Connection};
use std::borrow::Cow;
use std::path::PathBuf;
use std::convert::TryInto;
use std::sync::{Arc, RwLock};
#[inline(always)]
pub fn escape_double_quote(w: &str) -> Cow<str> {
if w.contains('"') {
Cow::from(w.replace('"', "\"\""))
} else {
Cow::from(w)
}
}
pub fn db_path() -> Result<PathBuf> {
let data_dir =
xdg::BaseDirectories::with_prefix("meli").map_err(|e| MeliError::new(e.to_string()))?;

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -641,6 +641,7 @@ impl State {
}
}
AccountAction(ref account_name, ReIndex) => {
#[cfg(feature = "sqlite3")]
match crate::sqlite3::index(&mut self.context, account_name) {
Ok(()) => {
self.context.replies.push_back(UIEvent::Notification(
@ -657,6 +658,15 @@ impl State {
));
}
}
#[cfg(not(feature = "sqlite3"))]
{
self.context.replies.push_back(UIEvent::Notification(
None,
"Message index rebuild failed: meli is not built with sqlite3 support."
.to_string(),
Some(NotificationType::ERROR),
));
}
}
v => {
self.rcv_event(UIEvent::Action(v));

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*! Terminal grid cells, keys, colors, etc.
*/
extern crate serde;
use self::serde::de::Visitor;
use self::serde::{de, Deserialize, Deserializer};

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -36,6 +36,9 @@ use termion::color::{AnsiValue, Rgb as TermionRgb};
/// In a scroll region up and down cursor movements shift the region vertically. The new lines are
/// empty.
///
/// See `CellBuffer::scroll_up` and `CellBuffer::scroll_down` for an explanation of how `xterm`
/// scrolling works.
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct ScrollRegion {
pub top: usize,
@ -56,7 +59,9 @@ pub struct CellBuffer {
cols: usize,
rows: usize,
buf: Vec<Cell>,
/// ASCII-only flag.
pub ascii_drawing: bool,
/// If printing to this buffer and we run out of space, expand it.
growable: bool,
}
@ -170,7 +175,7 @@ impl CellBuffer {
///
/// # Examples
///
/// ```norun
/// ```no_run
///
/// let mut term = Terminal::new().unwrap();
///
@ -188,7 +193,7 @@ impl CellBuffer {
///
/// # Examples
///
/// ```norun
/// ```no_run
///
/// let mut term = Terminal::new().unwrap();
///
@ -427,6 +432,8 @@ impl fmt::Display for CellBuffer {
pub struct Cell {
ch: char,
/// Set a `Cell` as empty when a previous cell spans multiple columns and it would
/// "overflow" to this cell.
empty: bool,
fg: Color,
bg: Color,
@ -440,8 +447,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let cell = Cell::new('x', Color::Default, Color::Green, Attr::Default);
/// assert_eq!(cell.ch(), 'x');
/// assert_eq!(cell.fg(), Color::Default);
@ -464,8 +470,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::with_char('x');
/// assert_eq!(cell.ch(), 'x');
/// assert_eq!(cell.fg(), Color::Default);
@ -480,8 +485,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::with_style(Color::Default, Color::Red, Attr::Bold);
/// assert_eq!(cell.fg(), Color::Default);
/// assert_eq!(cell.bg(), Color::Red);
@ -496,8 +500,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::with_char('x');
/// assert_eq!(cell.ch(), 'x');
/// ```
@ -509,8 +512,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::with_char('x');
/// assert_eq!(cell.ch(), 'x');
///
@ -528,8 +530,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::with_style(Color::Blue, Color::Default, Attr::Default);
/// assert_eq!(cell.fg(), Color::Blue);
/// ```
@ -541,8 +542,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::default();
/// assert_eq!(cell.fg(), Color::Default);
///
@ -560,7 +560,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
/// ```no_run
/// let mut cell = Cell::with_style(Color::Default, Color::Green, Attr::Default);
/// assert_eq!(cell.bg(), Color::Green);
/// ```
@ -572,7 +572,7 @@ impl Cell {
///
/// # Examples
///
/// ```norun
/// ```no_run
/// let mut cell = Cell::default();
/// assert_eq!(cell.bg(), Color::Default);
///
@ -626,8 +626,7 @@ impl Default for Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// let mut cell = Cell::default();
/// assert_eq!(cell.ch(), ' ');
/// assert_eq!(cell.fg(), Color::Default);
@ -650,8 +649,7 @@ impl Default for Cell {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// // The default color.
/// let default = Color::Default;
///
@ -676,6 +674,7 @@ pub enum Color {
White,
Byte(u8),
Rgb(u8, u8, u8),
/// Terminal default.
Default,
}
@ -1371,8 +1370,7 @@ impl Serialize for Color {
///
/// # Examples
///
/// ```norun
///
/// ```no_run
/// // Default attribute.
/// let def = Attr::Default;
///
@ -1384,6 +1382,7 @@ impl Serialize for Color {
/// ```
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Attr {
/// Terminal default.
Default = 0b000,
Bold = 0b001,
Underline = 0b100,
@ -2003,7 +2002,7 @@ pub mod ansi {
/// the iterator will simply return `None` when it reaches the end of the row.
/// `RowIterator` can be created via the `CellBuffer::row_iter` method and can be returned by
/// `BoundsIterator` which iterates each row.
/// ```norun
/// ```no_run
/// for c in grid.row_iter(
/// x..(x + 11),
/// 0,
@ -2017,7 +2016,7 @@ pub struct RowIterator {
}
/// `BoundsIterator` iterates each row returning a `RowIterator`.
/// ```norun
/// ```no_run
/// /* Visit each `Cell` in `area`. */
/// for c in grid.bounds_iter(area) {
/// grid[c].set_ch('w');

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2020 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2020 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*
@ -135,6 +135,7 @@ impl PartialEq<Key> for &Key {
}
#[derive(PartialEq)]
/// Keep track of whether we're accepting normal user input or a pasted string.
enum InputMode {
Normal,
Paste,
@ -142,10 +143,13 @@ enum InputMode {
}
#[derive(Debug)]
/// Main process sends commands to the input thread.
pub enum InputCommand {
/// Exit thread
Kill,
/// Send Raw bytes as well
/// Send raw bytes as well
Raw,
/// Ignore raw bytes
NoRaw,
}
@ -158,6 +162,7 @@ use termion::input::TermReadEventsAndRaw;
*
* The main loop uses try_wait_on_child() to check if child has exited.
*/
/// The thread function that listens for user input and forwards it to the main event loop.
pub fn get_events(
mut closure: impl FnMut(Key),
closure_raw: impl FnMut((Key, Vec<u8>)),
@ -202,6 +207,7 @@ pub fn get_events(
}
}
/// Same as `get_events` but also forwards the raw bytes of the input as well
pub fn get_events_raw(
closure_nonraw: impl FnMut(Key),
mut closure: impl FnMut((Key, Vec<u8>)),

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2018 Manos Pitsidianakis
*

View File

@ -1,5 +1,5 @@
/*
* meli - ui crate.
* meli
*
* Copyright 2017-2020 Manos Pitsidianakis
*

14