New package "brief" is now officially released in master packages/brief.
The temporary branch scratch/brief is deleted.
Hope you enjoy it!
----- the following duplicates yesterday's post -----
Brief editor is back!
New package Brief editor mode, for emulating the Brief editor, is added
inELPA master branch. Actually, it already reached v5.80, but it
never reached a stage that I consider releasable till now, after 17+
years.
History:
-------------
Starting from 31 May 2001 I started modifying XEmacs CRiSP mode
emulator for my own use on Linux, in order to get a similar
finger-feel like the MS-DOS-based Brief editor which I had been
using for ~10 years at that time. Those days around 2001 the
MS-DOS backward compatibility was getting worse and worse for
every MS-Windows release and which forced me to find a free
replacement for Brief. Then I found the XEmacs+CRiSP mode that
seems to be the best candidate at that moment. It implemented at
least the basic Brief editor functionality but far from a complete
emulator. Therefore I started doing modifications and adding
missing Brief features on a per-need basis.
After 17+ years of intermittent development (as the release of
version 5.80), the code is almost completely rewritten compare to
the original XEmacs CRiSP mode code.
A lot of editor behaviors were also adapted to Emacs. One example
is that Brief mode emulator could respect `visual-line-mode',
`toggle-truncate-lines' and hidden/abbreviated mode texts (which
usually shown as "..." in Emacs) such as org-mode, hideshow mode
and hideif (hide "#ifdef", conditional compilation units, another
package that I had rewritten). When texts are hidden at cursor
line, Brief line-oriented commands like line-cut, line-copy,
line-deletion ... will operate on all hidden lines.
Brief Extension:
------------------------
This Brief mode extends a lot of functionalities that the original
Brief editor don't have. For example, the original Brief <ctrl>-<->
(C--) kills current buffer; however, when prefixed with <ctrl>-<u>
(C-u) the <ctrl>-<-> (C--) command will restore the just killed
buffer. This is convenient as sometimes user accidentally hit C--
for some reason and lost the buffer. Another simple example is the
original Brief command <alt>-<f> (M-f) which shows the file name of
the current buffer; while prefixed with C-u it will also copy the
file name into the clipboard. The following sections list some of
the major extensions of this extended Brief mode.
* Visual mode, line truncation and hidden texts:
(config option: `brief-linecmd-respect-visual')
In the original DOS Brief editor, press [home] key once brings the
cursor to the beginning of the current line; a second [home] key to
the top of the window and the third [home] to the beginning of the
file. In Emacs it's a bit different; it has `toggle-truncate-lines'
to wrap long lines and `visual-line-mode' to do smart word-warp.
This Brief mode emulator thus adapted to Emacs accordingly: if long
lines are wrapped, the first [home] keystroke brings the cursor to
the beginning of the "visual line"; a second [home] then brings the
cursor to the beginning of the "physical line". The third [home] to
the top of the window and finally the fourth [home] to the beginning
of the file. When `toggle-truncate-lines' is enabled and
`visual-line-mode' is off, Brief mode then behaves the same as DOS
Brief. Similar behavior applies to the [end] key, as well as many
other keyboard commands like clipboard copy/paste functions.
This further leads to an user-customizable option:
`brief-linecmd-respect-visual'. This customized variable determines
if a user would like to have line commands (like line-copy, line-cut,
line-deletion...) by default respect visual mode or not. That
variable is by default nil and thus line commands will by default
operate on "physical" line(s) instead of "visual" lines. They
can be overridden by a common prefix C-u or a negative prefix
number.
See the comments of the function `brief-is-visual-operation' for
more detail.
Basically, the rules are:
1. `brief-linecmd-respect-visual' determines the current default
mode, either visual or physical line mode.
2. Either a common prefix C-u (\\[universal-argument]) or negative
prefix reverse the current mode; aka,
(not `brief-linecmd-respect-visual').
Example:
Try editing a text using line deletion command [M-d] on some very
long lines a few times longer than the window width (or shrink
window size), or an org-mode document with long lines. Now either
turn on `visual-line-mode' or enable line wrapping using
`toggle-truncate-lines'. Assuming `brief-linecmd-respect-visual'
is kept default value 'nil' which means physical line operations
are expected by default, now try the following key combinations:
1. [M-d] : delete one "physical" line.
2. [C-u] [M-d] : delete one "visual" line.
3. [C-4] [M-d] : delete four "physical" lines as it's
prefixed with integer '4'.
4. [C-u] [-] [4] [M-d] : delete four "visual" lines as it's
prefixed with integer '-4'.
On the other hand, cursor movement always respects visual mode
unless prefixed with C-u or negative prefix number.
* Fast line number computation cache:
(config option: `brief-replace-emacs-func:line-number-at-pos')
Brief editor window operation relies heavily on cursor position to
determine which window is going to be operated. As the original
Emacs line number computation is too slow (especially when a lot
of texts are hidden within a window) so a line counting caching
mechanism is implemented. By default, the original Emacs function
`line-number-at-pos' is replaced by `brief-fast-line-number-at-pos'
if Emacs version is older than 27 where native line numbering is
not yet supported. There is actually a custom variable named
`brief-replace-emacs-func:line-number-at-pos' defined near the end
of this file. It controls if the `line-number-at-pos' is going
to be replaced or not, regardless of the Brief mode is on or off.
It is recommended to keep the default value for fast line number
calculation which helps Linum mode as well, otherwise, you might
experience big slow down when switching windows using Brief window
commands (i.e. [F1-<arrow>] key).
* Huge clipboard/Xselection texts:
(config option: `brief-enable-postpone-selection')
In the following context and code the term Xselection and clipboard
are used interchangeably and refer to the same thing - the XWindow
selection (mainly "primary" and "clipboard", "secondary" is not
used) or the Windows clipboard. This emulator tries to sync kill-
ring with Xselection even in terminal mode (Xterm).
This Brief mode also implements an asynchronous mechanism to
prevent the selected texts from immediately going into the
Xselection, as all (most) *NIX GUI program currently do -- any
marked/selected text got copied into Xselection with no delay.
This helps to boost performance a lot especially when huge texts
(say, 500Mb texts) are being selected. There is no point to keep
copying texts into clipboard before user completed the text
selection. When the user tries to enlarge the huge selection area,
copying texts into clipboard could take very long and the system
seems to stop responding. The auto-repeated cursor movement key
commands are then accumulated into the key queue and make things
worse. Our Brief mode does not immediately copy texts into
Xselection until the cursor movement key is released, which usually
means a user has completed (say, at least temporarily) the
selection. Unfortunately, this key-releasing event cannot be seen
within Emacs Lisp so we workaround this by detecting if the keyboard
is idle or not. Functions are called asynchronously by the idle
timer.
There is also another important reason for doing so, on Xservers
running on MS Windows with MS office running in the background,
this problem is fatal and usually caused a system crash in the end.
With this selection postponement, we prevented that. For more
detail description about the MS problem, please search the comments
in the following source code containing "Xselection Postponement:".
The solution is not perfect but works for most cases.
A custom option `brief-enable-postpone-selection' is defined to
control if the selection postponement is enabled or not. By
default, it's turned on.
* External Xselection helper programs `xsel' and `xclip':
(config option: `brief-use-external-clipboard-when-possible')
In order to further boost the performance when a user selects huge
texts, external Xselection helper programs are used, although it
increased the complexity of the asynchronous event handling. The
main reason is that the internal Emacs Xselection code is
un-interruptible and not quit-able. When Emacs tries to get/set
Xselection, the operation is blocking and Emacs is not responding
to any key before the operation completes.
For example, when a user selects some huge texts using arrow keys
and paused a short period of time then try to continue enlarging/
shrinking the selection area using arrow keys, the previous Emacs
Xselection get/set operation is usually not completed yet (due to
the size of huge text). Therefore the attempt to continue
enlarging/shrinking texts will be blocked and user will experience
no response until Emacs completed the Xselection operation. What's
more, those continued arrow keys then in turn queued in the Xwindow
system. When Emacs eventually resume responding, the selection
area will be changed accordingly to some earlier keys in the queue
that the user typed a few seconds ago. This kind of non-real-time
response usually confuse the user and sometimes cause problems.
To workaround this we implemented our own non-blocking and quit-able
Xselection get/set functions, with the help of external X utilities
like `xsel' or `xclip'. Therefore user needs to install `xsel' or
`xclip' in the *NIX system to get the benefit. If neither xsel nor
xclip is installed, it will fall back using the Emacs internal
blocking Xselection code. With our non-blocking implementation,
when a user tries to enlarge/shrink/quit a huge text selection
while the Xselection gets/sets operation is in-progress, the
unfinished operation will be interrupted immediately. A user gets
an immediate response.
A custom variable `brief-use-external-clipboard-when-possible' (by
default 't) controls if this Brief mode would invoke external helper
or not. For further detail consult the help message for function
`brief-external-set-selection' and `brief-external-get-selection'.
There are also a few other configuration options controlling if
the progress is showing in the message area or not:
`brief-show-external-clipboard-recv-progress'
`brief-show-external-clipboard-send-progress' ...
With these two options, the user can see the progress when big
clipboard data are transferring.
Also, notice that for terminal mode Emacs under X running Brief mode
the external helpers are always invoked in order to copy/paste texts
with any other windowed mode applications.
* Fast cursor movement:
What I like most about the old DOS Brief editor is its super fast
cursor movement. On a lot of occasions, I didn't even need to do
page-up or page-down. Once you get used to the cursor speed you
really don't want to return to the normal speed. Unfortunately,
this cannot be done in Emacs. However, there is an alternative way
to achieve similar effect -- setting X keyboard autorepeat rate
using the command line `xset' X utility:
# xset r rate 255 100
Although it's still not as fast as DOS Brief editor, it's at least
closer. Also, notice that this will affect the global X window
environment.
Key Binding Compatibility Note:
---------------------------------------------
Notice that the original brief commands keypad-'+' (copy line) and
keypad-'-' (cut line) are now duplicated into <control>-<insert>
(copy line) and <shift>-<delete> (cut line). This is mainly for
keyboards and notebooks without a keypad.
As both <Alt>-<n> (M-n) and <Alt>-<p> (M-p) are so widely used in
various Emacs modes so in the Brief mode M-n and M-p are assigned
"weakly". This means any major mode can override the assignment of
M-n and M-p. In Brief mode, M-n is used for switching to next
buffer while M-- for the previous buffer. Both of them are
frequently used commands, therefore, we also weakly assigned M-+
and M-= for M-n and M-_ for M--. However, for M-p (brief-print)
we do not provide other key combinations for the same key.
For line marking commands, as Emacs regions always start/end at
cursor so the Brief mode region commands <Alt>-<L> <arrow> (M-L
prefixed arrow keys) behave a bit differently from the original
Brief ones (unless I implemented it using the secondary Xselection,
which could lead to more issues). This Brief mode does not
immediately mark the current line until the followed arrow key user
typed. Also, the 'paste' command key <insert> also insert keys
starting from the cursor position instead of the beginning of
current line. On the other hand, 'copy line', 'cut line' and
'delete line' commands work on the beginning of current line like
the original Brief editor did.
For a complete keybinding list, check the following source code
commented with "Brief mode key bindings".
Platform Compatibility Notes:
-----------------------------------------
This brief mode is mainly tested for X window system, as there are
too many combinations of versions (EmacsVers x {OSes} x {XServers})
need to be tested but I don't have all environments (and time).
Therefore, I mainly tested recent Emacs versions on Linux machines
on a daily use basis. For other combinations listed below they
are not heavily tested; usually tested when they are been used.
Test Matrix (note: all 64-bit systems):
On Linux: (including native X11 Emacs, terminal mode Emacs on xterm
and Linux X11 Emacs running on VcXsrv (1.19.3.4+) under
Win10):
Emacs 23.3.1, 24.4.50.2, 25.2.2, 26.0.50, 26.1 and 27.0.50.
Mainly focusing on Emacs 25 ~ 27.
For Emacs23 and 24, not all the functionality behaves the same
as in Emacs 25 ~ 27 (ex. search/replace in region/rectangle).
On Cygwin:
Emacs 25.3.1, 26.1.
On Win10:
Emacs 25.1.1 (x86_64-w64-mingw32).
On WSL (Windows Subsystem for Linux):
Emacs 24.5.1, terminal mode and on VcXsrv (1.19.3.4+).
Enabling Brief Mode:
------------------------------
Enable this package by putting "(require 'brief)" in your .emacs
and "(brief-mode 1)" to enable it. If you want to toggle it later
interactively just use "M-x brief-mode" to toggle it on or off.
Notice that "M-x" may be overridden if `brief-override-meta-x' is
set to non-nil (default value) when you enable brief mode. In this
case use function key #10 "F10 brief-mode" to toggle it off.
The default keybindings for Brief mode override the M-x key to exit
the editor. If you don't like this functionality, you can prevent
this behavior (or redefine it dynamically) by customizing the value
of `brief-override-meta-x' either in your .emacs or interactively.
The default setting is t, which means that M-x will by default
by default run `save-buffers-kill-emacs' instead of the command
`execute-extended-command'.
It is recommended to load the Ibuffer package "(require 'ibuffer)"
before or after loading Brief mode. "M-b" will invoke ibuffer
to show buffer menu if ibuffer package presents, otherwise it by
default runs `buffer-menu'.
This package will automatically load the "scroll-lock.el" package if
you put "(setq brief-load-scroll-lock t)" in your .emacs before
loading this package. If this feature is enabled, it will bind
"<Scroll_Lock>" to the scroll-lock mode toggle. The scroll-lock
package provides the scroll-locking feature in Brief.
Finally, if you want to change the string displayed in the modeline
when this mode is in effect, override the definition of
`brief-mode-mode-line-string' in your .emacs. The default value is
" Brief" which may be a bit lengthy if you have a lot of things
being displayed there.
All these overrides should go *before* the (require 'brief)
statement.
Cygwin 2.x Users:
-------------------------
When the default "mintty" application is used to lunch Cygwin, if
you would like to run Emacs with Brief mode enabled in mintty's
special terminal mode, some mintty window settings need to be
changed:
1. Right-click in the Cygwin "mintty" window on the title bar
2. Choose "Options"
3. At the left sided pane choose "Keys" category
4. Disable (uncheck) the following shortcuts:
Copy and Paste (Ctrl/Shift+Ins)
Switch window (Ctrl+[Shift+]Tab)
Zoom (Ctrl+plus/minus/zero)
Alt+Fn shortcuts
Ctrl+Shift+letter shortcuts
5. Click 'Apply' and 'Save'