Skip to content

Latest commit

 

History

History
1020 lines (761 loc) · 36.8 KB

README.org

File metadata and controls

1020 lines (761 loc) · 36.8 KB

Uniline

New: double arrows ↕ ↔

Getting started in 10 seconds

  • Type M-x uniline-mode
  • Move cursor with the arrow-keys on the keyboard → ↑ ↓ ←
  • Quit C-c C-c

Pure UNICODE text diagrams in Emacs

Draw diagrams like those:

Document a command:

images/document-command.png

   pdfjam source.pdf 3-5,9
        ▲    ▲        ▲  ▲
command╶╯    │        │  │
input file╶──╯        │  │
select pages 3,4,5╶───╯  │
and page 9╶──────────────╯

Connect boxes with arrows:

images/boxes-arrows.png

            ╭───────────────────────╮
  ╷123╭────▶┤ hundred and something │
  ╰───╯     ╰───────────────────────╯
                             ╭────▶──╮A╷
    ╭───╮    ┏━━━┓    ╔═══╗  │       ╰─╯
0╶─→┤ 1 ┝━━━▶┫ 2 ┣═══▷╣ 3 ╟──●────▶──╮B╷
    ╰───╯    ┗━┯━┛    ╚═╤═╝  │       ╰─╯
               ╰────←───╯    ╰────▶──╮C╷
                                     ╰─╯
   ╔══════════╗
   ║ 1        ║          ▐▀▀▀▀▀▀▀▀▜
   ║    ╭─────╫───╮ ◁──▷ ▐ 3      ▐
   ╚════╪═════╝ 2 │      ▐▄▄▄▄▄▄▄▄▟
        ╰─────────╯

Explain decisions trees:

images/decision-tree.png

┏━━━━━━━━━━━━┓
┃which color?┃
┗━┯━━━━━━━━━━┛
  │     ╭──────╮
  │  ╭──┤yellow├─▷╮good─choice╭□
  ▽  │  ╰──────╯  ╰═══════════╯
  ╰──●  ╭───╮    ┏━━━━━┓
     ├──┤red├───▷┨dark?┠──╮
     │  ╰───╯    ┗━━━━━┛  │
     │ ╭───◁──────────────╯
     │ │   ╭───╮
     │ ╰─●─┤yes├▷╮regular─red╭─□
     │   │ ╰───╯ ╰═══════════╯
     │   │ ╭──╮
     │   ╰─┤no├─▷╮pink╭────────□
     │     ╰──╯  ╰════╯
     │  ╭────╮
     ├──┤blue├───▷╮next week╭──□
     │  ╰────╯    ╰═════════╯
     │  ╭─────╮
     ╰──┤white├──▷╮available╭──□
        ╰─────╯   ╰═════════╯

Draw lines or blocks:

images/lines-blocks.png

                              ╭─╮←─╮
                         ╭╮   │ │  ╰──╴max 235
                       ╭╮││  ╭╯ │
                       │╰╯│╭─╯  │
      ╭╮               │  ││    │
   ╭─╮││╭╮   ╭──╮╭╮    │  ╰╯    ╰╮
  ╭╯ ╰╯╰╯│  ╭╯  ╰╯╰─╮  │         │ ╭╮
◁─╯      ╰──╯       ╰──╯         ╰─╯╰────▷
◀════════════════════════════════════════▶
                       ╭────────╮
   ▲                   │all time│
   ┃       ▄     ▗▟█ ←─┤highest │
  Qdx      █▌   ████   ╰────────╯
   ┃     ▗▄█▌   █████▙
   ┃   ▟███████▄█████████▄▄▄     ▗▄
   ┃▐▄▄████████████████████████████▄▄▖
    ╺━━━━━━━━━━╸time╺━━━━━━━━━━━━━━━━▶

Explain Lisp lists:

images/lisp-lists.png

  '(a b c)
     ┏━━━┳━━━┓   ┏━━━┳━━━┓   ┏━━━┳━━━┓
