Is It Possible To Replace Fringe Bitmaps With Text in Emacs? - emacs

I'd love to replace the ugly pixel arrows indicating truncated or wrapped lines with simple, tasteful text (maybe even a nice unicode character, like a \u2026 ellipsis). Is this possible?

No, it is not. Fringe “bitmaps” are really bitmaps, that is vectors of 0/1 bits, overlayed over the fringe. There is no way to directly render arbitrary unicode characters onto the fringe.
What you can do, is to render a unicode character into a 0/1 bitmap yourself. Any decent image editor (e.g. Gimp, Photoshop, Pixelmator, Paint.net, etc.) can do this. Then convert this bitmap into an fringe bitmap vector. The format of fringe bitmaps is described in Customizing Fringe Bitmaps.
Eventually you can use these bitmap vectors to replace the left-arrow, right-arrow (for truncated lines), left-curly-arrow, and right-curly-arrow (for continued lines) bitmaps, using the function define-fringe-bitmap.
However, I'd say that this is more hassle than it is worth. The fringe is 8 pixels wide, so you'd have to squeeze your beautiful unicode character into an 8x8 bitmap. This means no subpixel rendering, no aliasing, no bytecode rendering, nothing of what makes characters on the screen nice and fancy. It'd be just as ugly as the arrows you have replaced.

