Function to evaluate haskell in ghci while editing source file using Emacs - haskell

I'm editing a haskell source file. I want to run my main function in my inferior-haskell buffer (already opened in a different frame) and continue editing my source file. To do this, I do
C-c C-l, change frame, main<ret>, change back to original frame
This seems quite inefficient. I'd like an emacs function/key that does it one shot.

There is actually a function to do this already defined in inf-haskell.el: inferior-haskell-load-and-run. This loads your current file and runs :main.
You can bind it to a key in Haskell mode by adding a hook:
(defun my-haskell-mode-hook ()
(local-set-key (kbd "C-x C-r") 'inferior-haskell-load-and-run))
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
However, playing around with this for a bit, it seems to have an odd issue on my computer: sometimes, when it pops to the *haskell* buffer, it doesn't move the point to the end. I find this rather annoying. You can easily fix it by moving the point to the end yourself:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file."
(interactive)
(inferior-haskell-load-and-run inferior-haskell-run-command)
(sleep-for 0 100)
(end-of-buffer))
I believe the sleep-for is necessary because the Haskell command is run asynchronously and takes a little bit of time to return. This whole thing is something of a hack, but it seems to work.
Also, you might want to customize exactly what the inferior-haskell-run-command is. By default, it's :main. However, for me, I think just main would be better because main is affected by :set args ... where :main isn't.
If you want to stay in your current Haskell buffer, you can just do this:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file."
(interactive)
(let ((start-buffer (current-buffer)))
(inferior-haskell-load-and-run inferior-haskell-run-command)
(sleep-for 0 100)
(end-of-buffer)
(pop-to-buffer start-buffer)))

