A browser in your Emacs (macOS)

Since it’s no big deal for Linux users to use xwidget-webkit browser inside Emacs, it’s something that Emacs users on macOS has dreamed about for a really long time.

Now that it’s possible for us as well. You can just install the latest HEAD version of emacs with brew, with a note: The official emacs formula on brew doesn’t have the install options like --with-cocoa anymore, so you gotta use the alternative formula:

brew tap daviderestivo/emacs-head

Now, install Emacs with a couple of options, especially, don’t miss the --with-xwidgets:

brew install emacs-head --HEAD --with-jansson --without-imagemagick@7 --with-cocoa --with-xwidgets

After installed, you can start browsing in your emacs using xwidget-webkit-browse-url command.

Thanks /u/seagle0128 for the tips.

Being lazy turned out to be good

One thing I’ve learned about staying motivated on building your product is to stay consistent. Keep on improving it everyday.

Even when you feel like you don’t want to work on your project today, instead of give it a break and watching Youtube, try to find some small thing that doesn’t take too much of your effort and work on it. Maybe it’s a small bug that not a priority for a while, or a small UI improvement that nobody would even notice.

So, today is a day like that. I’ve been stuck with an issue in the code for a few days and I just want to give it a break. Finding some small things to fix and relax my mind. That’s how I decided to fix the Today view.

In case you don’t know what is Today view, just type today in Pomoday.

The Today view yesterday

This view looks “okay-ish” but there are some issues with it. Nobody actually need a numbered bullet there, the status text looks lengthy, the start time and time spent doesn’t looks brief enough for a timeline. So, here come the improved version:

The Today view today

Looks better, huh? In dark mode as well:

A minimal but useful mode-line

I’ve been using doom-modeline for a while, it was great but I still want it more simpler. So I rolled my own mode-line.

VQZDsBE.png

It only has a few things: editing status, an icon of the current mode, a file path, current line, and the current git branch.

Here’s the script:

