summaryrefslogtreecommitdiff
path: root/.emacs.d
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d')
-rw-r--r--.emacs.d/emacs.org896
1 files changed, 382 insertions, 514 deletions
diff --git a/.emacs.d/emacs.org b/.emacs.d/emacs.org
index dfcbcaa..c564e7f 100644
--- a/.emacs.d/emacs.org
+++ b/.emacs.d/emacs.org
@@ -3,17 +3,10 @@
#+auto_tangle: t
#+OPTIONS: num:nil toc:nil
-* Table of contents
-:PROPERTIES:
-:TOC: :include all
-:END:
-:CONTENTS:
-- [[#table-of-contents][Table of contents]]
+* Table of contents :TOC:
- [[#setting-up-packages][Setting up Packages]]
- [[#setup-for-guixsd-machines][Setup for GuixSD machines]]
- [[#define-and-install-packages][Define and install packages]]
- - [[#list-of-required-packages][List of required packages]]
- - [[#installation--activation][Installation & activation]]
- [[#ui-settings][UI Settings]]
- [[#basic-ui][Basic UI]]
- [[#dashboard][Dashboard]]
@@ -26,25 +19,20 @@
- [[#terminals][Terminals]]
- [[#vterm][Vterm]]
- [[#eshell][Eshell]]
-- [[#key-bindings][Key-bindings]]
-- [[#functions][Functions]]
-- [[#mu4e--email-configuration][mu4e | Email Configuration]]
-- [[#custom-key-bindings][Custom key-bindings]]
- - [[#general][General]]
- - [[#hydra][Hydra]]
+- [[#custom][Custom]]
+ - [[#chatgpt][ChatGPT]]
+ - [[#random-functions][Random functions]]
+ - [[#key-bindings][Key-bindings]]
- [[#org-mode-configuration][Org-mode Configuration]]
- [[#org-make-toc][org-make-toc]]
- [[#themes][Themes]]
- - [[#dracula][Dracula]]
- - [[#darkone][Darkone]]
- [[#settings][Settings]]
- [[#babel][Babel]]
- [[#markdown][Markdown]]
- [[#theme][Theme]]
- - [[#settings][Settings]]
+ - [[#settings-1][Settings]]
- [[#programming][Programming]]
- [[#essentials][Essentials]]
- - [[#magit][Magit]]
- [[#emacs-lisp][Emacs lisp]]
- [[#lsp-mode][LSP-Mode]]
- [[#python][Python]]
@@ -52,14 +40,11 @@
- [[#javascript][Javascript]]
- [[#elfeed][Elfeed]]
- [[#feeds][Feeds]]
- - [[#settings][Settings]]
+ - [[#settings-2][Settings]]
- [[#pdf][PDF]]
- [[#telega][Telega]]
-- [[#custom][Custom]]
- - [[#chatgpt][ChatGPT]]
- - [[#random-functions][Random functions]]
+- [[#mu4e--email-configuration][mu4e | Email Configuration]]
- [[#exwm][EXWM]]
-:END:
* Setting up Packages
** Setup for GuixSD machines
@@ -76,52 +61,53 @@ we use ~guix-emacs-autoload-packages~ to load emacs packages installed using gui
*** List of required packages
Request the following packages:
#+begin_src emacs-lisp
-(defconst my-package-list '(org-snooze
- all-the-icons
- all-the-icons-dired
- all-the-icons-ivy-rich
- general
- doom-themes
- doom-modeline
- counsel
- which-key
- ivy
- ivy-rich
- helpful
- org
- org-modern
- visual-fill-column
- rainbow-delimiters
- flycheck
- lsp-mode
- lsp-ui
- json-mode
- rjsx-mode
- typescript-mode
- python-mode
- pyvenv
- company
- company-box
- magit
- elfeed
- elfeed-goodies
- paredit
- corfu
- monkeytype
- sudo-edit
- exwm
- exwm-mff
- exwm-firefox-core
- consult
- alsamixer
- simple-httpd
- circe
- eshell-syntax-highlighting
- pdf-tools
- org-superstar
- mastodon
- dashboard
- org-auto-tangle))
+ (defconst my-package-list '(org-snooze
+ all-the-icons
+ all-the-icons-dired
+ all-the-icons-ivy-rich
+ toc-org
+ general
+ doom-themes
+ doom-modeline
+ counsel
+ which-key
+ ivy
+ ivy-rich
+ helpful
+ org
+ org-modern
+ visual-fill-column
+ rainbow-delimiters
+ flycheck
+ lsp-mode
+ lsp-ui
+ json-mode
+ rjsx-mode
+ typescript-mode
+ python-mode
+ pyvenv
+ company
+ company-box
+ magit
+ elfeed
+ elfeed-goodies
+ paredit
+ corfu
+ monkeytype
+ sudo-edit
+ exwm
+ exwm-mff
+ exwm-firefox-core
+ consult
+ alsamixer
+ simple-httpd
+ circe
+ eshell-syntax-highlighting
+ pdf-tools
+ org-superstar
+ mastodon
+ dashboard
+ org-auto-tangle))
#+end_src
*** Installation & activation
Set our ~package-archives~, and install our packages
@@ -408,40 +394,203 @@ Hook with ~dired-mode~
#+end_src
** Eshell
#+begin_src emacs-lisp
-(use-package eshell
- :ensure t
- :bind (("C-c e" . 'eshell))
- :config
- (defvar eshell-path-env (getenv "~/.local/bin")))
-
-(defun with-face (str &rest face-plist)
- (propertize str 'face face-plist))
-
-(defun apollo-eshell-prompt ()
- (let ((winter-blue "#3F3B6C")
- (white-summer "#E5E5CB")
- (green-night "#03C988")
- (orange-summer "#FFB100")
- (green-summer "#A3BB98")
- (summer-sea "#2192FF")
- (black "#000000"))
- (concat
- (with-face (concat "[" user-login-name) :foreground orange-summer :background black)
- (with-face "@" :foreground orange-summer :background black)
- (with-face (concat system-name "]\n") :foreground orange-summer :background black)
- (with-face (concat "|" (eshell/pwd) ) :foreground "#F0E9D2" :background winter-blue)
- (with-face (format-time-string " | %H:%M" (current-time)) :background winter-blue :foreground "#888")
- (with-face "\n -> "))))
-
-(setq eshell-prompt-function 'apollo-eshell-prompt)
-(setq eshell-highlight-prompt t)
+ (use-package eshell
+ :ensure nil
+ :bind (("C-c e" . 'eshell))
+ :config
+ (defvar eshell-path-env (getenv "~/.local/bin")))
+
+ (defun with-face (str &rest face-plist)
+ (propertize str 'face face-plist))
+
+ (defun apollo-eshell-prompt ()
+ (let ((winter-blue "#3F3B6C")
+ (white-summer "#E5E5CB")
+ (green-night "#03C988")
+ (orange-summer "#FFB100")
+ (green-summer "#A3BB98")
+ (summer-sea "#2192FF")
+ (black "#000000"))
+ (concat
+ (with-face (concat "[" user-login-name) :foreground orange-summer :background black)
+ (with-face "@" :foreground orange-summer :background black)
+ (with-face (concat system-name "]\n") :foreground orange-summer :background black)
+ (with-face (concat "|" (eshell/pwd) ) :foreground "#F0E9D2" :background winter-blue)
+ (with-face (format-time-string " | %H:%M" (current-time)) :background winter-blue :foreground "#888")
+ (with-face "\n -> "))))
+
+ ;; (setq eshell-prompt-function 'apollo-eshell-prompt)
+ ;; (setq eshell-highlight-prompt t)
#+end_src
-* Key-bindings
+* Custom
+** ChatGPT
#+begin_src emacs-lisp
-(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
+ (require 'seq)
+ (eval-when-compile
+ (require 'cl-lib)
+ (require 'subr-x)
+ (require 'env)
+ (require 'json))
+ (defgroup chatgpt nil
+ "ChatGPT frontend."
+ :group 'convenience
+ :prefix "chatgpt-")
+ (defcustom chatgpt-max-tokens 300
+ "Upper limit on the number of tokens the API will return."
+ :type 'integer)
+ (defvar chatgpt-buffer "*ChatGPT*"
+ "Title of the buffer used to store the results of an OpenAI API query.")
+ (define-error 'chatgpt-error "An error related to the ChatGPT emacs package")
+ (define-error 'chatgpt-parsing-error
+ "An error caused by a failure to parse an OpenAI API Response")
+ (defmacro chatgpt-show-results-buffer-if-active ()
+ "Show the results in other window if necessary."
+ `(if (and (not ;; visible
+ (get-buffer-window chatgpt-buffer))
+ (called-interactively-p 'interactive))
+ (lambda (&optional buf) (ignore buf)
+ (with-current-buffer buf
+ (view-mode t))
+ (switch-to-buffer-other-window chatgpt-buffer))
+ #'identity))
+ ;;;###autoload
+ (defun chatgpt-prompt (prompt callback)
+ "Query OpenAI with PROMPT calling the CALLBACK function on the resulting buffer.
+ Returns buffer containing the text from this query"
+ (interactive (list (read-string "Prompt ChatGPT with: ")
+ (lambda (buf) (with-current-buffer buf
+ (view-mode t))
+ (switch-to-buffer-other-window chatgpt-buffer))))
+ (chatgpt--query-open-api prompt
+ (lambda (results)
+ (with-current-buffer (get-buffer-create chatgpt-buffer)
+ ;; Erase contents of buffer after receiving response
+ (read-only-mode -1)
+ (erase-buffer)
+ (insert results)
+ ;; Return the chatgpt output buffer for non interactive usage
+ (funcall callback (current-buffer))))))
+ ;;;###autoload
+ (defun chatgpt-fix-region (BEG END)
+ "Takes a region BEG to END asks ChatGPT to explain whats wrong with it.
+ It then displays the answer in the `chatgpt-buffer'."
+ (interactive "r")
+ (let ((current-code (buffer-substring BEG END)))
+ (chatgpt-prompt (chatgpt--append-to-prompt
+ current-code
+ "Why doesn't this code work?")
+ (chatgpt-show-results-buffer-if-active))))
+ ;;;###autoload
+ (defun chatgpt-explain-region (BEG END)
+ "Takes a region BEG to END asks ChatGPT what it does.
+ The answer in the displays in `chatgpt-buffer'."
+ (interactive "r")
+ (let ((current-code (buffer-substring BEG END)))
+ (chatgpt-prompt (chatgpt--append-to-prompt
+ current-code
+ "What does this code do?")
+ (chatgpt-show-results-buffer-if-active))))
+ ;;;###autoload
+ (defun chatgpt-gen-tests-for-region (BEG END)
+ "Takes a region BEG to END asks ChatGPT to write a test for it.
+ It then displays the answer in the `chatgpt-buffer'."
+ (interactive "r")
+ (let ((current-code (buffer-substring BEG END)))
+ (chatgpt-prompt (chatgpt--append-to-prompt
+ current-code
+ "Write me a tests for this code")
+ (chatgpt-show-results-buffer-if-active))))
+ ;; TODO currently just says what changed but doesn't wanna show the code it's self
+ ;; (defun chatgpt-optimize-region (BEG END)
+ ;; "Takes a region BEG to END asks ChatGPT to optimize it for speed.
+ ;; It then displays the answer in the `chatgpt-buffer'."
+ ;; (interactive "r")
+ ;; (let ((current-code (buffer-substring BEG END)))
+ ;; (chatgpt-prompt (chatgpt--append-to-prompt
+ ;; current-code
+ ;; "Refactor this code for speed and tell me what you changed and why it's faster")
+ ;; (chatgpt-show-results-buffer-if-active))))
+ ;;;###autoload
+ (defun chatgpt-refactor-region (BEG END)
+ "Takes a region BEG to END asks ChatGPT refactor it.
+ It then displays the answer in the `chatgpt-buffer'."
+ (interactive "r")
+ (let ((current-code (buffer-substring BEG END)))
+ (chatgpt-prompt (chatgpt--append-to-prompt
+ current-code
+ "Refactor this code and tell me what you changed")
+ (chatgpt-show-results-buffer-if-active))))
+ ;;;###autoload
+ (defun chatgpt-prompt-region (BEG END)
+ "Prompt ChatGPT with the region BEG END.
+ It then displays the results in a separate buffer `chatgpt-buffer'."
+ (interactive "r")
+ (chatgpt-prompt (buffer-substring BEG END)
+ ;; Show the results if not already being viewed
+ (chatgpt-show-results-buffer-if-active)))
+ ;;;###autoload
+ (defun chatgpt-prompt-region-and-replace (BEG END)
+ "Replace region from BEG to END with the response from the ChatGPT API.
+ The region is BEG and until END"
+ (interactive "r")
+ (let ((og-buf (current-buffer)))
+ (chatgpt-prompt (buffer-substring BEG END)
+ (lambda (buf)
+ (save-excursion
+ (with-current-buffer og-buf
+ (delete-region BEG END)
+ (goto-char BEG)
+ (insert (with-current-buffer buf (buffer-string)))))))))
+ (defun chatgpt--append-to-prompt (prompt comment-str)
+ "Append the string COMMENT-STR extra information to a PROMPT as a comment."
+ (concat prompt
+ "\n"
+ comment-start
+ " "
+ comment-str))
+ (defun chatgpt--extract-text-from-query (query-result)
+ "Extract the resulting text from a given OpenAI response QUERY-RESULT."
+ (condition-case err
+ (thread-last query-result
+ (assoc-default 'choices)
+ seq-first
+ (assoc-default 'text)
+ string-trim)
+ (error
+ (signal 'chatgpt-parsing-error err))))
+ (defun chatgpt--parse-response (status callback)
+ "Ignoring STATUS and parse the response executing the CALLBACK function on the resulting string."
+ (ignore status)
+ ;; All this is ran inside the buffer containing the response
+ (goto-char 0)
+ (re-search-forward "^$")
+ (funcall callback (chatgpt--extract-text-from-query (json-read))))
+ (defun chatgpt--query-open-api (prompt callback)
+ "Send a string PROMPT to OpenAI API and pass the resulting buffer to CALLBACK.
+ The environment variable OPENAI_API_KEY is used as your API key
+ You can register an account here
+ https://beta.openai.com/docs/introduction/key-concepts"
+ (let* ((api-key (getenv secret-api))
+ (url-request-method (encode-coding-string "POST" 'us-ascii))
+ (url-request-extra-headers `(("Content-Type" . "application/json")
+ ("Authorization" . ,(format "Bearer %s" api-key))))
+ (url-request-data (json-encode
+ `(("model" . "text-davinci-003")
+ ("prompt" . ,prompt)
+ ("max_tokens" . ,chatgpt-max-tokens)
+ ("temperature" . 0)))))
+ (cl-assert (not (string= "" api-key))
+ t
+ "Current contents of the environmental variable OPENAI_API_KEY
+ are '%s' which is not an appropriate OpenAI token please ensure
+ you have the correctly set the OPENAI_API_KEY variable"
+ api-key)
+ (url-retrieve
+ "https://api.openai.com/v1/completions"
+ 'chatgpt--parse-response
+ (list callback))))
#+end_src
-
-* Functions
+** Random functions
#+begin_src emacs-lisp
(defun apollo/html-boostrap-boilerplate ()
"Insert html boilerplate with boostrap link."
@@ -521,22 +670,6 @@ Hook with ~dired-mode~
(interactive)
(start-process-shell-command
"setxkbmap" nil "setxkbmap gr"))
-
-(defun apollo/exwm-init-hook ()
- "Do this upon start."
- (display-battery-mode 0) ;;Change to 1 to display battery
-
- (setq display-time-day-and-date t)
- (display-time-mode 1)
-
- ;;Launch apps that will run in the background
-;; (apollo/run-in-background "blueman-applet")
- (apollo/run-in-background "picom")
-;; (apollo/run-in-background "nm-applet")
- (apollo/emacs-keys)
- (apollo/set-wallpaper)
- (start-polybar)
- )
(defun apollo/exwm-update-class ()
(exwm-workspace-rename-buffer exwm-class-name))
@@ -546,11 +679,6 @@ Hook with ~dired-mode~
(interactive)
(eshell 'N))
-(defun make-mini-buffer ()
- (interactive)
- (split-window-below 40)
- (other-window 1))
-
(defun make-mini-geiser ()
(interactive)
(split-window-below 60)
@@ -565,141 +693,11 @@ Hook with ~dired-mode~
(start-process-shell-command
"polybar" nil "polybar main")))
#+end_src
-* mu4e | Email Configuration
-
-# ** MacOS
-# If it's a mac, load from homebrew path
-
-# #+begin_src emacs-lisp
-# (when (equal system-type 'darwin)
-# (use-package mu4e
-# :load-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e/"))
-# #+end_src
-
+** Key-bindings
#+begin_src emacs-lisp
-(when (equal system-type 'darwin)
- (use-package mu4e
- :load-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e/"))
-
-(require 'mu4e)
-
-(setq mu4e-update-interval (* 10 60))
-(setq mu4e-get-mail-command "mbsync -a")
-(setq mu4e-maildir-list "~/Mail/Inbox")
-
-(defun set-mu4e-context (context-name full-name mail-address signature server)
- "Return a mu4e context named CONTEXT-NAME with :match-func matching
- folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
- `user-full-name' and `mu4e-compose-signature'`smtpmail-smpt-server' is set to MAIL-ADDRESS
- FULL-NAME SIGNATURE and SERVER respectively.
- Special folders are set to context specific folders."
- (let ((dir-name (concat "/" context-name)))
- (make-mu4e-context
- :name context-name
- ;; we match based on the maildir of the message
- :match-func
- `(lambda (msg)
- (when msg
- (string-match-p
- ,(concat "^" dir-name)
- (mu4e-message-field msg :maildir))))
- :vars
- `((user-mail-address . ,mail-address)
- (user-full-name . ,full-name)
- (mu4e-sent-folder . ,(concat dir-name "/Sent"))
- (mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
- (mu4e-trash-folder . ,(concat dir-name "/Trash"))
- (mu4e-trash-folder . ,(concat dir-name "/Starred"))
- (mu4e-refile-folder . ,(concat dir-name "/Archive"))
- (smtpmail-smtp-service . ,465)
- (smtpmail-smtp-server . ,server)
- (mu4e-compose-signature . ,signature)))))
-;;Fixing duplicate UID errors when using mbsync and mu4e
-(setq mu4e-change-filenames-when-moving t)
-
-(setq mu4e-maildir-shortcuts
- '(("/Fastmail/Inbox" . ?i)
- ("/Fastmail/Sent" . ?s)
- ;; ("/Gmail/Trash" . ?t)
- ;; ("/Gmail/Drafts" . ?d)
- ;; ("/Gmail/[Gmail]/All Mail" . ?a
- ))
-
-(setq mu4e-contexts
- `(, (set-mu4e-context
- "Fastmail" "Thanos Apollo"
- "[email protected]" "Thanos\nhttps://thanosapollo.com/public"
- "smtp.fastmail.com")))
-
-;; (setq smtpmail-smtp-service 465
-;; smtpmail-stream-type 'ssl
-;; smtpmail-smtp-server "smtp.fastmail.com")
-
-
-
-(setq message-send-mail-function 'smtpmail-send-it
- smtpmail-stream-type 'ssl)
-
+(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
#+end_src
-
-# ** Settings & Context setup
-# #+begin_src emacs-lisp
-# (require 'mu4e)
-# (setq mu4e-update-interval (* 10 60))
-# (setq mu4e-get-mail-command "mbsync -a")
-# (setq mu4e-maildir-list "~/Mail/Inbox")
-
-# (defun set-mu4e-context (context-name full-name mail-address signature server)
-# "Return a mu4e context named CONTEXT-NAME with :match-func matching
-# folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
-# `user-full-name' and `mu4e-compose-signature'`smtpmail-smpt-server' is set to MAIL-ADDRESS
-# FULL-NAME SIGNATURE and SERVER respectively.
-# Special folders are set to context specific folders."
-# (let ((dir-name (concat "/" context-name)))
-# (make-mu4e-context
-# :name context-name
-# ;; we match based on the maildir of the message
-# :match-func
-# `(lambda (msg)
-# (when msg
-# (string-match-p
-# ,(concat "^" dir-name)
-# (mu4e-message-field msg :maildir))))
-# :vars
-# `((user-mail-address . ,mail-address)
-# (user-full-name . ,full-name)
-# (mu4e-sent-folder . ,(concat dir-name "/Sent"))
-# (mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
-# (mu4e-trash-folder . ,(concat dir-name "/Trash"))
-# (mu4e-trash-folder . ,(concat dir-name "/Starred"))
-# (mu4e-refile-folder . ,(concat dir-name "/Archive"))
-# (smtpmail-smtp-service . ,465)
-# (smtpmail-smtp-server . ,server)
-# (mu4e-compose-signature . ,signature)))))
-
-# ;;Fixing duplicate UID errors when using mbsync and mu4e
-# (setq mu4e-change-filenames-when-moving t)
-# ;; Messaging
-# (setq message-send-mail-function 'smtpmail-send-it
-# smtpmail-stream-type 'ssl)
-# #+end_src
-# ** Shortcuts
-# #+begin_src emacs-lisp
-# (setq mu4e-maildir-shortcuts
-# '(("/Fastmail/Inbox" . ?i)
-# ("/Fastmail/Sent" . ?s)
-# ))
-# #+end_src
-# ** Contexts
-# #+begin_src emacs-lisp
-# (setq mu4e-contexts
-# `(, (set-mu4e-context
-# "Fastmail" "Thanos Apollo"
-# "[email protected]" "Thanos\nhttps://thanosapollo.com/public"
-# "smtp.fastmail.com")))
-# #+end_src
-* Custom key-bindings
-** General
+*** General
#+begin_src emacs-lisp
;; my general's leader key!
@@ -756,7 +754,7 @@ Hook with ~dired-mode~
:keymaps 'org-mode-map
"3" 'org-insert-image-size-300)
#+end_src
-** Hydra
+*** Hydra
#+begin_src emacs-lisp
(defhydra hydra-zoom (global-map "s-z")
"zoom"
@@ -850,23 +848,31 @@ Hook with ~dired-mode~
;; Hooks
(add-hook 'org-mode-hook 'apollo/org-theme-dracula)
(add-hook 'org-mode-hook 'org-superstar-mode)
- (add-hook 'org-mode-hook 'flyspell-mode)
+ (add-hook 'org-mode-hook 'flyspell-mode)
+ (add-hook 'org-mode-hook 'toc-org-mode)
#+end_src
** Babel
+
#+begin_src emacs-lisp
+ (defadvice org-edit-src-code (around set-buffer-file-name activate compile)
+ (let ((file-name (buffer-file-name))) ;; (1)
+ ad-do-it ;; (2)
+ (setq buffer-file-name file-name))) ;; (3)
+
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)))
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
- (add-to-list 'org-structure-template-alist '("b" . "src shell"))
+ (add-to-list 'org-structure-template-alist '("b" . "src bash"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
;;Auto tangle
(add-hook 'org-mode-hook 'org-auto-tangle-mode)
#+end_src
+
* Markdown
** Theme
#+begin_src emacs-lisp
@@ -1027,277 +1033,139 @@ In macOS, I have installed it through homebrew.
(setq telega-server-libs-prefix "/opt/homebrew/Cellar/tdlib/HEAD-3d0140b")))
#+end_src
-* Custom
-** ChatGPT
-#+begin_src emacs-lisp
-(require 'seq)
-(eval-when-compile
- (require 'cl-lib)
- (require 'subr-x)
- (require 'env)
- (require 'json))
-(defgroup chatgpt nil
- "ChatGPT frontend."
- :group 'convenience
- :prefix "chatgpt-")
-(defcustom chatgpt-max-tokens 300
- "Upper limit on the number of tokens the API will return."
- :type 'integer)
-(defvar chatgpt-buffer "*ChatGPT*"
- "Title of the buffer used to store the results of an OpenAI API query.")
-(define-error 'chatgpt-error "An error related to the ChatGPT emacs package")
-(define-error 'chatgpt-parsing-error
- "An error caused by a failure to parse an OpenAI API Response")
-(defmacro chatgpt-show-results-buffer-if-active ()
- "Show the results in other window if necessary."
- `(if (and (not ;; visible
- (get-buffer-window chatgpt-buffer))
- (called-interactively-p 'interactive))
- (lambda (&optional buf) (ignore buf)
- (with-current-buffer buf
- (view-mode t))
- (switch-to-buffer-other-window chatgpt-buffer))
- #'identity))
-;;;###autoload
-(defun chatgpt-prompt (prompt callback)
- "Query OpenAI with PROMPT calling the CALLBACK function on the resulting buffer.
-Returns buffer containing the text from this query"
- (interactive (list (read-string "Prompt ChatGPT with: ")
- (lambda (buf) (with-current-buffer buf
- (view-mode t))
- (switch-to-buffer-other-window chatgpt-buffer))))
- (chatgpt--query-open-api prompt
- (lambda (results)
- (with-current-buffer (get-buffer-create chatgpt-buffer)
- ;; Erase contents of buffer after receiving response
- (read-only-mode -1)
- (erase-buffer)
- (insert results)
- ;; Return the chatgpt output buffer for non interactive usage
- (funcall callback (current-buffer))))))
-;;;###autoload
-(defun chatgpt-fix-region (BEG END)
- "Takes a region BEG to END asks ChatGPT to explain whats wrong with it.
-It then displays the answer in the `chatgpt-buffer'."
- (interactive "r")
- (let ((current-code (buffer-substring BEG END)))
- (chatgpt-prompt (chatgpt--append-to-prompt
- current-code
- "Why doesn't this code work?")
- (chatgpt-show-results-buffer-if-active))))
-;;;###autoload
-(defun chatgpt-explain-region (BEG END)
- "Takes a region BEG to END asks ChatGPT what it does.
-The answer in the displays in `chatgpt-buffer'."
- (interactive "r")
- (let ((current-code (buffer-substring BEG END)))
- (chatgpt-prompt (chatgpt--append-to-prompt
- current-code
- "What does this code do?")
- (chatgpt-show-results-buffer-if-active))))
-;;;###autoload
-(defun chatgpt-gen-tests-for-region (BEG END)
- "Takes a region BEG to END asks ChatGPT to write a test for it.
-It then displays the answer in the `chatgpt-buffer'."
- (interactive "r")
- (let ((current-code (buffer-substring BEG END)))
- (chatgpt-prompt (chatgpt--append-to-prompt
- current-code
- "Write me a tests for this code")
- (chatgpt-show-results-buffer-if-active))))
-;; TODO currently just says what changed but doesn't wanna show the code it's self
-;; (defun chatgpt-optimize-region (BEG END)
-;; "Takes a region BEG to END asks ChatGPT to optimize it for speed.
-;; It then displays the answer in the `chatgpt-buffer'."
-;; (interactive "r")
-;; (let ((current-code (buffer-substring BEG END)))
-;; (chatgpt-prompt (chatgpt--append-to-prompt
-;; current-code
-;; "Refactor this code for speed and tell me what you changed and why it's faster")
-;; (chatgpt-show-results-buffer-if-active))))
-;;;###autoload
-(defun chatgpt-refactor-region (BEG END)
- "Takes a region BEG to END asks ChatGPT refactor it.
-It then displays the answer in the `chatgpt-buffer'."
- (interactive "r")
- (let ((current-code (buffer-substring BEG END)))
- (chatgpt-prompt (chatgpt--append-to-prompt
- current-code
- "Refactor this code and tell me what you changed")
- (chatgpt-show-results-buffer-if-active))))
-;;;###autoload
-(defun chatgpt-prompt-region (BEG END)
- "Prompt ChatGPT with the region BEG END.
-It then displays the results in a separate buffer `chatgpt-buffer'."
- (interactive "r")
- (chatgpt-prompt (buffer-substring BEG END)
- ;; Show the results if not already being viewed
- (chatgpt-show-results-buffer-if-active)))
-;;;###autoload
-(defun chatgpt-prompt-region-and-replace (BEG END)
- "Replace region from BEG to END with the response from the ChatGPT API.
-The region is BEG and until END"
- (interactive "r")
- (let ((og-buf (current-buffer)))
- (chatgpt-prompt (buffer-substring BEG END)
- (lambda (buf)
- (save-excursion
- (with-current-buffer og-buf
- (delete-region BEG END)
- (goto-char BEG)
- (insert (with-current-buffer buf (buffer-string)))))))))
-(defun chatgpt--append-to-prompt (prompt comment-str)
- "Append the string COMMENT-STR extra information to a PROMPT as a comment."
- (concat prompt
- "\n"
- comment-start
- " "
- comment-str))
-(defun chatgpt--extract-text-from-query (query-result)
- "Extract the resulting text from a given OpenAI response QUERY-RESULT."
- (condition-case err
- (thread-last query-result
- (assoc-default 'choices)
- seq-first
- (assoc-default 'text)
- string-trim)
- (error
- (signal 'chatgpt-parsing-error err))))
-(defun chatgpt--parse-response (status callback)
- "Ignoring STATUS and parse the response executing the CALLBACK function on the resulting string."
- (ignore status)
- ;; All this is ran inside the buffer containing the response
- (goto-char 0)
- (re-search-forward "^$")
- (funcall callback (chatgpt--extract-text-from-query (json-read))))
-(defun chatgpt--query-open-api (prompt callback)
- "Send a string PROMPT to OpenAI API and pass the resulting buffer to CALLBACK.
-The environment variable OPENAI_API_KEY is used as your API key
-You can register an account here
-https://beta.openai.com/docs/introduction/key-concepts"
- (let* ((api-key (getenv secret-api))
- (url-request-method (encode-coding-string "POST" 'us-ascii))
- (url-request-extra-headers `(("Content-Type" . "application/json")
- ("Authorization" . ,(format "Bearer %s" api-key))))
- (url-request-data (json-encode
- `(("model" . "text-davinci-003")
- ("prompt" . ,prompt)
- ("max_tokens" . ,chatgpt-max-tokens)
- ("temperature" . 0)))))
- (cl-assert (not (string= "" api-key))
- t
- "Current contents of the environmental variable OPENAI_API_KEY
-are '%s' which is not an appropriate OpenAI token please ensure
-you have the correctly set the OPENAI_API_KEY variable"
- api-key)
- (url-retrieve
- "https://api.openai.com/v1/completions"
- 'chatgpt--parse-response
- (list callback))))
-#+end_src
-** Random functions
-#+begin_src emacs-lisp
-(defun apollo/html-boostrap-boilerplate ()
- "Insert html boilerplate with boostrap link."
- (interactive)
- (insert
-"<!DOCTYPE html>
-<html lang=\"en\">
- <head>
- <meta charset=\"UTF-8\">
- <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
- <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">
- <title>My Title</title>
- <link rel=\"stylesheet\" href=\"./style.css\">
- <link href=\"https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi\" crossorigin=\"anonymous\">
- </head>
- <body>
- <main>
- <h1>Starting point</h1>
- </main>
- <script src=\"index.js\"></script>
- </body>
-</html>" ))
-
+* mu4e | Email Configuration
-(defun apollo/center-buffer ()
- "Centers/Uncenters selected buffer"
- (interactive)
- (if visual-fill-column-center-text
- (setq visual-fill-column-center-text nil)
- (setq visual-fill-column-center-text t))
- (visual-fill-column-mode 1)
- (message "General's task completed!"))
+# ** MacOS
+# If it's a mac, load from homebrew path
+# #+begin_src emacs-lisp
+# (when (equal system-type 'darwin)
+# (use-package mu4e
+# :load-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e/"))
+# #+end_src
-(defun apollo/rofi-switch-window ()
- "Navigate X11 buffers using rofi."
- (interactive)
- (start-process-shell-command
- "rofi" nil "rofi -show window"))
+#+begin_src emacs-lisp
+(when (equal system-type 'darwin)
+ (use-package mu4e
+ :load-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e/"))
-(defun apollo/run-in-background (command)
- "Run COMMAND in the background."
- (let ((command-parts (split-string command "[ ]+")))
- (apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
+(require 'mu4e)
-(defun rofi ()
- "Run Rofi."
- (interactive)
- (apollo/run-in-background "rofi -show drun"))
+(setq mu4e-update-interval (* 10 60))
+(setq mu4e-get-mail-command "mbsync -a")
+(setq mu4e-maildir-list "~/Mail/Inbox")
-(defun apollo/volume-increase ()
- "Increase Volume."
- (interactive)
- (start-process-shell-command
- "amixer" nil "amixer sset Master 5%+"))
+(defun set-mu4e-context (context-name full-name mail-address signature server)
+ "Return a mu4e context named CONTEXT-NAME with :match-func matching
+ folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
+ `user-full-name' and `mu4e-compose-signature'`smtpmail-smpt-server' is set to MAIL-ADDRESS
+ FULL-NAME SIGNATURE and SERVER respectively.
+ Special folders are set to context specific folders."
+ (let ((dir-name (concat "/" context-name)))
+ (make-mu4e-context
+ :name context-name
+ ;; we match based on the maildir of the message
+ :match-func
+ `(lambda (msg)
+ (when msg
+ (string-match-p
+ ,(concat "^" dir-name)
+ (mu4e-message-field msg :maildir))))
+ :vars
+ `((user-mail-address . ,mail-address)
+ (user-full-name . ,full-name)
+ (mu4e-sent-folder . ,(concat dir-name "/Sent"))
+ (mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
+ (mu4e-trash-folder . ,(concat dir-name "/Trash"))
+ (mu4e-trash-folder . ,(concat dir-name "/Starred"))
+ (mu4e-refile-folder . ,(concat dir-name "/Archive"))
+ (smtpmail-smtp-service . ,465)
+ (smtpmail-smtp-server . ,server)
+ (mu4e-compose-signature . ,signature)))))
+;;Fixing duplicate UID errors when using mbsync and mu4e
+(setq mu4e-change-filenames-when-moving t)
-(defun apollo/volume-decrease ()
- "Decrease Volume."
- (interactive)
- (start-process-shell-command
- "amixer" nil "amixer sset Master 5%-"))
+(setq mu4e-maildir-shortcuts
+ '(("/Fastmail/Inbox" . ?i)
+ ("/Fastmail/Sent" . ?s)
+ ;; ("/Gmail/Trash" . ?t)
+ ;; ("/Gmail/Drafts" . ?d)
+ ;; ("/Gmail/[Gmail]/All Mail" . ?a
+ ))
-(defun apollo/restore-wallpaper ()
- "Set NAME as wallpaper."
- (interactive)
- (start-process-shell-command
- "feh" nil "feh --bg-scale ~/dotfiles/wallpaper.png"))
+(setq mu4e-contexts
+ `(, (set-mu4e-context
+ "Fastmail" "Thanos Apollo"
+ "[email protected]" "Thanos\nhttps://thanosapollo.com/public"
+ "smtp.fastmail.com")))
-(defun apollo/emacs-keys ()
- "Swap caps with ctrl."
- (interactive)
- (start-process-shell-command
- "setxkbmap" nil "setxkbmap us -option ctrl:swapcaps"))
+;; (setq smtpmail-smtp-service 465
+;; smtpmail-stream-type 'ssl
+;; smtpmail-smtp-server "smtp.fastmail.com")
-(defun apollo/greek-keyboard ()
- "Swap caps with ctrl."
- (interactive)
- (start-process-shell-command
- "setxkbmap" nil "setxkbmap gr"))
-
-(defun apollo/exwm-update-class ()
- (exwm-workspace-rename-buffer exwm-class-name))
-(defun eshell-new()
- "Open a new instance of eshell."
- (interactive)
- (eshell 'N))
-(defun make-mini-geiser ()
- (interactive)
- (split-window-below 60)
- (geiser nil))
+(setq message-send-mail-function 'smtpmail-send-it
+ smtpmail-stream-type 'ssl)
-(defun start-polybar ()
- "Check which system is running, start polybar accordingly."
- (interactive)
- (if (string= (system-name) "fsociety")
- (start-process-shell-command
- "polybar" nil "polybar main & polybar second")
- (start-process-shell-command
- "polybar" nil "polybar main")))
#+end_src
+
+# ** Settings & Context setup
+# #+begin_src emacs-lisp
+# (require 'mu4e)
+# (setq mu4e-update-interval (* 10 60))
+# (setq mu4e-get-mail-command "mbsync -a")
+# (setq mu4e-maildir-list "~/Mail/Inbox")
+
+# (defun set-mu4e-context (context-name full-name mail-address signature server)
+# "Return a mu4e context named CONTEXT-NAME with :match-func matching
+# folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
+# `user-full-name' and `mu4e-compose-signature'`smtpmail-smpt-server' is set to MAIL-ADDRESS
+# FULL-NAME SIGNATURE and SERVER respectively.
+# Special folders are set to context specific folders."
+# (let ((dir-name (concat "/" context-name)))
+# (make-mu4e-context
+# :name context-name
+# ;; we match based on the maildir of the message
+# :match-func
+# `(lambda (msg)
+# (when msg
+# (string-match-p
+# ,(concat "^" dir-name)
+# (mu4e-message-field msg :maildir))))
+# :vars
+# `((user-mail-address . ,mail-address)
+# (user-full-name . ,full-name)
+# (mu4e-sent-folder . ,(concat dir-name "/Sent"))
+# (mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
+# (mu4e-trash-folder . ,(concat dir-name "/Trash"))
+# (mu4e-trash-folder . ,(concat dir-name "/Starred"))
+# (mu4e-refile-folder . ,(concat dir-name "/Archive"))
+# (smtpmail-smtp-service . ,465)
+# (smtpmail-smtp-server . ,server)
+# (mu4e-compose-signature . ,signature)))))
+
+# ;;Fixing duplicate UID errors when using mbsync and mu4e
+# (setq mu4e-change-filenames-when-moving t)
+# ;; Messaging
+# (setq message-send-mail-function 'smtpmail-send-it
+# smtpmail-stream-type 'ssl)
+# #+end_src
+# ** Shortcuts
+# #+begin_src emacs-lisp
+# (setq mu4e-maildir-shortcuts
+# '(("/Fastmail/Inbox" . ?i)
+# ("/Fastmail/Sent" . ?s)
+# ))
+# #+end_src
+# ** Contexts
+# #+begin_src emacs-lisp
+# (setq mu4e-contexts
+# `(, (set-mu4e-context
+# "Fastmail" "Thanos Apollo"
+# "[email protected]" "Thanos\nhttps://thanosapollo.com/public"
+# "smtp.fastmail.com")))
+# #+end_src
* EXWM
EXWM configuration is tangled with ~.exwm~
+ In GuixSD ~emacs-exwm~ package will look for ~~/.exwm~