office: Rename mail module to office module

Reflecting the somewhat expanding scope of the module, renamed it to
office. Still keeps the old files and setups but also got a new README
file.
This commit is contained in:
Marty Oehme 2022-12-06 17:55:47 +01:00
parent 593628b81d
commit 03684ce29f
Signed by: Marty
GPG key ID: 73BA40D5AFAF49C9
27 changed files with 28 additions and 15 deletions

View file

@ -0,0 +1,204 @@
{
"document": {
"block_prefix": "\n",
"block_suffix": "\n",
"color": "7",
"margin": 2
},
"block_quote": {
"indent": 0,
"color": "3",
"indent_token": "│ ",
"italic": true,
"margin": 1
},
"paragraph": {},
"list": {
"level_indent": 2,
"color": "7"
},
"heading": {
"block_suffix": "\n",
"color": "4",
"bold": true
},
"h1": {
"prefix": " ",
"suffix": " ",
"color": "7",
"background_color": "4",
"bold": true
},
"h2": {
"prefix": "## "
},
"h3": {
"prefix": "### "
},
"h4": {
"prefix": "#### "
},
"h5": {
"prefix": "##### "
},
"h6": {
"prefix": "###### ",
"color": "5",
"bold": false
},
"text": {},
"strikethrough": {
"crossed_out": true
},
"emph": {
"italic": true,
"color": "3"
},
"strong": {
"bold": true,
"color": "3"
},
"hr": {
"color": "0",
"format": "\n―――――――――――――――――――\n"
},
"item": {
"block_prefix": "• "
},
"enumeration": {
"block_prefix": ". ",
"color": "6"
},
"task": {
"ticked": "[✓] ",
"unticked": "[ ] "
},
"link": {
"color": "6",
"underline": true
},
"link_text": {
"color": "5",
"bold": true
},
"image": {
"color": "6",
"underline": true
},
"image_text": {
"color": "5",
"format": "Image: {{.text}} →"
},
"code": {
"color": "7",
"prefix": " ",
"suffix": " ",
"background_color": "#44475a"
},
"code_block": {
"color": "3",
"margin": 2,
"chroma": {
"text": {
"color": "#ansilightgray"
},
"error": {
"color": "#ansilightgray",
"background_color": "#ansidarkred"
},
"comment": {
"color": "#ansidarkgray"
},
"comment_preproc": {
"color": "#ansipurple"
},
"keyword": {
"color": "#ansipurple"
},
"keyword_reserved": {
"color": "#ansipurple"
},
"keyword_namespace": {
"color": "#ansipurple"
},
"keyword_type": {
"color": "#ansiteal"
},
"operator": {
"color": "#ansipurple"
},
"punctuation": {
"color": "#ansilightgray"
},
"name": {
"color": "#ansiteal"
},
"name_builtin": {
"color": "#ansiteal"
},
"name_tag": {
"color": "#ansipurple"
},
"name_attribute": {
"color": "#ansidarkgreen"
},
"name_class": {
"color": "#ansiteal"
},
"name_constant": {
"color": "#ansidarkblue"
},
"name_decorator": {
"color": "#ansidarkgreen"
},
"name_exception": {},
"name_function": {
"color": "#ansidarkgreen"
},
"name_other": {},
"literal": {},
"literal_number": {
"color": "#ansiturquoise"
},
"literal_date": {},
"literal_string": {
"color": "#ansibrown"
},
"literal_string_escape": {
"color": "#ansipurple"
},
"generic_deleted": {
"color": "#ansidarkred"
},
"generic_emph": {
"color": "#ansibrown",
"italic": true
},
"generic_inserted": {
"color": "#ansidarkgreen"
},
"generic_strong": {
"color": "#ansiyellow",
"bold": true
},
"generic_subheading": {
"color": "#ansidarkblue"
},
"background": {
"background_color": "#44475"
}
}
},
"table": {
"center_separator": "┼",
"column_separator": "│",
"row_separator": "─"
},
"definition_list": {},
"definition_term": {},
"definition_description": {
"block_prefix": "\n🠶 "
},
"html_block": {},
"html_span": {}
}

View file

@ -0,0 +1,15 @@
local accounts = {}
local status, gmailuser = pipe_from(
'gpg2 --decrypt --no-tty --quiet --no-verbose --for-your-eyes-only --pinentry-mode ask ~/.local/share/pass/misc/aerc-gmail-app-password.gpg | grep username | cut -d: -f2')
local status, gmailpass = pipe_from(
'gpg2 --decrypt --no-tty --quiet --no-verbose --for-your-eyes-only --pinentry-mode ask ~/.local/share/pass/misc/aerc-gmail-app-password.gpg | head -n1')
-- Setup an imap account called gmail
accounts.gmail = IMAP {
server = "imap.gmail.com",
username = gmailuser,
password = gmailpass,
ssl = "auto"
}
return accounts

