Emacs Haskell indentation - emacs

Please help me set up proper indentation in Emacs haskell-mode
When I'm trying to type down something like ADT or a record, I'm getting on the wrong column after pressing <ENTER>, and pressing <TAB> won't switch to the right one until I enter either | or ';'!
data MyADT = Oh
| Hi
| Hello
| <- the cursor is here again!
Trying to solve the problem I set
(define-key global-map (kbd "RET") 'reindent-then-newline-and-indent)
in my .emacs file, but it won't indent the current line on pressing <enter> too!
Another strange behaviour: indentation of case
oneChar c = case lookup c simpleEscapes of
| <- what? here?!

It sounds like you type <Enter> and then "|" and then <Tab>. If I do that, I get the same results. But if I type <Enter> and then <Tab> and then <Tab> again it automatically inserts the "|" and lines it up correctly, like so:
data MyADT = Oh
| Hi
|<Cursor>
When I check my haskell-mode version using M-x eval-expression haskell-version <Enter> I get "v2_4".
Emacs haskell-mode doesn't fully analyze the source code, so the "automatic" features are approximate, I think. Typing <Tab> several times on a new line cycles through several possible indentations, and also sometimes inserts text like the "|" for algebraic data types.

Caveat: I'm not a Haskell user, so take this with a grain of salt.
When you press RET after the Hello, Emacs doesn't know you're going to add a | (quick search shows you can have other symbols). The Haskell folks have deemed the proper indentation to be lined up directly below the H in Hello. If the indentation were to automatically line up with the | on the line above, then all the cases where you don't type a | will result in improper indentation. Damned if you do, damned if you don't...
Other programming modes (C/C++, Lisp, Tcl, ...) have the same problem - they cannot know ahead of time what you're going to put on the next line, so the indentation my not be what you'd hoped for.
One solution is to use "electric" keys, which is to say that they insert characters and also force re-indentation. You could easily define | to be electric with the following code:
(defun haskell-electric-| ()
"it's electric! (insert | and indent as long as the | follows whitespace)"
(interactive)
(insert "|")
(if (string-match-p "^\\s-*|" (buffer-substring (line-beginning-position)
(point)))
(haskell-indentation-indent-line)))
(define-key haskell-mode-map "|" 'haskell-electric-|)
I added a check to ensure that the | inserted is preceded by only whitespace, you can customize that however you want or remove the check altogether.
I presume there might also be other symbols in Haskell that would be worth making electric.

I commented the line
;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
And now I'm getting a good "tab" behavior: at least, it allows me to choose a column and does not tie down me to the one it likes. But no auto-indent at all annoys me a little bit, so I'm hoping it is a temporary solution

Related

how can a person add abbreviated names for unicode character names in Emacs

Using emacs-24.
Some unicode names are quite long. Some characters have more than one name depending on the context. I would like to add some abbreviations/synonyms. How?
This approach is not so bad, but I have problems with shorter names that alias with longer ones, and it is non-standard, i.e. not consistent with the way other names are entered:
(global-set-key (kbd "C-x g all") "∀")
The approach of putting characters on keys has problems in Emacs, partly because the keymap is already overloaded:
(define-key key-translation-map (kbd "C-~") (kbd "¬"))
As a secondary question, I am curious as to why this confuses emacs (give it a try):
(global-set-key (kbd "C-x g neg") "¬")
What I would like is to hook the abbreviations into the current emacs method for entering unicode characters by name. (I've been using C-x 8 RET name RET - though wish there was a method to do this in fewer key strokes.)
You can easily define a command that inserts a given character (or that chooses from some small set of characters rather than from the entire universe of Unicode characters).
Library ucs-cmds.el can help with this. When you use C-x 8 RET with a negative prefix arg (e.g. C--), it not only inserts the char you choose but it creates a command to insert the char - the command name is the same as the char name. And you can quickly create such commands for whole ranges or other sets of characters (e.g. by matching a regexp). You can of course rename commands to whatever you like, including shorter versions.
But you already know how to bind a key to a keyboard macro that inserts a given character, as you have shown. If it helps to provide a named command for that then ucs-cmds.el can help.
You can also just do that yourself individually, using, for example:
(defun neg (&optional n)
"Insert \"¬\". With prefix arg N, insert N times."
(interactive "p")
(dotimes (ii n) (insert "¬")))
(global-set-key (kbd "C-x g neg") 'neg)
But you apparently are not very interested in dedicated commands that insert particular characters, and you want to be able to use C-x 8 RET but to type an abbreviation for a character name when it prompts you, instead of trying to match the real character name.
For that, Icicles can help. When you use C-x 8 RET you can match the character name or its code point (or the character itself - useful when the char is easy to type and you want to know its name or code point). You can match any combination of these at the same time.
Matching can be substring, regexp, pcompletion or any of several kinds of fuzzy matching, and you can change the matching behavior on the fly. So you can get the effect of the abbreviations you are asking for, provided you abbreviate in a way that corresponds to matching.
As for your question about (global-set-key (kbd "C-x g neg") "¬"): I think it is a bug. Consider reporting it: M-x report-emacs-bug. This is the error that it raises:
After 0 kbd macro iterations: user-error: No M-x tags-search or M-x tags-query-replace in progress
There are several modes around which provide simplified input for symbols needed by math and logic. For example agda2-mode. http://wiki.portal.chalmers.se/agda
OP:
What I would like is to hook the abbreviations into the current emacs method for entering unicode characters by name. (I've been using C-x 8 RET name RET - though wish there was a method to do this in fewer key strokes.)
What the OP is asking for is:
a) To use the emacs function 'insert-char' with its built-in shortcut 'C-x 8 RET', and
b) To use an alias for completion in the interactive minibuffer for 'insert-char' input.
The issue is that the minibuffer for 'insert-char' has its own TAB completion. If you want to insert the greek small letter epsilon (ε) using TAB completion, you have to input a minimum number of keystrokes like this: "greek" TAB "sm" TAB "l" TAB "ep". Even if you have an alias for epsilon in your 'init.el' configuration file like this: '("eps" "GREEK SMALL LETTER EPSILON")', the minibuffer will not automatically recognize it.
You can still use the alias for epsilon you have in your 'init.el' file using a second function 'expand-abbrev'. Using the method described in the OP, you can get an 'ε' by using "C-x 8 RET" (or "M-x insert-char"), entering your alias "eps", then call 'expand-abbrev' ("M-x expand abbrev") and return. This will expand your alias for the 'insert-char' function. (There is also a 'C-x' shortcut for 'M-x expand-abbrev'.)
Like the OP, I prefer this method over (or in addition to) automatic alias replacement. If you have something in your config file like this:
;; a quick way to insert unicode characters by code point or name
(global-set-key [f8] 'insert-char)
;; call 'expand-abbrev', especially in the 'insert-char' input minibuffer
(global-set-key [f9] 'expand-abbrev)
;; abbreviate unicode names
(define-abbrev-table 'global-abbrev-table '(
("ueps" "GREEK SMALL LETTER EPSILON")
("Ueps" "ε")
("ugsl" "GREEK SMALL LETTER ")
("uforall" "FOR ALL")
("Uforall" "∀")
))
;; see .emacs.d/abbrev_defs
;; M-x edit-abbrevs
;; turn on abbrev mode by default
(setq-default abbrev-mode t)
, you have two ways to type an epsilon. You can let emacs replace the alias "Ueps" automatically, or you can use seven keystrokes "[f8]ueps[f9]RET". (Actually there are four ways here.)
As the OP suggests, it is somewhat impractical to have aliases (or key-bindings) for every single special character. That is why it makes sense to use 'insert-char' with 'expand-abbrev'. If you want to insert a less commonly used greek letter like omicron 'ο', for instance, you do not need a special alias; you can expand an alias like 'ugsl' to "GREEK SMALL LETTER ", and enter "omicron" (or "omi" + TAB).

How to disable underscore (_) subscripting in Emacs, TeX input method

On Emacs, while editing a text document of notes for myself (a .txt document, not a .tex document), I am using M-x set-input-method Ret TeX, in order to get easy access to various Unicode characters. So for example, typing \tospace causes a "→" to be inserted into the text, and typing x^2 causes "x2" to be inserted, because the font I am using has support for Unicode codepoints 0x2192 and 0x00B2, respectively.
One of the specially handled characters in the method is for the underscore key, _. However, the font I am using for Emacs does not appear to have support for the codepoints for the various subscript characters, such as subscript zero (codepoint 0x2080), and so when I type _0, I get something rendered as a thin blank in my output. I would prefer to just have the two characters _0 in this case.
I can get _0 by the awkward keystroke sequence _spacedel0, since the space keystroke in the middle of the sequence causes Emacs to abort the TeX input method. But this is awkward.
So, my question: How can I locally customize my Emacs to not remap the _ key at all when I am in the TeX input method? Or how can I create a modified clone (or extension, etc) of the TeX input method that leaves out underscore from its magic?
Things I have tried so far:
I have already done M-xdescribe-key on _; but it is just bound to self-insert-command, like many other text characters. I did see a post-self-insert-hook there, but I have not explored trying to use that to subvert the TeX input method.
Things I have not tried so far:
I have not tried learning anything about the input method architecture or its source code. From my quick purview of the code and methods. it did not seem like something I could quickly jump into.
So here is the solution I just found: Make a personalized copy of the TeX input method, with all of the undesirable entries removed. Then when using M-x set-input-method, select the personalized version instead of TeX.
I would have tried this earlier, but the built-in documentation for set-input-mode and its ilk does not provide sufficient guidance to the actual source for the input-methods for me to find it. It was only after doing another search on SO and finding this: Emacs: Can't activate input method that I was able to get enough information to do this on my own.
Details:
In Emacs, open /usr/share/emacs/22.1/leim/leim-list.el and find the entry for the input method you want to customize. The entry will be something like the following form:
(register-input-method
"TeX" "UTF-8" 'quail-use-package
"\\" "LaTeX-like input method for many characters."
"quail/latin-ltx")
Note the file name prefix referenced in the last element in the form above. Find the corresponding Elisp source file; in this case, it is a relative path to the file quail/latin-ltx.el[.gz]. Open that file in Emacs, and check it out; it should have the entries for the method remappings, both desired and undesired.
Make a user-local copy of that Elisp source file amongst your other Emacs customizations. Open that local copy in Emacs.
In your local copy, find the (quail-define-package ...) form in the file, and change the name of the package; I used FSK-TeX as my new name, like so:
(quail-define-package
"FSK-TeX" "UTF-8" "\\" t ;; <-- The first argument here is the important bit to change.
"LaTeX-like input method for many characters but not as many as you might think.
...)
Go through your local copy, and delete all the S-expressions for mappings that you don't want.
In your .emacs configuration file, register your customized input method, using a form analogous to the one you saw when you looked at leim-list.el in step 1:
(register-input-method
"FSK-TeX" "UTF-8" 'quail-use-package
"\\" "FSK-customized LaTeX-like input method for many characters."
"~/ConfigFiles/Elisp/leim/latin-ltx")
Restart Emacs and test your new input-method; in my case, by doing M-x set-input-method FSK-TeX, typing a_0, and confirming that a_0 shows up in the buffer.
So, there's at least one answer that is less awkward once you have it installed than some of the workarounds listed in the question (and as it turns out, are also officially documented in the Emacs 22 manual as a way to cut off input method processing).
However, I am not really happy with this solution, since I would prefer to inherit future changes to TeX mode, and just have my .emacs remove the undesirable entries on startup.
So I will wait to see if anyone else comes up with a better answer than this.
I did not test this myself, but this seems to be the exact thing you are looking for:
"How to disable underscore subscript in TeX mode in emacs" - source
Two solutions are given in this blogpot:
By the author of the blogpost: (setq font-lock-maximum-decoration nil) (from maximum)
Mentioned as comment:
(eval-after-load "tex-mode" '(fset 'tex-font-lock-subscript 'ignore))
The evil plugin for vim-like modal keybinding allows to map two subsequent presses of the _ key to the insertion of a single _ character:
(set-input-method 'TeX)
(define-key evil-insert-state-local-map (kbd "_ _")
(lambda () (interactive) (insert "_")))
(define-key evil-insert-state-local-map (kbd "^ ^")
(lambda () (interactive) (insert "^")))
When _ and then 1 is pressed, we get ₁ as before, but
when _ and then _ is pressed, we get _.
Analogous for ^.
As already explained in pnkfelix answer, it seems we have to make a personalized copy of the TeX input method. But here comes a lighter way to do that, without any file tweaking. Simply put the following in your .emacs :
(eval-after-load "quail/latin-ltx"
'(let ((pkg (copy-tree (quail-package "TeX"))))
(setcar pkg "MyTeX")
(assq-delete-all ?_ (nth 2 pkg))
(quail-add-package pkg)))
(set-input-method 'TeX)
(register-input-method "MyTeX" "UTF-8" 'quail-use-package "\\")
(set-input-method 'MyTeX)
The important part is the assq-delete-all line in the middle that remove all shortcut entries starting with _. It's a bit of a lisp hack but it seems to work. Since I'm also annoyed by the shortcuts starting with - and ^, I also use the following two lines to disable them :
(assq-delete-all ?- (nth 2 pkg))
(assq-delete-all ?^ (nth 2 pkg))
Note that afterwards you can M-x set-input-method at any time and indicate TeX or MyTeX to switch between the pristine TeX input method or the customized one.

emacs equivalent of ct

looking for an equivalent cut and paste strategy that would replicate vim's 'cut til'. I'm sure this is googleable if I actually knew what it was called in vim, but heres what i'm looking for:
if i have a block of text like so:
foo bar (baz)
and I was at the beginning of the line and i wanted to cut until the first paren, in visual mode, I'd do:
ct (
I think there is probably a way to look back and i think you can pass more specific regular expressions. But anyway, looking for some emacs equivalents to doing this kind of text replacement. Thanks.
Here are three ways:
Just type M-dM-d to delete two words. This will leave the final space, so you'll have to delete it yourself and then add it back if you paste the two words back elsewhere.
M-z is zap-to-char, which deletes text from the cursor up to and including a character you specify. In this case you'd have to do something like M-2M-zSPC to zap up to and including the second space character.
Type C-SPC to set the mark, then go into incremental search with C-s, type a space to jump to the first space, then C-s to search forward for the next space, RET to terminate the search, and finally C-w to kill the text you selected.
Personally I'd generally go with #1.
as ataylor said zap-to-char is the way to go, The following modification to the zap-to-char is what exactly you want
(defun zap-up-to-char (arg char)
"Like standard zap-to-char, but stops just before the given character."
(interactive "p\ncZap up to char: ")
(kill-region (point)
(progn
(search-forward (char-to-string char) nil nil arg)
(forward-char (if (>= arg 0) -1 1))
(point))))
(define-key global-map [(meta ?z)] 'zap-up-to-char) ; Rebind M-z to our version
BTW don't forget that it has the ability to go backward with a negative prefix
That sounds like zap-to-char in emacs, bound to M-z by default. Note that zap-to-char will cut all the characters up to and including the one you've selected.

Emacs close paren jumps to already existing close-paren when editing clojure code

If having this piece of code in an emacs buffer:
(if (> x 5
true
false))
When I try to edit it in order to fix the parenthesis, something very annoying is happening! When I try to add a closing parenthesis to the if condition, emacs is making the cursor jump to the closing parenthesis after 'false' instead of adding a new parenthesis after 5.
Is this part of some mode, maybe clojure-mode? Do you know how may I fix this? What is this useful for?
It sounds like you're using paredit. Did you install it like recommended on the project page?
As to what it's good for? It's good for editing lists. But you have to buy
into whe whole system, or you'll end up really confused. See the wiki
page.
Do you have this section in your ~/.emacs.el? Just remove it.
;; (require 'paredit) if you didn't install via package.el
(defun turn-on-paredit () (paredit-mode 1))
(add-hook 'clojure-mode-hook 'turn-on-paredit)
Yes, paredit is "different". It will always make sure your parenthesis balance. See http://www.emacswiki.org/emacs/PareditCheatsheet .
For your code, place the cursor beneath the first closing parenthesis and press C-left. Repeat the exercise and it will have moved to where you want it.
Cut&paste (kill & yank in emacs lingo) also allow you to manually screw with the balanced parenthesis, so until you get used to paredit it may be easier to use. Good luck!
how to verify that paredit is the offender
You can type C-h k ) while in your Lisp buffer to see what ) is bound to. If it is bound to paredit-close-round then yes paredit is the offender.
how to disable paredit when you don't know what's triggering it
Try auramo's answer in another thread
or if that doesn't work, try this:
(eval-after-load 'paredit
'(defalias 'paredit-mode 'ignore))
If you are curious about what is triggering paredit-mode in your Emacs, use M-x debug-on-entry RET paredit-mode RET
learning to live with paredit
But still I must encourage you to continue using paredit. Let's keep using paredit and let's see solutions for problems you posed. You asked "Do you know how may I fix this?" I'll just assume you are asking how to fix that if form. Marius Kjeldahl gave you solution which uses paredit-forward-barf-sexp, now in general, if you have some Lisp code where you see that some parens are in wrong places and you want to fix that, you can simply temporarily disable paredit-mode in that buffer (by typing M-x paredit-mode) and then fix your code and then enable paredit-mode again (by typing M-x paredit-mode again). Another thing to consider is that Emacs has undo, so if you arrive at (if (> x 5 true false)) through some action, you can undo that action and start over. Undo is bound to C-z if you use CUA mode.
Still you might find bindings of C-left, C-right to be weird, so you might want to use the following setup:
(eval-after-load 'paredit
'(progn
;; paredit-forward-barf-sexp is usually bound to <C-left>, C-}.
;; here we unbind it from <C-left>
;; so that one can continue to use <C-left> for movement.
(define-key paredit-mode-map (kbd "<C-left>") nil)
;; paredit-forward-slurp-sexp is usually bound to <C-right>, C-).
;; here we unbind it from <C-right>
;; so that one can continue to use <C-right> for movement.
(define-key paredit-mode-map (kbd "<C-right>") nil)
;; paredit-backward-kill-word is bound to M-DEL but not to <C-backspace>.
;; here we bind it to <C-backspace> as well
;; because most people prefer <C-backspace> to M-DEL.
(define-key paredit-mode-map (kbd "<C-backspace>") 'paredit-backward-kill-word)))
You asked "What is this useful for?" by which you may be asking two things:
Why is paredit-close-round useful?
Why does paredit have to bind paredit-close-round to ) when it could have bound it to better keys?
Best way to think of paredit-close-round is to think of it as a counterpart to C-M-u. Move point to | in the following code and try press C-M-u several times to see what happens, and then move point to | again and try press C-M-- C-M-u (i.e. type -u while Control and Alt are on) several times to see what happens.
(when t
(when t
(blah)
(blah))
(when t
(blah | blah)
(blah))
(when t
(blah)
(blah)))
C-M-u is useful for selecting expressions; in order to select an enclosing form or forms, you press C-M-u several times and then C-M-SPC several times. C-M-- C-M-u is useful for evaluating an enclosing form; you press C-M-- C-M-u several times and then C-x C-e to eval the enclosing form.
paredit-close-round basically does what C-M-- C-M-u does.
Why is it an OK thing that paredit binds ) to a command that does something other than simply inserting a close paren? Because you are not supposed to insert a closing parenthesis by yourself. Whenever you insert an open paren, a close paren is also inserted automatically. Whenever you want to change (blah) (blah) to ((blah) (blah)), you simply select the two blah forms and press (.

Emacs copy with regex

I have a text file. Can Emacs select text based on regex and put it in kill-ring, so I can copy it somewhere else? Something like regex-kill-ring-save?
inspired by the already given comments (the Charles answer doesn't work as I would want it), I added a new function to the isearch/isearch-regexp mode map which puts only the matching string into the kill ring (whereas Charles proposal kills from current point to end of matching string):
(defun hack-isearch-kill ()
"Push current matching string into kill ring."
(interactive)
(kill-new (buffer-substring (point) isearch-other-end))
(isearch-done))
(define-key isearch-mode-map (kbd "M-w") 'hack-isearch-kill)
The nice thing about the isearch/isearch-regexp approach (which you can enable with C-s and C-M-s respectively) is that you can see your search string growing and you can copy it with M-w as soon as you are satisfied (and go back to where you have been before with C-u C-Space).
This works for me with Emacs 23.1. Don't know if it will work in all situations. Anyway I hope you find it useful :)
UPDATE: going through the emacswiki I stumbled over KillISearchMatch which suggests more or less the same (plus some more tips ...).
Cheers,
Daniel
I'm not sure if there is such a function already, but what you can do it with a keyboard macro:
Start recording a kbd macro: C-x (
Search for your regexp with search-forward-regexp
Move to the beginning of your match (the text you want to kill) with the various emacs navigation commands, e.g. search or backward-word etc.
Mark: C-spc
Move to the end of your match
Kill the text: C-w
You can then name the keyboard macro with M-x name-last-kbd-macro so that you can execute the macro with a name rather than with C-x e.
If you want to save the macro for future sessions, you can open your .emacs and insert the macro into the buffer with M-x insert-kbd-macro. After than you can bind a key to the macro just like you bind keys to normal emacs functions, e.g. (global-set-key "\C-c m" 'funky-macro-macro).
More about emacs keyboard macros
Isearch+ does this already. It optionally sets the region around the search target. You can use C-SPC C-SPC or M-= C-SPC at any time during Isearch to toggle this.
isearchp-deactivate-region-flag is a variable defined in isearch+.el.
Its value is t
Documentation:
Non-nil means isearching deactivates the region.
See also option isearchp-restrict-to-region-flag.
You can toggle this option using M-= C-SPC during Isearch.
You can customize this variable.