* Indenting with the tab key like everyone else [not found] <1019418503.3900238.1559510385829.ref@mail.yahoo.com> @ 2019-06-02 21:19 ` R. Diez via help-gnu-emacs 2019-06-04 1:19 ` Emanuel Berg via help-gnu-emacs 2019-06-04 4:29 ` YUE Daian 0 siblings, 2 replies; 6+ messages in thread From: R. Diez via help-gnu-emacs @ 2019-06-02 21:19 UTC (permalink / raw) To: help-gnu-emacs@gnu.org Hi all: I want to change the indenting behaviour of the tab key when writing source code like C++, Perl or Bash. But I am a little confused, so I need some help. When in C mode, the Tab key is bound to c-indent-line-or-region . When in Perl mode, it is bound to indent-for-tab-command, which is a rather complicated function. I want the same behaviour as most other IDEs I know: If I just press tab, it should "intelligently" indent the current line of code as usual. But if I select several lines with the shift key, I want to rigidly indent the selected block of lines. At the moment, Emacs tries to reindent the selected lines, which often does nothing, because it thinks the lines are already properly indented. If I want to intelligently reindent a block of lines, I would rather manually call the right function, something like "reindent-code". I could create an alias or a new function just for that purpose. I never got used to Emacs "prefix" mechanism, so I do not want to use it. And I do not want to retrain my "muscle memory". I want the same behaviour as everywhere else. What would be the best way to achieve this? I know a little Lisp, but not enough for complex things. Many thanks in advance, rdiez ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Indenting with the tab key like everyone else 2019-06-02 21:19 ` Indenting with the tab key like everyone else R. Diez via help-gnu-emacs @ 2019-06-04 1:19 ` Emanuel Berg via help-gnu-emacs 2019-06-04 4:29 ` YUE Daian 1 sibling, 0 replies; 6+ messages in thread From: Emanuel Berg via help-gnu-emacs @ 2019-06-04 1:19 UTC (permalink / raw) To: help-gnu-emacs R. Diez via help-gnu-emacs wrote: > I want the same behaviour as most other IDEs > I know: If I just press tab, it should > "intelligently" indent the current line of > code as usual. But if I select several lines > with the shift key, I want to rigidly indent > the selected block of lines. At the moment, > Emacs tries to reindent the selected lines, > which often does nothing, because it thinks > the lines are already properly indented. TAB is the "intelligent" way and that works for regions as well. This makes sense IMO. If you want to just mechanically move a region forward or backward, first set the region, then do `C-u C-x TAB' for 4 steps `C-u C-u C-x TAB' for 4**2=16 steps (and so on), and for arbitrary values, do, e.g., `C-u 3 C-x TAB' for 3 steps (and so on). You can also do `C-u -2 C-x TAB' to move back two steps, for example. -- underground experts united http://user.it.uu.se/~embe8573 https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Indenting with the tab key like everyone else 2019-06-02 21:19 ` Indenting with the tab key like everyone else R. Diez via help-gnu-emacs 2019-06-04 1:19 ` Emanuel Berg via help-gnu-emacs @ 2019-06-04 4:29 ` YUE Daian 2019-06-25 8:09 ` R. Diez via help-gnu-emacs 1 sibling, 1 reply; 6+ messages in thread From: YUE Daian @ 2019-06-04 4:29 UTC (permalink / raw) To: R. Diez, help-gnu-emacs@gnu.org On 2019-06-02 21:19, "R. Diez via help-gnu-emacs" <help-gnu-emacs@gnu.org> wrote: > Hi all: > > I want to change the indenting behaviour of the tab key when writing source code like C++, Perl or Bash. But I am a little confused, so I need some help. > > When in C mode, the Tab key is bound to c-indent-line-or-region . When in Perl mode, it is bound to indent-for-tab-command, which is a rather complicated function. > > I want the same behaviour as most other IDEs I know: If I just press tab, it should "intelligently" indent the current line of code as usual. But if I select several lines with the shift key, I want to rigidly indent the selected block of lines. At the moment, Emacs tries to reindent the selected lines, which often does nothing, because it thinks the lines are already properly indented. > > If I want to intelligently reindent a block of lines, I would rather manually call the right function, something like "reindent-code". I could create an alias or a new function just for that purpose. > > I never got used to Emacs "prefix" mechanism, so I do not want to use it. And I do not want to retrain my "muscle memory". I want the same behaviour as everywhere else. > > What would be the best way to achieve this? I know a little Lisp, but not enough for complex things. > > Many thanks in advance, > rdiez Well, Emacs TAB key facility is a little bit complicated. I had similar requirement to yours when I was using Emacs 23. I wrote a function exactly for this. It triggers company-mode completion when the "current" character satisfies the regex. Otherwise, it just indent the line. Or when yasnippet is active, it moves to the next field. AFAIK `company-indent-or-complete-common` does not support it. --- BEGIN --- (defcustom company-begin-regex "[0-9a-zA-Z_.>:-]" "Used by function `complete-or-indent' to decide whether or not to start completion." :type 'string :group 'none :safe t) ;; Bind company complete to <TAB> in a smart way. ;; TODO Remove this snippet later... (defun complete-or-indent () "Complete using company-mode or indent current line by checking " (interactive) (cond ;; When in region, indent the region. ((use-region-p) (indent-region (region-beginning) (region-end))) ;; When yasnippet is active, move to next field. ((yas-active-snippets) (yas-next-field)) ;; When it is possible to complete, do it. ((and (string-match-p company-begin-regex (char-to-string (char-before))) (call-when-defined 'company-manual-begin)) (call-when-defined 'company-complete-common)) (t (indent-for-tab-command)))) --- END --- Hope that helps. Danny ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Indenting with the tab key like everyone else 2019-06-04 4:29 ` YUE Daian @ 2019-06-25 8:09 ` R. Diez via help-gnu-emacs 2019-07-01 4:29 ` YUE Daian 0 siblings, 1 reply; 6+ messages in thread From: R. Diez via help-gnu-emacs @ 2019-06-25 8:09 UTC (permalink / raw) To: YUE Daian; +Cc: help-gnu-emacs@gnu.org Hallo Danny: Thanks for your help. I got a little further, see the code I came up with below (I used some code I found on the Internet too). There is a little issue I have not been able to fix yet. Say I place the cursor at the beginning of a line, and select a few lines by keeping the "shift" key pressed and hitting the down arrow key a few times. I call this selecting lines "downwards". Then indenting by hitting the tab key multiple times works fine. However, if I select/mark the lines "upwards" (by using the up arrow key), then 'my-indent-rigidly' loses the selection after indenting the first time. I am confused with the terms 'region', 'mark' and 'transient mark', and my Lisp skills are not very good either. Have you got any ideas on how to fix that? The Lisp code is here: ; This routine keeps the region/mark/transient mark (?) when doing an indent-rigidly. (defun my-indent-rigidly (amount) "" (save-excursion (let ((deactivate-mark nil) (beg (region-beginning))) (move-beginning-of-line nil) (indent-rigidly beg (region-end) amount) (push-mark beg t t)))) ; Shift-Tab to decrease the indentation. ; As an alternative, block-select the columns of spaces you want to delete, and press the Del key. (defun unindent-rigidly nil "" (interactive) (my-indent-rigidly -1) ) (global-set-key [S-tab] 'unindent-rigidly) ; Sometimes "S-tab" does not work, use [backtab] instead: (global-set-key [backtab] 'unindent-rigidly) ; The Tab key has 2 functions: ; - If some text is selected, ridigly increases indentation. ; - Otherwise, intelligently indent the current line. (defun my-tab-indent nil "" (interactive) (if (use-region-p) (my-indent-rigidly 1) (indent-for-tab-command))) (global-set-key (kbd "TAB") 'my-tab-indent) Best regards, rdiez ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Indenting with the tab key like everyone else 2019-06-25 8:09 ` R. Diez via help-gnu-emacs @ 2019-07-01 4:29 ` YUE Daian 2019-07-16 7:23 ` R. Diez 0 siblings, 1 reply; 6+ messages in thread From: YUE Daian @ 2019-07-01 4:29 UTC (permalink / raw) To: R. Diez; +Cc: help-gnu-emacs@gnu.org On 2019-06-25 10:09, "R. Diez" <rdiezmail-emacs@yahoo.de> wrote: > Hallo Danny: > > Thanks for your help. I got a little further, see the code I came up with below (I used some code I found on the Internet too). > > There is a little issue I have not been able to fix yet. Say I place the cursor at the beginning of a line, and select a few lines by > keeping the "shift" key pressed and hitting the down arrow key a few times. I call this selecting lines "downwards". Then indenting by > hitting the tab key multiple times works fine. > > However, if I select/mark the lines "upwards" (by using the up arrow key), then 'my-indent-rigidly' loses the selection after indenting the > first time. > > I am confused with the terms 'region', 'mark' and 'transient mark', and my Lisp skills are not very good either. Have you got any ideas on > how to fix that? > > > The Lisp code is here: > > ; This routine keeps the region/mark/transient mark (?) when doing an indent-rigidly. > (defun my-indent-rigidly (amount) "" > (save-excursion > (let ((deactivate-mark nil) > (beg (region-beginning))) > (move-beginning-of-line nil) > (indent-rigidly beg (region-end) amount) > (push-mark beg t t)))) > > > ; Shift-Tab to decrease the indentation. > ; As an alternative, block-select the columns of spaces you want to delete, and press the Del key. > (defun unindent-rigidly nil "" > (interactive) > (my-indent-rigidly -1) > ) > > (global-set-key [S-tab] 'unindent-rigidly) > ; Sometimes "S-tab" does not work, use [backtab] instead: > (global-set-key [backtab] 'unindent-rigidly) > > > ; The Tab key has 2 functions: > ; - If some text is selected, ridigly increases indentation. > ; - Otherwise, intelligently indent the current line. > (defun my-tab-indent nil "" > (interactive) > (if (use-region-p) > (my-indent-rigidly 1) > (indent-for-tab-command))) > > (global-set-key (kbd "TAB") 'my-tab-indent) > > > Best regards, > rdiez Sorry for the late reply. I am not sure what you really want to do exactly. There are some tips I thought of based on the code: - If you look at the document of the function `push-mark`, you may notice that "Novice Emacs Lisp programmers often try to use the mark for the wrong purposes". I am not sure if this is the case but I presume that the weird behavior relates to it. - Key binding Tab can be obtained by calling `(kbd "<tab>")` and back-tab using `(kbd "S-<tab>")`. I tried your function and both selecting downwards and upwards work. Please check the real key binding by typing `C-h k <tab>` and see if your function got called. The global key binding can be overrode by mode-map. - If you want to edit multiple lines, you may consider using the multi-cursors package. - It is very unusual to use `nil` instead of `()` for argument list. Also document string usually remains below the header line of a function. Please describe what you want to achieve exactly so that more specific help could be given. Cheers. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Indenting with the tab key like everyone else 2019-07-01 4:29 ` YUE Daian @ 2019-07-16 7:23 ` R. Diez 0 siblings, 0 replies; 6+ messages in thread From: R. Diez @ 2019-07-16 7:23 UTC (permalink / raw) To: YUE Daian; +Cc: help-gnu-emacs@gnu.org > I am not sure what you really want to do exactly. There are some tips I > thought of based on the code: > [...] After much fighting with Emacs, I think I narrowed the problem down to a weird side-effect of calling (use-region-p). I have written this routine for test purposes. I would be interested to know if you can reproduce it on your Emacs. ; This routine lets you test the surprising side-effect of calling (use-region-p). ; ; Before calling this routine, select a few text lines by going to the beginning of a line ; (column 0) and pressing Shift + <cursor down> a few times. The lines will be highlighted. ; ; Then call this routine interactively a few times in a row. The lines will indent one character at a time. ; The first time, the highlighting will disappear, but the selection will somehow stay, so that ; further calls will still indent the same lines. ; ; After the test above, change "(if t" below to "(if (use-region-p)", and repeat the test. ; The first time, the text will indent one character, but the second call will not indent anymore, ; because the selection is completely lost. (defun indentation-test nil "" (interactive) (if t ; (if (use-region-p) (indent-rigidly (region-beginning) (region-end) 1) (message "Skipping because there is no selection.") ) ) Best regards, rdiez ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-07-16 7:23 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <1019418503.3900238.1559510385829.ref@mail.yahoo.com> 2019-06-02 21:19 ` Indenting with the tab key like everyone else R. Diez via help-gnu-emacs 2019-06-04 1:19 ` Emanuel Berg via help-gnu-emacs 2019-06-04 4:29 ` YUE Daian 2019-06-25 8:09 ` R. Diez via help-gnu-emacs 2019-07-01 4:29 ` YUE Daian 2019-07-16 7:23 ` R. Diez
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).