●━━━▶┫ ● ┃ ●─╂──▷┨ ● ┃ ●─╂──▷┨ ● ┃nil┃
     ┗━┿━┻━━━┛   ┗━┿━┻━━━┛   ┗━┿━┻━━━┛
       │           ╰──────────╮╰╮
       │  ╭─────┬───────────╮ │ │
       ╰─▷┤"a\0"│properties │ │ │
          ├─────┼───────────┤ │ │
          │"b\0"│properties ├◁╯ │
          ├─────┼───────────┤   │
          │"c\0"│properties ├◁──╯
          ├─────┼───────────┤
          │...  │...        │
          ╵     ╵           ╵

Draw sketched objects:

images/sketched-objects.png

 ◀─(-)────────(+)──▶    ~╭──────╮~
  ▗──────────────╮     ~~│ ╭~~╮ │~~
  ▐              ╰╮     ~│ ╵  ╵ │~
╭□▐   1.5 volts  ╭╯□╮    ╰─╖  ╓─╯
│ ▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘  │      ╠━━╣
│                   ╰──────╯  │
╰─────────────────────────────╯

images/water-sketch.png

 ╶╮       ╭╴
┏┳┥▒▒▒▒▒▒▒┝╸
┃┃│▒▒eau▒▒│
┃┃│▒▒▒▒▒▒▒│ ╔═════╗
┃┃╰──╮▒╭──╯ ║ ╶╮  ▽           ╭╴
┃┃    ▒     ║  │  ░           │
┃┃    ▒     ║  │░░░░░░░░░░░░░░│
┃┃    ╚═════╝  │░░░░░░░░░░░░░░╞════▷▒▒
┃┃             │░░░░░akvo░░░░░│    ╶╮ ▒         ╭╴
┃┃             │░░░░░░░░░░░░░░│     │  ▒        │
┃┃             ╰─┲┳━━━━━━━━┳┱─╯     │▒▒▒▒▒▒▒▒▒▒▒│
┃┃               ┃┃        ┃┃       │▒▒▒water▒▒▒│
┃┃               ┃┃        ┃┃       │▒▒▒▒▒▒▒▒▒▒▒│
┃┃               ┃┃        ┃┃       ╰───────────╯
▝▀▀▀▀▀▀▘        ▝▀▘        ▝▀▘      ▀▀▀▀▀▀▀▀▀▀▀▀▀

Those diagrams are pure text. There is nothing graphic. They are achieved using UNICODE characters. Most often, the text file will be encoded as UTF-8.

Creating such diagrams by hand is painfully slow. Use Uniline to draw lines while you move the cursor with keyboard arrows.

Beware!

If you see those diagrams miss-aligned, most likely the font used to display them does not support UNICODE block characters. See bellow the paragraph “Which fonts?”.

Minor mode

Uniline is a minor mode. Activate it temporarily:

M-x uniline-mode

Exit it with:

C-c C-c

The current major mode is still active underneath uniline-mode.

While in uniline-mode, overwriting is active, as well as long lines truncation. Also, a hollow cursor is provided. Those settings are reset to their previous state when exiting uniline-mode.

Drawing lines

Use keyboard arrows to draw lines.

By default, drawing lines only happens over empty space or over other lines. If there is already text, it will not be erased. However, by hitting the control-key while moving, lines overwrite whatever there is.

The buffer is “infinite” in bottom and right directions. Which means that when the cursor ends up outside the buffer, white space characters are automatically added.

The usual numeric prefix is available. For instance, to draw a line 12 characters wide downward, type: M-12 <down>

Brush style

Set the current brush with:

  •  -  single thin line ╭─┬─╮
  •  +  single thick line ┏━┳━┓
  •  =  double line ╔═╦═╗
  •  #  quarter block ▙▄▟▀
  • <delete> eraser
  • <return> move without drawing anything

The current bush and the current text direction (see below) are reflected in the mode-line (at the bottom of the Emacs screen). It looks like this:

        ╭─current brush
        ▽
→Uniline┼
△
╰──current text direction

The <insert> key

The <insert> key is a prefix for other keys:

  • for drawing arrows, squares, crosses, o-shapes glyphs,
  • for handling rectangles,
  • for inserting # = - + which otherwise change the brush style,
  • for trying a choice of mono-spaced fonts.