View file

@ -0,0 +1,86 @@
-- According to the IMAP specification, when trying to write a message
-- to a non-existent mailbox, the server must send a hint to the client,
-- whether it should create the mailbox and try again or not. However
-- some IMAP servers don't follow the specification and don't send the
-- correct response code to the client. By enabling this option the
-- client tries to create the mailbox, despite of the server's response.
-- This variable takes a boolean as a value. Default is “false”.
options.create = true
-- By enabling this option new mailboxes that were automatically created,
-- get auto subscribed
options.subscribe = true
-- How long to wait for servers response.
options.timeout = 120
-- whether to enter IDLE mode and conintuously check
-- for new incoming mail to filter
CONTINUOUS = false
-- time to wait for next synchronization
-- only used in case server does not support IDLE mode
UPDATE_TIME = 120
-- implement simple wait function in case server does not support IDLE mode
function sleep(n) os.execute("sleep " .. tonumber(n)) end
-- will set filters to be grabbed from XDG-compliant filter directory
-- can be overridden with env var IMAPFILTER_FILTERDIR
function getConfigDir()
-- -- set directory for imapfilter files
local configdir
if os.getenv("IMAPFILTER_CONFIGDIR") then
configdir = os.getenv("IMAPFILTER_CONFIGDIR")
elseif os.getenv("XDG_CONFIG_HOME") then
configdir = os.getenv("XDG_CONFIG_HOME") .. "/imapfilter"
else
configdir = os.getenv("HOME") .. "/.config/imapfilter"
end
return configdir
end
-- will set filters to be grabbed from XDG-compliant filter directory
-- can be overridden with env var IMAPFILTER_FILTERDIR
function getFilterDir()
-- -- set directory for imapfilter files
local imapfilterdir
if os.getenv("IMAPFILTER_FILTERDIR") then
imapfilterdir = os.getenv("IMAPFILTER_FILTERDIR")
else
imapfilterdir = configDir .. "/filters"
end
return imapfilterdir
end
-- dirlist, from https://stackoverflow.com/a/25266573
function applyFilters(dir)
local p = io.popen('find "' .. dir .. '" -type f -name "*.lua"') -- Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
for file in p:lines() do -- Loop through all files
loadfile(file)()
end
end
-- create global variable containing the configuration files
configDir = getConfigDir()
assert(configDir,
"No configuration directory found. Ensure " .. os.getenv("HOME") ..
"/.config/imapfilter exists.")
-- create global variable containing account access
accounts = loadfile(configDir .. "/accounts.lua")()
assert(accounts,
"No accounts configured. Ensure accounts.lua exists and returns a table of accounts.")
-- immediately act on the filters once
applyFilters(getFilterDir())
-- continuously watch for mail if needed
while CONTINUOUS == true do
local has_idle = accounts.gmail['Inbox']:enter_idle()
applyFilters(getFilterDir())
if has_idle == false then
print(
"Server does not support idle, application will be polling again in " ..
UPDATE_TIME .. "minutes.")
sleep(UPDATE_TIME)
end
end

View file

@ -0,0 +1,40 @@
function sendToFolder(folderFrom, folderTo, senders)
local messages = folderFrom:select_all()
for _, sender in pairs(senders) do
local filtered = messages:contain_from(sender)
filtered:mark_seen()
filtered:move_messages(folderTo)
end
end
-- will set filters to be grabbed from XDG-compliant filter directory
-- can be overridden with env var IMAPFILTER_ROLLUPFILE
function getRollupFile(fname)
local f
local fname = fname or "rollup.txt"
if os.getenv("IMAPFILTER_ROLLUPFILE") then
f = os.getenv("IMAPFILTER_ROLLUPFILE")
elseif os.getenv("XDG_DATA_HOME") then
f = os.getenv("XDG_DATA_HOME") .. "/imapfilter/" .. fname
else
f = os.getenv("HOME") .. "/.local/share/imapfilter/" .. fname
end
return f
end
function getSenderList(rollupfile)
local rollupSenders = {}
local file = io.open(rollupfile)
if file then
for line in file:lines() do table.insert(rollupSenders, line) end
else
print(
"ERROR: rollup did not find rollup.txt file containing mail addresses at " ..
rollupfile or "")
end
return rollupSenders
end
sendToFolder(accounts.gmail["Inbox"], accounts.gmail["Dump"],
getSenderList(getRollupFile()))

View file

