Compare commits

...

31 Commits

Author SHA1 Message Date
ee6a9b405e
Simplify completion styles by with overrides for certain categories
The default completion style is now to use orderless by default, but
certain categories can benefit from additional completions (e.g., file
and partial-completion).

It's quite hard to determine the appropriate completion categories,
though.  Does Org have a dedicated one?
2024-03-10 08:43:16 +01:00
ea0e94c312
Only keep orderless match faces that are readable with solarized 2024-03-09 20:19:41 +01:00
6b8b97fe8d
Prefer orderless completion style over others
The reason is that while filtering Org headlines, sometimes one of the
other completion styles matches, hiding other possible matches that
would have been found by the `orderless` style.  This can happen when
spaces are included in Org headlines (which is usually the case) and
those spaces match the search pattern.  In this case, the position of
point is also relevant, which is not something I want.

It would be better to know which completion category is use in this case
and override the completion style for this only, but so far I haven't
found it.  Continue looking …
2024-03-09 20:06:48 +01:00
42074f7d6a
Fix some docstring formatting 2024-03-09 16:30:08 +01:00
dbd19d0da8
Extend candidate list for custom grep-files function with history
It might be useful to actually see the history entries, so let's
explicitly include them in the candiate list.
2024-03-09 16:18:51 +01:00
4124bc28d5
Provide default value for custom grep-files pattern query function 2024-03-09 16:16:03 +01:00
7d398a66c8
Replace counsel Org heading dispatch by org-refile
This is nice enough and removes the last dependency to counsel :)
2024-03-09 15:04:21 +01:00
aadca01244
Simplify Org clocking hydra
No need to define an anonymous function her, just make the call
directly.
2024-03-09 15:03:10 +01:00
118b50c8da
Always show absolute time when annotating file selections
Via https://protesilaos.com/emacs/dotemacs#h:bd3f7a1d-a53d-4d3e-860e-25c5b35d8e7e.
2024-03-09 14:56:43 +01:00
7a2410642f
Remove redundant package declaration for helm-ring
This package is loaded in the main helm declaration, no need to mention
it separately.
2024-03-09 14:09:38 +01:00
8150725233
Use default completion functions for Info and Unicode lookup
Using vertico completion, they are quite nice! :)
2024-03-09 14:08:41 +01:00
3d0afd3f07
Experimentally replace default ivy completion with vertico
This may change back in the future.

The ivy configuration is kept on purpose, in particular because some
counsel functions are still in use.  Maybe those can be also be replaced
later on, maybe with helm functions?  Not quite sure whether this is a
good idea, though.
2024-03-09 13:46:36 +01:00
f6c40ad619
Fix wrong candiate specification in custom grep-read-files function
Somehow mixed up the order, I suppose.
2024-03-09 13:45:49 +01:00
a4325f30bf
Remove some obsolete counsel bindings 2024-03-08 17:26:25 +01:00
2bd2b5734a
Update dash 2024-03-06 21:12:01 +01:00
bcccc55ad3
Remove some obsolete scripts 2024-03-06 20:25:46 +01:00
a233d092de
Replace timestamp query in main agenda view with option setting
This is faster.
2024-03-06 19:01:31 +01:00
0e9ae4aa4d
Fix conditional loading of helm
It only makes sense to load helm when it's installed, isn't it?
2024-03-05 21:20:56 +01:00
b6ecb4eb53
Declutter custom Org agenda views
This is mostly to speed up agenda generation, in particular the main
agenda view.  It turns out that filtering out SCHEDULED items is
expensive, but in tags views there is no variable to exclude scheduled
items – as for todo and tags-todo views.  Thus, SCHEDULED items must be
removed with a corresponding search pattern, which is slow.
2024-03-05 17:38:16 +01:00
cd98c67e12
Add usual text surrounding backlink in TODO caputure template
I always add "Via " around the backlink, with some newlines.  Let's just
let Emacs do this for us :)
2024-02-18 10:37:06 +01:00
b75e70241b
Add Org capture template for generic Org item
This can be used when creating generic NOP headlines, among others.
2024-01-27 17:34:19 +01:00
1cc7abd4d7
Clarify that remaining time is computed over clocked time of subtree 2024-01-22 19:52:27 +01:00
8aa29be427
Use strict whitespace matching in isearch
This is less confusing for me :)
2024-01-19 17:12:48 +01:00
5214d7ceee
Disable global completion again
It's mostly annoying.
2024-01-17 17:48:07 +01:00
b954328b26
Simplify Org capture template for recording GOALs
I usually already have a first item for a GOAL recorded, so querying for
it via the capture template is unnecessary (and annoying).
2024-01-14 15:10:03 +01:00
af05bd2106
Collect custom Org key bindings in a custom hydra 2024-01-07 17:12:27 +01:00
cdb4721589
Allow access to Org link management via my usual Org keymap prefix
This is for consistency.
2024-01-06 12:19:18 +01:00
dc841d4790
Allow to reset current text scaling directly
This is easier then adjusting the text scale manually until it reaches
zero.

