EMACS and TAB key (indent vs \t insert) - emacs

Let's say I have a <weird language> file and I'm editing it.
If the cursor is at the beginning of a sentence (let's say an if, which is already indented 2 levels) and I hit TAB, I'd expect EMACS to increase +1 the indent level of that line (using a TAB or N SPACEs, depending on the indent style used in the file).
Anyways, if I hit TAB and the cursor is after the if, I'd expect EMACS to insert a plain \t.
How can I make EMACS behave like this?
Regards

Took current indentation as at-beginning. That condition might need a modification. See also third clause.
(defun my-indent-or-insert-tab ()
"Insert a TAB or indent depending on context. "
(interactive "*")
(cond((eq (current-column) (current-indentation))
(indent-for-tab-command))
((member (char-after) (list ?\t ? ?\n))
(insert "\t"))
(t (message "%s" "Don't know what to do if inside word"))))

Related

How to get auto indent (not smart indent) in emacs in all modes

I'm new to emacs, and its indenting is driving me up the walls. It's too smart for its own good; it (incorrectly) thinks it knows how I want to format my source, but I don't have time to chase down every setting for every mode for every different language that I write code for; and many of those languages don't have any mode enabled at all.
Here's the behaviour I'd like:
TAB inserts indent
RET inserts a new line then copies the blank characters from the start of the previous line to the first non-blank character, or end of line, whichever comes sooner
DEL (backspace key) in the blank text between line start and first non-blank character / end of line deletes one indent if possible, otherwise single character like normal
No auto-indent on {
No auto-unindent on }
In fact, no smart-ass indenting behaviour anywhere anytime, just copy previous line's indent on RET.
Two variables to be configured per source file format: display tab width, and contents of indent. Preferably these can be configured for random source code formats without having to write a major mode for them, unless writing a major mode is a one-liner in .emacs, consisting of two setqs.
This would get me logical and consistent behaviour across all languages. It would leave the work of formatting the code to me, but that's OK, I've been doing that for 20 years, and I know how to make other macros that make it efficient. More importantly, it saves me from endless fiddling with configuration settings trying to get the automatic behaviour to suit my preferences. And my macros can rely on consistent behaviour so they work correctly in all modes.
Is the above possible? Surely someone else has done this before? Is there some minor mode out there that makes it so?
Here's the code:
(setq tab-width 4)
(defun plain-tab ()
(interactive)
(insert (make-string tab-width ?\ )))
(defun plain-ret ()
(interactive)
(looking-back "^\\( +\\).*")
(newline)
(insert (match-string 1)))
(defun plain-del ()
(interactive)
(backward-delete-char
(if (looking-back (format " \\{%d\\}" tab-width)) tab-width 1)))
(defvar all-the-mode-maps
'(c-mode-map c++-mode-map java-mode-map
js-mode-map emacs-lisp-mode-map
clojure-mode-map))
(require 'cc-mode)
(require 'js)
(require 'clojure-mode)
(eval `(mapc
(lambda(map)
(define-key map [tab] 'plain-tab)
(define-key map [return] 'plain-ret)
(define-key map [backspace] 'plain-del)
(define-key map "{" (lambda()(interactive)(insert "{")))
(define-key map "}" (lambda()(interactive)(insert "}"))))
(list ,#all-the-mode-maps)))

how to put elscreen tabs on the top only?

I'm using elscreen in my GNU Emacs 24.2.1
Currently, when i split my window, I have a same tab panel in each half:
elscreen http://i.zlowiki.ru/121101_0f30ebba.png/800
Note that the two lower windows have the same tabs as the largest one.
How can I remove these two duplicates, and keep only the top one?
If it is too hard, what another alternative could be used for GNU screen?
Here's something to technically do what you asked:
(setq elscreen-display-tab nil) ; disable tabs display
;; get-alist was removed somewhere along the line
;; You can try substituting all instances of get-alist with assoc-default
;; instead of using defalias and see if that works; I haven't tried.
(defalias 'get-alist 'assoc-default) ; get-alist is gone
;; Put tabs display in your frame title bar instead.
(defun elscreen-frame-title-update ()
(when (elscreen-screen-modified-p 'elscreen-frame-title-update)
(let* ((screen-list (sort (elscreen-get-screen-list) '<))
(screen-to-name-alist (elscreen-get-screen-to-name-alist))
(title (concat "| " (mapconcat
(lambda (screen)
(format "%d%s %s |"
screen (elscreen-status-label screen)
(get-alist screen screen-to-name-alist)))
screen-list " "))))
(if (fboundp 'set-frame-name)
(set-frame-name title)
(setq frame-title-format title)))))
(eval-after-load "elscreen"
'(add-hook 'elscreen-screen-update-hook 'elscreen-frame-title-update))
I'm sure it's not what you had in mind, but hey, it's at the VERY top now and only at the top.
Take a look at http://www.emacswiki.org/emacs/ElscreenSeparateBufferLists modifies the operation of elscreen slightly borrowing from escreen. It allows the list of tabs to differ on each buffer.
How about using elscreen-tab plugin?
This plugins is created to resolve what you are annoyed with.
You can install via melpa.

Scala mode indentation in Emacs

When writing Scala code in Emacs, I notice the following indentation issue:
List(1,2,3).foreach{ x =>
Then press enter.
Then close the bracket, and this is what ends up happening:
List(1,2,3).foreach{ x =>
}
Although this is one particular example, this issue appears in a variety of ways when auto-indenting in Emacs.
An answer to either of these two questions would be appreciated:
How can this issue be fixed so that the brace gets put in the proper place and anything within the braces is indented one level to the right?
Is it possible to disable this type of auto-indentation (i.e. like 'set noautoindent' in vi). I tried solutions like the ones suggested here: Disable auto indent globally in Emacs without success.
Thanks in advance!
I've coded up a simple piece of code - it makes emacs keep indent level for most time, and indents two spaces to the right when the previous non-empty line ends with "{", "(", ">", "=".
Add file besi.el to your load path.
(provide 'besi)
(defun besi-indent-line ()
"Indent current line"
(interactive)
(scala-indent-line-to (besi-indent)))
(defun besi-indent ()
(save-excursion
(forward-comment -100000)
(backward-char 1)
(if (or (looking-at "{") (looking-at "=") (looking-at ">") (looking-at "("))
(+ (current-indentation) 2)
(current-indentation))))
(defun besi-newline ()
(interactive)
(newline-and-indent))
Edit line in scala-mode.el
indent-line-function 'besi-indent-line
and line in scala-mode-ui.el
("\r" 'besi-newline)
Also add a line (require 'besi) to the start of scala-mode.el.
Uploaded it to github for easy reference - besi
I tried to solve this by editing scala-mode-indent.el file. It breaks indent in some of the other situations, but at least you will not have all those indents half-screen forward.
Comment out this line:
;; (scala-indentation-from-following)
And modify scala-indentation-from-preceding:
(defun scala-indentation-from-preceding ()
;; Return suggested indentation based on the preceding part of the
;; current expression. Return nil if indentation cannot be guessed.
(save-excursion
(scala-backward-spaces)
(and
(not (bobp))
(if (eq (char-syntax (char-before)) ?\()
(scala-block-indentation)
(progn
(when (eq (char-before) ?\))
(backward-sexp)
(scala-backward-spaces))
t
;;(scala-looking-at-backward scala-expr-start-re)
))
(if (scala-looking-at-backward scala-expr-start-re)
(+ (current-indentation) scala-mode-indent:step)
(current-indentation)
))))
As I said, it still remains broken after that. I plan to write a better support shortly, maybe in a week or two.
EDIT:
If you want to disable scala indentation completely, comment out the line in scala-mode.el
;; indent-line-function 'scala-indent-line

(re)number numbered lists in emacs (muse)

suppose I have a text list in emacs like this:
a
b
c
...
d
Is there a way to assign numbers to those items in Emacs, by selecting the region? End results should look like:
1. a
2. b
3. c
j. ...
n. d
Thanks.
The way I do this, which may not be optimal, is to use regex search and replace. This, of course, requires that you be able to define a regex to match the start of the lines you want numbers on. Taking your example, I'd use a search regex like this:
\([a-z]\)
note the capturing brackets, we'll need that first letter soon. And a replace regex like this:
\#. \1
where:
\# is a special form which is replaced, by Emacs, by the right number (though see the warning below);
. writes a stop; and
\1 writes a space and the captured group.
WARNING: Emacs will number your items 0, 1, 2, .... Until someone posts to tell us how to start at 1, I always insert a dummy 0th element before the edit, then delete it.
You can use the Emacs Keyboard Macro Counter.
Put the cursor one line ABOVE your list.
Start a macro: F3
Insert the counter value: C-x C-k C-i. A 0 will appear
Insert the DOT and a space: .
Move the cursor to the next line
Stop the macro: F4
Select your list
M-x apply-macro-to-region-lines
You can delete the 0 you added on the top and enjoy :)
NOTE: This will create a numbered list. It will not use letters.
A much simpler way is to use the CUA library's advanced rectangle editing commands. CUA is included in Emacs (at least 23.1, I think it's in earlier versions as well), so there isn't any new code to get.
You can use cua-set-rectangle-mark (bound to C-Return by default) to start a rectangle, and then use cua-sequence-rectangle to insert increasing values. It also gives you control over the format and starting value, so there is a lot of flexibility.
As an aside, CUA is primarily designed to make Emacs operate more like standard text editors (with C-c for copy, C-v for paste, etc), but it also includes some unrelated niceties, like rectangle editing. Don't ask me why :). If you want to use the rectangle editing without enabling the CUA keybindings (which is what I do), set cua-enable-cua-keys to nil, which can be done via customize.
(defun number-region (start end)
(interactive "r")
(let* ((count 1)
(indent-region-function (lambda (start end)
(save-excursion
(setq end (copy-marker end))
(goto-char start)
(while (< (point) end)
(or (and (bolp) (eolp))
(insert (format "%d. " count))
(setq count (1+ count)))
(forward-line 1))
(move-marker end nil)))))
(indent-region start end)))
Here's some elisp code to do it; would be easy to customize if you like tinkering.
This will number the current region (unless it is already numbered), and also the last line binds to the M-n keys. You could use a function key "[F6]" as needed.
Modified to take a format string to use. The default is 1. but you could do something like %d) to get a bracket instead of a . and so on.
(defun number-region(fmt)
(interactive "sFormat : ")
(if (or (null fmt) (= 0 (length fmt)))
(setf fmt "%d. "))
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(goto-char (point-min))
(let ((num 1))
(while (> (point-max) (point))
(if (null (number-at-point))
(insert (format fmt num)))
(incf num)
(forward-line))))))
(global-set-key "\M-n" 'number-region)
Not a direct answer to your question, but if you find yourself manipulating numbered lists frequently, you may want to look into org-mode. In particular, the section on plain lists.

By Emacs, how to join two lines into one?

I am new to Emacs. I have googled this but no good answer there. One of them is
Ctrl-n Ctrl-a Backspace
This works but is stupid. Is there a quick and simple way to join a block of lines into a single line?
Actually, I can use Esc-q to auto-fill a paragraph now, but how could I get it to revert without UNDO?
Place point anywhere on the last line of the group of lines that need joining and call
M-^
repeatedly until all the lines are merged.
Note: It leaves one space between all of the now joined lines.
M-x join-line will join two lines. Just bind it to a convenient keystroke.
Multiple Cursors combined with M-^ will collapse all selected lines into one with all extraneous white-space removed.
For example to select an entire buffer, invoke multiple cursors mode, collapse into one line, and then disable multiple cursors mode:
C-x h
M-x mc/edit-lines
M-^
C-g
The Emacs conventional name for "join" is "fill". Yes, you can join
two lines with M-^ -- and that's handy -- but more generally you'll
want to join n lines. For this, see the fill* commands, such as
fill-region, fill-paragraph, etc.
See this for more info
on selecting things which can then be filled.
Also, you can join multiple lines with M-^ by selecting those lines first. (Note that the universal argument does not work with this.)
Just replace newlines with nothing.
I like the way Sublime text Join line with Command J so I do it this way:
(defun join-lines (arg)
(interactive "p")
(end-of-line)
(delete-char 1)
(delete-horizontal-space)
(insert " "))
You could define a new command for this, temporarily adjusting the fill width before using the the Esc-q command:
;; -- define a new command to join multiple lines together --
(defun join-lines () (interactive)
(setq fill-column 100000)
(fill-paragraph nil)
(setq fill-column 78)
)
Obviously this only works, if your paragraph has less than 100000 characters.
I use the following function and bind it to 'M-J'.
(defun concat-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space))
If you prefer to keep your cursor position, you can use save-excursion.
The most simplest way ever:
Select paragraph/lines by M-h or C-SPC
Press M-q
Witness the Emagics (Emacs Magic)!!
Because join-line will left one space between two lines, also it only support join two lines. In case of you want to join plenty of lines without one space left, you can use "search-replace" mode to solve, as follows:
C-%
Query: input C-q C-j Enter
Replace: Enter
Run the replacement. Enter
Done.
Two ways come to mind:
Once you think of it, the most obvious (or at least easiest to remember) way is to use M-q format-paragraph with a long line length C-x-f 1000.
There is also a built-in tool M-^ join-line. More usefully, if you select a region then it will combine them all into one line.
"how could I get it to revert without UNDO?":
(defun toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
(global-set-key (kbd "M-q") 'toggle-fill-paragraph)
From EmacsWiki: Unfill Paragraph
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
A basic join of 2 lines:
(delete-indentation)
I like to line below to be joined to the current without moving the cursor:
("C-j" .
(lambda (iPoint)
"Join next line onto current line"
(interactive "d")
(next-line)
(delete-indentation)
(goto-char iPoint)))
This one behaves like in vscode. So it add space only if join line consisted something else than whitespace. And I bind it to alt+shift+j.
Shorter version based on crux-top-join-line:
(global-set-key (kbd "M-J") (lambda () (interactive) (delete-indentation 1)))
Longer version based on https://stackoverflow.com/a/33005183/588759.
;; https://stackoverflow.com/questions/1072662/by-emacs-how-to-join-two-lines-into-one/68685485#68685485
(defun join-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space)
(unless (looking-at-p "\n") (insert " ")))
(global-set-key (kbd "M-J") 'join-lines)