diff --git a/.mc-lists.el b/.mc-lists.el index 2c4235ee..f816129a 100644 --- a/.mc-lists.el +++ b/.mc-lists.el @@ -15,12 +15,14 @@ isearch-printing-char keyboard-quit kill-region + org-delete-char org-self-insert-command phi-search python-indent-electric-colon sgml-slash skeleton-pair-insert-maybe tern-ac-dot-complete + undo-redo universal-argument-minus wdired-finish-edit )) diff --git a/init.el b/init.el index c2156eec..34d9d517 100644 --- a/init.el +++ b/init.el @@ -104,7 +104,6 @@ (setq make-backup-files nil) (setq auto-save-default nil) -;; Why is this necessary again? (defconst emacs-tmp-dir (format "%s/%s%s/" temporary-file-directory "emacs" (user-uid))) (setq backup-directory-alist `((".*" . ,emacs-tmp-dir))) @@ -155,69 +154,6 @@ ;; functions ;; ============================================================================= -(defun org-todo-force-notes () - (interactive) - (let ((org-todo-log-states - (mapcar (lambda (state) - (list state 'note 'time)) - (apply 'append org-todo-sets)))) - (cond ((eq major-mode 'org-mode) (org-todo)) - ((eq major-mode 'org-agenda-mode) (org-agenda-todo))))) - -(defun org-todo-force-notes () - (interactive) - (let ((org-todo-log-states - (mapcar (lambda (state) - (list state 'note 'time)) - (apply 'append org-todo-sets)))) - (org-todo) - )) - -(defun org-agenda-todo-force-notes () - (interactive) - (let ((org-todo-log-states - (mapcar (lambda (state) - (list state 'note 'time)) - (apply 'append org-todo-sets)))) - (org-agenda-todo))) - -(defun org-todo-no-note () - (interactive) - (org-todo 0)) - -(defun org-project-heading (heading) - (interactive - (list (read-string "Heading: "))) - (org-insert-or-goto-heading heading) - (hide-subtree) - (org-beginning-of-line) - (org-set-property "CATEGORY" heading)) - -(defun org-insert-or-goto-heading (heading) - (interactive - (list (read-string "Heading: "))) - (goto-char (point-min)) - (unless (derived-mode-p 'org-mode) - (error - "Target buffer \"%s\" for file+headline should be in Org mode" - (current-buffer))) - (if (re-search-forward - (format org-complex-heading-regexp-format (regexp-quote heading)) - nil t) - (goto-char (point-at-bol)) - (goto-char (point-max)) - (or (bolp) (insert "\n")) - (insert "* " heading))) - -(defun org-make-habit () - (interactive) - (org-set-property "STYLE" "habit")) - -(defun org-insert-habit () - (interactive) - (org-insert-todo-heading nil) - (org-make-habit)) - (defun undo-redo (&optional arg) (interactive "P") (if arg (undo-tree-redo) (undo-tree-undo))) @@ -393,7 +329,8 @@ The current directory is assumed to be the project's root otherwise." ;; Make mouse scrolling less jumpy. (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) -(eval-after-load "subword-mode" '(diminish 'subword-mode)) +(eval-after-load 'subword '(diminish 'subword-mode)) + ;; Set path from shell. (use-package exec-path-from-shell @@ -607,7 +544,8 @@ The current directory is assumed to be the project's root otherwise." ("C-c n h" . org-insert-habit) ("C-c n m" . org-make-habit) ("C-c C-t" . org-todo) - ("C-c C-S-t" . org-todo-force-notes)) + ("C-c C-S-t" . org-todo-force-notes) + ("C-c n p" . org-projectile:project-todo-completing-read)) :config (progn (setq org-habit-graph-column 50) @@ -616,13 +554,11 @@ The current directory is assumed to be the project's root otherwise." (defvar org-gtd-file "~/org/gtd.org")) (unless (boundp 'org-habits-file) (defvar org-habits-file "~/org/habits.org")) - (unless (boundp 'org-projects-file) - (defvar org-projects-file "~/org/projects.org")) (unless (boundp 'org-capture-templates) (defvar org-capture-templates nil)) (setq org-completion-use-ido t) (setq org-enforce-todo-dependencies t) - (setq org-agenda-files (list org-gtd-file org-habits-file org-projects-file)) + (setq org-agenda-files (list org-gtd-file org-habits-file org-projectile:projects-file)) (add-to-list 'org-capture-templates `("h" "Habit" entry (file+headline ,org-habits-file "Habits") "* TODO @@ -631,22 +567,32 @@ The current directory is assumed to be the project's root otherwise." :STYLE: habit :END:")) + (defun org-todo-force-notes () + (interactive) + (let ((org-todo-log-states + (mapcar (lambda (state) + (list state 'note 'time)) + (apply 'append org-todo-sets)))) + (cond ((eq major-mode 'org-mode) (org-todo)) + ((eq major-mode 'org-agenda-mode) (org-agenda-todo))))) + + (defun org-make-habit () + (interactive) + (org-set-property "STYLE" "habit")) + + (defun org-insert-habit () + (interactive) + (org-insert-todo-heading nil) + (org-make-habit)) + (add-to-list 'org-capture-templates `("t" "Life Todo" entry (file+headline ,org-gtd-file "Tasks") "* TODO %?\n")) - (defun org-get-project-name-of-capture-file () - (org-project-heading - (file-name-nondirectory - (directory-file-name (project-root-of-file - (plist-get org-capture-plist :original-file))))) - (org-end-of-line)) - - (add-to-list 'org-capture-templates - `("p" "Project Todo" entry - (file+function ,org-projects-file org-get-project-name-of-capture-file) - "* TODO %?\n")) + (add-to-list 'org-capture-templates (org-projectile:project-todo-entry)) + (add-to-list 'org-modules 'org-habit) + (let ((this-week-high-priority '(tags-todo "+PRIORITY=\"A\"+DEADLINE<\"<+1w>\"DEADLINE>\"<+0d>\"" ((org-agenda-overriding-header @@ -852,7 +798,7 @@ The current directory is assumed to be the project's root otherwise." (progn (use-package persp-projectile :ensure t - :commands persp-projectile) + :commands projectile-persp-switch-project) (use-package helm-projectile :ensure t :commands (helm-projectile-on) @@ -929,7 +875,7 @@ The current directory is assumed to be the project's root otherwise." (bind-key "C-c C-v" 'find-variable) (define-key lisp-mode-shared-map (kbd "C-c C-c") 'eval-defun) (define-key lisp-mode-shared-map (kbd "C-c C-r") 'eval-and-replace) -(define-key lisp-mode-shared-map (kbd "C-c o s") 'up-list-region) +(define-key lisp-mode-shared-map (kbd "C-c o r") 'up-list-region) (define-key lisp-mode-shared-map (kbd "C-c o o") 'up-list-back) ;; ============================================================================= @@ -1163,6 +1109,7 @@ The current directory is assumed to be the project's root otherwise." (bind-key "M-n" 'forward-paragraph) (bind-key "M-p" 'backward-paragraph) (bind-key "M-z" 'zap-to-char) +(bind-key "C-M-" 'backward-kill-sexp) (fset 'global-set-key-to-use-package (lambda (&optional arg) "Keyboard macro." (interactive "p") @@ -1249,9 +1196,9 @@ The current directory is assumed to be the project's root otherwise." (defun disable-all-themes () (interactive) -(mapcar - (lambda (theme) (unless (s-contains? "smart-mode" (symbol-name theme)) - (disable-theme theme))) custom-enabled-themes)) + (mapcar + (lambda (theme) (unless (s-contains? "smart-mode" (symbol-name theme)) + (disable-theme theme))) custom-enabled-themes)) (defun disable-and-load-theme (theme &optional no-confirm no-enable) (interactive diff --git a/load.d/org-projectile.el b/load.d/org-projectile.el new file mode 100644 index 00000000..d84130b4 --- /dev/null +++ b/load.d/org-projectile.el @@ -0,0 +1,70 @@ +(defvar org-projectile:projects-file "~/org/projects.org") + +(defun org-projectile:project-todo-entry (&optional todo-format) + (unless todo-format (setq todo-format "* TODO %?\n")) + `("p" "Project Todo" entry + (file+function ,org-projectile:projects-file + (lambda () (let ((heading (org-projectile:insert-heading-for-filename + (org-capture-get :original-file)))) + (org-projectile:insert-or-goto-heading heading) + (org-end-of-line) + heading))) + ,todo-format)) + +(defun org-projectile:project-heading-from-file (filename) + (file-name-nondirectory + (directory-file-name (project-root-of-file filename)))) + +(defun org-projectile:insert-heading-for-filename (filename) + (let ((project-heading + (org-projectile:project-heading-from-file + filename))) + (with-current-buffer (find-file-noselect org-projectile:projects-file) + (org-projectile:project-heading project-heading)) + project-heading)) + +(defun org-projectile:known-projects () + (delete-dups `(,@(mapcar #'org-projectile:project-heading-from-file (projectile-relevant-known-projects)) + ,@(org-map-entries (lambda () (nth 4 (org-heading-components))) nil (list org-projectile:projects-file) + (lambda () (when (< 1 (nth 1 (org-heading-components))) (point))))))) + + +(defun org-projectile:project-todo-completing-read () + (interactive) + (org-projectile:capture-for-project + (projectile-completing-read "Record TODO for project:" + (org-projectile:known-projects)))) + +(defun org-projectile:capture-for-project (heading) + (org-capture-set-plist (org-projectile:project-todo-entry)) + (with-current-buffer (find-file-noselect org-projectile:projects-file) + (org-projectile:project-heading heading)) + (org-capture-set-target-location `(file+headline ,org-projectile:projects-file ,heading)) + (org-capture-place-template)) + +(defun org-projectile:insert-or-goto-heading (heading) + (interactive + (list (read-string "Heading: "))) + (goto-char (point-min)) + (unless (derived-mode-p 'org-mode) + (error + "Target buffer \"%s\" for file+headline should be in Org mode" + (current-buffer))) + (if (re-search-forward + (format org-complex-heading-regexp-format (regexp-quote heading)) + nil t) + (goto-char (point-at-bol)) + (goto-char (point-max)) + (or (bolp) (insert "\n")) + (insert "* " heading))) + +(defun org-projectile:project-heading (heading) + (interactive + (list (read-string "Heading: "))) + (org-projectile:insert-or-goto-heading heading) + (hide-subtree) + (org-beginning-of-line) + (org-set-property "CATEGORY" heading)) + +(require 'org-capture) +(require 'projectile)