Why <insert>? Because:

  • Uniline tries to leave their original meaning to as much keys as possible,
  • the standard meaning of <insert> is to toggle the overwrite mode; but Uniline is already in overwrite-mode, and de-activating overwrite would break Uniline.

So preempting <insert> does not sacrifices anything.

Arrows glyphs ▷ ▶ → ▹ ▸ ↔

At any time, an arrow may be drawn. The arrow points in the direction that the line drawing follows.

Uniline supports 6 arrows types: ▷ ▶ → ▹ ▸ ↔

images/arrow-styles.png

 △    ▵    ↑    ▲    ▴
◁ ▷  ◃ ▹  ← →  ◀ ▶  ◂ ▸
 ▽    ▿    ↓    ▼    ▾

Actually, there are tons of arrows of all styles in the UNICODE standard. Unfortunately, the support by fonts is weak. So Uniline restrains itself to those five safe arrows.

To insert an arrow, type: <insert>a or <insert>aa or <insert>aaa. (a cycles through the 5 styles, A cycles backward).

<insert>4a is equivalent to <insert>aaaa, which is also equivalent to <insert>AAA. Those 3 shortcuts insert an arrow of this style: ▵▹▿◃. The actual direction where the arrow points follows the last movement of the cursor.

To change the direction of the arrow, use shift-arrow, for example: S-<up> will change from to .

Intersection glyphs ■ ◆ ●

There are a few other UNICODE characters which are mono-space and symmetric in the 4 directions. They are great at line intersections:

To insert a square □ ■ ▫ ▪ ◇ ◆ ◊ type: <insert>sss... (s cycles, S cycles backward).

To insert a circular shape · ∙ • ● ◦ Ø ø type: <insert>ooo... (o cycles, O cycles backward).

To insert a cross shape ╳ ÷ × ± ¤ type: <insert>xxx... (x cycles, X cycles backward).

To insert a usual ASCII letter or symbol, just type it.

As the keys - + = # are preempted by Uniline mode, to type them, prefix them with <insert>. Example: <insert>- inserts a - and <insert>+ inserts a +.

images/insert-glyphs.png

<insert>
    │
    ▼
   ╭┴╮   ╭───────╮  ╭─────────────────────╮
   │s├─▶─┤squares├──┤ □  ■  ▫  ▪  ◇  ◆  ◊ │
   ╰┬╯   ╰───────╯  ╰─────────────────────╯
   ╭┴╮   ╭───────╮  ╭─────────────────────╮
   │o├─▶─┼circles┼──┤ ·  ∙  •  ●  ◦  Ø  ø │
   ╰┬╯   ╰───────╯  ╰─────────────────────╯
   ╭┴╮   ╭───────╮  ╭───────────────╮
   │x├─▶─┼crosses┼──┤ ╳  ÷  ×  ±  ¤ │
   ╰┬╯   ╰───────╯  ╰───────────────╯
   ╭┴╮              ╭───╮
   │+├─▶────────────┤ + │
   ╰┬╯              ╰───╯
   ╭┴╮              ╭───╮
   │-├─▶────────────┤ - │
   ╰┬╯              ╰───╯
   ╭┴╮              ╭───╮
   │=├─▶────────────┤ = │
   ╰┬╯              ╰───╯
   ╭┴╮              ╭───╮
   │#├─▶────────────┤ # │
   ╰─╯              ╰───╯

Drawing rectangles

To draw a rectangle in one shot, select a rectangular region with C-SPC or C-x SPC and move the cursor.

You may also use S-<arrow> (<arrow> being any of the 4 directions) to extend the selection. The buffer grows as needed with white spaces to accommodate the selection. Selection extension mode is active when shift-select-mode is non-nil.

If needed, change the brush with any of - + = # <delete>

then hit

  •     r to draw a rectangle inside the selection
  •   S-R to draw a rectangle outside the selection
  •   C-r to overwrite a rectangle inside the selection
  • C-S-R to overwrite a rectangle outside the selection