;; Auto updating version control information
(setq auto-revert-check-vc-info t)
(setq-default mode-line-format (list
  ;; Check the buffer status and display its status
  ;; ⚿ for locked buffer. ⛯ for modified buffer. ⛆ is the normal one.
  '((:eval
     (cond
      (buffer-read-only
       (propertize " ⚿ " 'face '(:foreground "red" :weight 'bold)))
      ((buffer-modified-p)
       (propertize " ⛯ " 'face '(:foreground "orange")))
      ((not (buffer-modified-p))
       (propertize " ⛆ " 'face '(:foreground "gray85"))))))
  ;; Use all-the-icons to display the icon of current major mode
  '(:eval (propertize (all-the-icons-icon-for-mode major-mode
          :height (/ all-the-icons-scale-factor 1.4)
          :v-adjust -0.03)))
  ;; Show the file name with full path
  " %f "
  ;; Show the current position of the cursor in buffer
  'mode-line-position
  ;; Show the current major mode name
  "[" 'mode-name "] "
  ;; Check if the buffer is in any version control system, if yes, show the branch
  '(:eval
    (if vc-mode
        (let* ((noback (replace-regexp-in-string
                           (format "^ %s" (vc-backend buffer-file-name)) " " vc-mode))
               (face (cond ((string-match "^ -" noback) 'mode-line-vc)
                           ((string-match "^ [:@]" noback) 'mode-line-vc-edit)
                           ((string-match "^ [!\\?]" noback) 'mode-line-vc-modified))))
          (format "[git:%s]" (substring noback 2)))))))

Implementing firmware level key lock

One of the features of TMK/QMK firmware is the KC_LOCK key, when you hold a key, and press KC_LOCK, that key become persistent even if you release it. Just like the caps lock key.

This is pretty helpful for Emacs user, so they can move freely without holding Ctrl key.

To implement it, we can just add a new flag check, for example ctrlLockOn, to where we handle Ctrl keypress:

-    else if (keys[i].code == CTRL_KEY) {
+    else if (keys[i].code == CTRL_KEY || ctrlLockOn) {
      modifiers |= MODIFIERKEY_CTRL;
    }

And triggering ctrlLockOn where we desired. For example, I want to toggle ctrlLockOn when user pressed Fn + Ctrl + Shift + Alt, so the code would be:

+    if (keys[i].code == FN_KEY) {
+      fn = 1;
+    }

...

+    if (modifiers == CTRL_KEY | ALT_KEY | SHIFT_KEY && fn == 1) {
+      ctrlLockOn = ctrlLockOn ? 0 : 1;
+    }

By doing this, we can also press the above sequence again to turn off locking.

Packing two bytes into an integer

I’m working on building a 40% keyboard which has a 12×4 layout, and the firmware for now just need to support one key at a time.

The key scanning function returning a single integer, so I need to pack the two values Column and Row of a pressed key into this integer.

Since both of the column and row values are quite small (less than 255), I can just use two bytes to represent them. Therefore, I can pack them into an integer easily by using bit shift operators. Put the row value to the 8 low bits, and the rest is for the column value.

RESULT: int = (COL << 0) | (ROW << 8)

Later on in key sending logic, I can extract them all by shifting it back again:

COL: byte = (RESULT >> 0)
ROW: byte = (RESULT >> 8)

Use unicode symbol to display org-mode checkboxes

With the help of prettify-symbols-mode, you can make your Emacs displaying org-mode checkboxes as a real Unicode symbols, instead of a boring text, put this to your org-mode-hook:

(add-hook 'org-mode-hook (lambda ()
  "Beautify Org Checkbox Symbol"
  (push '("[ ]" .  "☐") prettify-symbols-alist)
  (push '("[X]" . "☑" ) prettify-symbols-alist)
  (push '("[-]" . "❍" ) prettify-symbols-alist)
  (prettify-symbols-mode)))

You can also use font-lock-add-keywords to add a different style for checked boxes, like what I did below, adding a strike-through style:

(defface org-checkbox-done-text
  '((t (:foreground "#71696A" :strike-through t)))
  "Face for the text part of a checked org-mode checkbox.")

(font-lock-add-keywords
 'org-mode
 `(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
    1 'org-checkbox-done-text prepend))
 'append)

Here’s the result:

Buffer-specific background color in Emacs

If you want to set a different background color for a specific buffer, maybe, of a specific mode, you can add a hook for that mode and do something like this:

(add-hook 'neotree-mode-hook (lambda ()
    (setq buffer-face-mode-face `(:background "#211C1C"))
    (buffer-face-mode 1)))

You can also toggle linum-mode or set the value for left-fringe-width, right-fringe-width, they’re only affects the current buffer.

The following screenshot is the example of my setup, changing the background color for neotree-mode and term-mode to have a fancy look:

Migrating from ZSH to Fish

One of the main reason I switched from ZSH to Fish is the ability of highlighting command output and the relative small autocomplete, which don’t lag your computer down when you have a few hundreds results like zsh.

But what I didn’t expect is to rewrite my whole .bash_profile in Fish (Fish is not bash, so it doesn’t use Bash syntax, that’s why you can’t source your .bash_profile file), well, that’s not a hard thing. Just need to read the documentation and learn some changes, such as:

export ABC="abc"
# now becomes
set -x ABC abc

If you execute a command during setting value, you need to change the syntax as well:

export RUST_SRC_PATH="$(rustc --print sysroot)/lib/rustlib/src/rust/src"
# now becomes
set -x RUST_SRC_PATH (rustc --print sysroot)/lib/rustlib/src/rust/src

For $PATH, I prefer to use export command separately from set -x, for whatever reason, I like it:

export PATH=new/path:$PATH
# now becomes
set PATH new/path $PATH
export PATH

For aliases, it’s almost the same:

alias vim="emacs"
# now becomes
alias vim "emacs"

If you use tmux, you probably have this in your .bash_profile or .bashrc:

if [ -z "$TMUX" ]; then
  if [ -z "$EMACS" ] && [ -z "$VSCODE" ]; then
    tmux new
  fi
fi

Then you need to convert it to Fish, mostly remove the brackets [] and add a test command:

if test -z "$TMUX";
  if test -z "$EMACS"; and test -z "$VSCODE";
    tmux new
  end
end

And if you use nvm, you hit the wall, since it’s heavily rely on Bash, there are some solutions such as installing bass to be able to run Bash scripts in your Fish config, but even if you go that route, initializing nvm still slowing down your shell startup time.

A better solution is using fash-nvm-fish, it’s a wrapper around nvm, which doesn’t required to parse the env config everytime you start your shell, so it’s fast. The installing process is simple, you can just follow the instruction on the Github repo. I’ll not copy it here.

If your nvm isn’t in the default directory, which is /root/.nvm/, you need to set the NVM_DIR variable, before calling nvm, in my case, it is:

set -gx NVM_DIR /usr/local/opt/nvm/
nvm use 9 --default

That’s it, just a few steps. Happy fishing.

Load light or dark theme based on time of the day

I have to work in a dark room sometimes during the night, so I have the screen brightness set to nearly zero. And it’s a PITA to see what on the screen with a dark color scheme such as tomorrow-night. Time like this, the light scheme is way better, I find that solarized-light is one of the best.

So I wrote a script to automatically select the right color scheme when I open Emacs. If it’s between 20:00 in the evening and 6:00 in the morning, it is the light theme, otherwise, use the dark one:

(defun set-light-theme ()
  "Set the light theme with some customization if needed."
  (interactive)
  (load-theme 'doom-solarized-light t))

(defun set-dark-theme ()
  "Set the dark theme with some customization if needed."
  (interactive)
  (load-theme 'doom-tomorrow-night t))

(let ((current-hour (string-to-number (format-time-string "%H"))))
  (if (or (< current-hour 6) (> current-hour 20)) (set-light-theme) (set-dark-theme)))

If you want your Emacs automatically switch between the color schemes when the time come, you can use run-with-timer function to do the check every hour:

(defun theme-switcher ()
  (let ((current-hour (string-to-number (format-time-string "%H"))))
    (if (or (< current-hour 6) (> current-hour 20)) (set-light-theme) (set-dark-theme))))

;; Run at every 3600 seconds, after 0s delay
(run-with-timer 0 3600 'theme-switcher)
Create your website with WordPress.com
Get started