To use interactive-haskell-mode, I found a similar setting than the other answer:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file main function."
(interactive)
(haskell-process-load-file)
(haskell-interactive-mode-run-expr "main"))
(defun my-haskell-mode-hook ()
(local-set-key (kbd "C-x C-r") 'my-haskell-load-and-run))
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
But I have a small issue with it, it always jumps to the end of the source buffer... which can be annoying.

Related

How to switch to Haskell Interactive and reload last line in emacs?

Is there a command available to load the the current buffer to the haskell process and execute the previous line I introduced in the ghci?
I am trying to make a function for this, but I get "Unexpected response from haskell process." because of this line: haskell-interactive-mode-history-previous
(defun reload-haskell-last-line () (interactive)
"blablabla"
(haskell-process-load-file)
(haskell-interactive-switch)
(haskell-interactive-mode-history-previous)
(haskell-interactive-mode-return)
)
This can be super handy for developing.
If this is not the right way, what do you usually use?
Atom haskell-ide repl has a similar feature, that I would like to replicate in emacs

Search visual selction in emacs evil

I want to emulate a behavior I've had in vim, but in emacs evil-mode. I want * to search for the current visually selected text. The code below sort of works, but pressing n or N does not retain the search string
(define-key evil-visual-state-map (kbd "*")
(lambda () (interactive)
(let ((search-string (buffer-substring
(evil-range-beginning (evil-visual-range))
(evil-range-end (evil-visual-range)))))
(evil-normal-state)
(evil-search search-string t))))
I'm new to emacs/elisp. Any ideas on what the "right way" to do this is? In the evil-search.el source I see a function evil-ex-search-update-pattern that may be useful, but I'm not sure how to put it together.
Thanks!
Bailey Ling (a former Vim user) has made a plugin that accomplishes the same thing you're after: https://github.com/bling/evil-visualstar.
You can either install it, or peek through the source code (which may help solve your issue).

Make hook local in emacs

How do I make this hook local:
(add-hook 'text-mode-hook(lambda ()
(set-frame-width (selected-frame) 80) ))
I want it to only effect the current buffer and not new buffers in other modes.
EDIT: found an even better way to narrow the frame to my liking:
(add-hook 'window-configuration-change-hook
(lambda ()
(set-window-margins (car (get-buffer-window-list (current-buffer) nil t)) 24 24)))
This of course is a hook in itself but the question remains the same:
How can I have the margins set to 24 24 when I change to text-mode and have them change back when I switch mode.
Great that a solution was found! For the record, I'll just add that a hook can be made buffer-local in Emacs. This may not be what the original question was after since a buffer-local variable applies to a specific buffer - not a specific mode or frame.
Anyway, the Emacs manual states on Hooks:
If the hook variable is buffer-local, the buffer-local variable will be used instead of the global variable. However, if the buffer-local variable contains the element t, the global hook variable will be run as well.
A hook can be made buffer-local by adding a fourth non-nil argument to add-hook as in:
(add-hook 'text-mode-hook #'the-function-to-add nil t)
See also: Buffer-local after-save-hook?
Hooks are, per definition, not local. They are designed so that whenever a new buffer is created in text mode (in this case), they run their hook.
In your case, this mean that whenever you create a new text file, your frame will be resized.
If you only want to do this once, you can easily create a command that does this.
(defun my-set-frame-width ()
(interactive)
(set-frame-width (selected-frame) 80))
You can call this using M-x my-set-frame-width RET.

Any editor/IDE that supports or could be hacked to support viewing diffs live while editing?

Is there any editor/IDE that provides a live view of differences (probably using diff) while I am editing a file. The ideal setting would be when I open a file for editing in such a diff-mode, the file is buffered in two independent panes (but put side by side), so that when I edit the contents of one, the differences of the two are highlighted for me.
There doesn't seem to be an existing Emacs mode to do exactly what you want, but a cursory googling turned up this and this.
From the second one (with mildly fixed formatting):
(defun diff-buffer-against-file (context)
"diff the current [edited] buffer and the file of the same name"
(interactive "P")
(let (($file buffer-file-name)
($tempFile "/tmp/emacs.diff")
($tempBuffer "emacs.diff"))
(delete-other-windows)
(push-mark (point) t)
(generate-new-buffer $tempFile)
(copy-to-buffer $tempBuffer (point-min) (point-max))
(set-buffer $tempBuffer)
(write-file $tempFile)
(shell-command (concat (if context "diff -c " "diff ") $file " " $tempFile))
(kill-buffer $tempFile)
(pop-mark)))
(global-set-key "\C-cd" 'diff-buffer-against-file)
The operation looks a bit too intense to bind to a change hook, but there's nothing preventing you from doing so if you're into that sort of thing.
Edit: Stefan points out that diff-buffer-with-file exists, and has the behavior you're looking for (it takes a buffer, and diffs that buffer with its file, showing that output in an unfocused temporary buffer), so you don't even need to define the above. I did try it though, and the naive
(defun diff-current (start end len) (diff-buffer-with-file (current-buffer)))
(add-hook 'after-change-functions 'diff-current)
makes editing too uncomfortable for my tastes. You'll probably want to follow Stefan's suggestion and use a timeout instead of diffing immediately on every change.

Change Emacs window appearance when it loses focus

When I program I use two screens with Emacs on both with two buffers split in each window totaling 4 open source files on screen at any one time.
I switch between buffers with C-x b and between Windows with Alt-TAB. I change the appearance of buffers when I switch between them by defining different faces for mode-line and mode-line-inactive. But how do I inactivate a buffer when I switch from the Emacs window completely to another Emacs window via Alt-TAB?
It's probably also relevant that I'm using Emacs 23.2.1 on Ubuntu 11.04 with Gnome 2.32.1.
PS: The question How to automatically save files on lose focus in Emacs is after a different goal but with the same original event of "window losing focus".
It may depend on your window manager and how it manages multiple windows, or frames, in emacs parlance. The code below works like a champ in fvwm but not always in gnome.
I map a keystroke, C-o, to go between frames, this helps when you want to go to the other frame but an alt-tab would take you through a number of superfluous apps on the way.
If you're running a single instance of emacs with two frames you could use something like the following:
(defun pgr-previous-frame ()
"go to the previous frame"
(interactive)
(pgr-switch-frame (previous-frame)))
(defun pgr-next-frame ()
"go to the next frame"
(interactive)
(pgr-switch-frame (next-frame)))
(defun pgr-switch-frame (frame)
"go to the specified frame and raise it"
;; reset the frame properties here
(select-frame frame)
(raise-frame frame)
;;change the display in some manner here
)
You could also try adding some advice to raise-frame and lower-frame haven't tried it but it's worth a try.
I really liked #logoscia answer, which allowed me to do this more generic version. It uses the mode-line-inactive face when no focus.
(add-hook 'focus-out-hook
(lambda ()
(copy-face 'mode-line '--mode-line-backup)
(copy-face 'mode-line-inactive 'mode-line)))
(add-hook 'focus-in-hook
(lambda ()
(copy-face '--mode-line-backup 'mode-line)))
In Emacs 24.4 and later, you can use focus-in-hook and focus-out-hook. This piece of code seems to work, such that the active window of an inactive frame has the same colour as an inactive window:
(defvar my-mode-line-active-background "gray75")
(defvar my-mode-line-inactive-background "gray40")
(defun my-unhighlight-mode-line ()
(set-face-attribute 'mode-line nil
:background my-mode-line-inactive-background))
(add-hook 'focus-out-hook 'my-unhighlight-mode-line)
(defun my-highlight-mode-line ()
(set-face-attribute 'mode-line nil
:background my-mode-line-active-background))
(add-hook 'focus-in-hook 'my-highlight-mode-line)
I don't know if it can be done only with Emacs, but a possible alternative is running wmctrl in a shell script which perodically checks which window has the focus and if there is a change then it lets Emacs know via emacsclient which can send lisp code to a running Emacs for evaluation:
-e'--eval'
Tell Emacs to evaluate some Emacs Lisp code, instead of visiting
some files. When this option is given, the arguments to
`emacsclient' are interpreted as a list of expressions to
evaluate, not as a list of files to visit.

Resources