images/draw-rectangle.png

╭───────╮          r: inside╮╭───────╮
│ one   │          ▗▄▄▄▄▄▄▖╭┤│▛▀▀▀▀▀▜│
│  ┏━━━━┿━━━━━━┓   ▐╭────╮▌│╰┼▌     ▐│
╰──╂────╯ two  ┃   ▐│    │▌│ │▙▄▄▄▄▄▟│
   ┃   ╔═══════╋═╗ ▐│    ├▌╯ ╰─────┬─╯
   ┗━━━╋━━━━━━━┛ ║ ▐╰────╯▌────────┴───╮
       ║  three  ║ ▝▀▀▀▀▀▀▘  R: outside╯
       ╚═════════╝

                       ╭─────────╮
my text I              │my text I│
want to  ╶─<insert>R─▷ │want to  │
box                    │box      │
                       ╰─────────╯

The usual C-_ or C-/ keys may be hit to undo, even with the region still active visually.

Moving rectangles

Select a region, then press <insert>. The selection becomes rectangular if it was not.

Use arrow keys to move the rectangle around. A numeric prefix may be used to move the rectangle that many characters. Be sure to specify the numeric prefix with just digits, without the Alt key. Typing 15<left> moves the rectangle 15 characters to the left. M-15<left> does not work.

Press q, RET, or C-g to stop moving the rectangle.

The C-_ key may also be used to undo the previous movements, even though the selection is still active.

images/move-rectangle.png

                ▲
                │
               <up>
          ╭─────┴──────╮
          │this is     │
          │my rectangle│
◀─<left>──┤I want to   ├─<right>─▶
          │move        │
          ╰─────┬──────╯
              <down>
                │
                ▼

A rectangle can be copied or killed, then yanked somewhere else. Press:

  • c to copy
  • k to kill
  • y to yank (aka paste)

This is similar to the Emacs standard rectangle handling:

  • C-x r r copy rectangle to register
  • C-x r k kill rectangle
  • C-x r y yank killed rectangle

The difference is that Uniline rectangles when killed and yanked, do not move surrounding characters.

Uniline and Emacs standard rectangle share the same storage for copied and killed rectangles, killed-rectangle. So, a rectangle can be killed one way, and yanked another way.

Tracing a contour

images/contour-tracing.png

  ╭──────────────╮
╭─╯A.written.text╰────────╮
│outlined by the.`contour'│
╰─╮function.gets╶┬────────╯
  ╰╮a.surrounding╰───────╮
   ╰─╮line.in.the.current│
     ╰─╮brush.style╭─────╯
       ╰───────────╯

Choose or change the brush style with any of -,+,=_,#,<delete>_. Put the cursor anywhere on the shape or outside but touching it. Then type:

<insert> c

A contour line is traced (or erased if brush style is <delete>) around the contiguous shape close to the cursor.

When hitting capital letter: <insert> C the contour is overwritten. This means that if there was already a different style of line on the contour path, it is overwritten.

The shape is distinguished because it floats in a blank characters ocean. For the shake of the contour function, blank characters are those containing lines as drawn by Uniline (including true blank characters). Locations outside the buffer are also considered blank.

The algorithm has an upper limit of 10000 steps. This avoids an infinite loop in which the algorithm may end up in some rare cases. One of those cases is when the contour crosses a new-page character, displayed by Emacs as ^L. 10000 steps require a fraction of a second to run. For shapes really huge, you may launch the contour command once again, at the point where the previous run ended.

Flood-fill

images/flood-fill.png

this.text.surrounds      this.text.surrounds
.                 /      .▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒/
.                //╶───▷╴.▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒//
...            ////      ...▒▒▒▒▒▒▒▒▒▒▒▒////
  ...a.hole/////           ...a.hole/////

A hollow shape is a contiguous region of identical characters (not necessarily blank), surrounded by a boundary of different characters. The end of the buffer in any direction is also considered a boundary.

Put the cursor anywhere in the hole. Then type:

INS i

Answer by giving a character to fill the hole.

If instead of a character, SPC or DEL is typed, then a shade of grey character is picked. SPC selects a darker grey than the one the point is on, while DEL selects a lighter. There are 5 shades of grey in the UNICODE standard: " ░▒▓█". Those grey characters are well supported by the suggested fonts.

C-y is also an option. The first character in the top of the kill ring will be chosen as the filling character. The kill ring is filled by functions like C-k or M-w, which remove text from the buffer.

Typing RET aborts the filling operation.

A rectangular shape may also be filled.

  • Mark a region
  • INS i
  • answer which character should be used to fill.

There is no limit on the area to fill. Therefore, the filling operation may flood the entire buffer (but no more).

Text direction

Usually, inserting text in a buffer moves the cursor to the right. (And sometimes to the left for some locales). Any of the 4 directions can be selected under Uniline. Just type any of:

INS C-<up>
INS C-<right>
INS C-<down>
INS C-<left>

The current direction is reflected in the mode-line, just before the word “uniline”.

Macros

Uniline adds directional macros to the Emacs standard macros.

Record a macro as usual with C-x (C-x ).

Then call it with the usual C-x e. But then, instead of executing the macro, a menu is offered to execute it in any of the 4 directions.

When a macro is executed in a direction other than the one it was recorded, it is twisted in that direction. This means that recorded hits on the 4 keyboard arrows are rotated. It happens also for shift and control variations of those keys. Direction of text insertion is also rotated.

There is still the classical e option to call the last recorded macro. So instead of the usual C-x e, type C-x e e. And of course, the usual repetition typing repeatedly e is available.

Why are directional macros useful? To create fancy lines. For instance, if we want a doted line instead of the continuous one, we record a macro for one step:

C-x (             ;; begin recording
INS o             ;; insert a small dot
<right> <right>   ;; draw a line over 2 characters
C-x )             ;; stop recording

Then we call this macro repeatedly in any of the 4 directions:

images/macro-doted-line.png

·─·─·─·─·  ╷     ·──·
        │  │     │  │
        ·  ·     ·  ·
        │  │     │  │
        ·  ·─·─·─·  ·
        │           │
        ·─·─·─·─·─·─·

We can draw complex shapes by just drawing one step. Hereafter, we call a macro in 4 directions, closing a square:

images/macro-fancy-squares.png

  ╭╮╭╮╭╮╭╮╭╮╭╮     △ △ △ △ △ △       ╭─╮ ╭─╮ ╭─╮ ╭─╮     ╭─╮ ╭─╮ ╭─╮ ╭─╮
╭─╯╰╯╰╯╰╯╰╯╰╯│    ╶╯╶╯╶╯╶╯╶╯╶╯╷   ╭──╯∙╰─╯∙╰─╯∙╰─╯∙│    ▷┤□├▷┤□├▷┤□├▷┤□├▽
╰╮           ╰╮  ◁╮           ╰▷  │∙               │   ╭┴┼─╯ ╰─╯ ╰─╯ ╰─┼┴╮
╭╯           ╭╯   ╵           ╷   ╰╮               ╰╮  │□│             │□│
╰╮           ╰╮  ◁╮           ╰▷   │               ∙│  ╰┬╯             ╰┬╯
╭╯           ╭╯   ╵           ╷   ╭╯               ╭╯   △               ▽
╰╮           ╰╮  ◁╮           ╰▷  │∙               │   ╭┴╮             ╭┴╮
╭╯           ╭╯   ╵           ╷   ╰╮               ╰╮  │□│             │□│
╰╮           ╰╮  ◁╮           ╰▷   │               ∙│  ╰┬┼─╮ ╭─╮ ╭─╮ ╭─┼┬╯
 │╭╮╭╮╭╮╭╮╭╮╭─╯   ╵╭╴╭╴╭╴╭╴╭╴╭╴    │∙╭─╮∙╭─╮∙╭─╮∙╭──╯   △┤□├◁┤□├◁┤□├◁┤□├◁
 ╰╯╰╯╰╯╰╯╰╯╰╯      ▽ ▽ ▽ ▽ ▽ ▽     ╰─╯ ╰─╯ ╰─╯ ╰─╯       ╰─╯ ╰─╯ ╰─╯ ╰─╯

Which fonts?

A mono-space character font must be used. It must also support UNICODE.

Not all fonts are born equal.

  • (set-frame-font "DejaVu Sans Mono" )
  • (set-frame-font "Unifont" )
  • (set-frame-font "Hack" )
  • (set-frame-font "JetBrains Mono" )
  • (set-frame-font "Cascadia Mono" )
  • (set-frame-font "Agave" )
  • (set-frame-font "JuliaMono" )
  • (set-frame-font "FreeMono" )
  • (set-frame-font "Iosevka Comfy Fixed")
  • (set-frame-font "Source Code Pro" )

Those fonts are known to support the required UNICODE characters, AND display them as mono-space. There are fonts advertised as mono-space which give arbitrary widths to non-ASCII characters. That is bad for the kind of drawings done by Uniline.

You may want to try any of the 10 suggested fonts. Just hit the corresponding entry in the Uniline menu, or type <insert>f. You may also execute the above Lisp commands like that:

M-: (set-frame-font "DejaVu Sans Mono")

This setting is for the current session only. If you want to make it permanent, you may use the Emacs customization:

INS f *

or

M-x customize-face default

Beware that Emacs tries to compensate for missing UNICODE support by the current font. Emacs substitutes one font for another, character per character. The user may not notice until the drawings done under Emacs are displayed on another text editor or on the Web.

To know which font Emacs has chosen for a given character, type:

C-u C-x =

Text menus (Hydra)

Casual usage of Uniline should be easy: just move the point, and lines are traced.

More complex actions are summoned by the INS key, with or without selection. This is a single key to remember. Then a textual menu is displayed, giving the possible keys continuations and their meaning. All that is achieved by the Hydra library, which is now part of Emacs (thanks!).

For seasoned users, those multi-lines textual menus may distract them from their workflow. Beside, they disturb the layout of windows.

It is now possible to switch to less distracting textual menus. They are displayed in the echo-area on a single line.

To do so, type:

  • TAB within a sub-mode (glyph insertion mode, rectangle handling, etc.)
  • C-h TAB at the top-level

This will flip between the two sizes of textual menus. It also affects the welcome message, the one displayed when entering the uniline minor mode.

The current size is controlled by the uniline-hint-style variable:

  • t for full fledged messages over several lines
  • 1 for one-liner messages
  • 0 for no message at all

The variable is “buffer-local”, which means that it can take distinct values on distinct buffers.

There are no customizable uniline variables (not yet). This does not prevent customizing uniline-hint-style for future sessions. For instance, in the ~/.emacs file, there might be:

(use-package uniline
  :config (set-default 'uniline-hint-style 1))

This setting gives one-liner messages. It can be changed later on a buffer per buffer basis with the TAB key. Note the use of set-default. Using setq instead would assign the value 1 only in the ~/.emacs buffer.

Line spacing

The line-spacing setting in Emacs can change the display of a sketch.

The best looking effect is given by:

(setq line-spacing nil)

You may want to change your current setting. Uniline may handle this variable some day. Right now, line-spacing is left as a matter of choice for everyone.

images/line-spacing.png

╭────┬────────┬────╮   ╺┯━━━━┯┯━━┯┯━┯┯━━━━━━━━┯┯━━━━━━━┯┯━━━━━━┯╸
│▒▒▒▒╰────────╯▒▒▒▒│    │    │╰is╯╰a╯│        ││       │╰around╯
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│    ╰this╯       ╰sentence╯╰hanging╯
│▒▒▒╭─╮▒▒▒▒▒▒╭─╮▒▒▒│            △
│▒▒▒╰─╯▒▒▒▒▒▒╰─╯▒▒▒│            │                  △
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│            ╰─────────┬────────╯
╰──────────────────╯                    verbs
             (setq line-spacing nil)

How Uniline behaves with its environment?

Compatibility with Picture-mode

Picture-mode and uniline-mode are compatible. Their features overlap somehow:

  • Both implement an unlimited buffer in east an south directions.
  • Both visually truncate long lines (actual text is not truncated).
  • Both set the overwrite mode (uniline-mode activates overwrite-mode, while picture-mode re-implements it)
  • Both are able to draw rectangles (uniline-mode in UNICODE, picture in ASCII), copy and yank them.

They also have features unique to each:

  • Picture-mode writes in 8 possible directions
  • Picture-mode handles TAB stops
  • Uniline-mode draws lines and arrows

Compatibility with Artist-mode

Artist-mode and uniline-mode are mostly incompatible. This is because Artist-mode preempts the arrow keys, which give access to a large part of uniline-mode features.

However, it is possible to use both one after the other.

Compatibility with Whitespace-mode

Whitespace-mode and uniline-mode are mostly compatible.

Why activate whitespace-mode while in uniline-mode? Because uniline-mode creates a lot of white-spaces to implement an infinite buffer. And it is funny to look at this activity.

To make uniline-mode and whitespace-mode fully compatible, disable the newline visualization:

  • M-x customize-variable whitespace-style
  • uncheck (Mark) NEWLINEs

This is due to a glitch in move-to-column when a visual property is attached to newlines. And uniline-mode makes heavy use of move-to-column.

Compatibility with Org Mode

You may want to customize the shift extension mode in Org Mode. This is because Org Mode preempts shift-select-mode for other useful purposes. Just type:

M-x customize-variable org-support-shift-select

and choose “when outside special context”, which sets it to t.

You then get the shift-selection from Org Mode, not from Uniline. The difference is that the Uniline’s one handles the infinite-ness of the buffer.

Other than that, Uniline is compatible with Org Mode

Org Mode and LaTex

Use the pmboxdraw LaTex module. This gives limited support for “box drawing” characters in LaTex documents.

Example:

#+LATEX_HEADER: \usepackage{pmboxdraw}


this works:
┌─────┐       ┌────────────┐
│     ├───────┤            │
└─────┘       │            │
┌─────┐  ┌────┤            │
│     ├──┘    │            │
└─────┘  ┌────┤            │
┌─────┐  │    │            │
│     ├──┘    └────────────┘
└─────┘

this does not quite work:
   ┏━━━┓  ┏━━┓     ┏━━━━━┓
   ┃   ┃  ┃  ┣━━━━━┫     ┃
   ┃   ┗━━┛  ┃    ┏┛     ┃
   ┗━━━━━━━━━┛    ┗━━━━━━┛

but that is OK:
     ┏━━━┓
     ┃   ┃
     ┗━━━┛

that is OK too:
╺════╦══╗  ╔════╗
     ║ A║  ║ B  ╚══╗
     ╚══╝  ╚═══════╝

this works:

├── dev
└┬┬ release
 │├── new
 │└── old
 ├── graph
 └── non-graph


Note that corners of thin lines should be sharp. There is no support for rounded corners. Uniline does not (yet) draw sharp thin corners. But it can recognize them.

To export this Org Mode example to PDF through LaTex, type:

C-c C-E l o

What about \t tabs?

Some files may contain tabs (the character \t). Those include programming code (Python, Perl, C++, D, Rust, JavaScript and so on).

When Uniline draws something in the middle of a tab, it first converts it to spaces, then proceeds as usual. This process is invisible. So be cautious if tabs have a special meaning in the file.

One way to see what is going on, is to activate the whitespace-mode.

What about ^L page separation?

Uniline does not work well with ^L (page separation) character. Nore with similar characters, like ^T. When trying to draw a line over such a character, the cursor may get stuck. This is because those characters occupy twice the width of a normal character.

Just try to get away from ^L, ^T and such when drawing with Uniline.

Emacs on the Linux console

Linux consoles are the 7 non-graphic screens which can be accessed usually typing C-M-F1, C-M-F2, and so on. Such a screen is also presented when connecting through ssh into a non-graphical server.

By default they use a font named “Fixed” with poor support for Unicode. However, it supports lines of the 3 types, mixing all of them in thin lines though.

Another problem is that by default S-<left> and C-<left> are indistinguishable from <left>. Same problem with <right>, <up>, <down> and <insert>. This has nothing to do with Emacs. A solution can be found here: https://www.emacswiki.org/emacs/MissingKeys

Emacs on a graphical terminal emulator

This is the Emacs launched from a terminal typing emacs -nw. In this environment, <insert> does not exists. It is replaced by <insertchar>. This has already been taken into account by Uniline by duplicating the key-bindings for the two flavors of this key.

If you decide to bind globally C-<insert> to the toggling of Uniline minor mode as suggested, then you will have to do the same for C-<insertchar>, for example with use-package in your ~/.emacs file:

(use-package uniline
  :defer t
  :bind ("C-<insert>"     . uniline-mode)
  :bind ("C-<insertchar>" . uniline-mode))

Emacs on Windows

On Windows the only native mono-spaced fonts are Lucida Console and Courier New. They are not mono-spaced for the Unicodes used by Uniline.

Often, the Consolas font is present on Windows. It supports quite well the required Unicodes to draw lines. A few glyphs produce unaligned result though. They should be avoided under Consolas: △▶▹◇◆

Of course, other fonts may be installed. It is quite easy.

Installation

Add the following lines to your .emacs file, and reload it, if not already done:

(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)

Alternately you may customize this variable:

M-x customize-variable package-archives

Then download the package:

(package-install "uniline")

Alternately, you can download the Lisp file, and load it:

(load-file "uniline.el")

You may want to give uniline-mode a key-binding. use-package in your $HOME/.emacs file is great for that:

(use-package uniline
  :defer t
  :bind ("C-<insert>" . uniline-mode))

In this example, C-<insert> was chosen. You can use whatever keys combination you want. <insert> happens to also be the key used inside Uniline.

Related packages

  • artist-mode: the ASCII art mode built into Emacs.
  • ascii-art-to-unicode: as the name suggest, converts ASCII drawings to UNICODE, giving results similar to those of Uniline.
  • picture-mode: as in Uniline, the buffer is infinite in east & south directions.
  • org-pretty-table: Org Mode tables appear to be drawn in UNICODE characters (actually they are still in ASCII).
  • boxes: draws artistic boxes around text, with nice looking unicorns, flowers, parchments, all in ASCII art.
  • org-drawio: a bridge between the Draw.Io editor and Emacs, producing drawing similar to those of Uniline, but in .svg.
  • syntree: draws ASCII trees on-the-fly from description.
  • unicode-enbox: create a UNICODE box around a text; input and output are strings.
  • unicode-fonts: in Emacs, helps alleviate the lack of full UNICODE coverage of most fonts.
  • org-superstar: prettify headings and plain lists in Org Mode, using UNICODE glyphs.
  • charmap: UNICODE table viewer for Emacs.
  • insert-char-preview: insert UNICODEs with character preview in completion prompt.
  • list-unicode-display: list all UNICODE characters, or a selection of them.
  • show-font: show font features in a buffer.
  • ob-svgbob: convert your ascii diagram scribbles into happy little SVG
  • el-easydraw: a full featured SVG editor right inside your Emacs
  • asciiflow: (not Emacs) draw on the web, then copy-paste your UNICODE text
  • dot-to-ascii.ggerganov.com: (not Emacs) describe your schema in the Graphviz language, and copy-past your UNICODE text.
  • monosketch: (not Emacs) draw on the web, then copy-paste your UNICODE text
  • ibm-box-drawing-hydra.el: keyboard interface to insert UNICODE box-drawing characters one at a time
  • org-excalidraw: integrate SVG images generated by excalidraw into Org Mode
  • rcd-box: create tables surrounded by box-drawing characters from Lisp descriptions
  • ob-diagram: generate various diagrams using diagrams backend
  • ob-mermaid: generate Mermaid diagrams within org-mode babel
  • quail-boxdrawing.el: input method for box drawing characters
  • make-box.el: box around part of a buffer
  • vim drawit ascii diagrams: in Vin, in ASCII

Author, contributors

  • Thierry Banel, author

Feedback:

License

Copyright (C) 2024 Thierry Banel

Uniline is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Uniline is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.