How to highlight weekend days in Emacs calendar? - emacs

I am using Emacs and open calendar, now i would like to highlight weekend days with a light background color, i tried to google but have no solid solutions. anyone can help on this? thanks a lot!
Sorry I can't post pictures yet, hope i have put the question clearly.

Here you have some code that does that. You would need to change font-lock-doc-string-face to the face you want to use (or make a new one and configure it) if you don't like the one I used.
(defadvice calendar-generate-month
(after highlight-weekend-days (month year indent) activate)
"Highlight weekend days"
(dotimes (i 31)
(let ((date (list month (1+ i) year)))
(if (or (= (calendar-day-of-week date) 0)
(= (calendar-day-of-week date) 6))
(calendar-mark-visible-date date 'font-lock-doc-string-face)))))

Related

How can I mark Org habits as done in the past

I regularly mark habits as DONE the day after the activity was done. The habits module automatically updates a bunch of dates in the metadata when I do this, but the date is always today. So then, I have to manually edit the SCHEDULED, LOGBOOK, and LAST_REPEAT states.
Is there a way to mark a habit as DONE for a day in the past? So instead of doing C-c C-t d (I have "d" set up as "DONE") I could get a prompt which asked me for a date.
I've wanted to do this for some time, too, and your question inspired me to finally figure it out.
There is a function called "org-todo-yesterday." By default, it's not mapped to any keys, but you could always call it with M-x org-todo-yesterday (or map it if you're using it a lot). For me, it breaks because it calls "third" which isn't a defined function in my install.
For a more generic function that prompts us for the date and marks things as done at that time, we can add this function (inspired by org-todo-yesterday) to our emacs init file. It will act as if you finished things at 23:59 on the target date, which is hopefully good enough.
(defun dk/org-todo-custom-date (&optional arg)
"Like org-todo-yesterday, but prompt the user for a date. The time
of change will be 23:59 on that day"
(interactive "P")
(let* ((hour (nth 2 (decode-time
(org-current-time))))
(daysback (- (date-to-day (current-time-string)) (org-time-string-to-absolute (org-read-date))))
(org-extend-today-until (+ 1 (* 24 (- daysback 1)) hour))
(org-use-effective-time t)) ; use the adjusted timestamp for logging
(if (eq major-mode 'org-agenda-mode)
(org-agenda-todo arg)
(org-todo arg))))
Will this work? This simply completes the habit and reschedule it for today
(defun org-todo-yesterday2 (&optional arg)
(interactive "P")
(org-todo-yesterday arg)
(org-schedule arg (format-time-string "%Y-%m-%d")
)
)

Custom diary-sunrise function not working. `autoload-diary`? (Emacs.)

Intro:
Based on the existing code for Emacs' diary-sunrise-sunset, I attempted to create two new functions diary-sunrise and diary-sunset.
My reasons for this are included below under the heading "XY-description".
I have code below which seems to work, except when I restart with a new Emacs. I can fix this by momentarily using the original built-in diary-sunrise-sunset. From then on, my functions perform beautifully.
In other words, I have to use the built-in %%(diary-sunrise-sunset) just a one time before my %%(diary-sunrise) and %%(diary-sunset) will work.
Question:
Can you help me fix my use of these functions so that I do not have to take the awkward step of first getting the built-in function called?
The lines of code that seem suspicious to me are the ones that go
;;;###diary-autoload
While I have some idea of the necessity of loading programs, I am not sure what's going on here, or if this is where the issue lies. (I've never seen that particular syntax.)
I have tried M-: (require 'solar) and M-: (require 'diary), but neither have worked (and just now calendar). I have tried putting my code both in my .emacs and in the built-in .../lisp/calendar/solar.el (and byte-recompiling), but neither have worked.
My functions:
(They are each slight modifications of solar-sunrise-sunset-string and diary-sunrise-sunset, which are both defined in .../lisp/calendar/solar.el).
Sunrise:
(defun solar-sunrise-string (date &optional nolocation)
"String of *local* time of sunrise and daylight on Gregorian DATE."
(let ((l (solar-sunrise-sunset date)))
(format
"%s (%s hours daylight)"
(if (car l)
(concat "Sunset " (apply 'solar-time-string (car l)))
"no sunset")
(nth 2 l)
)))
;; To be called from diary-list-sexp-entries, where DATE is bound.
;;;###diary-autoload
(defun diary-sunrise ()
"Local time of sunrise as a diary entry.
Accurate to a few seconds."
(or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup))
(solar-sunrise-string date))
Sunset:
(defun solar-sunset-string (date &optional nolocation)
"String of *local* time of sunset and daylight on Gregorian DATE."
(let ((l (solar-sunrise-sunset date)))
(format
"%s (%s hours daylight)"
(if (cadr l)
(concat "Sunset " (apply 'solar-time-string (cadr l)))
"no sunset")
(nth 2 l)
)))
;; To be called from diary-list-sexp-entries, where DATE is bound.
;;;###diary-autoload
(defun diary-sunset ()
"Local time of sunset as a diary entry.
Accurate to a few seconds."
(or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup))
(solar-sunset-string date))
XY description:
I am using Emacs' Org-mode, and just starting to use agenda views. I like the builtin diary-sunrise-sunset function, but wanted to make some minor tweaks to make it more to my liking.
Basically, Org-mode's agenda view will extract the first time it sees from the diary sexp %%(diary-sunrise-sunset), for instance
Sat, Apr 5, 2014
Sunrise 6:43am (PDT), sunset 7:42pm (PDT) at Springfield, OH (12:59 hours daylight)
and thus make an entry of
6:43am........ Sunrise (PDT), sunset 7:42pm (PDT) at Springfield, OH (12:59 hours daylight)
in the agenda view.
What I would like it to do is something more like,
6:43am........ Sunrise (PDT) (12:59 hours daylight)
8:00am........ ----------------
10:00am........ ----------------
12:00pm........ ----------------
2:00pm........ ----------------
4:00pm........ ----------------
5:51pm........ now - - - - - - - - - - - - - - - - - - - - - - - - -
6:00pm........ ----------------
7:42pm........ Sunset (PDT) (12:59 hours daylight)
Where the data is split into the two times, rather than all written only at the sunrise time.
Bonus:
a snippet so that C-c a d will give you a nice day agenda view:
(setq org-agenda-custom-commands
'(("d" "day's agenda"
agenda ""
(
(org-agenda-files '("/e/org/agendatest.org"))
(org-agenda-prefix-format "%t %s")
(org-agenda-span 'day)
(org-agenda-timegrid-use-ampm t)
)
)
))
In the last paragraph of my question (eighth paragraph?), I lied, (require 'solar) was the answer... I did not try it hard enough as it didn't respond to auto-completion.
The scenic route to the answer took me to these distractions:
Maintaining Emacs autoload files for user-installed elisp?
elisp - Where should I add autoload cookies in my Emacs Lisp package? Is there a definitive guide?
C-h i g (elisp) Autoload
a search through the lisp directory for any update-file-autoloads
I did some Edebugging wondering if anything I was using had an autoload cookie (not completely understanding it yet), but then noticed there was a (provide 'solar) at the end of solar.el, so then I figured (require 'solar) had to work. It did and that was that.
From the code in my question, I remove the autoload cookies (not sure if that's necessary), and add (require 'solar), and it works! Enjoy!

How to distinguish between different overlays at point

ORIGINAL QUESTION:  I'm looking for some assistance, please, to distinguish between overlays that may exist at point. If the overlays-at point is made with the lawlist-red-face then do X. If the overlays-at point is made with calendar-holiday-marker, then do Y. The overlays are made with these two functions.
(calendar-mark-visible-date (car holiday) lawlist-red-face)
(calendar-mark-visible-date (car holiday) calendar-holiday-marker)
EDIT (January 1, 2014):  #Drew wrote a nice test for this in calendar+.el ( http://www.emacswiki.org/emacs/calendar%2B.el ):
(when
(memq lawlist-red-face
(mapcar (function (lambda (ovr)
(overlay-get ovr 'face))) (overlays-at (point))))
... )
EDIT (February 13, 2014):  The above-listed snippet can also be used in conjunction with something like (while (re-search-backward "[0-9]" nil t) to create a combined list of dates with overlays -- month, day and year are extracted with calendar-extract-day, calendar-extract-month and calendar-extract-year -- the date is obtained with (calendar-cursor-to-nearest-date):
;; modified with the help of #phils based on comments down below.
(setq lawlist-mouse-marked
(append lawlist-mouse-marked
`((holiday-sexp '(list ,month ,day ,year) ""))))
That list can then be used with something like calendar-holiday-list (or the modified code below) to remark dates on a new calendar layout after it has been generated. This is useful if the user has manually marked dates (e.g., with the mouse) and wants those dates to reappear after scrolling the calendar forwards / backwards. The library holidays.el contains the function holiday-sexp which uses a filtering function holiday-filter-visible-calendar to edit the list of dates so that only those that are visible on the new calendar get marked:
(dolist (holiday
(let (res h err)
(sort
(dolist (p lawlist-mouse-marked res)
(if (setq h (eval p))
(setq res (append h res))))
'calendar-date-compare)))
(calendar-mark-visible-date (car holiday) lawlist-mouse-calendar-face))
Ok, let's try to figure this out (without really knowing anything about the calendar).
(overlays-at) returns a list of overlays. I will keep this simple and only handle the first, if you want to examine all of them, simply loop over them until you find one that is suitable.
Also, the face property can be more complex than simply the name of the face, if that is the case you would need to handle that as well.
But anyway, here is a simple piece of code that (hopefully) does what you want:
(let ((overlays (overlays-at (point))))
(if overlays
(let ((face (overlay-get (car overlays) 'face)))
(cond ((eq face 'lawlist-red-face)
;; Do something
)
((eq face 'holiday)
;; Do another thing
)
(t
;; Do something else)))))

Color code agenda view per file

I have several .org files, e.g. personal.org and work.org.
When viewing the agenda, I'd like to have events from each file differently colored.
For example,
Wednesday 12 June 2013
personal: 11:00am........ Personal Meeting
work: 2:00pm- 3:00pm Work Meeting
There are already some colors in the agenda, but those two lines are both white. How can I set the line coming from personal to one color, and the line coming from work to another? I figure at least there has to be a way to define a color scheme based on the personal: and work: text if there's no easy way to have org do it by file.
Thanks!
The only thing I found as solution for what you ask, you have to use a hook function, changing faces after the agenda view is ready. The following code is untested, but should get you going:
(add-hook 'org-finalize-agenda-hook
(lambda ()
(save-excursion
(goto-char (point-min))
(while (re-search-forward "personal:" nil t)
(add-text-properties (match-beginning 0) (point-at-eol)
'(face secondary-selection)))
(goto-char (point-min))
(while (re-search-forward "work:" nil t)
(add-text-properties (match-beginning 0) (point-at-eol)
'(face bold))))))
John Wiegley sent once a patch he wrote so that, with an :OVERLAY: property, all Work items have the same background color. And with another value for Personal, those items have a different color.
See http://comments.gmane.org/gmane.emacs.orgmode/54342

Insert whole month of dates in Emacs Lisp

I'm doing a bit of programming here and there in Emacs Lisp, but I'm not entirely sure how to go about certain things.
I'm trying to insert a whole month of dates, each on a new line like the list below:
January
01/01/09 Mon:
02/01/09 Tue:
03/01/09 Wed:
etc
How would I go about doing that? I've found how to format dates, but I can't find how to loop over a certain range of dates (in this instance to loop round a whole month and print a date for each day in the month).
Has anyone got some pointers they could give me on how to get started?
The functions you want are 'encode-time, 'format-time-string, and 'decode-time.
For the proper documentation, either C-h f function-name or will give you the documentation for the function, or the general elisp info pages can be found here: C-h i m elisp RET m time conversion RET
Here's that snippet:
(defun my-insert-dates ()
"insert a bunch of dates"
(interactive)
(let* ((month 3)
(day 1)
(time (encode-time 1 1 0 day month 2009)))
(while (= (nth 4 (decode-time time)) month)
(insert (format-time-string "%D %a:\n" time))
(setq day (1+ day))
(setq time (encode-time 1 1 0 day month 2009)))))
I couldn't find how to determine the number of days in a given month (sure, you could hard-code it, but then you've got to deal with leap years). Luckily, 'encode-time does all the addition for you, so if you pass it the equivalent of "February 31", it'll return "March 3" (assuming 28 days).
I would have done something like this, if you don't mind using the calendar feature...
(require 'calendar)
(defun display-a-month (day month year)
(insert (format "%s\n" (calendar-date-string (list month day year))))
(if (< day 30)
(display-a-month (+ day 1) month year)))
You can find help using describe-function (M-x describe-function or C-h f as said before); M-x apropos will give you a list of functions related to something and even better people on irc.freenode.org / #emacs will answer all you questions.
btw, the question was "insert a whole month" not "insert first day of each month" :) depends if you read dd/mm/yyyy of mm/dd/yyyy
Slight variation on Trey's answer using dotimes:
(defun my-insert-dates ()
"insert the first day of each month"
(interactive)
(dotimes (mo 12)
(insert (format-time-string "%D %a:\n" (encode-time 1 1 0 1 (1+ mo) 2009)))))