The answer by lunaryorn is correct, but it is perhaps beyond the reach of novice Emacs users -- e.g., programmer hobbyists such as myself.
The function fringe-helper-convert written by Nikolaj Schumacher in his library Fringe Helper -- https://github.com/nschum/fringe-helper.el -- makes it easy for Emacs hobbyists like myself to create a vector that is used by the the function define-fringe-bitmap (which is defined in the C-source code of Emacs). I chose a pilcrow, but the user is free to create any image that will fit -- e.g., using the capital letter X and the period ., the user could create the shape of a letter.
;; AUTHOR: Nikolaj Schumacher -- https://github.com/nschum/fringe-helper.el
(defun fringe-helper-convert (&rest strings)
"Convert STRINGS into a vector usable for `define-fringe-bitmap'.
Each string in STRINGS represents a line of the fringe bitmap.
Periods (.) are background-colored pixel; Xs are foreground-colored. The
fringe bitmap always is aligned to the right. If the fringe has half
width, only the left 4 pixels of an 8 pixel bitmap will be shown.
For example, the following code defines a diagonal line.
\(fringe-helper-convert
\"XX......\"
\"..XX....\"
\"....XX..\"
\"......XX\"\)"
(unless (cdr strings)
;; only one string, probably with newlines
(setq strings (split-string (car strings) "\n")))
(apply 'vector
(mapcar
(lambda (str)
(let ((num 0))
(dolist (c (string-to-list str))
(setq num (+ (* num 2) (if (eq c ?.) 0 1))))
num))
strings)))
The following example assumes a frame-char-height of 20 pixels -- so that the bitmap image is the same height as the text in the buffer. The let-bound snippet creates a pilcrow shape in the right fringe at the end of the line (wherever point is when the snippet is evaluated). The example assumes the right fringe is at least a width of eleven -- e.g., (add-to-list 'default-frame-alist '(right-fringe . 11)) The unicode symbol converted to string -- (char-to-string ?\uE000) could probably be substituted with " ".
(define-fringe-bitmap 'pilcrow (fringe-helper-convert
"......."
"......."
"......."
"......."
"......."
".XXXXXX"
"XXXX.X."
"XXXX.X."
"XXXX.X."
".XXX.X."
"...X.X."
"...X.X."
"...X.X."
"...X.X."
"...X.X."
"...X.X."
"......."
"......."
"......."
"......."))
(let ((peol (point-at-eol)))
(overlay-put (make-overlay peol peol) 'after-string
(propertize (char-to-string ?\uE000) 'display
'(right-fringe pilcrow font-lock-keyword-face))))

Related

Aligning lists in Emacs org-mode with a proportional font?

Does org-mode have a way to correctly align numbered lists (and other indented items) when using a proportional font, like Helvetica?
Thanks!
Not a full fix, but I use the following in my init.el:
;; Ensure the indent face is always fixed pitch. This matches my
;; headline font, and therefore we indent consistent with heading font
;; pitch.
(add-hook 'after-init-hook
(lambda ()
(set-face-attribute 'org-indent nil :inherit 'fixed-pitch)))
This gets the left-hand edge of indents working for me (so they match the indent of headings, for example), but isn't quite right if the bullet/list line is sufficiently long to wrap. Still, it fixes the main problem for me which was these items appearing to be at a higher level than the headings.

Centre Emacs buffer within window

I wrap all my code at 80 columns, and there are times where the Emacs window is wider than 80 columns and there is a lot of unused whitespace on the right side.
I would like to position the Emacs buffer, so all the text is displayed in the middle of the window.
This is different to centre aligning text (more akin to the whitespace on either side of the text when viewing pdfs).
I think this can be achieved by dynamically adjusting the fringe mode widths, depending on the current window size, but I'm not sure where to start. Any ideas?
As demonstrated here this is indeed possible:
(set-fringe-mode
(/ (- (frame-pixel-width)
(* 80 (frame-char-width)))
2))
However, as I am testing this I seem to have more luck with using margins, at least when also resizing my frame:
(defun my-resize-margins ()
(let ((margin-size (/ (- (frame-width) 80) 2)))
(set-window-margins nil margin-size margin-size)))
(add-hook 'window-configuration-change-hook #'my-resize-margins)
(my-resize-margins)
Here is a function which should do what you want, using margins instead of fringes (since I tend to display buffer boundaries in the fringe and I find it becomes ugly if the fringe is too large).
(defun my/center (width)
(interactive "nBuffer width: ")
(let* ((adj (- (window-text-width)
width))
(total-margin (+ adj
left-margin-width
right-margin-width)))
(setq left-margin-width (/ total-margin 2))
(setq right-margin-width (- total-margin left-margin-width)))
(set-window-buffer (selected-window) (current-buffer)))
You ask to display the buffer in the center of the window, which just moves some of the extra whitespace to the left of the buffer, from the right.
How about a solution that eliminates that extra whitespace instead? If that is acceptable, here are two approaches.
If the buffer is alone in its frame, then you can fit the frame to the buffer, using library fit-frame.el. I bind command fit-frame to C-x C-_. This saves space not only within Emacs but for your desktop. (Library zoom-frm.el lets you also shrink/enlarge a frame incrementally, so you can save space by shrinking a frame when you don't need to see its content in detail.)
If not (so the buffer is shown in a frame where there are multiple windows), and if the buffer's window has another window to the left or right of it, then you can do one of the following:
2a. If the buffer's window has another window to the left or right of it, then you can use command fit-window-to-buffer. But you will also need to set option fit-window-to-buffer-horizontally to non-nil.
2b. Use C-{ (shrink-window-horizontally), followed by C-x z z z..., to incrementally shrink the window width (removing the extra whitespace).
2c. Load library face-remap+.el. Whenever you use text-scaling (e.g. C-x C- or C-x =), the window size grows or shrinks along with the text size, so you don't get extra whitespace added at the right when you shrink the text. This is controlled by user option text-scale-resize-window.
Center window mode
https://github.com/anler/centered-window-mode
Global minor mode that centers the text of the window.
If another window is visible the text goes back to normal if its width is less than "cwm-centered-window-width."
Modern answer is https://github.com/rnkn/olivetti or https://github.com/joostkremers/writeroom-mode, both worked immediately for me where other things did not

How to add padding to emacs -nw linum-mode?

I am using Emacs -nw in Ubuntu. I like to turn on linum-mode to see line numbers on the left margin, but the numbers are put right next to my code.
I would love it if there could be some 'padding', like 1-character long, between line number and code. sorry I can't post an image since they are asking for 10 reputation, which I dont have:(
How can I do this?
You can use the variable linum-format to achieve this. Its value can either be a format string or a function which is called with line number as an argument. emacswiki has a couple of example of setting it to a format string
1) The following adds a space after the line-number
(setq linum-format "%d ")
2) You can also add a solid line separator
(setq linum-format "%4d \u2502 ")
I guess the above are sufficient for your needs. You can also find an example of using a function as linum-format here. Add whichever format suits your needs to your init file
In addition to the other answer(s) in this thread, options for putting distance between the line numbers and the text include, but are not limited to, adjusting the fringe width (and also set the color if you so choose).
The fringe is like a vertical ruler that runs from the top to the bottom of the buffer -- the left fringe is sandwiched between the line numbers and the text. It can be invisible if it is the same color as the default background of the user, or it can be a different color.
(setq-default left-fringe-width 10)
(setq-default right-fringe-width 0)
(set-face-attribute 'fringe nil :background "black")

How to interactively read in two inputs and use them in a function call

I am currently taking a class to learn elisp so I have no experience with this language. I am trying to interactively read in two inputs (the width and length of a rectangle) and then use them to call a function to compute the area of the rectangle. The code I have is as follows:
(defun rectangle_Area(w l)
"Compute the area of a rectangle, given its width and length interactively."
(interactive "nWidth: ")
(interactive "nLength: ")
(setq area (rectangleArea w l))
(message "The rectangle's area is %f." area))
Currently I get a wrong number of arguments error.
Like I said, I have no previous experience... all I really need to know is how to store/read in two separate values using interactive.
Thank you for any help
C-hf interactive RET:
To get several arguments, concatenate the individual strings,
separating them by newline characters.
So we have:
(defun rectangle_Area(w l)
"Compute the area of a rectangle, given its width and length interactively."
(interactive "nWidth: \nnLength: ")
(setq area (rectangleArea w l))
(message "The rectangle's area is %f." area))

How do I set the size of Emacs' window?

I'm trying to detect the size of the screen I'm starting emacs on, and adjust the size and position the window it is starting in (I guess that's the frame in emacs-speak) accordingly. I'm trying to set up my .emacs so that I always get a "reasonably-big" window with it's top-left corner near the top-left of my screen.
I guess this is a big ask for the general case, so to narrow things down a bit I'm most interested in GNU Emacs 22 on Windows and (Debian) Linux.
If you want to change the size according to resolution you can do something like this (adjusting the preferred width and resolutions according to your specific needs):
(defun set-frame-size-according-to-resolution ()
(interactive)
(if window-system
(progn
;; use 120 char wide window for largeish displays
;; and smaller 80 column windows for smaller displays
;; pick whatever numbers make sense for you
(if (> (x-display-pixel-width) 1280)
(add-to-list 'default-frame-alist (cons 'width 120))
(add-to-list 'default-frame-alist (cons 'width 80)))
;; for the height, subtract a couple hundred pixels
;; from the screen height (for panels, menubars and
;; whatnot), then divide by the height of a char to
;; get the height we want
(add-to-list 'default-frame-alist
(cons 'height (/ (- (x-display-pixel-height) 200)
(frame-char-height)))))))
(set-frame-size-according-to-resolution)
Note that window-system is deprecated in newer versions of emacs. A suitable replacement is (display-graphic-p). See this answer to the question How to detect that emacs is in terminal-mode? for a little more background.
I've got the following in my .emacs:
(if (window-system)
(set-frame-height (selected-frame) 60))
You might also look at the functions set-frame-size, set-frame-position, and set-frame-width. Use C-h f (aka M-x describe-function) to bring up detailed documentation.
I'm not sure if there's a way to compute the max height/width of a frame in the current windowing environment.
Taken from: http://www.gnu.org/software/emacs/windows/old/faq4.html
(setq default-frame-alist
'((top . 200) (left . 400)
(width . 80) (height . 40)
(cursor-color . "white")
(cursor-type . box)
(foreground-color . "yellow")
(background-color . "black")
(font . "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1")))
(setq initial-frame-alist '((top . 10) (left . 30)))
The first setting applies to all emacs frames including the first one that pops up when you start. The second setting adds additional attributes to the first frame. This is because it is sometimes nice to know the original frame that you start emacs in.
Try adding the following code to .emacs
(add-to-list 'default-frame-alist '(height . 24))
(add-to-list 'default-frame-alist '(width . 80))
The easiest way I've found to do that in an X-Window environment is through X resources. The relevant part of my .Xdefaults looks like this:
Emacs.geometry: 80x70
You should be able to suffix it with +0+0 location coordinates to force it to the upper-left corner of your display. (the reason I don't do it is that I occasionnally spawn new frames, and it makes things confusing if they appear in the exact same location as the previous one)
According to the manual, this technique works on MS Windows too, storing the resources as key/value pairs in the registry. I never tested that. It might be great, it might be much more of an inconvenience compared to simply editing a file.
You can also the -geometry parameter when firing up emacs: emacs -geometry 80x60+20+30 will give you a window 80 characters wide, 60 rows high, with the top left corner 20 pixels to the right and 30 pixels down from the top left corner of the background.
On ubuntu do:
(defun toggle-fullscreen ()
(interactive)
(x-send-client-message nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))
(x-send-client-message nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0))
)
(toggle-fullscreen)
On windows, you could make emacs frame maximized using this function :
(defun w32-maximize-frame ()
"Maximize the current frame"
(interactive)
(w32-send-sys-command 61488))
(setq initial-frame-alist
(append '((width . 263) (height . 112) (top . -5) (left . 5) (font . "4.System VIO"))
initial-frame-alist))
(setq default-frame-alist
(append '((width . 263) (height . 112) (top . -5) (left . 5) (font . "4.System VIO"))
default-frame-alist))
(defun set-frame-size-according-to-resolution ()
(interactive)
(if window-system
(progn
;; use 120 char wide window for largeish displays
;; and smaller 80 column windows for smaller displays
;; pick whatever numbers make sense for you
(if (> (x-display-pixel-width) 1280)
(add-to-list 'default-frame-alist (cons 'width 120))
(add-to-list 'default-frame-alist (cons 'width 80)))
;; for the height, subtract a couple hundred pixels
;; from the screen height (for panels, menubars and
;; whatnot), then divide by the height of a char to
;; get the height we want
(add-to-list 'default-frame-alist
(cons 'height (/ (- (x-display-pixel-height) 200)
(frame-char-height)))))))
(set-frame-size-according-to-resolution)
I prefer Bryan Oakley's settings. However the 'height not work properly in my GNU Emacs 24.1.1.