The additional indentation fixes are bonus ;)
2024-01-04 08:28:14 +01:00
1f0f00ad2c
Record more notes when changing TODO keywords of Org items
I find myself often adding these notes manually after state changes, so
let's make Org do this for us.
2024-01-04 08:26:12 +01:00
b7d190c513
Introduce separate hydra for Org jump commands
`hydra-org-clock` thus only hosts keybindings for clock-related
commands, while the new `hydra-org-jump` is for jumping to Org items in
various ways.  Feels cleaner to me this way.
2024-01-01 17:04:55 +01:00
3e09ee57dc
Use olivetti-mode to improve Org tree-slide presentations
This is motivated by a post by Daniel Liden (https://gitlab.com/dliden),
see https://www.danliden.com/posts/20231217-emacs-hooks.html (courtesy
of https://irreal.org/blog/?p=11849).
2023-12-31 12:54:55 +01:00
12 changed files with 146 additions and 710 deletions

View File

@ -1,167 +0,0 @@
#!/usr/bin/env perl
# by PerlStalker, http://perlstalker.vuser.org/blog/2014/06/04/importing-ical-into-org-mode/
# with minor modifications by exot
use warnings;
use strict;
use Data::ICal;
use Data::Dumper;
use DateTime::Format::ICal;
use Getopt::Long;
my $category = undef;
my $filetags = undef;
GetOptions(
'category|c=s' => \$category,
'filetags|f=s' => \$filetags
);
my $cal = Data::ICal->new(data => join '', <STDIN>);
#print Dumper $cal;
my %gprops = %{ $cal->properties };
print "#+TITLE: ical entries\n";
print "#+AUTHOR: ".$gprops{'x-wr-calname'}[0]->decoded_value."\n" if defined $gprops{'x-wr-calname'};
print "#+EMAIL: \n";
print "#+DESCRIPTION: Converted using ical2org.pl\n";
print "#+CATEGORY: $category\n" if defined($category);
print "#+FILETAGS: $filetags\n" if defined($filetags);
print "#+STARTUP: overview\n";
print "\n";
#print "* COMMENT original iCal properties\n";
#print Dumper \%gprops;
#print "Timezone: ", $gprops{'x-wr-timezone'}[0]->value, "\n";
#foreach my $prop (values %gprops) {
# foreach my $p (@{ $prop }) {
# print $p->key, ':', $p->value, "\n";
# }
#}
my $error_code = 0;
foreach my $entry (@{ $cal->entries }) {
next if not $entry->isa('Data::ICal::Entry::Event');
# print 'Entry: ', Dumper $entry;
eval { handle_entry($entry) };
if ($@) {
print STDERR $@;
$error_code = 1;
}
}
exit $error_code;
sub org_date_range {
my $start = shift;
my $end = shift;
my $str = sprintf('<%04d-%02d-%02d %s %02d:%02d>',
$start->year,
$start->month,
$start->day,
$start->day_abbr,
$start->hour,
$start->minute
);
$str .= '--';
$str .= sprintf('<%04d-%02d-%02d %s %02d:%02d>',
$end->year,
$end->month,
$end->day,
$end->day_abbr,
$end->hour,
$end->minute
);
return $str;
}
sub handle_entry {
my $entry = shift;
my %props = %{ $entry->properties };
# skip entries with no start
next if not $props{dtstart}[0];
my $dtstart = DateTime::Format::ICal->parse_datetime($props{dtstart}[0]->value);
my ($duration, $dtend);
if (not $props{dtend}[0]) {
$duration = DateTime::Format::ICal->parse_duration($props{duration}[0]->value);
$dtend = $dtstart->clone->add_duration($duration);
} else {
$dtend = DateTime::Format::ICal->parse_datetime($props{dtend}[0]->value);
$duration = $dtend->subtract_datetime($dtstart);
}
if (defined $props{rrule}) {
#print " REPEATABLE\n";
# Bad: There may be multiple rrules but I'm ignoring them
my $set = DateTime::Format::ICal->parse_recurrence(recurrence => $props{rrule}[0]->value,
dtstart => $dtstart,
dtend => DateTime->now->add(weeks => 1),
);
my $itr = $set->iterator;
while (my $dt = $itr->next) {
$dt->set_time_zone($props{dtstart}[0]->parameters->{'TZID'} || $gprops{'x-wr-timezone'}[0]->value);
print "* ".$props{summary}[0]->decoded_value."\n";
my $end = $dt->clone->add_duration($duration);
print ' ', org_date_range($dt, $end), "\n";
#print $dt, "\n";
print " :PROPERTIES:\n";
printf " :ID: %s\n", $props{uid}[0]->value;
if (defined $props{location}) {
printf " :LOCATION: %s\n", $props{location}[0]->value;
}
if (defined $props{status}) {
printf " :STATUS: %s\n", $props{status}[0]->value;
}
print " :END:\n";
if ($props{description}) {
print "\n", $props{description}[0]->decoded_value, "\n";
}
}
}
else {
print "* ".$props{summary}[0]->decoded_value."\n";
# my $tz = $gprops{'x-wr-timezone'}[0]->value;
# $dtstart->set_time_zone($props{dtstart}[0]->parameters->{'TZID'} || $tz);
# $dtend->set_time_zone($props{dtend}[0]->parameters->{'TZID'} || $tz);
print ' ', org_date_range($dtstart, $dtend), "\n";
print " :PROPERTIES:\n";
printf " :ID: %s\n", $props{uid}[0]->value;
if (defined $props{location}) {
printf " :LOCATION: %s\n", $props{location}[0]->value;
}
if (defined $props{status}) {
printf " :STATUS: %s\n", $props{status}[0]->value;
}
print " :END:\n";
if ($props{description}) {
print "\n", $props{description}[0]->decoded_value, "\n";
}
}
# print Dumper \%props;
}

View File

@ -1,426 +0,0 @@
# awk script for converting an iCal formatted file to a sequence of org-mode headings.
# this may not work in general but seems to work for day and timed events from Google's
# calendar, which is really all I need right now...
#
# usage:
# awk -f THISFILE < icalinputfile.ics > orgmodeentries.org --assign NAME=category
#
# where the category is used to define a CATEGORY for all entries in
# the file and also assign that label as a tag to each entry
#
# Note: change org meta information generated below for author and
# email entries!
#
# Known bugs:
# - not so much a bug as a possible assumption: date entries with no time
# specified are assumed to be independent of the time zone.
#
# Eric S Fraga
# 20100629 - initial version
# 20100708 - added end times to timed events
# - adjust times according to time zone information
# - fixed incorrect transfer for entries with ":" embedded within the text
# - added support for multi-line summary entries (which become headlines)
# 20100709 - incorporated time zone identification
# - fixed processing of continuation lines as Google seems to
# have changed, in the last day, the number of spaces at
# the start of the line for each continuation...
# - remove backslashes used to protect commas in iCal text entries
# no further revision log after this as the file was moved into a git
# repository...
#
# Last change: 2016.05.26 08:47:12
#----------------------------------------------------------------------------------
# a function to take the iCal formatted date+time, convert it into an
# internal form (seconds since time 0), and adjust according to the
# local time zone (specified by +-seconds calculated in the BEGIN
# section)
function datetimestamp(input)
{
# convert the iCal Date+Time entry to a format that mktime can understand
datespec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 \\4 \\5 \\6", "g", input);
# print "date spec : " datespec; convert this date+time into
# seconds from the beginning of time and include adjustment for
# time zone, as determined in the BEGIN section below. The
# adjustment is only included if the time stamp has a Z at the
# end. Of course, we should actually incorporate the time zone
# information in the time stamp line but ...
if (0 < index(input,"Z")) {
# For time
# zone adjustment, I have not tested edge effects, specifically
# what happens when UTC time is a different day to local time and
# especially when an event with a duration crosses midnight in UTC
# time. It should work but...
timestamp = mktime(datespec) + seconds;
}
else {
timestamp = mktime(datespec);
}
# print "date spec: " datespec;
#timestamp = mktime(datespec);
# print "adjusted : " timestamp
# print "Time stamp : " strftime("%Y-%m-%d %H:%M", timestamp);
return timestamp;
}
# version of above but for dates only
function datestamp(input)
{
# create a date using midnight as the time
datespec = gensub( "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 0 0 0", "g", input );
# convert to internal representation
timestamp = mktime(datespec);
# and finally convert to something org understands
datestring = strftime("%Y-%m-%d %a", timestamp);
#print "In datestamp: datespec=" datespec " timestamp=" timestamp " datestring=" datestring;
return datestring;
}
# start of the output file now
BEGIN {
# use a colon to separate the type of data line from the actual contents
FS = ":";
# determine the number of seconds to use for adjusting for time
# zone difference from UTC. This is used in the function
# datetimestamp above. The time zone information returned by
# strftime() is in hours * 100 so we multiply by 36 to get
# seconds. This does not work for time zones that are not an
# integral multiple of hours (e.g. Newfoundland)
seconds = gensub("([+-])0", "\\1", 1, strftime("%z")) * 36;
date1 = ""; # for start of an event
date2 = ""; # for end of an event, if specified
entry = ""
first = 1; # true until an event has been found
headline = ""
icalentry = "" # the full entry for inspection
id = ""
indescription = 0;
inevent = 0; # we have VEVENTS but also other items which we do not process
location = ""; # outlook entries, at least, often include a location
repeat = ""; # is item repeated? if so, how often
time1 = ""; # for start of an event, if specified
time2 = ""; # for end of an event, if specified
todotype = ""; # type of TODO
if (NAME == "")
NAME = "ical2org";
print "# -*- mode: auto-revert; mode: org; -*-" # suggested by Henrik Holmboe
print "#+TITLE: Main Google calendar entries"
print "#+AUTHOR: Eric S Fraga"
print "#+EMAIL: e.fraga@ucl.ac.uk"
print "#+DESCRIPTION: converted using the ical2org awk script"
print "#+CATEGORY: " NAME
print " "
}
# continuation lines (at least from Google) start with two spaces
# if the continuation is after a description or a summary, append the entry
# to the respective variable
/^[ ]+/ {
if (indescription) {
entry = entry gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0));
} else if (insummary) {
summary = summary gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0))
} else if (inuid) {
id = id gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0))
}
icalentry = icalentry "\n" $0
}
/^BEGIN:VEVENT/ {
# start of an event. if this is the first, output the preamble from the iCal file
if (first) {
print "* COMMENT original iCal preamble"
print gensub("\r", "", "g", icalentry)
icalentry = ""
}
havesummary = 0;
inevent = 1;
first = false;
repeat = "";
}
/^BEGIN:VTODO/ {
if (first){
print "* COMMENT original iCal preamble";
print gensub("\r", "", "g", icalentry);
icalentry = "";
first = false;
}
havesummary = 0;
intodo = 1;
repeat = "";
todotype = "";
}
# any line that starts at the left with a non-space character is a new data field
/^[A-Z]/ {
# we ignore DTSTAMP lines as they change every time you download
# the iCal format file which leads to a change in the converted
# org file as I output the original input. This change, which is
# really content free, makes a revision control system update the
# repository and confuses.
if (! index("DTSTAMP", $1)) icalentry = icalentry "\n" $0
# this line terminates the collection of description and summary entries
indescription = 0;
if (insummary) {
havesummary = 1;
}
insummary = 0;
}
# this type of entry represents a day entry, not timed, with date
# stamp YYYYMMDD. For a todo item, this indicates a scheduled item.
/^DTSTART;VALUE=DATE/ {
# print "DTSTART date only entry: " $0;
# date1 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", $2)
date1 = datestamp($2);
time1 = ""
}
# this represents a timed entry with date and time stamp
# YYYYMMDDTHHMMSS we ignore the seconds. This entry may have a time
# zone specification which is currently ignored although it should be
# possible, not easy, to incorporate. We assume that this information
# is only relevant for appointments and not TODO items. We expect
# TODO items to have only a date for the START field and that date
# will be the scheduled date. See above.
/^DTSTART(;TZID.*)?:/ {
if (inevent) {
# print "DTSTART line: " $0;
# print "checking start time: " $2;
date1 = strftime("%Y-%m-%d %a", datetimestamp($2));
time1 = strftime(" %H:%M", datetimestamp($2));
# print "====> time: " time1;
# print date;
}
}
# and the same for the end date; here we extract only the time and append this to the
# date+time found by the DTSTART entry. We assume that entry was there, of course.
# should probably add some error checking here! In time...
/^DTEND;VALUE=DATE/ {
if (inevent) {
# date2 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]", "\\1-\\2-\\3", "g", $2)
date2 = datestamp($2);
time2 = ""
}
}
/^DTEND(;TZID=[^:]*)?:/ {
if (inevent) {
# print $0
date2 = strftime("%Y-%m-%d %a", datetimestamp($2));
time2 = strftime("%H:%M", datetimestamp($2));
}
}
# TODO items may (should?) have a DUE date/time.
/^DUE(;TZID=[^:]*)?:/ {
if (intodo){
date2 = strftime("%Y-%m-%d %a", datetimestamp($2));
time2 = strftime("%H:%M", datetimestamp($2));
}
}
# deadline with only a date
/^DUE;VALUE=DATE/ {
# print "DUE;VALUE=DATE entry:" $0
# print "... date part is >" $2 "<"
# print "... date2 before " date2
if (intodo) {
#date2 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", $2)
date2 = datestamp($2);
time2 = ""
}
# print "... date2 after " date2
}
# The description will the contents of the entry in org-mode.
# this line may be continued.
/^DESCRIPTION/ {
$1 = "";
entry = entry "\n" gensub("\r", "", "g", $0);
indescription = 1;
}
/^LOCATION/ {
$1 = "";
location = gensub("\r", "", "g", $0);
}
# the status of a TODO item: we know about NEEDS-ACTION and
# COMPLETED. There may be others...
/^STATUS/ {
if ($2 == "NEEDS-ACTION")
todotype = "TODO";
else if ($2 == "COMPLETED")
todotype = "DONE";
else
todotype = "UNKNOWN";
}
# is there a repetition rule. I don't know how general this is but
# Microsoft's Outlook calendar uses this for repeats
/^RRULE/ {
# print ">>> Checking rule with string: " $2;
i = match($2,"FREQ=[A-Z]+;");
# printf(">>> Index=%d start=%d length=%d\n\n", i, RSTART, RLENGTH);
frequency = substr($2, RSTART+5, RLENGTH-6);
# print ">>> Frequency is " frequency "\n\n";
i = match($2,"INTERVAL=[0-9]+;");
interval = 1; # default interval if none is found
if (i>0) {
interval = substr($2, RSTART+9, RLENGTH-10);
}
period = "";
if (frequency == "DAILY") {
period = "d";
}
else if (frequency == "WEEKLY") {
period = "w";
}
else if(frequency == "MONTHLY") {
period = "m";
}
else if(frequency == "YEARLY") {
period = "y";
}
if (period != "") {
repeat = sprintf(" +%d%s", interval, period);
}
# print ">>> Repeat is " repeat;
}
# the summary will be the org heading
/^SUMMARY/ {
$1 = "";
if (!havesummary) {
summary = gensub("\r", "", "g", $0);
insummary = 1;
}
}
# the unique ID will be stored as a property of the entry
/^UID/ {
$1 = "";
id = gensub("\r", "", "g", $0);
inuid = 1;
}
# when we reach the end of the event line, we output everything we
# have collected so far, creating a top level org headline with the
# date/time stamp, unique ID property and the contents, if any
/^END:VEVENT/ {
# translate \n sequences to actual newlines and unprotect commas (,)
print "* " gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)) " :" NAME ":"
print ":PROPERTIES:"
print ":ID: " id
if (location != "") {
print ":LOCATION: " gensub("\\\\,", ",", "g", location);
}
print ":END:"
if (date1 == date2) {
if (time2 == "")
print " <" date1 time1 repeat ">"
else
print " <" date1 time1 "-" time2 repeat ">"
}
else {
if (time1 == "")
print "<" date1 ">--<" date2 ">"
else
print " <" date1 time1 ">--<" date2 " " time2 ">"
}
# for the entry, convert all embedded "\n" strings to actual newlines
print ""
# translate \n sequences to actual newlines and unprotect commas (,)
print gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry));
print "** COMMENT original iCal entry"
print gensub("\r", "", "g", icalentry)
summary = ""
date = ""
date1 = ""
date2 = ""
time1 = ""
time2 = ""
entry = ""
icalentry = ""
indescription = 0
inevent = 0
insummary = 0
period = "";
repeat = "";
}
# the end of a TODO item is similar to an event except that the dates
# are used for scheduling and deadline information
/^END:VTODO/ {
# translate \n sequences to actual newlines and unprotect commas (,)
print "* " todotype " " gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)) " :" NAME ":"
# scheduling and deadline information come immediately after the
# headline, before properties
if (date1 != "") {
if (date2 != "")
if (time2 != "")
print "SCHEDULED: <" date1 time1 "> DEADLINE: <" date2 " " time2 "> "
else
print "SCHEDULED: <" date1 time1 "> DEADLINE: <" date2 "> "
else
print "SCHEDULED: <" date1 time1 "> "
} else if (date2 != "") {
if (time2 != "")
print "DEADLINE: <" date2 " " time2 "> "
else
print "DEADLINE: <" date2 "> "
}
# now come the properties which include the ID always and possibly
# a location
print ":PROPERTIES:"
print ":ID: " id
if (location != "") {
print ":LOCATION: " gensub("\\\\,", ",", "g", location);
}
print ":END:"
# now the entry; we put in a blank line just because that's the
# way I like it, ah ha ah ha... ;-)
print ""
# translate \n sequences to actual newlines and unprotect commas (,)
print gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry));
print "** COMMENT original iCal entry"
print gensub("\r", "", "g", icalentry)
summary = "";
date = "";
date1 = "";
date2 = "";
time1 = "";
time2 = "";
entry = "";
icalentry = "";
indescription = 0;
inevent = 0;
insummary = 0;
intodo = 0;
period = "";
repeat = "";
}
# Local Variables:
# time-stamp-line-limit: 1000
# time-stamp-format: "%04y.%02m.%02d %02H:%02M:%02S"
# time-stamp-active: t
# time-stamp-start: "Last change:[ \t]+"
# time-stamp-end: "$"
# End:

