Skip to content

guilhermecomum/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

Welcome to my Emacs configuration, at a first glance Emacs seems like a text editor, but when you take time to play around, you will see it’s more than that. Took me a while to understand, and time to time I get surprise with their capabilities.

I use Emacs in my daily basis to work, organize my Life, programming in Javascript/Typescript, Elisp, Lua and Flutter.

As many Emacs users I update my configuration frequently with a new tool, new language or anything new I want to try.

I like to work with beautiful and fun environments, so I’m always trying to make Emacs prettier

Some screenshots

My Startup Screen ./screenshots/dashboard.png

Org Mode ./screenshots/org-mode.png

Typescript with autocomplete ./screenshots/typescript-autocomplete.png

Typescript erros ./screenshots/typescript-errors.png

References

The following list is from people I have been learning and stealing Emacs configuration ideas and chunks

Essentials

Sometimes there is a error on Emacs startup, so this following configs will enable to debug with some comfort.

(load-theme 'misterioso)

Mac OS

(when (eq system-type 'darwin)
  (add-to-list 'default-frame-alist '(undecorated . t))
  (setq mac-option-modifier 'alt)
  (setq mac-command-modifier 'meta)

  ;; Keys for visiting next & previous windows
  (global-set-key (kbd "<A-tab>") #'other-window)
  (global-set-key (kbd "<A-S-tab>")
                  #'(lambda () (interactive) (other-window -1)))

  ;; Keys for visiting next & previous frame
  (global-set-key (kbd "M-`") #'other-frame)
  (global-set-key (kbd "M-~") #'(lambda () (interactive) (other-frame -1)))

  ;; sets fn-delete to be right-delete
  (global-set-key [kp-delete] 'delete-char)
  (menu-bar-mode 1)

  ;; Enable mac option to create accented characters
  (setq ns-alternate-modifier 'none)
  (setq frame-resize-pixelwise t)
  (setq ns-left-alternate-modifier 'none))

Key mapping

Buffer/Window

Before kill a modified buffer, give option to see the diff Original code from here

(defun my/kill-this-buffer ()
  (interactive)
  (catch 'quit
    (save-window-excursion
      (let (done)
        (when (and buffer-file-name (buffer-modified-p))
          (while (not done)
            (let ((response (read-char-choice
                             (format "Save file %s? (y, n, d, q) " (buffer-file-name))
                             '(?y ?n ?d ?q))))
              (setq done (cond
                          ((eq response ?q) (throw 'quit nil))
                          ((eq response ?y) (save-buffer) t)
                          ((eq response ?n) (set-buffer-modified-p nil) t)
                          ((eq response ?d) (diff-buffer-with-file) nil))))))
        (kill-buffer (current-buffer))))))

(global-set-key [s-tab] 'next-buffer)
(global-set-key [S-s-iso-lefttab] 'previous-buffer)
(global-set-key ["M-{"] 'next-buffer)
(global-set-key ["M-}"] 'previous-buffer)


;; change window
(global-set-key [(C-tab)] 'other-window)
(global-set-key [(C-M-tab)] 'other-window)

;; Remap kill buffer to my/kill-this-buffer
(global-set-key (kbd "C-x k") 'my/kill-this-buffer)

;; Revert buffer
(global-set-key (kbd "C-<f5>") 'revert-buffer)

;; Go to scratch buffer
(global-set-key (kbd "<f2>") (lambda() (interactive)(switch-to-buffer "*scratch*")))

Code navigation

(global-set-key (kbd "M-g") 'goto-line)
(global-set-key (kbd "C-c s") 'sort-lines)

Editing

(global-set-key (kbd "C-c c") 'comment-region)
(global-set-key (kbd "C-c d") 'uncomment-region)

Conf

(global-set-key (kbd "<f6>") (lambda() (interactive)(find-file "~/.emacs.d/readme.org")))

Package manager

 (setq package-enable-at-startup nil)
 (defvar elpaca-installer-version 0.7)
 (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
 (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
 (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
 (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
				:ref nil
				:files (:defaults "elpaca-test.el" (:exclude "extensions"))
				:build (:not elpaca--activate-package)))
 (let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
	 (build (expand-file-name "elpaca/" elpaca-builds-directory))
	 (order (cdr elpaca-order))
	 (default-directory repo))
   (add-to-list 'load-path (if (file-exists-p build) build repo))
   (unless (file-exists-p repo)
     (make-directory repo t)
     (when (< emacs-major-version 28) (require 'subr-x))
     (condition-case-unless-debug err
	  (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
		   ((zerop (call-process "git" nil buffer t "clone"
					 (plist-get order :repo) repo)))
		   ((zerop (call-process "git" nil buffer t "checkout"
					 (or (plist-get order :ref) "--"))))
		   (emacs (concat invocation-directory invocation-name))
		   ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
					 "--eval" "(byte-recompile-directory \".\" 0 'force)")))
		   ((require 'elpaca))
		   ((elpaca-generate-autoloads "elpaca" repo)))
	      (progn (message "%s" (buffer-string)) (kill-buffer buffer))
	    (error "%s" (with-current-buffer buffer (buffer-string))))
	((error) (warn "%s" err) (delete-directory repo 'recursive))))
   (unless (require 'elpaca-autoloads nil t)
     (require 'elpaca)
     (elpaca-generate-autoloads "elpaca" repo)
     (load "./elpaca-autoloads")))
 (add-hook 'after-init-hook #'elpaca-process-queues)
 (elpaca `(,@elpaca-order))

 ;; Install use-package support
 (elpaca elpaca-use-package
   ;; Enable use-package :ensure support for Elpaca.
   (elpaca-use-package-mode))

 ;; Block until current queue processed.
 (elpaca-wait)

 ;;Turns off elpaca-use-package-mode current declaration
 ;;Note this will cause the declaration to be interpreted immediately (not deferred).
 ;;Useful for configuring built-in emacs features.
 (use-package emacs :ensure nil :config (setq ring-bell-function #'ignore))

General

;; Close all dired buffers after opening
(setq dired-kill-when-opening-new-dired-buffer t)

(defun dont-kill-scratch ()
  "This function doesn't let you kill scratch by mistake."
  (if (not (equal (buffer-name) "*scratch*"))
      t
    (bury-buffer)
    nil))
(add-hook 'kill-buffer-query-functions #'dont-kill-scratch)
;; Don't ask about variables and functions from .dir-locals
(advice-add 'risky-local-variable-p :override #'ignore)

(use-package ls-lisp
  :config
  (setq ls-lisp-dirs-first t
        ls-lisp-use-insert-directory-program nil))

Startup Performance

Make startup faster by reducing the frequency of garbage collection and then use a hook to measure Emacs startup time.

;; The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

Native Compilation

Silence compiler warnings as they can be pretty disruptive

(setq native-comp-async-report-warnings-errors nil)

Encoding

From Doom emacs Contrary to what many Emacs users have in their configs, you don’t need more than this to make UTF-8 the default coding system:

(set-language-environment "UTF-8")

Path

Load environment variables from the shell

;;(use-package add-node-modules-path)
(use-package exec-path-from-shell
  :ensure t
  :init (exec-path-from-shell-initialize)
  :config
  (setq exec-path-from-shell-variables '("GOPATH" "PATH" "MANPATH")))

Set the start point for the current buffer, this means if you will search for a file, the start point will be the default-directory value.

(setq default-directory "~/")

Startup Screen

(use-package dashboard
  :ensure t
  :config
  (setq dashboard-banner-logo-title "Olá, bem vindo ao Emacs"
        dashboard-startup-banner "~/.emacs.d/nyan-cat.png"
        dashboard-center-content t
        dashboard-agenda-release-buffers t
        dashboard-items '((projects . 5) (agenda . 5)))
  :init
  (add-hook 'elpaca-after-init-hook #'dashboard-open))

Keep .emacs.d clean

I don’t want a bunch of transient files showing up as untracked in the Git repo so I move them all to another location.

 (setq custom-file
	  (if (boundp 'server-socket-dir)
	      (expand-file-name "custom.el" server-socket-dir)
	    (expand-file-name (format "emacs-custom-%s.el" (user-uid)) temporary-file-directory)))
 (add-hook 'elpaca-after-init-hook (lambda () (load custom-file 'noerror)))


 (setq backup-directory-alist
	`((".*" . ,temporary-file-directory))
	auto-save-file-name-transforms
	`((".*" ,temporary-file-directory t))
	create-lockfiles nil)

 (setq tramp-auto-save-directory temporary-file-directory)

Emacs Server

Start the Emacs server from this instance so that all emacsclient calls are routed here. It’s required to be able to use Emacs as my dropdown terminal.

(server-start)

Look & Feel

Improve theme loading

Source: Reddit

(defadvice load-theme (before clear-previous-themes activate)
  "Clear existing theme settings instead of layering them"
  (mapc #'disable-theme custom-enabled-themes))

Theme

Doom Themes

(use-package doom-themes
  :ensure t
  :preface
  (setq
   doom-themes-treemacs-theme "doom-colors"
   light-theme "doom-oksolar-light"
   dark-theme "doom-material-dark")
  :init
  (load-theme (intern dark-theme) t)

  (defun gg-switch-theme()
    (interactive)
    (let* ((theme (car custom-enabled-themes))
           (change (if (string= theme light-theme) dark-theme light-theme)))
      (load-theme (intern change) t)
      (setq selected-theme change)
      (message "Theme switched from %s to %s" theme change)))
  (global-set-key (kbd "<f8>") 'gg-switch-theme)

  :config
  (doom-themes-neotree-config)
  (with-eval-after-load 'doom-themes
    (doom-themes-treemacs-config))
  (set-face-attribute 'default nil :font "Menlo 13")
  (set-face-attribute 'region nil :background "#000" :foreground "#ffffff"))

Neotree

(defun text-scale-twice ()
  (interactive)
  (progn(text-scale-adjust 0)(text-scale-decrease 2)))

(use-package neotree
  :ensure t
  :bind([f9] . neotree-toggle)
  :hook (neo-after-create . (lambda (_)(call-interactively 'text-scale-twice)))
  :config
  (setq neo-autorefresh nil)
  (setq neo-smart-open t)
  (with-eval-after-load 'neotree
    (define-key neotree-mode-map (kbd "h") 'neotree-hidden-file-toggle)))

Icons

(use-package all-the-icons :ensure t)
(use-package all-the-icons-dired
  :ensure t
  :hook (dired-mode . all-the-icons-dired-mode))

Nyan cat

(use-package nyan-mode
  :ensure t
  :init
  (nyan-mode t))

Emoji

(use-package emojify
  :ensure t
  :hook (elpaca-after-init . global-emojify-mode))

Dimmer

(use-package dimmer
  :ensure t
  :init
  (dimmer-mode t)
  :config
  (setq dimmer-fraction 0.3))

Emacs interface

(scroll-bar-mode 0)
(menu-bar-mode 0)
(tool-bar-mode 0)
(column-number-mode)
(setq ring-bell-function 'ignore)

Writing yes or no is length, type y / n instead

(defalias 'yes-or-no-p 'y-or-n-p)

Doom modeline

(use-package doom-modeline
  :ensure t
  :config
  (setq doom-modeline-height 35)
  (set-face-background 'doom-modeline-bar (face-background 'mode-line))
  (setq doom-modeline-bar-width 1)
  (doom-modeline-mode 1))

Dialog

Don’t pop up UI dialogs when prompting

(setq use-dialog-box nil)

Company

(use-package company
  :ensure t
  :hook (prog-mode . company-mode)
  :config
  (setq company-minimum-prefix-length 2)
  (global-company-mode)
  (global-set-key (kbd "TAB") #'company-indent-or-complete-common))

(setq company-tooltip-align-annotations t)

(use-package company-box
  :ensure t
  :hook (company-mode . company-box-mode))

Editing

;; Remembering the last place you visited in a file
(save-place-mode 1)

(setq-default truncate-lines t ;; Do not wrap lines
              indent-tabs-mode nil) ;; spaces instead of tabs

(setq show-trailing-whitespace t ;; Complain about trailing white spaces
      whitespace-style '(face trailing lines tabs big-indent)) ;; Cleanup white spaces before save

;; Cleanup whitespace before save
(add-hook 'before-save-hook 'whitespace-cleanup)

Parenthesis

(use-package smartparens
  :ensure t
  :config
  (smartparens-global-mode t))

(use-package rainbow-delimiters
  :ensure t
  :hook (prog-mode . rainbow-delimiters-mode))

(use-package rainbow-mode :ensure t)

(use-package string-inflection
  :ensure t
  :bind ("C-c i" . string-inflection-cycle))

(global-hl-line-mode t)

Display line numbers

(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'conf-mode-hook #'display-line-numbers-mode)

Indent Guides

(use-package highlight-indent-guides
  :ensure t
  :config
  (setq highlight-indent-guides-method 'character))

Multiple cursor

(use-package multiple-cursors
  :ensure t
  :bind (("A-S-c A-S-c" . mc/edit-lines)
	   ("C-." . mc/mark-next-like-this)
	   ("C-," . mc/mark-previous-like-this)
	   ("A->" . mc/mark-all-like-this)
	   ("C-A-<mouse-1>" . mc/add-cursor-on-click)))

Unfill paragraph

(defun unfill-paragraph (&optional region)
  "Takes a multi-line paragraph or (REGION) and make it into a single line of text."
  (interactive (progn (barf-if-buffer-read-only) '(t)))
  (let ((fill-column (point-max))
        ;; This would override `fill-column' if it's an integer.
        (emacs-lisp-docstring-fill-column t))
    (fill-paragraph nil region)))

Treesiter

(require 'treesit)
;; modules build from https://github.com/casouri/tree-sitter-module
(setq treesit-extra-load-path '("~/Projects/tree-sitter-module/dist"))
(push '(css-mode . css-ts-mode) major-mode-remap-alist)
(push '(javascript-mode . js-ts-mode) major-mode-remap-alist)
(push '(js-json-mode . json-ts-mode) major-mode-remap-alist)
(push '(typescript-mode . typescript-ts-mode) major-mode-remap-alist)
(push '(typescript-mode . tsx-ts-mode) major-mode-remap-alist)
(push '(ruby-mode . ruby-ts-mode) major-mode-remap-alist)
(add-to-list 'auto-mode-alist '("\\.tsx?\\'" . tsx-ts-mode))

Flymake

(use-package sideline-flymake
  :ensure t
  :hook (flymake-mode . sideline-mode)
  :custom
  (flymake-error-bitmap '(my-rounded-fringe-indicator compilation-error))
  (flymake-note-bitmap '(my-rounded-fringe-indicator compilation-info))
  (flymake-warning-bitmap '(my-rounded-fringe-indicator compilation-warning))
  :init
  (setq sideline-flymake-display-errors-whole-line 'point ; 'point to show errors only on point
	  sideline-backends-right '(sideline-flymake))) ; 'line to show errors on the current line

Custom Fringe

(when (fboundp 'define-fringe-bitmap)
  (define-fringe-bitmap 'my-rounded-fringe-indicator
    (vector #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00011100
            #b00111110
            #b00111110
            #b00111110
            #b00011100
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000)))

Eslint

 ;; source: https://github.com/angrybacon/dotemacs/blob/master/lisp/use-lint.el
 (use-package flymake-eslint
   :ensure t
   :functions flymake-eslint-enable
   :preface
   (defun flymake-eslint-enable-maybe ()
     "Enable `flymake-eslint' based on the project configuration.
 Search for the project ESLint configuration to determine whether the buffer
 should be checked."
     (when-let* ((root (locate-dominating-file (buffer-file-name) "package.json"))
		  (rc (locate-file ".eslintrc" (list root) '(".js" ".json"))))
	(make-local-variable 'exec-path)
	(push (file-name-concat root "node_modules" ".bin") exec-path)
	(setq-local flymake-eslint-project-root root)
	(flymake-eslint-enable))))

Flyspell

(use-package flyspell
  :ensure nil
  :bind (("<f7>" . 'fd-switch-dictionary)
         ("C-;" . 'flyspell-correct-wrapper)))

(use-package flyspell-correct-popup
  :ensure t
  :config
  (setq ispell-program-name "aspell")
  (ispell-change-dictionary "pt_BR"))

(defun fd-switch-dictionary()
  (interactive)
  (let* ((dic ispell-current-dictionary)
         (change (if (string= dic "pt_BR") "english" "pt_BR")))
    (ispell-change-dictionary change)
    (message "Dictionary switched from %s to %s" dic change)))

;; (global-set-key (kbd "<f7>") )
;; (define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Yasnippet

(use-package yasnippet
  :ensure t
  :init
  :config
  (yas-load-directory "~/.emacs.d/snippets")
  (yas-global-mode 1))

Code Folding

(use-package yafolding
  :ensure t
  :hook
  (prog-mode-hook . yafolding-mode)
  :bind ("C-c C-f" . yafolding-toggle-element))

Restclient

(use-package restclient :ensure t)

Projectile

(use-package projectile
  :ensure t
  :init
  (projectile-mode +1)
  :bind (
	   ("C-c p" . projectile-command-map)
	   ("M-[" . projectile-previous-project-buffer)
	   ("M-]" . projectile-next-project-buffer))
  :config
  (setq projectile-indexing-method 'hybrid
	  projectile-sort-order 'recently-active
	  compilation-read-command nil
	  projectile-comint-mode t)

  (add-to-list 'projectile-globally-ignored-directories "node_modules")
  (add-to-list 'projectile-globally-ignored-files "yarn.lock")
  :custom
  (projectile-globally-ignored-buffers '("*scratch*" "*lsp-log*" "*xref*" "*EGLOT" "*Messages*" "*compilation" "*vterm*" "*Flymake")))

Magit

(use-package magit :ensure t)
;;(use-package magit-todos :ensure t)

Git Timemachine

(use-package git-timemachine :ensure t)

Blamer

(use-package blamer
  :ensure t
  :bind (("s-i" . blamer-show-commit-info)
	   ("s-n" . blamer-mode))
  :defer 20
  :custom
  (blamer-idle-time 0.3)
  (blamer-min-offset 10)
  :custom-face
  (blamer-face ((t :foreground "#9099AB"
		     :background nil
		     :height .9
		     :italic t))))

Org

(use-package org
  :ensure nil
  :custom
  (org-agenda-files
   '(
     "/Users/guerra/Projects/org-files/roam/20230102102131-financeiro.org"
     "/Users/guerra/Projects/org-files/roam/20230102103928-pessoal.org"
     "/Users/guerra/Projects/org-files/roam/20230402214745-the_clear_cut.org"
     ))
  (org-agenda-span 15)
  (org-deadline-warning-days 0)
  (org-icalendar-deadline-summary-prefix "")
  (org-icalendar-timezone "")
  (org-icalendar-use-deadline '(event-if-todo todo-due))
  (org-icalendar-with-timestamps nil)
  :bind (("C-c a" . (lambda () (interactive) (org-agenda nil "z")) )
         ("C-c /" . 'org-capture)
         ("s-c" . 'ox-clip-formatted-copy))
  :hook (org-mode . turn-on-flyspell))

(use-package org-contrib
  :ensure t
  :config
  (require 'org-inlinetask)
  (require 'org-tempo)
  (require 'org-collector)  )

(use-package org-web-tools
  :ensure t
  :custom
  (org-web-tools-pandoc-sleep-time 1.8))

(use-package org-ql
  :ensure (org-ql
           :type git :host github
           :repo "alphapapa/org-ql")
  :after '(org))


(use-package git-auto-commit-mode :ensure t)
(use-package ox-clip :ensure t)

(setq org-export-coding-system 'utf-8
      org-directory "~/Projects/org-files/"
      org-tag-alist '(("work" . ?w) ("personal" . ?p) ("meta" . ?m) ("emacsLove" . ?l) ("quotes" . ?q) ("finances" . ?f) ("howto" . ?h))
      org-log-done nil
      org-log-repeat nil
      org-startup-indented t
      org-export-with-toc nil
      org-export-with-section-numbers nil
      gac-automatically-push-p t)

Ox

Slack

(use-package ox-slack
  :ensure t
  :bind ("C-c e s" . org-slack-export-to-clipboard-as-slack))

Reveal

 (use-package ox-reveal :ensure t)
 (setq org-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js"
	org-reveal-title-slide nil
	org-reveal-mathjax t)
 (use-package htmlize :ensure t)

Look & Feel

Olivetti

(use-package olivetti
  :ensure t
  :custom
  (olivetti-body-width 120))

Org modern

(use-package org-modern
  :ensure t
  :config
  (setq ;; Edit settings
   org-auto-align-tags nil
   org-tags-column 0
   org-fold-catch-invisible-edits 'show-and-error
   org-special-ctrl-a/e t
   org-insert-heading-respect-content t

   ;; Org styling, hide markup etc.
   org-hide-emphasis-markers t
   org-pretty-entities nil
   org-ellipsis "…")
  (global-org-modern-mode))

Super-agenda

 (use-package org-super-agenda
   :ensure t
   :after org-agenda
   :config
   (org-super-agenda-mode t)
   (setq org-agenda-skip-scheduled-if-done t))

 (setq org-agenda-custom-commands
	'(("z" "Super view"
	   ((tags "meta" ((org-agenda-overriding-header "Objetivos de 2023")))
	    (agenda "" ((org-agenda-span 'week)
			(org-agenda-overriding-header "")
			))
	    (alltodo "" ((org-agenda-overriding-header "")
			 (org-agenda-remove-tags t)
			 (org-super-agenda-groups
			  '(
			    (:name "🚨 Atrasados"
				   :deadline past
				   :order 7)
			    (:name "PrĂłximos eventos"
				   :discard (:tag ("finances"))
				   :deadline future
				   :order 8)
			    (:name "Sem data" :deadline nil :order 9)
			    (:discard (:tag ("Routine" "Daily" "meta" "finances")))))))
	    ))))

Functions

Check if a billing is paid based on the date

(defun is-paid? (time)
  (if (eq (string-to-number (format-time-string "%m")) (nth 4 (org-parse-time-string time)))
      "-" "pago"))

Add ID to all headings source

(defun add-id-to-tasks-in-file ()
  "Add ID properties to all tasks in the current file which
  do not already have one."
  (interactive)
  (org-ql-select (buffer-file-name)
    '(and
      (todo))
    :action #'org-id-get-create))

Roam

(use-package org-roam
  :ensure t
  :custom
  (org-roam-directory "~/Projects/org-files/roam")
  (setq org-roam-dailies-directory "daily/")
  (org-roam-completion-everywhere t)
  :bind (("C-c n l" . org-roam-buffer-toggle)
	   ("<f4>" . org-roam-node-find)
	   ("C-c n i" . org-roam-node-insert)
	   ("<f12>" . org-roam-dailies-goto-today)
	   ;; :map org-mode-map
	   ;; ("C-M-i" . completion-at-point)
	   :map org-roam-dailies-map
	   ("Y" . org-roam-dailies-capture-yesterday)
	   ("T" . org-roam-dailies-capture-tomorrow))
  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :config
  (require 'org-roam-dailies) ;; Ensure the keymap is available
  (org-roam-db-autosync-mode))

Sync

(defun org-agenda-export-to-ics ()
  (interactive)
  (org-icalendar-combine-agenda-files)
  (copy-file org-agenda-private-local-path org-agenda-private-remote-path t))

(use-package midnight
  :ensure nil
  :config
  (midnight-delay-set 'midnight-delay 16200)
  (setq midnight-period 2400 ;; in seconds
	  org-agenda-private-local-path "~/.org.ics"
	  org-agenda-private-remote-path "~/Google Drive/My Drive/org.ics")
  :hook (midnight . org-agenda-export-to-ics)
  :bind ("C-c e i" . org-agenda-export-to-ics))

Babel

(setq org-src-fontify-natively t)
(setq org-confirm-babel-evaluate nil)
(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)
   (sql . t)))

Markdown

(use-package markdown-mode :ensure t)

Web mode

(use-package web-mode
  :ensure t
  :mode (("\\.html?\\'" . web-mode))
  :config
  (setq web-mode-markup-indent-offset 2
        web-mode-enable-auto-indentation nil
        web-mode-css-indent-offset 2
        web-mode-code-indent-offset 2
        web-mode-block-padding 2
        web-mode-comment-style 2
        web-mode-enable-css-colorization t
        web-mode-enable-auto-pairing t
        web-mode-enable-comment-keywords t
        web-mode-enable-current-element-highlight t
        web-mode-enable-current-column-highlight t
        web-mode-content-types-alist  '(("django" . "\\.tpl\\'") ("django" . "\\.liquid\\'"))))

Auto rename tag

(use-package auto-rename-tag
  :ensure t
  :hook
  (tsx-ts-mode . auto-rename-tag-mode))

yasnippet

(eval-after-load 'yasnippet
  '(let ((dir "~/.emacs.d/snippets/web-mode"))
      (add-to-list 'yas-snippet-dirs dir)
      (yas-load-directory dir)))

liquid

(define-derived-mode liquid-mode web-mode "Liquid"
  "Use web mode to highlight liquid files.")
(provide 'liquid-mode)
(add-to-list 'auto-mode-alist '("\\.liquid\\'" . liquid-mode))

Zencoding

(use-package emmet-mode
  :ensure t
  :hook ((web-mode tsx-ts-mode typescript-ts-mode) . emmet-mode)
  :config
  (setq emmet-indent-after-insert nil
	  emmet-indentation 2
	  emmet-expand-jsx-className? t
	  emmet-move-cursor-between-quotes t
	  emmet-self-closing-tag-style " /")
  (add-to-list 'emmet-jsx-major-modes 'tsx-ts-mode))

Javascript

(setq js-indent-level 2)

prettier

(use-package prettier-js
  :ensure t
  :ensure-system-package (prettier . "npm i -g prettier")
  :hook ((typescript-ts-mode . prettier-js-mode)
	   (js-ts-mode . prettier-js-mode)
	   (tsx-ts-mode . prettier-js-mode)))

Jest mode

(use-package jest-test-mode
  :ensure t
  :commands jest-test-mode
  :hook (typescript-mode js-mode typescript-tsx-mode))

Typescript

Mode

(use-package typescript-ts-mode
  :ensure nil
  :ensure-system-package (typescript-language-server . "npm i -g typescript-language-server"))

(defun node-project-p ()
  "Predicate for determining if the open project is a Node one."
  (let ((p-root (cdr (project-current))))
    (file-exists-p (concat p-root "package.json"))))

;; source: https://github.com/emacs-typescript/typescript.el
(require 'ansi-color)
(defun colorize-compilation-buffer ()
  (ansi-color-apply-on-region compilation-filter-start (point-max)))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

ts-comint

(use-package ts-comint
  :ensure (ts-comint
           :type git :host github
           :repo "nverno/ts-comint"))

Ruby

(use-package flymake-ruby :ensure t)
(add-hook 'ruby-ts-mode-hook 'flymake-ruby-load)

Rubocop

(use-package rubocop
  :ensure t)

(use-package rubocopfmt
  :ensure t
  :hook
  (ruby-mode . rubocopfmt-mode))

Deno

(defun deno-project-p ()
  "Predicate for determining if the open project is a Deno one."
  (let ((p-root (cdr (project-current))))
    (file-exists-p (concat p-root "deno.json"))))

Elisp

Unit Test

Buttercup

(use-package buttercup :ensure t)

Lua :first-quarter-moon-with-face:

(use-package lua-mode :ensure t)

JSON

(use-package json-mode :ensure t)

Prisma

(use-package prisma-mode
  :straight (prisma-mode :host github :repo "pimeys/emacs-prisma-mode")
  :ensure-system-package (prisma-language-server . "npm i -g @prisma/language-server"))

YAML

(use-package yaml-mode :ensure t)

Dart/Flutter

(use-package dart-mode
  :ensure t
  :hook (dart-mode . flutter-test-mode)
  (dart-mode . eglot-ensure))

(use-package flutter
  :ensure t
  :after (dart-mode)
  :bind (:map dart-mode-map
		("C-M-x" . #'flutter-run-or-hot-reload)))

;; (use-package lsp-dart
;;   :ensure t
;;   :hook (dart-mode . lsp)
;;   :custom
;;   (lsp-dart-flutter-sdk-dir "~/snap/flutter/common/flutter")
;;   :config
;;   (setq gc-cons-threshold (* 100 1024 1024)
;;         read-process-output-max (* 1024 1024)))

Eglot

Original code from joaotavora/eglot#999

(defun ecma-server-program (_)
  "Decide which server to use for ECMA Script based on project characteristics."
  (cond ((deno-project-p) '("deno" "lsp" :initializationOptions (:enable t :lint t)))
        ((node-project-p) '("typescript-language-server" "--stdio"))
        (t                nil)))

;; source: https://manueluberti.eu/2022/09/01/consult-xref.html
(defun mu-project-find-regexp ()
  "Use `project-find-regexp' with completion."
  (interactive)
  (defvar xref-show-xrefs-function)
  (let ((xref-show-xrefs-function #'consult-xref))
    (if-let ((tap (thing-at-point 'symbol)))
        (project-find-regexp tap)
      (call-interactively #'project-find-regexp))))

(defun eglot-shutdown-project ()
  "Kill the LSP server for the current project if it exists."
  (when-let ((server (eglot-current-server)))
    (ignore-errors (eglot-shutdown server))))

(use-package eglot
  :ensure nil
  :init
  (put 'eglot-server-programs 'safe-local-variable 'listp)
  :hook
  (typescript-ts-mode . eglot-ensure)
  (js-mode . eglot-ensure)
  (js-ts-mode . eglot-ensure)
  (tsx-ts-mode . eglot-ensure)
  (web-mode . eglot-ensure)
  (liquid-mode . eglot-ensure)
  (ruby-ts-mode . eglot-ensure)
  (prisma-mode . eglot-ensure)
  (sql-mode . eglot-ensure)
  (eglot-managed-mode . flymake-eslint-enable-maybe)

  :bind (:map eglot-mode-map
              ("C-c ." . eglot-code-actions)
              ("C-c e r" . eglot-rename)
              ("C-c e f" . eglot-format)
              ("C-c C-d" . eglot-help-at-point)
              ("M-?" . xref-find-references)
              ("M-." . xref-find-definitions)
              ("C-c f n" . flymake-goto-next-error)
              ("C-c f p" . flymake-goto-prev-error)
              ("C-c f d" . flymake-show-project-diagnostics))
  :custom
  (eglot-autoshutdown t)
  (eglot-menu-string "LSP")
  (eglot-confirm-server-initiated-edits nil)
  :config
  (setq eglot-sync-connect 1)
  (fset #'jsonrpc--log-event #'ignore)
  (put 'eglot-error 'flymake-overlay-control nil)
  (put 'eglot-note 'flymake-overlay-control nil)
  (put 'eglot-warning 'flymake-overlay-control nil)
  (advice-add 'eglot--apply-workspace-edit :after #'me/project-save)
  (advice-add 'project-kill-buffers :before #'me/eglot-shutdown-project)
  (defclass eglot-sqls (eglot-lsp-server) () :documentation "SQL's Language Server")
  (add-to-list 'eglot-server-programs '((liquid-mode) . ("shopify" "theme" "language-server")))
  (add-to-list 'eglot-server-programs '(sql-mode . (eglot-sqls "sqls")))
  (add-to-list 'eglot-server-programs '((js-ts-mode tsx-ts-mode typescript-ts-mode) . ecma-server-program))

  ;; source https://github.com/joaotavora/eglot/issues/523#issuecomment-1746342643
  (defun sloth/org-babel-edit-prep (info)
    (setq buffer-file-name (or (alist-get :file (caddr info))
                               "org-src-babel-tmp"))
    (eglot-ensure))

  (advice-add 'org-edit-src-code
          :before (defun sloth/org-edit-src-code/before (&rest args)
                    (when-let* ((element (org-element-at-point))
                                (type (org-element-type element))
                                (lang (org-element-property :language element))
                                (mode (org-src-get-lang-mode lang))
                                ((eglot--lookup-mode mode))
                                (edit-pre (intern
                                           (format "org-babel-edit-prep:%s" lang))))
                      (if (fboundp edit-pre)
                          (advice-add edit-pre :after #'sloth/org-babel-edit-prep)
                        (fset edit-pre #'sloth/org-babel-edit-prep))))))

Eldoc

(use-package eldoc-box
  :ensure t
  :bind ("C-h ." . eldoc-box-help-at-point))

SQL

(use-package sql-indent :ensure t)
(use-package sqlformat
  :ensure t
  :config
  (setq sqlformat-command 'pgformatter
	  sqlformat-args '("-s2" "-g"))
  :hook (sql-mode . sqlformat-on-save-mode)
  :bind (:map sql-mode-map ("C-c C-f" . sqlformat)))

Vertigo

(use-package vertico
  :ensure t
  :init
  (vertico-mode)
  :custom
  (vertico-group-separator ((t (:inherit all-the-icons-dorange :strike-through t))))
  (vertico-group-title ((t (:inherit all-the-icons-dorange :slant italic)))))

(use-package savehist
  :init
  (savehist-mode))

(use-package orderless
  :ensure t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-overrides '((file (styles basic partial-completion)))))

Consult

(use-package consult
  :ensure t
  :bind (("C-M-l" . consult-imenu)
         ("C-s" . consult-line)
         ("C-M-g" . consult-ripgrep)
         ("C-M-o" . consult-org-heading))
  :hook (completion-list-mode . consult-preview-at-point-mode)
  :init
  (autoload 'projectile-project-root "projectile")
  (setq register-preview-delay 0
        register-preview-function #'consult-register-format
        xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref))

Consult org

(use-package consult-org-roam
   :ensure t
   :after org-roam
   :init
   (require 'consult-org-roam)
   ;; Activate the minor mode
   (consult-org-roam-mode 1)
   :custom
   ;; Use `ripgrep' for searching with `consult-org-roam-search'
   (consult-org-roam-grep-func #'consult-ripgrep)
   ;; Configure a custom narrow key for `consult-buffer'
   (consult-org-roam-buffer-narrow-key ?r)
   ;; Display org-roam buffers right after non-org-roam buffers
   ;; in consult-buffer (and not down at the bottom)
   (consult-org-roam-buffer-after-buffers t)
   :config
   ;; Eventually suppress previewing for certain functions
   (consult-customize
    consult-org-roam-forward-links
    :preview-key (kbd "M-."))
   :bind
   ;; Define some convenient keybindings as an addition
   ("C-c n e" . consult-org-roam-file-find)
   ("C-c n b" . consult-org-roam-backlinks)
   ("C-c n l" . consult-org-roam-forward-links)
   ("C-c n r" . consult-org-roam-search))

Embark

(use-package embark
  :ensure t

  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :init
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)

  ;; Show the Embark target at point via Eldoc.  You may adjust the Eldoc
  ;; strategy, if you want to see the documentation from multiple providers.
  (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
  ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)

  :config
  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :ensure t ; only need to install it, embark loads it after consult if found
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

which-key

(use-package which-key
  :ensure t
  :config
  (which-key-mode))

Commit

Javascript

(use-package js-comint :ensure t)

Read aloud

(use-package read-aloud
  :ensure t
  :config
  (setq read-aloud-engine "say"))

CSV Mode

(use-package csv-mode :ensure t)

Compile

(use-package compile
  :ensure nil
  :custom
  (compilation-scroll-output 'first-error)
  (compilation-always-kill t)
  (compilation-max-output-line-length nil)
  :hook (compilation-mode . hl-line-mode)
  :init
                                        ; from enberg on #emacs
  (add-hook 'compilation-finish-functions
            (lambda (buf str)
              (if (null (string-match ".*exited abnormally.*" str))
                  ;;no errors, make the compilation window go away in a few seconds
                  (progn
                    (run-at-time
                     "1 sec" nil 'delete-windows-on
                     (get-buffer-create "*compilation*"))
                    (message "No Compilation Errors!"))))))

Fancy Compile

(use-package fancy-compilation
  :ensure t
  :defer 3
  :config
  (fancy-compilation-mode)
  :custom
  (fancy-compilation-scroll-output 'first-error))

Recompile on Save

(use-package recompile-on-save
  :ensure t
  ;; Kill the buffer message that pops up after running advice on compile
  :hook (after-init . (lambda () (run-at-time 1 nil
                                              (lambda ()
                                                (when (get-buffer "*Compile-Log*")
                                                  (kill-buffer "*Compile-Log*"))
                                                (delete-other-windows)))))
  :init
  (recompile-on-save-advice compile))

Elfeed

(use-package elfeed
  :ensure t
  :custom
  (elfeed-db-directory
   (expand-file-name "elfeed" user-emacs-directory))
  (elfeed-show-entry-switch 'display-buffer))

GraphQL

(use-package graphql-mode
  :ensure t)

Python

(use-package with-venv
  :ensure t)

About

My emacs configuration

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published