diff options
Diffstat (limited to 'emacs/init.el')
-rw-r--r-- | emacs/init.el | 820 |
1 files changed, 369 insertions, 451 deletions
diff --git a/emacs/init.el b/emacs/init.el index 1654c22..c9599c4 100644 --- a/emacs/init.el +++ b/emacs/init.el @@ -71,37 +71,33 @@ (setopt confirm-nonexistent-file-or-buffer 'after-completion) -(defun noa/mode-line-modified () - (cond - (buffer-read-only "RO") - ((buffer-modified-p) "**") - (t "RW"))) - ;;; Replace the mode line with a header line ;; First, we set the mode line to nil. On my graphical display, this collapses it so all i get is a thin black line separating the buffer from the echo area. (setq-default mode-line-format nil) + ;; But the mode line still holds some useful information that i want to see. I would rather that be in the header line, because to me it makes sense for this kind of metadata to be /above/ the buffer it is describing. -(setq-default header-line-format '( - ;; First, in white on black text, i want the information about the state of the file. This will show three hyphens in the top left corner of the header line. The first two hyphens mean that the file is both writable and unchanged. If the buffer has been changed, they will change to two asterisks. If the buffer is read only, they will change two percentage symbols. And if the buffer is read only and has been changed, the first will change to a percentage symbol, and the second will change to an asterisk. The final hyphen represents that the file is local, specifically that the default-directory variable is local. If it is remote, an at symbol will be displayed instead. - (:propertize - ("" mode-line-modified mode-line-remote) - face highlight - ) - ;; Next, we want to display the buffer name. For buffers which belong to files, this will usually be the file name, but it is likely to be something more informative for special buffers. - " %b" - ;; Below that, show a line and column coördinate. There are special minor modes that will enable or disable this for the default mode line, but i ignore that and put the formatting code here directly. The docstring for the mode-line-format variable suggests that the column might not be displayed correctly in some situations without enabling the minor mode, but i haven't noticed that yet so i don't bother. This column number is zero-indexed; a capital c would make it one-indexed. For now i stick with zero-indexed as that's the emacs default and i'm not sure which is better. I guess it makes a bit more sense that the first character on a line is labeled "1". - ":%l,%c" - " " - ;; I don't know exactly what this variable covers, so i keep it here so that if something shows up i know that it gets put here. Because i have a global mode line in my tab bar, some of the things that would otherwise be here (like the time, battery percentage, and notifications for chat buffers) don't show up. - mode-line-misc-info - mode-line-end-spaces - ) -) + +;; First, in white on black text, i want the information about the state of the file. This will show three hyphens in the top left corner of the header line. The first two hyphens mean that the file is both writable and unchanged. If the buffer has been changed, they will change to two asterisks. If the buffer is read only, they will change two percentage symbols. And if the buffer is read only and has been changed, the first will change to a percentage symbol, and the second will change to an asterisk. The final hyphen represents that the file is local, specifically that the default-directory variable is local. If it is remote, an at symbol will be displayed instead. + +;; Next, we want to display the buffer name. For buffers which belong to files, this will usually be the file name, but it is likely to be something more informative for special buffers. + +;; Below that, show a line and column coördinate. There are special minor modes that will enable or disable this for the default mode line, but i ignore that and put the formatting code here directly. The docstring for the mode-line-format variable suggests that the column might not be displayed correctly in some situations without enabling the minor mode, but i haven't noticed that yet so i don't bother. This column number is zero-indexed; a capital c would make it one-indexed. For now i stick with zero-indexed as that's the emacs default and i'm not sure which is better. I guess it makes a bit more sense that the first character on a line is labeled "1". + +;; I don't know exactly what the final variable covers, so i keep it here so that if something shows up i know that it gets put here. Because i have a global mode line in my tab bar, some of the things that would otherwise be here (like the time, battery percentage, and notifications for chat buffers) don't show up. +(setq-default header-line-format + '((:propertize + ("" mode-line-modified mode-line-remote) + face highlight) + " %b" + ":%l,%c" + " " + mode-line-misc-info + mode-line-end-spaces)) (defun pulse-line (&rest _) - "Pulse the current line." - (pulse-momentary-highlight-one-line (point))) + "Pulse the current line." + (pulse-momentary-highlight-one-line (point))) (dolist (command '(scroll-up-command scroll-down-command recenter-top-bottom other-window)) (advice-add command :after #'pulse-line)) @@ -157,8 +153,8 @@ and when JID is not in `jabber-activity-banned'." (keymap-global-set "C-c C-j" #'jabber-activity-switch-to) (use-package nov - :ensure t - :mode ("\\.epub\\'" . nov-mode)) + :ensure t + :mode ("\\.epub\\'" . nov-mode)) @@ -217,121 +213,113 @@ and when JID is not in `jabber-activity-banned'." (setopt completion-in-region-function 'consult-completion-in-region) (use-package org-contacts - :ensure t - :pin gnu - :custom - (org-contacts-files org-agenda-files) - ;; Org contacts seems to require birthdays to have a year. However, i don't know the year of a lot of people's birthdays, so i set the year to 0000. This looks bad when the birthday comes up in the agenda. I figured that i don't usually need to know how old someone is going to be, so i change the format of how the birthday appears in the agenda so that i don't get the wrong age. - (org-contacts-birthday-format "Birthday: %l") - - - ) + :ensure t + :pin gnu + :custom + (org-contacts-files org-agenda-files) + ;; Org contacts seems to require birthdays to have a year. However, i don't know the year of a lot of people's birthdays, so i set the year to 0000. This looks bad when the birthday comes up in the agenda. I figured that i don't usually need to know how old someone is going to be, so i change the format of how the birthday appears in the agenda so that i don't get the wrong age. + (org-contacts-birthday-format "Birthday: %l")) ;; select the help window so that i can easily close it again with q (setopt help-window-select t) (use-package helpful - :ensure t - :bind ( - ([remap describe-function] . helpful-callable) - ([remap describe-variable] . helpful-variable) - ([remap describe-key] . helpful-key) - ([remap describe-command] . helpful-command) - ("C-c C-d" . helpful-at-point) - ("C-h F" . helpful-function) - )) + :ensure t + :bind ( + ([remap describe-function] . helpful-callable) + ([remap describe-variable] . helpful-variable) + ([remap describe-key] . helpful-key) + ([remap describe-command] . helpful-command) + ("C-c C-d" . helpful-at-point) + ("C-h F" . helpful-function))) (use-package window - :custom - (switch-to-buffer-obey-display-actions t)) + :custom + (switch-to-buffer-obey-display-actions t)) (use-package org-fc - :disabled - :ensure t - :custom - (org-fc-directories (expand-file-name "~/data/notes/"))) + :disabled + :ensure t + :custom + (org-fc-directories (expand-file-name "~/data/notes/"))) (use-package artbollocks-mode - :disabled t - :ensure t) + :disabled t + :ensure t) (use-package org - :custom - (org-use-sub-superscripts "{}") - ;; If we enable this, emphasis markers will be hidden for a more word processor feel. This has the downside of meaning you have to delete a hidden character to get rid of bold or italic text. I don't have much of a problem with seeing the emphasis markers so i'm willing to put up with any aesthetic shortcomings for a better user experience. The package org-appear solves this by hiding them, but showing them when the point is over them, but i don't think having a whole package just for that is worth it. - (org-hide-emphasis-markers nil) - (org-startup-with-inline-images t) - (org-image-actual-width '(300)) - (org-auto-align-tags nil) - (org-tags-column 0) - (org-catch-invisible-edits 'show-and-error) - (org-special-ctrl-a/e t) - (org-insert-heading-respect-content t) - (org-ellipsis "…") - (org-display-custom-times t) - (org-time-stamp-custom-formats '("%Y-%m-%d" . "%Y-%m-%d %H:%M")) - (org-extend-today-until 4) - (org-adapt-indentation nil) - (org-log-done 'time) - (org-return-follows-link t) - (org-agenda-files '("~/data/notes/notes.org")) - (org-capture-templates `(("j" "Journal" entry (file+datetree "~/data/notes/notes.org") "* %?\n" :empty-lines 1) - ("w" "Website" entry (file+datetree "~/data/notes/notes.org") "* %a\n%?\n" :empty-lines 1) - ("c" "Contact" entry (file+datetree "~/data/notes/notes.org") - "* %^{Name} + :custom + (org-use-sub-superscripts "{}") + ;; If we enable this, emphasis markers will be hidden for a more word processor feel. This has the downside of meaning you have to delete a hidden character to get rid of bold or italic text. I don't have much of a problem with seeing the emphasis markers so i'm willing to put up with any aesthetic shortcomings for a better user experience. The package org-appear solves this by hiding them, but showing them when the point is over them, but i don't think having a whole package just for that is worth it. + (org-hide-emphasis-markers nil) + (org-startup-with-inline-images t) + (org-image-actual-width '(300)) + (org-auto-align-tags nil) + (org-tags-column 0) + (org-catch-invisible-edits 'show-and-error) + (org-special-ctrl-a/e t) + (org-insert-heading-respect-content t) + (org-ellipsis "…") + (org-display-custom-times t) + (org-time-stamp-custom-formats '("%Y-%m-%d" . "%Y-%m-%d %H:%M")) + (org-extend-today-until 4) + (org-adapt-indentation nil) + (org-log-done 'time) + (org-return-follows-link t) + (org-agenda-files '("~/data/notes/notes.org")) + (org-capture-templates `(("j" "Journal" entry (file+datetree "~/data/notes/notes.org") "* %?\n" :empty-lines 1) + ("w" "Website" entry (file+datetree "~/data/notes/notes.org") "* %a\n%?\n" :empty-lines 1) + ("c" "Contact" entry (file+datetree "~/data/notes/notes.org") + "* %^{Name} :PROPERTIES: :ADDRESS: %^{Address} :BIRTHDAY: %^{yyyy-mm-dd} :EMAIL: %^{EMAIL}p :NOTE: %^{NOTE} :END:" -:empty-lines 1))) - - (org-agenda-tags-column t) - (org-agenda-block-separator ?─) - (org-agenda-time-grid - '((daily today require-timed) - (800 1000 1200 1400 1600 1800 2000) - " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")) - (org-agenda-current-time-string - "◀── now ─────────────────────────────────────────────────") - - :custom-face - ;;(org-ellipsis ((t (:inherit default :box nil)))) - - :bind (("C-c c" . org-capture) - ("C-c a" . org-agenda)) -) + :empty-lines 1))) + + (org-agenda-tags-column t) + (org-agenda-block-separator ?─) + (org-agenda-time-grid + '((daily today require-timed) + (800 1000 1200 1400 1600 1800 2000) + " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")) + (org-agenda-current-time-string + "◀── now ─────────────────────────────────────────────────") + + :custom-face + ;;(org-ellipsis ((t (:inherit default :box nil)))) + + :bind (("C-c c" . org-capture) + ("C-c a" . org-agenda))) (use-package org-modern - :ensure t - :after org - :hook - (org-mode . org-modern-mode) - (org-agenda-finalize . org-modern-agenda) - :custom - ;; There are three ways to make bullet lists in org mode, which seems a bit excessive to me. I almost always only use the hyphen, but i like my bullet points to look like bullets, so here i overwrite the hyphen display to show a bullet point. While i'm at it, i overwrite the others too, because they are functionally identical so should probably look the same too. - (org-modern-list '( - (?+ . " • ") - (?- . " • ") - (?* . " • ") - )) - (org-modern-timestamp nil) - (org-modern-star nil) - (org-modern-keyword nil) - (org-modern-checkbox '((88 . "☑") - (45 . - #("□–" 0 2 - (composition - ((2))))) - (32 . "□"))) - (org-modern-table nil)) + :ensure t + :after org + :hook (org-mode . org-modern-mode) + (org-agenda-finalize . org-modern-agenda) + :custom + ;; There are three ways to make bullet lists in org mode, which seems a bit excessive to me. I almost always only use the hyphen, but i like my bullet points to look like bullets, so here i overwrite the hyphen display to show a bullet point. While i'm at it, i overwrite the others too, because they are functionally identical so should probably look the same too. + (org-modern-list '((?+ . " • ") + (?- . " • ") + (?* . " • "))) + (org-modern-timestamp nil) + (org-modern-star nil) + (org-modern-keyword nil) + (org-modern-checkbox '((88 . "☑") + (45 . + #("□–" 0 2 + (composition + ((2))))) + (32 . "□"))) + (org-modern-table nil)) (defun read-file-as-string (filename) - "Read file contents from FILENAME." - (with-temp-buffer - (insert-file-contents filename) - (buffer-string))) + "Read file contents from FILENAME." + (with-temp-buffer + (insert-file-contents filename) + (buffer-string))) (setq noa/website-header (read-file-as-string "/home/noa/projects/org-website/templates/header.html")) (setq noa/website-footer (read-file-as-string "/home/noa/projects/org-website/templates/footer.html")) @@ -339,31 +327,19 @@ and when JID is not in `jabber-activity-banned'." ;; The index page generation functions were taken from Dennis Ogbe. Thank you! (defun my-blog-parse-sitemap-list (l) - "Convert the sitemap list in to a list of filenames." - ;; LIST looks like: - ;; (unordered ("[[file:uses.org][Things i use]]") ("[[file:media.org][Media Diary]]") ("[[file:tanklobsters.org][Tank lobsters]]")) - (mapcar - #'(lambda (i) - (let - ( - (link (with-temp-buffer ( - let ( - (org-inhibit-startup nil) - ) - (insert (car i)) - (org-mode) - (goto-char (point-min)) - (org-element-link-parser) - ))) - ) - (when link - (plist-get (cadr link) :path) - ) - ) - ) - (cdr l) - ) -) + "Convert the sitemap list in to a list of filenames." + ;; LIST looks like: + ;; (unordered ("[[file:uses.org][Things i use]]") ("[[file:media.org][Media Diary]]") ("[[file:tanklobsters.org][Tank lobsters]]")) + (mapcar #'(lambda (i) + (let ((link (with-temp-buffer + (let ((org-inhibit-startup nil)) + (insert (car i)) + (org-mode) + (goto-char (point-min)) + (org-element-link-parser))))) + (when link + (plist-get (cadr link) :path)))) + (cdr l))) (defun my-blog-sort-article-list (l p) "sort the article list anti-chronologically." @@ -373,115 +349,97 @@ and when JID is not in `jabber-activity-banned'." (not (time-less-p date-a date-b)))))) (defun noa/naive-org-first-paragraph (file) - "Naively returns the first paragraph of FILE. + "Naively returns the first paragraph of FILE. The way that the first paragraph is determined is to assume that there will be an org metadata block beforehand, so look for the first two consecutive newlines and mark the following paragraph." - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (re-search-forward "\n\n") - (mark-paragraph) - (let - ( - (beg (mark)) - (end (point)) - ) - (buffer-substring beg end)))) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (re-search-forward "\n\n") + (mark-paragraph) + (let ((beg (mark)) + (end (point))) + (buffer-substring beg end)))) (defun noa/website-sitemap (title list) - "Generate the index page for my website." - ;; LIST looks like: - ;; (unordered ("[[file:uses.org][Things i use]]") ("[[file:media.org][Media Diary]]") ("[[file:tanklobsters.org][Tank lobsters]]")) - (with-temp-buffer - ;; mangle the parsed list given to us into a plain lisp list of files - (let* - ( - (filenames (my-blog-parse-sitemap-list list)) - (project-plist (assoc "website-pages" org-publish-project-alist)) - (articles (my-blog-sort-article-list filenames project-plist)) - ) - (message (concat "PLIST: " (plist-get project-plist :base-directory))) - - (insert "Several parts of this website are broken as i wrangle with the monstrosity that is programming in emacs lisp. The content should still be fine, but for further cosmetics please hold <3\n\n") - (dolist (file filenames) - (let* - ( - (abspath (file-name-concat "/home/noa/data/share" file)) - ;; (abspath (file-name-concat (plist-get project-plist :base-directory) file)) - (relpath (file-relative-name abspath "/home/noa/data/share")) - (title (org-publish-find-title file project-plist)) - (date (format-time-string (car org-time-stamp-formats) (org-publish-find-date file project-plist))) - (preview (noa/naive-org-first-paragraph abspath)) - ) - (insert (concat "* [[file:" relpath "][" title "]]\n")) - (insert (concat - "*" date ":*" - preview - )) - (insert "\n") - ;; (insert (concat "[[file:" relpath "][Read More...]]\n")) - ) - ) - ;; insert a title and save - (insert "#+TITLE: noa.pub\n") - (buffer-string) - ) - ) -) - -(setq org-publish-project-alist `( - ("website" - :components ("website-pages" "website-assets")) - ("website-pages" - :publishing-function org-html-publish-to-html - :base-directory "/home/noa/data/share" - :publishing-directory "/home/noa/projects/org-website" - :base-extension "org" - - :section-numbers nil - :with-toc nil - :with-drawers t - :with-sub-superscript t - :html-link-home "/" - :html-head "<link rel=\"icon\" href=\"data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>𰻝</text></svg>\">" - :html-head-include-default-style nil - :html-head-include-scripts nil - :html-doctype "html5" - ;; :html-validation-link nil - - :html-preamble "" - :html-postamble ,noa/website-footer - - :html-home/up-format "" - :html-link-up "" - - :html-html5-fancy t - :html-indent t - - :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"love.css\" /> + "Generate the index page for my website." + ;; LIST looks like: + ;; (unordered ("[[file:uses.org][Things i use]]") ("[[file:media.org][Media Diary]]") ("[[file:tanklobsters.org][Tank lobsters]]")) + (with-temp-buffer + ;; mangle the parsed list given to us into a plain lisp list of files + (let* ((filenames (my-blog-parse-sitemap-list list)) + (project-plist (assoc "website-pages" org-publish-project-alist)) + (articles (my-blog-sort-article-list filenames project-plist))) + (message (concat "PLIST: " (plist-get project-plist :base-directory))) + + (insert "Several parts of this website are broken as i wrangle with the monstrosity that is programming in emacs lisp. The content should still be fine, but for further cosmetics please hold <3\n\n") + (dolist (file filenames) + (let* ((abspath (file-name-concat "/home/noa/data/share" file)) + ;; (abspath (file-name-concat (plist-get project-plist :base-directory) file)) + (relpath (file-relative-name abspath "/home/noa/data/share")) + (title (org-publish-find-title file project-plist)) + (date (format-time-string (car org-time-stamp-formats) (org-publish-find-date file project-plist))) + (preview (noa/naive-org-first-paragraph abspath))) + (insert (concat "* [[file:" relpath "][" title "]]\n")) + (insert (concat + "*" date ":*" + preview)) + (insert "\n"))) + ;; insert a title and save + (insert "#+TITLE: noa.pub\n") + (buffer-string)))) + +(setq org-publish-project-alist + `(("website" + :components ("website-pages" "website-assets")) + ("website-pages" + :publishing-function org-html-publish-to-html + :base-directory "/home/noa/data/share" + :publishing-directory "/home/noa/projects/org-website" + :base-extension "org" + + :section-numbers nil + :with-toc nil + :with-drawers t + :with-sub-superscript t + :html-link-home "/" + :html-head "<link rel=\"icon\" href=\"data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>𰻝</text></svg>\">" + :html-head-include-default-style nil + :html-head-include-scripts nil + :html-doctype "html5" + ;; :html-validation-link nil + + :html-preamble "" + :html-postamble ,noa/website-footer + + :html-home/up-format "" + :html-link-up "" + + :html-html5-fancy t + :html-indent t + + :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"love.css\" /> <meta name=\"color-scheme\" content=\"light dark\">" - :html-divs ( - (preamble "header" "") - (content "main" "") - (postamble "footer" "")) - - :auto-sitemap t - :sitemap-filename "/home/noa/projects/org-website/index.org" - :sitemap-title "noa.pub" - :sitemap-style list - ;; :sitemap-format-entry - :sitemap-function noa/website-sitemap - :sitemap-sort-folders ignore - :sitemap-sort-files anti-chronologically - :sitemap-ignore-case t - ) - ("website-assets" - :publishing-function org-publish-attachment - :base-directory "/home/noa/data/share" - :publishing-directory "/home/noa/projects/org-website" - :base-extension "css\\|js\\|png|\\jpg" - :recursive t))) + :html-divs ((preamble "header" "") + (content "main" "") + (postamble "footer" "")) + + :auto-sitemap t + :sitemap-filename "/home/noa/projects/org-website/index.org" + :sitemap-title "noa.pub" + :sitemap-style list + ;; :sitemap-format-entry + :sitemap-function noa/website-sitemap + :sitemap-sort-folders ignore + :sitemap-sort-files anti-chronologically + :sitemap-ignore-case t) + ("website-assets" + :publishing-function org-publish-attachment + :base-directory "/home/noa/data/share" + :publishing-directory "/home/noa/projects/org-website" + :base-extension "css\\|js\\|png|\\jpg" + :recursive t))) ;;; Make wide windows narrow with visual-fill-column (use-package visual-fill-column :ensure t) @@ -528,32 +486,30 @@ and when JID is not in `jabber-activity-banned'." (add-hook 'text-mode-hook #'abbrev-mode) -(use-package eldoc - :delight - :custom - (global-eldoc-mode t)) +(use-package eldoc) +(setopt global-eldoc-mode t) ;; use a bar cursor and blink it and don't stop blinking it. i don't know how i feel about this yet to be honest, but it helps me know which window is active so for now i'm keeping it (setopt - cursor-type 'bar - blink-cursor-mode -1 - blink-cursor-interval 0.7) + cursor-type 'bar + blink-cursor-mode -1 + blink-cursor-interval 0.7) ;; Dired is a really nice package which, as with a lot of emacs, has some dodgy defaults. Here we round off some of the sharp edges to make it more enjoyable to use. (use-package dired - :custom - ;; By default, dired permanently deletes files. But i have quite a bit of storage and also make bad decisions regularly, so it seems fitting to make use of the wonderful invention that is the trash. People who have used systems from the last forty years or so will likely be familiar with this innovation. - (delete-by-moving-to-trash t) - ;; It's not fun to be asked every time whether we want to delete a directory recursively. It's an understandable default for safety reasons, but because we are not deleting permanently but rather just moving to the trash, it's not such a concern. - (dired-recursive-deletes 'always) - ;; Recursive copying isn't even destructive, so i definitely don't want to be asked about that. - (dired-recursive-copies 'always) - ;; After we delete some files or directories, it makes sense to get rid of any buffers which are looking at those files or directories. - (dired-clean-up-buffers-too nil) - ;; With this set, if we have two dired buffers open next to one another, a rename operation in one will default to the directory shown in the other. In this way, we can pretend we are using some kind of norton commander like file browser instead of slumming it in emacs. - (dired-dwim-target t) - ;; These are some useful ls switches. We have to keep -l. To show dotfiles as well, we use -a. To sort numbers by number order instead of lumping together ones, twos, and so on, we use -v. Because we don't have colour, it's nice to have a clear indicator of what is a file and what is a directory, as well as other different things like symlinks which i never remember. By using -F, a forward slash is appended to every directory. And to get more easily understandable file sizes, we use -h, which will tell us the file size in kilobytes or megabytes rather than a huge number that means nothing to me. I won't explain the meaning of the long flag. - (dired-listing-switches "-alvFh --group-directories-first")) + :custom + ;; By default, dired permanently deletes files. But i have quite a bit of storage and also make bad decisions regularly, so it seems fitting to make use of the wonderful invention that is the trash. People who have used systems from the last forty years or so will likely be familiar with this innovation. + (delete-by-moving-to-trash t) + ;; It's not fun to be asked every time whether we want to delete a directory recursively. It's an understandable default for safety reasons, but because we are not deleting permanently but rather just moving to the trash, it's not such a concern. + (dired-recursive-deletes 'always) + ;; Recursive copying isn't even destructive, so i definitely don't want to be asked about that. + (dired-recursive-copies 'always) + ;; After we delete some files or directories, it makes sense to get rid of any buffers which are looking at those files or directories. + (dired-clean-up-buffers-too nil) + ;; With this set, if we have two dired buffers open next to one another, a rename operation in one will default to the directory shown in the other. In this way, we can pretend we are using some kind of norton commander like file browser instead of slumming it in emacs. + (dired-dwim-target t) + ;; These are some useful ls switches. We have to keep -l. To show dotfiles as well, we use -a. To sort numbers by number order instead of lumping together ones, twos, and so on, we use -v. Because we don't have colour, it's nice to have a clear indicator of what is a file and what is a directory, as well as other different things like symlinks which i never remember. By using -F, a forward slash is appended to every directory. And to get more easily understandable file sizes, we use -h, which will tell us the file size in kilobytes or megabytes rather than a huge number that means nothing to me. I won't explain the meaning of the long flag. + (dired-listing-switches "-alvFh --group-directories-first")) ;;; Indentation: tabs and whitespace settings @@ -612,13 +568,13 @@ and when JID is not in `jabber-activity-banned'." (setopt echo-keystrokes 0.1) ;; A useful feature when programming is to show matching parentheses. Show-paren-mode is a global mode. By default it runs in all buffers except those inheriting from special mode. -(setopt - show-paren-mode t - ;; This variable means that if there is no non-whitespace character in between the point and the paren, it will be highlighted. It's useful to highlight parentheses if the point is at the start of the line and the paren is indented. - show-paren-when-point-in-periphery t - ;; By default, the point has to be after a paren for it to be highlighted. But often the point will be just inside, in which case it's also helpful for the pair to be highlighted. - show-paren-when-point-inside-paren t -) +(setopt show-paren-mode t) + +;; This variable means that if there is no non-whitespace character in between the point and the paren, it will be highlighted. It's useful to highlight parentheses if the point is at the start of the line and the paren is indented. +(setopt show-paren-when-point-in-periphery t) + +;; By default, the point has to be after a paren for it to be highlighted. But often the point will be just inside, in which case it's also helpful for the pair to be highlighted. +(setopt show-paren-when-point-inside-paren t) ;; populate and enable the context menu ;; (setopt context-menu-functions '( @@ -629,45 +585,22 @@ and when JID is not in `jabber-activity-banned'." ;; goto-address-context-menu) ;; context-menu-mode t) (use-package mouse - :custom - (context-menu-mode nil)) - -(defun noa/helpline () - (concat - "[C-x C-f] Open \t" - "[M-w] copy \t" - "[C-w] Cut \t" - "[C-s] search \t" - "[C-x C-s] Save \t" - "[C-y] Paste \t" - "[C-/] Undo \t" - "[M-x] Command \t" - ) -) - -(use-package tab-bar - :custom - (tab-bar-mode t) - (tab-bar-format '( - ;; noa/helpline - tab-bar-format-menu-bar - tab-bar-format-align-right - tab-bar-format-global - )) -) - - -(use-package font-lock - :custom - (global-font-lock-mode t) - (font-lock-maximum-decoration nil)) + :custom + (context-menu-mode nil)) -(setopt - inhibit-startup-screen t - mouse-drag-and-drop-region nil - mouse-yank-at-point t - delete-selection-mode nil ;; deleting should be an explicit action - ) +(setopt tab-bar-mode t) +(setopt tab-bar-format '(tab-bar-format-menu-bar + tab-bar-format-align-right + tab-bar-format-global)) + +(setopt global-font-lock-mode t) +(setopt font-lock-maximum-decoration nil) + +(setopt inhibit-startup-screen t + mouse-drag-and-drop-region nil + mouse-yank-at-point t + ;; deleting should be an explicit action + delete-selection-mode nil) (global-set-key (kbd "C-t") 'tab-new) @@ -676,11 +609,11 @@ and when JID is not in `jabber-activity-banned'." (global-set-key (kbd "S-<down-mouse-1>") 'mouse-save-then-kill) ;;; packages -(setopt package-archives '( - ("gnu" . "https://elpa.gnu.org/packages/") - ("nongnu" . "https://elpa.nongnu.org/nongnu/") - ("melpa-stable" . "https://stable.melpa.org/packages/") - ("melpa" . "https://melpa.org/packages/"))) +(setopt package-archives + '(("gnu" . "https://elpa.gnu.org/packages/") + ("nongnu" . "https://elpa.nongnu.org/nongnu/") + ("melpa-stable" . "https://stable.melpa.org/packages/") + ("melpa" . "https://melpa.org/packages/"))) ;;; saving @@ -703,39 +636,34 @@ and when JID is not in `jabber-activity-banned'." (add-hook 'mouse-leave-buffer-hook (lambda () (interactive) (save-some-buffers t))) (use-package keyfreq - :ensure t - :custom - (keyfreq-mode t) - (keyfreq-autosave-mode t) -) + :ensure t + :custom + (keyfreq-mode t) + (keyfreq-autosave-mode t)) ;; C-l goes in order (setopt recenter-positions '(top middle bottom)) ;; Emacs uses choppy scrolling by default. If i scoll with my trackpad, it's nice to have it move tiny amounts at the same time as my fingers, which pixel-scroll-precision-mode allows for. This also has the benefit of making scrolling over images a little bit of a nicer experience. (setopt - pixel-scroll-precision-mode t - pixel-scroll-precision-use-momentum t) + pixel-scroll-precision-mode t + pixel-scroll-precision-use-momentum t) (use-package smartscan - :bind ( - ("M-n" . smartscan-symbol-go-forward) - ("M-p" . smartscan-symbol-go-backward) - ("<down-mouse-3>" . nil) - ("<mouse-3>" . smartscan-symbol-go-forward) - ) -) + :bind (("M-n" . smartscan-symbol-go-forward) + ("M-p" . smartscan-symbol-go-backward) + ("<down-mouse-3>" . nil) + ("<mouse-3>" . smartscan-symbol-go-forward))) ;;; sentences (setopt sentence-end-double-space nil) ;;; spellcheck (setopt - flyspell-mode t - ispell-program-name "aspell" - ispell-dictionary "en_GB" - ispell-extra-args '("--sug-mode=ultra") -) + flyspell-mode t + ispell-program-name "aspell" + ispell-dictionary "en_GB" + ispell-extra-args '("--sug-mode=ultra")) ;; If i write a script, i will always run chmod +x after saving it. This command means i don't have to do that. @@ -744,86 +672,79 @@ and when JID is not in `jabber-activity-banned'." ;; We are on a unix system, so it makes sense to end files in the unix system way. I'm surprised this isn't the default. (setopt require-final-newline t) -(setopt - window-min-height 1 - window-combination-resize t - window-resize-pixelwise t - frame-resize-pixelwise t) +(setopt window-min-height 1 + window-combination-resize t + window-resize-pixelwise t + frame-resize-pixelwise t) ;;; history -(setopt - history-length 250 - kill-ring-max 25) - +(setopt history-length 250 + kill-ring-max 25) + (use-package savehist - :custom - (savehist-file "~/.config/emacs/savehist") - (savehist-additional-variables '( - kill-ring - command-history - set-variable-value-history - custom-variable-history - query-replace-history - read-expression-history - minibuffer-history - read-char-history - face-name-history - bookmark-history - file-name-history)) - (savehist-mode t)) + :custom + (savehist-file "~/.config/emacs/savehist") + (savehist-additional-variables + '(kill-ring + command-history + set-variable-value-history + custom-variable-history + query-replace-history + read-expression-history + minibuffer-history + read-char-history + face-name-history + bookmark-history + file-name-history)) + (savehist-mode t)) (use-package frame - :custom - (window-divider-mode t) - (window-divider-default-right-width 1) - (window-divider-default-bottom-width 1) - (window-divider-default-places t) - ) + :custom + (window-divider-mode t) + (window-divider-default-right-width 1) + (window-divider-default-bottom-width 1) + (window-divider-default-places t)) (use-package emacs - :init - ;; Add prompt indicator to `completing-read-multiple'. - ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma. - (defun crm-indicator (args) - (cons (format "[CRM%s] %s" - (replace-regexp-in-string - "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" - crm-separator) - (car args)) - (cdr args))) - (advice-add #'completing-read-multiple :filter-args #'crm-indicator) - - ;; Do not allow the cursor in the minibuffer prompt - (setq minibuffer-prompt-properties - '(read-only t cursor-intangible t face minibuffer-prompt)) - (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) - - :custom - (display-battery-mode t) - (display-time-mode t) - (display-time-default-load-average nil) - (display-time-24hr-format t) - - ;; Support opening new minibuffers from inside existing minibuffers. - (enable-recursive-minibuffers t) - (debug-on-error t) - - ;; Hide commands in M-x which do not work in the current mode. - (read-extended-command-predicate 'command-completion-default-include-p)) + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) -(setopt - recentf-max-menu-items 25 - recentf-save-file "~/.config/emacs/recentf" - recentf-mode 1 - bookmark-default-file "~/.config/emacs/bookmarks") + :custom + (display-battery-mode t) + (display-time-mode t) + (display-time-default-load-average nil) + (display-time-24hr-format t) + + ;; Support opening new minibuffers from inside existing minibuffers. + (enable-recursive-minibuffers t) + (debug-on-error t) + ;; Hide commands in M-x which do not work in the current mode. + (read-extended-command-predicate 'command-completion-default-include-p)) +(setopt recentf-max-menu-items 25 + recentf-save-file "~/.config/emacs/recentf" + recentf-mode 1 + bookmark-default-file "~/.config/emacs/bookmarks") -;;; miscellaneous -(setopt - save-place-mode 1) +;;; miscellaneous +(setopt save-place-mode 1) (setenv "PAGER" "cat") (setenv "TERM" "dumb") @@ -930,16 +851,16 @@ and when JID is not in `jabber-activity-banned'." (global-set-key (kbd "M-z") 'zap-up-to-char) (use-package markdown-mode - :ensure t - :mode ("\\.md\\'" . markdown-mode) - ) + :ensure t + :mode ("\\.md\\'" . markdown-mode)) + (use-package valign - :ensure t - :hook (markdown-mode . valign-mode) - :hook (org-mode . valign-mode) - :custom - (valign-fancy-bar t) - (valign-max-table-size 0)) + :ensure t + :hook (markdown-mode . valign-mode) + :hook (org-mode . valign-mode) + :custom + (valign-fancy-bar t) + (valign-max-table-size 0)) (use-package eat :ensure t @@ -995,13 +916,13 @@ and when JID is not in `jabber-activity-banned'." "Handle touch begining at input INPUT." (interactive "e") (let* ((event (nth 1 input)) - (pos-pixel (nth 3 event)) - (pos-char (nth 6 event)) - (win (nth 1 event))) + (pos-pixel (nth 3 event)) + (pos-char (nth 6 event)) + (win (nth 1 event))) ;; (message (format "%s" input)) (if (not (equal (selected-window) win)) - ;; switch window - (select-window win)) + ;; switch window + (select-window win)) ;; set globals (setq touchscreen-last-time (touchscreen-time)) (setq touchscreen-last-pos-pixel pos-pixel) @@ -1012,49 +933,46 @@ and when JID is not in `jabber-activity-banned'." "Handle touch update at input INPUT." (interactive "e") (let* ((event (nth 0 (nth 1 input))) - (pos-pixel (nth 3 event)) - (pos-char (nth 6 event)) - (diff-time (- (touchscreen-time) touchscreen-last-time)) - (diff-pixel (- (cdr touchscreen-last-pos-pixel) (cdr pos-pixel))) - (diff-char (abs (- touchscreen-begin-char pos-char)))) + (pos-pixel (nth 3 event)) + (pos-char (nth 6 event)) + (diff-time (- (touchscreen-time) touchscreen-last-time)) + (diff-pixel (- (cdr touchscreen-last-pos-pixel) (cdr pos-pixel))) + (diff-char (abs (- touchscreen-begin-char pos-char)))) (if (= (length (nth 1 input)) 2) - ;; pinch zoom - (let* ((event2 (nth 1 (nth 1 input))) - (pos-pixel2 (nth 3 event2)) - (dist (sqrt (+ (expt (- (car pos-pixel2) (car pos-pixel)) 2) - (expt (- (cdr pos-pixel2) (cdr pos-pixel)) 2)))) - (dist-diff (- dist touchscreen-last-dist))) - (setq touchscreen-last-dist dist) - (if (> dist-diff 0) - (text-scale-increase 0.1) - (if (< dist-diff 0) - (text-scale-decrease 0.1))) - ) - - (if (> diff-time 1) - ;; TODO: set marker on long press - (goto-char pos-char)) - (if (> diff-char 1) - ;; scroll - (progn - (move-to-window-line nil) - (if (> diff-pixel 0) - (pixel-scroll-pixel-up diff-pixel) - (if (< diff-pixel 0) - (pixel-scroll-pixel-down (* -1 diff-pixel)))) - (setq touchscreen-last-time (touchscreen-time)) - (setq touchscreen-last-pos-pixel pos-pixel)) - )))) + ;; pinch zoom + (let* ((event2 (nth 1 (nth 1 input))) + (pos-pixel2 (nth 3 event2)) + (dist (sqrt (+ (expt (- (car pos-pixel2) (car pos-pixel)) 2) + (expt (- (cdr pos-pixel2) (cdr pos-pixel)) 2)))) + (dist-diff (- dist touchscreen-last-dist))) + (setq touchscreen-last-dist dist) + (if (> dist-diff 0) + (text-scale-increase 0.1) + (if (< dist-diff 0) + (text-scale-decrease 0.1)))) + (if (> diff-time 1) + ;; TODO: set marker on long press + (goto-char pos-char)) + (if (> diff-char 1) + ;; scroll + (progn + (move-to-window-line nil) + (if (> diff-pixel 0) + (pixel-scroll-pixel-up diff-pixel) + (if (< diff-pixel 0) + (pixel-scroll-pixel-down (* -1 diff-pixel)))) + (setq touchscreen-last-time (touchscreen-time)) + (setq touchscreen-last-pos-pixel pos-pixel)))))) (defun touchscreen-handle-touch-end (input) "Handle touch end at input INPUT." (interactive "e") (let* ((event (nth 1 input)) - (pos-char (nth 6 event))) + (pos-char (nth 6 event))) (if (= touchscreen-begin-char pos-char) - ;; move cursor - (goto-char pos-char)))) + ;; move cursor + (goto-char pos-char)))) (global-set-key [touchscreen-begin] #'touchscreen-handle-touch-begin) (global-set-key [touchscreen-update] #'touchscreen-handle-touch-update) |