[2020-06-05 Fri 13:31]
Because I’ve configured my GNU emacs to automatically run in daemon mode I wish to ‘use’ emacs by running emacsclient
exclusively. But emacsclient isn’t an OS-X ‘app’ which means that I can’t double click on a file to open it with emacsclient. It also means that I can’t use the ‘Open With’ menu to edit a file via emacsclient. Here is how to resolve those issues.
To create the app, I used Platypus. It is a truly great little application that enables one to put a wrapper around a shell script (or, I suppose, an a.out
) to make it act like a ‘real’ application.
- Create a trivial shell script called
ec
which callsemacsclient
. Make the script executable. I put it in my~/bin/
.#!/bin/bash # Start emacsclient and return immediately. /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n -c " $@ "
- Optional: If you want your app to have the pretty GNU Emacs icon, copy
Emacs.app/Contents/Resources/Emacs.icns
to the temp dir. - Launch Platypus. In the Platypus UI, do the following:
App Name --> 'emacsclient' Script Type --> 'bash' Script Path --> '~/bin/ec' Output --> 'None' Accepts dropped items --> 'checked' Everything else --> 'unchecked' Optional: Click the gear under the icon and set icon to: Emacs.icns
- In Platypus, click on ‘create’.
This will create a ‘real’ OS-X application named
emacsclient.app
in your temp dir. Copy thisemacsclient.app
to/Applications
.
You now have a functioning emacsclient OS-X ‘application’.
The app created by Platypus worked fine. However, nothing had been done to associate file extensions with the emacsclient.app
. Without those associations it would not be possible to, for example, double click a Python file and have emacsclient open it.
It seems like Platypus would offer a mechanism for associating file extensions with the application it generates, but I could not find one. Here’s what I did.
/Applications/emacsclient.app/Contents/Info.plist
contains an array of file extensions that emacsclient knows how to open; they are stored under the CFBundleDocumentTypes
key. The array was essentially empty.
I decided that I wanted to take the list of supported extensions from the Info.plist
under Emacs.app
and insert them into the plist for emacsclient.app
. But how to do this?
The duti
utility looked promising, but it would not compile on El Capitan. It may have just been a matter of updating a version string in the config, but I didn’t feel like investing time in the necessary research.
I believe that I could have used plutil
and PlistBuddy
to convert both plists to XML and then manually edit them, but seemed tedious and error-prone.
I was surprised to discover that Python includes plistlib
in its standard distribution. It made things ridiculously easy.
The following code will extract a key value from a source plist and insert that same key:value into a destination plist, saving the modified destination plist as a new plist.
#!/usr/bin/env python
# cppk.py -- This DOES NOT modify anything in /Applications
import sys , plistlib , os
( key , src , dest , new ) = sys . argv [ 1 :]
source = plistlib . readPlist ( src )
destination = plistlib . readPlist ( dest )
destination [ key ] = source [ key ]
plistlib . writePlist ( destination , new )
Example usage:
$ E =/Applications/Emacs.app/Contents/Info.plist
$ EC =/Applications/emacsclient.app/Contents/Info.plist
$ ./cppk.py CFBundleDocumentTypes $E $EC ./Info.plist
This creates the desired plist and saves it as ./Info.plist
. I then copied ./Info.plist
to emacsclient.app/Contents/Info.plist
(after making a backup copy).
To force OS-X to pick up the change, I ran lsregister
, causing Launch Services to rebuild its database:
# Valid for OS-X 10.11.2. If the path is invalid on your version,
# run 'locate lsregister' to find it.
% F =/System/Library/Frameworks/CoreServices.framework
% F +=/Versions/A/Frameworks/LaunchServices.framework
% F +=/Versions/A/Support/lsregister
% " $F " -lint -kill -r -domain local -domain system -domain user
This may take a while to complete.
After this point, emacsclient
will appear in the ‘Open With’ menu. Additionally, it is now possible to globally associate emacsclient with file types so that it is the default application used to open them.
I can now double-click on a python file and have emacsclient open it.
I’d like to automate setting the global default application for certain file types (e.g., .py, .txt, etc.), but that will wait for another day.
[2020-06-05 Fri 13:32]
I have used the Emacs for Mac OS-X distribution of Gnu Emacs for years and have been quite pleased with it. Emacs’ server-mode
is great in that it makes for very fast load times and it allows sharing buffer contents, kill rings, etc., between windows. However, I found it a little tricky to get it working perfectly on OS-X. These are my notes on how to install and configure it so that server-mode
works correctly on OS-X.
Under server-mode
, the emacsclient
program is used to edit files. I have another note about how to configure emacsclient as an OS-X application. This may be worth reading as well.
- Install Emacs for Mac OS-X.
- Update your path:
# Emacs.app binaries must come before /usr/bin # Using the apple provided emacsclient with a different # emacs in server mode is a common source of problems. PATH =/Applications/Emacs.app/Contents/MacOS/bin: $PATH
- Create a script named
ec
that invokes emacsclient with desired options. Note that this returns immediately; it does not wait for the edit to complete.#!/usr/bin/env bash # -n --> Return immediately, don't wait for edit to complete # -a "" --> If emacs is not running in server mode, start it # -c --> create a new frame instead of using existing frame emacsclient -n -a "" -c " $@ "
- Create a script named
ecw
that invokes emacsclient with desired options. Note that this command will not exit until the edit is complete.#!/usr/bin/env bash # -a "" --> If emacs is not running in server mode, start it # -c --> create a new frame instead of using existing frame emacsclient -a "" -c " $@ "
- Many programs use the EDITOR and VISUAL environment variables to determine which editor to use. Set these up to use
ecw
.export EDITOR =ecw export VISUAL =ecw
Whenever you run ec
or ecw
, an emacs daemon in server-mode will be started, if one doesn’t already exist.
This is the simplest emacs setup that I’ve used and it works well.
While not specific to OS-X, this is germane to server-mode emacs.
I’m used to killing buffers with = C-x k=. When first starting to use server-mode, I started seeing warnings about a client still using the buffer that I was killing. For my (simple) use case, the following allows me to keep using my old muscle-memory to kill the buffer yet avoid the warning:
( add-hook 'server-switch-hook
( lambda ()
( when ( current-local-map )
( use-local-map ( copy-keymap ( current-local-map ))))
( when server-buffer-clients
( local-set-key ( kbd "C-x k" ) 'server-edit ))))
Before I settled on the above approach, I configured OS-X to automatically start emacs in server-mode at boot time. This does work, but it isn’t as clean as the above. Here’s how to do it:
- Create the plist
~/Library/LaunchAgents/org.fsf.gnu.emacs.plist
using an editor:version= "1.0" > Label org.fsf.gnu.emacs ProgramArguments /Applications/Emacs.app/Contents/MacOS/Emacs --daemon RunAtLoad KeepAlive ServiceDescription Gnu Emacs Daemon
- Install the plist:
$ launchctl load -w ~/Library/LaunchAgents/org.fsf.gnu.emacs.plist
Note: I made up org.fsf.gnu.emacs
. There’s nothing magic about it; it could be any unique value.
Now OS-X will start emacs in daemon mode and keep it running for you. I have had weird things happen with this approach, which is why I converted to the first method presented.
After creating an emacsclient
app via Platypus, I was disappointed to notice that the app did not appear in the ‘Open With’ menu when a supported file was control-clicked on.
Here is how I took care of this issue.
/Applications/emacsclient.app/Contents/Info.plist
contains an array of file extensions that it knows how to open; they are stored under the CFBundleDocumentTypes
key. The array was empty, containing only a *
.
I concluded that a suitable array could be copied from Emacs.app
and set about trying to insert it into emacsclient
’s Info.plist
. After a few hours of PlistBuddy
and plutil
, I was unable to get what I inserted as the array to be properly recognized.
This is why I don’t like binary / non-editable configuration files. There’s no reason that the plist shouldn’t be editable text: YAML, XML, JSON, or whatever. A binary format for configuration files that can only be modified with dedicated tools is insane.
I finally dropped back to Python, having bypassed it initially, assuming that programming be the long road to get it done. I was surprised to see that Python includes plistlib
in its standard distribution. It made things ridiculously easy.
The following code grabs the array from Emacs.app
, and inserts it into a copy of Info.plist
taken from emacsclient.capp
. It saves the modified result as Info.plist.new
in the current directory.
#!/usr/bin/env python
# Run this script from the command line with the path to the Emacs.app
# Info.plist as the first argument and the path to the emacsclient.app
# Info.plist as the second argument. 'Info.plist.new' will be created
# in current direcotory.
import sys , plistlib , os
( pl_from , pl_to ) = sys . argv [ 1 :]
plf = plistlib . readPlist ( pl_from )
plt = plistlib . readPlist ( pl_to )
plt [ 'CFBundleDocumentTypes' ] = plf [ 'CFBundleDocumentTypes' ]
plistlib . writePlist ( plt , os . path . basename ( pl_to ) + '.new' )
When this completes, copy the resulting Info.plist.new
to emacsclient.app/Contents/Info.plist
(after making a backup copy).
So that OS-X picks up the change, it is necessary to run lsregister
, which causes Launch Services to rebuild its database. Here’s how:
# Valid for OS-X 10.11.2. If the path is invalid on yours,
# run 'locate lsregister' to find it.
% F =/System/Library/Frameworks/CoreServices.framework
% F +=/Versions/A/Frameworks/LaunchServices.framework
% F +=/Versions/A/Support/lsregister
% $F -lint -kill -r -domain local -domain system -domain user
This may take 15-30 seconds to run. After that, emacsclient
will appear in your ‘Open With’ menu the next time you use it; it’s worth the effort.
brew tap d12frosted/emacs-plus
brew install emacs-plus --with-modern-nuvola-icon --with-xwidgets --without-imagemagick --with-jansson
(define-key function-key-map (kbd "<kp-1>") 'event-apply-control-modifier)
(define-key function-key-map (kbd "<kp-2>") 'event-apply-meta-modifier)
(define-key function-key-map (kbd "<kp-3>") 'event-apply-super-modifier)
(define-key function-key-map (kbd "<kp-4>") 'event-apply-shift-modifier)
(define-key function-key-map (kbd "<kp-5>") 'event-apply-hyper-modifier)
(define-key function-key-map (kbd "<kp-6>") 'event-apply-alt-modifier)
[2020-08-18 Tue 23:35]
Been wanting to try Andrea Corallo’s gccemacs. Followed Allen Dang’s handy instructions to build it on macOS.
Though not had much of a chance to play with the new install, here’s what I did to get up and running…
Edit $(brew –prefix)/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb
$ diff -u $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb.patched --- $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb 2020-08-16 14:12:13.000000000 +0100 +++ $(brew --prefix)/Library/Taps/homebrew/homebrew-core/Formula/gcc.rb.patched 2020-08-07 09:16:42.000000000 +0100 @@ -47,7 +47,7 @@ # - Go, currently not supported on macOS # - BRIG # GCCEMACS - languages = %w[c c++ objc obj-c++ fortran] + languages = %w[c c++ objc obj-c++ fortran jit ] osmajor = `uname -r`.split(".").first pkgversion = "Homebrew GCC #{pkg_version} #{build.used_options*" "}".strip @@ -67,6 +67,7 @@ --with-system-zlib --with-pkgversion=#{pkgversion} --with-bugurl=https://github.com/Homebrew/homebrew-core/issues + --enable-host-shared ] # Xcode 10 dropped 32-bit support
brew install gcc --build-from-source --force
Create configure-gccemacs.sh
# !/bin/ bash set -o nounset set -o errexit # Configures Emacs for building native comp support # http://akrl.sdf.org/gccemacs.html # Installing under homebrew's opt, but could be anywhere. readonly GCCEMACS_PREFIX= "$( realpath $(brew --prefix )/opt/gccemacs)" readonly GCC_DIR= "$( realpath $(brew --prefix )/opt/gcc)" [[ -d $ GCC_DIR ]] || { echo "${GCC_DIR} not found"; exit 1; } readonly SED_DIR= "$( realpath $(brew --prefix )/opt/gnu-sed)" [[ -d $ SED_DIR ]] || { echo "${SED_DIR} not found"; exit 1; } readonly GCC_INCLUDE_DIR=${ GCC_DIR}/include [[ -d $ GCC_INCLUDE_DIR ]] || { echo "${GCC_INCLUDE_DIR} not found"; exit 1; } readonly GCC_LIB_DIR=${ GCC_DIR}/lib/gcc/10 [[ -d $ GCC_LIB_DIR ]] || { echo "${GCC_LIB_DIR} not found"; exit 1; } export PATH= "${SED_DIR}/libexec/gnubin:${PATH}" export CFLAGS= "-I${GCC_INCLUDE_DIR}" export LDFLAGS= "-L${GCC_LIB_DIR} -I${GCC_INCLUDE_DIR}" export DYLD_FALLBACK_LIBRARY_PATH= "${GCC_LIB_DIR}" echo "Environment" echo "-----------" echo PATH: $ PATH echo CFLAGS: $ CFLAGS echo LDFLAGS: $ LDFLAGS echo DYLD_FALLBACK_LIBRARY_PATH: $ DYLD_FALLBACK_LIBRARY_PATH echo "-----------" ./autogen.sh ./configure \ --prefix= "${GCCEMACS_PREFIX}" \ --enable-locallisppath= "${GCCEMACS_PREFIX}/opt/gccemacs/site-lisp" \ --with-mailutils \ --with-ns \ --with-imagemagick \ --with-cairo \ --with-modules \ --with-xml2 \ --with-gnutls \ --with-json \ --with-rsvg \ --with-nativecomp \ --disable-silent-rules \ --disable-ns-self-contained \ --without-dbus
Make it executable
chmod +x configure-gccemacs.sh
git clone https://github.com/emacs-mirror/emacs gccemacs
cd gccemacs git checkout feature/native-comp
../configure-gccemacs.sh
Verify native lisp compiler is found:
Does Emacs have native lisp compiler? yes
Build will take a while. Put those cores to use. Find out how many you got with:
sysctl hw.logicalcpu
hw.logicalcpu: 4
Ok so run:
make -j4 NATIVE_FAST_BOOT=1 make install
This will take hours and give your fans a good workout.
Without synlinking, opening Emacs.app from finder fails silently, so symlink as follows. Btw, if you changed $GCCEMACS_PREFIX, use that path prefix instead.
ln -s $( brew --prefix)/opt/gccemacs/share/emacs/28.0.50/lisp nextstep/Emacs.app/Contents/
ps. Without symlink, you won’t see an error unless the binary is executed explicitly from the terminal (ie. nextstep/Emacs.app/Contents/MacOS/Emacs), and then you’d see something like
nextstep/Emacs.app/Contents/MacOS/Emacs emacs: dlopen(nextstep/Emacs.app/Contents/MacOS/../lisp/emacs-lisp/eln-x86_64-apple-darwin19.4.0-abff6ce99a055711/lisp-mode.eln, 1): image not found
You likely want to start with a clean install, byte-compiling all packages with the latest Emacs version. In any case, rename ~/emacs.d (for backup?) or remove ~/emacs.d.
Ensure exec-path and LIBRARY_PATH both point to locations in $GCCEMACS_PREFIX and finally set comp-deferred-compilation. I wrapped mine in exec-path-from-shell, setting early in init.el should be enough.
( use-package exec-path-from-shell :ensure t :config (exec-path-from-shell-initialize) ( if ( and (fboundp 'native-comp-available-p) (native-comp-available-p)) ( progn (message "Native comp is available") (add-to-list 'exec-path (expand-file-name "~/homebrew/opt/gccemacs/bin")) (setenv "LIBRARY_PATH" (concat (getenv "LIBRARY_PATH") ( when (getenv "LIBRARY_PATH") ":") (car (file-expand-wildcards (expand-file-name "~/homebrew/opt/gcc/lib/gcc/*"))))) ;; Only set after LIBRARY_PATH can find gcc libraries. ( setq comp-deferred-compilation t)) (message "Native comp is *not* available")))
You’re good to go. Open Emacs.app via finder or shell:
open nextstep/Emacs.app
After setting comp-deferred-compilation (in init.el config section), .elc files should be asyncronously compiled. Function definition should be updated to native compiled equivalent.
Look out for an **Async-native-compile-log** buffer. Should have content like:
Compiling .emacs.d/elpa/moody-20200514.1946/moody.el... Compiling .emacs.d/elpa/minions-20200522.1052/minions.el... Compiling .emacs.d/elpa/persistent-scratch-20190922.1046/persistent-scratch.el... Compiling .emacs.d/elpa/which-key-20200721.1927/which-key.el... ...
Can also check for .eln files:
find ~/.emacs.d -iname *.eln | wc -l
149
[2020-08-19 Wed 00:23]
The language server protocol was proposed by Microsoft as a way for different editors and development environments to share language analysis backends
This post describes how to configure Emacs, lsp-mode and the palantir python-language-server for improved code intelligence when working on Python projects. (I’m planning a companion post for Emacs, C++ and the cquery language server.)
Before starting, it is motivating to see what we are working towards.
With a correctly configured setup, Emacs will sport, amongst others, improved completion with interactive documentation, imenu navigation, documentation on hover, and really snazzy find definitions (M-.
) and find references.
See the following screenshots for some examples:
Install the python-language-server
into the virtual environment, or user environment, that you’re planning to use.
These days, I tend to use pipenv
:
cd my_project pipenv install python-language-server [all ]
The [all]
means that it installs all optional providers, e.g. yapf formatting.
In Emacs, install the required and some optional packages using for example M-x package-install
:
lsp-mode
- the main language server protocol packagelsp-ui
- UI-related LSP extras, such as the sideline info, docs, flycheck, etc.company-lsp
- company-backend for LSP-based code completion.- =projectile= or =find-file-in-project= - we use a single function from here to determine the root directory of a project.
Add the following to your Emacs init.el
, and don’t forget to read the comments.
If you’re not yet using =use-package= now would be a good time to upgrade.
( use-package lsp-mode :ensure t :config ;; make sure we have lsp-imenu everywhere we have LSP ( require 'lsp-imenu ) ( add-hook 'lsp-after-open-hook 'lsp-enable-imenu ) ;; get lsp-python-enable defined ;; NB: use either projectile-project-root or ffip-get-project-root-directory ;; or any other function that can be used to find the root directory of a project ( lsp-define-stdio-client lsp-python "python" #' projectile-project-root ' ( "pyls" )) ;; make sure this is activated when python-mode is activated ;; lsp-python-enable is created by macro above ( add-hook 'python-mode-hook ( lambda () ( lsp-python-enable ))) ;; lsp extras ( use-package lsp-ui :ensure t :config ( setq lsp-ui-sideline-ignore-duplicate t ) ( add-hook 'lsp-mode-hook 'lsp-ui-mode )) ( use-package company-lsp :config ( push 'company-lsp company-backends )) ;; NB: only required if you prefer flake8 instead of the default ;; send pyls config via lsp-after-initialize-hook -- harmless for ;; other servers due to pyls key, but would prefer only sending this ;; when pyls gets initialised (:initialize function in ;; lsp-define-stdio-client is invoked too early (before server ;; start)) -- cpbotha ( defun lsp-set-cfg () ( let (( lsp-cfg ` ( :pyls ( :configurationSources ( "flake8" ))))) ;; TODO: check lsp--cur-workspace here to decide per server / project ( lsp--set-configuration lsp-cfg ))) ( add-hook 'lsp-after-initialize-hook 'lsp-set-cfg ))
Importantly, use =pyenv= or something similar to switch to the relevant virtualenv before opening the first Python file.
When you open the file, the pyls
should be automatically started up, and you can edit away with LSP-powered code intelligence.
This often gives better and more detailed results than =elpy=, probably because pyls uses a mix of static and dynamic (introspection-based) analysis.
Furthermore, the handling of LSP servers in Emacs can be unified, giving the same consistent level of support across a whole range of programming languages.
[2020-11-11 Wed 10:51]
So a lot of my notes and tasks will require me to reference outlook items, either emails or meetings.
There aren’t any real solutions for Achieving this on MacOS at the moment, and the Windows solutions are not too great.
So I decided to create this unholy abomination. I’m sorry.
So there’s a few moving parts to this, but overall it’s mainly leverging AppleScript, Karabiner and Emacs to provide this functionality.
Let’s start with the MacOS Native automation tools, this is how we’ll get the ID of the Outlook item, which we will need later when searching for it.
There are two AppleScript files, one for inserting a link into the current buffer, and another for using a capture template. Both are almost identical, but one evals some Elisp to ensure we insert at the right point and file.
Insertiontell application "Microsoft Outlook" set theMessages to selected objects repeat with theMessage in theMessages set toOpen to id of theMessage end repeat end tell tell application "Emacs" to activate do shell script "/usr/local/bin/emacsclient --eval '(with-current-buffer (window-buffer) (org-insert-link nil \"outlook:" & toOpen & "\" (read-string \"Link Name:\")))'"Capture
tell application "Microsoft Outlook" set theMessages to selected objects repeat with theMessage in theMessages set toOpen to id of theMessage end repeat end tell tell application "Emacs" to activate do shell script "/usr/local/bin/emacsclient \"org-protocol://capture?template=o&url=" & toOpen & "\""
Karabiner provides a very nice way of running a shell script from a keybind, and even supports filtering to the correct window. Thus this keybind will only trigger when Outlook is focused.
Command+L will insert and Command+Shift+L will capture
{ "title": "Outlook-Emacs", "rules": [ { "description": "Meta-L to copy outlook item to orgmode", "manipulators": [ { "type": "basic", "from": { "key_code": "l", "modifiers": { "mandatory": ["left_command"], "optional": ["caps_lock"] } }, "to": [ { "shell_command": "osascript ~/Documents/Store_Selected_OutlookItem_As_Orgmode_Link.scpt" } ], "conditions": [ { "type": "frontmost_application_if", "bundle_identifiers": ["^com\\.microsoft\\.Outlook$"] } ] } ] }, { "description": "Meta-L to copy outlook item to orgmode", "manipulators": [ { "type": "basic", "from": { "key_code": "l", "modifiers": { "mandatory": ["left_command", "left_shift"], "optional": ["caps_lock"] } }, "to": [ { "shell_command": "osascript ~/Documents/Capture_Selected_OutlookItem_As_Orgmode_Link.scpt" } ], "conditions": [ { "type": "frontmost_application_if", "bundle_identifiers": ["^com\\.microsoft\\.Outlook$"] } ] } ] } ] }
There are two parts of this for Emacs, the Capture template, and the custom hyperlink
Custom LinkI just dump this into my startup config, but you could make an ol-outlook.el
if you wanted to make it less platform specific.
This relies on MDFind which is the macos spotlight CLI, it will find it, then open it in outlook.
(require 'ol) (org-add-link-type "outlook" 'org-outlook-open) (defun org-outlook-open (id _) "Open the outlook item matching that ID" (shell-command (format "mdfind \"com_microsoft_outlook_recordID == '%s'\" -0 | xargs -0 open " id)))Capture template
Ideally this should be customized more for your setup, but this is what I use.
(add-to-list 'org-capture-templates '("o" "Outlook item to capture" entry (file+headline "~/Documents/Notes/inbox.org" "Tasks") "* TODO [[outlook:%:link][%^{Item name|Email}]]" :clock-in t :clock-resume t))
[2020-11-18 Wed 10:08]
ArticleSynchronizing OSX, Terminal, and Emacs Dark/Light AppearanceComposing Shell, Applescript, and Emacs EvalBy Jeremy Friesen on 2020-11-11
:: # emacs
Throughout the day, I find myself toggling between Light and Dark modes. This evening I wrote up a shell script to keep OS X 📖 , Emacs 📖 , and my Terminal synchronized.
I named the script =dark=. Now, from the command-line, I can type dark to switch between Light and Dark mode.
Below is a copy of that script:
#!/bin/sh # This script toggles the Operating System, Terminal, and Emacs # themes. It uses the state of the Operating System to determine # if the terminal and Emacs should be "dark" or "light". # First, tell OS-x to toggle dark mode. osascript -e 'tell application "System Events" to tell appearance preferences to set dark mode to not dark mode' # Second, determine what is the newly set appearance. appearance=`defaults read -g AppleInterfaceStyle 2>/dev/null` if [ -z "$appearance" ] then # No value for AppleInterfaceStyle, so the OS has us in light # mode, proceed accordingly. sh $HOME/.config/base16-shell/scripts/base16-google-light.sh editor --eval "(disable-theme 'modus-vivendi)" \ --eval "(modus-operandi-theme-load)" 1> /dev/null else # AppleInterfaceStyle is set, and that means we're now in "Dark" # mode. sh $HOME/.config/base16-shell/scripts/base16-google-dark.sh editor --eval "(disable-theme 'modus-operandi)" \ --eval "(modus-vivendi-theme-load)" 1> /dev/null fi
Nothing fancy.
*Nov 11, 2020 update:*
Emacs ConfigurationLater on this evening, I started tinkering to see about Emacs synchronizing with the Dark/Light mode of OS X .
(defun jnf-dark () "Toggle system-wide Dark or Light setting." (interactive) (shell-command "osascript -e 'tell application \"System Events\" to tell appearance preferences to set dark mode to not dark mode'") (jnf-emacs-theme-by-osx-appearance)) (defun jnf-emacs-theme-by-osx-appearance () "Set theme based on OSX apperance state." (if (equal "Dark" (substring (shell-command-to-string "defaults read -g AppleInterfaceStyle") 0 4)) (progn (disable-theme 'modus-operandi) (modus-vivendi-theme-load)) (progn (disable-theme 'modus-vivendi) (modus-operandi-theme-load)))) ;; Load the appropriate Emacs theme based on OSX appearance (jnf-emacs-theme-by-osx-appearance)
I added this to my one of the files I load for Emacs.
Web Mentions
Others mentions of this post:
Related Posts- Reducing Duplication in my Emacs Config
- Visual Changes to Take on Rules
- Why I Chose Emacs as My New Text Editor
- Using Emacs While Running Online Games
- Principles of My Text Editor
Synchronizing OSX, Terminal, and Emacs Dark/Light Appearance by Jeremy Friesen is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. Based on a work at https://takeonrules.com/2020/11/11/synchronizing-osx-terminal-and-emacs-dark-light-appearance/. Permissions beyond the scope of this license may be available at https://takeonrules.com/more_permissions/.
Homebrew/homebrew-core#14737 (comment)
brew install pinentry-mac
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
killall gpg-agent
Open a terminal window and cd into a folder under the repository. Then:
git fsck | awk '{print $3}' > tmp.txt
cat tmp.txt | xargs git show > tmp2.txt
Now open tmp2.txt in editor, locate your lost code, and find the commit-id on top of it. Then apply the code:
git stash apply <commit id>
rm tmp.txt tmp2.txt
recover lost stash:
gitk --all $(git fsck --no-reflog | awk '/dangling commit/ {print $3}')