diff options
-rw-r--r-- | init.el | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/init.el b/init.el index 70b9325..16c3c4c 100644 --- a/init.el +++ b/init.el | |||
@@ -781,3 +781,234 @@ | |||
781 | (add-to-list 'exec-path "C:/Program Files/Mozilla Firefox")) | 781 | (add-to-list 'exec-path "C:/Program Files/Mozilla Firefox")) |
782 | 782 | ||
783 | (bind-key [remap just-one-space] #'cycle-spacing) | 783 | (bind-key [remap just-one-space] #'cycle-spacing) |
784 | |||
785 | ;; Org mode | ||
786 | ;; org-return-dwim (unpacakged) | ||
787 | (defun unpackaged/org-element-descendant-of (type element) | ||
788 | "Return non-nil if ELEMENT is a descendant of TYPE. | ||
789 | TYPE should be an element type, like `item' or `paragraph'. | ||
790 | ELEMENT should be a list like that returned by `org-element-context'." | ||
791 | ;; MAYBE: Use `org-element-lineage'. | ||
792 | (when-let* ((parent (org-element-property :parent element))) | ||
793 | (or (eq type (car parent)) | ||
794 | (unpackaged/org-element-descendant-of type parent)))) | ||
795 | |||
796 | (defun unpackaged/org-return-dwim (&optional default) | ||
797 | "A helpful replacement for `org-return'. With prefix, call `org-return'. | ||
798 | |||
799 | On headings, move point to position after entry content. In | ||
800 | lists, insert a new item or end the list, with checkbox if | ||
801 | appropriate. In tables, insert a new row or end the table." | ||
802 | ;; Inspired by John Kitchin: | ||
803 | ;; http://kitchingroup.cheme.cmu.edu/blog/2017/04/09/A-better-return-in-org-mode/ | ||
804 | (interactive "P") | ||
805 | (if default | ||
806 | (org-return) | ||
807 | (cond | ||
808 | ;; Act depending on context around point. | ||
809 | |||
810 | ;; NOTE: I prefer RET to not follow links, but by uncommenting | ||
811 | ;; this block, links will be followed. | ||
812 | ;; FURTHER NOTE: Ideally, I would follow links unless point | ||
813 | ;; /appeared/ to be at the end of the line (even if it's still | ||
814 | ;; inside the link) -- when it would do `org-return'. That | ||
815 | ;; would take some /doing/, however. | ||
816 | |||
817 | ;; ((eq 'link (car (org-element-context))) | ||
818 | ;; ;; Link: Open it. | ||
819 | ;; (org-open-at-point-global)) | ||
820 | |||
821 | ((org-at-heading-p) | ||
822 | ;; Heading: Move to position after entry content. | ||
823 | ;; NOTE: This is probably the most interesting feature of this function. | ||
824 | (let ((heading-start (org-entry-beginning-position))) | ||
825 | (goto-char (org-entry-end-position)) | ||
826 | (cond ((and (org-at-heading-p) | ||
827 | (= heading-start (org-entry-beginning-position))) | ||
828 | ;; Entry ends on its heading; add newline after | ||
829 | (end-of-line) | ||
830 | (insert "\n\n")) | ||
831 | (t | ||
832 | ;; Entry ends after its heading; back up | ||
833 | (forward-line -1) | ||
834 | (end-of-line) | ||
835 | (when (org-at-heading-p) | ||
836 | ;; At the same heading | ||
837 | (forward-line) | ||
838 | (insert "\n") | ||
839 | (forward-line -1)) | ||
840 | ;; FIXME: looking-back is supposed to be called with | ||
841 | ;; more arguments. | ||
842 | (while (not (looking-back (rx | ||
843 | (repeat 3 | ||
844 | (seq (optional blank) | ||
845 | "\n"))) | ||
846 | nil)) | ||
847 | (insert "\n")) | ||
848 | (forward-line -1))))) | ||
849 | |||
850 | ((org-at-item-checkbox-p) | ||
851 | ;; Checkbox: Insert new item with checkbox. | ||
852 | (org-insert-todo-heading nil)) | ||
853 | |||
854 | ((org-in-item-p) | ||
855 | ;; Plain list. Yes, this gets a little complicated... | ||
856 | (let ((context (org-element-context))) | ||
857 | (if (or (eq 'plain-list (car context)) ; First item in list | ||
858 | (and (eq 'item (car context)) | ||
859 | (not (eq (org-element-property :contents-begin context) | ||
860 | (org-element-property :contents-end context)))) | ||
861 | ;; Element in list item, e.g. a link | ||
862 | (unpackaged/org-element-descendant-of 'item context)) | ||
863 | ;; Non-empty item: Add new item. | ||
864 | (org-insert-item) | ||
865 | ;; Empty item: Close the list. | ||
866 | ;; TODO: Do this with org functions rather than operating | ||
867 | ;; on the text. Can't seem to find the right function. | ||
868 | (delete-region (line-beginning-position) (line-end-position)) | ||
869 | (insert "\n")))) | ||
870 | |||
871 | ((when (fboundp 'org-inlinetask-in-task-p) | ||
872 | (org-inlinetask-in-task-p)) | ||
873 | ;; Inline task: Don't insert a new heading. | ||
874 | (org-return)) | ||
875 | |||
876 | ((org-at-table-p) | ||
877 | (cond ((save-excursion | ||
878 | (beginning-of-line) | ||
879 | ;; See `org-table-next-field'. | ||
880 | (cl-loop with end = (line-end-position) | ||
881 | for cell = (org-element-table-cell-parser) | ||
882 | always (equal (org-element-property :contents-begin cell) | ||
883 | (org-element-property :contents-end cell)) | ||
884 | while (re-search-forward "|" end t))) | ||
885 | ;; Empty row: end the table. | ||
886 | (delete-region (line-beginning-position) (line-end-position)) | ||
887 | (org-return)) | ||
888 | (t | ||
889 | ;; Non-empty row: call `org-return'. | ||
890 | (org-return)))) | ||
891 | (t | ||
892 | ;; All other cases: call `org-return'. | ||
893 | (org-return))))) | ||
894 | |||
895 | ;; org-fix-blank-lines (unpackaged) | ||
896 | (defun unpackaged/org-fix-blank-lines (&optional prefix) | ||
897 | "Ensure that blank lines exist between headings and between headings and their contents. | ||
898 | With prefix, operate on whole buffer. Ensures that blank lines | ||
899 | exist after each headings's drawers." | ||
900 | (interactive "P") | ||
901 | (org-map-entries (lambda () | ||
902 | (org-with-wide-buffer | ||
903 | ;; `org-map-entries' narrows the buffer, which prevents us | ||
904 | ;; from seeing newlines before the current heading, so we | ||
905 | ;; do this part widened. | ||
906 | (while (not (looking-back "\n\n" nil)) | ||
907 | ;; Insert blank lines before heading. | ||
908 | (insert "\n"))) | ||
909 | (let ((end (org-entry-end-position))) | ||
910 | ;; Insert blank lines before entry content | ||
911 | (forward-line) | ||
912 | (while (and (org-at-planning-p) | ||
913 | (< (point) (point-max))) | ||
914 | ;; Skip planning lines | ||
915 | (forward-line)) | ||
916 | (while (re-search-forward org-drawer-regexp end t) | ||
917 | ;; Skip drawers. You might think that `org-at-drawer-p' | ||
918 | ;; would suffice, but for some reason it doesn't work | ||
919 | ;; correctly when operating on hidden text. This | ||
920 | ;; works, taken from `org-agenda-get-some-entry-text'. | ||
921 | (re-search-forward "^[ \t]*:END:.*\n?" end t) | ||
922 | (goto-char (match-end 0))) | ||
923 | (unless (or (= (point) (point-max)) | ||
924 | (org-at-heading-p) | ||
925 | (looking-at-p "\n")) | ||
926 | (insert "\n")))) | ||
927 | t (if prefix | ||
928 | nil | ||
929 | 'tree))) | ||
930 | |||
931 | (defun hook--org-mode-fix-blank-lines () | ||
932 | (when (eq major-mode 'org-mode) | ||
933 | (let ((current-prefix-arg 4)) ; Emulate C-u | ||
934 | (call-interactively 'unpackaged/org-fix-blank-lines)))) | ||
935 | (add-hook 'before-save-hook #'hook--org-mode-fix-blank-lines) | ||
936 | |||
937 | (use-package org | ||
938 | :straight (:repo "https://code.orgmode.org/bzg/org-mode.git") | ||
939 | :init | ||
940 | (setq-default | ||
941 | org-directory "~/org" ; where to search for org files | ||
942 | ;; typesetting | ||
943 | org-hide-emphasis-markers t | ||
944 | org-fontify-whole-heading-line t | ||
945 | org-fontify-done-headline t | ||
946 | org-fontify-quote-and-verse-blocks t | ||
947 | org-src-fontify-natively t | ||
948 | org-ellipsis " ≡" | ||
949 | org-pretty-entities t | ||
950 | org-tags-column (- 0 fill-column (- (length org-ellipsis))) | ||
951 | ;; Source blocks | ||
952 | org-src-tab-acts-natively t | ||
953 | org-src-window-setup 'current-window | ||
954 | org-confirm-babel-evaluate nil | ||
955 | ;; Behavior | ||
956 | org-adapt-indentation t ; indent text after a header | ||
957 | org-catch-invisible-edits 'smart | ||
958 | org-special-ctrl-a/e t | ||
959 | org-special-ctrl-k t | ||
960 | org-imenu-depth 8 ; catch all headings | ||
961 | ;; Exporting | ||
962 | org-export-headline-levels 8 ; export all headings | ||
963 | org-export-with-smart-quotes t | ||
964 | org-export-with-sub-superscripts t | ||
965 | ;; Modules | ||
966 | org-modules '(;; default (commented if unused) | ||
967 | ;; bbdb | ||
968 | ;; bibtex | ||
969 | ;; docview | ||
970 | eww | ||
971 | ;; gnus | ||
972 | info | ||
973 | ;; irc | ||
974 | ;; mhe | ||
975 | ;; rmail | ||
976 | ;; w3m | ||
977 | ;; extra stuff for me | ||
978 | ;; habit ; track your consistency with habits | ||
979 | ;; inlinetask ; tasks independent of outline hierarchy | ||
980 | mouse ; additional mouse support | ||
981 | ;; protocol ; intercept calls from emacsclient | ||
982 | ;; man | ||
983 | tempo ; templates | ||
984 | ) | ||
985 | org-export-backends '(;; defaults | ||
986 | ascii | ||
987 | html | ||
988 | latex | ||
989 | odt | ||
990 | ;; added by me | ||
991 | man | ||
992 | md | ||
993 | ) | ||
994 | ) | ||
995 | :config | ||
996 | (require 'org-tempo) | ||
997 | (require 'ox-md) | ||
998 | :bind (:map org-mode-map | ||
999 | ("RET" . unpackaged/org-return-dwim))) | ||
1000 | |||
1001 | (use-package goto-addr | ||
1002 | :straight nil | ||
1003 | :config | ||
1004 | (goto-address-mode +1)) | ||
1005 | |||
1006 | (use-package web-mode | ||
1007 | :mode (("\\.phtml\\'" . web-mode) | ||
1008 | ("\\.tpl\\.php\\'" . web-mode) | ||
1009 | ("\\.[agj]sp\\'" . web-mode) | ||
1010 | ("\\as[cp]x\\'" . web-mode) | ||
1011 | ("\\.erb\\'" . web-mode) | ||
1012 | ("\\.mustache\\'" . web-mode) | ||
1013 | ("\\.djhtml\\'" . web-mode) | ||
1014 | ("\\.html?\\'" . web-mode))) | ||