@ -0,0 +1,68 @@
# documentation: https://wiki.archlinux.org/index.php/isync
IMAPAccount gmail
# Address to connect to
Host imap.gmail.com
UserCmd "pass show misc/gmail-app-password | grep username | cut -d: -f2"
PassCmd "pass show misc/gmail-app-password | head -n1"
# To store the password in an encrypted file use PassCmd instead of Pass
# PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d ~/.mailpass.gpg"
#
# Use SSL
TLSType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
# Throttle simultaneous access to make google happy
PipelineDepth 60
IMAPStore gmail-remote
Account gmail
MaildirStore mail-local
Subfolders Verbatim
# The trailing "/" is important
Path ~/documents/mail/
Inbox ~/documents/mail/Inbox
# define generous maximum size to store locally
MaxSize 50M
Channel gmail-inbox
Far :gmail-remote:INBOX
Near :mail-local:inbox
# Exclude everything under the internal [Gmail] folder, except the interesting folders
# Automatically create missing mailboxes, both locally and on the server
Create Near
# Save the synchronization state files in the relevant directory
SyncState *
Channel gmail-sent
Far :gmail-remote:"[Google Mail]/Sent Mail"
Near :mail-local:sent
Create Near
Channel gmail-trash
Far :gmail-remote:"[Google Mail]/Trash"
Near :mail-local:trash
Create Near
Channel gmail-important
Far :gmail-remote:"[Google Mail]/Starred"
Near :mail-local:important
Create Near
Channel gmail-drafts
Far :gmail-remote:"[Google Mail]/Drafts"
Near :mail-local:drafts
Create Near
Channel gmail-all
Far :gmail-remote:"[Google Mail]/All Mail"
Near :mail-local:archive
Create Near
# Put all the channels into one group
Group googlemail
Channel gmail-inbox
Channel gmail-important
Channel gmail-sent
Channel gmail-trash
Channel gmail-all

View file

