BEWARE: AUTHOR does’nt know much elisp and suffer from parenthesiophobia, but couldn’t stop tinker around.
I’ve been using emacs since 2012, It has been the love and hate story since day one, In summary emacs rocks but 🪨 rocks are not so pretty, and here you are looking at not so pretty side.
FYI "emacs vanilla is a lie"
Emacs is relics of the past, have a criminal learning curve 🌀 are cursed with the worst UI known to mankind with most unpleasing to looks I mean it’s a real dumpster 💩. It is not necessary to know how to use emacs in order to be unhappy 😩, but it helps. I have been constant search for the alternative over the years, non has come closer than vscode capture the same imagination constant improvement like in editor wars.
My nearly a decade long journey with emacs is nothing compared to age of the application which predates me and also the one of the longest lived application programs of all time. Yet to become obsolete, which is still ongoing development since 1976. Flexibility of altering its interface and behavior without going though original source has let to creation of surplus features by generation of users 🤓 (programmers). There has been some of 💫 indispensable tools which are yet to be match modern word processors.
It might be difficult for me to abandon the emacs although its prized features would be replicated soon some day. Over the years I constantly hear about Making Emacs popular again but its unlikely to happen again since entry barrier is too high. The vscode with built with the most popular language possess significant development advantage, unlike emacs built with lisp. Yet this repository itself stands as a testament about developers relation with text editor, which mean switching to new editor will need significant investment of time, not to mention IKEA effect.
We need more contributors to make emacs better. We need better emacs to attract more users who can later contribute back. Its never ending dilemma. Still there number of unfortunate facts about how emacs works. Most users will eventually need to dive into elisp in order get to their particular tastes. I have been using emacs for years sheer size of the project hard to comprehend itself. But recent years emacs has seen numerous improvement like lsp, native-compilation, yet emacs still needs more.
Customization began with single-file ~/.emacs
with few settings
and some random snippets. Didn’t took long to become monster. It
loved to cherry-picked 🍒 packages literally form anywhere, I was
like why don’t you apt-get.
It was becoming difficult maintaining 📦 packages manually,
tracking workable dependencies and freezing 🧊 versions. And came
package.el
, which I noticed in What’s new in emacs24 using
emacs25. also el-get existed, and now package.el
was official
too. I can’t seem to choose one, and great can use both.
Yet, I could barely remember Why I removed that package, what
happen?, git-whatchanged would have told me more if it was a
code. To org
organize was most sane thing till now
~/emacs.d/init.el was orgified (org-bable-tangle).
In summary, its not easy to declare bankruptcy when your config is:
- highly opinionated configuration
- does’nt provide the any layer of abstraction
- more of notes and rants and reason to do so
Since, version 27.1 emacs supported XDG convention every thing
can be in ~/.config/emacs
🧨 DISCLAIMER: 🐒 MAKE SURE YOU HAVE THE BACKUP
Oh! you wanna use my config! its super duper easy ! may be in
future I’m still trying avoiding make the installer (literally
don’t know how) and just trying to get by my work.
$ git clone https://github.com/rhoit/dot-emacs /path/to/dot-emacs
There is absolutely no reason for you to use this config, it would be like first time 🏊 swimmer, who mostly likely drown with unnecessary amount of effort. Although I’m great at underwater so to say some what athletic underachievers.
Time 🕥 and time 🕝 again I learned elisp just to forget with endless pondering and compromises, without ✍️ jotting things down, it would have been impossible to configure. May be this started for maintenance, now its more of rants taking over the configuration! 😎
If you ask, would I have started with other’s config? I would definitely say YES. But you should understand all-in-one package 📦 or distribution is like bringing gun 🔫 to the fist 👊 fight. You might end up using less than 5 % of the bloat. And if you want to change or fix something it big 😫 pain to pealing layers after layers to find the actual root cause. Yet you might want to try these first
- Doom Emacs
- Spacemacs
- Centaur Emacs
- ergoemacs-mode
- Graphene
- magnars emacs.d
- ohai-emacs
- Prelude
- Radian
- purcell emacs.d
And there configurations too.
- mattduck
- DiegoVicen
- stardiviner
- M-EMACS
- Farlado’s Illiterate GNU Emacs
- Emacs is Agar for Brain Worms
- David Wilson’s config
- rougier
- novoid
Entropy is important but not here
This is the way, I keep my things have been same for many year now!
~/.config/emacs -> dot-emacs ├── elpa # pacman ├── cfg.compile.el ├── cfg.tabbar.el : : │ ├── ... : ├── 00testing # testing stuffs └── snippets # yasnippet stuffs ├── fundamental-mode : └── python-mode
While troubleshooting I go though these procedure (may not be in same ordering)
- hate myself when it happens
- REMOVE the damn plugin and GET BACK TO WORK
- throw ERROR MSG at google and try catching relevant pages
- may be waste few hrs with random trials
- set debug variable
(setq debug-on-error 1) (setq debug-on-quit t) ;; C-g
I don’t really understand what its happening but here are some chatter over the years on reddit and stackexchange. Original motivation was let the emacs use more RAM, if java based IDE can eat up more than 200 Mb to get started. Don’t gc during startup to save time! so says hlissner/doom-emacs!
;;; restore gc suppress during early-init.el
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold (* 8 1024 1024)) ; default: 800000 bytes
(setq read-process-output-max (* 2 1024 1024)) ; default : 4KB
gc-cons-percentage 0.1))
Classic style 🧪 testing.
2>&1 /usr/bin/time --verbose /usr/bin/emacs --eval="(save-buffers-kill-terminal)"
Command being timed: "/usr/bin/emacs --eval=(save-buffers-kill-terminal)" User time (seconds): 2.95 System time (seconds): 0.32 Percent of CPU this job got: 98% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:03.34 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 285652 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 6 Minor (reclaiming a frame) page faults: 53556 Voluntary context switches: 396 Involuntary context switches: 338 Swaps: 0 File system inputs: 0 File system outputs: 24 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
Show emacs-init-time at startup
(add-hook 'emacs-startup-hook (lambda ()
(message (concat "conf-init-time: " (emacs-init-time) (format " gc: %d" gcs-done)))))
for comprehensive bench-marking install benchmark-init
M-x benchmark-init/show-durations-tree
Stop ⛔ opening emacs for each file. Set default open application to emacsclient, or set it manually:
emacsclient --no-wait--alternate-editor=emacs [FILE]
(require 'server)
(unless (server-running-p)
(server-start))
Set language to English all encoding in Unicode.
(setq set-default-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
;; (set-keyboard-coding-system 'utf-8) ;; has no-effect in GUI Terminal
(prefer-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(set-buffer-file-coding-system 'utf-8)
(set-language-environment "English") ;; Set up multilingual environment
I don’t like mess every where, there is better things for that called git!
(setq backup-directory-alist (quote ((".*" . "~/.cache/emacs_backup/"))))
(setq make-backup-files nil)
(setq auto-save-default nil)
(setq create-lockfiles nil)
<2021-06-24 Thu> Ignoring for now because I want it to be in separate file but problem is file doesn’t load back.
As written in Emacs is Agar for Brain Worms
By default, Emacs stores any configuration you make through its UI by writing custom-set-variables invocations to your init file, or to the file specified by custom-file. Though this is convenient, it’s also an excellent way to cause aggravation when the variable you keep trying to modify is being set in some custom-set-variables invocation. We can’t disable this behavior, and the custom-file variable can’t be nil, but we can make it look in a different place every time.
;; (setq custom-file (make-temp-file "")) ; ignore
(setq custom-file "/home/rho/.config/emacs/custom.el")
Warn when opening files bigger than 1 MiB. yup emacs kitchen sink can open 🌇 image, PDF but seriously 😵 ?
(setq large-file-warning-threshold (* 1 1024 1024))
You might wonder why that random number!
kilobyte (kB) | 1000 bytes |
kibibyte (KiB) | 1024 bytes, kB |
Since digital systems worked in binary, yet defacto is in base of 2, Still interface don’t show kibi, mebi, gibi. I don’t think I’m only one who feel 😠 cheated getting HDD of 1 TB and you getting 0.931 TB.
There are many 📦 package managers for emacs, ranging from simple scripts to download files from EmacsWiki to full-featured package management solutions like straight.el, these are few I have used
Its 2020, it has been harder to maintain packages with two managers. Finally decided to drop el-get in favor of build in package.el.
Add package other sources
(require 'package) ;; after 24 its pre-loaded
(add-to-list 'load-path "~/.config/emacs/elpa/")
;; (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") t)
;; https://melpa.org/#/getting-started
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
Use M-x package-refresh-contents
to reload the list of packages
after adding these for the first time.
- <2022-01-12 Wed>
org package is handled by gnu elpa after 9.5
- <2020-02-02 Sun>
having troubles with org-version babel support. using org package-archives for latest stuff.
- <2023-08-08 Tue>
In Emacs 29.1
package.el
can install packages directly from git with the new functionpackage-vc-install
, and packages installed that way can be updated withpackage-vc-update
orpackage-vc-update-all
.
The use-package macro allows you to isolate package configuration both performance-oriented and, well, tidy.
But My packages are already organized using org-mode and the
current init time is below 0.5 s given by emacs-init-time
within 2.0 s in total or Just I don’t use tons of package.
Or change my mind!
el-get is the package manager, which is similar to apt-get. Not using since starting of 2020.
More
Its bit tricky to make both ELPA and el-get work together, but
after years of procrastination, some how this works, you should
load el-get first, but emacs24+ loads package.el
by default,
thats why put this magic line before loading el-get (setq
package-enable-at-startup nil)
(add-to-list 'load-path "~/.emacs.d/el-get")
(require 'el-get)
(setq el-get-git-shallow-clone 't)
(el-get 'sync)
To replicate a package set for another emacs installation is explain in el-get README.
As of today, most people who use vi or emacs are incapable of using the other editor without using curse words 😡. Not surprisingly normal people without prior knowledge any text editor are pretty comfortable even 🪟 notepad make much more sense than emacs or vi. Yes you can pretty much do any text foo with these editor, even without touching 🐁 pointing device, but really does it really need to be like this.
Version 27.1 introduces ~/emacs.d/early-init.el, which is run before ~/emacs.d/init.el, before package and UI initialization happens. Themes and UI components can be setup here, which finally solves flickering UI.
Since emacs 28.1 Improved support for Emoji. On capable systems, Emacs now correctly displays Emoji and Emoji sequences by default, provided that a suitable font is available to Emacs. With a few exceptions.
“Noto Color Emoji” is automatically used if it’s installed if not install run for Arch Linux.
pacman -S extra/noto-fonts-emoji
Worst part of switching theme by loading is active theme is one disabled before loading the new one! this 🪄 trick was stolen from @thapakazi.
(defun theme-switch (theme)
"Disables any currently active themes and loads THEME."
;; This interactive call is taken from `load-theme'
(interactive
(list (intern (completing-read "Load custom theme: "
(mapc 'symbol-name
(custom-available-themes))))))
(let ((enabled-themes custom-enabled-themes))
(mapc #'disable-theme custom-enabled-themes)
(load-theme theme t)))
Historically emacs 💈 scrolling 💈 has bee choppy and riddled with bugs, after pgtk branch was merged on <2021-12-19> this has been better. Now in emacs 29.1 pixel-scroll-precision-mode builtin, no more custom 🛠️ builds.
(pixel-scroll-precision-mode t)
;; (setq pixel-scroll-precision-large-scroll-height 50.0)
;; (setq pixel-scroll-precision-use-momentum nil)
Similar to nano single line horizontal scroll in v26.1 introduced new feature, which only current line with cursor to be horizontally scrolled left or right window margin.
(setq auto-hscroll-mode 'current-line)
Vim does this with ~ (tildes) characters at the bottom of a window to indicate that there is nothing in the buffer, so emacs can do it too 🏁.
(toggle-indicate-empty-lines t)
As in this article of ergoemacs, 2 line numbers mode is been 📦 packaged with emacs.
year | emacs | package |
---|---|---|
2009 | 23 | linum-mode |
2018 | 26 | global-display-line-numbers-mode |
I used multiple line number plugins over years now, frontmacs config stood out for me the, but linum give lots of flicker, now using with nlinum which is quite good until it was deprecated.
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(add-hook 'org-mode-hook 'display-line-numbers-mode)
(add-hook 'display-line-numbers-mode-hook
(lambda ()
(setq display-line-numbers-width 4)))
- <2023-08-29 Tue>
nlinum is unusable
(setq inhibit-startup-message t)
(setq inhibit-splash-screen t)
The mode line contains textual summary about the buffer, such as its name, associated file, depth of recursive editing, and major and minor modes.
The purpose of dim package is to “customize” the mode-line names
of major and minor modes using dim-major-name
and
dim-minor-name
to change the names by one.
(require 'dim)
3.8.2 diminish
More
When we diminish a mode, we are saying we want it to continue doing its work for us, but we no longer want to be reminded of it. It becomes a night worker, like a janitor; it becomes an invisible man; it remains a component, perhaps an important one, sometimes an indispensable one, of the mechanism that maintains the day-people’s world, but its place in their thoughts is diminished, usually to nothing. As we grow old we diminish more and more such thoughts, such people, usually to nothing.
– Will Mengarini
(require 'diminish)
- <2022-03-12 Sat> not using
preferring dim instead
Its normal to use 5-10 modes on a buffer, which make the mode line full of clutter why not use icons!
(require 'mode-icons)
(mode-icons-mode)
(require 'powerline)
;;; https://github.com/rhoit/powerline-iconic-theme
(setq FILE-iconic "~/.config/emacs/00testing/powerline-iconic-theme/iconic.el")
(if (file-exists-p FILE-iconic)
(progn
(load-file FILE-iconic)
(powerline-iconic-theme))
(powerline-default-theme))
tabbar is something familiar to modern 🍭 GUI system, there is still the gap, like key-bindings, close buttons and icons which is which tabbar-ruler tries to address.
(require 'tabbar)
(tabbar-mode t)
(setq FILE-tabbar "~/.config/emacs/00testing/tabbar-ruler/tabbar-ruler.el")
(if (file-exists-p FILE-tabbar)
(load-file FILE-tabbar)
(require 'tabbar-ruler))
(setq tabbar-ruler-style 'firefox)
(load "~/.config/emacs/cfg.tabbar.el")
(define-key global-map (kbd "<header-line> <mouse-3>") 'mouse-buffer-menu)
scroll-right
and scroll-right
seems
to be strange for beginner and for me too, if you don’t believe
me try C-PgUp and
C-PgUp in vanilla 🍦 emacs, put it
to the good use tab-forward
and
tab-backward
(global-unset-key [(control prior)]) ; unbind (scroll-right)
(global-unset-key [(control next)]) ; unbind (scroll-left)
(define-key global-map [(control next)] 'tabbar-forward)
(define-key global-map [(control prior)] 'tabbar-backward)
grouping the tab by buffer name
(setq tabbar-buffer-groups-function (lambda ()
(list (cond
((string-match ".*magit.*" (buffer-name)) "magit Buffers")
((string-match "TAGS" (buffer-name)) "ctags")
((string-match "*pdb.*" (buffer-name)) "pdb Buffers")
((string-match "*helm.*" (buffer-name)) "helm Buffers")
((string-equal "*" (substring (buffer-name) 0 1)) "emacs Buffers")
((eq major-mode 'dired-mode) "Dired")
(t "User Buffers")
))))
Binding for the tab groups, some how I use lots of buffers.
(global-set-key [(control shift prior)] 'tabbar-backward-group)
(global-set-key [(control shift next)] 'tabbar-forward-group)
Similar packages
- centaur-tabs from centaur emacs
Sensible unique buffer names, [ inbuilt: package ]
by default in >= 24.4.1 else add (require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
3.11 speedbar
I prefer speedbar outside the frame, for without separate frame see SrSpeedbar.
(setq speedbar-show-unknown-files t)
;; (global-set-key [f9] 'speedbar)
- <2021-05-27 Thu>
its projectile now days and speedbar breaks my theme
This is the gem feature, this might be true answer to the sublime mini-map which is over rated, this is what you need.
(require 'goto-chg)
(global-unset-key (kbd "C-j")) ; unbind (eval-print-last-sexp)
(global-set-key (kbd "C-j") 'goto-last-change)
Fundamentally emacs is more over a scratchpad for elisp, which has been mistaken for the editor. Just 30+ years focused on features accumulation with barely any attention to GUI, I’m baffled when people come up with ⌨️ keybinding for each modes and mode to manage them again with keybindings. No wonder people get strain injuries.
I’m one of those who is keen 🔥 burning your finger tips for efficiency. and why do they generalize everyone uses same key layout and so call most efficient vi binding, just 🔒 locks me inside without the exit🚪!
I don’t understand why laptops 💻 OEM constantly change the key layouts. But why perfectly good layout are replace by terrible designs, Not to mention combining delete and backspace .
Some time you need to explicitly say what to do.
;;; you might not need this
(normal-erase-is-backspace-mode 1)
It seem more of “think different stupid” 🍎. And even seasoned
vi users can’t seems to escape from it ever, (Esc is back), and
copy 🐈 OEM does not know where to place power ⚡ button.
Although most of the emacs key binding are sill relevant till this day. I can not stop to appreciation the thought and design went on building it, but 🐁 mouse binding are terrible.
;; redundent with f10 and gtk-menu
(global-unset-key [(control down-mouse-3)]) ; unbind (global-menu)
;; M-C-t opens terminals
(global-unset-key (kbd "C-M-t")) ; unbind (transpose-sexps)
(global-unset-key [(control down-mouse-3)]) ; unbind (global-menu)
;; yet useful but utterly misplaced, using tabbar
(global-unset-key [(control down-mouse-1)]) ; unbind (buffer-menu)
;; emacs is terrible mail client
(global-unset-key (kbd "C-x m")) ;; unbind (compose-mail)
;; it dosn't make sense
(global-unset-key (kbd "M-o")) ;; unbind (facemenu-mode)
;; gnu license
(global-unset-key (kbd "C-h w"))
(if window-system
(global-unset-key (kbd "C-x C-c")))
forward-char
to C-f till date
is 🤦 dumb, let enable some what common like search/find 🔍.
(global-set-key (kbd "C-f") 'isearch-repeat-forward) ;; unbind (forward-char)
read-only-mode
don’t make any sense in
modern day or age.
(global-set-key [f2] 'read-only-mode) ;; unbind (2C-two-columns)
(global-set-key [f6] 'toggle-truncate-lines)
When new function like toggle-frame-fullscreen
(F11) and toggle-frame-maximized
(M-F11) keeps popping in recent version
24.4, lets me to think emacs hasn’t given up on
being Operating System.
;;; full-screen since 24.4
;; handled via window manager
;; lets reserve it for something i.e realgud
(global-unset-key [f11])
;;; since, C-x k <return> too much acrobat
(global-set-key [(control d)] 'kill-buffer) ; same as terminal
;; escape do its thing
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
;;; backward kill like terminal
(global-unset-key (kbd "C-w"))
(global-set-key (kbd "C-w") 'backward-kill-word) ;; like in terminal
;; since, C-x k <return> too much acrobat
(global-set-key [(control d)] 'kill-buffer) ; same as terminal
;; (global-set-key (kbd "<f5>") 'redraw-display)
(global-set-key [f12] '(lambda()
(interactive)
(find-file "~/.config/emacs/README.org")))
yup thing are annoying 😤 here! avoid typing complete ‘yes’ and ‘no’.
(fset 'yes-or-no-p 'y-or-n-p)
A fancy way of saying any change in file (yup not using same editor, duh!) will magically 🎩 appear in editor.
(global-auto-revert-mode)
;;(setq auto-revert-verbose nil)
Ctrl-z is synonyms to undo not here because its suspend to background in 🐚 shell, Since emacs traces it roots from the terminal.
;;; this is confusion
(global-unset-key (kbd "C-z")) ; unbind (suspend-frame)
undo-tree preserve your undo chain and maintain undo branching.
(require 'undo-tree)
(dim-minor-name 'undo-tree-mode "")
(global-undo-tree-mode 1)
(setq undo-tree-visualizer-timestamps t)
;; stop unde tree from saving *.~undo-tree~ everywhere
(setq undo-tree-auto-save-history nil)
;; region undo
;; (setq undo-tree-enable-undo-in-region t)
;; normal undo and redo
(global-set-key (kbd "C-z") 'undo-only)
(global-set-key (kbd "C-S-z") 'undo-tree-redo)
- <2023-08-04 Fri>
Have been using undo-tree for so long, didn’t know undo region existed more in irreal blog, but confusing to use.
- <2020-02-12 Wed> retrying undo-tree again!
there are moments when
undo-tree
breaks down but, it has been a while it hasn’t or simply I haven’t been working enough! COVID-19 😷 - <2018-11-13 Tue> stopped using undo-tree
full days work vanished 😥 thought undo would handle it.
If you can yank (paste) in search, why to add to kill-ring (copy) just select the text and hit C-s!
In addition there is the whole section in wiki about search at point.
(add-hook
'isearch-mode-hook
(lambda ()
"Use region as the isearch text."
(when mark-active
(let ((region (funcall region-extract-function nil)))
(deactivate-mark)
(isearch-push-state)
(isearch-yank-string region)))))
Search forward and backward for word under cursor.
(defun search-forward-under-cursor ()
"Search for the word under the cursor."
(interactive)
(let ((word (thing-at-point 'word)))
(if word (search-forward word nil t))))
(global-set-key (kbd "C-S-s") 'search-forward-under-cursor)
(defun search-backward-under-cursor ()
"Search for the word under the cursor."
(interactive)
(let ((word (thing-at-point 'word)))
(if word (search-backward word nil t))))
(global-set-key (kbd "C-S-r") 'search-backward-under-cursor)
anzu highlight all search matches, most of the text editor does even vi this why not emacs. Here is the gify from original repository.
(require 'anzu)
(global-anzu-mode +1)
(global-unset-key (kbd "M-%"))
(global-unset-key (kbd "C-M-%"))
(global-set-key (kbd "M-%") 'anzu-query-replace)
(global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp)
Beyond the syntax color, ability to highlight adds clear 🧐 perspective during variable hunting.
(require 'symbol-overlay)
(global-set-key
(kbd "<C-mouse-3>")
(lambda (event)
(interactive "e")
(save-excursion
(goto-char (posn-point (event-start event)))
(symbol-overlay-put))))
More
(require 'highlight-symbol)
(global-set-key (kbd "C-S-r") 'highlight-symbol-prev)
(global-set-key (kbd "C-S-s") 'highlight-symbol-next)
(global-set-key [(shift f3)] 'highlight-symbol-at-point)
(global-set-key [(ctrl f3)] 'highlight-symbol-query-replace)
(global-set-key (kbd "<C-mouse-3>") (lambda (event)
(interactive "e")
(save-excursion
(goto-char (posn-point (event-start event)))
(highlight-symbol-at-point))))
- <2023-08-01 Tue>
highlight symbol has been un-mantained since 2016 switching to alternative symbol-overlay
Make cursor adaptive the to the width of the character, helpful in showing non-monospace characters like TAB and emoji.
(setq x-stretch-cursor t)
beacon gives extra feedback of cursor’s position on big movement. It can be understood better with this gify from original repository.
(require 'beacon)
(setq beacon-blink-delay '0.2)
(setq beacon-blink-when-focused 't)
(setq beacon-dont-blink-commands 'nil)
(setq beacon-push-mark '1)
(dim-minor-name 'beacon-mode "")
(beacon-mode t)
If sublime can have multiple cursor, emacs can too.
Here is 📹 video from Emacs Rocks! about it in ep13.
(require 'multiple-cursors)
(global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
(global-set-key (kbd "C-S-<wheel-up>") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-S-<wheel-down>") 'mc/mark-next-like-this)
;; this need to be key bind needs region to be selected
;; (global-set-key (kbd "C-S-<mouse-2>") 'mc/mark-all-like-this)
Some of the default behavior of emacs 💩 weird, text-selection is on of them, some time its the 🌈 WOW 🦄 moment 🥳 and other time its WTF.
;;; doing expected things
(delete-selection-mode 1)
Hotkey for font dialog is kinda absurd, that to for changing font-face, although for resize has Ctrl mouse-scroll might be sensible option.
In the effort of not being weird Shift mouse-primary-click is
used in region/text selection mouse-save-then-kill
.
(global-unset-key [(shift down-mouse-1)]) ; unbind (mouse-apperance-menu EVENT)
(global-set-key [(shift down-mouse-1)] 'mouse-save-then-kill)
so called wow moments
as you think selecting selection, emacs binds the selection keyboard free, when followed by mouse-secondary-click if its not in conflict.
4.8.2 expand region
Expand region increases the selected region by semantic units.
Here is video from Emacs Rocks! about it in ep09.
(require 'expand-region)
(global-set-key (kbd "C-S-SPC") 'er/expand-region)
(global-set-key (kbd "C-SPC") (lambda()
"set-mark when nothing is selected"
(interactive)
(if (use-region-p)
(er/contract-region 1)
(call-interactively 'set-mark-command))))
Although helm features are from the another league, I have not gone beyond the minibuffer. It took me while to get hang of it, one of reasons might be constant flickering creation of helm temporary popup windows 🪟 which I don’t like.
If you want to know more you can into helm intro
(require 'helm)
(helm-mode 1)
(dim-minor-name 'helm-mode "")
(setq helm-allow-mouse t)
(define-key global-map [remap list-buffers] 'helm-buffers-list)
(define-key global-map [remap execute-extended-command] 'helm-M-x)
(define-key global-map [remap find-file] 'helm-find-files)
(unless (boundp 'completion-in-region-function)
(define-key lisp-interaction-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point)
(define-key emacs-lisp-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point))
;;; I need arrow keys
(customize-set-variable 'helm-ff-lynx-style-map t)
;;; terminal like tabs selection
(define-key helm-map (kbd "<tab>") 'helm-next-line)
(define-key helm-map (kbd "<backtab>") 'helm-previous-line)
;;; show command details
(define-key helm-map (kbd "<right>") 'helm-execute-persistent-action)
(define-key helm-map (kbd "<left>") 'helm-execute-persistent-action)
- <2023-08-02 Wed>
helm fixed! 🥳
- <2023-08-01 Tue>
After switing to emacs 29.1 and updating packages, helm stopped working, details in emacs-helm/helm#2608
custom-initialize-reset: Symbol's value as variable is void: helm-info-source
- <2020-08-31 Mon>
lynx style navigation fix after new update
Some useful helm packages 🤩.
name | description |
---|---|
helm-descbinds | A convenient helm version of describe-bindings . |
helm-xref | Helm interface for xref results |
If you are using helm matching space-separated component is provided by default, which I only found out after trying orderless and its called “multi pattern matching” in helm.
(require 'orderless)
(setq completion-styles '(orderless))
I still don’t understand 😒 why emacs way of changing font size is weird. Mapping behavior similar to web-browser might be helpful to have cohesive experience.
zoom | keyboard | keyboard + mouse |
---|---|---|
in | Ctrl + Shift + = | Ctrl + mouse-scroll-up |
out | Ctrl + - | Ctrl + mouse-scroll-down |
1x | Ctrl + 0 |
These config are for the single buffer
(global-set-key [C-mouse-4] 'text-scale-increase)
(global-set-key [(control ?+)] 'text-scale-increase)
(global-set-key [C-mouse-5] 'text-scale-decrease)
(global-set-key [(control ?-)] 'text-scale-decrease)
(global-set-key
(kbd "C-0")
(lambda()
(interactive)
(text-scale-adjust (- text-scale-mode-amount))
(text-scale-mode -1)))
4.11 bookmark
It has never been so much easy to bookmark 🔖!
(require 'bm)
(setq bm-marker 'bm-marker-left)
;; (setq bm-cycle-all-buffers t) ;; Allow cross-buffer
(global-set-key (kbd "<left-margin> <mouse-1>") 'bm-toggle-mouse)
(global-set-key (kbd "<left-fringe> <mouse-1>") 'bm-toggle-mouse)
(global-set-key (kbd "S-<wheel-down>") 'bm-next-mouse)
(global-set-key (kbd "S-<wheel-up>") 'bm-previous-mouse)
;;; org-mode to expand the region containing a bookmark
(add-hook 'bm-after-goto-hook 'org-bookmark-jump-unhide)
- <2022-03-10 Thu> better key binding
fringe are too small to be used precisely as suggest
In Emacs, Killing means 🔪 cut (maybe ✂️: were not invented then!). Yanking paste text from the kill-ring back into the buffer. The kill-ring is 📋 clipboard for text snippets to used later, which can access in cyclic ♻️ order.
Yanking with C-y and cycling through using M-y, M-y, M-y can be bit alarming.
Beginners find Ctrl+v jump outlandish and sometime also for me. In this day and age certain function are arcane (may be someone uses it) but its not for me. When beginners try to paste with C-v scroll-up outlandishly make me think this is main reason of 😞 poor adoption, when will emacs have better default.
(global-set-key [(control v)] 'yank) ; unbind (scroll-up-command)
emacs comes with 📋 clipboard support knows as kill ☠️ ring 💍,
helm provided one of the best way to explore the entries using
helm-show-kill-ring
. Other ways of browsing can are listed in
wiki,
(setq repetitive_yank_region_point 0) ; 0 doesn't exist min is 1
(defun repetitive-yanking()
"yank and yank whats rest are in the kill ring"
(interactive)
(message "last-command: %S" last-command)
(if (string= last-command "yank")
(progn
(undo-only)
(when (= (point) repetitive_yank_region_point)
(progn
(goto-char repetitive_yank_region_mark)
(set-mark-command nil)
(goto-char repetitive_yank_region_point)
(delete-selection-helper "yank")))
(helm-show-kill-ring))
(progn
(when (use-region-p)
(setq repetitive_yank_region_mark (mark))
(setq repetitive_yank_region_point (point))
(message "%s" repetitive_yank_region_point)
(delete-selection-helper "yank"))
(yank))))
(global-set-key [(shift insert)] 'repetitive-yanking)
4.12.3 popup kill ring
(require 'popup-kill-ring)
- <2022-10-06 Thu>
opted for helm since it hard to see multi-line clips
After using org-mode nothing is same, moving the section is one of the feature you want to have every where. Although many do have feature to drag a lines or the region. drag-stuff is great but its default binding is conflicts with org-mode.
(require 'drag-stuff)
;;; default bindings conflicts with org mode
;; (drag-stuff-define-keys)
;; better bindings
(global-set-key [(meta shift up)] 'drag-stuff-up)
(global-set-key [(meta shift down)] 'drag-stuff-down)
(global-set-key [(meta shift left)] 'drag-stuff-left)
(global-set-key [(meta shift right)] 'drag-stuff-right)
winner mode saving the window configure
(when (fboundp 'winner-mode)
(winner-mode 1))
(setq split-width-threshold 120)
some of the basic things provide by emacs internal packages.
(add-hook 'prog-mode-hook 'subword-mode) ; camelCase is subword
(add-hook 'prog-mode-hook 'which-function-mode)
(add-hook 'prog-mode-hook (lambda() (setq truncate-lines t)))
(setq show-paren-style 'expression)
;; (setq show-paren-match '((t (:inverse-video t)))) ;; this is not working using custom set face
(show-paren-mode 1)
This 🌈 mode is barely noticeable at first glance but, if you live by parenthesis it nice thing to have around.
(add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
Yet again, bad default for emacs 😳 the key-binding does not toggle comment on the line, may be its because of who always wrote the perfect code, only needed comment to add GPL!
But, Our code is SELF DOCUMENTED! 😎
;;; comment whole line
(defun comment-indent()
"custom over-ride comment-indent to comment whole line"
(interactive)
(comment-or-uncomment-region (line-beginning-position) (line-end-position)))
;;; default comment string
(setq-default comment-start "# ")
(defun watch-words ()
(interactive)
(font-lock-add-keywords
nil '(("\\<\\(FIX\\|TODO\\|BUGS?\\)"
1 font-lock-warning-face t))))
(add-hook 'prog-mode-hook 'watch-words)
Sorry Richard no tabs here!
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq tab-width 4)
After years using highlight indentation with performance issues and shifting through multiple 🍴 fork and patches, I have moved to highlight-indent-guides has much better compatibility. Although I hate default fill method.
(setq highlight-indent-guides-method 'character)
(setq highlight-indent-guides-character ?\┊)
(add-hook
'prog-mode-hook
'(lambda()
(require 'highlight-indent-guides)
(dim-minor-name 'highlight-indent-guides-mode "")
(highlight-indent-guides-mode)))
align.el has a few commands that can line up text with respect to
white-space, assignment, columns or regexp specified delimiters,
which can be modified using align-rules-list
, more info can be
found in wiki.
(eval-after-load "align"
'(add-to-list
'align-rules-list
'(prog-align-colon
(mode . '(prog-mode))
(regexp . "\\(\\s-*\\)[=:]\\(\\s-*\\)")
(repeat . nil))))
(add-hook
'prog-mode-hook
(lambda()
(local-set-key (kbd "C-S-a") 'align-entire)))
It is 😠 frustrating many code folding packages not folding-mode does not 🚧 work as planned. so many corner cases and constantly 💔 breaking. Some of the code folding I have tried are
(add-hook 'prog-mode-hook 'yafolding-mode)
(add-hook 'compilation-mode-hook 'yafolding-mode)
- <2022-03-11 Fri> hello ya-folding
have been using for a while
- <2021-05-27 Thu> org export problem
hideshow vis has trouble with org export
If you have working with non-emacs people sooner or later you might face this problem, those pesky trailing spaces/tabs.
Phenomenal Cosmic Powers! Itty Bitty trailing spaces!
Although end result might be same but it all shows in diff, ideally there should be no empty lines at the beginning of a file, no empty lines at the end of a file, no trailing whitespace, no mixture of tabs and spaces, etc.
older delete-trailing-whitespace
command, that simply deletes
trailing white-space.
whitespace-cleanup
aware of the whitespace-style variable, used
by whitespace-mode.
different types of hooks
- write-file-hooks
- before-save-hooks
(defun nuke-trailing ()
(add-hook 'write-file-hooks 'delete-trailing-whitespace)
(add-hook 'before-save-hooks 'whitespace-cleanup))
(add-hook 'prog-mode-hook 'nuke-trailing)
hungry-delete mode is interesting but still its quirky, mapping it to default delete/backspace will result typing your needed white-spaces back again! So as the mode its NO, NO. Manually toggling the mode just to delete few continous white spaces. Naah!
(require 'hungry-delete)
(global-set-key (kbd "S-<backspace>") 'hungry-delete-backward)
There is the interesting outlook of smart-hungry-delete, which I have not used for the while.
(require 'smart-hungry-delete)
(smart-hungry-delete-add-default-hooks)
(global-set-key (kbd "<backspace>") 'smart-hungry-delete-backward-char)
;; (global-set-key (kbd "<delete>") 'smart-hungry-delete-forward-char)
;; (global-set-key (kbd "<delete>") '(lambda ()
;; (if use-region-p '(smart-hungry-delete-forward-char) '(delete-char))))
Of course emacs can add newline at End Of File just to make sure git doesn’t go crazy! for unchanged files. But don’t enable it let fancy IDE people wonder how to remove newline at EOF.
CAUTION! BUT MOST OF WILL JUST MAKE MESS
;; (setq require-final-newline t)
I have been wanting white-space to be displayed for selected region since I saw feature in sublime.
Yet there was nothing similar to-be found, thankfully 😭 @twlz0ne created the new minor mode, (since, I can’t wrap my head to lisp).
(add-to-list 'load-path "~/.config/emacs/00testing/whitespace4r.el/")
(require 'whitespace4r)
(whitespace4r-mode)
- <2022-03-19 Sat> workable
mode is buggy or just because of my theme or configuration
(add-hook 'compilation-mode-hook (lambda() (setq truncate-lines t)))
(global-set-key (kbd "C-<f8>") 'recompile)
(global-set-key (kbd "<f8>")
(lambda()
(interactive)
(if (get-buffer-window "*compilation*")
(delete-windows-on "*compilation*")
(display-buffer "*compilation*"))))
(require 'ansi-color) ;; buitin 28.1
(add-hook 'compilation-filter-hook 'ansi-color-compilation-filter)
git is amazing but magit is magic 🪄!
(require 'magit)
(global-set-key (kbd "C-x C-g") 'magit-status)
(add-hook 'git-commit-mode-hook 'turn-on-flyspell)
(global-set-key (kbd "C-x C-l") 'magit-log-buffer-file) ; unbind (downcase-region)
(setq magit-diff-refine-hunk 'all)
(setq magit-display-buffer-function 'magit-display-buffer-fullframe-status-v1)
Tuning magit for performance from manual.
(setq magit-refresh-status-buffer nil)
(remove-hook 'magit-refs-sections-hook 'magit-insert-tags)
Many commands that are rarely used in magit are hidden by default.
magit uses the transient.el
library for popups and the
visibility of infix and suffix commands are controlled by
transient-default-level
. Default level is 4 some of the command I
use are in level 7.
(setq transient-default-level 7)
(setq magit-process-finish-apply-ansi-colors t)
(setq magit-ediff-dwim-show-on-hunks t)
(setq ediff-split-window-function 'split-window-horizontally)
magit status doesn’t show white space removal as mention in this issue
(setq magit-diff-paint-whitespace-lines 'all)
(setq magit-diff-paint-whitespace t)
(setq magit-diff-refine-ignore-whitespace nil)
(setq magit-diff-refine-hunk nil)
magit-lfs plugin for large-file-storage
project.el is a build-in package introduced around v26 which provides basic action for managing code project similar to projectile where I only use to find a file, or run grep.
(global-set-key (kbd "C-<f9>") 'project-compile)
(global-set-key (kbd "C-S-f") 'project-find-file)
(global-set-key (kbd "C-S-t") 'project-shell)
(global-set-key (kbd "C-S-g") 'project-find-regexp)
project.el marks the project by the version control if there is no version control file aren’t tracked.
https://andreyorst.gitlab.io/posts/2022-07-16-project-el-enhancements/ https://christiantietze.de/posts/2022/03/mark-local-project.el-directories/
If your source consist of hundreds of line then don’t be like me use projectile mode like @krazedkrish.
ya C-S-p for select line
previous, just get along with it, have you tried it in
chrome, sublime, vscode? and don’t forget
the helm-projectile
.
(require 'projectile)
(projectile-mode +1)
(require 'helm-projectile)
(helm-projectile-on)
(global-set-key (kbd "C-S-p") 'helm-projectile-find-file)
(global-set-key (kbd "C-S-t") 'projectile-find-tag)
(global-set-key (kbd "C-S-g") 'helm-projectile-grep)
Search files for the occurrence of a string of characters that matches a specified pattern.
ripgrep is modern rendition grep command using Rust’s regex engine which is extremely fast. ripgrep.el package integrates the command with emacs.
(advice-add #'project-find-regexp :override #'ripgrep-regexp)
facing trouble when in fresh copy of repo, will fix later
(add-hook
'prog-mode-hook
'(lambda()
(setq dired-omit-files
(concat dired-omit-files "\\|\\.git$\\|venv$"))))
(require 'company)
(dim-minor-name 'company-mode "")
(global-company-mode +1)
(require 'company-box)
(dim-minor-name 'company-box-mode "")
(add-hook 'company-mode-hook 'company-box-mode)
company mode supports emoji.
(require 'company-emoji)
(add-to-list 'company-backends 'company-emoji)
(add-to-list 'company-emoji-aliases '(:poop: . ":hankey:"))
customize face company-tooltip-selection
(custom-set-faces
'(company-tooltip-selection ((t (:inherit company-tooltip-selection :extend t :inverse-video t)))))
5.14 ggtags
Using language server protocol (LSP) since, ggtags make my emacs super slow, but not sure why!
More
(add-hook 'c-mode-common-hook (lambda ()
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
(ggtags-mode 1))))
(add-hook 'python-mode-hook 'ggtags-mode)
(global-set-key (kbd "<C-double-mouse-1>") 'ggtags-find-tag-mouse)
Language Server Protocol is a JSON-RPC protocol to delegate language aware features to a common server process using generic LSP client. The current lsp specifications was proposed by Microsoft as a way for different editors and development environments to share language analysis back-ends. If you’d like to read more about the inner workings, consider this post.
lsp-mode aims to provide IDE-like experience by providing optional integration with the most popular Emacs packages like company, flycheck and projectile.
The proper way to start lsp-mode is using M-x lsp
To check its capabilities on running lsp M-x lsp-describe-session
(require 'lsp-mode)
;; don't override ('er/expand-region)
(define-key lsp-mode-map (kbd "C-S-SPC") nil) ; unset (lsp-signature-activate)
(setq lsp-headerline-breadcrumb-enable nil)
(setq lsp-diagnostics-provider :none) ;; disable flycheck
;; (setq lsp-prefer-flymake nil) ;; use flycheck over flymake
debugging variables
;; (setq lsp-print-io t)
;; (setq lsp-trace t)
(setq lsp-print-performance t)
language-servers should be installed ⚒️ manually you can see the list of supported languages at their website and documented at lsp-clients.json.
(add-hook 'sh-mode-hook #'lsp)
M-x
lsp-doctor
🚑 is really handy to get started but still there
other tweak 🔧 in lsp-mode docs.
;; (setq lsp-log-io nil) ; default:nil, for debugging
(setq lsp-idle-delay 0.500)
(setq company-lsp-cache-candidates t)
It has been a while I have been using the native compile since it merge into main branch although its still worth it increased overall performance not just LSP,
To know about my builds see build or check my releases.
(setq lsp-use-plists t)
Using plists for de-serialization is only triggers
when emacs starts with LSP_USE_PLISTS
is true
, and lsp wiki
recommending shell to start, But it could be better 😎 just need
to replace emacs with 🐚 shell-script.
cat /usr/local/bin/emacs
LSP_USE_PLISTS=true exec /usr/bin/emacs $*
5.15.2.3 file-watcher
Watching all the files in huger project directories, may slow down performance.
Yet to find how it helps so disabling it.
(setq lsp-enable-file-watchers nil) ; default:t
Default warning threshold is 1000 which can be changing variable
(setq lsp-file-watch-threshold 1000)
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\venv\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\vendors\\'")
(add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\__pycache__\\'"))
This is extension for all the higher level UI modules of LSP, like flycheck support and code lenses.
By default, lsp-mode automatically activates lsp-ui unless
(setq lsp-auto-configure nil)
.
(require 'lsp-ui)
(add-hook 'lsp-mode-hook 'lsp-ui-mode)
(setq lsp-ui-doc-enable t
lsp-ui-doc-use-childframe t
lsp-ui-doc-position 'top
lsp-ui-doc-include-signature t
lsp-ui-sideline-enable nil
lsp-ui-flycheck-enable t
lsp-ui-flycheck-list-position 'right
lsp-ui-flycheck-live-reporting t
lsp-ui-peek-enable t
lsp-ui-peek-list-width 60
lsp-ui-peek-peek-height 25)
Although I barely use debugger, lets say I’m more of print()
person, may be because I work much with python
than C
.
Nevertheless, a good IDE should have 🐛 debugger, but emacs is
TextEditor OS, and ships with Grand Unified Debugger (GUD), its
fairly usable with terrible defaults and not to mention with more
key bindings.
;; unlike gdb, pdb is a inbuilt python module
(setq gud-pdb-command-name "python -m pdb")
GUD is great but realgud much better, although you will miss gdb-multiple-windows but it does’nt work with pdb to begin with. If you ask why realgud here is some interesting rant from its developer.
(setq realgud:pdb-command-name "python -m pdb")
I’m ashamed to say I haven’t used linter much before 2020. I accidentally found flymake working, as I can remember I had autopep8 recently in 2021. Since my lsp was already configure it started linting my code it was magical! 😀
I had kept my head under the sand, because its pain using self configured emacs and how a productive day goes to waste setting up your environment just right. Finally after to 2 days of I changed to flycheck as lsp recommended yet dealing with the virtual enivroment was frustrating which asked you to install flake8 in every environment.
(setq flycheck-check-syntax-automatically '(save))
In the realm of code, where tales go untold, Amidst chaos, style's worth is shown. Refuse temptation, resist the allure, For clarity and understanding, endure. Lost in the scroll, beyond limits surpassed, Let reason guide, and doubts be outlast. Expand horizons, with clarity set sail, Embrace new paths, where beauty prevails.
flycheck-pos-tip is the flycheck extension shows errors using pos-tip popup.
if you this with lsp extension mouse hover function would be overridden by lsp-ui.
(with-eval-after-load 'flycheck (flycheck-pos-tip-mode))
(add-to-list 'auto-mode-alist '("\\.mjs$" . js-mode))
(add-hook 'js-mode-hook #'lsp)
(add-hook 'css-mode-hook #'lsp)
For javascript typescript-language-server has been recommended by the wiki to install it in arch see AUR.
But it generates .log
directory on project root which can be
address by setting option to the server as mentioned in #1490
using configuration variables.
(setq lsp-clients-typescript-server-args '("--stdio" "--tsserver-log-file" "/dev/stderr"))
Naming seems to be different in Arch Official Packages 📦 and lsp-client, which lets lsp to not find executable.
type | packages | lsp-mode/client |
---|---|---|
official | vscode-css-languageserver | lsp-css.el |
official | vscode-html-languageserver | lsp-html.el |
I seem there is no way to change the list on startup other than registering the new client to stop using npm.
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection (list "vscode-css-languageserver" "--stdio"))
:activation-fn (lsp-activate-on "css")
:server-id 'my-css-ls))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection (list "vscode-css-languageserver" "--stdio"))
:activation-fn (lsp-activate-on "html")
:server-id 'my-html-ls))
- <2022-03-23 Wed> runs on eval expression
lsp couldn’t find the system binary if the change dependencies when kept in init file but ran on eval! 🤔
(lsp-dependency 'css-languageserver '(:system "vscode-css-languageserver"))
I mainly use eslint with flycheck.
(add-hook 'js-mode-hook 'flycheck-mode)
web-mode is an autonomous emacs major-mode for editing web templates.
(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(setq web-mode-enable-block-face t)
(setq web-mode-enable-current-column-highlight t)
(setq web-mode-style-padding 4)
(setq web-mode-script-padding 4)
;; they don't descend from prog-mode
(add-hook 'web-mode-hook (lambda () (run-hooks 'prog-mode-hook)))
;; ya-snippet completion for web-mode
(add-hook 'web-mode-hook #'(lambda () (yas-activate-extra-mode 'html-mode)))
djhtml is file format is for Django or Jinja template which works with mixed HTML, CSS and JS with template tags.
(add-to-list 'auto-mode-alist '("\\.djhtml?\\'" . web-mode))
Let lsp know djhtml is html.
(add-to-list 'lsp-language-id-configuration '(web-mode . "html"))
There are stuff like moz-repl, skewer-mode, impatient-mode but nothing beats good old way with xdotool hail X11 for now! 😂
(require 'browser-refresh)
(setq browser-refresh-default-browser 'firefox)
above thingi comment, lets do Makefile!
WINDOW=$(shell xdotool search --onlyvisible --class chromium) run: xdotool key --window ${WINDOW} 'F5' xdotool windowactivate ${WINDOW}
Welcome to flying circus 🎪.
My python familiarity predates emacs, It definitely should have its own section by now (<2021-05-27 Thu>) but I strangely even after dabbling through py-exec, python configuration has been simplest for decades.
Recently I have been testing lsp for development it has never been better, countless hours wasted configuring code jumps using ggtags gives be nightmare which never worked out in practical sense .
(setq-default py-indent-offset 4)
(add-hook
'python-mode-hook
(lambda()
(local-set-key (kbd "C-<") 'python-indent-shift-left)
(local-set-key (kbd "C->") 'python-indent-shift-right)))
python-docstring is a package that overrides fill-paragraph so it is compatible with Python docstrings. It works for both sphinx-doc and re Structured text formats.
(add-hook
'python-mode-hook
(lambda ()
(python-docstring-mode)
(dim-minor-name 'python-docstring-mode "")))
- <2022-03-01 Tue>
not working as expected something is not correct
http://tkf.github.io/emacs-jedi/
Since python3.3 virtual environment can be created using python
-m venv env
without python-virtualenv.
(autoload 'jedi:setup "jedi" nil t)
(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:complete-on-dot t) ; optional
(setq jedi:environment-virtualenv "python -m venv")
(setq jedi:setup-keys t) ; optional
For python lsp looks for pyls and pylsp by default, I use using pyright which need extra emacs package lsp-pyright.
(add-hook
'python-mode-hook
(lambda()
(when (not (derived-mode-p 'scons-mode))
(lsp))))
- <2020-10-14 Wed>
/usr/lib/python3.8/site-packages/pyls/uris.py:110 path = path if isinstance(path, str) else path.as_posix()
- <2020-09-24 Thu>
python-jedi 0.17.2 in system, lsp works without AUR
- <2020-08-25 Tue>
buggy python-jedi 17.0. Needed manually editing in path variable setting as
.as_posix()
or useyaourt -S python-jedi-git
Yes! we work on virtual environment (venv), and we do love to source them, who can’t seems to get things strait especially in unix systems.
In reality venv just switches executable, seriously loading venv
might be sane for terminal operation or running errands with
pip. but for running just execute directly form
./venv/bin/python your.py
.
Damn don’t try to solve artificial problems! so goes for idiotic venv modes trying to find venv folder.
Yet for emacs environment using lsp and console this might only option! yeah I’m eating on my own words bite me! but seriously all env packages gives me creeps.
to check if which venv is activated (getenv "VIRTUAL_ENV")
(defun pyvenv-autoload ()
(interactive)
"auto activate venv directory if exists"
(require 'pyvenv)
(f-traverse-upwards (lambda (path)
(let ((venv-path (f-expand "venv" path)))
(when (f-exists? venv-path)
(pyvenv-activate venv-path))))))
(add-hook 'python-mode-hook 'pyvenv-autoload)
Go beyond pycodestyle (PEP8) here is my config using flake8.
(add-hook 'python-mode-hook 'flycheck-mode)
;; append the default config for fallback
(add-to-list 'flycheck-flake8rc "~/.config/flake8" t)
(setq flycheck-python-flake8-executable "/usr/bin/flake8") ;; skip venv
;; (setq flycheck-disabled-checkers '(python-pylint))
(setq flycheck-python-pylint-executable "/usr/bin/python") ;; skip venv
;; (setq flycheck-python-complie-executable "/usr/bin/python") ;; skip venv
flake8 is suported by lsp which can be enable via
(setq lsp-pyls-plugins-flake8-enabled t)
flycheck allows multiple checker which can be enabled with or by verify setup UI.
(flycheck-add-next-checker 'python-flake8 'python-pyright)
py-exec is ess-style execution for python script.
(add-to-list 'load-path "~/.config/emacs/00testing/py-exec/")
(add-hook
(require 'py-exec)
'python-mode-hook
(lambda() (local-set-key (kbd "<C-return>") 'py-execution)))
If any one had created the Makefile in this day an age, it would definitely should be considered as 😖 crime. Make came out in 1976 and did more that what it promised to do now it has started showing the age. Many of complex projects are still handled by the Make which is shows the robustness of the system but its excruciatingly difficult to wrap you head around it. Now days Makefile is mostly the vomit 🤮 of automake which I find absolutely ridiculous.
After years of ignorance and pain staking writing Makefile I have to hang the 🏳️ white flag. Its worst than elisp which has at least documentation you don’t wander around searching how to do the simplest task . At times it made me think why not replace it with bash script! but make was built to replace bash script, do you sense the conundrum.
The SCons Github wiki has an in-depth explanation about why Make comes up short. But if some one told me it was written in 🐍 python I would have been sold in first palace, Let see where it leads to.
(setq compile-command "/usr/bin/python /usr/bin/scons")
(define-derived-mode scons-mode python-mode "scons"
"A python-mode for scons files")
(add-to-list 'auto-mode-alist '("SConstruct" . scons-mode))
(add-to-list 'auto-mode-alist '("SConscript" . scons-mode))
org-mode introduces to the you to different world, which makes it distinct. All but one complain is it throws the normal convention out of the window (just remember emacs has worst defaults)!
removing the C-j bind for goto-last-change
(add-hook
'org-mode-hook
(lambda () ; used for (goto-last-change)
(define-key org-mode-map (kbd "C-j") nil)))
(setq org-adapt-indentation t) ; edit structure (indent content also)
(setq org-support-shift-select t) ; enable text-selection when possible
(add-hook 'org-mode-hook 'lambda() (require 'org-mouse))
(setq sentence-end-double-space nil)
(add-hook 'org-mode-hook 'flyspell-mode)
auto-fill-mode
is named by auto-fill-function
via magnars.
(dim-minor-name 'auto-fill-function "")
(add-hook 'org-mode-hook 'turn-on-auto-fill)
- <2020-02-01 Sat>
problem with emacs 26 this see spacemacs issue
active Babel languages
(org-babel-do-load-languages 'org-babel-load-languages
'((shell . t)
(sql . t)
(js . t)
(C . t)
;; (rust . t)
;; (ipython . t) ; uses cl, install ob-ipython
(python . t)))
;; (add-hook 'org-babel-after-execute-hook 'org-display-inline-images 'append)
(add-to-list 'org-babel-default-header-args
'(:noweb . "yes")
'(:eval . "no-export"))
switch the python location command set Local Variables
org-babel-python-command: "/usr/bin/python2"
- <2018-05-30>
26 is official again sh should be shell
- <2018-01-04> sh mode
Currently babel code execution doesn’t work, haven’t found the work around yet, so downgraded emacs from 26 -> 25, couldn’t track what was the last working snapshot.
running in to problem recently sh is now shell, or will cause
ob-sh
not found error.
Its most 😞 disappointing when application opens doesn’t open in your favorite application, but org-mode has it covered 😭.
(add-hook
'org-mode-hook
'(lambda()
(setq org-file-apps
'((auto-mode . emacs)
("\\.jpg\\'" . "eog %s")
("\\.svg\\'" . "ristretto %s")
("\\.png\\'" . "eog %s")
("\\.gif\\'" . "eog %s")
("\\.mkv\\'" . "mplayer %s")
("\\.mp4\\'" . "vlc %s")
("\\.webm\\'" . "mplayer %s")
("\\.html\\'" . "firefox %s")
("\\.pdf\\'" . "evince %s")))))
fragtog mode automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them.
(add-hook 'org-mode-hook 'org-fragtog-mode)
based on zoom latex fragments relative to buffer text
(plist-put org-format-latex-options :scale 2.5)
;; (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.8))
(defun update-org-latex-fragments ()
(org-toggle-latex-fragment '(16))
(plist-put org-format-latex-options :scale text-scale-mode-amount)
(org-toggle-latex-fragment '(16)))
(add-hook 'org-mode-hook (lambda()
(add-hook 'text-scale-mode-hook 'update-org-latex-fragments)))
(setq
org-html-allow-name-attribute-in-anchors t
org-html-doctype "html5"
org-html-validation-link nil
org-html-checkbox-type 'html)
Add dot after headline
(defun my-html-filter-headline-yesdot (text backend info)
"Ensure dots in headlines."
(when (org-export-derived-backend-p backend 'html)
(save-match-data
(when (let ((case-fold-search t))
(string-match (rx (group "<span class=\"section-number-" (+ (char digit)) "\">"
(+ (char digit ".")))
(group "</span>"))
text))
(replace-match "\\1.\\2" t nil text)))))
(eval-after-load 'ox
'(progn
(add-to-list 'org-export-filter-headline-functions
'my-html-filter-headline-yesdot)))
custom exporter for checkbox as suggest by John Kitchin.
org-mode can be addictive, someone have missed a lot and created these awesome modes. Now we can use them minor-modes too inside comments.
org’s outline with outshine extension.
(require 'outshine)
(add-hook 'prog-mode-hook 'outline-minor-mode)
(add-hook 'compilation-mode-hook 'outline-minor-mode)
(add-hook 'outline-minor-mode-hook 'outshine-mode)
(add-hook
'outline-minor-mode-hook
'(lambda()
(dim-minor-name 'outshine-mode "")
(dim-minor-name 'outline-minor-mode "")
(global-unset-key (kbd "<M-right>"))
(local-set-key (kbd "<M-right>") 'outline-promote)
(global-unset-key (kbd "<M-left>"))
(local-set-key (kbd "<M-left>") 'outline-demote)
(local-set-key (kbd "C-<iso-lefttab>") 'outshine-cycle-buffer)))
for links you need orglink is available in MELPA.
(add-hook
'prog-mode-hook
(lambda()
(orglink-mode)
(dim-minor-name 'orglink-mode "")))
- <2022-02-27 Sun>
Warning (emacs): ‘outshine-hook-function’ has been deprecated, use ‘outshine-mode’ Disable showing Disable logging
Making power-point is lame, and updating is the mess! there is the thing call reveal.js The HTML Presentation Framework which lets you make slides in browser but, its more of HTML than the actual content, *org-reveal take the next step generate the slides from the org-file, isn’t that neat!
org-re-reveal is the fork of yjwen/org-reveal with enhancement
(add-hook 'org-mode-hook '(lambda ()
(require 'org-re-reveal)))
(setq
org-re-reveal-root "~/Public/vendors/reveal.js"
org-re-reveal-extra-css "~/Public/vendors/reveal.js/override.css"
org-re-reveal-mathjax-url "~/Public/vendors/MathJax/es5/tex-mml-chtml.js"
org-re-reveal-theme "night")
- <2020-02-05 Wed>
org-re-reveal trying
- <2018-06-21 Thu>
yjwen/org-reveal working again
- <2018-05-20 Sun>
yjwen/org-reveal isn’t working anymore
(set-face-attribute 'default nil :family "Andale Mono" )
(custom-set-faces
'(org-level-1 ((t (:family "Iosevka" :height 150))))
'(org-level-2 ((t (:family "Fira Mono for Powerline" :height 120))))
'(org-block-begin-line ((t (:foreground "#008EA1"))))
'(org-block ((t (:family "Source Code Pro" :background "#244"))))
'(org-block-end-line ((t (:foreground "#008EA1"))))
'(org-table ((t (:background "#244"))))
'(org-quote ((t (:foreground "#E6E6FA" :background "#244"))))
'(org-verse ((t (:foreground "#E6E6FA" :background "#244"))))
)
http://www.gnu.org/software/emacs/manual/html_mono/ccmode.html
(setq c-tab-always-indent t)
(setq c-basic-offset 4)
(setq c-indent-level 4)
(setq gdb-many-windows t)
(setq gdb-show-main t)
styling
https://www.emacswiki.org/emacs/IndentingC
(require 'cc-mode)
(c-set-offset 'substatement-open 0)
(c-set-offset 'arglist-intro '+)
(add-hook 'c-mode-common-hook '(lambda() (c-toggle-hungry-state 1)))
(define-key c-mode-base-map (kbd "RET") 'newline-and-indent)
https://github.com/rust-lang/rust-mode
ob-rust
for org mode
(add-hook
'rust-mode-hook
(lambda ()
(require 'rust-mode)
(setq indent-tabs-mode nil)))
;; (setq rust-format-on-save t) ; needs rustfmt
https://www.emacswiki.org/emacs/SqlMode
Starting with version 21.4, sql-mode included with emacs
to start interactive mode
M-x sql-product-interactive
https://www.emacswiki.org/emacs/download/sql-upcase.el
See also http://stackoverflow.com/q/22091936/324105
(when (require 'sql-upcase nil :noerror)
(add-hook 'sql-mode-hook 'sql-upcase-mode)
(add-hook 'sql-interactive-mode-hook 'sql-upcase-mode))
(add-hook 'conf-mode-hook 'nlinum-mode)
(add-to-list 'auto-mode-alist '("\\.service" . systemd-mode))
(add-hook 'systemd-mode-hook 'company-mode)
Goodies for 🐳 🐳 🐳
(require 'dockerfile-mode)
(add-to-list 'auto-mode-alist '("Dockerfile" . dockerfile-mode))
(setq auto-mode-alist
(cons '("\.json$" . json-mode) auto-mode-alist))
(add-hook 'latex-mode-hook (lambda ()
(nlinum-mode)
(drag-stuff-mode-rho-bindings)
(toggle-truncate-lines +1)))
yasnippet is template system for emacs, snippet collection in
distributed separately as yasnippet-snippet
.
(require 'yasnippet)
(require 'yasnippet-snippets)
(yas-reload-all)
(add-hook 'prog-mode-hook 'yas-minor-mode-on)
(add-hook 'org-mode-hook 'yas-minor-mode-on)
wordplay consist of collection of nifty scripts.
(load "~/.config/emacs/scripts/wordplay.el")
Normally C-a will move your cursor to 0th column of the line,
this snippet takes consideration of the indentation, and for
default behavior “repeat the action” which will toggle between the
first non-whitespace character and the bol
.
(global-set-key [remap move-beginning-of-line]
'smarter-move-beginning-of-line)
10.2 toggle lettercase
By default, you can use M-c to change the case of a character at the cursor’s position. This also jumps you to the end of the word. However it is far more useful to define a new function by adding the following code to your emacs config file. Once you have done this, M-c will cycle through “all lower case”, “Initial Capitals”, and “ALL CAPS” for the word at the cursor position, or the selected text if a region is highlighted.
(global-set-key "\M-c" 'toggle-letter-case)
(global-set-key (kbd "C-`") 'duplicate-current-line)
(global-set-key (kbd "C-~") 'duplicate-current-word)
only enable for C-<insert>
(global-set-key (kbd "C-<insert>") 'kill-ring-save-current-line)