dot-emacs icon indicating copy to clipboard operation
dot-emacs copied to clipboard

my emacs config :godmode:

#+TITLE: emacs diaries #+DATE: Sunday, Jan 17 2016 #+DESCRIPTION: my emacs config diaries! #+AUTHOR: rho #+OPTIONS: num:t toc:1 #+STARTUP: overview

BEWARE: AUTHOR does'nt know much elisp and suffer from parenthesiophobia, but couldn't stop tinker around.

#+ATTR_HTML: title="screenshot" [[https://www.google.com][file:https://raw.githubusercontent.com/rhoit/dot-emacs/dump/screenshot/screenshot02.png]]

  • INTRO

    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.

    #+BEGIN_EXAMPLE FYI "emacs vanilla is a lie" #+END_EXAMPLE

    Emacs is relics of the past, have a criminal [[http://www.manuelmagic.me/manuelsweb/resources/Geek/Text-editors/text_editors.pdf][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 [[https://slate.com/technology/2014/05/oldest-software-rivalry-emacs-and-vi-two-text-editors-used-by-programmers.html][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 [[https://lwn.net/Articles/819452/][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 [[https://en.wikipedia.org/wiki/IKEA_effect][IKEA effect]].

** introspect

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][lsp]], native-compilation, yet emacs still needs more.