@ -0,0 +1,16 @@
[calendars]
[[calendar_local]]
path = ~/documents/calendars/*
type = discover
color = auto
[locale]
timeformat = %H:%M
dateformat = %Y-%m-%d
longdateformat = %Y-%m-%d
datetimeformat = %Y-%m-%d %H:%M
longdatetimeformat = %Y-%m-%d %H:%M
[default]
default_calendar = Activities

View file

@ -0,0 +1,18 @@
# Set default values for all following accounts.
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
# logfile ~/.msmtp.log
# Gmail
account personal-gmail
host smtp.gmail.com
port 587
from marty.oehme@gmail.com
user marty.oehme@gmail.com
# password plain-text-password-goes-here
passwordeval "pass show misc/gmail-app-password | head -n1"
# Set a default account
account default : personal-gmail

View file

@ -0,0 +1,16 @@
# Account settings
# local maildir settings
set mbox_type = Maildir
set folder = ~/documents/mail # This has the shortcut '+' or '='
set spoolfile = "+inbox" # This has the shortcut '!'
set postponed = "+drafts"
set trash = "+trash"
# Disable saving outgoing mail since Gmail saves them by default.
unset record
mailboxes ! \
"+important" \
"+sent" \
"+drafts" \
"+trash" \
"+archive"

View file

@ -0,0 +1,233 @@
# # taken from https://gideonwolfe.com/posts/workflow/neomutt/intro/
# # Header colors:
color header blue default ".*"
color header brightmagenta default "^(From)"
color header brightcyan default "^(Subject)"
color header brightwhite default "^(CC|BCC)"
# mono bold bold
# mono underline underline
# mono indicator reverse
# mono error bold
# color normal default default
# color indicator brightyellow default # currently selected message. default makes bar clear, disabled arrow to save space.
# color sidebar_highlight red default
# color sidebar_divider brightblack black
# color sidebar_flagged red black
# color sidebar_new green black
# color normal brightyellow default
# color error red default
# color tilde black default
# color message cyan default
# color markers red white
# color attachment white default
# color search brightmagenta default
# color status brightyellow black
# color hdrdefault brightgreen default
# color quoted green default
# color quoted1 blue default
# color quoted2 cyan default
# color quoted3 yellow default
# color quoted4 red default
# color quoted5 brightred default
# color signature brightgreen default
# color bold black default
# color underline black default
# color normal default default
color body brightred default "[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+" # Email addresses
color body brightblue default "(https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+" # URL
color body green default "\`[^\`]*\`" # Green text between ` and `
color body brightblue default "^# \.*" # Headings as bold blue
color body brightcyan default "^## \.*" # Subheadings as bold cyan
color body brightgreen default "^### \.*" # Subsubheadings as bold green
color body yellow default "^(\t| )*(-|\\*) \.*" # List items as yellow
color body brightcyan default "[;:][-o][)/(|]" # emoticons
color body brightcyan default "[;:][)(|]" # emoticons
color body brightcyan default "[ ][*][^*]*[*][ ]?" # more emoticon?
color body brightcyan default "[ ]?[*][^*]*[*][ ]" # more emoticon?
color body red default "(BAD signature)"
color body cyan default "(Good signature)"
color body brightblack default "^gpg: Good signature .*"
color body brightyellow default "^gpg: "
color body brightyellow red "^gpg: BAD signature from.*"
mono body bold "^gpg: Good signature"
mono body bold "^gpg: BAD signature from.*"
color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
# Default index colors:
color index yellow default '.*'
color index_author red default '.*'
color index_number blue default
color index_subject cyan default '.*'
# For new mail:
color index brightyellow black "~N"
color index_author brightred black "~N"
color index_subject brightcyan black "~N"
color progress black cyan
# Nerd icons idea based on https://github.com/sheoak/neomutt-powerline-nerdfonts/
# Dracula colors based on Dracula Theme by Paul Townsend <paul@caprica.org>
# Formatting ----------------------------------------------------------------------
set date_format = "%a %d %h %H:%M"
set index_format=" %zc %zs %zt | %-35.35L %@attachment_info@ %?M10?~(%1M) ?%-30.100s %> %?Y?%Y ? %(!%a %d %h %H:%M) "
set pager_format="%n %T %s%*  %{!%d %b · %H:%M} %?X? %X?%P"
set status_format = " %D %?u? %u ?%?R? %R ?%?d? %d ?%?t? %t ?%?F? %F ?%?p? %p? \n \n"
set compose_format="-- NeoMutt: Compose [Approx. msg size: %l Atts: %a]%>-"
# set vfolder_format = "%N %?n?%3n& ? %8m  · %f"
set attach_format = "%u%D  %T%-75.75d %?T?%& ? %5s · %m/%M"
set sidebar_format = '%D%?Z? [%Z]?%* %?S?%S?'
index-format-hook attachment_info '=B text/calendar ~X 1' ' '
index-format-hook attachment_info '=B text/calendar' " "
index-format-hook attachment_info '~X 1' " "
index-format-hook attachment_info '~A' " "
# General Colors ------------------------------------------------------------------
color normal default default # general text
color error color231 color212 # error messages
color message default default # messages at the bottom
color prompt default default # prompt text
color search black color10 # search highlight
# Statusbar Colors ----------------------------------------------------------------
color status color141 default
color status color7 color8 '([a-zA-Z0-9\.,]|\[|\])(\s)' # bubble content 1
color status color7 color8 '(\s)([a-zA-Z0-9\.,]|\[|\])' # bubble content 2
color status color7 color8 '(\% )' # % symbol
color status color7 color8 '(\S)' # empty spaces
color status color8 default '(|)' # statusline "bubbles"
color status color69 black '(\` )' # bubble account variation
color status white color69 '([a-zA-Z0-9\.]+)()' # account text
color status green color8 '' # Unread messages count
color status blue color8 '' # Read messages count icon
color status yellow color8 '' # Flagged icon
color status red color8 '' # Pending delete icon
# Index Colors --------------------------------------------------------------------
color index color15 default '~N' # new messages
color index color8 default '~R' # read messages
color index color8 default '~Q' # messages which have been replied to
color index_collapsed color4 default # collapsed thread (message count text)
color index color5 default '!~Q^~p' # sent only to me and haven't been replied to
color index color22 default '~h X-Label..' # messages with a complete label
color index color6 default '~F' # flagged messages
color index color6 default '~F~N' # flagged messages (new)
color index color14 default '~F~R' # flagged messages (read)
color index color1 default '~D' # deleted messages
color index color1 default '~D~N' # deleted messages (new)
color index color9 default '~D~R' # deleted messages (read)
color index color3 default '~T' # tagged messages
color index color3 default '~T~N' # tagged messages (new)
color index color11 default '~T~R' # tagged messages (read)
color tree color8 color8 # thread tree lines/arrow
color indicator default color8 # selection indicator
color index_date color8 default # date is always the same colour
color index_label color6 default # label is always the same colour
# Sidebar Colors ------------------------------------------------------------------
color sidebar_indicator color14 black # currently selected mailbox
color sidebar_highlight white color8 # highlighted, but not open, mailbox.
color sidebar_ordinary color8 default # Color to give mailboxes by default
color sidebar_divider color8 black # divider between sidebar & content
color sidebar_flagged red black # mailboxes containing flagged mail
color sidebar_new green black # mailboxes containing new mail
color sidebar_unread color7 default # mailboxes containing unread mail
color sidebar_unread color7 default # mailboxes containing unread mail
# Message Headers -----------------------------------------------------------------
color hdrdefault color8 default
# Message Body --------------------------------------------------------------------
# Attachments
color attachment color8 default
# Signature
color signature color8 default
# emails
# color body color14 default '[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+'
# hide "mailto"
color body color0 color0 '<mailto:[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+>'
# URLs
color body color3 default '(https?|ftp)://[-\.,/%~_:?&=\#a-zA-Z0-9\+]+'
# Dividers
color body color8 default '(^[-_]*$)'
# Important info in calendar invites
color body color6 default '^(Date\/Time|Location|Organiser|Invitees|Teams Meeting)(:| \~\~)'
# Quotes
color quoted color61 default
color quoted1 color117 default
color quoted2 color84 default
color quoted3 color215 default
color quoted4 color212 default
# Forward/reply headers
color body color8 default '(^(To|From|Sent|Subject):.*)'
# Patch syntax highlighting
# color body brightwhite default '^[[:space:]].*'
# color body yellow default ^(diff).*
# color body white default ^[\-\-\-].*
# color body white default ^[\+\+\+].*
# color body green default ^[\+].*
# color body red default ^[\-].*
# color body brightblue default [@@].*
# color body cyan default ^(Signed-off-by).*
# color body brightwhite default ^(Cc)
# color body yellow default "^diff \-.*"
# color body brightwhite default "^index [a-f0-9].*"
# color body brightblue default "^---$"
# color body white default "^\-\-\- .*"
# color body white default "^[\+]{3} .*"
# color body green default "^[\+][^\+]+.*"
# color body red default "^\-[^\-]+.*"
# color body brightblue default "^@@ .*"
# color body green default "LGTM"
# color body brightmagenta default "-- Commit Summary --"
# color body brightmagenta default "-- File Changes --"
# color body brightmagenta default "-- Patch Links --"
# color body green default "^Merged #.*"
# color body red default "^Closed #.*"
# color body brightblue default "^Reply to this email.*"
# Misc -----------------------------------------------------------------------------
# no addressed to me, to me, group, cc, sent by me, mailing list
set to_chars=" "
# unchanged mailbox, changed, read only, attach mode
set status_chars = " "
ifdef crypt_chars set crypt_chars = " "
set flag_chars = " "
# hide some tags
set hidden_tags = "unread,draft,flagged,passed,replied,attachment,signed,encrypted"
tag-transforms "replied" "↻ " \
"encrytpted" "" \
"signed" "" \
"attachment" "" \
# The formats must start with 'G' and the entire sequence is case sensitive.
tag-formats "replied" "GR" \
"encrypted" "GE" \
"signed" "GS" \
"attachment" "GA" \
# don't put '+' at the beginning of wrapped lines
set markers=no

View file

@ -0,0 +1,28 @@
# open html emails in browser (or whatever GUI program is used to render HTML)
text/html; xdg-open %s ; nametemplate=%s.html
# render html emails inline using magic (uncomment the line below to use lynx instead)
# text/html; lynx -assume_charset=%{charset} -display_charset=utf-8 -collapse_br_tags -dump %s; nametemplate=%s.html; copiousoutput
text/html; render-prettyhtml %s; nametemplate=%s.html; copiousoutput;
text/plain; $EDITOR %s ;
# show calendar invites
text/calendar; mutt-ics; copiousoutput
application/ics; mutt-ics; copiousoutput
# open images externally
image/*; nsxiv %s ;
# open videos in mpv
video/*; mpv --autofit-larger=90\%x90\% %s; needsterminal;
video/*; setsid mpv --quiet %s &; copiousoutput
# open spreadsheets in sc-im
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; sc-im %s; needsterminal
# open anything else externally
application/pdf; xdg-open %s;
application/*; mkdir -p /tmp/mutt \; cp %s /tmp/mutt \; xdg-open /tmp/mutt/$(basename %s) &
application/pgp-encrypted; gpg -d '%s'; copiousoutput;
application/pgp-keys; gpg --import '%s'; copiousoutput;

View file

@ -0,0 +1,61 @@
# index navigation
bind index l display-message
bind index L limit
bind index,pager g noop # don't send group-replies with g
bind index gg first-entry
bind index G last-entry
bind index <space> collapse-thread
bind index,pager \CF next-page
bind index,pager \CB previous-page
bind index,pager N search-opposite # vim-like search
bind index s toggle-new
macro index \CS "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
# Email completion bindings
bind editor <Tab> complete-query
bind editor ^T complete
# Press A to add contact to Khard address book
macro index,pager A \
"<pipe-message>khard add-email<return>" \
"add the sender email address to khard"
# mailbox navigation
macro index,pager gi "<change-folder>=inbox<enter>" "go to inbox"
macro index,pager gm "<change-folder>=important<enter>" "go to important"
macro index,pager gs "<change-folder>=sent<enter>" "go to sent"
macro index,pager gd "<change-folder>=drafts<enter>" "go to drafts"
macro index,pager gt "<change-folder>=trash<enter>" "go to trash"
macro index,pager ga "<change-folder>=archive<enter>" "go to archive"
# sidebar navigation
bind index,pager B sidebar-toggle-visible
bind index,pager <down> sidebar-next
bind index,pager <up> sidebar-prev
bind index,pager <right> sidebar-open
# search navigation
macro index a "<limit>all\n" "show all messages (undo limit)"
# notmuch search navigation
bind index \\ vfolder-from-query # notmuch search
# pager navigation
bind pager,attach h exit
bind pager l view-attachments
bind pager k previous-line
bind pager j next-line
bind pager gg top
bind pager G bottom
# compose postpone
bind compose p postpone-message
# markdown to html for composition
macro compose M "F pandoc -s -f markdown -t html \ny^T^Utext/html; charset=UTF-8\n" "Convert from MD to HTML"
# since we unbound the original g
bind index,pager R group-reply
# open urls found in the e-mail
macro index,pager \CU "|urlview<enter>" "call urlview to open links"
# Refresh far imap email
macro index O "<sync-mailbox><shell-escape>export MBSYNC_PRE=true; sync-mail<enter><sync-mailbox>" "refresh all e-mail"
macro index o "<sync-mailbox><shell-escape>export MBSYNC_PRE=true; sync-mail gmail-inbox<enter><sync-mailbox>" "refresh inbox e-mail"
# Saner copy/move dialogs
macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"

View file

@ -0,0 +1,6 @@
source colors
source settings
source maps
source account

View file

@ -0,0 +1,105 @@
# Identity
#
set realname = "Marty Oehme"
set from = "marty.oehme@gmail.com"
# # If you have another address:
# alternates "^neomutt@example\.com$"
# # Or, if you use the entire domain:
# alternates "@example\.com$"
# set reverse_name
set mail_check = 60
set mail_check_stats
set quit # at least for rapid prototyping
set sleep_time = 0 # no pause for info messages
set mark_old = no # things should only be new/unread or I actually looked at them
set pager_read_delay = 3 # mark read after 3 sec
set pipe_decode # get rid of headers when passing messages along
set auto_tag # apply commands to all tagged messages automatically
set wait_key = no # don't wait for user input after shell cmds, auto-view, piping, etc
set thorough_search = no # don't pre-process mail for ~b/~B searches
set flag_safe # make it impossible to delete flagged mails
# Pager settings
# filetypes and mailcap
set mailcap_path = "~/.config/neomutt/mailcap:~/.mailcap:/usr/share/neomutt/mailcap:/etc/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap"
# Consult mime.types for determining types of these attachments
mime_lookup application/octet-stream
# This requires a ~/.mailcap entry with the copiousoutput flag, such as:
# text/html; lynx -dump -width ${COLUMNS:-80} %s; nametemplate=%s.html; copiousoutput
# Prefer plain text to html but multipart to plain for those only sending that
auto_view application/ics
auto_view text/calendar
auto_view text/plain
auto_view text/html
alternative_order text/calendar application/ics text/plain text/enriched text/html text/* multipart/mixed multipart/related text/plain
set count_alternatives = yes # look for attachments also in multipart/alternatives
# Remember to `mkdir -p ~/.neomutt/hcache` first:
set header_cache= "~/.neomutt/hcache"
# Compose settings
set edit_headers # allow editing headers while writing mail
set sig_dashes # separate signature from mail
set fast_reply # automatically fill in from and subject for replies
set forward_format = "Fwd: %s"
set reply_to # default send back to reply-to: header instead of from: header
set reverse_name # default to reply as person e-mail was originally sent to
set include # include original msg in reply
set forward_quote # include original msg as quote in fwd
set forward_format = "FW: %s" # subject for forwarding
set mime_forward = no # forward attachments with mail
set fcc_attach # attachments saved with body
# set editor = "emacsclient -a emacs -t"
# set editor = "vim"
set mime_type_query_command = "xdg-mime query filetype"
# send settings
set sendmail = "/usr/bin/msmtp -a personal-gmail"
set sendmail_wait = 0
# Display Settings
set allow_ansi # allow escape codes for color etc
set sort = threads
set sort_re # thread based on regex below
set reply_regex = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
set quote_regex = "^( {0,4}[>|:#%]| {0,4}[A-Za-z0-9]+[>|]+)+"
set sort_aux = last-date-received
#### Thread ordering
set use_threads=reverse
set sort='last-date'
set collapse_all = yes
set uncollapse_new = no
set thread_received = yes
set narrow_tree=no
# set date_format = "%z/%m/%d %I:%M%p"
# set date_format = "%m/%d"
# set index_format = "%4C [%Z] %{%y/%b %d} %-20.20F %s"
# sidebar view options
set sidebar_visible = yes
set sidebar_width = 24
# set sidebar_format = "%B%?F? [%F]?%* %?N?%N/?%S"
set sidebar_divider_char = ' ░'
set sidebar_folder_indent = yes
set sidebar_indent_string = ' - '
set sidebar_visible = no
set sidebar_next_new_wrap = yes
set sidebar_short_path = yes
set sidebar_component_depth = 0
color sidebar_new color221 color233
# statusbar view options
set status_chars = " *%A"
# set status_format = "───[ Folder: %f ]───[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]───%>─%?p?( %p postponed )?───"
# pager view options
set pager_index_lines = 10
set pager_context = 3
set pager_stop # do not go to next msg if at bottom of pager
set menu_scroll = yes
set tilde # show tildes for blank lines
unset markers # no + markers for wrapped stuff
set wrap = 90
# hide headers except for those explicitly unignored
ignore *
unignore From To Cc Bcc Date Subject Message-ID
unhdr_order *
unignore From To Cc Bcc Date Subject Message-ID
set query_command = "khard email --parsable --search-in-source-files '%s'"
set nm_query_type = "threads" # Makes notmuch return threads rather than messages

View file

@ -0,0 +1,88 @@
# .notmuch-config - Configuration file for the notmuch mail system
#
# For more information about notmuch, see https://notmuchmail.org
# Database configuration
#
# The only value supported here is 'path' which should be the top-level
# directory where your mail currently exists and to where mail will be
# delivered in the future. Files should be individual email messages.
# Notmuch will store its database within a sub-directory of the path
# configured here named ".notmuch".
#
[database]
path=documents/mail
# User configuration
#
# Here is where you can let notmuch know how you would like to be
# addressed. Valid settings are
#
# name Your full name.
# primary_email Your primary email address.
# other_email A list (separated by ';') of other email addresses
# at which you receive email.
#
# Notmuch will use the various email addresses configured here when
# formatting replies. It will avoid including your own addresses in the
# recipient list of replies, and will set the From address based on the
# address to which the original email was addressed.
#
[user]
name=Marty Oehme
primary_email=marty.oehme@gmail.com
other_email=mo82rimu@studserv.uni-leipzig.de;moehme@ruc.dk;
# Configuration for "notmuch new"
#
# The following options are supported here:
#
# tags A list (separated by ';') of the tags that will be
# added to all messages incorporated by "notmuch new".
#
# ignore A list (separated by ';') of file and directory names
# that will not be searched for messages by "notmuch new".
#
# NOTE: *Every* file/directory that goes by one of those
# names will be ignored, independent of its depth/location
# in the mail store.
#
[new]
tags=
ignore=
# Search configuration
#
# The following option is supported here:
#
# exclude_tags
# A ;-separated list of tags that will be excluded from
# search results by default. Using an excluded tag in a
# query will override that exclusion.
#
[search]
exclude_tags=deleted;spam;
# Maildir compatibility configuration
#
# The following option is supported here:
#
# synchronize_flags Valid values are true and false.
#
# If true, then the following maildir flags (in message filenames)
# will be synchronized with the corresponding notmuch tags:
#
# Flag Tag
# ---- -------
# D draft
# F flagged
# P passed
# R replied
# S unread (added when 'S' flag is not present)
#
# The "notmuch new" command will notice flag changes in filenames
# and update tags, while the "notmuch tag" and "notmuch restore"
# commands will notice tag changes and update flags in filenames
#
[maildir]
synchronize_flags=true

View file

@ -0,0 +1,27 @@
#!/usr/bin/env sh
#
# Wraps around the calcurse invocation and syncs calendar data
# to local vdir - given by default below.
#
# For now ONLY PROVIDES ONE-WAY Synchronization, see below.
# The path in which *the calendars* reside (i.e. toplevel with access to all paths)
CAL_PATH="$HOME/documents/calendars"
calcurse() {
find "$CAL_PATH" -maxdepth 1 -type d -exec calcurse-vdir import {} \;
}
# Enable two-way sync. One issue is that calcurse would sync everything
# into the top-level path (or the selected calendar path) since it makes
# not the same differentiation as the vdir between calendars.
# FIXME Not sure how to resolve currently.
#
# The below works as a simple two-way synchronization on exiting calcurse.
# To function the invocation has to be turned from a function above to an
# executable shell-script file instead.
# trap 'calcurse_export' 0
#
# calcurse_export() {
# calcurse-vdir export "$CAL_PATH"
# }

View file

@ -0,0 +1,79 @@
#!/usr/bin/env sh
# Fzf searching notmuch email database
# Search with notmuch queries
# You can either invoke:
# `fzfmail` -> and then interactively create a notmuch query (not fuzzy searching)
# or:
# `fzfmail [notmuchquery]` -> pre-craft a query and then use fzf to filter it further, e.g.
# fzfmail tag:archived and subject:Important and not tag:flagged
#
# select as many mails as you wish (ctrl-a for all current results)
# preview mails with ?
#
# read with <enter>
# re-tag with <ctrl-t>
if exist fzf; then
# Allow fuzzy search filtering of a notmuch search query
fzfmail() {
# shellcheck disable=2016 # we only want the expression to expand when fzf preview is actually called not by the shell
if [ -z "$1" ]; then
# interactive query
fzfmail_mails=$(
printf "
\nStart a notmuch search query:\n" |
fzf --multi \
--header "tag: | from: | to: | subject: | folder: | date: || and | not | or | near | adj || <enter> read | <ctrl-t> tag" \
--bind "change:reload:notmuch search {q} || true" \
--bind "ctrl-a:toggle-all" \
--bind '?:toggle-preview' \
--expect 'ctrl-t,esc' \
--preview='notmuch show --part=1 $(echo {} | cut -d" " -f1)' \
--preview-window hidden \
--phony |
cut -d" " -f1
)
else
# pre-queried fuzzy search
fzfmail_mails=$(
notmuch search "$*" |
fzf --multi \
--header "<enter> read | <ctrl-t> tag" \
--bind "ctrl-a:toggle-all" \
--bind '?:toggle-preview' \
--expect 'ctrl-t,esc' \
--preview='notmuch show --part=1 $(echo {} | cut -d" " -f1)' \
--preview-window hidden |
cut -d" " -f1
)
fi
# find out expected action
fzfmail_action=$(echo "$fzfmail_mails" | head -n1)
# quit on esc pressed -- do not do anything with selected results
if echo "$fzfmail_action" | grep -qe 'esc'; then return 0; fi
# get the selected mails
fzfmail_mails=$(echo "$fzfmail_mails" | tail -n+2)
# tag mails
if echo "$fzfmail_action" | grep -qe 'ctrl-t'; then
printf "current tags: %s\n" "$(notmuch search --output=tags "$fzfmail_mails" | tr '\n' ' ')"
printf "add tags with +tag; remove with -tag\n"
printf "apply tags: "
read -r fzfmail_tags
notmuch tag "$fzfmail_tags" -- "$fzfmail_mails"
return 0
fi
# display the mails, in semi-readable format
# highlight subject line in color
# allow moving through results with n/p
notmuch show "$fzfmail_mails" | sed -e 's/^\fmessage{.*$/MESSAGE:/' -e '/^\f[a-z]/d' -e 's/^Subject:/\o033[41mSubject:\o033[0m/' | less --pattern '^MESSAGE:$' -R
unset fzfmail_mails
unset fzfmail_action
unset fzfmail_tags
}
fi

View file

@ -0,0 +1,3 @@
#!/bin/sh
alias imapfilter='imapfilter -c "${XDG_CONFIG_HOME:-$HOME/.config}/imapfilter/config.lua"'

View file

@ -0,0 +1,3 @@
#!/bin/sh
alias mbsync='mbsync -c ${XDG_CONFIG_HOME:-$HOME/.config}/isync/mbsyncrc'

View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
# Ensure the neomutt cache directories exist
[ -d "${XDG_CACHE_HOME:-~/.cache}/neomutt" ] || mkdir -p "${XDG_CACHE_HOME:-~/.cache}/neomutt/hcache"

View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
# Make notmuch config comply with xdg base dir specification
export NOTMUCH_CONFIG="${XDG_CONFIG_HOME:-~/.config}/notmuch/config"

View file

@ -0,0 +1,39 @@
[general]
status_path = "~/.local/vdirsyncer/status/"
[pair calendar]
a = "calendar_local"
b = "calendar_nextcloud"
collections = ["from a", "from b"]
metadata = ["displayname", "color"]
conflict_resolution = "b wins"
[storage calendar_local]
type = "filesystem"
path = "~/documents/calendars/"
fileext = ".ics"
[storage calendar_nextcloud]
type = "caldav"
url = "https://files.martyoeh.me/remote.php/dav/"
username.fetch = ["shell", "pass personal/files.martyoeh.me/me | awk -F': ' '{print $2}'"]
password.fetch = ["shell", "pass personal/files.martyoeh.me/me | head -n1"]
[pair contacts]
a = "contacts_local"
b = "contacts_nextcloud"
collections = ["from a", "from b"]
metadata = ["displayname", "description"]
conflict_resolution = "b wins"
[storage contacts_local]
type = "filesystem"
path = "~/documents/contacts/"
fileext = ".vcf"
[storage contacts_nextcloud]
type = "carddav"
url = "https://files.martyoeh.me/remote.php/dav/"
username.fetch = ["shell", "pass personal/files.martyoeh.me/me | awk -F': ' '{print $2}'"]
password.fetch = ["shell", "pass personal/files.martyoeh.me/me | head -n1"]