Mwim.el
Move to the beginning/end of line, code or comment
Install / Use
/learn @alezost/Mwim.elREADME
[[https://www.gnu.org/licenses/gpl-3.0.txt][file:https://img.shields.io/badge/license-GPL_3-orange.svg]] [[https://melpa.org/#/mwim][file:https://melpa.org/packages/mwim-badge.svg]] [[https://stable.melpa.org/#/mwim][file:https://stable.melpa.org/packages/mwim-badge.svg]]
- About
This Emacs package provides several commands to switch between various line positions, like moving to the beginning/end of code, line or comment. It is inspired by [[https://www.emacswiki.org/emacs/BackToIndentationOrBeginning][this EmacsWiki page]] (some code from this page is used). =mwim= stands for =Move Where I Mean=.
[[file:demo.gif]]
** Quick start
If you don't have a wish to read all the text written below, just try the following key bindings and see what happens:
#+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-a") 'mwim-beginning) (global-set-key (kbd "C-e") 'mwim-end) #+END_SRC
- Installation
** Automatic
This package can be installed from [[https://melpa.org/][MELPA]] (with =M-x package-install= or =M-x list-packages=).
** Manual
For the manual installation, clone the repo, add the directory to =load-path= and add autoloads for the commands you need:
#+BEGIN_SRC emacs-lisp (add-to-list 'load-path "/path/to/mwim-dir") (autoload 'mwim "mwim" nil t) (autoload 'mwim-beginning "mwim" nil t) (autoload 'mwim-end "mwim" nil t) (autoload 'mwim-beginning-of-code-or-line "mwim" nil t) (autoload 'mwim-beginning-of-line-or-code "mwim" nil t) (autoload 'mwim-beginning-of-code-or-line-or-comment "mwim" nil t) (autoload 'mwim-end-of-code-or-line "mwim" nil t) (autoload 'mwim-end-of-line-or-code "mwim" nil t) #+END_SRC
- Usage
** Simple commands
As you can see in the gif demonstration:
-
=M-x mwim-beginning-of-code-or-line= moves the point between a first non-space character and a first character of the line.
-
=M-x mwim-end-of-code-or-line= moves the point between the end of code (not counting a trailing comment) and the end of the line.
=M-x mwim-beginning-of-line-or-code= and =M-x mwim-end-of-line-or-code= do the same but in a reverse order.
Also there is =M-x mwim-beginning-of-code-or-line-or-comment= command that switches the point between these 3 positions.
You may bind some keys to some of those commands in a usual manner, for example:
#+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-a") 'mwim-beginning-of-code-or-line) (global-set-key (kbd "C-e") 'mwim-end-of-code-or-line) (global-set-key (kbd "<home>") 'mwim-beginning-of-line-or-code) (global-set-key (kbd "<end>") 'mwim-end-of-line-or-code) #+END_SRC
Note that =shift-selection= is supported by all MWIM commands, which means if you press =Shift= with the bound keys (for example, =<S-home>=), the region of text will be selected (see [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Shift-Selection.html#Shift-Selection][Emacs manual]] for details).
** Move where you really want
Along with the described simple commands, there are more general commands that allow you to switch between any positions you want:
- =M-x mwim-beginning=
- =M-x mwim-end=
- =M-x mwim=
You can configure switching positions for these commands with =mwim-beginning-position-functions=, =mwim-end-position-functions= and =mwim-position-functions= variables.
The position functions from these variables are called without arguments and they should return a new point position. For example, after:
#+BEGIN_SRC emacs-lisp (setq mwim-beginning-position-functions (list (lambda () (+ 2 (line-beginning-position))) 'mwim-code-beginning)) #+END_SRC
=M-x mwim-beginning= will switch between the third character (the second counting from 0) on the current line and the code beginning position.
You can also make mode-specific positions by making these variables local. Let's say, for =emacs-lisp-mode=, you want a usual switch between the code end and line end when you call =M-x mwim-end=; but if there is a comment on the current line, you want to move to the beginning of this comment instead of the code end position. You can do it like this:
#+BEGIN_SRC emacs-lisp (defun my/comment-beginning-or-code-end () (or (mwim-line-comment-beginning) (mwim-code-end)))
(defun my/setup-elisp-mwim-positions () (setq-local mwim-end-position-functions '(my/comment-beginning-or-code-end mwim-line-end)))
(add-hook 'emacs-lisp-mode-hook 'my/setup-elisp-mwim-positions) #+END_SRC
So, if you want to use these commands instead of the Emacs defaults, you can bind them like this:
#+BEGIN_SRC emacs-lisp (global-set-key (kbd "<C-tab>") #'mwim) (global-set-key [remap move-beginning-of-line] #'mwim-beginning) (global-set-key [remap move-end-of-line] #'mwim-end) #+END_SRC
** Define your own commands
Finally, you can define your own commands using =mwim-move-to-next-position= macro. See the code of =mwim=, =mwim-beginning= or =mwim-end= commands for examples.
- Acknowledgments
Many thanks to Adam Porter, who wrote [[https://github.com/alphapapa/mosey.el][mosey.el]] package, which provides similar facilities as =mwim.el=. Several ideas were taken from it.
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
