How can I get emacs to shift-tab to move the selected text to the left by 4 spaces?
问题:
回答1:
This removes 4 spaces from the front of the current line (provided the spaces exist).
(global-set-key (kbd "") 'un-indent-by-removing-4-spaces) (defun un-indent-by-removing-4-spaces () "remove 4 spaces from beginning of of line" (interactive) (save-excursion (save-match-data (beginning-of-line) ;; get rid of tabs at beginning of line (when (looking-at "^\\s-+") (untabify (match-beginning 0) (match-end 0))) (when (looking-at "^ ") (replace-match ""))))) If your variable tab-width happens to be 4 (and that's what you want to "undo"), then you can replace the (looking-at "^ ") with something more general like (concat "^" (make-string tab-width ?\ )).
Also, the code will convert the tabs at the front of the line to spaces using untabify.
回答2:
To do that, I use the command indent-rigidly, bound to C-x TAB. Give it the argument -4 to move the selected region to the left by four spaces: C-u -4 C-x TAB.
http://www.gnu.org/s/emacs/manual/html_node/elisp/Region-Indent.html
回答3:
I made some functions for tabbing a region over by four spaces left or right depending on if you use tab or shift+tab:
(defun indent-region-custom(numSpaces) (progn ; default to start and end of current line (setq regionStart (line-beginning-position)) (setq regionEnd (line-end-position)) ; if there's a selection, use that instead of the current line (when (use-region-p) (setq regionStart (region-beginning)) (setq regionEnd (region-end)) ) (save-excursion ; restore the position afterwards (goto-char regionStart) ; go to the start of region (setq start (line-beginning-position)) ; save the start of the line (goto-char regionEnd) ; go to the end of region (setq end (line-end-position)) ; save the end of the line (indent-rigidly start end numSpaces) ; indent between start and end (setq deactivate-mark nil) ; restore the selected region ) ) ) (defun untab-region (N) (interactive "p") (indent-region-custom -4) ) (defun tab-region (N) (interactive "p") (if (active-minibuffer-window) (minibuffer-complete) ; tab is pressed in minibuffer window -> do completion ; else (if (string= (buffer-name) "*shell*") (comint-dynamic-complete) ; in a shell, use tab completion ; else (if (use-region-p) ; tab is pressed is any other buffer -> execute with space insertion (indent-region-custom 4) ; region was selected, call indent-region (insert " ") ; else insert four spaces as expected ))) ) (global-set-key (kbd "") 'untab-region) (global-set-key (kbd "") 'tab-region) Edit: Added Maven's code to check if in minibuffer, as well as for tab completion in specific buffers (shell, for example).
回答4:
I have improved upon Stanley Bak's answer. For me, this global key binding was messing up minibuffer completion.
So I have included a case for minibuffer as well.
Edit : Renaming indent-region -> indent-region-custom.
indent-region is clashing with existing command and gives error for indent on save (hook for before save) and some other key combinations.
(defun indent-region-custom(numSpaces) (progn ;; default to start and end of current line (setq regionStart (line-beginning-position)) (setq regionEnd (line-end-position)) ;; if there's a selection, use that instead of the current line (when (use-region-p) (setq regionStart (region-beginning)) (setq regionEnd (region-end)) ) (save-excursion ; restore the position afterwards (goto-char regionStart) ; go to the start of region (setq start (line-beginning-position)) ; save the start of the line (goto-char regionEnd) ; go to the end of region (setq end (line-end-position)) ; save the end of the line (indent-rigidly start end numSpaces) ; indent between start and end (setq deactivate-mark nil) ; restore the selected region ) ) ) (defun untab-region (N) (interactive "p") (indent-region-custom -4) ) (defun tab-region (N) (interactive "p") (if (active-minibuffer-window) (minibuffer-complete) ; tab is pressed in minibuffer window -> do completion (if (use-region-p) ; tab is pressed is any other buffer -> execute with space insertion (indent-region-custom 4) ; region was selected, call indent-region-custom (insert " ") ; else insert four spaces as expected ) ) ) (global-set-key (kbd "") 'untab-region) (global-set-key (kbd "") 'tab-region)