But there is another form of good-bye that is very commonly used, although mostly with good friends. It is very casual. It comes from a long time past when it was fashionable to use the French word when bidding farewell to friends: adieu. In the course of time, and with people from all over the German-speaking world pronouncing and mispronouncing the word, it somehow got an s attached to it. Then it lost its first syllable. And in time it became simply Tschis (CHUESS).
different weather phenomena along with their genders.
die Sonne (the sun) - Feminine
der Regen (the rain) - Masculine
der Schnee (the snow) - Masculine
das Gewitter (the thunderstorm) - Neuter
die Wolke (the cloud) - Feminine
der Blitz (the lightning) - Masculine
der Sturm (the storm) - Masculine
der Wind (the wind) - Masculine
Mnemonic Device
Feminine (die): Think of Sun and Clouds as nurturing elements in nature, traditionally associated with feminine qualities. Hence, “die Sonne” (sun) and “die Wolke” (cloud) are feminine.
Masculine (der): Rain, Snow, Lightning, Storm, and Wind can be associated with strength and force, often seen as masculine traits. So, “der Regen” (rain), “der Schnee” (snow), “der Blitz” (lightning), “der Sturm” (storm), and “der Wind” (wind) are masculine.
Neuter (das): Thunderstorm is a mix of various elements (rain, lightning, thunder). You can think of it as a complex phenomenon that doesn’t fit into a single category, thus making “das Gewitter” (thunderstorm) neuter.
Docker daemon ports: add something like tcp://0.0.0.0:9999 in /etc/docker/daemon.json
It’s about the Docker daemon’s ability to accept commands (like starting/stopping containers, pulling images, etc.) over the network.
forwarding container ports
This is about exposing a specific port of a running container to the host or the outside world, allowing network traffic to reach the service running inside the container.
summary
In summary, setting the Docker daemon to listen on certain TCP ports is about remote management of the Docker engine itself, while forwarding ports for a container is about allowing external access to services running inside that container.
As a seasoned Emacs user, I’ve been eagerly anticipating the built-in arrival of use-package in version 29.1. And now it’s finally here! This
declarative configuration tool
has already become my go-to for confining all the chaotic Emacs configurations, making everything more organized and manageable. So, if you haven’t already, I’d wholeheartedly recommend upgrading your Emacs to the latest version 29.1.
Tips for Checking Package Installation
When you’re neck-deep in code, it’s quite common to forget whether you’ve installed a particular package or not. Emacs has got you covered with several commands:
featurep: Use this if a package ends with provide.
fboundp: This comes in handy when you need to check if a certain function is defined.
bound-and-true-p: Use this to confirm whether a global minor mode is both installed and activated.
The Power of cl-letf
I’ve found
cl-letfto be incredibly useful when I need to dynamically and temporarily override functions and values defined externally. It’s particularly handy when paired with advice, allowing me to alter the behavior of third-party packages without meddling with their source code.
Here’s a practical example of how to override a function defined in a package. The code modifies the behavior of original-split-window-horizontally inside create-window so that no matter what argument it receives, a fixed width is used:
(defunmy-create-window-advice(orig-fun&restargs)"Advice to modify the behavior of `split-window-horizontally' in `create-window'."(let((original-split-window-horizontally(symbol-function'split-window-horizontally))(fixed-width20)))(cl-letf(((symbol-function'split-window-horizontally)(lambda(&optionalsize)(funcalloriginal-split-window-horizontallyfixed-width))))(applyorig-funargs))))(advice-add'create-window:around#'my-create-window-advice)
Embracing thread-first and thread-last Macros
One of my favorite features of Emacs version 25 and onwards is the built-in thread-first and thread-last macros. These can prove immensely useful when dealing with complex data transformations - they help maintain clean and readable code.
In Emacs Lisp, the thread-first and thread-last are powerful tools for improving the readability of function call sequences. They allow for a more intuitive and linear style of writing nested function calls, especially useful in situations where you have multiple operations that need to be applied in sequence.
After a decade of using Emacs, it continues to be an indispensable part of my programming arsenal. Once one has really recognized the extensibility of emacs, it’s hard to not miss it every time using another editor.
System Prefs / Keyboard / Shortcuts / App Shortcuts / All Applications, click the + button at the bottom, type Emoji & Symbols, and then enter a new keyboard shortcut (option-shift-command-t, or anything really) to free the shortcut
I’ve been searching for a good solution to use Emacs29 with tree-sitter config in nix-darwin for quite some time.
Emacs29 comes with built-in support for Tree-Sitter, a parser generator tool and an incremental parsing library, the only requirement is the grammar files, detail in this
masteringemacs article
.
While there are some proposed solutions out there, such as the one found on the
nixos discourse
, they didn’t quite hit the mark for me. The issue was that I’m using an overridden package definition of pkgs.emacs29-macport, which complicated things a bit.
The above treesit-grammars.with-all-grammars definition only installs the dynamic libraries. However, Emacs was still unable to find the files. The crux of the problem was that I needed to link the directory to a location that Tree-Sitter could locate.
After many trials and tribulations, I finally managed to come up with a functional solution.
Solution
pkg-emacs29-macport.nix: package definition of emacs
{pkgs?(import<nixpkgs>{})}:let# https://github.com/railwaycat/homebrew-emacsmacport/blob/master/Formula/emacs-mac.rbemacs29-macport=(pkgs.emacs29-macport.overrideAttrs(prevAttrs:{patches=(prevAttrs.patches)++[# patch for multi-tty support, see the following links for details# https://bitbucket.org/mituharu/emacs-mac/pull-requests/2/add-multi-tty-support-to-be-on-par-with/diff# https://ylluminarious.github.io/2019/05/23/how-to-fix-the-emacs-mac-port-for-multi-tty-access/(pkgs.fetchpatch{url="https://raw.githubusercontent.com/railwaycat/homebrew-emacsmacport/8b06f75ea28a68f9a490d9001ce33fd1b0d426aa/patches/emacs-mac-29-multi-tty.diff";sha256="sha256-OpSYG5ew8A1IL5rW/wPwmG2bzZa8iFF+xTYQGiWjzKg=";})# no-title-bars(pkgs.fetchpatch{url="https://raw.githubusercontent.com/railwaycat/homebrew-emacsmacport/667f0efc08506facfc6963ac1fd1d5b9b777e094/patches/emacs-26.2-rc1-mac-7.5-no-title-bar.patch";sha256="sha256-f2DRcUZq8Y18n6MJ6vtChN5hLGERduMB8B1mrrds6Ns=";})];})).override{# not necessary, but enforce these options to be truewithNativeCompilation=true;withTreeSitter=true;};buildEmacs=(pkgs.emacsPackagesForemacs29-macport).emacsWithPackages;treesitGrammars=(pkgs.emacsPackagesForemacs29-macport).treesit-grammars.with-all-grammars;in{emacs=buildEmacs(epkgs:withepkgs;[vtermtreesitGrammars]);treesitGrammars=treesitGrammars;}
config-emacs.nix: configuraiton of emacs
{pkgs,config,lib,...}:letemacs29=(pkgs.callPackage./pkg-emacs29-macport.nix{});in{home.packages=lib.mkBefore([emacs29.emacs]);home.file={# tree-sitter subdirectory of the directory specified by user-emacs-directory".config/emacs/.local/cache/tree-sitter".source="${emacs29.treesitGrammars}/lib";};}
Tree-sitter language grammars are distributed as dynamic libraries. In order to use a language grammar in Emacs, you need to make sure that the dynamic library is installed on the system. Emacs looks for language grammars in several places, in the following order:
first, in the list of directories specified by the variable treesit-extra-load-path;
then, in the tree-sitter subdirectory of the directory specified by user-emacs-directory (see The Init File);
and finally, in the system’s default locations for dynamic libraries.
I use Emacs --with-no-title-bar and use
yabaito auto layout window,
sketchybarto display current window title at the menu bar.
Due to the limited screen size on a laptop, it can be challenging to view the entire file path. Therefore, I created a function that shows a shortened version of the file path.
If you are editing a file, the function will display the file path. Otherwise, it will display the buffer name.
for example, ~/projects/blog/content/posts/emacs-frame-title-format.md will be display as ~/p/b/c/posts/emacs-frame-title-format.md
(defunshorten-path-for-title(path)"Shorten a file PATH to be displayed in the frame title.
Only the last directory's name is fully displayed; upper-layer directories are represented by their first letters."(let*((components(split-string(orpath"")"/"t))(filename(or(car(lastcomponents))""))(lastdir(if(>(lengthcomponents)1)(nth(-(lengthcomponents)2)components)""))(dirs(butlastcomponents2))(shortened-dirs(mapcar(lambda(dir)(substringdir01))dirs)))(concat(string-joinshortened-dirs"/")(ifshortened-dirs"/")lastdir"/"filename)))(setqframe-title-format'((:eval(if(buffer-file-name)(shorten-path-for-title(abbreviate-file-name(buffer-file-name)))))(:eval(if(not(buffer-file-name))(buffer-name)))))
Mac OS intercepts and handles certain key combinations (e.g., - for switching input languages). These will not be passed to Emacs. One can disable this interception by setting mac-pass-command-to-system or mac-pass-control-to-system to nil.
When I decided to manage my sketchybar configuration as a git submodule within my Nix Flakes setup, I encountered an unexpected obstacle. Attempting to run darwin-rebuild was met with failure as the system couldn’t locate the source of the local directory. It’s a known issue as discussed in the
Submodules of flakes are not working
thread.
Overcoming the Submodule Challenge
I devised a workaround that resolved the problem and ensured proper file execution permissions. Before diving into the implementation details, I must emphasize the necessity of updating the flake.lock file. This is a critical step to ensure submodule is recognized by nix:
{inputs,pkgs,...}:pkgs.stdenv.mkDerivation{name="sketchybar-config";dontConfigure=true;dontUnpack=true;src=inputs.config-sketchybar-src;installPhase=''
mkdir -p $out
cp -r $src/config/sketchybar/* $out
# Find all .sh files and substitute 'jq' with the full path to the jq binary
find $out -type f -name "*.sh" | while read script; do
substituteInPlace "$script" \
--replace 'jq' '${pkgs.jq}/bin/jq'
done
chmod -R +x $out
'';}
In the end, the satisfaction of having your local directory seamlessly integrated as a git submodule and functioning perfectly within the Nix ecosystem is well worth the effort.