<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>~iany/ Emacs</title><link>https://blog.iany.me/tags/emacs/</link><description>Recent content in Emacs «~iany/»</description><language>en-US</language><managingEditor>me@iany.me (Ian Yang)</managingEditor><webMaster>me@iany.me (Ian Yang)</webMaster><copyright>CC-BY-SA 4.0</copyright><lastBuildDate>Sat, 22 Nov 2025 23:17:05 +0800</lastBuildDate><atom:link href="https://blog.iany.me/tags/emacs/index.xml" rel="self" type="application/rss+xml"/><item><title>Temporary Vi Mode in PowerShell</title><link>https://blog.iany.me/2025/11/temporary-vi-mode-in-powershell/</link><pubDate>Sat, 22 Nov 2025 23:17:05 +0800</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/2025/11/temporary-vi-mode-in-powershell/</guid><description>&lt;p&gt;I miss the feature in readline (Bash/Zsh) where &lt;code&gt;Ctrl+x, Ctrl+v&lt;/code&gt; switches to Vi command mode temporarily. In that workflow, entering Insert mode switches back to Emacs mode. &lt;code&gt;PSReadLine&lt;/code&gt; has a command &lt;code&gt;ViCommandMode&lt;/code&gt;, but binding it directly in Emacs mode will report errors on every key input.&lt;/p&gt;
&lt;p&gt;The solution requires handling the mode change event to toggle the global &lt;code&gt;EditMode&lt;/code&gt; between &lt;code&gt;Emacs&lt;/code&gt; and &lt;code&gt;Vi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When entering &amp;ldquo;Insert&amp;rdquo; mode (the default for Emacs users), we force the mode to &lt;code&gt;Emacs&lt;/code&gt; and set up the trigger for the temporary Vi mode. When that trigger (&lt;code&gt;Ctrl+x, Ctrl+v&lt;/code&gt;) is fired, we switch the edit mode to &lt;code&gt;Vi&lt;/code&gt; and jump to command mode.&lt;/p&gt;
&lt;p&gt;Here is the configuration for your &lt;code&gt;$PROFILE&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;function OnViModeChange {
if ($args[0] -eq 'Insert') {
Set-PSReadLineOption -EditMode Emacs
Set-PSReadlineKeyHandler -Chord &amp;quot;Ctrl+x,Ctrl+v&amp;quot; -ScriptBlock {
Set-PSReadLineOption -EditMode Vi
[Microsoft.PowerShell.PSConsoleReadLine]::ViCommandMode()
}
# Add other Emacs key bindings here.
# Switching `EditMode` resets key bindings to their defaults.
# Remember to reconfigure them.
# Set-PSReadlineKeyHandler -Chord &amp;quot;Ctrl+w&amp;quot; -Function BackwardKillWord
}
}
Set-PSReadLineOption -ViModeIndicator Script
Set-PSReadLineOption -ViModeChangeHandler $Function:OnViModeChange
Set-PSReadLineOption -EditMode Emacs
# Reuse the function to start Emacs mode
OnViModeChange Insert
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Switching &lt;code&gt;EditMode&lt;/code&gt; resets key bindings to their defaults. Remember to reconfigure them.&lt;/p&gt;</description><category domain="https://blog.iany.me/post/">Posts</category><category domain="https://blog.iany.me/tags/powershell/">PowerShell</category><category domain="https://blog.iany.me/tags/vim/">Vim</category><category domain="https://blog.iany.me/tags/emacs/">Emacs</category><category domain="https://blog.iany.me/tags/console/">Console</category></item><item><title>Fix TAB Binding For yasnippet And auto-complete</title><link>https://blog.iany.me/2012/03/fix-tab-binding-for-yasnippet-and-auto-complete/</link><pubDate>Sat, 31 Mar 2012 00:00:00 +0000</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/2012/03/fix-tab-binding-for-yasnippet-and-auto-complete/</guid><description>&lt;p&gt;There are two TAB&amp;rsquo;s in Emacs, &lt;code&gt;(kbd &amp;quot;TAB&amp;quot;)&lt;/code&gt; (&lt;code&gt;\t&lt;/code&gt;, &lt;code&gt;[9]&lt;/code&gt;) and &lt;code&gt;(kbd &amp;quot;&amp;lt;tab&amp;gt;&amp;quot;)&lt;/code&gt; (&lt;code&gt;[tab]&lt;/code&gt;). If modes like &lt;a href="https://github.com/joaotavora/yasnippet"&gt;yasnippet&lt;/a&gt; and &lt;a href="https://github.com/auto-complete/auto-complete"&gt;auto-complete&lt;/a&gt; want to bind on &lt;code&gt;TAB&lt;/code&gt;, their trigger key must be the same with the original Tab command. Since Emacs binds &lt;code&gt;indent-for-tab-command&lt;/code&gt; on &lt;code&gt;(kbd &amp;quot;TAB&amp;quot;)&lt;/code&gt;, so it&amp;rsquo;s better to use it as the trigger key. Yasnippet binds to it by default, It is also easy to setup &lt;code&gt;auto-complete&lt;/code&gt; to trigger using Tab.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;;; trigger using TAB and disable auto start
(custom-set-variables
'(ac-trigger-key &amp;quot;TAB&amp;quot;)
'(ac-auto-start nil)
'(ac-use-menu-map t))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But in some modes (&lt;code&gt;ruby-mode&lt;/code&gt;, &lt;code&gt;markdown-mode&lt;/code&gt;, &lt;code&gt;org-mode&lt;/code&gt;), the command is bind to &lt;code&gt;(kbd &amp;quot;&amp;lt;tab&amp;gt;&amp;quot;)&lt;/code&gt;, when the real Tab key is typed, the function bind on &lt;code&gt;(kbd &amp;quot;&amp;lt;tab&amp;gt;)&lt;/code&gt; has higher priority, so yasnippet and auto-complete are not invoked. It is easy to fix by moving the keybinding:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;(defun iy-tab-noconflict ()
(let ((command (key-binding [tab]))) ; remember command
(local-unset-key [tab]) ; unset from (kbd &amp;quot;&amp;lt;tab&amp;gt;&amp;quot;)
(local-set-key (kbd &amp;quot;TAB&amp;quot;) command))) ; bind to (kbd &amp;quot;TAB&amp;quot;)
(add-hook 'ruby-mode-hook 'iy-ac-tab-noconflict)
(add-hook 'markdown-mode-hook 'iy-ac-tab-noconflict)
(add-hook 'org-mode-hook 'iy-ac-tab-noconflict)
&lt;/code&gt;&lt;/pre&gt;</description><category domain="https://blog.iany.me/post/">Posts</category><category domain="https://blog.iany.me/tags/emacs/">Emacs</category></item><item><title>Use Popup isearch For Yasnippet Prompt</title><link>https://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/</link><pubDate>Fri, 30 Mar 2012 00:00:00 +0000</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/</guid><description>&lt;p&gt;&lt;a href="https://github.com/joaotavora/yasnippet"&gt;Yasnippet&lt;/a&gt; tries functions in &lt;code&gt;yas/prompt-functions&lt;/code&gt; when it needs user to select one choice, such as selecting snippets with the same trigger key, such as helper method &lt;code&gt;yas/choose-value&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/auto-complete/popup-el"&gt;popup&lt;/a&gt; is a visual popup interface library extracted from &lt;a href="https://github.com/auto-complete/auto-complete"&gt;auto-complete&lt;/a&gt; by its author. It has better look and feel than all the built-in &lt;code&gt;yas/prompt-functions&lt;/code&gt;. Also it is easy to customize, and its isearch mode is very efficient, the items are filtered on-the-fly when typing.&lt;/p&gt;
&lt;figure class="kg-card kg-gallery-card kg-width-wide"&gt;
&lt;div class="kg-gallery-container"&gt;
&lt;div class="kg-gallery-row"&gt;
&lt;div class="kg-gallery-image"&gt;&lt;img alt="Popup snapshot: choices" class="tippy" loading="lazy" width="273" height="166" src="https://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/choises_hu_f31d4431d0059d2d.png" data-tippy-content="Popup snapshot: choices" /&gt;&lt;/div&gt;
&lt;div class="kg-gallery-image"&gt;&lt;img alt="Popup snapshot: filter" class="tippy" loading="lazy" width="273" height="104" src="https://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/filter_by_keyword_hu_d1cdbe0e3f825240.png" data-tippy-content="Popup snapshot: filter" /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;The integration is easy. Load &lt;code&gt;popup.el&lt;/code&gt;, implement one prompt function and
add it to &lt;code&gt;yas/prompt-functions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;※ &lt;a href="https://gist.github.com/doitian/2245733"&gt;yasnippet-popup-isearch-prompt.el&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-lisp"&gt;(require 'popup)
(require 'yasnippet)
;; add some shotcuts in popup menu mode
(define-key popup-menu-keymap (kbd &amp;quot;M-n&amp;quot;) 'popup-next)
(define-key popup-menu-keymap (kbd &amp;quot;TAB&amp;quot;) 'popup-next)
(define-key popup-menu-keymap (kbd &amp;quot;&amp;lt;tab&amp;gt;&amp;quot;) 'popup-next)
(define-key popup-menu-keymap (kbd &amp;quot;&amp;lt;backtab&amp;gt;&amp;quot;) 'popup-previous)
(define-key popup-menu-keymap (kbd &amp;quot;M-p&amp;quot;) 'popup-previous)
(defun yas/popup-isearch-prompt (prompt choices &amp;amp;optional display-fn)
(when (featurep 'popup)
(popup-menu*
(mapcar
(lambda (choice)
(popup-make-item
(or (and display-fn (funcall display-fn choice))
choice)
:value choice))
choices)
:prompt prompt
;; start isearch mode immediately
:isearch t
)))
(setq yas/prompt-functions '(yas/popup-isearch-prompt yas/no-prompt))
&lt;/code&gt;&lt;/pre&gt;</description><category domain="https://blog.iany.me/post/">Posts</category><category domain="https://blog.iany.me/tags/emacs/">Emacs</category></item><item><title>Highlight Ruby New Hash In Emacs</title><link>https://blog.iany.me/2012/01/hilight-ruby-new-hash-in-emacs/</link><pubDate>Thu, 12 Jan 2012 00:00:00 +0000</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/2012/01/hilight-ruby-new-hash-in-emacs/</guid><description>&lt;p&gt;Not fully tested, let me know if it mess up your buffer.&lt;/p&gt;
&lt;p&gt;※ &lt;a href="https://gist.github.com/doitian/1600148"&gt;my-ruby-mode.el&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-c"&gt;(font-lock-add-keywords
'ruby-mode
'((&amp;quot;\\(\\b\\sw[_a-zA-Z0-9]*:\\)\\(?:\\s-\\|$\\)&amp;quot; (1 font-lock-constant-face))))
&lt;/code&gt;&lt;/pre&gt;</description><category domain="https://blog.iany.me/post/">Posts</category><category domain="https://blog.iany.me/tags/emacs/">Emacs</category><category domain="https://blog.iany.me/tags/ruby/">Ruby</category></item></channel></rss>