Displaying info panel at top of buffer - emacs

I'd like to display a few lines at the top of the buffer, but not as part of the actual buffer text, just for display.
Specifically, I'd like to display a Git timeline (not yet released, sorry), like this automatically when I open a file, so I can easily see any recent activity:
P DP D D
T=F=S=S=M=T=W=T=F=S=S=M=T=W=T=F=S=S=M==T==W==T==F==S==S==M==T==W==T==F==S==S==M=
11 18 25 2 9
(Single chars are first initials of people with commits on those days. There will be a legend below as well)
It sounds like I want something like the header line, but for the buffer. Is there anything like that?
One idea I had was to use an overlay at the start of the buffer and put my text there, but I'm not at all sure this is "the right thing" or a completely inappropriate / unsuitable use of this.
I tried, and got it working, using an overlay of the char at (point-min), with the text-property of 'before-string and the string literal above (with newlines and a trailing newline). Here's a proof of concept:
(defun test/add-overlay ()
(interactive)
(setq test/timeline-overlay (make-overlay (point-min) (+ (point-min) 1)))
(overlay-put test/timeline-overlay 'timeline-panel t)
(overlay-put test/timeline-overlay 'before-string
(propertize " P DP D D \nT=F=S=S=M=T=W=T=F=S=S=M=T=W=T=F=S=S=M==T==W==T==F==S==S==M==T==W==T==F==S==S==M=\n 11 18 25 2 9
" 'face 'font-lock-comment-face))
)
(defun test/remove-overlay ()
(interactive)
(remove-overlays (point-min) (point-max) 'timeline-panel t)
)
This does seem to work quite fine, but I'm not sure if it might conflict with something else.
Is this the way to go, or are the more suitable user interface constructs in Emacs to do what I want?

If you can reduce it to a single line, then use header-line-format -- it's local in every buffer. Just set the variable for the buffer you want. See the Emacs sources for examples, e.g., ruler-mode.el.
You seem to have dismissed using a header line, saying that you want something "for the buffer". I don't understand why you think header-line-format does not give you what you want (except that it is one line only).

Yes, if you want display-only text placed at a particular location in the buffer, then an overlay with some after-string or before-string is the way to go.

Related

How to make a function that makes each sentence in a paragraph occupy one line?

I use emacs for my creative writing. To better analyze the structure of my sentences I would like to see my paragraphs displayed as consisting of one sentence per line. So I need a function that can take a normal auto-filled paragraph and do the following: 1) stretches all sentences into one line, and 2) put only one sentence per line.
Imagine I had written the following paragraph (lyrics from Suzanne Vega)
My name is Luka. I live on the second floor. I live upstairs from you. Yes I think you've seen me before. If you hear something late at night. Some kind of trouble. Some kind of fight.
With the function I want the paragraph would appear like this:
My name is Luka.
I live on the second floor.
I live upstairs from you.
Yes I think you've seen me before.
If you hear something late at night.
Some kind of trouble.
Some kind of fight.
Since I would like to do some of the writing when the sentences are displayed like this, the function should in addition to stretching out the sentences also turn off the autofill mode.
Ideally I would like a function that can toggle the display between auto-fill mode with all sentences wrapped, and this new mode with auto-fill turned off and all sentences stretched out.
Thanks in advance to all sort of suggestions or help to make such a function!
#Drew: Here is a text I am not able to split up with your code:
There are two ways to enable it: the first is with M-x visual-line-mode (for those with real menus, apparently Options->Line Wrapping in this Buffer->Word Wrap), which will give you a minor mode “wrap” in the mode line. As explained in C-h f visual-line-mode, one of the effects of this command is to subtly change the effect of commands that deal with “lines”: C-a, C-e no longer go to the end of the line (as in \n), but go to the end of the line (as in display line). M-a, M-e still work as they should. In addition, vertical split windows are guaranteed to not be truncated, and resize properly on changing width. Works wonderfully, especially if you have free form text that you’re keeping in version control (like a thesis in Latex) where hard-wrapping just doesn’t work out very well. It also makes vertical splitting much more useful, especially with huge windows. In my experience, it slows down redraw a little bit, but it’s worth it.
I guess something like this is what you're asking for.
(defun split-para-at-sentence-ends ()
"Split current paragraph into lines with one sentence each.
Then turn off `auto-fill-mode'."
(interactive)
(let ((mode major-mode))
(unwind-protect
(progn (text-mode)
(save-excursion
(let ((emacs-lisp-docstring-fill-column t)
(fill-column (point-max)))
(fill-paragraph))
(let ((bop (copy-marker (progn (backward-paragraph) (point))))
(eop (copy-marker (progn (forward-paragraph) (point)))))
(goto-char bop)
(while (< (point) eop)
(forward-sentence)
(forward-whitespace 1)
(unless (>= (point) eop)
(delete-horizontal-space)
(insert "\n"))))))
(funcall mode)))
(auto-fill-mode -1))
(define-minor-mode split-para-mode
"Toggle between a filled paragraph and one split into sentences."
nil nil nil
(if (not split-para-mode)
(split-para-at-sentence-ends)
(auto-fill-mode 1)
(fill-paragraph)))
(global-set-key "\C-o" 'split-para-mode) ; Or some other key.

Emacs: contextual margin settings or filling text to narrow range of columns?

I'd like to quickly generate text in a buffer that looks like this:
(fact "This is some text which will hang out
only on this part of the screen, ideally
automatically flowing to the correct
margins as I type."
(+ 1 1) => 2
;; more Clojure tests...
)
I have an Elisp keybinding which quickly spits out a starting template and puts my cursor in the right place:
(global-set-key "\C-of" (lambda ()
(interactive)
(insert "(fact \"\"\n\n )")
(backward-char 6)))
Now, when I am typing in the string portion ("This is some text..."), it'd be awesome if I could get Emacs to automatically flow text to the "correct" margins. Is there some way Emacs can be made to adjust margins and wraparound behavior based on where you're typing? At least, the first time you are typing there?
Barring that, for a given selection of text, how can I do the equivalent of fill-region, but with the desired left and right margins? Currently fill-region deletes all space between fact and "This is...., and left-justifies the rest.
There might be a simpler way that I'm overlooking now, but I would just do this:
Configure the text block in a temporary buffer, by doing this there:
a. Set fill-column to the width of the text block that you want.
b. Put the text at the beginning of the line, i.e., not indented.
c. Fill the text.
d. Use indent-rigidly to indent the text to the column you want, except for the first line.
Insert into your target buffer (fact followed by the indentation you want for the first line of the text block. Then insert the contents of the temporary buffer. Then insert whatever other text/code you need.
IOW, I would separate filling the text block from indenting it.
The following seems to work for the moment for my alternative (weaker) case:
;; Set up Midje fact with mark inserted at beginning of comment text
;; (refill as needed in appropriate columns, using C-oF).
(global-set-key "\C-of" (lambda ()
(interactive)
(insert "(fact \"\"\n\n )")
(backward-char 6)
(set-mark (point))))
;; Perform the refill operation to properly reformat the text string
;; in a Midje fact, started with C-of:
(global-set-key "\C-oF" (lambda ()
(interactive)
(set-left-margin (mark) (point) 37)
(fill-region (mark) (point))))
I expect I'll have to tweak this as I get experience using it, but it is pretty close. Still, it'd be nice to figure out how to have this happen automatically, while I'm typing inside the string.

emacs: second toolbar (row)

this is my first question, so apologies for breaking any rules.
I've just started writing some functions in elisp to help me navigate certain types of text files more efficiently. To make these accessible, I've added some buttons to the tool-bar. As it's now becoming busy, I'd like to either: 1) move some of these additional buttons to a second line; or 2) instantiate a second tool-bar that could be placed somewhere else in the frame (either under the existing tool-bar, or perhaps vertically along the side where the scrollbar is).
I've searched high and low but am unable to find an existing example of this and, as I don't yet really know what I'm doing, I wonder if somebody has a code snippet from which I might start to hack a solution together.
Many thanks in advance.
System: CentOS 5/6, emacs for linux 23.1
Edit:
Thanks for the comment, William. Here's a simple example representing what my tool-bar code might do:
;
; functions used by the toolbar
;
;
(defun copy-paste-whole-line ()
"copies and pastes the whole of the current into a new line underneath"
(interactive)
(beginning-of-line)
(set-mark (point))
(end-of-line)
(setq temp (buffer-substring (region-beginning) (region-end)))
(message " copying: %s" temp )
(newline)
(insert temp))
;
;
; population of the toolbar:
;
;
(when (find-image '((:type xpm :file "copy_paste_line.xpm")))
(unless tool-bar-mode (tool-bar-mode 1))
; (setq tool-bar-map (make-sparse-keymap)) ; <- uncomment this line to have only this button present
(tool-bar-add-item
"copy_paste_line"
'copy-paste-whole-line
'copy-paste-whole-line
:help "copies and pastes the whole of the current line into a new line underneath"))
so, as you can see (actually, I'm not allowed to post images until I have 10 reputation points, so you won't be able to see), the code adds an extra button to the end of the existing tool-bar buttons. I believe this to be a reasonable way to achieve this, but I'm not an experienced elisp programmer, so if you think it's poorly written, please comment - I'd like to understand why... :)
If I only had 1 button, it would be ok like that, however, I have multiple buttons. I would, thus, like to add them to a second instance of a similar tool-bar (or, perhaps a vertical one placed where the scrollbars are).
Thanks again for any input.
Frame parameter tool-bar-lines is supposed to control this. You can, for instance, customize option default-frames-alist if you want to change the number of tool-bar rows to 2 or 3 everywhere. Or you can do this on a mode-by-mode or frame-by-frame basis. You can, for instance, use M-: (set-frame-parameter nil 'tool-bar-lines 3).
Depending on your platform (and toolkit), the behavior might be variable. See the Elisp manual, node Layout Parameters and node Tool Bars.
I believe you are out of luck. It seems to me that (at least on ubuntu and cygwin) only one row of buttons in the tool-bar is supported.
Here is what I have tried without luck on both systems:
(progn
(set-frame-parameter nil 'tool-bar-lines 3)
(loop for i from 1 upto 20 do
(setcdr tool-bar-map (cons (cadr tool-bar-map) (cdr tool-bar-map)))))
The following picture shows what I get:
The other buttons appear in a pull-down menu if you click on the little triangle at the right end of the toolbar:
You can restore the old tool-bar with the following commands:
(progn
(setq tool-bar-map (make-sparse-keymap))
(tool-bar-setup))
Finally, I have 3 rows of buttons. This is possible with emacs-w32:
So it is the gtk+ / nextstep problem.

fix an auto-complete-mode and linum-mode annoyance

I'm using auto-complete-mode which I think is totally fantastic. I'm also a big fan of linum-mode but I've got a very irritating issue when the two are used together, especially when I'm working in a new buffer (or a buffer with very few lines).
Basically the buffer is 'x' lines long but when auto-complete kicks in it "adds" lines to the buffer, so linum-mode keeps switching, for example, between displaying line numbers on one column or two columns, depending on whether auto-complete is suggesting a completion or not.
So you type a sentence and you see your buffer's content frantically shifting from left to right at every keypress. It is really annoying.
I take it the solution involves configuring the linum-format variable but I don't know how.
Ideally it would be great if my linum-format was:
dynamic
right-aligned
considering there are 'y' more lines to the buffer than what the buffer actually has
My rationale being that auto-complete shall not suggest more than 'y' suggestion and that, hence, the two shall start playing nicely together.
For example, if 'y' is set to 20 and my buffer has 75 lines, then linum should use two columns: because no matter where I am auto-complete shall not make the buffer 'bigger' than 99 lines.
On the contrary, if 'y' is still set to 20 and my buffer has 95 lines, then linum should use three columns because otherwise if I'm near the end of the buffer and auto-complete kicks in my buffer shall start "wobbling" left and right when I type.
I'd rather not hardcode "3 columns wide" for linum.
I guess using "dynamic but always at least two columns" would somehow fix most annoyances but still something as I described would be great.
P.S: I realize that my 'fix' would imply that linum would always display on at least two columns, and I'm fine with that... As long as it stays right-aligned and use 2, 3 or 4 columns depending on the need.
Simply put the following line in .emacs which resolves this issue. It is in auto-complete.el.
(ac-linum-workaround)
I've written a couple of previous answers on modifying the linum-mode output, which you could probably adapt to your purposes.
Relative Line Numbers In Emacs
Colorize current line number
Edit: Here's the most basic version of that code (also on EmacsWiki, albeit somewhat buried), which doesn't modify the default output at all, but uses the techniques from those other answers to be more efficient than the default code. That's probably a more useful starting point for you.
(defvar my-linum-format-string "%4d")
(add-hook 'linum-before-numbering-hook 'my-linum-get-format-string)
(defun my-linum-get-format-string ()
(let* ((width (length (number-to-string
(count-lines (point-min) (point-max)))))
(format (concat "%" (number-to-string width) "d")))
(setq my-linum-format-string format)))
(setq linum-format 'my-linum-format)
(defun my-linum-format (line-number)
(propertize (format my-linum-format-string line-number) 'face 'linum))
Just have the same problem, after seeing 'patching the source' I believe it could be done with advice. Here is what I come up with
(defadvice linum-update
(around tung/suppress-linum-update-when-popup activate)
(unless (ac-menu-live-p)
ad-do-it))
I would like to use popup-live-p as mentioned but unfortunately it requires the variable for the popup, which we couldn't know in advance.
Update:
I ended up patching the source for linum.el. I added an extra hook that runs before updates.
Here's the patched file: linum.el (github)
Here's the code I have in my init.el:
;; Load custom linum.
(load-file "~/.emacs.d/linum.el")
;; Suppress line number updates while auto-complete window
;; is displayed.
(add-hook 'linum-before-update-hook
'(lambda ()
(when auto-complete-mode
(if (ac-menu-live-p)
(setq linum-suppress-updates t)
(setq linum-suppress-updates nil)))))
Hope it helps!

How to undo fill-paragraph in emacs?

I have a text file that is pretty long. Any easy way to "undo" a M-q (fill-paragraph) on a file that was written and saved a while ago?
For example, I want to change this:
They're coming to take me away,
ha-haaa!! They're coming to take me
away, ho-ho, hee-hee, ha-haaa
To the funny farm. Where life is
beautiful all the time and I'll be
happy to see those nice young men in
their clean white coats and they're
coming to take me away, ha-haaa!!!!!
To this:
They're coming to take me away,
ha-haaa!! They're coming to take me
away, ho-ho, hee-hee, ha-haaa
To the funny farm. Where life is
beautiful all the time and I'll be
happy to see those nice young men in
their clean white coats and they're
coming to take me away, ha-haaa!!!!!
Use the following from my .emacs:
(defun unfill-paragraph ()
(interactive)
(let ((fill-column (point-max)))
(fill-paragraph nil)))
(defun unfill-region ()
(interactive)
(let ((fill-column (point-max)))
(fill-region (region-beginning) (region-end) nil)))
I can't take credit, I googled this years ago.
You can set fill-columnn to a really large number, and fill.
C-u 10000 C-x f M-x fill-individual-paragraphs
Or you can use a little custom function:
(defun refill-paragraphs-to-be-one-line ()
"fill individual paragraphs with large fill column"
(interactive)
(let ((fill-column 100000))
(fill-individual-paragraphs (point-min) (point-max))))
When I asked for help on M-Q (as opposed to M-q) in emacs 24.4.1, I got this:
M-Q (translated from <escape> Q) runs the command unfill-paragraph, which is an
interactive Lisp function in `init-util.el'.
It is bound to M-Q.
(unfill-paragraph &optional REGION)
Takes a multi-line paragraph and makes it into a single line of text.
C-x f 100000 M-q
This fills exactly one paragraph.
Explanation:
C-x f Number: Set a large number (100 000) of characters for the column.
M-q: Invoke the fill-paragraph command. (Alternative for multiple paragraphs: M-x fill-individual-paragraphs)
Afterwards, don't forget to revert the column width back to the previous value (here: 78).
C-x f 78