** about

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 [[https://www.gnu.org/software/emacs/manual/html_node/efaq/New-in-Emacs-24.html][What's new in emacs24]] using emacs25. also [[https://www.emacswiki.org/emacs/el-get][el-get]] existed, and now =package.el= was official too. I can't seem to [[https://github.com/dimitri/el-get/issues/1468][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 [[https://github.com/rhoit/dot-emacs/blob/master/init.el][~/emacs.d/init.el]] was orgified (org-bable-tangle).

In summary its,

  • highly opinionated configuration tracked in git
  • does'nt provide the any layer of abstraction
  • more of notes and rants and reason to do so

Since, version [[https://www.masteringemacs.org/article/whats-new-in-emacs-27-1#startup-changes-in-emacs-27.1][27.1]] emacs supported [[https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html][XDG]] convention every thing can be in =~/.config/emacs=

** getting-it

๐Ÿงจ DISCLAIMER: ๐Ÿ’ MAKE SURE YOU HAVE THE BACKUP โš ๏ธ AUTHOR will not be responsible for the ๐Ÿ”ฅ harm ๐Ÿ”ฅ cause by using this configuration.

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.

#+BEGIN_EXAMPLE $ git clone https://github.com/rhoit/dot-emacs /path/to/dot-emacs #+END_EXAMPLE

** why-this-config?

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

  • [[https://github.com/hlissner/doom-emacs][Doom Emacs]]
  • [[https://github.com/syl20bnr/spacemacs][Spacemacs]]
  • [[https://github.com/seagle0128/.emacs.d][Centaur Emacs]]
  • [[https://github.com/ergoemacs/ergoemacs-mode][ergoemacs-mode]]
  • [[https://github.com/rdallasgray/graphene][Graphene]]
  • [[https://github.com/magnars/.emacs.d][magnars emacs.d]]
  • [[https://github.com/bodil/ohai-emacs][ohai-emacs]]
  • [[https://github.com/bbatsov/prelude][Prelude]]
  • [[https://github.com/raxod502/radian][Radian]]
  • [[https://github.com/purcell/emacs.d][purcell emacs.d]]

And there configurations too.

  • [[https://github.com/mattduck/dotfiles/blob/master/emacs.d.symlink/init.org][mattduck]]
  • [[https://github.com/DiegoVicen/my-emacs][DiegoVicen]]
  • [[https://github.com/stardiviner/emacs.d][stardiviner]]
  • [[https://github.com/MatthewZMD/.emacs.d][M-EMACS]]
  • [[https://github.com/farlado/dotemacs][Farladoโ€™s Illiterate GNU Emacs]]
  • [[https://blog.sumtypeofway.com/posts/emacs-config.html][Emacs is Agar for Brain Worms]]
  • [[https://config.daviwil.com/emacs][David Wilson's config]]
  • [[https://github.com/rougier/dotemacs/blob/master/dotemacs.org][rougier]]
  • [[https://github.com/novoid/dot-emacs/blob/master/config.org][novoid]]

** structure

#+BEGIN_EXAMPLE Entropy is important but not here #+END_EXAMPLE

This is the way, I keep my things have been same for many year now!

#+BEGIN_EXAMPLE ~/.config/emacs -> dot-emacs โ”œโ”€โ”€ elpa # pacman โ”œโ”€โ”€ cfg.compile.el โ”œโ”€โ”€ cfg.tabbar.el : : โ”‚ โ”œโ”€โ”€ ... : โ”œโ”€โ”€ 00testing # testing stuffs โ””โ”€โ”€ snippets # yasnippet stuffs โ”œโ”€โ”€ fundamental-mode : โ””โ”€โ”€ python-mode #+END_EXAMPLE

** troubleshooting

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

    #+BEGIN_SRC emacs-lisp :tangle no (setq debug-on-error 1) (setq debug-on-quit t) ;; C-g #+END_SRC

  • CORE ** garbage collector

    I don't really understand what its happening but here are some /chatter/ over the years on [[https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/][reddit]] and [[https://emacs.stackexchange.com/questions/34342/is-there-any-downside-to-setting-gc-cons-threshold-very-high-and-collecting-ga][stackexchange]]. Original motivation was let the emacs use more RAM, if java based IDE can eat up more than 200 Mb :rage1: to get started. Don't gc during startup to save time! so says [[https://github.com/hlissner/doom-emacs/blob/develop/docs/faq.org#how-does-doom-start-up-so-quickly][hlissner/doom-emacs]]!

    #+BEGIN_SRC emacs-lisp ;;; 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)) #+END_SRC

** load-time

Classic style ๐Ÿงช testing.

#+HEADER: :results output :eval no-export #+BEGIN_SRC sh :exports both 2>&1 /usr/bin/time --verbose /usr/bin/emacs --eval="(save-buffers-kill-terminal)" #+END_SRC

#+RESULTS: #+begin_example 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 #+end_example

Show emacs-init-time at startup

#+BEGIN_SRC emacs-lisp (add-hook 'emacs-startup-hook (lambda () (message (concat "conf-init-time: " (emacs-init-time) (format " gc: %d" gcs-done))))) #+END_SRC

for comprehensive bench-marking install =benchmark-init=

=M-x benchmark-init/show-durations-tree=

** server

Stop โ›” opening emacs for each file. Set default open application to emacsclient, or set it manually:

=emacsclient --no-wait--alternate-editor=emacs [FILE]=

#+BEGIN_SRC emacs-lisp (require 'server) (unless (server-running-p) (server-start)) #+END_SRC

** encoding

Set language to English all encoding in Unicode.

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (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

#+END_SRC

** backup

I don't like mess every where, there is better things for that called git!

#+BEGIN_SRC emacs-lisp (setq backup-directory-alist (quote ((".*" . "~/.cache/emacs_backup/")))) (setq make-backup-files nil) (setq auto-save-default nil) (setq create-lockfiles nil) #+END_SRC

** custom

<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 [[https://blog.sumtypeofway.com/posts/emacs-config.html#cb11][Emacs is Agar for Brain Worms]]

#+BEGIN_QUOTE 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. #+END_QUOTE

#+BEGIN_SRC emacs-lisp :tangle no ;; (setq custom-file (make-temp-file "")) ; ignore (setq custom-file "/home/rho/.config/emacs/custom.el") #+END_SRC

** big files

Warn when opening files bigger than 1 MiB. yup emacs kitchen sink can open ๐ŸŒ‡ image, PDF but seriously ๐Ÿ˜ต ?

#+BEGIN_SRC emacs-lisp (setq large-file-warning-threshold (* 1 1024 1024)) #+END_SRC

You might wonder why that random number!

| kilobyte (kB) | 1000 bytes | | [[https://en.wikipedia.org/wiki/Kibibyte][kibibyte]] (KiB) | 1024 bytes, kB |

Since digital systems worked in binary, yet defacto is in base of 0x10, 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.

** pacman

There are many ๐Ÿ“ฆ package managers for emacs, ranging from simple scripts to download files from [[https://www.emacswiki.org][EmacsWiki]] to full-featured package management solutions like [[https://github.com/raxod502/straight.el][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]].

*** package.el

Add package other sources

#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

Use =M-x package-refresh-contents= to reload the list of packages
after adding these for the first time.

#+BEGIN_HTML
  # <p>Updating all packages is kinda strange chore type
  <kbd>M</kbd>-<kbd>x</kbd> <code>package-list-packages</code>
  which will take you to the <b>Packages</b> buffer, and then type
  <kbd>U</kbd> <kbd>x</kbd>.</p>
#+END_HTML

- <2022-01-12 Wed>

  org package is handled by gnu elpa after 9.5

- <2020-02-02 Sun>

  having troubles with org-version babel [[https://github.com/io12/org-fragtog/issues/1][support]]. using org
  package-archives for latest stuff.

*** why-no-use-package

#+BEGIN_EXAMPLE
  The use-package macro allows you to isolate package configuration
  both performance-oriented and, well, tidy.
#+END_EXAMPLE

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 [[https://github.com/rhoit/dot-emacs/issues/new][mind]]!

*** el-get :PROPERTIES: :header-args: :tangle no :END:

[[https://github.com/dimitri/el-get][el-get]] is the package manager, which is similar to *apt-get*. Not
using since starting of *2020*.

#+BEGIN_HTML
  <details><summary>More</summary>
#+END_HTML

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)=

#+BEGIN_SRC emacs-lisp :tangle no
  (add-to-list 'load-path "~/.emacs.d/el-get")
  (require 'el-get)
  (setq el-get-git-shallow-clone 't)
  (el-get 'sync)
#+END_SRC

To replicate a package set for another emacs installation is
explain in el-get [[https://github.com/dimitri/el-get#replicating-a-package-set-on-another-emacs-installation][README]].

#+BEGIN_HTML
  </details>
#+END_HTML
  • UI

    As of today, most people who use vi or emacs are [[https://github.com/fuqcool/atom-emacs-mode#deprecated][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.

** early-init

Version [[https://www.masteringemacs.org/article/whats-new-in-emacs-27-1#startup-changes-in-emacs-27.1][27.1]] introduces [[https://github.com/rhoit/dot-emacs/blob/master/early-init.el][~/emacs.d/early-init.el]], which is run before [[https://github.com/rhoit/dot-emacs/blob/master/init.el][~/emacs.d/init.el]], before package and UI initialization happens. Themes and UI components can be setup here, which finally solves flickering UI.

** emoji

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.

** theme-switch

Worst part of switching theme by loading is active theme is one disabled before loading the new one! this ๐Ÿช„ trick was stolen from [[https://github.com/thapakazi][@thapakazi]].

#+BEGIN_SRC emacs-lisp (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))) #+END_SRC

** scroll

Historically emacs ๐Ÿ’ˆ [[https://www.emacswiki.org/emacs/SmoothScrolling][scrolling]] ๐Ÿ’ˆ has bee choppy and riddled with bugs, after pgtk branch was [[https://mail.gnu.org/archive/html/emacs-devel/2021-12/msg00126.html][merged]] on <2021-12-19> this has been better. Now in emacs 29.1 pixel-scroll-precision-mode builtin, no more custom ๐Ÿ› ๏ธ builds.

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (pixel-scroll-precision-mode t) ;; (setq pixel-scroll-precision-large-scroll-height 50.0) ;; (setq pixel-scroll-precision-use-momentum nil) #+END_SRC

*** scroll-horizontal

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.

#+BEGIN_SRC emacs-lisp :tangle no
  (setq auto-hscroll-mode 'current-line)
#+END_SRC

** line-number

As in this [[http://ergoemacs.org/emacs/emacs_line_number_mode.html][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 [[https://www.emacswiki.org/emacs/LineNumbers][line number]] plugins over years now, [[https://github.com/thefrontside/frontmacs/blob/master/frontmacs-windowing.el][frontmacs]] config stood out for me the, but linum give lots of flicker, now using with nlinum which is quite good.

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (require 'nlinum)

 (setq nlinum-delay t)
 (setq nlinum-highlight-current-line t)
 (setq nlinum-format " %4d ")

 (add-hook 'prog-mode-hook 'nlinum-mode)
 (add-hook 'org-mode-hook 'nlinum-mode)

 (global-set-key [f7] 'nlinum-mode)

#+END_SRC

** initial-screen

#+BEGIN_SRC emacs-lisp (setq inhibit-startup-message t) (setq inhibit-splash-screen t) #+END_SRC

** mode line

The mode line contains textual summary about the buffer, such as its name, associated file, depth of recursive editing, and major and minor modes.

*** dim

The purpose of [[https://github.com/alezost/dim.el][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.

#+BEGIN_SRC emacs-lisp
  (require 'dim)
#+END_SRC

*** [[https://github.com/emacsmirror/diminish][diminish]]

#+BEGIN_HTML
  <details><summary>More</summary>
#+END_HTML

#+BEGIN_QUOTE
  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
#+END_QUOTE

#+BEGIN_SRC emacs-lisp :tangle no
  (require 'diminish)
#+END_SRC

#+BEGIN_HTML
  </details>
#+END_HTML

- <2022-03-12 Sat> not using

  preferring [[dim]] instead

*** mode icons

Its normal to use 5-10 modes on a buffer, which make the mode line
full of clutter why not use icons!

#+ATTR_HTML: title="modline-screenshot"
[[https://github.com/ryuslash/mode-icons][file:https://raw.githubusercontent.com/rhoit/mode-icons/dump/screenshots/screenshot01.png]]

#+BEGIN_SRC emacs-lisp
  (require 'mode-icons)
  (mode-icons-mode)
#+END_SRC

*** theme

#+BEGIN_SRC emacs-lisp
  (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))
#+END_SRC

** tabbar

[[https://github.com/rhoit/dot-emacs/blob/master/config/tabbar.cfg.el][tabbar]] is something familiar to modern ๐Ÿญ GUI system, there is still the gap, like key-bindings, close buttons and icons which is which [[https://github.com/mattfidler/tabbar-ruler.el][tabbar-ruler]] tries to address.

#+ATTR_HTML: title="tabbar-screenshot" [[https://github.com/mattfidler/tabbar-ruler.el][file:https://raw.githubusercontent.com/rhoit/tabbar-ruler.el/dump/screenshots/01.png]]

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

#+BEGIN_HTML

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

#+END_HTML

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

grouping the tab by buffer name

#+BEGIN_SRC emacs-lisp (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") )))) #+END_SRC

Binding for the tab groups, some how I use lots of buffers.

#+BEGIN_SRC emacs-lisp (global-set-key [(control shift prior)] 'tabbar-backward-group) (global-set-key [(control shift next)] 'tabbar-forward-group) #+END_SRC

Similar packages

  • centaur-tabs from [[https://github.com/seagle0128/.emacs.d][centaur emacs]]

** buffer

Sensible unique buffer names, [ inbuilt: package ] by default in >= 24.4.1 else add =(require 'uniquify)=

#+BEGIN_SRC emacs-lisp (setq uniquify-buffer-name-style 'forward) #+END_SRC

** search

#+BEGIN_HTML

If you can yank (paste) in search, why to add to kill-ring (copy) just select the text and hit C-s!

#+END_HTML

In addition there is the whole section in [[https://www.emacswiki.org/emacs/SearchAtPoint][wiki]] about search at point.

#+BEGIN_SRC emacs-lisp (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))))) #+END_SRC

*** anzu

[[https://github.com/syohex/emacs-anzu][anzu]] highlight all search matches, most of the text editor does
even [[https://github.com/osyo-manga/vim-anzu][vi]] this why not emacs. Here is the [[https://raw.githubusercontent.com/syohex/emacs-anzu/master/image/anzu.gif][gify]] from original
repository.

#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

*** highlight

Beyond the syntax color, ability to highlight adds clear ๐Ÿง
perspective during variable hunting.

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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))))
#+END_SRC

#+BEGIN_HTML
  <details><summary>More</summary>
#+END_HTML

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp :tangle no
  (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))))
#+END_SRC

#+BEGIN_HTML
  </details>
#+END_HTML

- <2023-08-01 Tue>

  [[https://github.com/nschum/highlight-symbol.el][highlight symbol]] has been un-mantained since 2016 switching to
  alternative symbol-overlay

** [[https://www.emacswiki.org/emacs/SpeedBar][speedbar]]

I prefer speedbar outside the frame, for without separate frame see [[https://www.emacswiki.org/emacs/SrSpeedbar][SrSpeedbar]].

#+BEGIN_SRC emacs-lisp (setq speedbar-show-unknown-files t) ;; (global-set-key [f9] 'speedbar) #+END_SRC

  • <2021-05-27 Thu>

    its projectile now days and speedbar breaks my theme

** goto-last-change

This is the gem feature, this might be true answer to the /sublime mini-map/ which is over rated, this is what you need.

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (require 'goto-chg) (global-unset-key (kbd "C-j")) ; unbind (eval-print-last-sexp) (global-set-key (kbd "C-j") 'goto-last-change) #+END_SRC

  • UX

    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 [[http://xahlee.info/emacs/emacs/emacs_hand_pain_celebrity.html][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๐Ÿšช!

** oem

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 @@html:@@ delete @@html:@@ and @@html:@@ backspace @@html:@@.

Some time you need to [[https://www.gnu.org/software/emacs/manual/html_node/emacs/DEL-Does-Not-Delete.html][explicitly]] say what to do.

#+BEGIN_SRC emacs-lisp ;;; you might not need this (normal-erase-is-backspace-mode 1) #+END_SRC

It seem more of "think +different+ stupid" ๐ŸŽ. And even seasoned vi users can't seems to escape from it ever, (Esc is [[https://www.bbc.com/news/technology-50408649][back]]), and copy ๐Ÿˆ OEM does not know where to [[https://www.reddit.com/r/mildlyinfuriating/comments/by5fy4/backspace_and_delete_keys_next_to_power_button_on/][place]] power โšก button.

** sane-binding

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.

#+BEGIN_SRC emacs-lisp ;; 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)

#+END_SRC

#+BEGIN_HTML I prefer to disable exit binding (C-x C-c), Since I don't use emacs in terminal. #+END_HTML

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (global-unset-key (kbd "C-x C-c")) #+END_SRC

*** find

#+BEGIN_HTML
  โฌ…๏ธ <a href="https://en.wikipedia.org/wiki/Arrow_keys">Arrows</a>
  โžก๏ธ keys might have been hard to find before 1980's, but binding
  <code>forward-char</code> to <kbd>C</kbd>-<kbd>f</kbd> till date
  is ๐Ÿคฆ dumb, let enable some what common like search/find ๐Ÿ”.
#+END_HTML

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (global-set-key (kbd "C-f") 'isearch-repeat-forward)  ;; unbind (forward-char)
#+END_SRC

*** readonly

#+BEGIN_HTML
  In most of the modern applications <kdb>F2</kbd> is use for
  rename or edit โœ๏ธ. Currently <kdb>F2</kbd> binded to <b>2 column
  mode</b> which I haven't found any use till date. Default
  binding (<kbd>C</kbd>-<kbd>x</kbd> <kbd>C</kbd>-<kbd>q</kbd>) to
  toggle <code>read-only-mode</code> don't make any sense in
  modern day or age.
#+END_HTML

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (global-set-key [f2] 'read-only-mode) ;; unbind (2C-two-columns)
#+END_SRC

*** word-wrap

#+BEGIN_SRC emacs-lisp
  (global-set-key [f6] 'toggle-truncate-lines)
#+END_SRC

*** fullscreen

#+BEGIN_HTML
  <p>When new function like <code>toggle-frame-fullscreen</code>
  (<kbd>F11</kbd>) and <code>toggle-frame-maximized</code>
  (<kbd>M</kbd>-<kbd>F11</kbd>) keeps popping in recent version
  <i>24.4</i>, lets me to think <b>emacs</b> hasn't given up on
  being <b>Operating System</b>.</p>
#+END_HTML

#+BEGIN_SRC emacs-lisp
  ;;; full-screen since 24.4
  ;; handled via window manager
  ;; lets reserve it for something i.e realgud
  (global-unset-key [f11])
#+END_SRC

*** buffer-close

#+BEGIN_SRC emacs-lisp
 ;;; since, C-x k <return> too much acrobat
 (global-set-key [(control d)] 'kill-buffer)  ; same as terminal
#+END_SRC

*** helpful

#+BEGIN_SRC emacs-lisp
  ;; 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")))
#+END_SRC

** yes-or-no

yup thing are annoying ๐Ÿ˜ค here! avoid typing complete 'yes' and 'no'.

#+BEGIN_SRC emacs-lisp (fset 'yes-or-no-p 'y-or-n-p) #+END_SRC

** update-buffer

A fancy :bowtie: way of saying any change in file (yup not using same editor, duh!) will magically ๐ŸŽฉ appear in editor.

#+BEGIN_SRC emacs-lisp (global-auto-revert-mode) ;;(setq auto-revert-verbose nil) #+END_SRC

** undo

@@html:@@Ctrl@@html:@@-@@html:@@z@@html:@@ is synonyms to undo not here because its [[https://en.wikipedia.org/wiki/Substitute_character][suspend]] to background in ๐Ÿš shell, Since emacs traces it roots from the terminal.

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp ;;; this is confusion (global-unset-key (kbd "C-z")) ; unbind (suspend-frame) #+END_SRC

*** undo-tree

[[http://www.dr-qubit.org/undo-tree.html][undo-tree]] preserve your undo chain and maintain undo branching.

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

- <2023-08-04 Fri>

  Have been using *undo-tree* for so long, didn't know undo region
  existed more in irreal [[https://irreal.org/blog/?p=8614][blog]].

- <2020-02-12 Wed> retrying undo-tree again!

  there are moments when =undo-tree= [[http://www.dr-qubit.org/Lost_undo-tree_history.html][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.

** cursor

Make cursor [[http://pragmaticemacs.com/emacs/adaptive-cursor-width/][adaptive]] the to the width of the character, helpful in showing non-monospace characters like TAB and emoji.

#+BEGIN_SRC emacs-lisp (setq x-stretch-cursor t) #+END_SRC

*** beacon-mode

[[https://github.com/Malabarba/beacon][beacon]] gives extra feedback of cursor's position on big movement.
It can be understood better with this [[https://raw.githubusercontent.com/Malabarba/beacon/master/example-beacon.gif][gify]] from original
repository.

#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

*** multiple-cursor

If [[https://www.sublimetext.com/][sublime]] can have [[https://github.com/magnars/multiple-cursors.el][multiple]] cursor, *emacs* can too.

Here is ๐Ÿ“น [[https://youtu.be/jNa3axo40qM][video]] from [[http://emacsrocks.com/][Emacs Rocks!]] about it in [[http://emacsrocks.com/e13.html][ep13]].

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

** selection

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.

#+BEGIN_SRC emacs-lisp ;;; doing expected things (delete-selection-mode 1) #+END_SRC

*** why-changing-fonts

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=.

#+BEGIN_SRC emacs-lisp
  (global-unset-key [(shift down-mouse-1)])  ; unbind (mouse-apperance-menu EVENT)
  (global-set-key [(shift down-mouse-1)] 'mouse-save-then-kill)
#+END_SRC

*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.

*** [[https://github.com/magnars/expand-region.el][expand region]]

Expand region increases the selected region by semantic units.

Here is [[https://www.youtube.com/watch?v=_RvHz3vJ3kA][video]] from [[http://emacsrocks.com/][Emacs Rocks!]] about it in [[http://emacsrocks.com/e09.html][ep09]].

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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))))
#+END_SRC

** mini-buffer *** helm

Although [[https://github.com/emacs-helm/helm][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 [[https://tuhdo.github.io/helm-intro.html][intro]]

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

- <2023-08-02 Wed>

  helm fixed! ๐Ÿฅณ

- <2023-08-01 Tue>

  After switing to emacs 29.1 and updating packages, helm stopped
  working, details in https://github.com/emacs-helm/helm/issues/2608

  #+BEGIN_EXAMPLE
   custom-initialize-reset: Symbol's value as variable is void: helm-info-source
  #+END_EXAMPLE

- <2020-08-31 Mon>

  lynx style navigation [[https://github.com/emacs-helm/helm/issues/2175][fix]] after new update

**** helm-packages

 Some useful helm packages ๐Ÿคฉ.

 | name           | description                                       |
 |----------------+---------------------------------------------------|
 | helm-descbinds | A convenient helm version of =describe-bindings=. |
 | helm-xref      | Helm interface for xref results                   |

*** orderless

If you are using [[helm]] matching space-separated component is
provided by default, which I only found out after trying [[https://github.com/oantolin/orderless][orderless]]
and its called "multi pattern matching" in helm.

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp :tangle no
  (require 'orderless)
  (setq completion-styles '(orderless))
#+END_SRC

** text zoom

I still don't understand ๐Ÿ˜’ why emacs way of changing font [[https://www.emacswiki.org/emacs/SetFonts#ChangingFontSize][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

#+BEGIN_SRC emacs-lisp (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))) #+END_SRC

** [[https://github.com/joodland/bm][bookmark]]

It has never been so much easy to bookmark ๐Ÿ”–!

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (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)

#+END_SRC

  • <2022-03-10 Thu> better key binding

    fringe are too small to be used precisely as suggest

** killing group

#+BEGIN_HTML

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.

 <p>Yanking with <kbd>C</kbd>-<kbd>y</kbd> and cycling through
 using <kbd>M</kbd>-<kbd>y</kbd>, <kbd>M</kbd>-<kbd>y</kbd>,
 <kbd>M</kbd>-<kbd>y</kbd> can be bit alarming.</p>

#+END_HTML

*** paste

Beginners find *Ctrl+v* jump outlandish and sometime also for me.
In this day and age certain function are arcane (may be [[https://xkcd.com/1172/][someone]]
uses it) but its not for me. When beginners try to *paste* with
@@html:<kbd>@@C@@html:</kbd>@@-@@html:<kbd>@@v@@html:</kbd>@@
scroll-up outlandishly make me think this is main reason of ๐Ÿ˜ž
poor adoption, when will *emacs* have better default.

#+BEGIN_SRC emacs-lisp
  (global-set-key [(control v)] 'yank) ; unbind (scroll-up-command)
#+END_SRC

*** kill-ring

*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
[[https://www.emacswiki.org/emacs/BrowseKillRing][wiki]],

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

*** [[https://www.emacswiki.org/emacs/popup-kill-ring.el][popup kill ring]]

#+BEGIN_SRC emacs-lisp :tangle no
  (require 'popup-kill-ring)
#+END_SRC

- <2022-10-06 Thu>

  opted for helm since it hard to see multi-line clips

*** drag

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. [[https://github.com/rejeep/drag-stuff.el][drag-stuff]] is great but its
default binding is conflicts with *org-mode*.

#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

** layout

winner mode saving the window configure

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (when (fboundp 'winner-mode) (winner-mode 1)) #+END_SRC

** splits

#+BEGIN_SRC emacs-lisp (setq split-width-threshold 120) #+END_SRC

  • PROGRAMMING

    some of the basic things provide by emacs internal packages.

    #+BEGIN_SRC emacs-lisp (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))) #+END_SRC

** parenthesis

#+BEGIN_SRC emacs-lisp (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) #+END_SRC

*** rainbow-delimiters

This ๐ŸŒˆ mode is barely noticeable at first glance but, if you live
by parenthesis it nice thing to have around.

#+BEGIN_SRC emacs-lisp
  (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
#+END_SRC

** comments

Yet again, bad default for emacs ๐Ÿ˜ณ the /key-binding/ does not toggle comment on the line, may be its because of :neckbeard: who /always wrote the perfect code/, only needed comment to add GPL!

#+BEGIN_EXAMPLE But, Our code is SELF DOCUMENTED! ๐Ÿ˜Ž #+END_EXAMPLE

#+BEGIN_SRC emacs-lisp ;;; 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 "# ")

#+END_SRC

** watch-word

#+BEGIN_SRC emacs-lisp :tangle no (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)

#+END_SRC

** indentation

Sorry [[http://silicon-valley.wikia.com/wiki/Richard_Hendrix][Richard]] no tabs here!

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (setq-default indent-tabs-mode nil) (setq-default tab-width 4) (setq tab-width 4) #+END_SRC

*** highlight-indent-guides

After years using [[https://github.com/antonj/Highlight-Indentation-for-Emacs][highlight indentation]] with performance issues
and shifting through multiple ๐Ÿด fork and patches, I have moved to
[[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] has much better compatibility. Although I
hate default fill method.

#+HEADER: :results silent
#+BEGIN_SRC emacs-lisp
  (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)))
#+END_SRC

** align-rules

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 [[https://www.emacswiki.org/emacs/AlignCommands][wiki]].

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (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)))

#+END_SRC

** folding

It is ๐Ÿ˜  frustrating many code folding packages not [[https://www.emacswiki.org/emacs/FoldingMode][folding-mode]] does not ๐Ÿšง work as planned. so many corner cases and constantly ๐Ÿ’” breaking. Some of the code folding I have tried are

  • [[http://www.emacswiki.org/emacs/download/hideshowvis.el][hideshowvis]]
  • [[https://github.com/gregsexton/origami.el][origimi]]
  • [[https://github.com/mrkkrp/vimish-fold][vimish-fold]]
  • [[https://github.com/zenozeng/yafolding.el][yafolding]]

#+BEGIN_SRC emacs-lisp (add-hook 'prog-mode-hook 'yafolding-mode) #+END_SRC

  • <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

** white-spaces

If you have working with non-emacs people sooner or later you might face this problem, those pesky trailing spaces/tabs.

#+BEGIN_EXAMPLE Phenomenal Cosmic Powers! Itty Bitty trailing spaces! #+END_EXAMPLE

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

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

[[https://github.com/nflath/hungry-delete][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!

#+BEGIN_SRC emacs-lisp (require 'hungry-delete) (global-set-key (kbd "S-") 'hungry-delete-backward) #+END_SRC

There is the interesting outlook of [[https://github.com/hrehfeld/emacs-smart-hungry-delete/issues][smart-hungry-delete]], which I have not used for the while.

#+BEGIN_SRC emacs-lisp :tangle no (require 'smart-hungry-delete) (smart-hungry-delete-add-default-hooks) (global-set-key (kbd "") 'smart-hungry-delete-backward-char) ;; (global-set-key (kbd "") 'smart-hungry-delete-forward-char) ;; (global-set-key (kbd "") '(lambda () ;; (if use-region-p '(smart-hungry-delete-forward-char) '(delete-char)))) #+END_SRC

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

#+BEGIN_SRC emacs-lisp ;; (setq require-final-newline t) #+END_SRC

*** whitespace4r.el

I have been wanting white-space to be displayed for selected
region since I saw feature in [[https://www.sublimetext.com/][sublime]].

[[https://i.stack.imgur.com/9GInk.png]]

Yet there was nothing similar to-be [[https://emacs.stackexchange.com/questions/54305/show-white-spaces-only-when-region-is-selected][found]], thankfully ๐Ÿ˜ญ [[https://github.com/twlz0ne][@twlz0ne]]
created the new minor [[https://github.com/twlz0ne/whitespace4r.el][mode]], (since, I can't wrap my head to
*lisp*).

#+BEGIN_SRC emacs-lisp
  (add-to-list 'load-path "~/.config/emacs/00testing/whitespace4r.el/")
  (require 'whitespace4r)
  (whitespace4r-mode)
#+END_SRC

- <2022-03-19 Sat> workable

  mode is buggy or just because of my theme or configuration

** compile

#+BEGIN_SRC emacs-lisp (load "~/.config/emacs/cfg.compile.el")

 (defun my-compilation-mode-hook ()
   (set (make-local-variable 'truncate-partial-width-windows) nil))
 (add-hook 'compilation-mode-hook 'my-compilation-mode-hook)
 (add-hook 'compilation-mode-hook (lambda() (setq truncate-lines t)))

 ;; bindings
 (global-set-key (kbd "C-<f8>") 'save-and-compile-again)
 (global-set-key (kbd "C-<f9>") 'ask-new-compile-command)
 (global-set-key (kbd "<f8>") 'toggle-compilation-buffer)

#+END_SRC

** git

git is amazing but [[https://github.com/magit][magit]] is magic ๐Ÿช„!

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

magit performance can be [[https://www.reddit.com/r/emacs/comments/9n1ck6/call_to_arms_emacs_bindings_for_libgit2/][boosted]] using [[https://github.com/magit/libegit2][libgit]] which is a thin wrapper written in C around [[https://github.com/libgit2][libgit2]], Install =cmake= to build libgit first time. More stuff about the tuning can be found in its [[https://magit.vc/manual/magit/Performance.html][manual]].

#+BEGIN_SRC emacs-lisp (require 'libgit) (require 'magit-libgit) (setq magit-refresh-status-buffer nil) (remove-hook 'magit-refs-sections-hook 'magit-insert-tags) #+END_SRC

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.

#+BEGIN_SRC emacs-lisp (setq transient-default-level 7) #+END_SRC

*** diff

#+BEGIN_SRC emacs-lisp
  (setq magit-ediff-dwim-show-on-hunks t)
  (setq ediff-split-window-function 'split-window-horizontally)
#+END_SRC

** projectile

If your source consist of hundreds of line then don't be like me use [[https://github.com/bbatsov/projectile][projectile]] mode like [[https://github.com/krazedkrish][@krazedkrish]].

#+BEGIN_HTML

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.

#+END_HTML

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

** dired-mode

facing trouble when in fresh copy of repo, will fix later

#+BEGIN_SRC emacs-lisp :tangle no (add-hook 'prog-mode-hook '(lambda() (setq dired-omit-files (concat dired-omit-files "\|\.git$\|venv$")))) #+END_SRC

** auto-complete

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

company mode supports [[https://github.com/dunn/company-emoji][emoji]].

#+BEGIN_SRC emacs-lisp (require 'company-emoji) (add-to-list 'company-backends 'company-emoji)

 (add-to-list 'company-emoji-aliases '(:poop: . ":hankey:"))

#+END_SRC

** [[https://github.com/leoliu/ggtags][ggtags]]

Using [[https://langserver.org/][language server protocol]] (LSP) since, ggtags make my emacs super slow, but not sure why!

#+BEGIN_HTML

More #+END_HTML

#+BEGIN_SRC emacs-lisp :tangle no (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) #+END_SRC

#+BEGIN_HTML #+END_HTML

** LSP

[[https://langserver.org/][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 [[https://microsoft.github.io/language-server-protocol/specifications/specification-current/][specifications]] was proposed by Microsoft as a way for different editors and development environments to share language analysis back-ends.

#+BEGIN_QUOTE [[https://emacs-lsp.github.io/lsp-mode/][lsp-mode]] aims to provide IDE-like experience by providing optional integration with the most popular Emacs packages like company, flycheck and projectile. #+END_QUOTE

#+BEGIN_HTML

The proper way to start lsp-mode is using M-x lsp

  <p>To check its capabilities on running lsp
  <kbd>M</kbd>-<kbd>x</kbd> lsp-describe-session </p>

#+END_HTML

#+BEGIN_SRC emacs-lisp (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

#+END_SRC

debugging variables

#+BEGIN_SRC emacs-lisp ;; (setq lsp-print-io t) ;; (setq lsp-trace t) (setq lsp-print-performance t) #+END_SRC

*** servers

language-servers should be installed โš’๏ธ manually you can see the
list of supported languages at their [[https://emacs-lsp.github.io/lsp-mode/page/languages/][website]] and documented at
[[https://github.com/emacs-lsp/lsp-mode/blob/master/docs/lsp-clients.json][lsp-clients.json]].

#+BEGIN_SRC emacs-lisp
  (add-hook 'sh-mode-hook #'lsp)
#+END_SRC

*** performance

@@html:<kbd>@@M@@html:</kbd>@@-@@html:<kbd>@@x@@html:</kbd>@@
=lsp-doctor= ๐Ÿš‘ is really handy to get started but still there
other tweak ๐Ÿ”ง in lsp-mode [[https://emacs-lsp.github.io/lsp-mode/page/performance/][docs]].

#+BEGIN_SRC emacs-lisp
  ;; (setq lsp-log-io nil)  ; default:nil, for debugging
  (setq lsp-idle-delay 0.500)
  (setq company-lsp-cache-candidates t)
#+END_SRC

**** native compile

 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 [[ https://github.com/rhoit/dot-emacs/tree/master/build][build]] or check my [[https://github.com/rhoit/dot-emacs/releases][releases]].

**** plists

 #+BEGIN_SRC emacs-lisp
  (setq lsp-use-plists t)
 #+END_SRC

 Using *plists* for de-serialization :feelsgood: is only triggers
 when *emacs* starts with =LSP_USE_PLISTS= is =true=, and lsp [[https://emacs-lsp.github.io/lsp-mode/page/performance/#use-plists-for-deserialization][wiki]]
 recommending shell to start, But it could be better ๐Ÿ˜Ž just need
 to replace emacs with ๐Ÿš shell-script.

 #+HEADER: :results output :eval no-export
 #+BEGIN_SRC sh :exports both
   cat /usr/local/bin/emacs
 #+END_SRC

 #+RESULTS:
 : LSP_USE_PLISTS=true exec /usr/bin/emacs $*

**** [[https://emacs-lsp.github.io/lsp-mode/page/file-watchers/][file-watcher]]

 Watching all the files in huger project directories, may slow down
 performance.

 Yet to find how it helps so disabling it.

 #+BEGIN_SRC emacs-lisp
   (setq lsp-enable-file-watchers nil) ; default:t
 #+END_SRC

 Default warning threshold is *1000* which can be changing variable
 =(setq lsp-file-watch-threshold 1000)=

 #+BEGIN_SRC emacs-lisp
   (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__\\'"))
 #+END_SRC

*** lsp-ui

This is [[https://emacs-lsp.github.io/lsp-ui/][extension]] for all the higher level UI modules of [[LSP]], like
[[https://www.flycheck.org][flycheck]] support and code lenses.

By default, *lsp-mode* automatically activates *lsp-ui* unless
=(setq lsp-auto-configure nil)=.

#+BEGIN_SRC emacs-lisp
  (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)
#+END_SRC

** debugger

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.

#+BEGIN_SRC emacs-lisp ;; unlike gdb, pdb is a inbuilt python module (setq gud-pdb-command-name "python -m pdb") #+END_SRC

GUD is great but [[https://github.com/realgud/realgud/][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 [[https://github.com/realgud/realgud/blob/09431a4561921bece36a6083b6e27ac4dc82432d/realgud.el#L36-L47][rant]] from its developer.

#+BEGIN_SRC emacs-lisp (setq realgud:pdb-command-name "python -m pdb") #+END_SRC

** linter

I'm ashamed to say I haven't used linter much before 2020. I accidentally found [[https://www.emacswiki.org/emacs/FlyMake][flymake]] working, as I can remember I had autopep8 recently in 2021. Since my [[LSP][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 [[https://www.flycheck.org/en/latest/user/flycheck-versus-flymake.html][flycheck]] as [[LSP][lsp]] recommended yet dealing with the virtual enivroment was frustrating which asked you to install flake8 in every environment.

#+BEGIN_SRC emacs-lisp (setq flycheck-check-syntax-automatically '(save)) #+END_SRC

#+BEGIN_EXAMPLE 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.

#+END_EXAMPLE

*** flycheck-pos-tip

[[https://github.com/flycheck/flycheck-pos-tip][flycheck-pos-tip]] is the [[https://www.flycheck.org/en/latest/user/flycheck-versus-flymake.html][flycheck]] extension shows errors using
[[https://github.com/syohex/pos-tip][pos-tip]] popup.

if you this with [[lsp]] extension mouse hover function would be
overridden by [[lsp-ui]].

#+BEGIN_SRC emacs-lisp
  (with-eval-after-load 'flycheck (flycheck-pos-tip-mode))
#+END_SRC
  • WEB ** javascript

    #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\.mjs$" . js-mode)) #+END_SRC

** lsp-support

#+BEGIN_SRC emacs-lisp (add-hook 'js-mode-hook #'lsp) (add-hook 'css-mode-hook #'lsp) #+END_SRC

*** lsp-typescript

For javascript [[https://github.com/typescript-language-server/typescript-language-server][typescript-language-server]] has been recommended by
the [[https://emacs-lsp.github.io/lsp-mode/page/lsp-typescript/][wiki]] to install it in arch see [[https://aur.archlinux.org/packages?K=typescript-language-server][AUR]].

But it generates =.log= directory on project root which can be
address by setting option to the server as mentioned in [[https://github.com/emacs-lsp/lsp-mode/issues/1490][#1490]]
using [[https://emacs-lsp.github.io/lsp-mode/page/lsp-typescript/][configuration]] variables.

#+BEGIN_SRC emacs-lisp
  (setq lsp-clients-typescript-server-args '("--stdio" "--tsserver-log-file" "/dev/stderr"))
#+END_SRC

*** system-package

Naming seems to be different in Arch Official Packages ๐Ÿ“ฆ and
[[https://github.com/emacs-lsp/lsp-mode/blob/master/docs/lsp-clients.json][lsp-client]], which lets lsp to not find executable.

| type     | packages                   | lsp-mode/client |
|----------+----------------------------+-----------------|
| official | [[https://archlinux.org/packages/community/any/vscode-css-languageserver/files/][vscode-css-languageserver]]  | [[https://github.com/emacs-lsp/lsp-mode/blob/828c6c234a3231670ba5649666652e22a9bc4f35/clients/lsp-css.el#L237][lsp-css.el]]      |
| official | [[https://archlinux.org/packages/community/any/vscode-html-languageserver/files/][vscode-html-languageserver]] | [[https://github.com/emacs-lsp/lsp-mode/blob/828c6c234a3231670ba5649666652e22a9bc4f35/clients/lsp-html.el#L182][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.

#+BEGIN_SRC emacs-lisp
  (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))
#+END_SRC

- <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*! ๐Ÿค”

  #+BEGIN_SRC emacs-lisp :tangle no
    (lsp-dependency
      'css-languageserver
      '(:system "vscode-css-languageserver"))
  #+END_SRC

** linter *** flycheck

I mainly use [[https://eslint.org/][eslint]] with flycheck.

#+BEGIN_SRC emacs-lisp
  (add-hook 'js-mode-hook 'flycheck-mode)
#+END_SRC

** web-mode

[[https://web-mode.org/][web-mode]] is an autonomous emacs major-mode for editing web templates.

#+BEGIN_SRC emacs-lisp (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)))

#+END_SRC

*** template

*djhtml* is file format is for [[https://www.djangoproject.com/][Django]] or [[https://jinja2docs.readthedocs.io/en/stable/][Jinja]] template which works
with mixed *HTML*, *CSS* and *JS* with template tags.

#+BEGIN_SRC emacs-lisp
  (add-to-list 'auto-mode-alist '("\\.djhtml?\\'" . web-mode))
#+END_SRC

Let [[lsp]] know *djhtml* is *html*.

#+BEGIN_SRC emacs-lisp
  (add-to-list 'lsp-language-id-configuration '(web-mode . "html"))
#+END_SRC

** browser-refresh

There are stuff like [[http://www.emacswiki.org/emacs/MozRepl][moz-repl]], [[https://github.com/skeeto/skewer-mode][skewer-mode]], [[https://github.com/skeeto/impatient-mode][impatient-mode]] but nothing beats good old way with xdotool hail X11 for now! :joy:

#+BEGIN_SRC emacs-lisp :tangle no (require 'browser-refresh) (setq browser-refresh-default-browser 'firefox) #+END_SRC

above thingi comment, lets do Makefile!

#+BEGIN_EXAMPLE WINDOW=$(shell xdotool search --onlyvisible --class chromium) run: xdotool key --window ${WINDOW} 'F5' xdotool windowactivate ${WINDOW} #+END_EXAMPLE

  • PYTHON

    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 [[https://gitlab.com/rhoit/py-exec][py-exec]], python configuration has been simplest for decades.

    Recently I have been testing [[language server protocol][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 .

    #+BEGIN_SRC emacs-lisp (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))) #+END_SRC

** docstring

[[https://github.com/glyph/python-docstring-mode/blob/master/README.md][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.

#+BEGIN_SRC emacs-lisp (add-hook 'python-mode-hook (lambda () (python-docstring-mode) (dim-minor-name 'python-docstring-mode ""))) #+END_SRC

  • <2022-03-01 Tue>

    not working as expected something is not correct

** jedi

[[http://tkf.github.io/emacs-jedi/]]

Since python3.3 virtual environment can be created using =python -m venv env= without python-virtualenv.

#+BEGIN_SRC emacs-lisp :tangle no (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

#+END_SRC

** lsp

For python lsp looks for pyls and pylsp by default, I use using pyright which need extra emacs package lsp-pyright.

#+BEGIN_SRC emacs-lisp (add-hook 'python-mode-hook (lambda() (when (not (derived-mode-p 'scons-mode)) (lsp)))) #+END_SRC

  • <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 use =yaourt -S python-jedi-git=

** venv

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=.

#+BEGIN_QUOTE Damn don't try to solve artificial problems! so goes for idiotic venv modes trying to find venv folder. #+END_QUOTE

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")=

#+BEGIN_SRC emacs-lisp (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)

#+END_SRC

** linter

Go beyond pycodestyle (PEP8) here is my [[https://github.com/rhoit/my-config/blob/master/python/flake8][config]] using flake8.

#+BEGIN_SRC emacs-lisp (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

#+END_SRC

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.

#+BEGIN_SRC emacs-lisp (flycheck-add-next-checker 'python-flake8 'python-pyright) #+END_SRC

#+RESULTS: : (python-pyright (warning . python-pylint) (warning . python-mypy))

** py-exec

[[https://github.com/rhoit/py-exec][py-exec]] is ess-style execution for /python/ script.

#+BEGIN_SRC emacs-lisp (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))) #+END_SRC

** scons

If any one had created the Makefile in this day an age, it would definitely should be considered as ๐Ÿ˜– crime. [[https://en.wikipedia.org/wiki/Make_(software)][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 [[https://en.wikipedia.org/wiki/Automake][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 [[https://github.com/SCons/scons/wiki/FromMakeToScons][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.

#+BEGIN_SRC emacs-lisp (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))

#+END_SRC

  • ORG-MODE

    [[https://orgmode.org/][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]]

    #+BEGIN_SRC emacs-lisp (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) #+END_SRC

** auto-fill

=auto-fill-mode= is named by =auto-fill-function= via [[https://github.com/magnars/.emacs.d/blob/master/site-lisp/diminish.el#L87][magnars]].

#+BEGIN_SRC emacs-lisp (dim-minor-name 'auto-fill-function "") (add-hook 'org-mode-hook 'turn-on-auto-fill) #+END_SRC

  • <2020-02-01 Sat>

    problem with emacs 26 this see [[https://github.com/syl20bnr/spacemacs/issues/5697][spacemacs]] issue

** babel

active Babel languages

#+BEGIN_SRC emacs-lisp (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"))

#+END_SRC

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.

** default applications

Its most ๐Ÿ˜ž disappointing when application opens doesn't open in your favorite application, but org-mode has it covered ๐Ÿ˜ญ.

#+BEGIN_SRC emacs-lisp (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"))))) #+END_SRC

** latex

[[https://github.com/io12/org-fragtog][fragtog]] mode automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them.

#+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook 'org-fragtog-mode) #+END_SRC

based on [[https://emacs.stackexchange.com/questions/3387/how-to-enlarge-latex-fragments-in-org-mode-at-the-same-time-as-the-buffer-text][zoom latex fragments relative to buffer text]]

#+HEADER: :results silent #+BEGIN_SRC emacs-lisp (plist-put org-format-latex-options :scale 2.5) ;; (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.8)) #+END_SRC

#+BEGIN_SRC emacs-lisp (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)))

#+END_SRC

** html export

#+BEGIN_SRC emacs-lisp (setq org-html-allow-name-attribute-in-anchors t org-html-doctype "html5" org-html-validation-link nil org-html-checkbox-type 'html) #+END_SRC

Add dot after headline

https://yoo2080.wordpress.com/2013/08/24/changing-the-number-format-for-section-headings-in-org-mode-html-export/

#+BEGIN_SRC emacs-lisp (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 "")) 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)))

#+END_SRC

custom exporter for [[https://emacs.stackexchange.com/questions/55231/org-mode-export-html-add-name-attirbute-to-checkbox-input/55273#55273][checkbox]] as suggest by [[Name of the link][John Kitchin]].

** minor-mode

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 [[https://github.com/alphapapa/outshine][outshine]] extension.

#+BEGIN_SRC emacs-lisp (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)))

#+END_SRC

for links you need [[https://github.com/tarsius/orglink][orglink]] is available in MELPA.

#+BEGIN_SRC emacs-lisp (add-hook 'prog-mode-hook (lambda() (orglink-mode) (dim-minor-name 'orglink-mode ""))) #+END_SRC

  • <2022-02-27 Sun>

    Warning (emacs): โ€˜outshine-hook-functionโ€™ has been deprecated, use โ€˜outshine-modeโ€™ Disable showing Disable logging

** reveal.js

Making power-point is lame, and updating is the mess! there is the thing call [[https://github.com/hakimel/reveal.js/][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!

[[https://gitlab.com/oer/org-re-reveal][org-re-reveal]] is the fork of [[https://github.com/yjwen/org-reveal][yjwen/org-reveal]] with enhancement

#+BEGIN_SRC emacs-lisp (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")

#+END_SRC

  • <2020-02-05 Wed>

    org-re-reveal trying

  • <2018-06-21 Thu>

    [[https://github.com/yjwen/org-reveal][yjwen/org-reveal]] working again

  • <2018-05-20 Sun>

    [[https://github.com/yjwen/org-reveal][yjwen/org-reveal]] isn't working anymore

** theme

#+BEGIN_SRC emacs-lisp (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"))))
 )

#+END_SRC

  • MODES ** C/C++

    http://www.gnu.org/software/emacs/manual/html_mono/ccmode.html

    #+BEGIN_SRC emacs-lisp (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) #+END_SRC

    styling

    https://www.emacswiki.org/emacs/IndentingC

    #+BEGIN_SRC emacs-lisp (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) #+END_SRC

** rust

https://github.com/rust-lang/rust-mode

=ob-rust= for org mode

#+BEGIN_SRC emacs-lisp :tangle no (add-hook 'rust-mode-hook (lambda () (require 'rust-mode) (setq indent-tabs-mode nil)))

 ;; (setq rust-format-on-save t) ; needs rustfmt

#+END_SRC

** sql

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

*** Automatically upcase SQL keywords

https://www.emacswiki.org/emacs/download/sql-upcase.el

See also http://stackoverflow.com/q/22091936/324105

#+BEGIN_SRC emacs-lisp
  (when (require 'sql-upcase nil :noerror)
    (add-hook 'sql-mode-hook 'sql-upcase-mode)
    (add-hook 'sql-interactive-mode-hook 'sql-upcase-mode))
#+END_SRC

** conf

#+BEGIN_SRC emacs-lisp (add-hook 'conf-mode-hook 'nlinum-mode) #+END_SRC

** systemd

#+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("\.service" . systemd-mode)) (add-hook 'systemd-mode-hook 'company-mode) #+END_SRC

** dockerfile

Goodies for ๐Ÿณ ๐Ÿณ ๐Ÿณ

#+BEGIN_SRC emacs-lisp :tangle no (require 'dockerfile-mode) (add-to-list 'auto-mode-alist '("Dockerfile" . dockerfile-mode)) #+END_SRC

** json

#+BEGIN_SRC emacs-lisp (setq auto-mode-alist (cons '(".json$" . json-mode) auto-mode-alist)) #+END_SRC

** latex

#+BEGIN_SRC emacs-lisp (add-hook 'latex-mode-hook (lambda () (nlinum-mode) (drag-stuff-mode-rho-bindings) (toggle-truncate-lines +1))) #+END_SRC

** yasnippet

[[https://github.com/joaotavora/yasnippet][yasnippet]] is template system for emacs, snippet collection in distributed separately as =yasnippet-snippet=.

#+BEGIN_SRC emacs-lisp (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) #+END_SRC

  • WORDPLAY

    [[https://github.com/rhoit/dot-emacs/blob/master/scripts/wordplay.el][wordplay]] consist of collection of nifty scripts.

    #+BEGIN_SRC emacs-lisp (load "~/.config/emacs/scripts/wordplay.el") #+END_SRC

** [[http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/][smarter move to beginning of line]]

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=.

#+BEGIN_SRC emacs-lisp (global-set-key [remap move-beginning-of-line] 'smarter-move-beginning-of-line) #+END_SRC

** [[http://ergoemacs.org/emacs/modernization_upcase-word.html][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.

#+BEGIN_SRC emacs-lisp (global-set-key "\M-c" 'toggle-letter-case) #+END_SRC

** duplicate lines/words

#+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-`") 'duplicate-current-line) (global-set-key (kbd "C-~") 'duplicate-current-word) #+END_SRC

** on point line copy

only enable for =C-=

#+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-") 'kill-ring-save-current-line) #+END_SRC

  • META :noexport:

    Local Variables:

    buffer-read-only: t

    End: