Compare commits
No commits in common. "590bc6f567aa164b763005e4487fb13b12e89cc4" and "9dcfb216d3536c82dc76a61d0cf44c5bafb2f9ff" have entirely different histories.
590bc6f567
...
9dcfb216d3
17 changed files with 238 additions and 390 deletions
|
|
@ -44,7 +44,7 @@ Best success comes from using the [[https://github.com/d12frosted/homebrew-emacs
|
||||||
I find that I need to … at least, on my work computer, install two different versions of Emacs that I use to distinguish one for “work” and the other for other activities, like IRC and [[file:ha-feed-reader.org][elfeed]]. To that end, I run the following command to install Emacs:
|
I find that I need to … at least, on my work computer, install two different versions of Emacs that I use to distinguish one for “work” and the other for other activities, like IRC and [[file:ha-feed-reader.org][elfeed]]. To that end, I run the following command to install Emacs:
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
brew reinstall $(brew deps emacs-plus@30)
|
brew reinstall $(brew deps emacs-plus@30)
|
||||||
brew reinstall emacs-plus@30 --with-mailutils
|
brew install emacs-plus@30 --with-native-comp --with-mailutils --with-imagemagick --with-savchenkovaleriy-big-sur-icon --with-no-frame-refocus --debug
|
||||||
#+end_src
|
#+end_src
|
||||||
And if it fails, choose =shell= and type:
|
And if it fails, choose =shell= and type:
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"A WAV or AU file used at the completion of a function.")
|
"A WAV or AU file used at the completion of a function.")
|
||||||
|
|
||||||
;; My replacement in case we can't play internal sounds:
|
;; My replacement in case we can't play internal sounds:
|
||||||
(defun beep-beep (&rest _)
|
(defun beep-beep ()
|
||||||
"Play a default notification sound file.
|
"Play a default notification sound file.
|
||||||
Customize the variable, `beep-alert-sound-file' to adjust the sound."
|
Customize the variable, `beep-alert-sound-file' to adjust the sound."
|
||||||
(if (fboundp 'play-sound-internal)
|
(if (fboundp 'play-sound-internal)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ start some music to indicate we are working, and set a timer.
|
||||||
Call `ha-focus-break' when finished."
|
Call `ha-focus-break' when finished."
|
||||||
(interactive)
|
(interactive)
|
||||||
(ha-focus-countdown-timer 25 'ha-focus-break)
|
(ha-focus-countdown-timer 25 'ha-focus-break)
|
||||||
(ha-focus--command "tell application \"VLC\" to play")
|
(ha-focus--command "tell application \"Spotify\" to play")
|
||||||
(if (eq major-mode 'org-mode)
|
(if (eq major-mode 'org-mode)
|
||||||
(org-clock-in)
|
(org-clock-in)
|
||||||
(org-clock-in-last))
|
(org-clock-in-last))
|
||||||
|
|
@ -47,7 +47,7 @@ This also starts another break timer, that calls
|
||||||
`ha-focus-break-over' when finished."
|
`ha-focus-break-over' when finished."
|
||||||
(interactive)
|
(interactive)
|
||||||
(run-with-idle-timer 30 nil 'ha-focus-capture)
|
(run-with-idle-timer 30 nil 'ha-focus-capture)
|
||||||
(ha-focus--command "tell application \"VLC\" to pause")
|
(ha-focus--command "tell application \"Spotify\" to pause")
|
||||||
(ha-focus-countdown-timer 5 'ha-focus-break-over)
|
(ha-focus-countdown-timer 5 'ha-focus-break-over)
|
||||||
(message "🍅 Time to take a break."))
|
(message "🍅 Time to take a break."))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,34 +26,6 @@ A literate programming file configuring critical applications.
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Can we call the following /applications/? I guess.
|
Can we call the following /applications/? I guess.
|
||||||
* Agentic Interface
|
|
||||||
Ethic issues aside, I’m [[https://technobabble.bearblog.dev/fine-ill-try-ai/][trying AI]] … primarily because my company requires my participation. I appreciate the approaches from my fellow Emacsians, for while VSCode may be a fine editor, it can’t compete with my creation here.
|
|
||||||
** Agent Shell
|
|
||||||
Installing Xenodium’s [[https://github.com/xenodium/agent-shell][agent-shell]], requires installing the ACP libraries:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package acp
|
|
||||||
:straight (:type git :host github :repo "xenodium/acp.el"))
|
|
||||||
|
|
||||||
(use-package agent-shell
|
|
||||||
:straight (:type git :host github :repo "xenodium/agent-shell")
|
|
||||||
:after acp
|
|
||||||
|
|
||||||
:config
|
|
||||||
(ha-leader "a i" '("agent chat" . agent-shell))
|
|
||||||
|
|
||||||
;; Evil state-specific RET behavior: insert mode = newline, normal mode = send
|
|
||||||
(evil-define-key 'insert agent-shell-mode-map (kbd "RET") #'newline)
|
|
||||||
(evil-define-key 'insert agent-shell-mode-map (kbd "C-RET") #'agent-shell-submit)
|
|
||||||
(evil-define-key 'normal agent-shell-mode-map (kbd "RET") #'comint-send-input)
|
|
||||||
|
|
||||||
;; Configure *agent-shell-diff* buffers to start in Emacs state
|
|
||||||
(add-hook 'diff-mode-hook
|
|
||||||
(lambda ()
|
|
||||||
(when (string-match-p "\\*agent-shell-diff\\*" (buffer-name))
|
|
||||||
(evil-emacs-state)))))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
* Git and Magit
|
* Git and Magit
|
||||||
Can not live without [[https://magit.vc/][Magit]], a Git porcelain for Emacs. I stole the bulk of this work from Doom Emacs.
|
Can not live without [[https://magit.vc/][Magit]], a Git porcelain for Emacs. I stole the bulk of this work from Doom Emacs.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
|
@ -370,51 +342,15 @@ Let's extend Magit with [[https://github.com/magit/forge][Magit Forge]] for work
|
||||||
Every /so often/, pop over to the following URLs and generate a new token where the *Note* is =forge=, and then copy that into the [[file:~/.authinfo.gpg][~/.authinfo.gpg]]:
|
Every /so often/, pop over to the following URLs and generate a new token where the *Note* is =forge=, and then copy that into the [[file:~/.authinfo.gpg][~/.authinfo.gpg]]:
|
||||||
- [[https://gitlab.com/-/user_settings/personal_access_tokens][Gitlab]]
|
- [[https://gitlab.com/-/user_settings/personal_access_tokens][Gitlab]]
|
||||||
- [[https://github.com/settings/tokens][Github]]
|
- [[https://github.com/settings/tokens][Github]]
|
||||||
|
and make sure this works:
|
||||||
|
|
||||||
Make sure this works:
|
#+begin_src emacs-lisp :tangle no :results replace
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no :results replace
|
|
||||||
(ghub-request "GET" "/user" nil
|
(ghub-request "GET" "/user" nil
|
||||||
:forge 'github
|
:forge 'github
|
||||||
:host "api.github.com"
|
:host "api.github.com"
|
||||||
:username "howardabrams"
|
:username "howardabrams"
|
||||||
:auth 'forge)
|
:auth 'forge)
|
||||||
|
#+end_src
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Magit Github
|
|
||||||
Jonathan Chu’s [[https://github.com/jonathanchu/magit-gh][magit-gh]] project is /simpler/ than [[#Forge][Forge]] (see [[https://jonathanchu.is/posts/introducing-magit-gh/][this essay]] for details).
|
|
||||||
|
|
||||||
First, install and configure the [[https://github.com/cli/cli/blob/trunk/docs/install_macos.md#homebrew][Github CLI]] program.
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
brew install gh
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Create a =GITHUB_TOKEN= under =/settings/tokens=.
|
|
||||||
The required scopes are =repo=, =read:org=, =admin:public_key=.
|
|
||||||
Also, these don’t last long, so return and regenerate routinely.
|
|
||||||
|
|
||||||
Next, [[https://cli.github.com/manual/gh_auth_login][configure it]] with:
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
gh auth login --hostname ${GH_HOST:-github.com}
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
And pass in the =GITHUB_TOKEN= environment variable.
|
|
||||||
|
|
||||||
Verify that this works:
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
gh pr list
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
With the =gh= CLI working, we can install and use this project:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package magit-gh
|
|
||||||
:after magit
|
|
||||||
:straight (:type git :host github :repo "jonathanchu/magit-gh"))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
|
|
||||||
** Pushing is Bad
|
** Pushing is Bad
|
||||||
Pushing directly to the upstream branch is /bad form/, as one should create a pull request, etc. To prevent an accidental push, we /double-check/ first:
|
Pushing directly to the upstream branch is /bad form/, as one should create a pull request, etc. To prevent an accidental push, we /double-check/ first:
|
||||||
|
|
||||||
|
|
@ -428,11 +364,10 @@ Pushing directly to the upstream branch is /bad form/, as one should create a pu
|
||||||
(magit-get "branch" branch "remote"))))
|
(magit-get "branch" branch "remote"))))
|
||||||
(user-error "Push to upstream aborted by user"))))
|
(user-error "Push to upstream aborted by user"))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Github Search?
|
** Github Search?
|
||||||
Wanna see an example of how other’s use a particular function?
|
Wanna see an example of how other’s use a particular function?
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-github-code-search(&optional search)
|
(defun my-github-search(&optional search)
|
||||||
(interactive (list (read-string "Search: " (thing-at-point 'symbol))))
|
(interactive (list (read-string "Search: " (thing-at-point 'symbol))))
|
||||||
(let* ((language (cond ((eq major-mode 'python-mode) "Python")
|
(let* ((language (cond ((eq major-mode 'python-mode) "Python")
|
||||||
((eq major-mode 'emacs-lisp-mode) "Emacs Lisp")
|
((eq major-mode 'emacs-lisp-mode) "Emacs Lisp")
|
||||||
|
|
@ -970,5 +905,4 @@ Let's provide a name so that the file can be required:
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# eval: (add-hook 'after-save-hook #'org-babel-tangle t t)
|
# eval: (add-hook 'after-save-hook #'org-babel-tangle t t)
|
||||||
# jinx-local-words: "Emacsians VSCode"
|
|
||||||
# End:
|
# End:
|
||||||
|
|
|
||||||
107
ha-aux-apps.org
107
ha-aux-apps.org
|
|
@ -26,7 +26,7 @@ A literate programming file for helper apps in Emacs.
|
||||||
#+end_src
|
#+end_src
|
||||||
* Introduction
|
* Introduction
|
||||||
The following applications are not needed. I alternate between trying to /stay in Emacs/ taking advantage of the consistent interface, and using a stand-alone app on my Workday computer.
|
The following applications are not needed. I alternate between trying to /stay in Emacs/ taking advantage of the consistent interface, and using a stand-alone app on my Workday computer.
|
||||||
* Social Media Apps
|
* Federation
|
||||||
** Mastodon
|
** Mastodon
|
||||||
Glad to see the 2FA feature is working on the [[https://codeberg.org/martianh/mastodon.el][mastodon.el]] project, and even more glad to see the great birdland diaspora arrive in the land of the toots.
|
Glad to see the 2FA feature is working on the [[https://codeberg.org/martianh/mastodon.el][mastodon.el]] project, and even more glad to see the great birdland diaspora arrive in the land of the toots.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
|
@ -143,6 +143,19 @@ Perhaps we can make it more attractive:
|
||||||
ement-room-timestamp-format ""
|
ement-room-timestamp-format ""
|
||||||
ement-room-send-message-filter 'ement-room-send-org-filter))
|
ement-room-send-message-filter 'ement-room-send-org-filter))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
* Other
|
||||||
|
** Twitter
|
||||||
|
The venerable [[https://github.com/hayamiz/twittering-mode/tree/master][twittering-mode]] allows me to follow all the twits.
|
||||||
|
#+begin_src emacs-lisp :tangle no
|
||||||
|
(use-package twittering-mode
|
||||||
|
:init
|
||||||
|
(setq twittering-use-master-password t
|
||||||
|
epa-pinentry-mode 'loopback)
|
||||||
|
:config
|
||||||
|
(defalias 'epa--decode-coding-string 'decode-coding-string)
|
||||||
|
(ha-leader "a t" '("twitter" . twit)))
|
||||||
|
#+end_src
|
||||||
|
And we are no longer using this package.
|
||||||
** Telega
|
** Telega
|
||||||
I'm thinking the [[https://zevlg.github.io/telega.el/][Telega package]] would be better than Bitlbee for Telegram communication.
|
I'm thinking the [[https://zevlg.github.io/telega.el/][Telega package]] would be better than Bitlbee for Telegram communication.
|
||||||
|
|
||||||
|
|
@ -214,89 +227,17 @@ And my [[https://gitlab.com/howardabrams/emacs-ironsworn][new Ironsworn project]
|
||||||
#+end_src
|
#+end_src
|
||||||
The project is interesting, and I should record a tutorial how to use it.
|
The project is interesting, and I should record a tutorial how to use it.
|
||||||
* Playing Music
|
* Playing Music
|
||||||
After building a NAS out of a Raspberry Pi to hold my /ripped/ CD collection, let’s control my playlists from Emacs.
|
Why not? Let’s see if the [[https://github.com/isamert/empv.el][empv]] project is sufficient. First install =mpv=, as in:
|
||||||
A more /rich/ experience than the [[https://github.com/isamert/empv.el][empv]] project is Álvaro’s [[https://github.com/xenodium/ready-player][ready-player]]. First install [[https://mpv.io/][mpv]]:
|
#+begin_src sh
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
brew install mpv
|
brew install mpv
|
||||||
#+END_SRC
|
#+end_src
|
||||||
|
What else?
|
||||||
And make sure we can play it:
|
#+begin_src emacs-lisp
|
||||||
|
(use-package empv
|
||||||
#+BEGIN_SRC sh
|
:straight (:host github :repo "isamert/empv.el")
|
||||||
mpv "/Volumes/music/Steely Dan/Aja/01 Black Cow.mp3"
|
:general (ha-leader
|
||||||
#+END_SRC
|
"a p" '(empv-map :wk "play music")))
|
||||||
|
#+end_src
|
||||||
And stream my favorite local Jazz radio station:
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
mpv --terminal --force-window=no --no-resume-playback \
|
|
||||||
'https://ais-sa3.cdnstream1.com/2442_128.aac/playlist.m3u8' &
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
And then the configuration:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package ready-player
|
|
||||||
:straight (:type git :host github :repo "xenodium/ready-player")
|
|
||||||
:config
|
|
||||||
(when (eq system-type 'darwin)
|
|
||||||
(set-fontset-font t nil "SF Pro Display" nil 'append)
|
|
||||||
(ready-player-macos-use-sf-symbols))
|
|
||||||
|
|
||||||
(setq ready-player-my-media-collection-location "/Volumes/music")
|
|
||||||
|
|
||||||
(defun ha-ready-player-load-playlist ()
|
|
||||||
"Open a playlist in the correct location."
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory
|
|
||||||
(expand-file-name "Playlists/"
|
|
||||||
ready-player-my-media-collection-location)))
|
|
||||||
(setq ready-player-shuffle t)
|
|
||||||
(call-interactively 'ready-player-load-m3u-playlist)))
|
|
||||||
|
|
||||||
(transient-append-suffix 'ready-player-menu "?"
|
|
||||||
'("P" "Load Playlist" ha-ready-player-load-playlist))
|
|
||||||
|
|
||||||
(defun ha-ready-player-load-directory ()
|
|
||||||
"Open a directory in the correct location."
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory
|
|
||||||
(file-name-as-directory ready-player-my-media-collection-location)))
|
|
||||||
(setq ready-player-shuffle nil)
|
|
||||||
(call-interactively 'ready-player-load-directory)))
|
|
||||||
|
|
||||||
(transient-append-suffix 'ready-player-menu "d"
|
|
||||||
'("A" "Play Album" ha-ready-player-load-directory))
|
|
||||||
|
|
||||||
(ha-leader "a r" '("ready player" . ready-player-menu))
|
|
||||||
(ready-player-mode +1))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Since ready-player doesn’t support [[https://github.com/xenodium/ready-player/issues/36][adjusting the volume]], I can, at least, set the /default volume/ low enough that my speaker adjustment affects it:
|
|
||||||
|
|
||||||
#+BEGIN_SRC conf :tangle ~/.config/mpv/mpv.conf
|
|
||||||
volume=60
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Would love to have the /playing/ media in a particular tab-bar and in a particular location.
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp :tangle no
|
|
||||||
(defun ha-ready-player-switch ()
|
|
||||||
"Switch to the buffer window of the ready-player."
|
|
||||||
(interactive)
|
|
||||||
(let* ((buf-list
|
|
||||||
(seq-filter (lambda (buf)
|
|
||||||
(string-match (rx string-start "ready-player: "
|
|
||||||
(+ (not "*")) string-end)
|
|
||||||
(buffer-name buf)))
|
|
||||||
(buffer-list)))
|
|
||||||
(buffer (car buf-list))
|
|
||||||
(tab (tab-bar-get-buffer-tab (buffer-name buffer) t)))
|
|
||||||
(if tab
|
|
||||||
(tab-bar-switch-to-tab (alist-get 'name tab))
|
|
||||||
(tab-bar-switch-to-tab "main"))))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
* Technical Artifacts :noexport:
|
* Technical Artifacts :noexport:
|
||||||
Let's =provide= a name so we can =require= this file:
|
Let's =provide= a name so we can =require= this file:
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,6 @@ I’m use [[https://github.com/deseven/icanhazshortcut][ICanHazShortcut]] to hav
|
||||||
#+begin_src sh :shebang "#!/bin/bash" :tangle ~/bin/emacs-capture-clock
|
#+begin_src sh :shebang "#!/bin/bash" :tangle ~/bin/emacs-capture-clock
|
||||||
/usr/bin/osascript ~/bin/emacs-capture-clock.scr
|
/usr/bin/osascript ~/bin/emacs-capture-clock.scr
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
But the following Applescript does the work:
|
But the following Applescript does the work:
|
||||||
#+begin_src applescript :sheband "#!/usr/bin/osascript" :tangle ~/bin/emacs-capture-clock.scr
|
#+begin_src applescript :sheband "#!/usr/bin/osascript" :tangle ~/bin/emacs-capture-clock.scr
|
||||||
tell application "System Events" to set theApp to name of first application process whose frontmost is true
|
tell application "System Events" to set theApp to name of first application process whose frontmost is true
|
||||||
|
|
@ -274,7 +273,6 @@ Now we have some goodies on the clipboard, and the script uses =emacsclient= to
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
(delete-frame)))
|
(delete-frame)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Oh, and it this is from the Terminal program, let’s wrap it in a block:
|
Oh, and it this is from the Terminal program, let’s wrap it in a block:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-external-capture-code-to-org ()
|
(defun ha-external-capture-code-to-org ()
|
||||||
|
|
@ -290,10 +288,136 @@ Oh, and it this is from the Terminal program, let’s wrap it in a block:
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
(delete-frame)))
|
(delete-frame)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
#+begin_src conf :tangle ~/.config/iCanHazShortcut/config.ini
|
||||||
|
[main]
|
||||||
|
config version = 2
|
||||||
|
shell = /bin/bash -l
|
||||||
|
populate_menu_with_actions = yes
|
||||||
|
show_hotkeys_in_menu = yes
|
||||||
|
check_for_updates = yes
|
||||||
|
start_on_login = yes
|
||||||
|
show_icon_in_statusbar = yes
|
||||||
|
set_workdir_with_cd = no
|
||||||
|
window_x = -988
|
||||||
|
window_y = 172
|
||||||
|
window_width = 600
|
||||||
|
window_height = 361
|
||||||
|
shortcut_column_enabled = yes
|
||||||
|
action_column_enabled = yes
|
||||||
|
command_column_enabled = yes
|
||||||
|
workdir_column_enabled = no
|
||||||
|
shortcut_column_width = 80
|
||||||
|
action_column_width = 160
|
||||||
|
command_column_width = 173
|
||||||
|
workdir_column_width = 100
|
||||||
|
|
||||||
|
[shortcut1]
|
||||||
|
shortcut = ⇧⌃⌥⌘E
|
||||||
|
action = Personal Emacs
|
||||||
|
command = open -a Emacs
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut2]
|
||||||
|
shortcut = ⇧⌃⌥E
|
||||||
|
action = Work Emacs
|
||||||
|
command = FOR_WORK=yes open -a Emacs-Work
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut3]
|
||||||
|
shortcut = ⇧⌃⌥⌘X
|
||||||
|
action = Emacs Capture
|
||||||
|
command = ~/bin/emacs-capture
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut4]
|
||||||
|
shortcut = ⇧⌃⌥X
|
||||||
|
action = Emacs Capture Clipboard
|
||||||
|
command = ~/bin/emacs-capture-clock
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut5]
|
||||||
|
shortcut = ⇧⌃⌥T
|
||||||
|
action = iTerm
|
||||||
|
command = open -a iTerm
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut6]
|
||||||
|
shortcut = ⇧⌃⌥S
|
||||||
|
action = Slack
|
||||||
|
command = open -a Slack
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut7]
|
||||||
|
shortcut = ⇧⌃⌥W
|
||||||
|
action = Spotify
|
||||||
|
command = open -a Spotify
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut8]
|
||||||
|
shortcut = ⇧⌃⌥F
|
||||||
|
action = Firefox
|
||||||
|
command = open -a Firefox
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut9]
|
||||||
|
shortcut = ⇧⌃⌥C
|
||||||
|
action = Chome
|
||||||
|
command = ~/bin/chrome.scr
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut10]
|
||||||
|
shortcut = ⇧⌃⌥Q
|
||||||
|
action = Keepass
|
||||||
|
command = open -a KeepassXC
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut11]
|
||||||
|
shortcut = ⇧⌃⌥Z
|
||||||
|
action = Zoom
|
||||||
|
command = open -a zoom.us
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut12]
|
||||||
|
shortcut = ⌃F1
|
||||||
|
action = Mute Zoom
|
||||||
|
command = ~/bin/zoom-muter
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut13]
|
||||||
|
shortcut = ⇧⌃⌥⌘M
|
||||||
|
action = Capture Meeting
|
||||||
|
command = ~/bin/emacs-capture-meeting
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut14]
|
||||||
|
shortcut = ⇧⌃⌥⌘B
|
||||||
|
action = Outlook
|
||||||
|
command = open -a "Microsoft Outlook"
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
|
||||||
|
[shortcut15]
|
||||||
|
shortcut = ⇧⌃⌥⌘D
|
||||||
|
action = Discord
|
||||||
|
command = open -a Discord
|
||||||
|
workdir =
|
||||||
|
enabled = yes
|
||||||
|
#+end_src
|
||||||
Configure the *ICanHazShortcut* shortcuts to call these scripts, as in this screenshot:
|
Configure the *ICanHazShortcut* shortcuts to call these scripts, as in this screenshot:
|
||||||
[[file:screenshots/icanhazshortcuts.png]]
|
[[file:screenshots/icanhazshortcuts.png]]
|
||||||
|
|
||||||
And here is the configuration file for that:
|
And here is the configuration file for that:
|
||||||
#+begin_src conf :tangle ~/.config/iCanHazShortcut/config.ini :mkdirp yes
|
#+begin_src conf :tangle ~/.config/iCanHazShortcut/config.ini :mkdirp yes
|
||||||
[main]
|
[main]
|
||||||
|
|
|
||||||
|
|
@ -164,20 +164,16 @@ I’ve often called =imenu= to easily jump to a function definition in a file (o
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-imenu-setup ()
|
(defun ha-imenu-setup ()
|
||||||
"Set up the imenu customization. Use in hooks."
|
"Set up the imenu customization. Use in hooks."
|
||||||
(condition-case err
|
(ignore-errors
|
||||||
(imenu-add-menubar-index)
|
(imenu-add-menubar-index)
|
||||||
(setq-local imenu-auto-rescan t)
|
(setq-local imenu-auto-rescan t)
|
||||||
(when (derived-mode-p 'prog-mode)
|
(when (derived-mode-p 'prog-mode)
|
||||||
(setq-local imenu-sort-function 'imenu--sort-by-name))
|
(setq-local imenu-sort-function 'imenu--sort-by-name))))
|
||||||
|
|
||||||
(imenu-unavailable
|
|
||||||
(let ((inhibit-message t))
|
|
||||||
(message "Warning: %s" (error-message-string err))))))
|
|
||||||
|
|
||||||
(add-hook 'org-mode-hook 'ha-imenu-setup)
|
(add-hook 'org-mode-hook 'ha-imenu-setup)
|
||||||
(add-hook 'markdown-mode-hook 'ha-imenu-setup)
|
(add-hook 'markdown-mode-hook 'ha-imenu-setup)
|
||||||
(add-hook 'makefile-mode-hook 'ha-imenu-setup)
|
|
||||||
(add-hook 'prog-mode-hook 'ha-imenu-setup)
|
(add-hook 'prog-mode-hook 'ha-imenu-setup)
|
||||||
|
(add-hook 'makefile-mode-hook 'ha-imenu-setup)
|
||||||
#+end_src
|
#+end_src
|
||||||
** File Access
|
** File Access
|
||||||
*** Remote Files
|
*** Remote Files
|
||||||
|
|
@ -809,37 +805,6 @@ If you hit the following keys /before/ you select a target, you get special acti
|
||||||
- ~z~ :: =zap-to-char= … kill from current point to the target
|
- ~z~ :: =zap-to-char= … kill from current point to the target
|
||||||
I’m not thinking of ideas of what would be useful, e.g. ~v~ to highlight from cursor to target, etc.
|
I’m not thinking of ideas of what would be useful, e.g. ~v~ to highlight from cursor to target, etc.
|
||||||
|
|
||||||
What is missing is copying the entire line:
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package avy
|
|
||||||
:config
|
|
||||||
(defun avy-action-copy-whole-line (pt)
|
|
||||||
(save-excursion
|
|
||||||
(goto-char pt)
|
|
||||||
(cl-destructuring-bind (start . end)
|
|
||||||
(bounds-of-thing-at-point 'line)
|
|
||||||
(copy-region-as-kill start end)))
|
|
||||||
(select-window
|
|
||||||
(cdr
|
|
||||||
(ring-ref avy-ring 0)))
|
|
||||||
t)
|
|
||||||
|
|
||||||
(defun avy-action-copy-rest-line (pt)
|
|
||||||
(save-excursion
|
|
||||||
(goto-char pt)
|
|
||||||
(let ((start pt)
|
|
||||||
(end (line-end-position)))
|
|
||||||
(copy-region-as-kill start end)))
|
|
||||||
(select-window
|
|
||||||
(cdr
|
|
||||||
(ring-ref avy-ring 0)))
|
|
||||||
t)
|
|
||||||
|
|
||||||
(setf (alist-get ?w avy-dispatch-alist) 'avy-action-copy
|
|
||||||
(alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line
|
|
||||||
(alist-get ?N avy-dispatch-alist) 'avy-action-copy-rest-line))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Want to know something amazing. In a Terminal, like =vterm= or =eshell=, I run ~s-g~ and pinpoint the UUID in the output of a long command. Then type ~y~ and then ~C-y~ to paste that ID without even moving the mouse.
|
Want to know something amazing. In a Terminal, like =vterm= or =eshell=, I run ~s-g~ and pinpoint the UUID in the output of a long command. Then type ~y~ and then ~C-y~ to paste that ID without even moving the mouse.
|
||||||
*** Link Hint, the Link Jumper
|
*** Link Hint, the Link Jumper
|
||||||
The [[info:emacs#Goto Address mode][Goto Address]] mode (see this [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Goto-Address-mode.html][online link]]) turns URLs into clickable links. Nice feature and built into Emacs, but it requires using the mouse or moving to the URL and hitting ~Return~ (if you like this idea, check out [[https://xenodium.com/actionable-urls-in-emacs-buffers/][Álvaro Ramírez's configuration]] for this).
|
The [[info:emacs#Goto Address mode][Goto Address]] mode (see this [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Goto-Address-mode.html][online link]]) turns URLs into clickable links. Nice feature and built into Emacs, but it requires using the mouse or moving to the URL and hitting ~Return~ (if you like this idea, check out [[https://xenodium.com/actionable-urls-in-emacs-buffers/][Álvaro Ramírez's configuration]] for this).
|
||||||
|
|
@ -991,6 +956,7 @@ Since I wasn’t using all the features that [[https://github.com/bbatsov/projec
|
||||||
:config
|
:config
|
||||||
(ha-leader
|
(ha-leader
|
||||||
"p" '(:ignore t :which-key "projects")
|
"p" '(:ignore t :which-key "projects")
|
||||||
|
"p W" '("initialize workspace" . ha-workspace-initialize)
|
||||||
"p p" '("switch project" . ha-tab-bar-new-project)
|
"p p" '("switch project" . ha-tab-bar-new-project)
|
||||||
|
|
||||||
"p !" '("run cmd in project root" . project-shell-command)
|
"p !" '("run cmd in project root" . project-shell-command)
|
||||||
|
|
@ -1022,8 +988,9 @@ Couple notes:
|
||||||
tab-bar-close-button-show nil ; hide tab close / X button
|
tab-bar-close-button-show nil ; hide tab close / X button
|
||||||
tab-bar-new-tab-choice "*dashboard*" ; buffer to show in new tabs
|
tab-bar-new-tab-choice "*dashboard*" ; buffer to show in new tabs
|
||||||
tab-bar-tab-hints t ; show tab numbers
|
tab-bar-tab-hints t ; show tab numbers
|
||||||
tab-bar-separator " "
|
|
||||||
tab-bar-button-relief 0
|
tab-bar-button-relief 0
|
||||||
|
tab-bar-button-margin '(40 . 1)
|
||||||
|
|
||||||
;; Jump to a tab by numbers (see the keybindings set later):
|
;; Jump to a tab by numbers (see the keybindings set later):
|
||||||
tab-bar-select-tab-modifiers '(super control))
|
tab-bar-select-tab-modifiers '(super control))
|
||||||
|
|
@ -1040,8 +1007,8 @@ New workspace is a tab with a specific name that opens up a specific buffer or a
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-tab-bar-new (name &optional bff)
|
(defun ha-tab-bar-new (name &optional bff)
|
||||||
"Create a new tab with a NAME.
|
"Create a new tab with a NAME.
|
||||||
With a non-nil BFF, call BFF as a function or switch
|
With a non-nil IFF, call IFF as a function or switch
|
||||||
to the BFF buffer or the files listed."
|
to the IFF buffer or the files listed."
|
||||||
(interactive "sWorkspace Name: ")
|
(interactive "sWorkspace Name: ")
|
||||||
(tab-bar-switch-to-tab name)
|
(tab-bar-switch-to-tab name)
|
||||||
(when bff
|
(when bff
|
||||||
|
|
@ -1091,20 +1058,9 @@ If we close a tab that is a project, we want to close all the buffers associated
|
||||||
(buffer-list)))
|
(buffer-list)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
And let’s make one tab to be /special/:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(defun ha-switch-to-special ()
|
|
||||||
"Change the perspective to the Sprint/Notes project."
|
|
||||||
(interactive)
|
|
||||||
(tab-bar-switch-to-tab "main"))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
And some shortcut keys from the =general= project:
|
And some shortcut keys from the =general= project:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(use-package emacs
|
|
||||||
:config
|
|
||||||
(general-nmap :prefix "SPC"
|
(general-nmap :prefix "SPC"
|
||||||
"<tab>" '(:ignore t :which-key "workspaces")
|
"<tab>" '(:ignore t :which-key "workspaces")
|
||||||
"<tab> <tab>" '("switch" . tab-switch)
|
"<tab> <tab>" '("switch" . tab-switch)
|
||||||
|
|
@ -1112,15 +1068,13 @@ And some shortcut keys from the =general= project:
|
||||||
"<tab> n" '("new space" . ha-tab-bar-new)
|
"<tab> n" '("new space" . ha-tab-bar-new)
|
||||||
"<tab> u" '("update names" . ha-tab-bar-update-names)
|
"<tab> u" '("update names" . ha-tab-bar-update-names)
|
||||||
"<tab> d" '("delete space" . ha-tab-bar-delete)
|
"<tab> d" '("delete space" . ha-tab-bar-delete)
|
||||||
"<tab> t" '("toggle tab-bar" . tab-bar-mode)
|
|
||||||
"<tab> w" '("special space" . ha-switch-to-special)
|
|
||||||
"<tab> `" '("recent" . tab-bar-switch-to-recent-tab))
|
"<tab> `" '("recent" . tab-bar-switch-to-recent-tab))
|
||||||
|
|
||||||
(global-set-key (kbd "s-C-t") 'ha-tab-bar-new)
|
(global-set-key (kbd "s-C-t") 'ha-tab-bar-new)
|
||||||
(global-set-key (kbd "s-C-[") 'tab-bar-switch-to-prev-tab)
|
(global-set-key (kbd "s-C-[") 'tab-bar-switch-to-prev-tab)
|
||||||
(global-set-key (kbd "s-C-]") 'tab-bar-switch-to-next-tab)
|
(global-set-key (kbd "s-C-]") 'tab-bar-switch-to-next-tab)
|
||||||
|
|
||||||
(tab-bar-mode 1))
|
(tab-bar-mode 1)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
I want to quickly jump, by the number shown on the tab, to that grouping. The following two functions create leader sequences with the name of the tab group:
|
I want to quickly jump, by the number shown on the tab, to that grouping. The following two functions create leader sequences with the name of the tab group:
|
||||||
|
|
@ -1224,6 +1178,24 @@ First, create a variable that contains the Unicode values for the numbers. I am
|
||||||
And then use this function to replace the standard =tab-bar-tab-name-format-function=:
|
And then use this function to replace the standard =tab-bar-tab-name-format-function=:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun ha/tab-bar-tab-name-format-default (tab i)
|
||||||
|
"Replacement for `tab-bar-tab-name-format-function'.
|
||||||
|
Places a special symbol for the initial digit."
|
||||||
|
(let ((current-p (eq (car tab) 'current-tab))
|
||||||
|
(tab-num (if (and tab-bar-tab-hints (< i 10))
|
||||||
|
(alist-get i ha/circle-numbers-alist) "")))
|
||||||
|
(propertize
|
||||||
|
(concat tab-num
|
||||||
|
" "
|
||||||
|
(alist-get 'name tab)
|
||||||
|
(or (and tab-bar-close-button-show
|
||||||
|
(not (eq tab-bar-close-button-show
|
||||||
|
(if current-p 'non-selected 'selected)))
|
||||||
|
tab-bar-close-button)
|
||||||
|
"")
|
||||||
|
" ")
|
||||||
|
'face (funcall tab-bar-tab-face-function tab))))
|
||||||
|
|
||||||
(defun ha/tab-bar-tab-name-format-default (tab i)
|
(defun ha/tab-bar-tab-name-format-default (tab i)
|
||||||
"Replacement for `tab-bar-tab-name-format-function'.
|
"Replacement for `tab-bar-tab-name-format-function'.
|
||||||
Places a special symbol for the initial digit."
|
Places a special symbol for the initial digit."
|
||||||
|
|
@ -1233,12 +1205,10 @@ And then use this function to replace the standard =tab-bar-tab-name-format-fun
|
||||||
(propertize
|
(propertize
|
||||||
(if (and tab-bar-tab-hints (< i 10)) (alist-get i ha/circle-numbers-alist) "")
|
(if (and tab-bar-tab-hints (< i 10)) (alist-get i ha/circle-numbers-alist) "")
|
||||||
'face 'ha/tab-bar-numbers)
|
'face 'ha/tab-bar-numbers)
|
||||||
;; Fixed-width gap so active (variable-pitch) and inactive tabs match
|
|
||||||
(propertize " " 'face 'tab-bar)
|
|
||||||
;; Add tab name with the face returned by tab-bar-tab-face-function
|
;; Add tab name with the face returned by tab-bar-tab-face-function
|
||||||
(propertize
|
(propertize
|
||||||
(concat
|
(concat
|
||||||
" "
|
" " ; Add initial space
|
||||||
(alist-get 'name tab)
|
(alist-get 'name tab)
|
||||||
(or (and tab-bar-close-button-show
|
(or (and tab-bar-close-button-show
|
||||||
(not (eq tab-bar-close-button-show
|
(not (eq tab-bar-close-button-show
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,8 @@ To make the active window /more noticeable/, we /dim/ the in-active windows with
|
||||||
As an interesting alternative, check out the [[https://www.emacs.dyerdwelling.family/emacs/20240208164549-emacs-selected-window-accent-mode-now-on-melpa/][selected-window-accent]] project.
|
As an interesting alternative, check out the [[https://www.emacs.dyerdwelling.family/emacs/20240208164549-emacs-selected-window-accent-mode-now-on-melpa/][selected-window-accent]] project.
|
||||||
** Ultra Scroll
|
** Ultra Scroll
|
||||||
|
|
||||||
The [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]] project allows smoother scrolling of text and images. While this splits text at the top/bottom of buffer windows, we no longer work within a 80x24 text matrix. Large images would either be "there or not" which resulted large jumps and large distractions.
|
The [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]] project allows smoother scrolling of text and images. While this splits text at the top/bottom of buffer windows, we no longer work within a 80x24 text matrix. Large images would
|
||||||
|
either be "there or not" which resulted large jumps and large distractions.
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(use-package ultra-scroll
|
(use-package ultra-scroll
|
||||||
|
|
@ -88,45 +89,16 @@ The [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]] project allows sm
|
||||||
(ultra-scroll-mode 1))
|
(ultra-scroll-mode 1))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
** Find the Bloody Cursor
|
** Find the Bloody Cursor
|
||||||
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, Sacha Chua’s [[https://fediscience.org/@ericsfraga/116279043710841253][suggestion]] solves the problem of the built-in =hl-line= that /highlights paragraphs/ in Org with a single function:
|
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F8~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(defun get-visual-line-range ()
|
|
||||||
"Identify current visual line (for highlighting mostly)
|
|
||||||
|
|
||||||
Use the visual line functions to define the range in the buffer
|
|
||||||
that should be highlighted when ~hl-line-mode~ is enabled. By
|
|
||||||
default, the whole line in the file is highlighted. This is not
|
|
||||||
particularly useful in org files where I have whole paragraphs in a
|
|
||||||
single file line."
|
|
||||||
(let (b e)
|
|
||||||
(save-excursion
|
|
||||||
(beginning-of-visual-line)
|
|
||||||
(setq b (point))
|
|
||||||
(end-of-visual-line)
|
|
||||||
(setq e (point)))
|
|
||||||
(cons b e)))
|
|
||||||
|
|
||||||
(setq hl-line-range-function #'get-visual-line-range)
|
|
||||||
|
|
||||||
(global-hl-line-mode 1)
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
The real trick should /visually/ highlight the current line without being too light and interfering with seeing the text or being too obnoxious (see my [[file:ha-theme.org::*Dark Theme][Dark Theme]]).
|
|
||||||
|
|
||||||
I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F8~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package pulsar
|
(use-package pulsar
|
||||||
:straight (:host github :repo "protesilaos/pulsar")
|
:straight (:host github :repo "protesilaos/pulsar")
|
||||||
:after winum ace-window
|
|
||||||
:custom
|
:custom
|
||||||
(pulsar-face 'pulsar-generic)
|
(pulsar-face 'pulsar-generic)
|
||||||
(pulsar-delay 0.15)
|
(pulsar-delay 0.15)
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(set-face-attribute 'pulsar-generic nil :background "orange")
|
|
||||||
|
|
||||||
(dolist (built-in-function '(recenter-top-bottom move-to-window-line-top-bottom reposition-window
|
(dolist (built-in-function '(recenter-top-bottom move-to-window-line-top-bottom reposition-window
|
||||||
bookmark-jump other-window delete-window delete-other-windows
|
bookmark-jump other-window delete-window delete-other-windows
|
||||||
forward-page backward-page scroll-up-command scroll-down-command
|
forward-page backward-page scroll-up-command scroll-down-command
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ I split the configuration of Evil mode into sections. First, global settings:
|
||||||
evil-want-keybinding nil ; work with evil-collection
|
evil-want-keybinding nil ; work with evil-collection
|
||||||
evil-want-integration t
|
evil-want-integration t
|
||||||
evil-want-C-u-scroll nil
|
evil-want-C-u-scroll nil
|
||||||
evil-want-C-i-jump nil))
|
evil-want-C-i-jump nil
|
||||||
|
evil-escape-key-sequence "jk"
|
||||||
|
evil-escape-unordered-key-sequence t))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The Escape key act like ~C-g~ and always go back to normal mode?
|
The Escape key act like ~C-g~ and always go back to normal mode?
|
||||||
|
|
@ -197,7 +199,7 @@ I find that myself not noticing I’m in /insert/ mode, and start typing =j= rep
|
||||||
|
|
||||||
To remedy this, I’m using the [[https://www.emacswiki.org/emacs/KeyChord][KeyChord]] code:
|
To remedy this, I’m using the [[https://www.emacswiki.org/emacs/KeyChord][KeyChord]] code:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp :tangle no
|
||||||
(use-package key-chord
|
(use-package key-chord
|
||||||
:config
|
:config
|
||||||
(setq key-chord-two-keys-delay 0.1)
|
(setq key-chord-two-keys-delay 0.1)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ Each year, specify the first day of the first sprint of the year:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
;; CHANGEME Each year as this should update:
|
;; CHANGEME Each year as this should update:
|
||||||
(defvar sprint-start-date (get-date-time "2026-01-06")
|
(defvar sprint-start-date (get-date-time "2026-01-13")
|
||||||
"The date of the first day of the first sprint of the year.
|
"The date of the first day of the first sprint of the year.
|
||||||
See `sprint-range'.")
|
See `sprint-range'.")
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
@ -301,20 +301,15 @@ My company has sprints two weeks long that we can calculate from
|
||||||
The number of the sprint comes from the number of /bi-weeks/ (14 day increments) from the =sprint-start-date=. We can calculate the number of seconds from this /start date/ and divide it by the =sprint-length=:
|
The number of the sprint comes from the number of /bi-weeks/ (14 day increments) from the =sprint-start-date=. We can calculate the number of seconds from this /start date/ and divide it by the =sprint-length=:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun sprint-number (&optional date)
|
(defun sprint-number (date)
|
||||||
"Return the number of 14-day intervals since SPRINT-START-DATE to DATE.
|
"Return the number of 14-day intervals since SPRINT-START-DATE to DATE.
|
||||||
DATE is a string in YYYY-MM-DD format."
|
DATE is a string in YYYY-MM-DD format."
|
||||||
(unless date
|
|
||||||
(setq date (format-time-string "%Y-%m-%d")))
|
|
||||||
|
|
||||||
(let* ((end-time (get-date-time date))
|
(let* ((end-time (get-date-time date))
|
||||||
(diff-seconds (float-time (time-subtract end-time sprint-start-date))))
|
(diff-seconds (float-time (time-subtract end-time sprint-start-date))))
|
||||||
|
|
||||||
;; After calculating the number of 'bi-weeks' (2 week sprint increments),
|
;; After calculating the number of 'bi-weeks' (2 week sprint increments),
|
||||||
;; we add one to return the correct sprint for the networking team:
|
;; we add one to return the correct sprint:
|
||||||
;; (1+ (floor (/ diff-seconds sprint-length)))
|
(1+ (floor (/ diff-seconds sprint-length)))))
|
||||||
;; Or for the platform storage team:
|
|
||||||
(1+ (* 2 (floor (/ diff-seconds sprint-length))))))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
And some tests to verify that:
|
And some tests to verify that:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#+date: 2020-09-18
|
#+date: 2020-09-18
|
||||||
#+tags: emacs org
|
#+tags: emacs org
|
||||||
#+startup: inlineimages
|
#+startup: inlineimages
|
||||||
#+lastmod: [2026-04-08 Wed]
|
#+lastmod: [2025-12-02 Tue]
|
||||||
|
|
||||||
A literate programming file for configuring org-mode and those files.
|
A literate programming file for configuring org-mode and those files.
|
||||||
|
|
||||||
|
|
@ -1022,8 +1022,8 @@ Next, create a configuration file, =~/.config/proselint/config= file, to turn on
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
And tell [[https://www.flycheck.org/][flycheck]] to use Proselint:
|
And tell [[https://www.flycheck.org/][flycheck]] to use this:
|
||||||
#+begin_src emacs-lisp :tangle no
|
#+begin_src emacs-lisp
|
||||||
(use-package flycheck
|
(use-package flycheck
|
||||||
:config
|
:config
|
||||||
(add-to-list 'flycheck-checkers 'proselint)
|
(add-to-list 'flycheck-checkers 'proselint)
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,8 @@ While Emacs supplies a Python editing environment, we’ll still use =use-packag
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package python
|
(use-package python
|
||||||
:after flycheck
|
:after flycheck
|
||||||
:mode (((rx ".flake8" eol) . conf-mode)
|
:mode ("[./]flake8\\'" . conf-mode)
|
||||||
((rx "Pipfile" eol) . conf-mode)
|
:mode ("/Pipfile\\'" . conf-mode)
|
||||||
((rx ".wsgi" eol) . python-mode))
|
|
||||||
:init
|
:init
|
||||||
(setq python-indent-guess-indent-offset-verbose nil
|
(setq python-indent-guess-indent-offset-verbose nil
|
||||||
flycheck-flake8-maximum-line-length 120)
|
flycheck-flake8-maximum-line-length 120)
|
||||||
|
|
@ -333,13 +332,6 @@ The [[https://elpy.readthedocs.io/en/latest/introduction.html][Elpy Project]] ex
|
||||||
(setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))
|
(setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
Elpy uses its *own* virtual environment for its backend process (jedi, rope, etc.), keeping elpy's own dependencies out of your project venvs. While there is a [[help:elpy-rpc-reinstall-virtualenv][elpy-rpc-reinstall-virtualenv]] function, I find it doesn’t seem to install everything correctly, and I need to do this by hand:
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
source ~/.emacs.d/elpy/rpc-venv/bin/activate
|
|
||||||
pip install jedi black flake8 ipython
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
After we’ve loaded the Company section, we can add jedi to the list of completions:
|
After we’ve loaded the Company section, we can add jedi to the list of completions:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
|
|
||||||
|
|
@ -138,10 +138,10 @@ I appreciate calling =hi-lock-face-symbol-at-point= (or =highlight-symbol-at-poi
|
||||||
:config
|
:config
|
||||||
(setq ahs-idle-interval 0.1)
|
(setq ahs-idle-interval 0.1)
|
||||||
|
|
||||||
(set-face-attribute ahs-face nil :foreground 'unspecified :background 'unspecified
|
(set-face-attribute ahs-face nil :foreground nil :background nil
|
||||||
:weight 'ultra-bold :slant 'italic)
|
:weight 'ultra-bold :slant 'italic)
|
||||||
(set-face-attribute ahs-plugin-default-face nil :foreground 'unspecified
|
(set-face-attribute ahs-plugin-default-face nil :foreground nil
|
||||||
:background 'unspecified :weight 'bold :slant 'normal))
|
:background nil :weight 'bold :slant 'normal))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Instead of calling =global-auto-highlight-symbol-mode=, we should just hook it to the =prog-mode=:
|
Instead of calling =global-auto-highlight-symbol-mode=, we should just hook it to the =prog-mode=:
|
||||||
|
|
@ -370,7 +370,7 @@ Normally, you would need to add all the projects to directory clones in =~/src=
|
||||||
https://github.com/tree-sitter/tree-sitter-go
|
https://github.com/tree-sitter/tree-sitter-go
|
||||||
https://github.com/tree-sitter/tree-sitter-javascript
|
https://github.com/tree-sitter/tree-sitter-javascript
|
||||||
https://github.com/tree-sitter/tree-sitter-templ
|
https://github.com/tree-sitter/tree-sitter-templ
|
||||||
https://github.com/tree-sitter-grammars/tree-sitter-yaml
|
https://github.com/ikatyang/tree-sitter-yaml
|
||||||
https://github.com/tree-sitter/tree-sitter-json
|
https://github.com/tree-sitter/tree-sitter-json
|
||||||
https://github.com/tree-sitter/tree-sitter-css
|
https://github.com/tree-sitter/tree-sitter-css
|
||||||
https://github.com/tree-sitter/tree-sitter-python
|
https://github.com/tree-sitter/tree-sitter-python
|
||||||
|
|
@ -422,7 +422,7 @@ In most cases,the =npm install= /usually/ works, but I may work on some sort of
|
||||||
#+end_src
|
#+end_src
|
||||||
At this point, we can now parse stuff using: =tree-sitter parse <source-code-file>=
|
At this point, we can now parse stuff using: =tree-sitter parse <source-code-file>=
|
||||||
**** Emacs Part
|
**** Emacs Part
|
||||||
Note that Emacs already has the ability to download and install grammars, so following instructions from Mickey Petersen’s essay on [[https://www.masteringemacs.org/article/combobulate-structured-movement-editing-treesitter][using Tree-sitter with Combobulate]]:
|
However, Emacs already has the ability to download and install grammars, so following instructions from Mickey Petersen’s essay on [[https://www.masteringemacs.org/article/combobulate-structured-movement-editing-treesitter][using Tree-sitter with Combobulate]]:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(when (treesit-available-p)
|
(when (treesit-available-p)
|
||||||
(use-package treesit
|
(use-package treesit
|
||||||
|
|
@ -460,7 +460,7 @@ Note that Emacs already has the ability to download and install grammars, so fol
|
||||||
(toml "https://github.com/tree-sitter/tree-sitter-toml")
|
(toml "https://github.com/tree-sitter/tree-sitter-toml")
|
||||||
;; (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
|
;; (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
|
||||||
;; (typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
|
;; (typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
|
||||||
(yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml")))
|
(yaml "https://github.com/ikatyang/tree-sitter-yaml")))
|
||||||
|
|
||||||
(defun mp-setup-install-grammars ()
|
(defun mp-setup-install-grammars ()
|
||||||
"Install Tree-sitter grammars if they are absent."
|
"Install Tree-sitter grammars if they are absent."
|
||||||
|
|
|
||||||
|
|
@ -50,19 +50,16 @@ Will Schenk has [[https://willschenk.com/articles/2020/tramp_tricks/][a simple e
|
||||||
(tramp-remote-shell-args ("-i") ("-c"))))
|
(tramp-remote-shell-args ("-i") ("-c"))))
|
||||||
tramp-methods)
|
tramp-methods)
|
||||||
|
|
||||||
(defun ha-tramp-completion-docker (orig-fun &rest args)
|
(defadvice tramp-completion-handle-file-name-all-completions
|
||||||
"Advice for `tramp-completion-handle-file-name-all-completions`.
|
(around dotemacs-completion-docker activate)
|
||||||
Return active Docker container names when completing for `/docker:`."
|
"(tramp-completion-handle-file-name-all-completions \"\" \"/docker:\" returns
|
||||||
(if (equal (nth 1 args) "/docker:")
|
a list of active Docker container names, followed by colons."
|
||||||
|
(if (equal (ad-get-arg 1) "/docker:")
|
||||||
(let* ((command "docker ps --format '{{.Names}}:'")
|
(let* ((command "docker ps --format '{{.Names}}:'")
|
||||||
(dockernames-raw (shell-command-to-string command))
|
(dockernames-raw (shell-command-to-string command))
|
||||||
(dockernames (split-string dockernames-raw "\n" t)))
|
(dockernames (split-string dockernames-raw "\n")))
|
||||||
dockernames)
|
(setq ad-return-value dockernames))
|
||||||
;; Call the original function
|
ad-do-it)))
|
||||||
(apply orig-fun args)))
|
|
||||||
|
|
||||||
(advice-add 'tramp-completion-handle-file-name-all-completions
|
|
||||||
:around #'ha-tramp-completion-docker))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Keep in mind you need to /name/ your Docker session, with the =—name= option. I actually do more docker work on remote systems (as Docker seems to make my fans levitate my laptop over the desk). Granted, the =URL= is a bit lengthy, for instance:
|
Keep in mind you need to /name/ your Docker session, with the =—name= option. I actually do more docker work on remote systems (as Docker seems to make my fans levitate my laptop over the desk). Granted, the =URL= is a bit lengthy, for instance:
|
||||||
|
|
@ -157,26 +154,6 @@ VTerm has an issue (at least for me) with ~M-Backspace~ not deleting the previou
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The advantage of running terminals in Emacs is the ability to copy text without a mouse. For that, hit ~C-c C-t~ to enter a special copy-mode. If I go into this mode, I might as well also go into normal mode to move the cursor. To exit the copy-mode (and copy the selected text to the clipboard), hit ~Return~.
|
The advantage of running terminals in Emacs is the ability to copy text without a mouse. For that, hit ~C-c C-t~ to enter a special copy-mode. If I go into this mode, I might as well also go into normal mode to move the cursor. To exit the copy-mode (and copy the selected text to the clipboard), hit ~Return~.
|
||||||
|
|
||||||
An odd use case I have: working in a Terminal session in one buffer window, and reading instructions in another. I want to copy commands from the document into the session using Avy to mark the command. Normally, I would use ~s-g~ to call [[file:ha-config.org::*Jump with Avy][avy-goto-char-timer]], and typing the /beginning of the command/, but before /jumping/, I press ~N~ to copy the line into the clipboard (kill-ring), and then /paste/ that into the Terminal using ~C-y~. One-too-many keystrokes.
|
|
||||||
|
|
||||||
Now, I can type: ~s-G~ (with the shift), select the line with Avy, and type ~N~ to have it copy/paste into the buffer:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package vterm
|
|
||||||
:config
|
|
||||||
(defun ha-vterm-avy-paste-line ()
|
|
||||||
"docstring"
|
|
||||||
(interactive)
|
|
||||||
(let ((buf (current-buffer)))
|
|
||||||
(call-interactively 'avy-goto-char-timer)
|
|
||||||
|
|
||||||
(when (equal buf (current-buffer))
|
|
||||||
(vterm-yank))))
|
|
||||||
|
|
||||||
(general-def 'vterm-mode-map "s-G" 'ha-vterm-avy-paste-line))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Eat
|
** Eat
|
||||||
While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[https://codeberg.org/akib/emacs-eat][Emulate a Terminal]] project (eat) is fast enough, and doesn’t require a dedicate library that requires re-compilation. While offering [[https://elpa.nongnu.org/nongnu-devel/doc/eat.html][online documentation]], I’m glad for an [[info:eat#Top][Info version]].
|
While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[https://codeberg.org/akib/emacs-eat][Emulate a Terminal]] project (eat) is fast enough, and doesn’t require a dedicate library that requires re-compilation. While offering [[https://elpa.nongnu.org/nongnu-devel/doc/eat.html][online documentation]], I’m glad for an [[info:eat#Top][Info version]].
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -325,16 +325,15 @@ Let’s make a /theme/:
|
||||||
`(window-divider ((t :foreground "black")))
|
`(window-divider ((t :foreground "black")))
|
||||||
`(cursor ((t (:foreground ,gray-10 :background ,cursor))))
|
`(cursor ((t (:foreground ,gray-10 :background ,cursor))))
|
||||||
`(region ((t (:background ,region))))
|
`(region ((t (:background ,region))))
|
||||||
`(hl-line ((t (:background ,gray-20))))
|
|
||||||
|
|
||||||
`(mode-line ((t (:background ,active :foreground "white"))))
|
`(mode-line ((t (:background ,active :foreground "white"))))
|
||||||
`(mode-line-active ((t (:background ,active))))
|
`(mode-line-active ((t (:background ,active))))
|
||||||
`(mode-line-inactive ((t (:background ,inactive))))
|
`(mode-line-inactive ((t (:background ,inactive))))
|
||||||
|
|
||||||
`(tab-bar ((t :foreground ,default-fg :background ,inactive :inherit variable-pitch)))
|
`(tab-bar ((t :foreground ,default-fg :background ,inactive)))
|
||||||
`(tab-line ((t :foreground ,default-fg :background ,inactive)))
|
`(tab-line ((t :foreground ,default-fg :background ,inactive)))
|
||||||
`(tab-bar-tab ((t (:inherit variable-pitch :background ,active :weight bold))))
|
`(tab-bar-tab ((t (:inherit variable-pitch :background ,active))))
|
||||||
`(tab-bar-tab-inactive ((t (:inherit variable-pitch :background ,inactive :weight normal))))
|
`(tab-bar-tab-inactive ((t (:inherit variable-pitch :background ,inactive))))
|
||||||
|
|
||||||
`(doom-modeline-buffer-path ((t (:foreground ,almond))))
|
`(doom-modeline-buffer-path ((t (:foreground ,almond))))
|
||||||
`(doom-modeline-buffer-file ((t (:foreground "white" :weight bold))))
|
`(doom-modeline-buffer-file ((t (:foreground "white" :weight bold))))
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#+author: Howard X. Abrams
|
#+author: Howard X. Abrams
|
||||||
#+date: 2025-11-24
|
#+date: 2025-11-24
|
||||||
#+filetags: emacs hamacs
|
#+filetags: emacs hamacs
|
||||||
#+lastmod: [2026-02-04 Wed]
|
#+lastmod: [2025-12-02 Tue]
|
||||||
|
|
||||||
A literate programming file for configuring Hammerspoon.
|
A literate programming file for configuring Hammerspoon.
|
||||||
|
|
||||||
|
|
@ -79,11 +79,6 @@ To create special key bindings, I can:
|
||||||
hs.hotkey.bind({"alt", "ctrl", "shift"}, "M", function()
|
hs.hotkey.bind({"alt", "ctrl", "shift"}, "M", function()
|
||||||
hs.execute("~/bin/emacs-capture-meeting")
|
hs.execute("~/bin/emacs-capture-meeting")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Current music system is actually in Emacs:
|
|
||||||
hs.hotkey.bind({"alt", "ctrl", "shift"}, "R", function()
|
|
||||||
hs.execute("/opt/homebrew/bin/emacsclient -s work -e '(ready-player-toggle-play-stop)'")
|
|
||||||
end)
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
* Zoom
|
* Zoom
|
||||||
Library extensions to Hammerspoon are called /spoons/, and most of these are a simple Lua script, =init.lua= stored in the =Spoons= subdirectory. We grab these with a =git clone=, typically. To use the Zoom spoon, clone it:
|
Library extensions to Hammerspoon are called /spoons/, and most of these are a simple Lua script, =init.lua= stored in the =Spoons= subdirectory. We grab these with a =git clone=, typically. To use the Zoom spoon, clone it:
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,8 @@
|
||||||
;; -*- mode:lisp; -*-
|
;; -*- mode:lisp; -*-
|
||||||
;;
|
|
||||||
;; Here is a keyboard setup for an Apple Macbook keyboard to work with
|
;; Here is a keyboard setup for an Apple Macbook keyboard to work with
|
||||||
;; "home row mods" where holding down keys on the home row can act
|
;; "home row mods" where holding down keys on the home row can act like a
|
||||||
;; like a modifier, so holding down `d` and hitting `p` results in a
|
;; modifier, so holding down `d` and hitting `p` results in `P` being
|
||||||
;; capital `P` being entered.
|
;; entered.
|
||||||
;;
|
|
||||||
;; This also includes a dedicated Hyper and Mega modifier layers,
|
|
||||||
;; where holding down the `m' key and striking `a' creates a
|
|
||||||
;; Control+Shift+Option+a key combination. This is useful for fancy
|
|
||||||
;; hotkeys for Hammerspoon and the like.
|
|
||||||
;;
|
;;
|
||||||
;; Installation:
|
;; Installation:
|
||||||
;; brew install kanata
|
;; brew install kanata
|
||||||
|
|
@ -49,7 +43,6 @@
|
||||||
;; the `h' or `g' keys.
|
;; the `h' or `g' keys.
|
||||||
|
|
||||||
(defalias
|
(defalias
|
||||||
;; Home row mods
|
|
||||||
a (tap-hold $tap-time $hold-time a lmet)
|
a (tap-hold $tap-time $hold-time a lmet)
|
||||||
s (tap-hold $tap-time $hold-time s lctl)
|
s (tap-hold $tap-time $hold-time s lctl)
|
||||||
d (tap-hold $tap-time $hold-time d lsft)
|
d (tap-hold $tap-time $hold-time d lsft)
|
||||||
|
|
@ -60,34 +53,7 @@
|
||||||
k (tap-hold $tap-time $hold-time k rsft)
|
k (tap-hold $tap-time $hold-time k rsft)
|
||||||
l (tap-hold $tap-time $hold-time l rctl)
|
l (tap-hold $tap-time $hold-time l rctl)
|
||||||
; (tap-hold $tap-time $hold-time ; rmet)
|
; (tap-hold $tap-time $hold-time ; rmet)
|
||||||
caps (tap-hold $tap-time $hold-time esc lctl)
|
caps (tap-hold $tap-time $hold-time esc lctl))
|
||||||
|
|
||||||
;; ----------------------------------------------------
|
|
||||||
;; HYPER ALIASES (Shift + Ctrl + Option)
|
|
||||||
;; ----------------------------------------------------
|
|
||||||
hq (multi lsft lctl lalt q) hw (multi lsft lctl lalt w) he (multi lsft lctl lalt e) hr (multi lsft lctl lalt r) ht (multi lsft lctl lalt t)
|
|
||||||
hy (multi lsft lctl lalt y) hu (multi lsft lctl lalt u) hi (multi lsft lctl lalt i) ho (multi lsft lctl lalt o) hp (multi lsft lctl lalt p)
|
|
||||||
|
|
||||||
ha (multi lsft lctl lalt a) hs (multi lsft lctl lalt s) hd (multi lsft lctl lalt d) hf (multi lsft lctl lalt f) hg (multi lsft lctl lalt g)
|
|
||||||
hh (multi lsft lctl lalt h) hj (multi lsft lctl lalt j) hk (multi lsft lctl lalt k) hl (multi lsft lctl lalt l) h; (multi lsft lctl lalt ;)
|
|
||||||
|
|
||||||
hz (multi lsft lctl lalt z) hx (multi lsft lctl lalt x) hc (multi lsft lctl lalt c) hv (multi lsft lctl lalt v) hb (multi lsft lctl lalt b)
|
|
||||||
hn (multi lsft lctl lalt n) hm (multi lsft lctl lalt m) h, (multi lsft lctl lalt ,) h. (multi lsft lctl lalt .) h/ (multi lsft lctl lalt /)
|
|
||||||
|
|
||||||
;; ----------------------------------------------------
|
|
||||||
;; MEGA ALIASES (Shift + Ctrl + Option + Cmd)
|
|
||||||
;; ----------------------------------------------------
|
|
||||||
mq (multi lsft lctl lalt lmet q) mw (multi lsft lctl lalt lmet w) me (multi lsft lctl lalt lmet e) mr (multi lsft lctl lalt lmet r) mt (multi lsft lctl lalt lmet t)
|
|
||||||
my (multi lsft lctl lalt lmet y) mu (multi lsft lctl lalt lmet u) mi (multi lsft lctl lalt lmet i) mo (multi lsft lctl lalt lmet o) mp (multi lsft lctl lalt lmet p)
|
|
||||||
|
|
||||||
ma (multi lsft lctl lalt lmet a) ms (multi lsft lctl lalt lmet s) md (multi lsft lctl lalt lmet d) mf (multi lsft lctl lalt lmet f) mg (multi lsft lctl lalt lmet g)
|
|
||||||
mh (multi lsft lctl lalt lmet h) mj (multi lsft lctl lalt lmet j) mk (multi lsft lctl lalt lmet k) ml (multi lsft lctl lalt lmet l) m; (multi lsft lctl lalt lmet ;)
|
|
||||||
|
|
||||||
mz (multi lsft lctl lalt lmet z) mx (multi lsft lctl lalt lmet x) mc (multi lsft lctl lalt lmet c) mv (multi lsft lctl lalt lmet v) mb (multi lsft lctl lalt lmet b)
|
|
||||||
mn (multi lsft lctl lalt lmet n) mm (multi lsft lctl lalt lmet m) m, (multi lsft lctl lalt lmet ,) m. (multi lsft lctl lalt lmet .) m/ (multi lsft lctl lalt lmet /)
|
|
||||||
|
|
||||||
m (tap-hold $tap-time $hold-time m (layer-while-held HYPER))
|
|
||||||
c (tap-hold $tap-time $hold-time c (layer-while-held MEGA)))
|
|
||||||
|
|
||||||
;; The base layer is fairly normal, except we all out aliases defined
|
;; The base layer is fairly normal, except we all out aliases defined
|
||||||
;; above, os the @a is both a `tap-hold' feature as well as a regular
|
;; above, os the @a is both a `tap-hold' feature as well as a regular
|
||||||
|
|
@ -98,7 +64,7 @@
|
||||||
` 1 2 3 4 5 6 7 8 9 0 - = bspc
|
` 1 2 3 4 5 6 7 8 9 0 - = bspc
|
||||||
tab q w e r t y u i o p [ ] \
|
tab q w e r t y u i o p [ ] \
|
||||||
@caps @a @s @d @f @g @h @j @k @l @; ' ret
|
@caps @a @s @d @f @g @h @j @k @l @; ' ret
|
||||||
lsft z x @c v b n @m , . / rsft
|
lsft z x c v b n m , . / rsft
|
||||||
@h lctl lalt lmet spc rmet ralt)
|
@h lctl lalt lmet spc rmet ralt)
|
||||||
|
|
||||||
;; The other layer is our `symbols' which allows me to hold down the
|
;; The other layer is our `symbols' which allows me to hold down the
|
||||||
|
|
@ -111,22 +77,3 @@
|
||||||
_ S-3 S-4 S-9 S-0 ` left down up right pgdn _ _
|
_ S-3 S-4 S-9 S-0 ` left down up right pgdn _ _
|
||||||
_ S-5 S-6 [ ] S-` F11 F12 F13 F14 F15 _
|
_ S-5 S-6 [ ] S-` F11 F12 F13 F14 F15 _
|
||||||
_ _ _ _ _ _ _)
|
_ _ _ _ _ _ _)
|
||||||
|
|
||||||
;; The other layer is our `magic' which allows me to hold down the
|
|
||||||
;; `m' key to invoke a magical VI-like h/j/k/l arrow keys:
|
|
||||||
|
|
||||||
(deflayer HYPER
|
|
||||||
_ _ _ _ _ _ _ _ _ _ _ _ _
|
|
||||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
||||||
_ @hq @hw @he @hr @ht @hy @hu @hi @ho @hp _ _ _
|
|
||||||
_ @ha @hs @hd @hf @hg @hh @hj @hk @hl @h; _ _
|
|
||||||
_ @hz @hx @hc @hv @hb @hn @hm _ _ _ _
|
|
||||||
_ _ _ _ _ _ _)
|
|
||||||
|
|
||||||
(deflayer MEGA
|
|
||||||
_ _ _ _ _ _ _ _ _ _ _ _ _
|
|
||||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
||||||
_ @mq @mw @me @mr @mt @my @mu @mi @mo @mp _ _ _
|
|
||||||
_ @ma @ms @md @mf @mg @mh @mj @mk @ml @m; _ _
|
|
||||||
_ @mz @mx @mc @mv @mb @mn @mm _ _ _ _
|
|
||||||
_ _ _ _ _ _ _)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue