Compare commits
31 Commits
d7ce497278
...
ee6a9b405e
| Author | SHA1 | Date | |
|---|---|---|---|
| ee6a9b405e | |||
| ea0e94c312 | |||
| 6b8b97fe8d | |||
| 42074f7d6a | |||
| dbd19d0da8 | |||
| 4124bc28d5 | |||
| 7d398a66c8 | |||
| aadca01244 | |||
| 118b50c8da | |||
| 7a2410642f | |||
| 8150725233 | |||
| 3d0afd3f07 | |||
| f6c40ad619 | |||
| a4325f30bf | |||
| 2bd2b5734a | |||
| bcccc55ad3 | |||
| a233d092de | |||
| 0e9ae4aa4d | |||
| b6ecb4eb53 | |||
| cd98c67e12 | |||
| b75e70241b | |||
| 1cc7abd4d7 | |||
| 8aa29be427 | |||
| 5214d7ceee | |||
| b954328b26 | |||
| af05bd2106 | |||
| cdb4721589 | |||
| dc841d4790 | |||
| 1f0f00ad2c | |||
| b7d190c513 | |||
| 3e09ee57dc |
167
bin/ical2org
167
bin/ical2org
@ -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;
|
||||
}
|
||||
426
bin/ical2org.awk
426
bin/ical2org.awk
@ -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:
|
||||
@ -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"))
|
||||
@ -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
|
||||
@ -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 © 2012–2023 Free Software Foundation, Inc.
|
||||
Copyright © 2012–2024 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 © 2012–2023 Free Software Foundation, Inc.
|
||||
Copyright © 2012–2024 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
171
init.el
@ -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))
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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))))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user