Compare commits
6 Commits
87b3deeed3
...
610046ce96
Author | SHA1 | Date |
---|---|---|
Lucien Cartier-Tilet | 610046ce96 | |
Lucien Cartier-Tilet | 2ef0f4fc89 | |
Lucien Cartier-Tilet | 9c1fe06d26 | |
Lucien Cartier-Tilet | 4d25ef6b5b | |
Lucien Cartier-Tilet | 4cc062cd0c | |
Lucien Cartier-Tilet | 5f70aed2aa |
|
@ -2,5 +2,4 @@
|
|||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((org-mode . ((org-list-allow-alphabetical . nil)
|
||||
(org-confirm-babel-evaluate . nil)
|
||||
(eval . (add-hook 'after-save-hook #'org-babel-tangle)))))
|
||||
(org-confirm-babel-evaluate . nil))))
|
||||
|
|
|
@ -25,9 +25,54 @@ loaded, speeding Emacs up a bit.
|
|||
(set-fringe-mode 10) ; give some breathing room
|
||||
(menu-bar-mode -1) ; disable menubar
|
||||
(blink-cursor-mode 0) ; disable blinking cursor
|
||||
(setq gc-cons-threshold (* 1024 1024 1024))
|
||||
#+end_src
|
||||
|
||||
*** Better garbage collection
|
||||
Emacs sometimes freezes up a bit when doing some garbage collection,
|
||||
which is not super. So, in order to fix that, I do two things:
|
||||
1. Set up a really high threshold (I have a lot of RAM to spare, so I
|
||||
don’t really care),
|
||||
2. Hook garbage collection thirty seconds after Emacs loses focus and
|
||||
every thirty seconds after that,
|
||||
3. Cancel garbage collection if Emacs gains focus back within this
|
||||
thirty seconds window.
|
||||
|
||||
With a garbage collection threshold, Emacs should never garbage
|
||||
collect on its own, and Emacs is free to freeze up for a few seconds
|
||||
when it loses focus since I’m looking away.
|
||||
#+begin_src emacs-lisp
|
||||
(setq garbage-collection-messages t ;; tell me when garbage collecting
|
||||
gc-cons-threshold (* 16 1024 1024 1024)) ;; 16GiB of RAM
|
||||
|
||||
(defmacro my/time (&rest body)
|
||||
`(let ((time (current-time)))
|
||||
,@body
|
||||
(float-time (time-since time))))
|
||||
|
||||
(defun my/garbage-collect ()
|
||||
"Garbage collect and tell the user how much time it took."
|
||||
(message "Garbage collector ran for %.06fs"
|
||||
(my/time (garbage-collect))))
|
||||
|
||||
(defvar my/gc-timer nil
|
||||
"Timer for garbage collection. See
|
||||
`my/garbage-collect-on-focus-lost'.")
|
||||
|
||||
(defun my/garbage-collect-on-focus-lost ()
|
||||
"Garbage collect when Emacs loses focus.
|
||||
|
||||
Garbage collection is only triggered thirty seconds after losing
|
||||
focus, and only once."
|
||||
(if (frame-focus-state
|
||||
(cancel-timer my/gc-timer))
|
||||
(setq my/gc-timer (run-with-idle-timer 30 nil #'my/garbage-collect))))
|
||||
|
||||
(add-function :after after-focus-change-function #'my/garbage-collect-on-focus-lost)
|
||||
#+end_src
|
||||
|
||||
To write this, I mostly based myself on [[https://news.ycombinator.com/item?id=39190110][this HackerNews thread]] and [[https://akrl.sdf.org/#orgc15a10d][its
|
||||
related article]].
|
||||
|
||||
** Emacs Behavior
|
||||
*** Editing Text in Emacs
|
||||
I *never* want to keep trailing spaces in my files, which is why I’m
|
||||
|
|
|
@ -23,102 +23,6 @@ buffer in new Emacs buffers.
|
|||
(file-list))))
|
||||
#+end_src
|
||||
|
||||
** Switch between buffers
|
||||
Two default shortcuts I really like from Spacemacs are ~SPC b m~ and ~SPC
|
||||
b s~, which bring the user directly to the ~*Messages*~ buffer and the
|
||||
~*scratch*~ buffer respectively. These functions do exactly this.
|
||||
#+begin_src emacs-lisp
|
||||
(defun switch-to-messages-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer (messages-buffer)))
|
||||
|
||||
(defun switch-to-scratch-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer "*scratch*"))
|
||||
#+end_src
|
||||
|
||||
** Screenshots
|
||||
Since Emacs27, it is possible for Emacs to take screenshots of itself
|
||||
in various formats. I’m mainly interested in the SVG and PNG format,
|
||||
so I’ll only write functions for these. It isn’t really redundant with
|
||||
the ~screenshot.el~ package used [[file:./packages/applications.md#screenshot][here]] since these functions take a
|
||||
screenshot of Emacs as a whole rather than of a code snippet.
|
||||
|
||||
First, we have a general function which is a slight modification of
|
||||
the function shared by Alphapapa in [[https://www.reddit.com/r/emacs/comments/idz35e/emacs_27_can_take_svg_screenshots_of_itself/g2c2c6y/][this Reddit comment]]. I modified it
|
||||
to make it possible to pass as an argument the format the screenshot
|
||||
will be taken as or ask the user which format they would like to save
|
||||
it as.
|
||||
#+begin_src emacs-lisp
|
||||
(defun self-screenshot (&optional type)
|
||||
"Save a screenshot of type TYPE of the current Emacs frame.
|
||||
As shown by the function `', type can wield the value `svg',
|
||||
`png', `pdf'.
|
||||
|
||||
This function will output in /tmp a file beginning with \"Emacs\"
|
||||
and ending with the extension of the requested TYPE."
|
||||
(interactive (list
|
||||
(intern (completing-read "Screenshot type: "
|
||||
'(png svg pdf postscript)))))
|
||||
(let* ((extension (pcase type
|
||||
('png ".png")
|
||||
('svg ".svg")
|
||||
('pdf ".pdf")
|
||||
('postscript ".ps")
|
||||
(otherwise (error "Cannot export screenshot of type %s" otherwise))))
|
||||
(filename (make-temp-file "Emacs-" nil extension))
|
||||
(data (x-export-frames nil type)))
|
||||
(with-temp-file filename
|
||||
(insert data))
|
||||
(kill-new filename)
|
||||
(message filename)))
|
||||
#+end_src
|
||||
|
||||
I used this function to take the screenshots you can see in this
|
||||
document.
|
||||
|
||||
** Handle new windows
|
||||
The two functions below allow the user to not only create a new window
|
||||
to the right or below the current window (respectively), but also to
|
||||
focus the new window immediately.
|
||||
#+begin_src emacs-lisp
|
||||
(defun split-window-right-and-focus ()
|
||||
"Spawn a new window right of the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-right)
|
||||
(windmove-right))
|
||||
|
||||
(defun split-window-below-and-focus ()
|
||||
"Spawn a new window below the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-below)
|
||||
(windmove-down))
|
||||
|
||||
(defun kill-buffer-and-delete-window ()
|
||||
"Kill the current buffer and delete its window."
|
||||
(interactive)
|
||||
(progn
|
||||
(kill-this-buffer)
|
||||
(delete-window)))
|
||||
#+end_src
|
||||
|
||||
** Resize windows
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'hydra
|
||||
(defhydra windows-adjust-size ()
|
||||
"
|
||||
_s_: enlarge
|
||||
_c_: enlarge _r_: right
|
||||
_t_: shrink
|
||||
"
|
||||
("c" enlarge-window-horizontally)
|
||||
("t" shrink-window)
|
||||
("s" enlarge-window)
|
||||
("r" shrink-window-horizontally)))
|
||||
#+end_src
|
||||
|
||||
** Extend ~add-to-list~
|
||||
One function I find missing regarding ~add-to-list~ is ~add-all-to-list~
|
||||
which enables the user to add multiple elements to a list at once.
|
||||
|
@ -164,3 +68,99 @@ APPEND and COMPARE-FN, see `add-to-list'."
|
|||
nil))
|
||||
32))))
|
||||
#+end_src
|
||||
|
||||
** Handle new windows
|
||||
The two functions below allow the user to not only create a new window
|
||||
to the right or below the current window (respectively), but also to
|
||||
focus the new window immediately.
|
||||
#+begin_src emacs-lisp
|
||||
(defun split-window-right-and-focus ()
|
||||
"Spawn a new window right of the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-right)
|
||||
(windmove-right))
|
||||
|
||||
(defun split-window-below-and-focus ()
|
||||
"Spawn a new window below the current one and focus it."
|
||||
(interactive)
|
||||
(split-window-below)
|
||||
(windmove-down))
|
||||
|
||||
(defun kill-buffer-and-delete-window ()
|
||||
"Kill the current buffer and delete its window."
|
||||
(interactive)
|
||||
(progn
|
||||
(kill-this-buffer)
|
||||
(delete-window)))
|
||||
#+end_src
|
||||
|
||||
** Resize windows
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'hydra
|
||||
(defhydra windows-adjust-size ()
|
||||
"
|
||||
_s_: enlarge
|
||||
_c_: enlarge _r_: right
|
||||
_t_: shrink
|
||||
"
|
||||
("c" enlarge-window-horizontally)
|
||||
("t" shrink-window)
|
||||
("s" enlarge-window)
|
||||
("r" shrink-window-horizontally)))
|
||||
#+end_src
|
||||
|
||||
** Screenshots
|
||||
Since Emacs27, it is possible for Emacs to take screenshots of itself
|
||||
in various formats. I’m mainly interested in the SVG and PNG format,
|
||||
so I’ll only write functions for these. It isn’t really redundant with
|
||||
the ~screenshot.el~ package used [[file:./packages/applications.md#screenshot][here]] since these functions take a
|
||||
screenshot of Emacs as a whole rather than of a code snippet.
|
||||
|
||||
First, we have a general function which is a slight modification of
|
||||
the function shared by Alphapapa in [[https://www.reddit.com/r/emacs/comments/idz35e/emacs_27_can_take_svg_screenshots_of_itself/g2c2c6y/][this Reddit comment]]. I modified it
|
||||
to make it possible to pass as an argument the format the screenshot
|
||||
will be taken as or ask the user which format they would like to save
|
||||
it as.
|
||||
#+begin_src emacs-lisp
|
||||
(defun self-screenshot (&optional type)
|
||||
"Save a screenshot of type TYPE of the current Emacs frame.
|
||||
As shown by the function `', type can wield the value `svg',
|
||||
`png', `pdf'.
|
||||
|
||||
This function will output in /tmp a file beginning with \"Emacs\"
|
||||
and ending with the extension of the requested TYPE."
|
||||
(interactive (list
|
||||
(intern (completing-read "Screenshot type: "
|
||||
'(png svg pdf postscript)))))
|
||||
(let* ((extension (pcase type
|
||||
('png ".png")
|
||||
('svg ".svg")
|
||||
('pdf ".pdf")
|
||||
('postscript ".ps")
|
||||
(otherwise (error "Cannot export screenshot of type %s" otherwise))))
|
||||
(filename (make-temp-file "Emacs-" nil extension))
|
||||
(data (x-export-frames nil type)))
|
||||
(with-temp-file filename
|
||||
(insert data))
|
||||
(kill-new filename)
|
||||
(message filename)))
|
||||
#+end_src
|
||||
|
||||
I used this function to take the screenshots you can see in this
|
||||
document.
|
||||
|
||||
** Switch between buffers
|
||||
Two default shortcuts I really like from Spacemacs are ~SPC b m~ and ~SPC
|
||||
b s~, which bring the user directly to the ~*Messages*~ buffer and the
|
||||
~*scratch*~ buffer respectively. These functions do exactly this.
|
||||
#+begin_src emacs-lisp
|
||||
(defun switch-to-messages-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer (messages-buffer)))
|
||||
|
||||
(defun switch-to-scratch-buffer ()
|
||||
"Switch to Messages buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer "*scratch*"))
|
||||
#+end_src
|
||||
|
|
|
@ -1245,6 +1245,18 @@ which is really nice! However, most of my configuration will be stolen
|
|||
(org-present-mode-quit . my/org-present-quit)))
|
||||
#+end_src
|
||||
|
||||
** Tangle config org files on save
|
||||
Something really, really useful is tangling all my configuration files
|
||||
on save. For this, a dedicated function will do the trick.
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/tangle-config-file ()
|
||||
(when (and (eq major-mode 'org-mode)
|
||||
(f-ancestor-of-p (f-full "~/.nosync/org/config") default-directory))
|
||||
(org-babel-tangle)))
|
||||
|
||||
(add-hook 'after-save-hook #'my/tangle-config-file)
|
||||
#+end_src
|
||||
|
||||
** Visual Configuration
|
||||
While most modes of Emacs are dedicated to development, and therefore
|
||||
are much more comfortable with a fixed-pitch font, more literary modes
|
||||
|
|
|
@ -32,6 +32,21 @@ file (which you can find [[https://labs.phundrak.com/phundrak/dotfiles/src/branc
|
|||
fenv source ~/.profile
|
||||
#+end_src
|
||||
|
||||
[[https://direnv.net/][Direnv]] is a really neat tool that allows you to load the content of a
|
||||
dotenv file as environment variables. Its installation is quite simple
|
||||
for fish.
|
||||
#+begin_src fish
|
||||
direnv hook fish | source
|
||||
#+end_src
|
||||
|
||||
Since I don’t really have a better place on this website to put it,
|
||||
here is my direnv configuration located at
|
||||
=$HOME/.config/direnv/direnv.toml=.
|
||||
#+begin_src toml :tangle ~/.config/direnv/direnv.toml :mkdirp yes :exports code
|
||||
[global]
|
||||
load_dotenv = true
|
||||
#+end_src
|
||||
|
||||
*** Development
|
||||
Finally, some development packages require the =PKG_CONFIG_PATH= to be
|
||||
set, so let’s do so.
|
||||
|
@ -302,23 +317,39 @@ Here is the corresponding fish configuration:
|
|||
<<generate-abbr(table=abbr-cmake)>>
|
||||
#+END_SRC
|
||||
|
||||
**** Docker
|
||||
And of course, when it comes to Docker Compose, I don't have time to write the
|
||||
full command, so I use these instead.
|
||||
**** Docker and Podman
|
||||
# And of course, when it comes to Docker Compose, I don't have time to write the
|
||||
# full command, so I use these instead. Actually, let me rephrase that: I used to use
|
||||
I used to use Docker on my machine, but I switched to Podman. Still,
|
||||
my muscle memory is really strong and I keep trying to type my old
|
||||
Docker abbreviations. So, I keep them, but I also have a slight
|
||||
variation for each one of them for Podman.
|
||||
|
||||
#+NAME: abbr-docker
|
||||
| abbreviation | command |
|
||||
|--------------+------------------------------|
|
||||
| dc | docker-compose |
|
||||
| dcb | docker-compose build |
|
||||
| dcd | docker-compose down |
|
||||
| dcl | docker-compose logs |
|
||||
| dclf | docker-compose logs -f |
|
||||
| dcp | docker-compose pull |
|
||||
| dcr | docker-compose run --rm |
|
||||
| dcu | docker-compose up |
|
||||
| dcub | docker-compose up --build |
|
||||
| dcud | docker-compose up -d |
|
||||
| dcudb | docker-compose up -d --build |
|
||||
| dc | podman-compose |
|
||||
| dcb | podman-compose build |
|
||||
| dcd | podman-compose down |
|
||||
| dcl | podman-compose logs |
|
||||
| dclf | podman-compose logs -f |
|
||||
| dcp | podman-compose pull |
|
||||
| dcr | podman-compose run --rm |
|
||||
| dcu | podman-compose up |
|
||||
| dcub | podman-compose up --build |
|
||||
| dcud | podman-compose up -d |
|
||||
| dcudb | podman-compose up -d --build |
|
||||
| pc | podman-compose |
|
||||
| pcb | podman-compose build |
|
||||
| pcd | podman-compose down |
|
||||
| pcl | podman-compose logs |
|
||||
| pclf | podman-compose logs -f |
|
||||
| pcp | podman-compose pull |
|
||||
| pcr | podman-compose run --rm |
|
||||
| pcu | podman-compose up |
|
||||
| pcub | podman-compose up --build |
|
||||
| pcud | podman-compose up -d |
|
||||
| pcudb | podman-compose up -d --build |
|
||||
|
||||
Here is the corresponding fish configuration:
|
||||
#+BEGIN_SRC fish
|
||||
|
|
|
@ -550,6 +550,24 @@ in order to send to Emacs any ~mailto:~ requests made in my system.
|
|||
emacsclient -c -n -a emacs -e "(browse-url-mail \"$*\")"
|
||||
#+END_SRC
|
||||
|
||||
*** Restart Emacs
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS: :shebang "#!/bin/bash" :mkdirp yes :tangle ~/.local/bin/restart-emacs
|
||||
:END:
|
||||
Believe me or not, it happens I restart Emacs. I generally start Emacs
|
||||
manually with =emacs --daemon= because of an issue rendering =lsp-mode=
|
||||
useless when started by the user systemd service.
|
||||
#+begin_src bash
|
||||
PID_EMACS=$(pidof emacs)
|
||||
killall emacs
|
||||
echo "Waiting for Emacs to be killed... (pid: $PID_EMACS)"
|
||||
if timeout 30 tail --pid=$PID_EMACS -f /dev/null ; then
|
||||
emacs --daemon
|
||||
else
|
||||
echo "Failed to kill Emacs after 30s"
|
||||
fi
|
||||
#+end_src
|
||||
|
||||
** Media
|
||||
*** mp42webm
|
||||
:PROPERTIES:
|
||||
|
|
Loading…
Reference in New Issue