View File

@ -1,6 +1,6 @@
(define-package "dash" "20230714.723" "A modern list library for Emacs"
(define-package "dash" "20240103.1301" "A modern list library for Emacs"
'((emacs "24"))
:commit "f46268c75cb7c18361d3cee942cd4dc14a03aef4" :authors
:commit "e32a70ca636bad42232b6c79f1491dc86802a721" :authors
'(("Magnar Sveen" . "magnars@gmail.com"))
:maintainers
'(("Magnar Sveen" . "magnars@gmail.com"))

View File

@ -1,6 +1,6 @@
;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2012-2023 Free Software Foundation, Inc.
;; Copyright (C) 2012-2024 Free Software Foundation, Inc.
;; Author: Magnar Sveen <magnars@gmail.com>
;; Version: 2.19.1

View File

@ -2,7 +2,7 @@ This is dash.info, produced by makeinfo version 6.7 from dash.texi.
This manual is for Dash version 2.19.1.
Copyright © 20122023 Free Software Foundation, Inc.
Copyright © 20122024 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
@ -24,7 +24,7 @@ Dash
This manual is for Dash version 2.19.1.
Copyright © 20122023 Free Software Foundation, Inc.
Copyright © 20122024 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,

171
init.el
View File

@ -472,6 +472,20 @@
mc/mark-previous-like-this
mc/mark-all-like-this))
(use-package olivetti
:ensure t
:commands (olivetti-mode)
:preface (progn
(defun turn-on-olivetti-mode ()
"Turn on `olivetti-mode'."
(interactive)
(olivetti-mode 1))
(defun turn-off-olivetti-mode ()
"Turn off `olivetti-mode'."
(interactive)
(olivetti-mode -1)))
:init (setq-default olivetti-body-width 0.618034))
(use-package undo-tree
:ensure t
:commands (global-undo-tree-mode
@ -524,6 +538,8 @@
db/org-timestamp-difference
db/org-capture-code-snippet
hydra-org-clock/body
hydra-org-jump/body
hydra-org-custom/body
db/make-org-capture-frame
db/org-onenote-open
db/org-outlook-open
@ -607,10 +623,10 @@
;; Keywords and Tags
(setq org-todo-keywords
'((sequence "TODO(t)" "CONT(n!)" "REFINE(f!)" "|" "DONE(d@/!)" "CANC(c@/!)" "MRGD(m@/!)")
(sequence "GOTO(g)" "ATTN(a!)" "|" "DONE(d@/!)")
(sequence "READ(r)" "CONT(n!)" "|" "DONE(d@/!)")
(sequence "DELG(e@/!)" "WAIT(w@/!)" "HOLD(h@/!)" "|" "CANC(c@/!)"))
'((sequence "TODO(t@)" "CONT(n!)" "REFINE(f!)" "|" "DONE(d@)" "CANC(c@)" "MRGD(m@)")
(sequence "GOTO(g@)" "ATTN(a!)" "|" "DONE(d@)")
(sequence "READ(r@)" "CONT(n!)" "|" "DONE(d@)")
(sequence "DELG(e@)" "WAIT(w@)" "HOLD(h@)" "|" "CANC(c@)"))
org-todo-state-tags-triggers
'(("WAIT" ("HOLD") ("WAIT" . t))
@ -973,10 +989,13 @@
((org-agenda-overriding-header "Deadlines")
(org-agenda-sorting-strategy '(deadline-up priority-down))
(org-deadline-warning-days 30)))
(tags-todo "TODO={CONT\\|ATTN}-HOLD-TIMESTAMP>=\"<today>\"-SCHEDULED<>\"\"-NOT_BEFORE>=\"<today>\""
((org-agenda-overriding-header "Things to do next (Task shortlist and WIP, TODO ∈ {CONT,ATTN}, not scheduled)")))
(tags-todo "TODO<>\"CONT\"-HOLD-SOMEWHEN-DATE-WAIT-TEMPLATE-SCHEDULED<>\"\"-NOT_BEFORE>=\"<today>\""
(tags-todo "TODO={CONT\\|ATTN}-HOLD"
((org-agenda-overriding-header "Things to do next (Task shortlist and WIP, TODO ∈ {CONT,ATTN}, not scheduled)")
(org-agenda-todo-ignore-scheduled 'all)
(org-agenda-todo-ignore-timestamp 0)))
(tags-todo "TODO<>\"CONT\"-HOLD-SOMEWHEN-DATE-WAIT-TEMPLATE"
((org-agenda-overriding-header "Task Backlog (not WIP, not scheduled)")
(org-agenda-todo-ignore-scheduled 'all)
(org-tags-match-list-sublevels t)))))
("B" "Backlog"
@ -995,44 +1014,20 @@
;; DEADLINE is not necessary, as items will appear on the
;; deadline view anyway.
;; Check whether any NOT_BEFORE entries are not actually timestaps
(org-ql-block '(and (property "NOT_BEFORE")
(not (string-match-p org-element--timestamp-regexp
(property "NOT_BEFORE"))))
((org-ql-block-header "Items whose NOT_BEFORE entry is not a timestamp")))
;; Check whether any NOT_BEFORE is behind a SCHEDULED
(org-ql-block '(and (property "NOT_BEFORE")
(scheduled)
(> (org-2ft (property "NOT_BEFORE"))
(org-2ft (property "SCHEDULED"))))
((org-ql-block-header "Items whose NOT_BEFORE value is after SCHEDULED")))
;; Check whether any NOT_BEFORE is beind their DEADLINE
(org-ql-block '(and (property "NOT_BEFORE")
(deadline)
(> (org-2ft (property "NOT_BEFORE"))
(org-2ft (property "DEADLINE"))))
((org-ql-block-header "Items whose NOT_BEFORE value is after their DEADLINE")))
))
("U" "Unsupervised (Waiting, Missed Appointments, Hold)"
((tags "WAIT-TODO={DONE\\|CANC\\|MRGD}-HOLD-SOMEWHEN-SCHEDULED>=\"<today>\"-NOT_BEFORE>=\"<today>\""
((tags "WAIT-TODO={DONE\\|CANC\\|MRGD}-HOLD-SOMEWHEN-SCHEDULED>=\"<today>\""
((org-agenda-overriding-header "Waiting For List")))
(tags-todo "DATE-TIMESTAMP>=\"<today>\""
((org-agenda-overriding-header "Missed appointments (DATEs with timestamp in the past)")))
(tags "REFILE"
((org-agenda-files (list db/org-default-refile-file))
(org-agenda-overriding-header "Things to refile (make it empty!)")))
(tags "HOLD-TODO={DONE\\|CANC\\|MRGD}-SOMEWHEN-SCHEDULED>=\"<today>\"-NOT_BEFORE>=\"<today>\""
(tags "HOLD-TODO={DONE\\|CANC\\|MRGD}-SOMEWHEN-SCHEDULED>=\"<today>\""
((org-agenda-overriding-header "Tasks on Hold")))))
("S" "Somewhen (Do if nothing else to do, i.e., personal backlog)"
((tags "TAGS={SOMEWHEN}+TODO=\"\"-TAGS={NOP\\|TOPIC}-PERIODIC-DATE-SCHEDULED>=\"<today>\"-NOT_BEFORE>=\"<today>\""
((tags "TAGS={SOMEWHEN}+TODO=\"\"-NOP-TOPIC-PERIODIC-DATE-SCHEDULED>=\"<today>\""
((org-agenda-overriding-header "Open Tasks to do SOMEWHEN (no TODO keyword, no PERIODIC, no DATE, no now or future SCHEDULED)")))
(tags-todo "SOMEWHEN-NOT_BEFORE>=\"<today>\"-ALLTAGS={HOLD}"
(tags-todo "SOMEWHEN-HOLD"
((org-agenda-overriding-header "Things To Do SOMEWHEN")
(org-agenda-todo-ignore-with-date t)
(org-tags-match-list-sublevels nil)))))
@ -1040,11 +1035,11 @@
("P" "Current Projects and Topics"
((stuck ""
((org-agenda-overriding-header "Stuck Complex Tasks")))
(tags "TAGS={NOTE}-TODO={CANC\\|DONE\\|MRGD}-HOLD-NOP-SOMEWHEN-SCHEDULED>=\"<today>\"-NOT_BEFORE>=\"<today>\""
(tags "TAGS={NOTE}-TODO={CANC\\|DONE\\|MRGD}-HOLD-NOP-SOMEWHEN-SCHEDULED>=\"<today>\""
((org-agenda-overriding-header "Project Notes (items explicitly tagged with NOTE but not NOP)")))
(tags "TAGS={TOPIC}-TODO={DONE\\|CANC\\|MRGD}-SOMEWHEN-SCHEDULED>=\"<today>\"-HOLD-WAIT-NOT_BEFORE>=\"<today>\""
(tags "TAGS={TOPIC}-TODO={DONE\\|CANC\\|MRGD}-SOMEWHEN-SCHEDULED>=\"<today>\"-HOLD-WAIT"
((org-agenda-overriding-header "Topics (items directly tagged with TOPIC)")))
(tags "TAGS={PERIODIC}-TODO={DONE\\|CANC\\|MRGD}-HOLD-SCHEDULED>=\"<today>\"-HOLD-WAIT-NOT_BEFORE>=\"<today>\""
(tags "TAGS={PERIODIC}-TODO={DONE\\|CANC\\|MRGD}-HOLD-SCHEDULED>=\"<today>\"-HOLD-WAIT"
((org-agenda-overriding-header "Periodic Projects (PERIODIC, not scheduled in the future, not done, not on hold)")))))
("W" "Weekly Review"
@ -1095,17 +1090,22 @@
(file db/org-default-refile-file)
,(concat "* TODO [#B] %^{What}\n"
":PROPERTIES:\n:CREATED: %U\n:END:\n"
"%a\n"
"\nVia %a.\n\n"
"%?")
:empty-lines 1)
("g" "Record new goal with first item"
("g" "Record new goal"
entry
(file db/org-default-refile-file)
,(concat "* %^{Ticket Description} (%^{Ticket Number}) :GOAL:\n"
":PROPERTIES:\n:CREATED: %U\n:END:\n"
"\n** TODO [#B] %^{First Task}\n"
,(concat "* %^{Description} (%^{Ticket Number}) :GOAL:\n"
":PROPERTIES:\n:CREATED: %U\n:END:\n"
"\n%?"))
("h" "Headline (generic Org item)"
entry
(file db/org-default-refile-file)
,(concat "* [#B] %^{What}\n"
":PROPERTIES:\n:CREATED: %U\n:END:\n"
"%a\n"
"%?"))
("n" "Note"
entry
(file db/org-default-refile-file)
@ -1243,7 +1243,9 @@
:bind (:map org-tree-slide-mode-map
("<C-down>" . org-tree-slide-display-header-toggle)
("<C-right>" . org-tree-slide-move-next-tree)
("<C-left>" . org-tree-slide-move-previous-tree)))
("<C-left>" . org-tree-slide-move-previous-tree))
:hook ((org-tree-slide-play . turn-on-olivetti-mode)
(org-tree-slide-stop . turn-off-olivetti-mode)))
(use-package org-roam
:init (progn
@ -2088,7 +2090,14 @@ Note that this workaround is incomplete, as explained in this comment."
(setq suggest-key-bindings t
extended-command-suggest-shorter t
completions-detailed t
completion-cycle-threshold 10)
completion-cycle-threshold 10
completion-styles '(orderless basic)
completion-category-defaults nil
;; Via https://protesilaos.com/emacs/dotemacs, with additional changes
completion-category-overrides '((file (styles . (basic partial-completion orderless)))
(bookmark (styles . (basic substring orderless)))
(imenu (styles . (basic substring orderless)))
(kill-ring (styles . (emacs22 orderless)))))
(use-package helm
:ensure t
@ -2096,7 +2105,8 @@ Note that this workaround is incomplete, as explained in this comment."
:autoload (helm-execute-persistent-action
helm-select-action
helm-make-source)
:defines (helm-source-bookmarks) ; via helm-bookmarks.el
:commands (helm-show-kill-ring)
:defines (helm-source-bookmarks) ; via helm-bookmarks.el
:init (setq helm-command-prefix-key "C-c h" ; see `db/run-init' for explicit binding
helm-input-idle-delay 0.0
helm-buffers-fuzzy-matching t
@ -2136,13 +2146,8 @@ Note that this workaround is incomplete, as explained in this comment."
(bind-key "C-i" #'helm-execute-persistent-action helm-map)
(bind-key "C-z" #'helm-select-action helm-map)))
(use-package helm-ring
:commands (helm-show-kill-ring))
(use-package ivy
:ensure t
:commands (ivy-mode
ivy-resume)
:commands (ivy-mode)
:diminish ivy-mode
:init (setq ivy-use-virtual-buffers t
ivy-magic-tilde nil
@ -2163,22 +2168,6 @@ Note that this workaround is incomplete, as explained in this comment."
;; functionality.
(define-key ivy-minibuffer-map (kbd "S-SPC") nil)))
(use-package counsel
:ensure t
:commands (counsel-org-goto-all
counsel-M-x
counsel-find-file
counsel-info-lookup-symbol
counsel-unicode-char
counsel-descbinds
counsel-describe-variable
counsel-describe-function
counsel-recentf
counsel-shell-history))
(use-package smex
:init (setq smex-save-file (expand-file-name "smex-items" emacs-d-userdata)))
(use-package swiper
:ensure t
:commands (swiper
@ -2194,6 +2183,22 @@ Note that this workaround is incomplete, as explained in this comment."
:commands (company-mode global-company-mode)
:init (setq company-show-quick-access t))
(use-package marginalia
:ensure t
:commands (marginalia-mode)
:init (setq marginalia-max-relative-age 0))
(use-package vertico
:ensure t
:commands (vertico-mode))
(use-package orderless
:ensure t
:init (setq orderless-match-faces ; Some of the default faces are hard to
; read with when solarized is enabled;
; only keep those that are readable
[orderless-match-face-1 orderless-match-face-2]))
;; * Navigation
@ -2292,7 +2297,8 @@ eventuelly be set to nil, however)."
(use-package isearch
:init (setq isearch-allow-scroll t
isearch-lazy-count t
search-whitespace-regexp "[ \t\r\n]+"))
isearch-lax-whitespace nil
isearch-regexp-lax-whitespace nil))
(use-package goto-last-change
:commands goto-last-change)
@ -2488,8 +2494,6 @@ eventuelly be set to nil, however)."
(use-package shell
:commands (shell)
:bind (:map shell-mode-map
("C-r" . counsel-shell-history))
:config (progn
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
(add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m)
@ -2937,13 +2941,16 @@ eventuelly be set to nil, however)."
minibuffer-depth-indicate-mode
ace-window-display-mode
key-chord-mode
ivy-mode
;; ivy-mode
minions-mode
which-key-mode
projectile-mode
yas-global-mode
global-git-commit-mode
global-company-mode))
;; global-company-mode
marginalia-mode
vertico-mode
))
(with-demoted-errors "Cannot activate mode: %s"
(funcall mode +1)))
@ -2957,10 +2964,6 @@ eventuelly be set to nil, however)."
(with-demoted-errors "Cannot activate `vlf': %s"
(require 'vlf-setup))
;; Explicitly require helm, because autoloading is difficult with helm's
;; separate `helm-command-prefix-key' mechanism.
(require 'helm)
;; Global Hooks
(add-hook 'minibuffer-setup-hook 'cursor-intangible-mode)
@ -3001,7 +3004,6 @@ eventuelly be set to nil, however)."
(bind-key "C-S-c C-S-c" #'mc/edit-lines)
(bind-key "C-Z" #'undo-tree-redo)
(bind-key "C-c C-<" #'mc/mark-all-like-this)
(bind-key "C-c C-r" #'ivy-resume)
(bind-key "C-c D" #'define-word)
(bind-key "C-c J" #'avy-goto-word-or-subword-1)
(bind-key "C-c a" #'org-agenda)
@ -3015,7 +3017,7 @@ eventuelly be set to nil, however)."
(bind-key "C-c n f" #'org-roam-node-find)
(bind-key "C-c n i" #'org-roam-node-insert)
(bind-key "C-c n c" #'org-roam-capture)
(bind-key "C-c o" #'hydra-org-clock/body)
(bind-key "C-c o" #'hydra-org-custom/body)
(bind-key "C-c t" #'hydra-toggle/body)
(bind-key "C-h C-f" #'find-function)
(bind-key "C-h C-k" #'find-function-on-key)
@ -3048,15 +3050,10 @@ eventuelly be set to nil, however)."
;; Overwrite certain keybindings only if packages are avilable
(when (package-installed-p 'counsel)
(bind-key "M-x" #'counsel-M-x) ; gets nicer sorting with smex installed
(bind-key "C-x C-f" #'counsel-find-file)
(bind-key "C-h f" #'counsel-describe-function)
(bind-key "C-h v" #'counsel-describe-variable)
(bind-key "C-h b" #'counsel-descbinds)
(bind-key "C-S-s" #'counsel-grep-or-swiper))
(when (package-installed-p 'helm)
;; Explicitly require helm, because autoloading is difficult with helm's
;; separate `helm-command-prefix-key' mechanism.
(require 'helm)
(bind-key "M-y" #'helm-show-kill-ring)
(bind-key helm-command-prefix-key #'helm-command-prefix))

View File

@ -146,8 +146,8 @@ in the main agenda view."
("EShell" ?e db/run-or-hide-eshell)
("Refile File" ?r #'(lambda () (interactive) (find-file db/org-default-refile-file)))
("Goto Currnet Clock" ?c db/org-clock-goto-first-open-checkbox)
("Info Lookup" ?I counsel-info-lookup-symbol)
("Unicode Lookup" ?U counsel-unicode-char)
("Info Lookup" ?I info-lookup-symbol)
("Unicode Lookup" ?U insert-char)
("Timeline of Day" ?T timeline-tools-format-timeline-of-day)
("Copy template to point" ?C db/org-insert-checklist))
"Mapping of frequently used features to functions implementing

View File

@ -21,17 +21,18 @@
;; zooming with single keystrokes (from oremacs)
(defhydra hydra-zoom (:color red
:body-pre (require 'face-remap))
:body-pre (require 'face-remap))
;; the following newline is important, as otherwise the format string is not
;; interpreted correctly; cf. https://oremacs.com/2015/02/23/hydra-0.11.0/
"
Zoom (%`text-scale-mode-amount): "
("g" text-scale-increase "increase")
("l" text-scale-decrease "decrease"))
("l" text-scale-decrease "decrease")
("0" (text-scale-adjust 0) "reset"))
(defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1)
:color pink
:post (deactivate-mark))
:color pink
:post (deactivate-mark))
"
^_k_^ _d_elete _s_tring
_h_ _l_ _o_k _y_ank
@ -48,7 +49,7 @@ _h_ _l_ _o_k _y_ank
("r" (if (region-active-p)
(deactivate-mark)
(rectangle-mark-mode 1))
nil)
nil)
("y" yank-rectangle nil)
("u" undo nil)
("s" string-rectangle nil)

View File

@ -19,7 +19,6 @@
(require 'ox-icalendar)
(require 'org-ql)
(autoload 'counsel-org-goto-all "counsel")
(autoload 'which-function "which-func")
(autoload 'org-element-property "org-element")
@ -210,6 +209,8 @@ _y_: ?y? year _q_: quit _L__l__c_: ?l?
The remaining effort is computed as the planned effort minus the
already clocked time. If this result is negative, return zero.
The clocked time is computed over the complete subtree of the Org
item at point, and not only from the item itself.
Return the remaining effort as duration string by default. When
optional AS-NUMBER is non-nil, return the effort as number.
@ -478,10 +479,11 @@ user for the next task to clock into."
(message org-clock-current-task))
(defun db/org-clocked-time-for-current-item ()
"Return all clocked time for Org item at point.
"Return overall clocked time for the subtree of the Org item at point.
Also includes the currently running clock when the current item
is clocked in."
The clocked time of the item itself is also included, as is the
time of the currently running clock, in case item at point is
clocked in."
(unless (derived-mode-p 'org-mode)
(user-error "Not in Org mode buffer, aborting"))
@ -851,19 +853,14 @@ default task, though."
Current Task: %s(replace-regexp-in-string \"%\" \"%%\" (or org-clock-current-task \"\"));
- Clock in to [_w_]ork, [_h_]ome, [_b_]reak default task
- Clock in to [_l_]ast, or [_s_]elect task to clock in to
- [_j_]ump to current clock or to [_a_]ny item
- [_j_]ump to current clock
- Clock [_o_]ut
"
("w" (db/org-clock-in-work-task) nil)
("h" (db/org-clock-in-home-task) nil)
("b" (db/org-clock-in-break-task) nil)
("s" (lambda ()
(interactive)
(org-clock-in '(4)))
nil)
("j" (db/org-clock-goto-first-open-checkbox)
nil)
("a" counsel-org-goto-all nil)
("s" (org-clock-in '(4)) nil)
("j" (db/org-clock-goto-first-open-checkbox) nil)
("o" org-clock-out nil)
("l" db/org-clock-in-last-task nil))
@ -1037,6 +1034,36 @@ The password is assumed to be stored at the PASSWORD property."
heading
org-password-manager-default-password-wait-time))))
(defhydra hydra-org-jump (:color blue)
;; Quote %, as otherwise they would be misinterpreted as format characters
"
Current Task: %s(replace-regexp-in-string \"%\" \"%%\" (or org-clock-current-task \"\"));
- Jump to [_c_]urrent clock
- Jump to [_a_]ny item
- Jump to item [_s_]elected from clock history
"
("c" (db/org-clock-goto-first-open-checkbox nil)
nil)
("a" (org-refile '(4)) nil)
("s" (db/org-clock-goto-first-open-checkbox t)
nil))
(defhydra hydra-org-custom (:foreign-keys warn
:exit t)
"
Custom Org commands:
_c_ Clocking commands
_j_ Jumping commands
_l_ Linking commands
_a_ Open agenda
_q_ Quit this hydra"
("c" hydra-org-clock/body nil)
("j" hydra-org-jump/body nil)
("l" hydra-org-linking/body nil)
("a" db/org-agenda nil)
("q" (message "Abort") nil)
("C-g" (message "Abort") nil))
;;; Checklist Handling

View File

@ -36,8 +36,9 @@
;;; Application Shortcuts
(defun db/run-or-hide-ansi-term ()
"Find `*ansi-term*' or run `ansi-term' with `explicit-shell-file-name'.
If already in `*ansi-term*' buffer, bury it."
"Find *ansi-term* buffer or run `ansi-term' with `explicit-shell-file-name'.
If already in *ansi-term* buffer, bury it."
(interactive)
(if (string= "term-mode" major-mode)
(bury-buffer)
@ -536,14 +537,17 @@ entries, even if I want to use the input directly."
(car grep-files-history)
(car (car grep-files-aliases))))
(files (completing-read
(format "Search for \"%s\" in files matching wildcard: "
regexp)
nil nil nil
(format "Search for \"%s\" in files matching wildcard (default: %s): "
regexp
default)
(delete-dups
(delq nil
(append (list default default-alias default-extension)
grep-files-history
(mapcar #'car grep-files-aliases))))
'grep-files-history)))
nil nil nil
'grep-files-history
default)))
(and files
(or (cdr (assoc files grep-files-aliases))
files))))