emacs-config/my-redefs.org
2019-07-20 21:04:20 -05:00

35 KiB

Filter by top heading, but only top todo heading

  (defun my/org-find-parent (pos)
    (save-excursion
      (with-current-buffer (if (markerp pos) (marker-buffer pos) (current-buffer))
        (when pos (goto-char pos))
        ;; Skip up to the topmost parent.
        (while (save-excursion
                 (org-up-heading-safe)
                 (org-get-todo-state))
          (org-up-heading-safe))
        (ignore-errors (nth 4 (org-heading-components))))))

  (defun org-agenda-filter-by-top-headline (strip)
    "Keep only those lines that are descendants from the same top headline.
  The top headline is that of the current line."
    (interactive "P")
    (if org-agenda-filtered-by-top-headline
        (progn
          (setq org-agenda-filtered-by-top-headline nil
                org-agenda-top-headline-filter nil)
          (org-agenda-filter-show-all-top-filter))
      (let ((toph (my/org-find-parent (org-get-at-bol 'org-hd-marker))))
        (if toph (org-agenda-filter-top-headline-apply toph strip)
          (error "No top-level headline at point")))))

org-timeline at beginning of agenda buffer

  (defun org-timeline-insert-timeline ()
    "Insert graphical timeline into agenda buffer."
    (unless (buffer-narrowed-p)
      (goto-char (point-min))
      (while (and (not (eq (get-text-property (line-beginning-position) 'org-agenda-type) 'agenda))
                  (not (eobp)))
        (forward-line))
      (forward-line)
      (unless (eobp)
        (let ((inhibit-read-only t))
          (insert (org-timeline--generate-timeline))
          (insert (propertize (concat "\n" (make-string (/ (window-width) 2) ?─)) 'face 'org-time-grid) "\n"))
        ;; enable `font-lock-mode' in agenda view to display the "chart"
        (font-lock-mode))))

org-caldav bug

    (defun org-caldav-skip-function (backend)
      (when (eq backend 'icalendar)
        (org-map-entries
         (lambda ()
           (let ((pt (save-excursion (apply 'org-agenda-skip-entry-if org-caldav-skip-conditions))))
             (when (or pt
                       ;;(org-get-repeat)
                       ) ;; No repeating tasks
               (org-todo 'none)
               (let ((current-prefix-arg '(4))) 
                 (call-interactively 'org-schedule)
                 (call-interactively 'org-deadline))))))))

Another org-caldav bug

https://github.com/org-trello/org-trello/issues/258

  (defun url-http-end-of-document-sentinel (proc why)
  ;; Sentinel used to handle (i) terminated old HTTP/0.9 connections,
  ;; and (ii) closed connection due to reusing a HTTP connection which
  ;; we believed was still alive, but which the server closed on us.
  ;; We handle case (ii) by calling `url-http' again.
  (url-http-debug "url-http-end-of-document-sentinel in buffer (%s)"
		  (process-buffer proc))
  (url-http-idle-sentinel proc why)
  (when (buffer-name (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (goto-char (point-min))
      (cond ((not (looking-at "HTTP/"))
	     (if url-http-no-retry
		 ;; HTTP/0.9 just gets passed back no matter what
		 (url-http-activate-callback)
	       ;; Call `url-http' again if our connection expired.
	       (erase-buffer)
               (let ((url-request-method url-http-method)
                     (url-request-extra-headers url-http-extra-headers)
                     (url-request-data url-http-data)
                     (url-using-proxy (url-find-proxy-for-url
                                       url-current-object
                                       (url-host url-current-object))))
                 (when url-using-proxy
                   (setq url-using-proxy
                         (url-generic-parse-url url-using-proxy)))
                 (if (string= "https" (url-type url-current-object))
                     (setq url-gateway-method 'tls))
                 (url-http url-current-object url-callback-function
                           url-callback-arguments (current-buffer)))))
	    ((url-http-parse-headers)
	     (url-http-activate-callback))))))

I don't like the help window behavior

  (defun my/goto-variable (var &optional file)
    (when (eq file 'C-source)
      (setq file (help-C-file-name var 'var)))
    (let* ((location (find-variable-noselect var file))
           (position (cdr location)))
      (switch-to-buffer (car location))
      (run-hooks 'find-function-after-hook)
      (if position
          (progn
            ;; Widen the buffer if necessary to go to this position.
            (when (or (< position (point-min))
                      (> position (point-max)))
              (widen))
            (goto-char position))
        (message "Unable to find location in file"))))

  (define-button-type 'help-variable-def
    :supertype 'help-xref
    'help-function #'my/goto-variable
    'help-echo (purecopy "mouse-2, RET: find variable's definition"))

  (defun my/goto-function (fun &optional file type)
    (or file
        (setq file (find-lisp-object-file-name fun type)))
    (if (not file)
        (message "Unable to find defining file")
      (require 'find-func)
      (when (eq file 'C-source)
        (setq file
              (help-C-file-name (indirect-function fun) 'fun)))
      ;; Don't use find-function-noselect because it follows
      ;; aliases (which fails for built-in functions).
      (let ((location
             (find-function-search-for-symbol fun type file)))
        (switch-to-buffer (car location))
        (run-hooks 'find-function-after-hook)
        (if (cdr location)
            (goto-char (cdr location))
          (message "Unable to find location in file")))))

  (define-button-type 'help-function-def
    :supertype 'help-xref
    'help-function #'my/goto-function
    'help-echo (purecopy "mouse-2, RET: find function's definition"))

Org agenda supposedly has an option to make no timestamp on a date mean the end of the day

However, the behavior reflected is not so. Therefore, I have added some code to manually add the end-of-day timestamp manually

      (setq org-sort-agenda-notime-is-late t)

      (defun my-org-agenda-entry-get-agenda-timestamp (pom)
        "Retrieve timestamp information for sorting agenda views.
                    Given a point or marker POM, returns a cons cell of the timestamp
                    and the timestamp type relevant for the sorting strategy in
                    `org-agenda-sorting-strategy-selected'."
        (let (ts ts-date-type)
          (save-match-data
            (cond ((org-em 'scheduled-up 'scheduled-down
                           org-agenda-sorting-strategy-selected)
                   (setq ts (org-entry-get pom "SCHEDULED")
                         ts-date-type " scheduled"))
                  ((org-em 'deadline-up 'deadline-down
                           org-agenda-sorting-strategy-selected)
                   (setq ts (org-entry-get pom "DEADLINE")
                         ts-date-type " deadline"))
                  ((org-em 'ts-up 'ts-down
                           org-agenda-sorting-strategy-selected)
                   (setq ts (org-entry-get pom "TIMESTAMP")
                         ts-date-type " timestamp"))
                  ((org-em 'tsia-up 'tsia-down
                           org-agenda-sorting-strategy-selected)
                   (setq ts (org-entry-get pom "TIMESTAMP_IA")
                         ts-date-type " timestamp_ia"))
                  ((org-em 'timestamp-up 'timestamp-down
                           org-agenda-sorting-strategy-selected)
                   (setq ts (or (org-entry-get pom "SCHEDULED")
                                (org-entry-get pom "DEADLINE")
                                (org-entry-get pom "TIMESTAMP")
                                (org-entry-get pom "TIMESTAMP_IA"))
                         ts-date-type ""))
                  (t (setq ts-date-type "")))
            (cons (when ts 
                    (ignore-errors 
                      (org-time-string-to-seconds 
                       (if (string-match-p ":" ts)
                           ts
                         (let ((s (substring ts 0 (1- (length ts))))) ;; Added code here
                           (concat s
                                   " 23:59>"))))))
                  ts-date-type))))

      (advice-add 'org-agenda-entry-get-agenda-timestamp
                  :override
                  #'my-org-agenda-entry-get-agenda-timestamp)

org-mru-clock

Include the tags dammit

  (defun org-mru-clock-format-entry ()
    "Return the parent heading string appended to the heading at point."
    (let* ((this (org-get-heading 'no-tags 'no-todo))
           (parent
            (save-excursion
              (org-up-heading-safe)
              (concat (org-get-heading 'no-tags 'no-todo)
                      "   "
                      (string-join (org-get-tags-at) ","))))
           (parent-post (if parent
                            (format " (%s)" parent)
                          ""))
           (with-parent (concat this parent-post)))
      (if org-mru-clock-keep-formatting
          with-parent
        (substring-no-properties with-parent))))

Scan Tags Indent

  (defun get-parent-indent-level ()
    (save-excursion
      (let ((levels 0))
        (while (and (org-up-heading-safe)
                    (org-get-todo-state))
          (incf levels))
        levels)))

  (defun my/org-scan-tags (action matcher todo-only &optional start-level)
    "Scan headline tags with inheritance and produce output ACTION.

    ACTION can be `sparse-tree' to produce a sparse tree in the current buffer,
    or `agenda' to produce an entry list for an agenda view.  It can also be
    a Lisp form or a function that should be called at each matched headline, in
    this case the return value is a list of all return values from these calls.

    MATCHER is a function accepting three arguments, returning
    a non-nil value whenever a given set of tags qualifies a headline
    for inclusion.  See `org-make-tags-matcher' for more information.
    As a special case, it can also be set to t (respectively nil) in
    order to match all (respectively none) headline.

    When TODO-ONLY is non-nil, only lines with a TODO keyword are
    included in the output.

    START-LEVEL can be a string with asterisks, reducing the scope to
    headlines matching this string."
    (require 'org-agenda)
    (let* ((re (concat "^"
                       (if start-level
                           ;; Get the correct level to match
                           (concat "\\*\\{" (number-to-string start-level) "\\} ")
                         org-outline-regexp)
                       " *\\(" (regexp-opt org-todo-keywords-1 'words) "\\)?"
                       " *\\(.*?\\)\\([ \t]:\\(?:" org-tag-re ":\\)+\\)?[ \t]*$"))
           (props (list 'face 'default
                        'done-face 'org-agenda-done
                        'undone-face 'default
                        'mouse-face 'highlight
                        'org-not-done-regexp org-not-done-regexp
                        'org-todo-regexp org-todo-regexp
                        'org-complex-heading-regexp org-complex-heading-regexp
                        'help-echo
                        (format "mouse-2 or RET jump to Org file %S"
                                (abbreviate-file-name
                                 (or (buffer-file-name (buffer-base-buffer))
                                     (buffer-name (buffer-base-buffer)))))))
           (org-map-continue-from nil)
           lspos tags tags-list
           (tags-alist (list (cons 0 org-file-tags)))
           (llast 0) rtn rtn1 level category i txt
           todo marker entry priority
           ts-date ts-date-type ts-date-pair)
      (unless (or (member action '(agenda sparse-tree)) (functionp action))
        (setq action (list 'lambda nil action)))
      (save-excursion
        (goto-char (point-min))
        (when (eq action 'sparse-tree)
          (org-overview)
          (org-remove-occur-highlights))
        (while (let (case-fold-search)
                 (re-search-forward re nil t))
          (setq org-map-continue-from nil)
          (catch :skip
            ;; Ignore closing parts of inline tasks.
            (when (and (fboundp 'org-inlinetask-end-p) (org-inlinetask-end-p))
              (throw :skip t))
            (setq todo (and (match-end 1) (match-string-no-properties 1)))
            (setq tags (and (match-end 4) (org-trim (match-string-no-properties 4))))
            (goto-char (setq lspos (match-beginning 0)))
            (setq level (org-reduced-level (org-outline-level))
                  category (org-get-category))
            (when (eq action 'agenda)
              (setq ts-date-pair (org-agenda-entry-get-agenda-timestamp (point))
                    ts-date (car ts-date-pair)
                    ts-date-type (cdr ts-date-pair)))
            (setq i llast llast level)
            ;; remove tag lists from same and sublevels
            (while (>= i level)
              (when (setq entry (assoc i tags-alist))
                (setq tags-alist (delete entry tags-alist)))
              (setq i (1- i)))
            ;; add the next tags
            (when tags
              (setq tags (org-split-string tags ":")
                    tags-alist
                    (cons (cons level tags) tags-alist)))
            ;; compile tags for current headline
            (setq tags-list
                  (if org-use-tag-inheritance
                      (apply 'append (mapcar 'cdr (reverse tags-alist)))
                    tags)
                  org-scanner-tags tags-list)
            (when org-use-tag-inheritance
              (setcdr (car tags-alist)
                      (mapcar (lambda (x)
                                (setq x (copy-sequence x))
                                (org-add-prop-inherited x))
                              (cdar tags-alist))))
            (when (and tags org-use-tag-inheritance
                       (or (not (eq t org-use-tag-inheritance))
                           org-tags-exclude-from-inheritance))
              ;; Selective inheritance, remove uninherited ones.
              (setcdr (car tags-alist)
                      (org-remove-uninherited-tags (cdar tags-alist))))
            (when (and

                   ;; eval matcher only when the todo condition is OK
                   (and (or (not todo-only) (member todo org-todo-keywords-1))
                        (if (functionp matcher)
                            (let ((case-fold-search t) (org-trust-scanner-tags t))
                              (funcall matcher todo tags-list level))
                          matcher))

                   ;; Call the skipper, but return t if it does not
                   ;; skip, so that the `and' form continues evaluating.
                   (progn
                     (unless (eq action 'sparse-tree) (org-agenda-skip))
                     t)

                   ;; Check if timestamps are deselecting this entry
                   (or (not todo-only)
                       (and (member todo org-todo-keywords-1)
                            (or (not org-agenda-tags-todo-honor-ignore-options)
                                (not (org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item))))))

              ;; select this headline
              (cond
               ((eq action 'sparse-tree)
                (and org-highlight-sparse-tree-matches
                     (org-get-heading) (match-end 0)
                     (org-highlight-new-match
                      (match-beginning 1) (match-end 1)))
                (org-show-context 'tags-tree))
               ((eq action 'agenda)
                (setq txt (org-agenda-format-item
                           ""
                           (concat
                            (if (eq org-tags-match-list-sublevels 'indented)
                                (make-string (get-parent-indent-level) ?.) "")
                            (org-get-heading))
                           (make-string level ?\s)
                           category
                           tags-list)
                      priority (org-get-priority txt))
                (goto-char lspos)
                (setq marker (org-agenda-new-marker))
                (org-add-props txt props
                  'org-marker marker 'org-hd-marker marker 'org-category category
                  'todo-state todo
                  'ts-date ts-date
                  'priority priority
                  'type (concat "tagsmatch" ts-date-type))
                (push txt rtn))
               ((functionp action)
                (setq org-map-continue-from nil)
                (save-excursion
                  (setq rtn1 (funcall action))
                  (push rtn1 rtn)))
               (t (user-error "Invalid action")))

              ;; if we are to skip sublevels, jump to end of subtree
              (unless org-tags-match-list-sublevels
                (org-end-of-subtree t)
                (backward-char 1))))
          ;; Get the correct position from where to continue
          (if org-map-continue-from
              (goto-char org-map-continue-from)
            (and (= (point) lspos) (end-of-line 1)))))
      (when (and (eq action 'sparse-tree)
                 (not org-sparse-tree-open-archived-trees))
        (org-hide-archived-subtrees (point-min) (point-max)))
      (nreverse rtn)))

  (defun my/org-tags-view (&optional todo-only match)
    "Show all headlines for all `org-agenda-files' matching a TAGS criterion.
  The prefix arg TODO-ONLY limits the search to TODO entries."
    (interactive "P")
    (when org-agenda-overriding-arguments
      (setq todo-only (car org-agenda-overriding-arguments)
            match (nth 1 org-agenda-overriding-arguments)))
    (let* ((org-tags-match-list-sublevels
            org-tags-match-list-sublevels)
           (completion-ignore-case t)
           (org--matcher-tags-todo-only todo-only)
           rtn rtnall files file pos matcher
           buffer)
      (when (and (stringp match) (not (string-match "\\S-" match)))
        (setq match nil))
      (catch 'exit
        ;; TODO: this code is repeated a lot...
        (when org-agenda-sticky
          (setq org-agenda-buffer-name
                (if (stringp match)
                    (format "*Org Agenda(%s:%s)*"
                            (or org-keys (or (and todo-only "M") "m")) match)
                  (format "*Org Agenda(%s)*" (or (and todo-only "M") "m")))))
        (setq matcher (org-make-tags-matcher match))
        ;; Prepare agendas (and `org-tag-alist-for-agenda') before
        ;; expanding tags within `org-make-tags-matcher'
        (org-agenda-prepare (concat "TAGS " match))
        (setq match (car matcher)
              matcher (cdr matcher))
        (org-compile-prefix-format 'tags)
        (org-set-sorting-strategy 'tags)
        (setq org-agenda-query-string match)
        (setq org-agenda-redo-command
              (list 'org-tags-view
                    `(quote ,org--matcher-tags-todo-only)
                    `(if current-prefix-arg nil ,org-agenda-query-string)))
        (setq files (org-agenda-files nil 'ifmode)
              rtnall nil)
        (while (setq file (pop files))
          (catch 'nextfile
            (org-check-agenda-file file)
            (setq buffer (if (file-exists-p file)
                             (org-get-agenda-file-buffer file)
                           (error "No such file %s" file)))
            (if (not buffer)
                ;; If file does not exist, error message to agenda
                (setq rtn (list
                           (format "ORG-AGENDA-ERROR: No such org-file %s" file))
                      rtnall (append rtnall rtn))
              (with-current-buffer buffer
                (unless (derived-mode-p 'org-mode)
                  (error "Agenda file %s is not in Org mode" file))
                (save-excursion
                  (save-restriction
                    (if (eq buffer org-agenda-restrict)
                        (narrow-to-region org-agenda-restrict-begin
                                          org-agenda-restrict-end)
                      (widen))
                    (setq rtn (org-scan-tags 'agenda
                                             matcher
                                             org--matcher-tags-todo-only))
                    (setq rtnall (append rtnall rtn))))))))
        (org-agenda--insert-overriding-header
          (with-temp-buffer
            (insert "Headlines with TAGS match: ")
            (add-text-properties (point-min) (1- (point))
                                 (list 'face 'org-agenda-structure
                                       'short-heading
                                       (concat "Match: " match)))
            (setq pos (point))
            (insert match "\n")
            (add-text-properties pos (1- (point)) (list 'face 'org-warning))
            (setq pos (point))
            (unless org-agenda-multi
              (insert (substitute-command-keys
                       "Press \
  \\<org-agenda-mode-map>`\\[universal-argument] \\[org-agenda-redo]' \
  to search again\n")))
            (add-text-properties pos (1- (point))
                                 (list 'face 'org-agenda-structure))
            (buffer-string)))
        (org-agenda-mark-header-line (point-min))
        (when rtnall
          (insert (org-agenda-finalize-entries rtnall 'tags) "\n"))
        (goto-char (point-min))
        (or org-agenda-multi (org-agenda-fit-window-to-buffer))
        (add-text-properties
         (point-min) (point-max)
         `(org-agenda-type tags
                           org-last-args (,org--matcher-tags-todo-only ,match)
                           org-redo-cmd ,org-agenda-redo-command
                           org-series-cmd ,org-cmd))
        (org-agenda-finalize)
        (setq buffer-read-only t))))

  (advice-add 'org-scan-tags
              :override
              #'my/org-scan-tags)

gdb window layout custom

  (defun gdb-setup-windows ()
    "Layout the window pattern for option `gdb-many-windows'."
    (gdb-get-buffer-create 'gdb-locals-buffer)
    (gdb-get-buffer-create 'gdb-stack-buffer)
    (gdb-get-buffer-create 'gdb-breakpoints-buffer)
    (set-window-dedicated-p (selected-window) nil)
    (switch-to-buffer gud-comint-buffer)
    (delete-other-windows)
    (let ((win0 (selected-window))
          (win1 (split-window nil ( / ( * (window-height) 3) 4)))
          (win2 (split-window nil ( / (window-height) 3)))
          (win3 (split-window-right)))
      (gdb-set-window-buffer (gdb-locals-buffer-name) nil win3)
      (select-window win2)
      (set-window-buffer
       win2
       (if gud-last-last-frame
           (gud-find-file (car gud-last-last-frame))
         (if gdb-main-file
             (gud-find-file gdb-main-file)
           ;; Put buffer list in window if we
           ;; can't find a source file.
           (list-buffers-noselect))))
      (setq gdb-source-window (selected-window))
      (let ((win4 (split-window-right)))
        (gdb-set-window-buffer
         (gdb-get-buffer-create 'gdb-disassembly-buffer) nil win4))
      (select-window win1)
      (gdb-set-window-buffer (gdb-stack-buffer-name))
      (let ((win5 (split-window-right)))
        (gdb-set-window-buffer (if gdb-show-threads-by-default
                                   (gdb-threads-buffer-name)
                                 (gdb-breakpoints-buffer-name))
                               nil win5))
      (select-window win0)))

org-clock-out resolve dangling clock time

    (defun my/org-clock-out (&optional switch-to-state fail-quietly at-time)
      "Stop the currently running clock.
    Throw an error if there is no running clock and FAIL-QUIETLY is nil.
    With a universal prefix, prompt for a state to switch the clocked out task
    to, overriding the existing value of `org-clock-out-switch-to-state'."
      (interactive "P")
      (catch 'exit
        (when (not (org-clocking-p))
          (setq global-mode-string
                (delq 'org-mode-line-string global-mode-string))
          (setq frame-title-format org-frame-title-format-backup)
          (force-mode-line-update)
          (if fail-quietly (throw 'exit t) (user-error "No active clock")))
        (let ((org-clock-out-switch-to-state
               (if switch-to-state
                   (completing-read "Switch to state: "
                                    (with-current-buffer
                                        (marker-buffer org-clock-marker)
                                      org-todo-keywords-1)
                                    nil t "DONE")
                 org-clock-out-switch-to-state))
              (now (org-current-time org-clock-rounding-minutes))
              ts te s h m remove)
          (setq org-clock-out-time (or at-time now))                          ;; This line is changed from now to (or at-time now)
          (save-excursion ; Do not replace this with `with-current-buffer'.
            (with-no-warnings (set-buffer (org-clocking-buffer)))
            (save-restriction
              (widen)
              (goto-char org-clock-marker)
              (beginning-of-line 1)
              (if (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
                       (equal (match-string 1) org-clock-string))
                  (setq ts (match-string 2))
                (if fail-quietly (throw 'exit nil) (error "Clock start time is gone")))
              (goto-char (match-end 0))
              (delete-region (point) (point-at-eol))
              (insert "--")
              (setq te (org-insert-time-stamp (or at-time now) 'with-hm 'inactive))
              (setq s (- (float-time
                          (apply #'encode-time (org-parse-time-string te)))
                         (float-time
                          (apply #'encode-time (org-parse-time-string ts))))
                    h (floor (/ s 3600))
                    s (- s (* 3600 h))
                    m (floor (/ s 60))
                    s (- s (* 60 s)))
              (insert " => " (format "%2d:%02d" h m))
              (move-marker org-clock-marker nil)
              (move-marker org-clock-hd-marker nil)
              ;; Possibly remove zero time clocks.  However, do not add
              ;; a note associated to the CLOCK line in this case.
              (cond ((and org-clock-out-remove-zero-time-clocks
                          (= (+ h m) 0))
                     (setq remove t)
                     (delete-region (line-beginning-position)
                                    (line-beginning-position 2)))
                    (org-log-note-clock-out
                     (org-add-log-setup
                      'clock-out nil nil nil
                      (concat "# Task: " (org-get-heading t) "\n\n"))))
              (when org-clock-mode-line-timer
                (cancel-timer org-clock-mode-line-timer)
                (setq org-clock-mode-line-timer nil))
              (when org-clock-idle-timer
                (cancel-timer org-clock-idle-timer)
                (setq org-clock-idle-timer nil))
              (setq global-mode-string
                    (delq 'org-mode-line-string global-mode-string))
              (setq frame-title-format org-frame-title-format-backup)
              (when org-clock-out-switch-to-state
                (save-excursion
                  (org-back-to-heading t)
                  (let ((org-clock-out-when-done nil))
                    (cond
                     ((functionp org-clock-out-switch-to-state)
                      (let ((case-fold-search nil))
                        (looking-at org-complex-heading-regexp))
                      (let ((newstate (funcall org-clock-out-switch-to-state
                                               (match-string 2))))
                        (when newstate (org-todo newstate))))
                     ((and org-clock-out-switch-to-state
                           (not (looking-at (concat org-outline-regexp "[ \t]*"
                                                    org-clock-out-switch-to-state
                                                    "\\>"))))
                      (org-todo org-clock-out-switch-to-state))))))
              (force-mode-line-update)
              (message (concat "Clock stopped at %s after "
                               (org-duration-from-minutes (+ (* 60 h) m)) "%s")
                       te (if remove " => LINE REMOVED" ""))
              (run-hooks 'org-clock-out-hook)
              (unless (org-clocking-p)
                (setq org-clock-current-task nil)))))))

  (defun my/org-clock-resolve-clock
      (clock resolve-to clock-out-time close restart fail-quietly)
    "Resolve CLOCK given the time RESOLVE-TO, and the present.
  CLOCK is a cons cell of the form (MARKER START-TIME)."
    (let ((org-clock-resolving-clocks t)
          ;; If the clocked entry contained only a clock and possibly
          ;; the associated drawer, and we either cancel it or clock it
          ;; out, `org-clock-out-remove-zero-time-clocks' may clear all
          ;; contents, and leave point on the /next/ headline.  We store
          ;; the current entry location to be able to get back here when
          ;; we need to clock in again the previously clocked task.
          (heading (org-with-point-at (car clock)
                     (org-back-to-heading t)
                     (point-marker))))
      (pcase resolve-to
        (`nil
         (org-clock-clock-cancel clock)
         (when (and restart (not org-clock-clocking-in))
           (org-with-point-at heading (org-clock-in))))
        (`now
         (cond
          (restart (error "RESTART is not valid here"))
          ((or close org-clock-clocking-in)
           (org-clock-clock-out clock fail-quietly))
          ((org-is-active-clock clock) nil)
          (t (org-clock-clock-in clock t))))
        ((pred (time-less-p (current-time)))
         ;; ^ NOTE: Here and in other `time-less-p' calls, we use
         ;; (current-time) rather than nil for Emacs 24 compatibility.
         (error "RESOLVE-TO must refer to a time in the past"))
        (_
         (when restart (error "RESTART is not valid here"))
         (org-clock-clock-out clock fail-quietly (or clock-out-time resolve-to))
         (cond
          (org-clock-clocking-in nil)
          (close
           (setq org-clock-leftover-time (and (null clock-out-time) resolve-to))
           (move-marker org-clock-marker nil))
          (t
           (org-with-point-at heading
             (org-clock-in nil (and clock-out-time resolve-to)))))))))

  (advice-add 'org-clock-out
              :override
              #'my/org-clock-out)

  (advice-add 'org-clock-resolve-clock
              :override
              #'my/org-clock-resolve-clock)

Modifications to the switch buffer functions

  (defvar switch-buffer-functions--in-minibuffer nil)

    ;;;###autoload
  (defun switch-buffer-functions-run ()
    "Run `switch-buffer-functions' if needed.

    This function checks the result of `current-buffer', and run
    `switch-buffer-functions' when it has been changed from
    the last buffer.

    This function should be hooked to `post-command-hook'."
    (when (and switch-buffer-functions--in-minibuffer
               (member this-command '(exit-minibuffer minibuffer-keyboard-quit ivy-alt-done)))
      (setq switch-buffer-functions--in-minibuffer nil))
    (if (member this-command '(eval-expression counsel-M-x ivy-switch-buffer edebug-eval-expression counsel-grep-or-swiper)) ;; counsel-M-x doesn't work...
        (setq switch-buffer-functions--in-minibuffer t)
      (unless (or (eq (current-buffer)
                      switch-buffer-functions--last-buffer))
        (let ((current (current-buffer))
              (previous switch-buffer-functions--last-buffer))
          (setq switch-buffer-functions--last-buffer
                current)
          (run-hook-with-args 'switch-buffer-functions
                              previous
                              current)))))

Don't colorize joins and leaves

Makes for easier reading

  (defvar dont-colorize-these-commands '("JOIN" "PART" "QUIT"))

  (defun erc-colorize-privmsgs ()
    "Function used in `erc-insert-modify-hook' to apply the same face to a
  message coming from a user."
    (erc-find-parsed-property)
    (let* ((vector (erc-get-parsed-vector (point)))
           (nickuserhost (erc-get-parsed-vector-nick vector))
           (nickname (and nickuserhost
                          (nth 0 (erc-parse-user nickuserhost))))
           (match-face (erc-colorize-color nickname)))
      (when (and match-face
                 (not (member (erc-response.command vector)
                              dont-colorize-these-commands)))
        (erc-button-add-face (point-min) (point-max) match-face))))

  (advice-add #'erc-colorize-message
              :override
              #'erc-colorize-privmsgs)

Auto commit when saving org files

  (defvar org-agenda-auto-commit nil)
  (defconst org-agenda-git-repo-path (expand-file-name "~/MEGA/org/2019-05-agenda"))

  (defun my/toggle-auto-commit ()
    (interactive)
    (setq org-agenda-auto-commit (not org-agenda-auto-commit)))

  (defun auto-commit-agenda (&optional arg)
    (when-let (f (buffer-file-name))
      (let ((fname (expand-file-name f))
            (sfname (buffer-name)))
        (when (and org-agenda-auto-commit
                   (string-prefix-p org-agenda-git-repo-path
                                    fname)
                   (magit-anything-modified-p t fname)
                   (not (magit-merge-in-progress-p))
                   (or (string= (magit-get-current-branch)
                                "master")
                       (progn
                         (magit-git-command-topdir "git checkout master")
                         (string= (magit-get-current-branch)
                                  "master"))))
          (save-window-excursion 
            (magit-stage-file fname)
            (magit-commit-create `("-m" ,(format "\"%s\" modified, %s"
                                                 sfname (current-time-string)))))))))

  (advice-add #'save-buffer
              :after
              #'auto-commit-agenda)

ivy-occur take up whole buffer

  (defun my/ivy-occur (&rest _)
    (interactive)
    (let ((buffer (current-buffer)))
      (delete-window)
      (switch-to-buffer buffer)))

  ;;(advice-add #'ivy-occur :override #'my/ivy-occur)
  ;;(advice-remove #'ivy-occur #'my/ivy-occur)