├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── FreeBSD ├── Makefile └── manifest.in ├── Makefile.am ├── NEWS ├── README ├── README.FreeBSD ├── README.auto-execute ├── README.bindings ├── README.bsd ├── README.clike-mode ├── README.debian ├── README.dired ├── README.fill-paragraph ├── README.md ├── README.mg3 ├── README.misc ├── README.programmer ├── README.python-mode ├── README.reference ├── README.rpm ├── README.shell-command ├── README.todo ├── README.ucsnames ├── README.undo ├── README.user_macros ├── README.user_modes ├── basic.c ├── bl ├── Makefile.am ├── README ├── dot.mg ├── dot.mg-cygwin ├── dot.mg-xterm └── dot.mg3 ├── bootstrap.sh ├── buffer.c ├── chrdef.h ├── cinfo.c ├── configure.ac ├── cpall.h ├── cpextern.h ├── debian ├── README.Debian ├── README.source ├── changelog ├── control ├── copyright ├── rules └── source │ └── format ├── def.h ├── dir.c ├── dired.c ├── display.c ├── echo.c ├── extend.c ├── file.c ├── fileio.c ├── help.c ├── kbd.c ├── kbd.h ├── key.h ├── keymap.c ├── langmode_c.c ├── langmode_clike.c ├── langmode_make.c ├── langmode_python.c ├── line.c ├── macro.c ├── macro.h ├── main.c ├── match.c ├── modes.c ├── orig ├── Makefile.am ├── README ├── mg.pdf ├── mg.tex ├── mg2a.change ├── mgidx.tex ├── mgprog.doc ├── sys │ ├── README │ ├── bsd │ │ ├── Makefile │ │ ├── README │ │ ├── fileio.c │ │ ├── fileio.c.old │ │ ├── spawn.c │ │ ├── spawn.c.old │ │ ├── sysdef.h │ │ ├── sysdef.h.old │ │ ├── ttyio.c │ │ └── ttyio.c.old │ ├── default │ │ ├── README │ │ ├── alloca.c │ │ ├── chrdef.h │ │ ├── cinfo.c │ │ ├── tty.c │ │ ├── tty.c.old │ │ ├── ttydef.h │ │ ├── ttydef.h.old │ │ ├── ttykbd.c │ │ └── varargs.h │ └── sysv │ │ ├── Makefile │ │ ├── fileio.c │ │ ├── fileio.c.old │ │ ├── spawn.c │ │ ├── sysdef.h │ │ ├── ttyio.c │ │ └── ttyio.c.old └── tutorial ├── paragraph.c ├── random.c ├── region.c ├── search.c ├── slowputc.h ├── spawn.c ├── sys ├── README ├── bsd │ ├── Makefile │ ├── pkg-descr │ └── pkg-plist ├── osx │ ├── README │ └── mg3a.rb ├── rudix │ ├── COPYING │ └── Makefile └── unix │ ├── README │ ├── mgedit.sh │ ├── mgfunc.sh │ └── mgt.sh ├── sysdef.h ├── tty.c ├── ttydef.h ├── ttyio.c ├── ttykbd.c ├── ucs.c ├── ucsnames.c ├── undo.c ├── util.c ├── variables.c ├── version.c ├── wcwidth.c ├── width.c ├── window.c ├── word.c └── xtras ├── Dockerfile ├── Dockerfile.f41 ├── bin ├── mkmg └── mkrpm ├── build-deb.sh ├── build-rpm.sh ├── docker-build.sh └── specs └── mg3a.spec /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | aclocal.m4 3 | compile 4 | configure 5 | depcomp 6 | install-sh 7 | missing 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Robert A. Larson 2 | Bengt Larsson 3 | Pedro Andres Aranda 4 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This is a fork for the original mg3a code by Bengt Larson 2 | 3 | I was in contact with Bengt Larson until April 2017. Then, suddenly, 4 | his email address was cancelled. His repository has not been updated 5 | since the 4th of April, 2017. As of the 15th of December 2017, 6 | www.bengtl.net became inaccessible and thus the original code repository i 7 | www.bengtl.net/files/mg3a is lost. 8 | 9 | -------------------------------------------------------------------------------- /FreeBSD/Makefile: -------------------------------------------------------------------------------- 1 | VERSION= 250114 2 | PKG = mg-${VERSION}.pkg 3 | PREFIX= /usr/local 4 | INSTALL_DIR=${:! pwd !}/stage 5 | 6 | .PHONY: all clean clean-stage 7 | 8 | all: ${PKG} 9 | 10 | realclean: clean 11 | rm -f ${PKG} 12 | clean: clean-stage 13 | rm -f pkg-plist manifest 14 | rm -rf build_dir 15 | 16 | clean-stage: 17 | rm -rf stage 18 | 19 | src: 20 | [ -d src ] && cd src; git pull 21 | [ -d src ] || git clone https://github.com/paaguti/mg3a.git src 22 | 23 | SRC_FILES = ${:! find src -type f !} 24 | 25 | ${PKG}: clean-stage src 26 | mkdir -p ${INSTALL_DIR}${PREFIX} 27 | cd src; pwd; bash bootstrap.sh 28 | cd src; pwd; bash configure 29 | gmake -C src all 30 | echo gmake DESTDIR=${INSTALL_DIR} -C src install 31 | gmake DESTDIR=${INSTALL_DIR} -C src install 32 | cat manifest.in | sed -e 's|%%VERSION%%|${VERSION}|' | sed -e 's|%%PREFIX%%|${PREFIX}|' > manifest 33 | echo ${:! find stage -type f !:C/^stage//} | tr ' ' '\n' > pkg-plist 34 | pkg create -M manifest -r stage -p pkg-plist 35 | -------------------------------------------------------------------------------- /FreeBSD/manifest.in: -------------------------------------------------------------------------------- 1 | name: mg3a 2 | version: %%VERSION%% 3 | origin: editors/mg3a 4 | comment: UTF-8 enabled mg editor 5 | www: https://http://github.com/paaguti/mg3a 6 | maintainer: paaguti@gmail.com 7 | prefix: %%PREFIX%% 8 | desc: UTF-8 enabled mg editor with additional functions 9 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS = 2 | AM_LDFLAGS = 3 | SUBDIRS = . 4 | OSRCS = cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c 5 | SRCS = basic.c dir.c dired.c file.c line.c match.c paragraph.c \ 6 | random.c region.c search.c version.c window.c word.c \ 7 | buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \ 8 | macro.c main.c modes.c ucs.c util.c variables.c width.c \ 9 | langmode_c.c langmode_python.c langmode_make.c langmode_clike.c \ 10 | ucsnames.c undo.c 11 | 12 | OINCS = ttydef.h sysdef.h chrdef.h cpextern.h 13 | INCS = def.h 14 | 15 | mg_SOURCES = $(OSRCS) $(SRCS) $(OINCS) $(INCS) 16 | bin_PROGRAMS = mg 17 | 18 | docdir = $(datadir)/doc/@PACKAGE@ 19 | 20 | install-data-hook: 21 | mkdir -p $(DESTDIR)$(docdir) ; \ 22 | zip -9rD $(DESTDIR)$(docdir)/READMES.zip README \ 23 | README.debian README.programmer README.ucsnames \ 24 | README.auto-execute README.dired README.mg3 README.python-mode README.undo \ 25 | README.bindings README.fill-paragraph README.reference README.user_macros \ 26 | README.bsd README.md README.shell-command README.user_modes \ 27 | README.clike-mode README.misc README.todo ; \ 28 | zip -9rD $(DESTDIR)$(docdir)/samples.zip bl/* ; \ 29 | zip -9rD $(DESTDIR)$(docdir)/orig-doc.zip orig/* 30 | 31 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | I'm moving the development towards autotools 2 | This should make it easier to detect ncursesw on Linux and Rudix 3 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is mg3a, a MicroGNUEmacs clone. The original work was by Bengt Larsson. 2 | Once the original source became unavailable and the author out of reach, 3 | I decided to continue with the editor and make it publicly available 4 | through github. 5 | The first commit in github is Bengt Larsson's original code. 6 | Anything after that is my work. 7 | 8 | Currently mg3a is tested and developed both on Linux and macOS. 9 | I use my own fork for the Rudix package manager to compile and 10 | install it on my macOS machines. Linux development is done on a 11 | stock Ubuntu 20.04 machine and tested on several Debian and Ubuntu 12 | deplyments. 13 | -------------------------------------------------------------------------------- /README.FreeBSD: -------------------------------------------------------------------------------- 1 | To create a FreeBSD package, create a directory and place 2 | Makefile and manifest.in from the FreeBSD directory in it. 3 | Enter this directory directory and 4 | 5 | ```make all clean``` 6 | 7 | to generate the FreeBSD package 8 | -------------------------------------------------------------------------------- /README.auto-execute: -------------------------------------------------------------------------------- 1 | On "auto-execute" and "auto-execute-list": 2 | 3 | You can add only commands by leaving the file pattern(s) empty, and 4 | add only patterns by leaving the command(s) empty. You can also add 5 | several "shebang" tests. Trailing empty parameters can be left out in 6 | a script. 7 | 8 | Example: 9 | 10 | shebang "stringa" 11 | shebang "stringb" 12 | auto-execute "" "some-command" 13 | 14 | This test for two shebangs, and if any of them match, the command is 15 | executed. 16 | 17 | 18 | You can build arbitrary lists: 19 | 20 | shebang "xyz" 21 | auto-execute "*.abc" 22 | auto-execute "*.def" 23 | auto-execute "" "command1" 24 | auto-execute "" "command2" 25 | 26 | is equivalent to: 27 | 28 | shebang "xyz" 29 | auto-execute-list "*.abc;*.def" "command1; command2" 30 | 31 | except that "auto-execute" doesn't treat ";" specially in a file 32 | pattern. 33 | 34 | 35 | If there are no commands, nothing will be executed. 36 | 37 | This alone will work, but do nothing. 38 | 39 | auto-execute "*.allan" 40 | 41 | This alone will give an error. 42 | 43 | auto-execute "" "message hej" 44 | 45 | 46 | There is an internal list where all the tests and commands are stored 47 | in the same list. Only the order in which things are entered into this 48 | list matters. The combination of different tests is always an "or". 49 | 50 | 51 | Matching only once: 52 | 53 | Normally the commands are executed only if the associated tests are 54 | the first ones to pass. This is to enable prioritization among several 55 | sets of tests that pass for a file. Example: 56 | 57 | auto-execute "/some/dir/*.c" "local-set-mode gnuc" 58 | auto-execute "*.c" "local-set-mode stdc" 59 | 60 | You can override this with a numeric parameter 1: 61 | 62 | auto-execute 1 "pattern" "commands" 63 | 64 | This will set a flag in the associated commands so that they will 65 | always execute if the associated tests passed. The 1 must not be 66 | quoted. 67 | 68 | 69 | Performance: 70 | 71 | As an aside my 1.4 GHz Sandy Bridge matches 400000 patterns per 72 | second. So unless you have more than 10000 patterns you don't need to 73 | worry about performance. 74 | 75 | 76 | The null command: 77 | 78 | If you want to have an auto-execute statement that executes nothing, I 79 | suggest using " " for the commands. "" will be interpreted as not 80 | there at all and only a pattern will be entered. 81 | -------------------------------------------------------------------------------- /README.bindings: -------------------------------------------------------------------------------- 1 | Function keys that are assigned: 2 | 3 | , , , : The ANSI keys are statically defined, but 4 | overlaid with terminfo keys in case they 5 | are different. 6 | 7 | ESC , ESC : "backward-word", "forward-word". 8 | 9 | Ctrl-X , Ctrl-X : "previous-buffer", "next-buffer". 10 | 11 | , : "beginning-of-line", "end-of-line". 12 | 13 | ESC , ESC : "beginning-of-buffer", "end-of-buffer" 14 | 15 | , : "scroll-down", "scroll-up" 16 | 17 | ESC , ESC : "scroll-other-window-down", "scroll- 18 | other-window" 19 | 20 | : "delete-char" 21 | 22 | ESC : "kill-word" 23 | 24 | : "help-help" 25 | 26 | 27 | The global bindings (in an xterm): 28 | 29 | Global bindings: 30 | 31 | C-@ set-mark-command 32 | C-a beginning-of-line 33 | C-b backward-char 34 | C-d delete-char 35 | C-e end-of-line 36 | C-f forward-char 37 | C-g keyboard-quit 38 | C-h help 39 | TAB insert-tab 40 | C-j newline-and-indent 41 | C-k kill-line 42 | C-l recenter-top-bottom 43 | RET newline 44 | C-n next-line 45 | C-o open-line 46 | C-p previous-line 47 | C-q quoted-insert 48 | C-r isearch-backward 49 | C-s isearch-forward 50 | C-t transpose-chars 51 | C-u universal-argument 52 | C-v scroll-up 53 | C-w kill-region 54 | C-x c-x prefix 55 | C-y yank 56 | C-z suspend-emacs 57 | ESC esc prefix 58 | C-_ undo 59 | SPC .. ( self-insert-command 60 | ) blink-and-insert 61 | * .. ~ self-insert-command 62 | DEL delete-backward-char 63 | 64 | C-h C-g keyboard-quit 65 | C-h C-h help-help 66 | C-h a apropos 67 | C-h b describe-bindings 68 | C-h c describe-key-briefly 69 | 70 | C-x C-b list-buffers 71 | C-x C-c save-buffers-kill-emacs 72 | C-x C-f find-file 73 | C-x C-g keyboard-quit 74 | C-x C-j dired-jump 75 | C-x C-l downcase-region 76 | C-x C-o delete-blank-lines 77 | C-x C-q toggle-read-only 78 | C-x C-r find-file-read-only 79 | C-x C-s save-buffer 80 | C-x C-u upcase-region 81 | C-x C-w write-file 82 | C-x C-x exchange-point-and-mark 83 | C-x ( start-kbd-macro 84 | C-x ) end-kbd-macro 85 | C-x + balance-windows 86 | C-x - shrink-window-if-larger-than-buffer 87 | C-x 0 delete-window 88 | C-x 1 delete-other-windows 89 | C-x 2 split-window-vertically 90 | C-x 4 c-x 4 prefix 91 | C-x = what-cursor-position 92 | C-x ^ enlarge-window 93 | C-x b switch-to-buffer 94 | C-x d dired 95 | C-x e call-last-kbd-macro 96 | C-x f set-fill-column 97 | C-x g goto-line 98 | C-x h mark-whole-buffer 99 | C-x i insert-file 100 | C-x k kill-buffer 101 | C-x n other-window 102 | C-x o other-window 103 | C-x p previous-window 104 | C-x s save-some-buffers 105 | C-x u undo 106 | 107 | 108 | C-x ESC O C next-buffer 109 | C-x ESC O D previous-buffer 110 | 111 | C-x 4 C-f find-file-other-window 112 | C-x 4 C-g keyboard-quit 113 | C-x 4 C-j dired-jump-other-window 114 | C-x 4 0 kill-buffer-and-window 115 | C-x 4 b switch-to-buffer-other-window 116 | C-x 4 d dired-other-window 117 | C-x 4 f find-file-other-window 118 | C-x 4 r find-file-read-only-other-window 119 | 120 | C-x 8 RET ucs-insert 121 | 122 | ESC C-g keyboard-quit 123 | ESC C-v scroll-other-window 124 | ESC C-w append-next-kill 125 | ESC SPC just-one-space 126 | ESC ! shell-command 127 | ESC % query-replace 128 | ESC - negative-argument 129 | ESC 0 digit-argument 130 | ESC 1 digit-argument 131 | ESC 2 digit-argument 132 | ESC 3 digit-argument 133 | ESC 4 digit-argument 134 | ESC 5 digit-argument 135 | ESC 6 digit-argument 136 | ESC 7 digit-argument 137 | ESC 8 digit-argument 138 | ESC 9 digit-argument 139 | ESC ; comment-line 140 | ESC : eval-expression 141 | ESC < beginning-of-buffer 142 | ESC > end-of-buffer 143 | ESC \ delete-horizontal-space 144 | ESC ^ join-line 145 | ESC b backward-word 146 | ESC c capitalize-word 147 | ESC d kill-word 148 | ESC f forward-word 149 | ESC h mark-paragraph 150 | ESC i insert-tab-8 151 | ESC l downcase-word 152 | ESC m back-to-indentation 153 | ESC q fill-paragraph 154 | ESC r move-to-window-line-top-bottom 155 | ESC s search-forward 156 | ESC t transpose-words 157 | ESC u upcase-word 158 | ESC v scroll-down 159 | ESC w copy-region-as-kill 160 | ESC x execute-extended-command 161 | ESC { backward-paragraph 162 | ESC } forward-paragraph 163 | ESC ~ not-modified 164 | ESC DEL backward-kill-word 165 | 166 | 167 | ESC ESC O C forward-word 168 | ESC ESC O D backward-word 169 | ESC ESC O F end-of-buffer 170 | ESC ESC O H beginning-of-buffer 171 | 172 | 173 | ESC ESC [ 3 ~ kill-word 174 | 175 | ESC ESC [ 5 ~ scroll-other-window-down 176 | 177 | ESC ESC [ 6 ~ scroll-other-window 178 | 179 | ESC O A previous-line 180 | ESC O B next-line 181 | ESC O C forward-char 182 | ESC O D backward-char 183 | ESC O F end-of-line 184 | ESC O H beginning-of-line 185 | ESC O P help-help 186 | 187 | ESC [ A previous-line 188 | ESC [ B next-line 189 | ESC [ C forward-char 190 | ESC [ D backward-char 191 | 192 | ESC [ 3 ~ delete-char 193 | 194 | ESC [ 5 ~ scroll-down 195 | 196 | ESC [ 6 ~ scroll-up 197 | 198 | ESC g g goto-line 199 | 200 | ESC g ESC g goto-line 201 | 202 | 203 | Buffer menu: a small subset of GNU Emacs buffer menu. 204 | 205 | "buffer-menu" - Show a buffer list in the same window. 206 | 207 | "buffer-menu-other-window" - Show a buffer list in another window and switch 208 | to it. 209 | 210 | 211 | Bindings in *Buffer List* (these bindings are a subset of those in GNU 212 | Emacs): 213 | 214 | Local keybindings for mode bufmenu: 215 | 216 | RET Buffer-menu-this-window 217 | C-o Buffer-menu-switch-other-window 218 | 1 Buffer-menu-1-window 219 | 2 Buffer-menu-2-window 220 | ? describe-bindings 221 | e Buffer-menu-this-window 222 | f Buffer-menu-this-window 223 | h describe-bindings 224 | o Buffer-menu-other-window 225 | q quit-window 226 | 227 | 228 | Bindings in Dired (also subset): 229 | 230 | Local keybindings for mode dired: 231 | 232 | C-d dired-flag-file-deleted 233 | RET dired-find-file 234 | SPC next-line 235 | + dired-create-directory 236 | 1 dired-find-file-one-window 237 | < dired-prev-dirline 238 | > dired-next-dirline 239 | ? describe-bindings 240 | ^ dired-up-directory 241 | c dired-copy-file 242 | d dired-flag-file-deleted 243 | e dired-find-file 244 | f dired-find-file 245 | g revert-buffer 246 | h describe-bindings 247 | n next-line 248 | o dired-find-file-other-window 249 | p previous-line 250 | q quit-window 251 | r dired-rename-file 252 | u dired-unflag 253 | x dired-do-deletions 254 | DEL dired-unflag-backward 255 | 256 | 257 | Bindings in a help buffer: 258 | 259 | Local keybindings for mode helpbuf: 260 | 261 | ? describe-bindings 262 | h describe-bindings 263 | q quit-window 264 | -------------------------------------------------------------------------------- /README.bsd: -------------------------------------------------------------------------------- 1 | 20171226: A first version of the FreeBSD port infrastructure 2 | 3 | I have created a first version of the infrastructure needed to install 4 | mg3a from the ports. Files are part of the 02-Makefile.bsd patch 5 | 6 | To install mg3a on FreeBSD using the ports: 7 | 8 | git clone 9 | cd mg3a 10 | quilt push -a 11 | cd sys/bsd 12 | sudo make install 13 | sudo make clean 14 | -------------------------------------------------------------------------------- /README.debian: -------------------------------------------------------------------------------- 1 | The debian/ directory will allow you to create a .deb pacakge for mg3a 2 | in your Debian based distribution. You can then install it using dpkg. 3 | 4 | CAVEATs: new debian features are included as quilt patches. 5 | This way I can preserve the original mg3a code 6 | 7 | I usually create the .deb package the lazy way with 8 | fakeroot debian/rules clean binary 9 | Purists can always improve this ;-) 10 | -------------------------------------------------------------------------------- /README.dired: -------------------------------------------------------------------------------- 1 | Dired is optional. There are a lot of options in GNU Emacs Dired. 2 | These are the ones that are implemented. 3 | 4 | Commands: 5 | 6 | "dired" Ask for a directory, open a display of the directory in 7 | the current window. 8 | 9 | "dired-other-window" As dired, in another window. 10 | 11 | "dired-jump" Do a dired of the directory of the file in the current 12 | buffer, moving the cursor to the current file. Do a dired 13 | in the current directory if no file. 14 | 15 | "dired-jump-other-window" As dired-jump, in another window. 16 | 17 | 18 | Global key assignments: 19 | 20 | "Ctrl-X d" dired 21 | 22 | "Ctrl-X 4 d" dired-other-window 23 | 24 | "Ctrl-X Ctrl-J" dired-jump 25 | 26 | "Ctrl-X 4 Ctrl-J" dired-jump-other-window 27 | 28 | 29 | Assignments in a Dired window: 30 | 31 | "e", "f", RET Open the file in the current window. 32 | 33 | "o" Open the file in another window. 34 | 35 | "+" Create a directory 36 | 37 | "1" Open the file in one window. 38 | 39 | "d", Ctrl-D Mark file for deletion. 40 | 41 | "u" Unmark file for deletion. 42 | 43 | DEL Unmark the file above for deletion, and backup. 44 | 45 | "x" Delete the files marked for deletion. 46 | 47 | "c" Copy file. 48 | 49 | "r" Rename file. 50 | 51 | "^" Open a display of the parent directory, moving 52 | the cursor to this directory. 53 | 54 | ">" Move to the next subdirectory. 55 | 56 | "<" Move to the previous subdirectory. 57 | 58 | "g" Re-read the directory ("revert-buffer") 59 | 60 | "q" Quit the window. 61 | 62 | 63 | Press "h" in a Dired window for a listing of local bindings. 64 | -------------------------------------------------------------------------------- /README.fill-paragraph: -------------------------------------------------------------------------------- 1 | "fill-paragraph" works differently from in Emacs, except for the most 2 | simple function. You can set options in the variable "fill-options" 3 | and you can also set (invert) them by giving an argument to 4 | "fill-paragraph". Useful modes to do interactively are: 5 | 6 | 2 An argument of 2 to "fill-paragraph" turns on adaptive fill. 7 | This fill is not as smart as the one in Emacs, but it does do 8 | indented paragraphs, and paragraphs where you use delimiters 9 | as bullets. The exact algorithm is: 10 | 11 | 1) Find the first non-blank line in the current paragraph. 12 | 13 | 2) Find the first non-blank character that is part of a 14 | sequence of non-blank characters which contains at least 15 | one of: 1) an alphanumeric character, 2) One of the quotes 16 | '"', "'", U+00AB, U+00BB, U+2039, U+203A or U+2018-U+201F. 17 | 18 | 3) Fill the paragraph forward with the left margin at the 19 | column found in 2). 20 | 21 | The adaptive fill is very useful to set as default in "fill- 22 | options". It isn't default to remain compatible with old Mg. 23 | 24 | 25 | 4 An argument of 4 (or plain ^U) turns on manual fill. In this, 26 | the current cursor is used to indicate where the first word of 27 | the paragraph starts. Subsequent lines (until a blank line) 28 | are aligned under the cursor, filling with tabs and blanks to 29 | the left. 30 | 31 | 8 An argument of 8 turns on replicated fill, or fill with prefix 32 | if you prefer. It does the same as 4, but replicates the 33 | content of the indent of the first line onto following lines, 34 | ignoring the content of the indent there. The paragraph ends 35 | where there are only blanks on or after the cursor column. 36 | 37 | 64 Works like an argument of 2, except that it considers word 38 | characters to be alphabetic, rather than alphanumeric. 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mg3a 2 | An extended mg clone 3 | 4 | This is a fork for the original mg3a code by Bengt Larson 5 | 6 | ## Status 7 | 8 | I was in contact with Bengt Larson until April 2017. Then, suddenly, his email address was cancelled. 9 | His repository has not been updated since the 4th of April, 2017. As of the 15th of December 2017, www.bengtl.net became inaccessible and thus the original code repository www.bengtl.net/files/mg3a is lost. 10 | 11 | ## Intent of this repository 12 | 13 | The intent of this repository is to preserve the original code and establish a home for further developing this very nice piece of software. My focus will be on Debian/ubuntu, OSX and FreeBSD, which are the three operating systems I use. I'll try not to break things too much and keep compatibility wiht MinGW/CygWin (although it's ages I haven't actively developed anything for that environment) 14 | 15 | ## What is original, what has been added 16 | 17 | The closest to the original code is the first tag (https://github.com/paaguti/mg3a/releases/tag/20171130) in this github. My initial additions have initially been included as patches in the Debian building infrastructure (which is also mine) I have included a FreeBSD ports directory under sys/bsd and the Homebrew .rb file from my OSX Homebrew personal tap. under sys/osx. 18 | 19 | As of 20180101, I have integrated all patches in the master branch. 20 | 21 | ## Licensing, etc. 22 | 23 | Refer to the different README.* files 24 | 25 | ## Ways of working 26 | 27 | Use quilt to add features or correct bugs. The home for the patches is in debian/patches. Create pull requests that include the full patch. 28 | 29 | -------------------------------------------------------------------------------- /README.mg3: -------------------------------------------------------------------------------- 1 | This is Mg3a, a public domain MicroEMACS-based editor with commands 2 | and key-bindings similar to GNU Emacs. It is a development of the 3 | earlier public domain Mg2a editor, with the addition of functions to 4 | deal with UTF-8, CRLF/LF line endings, and some other updates. 5 | 6 | The original README and documents for Mg2a are in orig/. 7 | 8 | If you are on Cygwin, Mg3a now defaults to LF line endings. You can 9 | set them to CRLF by putting this in a file .mg in your home directory: 10 | 11 | (set-default-mode "crlf") 12 | 13 | If you have files in an old 8-bit character set, and if you are in a 14 | UTF-8 locale, you may want to add a command to set the default 8bit 15 | character set. Default is CP1252. For example: 16 | 17 | (set-default-8bit-charset "cp1250") 18 | 19 | "list-charsets" lists the available charsets. 20 | 21 | 22 | Commands are documented in README.reference. README.programmer and 23 | README.misc include some extra info. README.bindings lists the default 24 | bindings. 25 | 26 | 27 | bl/ contains some examples of mg init files. 28 | sys/ contains some files useful for various systems. 29 | 30 | 31 | Compiling with "make" creates an "mg" in the current directory. There 32 | is an "install" entry in the Makefile for Linux/BSD/OSX. 33 | 34 | ## INACTIVE -- Report bugs to: mg3abugs(at)bengtl.net 35 | -------------------------------------------------------------------------------- /README.misc: -------------------------------------------------------------------------------- 1 | Startup files: 2 | 3 | Starting from 170703, Mg can be placed at the end of a pipe. 4 | It will then read the pipe and display the output in 5 | a READ ONLY buffer named *stdin*: 6 | 7 | ls | mg 8 | 9 | Time consuming commands will make mg to show the *scratch* buffer until 10 | the pipe is fully read. 11 | 12 | For compatibility, Mg reads two startup files if they exist, .mg-$TERM 13 | and .mg, in that order. Startup execution is below. 14 | 15 | 16 | Command line options: 17 | 18 | -q Don't run startup files. 19 | 20 | -p pattern Set the initial search pattern. 21 | 22 | -L loadfile Load a file after startup scripts. 23 | 24 | -l loadfile Load a file after startup. 25 | 26 | -e commands Execute a command list after startup and after -l. 27 | 28 | When Mg starts with two arguments (after options) and one starts with 29 | "+" as "mg +number file" or "mg file +number", the file is visited at 30 | that line number. A negative number counts backwards from the end of 31 | file. "+" without a number or "+0" goes to the end of file. 32 | 33 | 34 | Startup execution: 35 | 36 | if (exist $HOME/.mg3) 37 | load $HOME/.mg3-$TERM 38 | load $HOME/.mg3 39 | elseif (exist $HOME/.mg) 40 | load $HOME/.mg-$TERM 41 | load $HOME/.mg 42 | else 43 | load /etc/mg3 44 | endif 45 | load "-L" script 46 | visit file(s) 47 | read stdin to *stdin* buffer if mg at end of pipe 48 | goto "+" line 49 | load "-l" script 50 | execute "-e" commands. 51 | 52 | 53 | Arguments: 54 | 55 | A universal-argument (^U) to "revert-buffer" reverts a buffer without 56 | asking. 57 | 58 | A universal-argument (^U) to "kill-buffer-quickly" kills a buffer 59 | without asking even when it has an associated file and is modified. 60 | 61 | Any argument to "save-buffers-kill-emacs" saves all modified buffers 62 | without asking before exiting. There is a warning, that can be turned 63 | off, because the previous behavior was the opposite (to not save). 64 | 65 | Any argument to "save-some-buffers" saves all modified buffers without 66 | asking. 67 | 68 | Any argument to "list-charsets" shows a simplified list with only the 69 | charset names. 70 | 71 | Any argument to "list-buffers" or "buffer-menu" makes these commands 72 | show the number of lines in addition to the size, in wider fields and 73 | right-adjusted. If the argument is 0, the buffer name is not 74 | truncated. 75 | 76 | Any argument to "list-variables" lists local variables even if they are 77 | unset. 78 | 79 | Any argument to "redraw-display" shows the size of the display rather 80 | than redrawing. 81 | 82 | Arguments to "what-cursor-position" (^X =): 83 | 84 | For 8-bit and UTF-8: 85 | 86 | Any argument: shows Unicode as U+xxxx, decimal and octal 87 | 88 | For combined characters, numeric or repeated universal argument: 89 | 90 | show raw values in hex (default) 91 | 1: Unicode as U+xxxx (^U) 92 | 2: raw values in decimal (^U^U) 93 | 3: Unicode in decimal (^U^U^U) 94 | 4: raw values in octal (^U^U^U^U) 95 | 5: Unicode in octal (^U^U^U^U^U) 96 | 97 | An argument to "fill-paragraph" can set options. See README.reference. 98 | 99 | 100 | Cygwin auto-mode: 101 | 102 | On Cygwin, files visited with names ending with ".cmd" or ".bat" 103 | trigger an automode that sets the buffer to CRLF and no BOM. CMD.EXE 104 | doesn't tolerate anything else. It sets the charset to that of the 105 | "set-alternate-charset" command (default is CP437). 106 | 107 | There is also a mode for the Powershell extensions ".ps1", ".psd1" and 108 | ".psm1". An empty file with these will be set to CRLF, and a file 109 | without a BOM will be set to 8-bit. 110 | 111 | 112 | Indicators in *Buffer list*: 113 | 114 | "." = current buffer 115 | M: "*" = modified buffer 116 | L: "l" = LF line endings, "c" = CRLF line endings 117 | C: "u" = UTF-8 character set, "d" = dos charset (CP437), 118 | "8" = default 8-bit charset, "l" = locally set charset. 119 | B: "b" = BOM (Byte Order Mark), "n" = no BOM 120 | 121 | 122 | Indicators in "List of charsets": 123 | 124 | "." = current buffer 125 | "d" = default charset 126 | "8" = default 8-bit charset. 127 | "a" = alternate charset 128 | 129 | 130 | Charset names and comparisons: 131 | 132 | Charsets available: CP437 CP737 CP775 CP850 CP852 CP855 CP857 CP858 133 | CP866 CP874 CP1250 CP1251 CP1252 CP1253 CP1254 CP1257 CP1258 134 | ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-7 135 | ISO-8859-9 ISO-8859-10 ISO-8859-11 ISO-8859-13 ISO-8859-14 ISO-8859-15 136 | ISO-8859-16 KOI8-R KOI8-U UTF-8. 137 | 138 | Charset names are compared ignoring upper/lower case, hyphens and 139 | underscores. 140 | 141 | 142 | Escape sequences: 143 | 144 | "\t" Tab 145 | 146 | "\n" Newline 147 | 148 | "\r" Carriage Return 149 | 150 | "\e" ESC 151 | 152 | "\^c" Control character ^C. c can be upper or lower case. 153 | 154 | "\nnn" 8-bit byte, up to three octal digits. 155 | 156 | "\fnn" Function key nn, up to two decimal digits. 157 | 158 | "\{cap}" Named Terminfo string capability. For example 159 | "\{khome}" for the Home key. 160 | 161 | "\"" Quoting of the double quote. 162 | 163 | "\\" Quoting of the backslash. 164 | 165 | "\xhh" 8-bit byte, up to two hex digits. 166 | 167 | "\uxxxxxx" Unicode codepoint, up to six hex digits. 168 | 169 | An unrecognized "\" sequence, an unrecognized "\{cap}" capability, or 170 | "\x", "\f" or "\u" without digits after it causes the current command 171 | to be silently ignored. 172 | 173 | "\nnn" and "\x" insert raw bytes, which are then interpreted in the 174 | locale's charset. "\u" translates the codepoint to the locale's 175 | charset. If that is not possible, the current command is silently 176 | ignored. 177 | 178 | The "\u" escape can optionally have its value within "{}", eg 179 | "\u{abc}3". 180 | 181 | 182 | Terminfo key name aliases: 183 | 184 | The names of some Terminfo string capabilities are obscure, like 185 | "kcuu1" for up-arrow key. There are therefore a number of aliases, for 186 | example "\{up}" for up-arrow key: 187 | 188 | "up", "down", "left", "right", "pageup", "pagedn", "home", "end", 189 | "insert", "delete". 190 | 191 | 192 | Echo-line input control characters: 193 | 194 | Backspace Erase previous character 195 | 196 | ^W Erase previous word 197 | 198 | ^U Erase to beginning of line 199 | 200 | ^R Redraw the line 201 | 202 | Tab Unix-style completion (ambiguous alternatives are not 203 | listed) 204 | 205 | Space Word-completion, completes the next word and at most 206 | one delimiter. 207 | 208 | ESC-Space Word-completion for files. 209 | 210 | Return Enter string 211 | 212 | ^G Abort without entering anything 213 | 214 | ^Q Quote next character 215 | 216 | Synonyms: 217 | 218 | Backspace (U+0008), Delete (U+00FF) 219 | ^U, ^X, ESC-ESC 220 | Return, ^J 221 | ^Q, ^\ 222 | 223 | 224 | The echo-line doesn't support real line editing, but it does support 225 | shifting sideways for input of long strings. 226 | 227 | As a convention, entering nothing on the echo-line aborts the 228 | current command quietly in Mg and doesn't do anything, except when 229 | there is a default. 230 | 231 | Completing an empty string inserts a default: the last full entry 232 | completed for variables, commands or keymaps, the directory name 233 | of the current buffer (for files), "*scratch*" (for buffers), or the 234 | default charset (for charsets). Search and replacement strings can 235 | be filled in with TAB if there previously was any. 236 | 237 | Everything else can also be completed from an empty string. 238 | Everything else shares a single line of recall. 239 | 240 | 241 | Pattern matching for "auto-execute": 242 | 243 | If the pattern contains a "/", it matches the whole pathname, 244 | otherwise only the filename. 245 | 246 | Patterns supported are "*", "?", "[abc]", "[a-c]", "[!abc]", "[^abc]", 247 | "[-abc]", "[abc-]", "[]abc]", "{pat1,pat2,...}" 248 | 249 | "\" quotes the next character everywhere in the pattern. Note that you 250 | must use two of them in a quoted argument. Ie "\\". 251 | 252 | The ordering within "[a-b]" ranges is Unicode codepoint order. 253 | 254 | Invalid UTF-8 characters match only themselves and "*", and cannot be 255 | quoted with "\". 256 | 257 | Unmapped 8-bit characters match only themselves, "*" and "?", and can 258 | be quoted with "\". 259 | 260 | Valid characters in the locale are fully supported. 261 | 262 | The matching is case-insensitive if the variable "compare-fold-file" 263 | is set. 264 | 265 | "~" at the start of a pattern refers to a home directory. 266 | 267 | "{pat1,pat2,...}" is a textual replacement of alternatives like in 268 | shells. 269 | -------------------------------------------------------------------------------- /README.programmer: -------------------------------------------------------------------------------- 1 | Parsing: 2 | 3 | When reading a file, Mg keeps a count of CRLFs vs. LFs. Biggest one wins 4 | and becomes the buffer mode. 5 | 6 | Ditto when reading a file a count is kept of valid UTF-8 characters vs. 7 | other 8-bit characters. Biggest one wins and becomes the mode. 8 | 9 | When the counts are equal, a default is used. 10 | 11 | 12 | Rationale for what charsets are included: 13 | 14 | - The Windows OEM codepages from 15 | http://msdn.microsoft.com/en-us/goglobal/bb964655 16 | 17 | - The single-byte Windows codepages from 18 | http://msdn.microsoft.com/en-us/goglobal/bb964654 19 | 20 | - The ISO-8859-* series. 21 | 22 | - KOI8-R and KOI8-U. 23 | 24 | - UTF-8 - it is the future. 25 | 26 | - Arabic and Hebrew are excluded because there is no right-to-left 27 | display. 28 | 29 | There are only ASCII-compatible 8-bit charsets and UTF-8. Other 30 | multi-byte charsets are more tricky to implement and it hasn't been 31 | done. 32 | 33 | 34 | Suspend and subshell: 35 | 36 | There is code for suspending Mg with ^Z where that is supported, but 37 | no code for starting a subshell. 38 | 39 | 40 | Terminal resizing: 41 | 42 | Mg catches SIGWINCH and acts appropriately. 43 | 44 | 45 | Mods from original Mg: 46 | 47 | The ANSI cursor-key sequences are always defined to next-line etc. 48 | 49 | Mg always adds a newline to the end of a file if there isn't one. Mg 50 | doesn't even pretend to be a binary editor. For one thing, it doesn't 51 | preserve newlines. 52 | 53 | 54 | Code guidelines: 55 | 56 | Mg3a maintains dot position and buffer size (in bytes). The essential 57 | thing is to not set "curwp->w_dotp" or "curwp->w_doto" directly. Use 58 | adjustpos(), which updates the byte position. Unless you hack 59 | lowlevel, you shouldn't have to update "curbp->b_size". 60 | -------------------------------------------------------------------------------- /README.python-mode: -------------------------------------------------------------------------------- 1 | A mode for python. 2 | 3 | 4 | Finding the indent for python: 5 | 6 | Scan back for the previous non-blank line. Lines whose first 7 | non-blank character is "#" are considered blank lines. Take 8 | the indent of the line. If the line ends with ':', add a 9 | tabstop. 10 | 11 | 12 | Assignments and functions: 13 | 14 | Key Function 15 | 16 | RET "python-newline-and-indent" 17 | 18 | Insert a newline, find the indent, and indent. 19 | 20 | ESC TAB "python-indent" 21 | 22 | Re-indent the current line for python. 23 | 24 | "python-mode" 25 | 26 | python-mode toggle. 27 | 28 | 29 | Changing indent: 30 | 31 | The indent is changed with soft tabs. The default is "local- 32 | set-tabs 4 1 1", ie indent of 4 using only spaces, with "tabs" 33 | of size 8 outside of leading whitespace. 34 | 35 | Compile: 36 | 37 | Enabled with LANGMODE_PYTHON. 38 | -------------------------------------------------------------------------------- /README.rpm: -------------------------------------------------------------------------------- 1 | The `xtras` directory contains the infrastructure to create an RPM for 2 | installation in Fedora 41. Docker will allow you to create it, regardless of 3 | your base Operating System. Use `build-rpm.sh` to launch the process. 4 | -------------------------------------------------------------------------------- /README.shell-command: -------------------------------------------------------------------------------- 1 | "shell-command" 2 | --------------- 3 | 4 | "shell-command" works like in Emacs, but with no support for 5 | asynchronous mode. 6 | 7 | "shell-command" asks for a shell command and executes it, capturing 8 | the output. 9 | 10 | With no argument, the output is put in a buffer "*Shell Command 11 | Output*". 12 | 13 | With an argument, the output is put in the current buffer, the cursor 14 | is set at the beginning of the inserted text and the inserted text is 15 | surrounded by the region. The inserted text ends with a newline if the 16 | output did. 17 | 18 | Should the command hang, it can be interrupted with ^G. The first ^G 19 | sends a SIGINT, the second a SIGKILL. 20 | 21 | 22 | Limit on memory: 23 | 24 | * A command can easily fill all of memory. Therefore, the editor 25 | memory used by the output from "shell-command" is limited by the 26 | variable "shell-command-limit". Default is 10000000 (ten million 27 | bytes). Overhead per line is included. 28 | 29 | 30 | "yank-process" 31 | -------------- 32 | 33 | "yank-process" in Mg3a is a variant of "shell-command". It always 34 | inserts in the current buffer, leaves the cursor after the text, and 35 | doesn't insert the final newline. 36 | 37 | 38 | "set-shell" 39 | ----------- 40 | 41 | "set-shell" can override which shell is used for the above. Default is 42 | the value of SHELL, or "/bin/sh". 43 | -------------------------------------------------------------------------------- /README.todo: -------------------------------------------------------------------------------- 1 | My list of TODOs: 2 | 3 | Editing in the message buffer (at least ^A, ^E, ^K, ^D and the cursor keys) 4 | 5 | * Find the first non-blank character to place comment (at least for Python) 6 | 7 | comment-line/comment-region 8 | 9 | duplicate-region 10 | 11 | indent-region/unindent-region (C-x < / C-x >) 12 | -------------------------------------------------------------------------------- /README.ucsnames: -------------------------------------------------------------------------------- 1 | How things work with UCSNAMES: 2 | 3 | New functions: 4 | 5 | "set-unicode-data" - Set the file name of a Unicode database. It should be in 6 | the format of 7 | http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. 8 | Default is unset. 9 | 10 | "list-unicode" - Ask for a string and list matching entries from the 11 | Unicode database in a help window. 12 | 13 | If the string is of the form "U+(hex)" then it matches 14 | the character with that codepoint. Otherwise it matches 15 | a substring of the two first fields in the database (hex 16 | codepoint ";" character name). 17 | 18 | The matching is done on the string and an uppercase 19 | version of it. 20 | 21 | If the command is given an argument, the string matches 22 | the whole database line, and the whole line is shown in 23 | the help window. 24 | 25 | "help-ret" - Assigned to RET in a help buffer. In a listing by "list- 26 | unicode" or "what-cursor-position" it copies the 27 | character indicated in the current line to the 28 | killbuffer. If preceded with "append-next-kill", the 29 | character is appended. 30 | 31 | Changed functions: 32 | 33 | "ucs-insert" - Allow input of Unicode character names like in GNU 34 | Emacs, with input-completion. 35 | 36 | "what-cursor-position" - Arguments are interpreted differently when the database 37 | is set with "set-unicode-data": 38 | 39 | ^U - Show information about the current character(s) in a 40 | help window: shown are width of character (width on 41 | screen in brackets), raw bytes of character in hex, 42 | Unicode codepoint, and Unicode name (if available). 43 | 44 | One line of information is shown per codepoint. 45 | 46 | ^U^U: - Same as ^U but numbers are shown in decimal. 47 | 48 | ^U^U^U: - Same as ^U but numbers are shown in octal. 49 | 50 | ^U^U^U^U: - List the raw database lines. 51 | 52 | Numeric arguments 1 .. 4 can be used instead of 53 | repeated ^U. 54 | -------------------------------------------------------------------------------- /README.undo: -------------------------------------------------------------------------------- 1 | The undo in Mg3a is similar to in GUI applications. It's a linear 2 | undo, with one undo list per buffer. 3 | 4 | 5 | Commands: 6 | 7 | "undo" - An undo that initially goes backward in time. If you do 8 | something else that doesn't change the buffer, it 9 | switches direction from backward to forward or from 10 | forward to backward. Bound to "C-x u" and "C-_". 11 | 12 | Note that if you change the buffer while undone, "the 13 | future" is removed. 14 | 15 | "undo-only" - An undo that goes only backward in time. 16 | 17 | "redo" - An undo that goes only forward in time. 18 | 19 | "undo-boundary" - Manually specify an undo boundary. Scripts are otherwise 20 | undone as one unit. 21 | 22 | 23 | Variables: 24 | 25 | "undo-limit" - A limit on the number of bytes in the undo-list, per- 26 | buffer. This is a hard limit. Default is 1000000. 27 | 28 | "undo-enabled" - Controls whether undo is enabled. Default is 1. 29 | 30 | 31 | Repeat counts: 32 | 33 | "undo", "undo-only" and "redo" accept repeat counts. A repeat count of 34 | 0 counts as infinite. 35 | 36 | 37 | Notes: 38 | 39 | - Undo restores content, and the modified flag; not other buffer 40 | flags. 41 | 42 | - Each step of undoing/redoing is done to the next undo boundary. 43 | 44 | Interactively, there is an undo boundary before each command, except 45 | if two sequential commands are the same and they are "self-insert- 46 | command", "delete-char", "delete-backward-char" or "backward-delete- 47 | char-untabify". 48 | 49 | - Overhead is counted toward "undo-limit". 50 | 51 | - #define LIST_UNDO to enable a "list-undo" command to show the undo list. 52 | -------------------------------------------------------------------------------- /README.user_macros: -------------------------------------------------------------------------------- 1 | What is included with USER_MACROS: 2 | 3 | "create-macro" - Create a named macro for a list of commands. The macro 4 | can then be used as a command. 5 | 6 | Example: 7 | 8 | create-macro "com12" "command1; command2" 9 | 10 | A macro doesn't take any parameters, but it uses a 11 | prefix argument as a repeat count. 12 | 13 | "list-macros" - List the user-defined macros. "list-macro" is now an 14 | alias for "list-kbd-macro". 15 | 16 | 17 | Macro names are case-sensitive and can include any character in your 18 | locale. 19 | 20 | 21 | Key assignment: 22 | 23 | A named macro can be assigned to a key, like a function. Example: 24 | 25 | create-macro testmacro "message hello" 26 | global-set-key "\^a" testmacro 27 | 28 | A macro can also be assigned directly to a key without naming it: 29 | 30 | global-set-key "\^a" "message hello" 31 | 32 | Max 100 macros (named or unnamed) kan be assigned to keys. Named 33 | macros without key assignment have no limit. A macro assigned to a key 34 | must either be the name of a named macro, or a string containing at 35 | least one ' ' or ';'. 36 | 37 | 38 | Listing keys: 39 | 40 | "describe-bindings" with an argument lists only the keys with macros. 41 | -------------------------------------------------------------------------------- /README.user_modes: -------------------------------------------------------------------------------- 1 | What is included with USER_MODES: 2 | 3 | "create-mode" - Create a new, user-defined named mode with optional 4 | initialization commands and an empty keymap. You can 5 | then populate the keymap with "define-key." 6 | 7 | Examples: 8 | 9 | create-mode "mymode" 10 | create-mode "mymode_tab4" "local-set-tabs 4 0" 11 | define-key mymode "\r" newline-and-indent 12 | 13 | "delete-mode" - Delete a mode. 14 | 15 | "copy-mode" - Copy a mode with its key assignments. The commands are 16 | not copied. 17 | 18 | Example: 19 | 20 | copy-mode clike mymode "new commands" 21 | 22 | "rename-mode" - Rename a mode. 23 | 24 | "list-modes" - List the modes and any initialization-commands. 25 | 26 | "local-set-mode" - Set the mode in the current buffer. If the mode has 27 | initialization commands, run them first. 28 | 29 | "local-unset-mode" - Clear the mode from the current buffer. 30 | 31 | "local-toggle-mode" - Toggle the mode in the current buffer. 32 | 33 | 34 | These commands can operate on user-defined modes, and on builtin 35 | language-modes, but not on other builtin modes. 36 | 37 | "local-set-mode", "local-unset-mode" and "local-toggle-mode" are 38 | included with LANGMODE_CLIKE. 39 | 40 | Mode names are case-sensitive and can include any character in your 41 | locale. 42 | 43 | When USER_MODES is defined, "list-keymaps" is an alias of "list- 44 | modes". 45 | 46 | 47 | Rationales: 48 | 49 | "create-mode": "define-key" and "local-set-key" aren't particularly useful without it. 50 | 51 | "delete-mode": the names of builtin language modes should not be reserved. 52 | 53 | "copy-mode": it's tedious to copy all key assignments. 54 | 55 | "rename-mode": trivial to do, completeness, perhaps useful. 56 | 57 | "local-toggle-mode": more useful interactively than -set and -unset. 58 | 59 | "local-set-mode", "local-unset-mode": more comfortable to use in a script than a toggle. 60 | -------------------------------------------------------------------------------- /bl/Makefile.am: -------------------------------------------------------------------------------- 1 | exampledir = $(datarootdir)/doc/@PACKAGE@/bl 2 | example_DATA = dot.mg dot.mg3 dot.mg-cygwin dot.mg-xterm README 3 | -------------------------------------------------------------------------------- /bl/README: -------------------------------------------------------------------------------- 1 | A copy of my .mg, .mg-cygwin and .mg-xterm (as dot.mg etc.) as an 2 | example of init files. 3 | -------------------------------------------------------------------------------- /bl/dot.mg: -------------------------------------------------------------------------------- 1 | ; 2 | ; This is my .mg as of 2017-03-31. Note that you have to compile with 3 | ; -DALL to use it. 4 | 5 | ; 6 | ; This file contains initialization commands for mg 7 | ; 8 | (global-set-key "\eg" 'goto-line) 9 | (global-set-key "\r" 'newline-and-indent) 10 | (global-set-key "\n" 'newline) 11 | ; 12 | (global-set-key "\^n" 'next-buffer) 13 | (global-set-key "\en" 'previous-buffer) 14 | (global-set-key "\^o" 'other-window) 15 | (global-set-key "\eo" 'previous-window) 16 | (global-set-key "\^xo" 'open-line) 17 | 18 | (global-set-key "\^p" 'call-last-kbd-macro) 19 | (global-set-key "\^v" 'yank) 20 | (global-set-key "\^f" 'search-forward) 21 | (global-set-key "\^r" 'redraw-display) 22 | 23 | (global-set-key "\eu" 'ucs-insert) 24 | (global-set-key "\e8" 'insert-8bit) 25 | (global-set-key "\ee" 'explode-character) 26 | (global-set-key "\ei" 'implode-character) 27 | (global-set-key "\ev" 'show-bytes) 28 | 29 | (global-set-key "\ek" 'kill-whole-line) 30 | (global-set-key "\ey" 'yank) 31 | 32 | (global-set-key "\^x\^r" 'revert-buffer-forget) 33 | (global-set-key "\^xr" 'find-file-read-only) 34 | 35 | (global-set-key "\^xg" 'global-set-key) 36 | (global-set-key "\^xG" 'local-set-key) 37 | (global-set-key "\^xl" 'local-set-charset) 38 | (global-set-key "\^xL" 'load) 39 | (global-set-key "\^xv" 'set-variable) 40 | (global-set-key "\^xV" 'local-set-variable) 41 | 42 | ; 43 | ; "helpbuf" is the mode/keymap in a help buffer. "help" is the keymap 44 | ; used by the "^H" command. 45 | ; 46 | 47 | (define-key "helpbuf" "a" 'apropos) 48 | (define-key "helpbuf" "b" 'describe-bindings) 49 | (define-key "helpbuf" "c" 'describe-key-briefly) 50 | (define-key "helpbuf" "l" 'list-charsets) 51 | (define-key "helpbuf" "v" 'list-variables) 52 | (define-key "helpbuf" "k" 'list-keymaps) 53 | (define-key "helpbuf" "m" 'list-macro) 54 | (ignore-errors define-key "helpbuf" "M" 'list-macros) 55 | 56 | (define-key "help" "\^b" 'buffer-menu) 57 | (define-key "help" "l" 'list-charsets) 58 | (define-key "help" "v" 'list-variables) 59 | (define-key "help" "k" 'list-keymaps) 60 | (define-key "help" "m" 'list-macro) 61 | (ignore-errors define-key "help" "M" 'list-macros) 62 | 63 | (ignore-errors define-key "dired" "n" 'dired-next-dirline) 64 | (ignore-errors define-key "dired" "p" 'dired-prev-dirline) 65 | 66 | ; 67 | ; "bufmenu" is the mode/keymap in "*Buffer List*" 68 | ; 69 | (define-key "bufmenu" "b" 'buffer-menu) 70 | 71 | ; 72 | ; This is how to undefine a key "with define-key" 73 | ; 74 | (define-key "bufmenu" "\^o" 'nil) 75 | (define-key "bufmenu" "0" 'Buffer-menu-switch-other-window) 76 | 77 | (global-set-key "\f1" 'help-help) ; F1 78 | (global-set-key "\f3" 'search-again) ; F3 79 | 80 | (ignore-errors global-set-key "\f4" 'search-all-forward) ; F4 81 | (ignore-errors global-set-key "\f5" 'search-all-backward) ; F5 82 | 83 | (global-set-key "\e\{right}" 'tab-region-right) ; ESC-Right 84 | (global-set-key "\e\{left}" 'tab-region-left) ; ESC-Left 85 | 86 | (global-set-key "\^x\{up}" 'shrink-window) ; ^X-Up 87 | (global-set-key "\^x\{down}" 'enlarge-window) ; ^X-Down 88 | 89 | (ignore-errors global-set-key "\es" 'slow-mode) 90 | (ignore-errors global-set-key "\^t" 'test) 91 | (ignore-errors global-set-key "\^c" 'charsdebug) 92 | (ignore-errors global-set-key "\ez" 'charsdebug-zero) 93 | (ignore-errors global-set-key "\^s" 'search-all-simple) 94 | 95 | (global-set-key "\^x\^?" 'delete-region) 96 | 97 | ; 98 | ; Assigned "ESC Euro-sign" for test purposes 99 | ; 100 | (global-set-key "\e\u20AC" 'emacs-version) 101 | (global-set-key "\^x " 'no-break) 102 | 103 | (set-variable "case-fold-search" 0) 104 | (set-variable "modeline-show" 15) 105 | (set-variable "quoted-char-radix" 16) 106 | (set-variable "trim-whitespace" 1) 107 | (set-variable "insert-default-directory" 0) 108 | (set-variable "complete-fold-file" 1) 109 | (set-variable "fill-options" 115) 110 | (set-variable "kill-whole-lines" 1) 111 | (set-variable "blink-wait" 250) 112 | 113 | (global-set-key "\^a" 'beginning-of-visual-line) 114 | (global-set-key "\^e" 'end-of-visual-line) 115 | (global-set-key "\e\^?" 'join-line) 116 | (global-set-key "\e\{delete}" 'join-line-forward) 117 | (global-set-key "\^xt" 'local-set-tabs) 118 | (ignore-errors global-set-key "\el" 'local-toggle-mode) 119 | 120 | (auto-execute-list "*dos.txt;/users/Public/Documents/backup.log" "local-set-charset cp437") 121 | (auto-execute-list "README.reference;README.ucsnames" "set-fill-column 90; local-mode-name fill90") 122 | 123 | (define-key "helpbuf" "p" 'list-patterns) 124 | (define-key "help" "p" 'list-patterns) 125 | 126 | (global-set-key "\^x\^k" 'kill-buffer-quickly) 127 | (define-key "dired" "q" 'kill-buffer-quickly) 128 | 129 | (ignore-errors set-unicode-data "~/misc/UnicodeData.txt") 130 | (ignore-errors define-key "help" "u" 'list-unicode) 131 | (ignore-errors define-key "helpbuf" "u" 'list-unicode) 132 | 133 | ; 134 | ; Do not want to lose it by copying mistakes 135 | ; 136 | (auto-execute "/src/mg2a/Changelog" "local-set-variable make-backup 1") 137 | auto-execute-list "~/.mg;~/.bashrc" "lv make-backup 1" 138 | 139 | ; 140 | ; fill-options for filling block comments in C, and use hard tabs with 141 | ; auto-cleanup. 142 | ; 143 | create-macro "myprog" "local-set-variable fill-options 9; local-set-tabs 8 0" 144 | 145 | ; 146 | ; Use hard tabs, but clean up whitespace 147 | ; 148 | create-macro "myprog2" "local-set-tabs 8 0" 149 | 150 | ; 151 | ; Various C modes. 152 | ; 153 | auto-execute "/c/Cache/src/winsup/*/malloc.cc" "myprog; local-set-mode stdc; lv clike-style 4; local-set-tabs 2 1 1" 154 | auto-execute "/c/Cache/src/winsup/*.{cc,c,h}" "myprog; local-set-mode gnuc" 155 | auto-execute-list "*.c;*.h;*.inc" "local-set-mode stdc; myprog" 156 | 157 | ; 158 | ; Python mode 159 | ; 160 | shebang "python" 161 | auto-execute "*.py" "python-mode" 162 | 163 | ; 164 | ; Perl mode 165 | ; 166 | shebang "perl" 167 | auto-execute-list "*.pl;*.pcmd" "local-set-mode perl; myprog2" 168 | 169 | ; 170 | ; Mode for Windows CMD.EXE 171 | ; 172 | create-mode cmd "myprog2" 173 | define-key cmd "\r" clike-newline-and-indent 174 | define-key cmd ")" clike-insert 175 | define-key cmd "\e\t" clike-indent 176 | auto-execute-list "*.cmd;*.bat" "local-set-mode cmd" 177 | 178 | ; 179 | ; Powershell mode 180 | ; 181 | copy-mode clike powershell "myprog2" 182 | auto-execute-list "*.ps1;*.psd1;*.psm1" "local-set-mode powershell" 183 | 184 | ; 185 | ; JavaScript mode 186 | ; 187 | auto-execute "*.js" "local-set-mode javascript; myprog2" 188 | 189 | ; 190 | ; Re-indent a line in C mode, step to the next line. 191 | ; 192 | global-set-key "\f8" clike-indent-next 193 | 194 | ; 195 | ; Re-indent the region in C mode 196 | ; 197 | global-set-key "\f9" clike-indent-region 198 | 199 | ; 200 | ; Two different displays of buffer list 201 | ; 202 | global-set-key "\f7" "sv buffer-name-width 20; list-buffers 1; sv buffer-name-width 24" 203 | global-set-key "\f6" list-buffers 204 | 205 | ; 206 | ; Calc (http://www.isthe.com/chongo/tech/comp/calc/) mode 207 | ; 208 | copy-mode clike calc "myprog2" 209 | auto-execute "*.cal" "local-set-mode calc" 210 | 211 | ; 212 | ; Go to top or bottom of window 213 | ; 214 | global-set-key "\e\{up}" "move-to-window-line 0" 215 | global-set-key "\e\{down}" "move-to-window-line -1" 216 | 217 | ; 218 | ; Swift mode, with "case" indented a la Apple 219 | ; 220 | auto-execute "*.swift" "local-set-mode swift; lv clike-style 2" 221 | 222 | ; 223 | ; Go mode 224 | ; 225 | auto-execute "*.go" "local-set-mode go" 226 | 227 | ; 228 | ; Position function for nice view after 'mgfunc' 229 | ; 230 | global-set-key "\ea" "recenter 8" 231 | 232 | ; 233 | ; Undo and redo 234 | ; 235 | ignore-errors global-set-key "\f10" list-undo 236 | global-set-key "\f11" undo-only 237 | global-set-key "\f12" redo 238 | 239 | ; 240 | ; Bell off 241 | ; 242 | set-variable bell-type 0 243 | 244 | ; 245 | ; Exit quickly 246 | ; 247 | global-set-key "\^x\^a\^z" kill-emacs 248 | 249 | ; 250 | ; Edit at the end: "mg -end ..." 251 | ; 252 | create-macro nd "end-of-buffer; recenter -3" 253 | 254 | ; 255 | ; Interactive edit at the end 256 | ; 257 | global-set-key "\ej" "end-of-buffer; recenter -3" 258 | 259 | ; 260 | ; Put the next end of a function at the bottom of the window, 261 | ; and the cursor in the middle of the window. 262 | ; 263 | create-macro endfunc "search-forward \"\\n}\"; recenter -1; move-to-window-line" 264 | 265 | ; 266 | ; Insert the date in international format 267 | ; 268 | create-macro date "yank-process \"date --rfc-3339=second\"" 269 | -------------------------------------------------------------------------------- /bl/dot.mg-cygwin: -------------------------------------------------------------------------------- 1 | ; 2 | ; For cygwin 3 | ; 4 | 5 | (global-set-key "\e[1;5~" 'beginning-of-buffer); ; Ctrl-Home 6 | (global-set-key "\e[4;5~" 'end-of-buffer); ; Ctrl-End 7 | 8 | (global-set-key "\e[1;5C" 'forward-word) ; Ctrl-right 9 | (global-set-key "\e[1;5D" 'backward-word) ; Ctrl-left 10 | 11 | (global-set-key "\e[1;5A" 'scroll-one-line-down) ; Ctrl-Up 12 | (global-set-key "\e[1;5B" 'scroll-one-line-up) ; Ctrl-Down 13 | -------------------------------------------------------------------------------- /bl/dot.mg-xterm: -------------------------------------------------------------------------------- 1 | ; 2 | ; For mintty 3 | ; 4 | 5 | (global-set-key "\e[1;5H" 'beginning-of-buffer) ; Ctrl-Home 6 | (global-set-key "\e[1;5F" 'end-of-buffer) ; Ctrl-End 7 | 8 | (global-set-key "\e[1;5C" 'forward-word) ; Ctrl-right 9 | (global-set-key "\e[1;5D" 'backward-word) ; Ctrl-left 10 | 11 | (global-set-key "\e[1;5A" 'scroll-one-line-down) ; Ctrl-Up 12 | (global-set-key "\e[1;5B" 'scroll-one-line-up) ; Ctrl-Down 13 | -------------------------------------------------------------------------------- /bl/dot.mg3: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; General keys and variables 3 | ;; 4 | (global-set-key "\ez" "save-buffers-kill-emacs 1") 5 | (global-set-key "\e\^?" 'backward-kill-word) 6 | (global-set-key "\^h" 'delete-backward-char) 7 | (global-set-key "\e\^h" 'backward-kill-word) 8 | (global-set-key "\e " 'set-mark-command) 9 | (global-set-key "\eg" 'goto-line) 10 | (global-set-key "\ep" 'fill-paragraph) 11 | (global-set-key "\esa" 'search-again) 12 | (global-set-key "\ess" 'search-all-forward) 13 | (global-set-key "\esr" 'search-all-backward) 14 | (global-set-key "\esf" 'search-forward) 15 | (global-set-key "\esb" 'search-backward) 16 | (global-set-key "\esF" 'isearch-forward) 17 | (global-set-key "\esB" 'isearch-backward) 18 | ; 19 | ; Sun, 26 Apr 2020 07:04:39 +0000 20 | ; 21 | (global-set-key "\e[5~" 'scroll-down) 22 | (global-set-key "\e[6~" 'scroll-up) 23 | ; 24 | ; Fri, 20 Nov 2020 07:11:28 +0100 25 | ; 26 | (global-set-key "\^x;" "comment-line 1") 27 | 28 | ; 29 | ; Tue, 04 Apr 2017 15:04:44 +0200 30 | ; 31 | (global-set-key "\e\^d" "yank-process \"LC_ALL=C date '+%a, %d %b %Y %H:%m:%S %z'\"") 32 | 33 | (set-default-mode "lf") 34 | (set-variable "blink-wait" 0) 35 | 36 | ; 37 | ; fill-options for filling block comments in C, and use hard tabs with 38 | ; auto-cleanup. 39 | ; 40 | create-macro "myprog" "lv fill-options 9; local-set-tabs 8 0" 41 | 42 | ;; 43 | ;; LaTEX with filling 44 | ;; 45 | (set-variable "fill-column" 72) 46 | (auto-execute *.tex 'auto-fill-mode) 47 | ;; 48 | ;; Explicitly NO backups 49 | ;; Sun, 07 Jun 2020 08:06:35 +0200 50 | ;; 51 | (set-variable "make-backup" 0) 52 | 53 | ;; 54 | ;; Python 55 | ;; 56 | shebang "python" 57 | auto-execute "*.py" "python-mode" 58 | ;; 59 | ;; for scapy development 60 | ;; 61 | ;;auto-execute "*.uts" "python-mode" 62 | 63 | ;; 64 | ;; GNU make 65 | ;; 66 | ;; 67 | ;; This is when you compile with make-mode 68 | ;; 69 | ;; auto-execute "Makefile" "make-mode" 70 | ;; auto-execute "GNUMakefile" "make-mode" 71 | ;; auto-execute "*.mak" "make-mode; lv comment-begin \"## \"" 72 | ;; 73 | ;; which only does this: so what is the merit of it? 74 | ;; 75 | auto-execute "Makefile" "lv comment-begin \"# \"" 76 | auto-execute "GNUMakefile" "lv comment-begin \"# \"" 77 | auto-execute "*.mak" "lv comment-begin \"# \"" 78 | 79 | 80 | shebang "bash" 81 | auto-execute "*.sh" "lv comment-begin \"# \"; local-set-tabs 2 1 1" 82 | auto-execute ".bash_aliases" "lv comment-begin \"# \"; local-set-tabs 2 1 1" 83 | auto-execute ".bashrc" "lv comment-begin \"# \"; local-set-tabs 2 1 1" 84 | ; 85 | ; C mode 86 | ; 87 | auto-execute "*.[ch]" "myprog; local-set-mode stdc; lv clike-style 4; lv comment-begin '// '; local-set-tabs 2 1 1" 88 | ;; auto-execute "*.c" "myprog; local-set-mode stdc; lv clike-style 4; local-set-tabs 2 1 1" 89 | 90 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | aclocal 3 | automake --add-missing 4 | autoreconf 5 | -------------------------------------------------------------------------------- /chrdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys/default/chardef.h: character set specific #defines for mg 2a 3 | * Warning: System specific ones exist 4 | */ 5 | 6 | #ifndef CHARMASK 7 | /* 8 | * Casting should be at least as efficent as anding with 0xff, 9 | * and won't have the size problems. Override in sysdef.h if no 10 | * unsigned char type. 11 | */ 12 | #define CHARMASK(c) ((unsigned char) (c)) 13 | #endif 14 | 15 | 16 | /* 17 | * These flags, and the macros below them, make up a do-it-yourself 18 | * set of "ctype" macros that understand the DEC multinational set, 19 | * and let me ask a slightly different set of questions. 20 | */ 21 | 22 | #define _W 0x01 /* Word. */ 23 | #define _U 0x02 /* Upper case letter. */ 24 | #define _L 0x04 /* Lower case letter. */ 25 | #define _C 0x08 /* Control. */ 26 | #define _D 0x10 /* is decimal digit */ 27 | #define _S 0x20 /* General whitespace: HT,LF,VT,FF,CR,Space */ 28 | 29 | #define ISWORD(c) ((cinfo[CHARMASK(c)]&_W)!=0) 30 | #define ISCTRL(c) ((cinfo[CHARMASK(c)]&_C)!=0) 31 | #define ISUPPER(c) ((cinfo[CHARMASK(c)]&_U)!=0) 32 | #define ISLOWER(c) ((cinfo[CHARMASK(c)]&_L)!=0) 33 | #define ISDIGIT(c) ((cinfo[CHARMASK(c)]&_D)!=0) 34 | #define ISALPHA(c) ((cinfo[CHARMASK(c)]&(_U|_L))!=0) 35 | #define ISALNUM(c) ((cinfo[CHARMASK(c)]&(_U|_L|_D))!=0) 36 | #define ISSPACE(c) ((cinfo[CHARMASK(c)]&_S)!=0) 37 | #define ISDELIM(c) ((cinfo[CHARMASK(c)]&(_W|_C|_S))==0) 38 | #define ISASCII(c) ((c) >= 0 && (c) <= 127) 39 | #define TOUPPER(c) ((c)-0x20) 40 | #define TOLOWER(c) ((c)+0x20) 41 | 42 | 43 | /* 44 | * generally useful thing for chars 45 | */ 46 | 47 | #define CCHR(x) ((x) ^ 0x40) /* CCHR('?') == DEL */ 48 | 49 | #ifndef METACH 50 | #define METACH CCHR('[') 51 | #endif 52 | -------------------------------------------------------------------------------- /cinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Character class tables. 3 | * 4 | * Do it yourself character classification macros, that understand the 5 | * multinational character set, and let me ask some questions the 6 | * standard macros (in ctype.h) don't let you ask. 7 | */ 8 | 9 | #include "def.h" 10 | 11 | /* 12 | * This table, indexed by a character drawn from the 256 member 13 | * character set, is used by my own character type macros to answer 14 | * questions about the type of a character. 15 | * 16 | * Mg3a: Tweaked to be useful for Mg3a when the locale isn't 17 | * recognized. 18 | */ 19 | 20 | const uint_least8_t cinfo[256] = { 21 | _C, _C, _C, _C, /* 0x0X */ 22 | _C, _C, _C, _C, 23 | _C, _C|_S, _C|_S, _C|_S, 24 | _C|_S, _C|_S, _C, _C, 25 | _C, _C, _C, _C, /* 0x1X */ 26 | _C, _C, _C, _C, 27 | _C, _C, _C, _C, 28 | _C, _C, _C, _C, 29 | _S, 0, 0, 0, /* 0x2X */ 30 | 0, 0, 0, 0, 31 | 0, 0, 0, 0, 32 | 0, 0, 0, 0, 33 | _D|_W, _D|_W, _D|_W, _D|_W, /* 0x3X */ 34 | _D|_W, _D|_W, _D|_W, _D|_W, 35 | _D|_W, _D|_W, 0, 0, 36 | 0, 0, 0, 0, 37 | 0, _U|_W, _U|_W, _U|_W, /* 0x4X */ 38 | _U|_W, _U|_W, _U|_W, _U|_W, 39 | _U|_W, _U|_W, _U|_W, _U|_W, 40 | _U|_W, _U|_W, _U|_W, _U|_W, 41 | _U|_W, _U|_W, _U|_W, _U|_W, /* 0x5X */ 42 | _U|_W, _U|_W, _U|_W, _U|_W, 43 | _U|_W, _U|_W, _U|_W, 0, 44 | 0, 0, 0, 0, 45 | 0, _L|_W, _L|_W, _L|_W, /* 0x6X */ 46 | _L|_W, _L|_W, _L|_W, _L|_W, 47 | _L|_W, _L|_W, _L|_W, _L|_W, 48 | _L|_W, _L|_W, _L|_W, _L|_W, 49 | _L|_W, _L|_W, _L|_W, _L|_W, /* 0x7X */ 50 | _L|_W, _L|_W, _L|_W, _L|_W, 51 | _L|_W, _L|_W, _L|_W, 0, 52 | 0, 0, 0, _C, 53 | _W, _W, _W, _W, /* 0x8X */ 54 | _W, _W, _W, _W, 55 | _W, _W, _W, _W, 56 | _W, _W, _W, _W, 57 | _W, _W, _W, _W, /* 0x9X */ 58 | _W, _W, _W, _W, 59 | _W, _W, _W, _W, 60 | _W, _W, _W, _W, 61 | _W, _W, _W, _W, /* 0xAX */ 62 | _W, _W, _W, _W, 63 | _W, _W, _W, _W, 64 | _W, _W, _W, _W, 65 | _W, _W, _W, _W, /* 0xBX */ 66 | _W, _W, _W, _W, 67 | _W, _W, _W, _W, 68 | _W, _W, _W, _W, 69 | _W, _W, _W, _W, /* 0xCX */ 70 | _W, _W, _W, _W, 71 | _W, _W, _W, _W, 72 | _W, _W, _W, _W, 73 | _W, _W, _W, _W, /* 0xDX */ 74 | _W, _W, _W, _W, 75 | _W, _W, _W, _W, 76 | _W, _W, _W, _W, 77 | _W, _W, _W, _W, /* 0xEX */ 78 | _W, _W, _W, _W, 79 | _W, _W, _W, _W, 80 | _W, _W, _W, _W, 81 | _W, _W, _W, _W, /* 0xFX */ 82 | _W, _W, _W, _W, 83 | _W, _W, _W, _W, 84 | _W, _W, _W, _W, 85 | }; 86 | 87 | 88 | /* 89 | * Find the name of a keystroke. Returns a pointer to the terminating 90 | * '\0'. 91 | */ 92 | 93 | char * 94 | keyname(char *cp, INT k) 95 | { 96 | char *np; 97 | 98 | if(k < 0) k = CHARMASK(k); /* sign extended char */ 99 | switch(k) { 100 | // case CCHR('@'): np = "NUL"; break; 101 | case CCHR('I'): np = "TAB"; break; 102 | // case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */ 103 | case CCHR('M'): np = "RET"; break; 104 | case CCHR('['): np = "ESC"; break; 105 | case ' ': np = "SPC"; break; /* yuck again */ 106 | case CCHR('?'): np = "DEL"; break; 107 | default: 108 | if (k >= 128) { 109 | if (termcharset) { 110 | sprintf(cp, "U+%04X", (int)k); 111 | } else { 112 | sprintf(cp, "0%o", (int)k); 113 | } 114 | cp += strlen(cp); 115 | return cp; 116 | } 117 | if(k < ' ') { 118 | *cp++ = 'C'; 119 | *cp++ = '-'; 120 | k = CCHR(k); 121 | if(ISUPPER(k)) k = TOLOWER(k); 122 | } 123 | *cp++ = k; 124 | *cp = '\0'; 125 | return cp; 126 | } 127 | strcpy(cp, np); 128 | return cp + strlen(cp); 129 | } 130 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.69]) 5 | AC_INIT([mg3a],[20250112],[paaguti@gmail.com]) 6 | AM_INIT_AUTOMAKE 7 | dnl AC_CONFIG_SRCDIR([display.c]) 8 | AC_CONFIG_HEADERS([config.h]) 9 | 10 | # Checks for programs. 11 | AC_PROG_CC 12 | AC_PROG_INSTALL 13 | AC_PROG_LN_S 14 | 15 | # Checks for libraries. 16 | 17 | AC_SEARCH_LIBS([beep],[ncursesw ncurses],[], 18 | [ AC_MSG_ERROR([unable to find beep in NCURSES])] 19 | ) 20 | 21 | # FIXME: Replace `main' with a function in `-ltermcap': 22 | # AC_CHECK_LIB([termcap], [main]) 23 | 24 | # Checks for header files. 25 | AC_CHECK_HEADERS([fcntl.h langinfo.h limits.h locale.h sgtty.h stddef.h stdint.h stdlib.h string.h sys/file.h sys/ioctl.h sys/time.h termio.h termios.h unistd.h wchar.h wctype.h]) 26 | 27 | # Checks for typedefs, structures, and compiler characteristics. 28 | AC_TYPE_UID_T 29 | AC_TYPE_MODE_T 30 | AC_TYPE_OFF_T 31 | AC_TYPE_PID_T 32 | AC_TYPE_SIZE_T 33 | AC_TYPE_SSIZE_T 34 | 35 | # Checks for library functions. 36 | AC_FUNC_ALLOCA 37 | AC_FUNC_FORK 38 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK 39 | AC_FUNC_MALLOC 40 | AC_FUNC_REALLOC 41 | AC_CHECK_FUNCS([dup2 getcwd gettimeofday memchr memmove mkdir nl_langinfo realpath rmdir select setlocale strchr strerror strrchr strstr strtol wcwidth]) 42 | 43 | AM_CPPFLAGS="" 44 | 45 | AC_ARG_ENABLE([dired], 46 | AS_HELP_STRING([--enable-dired], 47 | [ Enable dired @<:@default=yes@:>@ ])], 48 | [enable_dired="${enableval:-yes}"], 49 | [enable_dired=yes]) 50 | AS_IF([ test "x$enable_dired" == "xyes" ], 51 | [AC_DEFINE([DIRED], [1], [Enable dired.])] 52 | ) 53 | 54 | AC_ARG_ENABLE([pipein], 55 | AS_HELP_STRING([--enable-pipein], 56 | [ Enable read from pipe at startup @<:@default=yes@:>@ ])], 57 | [enable_pipein=yes"${enableval:-yes}"], 58 | [enable_pipein=yes]) 59 | AS_IF([ test "x$enable_pipein" == "xyes" ], 60 | [AC_DEFINE([PIPEIN], [1], [Enable input from pipe.])] 61 | ) 62 | 63 | AC_ARG_ENABLE([prefixregion], 64 | AS_HELP_STRING([--enable-prefixregion], 65 | [ Enable prefix region @<:@default=yes@:>@ ])], 66 | [enable_prefixregion="${enableval:-yes}"], 67 | [enable_prefixregion=yes]) 68 | AS_IF([ test "x$enable_prefixregion" == "xyes" ], 69 | [AC_DEFINE([PREFIXREGION], [1], [Enable prefix region.])] 70 | ) 71 | 72 | AC_ARG_ENABLE([slow], 73 | AS_HELP_STRING([--enable-slow], 74 | [ Enable slow terminal emulation@<:@default=no@:>@ ])], 75 | [enable_slow="${enableval:-yes}"], 76 | [enable_slow=no]) 77 | AS_IF([ test "x$enable_slow" == "xyes" ], 78 | [AC_DEFINE([SLOW], [1], [Enable slow terminal emulation.])] 79 | ) 80 | 81 | AC_ARG_ENABLE([mouse], 82 | AS_HELP_STRING([--enable-mouse], 83 | [ Enable mouse@<:@default=no@:>@ ])], 84 | [enable_mouse="${enableval:-yes}"], 85 | [enable_mouse=yes]) 86 | AS_IF([ test "x$enable_mouse" == "xyes" ], 87 | [AC_DEFINE([MOUSE], [1], [Enable mouse.])] 88 | ) 89 | 90 | AC_ARG_ENABLE([pythonmode], 91 | AS_HELP_STRING([--enable-pythonmode], 92 | [ Enable Python mode @<:@default=yes@:>@ ])], 93 | [enable_pythonmode="${enableval:-yes}"], 94 | [enable_pythonmode=yes]) 95 | AS_IF([ test "x$enable_pythonmode" == "xyes"], 96 | [AC_DEFINE([LANGMODE_PYTHON], [1], [Enable Python mode.])] 97 | ) 98 | 99 | AC_ARG_ENABLE([makemode], 100 | AS_HELP_STRING([--enable-makemode], 101 | [ Enable Makefile mode @<:@default=no@:>@ ])], 102 | [enable_makemode="${enableval:-yes}"], 103 | [enable_makemode=no]) 104 | AS_IF([ test "x$enable_makemode" == "xyes"], 105 | [AC_DEFINE([LANGMODE_MAKE], [1], [Enable Makefile mode.])] 106 | ) 107 | 108 | AC_ARG_ENABLE([cmode], 109 | AS_HELP_STRING([--enable-cmode], 110 | [ Enable old C mode @<:@default=no@:>@ ])], 111 | [enable_cmode="${enableval:-yes}"], 112 | [enable_cmode=no]) 113 | AS_IF([ test "x$enable_cmode" == "xyes"], 114 | [AC_DEFINE([LANGMODE_C], [1], [Enable C mode.])] 115 | ) 116 | 117 | AC_ARG_ENABLE([clikemode], 118 | AS_HELP_STRING([--enable-clikemode], 119 | [ Enable C-like modes @<:@default=yes@:>@ ])], 120 | [enable_clikemode="${enableval:-yes}"], 121 | [enable_clikemode=yes]) 122 | AS_IF([ test "x$enable_clikemode" == "xyes"], 123 | [AC_DEFINE([LANGMODE_CLIKE], [1], [Enable C-like mode.])] 124 | ) 125 | 126 | AC_ARG_ENABLE([usermodes], 127 | AS_HELP_STRING([--enable-usermodes], 128 | [ Enable user modes @<:@default=yes@:>@ ])], 129 | [enable_usermodes="${enableval:-yes}"], 130 | [enable_usermodes=yes]) 131 | AS_IF([ test "x$enable_usermodes" == "xyes"], 132 | [AC_DEFINE([USER_MODES], [1], [Enable user modes.])] 133 | ) 134 | 135 | AC_ARG_ENABLE([usermacros], 136 | AS_HELP_STRING([--enable-usermacros], 137 | [ Enable user macros @<:@default=yes@:>@ ])], 138 | [enable_usermacros="${enableval:-yes}"], 139 | [enable_usermacros=yes]) 140 | AS_IF([ test "x$enable_usermacros" == "xyes"], 141 | [AC_DEFINE([USER_MACROS], [1], [Enable user macros.])] 142 | ) 143 | AC_ARG_ENABLE([ucsnames], 144 | AS_HELP_STRING([--enable-ucsnames], 145 | [ Enable Unicode character names @<:@default=no@:>@ ])], 146 | [enable_ucsnames="${enableval:-yes}"], 147 | [enable_ucsnames=no]) 148 | AS_IF([ test "x$enable_ucsnames" == "xyes"], 149 | [AC_DEFINE([UCSNAMES], [1], [Enable end search with Enter key.])] 150 | ) 151 | 152 | AC_ARG_ENABLE([all], 153 | AS_HELP_STRING([--enable-all], 154 | [ Enable all features @<:@default=no@:>@ ])], 155 | [enable_all="${enableval:-yes}"], 156 | [enable_all=no]) 157 | AS_IF( 158 | [ test "x$enable_all" == "xyes" ], 159 | [AC_DEFINE([ALL], [1], [Enable all options.])] 160 | ) 161 | 162 | AC_ARG_ENABLE([searchall], 163 | AS_HELP_STRING([--enable-searchall], 164 | [ Enable search-all commands @<:@default=yes@:>@ ])], 165 | [enable_searchall="${enableval:-yes}"], 166 | [enable_searchall=yes]) 167 | AS_IF( 168 | [ test "x$enable_searchall" == "xyes" ], 169 | [AC_DEFINE([SEARCHALL], [1], [Enable search all commands.])] 170 | ) 171 | 172 | AC_ARG_ENABLE([searchsimple], 173 | AS_HELP_STRING([--enable-searchsimple], 174 | [ Enable search-all commands @<:@default=no@:>@ ])], 175 | [enable_searchsimple="${enableval:-yes}"], 176 | [enable_searchsimple=no]) 177 | AS_IF( 178 | [ test "x$enable_searchsimple" == "xyes" ], 179 | [AC_DEFINE([SEARCHSIMPLE], [1], [Enable simple search commands.])] 180 | ) 181 | 182 | AC_ARG_ENABLE([searchenter], 183 | AS_HELP_STRING([--enable-searchenter], 184 | [ Enable end search with Enter key @<:@default=no@:>@ ])], 185 | [enable_searchenter="${enableval:-yes}"], 186 | [enable_searchenter=no]) 187 | AS_IF( 188 | [ test "x$enable_searchenter" == "xyes" ], 189 | [AC_DEFINE([SEARCHENTER], [1], [Enable end search with Enter key.])] 190 | ) 191 | 192 | AC_ARG_ENABLE([noobjs], 193 | AS_HELP_STRING([--enable-no-objs], 194 | [Enable supressing .o files in dired @<:@default=no@:>@])], 195 | [enable_noobjs="${enableval:-yes}"], 196 | [enable_noobjs=no]) 197 | AS_IF( 198 | [test "x$enable_noobjs" == "xyes"], 199 | [AC_DEFINE([NO_O], [1], [Define to suppress .o files in dired])] 200 | ) 201 | 202 | AC_ARG_ENABLE([backups], 203 | AS_HELP_STRING([--enable-backups], 204 | [Enable automatic backups @<:@default=no@:>@])], 205 | [enable_backups="${enableval:-yes}"], 206 | [enable_backups=no]) 207 | AS_IF( 208 | [test "x$enable_backups" == "xyes"], 209 | [AC_DEFINE([MAKEBACKUP], [1], [Enable automatic backups])] 210 | ) 211 | 212 | AC_ARG_ENABLE([minidired], 213 | AS_HELP_STRING([--enable-minidired], 214 | [Enable minidired @<:@default=no@:>@])], 215 | [enable_minidired="${enableval:-yes}"], 216 | [enable_minidired=no]) 217 | AS_IF( 218 | [test "x$minidired" == "xyes"], 219 | [AC_DEFINE([MINIDIRED], [1], [Enable minidired mode.])] 220 | ) 221 | 222 | termh=no 223 | AC_CHECK_HEADERS([term.h], [termh=yes]) 224 | AS_IF([test "x$termh" != "xyes"], 225 | [AC_DEFINE([NO_TERMH], [1], [Define if there is no term.h.])]) 226 | 227 | dnl Just to silence the debian/rules warning 228 | 229 | AC_ARG_ENABLE([maintainer-mode], 230 | AS_HELP_STRING([--enable-maintainer-mode], 231 | [Enable maintainer-mode @<:@default=no@:>@])], 232 | [enable_maintainer_mode="${enableval:-yes}"], 233 | [enable_maintainer_mode=no]) 234 | 235 | AC_SUBST([AM_CPPFLAGS]) 236 | AC_CONFIG_FILES([Makefile bl/Makefile orig/Makefile]) 237 | AC_OUTPUT 238 | -------------------------------------------------------------------------------- /cpextern.h: -------------------------------------------------------------------------------- 1 | extern const ucs2 cp437[]; 2 | extern const ucs2 cp737[]; 3 | extern const ucs2 cp775[]; 4 | extern const ucs2 cp850[]; 5 | extern const ucs2 cp852[]; 6 | extern const ucs2 cp855[]; 7 | extern const ucs2 cp857[]; 8 | extern const ucs2 cp858[]; 9 | extern const ucs2 cp866[]; 10 | extern const ucs2 cp874[]; 11 | extern const ucs2 cp1250[]; 12 | extern const ucs2 cp1251[]; 13 | extern const ucs2 cp1252[]; 14 | extern const ucs2 cp1253[]; 15 | extern const ucs2 cp1254[]; 16 | extern const ucs2 cp1257[]; 17 | extern const ucs2 cp1258[]; 18 | extern const ucs2 iso_8859_1[]; 19 | extern const ucs2 iso_8859_2[]; 20 | extern const ucs2 iso_8859_3[]; 21 | extern const ucs2 iso_8859_4[]; 22 | extern const ucs2 iso_8859_5[]; 23 | extern const ucs2 iso_8859_7[]; 24 | extern const ucs2 iso_8859_9[]; 25 | extern const ucs2 iso_8859_10[]; 26 | extern const ucs2 iso_8859_11[]; 27 | extern const ucs2 iso_8859_13[]; 28 | extern const ucs2 iso_8859_14[]; 29 | extern const ucs2 iso_8859_15[]; 30 | extern const ucs2 iso_8859_16[]; 31 | extern const ucs2 koi8_r[]; 32 | extern const ucs2 koi8_u[]; 33 | extern const ucs2 utf_8[]; 34 | 35 | typedef const ucs2 *charset_t; 36 | typedef const struct {char *name; charset_t set; int flags;} charset_entry; 37 | 38 | extern const charset_entry charsets[]; 39 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | mg3a for Debian 2 | -------------- 3 | 4 | 5 | 6 | -- Pedro A. Aranda Gutiérrez Tue, 10 Jan 2023 17:47:48 +0100 7 | -------------------------------------------------------------------------------- /debian/README.source: -------------------------------------------------------------------------------- 1 | mg3a for Debian 2 | -------------- 3 | 4 | 6 | 7 | 8 | 9 | -- Pedro A. Aranda Gutiérrez Tue, 10 Jan 2023 17:47:48 +0100 10 | 11 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | mg3a (250112-1) UNRELEASED; urgency=medium 2 | 3 | * Fix enable mouse, add support for RPMs, compress READMEs 4 | 5 | -- Pedro A. Aranda Gutiérrez Sun, 12 Jan 2025 16:01:50 +0100 6 | 7 | mg3a (230110-1) UNRELEASED; urgency=medium 8 | 9 | * Initial release (Closes: #nnnn) 10 | 11 | -- Pedro A. Aranda Gutiérrez Tue, 10 Jan 2023 17:47:48 +0100 12 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: mg3a 2 | Section: unknown 3 | Priority: optional 4 | Maintainer: Pedro A. Aranda Gutiérrez 5 | Build-Depends: debhelper-compat (= 13), autotools-dev 6 | Standards-Version: 4.6.0 7 | Homepage: 8 | #Vcs-Browser: https://salsa.debian.org/debian/mg3a 9 | #Vcs-Git: https://salsa.debian.org/debian/mg3a.git 10 | Rules-Requires-Root: no 11 | 12 | Package: mg3a 13 | Architecture: any 14 | Depends: ${shlibs:Depends}, ${misc:Depends} 15 | Description: 16 | 17 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: mg3a 3 | Upstream-Contact: 4 | Source: 5 | 6 | Files: * 7 | Copyright: 8 | 9 | License: 10 | 11 | 12 | . 13 | 14 | 15 | # If you want to use GPL v2 or later for the /debian/* files use 16 | # the following clauses, or change it to suit. Delete these two lines 17 | Files: debian/* 18 | Copyright: 2023 Pedro A. Aranda Gutiérrez 19 | License: GPL-2+ 20 | This package is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU General Public License as published by 22 | the Free Software Foundation; either version 2 of the License, or 23 | (at your option) any later version. 24 | . 25 | This package is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU General Public License for more details. 29 | . 30 | You should have received a copy of the GNU General Public License 31 | along with this program. If not, see 32 | . 33 | On Debian systems, the complete text of the GNU General 34 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 35 | 36 | # Please also look if there are files or directories which have a 37 | # different copyright/license attached and list them here. 38 | # Please avoid picking licenses with terms that are more restrictive than the 39 | # packaged work, as it may make Debian's contributions unacceptable upstream. 40 | # 41 | # If you need, there are some extra license texts available in two places: 42 | # /usr/share/debhelper/dh_make/licenses/ 43 | # /usr/share/common-licenses/ 44 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | #export DH_VERBOSE = 1 5 | 6 | 7 | # see FEATURE AREAS in dpkg-buildflags(1) 8 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 9 | 10 | # see ENVIRONMENT in dpkg-buildflags(1) 11 | # package maintainers to append CFLAGS 12 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 13 | # package maintainers to append LDFLAGS 14 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 15 | 16 | 17 | %: 18 | dh $@ 19 | 20 | 21 | # dh_make generated override targets 22 | # This is example for Cmake (See https://bugs.debian.org/641051 ) 23 | #override_dh_auto_configure: 24 | # dh_auto_configure -- \ 25 | # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) 26 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /dir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MG 2a 3 | * Directory management functions 4 | * Created: Ron Flax (ron@vsedev.vse.com) 5 | * Modified for MG 2a by Mic Kaczmarczik 03-Aug-1987 6 | */ 7 | 8 | #include "def.h" 9 | 10 | char *wdir; 11 | static char cwd[NFILEN]; 12 | 13 | 14 | /* 15 | * Initialize anything the directory management routines need 16 | */ 17 | 18 | void 19 | dirinit() 20 | { 21 | if (!(wdir = getcwd(cwd, NFILEN))) 22 | panic("Can't get current directory!", errno); 23 | } 24 | 25 | 26 | /* 27 | * Change current working directory 28 | */ 29 | 30 | INT 31 | changedir(INT f, INT n) 32 | { 33 | INT s; 34 | char bufc[NFILEN], *adjf; 35 | 36 | if ((s=eread("Change default directory: ", bufc, NFILEN, EFFILE)) != TRUE) 37 | return(s); 38 | 39 | if (bufc[0] == '~') { 40 | if ((adjf = adjustname(bufc)) == NULL) return FALSE; 41 | stringcopy(bufc, adjf, NFILEN); 42 | } 43 | 44 | if (chdir(bufc) == -1) { 45 | ewprintf("Can't change dir to %s", bufc); 46 | return(FALSE); 47 | } else { 48 | if (!(wdir = getcwd(cwd, NFILEN))) 49 | panic("Can't get current directory!", errno); 50 | ewprintf("Current directory is now %s", wdir); 51 | return(TRUE); 52 | } 53 | } 54 | 55 | 56 | /* 57 | * Show current directory 58 | */ 59 | 60 | INT 61 | showcwdir(INT f, INT n) 62 | { 63 | ewprintf("Current directory: %s", wdir); 64 | return(TRUE); 65 | } 66 | -------------------------------------------------------------------------------- /kbd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kbd.h: type definitions for symbol.c and kbd.c for mg experimental 3 | */ 4 | 5 | typedef struct { 6 | KCHAR k_base; /* first key in element */ 7 | KCHAR k_num; /* last key in element */ 8 | PF *k_funcp; /* pointer to array of pointers to functions */ 9 | struct keymap_s *k_prefmap; /* keymap of ONLY prefix key in element */ 10 | } MAP_ELEMENT; 11 | 12 | 13 | /* 14 | * Predefined keymaps are NOT type KEYMAP because final array needs 15 | * dimension. If any changes are made to this struct, they must be 16 | * reflected in all keymap declarations. 17 | */ 18 | 19 | #define KEYMAPE(NUM) {\ 20 | KCHAR map_num;\ 21 | KCHAR map_max;\ 22 | PF map_default;\ 23 | MAP_ELEMENT map_element[NUM];\ 24 | } 25 | /* elements used */ 26 | /* elements allocated */ 27 | /* default function */ 28 | /* realy [e_max] */ 29 | typedef struct keymap_s KEYMAPE(1) KEYMAP; 30 | 31 | #define none ctrlg 32 | #define prefix (PF)NULL 33 | 34 | 35 | /* number of map_elements to grow an overflowed keymap by */ 36 | 37 | #define MAPGROW 3 38 | #define MAPINIT (MAPGROW+1) 39 | 40 | 41 | /* max number of default bindings added to avoid creating new element */ 42 | 43 | #define MAPELEDEF 4 44 | 45 | #define MODE_NAMEDYN 1 // Mode name was dynamically allocated 46 | 47 | typedef struct { 48 | KEYMAP *p_map; 49 | char *p_name; 50 | int p_flags; 51 | char *p_commands; 52 | } MAPS; 53 | 54 | extern MAPS *map_table; 55 | 56 | typedef const struct { 57 | PF n_funct; 58 | char *n_name; 59 | int n_flag; 60 | } FUNCTNAMES; 61 | 62 | extern const FUNCTNAMES functnames[]; 63 | extern const INT nfunct; 64 | 65 | PF doscan(KEYMAP *map, INT c); 66 | char *map_name(KEYMAP *map); 67 | MODE name_mode(char *name); 68 | char *mode_name(MODE mode); 69 | char *mode_name_check(MODE mode); 70 | KEYMAP *mode_map(MODE mode); 71 | int invalid_mode(MODE mode); 72 | KEYMAP *name_map(char *name); 73 | PF name_function(char *fname); 74 | INT complete_function(char *fname, INT c); 75 | char *function_name(PF fpoint); 76 | 77 | extern MAP_ELEMENT *ele; 78 | -------------------------------------------------------------------------------- /key.h: -------------------------------------------------------------------------------- 1 | /* key.h: Insert file for mg 2 functions that need to reference key pressed */ 2 | 3 | #define MAXKEY 16 /* maximum number of prefix chars */ 4 | 5 | typedef struct { /* the chacter sequence in a key */ 6 | INT k_count; /* number of chars */ 7 | KCHAR k_chars[MAXKEY]; /* chars */ 8 | } key_struct; 9 | 10 | extern key_struct key; 11 | -------------------------------------------------------------------------------- /langmode_make.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is in the public domain. 3 | * 4 | * Author: Pedro A. Aranda 5 | * 6 | * Modified by: Bengt Larsson. 7 | * 8 | */ 9 | 10 | /* 11 | * Implement a mode for editing Makefiles 12 | */ 13 | 14 | #include "def.h" 15 | 16 | 17 | #ifdef LANGMODE_MAKE 18 | /* 19 | * Enable/toggle python-mode 20 | */ 21 | 22 | INT 23 | makemode(INT f, INT n) 24 | { 25 | return changemode(curbp, f, n, "make"); 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /langmode_python.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is in the public domain. 3 | * 4 | * Author: Pedro A. Aranda 5 | * 6 | * Modified by: Bengt Larsson. 7 | * 8 | */ 9 | 10 | /* 11 | * Implement a mode for editing Python code. 12 | */ 13 | 14 | #include "def.h" 15 | 16 | 17 | #ifdef LANGMODE_PYTHON 18 | 19 | 20 | static int 21 | is_blank(INT c) 22 | { 23 | return (c == ' ') || (c == '\t'); 24 | } 25 | 26 | 27 | static LINE * 28 | findnonblank(LINE *lp) 29 | { 30 | while (lback(lp) != curbp->b_linep) { 31 | INT curchar, offs; 32 | lp = lback(lp); 33 | for (offs = 0; offs < llength(lp); offs++) { 34 | curchar = lgetc(lp,offs); 35 | if (is_blank(curchar)) 36 | continue; 37 | if (curchar != '#') 38 | return lp; 39 | break; 40 | } 41 | } 42 | return lp; 43 | } 44 | 45 | 46 | /* 47 | * Get the level of indention after line lp is processed 48 | * return value = value affecting subsequent lines. 49 | */ 50 | 51 | static INT 52 | _getpyindent(LINE *lp) 53 | { 54 | INT col, i, c; 55 | 56 | if (getindent(lp, NULL, &col) == FALSE) return -1; 57 | 58 | for (i = llength(lp) - 1; i >= 0; i--) { 59 | c = lgetc(lp, i); 60 | 61 | if (c == ':') { 62 | if (col < MAXINT - 100) col += gettabsize(curbp); 63 | break; 64 | } else if (!is_blank(c)) { 65 | break; 66 | } 67 | } 68 | 69 | return col; 70 | } 71 | 72 | 73 | static INT 74 | getpyindent(LINE *lp) 75 | { 76 | return _getpyindent(findnonblank(lp)); 77 | } 78 | 79 | 80 | /* 81 | * Enable/toggle python-mode 82 | */ 83 | 84 | INT 85 | pymode(INT f, INT n) 86 | { 87 | return changemode(curbp, f, n, "python"); 88 | } 89 | 90 | 91 | /* 92 | * Attempt to indent current line 93 | */ 94 | 95 | INT 96 | py_indent(INT f, INT n) 97 | { 98 | return setindent(getpyindent(curwp->w_dotp)); 99 | } 100 | 101 | 102 | /* 103 | * Python newline and indent 104 | */ 105 | 106 | INT 107 | py_lfindent(INT f, INT n) 108 | { 109 | if (n < 0) return FALSE; 110 | 111 | while (n-- > 0) { 112 | if (lnewline() == FALSE) return FALSE; 113 | if (py_indent(FFRAND, 1) == FALSE) return FALSE; 114 | } 115 | 116 | return TRUE; 117 | } 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /macro.h: -------------------------------------------------------------------------------- 1 | /* definitions for keyboard macros */ 2 | 3 | #define MAXMACRO 256 /* maximum functs in a macro */ 4 | 5 | extern INT inmacro; 6 | extern INT inkbdmacro; 7 | extern INT macrodef; 8 | extern INT macrocount; 9 | 10 | typedef union { 11 | PF m_funct; 12 | INT m_count; /* for count-prefix */ 13 | INT m_flag; /* Mg3a: save the flag also */ 14 | } macrorecord; 15 | 16 | extern macrorecord macro[]; 17 | 18 | extern LINE *maclhead; 19 | extern LINE *maclcur; 20 | extern LINE *cmd_maclhead; /* For excline() */ 21 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mainline 3 | */ 4 | #include "def.h" 5 | #include "macro.h" 6 | 7 | #include 8 | 9 | INT thisflag = 0; /* Flags, this command */ 10 | INT lastflag = 0; /* Flags, last command */ 11 | INT curgoal = 0; /* Goal column */ 12 | BUFFER *curbp; /* Current buffer */ 13 | WINDOW *curwp; /* Current window */ 14 | BUFFER *bheadp = NULL; /* BUFFER listhead */ 15 | WINDOW *wheadp = NULL; /* WINDOW listhead */ 16 | char pat[NPAT] = ""; /* Pattern */ 17 | #ifndef NO_DPROMPT 18 | extern char prompt[], *promptp; /* delayed prompting */ 19 | #endif 20 | INT inhibit_startup = 0; /* Inhibit startup files */ 21 | 22 | extern char version[]; 23 | static void edinit(void); 24 | 25 | INT gotoline(INT f, INT n); 26 | void iresetmark(void); 27 | 28 | static int 29 | usage(char *progname) 30 | { 31 | fprintf(stderr, "Usage:\n %s [-q] [-p pattern] [-L loadfile] [-l loadfile]" 32 | " [-e commands] [+line] [files...]\n", progname); 33 | fprintf(stderr, " %s -v: print program version\n", progname); 34 | return 1; 35 | } 36 | 37 | 38 | int 39 | main(int argc, char *argv[]) 40 | { 41 | char *cp; 42 | BUFFER *bp; 43 | INT c, n; 44 | char *linearg = NULL; 45 | INT lineno; 46 | char *loadfile = NULL, *startexpr = NULL, *pre_loadfile = NULL; 47 | #ifdef PIPEIN 48 | FILE *pipein = NULL; 49 | 50 | if (!isatty(fileno(stdin))) { 51 | /* 52 | * Create a copy of stdin for future use 53 | */ 54 | pipein = fdopen(dup(fileno(stdin)),"r"); 55 | /* 56 | * Reopen the console device /dev/tty as stdin 57 | */ 58 | stdin = freopen("/dev/tty","r",stdin); 59 | } 60 | #else 61 | if (!isatty(0)) { 62 | fprintf(stderr, "mg: standard input is not a tty\n"); 63 | exit(1); 64 | } 65 | #endif 66 | setlocale(LC_ALL, ""); 67 | 68 | while ((c = getopt(argc, argv, "vqp:L:l:e:")) != -1) { 69 | switch (c) { 70 | case 'v': 71 | fprintf(stdout,"%s\n",version); 72 | exit(0); 73 | break; 74 | case 'q': 75 | inhibit_startup = 1; 76 | break; 77 | case 'p': 78 | stringcopy(pat, optarg, NPAT); 79 | break; 80 | case 'L': 81 | pre_loadfile = optarg; 82 | break; 83 | case 'l': 84 | loadfile = optarg; 85 | break; 86 | case 'e': 87 | startexpr = optarg; 88 | break; 89 | default: 90 | return usage(argv[0]); 91 | } 92 | } 93 | 94 | vtinit(); /* Virtual terminal. */ 95 | dirinit(); /* Get current directory */ 96 | edinit(); /* Buffers, windows. */ 97 | 98 | /* 99 | * Doing update() before reading files causes the error 100 | * messages from the file I/O show up on the screen. (and also 101 | * an extra display of the mode line if there are files 102 | * specified on the command line.) 103 | */ 104 | 105 | update(); 106 | 107 | ttykeymapinit(); /* Symbols, bindings. */ 108 | 109 | if (!inhibit_startup && (cp = startupfile(NULL)) != NULL) { 110 | load(cp); 111 | } 112 | 113 | /* "-L" argument */ 114 | 115 | if (pre_loadfile) load(pre_loadfile); 116 | 117 | if ((bp = bfind("*scratch*", TRUE)) != NULL) { 118 | resetbuffer(bp); /* Buffer "*scratch*" will need reset of modes */ 119 | } 120 | 121 | /* Goto line if two arguments */ 122 | 123 | if (argc - optind == 2) { 124 | if (argv[optind][0] == '+') { 125 | linearg = argv[optind]; 126 | optind++; 127 | } else if (argv[argc - 1][0] == '+') { 128 | linearg = argv[argc - 1]; 129 | argc--; 130 | } 131 | } 132 | 133 | for (n = argc - 1; n >= optind; n--) { /* Backwards, for prettier list */ 134 | if ((cp = adjustname(argv[n])) == NULL) continue; 135 | #ifndef DIRED 136 | if (isdirectory(cp)) continue; 137 | #endif 138 | if (existsandnotreadable(cp)) continue; 139 | if ((bp = findbuffer(cp)) == NULL) break; 140 | 141 | curbp = bp; 142 | showbuffer(curbp, curwp); 143 | 144 | if (readin(cp) != TRUE) break; 145 | } 146 | #ifdef PIPEIN 147 | if (NULL != pipein) { 148 | if ((bp = findbuffer("*stdin*")) != NULL) { 149 | curbp = bp; 150 | showbuffer(curbp, curwp); 151 | freadin(pipein); 152 | curbp->b_flag |= BFREADONLY; 153 | } 154 | } 155 | #endif 156 | if (linearg) { 157 | if (linearg[1] == 0) gotoline(FFARG, 0); 158 | else if (getINT(linearg + 1, &lineno, 1)) gotoline(FFARG, lineno); 159 | } 160 | 161 | if (loadfile) load(loadfile); 162 | if (startexpr) excline_copy_list(startexpr); 163 | 164 | for(;;) { 165 | #ifndef NO_DPROMPT 166 | *(promptp = prompt) = '\0'; 167 | #endif 168 | if (epresf == KPROMPT) eerase(); 169 | else if (epresf == TRUE) epresf = KPROMPT; 170 | 171 | ucs_adjust(); 172 | update(); 173 | 174 | lastflag = thisflag; 175 | thisflag = 0; 176 | 177 | switch(doin()) { 178 | case TRUE: break; 179 | case ABORT: 180 | while (type_ahead()) ttgetc(); 181 | if (!(thisflag & CFNOQUIT)) ewprintf("Quit"); 182 | /* fallthrough */ 183 | case FALSE: 184 | default: 185 | ttbeep(); 186 | #ifndef NO_MACRO 187 | macrodef = FALSE; 188 | #endif 189 | } 190 | } 191 | } 192 | 193 | 194 | /* 195 | * Initialize default buffer and window. 196 | */ 197 | 198 | static void 199 | edinit() 200 | { 201 | BUFFER *bp; 202 | WINDOW *wp; 203 | 204 | bheadp = NULL; 205 | bp = bfind("*scratch*", TRUE); /* Text buffer. */ 206 | wp = (WINDOW *)malloc(sizeof(WINDOW)); /* Initial window. */ 207 | if (bp==NULL || wp==NULL) panic("edinit", 0); 208 | curbp = bp; /* Current ones. */ 209 | wheadp = wp; 210 | curwp = wp; 211 | wp->w_wndp = NULL; /* Initialize window. */ 212 | wp->w_bufp = bp; 213 | bp->b_nwnd = 1; /* Displayed. */ 214 | wp->w_linep = wp->w_dotp = bp->b_linep; 215 | wp->w_doto = 0; 216 | wp->w_markp = NULL; 217 | wp->w_marko = 0; 218 | wp->w_toprow = 0; 219 | wp->w_ntrows = nrow-2; /* 2 = mode, echo. */ 220 | wp->w_force = 0; 221 | wp->w_flag = WFMODE|WFHARD; /* Full. */ 222 | wp->w_dotpos = 0; 223 | 224 | variable_completion_init(); 225 | } 226 | 227 | 228 | /* 229 | * Mg3a: Warn for new behavior of "save-buffers-kill-emacs" with an 230 | * argument. Return TRUE if OK to save and exit. 231 | */ 232 | 233 | static INT 234 | quit_warning() 235 | { 236 | BUFFER *bp; 237 | INT s; 238 | 239 | bp = emptyhelpbuffer(); 240 | if (!bp) return FALSE; 241 | 242 | if ((s = addline(bp, "Mg now behaves like GNU Emacs when \"save-buffers-kill-emacs\" is called")) != TRUE) 243 | return s; 244 | 245 | if ((s = addline(bp, "with an argument: all modified buffers will be saved before exiting.")) != TRUE) 246 | return s; 247 | 248 | if ((s = addline(bp, "")) != TRUE) 249 | return s; 250 | 251 | if ((s = addline(bp, "To turn off this warning set bit 1 in the variable \"emacs-compat\".")) != TRUE) 252 | return s; 253 | 254 | if ((s = addline(bp, "")) != TRUE) 255 | return s; 256 | 257 | if ((s = addline(bp, "To exit easily without saving, assign \"kill-emacs\" to a key.")) != TRUE) 258 | return s; 259 | 260 | if ((s = popbuftop(bp)) != TRUE) return s; 261 | 262 | update(); 263 | 264 | return eyesno("Save all modified buffers and exit"); 265 | } 266 | 267 | 268 | /* 269 | * Quit command. 270 | */ 271 | 272 | INT 273 | quit(INT f, INT n) 274 | { 275 | INT s, saveall = 0; 276 | 277 | if (inmacro) { 278 | if (anycb(1) != FALSE) { 279 | return emessage(FALSE, "Some buffers could not be saved; not exiting"); 280 | } 281 | 282 | vttidy(); 283 | exit(GOOD); 284 | } 285 | 286 | if (f & FFRAND) { 287 | saveall = 1; 288 | } else if (f & FFARG) { 289 | if (!(emacs_compat & 1) && (s = quit_warning()) != TRUE) return s; 290 | saveall = 1; 291 | } 292 | 293 | if ((s = anycb(saveall)) == ABORT) return ABORT; 294 | 295 | if (s == FALSE 296 | || eyesno("Modified buffers exist, really exit") == TRUE) { 297 | vttidy(); 298 | exit(GOOD); 299 | } 300 | return TRUE; 301 | } 302 | 303 | 304 | /* 305 | * Mg3a: Quick exit 306 | */ 307 | 308 | INT 309 | hardquit(INT f, INT n) 310 | { 311 | vttidy(); 312 | exit(GOOD); 313 | 314 | return TRUE; 315 | } 316 | 317 | 318 | /* 319 | * Mg3a: Save all files and exit (not in Emacs) 320 | */ 321 | 322 | INT 323 | save_and_exit(INT f, INT n) 324 | { 325 | return quit(FFRAND, 1); 326 | } 327 | 328 | 329 | /* 330 | * paaguti: in Emacs, Ctrl-G clears the mark! 331 | */ 332 | 333 | INT keyboard_quit(INT f, INT n) 334 | { 335 | ewprintf("Clearing..."); 336 | iresetmark(); 337 | return TRUE; 338 | } 339 | 340 | /* 341 | * User abort. Should be called by any input routine that sees a C-g 342 | * to abort whatever C-g is aborting these days. Currently does 343 | * nothing. 344 | */ 345 | INT 346 | ctrlg(INT f, INT n) 347 | { 348 | return ABORT; 349 | } 350 | -------------------------------------------------------------------------------- /match.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MicroEMACS 3 | * Limited parenthesis matching routines 4 | * 5 | * The hacks in this file implement automatic matching of (), [], {}, 6 | * and other characters. It would be better to have a full-blown 7 | * syntax table, but there's enough overhead in the editor as it is. 8 | * 9 | * Since I often edit Scribe code, I've made it possible to blink 10 | * arbitrary characters -- just bind delimiter characters to 11 | * "blink-and-insert" 12 | */ 13 | 14 | #include "def.h" 15 | #include "key.h" 16 | 17 | static INT balance(void); 18 | 19 | INT selfinsert(INT f, INT n); 20 | 21 | 22 | /* 23 | * Balance table. When balance() encounters a character that is to be 24 | * matched, it first searches this table for a balancing left-side 25 | * character. If the character is not in the table, the character is 26 | * balanced by itself. This is to allow delimiters in Scribe documents 27 | * to be matched. 28 | * 29 | * Mg3a: Added Unicode angled brackets. 30 | */ 31 | 32 | static const struct balance { 33 | ucs2 left, right; 34 | } bal[] = { 35 | { '(', ')' }, 36 | { '[', ']' }, 37 | { '{', '}' }, 38 | { '<', '>' }, 39 | { 0xab, 0xbb }, 40 | { 0x2039, 0x203a }, 41 | { '\0','\0'} 42 | }; 43 | 44 | 45 | /* 46 | * Mg3a: Return the left paren of, or zero 47 | */ 48 | 49 | INT 50 | leftparenof(INT c) 51 | { 52 | INT i; 53 | 54 | for (i = 0;; i++) { 55 | if (bal[i].right == c) return bal[i].left; 56 | if (bal[i].right == 0) return 0; 57 | } 58 | } 59 | 60 | 61 | /* 62 | * Mg3a: Return the right paren of, or 0 63 | */ 64 | 65 | INT 66 | rightparenof(INT c) 67 | { 68 | INT i; 69 | 70 | for (i = 0;; i++) { 71 | if (bal[i].left == c) return bal[i].right; 72 | if (bal[i].left == 0) return 0; 73 | } 74 | } 75 | 76 | 77 | /* 78 | * Self-insert character, then show matching character, if any. Bound 79 | * to "blink-and-insert". 80 | */ 81 | 82 | INT 83 | showmatch(INT f, INT n) 84 | { 85 | INT s; 86 | 87 | if ((s = selfinsert(f|FFRAND, n)) != TRUE) return s; 88 | if (balance() != TRUE) ttbeep(); /* unbalanced -- warn user */ 89 | 90 | return TRUE; 91 | } 92 | 93 | 94 | /* 95 | * Search for and display a matching character. 96 | * 97 | * This routine does the real work of searching backward for a 98 | * balancing character. If such a balancing character is found, it 99 | * uses displaymatch() to display the match. 100 | * 101 | * Mg3a: Do Unicode chars. 102 | */ 103 | 104 | static INT 105 | balance() 106 | { 107 | LINE *clp; 108 | INT cbo, cbsave, size = 0; 109 | INT c; 110 | INT rbal, lbal; 111 | ssize_t depth; 112 | charset_t charset = curbp->charset; 113 | 114 | rbal = key.k_chars[key.k_count-1]; 115 | 116 | if (ucs_width(rbal) == 0) return FALSE; /* Not useful */ 117 | 118 | /* See if there is a matching character -- default to the same */ 119 | 120 | lbal = leftparenof(rbal); 121 | if (lbal == 0) lbal = rbal; 122 | 123 | /* Move behind the inserted character. We are always guaranteed */ 124 | /* that there is at least one character on the line, since one was */ 125 | /* just self-inserted by blinkparen. */ 126 | 127 | clp = curwp->w_dotp; 128 | cbo = ucs_prevc(charset, clp, curwp->w_doto); 129 | 130 | depth = 0; /* init nesting depth */ 131 | 132 | for (;;) { 133 | if (cbo == 0) { /* beginning of line */ 134 | clp = lback(clp); 135 | if (clp == curbp->b_linep) 136 | return (FALSE); 137 | cbo = llength(clp)+1; 138 | } 139 | 140 | cbsave = cbo; 141 | 142 | if (cbo == llength(clp) + 1) { /* end of line */ 143 | cbo--; 144 | c = '\n'; 145 | } else { /* somewhere in middle */ 146 | c = lgetc(clp, cbo - 1); 147 | 148 | if (c < 128) { /* speed up ASCII */ 149 | cbo--; 150 | } else { 151 | cbo = ucs_prevc(charset, clp, cbo); 152 | c = ucs_char(charset, clp, cbo, NULL); 153 | } 154 | } 155 | 156 | /* Check for a matching character. If still in a nested */ 157 | /* level, pop out of it and continue search. This check */ 158 | /* is done before the nesting check so single-character */ 159 | /* matches will work too. */ 160 | if (c == lbal) { 161 | if (depth == 0) { 162 | displaymatch(clp, cbo); 163 | return (TRUE); 164 | } 165 | else 166 | depth--; 167 | } 168 | /* Check for another level of nesting. */ 169 | if (c == rbal) 170 | depth++; 171 | 172 | /* Limit max size like Emacs */ 173 | size += (cbsave - cbo); 174 | if (size > 102400) return FALSE; 175 | } 176 | /*NOTREACHED*/ 177 | } 178 | 179 | 180 | /* 181 | * Mg3a: How long to blink the matching paren, in milliseconds 182 | */ 183 | 184 | INT blink_wait = 1000; 185 | 186 | 187 | /* 188 | * Display matching character. Matching characters that are not in the 189 | * current window are displayed in the echo line. If in the current 190 | * window, move dot to the matching character, sit there a while, then 191 | * move back. 192 | */ 193 | 194 | void 195 | displaymatch(LINE *clp, INT cbo) 196 | { 197 | LINE *tlp; 198 | INT tbo; 199 | INT i; 200 | INT bufo; 201 | INT c; 202 | int inwindow; 203 | 204 | /* Figure out if matching char is in current window by */ 205 | /* searching from the top of the window to dot. */ 206 | 207 | inwindow = 0; 208 | for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp); tlp = lforw(tlp)) 209 | if (tlp == clp) 210 | inwindow = 1; 211 | 212 | if (inwindow && blink_wait > 0 && blink_wait <= 10000) { 213 | tlp = curwp->w_dotp; /* save current position */ 214 | tbo = curwp->w_doto; 215 | 216 | adjustpos(clp, cbo); /* move to new position */ 217 | 218 | update(); /* show match */ 219 | waitforinput(blink_wait); /* wait for a while, or for input */ 220 | 221 | adjustpos(tlp, tbo); /* return to old position */ 222 | } else { /* match not in this window so display line in echo area */ 223 | bufo = 0; 224 | estart(); 225 | ewprintfc("Matches "); 226 | for (i = 0; i < llength(clp);) { /* expand tabs */ 227 | c = ucs_char(curbp->charset, clp, i, &i); 228 | 229 | if (c == '\t') { 230 | do { 231 | ewprintfc(" "); 232 | bufo++; 233 | } while (bufo & 7); 234 | } else { 235 | ewprintfc("%C", c); 236 | bufo += ucs_termwidth(c); 237 | } 238 | 239 | if (i > cbo || bufo > ncol) break; 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /orig/Makefile.am: -------------------------------------------------------------------------------- 1 | origdir = $(datarootdir)/doc/@PACKAGE@/orig 2 | orig_DATA = README tutorial mg.tex mg.pdf 3 | -------------------------------------------------------------------------------- /orig/mg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paaguti/mg3a/9b2cb78fe2d1f723ce4f72bf4dd042f2c926d690/orig/mg.pdf -------------------------------------------------------------------------------- /orig/mg2a.change: -------------------------------------------------------------------------------- 1 | Here is a list of some of the changes from Mg version 1b to 2a, in 2 | reverse semi-cronological order. Much is only of interest if you are 3 | modifying Mg. Some things may only apply relitive to beta versions. 4 | (I tried to edit these out.) 5 | 6 | 7 | The kill buffer should now avoid growing bigger than possible. 8 | (malloc takes an unsigned arg, which may only be 16 bits.) This is a 9 | temporary hack until the kill buffer code is rewriten. 10 | 11 | Bcopy is NOT used properly, the third argument should be declared 12 | unsigned but isn't. 16 bit int systems need to treat the third agument 13 | as unsigned. 14 | 15 | Added functions set-default-mode, global-unset-key, and 16 | local-unset-key. dired_ functions in system dependent code now need 17 | to set bp->b_nmodes to 0. 18 | 19 | Function key binding should finally work properly. #define FKEYS 20 | if you have function keys that don't fit into a char. 21 | 22 | Termcap XKEYS code completly rewritten. It does not use the FKEYS 23 | code. Terminal-dependant initialization files may now be present. 24 | 25 | System dependent routine startupfile now takes a single char * 26 | arguement. It is NULL for the normal startup file, the terminal type 27 | name for the terminal dependent file. The BSD version no longer tries 28 | to use .emacs if .mg isn't found. BSD, SYS V, and OSK versions can 29 | look for a system-wide startup file if STARTUPFILE is #defined to the 30 | directory to look in. 31 | 32 | Extend.c now has a dependancy on key.h. 33 | 34 | Insert-file now uses adjustname. 35 | 36 | Optional SYSCLEANUP macro. 37 | 38 | Various changes to make mg smaller and faster. 39 | 40 | Portability issuses: Identifiers should now be unique in first 7 41 | chars. (Change dired_makename to d_makename in fileio.c.) Lint found 42 | various bugs. 43 | 44 | Character set dependent portion of def.h moved to 45 | sys/default/chrdef.h. Cinfo.c moved there. tty/termcap/* moved 46 | there. 47 | 48 | Bug fixes: insert-file, fill-paragraph, startup code, "make lint" 49 | in bsd makefile. 50 | 51 | "varargs.h" in sys/default is for systems that worked with the 52 | non-varargs code on mg1. It does not work on systems that don't 53 | happen to pass arguments that way. 54 | 55 | fncmp is now also used to compare buffer names. Buffer names are 56 | now case sensitive iff file names are. 57 | 58 | The #ifndef ... in some files moved after the #include "def.h". 59 | This should be better for systems that define various things in 60 | sysdef.h. Let me know what I missed. 61 | 62 | Minibuffer and search commands modified so ^H does the same as ^?, 63 | ^\ as ^Q, and ^] as ^S. bsmap-mode may be done by key bindings, 64 | flow-mode still needs to toggle system-dependent capture of ^S/^Q. 65 | re_search.c probably needs to change also. 66 | 67 | dired mode. (requires a significant amount of system dependent code.) 68 | 69 | Two case, non-case sensitive systems are now fully supported. The 70 | routine fncmp is used to compare file names. (strcmp may be used on 71 | monocase or case sensitive systems.) 72 | 73 | If NO_DIR is not defined, adjustname (the replacement for 74 | adjustcase) must append the directory name to the filename if it 75 | doesn't have one already. 76 | 77 | Cleanup and rearangement. symbol.c has been renamed to keymap.c. 78 | The key name function has been moved to cinfo.c to reduce the number 79 | of files dependent on character set. 80 | 81 | The terminal type determining code has been moved out of 82 | sys/default/tty.c. For unix systems, just "#define gettermtype() 83 | getenv("TERM")". For VMS and Primos, it's a bit more compicated. 84 | 85 | I made some changes to the regular expression code to get it to 86 | compile under os9/68k. It now compiles, but requires a number of 87 | routines not present in the library that would be difficult to 88 | implement. 89 | 90 | lalloc has be rewriten and split into lallocx (for lines not 91 | expected to grow) and lalloc. The OFFSET macro may have to be defined 92 | in the system dependent file if the normal definition supplied will 93 | not work with your compiler. (I considered alternatives, but could 94 | not think of one that used as little storage. Use the offsetof macro 95 | if your compiler conforms to the ANSI C draft standard.) The 96 | MALLOCROUND macro should be defined if you can predict the behavior of 97 | your libraries malloc. It takes a single lvalue arguement, and rounds 98 | it up to the amount of memory that realy would be allocated by a 99 | malloc of that size. (This is most important on memory tight systems.) 100 | 101 | Apropos is new. It has a few minor problems: slow, displays only 102 | global key bindings, dosn't like lots of keys bound to the same 103 | function. (Digit-argument is closest to causing problems.) Its 104 | output should probably be the basis of future functions files. 105 | 106 | The file reading and writing code has changed to fix a couple of 107 | long-standing bugs. Files no longer get an extra newline at the end 108 | of the last line if it doesn't have one. Line length is now only 109 | limited by memory and how big a number will fit in a short int. See 110 | description below on what needs to change. 111 | 112 | Umpteen minor bugs fixed. If anyone is doing serious development 113 | based on 1b, some should be merged back in. (Kill-buffer had several 114 | bugs, help didn't redisplay properly if the *help* buffer was already 115 | present, etc.) 116 | 117 | The display wrap code is better that what was done before, but not at 118 | all what GNU emacs does in the same situation. 119 | 120 | Compile options have been changed to make those things present in GNU 121 | emacs the default. Compile-time options to turn on features not in 122 | GNU emacs and to turn of features that are in GNU emacs are documented 123 | below. 124 | -------------------------------------------------------------------------------- /orig/mgidx.tex: -------------------------------------------------------------------------------- 1 | \indexentry{apropos}{31} 2 | \indexentry{auto-fill-mode}{27} 3 | \indexentry{auto-indent-mode}{28} 4 | \indexentry{backward-char}{9} 5 | \indexentry{backward-kill-word}{14} 6 | \indexentry{backward-paragraph}{9} 7 | \indexentry{backward-word}{9} 8 | \indexentry{beginning-of-buffer}{9} 9 | \indexentry{beginning-of-line}{9} 10 | \indexentry{blink-matching-paren}{28} 11 | \indexentry{blink-matching-paren-hack}{28} 12 | \indexentry{call-last-kbd-macro}{32} 13 | \indexentry{capitalize-word}{32} 14 | \indexentry{cd}{25} 15 | \indexentry{copy-region-as-kill}{14} 16 | \indexentry{count-matches}{19} 17 | \indexentry{count-non-matches}{19} 18 | \indexentry{define-key}{34} 19 | \indexentry{delete-backward-char}{14} 20 | \indexentry{delete-blank-lines}{14} 21 | \indexentry{delete-char}{14} 22 | \indexentry{delete-horizontal-space}{15} 23 | \indexentry{delete-matching-lines}{19} 24 | \indexentry{delete-non-matching-lines}{19} 25 | \indexentry{delete-other-windows}{21} 26 | \indexentry{delete-window}{21} 27 | \indexentry{describe-bindings}{31} 28 | \indexentry{describe-key-briefly}{31} 29 | \indexentry{digit-argument}{8} 30 | \indexentry{dired}{29} 31 | \indexentry{dired-backup-unflag}{29} 32 | \indexentry{dired-copy-file}{29} 33 | \indexentry{dired-do-deletions}{29} 34 | \indexentry{dired-find-file}{29} 35 | \indexentry{dired-find-file-other-window}{29} 36 | \indexentry{dired-flag-file-deleted}{29} 37 | \indexentry{dired-other-window}{30} 38 | \indexentry{dired-rename-file}{30} 39 | \indexentry{dired-unflag}{30} 40 | \indexentry{downcase-region}{32} 41 | \indexentry{downcase-word}{32} 42 | \indexentry{emacs-version}{32} 43 | \indexentry{end-kbd-macro}{32} 44 | \indexentry{end-of-buffer}{9} 45 | \indexentry{end-of-line}{10} 46 | \indexentry{enlarge-window}{21} 47 | \indexentry{eval-current-buffer}{36} 48 | \indexentry{eval-expression}{36} 49 | \indexentry{exchange-point-and-mark}{10} 50 | \indexentry{execute-extended-command}{8} 51 | \indexentry{fill-paragraph}{27} 52 | \indexentry{find-file}{24} 53 | \indexentry{find-file-other-window}{24} 54 | \indexentry{forward-char}{10} 55 | \indexentry{forward-paragraph}{10} 56 | \indexentry{forward-word}{10} 57 | \indexentry{global-set-key}{34} 58 | \indexentry{global-unset-key}{34} 59 | \indexentry{goto-line}{10} 60 | \indexentry{help-help}{31} 61 | \indexentry{insert}{12} 62 | \indexentry{insert-buffer}{23} 63 | \indexentry{insert-file}{24} 64 | \indexentry{insert-with-wrap}{27} 65 | \indexentry{isearch-backward}{16} 66 | \indexentry{isearch-forward}{16} 67 | \indexentry{just-one-space}{15} 68 | \indexentry{keyboard-quit}{8} 69 | \indexentry{kill-buffer}{23} 70 | \indexentry{kill-line}{15} 71 | \indexentry{kill-paragraph}{15} 72 | \indexentry{kill-region}{15} 73 | \indexentry{kill-word}{15} 74 | \indexentry{list-buffers}{23} 75 | \indexentry{load}{36} 76 | \indexentry{local-set-key}{34} 77 | \indexentry{local-unset-key}{35} 78 | \indexentry{make-backup-files}{25} 79 | \indexentry{meta-key-mode}{32} 80 | \indexentry{negative-argument}{8} 81 | \indexentry{newline}{12} 82 | \indexentry{newline-and-indent}{12} 83 | \indexentry{next-line}{10} 84 | \indexentry{no-tab-mode}{26} 85 | \indexentry{not-modified}{24} 86 | \indexentry{open-line}{12} 87 | \indexentry{other-window}{21} 88 | \indexentry{overwrite-mode}{27} 89 | \indexentry{prefix-region}{33} 90 | \indexentry{previous-line}{10} 91 | \indexentry{previous-window}{22} 92 | \indexentry{pwd}{25} 93 | \indexentry{query-replace}{17} 94 | \indexentry{query-replace-regexp}{19} 95 | \indexentry{quoted-insert}{12} 96 | \indexentry{re-search-again}{20} 97 | \indexentry{re-search-backward}{20} 98 | \indexentry{re-search-forward}{20} 99 | \indexentry{recenter}{10} 100 | \indexentry{redraw-display}{11} 101 | \indexentry{save-buffer}{24} 102 | \indexentry{save-buffers-kill-emacs}{24} 103 | \indexentry{save-some-buffers}{25} 104 | \indexentry{scroll-down}{11} 105 | \indexentry{scroll-one-line-down}{11} 106 | \indexentry{scroll-one-line-up}{11} 107 | \indexentry{scroll-other-window}{11} 108 | \indexentry{scroll-up}{11} 109 | \indexentry{search-again}{17} 110 | \indexentry{search-backward}{17} 111 | \indexentry{search-forward}{17} 112 | \indexentry{self-insert-command}{13} 113 | \indexentry{set-case-fold-search}{20} 114 | \indexentry{set-default-mode}{26} 115 | \indexentry{set-fill-column}{27} 116 | \indexentry{set-mark-command}{11} 117 | \indexentry{set-prefix-string}{33} 118 | \indexentry{shrink-window}{22} 119 | \indexentry{space-to-tabstop}{26} 120 | \indexentry{split-window-vertically}{22} 121 | \indexentry{start-kbd-macro}{32} 122 | \indexentry{suspend-emacs}{33} 123 | \indexentry{switch-to-buffer}{24} 124 | \indexentry{switch-to-buffer-other-window}{24} 125 | \indexentry{transpose-chars}{33} 126 | \indexentry{universal-argument}{8} 127 | \indexentry{upcase-region}{32} 128 | \indexentry{upcase-word}{32} 129 | \indexentry{what-cursor-position}{11} 130 | \indexentry{write-file}{25} 131 | \indexentry{yank}{15} 132 | -------------------------------------------------------------------------------- /orig/sys/README: -------------------------------------------------------------------------------- 1 | Some of the older system-specific files that may be useful to 2 | look at. Not used anymore. 3 | -------------------------------------------------------------------------------- /orig/sys/bsd/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Mg 2a 2 | 3 | SYS = bsd 4 | LIBS = -ltermcap 5 | # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't 6 | # get passed to lint. 7 | # 8 | # (Common) compile-time options: 9 | # 10 | # DO_METAKEY -- if bit 7 is set for a key, treat like a META key 11 | # STARTUP -- look for and handle initialization file 12 | # SYMBLINK -- follow symbolic links the same as the BSD kernel 13 | # XKEYS -- use termcap function key definitions. Warning - 14 | # XKEYS and bsmap mode do _not_ get along. 15 | # BACKUP -- enable "make-backup-files" 16 | # PREFIXREGION -- enable function "prefix-region" 17 | # REGEX -- create regular expression functions 18 | # 19 | #CDEFS = -DDO_METAKEY 20 | CDEFS = -DDO_METAKEY -DPREFIXREGION 21 | CFLAGS = -g $(CDEFS) 22 | 23 | # Objects which only depend on the "standard" includes 24 | OBJS = basic.o dir.o dired.o file.o line.o match.o paragraph.o \ 25 | random.o region.o search.o version.o window.o word.o 26 | 27 | # Those with unique requirements 28 | IND = buffer.o display.o echo.o extend.o help.o kbd.o keymap.o \ 29 | macro.o main.o modes.o regex.o re_search.o 30 | 31 | # System dependent objects 32 | OOBJS = cinfo.o spawn.o ttyio.o tty.o ttykbd.o 33 | 34 | OBJ = $(OBJS) $(IND) $(OOBJS) fileio.o 35 | 36 | OSRCS = cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c 37 | SRCS = basic.c dir.c dired.c file.c line.c match.c paragraph.c \ 38 | random.c region.c search.c version.c window.c word.c \ 39 | buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \ 40 | macro.c main.c modes.c regex.c re_search.c 41 | 42 | OINCS = ttydef.h sysdef.h chrdef.h 43 | INCS = def.h 44 | 45 | mg: $(OBJ) 46 | cc $(CFLAGS) -o mg $(OBJ) $(LIBS) 47 | 48 | # strip mg once you're satisfied it'll run -- makes it much smaller 49 | strip: 50 | strip mg 51 | 52 | lint: $(SRCS) $(OSRCS) $(INCS) $(OINCS) 53 | lint -ahbz $(CDEFS) $(SRCS) $(OSRCS) 54 | 55 | $(OBJ): $(INCS) $(OINCS) 56 | 57 | 58 | dir.r search.o: $(INCS) $(OINCS) 59 | 60 | regex.o re_search.o: $(INCS) $(OINCS) regex.h 61 | 62 | kbd.o: $(INCS) $(OINCS) macro.h kbd.h key.h 63 | 64 | macro.o main.o: $(INCS) $(OINCS) macro.h 65 | 66 | buffer.o display.o keymap.o help.o modes.o dired.o fileio.o: \ 67 | $(INCS) $(OINCS) kbd.h 68 | 69 | extend.o: $(INCS) $(OINCS) kbd.h macro.h key.h 70 | 71 | help.o: $(INCS) $(OINCS) kbd.h key.h macro.h 72 | 73 | echo.o: $(INCS) $(OINCS) key.h macro.h 74 | 75 | $(OOBJS): $(INCS) $(OINCS) 76 | 77 | sysdef.h: sys/$(SYS)/sysdef.h # Update links, if needed. 78 | rm -f sysdef.h 79 | ln sys/$(SYS)/sysdef.h . 80 | 81 | ttydef.h: sys/default/ttydef.h 82 | rm -f ttydef.h 83 | ln sys/default/ttydef.h . 84 | 85 | chrdef.h: sys/default/chrdef.h 86 | rm -f chrdef.h 87 | ln sys/default/chrdef.h . 88 | 89 | fileio.c: sys/$(SYS)/fileio.c 90 | rm -f fileio.c 91 | ln sys/$(SYS)/fileio.c . 92 | 93 | spawn.c: sys/$(SYS)/spawn.c 94 | rm -f spawn.c 95 | ln sys/$(SYS)/spawn.c . 96 | 97 | tty.c: sys/default/tty.c 98 | rm -f tty.c 99 | ln sys/default/tty.c . 100 | 101 | ttyio.c: sys/$(SYS)/ttyio.c 102 | rm -f ttyio.c 103 | ln sys/$(SYS)/ttyio.c . 104 | 105 | ttykbd.c: sys/default/ttykbd.c 106 | rm -f ttykbd.c 107 | ln sys/default/ttykbd.c . 108 | 109 | cinfo.c: sys/default/cinfo.c 110 | rm -f cinfo.c 111 | ln sys/default/cinfo.c . 112 | 113 | port: $(SRCS) $(INCS) 114 | rm -f port 115 | tar cfb port 1 $? 116 | 117 | clean:; rm -f $(OBJ) $(OSRCS) $(OINCS) 118 | 119 | -------------------------------------------------------------------------------- /orig/sys/bsd/README: -------------------------------------------------------------------------------- 1 | Not much here; contributions welcome. 2 | 3 | Two important things to note: 4 | 5 | 1) The editor supports the notion that "~" is your home directory. 6 | 7 | 2) Startup files are either ~/.mg, or (optionaly) a system default. 8 | Only one is used. 9 | 10 | -------------------------------------------------------------------------------- /orig/sys/bsd/spawn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Spawn. New version, which 3 | * interracts with the job control stuff 4 | * in the 4.X BSD C shell. 5 | * Last edit: Wed Aug 27 11:16:07 PDT 1986 6 | * By: rtech!daveb, to use stop for ksh. 7 | */ 8 | #include "def.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | char *shellp = NULL; /* Saved "SHELL" name. */ 15 | 16 | extern struct sgttyb oldtty; /* There really should be a */ 17 | extern struct sgttyb newtty; /* nicer way of doing this, so */ 18 | extern struct sgttyb oldtchars; /* spawn does not need to know */ 19 | extern struct sgttyb newtchars; /* about the insides of the */ 20 | extern struct sgttyb oldltchars; /* terminal I/O code. */ 21 | extern struct sgttyb newltchars; 22 | 23 | extern char *getenv(); 24 | 25 | /* 26 | * This code does a one of 2 different 27 | * things, depending on what version of the shell 28 | * you are using. If you are using the C shell, which 29 | * implies that you are using job control, then MicroEMACS 30 | * moves the cursor to a nice place and sends itself a 31 | * stop signal. If you are using the Bourne shell it runs 32 | * a subshell using fork/exec. Bound to "C-C", and used 33 | * as a subcommand by "C-Z". 34 | * 35 | * Daveb -- changed sense of test so that we only spawn if you 36 | * are explicitly using /bin/sh. This makes it stop 37 | * work with the ksh. 38 | */ 39 | /*ARGSUSED*/ 40 | spawncli(f, n) { 41 | register int pid, wpid, (*oqsig)(), (*oisig)(), omask; 42 | union wait status; 43 | extern ttykeymapinit(), ttykeymapdity(), ttflush(); 44 | int i; 45 | 46 | if (shellp == NULL) { 47 | shellp = getenv("SHELL"); 48 | if (shellp == NULL) 49 | shellp = getenv("shell"); 50 | if (shellp == NULL) 51 | shellp = "/bin/sh"; /* Safer. */ 52 | } 53 | ttcolor(CTEXT); 54 | ttnowindow(); 55 | if (strcmp(shellp, "/bin/csh") == 0) { 56 | if (epresf != FALSE) { 57 | ttmove(nrow-1, 0); 58 | tteeol(); 59 | epresf = FALSE; 60 | } /* Csh types a "\n" */ 61 | ttmove(nrow-2, 0); /* before "Stopped". */ 62 | } else { 63 | ttmove(nrow-1, 0); 64 | if (epresf != FALSE) { 65 | tteeol(); 66 | epresf = FALSE; 67 | } 68 | } 69 | #ifdef XKEYS 70 | ttykeymaptidy(); 71 | ttflush(); 72 | #endif 73 | if (ttcooked() == FALSE) 74 | return (FALSE); 75 | if (strcmp(shellp, "/bin/sh") != 0) { /* C shell, ksh */ 76 | omask = sigsetmask(0); 77 | (void) kill(0, SIGTSTP); 78 | (void) sigsetmask(omask); 79 | } else { /* Bourne shell. */ 80 | oqsig = signal(SIGQUIT, SIG_IGN); 81 | oisig = signal(SIGINT, SIG_IGN); 82 | if ((pid=fork()) < 0) { 83 | (void) signal(SIGQUIT, oqsig); 84 | (void) signal(SIGINT, oisig); 85 | ewprintf("Failed to create process"); 86 | return (FALSE); 87 | } 88 | if (pid == 0) { 89 | execl(shellp, "sh", "-i", NULL); 90 | _exit(0); /* Should do better! */ 91 | } 92 | while ((wpid=wait(&status))>=0 && wpid!=pid) 93 | ; 94 | (void) signal(SIGQUIT, oqsig); 95 | (void) signal(SIGINT, oisig); 96 | } 97 | sgarbf = TRUE; /* Force repaint. */ 98 | #ifdef XKEYS 99 | i = ttraw(); 100 | ttykeymapinit(); 101 | return i; 102 | #else 103 | return ttraw(); 104 | #endif 105 | } 106 | -------------------------------------------------------------------------------- /orig/sys/bsd/spawn.c.old: -------------------------------------------------------------------------------- 1 | /* 2 | * Spawn. New version, which 3 | * interracts with the job control stuff 4 | * in the 4.X BSD C shell. 5 | * Last edit: Wed Aug 27 11:16:07 PDT 1986 6 | * By: rtech!daveb, to use stop for ksh. 7 | */ 8 | #include "def.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | char *shellp = NULL; /* Saved "SHELL" name. */ 15 | 16 | extern struct sgttyb oldtty; /* There really should be a */ 17 | extern struct sgttyb newtty; /* nicer way of doing this, so */ 18 | extern struct sgttyb oldtchars; /* spawn does not need to know */ 19 | extern struct sgttyb newtchars; /* about the insides of the */ 20 | extern struct sgttyb oldltchars; /* terminal I/O code. */ 21 | extern struct sgttyb newltchars; 22 | 23 | extern char *getenv(); 24 | 25 | /* 26 | * This code does a one of 2 different 27 | * things, depending on what version of the shell 28 | * you are using. If you are using the C shell, which 29 | * implies that you are using job control, then MicroEMACS 30 | * moves the cursor to a nice place and sends itself a 31 | * stop signal. If you are using the Bourne shell it runs 32 | * a subshell using fork/exec. Bound to "C-C", and used 33 | * as a subcommand by "C-Z". 34 | * 35 | * Daveb -- changed sense of test so that we only spawn if you 36 | * are explicitly using /bin/sh. This makes it stop 37 | * work with the ksh. 38 | */ 39 | /*ARGSUSED*/ 40 | spawncli(f, n) { 41 | register int pid, wpid, (*oqsig)(), (*oisig)(), omask; 42 | union wait status; 43 | 44 | if (shellp == NULL) { 45 | shellp = getenv("SHELL"); 46 | if (shellp == NULL) 47 | shellp = getenv("shell"); 48 | if (shellp == NULL) 49 | shellp = "/bin/sh"; /* Safer. */ 50 | } 51 | ttcolor(CTEXT); 52 | ttnowindow(); 53 | if (strcmp(shellp, "/bin/csh") == 0) { 54 | if (epresf != FALSE) { 55 | ttmove(nrow-1, 0); 56 | tteeol(); 57 | epresf = FALSE; 58 | } /* Csh types a "\n" */ 59 | ttmove(nrow-2, 0); /* before "Stopped". */ 60 | } else { 61 | ttmove(nrow-1, 0); 62 | if (epresf != FALSE) { 63 | tteeol(); 64 | epresf = FALSE; 65 | } 66 | } 67 | if (ttcooked() == FALSE) 68 | return (FALSE); 69 | if (strcmp(shellp, "/bin/sh") != 0) { /* C shell, ksh */ 70 | omask = sigsetmask(0); 71 | (void) kill(0, SIGTSTP); 72 | (void) sigsetmask(omask); 73 | } else { /* Bourne shell. */ 74 | oqsig = signal(SIGQUIT, SIG_IGN); 75 | oisig = signal(SIGINT, SIG_IGN); 76 | if ((pid=fork()) < 0) { 77 | (void) signal(SIGQUIT, oqsig); 78 | (void) signal(SIGINT, oisig); 79 | ewprintf("Failed to create process"); 80 | return (FALSE); 81 | } 82 | if (pid == 0) { 83 | execl(shellp, "sh", "-i", NULL); 84 | _exit(0); /* Should do better! */ 85 | } 86 | while ((wpid=wait(&status))>=0 && wpid!=pid) 87 | ; 88 | (void) signal(SIGQUIT, oqsig); 89 | (void) signal(SIGINT, oisig); 90 | } 91 | sgarbf = TRUE; /* Force repaint. */ 92 | return ttraw(); 93 | } 94 | -------------------------------------------------------------------------------- /orig/sys/bsd/sysdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD unix based systems (sunos, ultrix) 3 | */ 4 | #include 5 | 6 | #define KBLOCK 8192 /* Kill grow. */ 7 | #define GOOD 0 /* Good exit status. */ 8 | #define SYMBLINK 1 /* Handle symbolic links */ 9 | #define MAXPATH 256 /* Maximum length of path for chdir */ 10 | 11 | typedef int RSIZE; /* Type for file/region sizes */ 12 | 13 | #ifdef __alpha 14 | typedef int KCHAR; /* Type for internal keystrokes */ 15 | #else 16 | typedef short KCHAR; /* Type for internal keystrokes */ 17 | #endif 18 | /* 19 | * Macros used by the buffer name making code. 20 | * Start at the end of the file name, scan to the left 21 | * until BDC1 (or BDC2, if defined) is reached. The buffer 22 | * name starts just to the right of that location, and 23 | * stops at end of string (or at the next BDC3 character, 24 | * if defined). BDC2 and BDC3 are mainly for VMS. 25 | */ 26 | #define BDC1 '/' /* Buffer names. */ 27 | 28 | #define MALLOCROUND(m) (m+=7,m&=~7) /* round up to 8 byte boundry */ 29 | 30 | #define fncmp strcmp /* file name comparison */ 31 | #define unlinkdir(fn) rmdir(fn) /* unlink directory */ 32 | char *getenv(); 33 | #define gettermtype() getenv("TERM") /* determine terminal type */ 34 | -------------------------------------------------------------------------------- /orig/sys/bsd/sysdef.h.old: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD unix based systems (sunos, ultrix) 3 | */ 4 | #include 5 | 6 | #define KBLOCK 8192 /* Kill grow. */ 7 | #define GOOD 0 /* Good exit status. */ 8 | #define SYMBLINK 1 /* Handle symbolic links */ 9 | #define MAXPATH 256 /* Maximum length of path for chdir */ 10 | 11 | typedef int RSIZE; /* Type for file/region sizes */ 12 | typedef short KCHAR; /* Type for internal keystrokes */ 13 | 14 | /* 15 | * Macros used by the buffer name making code. 16 | * Start at the end of the file name, scan to the left 17 | * until BDC1 (or BDC2, if defined) is reached. The buffer 18 | * name starts just to the right of that location, and 19 | * stops at end of string (or at the next BDC3 character, 20 | * if defined). BDC2 and BDC3 are mainly for VMS. 21 | */ 22 | #define BDC1 '/' /* Buffer names. */ 23 | 24 | #define MALLOCROUND(m) (m+=7,m&=~7) /* round up to 8 byte boundry */ 25 | 26 | #define fncmp strcmp /* file name comparison */ 27 | #define unlinkdir(fn) rmdir(fn) /* unlink directory */ 28 | char *getenv(); 29 | #define gettermtype() getenv("TERM") /* determine terminal type */ 30 | -------------------------------------------------------------------------------- /orig/sys/bsd/ttyio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultrix-32 and Unix terminal I/O. 3 | * The functions in this file 4 | * negotiate with the operating system for 5 | * keyboard characters, and write characters to 6 | * the display in a barely buffered fashion. 7 | */ 8 | #include "def.h" 9 | 10 | #include 11 | 12 | #define NOBUF 512 /* Output buffer size. */ 13 | 14 | char obuf[NOBUF]; /* Output buffer. */ 15 | int nobuf; 16 | struct sgttyb oldtty; /* V6/V7 stty data. */ 17 | struct sgttyb newtty; 18 | struct tchars oldtchars; /* V7 editing. */ 19 | struct tchars newtchars; 20 | struct ltchars oldltchars; /* 4.2 BSD editing. */ 21 | struct ltchars newltchars; 22 | #ifdef TIOCGWINSZ 23 | struct winsize winsize; /* 4.3 BSD window sizing */ 24 | #endif 25 | int nrow; /* Terminal size, rows. */ 26 | int ncol; /* Terminal size, columns. */ 27 | 28 | /* 29 | * This function gets called once, to set up 30 | * the terminal channel. On Ultrix is's tricky, since 31 | * we want flow control, but we don't want any characters 32 | * stolen to send signals. Use CBREAK mode, and set all 33 | * characters but start and stop to 0xFF. 34 | */ 35 | ttopen() { 36 | register char *tv_stype; 37 | char *getenv(), *tgetstr(), tcbuf[1024], err_str[72]; 38 | #if !defined(__alpha) && !defined(__STDC__) 39 | char *sprintf(); 40 | #endif 41 | 42 | /* do this the REAL way */ 43 | if ((tv_stype = getenv("TERM")) == NULL) 44 | { 45 | puts("Environment variable TERM not defined!"); 46 | exit(1); 47 | } 48 | 49 | if((tgetent(tcbuf, tv_stype)) != 1) 50 | { 51 | (void) sprintf(err_str, "Unknown terminal type %s!", tv_stype); 52 | puts(err_str); 53 | exit(1); 54 | } 55 | if (ttraw() == FALSE) 56 | panic("aborting due to terminal initialize failure"); 57 | } 58 | 59 | /* 60 | * This function sets the terminal to RAW mode, as defined for the current 61 | * shell. This is called both by ttopen() above and by spawncli() to 62 | * get the current terminal settings and then change them to what 63 | * mg expects. Thus, stty changes done while spawncli() is in effect 64 | * will be reflected in mg. 65 | */ 66 | ttraw() { 67 | extern short ospeed; 68 | int flowcontrol; 69 | 70 | flowcontrol = (getenv("MG_RAW") == NULL && 71 | getenv("DISPLAY") == NULL); 72 | 73 | if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0) { 74 | ewprintf("ttopen can't get sgtty"); 75 | return(FALSE); 76 | } 77 | newtty.sg_ospeed = ospeed = oldtty.sg_ospeed; 78 | newtty.sg_ispeed = oldtty.sg_ispeed; 79 | newtty.sg_erase = oldtty.sg_erase; 80 | newtty.sg_kill = oldtty.sg_kill; 81 | newtty.sg_flags = oldtty.sg_flags; 82 | newtty.sg_flags &= ~(ECHO|CRMOD); /* Kill echo, CR=>NL. */ 83 | if (flowcontrol) 84 | newtty.sg_flags |= CBREAK; /* Half-cooked mode. */ 85 | else 86 | newtty.sg_flags |= RAW|ANYP; /* raw mode for 8 bit path.*/ 87 | 88 | if (ioctl(0, TIOCSETP, (char *) &newtty) < 0) { 89 | ewprintf("ttopen can't set sgtty"); 90 | return(FALSE); 91 | } 92 | if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0) { 93 | ewprintf("ttopen can't get chars"); 94 | return(FALSE); 95 | } 96 | newtchars.t_intrc = 0xFF; /* Interrupt. */ 97 | newtchars.t_quitc = 0xFF; /* Quit. */ 98 | if (flowcontrol) { 99 | newtchars.t_startc = 0x11; /* ^Q, for terminal. */ 100 | newtchars.t_stopc = 0x13; /* ^S, for terminal. */ 101 | } else { 102 | newtchars.t_startc = 0xFF; /* ^Q, for terminal. */ 103 | newtchars.t_stopc = 0xFF; /* ^S, for terminal. */ 104 | } 105 | newtchars.t_eofc = 0xFF; 106 | newtchars.t_brkc = 0xFF; 107 | if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0) { 108 | ewprintf("ttraw can't set chars"); 109 | return(FALSE); 110 | } 111 | if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0) { 112 | panic("ttraw can't get ltchars"); 113 | return(FALSE); 114 | } 115 | newltchars.t_suspc = 0xFF; /* Suspend #1. */ 116 | newltchars.t_dsuspc = 0xFF; /* Suspend #2. */ 117 | newltchars.t_rprntc = 0xFF; 118 | newltchars.t_flushc = 0xFF; /* Output flush. */ 119 | newltchars.t_werasc = 0xFF; 120 | newltchars.t_lnextc = 0xFF; /* Literal next. */ 121 | if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0) { 122 | ewprintf("ttraw can't set ltchars"); 123 | return(FALSE); 124 | } 125 | setttysize() ; 126 | return(TRUE); 127 | } 128 | 129 | /* 130 | * This function gets called just 131 | * before we go back home to the shell. Put all of 132 | * the terminal parameters back. 133 | * Under UN*X this just calls ttcooked(), but the ttclose() hook is in 134 | * because vttidy() in display.c expects it for portability reasons. 135 | */ 136 | ttclose() { 137 | if (ttcooked() == FALSE) 138 | panic(""); /* ttcooked() already printf'd */ 139 | } 140 | 141 | /* 142 | * This function restores all terminal settings to their default values, 143 | * in anticipation of exiting or suspending the editor. 144 | */ 145 | 146 | ttcooked() { 147 | ttflush(); 148 | if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0) { 149 | ewprintf("ttclose can't set ltchars"); 150 | return(FALSE); 151 | } 152 | if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0) { 153 | ewprintf("ttclose can't set chars"); 154 | return(FALSE); 155 | } 156 | if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0) { 157 | ewprintf("ttclose can't set sgtty"); 158 | return(FALSE); 159 | } 160 | return(TRUE); 161 | } 162 | 163 | /* 164 | * Write character to the display. 165 | * Characters are buffered up, to make things 166 | * a little bit more efficient. 167 | */ 168 | ttputc(c) 169 | int c; 170 | { 171 | if (nobuf >= NOBUF) 172 | ttflush(); 173 | obuf[nobuf++] = c; 174 | } 175 | 176 | /* 177 | * Flush output. 178 | */ 179 | ttflush() { 180 | if (nobuf != 0) { 181 | if (write(1, obuf, nobuf) != nobuf) 182 | panic("ttflush write failed"); 183 | nobuf = 0; 184 | } 185 | } 186 | 187 | /* 188 | * Read character from terminal. 189 | * All 8 bits are returned, so that you can use 190 | * a multi-national terminal. 191 | */ 192 | ttgetc() { 193 | char buf[1]; 194 | 195 | while (read(0, &buf[0], 1) != 1) 196 | ; 197 | return (buf[0] & 0xFF); 198 | } 199 | /* 200 | * set the tty size. Functionized for 43BSD. 201 | */ 202 | setttysize() { 203 | 204 | #ifdef TIOCGWINSZ 205 | if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { 206 | nrow = winsize . ws_row; 207 | ncol = winsize . ws_col; 208 | } else nrow = 0; 209 | if(nrow<=0 || ncol<=0) 210 | #endif 211 | if ((nrow=tgetnum ("li")) <= 0 212 | || (ncol=tgetnum ("co")) <= 0) { 213 | nrow = 24; 214 | ncol = 80; 215 | } 216 | if (nrow > NROW) /* Don't crash if the */ 217 | nrow = NROW; /* termcap entry is */ 218 | if (ncol > NCOL) /* too big. */ 219 | ncol = NCOL; 220 | } 221 | 222 | /* 223 | * typeahead returns TRUE if there are characters available to be read 224 | * in. 225 | */ 226 | typeahead() { 227 | int x; 228 | 229 | return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x); 230 | } 231 | 232 | /* 233 | * panic - just exit, as quickly as we can. 234 | */ 235 | panic(s) char *s; { 236 | (void) fputs("panic: ", stderr); 237 | (void) fputs(s, stderr); 238 | (void) fputc('\n', stderr); 239 | (void) fflush(stderr); 240 | abort(); /* To leave a core image. */ 241 | } 242 | #ifndef NO_DPROMPT 243 | #include 244 | /* 245 | * A program to return TRUE if we wait for 2 seconds without anything 246 | * happening, else return FALSE. Cribbed from mod.sources xmodem. 247 | */ 248 | int ttwait() { 249 | int readfd; 250 | struct timeval tmout; 251 | 252 | tmout.tv_sec = 2; 253 | tmout.tv_usec = 0; 254 | 255 | readfd = 1; 256 | 257 | if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0) 258 | return(TRUE); 259 | return(FALSE); 260 | } 261 | #endif 262 | -------------------------------------------------------------------------------- /orig/sys/bsd/ttyio.c.old: -------------------------------------------------------------------------------- 1 | /* 2 | * Ultrix-32 and Unix terminal I/O. 3 | * The functions in this file 4 | * negotiate with the operating system for 5 | * keyboard characters, and write characters to 6 | * the display in a barely buffered fashion. 7 | */ 8 | #include "def.h" 9 | 10 | #include 11 | 12 | #define NOBUF 512 /* Output buffer size. */ 13 | 14 | char obuf[NOBUF]; /* Output buffer. */ 15 | int nobuf; 16 | struct sgttyb oldtty; /* V6/V7 stty data. */ 17 | struct sgttyb newtty; 18 | struct tchars oldtchars; /* V7 editing. */ 19 | struct tchars newtchars; 20 | struct ltchars oldltchars; /* 4.2 BSD editing. */ 21 | struct ltchars newltchars; 22 | #ifdef TIOCGWINSZ 23 | struct winsize winsize; /* 4.3 BSD window sizing */ 24 | #endif 25 | int nrow; /* Terminal size, rows. */ 26 | int ncol; /* Terminal size, columns. */ 27 | 28 | /* 29 | * This function gets called once, to set up 30 | * the terminal channel. On Ultrix is's tricky, since 31 | * we want flow control, but we don't want any characters 32 | * stolen to send signals. Use CBREAK mode, and set all 33 | * characters but start and stop to 0xFF. 34 | */ 35 | ttopen() { 36 | register char *tv_stype; 37 | char *getenv(), *tgetstr(), tcbuf[1024], err_str[72]; 38 | char *sprintf(); 39 | 40 | /* do this the REAL way */ 41 | if ((tv_stype = getenv("TERM")) == NULL) 42 | { 43 | puts("Environment variable TERM not defined!"); 44 | exit(1); 45 | } 46 | 47 | if((tgetent(tcbuf, tv_stype)) != 1) 48 | { 49 | (void) sprintf(err_str, "Unknown terminal type %s!", tv_stype); 50 | puts(err_str); 51 | exit(1); 52 | } 53 | if (ttraw() == FALSE) 54 | panic("aborting due to terminal initialize failure"); 55 | } 56 | 57 | /* 58 | * This function sets the terminal to RAW mode, as defined for the current 59 | * shell. This is called both by ttopen() above and by spawncli() to 60 | * get the current terminal settings and then change them to what 61 | * mg expects. Thus, stty changes done while spawncli() is in effect 62 | * will be reflected in mg. 63 | */ 64 | ttraw() { 65 | extern short ospeed; 66 | 67 | if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0) { 68 | ewprintf("ttopen can't get sgtty"); 69 | return(FALSE); 70 | } 71 | newtty.sg_ospeed = ospeed = oldtty.sg_ospeed; 72 | newtty.sg_ispeed = oldtty.sg_ispeed; 73 | newtty.sg_erase = oldtty.sg_erase; 74 | newtty.sg_kill = oldtty.sg_kill; 75 | newtty.sg_flags = oldtty.sg_flags; 76 | newtty.sg_flags &= ~(ECHO|CRMOD); /* Kill echo, CR=>NL. */ 77 | #ifdef FLOWCONTROL 78 | newtty.sg_flags |= CBREAK; /* Half-cooked mode. */ 79 | #else 80 | newtty.sg_flags |= RAW|ANYP; /* raw mode for 8 bit path.*/ 81 | #endif 82 | if (ioctl(0, TIOCSETP, (char *) &newtty) < 0) { 83 | ewprintf("ttopen can't set sgtty"); 84 | return(FALSE); 85 | } 86 | if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0) { 87 | ewprintf("ttopen can't get chars"); 88 | return(FALSE); 89 | } 90 | newtchars.t_intrc = 0xFF; /* Interrupt. */ 91 | newtchars.t_quitc = 0xFF; /* Quit. */ 92 | #if FLOWCONTROL 93 | newtchars.t_startc = 0x11; /* ^Q, for terminal. */ 94 | newtchars.t_stopc = 0x13; /* ^S, for terminal. */ 95 | #else 96 | newtchars.t_startc = 0xFF; /* ^Q, for terminal. */ 97 | newtchars.t_stopc = 0xFF; /* ^S, for terminal. */ 98 | #endif 99 | newtchars.t_eofc = 0xFF; 100 | newtchars.t_brkc = 0xFF; 101 | if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0) { 102 | ewprintf("ttraw can't set chars"); 103 | return(FALSE); 104 | } 105 | if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0) { 106 | panic("ttraw can't get ltchars"); 107 | return(FALSE); 108 | } 109 | newltchars.t_suspc = 0xFF; /* Suspend #1. */ 110 | newltchars.t_dsuspc = 0xFF; /* Suspend #2. */ 111 | newltchars.t_rprntc = 0xFF; 112 | newltchars.t_flushc = 0xFF; /* Output flush. */ 113 | newltchars.t_werasc = 0xFF; 114 | newltchars.t_lnextc = 0xFF; /* Literal next. */ 115 | if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0) { 116 | ewprintf("ttraw can't set ltchars"); 117 | return(FALSE); 118 | } 119 | setttysize() ; 120 | return(TRUE); 121 | } 122 | 123 | /* 124 | * This function gets called just 125 | * before we go back home to the shell. Put all of 126 | * the terminal parameters back. 127 | * Under UN*X this just calls ttcooked(), but the ttclose() hook is in 128 | * because vttidy() in display.c expects it for portability reasons. 129 | */ 130 | ttclose() { 131 | if (ttcooked() == FALSE) 132 | panic(""); /* ttcooked() already printf'd */ 133 | } 134 | 135 | /* 136 | * This function restores all terminal settings to their default values, 137 | * in anticipation of exiting or suspending the editor. 138 | */ 139 | 140 | ttcooked() { 141 | ttflush(); 142 | if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0) { 143 | ewprintf("ttclose can't set ltchars"); 144 | return(FALSE); 145 | } 146 | if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0) { 147 | ewprintf("ttclose can't set chars"); 148 | return(FALSE); 149 | } 150 | if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0) { 151 | ewprintf("ttclose can't set sgtty"); 152 | return(FALSE); 153 | } 154 | return(TRUE); 155 | } 156 | 157 | /* 158 | * Write character to the display. 159 | * Characters are buffered up, to make things 160 | * a little bit more efficient. 161 | */ 162 | ttputc(c) 163 | int c; 164 | { 165 | if (nobuf >= NOBUF) 166 | ttflush(); 167 | obuf[nobuf++] = c; 168 | } 169 | 170 | /* 171 | * Flush output. 172 | */ 173 | ttflush() { 174 | if (nobuf != 0) { 175 | if (write(1, obuf, nobuf) != nobuf) 176 | panic("ttflush write failed"); 177 | nobuf = 0; 178 | } 179 | } 180 | 181 | /* 182 | * Read character from terminal. 183 | * All 8 bits are returned, so that you can use 184 | * a multi-national terminal. 185 | */ 186 | ttgetc() { 187 | char buf[1]; 188 | 189 | while (read(0, &buf[0], 1) != 1) 190 | ; 191 | return (buf[0] & 0xFF); 192 | } 193 | /* 194 | * set the tty size. Functionized for 43BSD. 195 | */ 196 | setttysize() { 197 | 198 | #ifdef TIOCGWINSZ 199 | if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { 200 | nrow = winsize . ws_row; 201 | ncol = winsize . ws_col; 202 | } else nrow = 0; 203 | if(nrow<=0 || ncol<=0) 204 | #endif 205 | if ((nrow=tgetnum ("li")) <= 0 206 | || (ncol=tgetnum ("co")) <= 0) { 207 | nrow = 24; 208 | ncol = 80; 209 | } 210 | if (nrow > NROW) /* Don't crash if the */ 211 | nrow = NROW; /* termcap entry is */ 212 | if (ncol > NCOL) /* too big. */ 213 | ncol = NCOL; 214 | } 215 | 216 | /* 217 | * typeahead returns TRUE if there are characters available to be read 218 | * in. 219 | */ 220 | typeahead() { 221 | int x; 222 | 223 | return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x); 224 | } 225 | 226 | /* 227 | * panic - just exit, as quickly as we can. 228 | */ 229 | panic(s) char *s; { 230 | (void) fputs("panic: ", stderr); 231 | (void) fputs(s, stderr); 232 | (void) fputc('\n', stderr); 233 | (void) fflush(stderr); 234 | abort(); /* To leave a core image. */ 235 | } 236 | #ifndef NO_DPROMPT 237 | #include 238 | /* 239 | * A program to return TRUE if we wait for 2 seconds without anything 240 | * happening, else return FALSE. Cribbed from mod.sources xmodem. 241 | */ 242 | int ttwait() { 243 | int readfd; 244 | struct timeval tmout; 245 | 246 | tmout.tv_sec = 2; 247 | tmout.tv_usec = 0; 248 | 249 | readfd = 1; 250 | 251 | if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0) 252 | return(TRUE); 253 | return(FALSE); 254 | } 255 | #endif 256 | -------------------------------------------------------------------------------- /orig/sys/default/README: -------------------------------------------------------------------------------- 1 | MG Termcap Terminal Driver 2 | 3 | The termcap library needs to know where to get the terminal type and 4 | termcap capibilities file from. UNIX and Os9/68k users should 5 | 6 | setenv TERM term-type 7 | 8 | to their terminal type, and 9 | 10 | setenv TERMCAP termcap-file 11 | 12 | if they are using a non-standard termcap file. VMS users should see 13 | [.SYS.VMS]AAAREADME.1ST for information on how to define the logical 14 | names TERM and ETC to point to the termcap definition file. Users of 15 | other operating systems should do the aproprate thing. For an example 16 | of a termcap file, UNIX users may look in /etc/termcap, Os9/68k users 17 | may look at /dd/sys/termcap (if present), and VMS users should see the 18 | file [.SYS.VMS.TERMCAP]TERMCAP. 19 | 20 | MG requires that certain terminal capabilities exist in the specified 21 | termcap entry. The "cm" (cursor motion) capability *must* be 22 | available to use MG. (Yes, it is possible to fake cm with some other 23 | capibilities, but MG doesn't try.) If your terminal is one that uses 24 | control characters in the paramater portion of the "cm" string, the 25 | "up" and "bc" capabilites may also be needed. (See your termlib 26 | documentation for when this is so.) 27 | 28 | If the following capabilities are available, they are used. The AL 29 | and DL sequences are not totally standard, but having them improves 30 | the performance of the editor, since it doesn't have to redraw the 31 | screen to delete a line. They should not be used if they need control 32 | characters as paramaters. 33 | 34 | cd -- clear display 35 | ce -- clear to end of line 36 | 37 | al -- insert 1 line 38 | dl -- delete 1 line 39 | 40 | AL -- insert multiple lines (note capitalization) 41 | DL -- delete multiple lines (note capitalization) 42 | 43 | ti -- cursor movement initialization string 44 | te -- cursor movement end string 45 | 46 | The cs capability is not as standard as some of the other 47 | capibilities, but is used by MG when available. It is used to define 48 | a "scrolling region", which defines a window within the screen where 49 | all the action takes place. A newline character at the bottom of this 50 | area scrolls the rest of the text in the area up one line, just like 51 | the normal screen; a reverse linefeed (sr) at the top of the window 52 | moves all the text in the area down a line. MG does not properly 53 | handle "cs" if your terminal needs control characters as paramaters, 54 | and in this case "cs" should not be defined. 55 | 56 | If the cs and sr capabilities are available, the termcap driver uses 57 | these to make the insert/delete line functions work more smoothly. If 58 | only the cs capability is present, it is still used for the delete 59 | line function, but not for inserting lines. 60 | 61 | Use of the cs capability is often desirable, but is not a win on 62 | bit-mapped screens such as Sun workstation console windows. This is 63 | because it takes longer to scroll the window than to redraw it. If 64 | you are using a workstation window, you might consider using a termcap 65 | entry that doesn't have the cs capability. 66 | 67 | The definition of the cs capability is: the first parameter in the 68 | sequence defines the first row (origin 0) that is in the scrolling 69 | region, and the second argument defines the last row to include in the 70 | scrolling region. 71 | 72 | cs -- set scrolling region (arg1 = top, arg2 = bottom) 73 | sr -- reverse index 74 | 75 | The following capabilities provide for an enhanced (reverse-video or 76 | otherwise rendered) mode line. The sg entry should not be present on 77 | terminals that do this to characters as they are placed on the screen. 78 | Terminals that put a region of the screen in the standout mode should 79 | have sg defined as numeric: :sg#0: for terminals that do this on 80 | regions but don't take any character positions to do this, (this may 81 | be a non-standard interprition of the meaning of sg) and the number of 82 | character positions taken by any other terminal. 83 | 84 | so -- enter standout mode 85 | se -- leave standout mode 86 | sg -- number of character positions used by standout 87 | 88 | Terminal-specific initialization file 89 | 90 | If the MG termcap terminal driver is compiled with XKEYS defined, and 91 | the startup file option is enabled as well, MG will look for a 92 | terminal-specific initialization file. The name of the terminal 93 | initialization file varies between operating systems, but will usually 94 | look like .mg-TERM, where TERM represents your terminal type. For 95 | example, a terminal initialization file under Unix and VMS for the DEC 96 | VT100 terminal (termcap type vt100) would have the name ".mg-vt100". 97 | 98 | The terminal-specific startup file has the same format as the mg 99 | startup file, and is executed immediately after the startup file 100 | during mg's startup phase. An example vt100 initialization file 101 | follows, which globally binds the key sequences sent by the VT100 102 | terminal (in keypad mode) to the appropriate functions. 103 | 104 | ----------------------------------CUT HERE----------------------------------- 105 | ; 106 | ; Small key definition file for VT100 terminals using the termcap 107 | ; driver. This only works if XKEYS is defined during compilation. 108 | ; 109 | (global-set-key "\eOA" 'previous-line) ; up arrow 110 | (global-set-key "\eOB" 'next-line) ; down arrow 111 | (global-set-key "\eOC" 'forward-char) ; right arrow 112 | (global-set-key "\eOD" 'backward-char) ; left arrow 113 | -------------------------------------------------------------------------------- /orig/sys/default/alloca.c: -------------------------------------------------------------------------------- 1 | /* 2 | alloca -- (mostly) portable public-domain implementation 3 | 4 | last edit: 86/01/26 D A Gwyn 5 | 6 | This implementation of the PWB library alloca() function, 7 | which is used to allocate space off the run-time stack so 8 | that it is automatically reclaimed upon procedure exit, 9 | was inspired by discussions with J. Q. Johnson of Cornell. 10 | 11 | It should work under any C implementation that uses an 12 | actual procedure stack (as opposed to a linked list of 13 | frames). There are some preprocessor constants that can 14 | be defined when compiling for your specific system, for 15 | improved efficiency; however, the defaults should be okay. 16 | 17 | The general concept of this implementation is to keep 18 | track of all alloca()-allocated blocks, and reclaim any 19 | that are found to be deeper in the stack than the current 20 | invocation. This heuristic does not reclaim storage as 21 | soon as it becomes invalid, but it will do so eventually. 22 | 23 | As a special case, alloca(0) reclaims storage without 24 | allocating any. It is a good idea to use alloca(0) in 25 | your main control loop, etc. to force garbage collection. 26 | */ 27 | #ifndef lint 28 | static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ 29 | #endif 30 | 31 | #ifdef X3J11 32 | typedef void *pointer; /* generic pointer type */ 33 | #else 34 | typedef char *pointer; /* generic pointer type */ 35 | #endif 36 | 37 | #define NULL 0 /* null pointer constant */ 38 | 39 | extern void free(); 40 | extern pointer malloc(); 41 | 42 | /* 43 | Define STACK_DIRECTION if you know the direction of stack 44 | growth for your system; otherwise it will be automatically 45 | deduced at run-time. 46 | 47 | STACK_DIRECTION > 0 => grows toward higher addresses 48 | STACK_DIRECTION < 0 => grows toward lower addresses 49 | STACK_DIRECTION = 0 => direction of growth unknown 50 | */ 51 | 52 | #ifndef STACK_DIRECTION 53 | #define STACK_DIRECTION 0 /* direction unknown */ 54 | #endif 55 | 56 | #if STACK_DIRECTION != 0 57 | 58 | #define STACK_DIR STACK_DIRECTION /* known at compile-time */ 59 | 60 | #else /* STACK_DIRECTION == 0; need run-time code */ 61 | 62 | static int stack_dir = 0; /* 1 or -1 once known */ 63 | #define STACK_DIR stack_dir 64 | 65 | static void 66 | find_stack_direction( /* void */ ) 67 | { 68 | static char *addr = NULL; /* address of first 69 | `dummy', once known */ 70 | auto char dummy; /* to get stack address */ 71 | 72 | if ( addr == NULL ) 73 | { /* initial entry */ 74 | addr = &dummy; 75 | 76 | find_stack_direction(); /* recurse once */ 77 | } 78 | else /* second entry */ 79 | if ( &dummy > addr ) 80 | stack_dir = 1; /* stack grew upward */ 81 | else 82 | stack_dir = -1; /* stack grew downward */ 83 | } 84 | 85 | #endif /* STACK_DIRECTION == 0 */ 86 | 87 | /* 88 | An "alloca header" is used to: 89 | (a) chain together all alloca()ed blocks; 90 | (b) keep track of stack depth. 91 | 92 | It is very important that sizeof(header) agree with malloc() 93 | alignment chunk size. The following default should work okay. 94 | */ 95 | 96 | #ifndef ALIGN_SIZE 97 | #define ALIGN_SIZE sizeof(double) 98 | #endif 99 | 100 | typedef union hdr 101 | { 102 | char align[ALIGN_SIZE]; /* to force sizeof(header) */ 103 | struct { 104 | union hdr *next; /* for chaining headers */ 105 | char *deep; /* for stack depth measure */ 106 | } h; 107 | } header; 108 | 109 | /* 110 | alloca( size ) returns a pointer to at least `size' bytes of 111 | storage which will be automatically reclaimed upon exit from 112 | the procedure that called alloca(). Originally, this space 113 | was supposed to be taken from the current stack frame of the 114 | caller, but that method cannot be made to work for some 115 | implementations of C, for example under Gould's UTX/32. 116 | */ 117 | 118 | pointer 119 | alloca( size ) /* returns pointer to storage */ 120 | unsigned size; /* # bytes to allocate */ 121 | { 122 | static header *last = NULL; /* -> last alloca header */ 123 | auto char probe; /* probes stack depth: */ 124 | register char *depth = &probe; 125 | 126 | #if STACK_DIRECTION == 0 127 | if ( STACK_DIR == 0 ) /* unknown growth direction */ 128 | find_stack_direction(); 129 | #endif 130 | 131 | /* Reclaim garbage, defined as all alloca()ed storage that 132 | was allocated from deeper in the stack than currently. */ 133 | 134 | { 135 | register header *hp; /* traverses linked list */ 136 | 137 | for ( hp = last; hp != NULL; ) 138 | if ( STACK_DIR > 0 && hp->h.deep > depth 139 | || STACK_DIR < 0 && hp->h.deep < depth 140 | ) { 141 | register header *np = hp->h.next; 142 | 143 | free( (pointer)hp ); /* collect garbage */ 144 | 145 | hp = np; /* -> next header */ 146 | } 147 | else 148 | break; /* rest are not deeper */ 149 | 150 | last = hp; /* -> last valid storage */ 151 | } 152 | 153 | if ( size == 0 ) 154 | return NULL; /* no allocation required */ 155 | 156 | /* Allocate combined header + user data storage. */ 157 | 158 | { 159 | register pointer new = malloc( sizeof(header) + size ); 160 | /* address of header */ 161 | 162 | if ( new == NULL ) 163 | return NULL; /* abort() is traditional */ 164 | 165 | ((header *)new)->h.next = last; 166 | ((header *)new)->h.deep = depth; 167 | 168 | last = (header *)new; 169 | 170 | /* User storage begins just after header. */ 171 | 172 | return (pointer)((char *)new + sizeof(header)); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /orig/sys/default/chrdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys/default/chardef.h: character set specific #defines for mg 2a 3 | * Warning: System specific ones exist 4 | */ 5 | 6 | #ifndef CHARMASK 7 | /* 8 | * casting should be at least as efficent as anding with 0xff, 9 | * and won't have the size problems. Override in sysdef.h if no 10 | * unsigned char type. 11 | */ 12 | #define CHARMASK(c) ((unsigned char) (c)) 13 | #endif 14 | 15 | /* 16 | * These flags, and the macros below them, 17 | * make up a do-it-yourself set of "ctype" macros that 18 | * understand the DEC multinational set, and let me ask 19 | * a slightly different set of questions. 20 | */ 21 | #define _W 0x01 /* Word. */ 22 | #define _U 0x02 /* Upper case letter. */ 23 | #define _L 0x04 /* Lower case letter. */ 24 | #define _C 0x08 /* Control. */ 25 | #define _P 0x10 /* end of sentence punctuation */ 26 | #define _D 0x20 /* is decimal digit */ 27 | 28 | #define ISWORD(c) ((cinfo[CHARMASK(c)]&_W)!=0) 29 | #define ISCTRL(c) ((cinfo[CHARMASK(c)]&_C)!=0) 30 | #define ISUPPER(c) ((cinfo[CHARMASK(c)]&_U)!=0) 31 | #define ISLOWER(c) ((cinfo[CHARMASK(c)]&_L)!=0) 32 | #define ISEOSP(c) ((cinfo[CHARMASK(c)]&_P)!=0) 33 | #define ISDIGIT(c) ((cinfo[CHARMASK(c)]&_D)!=0) 34 | #define TOUPPER(c) ((c)-0x20) 35 | #define TOLOWER(c) ((c)+0x20) 36 | 37 | /* 38 | * generally useful thing for chars 39 | */ 40 | #define CCHR(x) ((x) ^ 0x40) /* CCHR('?') == DEL */ 41 | 42 | #ifndef METACH 43 | #define METACH CCHR('[') 44 | #endif 45 | 46 | #ifdef XKEYS 47 | #define K00 256 48 | #define K01 257 49 | #define K02 258 50 | #define K03 259 51 | #define K04 260 52 | #define K05 261 53 | #define K06 262 54 | #define K07 263 55 | #define K08 264 56 | #define K09 265 57 | #define K0A 266 58 | #define K0B 267 59 | #define K0C 268 60 | #define K0D 269 61 | #define K0E 270 62 | #define K0F 271 63 | #define K10 272 64 | #define K11 273 65 | #define K12 274 66 | #define K13 275 67 | #define K14 276 68 | #define K15 277 69 | #define K16 278 70 | #define K17 279 71 | #define K18 280 72 | #define K19 281 73 | #define K1A 282 74 | #define K1B 283 75 | #define K1C 284 76 | #define K1D 285 77 | #define K1E 286 78 | #define K1F 287 79 | #endif 80 | -------------------------------------------------------------------------------- /orig/sys/default/cinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Character class tables. 3 | * Do it yourself character classification 4 | * macros, that understand the multinational character set, 5 | * and let me ask some questions the standard macros (in 6 | * ctype.h) don't let you ask. 7 | */ 8 | #include "def.h" 9 | 10 | /* 11 | * This table, indexed by a character drawn 12 | * from the 256 member character set, is used by my 13 | * own character type macros to answer questions about the 14 | * type of a character. It handles the full multinational 15 | * character set, and lets me ask some questions that the 16 | * standard "ctype" macros cannot ask. 17 | */ 18 | char cinfo[256] = { 19 | _C, _C, _C, _C, /* 0x0X */ 20 | _C, _C, _C, _C, 21 | _C, _C, _C, _C, 22 | _C, _C, _C, _C, 23 | _C, _C, _C, _C, /* 0x1X */ 24 | _C, _C, _C, _C, 25 | _C, _C, _C, _C, 26 | _C, _C, _C, _C, 27 | 0, _P, 0, 0, /* 0x2X */ 28 | _W, _W, 0, _W, 29 | 0, 0, 0, 0, 30 | 0, 0, _P, 0, 31 | _D|_W, _D|_W, _D|_W, _D|_W, /* 0x3X */ 32 | _D|_W, _D|_W, _D|_W, _D|_W, 33 | _D|_W, _D|_W, 0, 0, 34 | 0, 0, 0, _P, 35 | 0, _U|_W, _U|_W, _U|_W, /* 0x4X */ 36 | _U|_W, _U|_W, _U|_W, _U|_W, 37 | _U|_W, _U|_W, _U|_W, _U|_W, 38 | _U|_W, _U|_W, _U|_W, _U|_W, 39 | _U|_W, _U|_W, _U|_W, _U|_W, /* 0x5X */ 40 | _U|_W, _U|_W, _U|_W, _U|_W, 41 | _U|_W, _U|_W, _U|_W, 0, 42 | 0, 0, 0, 0, 43 | 0, _L|_W, _L|_W, _L|_W, /* 0x6X */ 44 | _L|_W, _L|_W, _L|_W, _L|_W, 45 | _L|_W, _L|_W, _L|_W, _L|_W, 46 | _L|_W, _L|_W, _L|_W, _L|_W, 47 | _L|_W, _L|_W, _L|_W, _L|_W, /* 0x7X */ 48 | _L|_W, _L|_W, _L|_W, _L|_W, 49 | _L|_W, _L|_W, _L|_W, 0, 50 | 0, 0, 0, _C, 51 | 0, 0, 0, 0, /* 0x8X */ 52 | 0, 0, 0, 0, 53 | 0, 0, 0, 0, 54 | 0, 0, 0, 0, 55 | 0, 0, 0, 0, /* 0x9X */ 56 | 0, 0, 0, 0, 57 | 0, 0, 0, 0, 58 | 0, 0, 0, 0, 59 | 0, 0, 0, 0, /* 0xAX */ 60 | 0, 0, 0, 0, 61 | 0, 0, 0, 0, 62 | 0, 0, 0, 0, 63 | 0, 0, 0, 0, /* 0xBX */ 64 | 0, 0, 0, 0, 65 | 0, 0, 0, 0, 66 | 0, 0, 0, 0, 67 | _U|_W, _U|_W, _U|_W, _U|_W, /* 0xCX */ 68 | _U|_W, _U|_W, _U|_W, _U|_W, 69 | _U|_W, _U|_W, _U|_W, _U|_W, 70 | _U|_W, _U|_W, _U|_W, _U|_W, 71 | 0, _U|_W, _U|_W, _U|_W, /* 0xDX */ 72 | _U|_W, _U|_W, _U|_W, _U|_W, 73 | _U|_W, _U|_W, _U|_W, _U|_W, 74 | _U|_W, _U|_W, 0, _W, 75 | _L|_W, _L|_W, _L|_W, _L|_W, /* 0xEX */ 76 | _L|_W, _L|_W, _L|_W, _L|_W, 77 | _L|_W, _L|_W, _L|_W, _L|_W, 78 | _L|_W, _L|_W, _L|_W, _L|_W, 79 | 0, _L|_W, _L|_W, _L|_W, /* 0xFX */ 80 | _L|_W, _L|_W, _L|_W, _L|_W, 81 | _L|_W, _L|_W, _L|_W, _L|_W, 82 | _L|_W, _L|_W, 0, 0 83 | }; 84 | 85 | /* 86 | * Find the name of a keystroke. Needs to be changed to handle 8-bit printing 87 | * characters and function keys better. Returns a pointer to the terminating 88 | * '\0'. 89 | */ 90 | 91 | char *keyname(cp, k) 92 | register char *cp; 93 | register int k; 94 | { 95 | register char *np; 96 | #ifdef FKEYS 97 | extern char *keystrings[]; 98 | #endif 99 | 100 | if(k < 0) k = CHARMASK(k); /* sign extended char */ 101 | switch(k) { 102 | case CCHR('@'): np = "NUL"; break; 103 | case CCHR('I'): np = "TAB"; break; 104 | case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */ 105 | case CCHR('M'): np = "RET"; break; 106 | case CCHR('['): np = "ESC"; break; 107 | case ' ': np = "SPC"; break; /* yuck again */ 108 | case CCHR('?'): np = "DEL"; break; 109 | default: 110 | #ifdef FKEYS 111 | if(k >= KFIRST && k <= KLAST && 112 | (np = keystrings[k - KFIRST]) != NULL) 113 | break; 114 | #endif 115 | if(k > CCHR('?')) { 116 | *cp++ = '0'; 117 | *cp++ = ((k>>6)&7) + '0'; 118 | *cp++ = ((k>>3)&7) + '0'; 119 | *cp++ = (k&7) + '0'; 120 | *cp = '\0'; 121 | return cp; 122 | } 123 | if(k < ' ') { 124 | *cp++ = 'C'; 125 | *cp++ = '-'; 126 | k = CCHR(k); 127 | if(ISUPPER(k)) k = TOLOWER(k); 128 | } 129 | *cp++ = k; 130 | *cp = '\0'; 131 | return cp; 132 | } 133 | (VOID) strcpy(cp, np); 134 | return cp + strlen(cp); 135 | } 136 | -------------------------------------------------------------------------------- /orig/sys/default/ttydef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Termcap terminal file, nothing special, just make it big 3 | * enough for windowing systems. 4 | */ 5 | 6 | #define GOSLING /* Compile in fancy display. */ 7 | /* #define MEMMAP */ /* Not memory mapped video. */ 8 | 9 | #define NROW 80 /* (maximum) Rows. */ 10 | #define NCOL 132 /* (maximum) Columns. */ 11 | /* #define MOVE_STANDOUT /* don't move in standout mode */ 12 | #define STANDOUT_GLITCH /* possible standout glitch */ 13 | #define TERMCAP /* for possible use in ttyio.c */ 14 | 15 | #define getkbd() (ttgetc()) 16 | 17 | #ifndef XKEYS 18 | #define ttykeymapinit() {} 19 | #endif 20 | 21 | extern int tputs(); 22 | #define putpad(str, num) tputs(str, num, ttputc) 23 | 24 | #define KFIRST K00 25 | #define KLAST K00 26 | -------------------------------------------------------------------------------- /orig/sys/default/ttydef.h.old: -------------------------------------------------------------------------------- 1 | /* 2 | * Termcap terminal file, nothing special, just make it big 3 | * enough for windowing systems. 4 | */ 5 | 6 | #define GOSLING /* Compile in fancy display. */ 7 | /* #define MEMMAP */ /* Not memory mapped video. */ 8 | 9 | #define NROW 66 /* (maximum) Rows. */ 10 | #define NCOL 132 /* (maximum) Columns. */ 11 | /* #define MOVE_STANDOUT /* don't move in standout mode */ 12 | #define STANDOUT_GLITCH /* possible standout glitch */ 13 | #define TERMCAP /* for possible use in ttyio.c */ 14 | 15 | #define getkbd() (ttgetc()) 16 | 17 | #ifndef XKEYS 18 | #define ttykeymapinit() {} 19 | #endif 20 | 21 | extern int tputs(); 22 | #define putpad(str, num) tputs(str, num, ttputc) 23 | 24 | #define KFIRST K00 25 | #define KLAST K00 26 | -------------------------------------------------------------------------------- /orig/sys/default/ttykbd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MG 2a 3 | * Termcap keyboard driver using key files 4 | * Created: 22-Nov-1987 Mic Kaczmarczik (mic@emx.cc.utexas.edu) 5 | */ 6 | 7 | #include "def.h" 8 | #ifdef XKEYS 9 | 10 | /* 11 | * Get keyboard character. Very simple if you use keymaps and keys files. 12 | * Bob was right -- the old XKEYS code is not the right solution. 13 | * FKEYS code is not usefull other than to help debug FKEYS code in 14 | * extend.c. 15 | */ 16 | 17 | #ifdef FKEYS 18 | char *keystrings[] = { NULL } ; 19 | #endif 20 | 21 | /* 22 | * Turn on function keys using KS, then load a keys file, if available. 23 | * The keys file is located in the same manner as the startup file is, 24 | * depending on what startupfile() does on your system. 25 | */ 26 | extern int ttputc(); 27 | 28 | ttykeymapinit() 29 | { 30 | extern char *KS; 31 | #ifndef NO_STARTUP 32 | char *cp, *startupfile(); 33 | 34 | if (cp = gettermtype()) { 35 | if (((cp = startupfile(cp)) != NULL) 36 | && (load(cp) != TRUE)) 37 | ewprintf("Error reading key initialization file"); 38 | } 39 | #endif 40 | if (KS && *KS) /* turn on keypad */ 41 | putpad(KS, 1); 42 | } 43 | 44 | /* 45 | * Clean up the keyboard -- called by tttidy() 46 | */ 47 | ttykeymaptidy() 48 | { 49 | extern char *KE; 50 | 51 | if (KE && *KE) 52 | putpad(KE, 1); /* turn off keypad */ 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /orig/sys/default/varargs.h: -------------------------------------------------------------------------------- 1 | /* varargs.h for MicroGnuEmacs 2a. This one will work on systems that */ 2 | /* the non-varargs version of mg 1 did. */ 3 | /* based on the one I wrote for os9/68k . I did not look at the bsd code. */ 4 | 5 | /* by Robert A. Larson */ 6 | 7 | /* assumptions made about how arguments are passed: */ 8 | /* arguments are stored in a block of memory with no padding between. */ 9 | /* The first argument will have the lowest address */ 10 | 11 | /* varargs is a "portable" way to write a routine that takes a variable */ 12 | /* number of arguements. This implemination agrees with both the 4.2bsd*/ 13 | /* and Sys V documentation of varargs. Note that just because varargs.h*/ 14 | /* is used does not mean that it is used properly. */ 15 | 16 | #define va_dcl unsigned va_alist; 17 | 18 | typedef char *va_list; 19 | 20 | #define va_start(pvar) ((pvar) = (char *)&va_alist) 21 | 22 | #define va_arg(pvar,type) (((pvar)+=sizeof(type)),*(((type *)(pvar)) - 1)) 23 | 24 | #define va_end(pvar) /* va_end is simple */ 25 | -------------------------------------------------------------------------------- /orig/sys/sysv/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for MicroEMACS. 2 | # Is there a better way to do the rebuilds, other than using 3 | # the links? 4 | 5 | SYS = sysv 6 | LIBS = -lcurses 7 | # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't 8 | # get passed to lint. 9 | # 10 | # (Common) compile-time options: 11 | # 12 | # DO_METAKEY -- if bit 7 is set for a key, treat like a META key 13 | # STARTUP -- look for and handle initialization file 14 | # XKEYS -- use termcap function key definitions. Warning - 15 | # XKEYS and bsmap mode do _not_ get along. 16 | # BACKUP -- enable "make-backup-files" 17 | # PREFIXREGION -- enable function "prefix-region" 18 | # REGEX -- create regular expression functions 19 | # 20 | #CDEFS = -DDO_METAKEY 21 | CDEFS = -DDO_METAKEY -DPREFIXREGION 22 | CFLAGS = -g $(CDEFS) 23 | 24 | # Objects which only depend on the "standard" includes 25 | OBJS = basic.o dir.o dired.o file.o line.o match.o paragraph.o \ 26 | random.o region.o search.o version.o window.o word.o 27 | 28 | # Those with unique requirements 29 | IND = buffer.o display.o echo.o extend.o help.o kbd.o keymap.o \ 30 | macro.o main.o modes.o regex.o re_search.o 31 | 32 | # System dependent objects 33 | OOBJS = cinfo.o spawn.o ttyio.o tty.o ttykbd.o 34 | 35 | OBJ = $(OBJS) $(IND) $(OOBJS) fileio.o 36 | 37 | OSRCS = cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c 38 | SRCS = basic.c dir.c dired.c file.c line.c match.c paragraph.c \ 39 | random.c region.c search.c version.c window.c word.c \ 40 | buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \ 41 | macro.c main.c modes.c regex.c re_search.c 42 | 43 | OINCS = ttydef.h sysdef.h chrdef.h 44 | INCS = def.h 45 | 46 | mg: $(OBJ) 47 | cc $(CFLAGS) -o mg $(OBJ) $(LIBS) 48 | 49 | # strip mg once you're satisfied it'll run -- makes it much smaller 50 | strip: 51 | strip mg 52 | 53 | lint: $(SRCS) $(OSRCS) $(INCS) $(OINCS) 54 | lint -ahbz $(CDEFS) $(SRCS) $(OSRCS) 55 | 56 | $(OBJ): $(INCS) $(OINCS) 57 | 58 | 59 | dir.r search.o: $(INCS) $(OINCS) 60 | 61 | regex.o re_search.o: $(INCS) $(OINCS) regex.h 62 | 63 | kbd.o: $(INCS) $(OINCS) macro.h kbd.h key.h 64 | 65 | macro.o main.o: $(INCS) $(OINCS) macro.h 66 | 67 | buffer.o display.o keymap.o help.o modes.o dired.o fileio.o: \ 68 | $(INCS) $(OINCS) kbd.h 69 | 70 | extend.o: $(INCS) $(OINCS) kbd.h macro.h key.h 71 | 72 | help.o: $(INCS) $(OINCS) kbd.h key.h macro.h 73 | 74 | echo.o: $(INCS) $(OINCS) key.h macro.h 75 | 76 | $(OOBJS): $(INCS) $(OINCS) 77 | 78 | sysdef.h: sys/$(SYS)/sysdef.h # Update links, if needed. 79 | rm -f sysdef.h 80 | ln sys/$(SYS)/sysdef.h . 81 | 82 | ttydef.h: sys/default/ttydef.h 83 | rm -f ttydef.h 84 | ln sys/default/ttydef.h . 85 | 86 | chrdef.h: sys/default/chrdef.h 87 | rm -f chrdef.h 88 | ln sys/default/chrdef.h . 89 | 90 | fileio.c: sys/$(SYS)/fileio.c 91 | rm -f fileio.c 92 | ln sys/$(SYS)/fileio.c . 93 | 94 | spawn.c: sys/$(SYS)/spawn.c 95 | rm -f spawn.c 96 | ln sys/$(SYS)/spawn.c . 97 | 98 | tty.c: sys/default/tty.c 99 | rm -f tty.c 100 | ln sys/default/tty.c . 101 | 102 | ttyio.c: sys/$(SYS)/ttyio.c 103 | rm -f ttyio.c 104 | ln sys/$(SYS)/ttyio.c . 105 | 106 | ttykbd.c: sys/default/ttykbd.c 107 | rm -f ttykbd.c 108 | ln sys/default/ttykbd.c . 109 | 110 | cinfo.c: sys/default/cinfo.c 111 | rm -f cinfo.c 112 | ln sys/default/cinfo.c . 113 | 114 | port: $(SRCS) $(INCS) 115 | rm -f port 116 | tar cfb port 1 $? 117 | 118 | clean:; rm -f $(OBJ) $(OSRCS) $(OINCS) 119 | -------------------------------------------------------------------------------- /orig/sys/sysv/spawn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MicroGnuEmacs 3 | * Spawn CLI for System V. 4 | * 5 | * Spawn for System V. 6 | */ 7 | #include "def.h" 8 | 9 | #include 10 | 11 | char *shellp = NULL; /* Saved "SHELL" program. */ 12 | char *shname = NULL; /* Saved shell name */ 13 | 14 | extern char *getenv(); 15 | 16 | /* 17 | * On System V, we no gots job control, so always run 18 | * a subshell using fork/exec. Bound to "C-C", and used 19 | * as a subcommand by "C-Z". (daveb) 20 | * 21 | * Returns 0 if the shell executed OK, something else if 22 | * we couldn't start shell or it exited badly. 23 | */ 24 | spawncli(f, n) 25 | { 26 | extern char *strrchr(); 27 | register int pid; 28 | register int wpid; 29 | register int (*oqsig)(); 30 | register int (*oisig)(); 31 | int status; 32 | int errp = FALSE; 33 | 34 | if (shellp == NULL) { 35 | shellp = getenv("SHELL"); 36 | if (shellp == NULL) 37 | shellp = getenv("shell"); 38 | if (shellp == NULL) 39 | shellp = "/bin/sh"; /* Safer. */ 40 | shname = strrchr( shellp, '/' ); 41 | shname = shname ? shname++ : shellp; 42 | 43 | } 44 | ttcolor(CTEXT); 45 | ttnowindow(); 46 | ttmove(nrow-1, 0); 47 | if (epresf != FALSE) { 48 | tteeol(); 49 | epresf = FALSE; 50 | } 51 | ttclose(); 52 | sgarbf = TRUE; /* Force repaint. */ 53 | oqsig = signal(SIGQUIT, SIG_IGN); 54 | oisig = signal(SIGINT, SIG_IGN); 55 | if ((pid=fork()) == 0) { 56 | (void) signal(SIGINT, oisig); 57 | (void) signal(SIGQUIT, oqsig); 58 | execlp(shellp, shname, "-i", (char *)NULL); 59 | _exit(1); /* Should do better! */ 60 | } 61 | else if (pid > 0) { 62 | while ((wpid=wait(&status))>=0 && wpid!=pid) 63 | ; 64 | } 65 | else errp = TRUE; 66 | 67 | signal(SIGINT, oisig); 68 | signal(SIGQUIT, oqsig); 69 | ttopen(); 70 | if(errp) 71 | ewprintf("Failed to create process"); 72 | 73 | return ( errp | status ); 74 | } 75 | -------------------------------------------------------------------------------- /orig/sys/sysv/sysdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * System V system header file 3 | */ 4 | #include 5 | 6 | #define KBLOCK 8192 /* Kill grow. */ 7 | #define GOOD 0 /* Good exit status. */ 8 | #define MAXPATH 256 /* Maximum length of path for chdir */ 9 | 10 | typedef long RSIZE; /* Type for file/region sizes */ 11 | typedef short KCHAR; /* Type for internal keystrokes */ 12 | 13 | /* 14 | * Macros used by the buffer name making code. 15 | * Start at the end of the file name, scan to the left 16 | * until BDC1 (or BDC2, if defined) is reached. The buffer 17 | * name starts just to the right of that location, and 18 | * stops at end of string (or at the next BDC3 character, 19 | * if defined). BDC2 and BDC3 are mainly for VMS. 20 | */ 21 | #define BDC1 '/' /* Buffer names. */ 22 | 23 | #define MALLOCROUND(m) (m+=7,m&=~7) /* round up to 8 byte boundry */ 24 | 25 | #define fncmp strcmp /* file name comparison */ 26 | #define bcopy(s,d,n) memcpy(d,s,n) /* memory-to-memory copy */ 27 | char *getenv(); 28 | #define gettermtype() getenv("TERM") /* determine terminal type */ 29 | char *getcwd(); 30 | #define getwd(cwd) getcwd(cwd,NFILEN) /* get current working dir */ 31 | -------------------------------------------------------------------------------- /orig/sys/sysv/ttyio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MicroEMACS 3 | * System V terminal I/O. 4 | * Version: 0 5 | * Last edit: Tue Aug 26 23:57:57 PDT 1986 6 | * By: gonzo!daveb 7 | * {sun, amdahl, mtxinu}!rtech!gonzo!daveb 8 | * 9 | * The functions in this file 10 | * negotiate with the operating system for 11 | * keyboard characters, and write characters to 12 | * the display in a barely buffered fashion. 13 | * 14 | * This version goes along with tty/termcap/tty.c. 15 | * Terminal size is determined there, rather than here, and 16 | * this does not open the termcap file 17 | */ 18 | #include "def.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define NOBUF 512 /* Output buffer size. */ 25 | 26 | char obuf[NOBUF]; /* Output buffer. */ 27 | int nobuf; /* buffer count */ 28 | 29 | static struct termio ot; /* entry state of the terminal */ 30 | static struct termio nt; /* editor's terminal state */ 31 | 32 | static int ttyactivep = FALSE; /* terminal in editor mode? */ 33 | static int ttysavedp = FALSE; /* terminal state saved? */ 34 | 35 | #ifdef TIOCGWINSZ 36 | struct winsize winsize; /* 4.3 BSD window sizing */ 37 | #endif 38 | 39 | int nrow; /* Terminal size, rows. */ 40 | int ncol; /* Terminal size, columns. */ 41 | 42 | /* These are used to implement typeahead on System V */ 43 | 44 | int kbdflgs; /* saved keyboard fd flags */ 45 | int kbdpoll; /* in O_NDELAY mode */ 46 | int kbdqp; /* there is a char in kbdq */ 47 | char kbdq; /* char we've already read */ 48 | 49 | /* 50 | * This function gets called once, to set up 51 | * the terminal channel. This version turns off flow 52 | * control. This may be wrong for your system, but no 53 | * good solution has really been found (daveb). 54 | */ 55 | ttopen() 56 | { 57 | register char *cp; 58 | extern char *getenv(); 59 | int flowcontrol; 60 | 61 | if (ttyactivep) 62 | return; 63 | 64 | flowcontrol = (getenv("MG_RAW") == NULL); 65 | 66 | if( !ttysavedp ) 67 | { 68 | if (ioctl(0, TCGETA, &ot) < 0) 69 | abort(); 70 | nt = ot; /* save entry state */ 71 | nt.c_cc[VMIN] = 1; /* one character read is OK */ 72 | nt.c_cc[VTIME] = 0; /* Never time out. */ 73 | nt.c_cc[VLNEXT] = 0xff; 74 | nt.c_iflag |= IGNBRK; 75 | if (flowcontrol) 76 | nt.c_iflag &= ~( ICRNL | INLCR | ISTRIP); 77 | else 78 | nt.c_iflag &= ~( ICRNL | INLCR | ISTRIP | IXON | IXOFF ); 79 | nt.c_oflag &= ~OPOST; 80 | nt.c_cflag |= CS8; /* allow 8th bit on input */ 81 | nt.c_cflag &= ~PARENB; /* Don't check parity */ 82 | nt.c_lflag &= ~( ECHO | ICANON | ISIG ); 83 | 84 | kbdpoll = (((kbdflgs = fcntl(0, F_GETFL, 0)) & O_NDELAY) != 0); 85 | 86 | ttysavedp = TRUE; 87 | } 88 | 89 | if (ioctl(0, TCSETAF, &nt) < 0) 90 | abort(); 91 | 92 | /* This really belongs in tty/termcap... */ 93 | 94 | if ((cp=getenv("TERMCAP")) == NULL 95 | || (nrow=getvalue(cp, "li")) <= 0 96 | || (ncol=getvalue(cp, "co")) <= 0) { 97 | nrow = 24; 98 | ncol = 80; 99 | } 100 | if (nrow > NROW) /* Don't crash if the */ 101 | nrow = NROW; /* termcap entry is */ 102 | if (ncol > NCOL) /* too big. */ 103 | ncol = NCOL; 104 | 105 | ttyactivep = TRUE; 106 | } 107 | 108 | /* 109 | * This routine scans a string, which is 110 | * actually the return value of a getenv call for the TERMCAP 111 | * variable, looking for numeric parameter "name". Return the value 112 | * if found. Return -1 if not there. Assume that "name" is 2 113 | * characters long. This limited use of the TERMCAP lets us find 114 | * out the size of a window on the X display. 115 | */ 116 | getvalue(cp, name) 117 | register char *cp; 118 | register char *name; 119 | { 120 | for (;;) { 121 | while (*cp!=0 && *cp!=':') 122 | ++cp; 123 | if (*cp++ == 0) /* Not found. */ 124 | return (-1); 125 | if (cp[0]==name[0] && cp[1]==name[1] && cp[2]=='#') 126 | return (atoi(cp+3)); /* Stops on ":". */ 127 | } 128 | } 129 | 130 | /* 131 | * This function gets called just 132 | * before we go back home to the shell. Put all of 133 | * the terminal parameters back. 134 | */ 135 | ttclose() 136 | { 137 | if(!ttysavedp || !ttyactivep) 138 | return; 139 | ttflush(); 140 | if (ioctl(0, TCSETAF, &ot) < 0 || fcntl( 0, F_SETFL, kbdflgs ) < 0) 141 | abort(); 142 | ttyactivep = FALSE; 143 | } 144 | 145 | /* 146 | * Write character to the display. 147 | * Characters are buffered up, to make things 148 | * a little bit more efficient. 149 | */ 150 | ttputc(c) 151 | { 152 | if (nobuf >= NOBUF) 153 | ttflush(); 154 | obuf[nobuf++] = c; 155 | } 156 | 157 | /* 158 | * Flush output. 159 | */ 160 | ttflush() 161 | { 162 | if (nobuf != 0) { 163 | write(1, obuf, nobuf); 164 | nobuf = 0; 165 | } 166 | } 167 | 168 | /* 169 | * Read character from terminal. 170 | * All 8 bits are returned, so that you can use 171 | * a multi-national terminal. 172 | * 173 | * If keyboard 'queue' already has typeahead from a typeahead() call, 174 | * just return it. Otherwise, make sure we are in blocking i/o mode 175 | * and read a character. 176 | */ 177 | ttgetc() 178 | { 179 | if( kbdqp ) 180 | kbdqp = FALSE; 181 | else 182 | { 183 | if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 ) 184 | abort(); 185 | kbdpoll = FALSE; 186 | while (read(0, &kbdq, 1) != 1) 187 | ; 188 | } 189 | return ( kbdq & 0xff ); 190 | } 191 | 192 | /* 193 | * Return non-FALSE if typeahead is pending. 194 | * 195 | * If already got unread typeahead, do nothing. 196 | * Otherwise, set keyboard to O_NDELAY if not already, and try 197 | * a one character read. 198 | */ 199 | typeahead() 200 | { 201 | if( !kbdqp ) 202 | { 203 | if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 ) 204 | abort(); 205 | kbdpoll = TRUE; 206 | kbdqp = (1 == read( 0, &kbdq, 1 )); 207 | } 208 | return ( kbdqp ); 209 | } 210 | 211 | 212 | /* 213 | * panic: print error and die, leaving core file. 214 | * Don't know why this is needed (daveb). 215 | */ 216 | panic(s) 217 | char *s; 218 | { 219 | fprintf(stderr, "%s\r\n", s); 220 | abort(); 221 | } 222 | 223 | 224 | /* 225 | ** This should check the size of the window, and reset if needed. 226 | */ 227 | 228 | setttysize() 229 | { 230 | #ifdef TIOCGWINSZ 231 | if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { 232 | nrow = winsize . ws_row; 233 | ncol = winsize . ws_col; 234 | } else 235 | #endif 236 | if ((nrow=tgetnum ("li")) <= 0 237 | || (ncol=tgetnum ("co")) <= 0) { 238 | nrow = 24; 239 | ncol = 80; 240 | } 241 | if (nrow > NROW) /* Don't crash if the */ 242 | nrow = NROW; /* termcap entry is */ 243 | if (ncol > NCOL) /* too big. */ 244 | ncol = NCOL; 245 | } 246 | 247 | #ifndef NO_DPROMPT 248 | #include 249 | #include 250 | 251 | static jmp_buf tohere; 252 | 253 | static alrm() 254 | { 255 | longjmp(tohere, -1); 256 | } 257 | 258 | /* 259 | * Return TRUE if we wait without doing anything, else return FALSE. 260 | */ 261 | 262 | ttwait() 263 | { 264 | int alrm(); 265 | 266 | if (kbdqp) 267 | return FALSE; /* already pending input */ 268 | if (setjmp(tohere)) 269 | return TRUE; /* timeout on read if here */ 270 | signal(SIGALRM, alrm); alarm(2); 271 | kbdqp = (1 == read(0, &kbdq, 1)); 272 | alarm(0); 273 | return FALSE; /* successful read if here */ 274 | } 275 | #endif NO_DPROMPT 276 | -------------------------------------------------------------------------------- /orig/sys/sysv/ttyio.c.old: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MicroEMACS 3 | * System V terminal I/O. 4 | * Version: 0 5 | * Last edit: Tue Aug 26 23:57:57 PDT 1986 6 | * By: gonzo!daveb 7 | * {sun, amdahl, mtxinu}!rtech!gonzo!daveb 8 | * 9 | * The functions in this file 10 | * negotiate with the operating system for 11 | * keyboard characters, and write characters to 12 | * the display in a barely buffered fashion. 13 | * 14 | * This version goes along with tty/termcap/tty.c. 15 | * Terminal size is determined there, rather than here, and 16 | * this does not open the termcap file 17 | */ 18 | #include "def.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define NOBUF 512 /* Output buffer size. */ 25 | 26 | char obuf[NOBUF]; /* Output buffer. */ 27 | int nobuf; /* buffer count */ 28 | 29 | static struct termio ot; /* entry state of the terminal */ 30 | static struct termio nt; /* editor's terminal state */ 31 | 32 | static int ttyactivep = FALSE; /* terminal in editor mode? */ 33 | static int ttysavedp = FALSE; /* terminal state saved? */ 34 | 35 | int nrow; /* Terminal size, rows. */ 36 | int ncol; /* Terminal size, columns. */ 37 | 38 | /* These are used to implement typeahead on System V */ 39 | 40 | int kbdflgs; /* saved keyboard fd flags */ 41 | int kbdpoll; /* in O_NDELAY mode */ 42 | int kbdqp; /* there is a char in kbdq */ 43 | char kbdq; /* char we've already read */ 44 | 45 | /* 46 | * This function gets called once, to set up 47 | * the terminal channel. This version turns off flow 48 | * control. This may be wrong for your system, but no 49 | * good solution has really been found (daveb). 50 | */ 51 | ttopen() 52 | { 53 | register char *cp; 54 | extern char *getenv(); 55 | 56 | if (ttyactivep) 57 | return; 58 | 59 | if( !ttysavedp ) 60 | { 61 | if (ioctl(0, TCGETA, &ot) < 0) 62 | abort(); 63 | nt = ot; /* save entry state */ 64 | nt.c_cc[VMIN] = 1; /* one character read is OK */ 65 | nt.c_cc[VTIME] = 0; /* Never time out. */ 66 | nt.c_iflag |= IGNBRK; 67 | nt.c_iflag &= ~( ICRNL | INLCR | ISTRIP | IXON | IXOFF ); 68 | nt.c_oflag &= ~OPOST; 69 | nt.c_cflag |= CS8; /* allow 8th bit on input */ 70 | nt.c_cflag &= ~PARENB; /* Don't check parity */ 71 | nt.c_lflag &= ~( ECHO | ICANON | ISIG ); 72 | 73 | kbdpoll = (((kbdflgs = fcntl(0, F_GETFL, 0)) & O_NDELAY) != 0); 74 | 75 | ttysavedp = TRUE; 76 | } 77 | 78 | if (ioctl(0, TCSETAF, &nt) < 0) 79 | abort(); 80 | 81 | /* This really belongs in tty/termcap... */ 82 | 83 | if ((cp=getenv("TERMCAP")) == NULL 84 | || (nrow=getvalue(cp, "li")) <= 0 85 | || (ncol=getvalue(cp, "co")) <= 0) { 86 | nrow = 24; 87 | ncol = 80; 88 | } 89 | if (nrow > NROW) /* Don't crash if the */ 90 | nrow = NROW; /* termcap entry is */ 91 | if (ncol > NCOL) /* too big. */ 92 | ncol = NCOL; 93 | 94 | ttyactivep = TRUE; 95 | } 96 | 97 | /* 98 | * This routine scans a string, which is 99 | * actually the return value of a getenv call for the TERMCAP 100 | * variable, looking for numeric parameter "name". Return the value 101 | * if found. Return -1 if not there. Assume that "name" is 2 102 | * characters long. This limited use of the TERMCAP lets us find 103 | * out the size of a window on the X display. 104 | */ 105 | getvalue(cp, name) 106 | register char *cp; 107 | register char *name; 108 | { 109 | for (;;) { 110 | while (*cp!=0 && *cp!=':') 111 | ++cp; 112 | if (*cp++ == 0) /* Not found. */ 113 | return (-1); 114 | if (cp[0]==name[0] && cp[1]==name[1] && cp[2]=='#') 115 | return (atoi(cp+3)); /* Stops on ":". */ 116 | } 117 | } 118 | 119 | /* 120 | * This function gets called just 121 | * before we go back home to the shell. Put all of 122 | * the terminal parameters back. 123 | */ 124 | ttclose() 125 | { 126 | if(!ttysavedp || !ttyactivep) 127 | return; 128 | ttflush(); 129 | if (ioctl(0, TCSETAF, &ot) < 0 || fcntl( 0, F_SETFL, kbdflgs ) < 0) 130 | abort(); 131 | ttyactivep = FALSE; 132 | } 133 | 134 | /* 135 | * Write character to the display. 136 | * Characters are buffered up, to make things 137 | * a little bit more efficient. 138 | */ 139 | ttputc(c) 140 | { 141 | if (nobuf >= NOBUF) 142 | ttflush(); 143 | obuf[nobuf++] = c; 144 | } 145 | 146 | /* 147 | * Flush output. 148 | */ 149 | ttflush() 150 | { 151 | if (nobuf != 0) { 152 | write(1, obuf, nobuf); 153 | nobuf = 0; 154 | } 155 | } 156 | 157 | /* 158 | * Read character from terminal. 159 | * All 8 bits are returned, so that you can use 160 | * a multi-national terminal. 161 | * 162 | * If keyboard 'queue' already has typeahead from a typeahead() call, 163 | * just return it. Otherwise, make sure we are in blocking i/o mode 164 | * and read a character. 165 | */ 166 | ttgetc() 167 | { 168 | if( kbdqp ) 169 | kbdqp = FALSE; 170 | else 171 | { 172 | if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 ) 173 | abort(); 174 | kbdpoll = FALSE; 175 | while (read(0, &kbdq, 1) != 1) 176 | ; 177 | } 178 | return ( kbdq & 0xff ); 179 | } 180 | 181 | /* 182 | * Return non-FALSE if typeahead is pending. 183 | * 184 | * If already got unread typeahead, do nothing. 185 | * Otherwise, set keyboard to O_NDELAY if not already, and try 186 | * a one character read. 187 | */ 188 | typeahead() 189 | { 190 | if( !kbdqp ) 191 | { 192 | if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 ) 193 | abort(); 194 | kbdpoll = TRUE; 195 | kbdqp = (1 == read( 0, &kbdq, 1 )); 196 | } 197 | return ( kbdqp ); 198 | } 199 | 200 | 201 | /* 202 | * panic: print error and die, leaving core file. 203 | * Don't know why this is needed (daveb). 204 | */ 205 | panic(s) 206 | char *s; 207 | { 208 | fprintf(stderr, "%s\r\n", s); 209 | abort(); 210 | } 211 | 212 | 213 | /* 214 | ** This should check the size of the window, and reset if needed. 215 | */ 216 | 217 | setttysize() 218 | { 219 | #ifdef TIOCGWINSZ 220 | if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { 221 | nrow = winsize . ws_row; 222 | ncol = winsize . ws_col; 223 | } else 224 | #endif 225 | if ((nrow=tgetnum ("li")) <= 0 226 | || (ncol=tgetnum ("co")) <= 0) { 227 | nrow = 24; 228 | ncol = 80; 229 | } 230 | if (nrow > NROW) /* Don't crash if the */ 231 | nrow = NROW; /* termcap entry is */ 232 | if (ncol > NCOL) /* too big. */ 233 | ncol = NCOL; 234 | } 235 | 236 | #ifndef NO_DPROMPT 237 | #include 238 | #include 239 | 240 | static jmp_buf tohere; 241 | 242 | static alrm() 243 | { 244 | longjmp(tohere, -1); 245 | } 246 | 247 | /* 248 | * Return TRUE if we wait without doing anything, else return FALSE. 249 | */ 250 | 251 | ttwait() 252 | { 253 | int alrm(); 254 | 255 | if (kbdqp) 256 | return FALSE; /* already pending input */ 257 | if (setjmp(tohere)) 258 | return TRUE; /* timeout on read if here */ 259 | signal(SIGALRM, alrm); alarm(2); 260 | kbdqp = (1 == read(0, &kbdq, 1)); 261 | alarm(0); 262 | return FALSE; /* successful read if here */ 263 | } 264 | #endif NO_DPROMPT 265 | -------------------------------------------------------------------------------- /slowputc.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | /* 6 | * Time as a floating point double, in seconds. 7 | */ 8 | 9 | static double 10 | slowdown_dtime() 11 | { 12 | struct timeval t; 13 | 14 | gettimeofday(&t, NULL); 15 | return (double) t.tv_sec + (double) t.tv_usec * 1e-6; 16 | } 17 | 18 | 19 | INT slowspeed = -1; // Speed in baud, with 10 bits per byte, negative off 20 | 21 | 22 | /* 23 | * Potentially wait and flush to simulate output speed. 24 | */ 25 | 26 | static void 27 | slowdown(INT c) 28 | { 29 | static INT count=0; 30 | static double timepoint = 0.0; 31 | INT buf; 32 | double bufwait, now, delayperchar; 33 | 34 | buf = slowspeed/1000; // 1000 = 10 bits per byte * 100 Hz 35 | if (buf < 1) buf = 1; 36 | 37 | if (++count >= buf && ((c & 0xc0) != 0x80 || !termisutf8)) { 38 | delayperchar = 10.0/(double) slowspeed; 39 | timepoint = timepoint + count*delayperchar; 40 | 41 | now = slowdown_dtime(); 42 | bufwait = timepoint - now; 43 | 44 | if (bufwait < -0.2) { 45 | /* There is an external wait of more than */ 46 | /* 200 msec, reset */ 47 | timepoint = now; 48 | } else if (bufwait > 0.0) { 49 | usleep((useconds_t)(1.0e6*bufwait)); 50 | } 51 | 52 | ttflush(); 53 | count = 0; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sys/README: -------------------------------------------------------------------------------- 1 | Some files that may be useful on various systems. 2 | -------------------------------------------------------------------------------- /sys/bsd/Makefile: -------------------------------------------------------------------------------- 1 | # $FreeBSD$ 2 | 3 | PORTNAME= mg3a 4 | DISTVERSION= 190113 5 | CATEGORIES= editors 6 | MASTER_SITES= http://github.com/paaguti/mg3a/archive/ 7 | DISTNAME= ${DISVERSION} 8 | 9 | # No patches in this release 10 | #PATCH_SITES= https://raw.githubusercontent.com/paaguti/mg3a/master/debian/patches/ 11 | #PATCHFILES= 01-pipein.diff 02-Makefile.bsd 12 | #PATCH_DIST_STRIP= -p1 13 | 14 | MAINTAINER= paaguti@gmail.com 15 | COMMENT= Yet another public domain MicroEMACS-based editor with UTF8 support 16 | 17 | LICENSE= BSD2CLAUSE 18 | #LICENSE_FILE= ${WRKSRC}/LICENSE 19 | 20 | CONFLICTS_INSTALL= mg 21 | 22 | USE_GITHIB= yes 23 | GH_ACCOUNT= paaguti 24 | GH_PROJECT= mg3a 25 | GH_TAGNAME= ${DISVERSION} 26 | 27 | WRKSRC=${WRKDIR}/mg3a-${DISTVERSION} 28 | .include 29 | -------------------------------------------------------------------------------- /sys/bsd/pkg-descr: -------------------------------------------------------------------------------- 1 | This is Mg3a, a public domain MicroEMACS-based editor with commands 2 | and key-bindings similar to GNU Emacs. It is a development of the 3 | earlier public domain Mg2a editor, with the addition of functions to 4 | deal with UTF-8, CRLF/LF line endings, and some other updates. 5 | 6 | WWW: https://github.com/paaguti/mg3a 7 | -------------------------------------------------------------------------------- /sys/bsd/pkg-plist: -------------------------------------------------------------------------------- 1 | bin/mg 2 | share/mg3a/dot.mg 3 | share/mg3a/dot.mg-cygwin 4 | share/mg3a/dot.mg-xterm 5 | share/mg3a/README 6 | share/doc/mg3a/README 7 | share/doc/mg3a/README.shell-command 8 | share/doc/mg3a/README.dired 9 | share/doc/mg3a/README.ucsnames 10 | share/doc/mg3a/README.fill-paragraph 11 | share/doc/mg3a/README.undo 12 | share/doc/mg3a/README.auto-execute 13 | share/doc/mg3a/README.misc 14 | share/doc/mg3a/README.user_macros 15 | share/doc/mg3a/README.bindings 16 | share/doc/mg3a/README.programmer 17 | share/doc/mg3a/README.user_modes 18 | share/doc/mg3a/README.clike-mode 19 | share/doc/mg3a/README.python-mode 20 | share/doc/mg3a/README.debian 21 | share/doc/mg3a/README.reference 22 | share/doc/mg3a/README.todo 23 | 24 | -------------------------------------------------------------------------------- /sys/osx/README: -------------------------------------------------------------------------------- 1 | This is the Hombrew Formula from my personal tap 2 | -------------------------------------------------------------------------------- /sys/osx/mg3a.rb: -------------------------------------------------------------------------------- 1 | class Mg3a < Formula 2 | desc "Small Emacs-like editor inspired by mg with UTF8 support." 3 | homepage "https://gtihub.com/paaguti/mg3a/" 4 | 5 | url "https://github.com/paaguti/mg3a/archive/20201201.tar.gz" 6 | 7 | option "with-full", "Include all fancy stuff (build with -DALL)" 8 | 9 | conflicts_with "mg", :because => "both install `mg`" 10 | 11 | def install 12 | if build.with?("full") 13 | mg3aopts = %w[all] 14 | end 15 | 16 | system "./bootstrap.sh" 17 | system "./configure", "#{mg3aopts * " "}" 18 | system "make" 19 | bin.install "mg" 20 | doc.install Dir["bl/dot.*"] 21 | doc.install Dir["README*"] 22 | end 23 | 24 | test do 25 | (testpath/"command.sh").write <<~EOS 26 | #!/usr/bin/expect -f 27 | set timeout -1 28 | spawn #{bin}/mg 29 | match_max 100000 30 | send -- "\u0018\u0003" 31 | expect eof 32 | EOS 33 | (testpath/"command.sh").chmod 0755 34 | 35 | system testpath/"command.sh" 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /sys/rudix/COPYING: -------------------------------------------------------------------------------- 1 | This is a fork for the original mg3a code by Bengt Larson 2 | 3 | I was in contact with Bengt Larson until April 2017. Then, suddenly, 4 | his email address was cancelled. His repository has not been updated 5 | since the 4th of April, 2017. As of the 15th of December 2017, 6 | www.bengtl.net became inaccessible and thus the original code repository i 7 | www.bengtl.net/files/mg3a is lost. 8 | 9 | -------------------------------------------------------------------------------- /sys/rudix/Makefile: -------------------------------------------------------------------------------- 1 | include ../../Library/GNU.mk 2 | #BuildDepends += /usr/local/bin/ncursesw6-config 3 | 4 | Title= MG3a 5 | Name= mg3a 6 | Version= 20201201 7 | Site= https://github.com/paaguti 8 | Source= https://github.com/paaguti/$(Name)/archive/$(Version).tar.gz 9 | License= GPL 10 | 11 | ReadMeFile= $(SourceDir)/README 12 | PatchLevel = -p1 13 | 14 | define before_build_hook 15 | cd $(BuildDir) && ./bootstrap.sh 16 | endef 17 | 18 | define test_hook 19 | $(BinDir)/mg -v | grep $(Version) 20 | endef 21 | -------------------------------------------------------------------------------- /sys/unix/README: -------------------------------------------------------------------------------- 1 | Some scripts I use. Should work with a modern /bin/sh. Works in any 2 | case with /bin/bash. 3 | 4 | 5 | mgfunc string [files] 6 | 7 | Search for the string as an identifier at the beginning of a line in 8 | files, and start the editor, going there. This can be a function name, 9 | if you format things that way. The files default to *.c. 10 | 11 | 12 | mgedit string [files] 13 | 14 | Start the editor with the files containing the string. The files 15 | default to *.c. The search string of the editor is set to the string. 16 | 17 | 18 | mgt string [files] 19 | 20 | Search for the string "Tag:string" in files, and start the editor, 21 | going there. The files default to *.h *.c. 22 | 23 | 24 | Changed 2015-01-01: "LC_ALL=C" in the scripts is so that grep won't think 25 | that something with a non-locale charset is a binary file. 26 | -------------------------------------------------------------------------------- /sys/unix/mgedit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | case $1 in 3 | -*) opts="$1"; grep="$2"; shift 2;; 4 | *) opts=""; grep="$1"; shift;; 5 | esac 6 | mg -p"$grep" $(LC_ALL=C grep -l $opts -e "$grep" ${*:-*.c}) 7 | -------------------------------------------------------------------------------- /sys/unix/mgfunc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | grep="$1" 3 | shift 4 | match="$(LC_ALL=C grep -n "^$grep[^A-Za-z0-9_]" ${*:-*.c} /dev/null | head -1)" 5 | case $match in "") echo Not found; exit 1;; esac 6 | file="${match%%:*}" 7 | num="${match#*:}" 8 | num="${num%%:*}" 9 | mg -p"$grep" "+$num" "$file" 10 | -------------------------------------------------------------------------------- /sys/unix/mgt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | grep="$1" 3 | shift 4 | match="$(LC_ALL=C grep -n "Tag:$grep" ${*:-*.h *.c} /dev/null | head -1)" 5 | case $match in "") echo Not found; exit 1;; esac 6 | file="${match%%:*}" 7 | num="${match#*:}" 8 | num="${num%%:*}" 9 | mg "+$num" "$file" 10 | -------------------------------------------------------------------------------- /sysdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * System V system header file 3 | */ 4 | 5 | /* Needed on Linux and Cygwin for getting the prototypes for wcwidth() */ 6 | /* and wcswidth(). */ 7 | 8 | #if defined(__linux__) || defined(__CYGWIN__) 9 | #define _XOPEN_SOURCE 500 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define KBLOCK 8192 /* Kill grow. */ 24 | #define GOOD 0 /* Good exit status. */ 25 | 26 | typedef uint_least16_t ucs2; /* BMP Unicode */ 27 | typedef int_least32_t ucs4; /* General Unicode */ 28 | typedef ucs4 KCHAR; /* Type for internal keystrokes */ 29 | 30 | #define MALLOCROUND 8 /* round up to 8 byte boundary */ 31 | 32 | #ifdef __linux__ 33 | # define bcopy(s,d,n) memmove((d),(s),(n)) /* memory-to-memory copy */ 34 | #endif 35 | #define gettermtype() getenv("TERM") /* determine terminal type */ 36 | -------------------------------------------------------------------------------- /tty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Termcap/terminfo display driver 3 | * 4 | * Mg3a: Cleaned up a bit. Uses setupterm. And sigaction. 5 | */ 6 | 7 | #include "def.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define BEL 0x07 /* BEL character. */ 14 | 15 | char *tgetstr(char *, char **); 16 | char *tgoto(char *, int, int); 17 | int setupterm(char *, int, int *); 18 | int tputs(const char *, int, int (*)(int)); 19 | 20 | #ifdef MOUSE 21 | static void mouse_mode(INT); 22 | static void ttputsf(char *, ...); 23 | #endif 24 | 25 | char *CM, /* cursor move */ 26 | *CE, /* clear to end of line */ 27 | *TI, /* term init -- start using cursor motion */ 28 | *TE, /* term end --- end using cursor motion */ 29 | *SO, /* invers video */ 30 | *SE, /* normal video */ 31 | *CD, /* clear to end of display */ 32 | *CS, /* set scroll region */ 33 | *KS, /* enter keypad mode */ 34 | *KE; /* exit keypad mode */ 35 | 36 | #ifdef UTF8 37 | INT termisutf8 = 0; // Terminal is UTF-8 38 | INT termdoeswide = 1; // Terminal handles wide characters 39 | INT termdoescombine = 1; // Terminal handles combining characters 40 | INT termdoesonlybmp = 1; // Terminal is restricted to BMP 41 | 42 | charset_t buf8bit = cp1252; // Default 8-bit charset 43 | charset_t termcharset = cp1252; // Terminal/locale charset 44 | charset_t bufdefaultcharset = cp1252; // Default charset 45 | charset_t doscharset = cp437; // Alternate/Dos charset 46 | 47 | /* Internal variable. If true, assume all terminal capabilities are there */ 48 | INT fullterm = 0; 49 | #endif 50 | 51 | 52 | INT refresh(INT f, INT n); 53 | 54 | 55 | /* 56 | * Mg3a: Finally deal with window change. 57 | */ 58 | 59 | volatile sig_atomic_t winchanged = 0; 60 | 61 | static void 62 | winchange(int dummy) 63 | { 64 | winchanged = 1; 65 | } 66 | 67 | /* 68 | * Initialize the terminal when the editor gets started up. 69 | * 70 | * Mg3a: and do a minimal re-init when resuming. 71 | */ 72 | 73 | void 74 | ttinit() 75 | { 76 | char *tv_stype; 77 | struct sigaction sa; 78 | static int inited = 0; 79 | int errret; 80 | char errstr[160]; 81 | 82 | if (inited) { 83 | // Comes here after resuming 84 | mouse_mode(1); 85 | if (TI && *TI) putpad(TI, 1); /* init the term */ 86 | if (KS && *KS) putpad(KS, 1); /* turn on keypad */ 87 | refresh(0, 1); /* Check for size, and set up to repaint */ 88 | winchanged = 0; /* Already done */ 89 | return; 90 | } 91 | 92 | inited = 1; 93 | 94 | if((tv_stype = gettermtype()) == NULL) 95 | panic("Could not determine terminal type", 0); 96 | 97 | setupterm(tv_stype, 1, &errret); 98 | 99 | if (errret == -1) { 100 | panic("Terminfo database not found", 0); 101 | } else if (errret == 0) { 102 | snprintf(errstr, sizeof(errstr), "Terminfo entry for '%s' not found", tv_stype); 103 | panic(errstr, 0); 104 | } 105 | 106 | CD = tgetstr("cd", NULL); 107 | CM = tgetstr("cm", NULL); 108 | CE = tgetstr("ce", NULL); 109 | TI = tgetstr("ti", NULL); 110 | TE = tgetstr("te", NULL); 111 | SO = tgetstr("so", NULL); 112 | SE = tgetstr("se", NULL); 113 | CS = tgetstr("cs", NULL); /* set scrolling region */ 114 | KS = tgetstr("ks", NULL); /* keypad start, keypad end */ 115 | KE = tgetstr("ke", NULL); 116 | mouse_mode (1); 117 | 118 | #ifdef UTF8 119 | termcharset = nametocharset(nl_langinfo(CODESET), CHARSETALL); 120 | bufdefaultcharset = termcharset; 121 | 122 | if (termcharset == utf_8) { 123 | termisutf8 = 1; 124 | } else { 125 | buf8bit = termcharset; 126 | } 127 | 128 | if (strncmp(tv_stype, "cygwin", 6) == 0) { 129 | termdoeswide = 0; 130 | termdoescombine = 0; 131 | termdoesonlybmp = 1; 132 | } 133 | #endif 134 | 135 | #if LF_DEFAULT 136 | defb_flag |= BFUNIXLF; 137 | #endif 138 | if(CM == NULL) 139 | panic("This terminal is too stupid to run Mg", 0); 140 | 141 | ttresize(); /* set nrow & ncol */ 142 | 143 | /* watch out for empty capabilities (sure to be wrong) */ 144 | if (CE && !*CE) CE = NULL; 145 | if (CS && !*CS) CS = NULL; 146 | if (CD && !*CD) CD = NULL; 147 | 148 | if (TI && *TI) putpad(TI, 1); /* init the term */ 149 | if (KS && *KS) putpad(KS, 1); /* turn on keypad */ 150 | 151 | sa.sa_handler = winchange; 152 | sigemptyset(&sa.sa_mask); 153 | sa.sa_flags = 0; 154 | sigaction(SIGWINCH, &sa, NULL); 155 | sigaction(SIGCONT, &sa, NULL); 156 | } 157 | 158 | 159 | /* 160 | * Clean up the terminal, in anticipation of a return to the command 161 | * interpreter. This is a no-op on the ANSI display. On the SCALD 162 | * display, it sets the window back to half screen scrolling. Perhaps 163 | * it should query the display for the increment, and put it back to 164 | * what it was. 165 | */ 166 | 167 | void 168 | tttidy() 169 | { 170 | mouse_mode(0); /* turn off mouse */ 171 | if (KE && *KE) putpad(KE, 1); /* turn off keypad */ 172 | if (TE && *TE) putpad(TE, 1); /* set the term back to normal mode */ 173 | } 174 | 175 | 176 | /* 177 | * Move the cursor to the specified origin 0 row and column position. 178 | * Try to optimize out extra moves; redisplay may have left the cursor 179 | * in the right location last time! 180 | */ 181 | 182 | void 183 | ttmove(INT row, INT col) 184 | { 185 | if (row != ttrow || col != ttcol) { 186 | putpad(tgoto(CM, col, row), 1); 187 | ttrow = row; 188 | ttcol = col; 189 | } 190 | } 191 | 192 | 193 | /* 194 | * Erase to end of line. 195 | */ 196 | 197 | void 198 | tteeol() 199 | { 200 | if (CE) putpad(CE, 1); 201 | else { 202 | INT i = ncol - ttcol; 203 | if (ttrow == nrow - 1) i--; 204 | while(i-- > 0) ttputc(' '); 205 | ttcol = HUGE; 206 | } 207 | } 208 | 209 | 210 | /* 211 | * Erase to end of page. 212 | */ 213 | 214 | void 215 | tteeop() 216 | { 217 | INT line; 218 | 219 | if (CD) putpad(CD, nrow - ttrow); 220 | else { 221 | tteeol(); 222 | 223 | /* do it by hand */ 224 | for (line = ttrow + 1; line < nrow; line++) { 225 | ttmove(line, 0); 226 | tteeol(); 227 | } 228 | 229 | ttrow = ttcol = HUGE; 230 | } 231 | } 232 | 233 | 234 | /* 235 | * Mg3a: Controlling type of bell 236 | */ 237 | 238 | INT bell_type = 1; // Audio bell default 239 | static int inverse_video = 0; 240 | 241 | 242 | /* 243 | * Make a noise. 244 | */ 245 | 246 | void 247 | ttbeep() { 248 | char *ce = CE; 249 | 250 | if (bell_type == 1) { 251 | ttputc(BEL); 252 | ttflush(); 253 | } else if (bell_type == 2) { 254 | CE = NULL; 255 | refreshbuf(NULL); 256 | invalidatecache(); 257 | inverse_video = 1; 258 | update(); 259 | usleep(100000); 260 | refreshbuf(NULL); 261 | invalidatecache(); 262 | inverse_video = 0; 263 | update(); 264 | CE = ce; 265 | } 266 | } 267 | 268 | 269 | /* 270 | * Switch to full screen scroll. This is used by "spawn.c" just before 271 | * is suspends the editor, and by "display.c" when it is getting ready 272 | * to exit. 273 | */ 274 | 275 | void 276 | ttnowindow() 277 | { 278 | if (CS) { 279 | putpad(tgoto(CS, nrow - 1, 0), nrow - ttrow); 280 | ttrow = HUGE; /* Unknown. */ 281 | ttcol = HUGE; 282 | } 283 | } 284 | 285 | 286 | /* 287 | * Set the current writing color to the specified color. Watch for 288 | * color changes that are not going to do anything (the color is 289 | * already right) and don't send anything to the display. 290 | * 291 | * Mg3a: added inverse video. 292 | */ 293 | 294 | void 295 | ttcolor(INT color) 296 | { 297 | if (inverse_video) { 298 | if (color == CTEXT) color = CMODE; 299 | else if (color == CMODE) color = CTEXT; 300 | } 301 | 302 | if (color != tthue) { 303 | if (color == CTEXT) { /* Normal video. */ 304 | putpad(SE, 1); 305 | } else if (color == CMODE) { /* Reverse video. */ 306 | putpad(SO, 1); 307 | } 308 | tthue = color; /* Save the color. */ 309 | } 310 | } 311 | 312 | 313 | /* 314 | * This routine is called by the "refresh the screen" command to try 315 | * and resize the display. 316 | */ 317 | 318 | void 319 | ttresize() 320 | { 321 | setttysize(); /* found in "ttyio.c", */ 322 | /* ask OS for tty size */ 323 | if (nrow < 1) /* Check limits. */ 324 | nrow = 1; 325 | 326 | if (ncol < 1) 327 | ncol = 1; 328 | } 329 | 330 | /* 331 | * mode 0 => disable mouse reporting 332 | * 1 => enable mouse reporting 333 | */ 334 | #ifdef MOUSE 335 | static void 336 | mouse_mode(INT mode) 337 | { 338 | ttputsf("\e[?1000%c", (mode == 1) ? 'h' : 'l'); // Enable/Disable mouse report 339 | } 340 | 341 | static void 342 | ttputsf(char *format, ...) 343 | { 344 | char localbuf[256]; 345 | va_list valist; 346 | va_start (valist,format); 347 | vsnprintf(localbuf,255,format,valist); 348 | va_end(valist); 349 | for (int i=0; localbuf[i]; i++) 350 | ittputc(localbuf[i]); 351 | } 352 | #endif 353 | -------------------------------------------------------------------------------- /ttydef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Termcap terminal file, nothing special, just make it big 3 | * enough for windowing systems. 4 | */ 5 | 6 | // #define GOSLING /* Compile in fancy display. */ 7 | // #define MEMMAP */ /* Not memory mapped video. */ 8 | 9 | #define NROW 100 /* (maximum) Rows. */ 10 | #define NCOL 200 /* (maximum) Columns. */ 11 | #define TERMCAP /* for possible use in ttyio.c */ 12 | 13 | #define getkbd() (ttgetc()) 14 | #define putpad(str, num) tputs(str, num, ittputc) 15 | 16 | #define KFIRST K00 17 | #define KLAST K00 18 | -------------------------------------------------------------------------------- /ttyio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Name: MicroEMACS 3 | * System V terminal I/O. 4 | * Version: 0 5 | * Last edit: Tue Aug 26 23:57:57 PDT 1986 6 | * By: gonzo!daveb 7 | * {sun, amdahl, mtxinu}!rtech!gonzo!daveb 8 | * 9 | * The functions in this file negotiate with the operating system for 10 | * keyboard characters, and write characters to the display in a 11 | * barely buffered fashion. 12 | * 13 | * Mg3a: many changes, including converting to termios. 14 | */ 15 | 16 | #include "def.h" 17 | 18 | #ifdef SLOW 19 | #include "slowputc.h" 20 | #endif 21 | 22 | #ifndef SELECT_FOR_TYPEAHEAD 23 | #define SELECT_FOR_TYPEAHEAD 1 /* May be more portable */ 24 | #endif 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #define NOBUF 512 /* Output buffer size. */ 34 | 35 | int tgetnum(char *); 36 | 37 | static char obuf[NOBUF]; /* Output buffer. */ 38 | static INT nobuf = 0; /* buffer count */ 39 | 40 | static struct termios ot; /* entry state of the terminal */ 41 | static struct termios nt; /* editor's terminal state */ 42 | 43 | static int ttyactivep = FALSE; /* terminal in editor mode? */ 44 | static int ttysavedp = FALSE; /* terminal state saved? */ 45 | 46 | #ifdef TIOCGWINSZ 47 | static struct winsize winsize; /* 4.3 BSD window sizing */ 48 | #endif 49 | 50 | INT nrow; /* Terminal size, rows. */ 51 | INT ncol; /* Terminal size, columns. */ 52 | 53 | #ifdef CHARSDEBUG 54 | INT charsoutput = 0; /* Bytes output since last display */ 55 | INT totalkeys = 0; /* Total bytes input */ 56 | #endif 57 | 58 | INT refresh(INT f, INT n); 59 | 60 | 61 | /* 62 | * This function gets called once, to set up the terminal channel. 63 | * This version turns off flow control. This may be wrong for your 64 | * system, but no good solution has really been found (daveb). 65 | */ 66 | 67 | void 68 | ttopen() 69 | { 70 | int i; 71 | 72 | if( !ttysavedp ) 73 | { 74 | if (tcgetattr(0, &ot) < 0) 75 | panic("ttopen: tcgetattr", errno); 76 | nt = ot; /* save entry state */ 77 | for (i = 0; i < NCCS; i++) nt.c_cc[i] = 0; 78 | nt.c_cc[VMIN] = 1; /* one character read is OK */ 79 | nt.c_cc[VTIME] = 0; /* Never time out. */ 80 | nt.c_iflag |= IGNBRK; 81 | nt.c_iflag &= ~( ICRNL | INLCR | IGNCR | ISTRIP | IXON | IXOFF ); 82 | nt.c_oflag &= ~OPOST; 83 | nt.c_cflag |= CS8; /* allow 8th bit on input */ 84 | nt.c_cflag &= ~PARENB; /* Don't check parity */ 85 | nt.c_lflag &= ~( ECHO | ICANON | ISIG | IEXTEN ); 86 | 87 | ttysavedp = TRUE; 88 | } 89 | 90 | if (tcsetattr(0, TCSADRAIN, &nt) < 0) 91 | panic("ttopen: tcsetattr", errno); 92 | 93 | ttyactivep = TRUE; 94 | } 95 | 96 | 97 | /* 98 | * This function gets called just before we go back home to the shell. 99 | * Put all of the terminal parameters back. 100 | */ 101 | 102 | void 103 | ttclose() 104 | { 105 | if(!ttysavedp || !ttyactivep) 106 | return; 107 | ttflush(); 108 | if (tcsetattr(0, TCSADRAIN, &ot) < 0) 109 | panic("ttclose: tcsetattr", errno); 110 | ttyactivep = FALSE; 111 | } 112 | 113 | 114 | /* 115 | * Mg3a: set/clear SIGINT on ^G. Return success status. 116 | */ 117 | 118 | int 119 | setctrlg_interrupt(int on) 120 | { 121 | struct termios gnt; 122 | 123 | if (on) { 124 | gnt = nt; 125 | gnt.c_cc[VINTR] = CCHR('G'); 126 | gnt.c_lflag |= ISIG; 127 | return !tcsetattr(0, TCSANOW, &gnt); 128 | } else { 129 | return !tcsetattr(0, TCSANOW, &nt); 130 | } 131 | } 132 | 133 | 134 | /* 135 | * Write character to the display. Characters are buffered up, to make 136 | * things a little bit more efficient. 137 | */ 138 | 139 | void 140 | ttputc(INT c) 141 | { 142 | /* Work around cygwin term bug */ 143 | /* Possibly good to never flush in the middle of UTF-8 character */ 144 | 145 | if ((nobuf >= NOBUF-3 && (c & 0xc0) != 0x80) || nobuf >= NOBUF) 146 | ttflush(); 147 | 148 | #ifdef SLOW 149 | if (slowspeed > 0) slowdown(c); // May also flush 150 | #endif 151 | 152 | obuf[nobuf++] = c; 153 | 154 | #ifdef CHARSDEBUG 155 | charsoutput++; 156 | #endif 157 | } 158 | 159 | 160 | /* 161 | * Flush output. 162 | */ 163 | 164 | void 165 | ttflush() 166 | { 167 | ssize_t s; 168 | char *buf = obuf; 169 | 170 | while (nobuf > 0) { 171 | s = write(1, buf, nobuf); 172 | 173 | if (s == -1) { 174 | if (errno == EINTR) continue; 175 | 176 | nobuf = 0; 177 | panic("Error writing screen", errno); 178 | } 179 | 180 | buf += s; 181 | nobuf -= s; 182 | } 183 | } 184 | 185 | 186 | /* 187 | * Mg3a: This is to fit the signature of tputs(). It might work 188 | * anyway, but for safety's sake. 189 | */ 190 | 191 | int 192 | ittputc(int c) 193 | { 194 | ttputc(c); 195 | return 0; 196 | } 197 | 198 | 199 | /* 200 | * Read character from terminal. All 8 bits are returned, so that you 201 | * can use a multi-national terminal. 202 | * 203 | * Mg3a: New dealing with typeahead. Deal with window change. Deal 204 | * severely with read errors other than EINTR (which is not an error). 205 | * using type_ahead instead of typeahead to avoid possible collisions 206 | * with ncurses 207 | */ 208 | 209 | INT 210 | ttgetc() 211 | { 212 | extern volatile sig_atomic_t winchanged; 213 | char c; 214 | ssize_t ret; 215 | 216 | while (1) { 217 | while (winchanged) { 218 | winchanged = 0; 219 | refresh(0, 1); 220 | update(); 221 | } 222 | 223 | ret = read(0, &c, 1); 224 | 225 | if (ret == 1) { 226 | break; 227 | } else if (ret == 0) { 228 | panic("Stdin EOF", 0); 229 | } else if (ret == -1 && errno != EINTR) { 230 | panic("Stdin I/O Error", errno); 231 | } 232 | } 233 | 234 | #ifdef CHARSDEBUG 235 | totalkeys++; 236 | #endif 237 | return c & 0xff; 238 | } 239 | 240 | 241 | /* 242 | * Return non-FALSE if typeahead is pending. 243 | * 244 | * Mg3a: Stolen ioctl version from Portable Mg. So this doesn't work 245 | * on Cygwin, but it should be reliable. 246 | * 247 | * Using select() may be better. We will see. 248 | */ 249 | 250 | int 251 | type_ahead() 252 | { 253 | #if SELECT_FOR_TYPEAHEAD 254 | fd_set readset; 255 | struct timeval t; 256 | 257 | FD_ZERO(&readset); 258 | FD_SET(0, &readset); 259 | t.tv_sec = 0; 260 | t.tv_usec = 0; 261 | return select(1, &readset, NULL, NULL, &t) > 0; 262 | #else 263 | int x; 264 | 265 | #ifdef FIONREAD 266 | return ((ioctl(0, FIONREAD, &x) < 0) ? 0 : x); 267 | #else /* For platforms that don't have FIONREAD */ 268 | return ((ioctl(0, TIOCINQ, &x) < 0) ? 0 : x); 269 | #endif 270 | #endif 271 | } 272 | 273 | 274 | /* 275 | * Mg3a: Wait for input for a while. Return true if there was any. 276 | */ 277 | 278 | int 279 | waitforinput(INT milliseconds) 280 | { 281 | fd_set readset; 282 | struct timeval t; 283 | 284 | FD_ZERO(&readset); 285 | FD_SET(0, &readset); 286 | t.tv_sec = milliseconds / 1000; 287 | t.tv_usec = (milliseconds - t.tv_sec*1000) * 1000; 288 | return select(1, &readset, NULL, NULL, &t) > 0; 289 | } 290 | 291 | 292 | /* 293 | * Mg3a: Try to reset the tty channel, then quick and rude exit. 294 | * Report errno. 295 | */ 296 | 297 | void 298 | panic(char *s, int error) 299 | { 300 | static int panicking = 0; 301 | 302 | if (panicking) return; 303 | panicking = 1; 304 | 305 | ttclose(); 306 | 307 | fprintf(stderr, "\r\n********************\r\n"); 308 | fprintf(stderr, "mg panic: %s \r\n", s); 309 | if (error) fprintf(stderr, "errno = %d, %s \r\n", error, strerror(error)); 310 | exit(1); 311 | } 312 | 313 | 314 | /* 315 | * This should check the size of the window, and reset if needed. 316 | */ 317 | 318 | void 319 | setttysize() 320 | { 321 | #ifdef TIOCGWINSZ 322 | if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { 323 | nrow = winsize . ws_row; 324 | ncol = winsize . ws_col; 325 | } else 326 | #endif 327 | if ((nrow=tgetnum ("li")) <= 0 328 | || (ncol=tgetnum ("co")) <= 0) { 329 | nrow = 24; 330 | ncol = 80; 331 | } 332 | } 333 | 334 | 335 | #ifdef SLOW 336 | 337 | /* 338 | * Mg3a: Set or clear the emulation of a slow terminal. 339 | */ 340 | 341 | INT 342 | slowmode(INT f, INT n) 343 | { 344 | char buf[20]; 345 | INT speed; 346 | int ok = 1; 347 | 348 | if (f & FFARG) { 349 | speed = n; 350 | } else { 351 | if (ereply("Baud rate: ", buf, sizeof(buf)) == ABORT) return ABORT; 352 | ok = getINT(buf, &speed, 0); 353 | } 354 | 355 | if (ok && speed > 0) { 356 | if (speed < 70) { 357 | ewprintf("Minimum speed is 70 baud"); 358 | return FALSE; 359 | } 360 | 361 | slowspeed = speed; 362 | } else { 363 | slowspeed = -1; 364 | ewprintf("Slow mode cleared"); 365 | } 366 | 367 | upmodes(NULL); 368 | return TRUE; 369 | } 370 | #endif 371 | -------------------------------------------------------------------------------- /ttykbd.c: -------------------------------------------------------------------------------- 1 | #include "def.h" 2 | 3 | /* 4 | * Mg3a: Define keys and run terminal startup file. 5 | */ 6 | 7 | void 8 | ttykeymapinit() 9 | { 10 | char *cp; 11 | 12 | do_internal_bindings(); 13 | 14 | if (!inhibit_startup && (cp = gettermtype())) { 15 | if ((cp = startupfile(cp)) != NULL) 16 | load(cp); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains the string that get written out by the emacs- 3 | * version command. 4 | */ 5 | 6 | #include "def.h" 7 | 8 | char version[] = "Mg3a, version " VERSION; 9 | 10 | 11 | /* 12 | * Display the version. All this does is copy the version string onto 13 | * the echo line. 14 | */ 15 | 16 | INT 17 | showversion(INT f, INT n) 18 | { 19 | ewprintf(version); 20 | return TRUE; 21 | } 22 | -------------------------------------------------------------------------------- /word.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Word mode commands. 3 | * 4 | * The routines in this file implement commands that work word at a 5 | * time. There are all sorts of word mode commands. 6 | */ 7 | 8 | #include "def.h" 9 | 10 | INT forwword(INT f, INT n); 11 | INT backchar(INT f, INT n); 12 | INT forwchar(INT f, INT n); 13 | 14 | /* 15 | * Move the cursor backward by "n" words. All of the details of motion 16 | * are performed by the "backchar" and "forwchar" routines. 17 | */ 18 | 19 | INT 20 | backword(INT f, INT n) 21 | { 22 | if (n < 0) return forwword(f, -n); 23 | if (backchar(FFRAND, 1) == FALSE) 24 | return FALSE; 25 | while (n--) { 26 | while (inword() == FALSE) { 27 | if (backchar(FFRAND, 1) == FALSE) 28 | return TRUE; 29 | } 30 | while (inword() != FALSE) { 31 | if (backchar(FFRAND, 1) == FALSE) 32 | return TRUE; 33 | } 34 | } 35 | return forwchar(FFRAND, 1); 36 | } 37 | 38 | 39 | /* 40 | * Move the cursor forward by the specified number of words. All of 41 | * the motion is done by "forwchar". 42 | */ 43 | 44 | INT 45 | forwword(INT f, INT n) 46 | { 47 | if (n < 0) 48 | return backword(f, -n); 49 | while (n--) { 50 | while (inword() == FALSE) { 51 | if (forwchar(FFRAND, 1) == FALSE) 52 | return TRUE; 53 | } 54 | while (inword() != FALSE) { 55 | if (forwchar(FFRAND, 1) == FALSE) 56 | return TRUE; 57 | } 58 | } 59 | return TRUE; 60 | } 61 | 62 | 63 | /* 64 | * Mg3a: Help function since they are so alike. 65 | */ 66 | 67 | static INT 68 | changeword(INT firstcase, INT restcase, INT n) 69 | { 70 | INT c; 71 | INT nextoffset; 72 | charset_t charset = curbp->charset; 73 | INT *special; 74 | INT i, speclen, first; 75 | 76 | if (curbp->b_flag & BFREADONLY) return readonly(); 77 | 78 | if (n < 0) return FALSE; 79 | 80 | while (n--) { 81 | while (inword() == FALSE) { 82 | if (forwchar(FFRAND, 1) == FALSE) 83 | return TRUE; 84 | } 85 | 86 | first = 1; 87 | 88 | while (inword() != FALSE) { 89 | c = ucs_char(charset, curwp->w_dotp, curwp->w_doto, &nextoffset); 90 | 91 | if (ucs_changecase(first ? firstcase : restcase, c, &special, &speclen)) { 92 | if (ldeleteraw(nextoffset - curwp->w_doto, KNONE) == FALSE) return FALSE; 93 | 94 | for (i = 0; i < speclen; i++) { 95 | if (linsert_ucs(charset, 1, special[i]) == FALSE) 96 | return FALSE; 97 | } 98 | } else { 99 | adjustpos(curwp->w_dotp, nextoffset); 100 | } 101 | 102 | first = 0; 103 | } 104 | } 105 | return TRUE; 106 | } 107 | 108 | 109 | /* 110 | * Move the cursor forward by the specified number of words. As you 111 | * move, convert any characters to upper case. 112 | */ 113 | 114 | INT 115 | upperword(INT f, INT n) 116 | { 117 | return changeword(CASEUP, CASEUP, n); 118 | } 119 | 120 | 121 | /* 122 | * Move the cursor forward by the specified number of words. As you 123 | * move convert characters to lower case. 124 | */ 125 | 126 | INT 127 | lowerword(INT f, INT n) 128 | { 129 | return changeword(CASEDOWN, CASEDOWN, n); 130 | } 131 | 132 | 133 | /* 134 | * Move the cursor forward by the specified number of words. As you 135 | * move convert the first character of the word to upper case, and 136 | * subsequent characters to lower case. Error if you try and move past 137 | * the end of the buffer. 138 | * 139 | * Mg3a: Use titlecase instead of uppercase. 140 | */ 141 | 142 | INT 143 | capword(INT f, INT n) 144 | { 145 | return changeword(CASETITLE, CASEDOWN, n); 146 | } 147 | 148 | 149 | /* 150 | * Kill forward by "n" words. 151 | */ 152 | 153 | INT 154 | delfword(INT f, INT n) 155 | { 156 | INT size; 157 | LINE *dotp; 158 | INT doto; 159 | size_t dotpos; 160 | 161 | if (curbp->b_flag & BFREADONLY) return readonly(); 162 | 163 | if (n < 0) return FALSE; 164 | 165 | initkill(); 166 | 167 | dotp = curwp->w_dotp; 168 | doto = curwp->w_doto; 169 | dotpos = curwp->w_dotpos; 170 | size = 0; 171 | 172 | while (n--) { 173 | while (inword() == FALSE) { 174 | if (forwchar(FFRAND, 1) == FALSE) 175 | goto out; /* Hit end of buffer. */ 176 | ++size; 177 | } 178 | while (inword() != FALSE) { 179 | if (forwchar(FFRAND, 1) == FALSE) 180 | goto out; /* Hit end of buffer. */ 181 | ++size; 182 | } 183 | } 184 | out: 185 | adjustpos3(dotp, doto, dotpos); 186 | return ldelete(size, KFORW); 187 | } 188 | 189 | 190 | /* 191 | * Kill backwards by "n" words. The rules for success and failure are 192 | * now different, to prevent strange behavior at the start of the 193 | * buffer. The command only fails if something goes wrong with the 194 | * actual delete of the characters. It is successful even if no 195 | * characters are deleted, or if you say delete 5 words, and there are 196 | * only 4 words left. I considered making the first call to "backchar" 197 | * special, but decided that that would just be wierd. Normally this 198 | * is bound to "M-Rubout" and to "M-Backspace". 199 | */ 200 | 201 | INT 202 | delbword(INT f, INT n) 203 | { 204 | INT size; 205 | LINE *dotp; 206 | INT doto; 207 | size_t dotpos; 208 | 209 | if (curbp->b_flag & BFREADONLY) return readonly(); 210 | 211 | if (n < 0) return FALSE; 212 | initkill(); 213 | dotp = curwp->w_dotp; 214 | doto = curwp->w_doto; 215 | dotpos = curwp->w_dotpos; 216 | if (backchar(FFRAND, 1) == FALSE) 217 | return (TRUE); /* Hit buffer start. */ 218 | size = 1; /* One deleted. */ 219 | while (n--) { 220 | while (inword() == FALSE) { 221 | if (backchar(FFRAND, 1) == FALSE) 222 | goto out; /* Hit buffer start. */ 223 | ++size; 224 | } 225 | while (inword() != FALSE) { 226 | if (backchar(FFRAND, 1) == FALSE) 227 | goto out; /* Hit buffer start. */ 228 | ++size; 229 | } 230 | } 231 | if (forwchar(FFRAND, 1) == FALSE) 232 | return FALSE; 233 | --size; /* Undo assumed delete. */ 234 | out: 235 | adjustpos3(dotp, doto, dotpos); 236 | return ldeleteback(size, KBACK); 237 | } 238 | 239 | 240 | /* 241 | * Return TRUE if the character at dot is a character that is 242 | * considered to be part of a word. The word character list is hard 243 | * coded. Should be setable. 244 | */ 245 | 246 | int 247 | inword() 248 | { 249 | /* can't use lgetc in ISWORD due to bug in OSK cpp */ 250 | // return curwp->w_doto != llength(curwp->w_dotp) && 251 | // ISWORD(curwp->w_dotp->l_text[curwp->w_doto]); 252 | 253 | return (curwp->w_doto != llength(curwp->w_dotp) && 254 | ucs_isword(ucs_char(curbp->charset, curwp->w_dotp, curwp->w_doto, NULL))) 255 | ? TRUE : FALSE; 256 | } 257 | 258 | -------------------------------------------------------------------------------- /xtras/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | ARG CACHEBUST=1 4 | RUN apt update -qq && apt upgrade -y -qq && \ 5 | apt autoremove --purge -y -qq && \ 6 | apt clean -y -qq && \ 7 | apt install -y -qq zip git \ 8 | debhelper debmake fakeroot libncursesw5-dev \ 9 | autoconf make checkinstall \ 10 | dh-autoreconf dh-make dh-strip-nondeterminism && \ 11 | apt autoremove --purge -y -qq && \ 12 | apt clean -y -qq 13 | 14 | RUN useradd -ms /bin/bash paag 15 | USER paag 16 | -------------------------------------------------------------------------------- /xtras/Dockerfile.f41: -------------------------------------------------------------------------------- 1 | FROM fedora:41 2 | 3 | # Update 4 | RUN dnf update -y && dnf clean all 5 | 6 | # Install build dependencies 7 | RUN dnf install -y gcc rpm-build rpm-devel rpmlint make \ 8 | coreutils diffutils patch rpmdevtools git \ 9 | && dnf install -y autoconf automake ncurses-devel \ 10 | && dnf clean all -y 11 | 12 | RUN rpmdev-setuptree 13 | # RUN rpmdev-newspec mg3a 14 | 15 | ENTRYPOINT ["/bin/bash"] 16 | -------------------------------------------------------------------------------- /xtras/bin/mkmg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd ${HOME} 3 | git clone --depth 1 https://github.com/paaguti/mg3a src 4 | cd src 5 | fakeroot debian/rules clean binary 6 | mv ../mg3a*.deb ${HOME}/debs 7 | -------------------------------------------------------------------------------- /xtras/bin/mkrpm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # VERSION=${1:250112} 3 | # cd /root/rpmbuild/SOURCES 4 | # curl -OL https://github.com/paaguti/mg3a/archive/refs/tags/${VERSION}.tar.gz 5 | # mv ${VERSION}.tar.gz mg3a-${VERSION}.tar.gz 6 | cd /root 7 | rpmbuild -bb ~/rpmbuild/SPECS/mg3a.spec 8 | -------------------------------------------------------------------------------- /xtras/build-deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # cd $(dirname $0) 4 | 5 | # if [ -d src ]; then 6 | # cd src; git clean -dfx; git pull; cd .. 7 | # else 8 | # git clone --depth 1 https://github.com/paaguti/mg3a src 9 | # fi 10 | 11 | # [ -d src ] || exit 1 12 | 13 | # SEGPRG=$(printf "/^UPDATE=/s/UPDATE=./UPDATE=%s/g" $UPDATE) 14 | 15 | IMAGE=jammy 16 | PRG=/usr/local/bin/mkmg 17 | MSG=1 18 | # while [ -n "$(docker ps -aq)" ]; do 19 | # [ $MSG -eq 1 ] && echo "Waiting for other compilation to end..." 20 | # sleep 1 21 | # MSG=0 22 | # done 23 | 24 | [ -d $(pwd)/debs ] || mkdir -p $(pwd)/debs 25 | [ -z "$(docker image ls debmaker:${IMAGE} -aq)" ] && docker -D build -t debmaker:${IMAGE} . -f Dockerfile 26 | echo "Compiling for ${IMAGE}..." 27 | 28 | docker -D run -it \ 29 | --mount "type=bind,source=$(pwd)/bin,target=/usr/local/bin" \ 30 | --mount "type=bind,source=$(pwd)/debs,target=/home/paag/debs" \ 31 | --entrypoint="" \ 32 | --user=$UID:$GID \ 33 | --workdir=/home/paag \ 34 | --name mg3a-build debmaker:${IMAGE} ${PRG} 35 | # --mount "type=bind,source=$(pwd)/src,target=/home/paag/src" \ 36 | 37 | EXITED="$(docker ps -aq -f status=exited)" 38 | DANGLING="$(docker image ls -q -f dangling=true)" 39 | 40 | [ -n "$EXITED" ] && docker rm $EXITED 41 | [ -n "$DANGLING" ] && docker rmi $EXITED 42 | -------------------------------------------------------------------------------- /xtras/build-rpm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | [ -d rpms ] || mkdir rpms 4 | if [ -d src ]; then 5 | cd src; git clean -dfx; git pull; cd .. 6 | else 7 | git clone https://github.com/paaguti/mg3a src 8 | fi 9 | docker -D build -t fedora:builder . -f Dockerfile.f41 10 | docker -D run -it \ 11 | --mount "type=bind,source=$(pwd)/rpms,target=/root/rpmbuild/RPMS" \ 12 | --mount "type=bind,source=$(pwd)/specs,target=/root/rpmbuild/SPECS" \ 13 | --mount "type=bind,source=$(pwd)/bin,target=/usr/local/bin" \ 14 | --mount "type=bind,source=$(pwd)/src,target=/root/rpmbuild/SOURCES" \ 15 | --name mg3a-f41 \ 16 | --entrypoint="" fedora:builder /usr/local/bin/mkrpm 17 | docker ps -aq | xargs docker rm 18 | -------------------------------------------------------------------------------- /xtras/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eE 3 | 4 | function usage () { 5 | printf "%s: build mg3a\nUsage:\n" $(basename $0) 6 | printf " %s [-r RELEASE] [-d distro] [-c] MGRELEASE\tto use specific RELEASE from github\n" $(basename $0) 7 | printf " %s [-r RELEASE] [-d distro] [-c] git\t\tto use HEAD from github\n\n" $(basename $0) 8 | printf " -c clean all packages before building\n" "$1" 9 | printf " -d DISTRO: distro (default %s)\n" "$1" 10 | printf " -r RELEASE: release (default %s)\n\n" "$2" 11 | } 12 | 13 | DISTRO=ubuntu 14 | RELEASE=20.04 15 | CLEAN=0 16 | MGRELEASE=20211116 17 | 18 | while getopts ":hcd:r:" opt; do 19 | case $opt in 20 | c) 21 | CLEAN=1 22 | ;; 23 | d) 24 | DISTRO=${OPTARG} 25 | ;; 26 | r) 27 | RELEASE=${OPTARG} 28 | ;; 29 | h|\?) 30 | usage ${DISTRO} ${RELEASE} 31 | exit 32 | ;; 33 | esac 34 | done 35 | shift $((OPTIND-1)) 36 | 37 | if [ $# -ne 1 ]; then 38 | usage ${DISTRO} ${RELEASE} 39 | exit 40 | fi 41 | 42 | MGRELEASE=$1 43 | # 44 | # Make sure that you have a -slim image for debian 45 | # 46 | if [ "${DISTRO}" == "debian" ]; then 47 | RELEASE="$(echo $RELEASE | sed 's/-slim//g' )-slim" 48 | fi 49 | 50 | IMAGE=${DISTRO}:${RELEASE} 51 | echo "Using Image: ${IMAGE}" 52 | 53 | # 54 | # Debian docker images with -slim avoid many unnecesary dependencies and files 55 | # 56 | DEBDIR=$(echo ${DISTRO}-${RELEASE} | sed 's/-slim//g') 57 | 58 | if [ ${CLEAN} -eq 1 ]; then 59 | [ -d ${DEBDIR} ] && rm -vf ${DEBDIR}/mg*.deb 60 | fi 61 | [ -d ${DEBDIR} ] || mkdir -v ${DEBDIR} 62 | 63 | function cleanup () { 64 | if [ "$?" == "0" ]; then 65 | echo "Built successfully ($?): removing container" 66 | docker container rm --force build-z 67 | fi 68 | # [ $? -gt 0 ] && rm -rf ${DEBDIR} 69 | chown ${SUDO_USER}:${SUDO_USER} ${DEBDIR} 70 | chmod 0755 ${DEBDIR} 71 | chmod 0644 ${DEBDIR}/* 72 | } 73 | 74 | trap cleanup EXIT 75 | 76 | function apt_install () { 77 | echo "DEBIAN_FRONTEND=noninteractive TZ=Europe/Madrid apt-get install -y $@" 78 | } 79 | 80 | docker container rm --force build-z || true 81 | 82 | docker run -it -d --name build-z ${IMAGE} bash 83 | # 84 | # get the development libraries 85 | # 86 | docker exec build-z bash -c "DEBIAN_FRONTEND=noninteractive apt-get update" 87 | # 88 | # only upgrade the packages that strictly are needed in the build 89 | # 90 | # docker exec build-z bash -c "DEBIAN_FRONTEND=noninteractive apt-get upgrade -y" 91 | # 92 | docker exec build-z bash -c "$(apt_install build-essential)" 93 | docker exec build-z bash -c "$(apt_install autotools-dev debhelper)" 94 | docker exec build-z bash -c "$(apt_install libncurses-dev)" 95 | if [ "${MGRELEASE}" != "git" ]; then 96 | docker exec build-z bash -c "$(apt_install wget unzip)" 97 | docker exec build-z bash -c "cd /root; wget https://github.com/paaguti/mg3a/archive/${MGRELEASE}.zip; unzip ${MGRELEASE}.zip" 98 | docker exec build-z bash -c "cd /root/mg3a-${MGRELEASE}; ./bootstrap.sh; debian/rules clean binary" 99 | else 100 | docker exec build-z bash -c "$(apt_install git)" 101 | docker exec build-z bash -c "cd /root; git clone https://github.com/paaguti/mg3a.git" 102 | docker exec build-z bash -c "cd /root/mg3a; ./bootstrap.sh; debian/rules clean binary" 103 | fi 104 | 105 | for f in $(docker exec build-z bash -c "cd /root; ls *.deb") 106 | do 107 | echo "build-z:/root/$f --> ${DEBDIR}" 108 | docker cp build-z:/root/$f ${DEBDIR} 109 | done 110 | -------------------------------------------------------------------------------- /xtras/specs/mg3a.spec: -------------------------------------------------------------------------------- 1 | Name: mg3a 2 | Version: 250112 3 | Release: 1%{?dist} 4 | Summary: Tiny Emacs-like editor 5 | 6 | License: Public Domain 7 | URL: https://github.com/paaguti/mg3a 8 | Source0: https://github.com/paaguti/%{name}/archive/refs/tags/%{version}.tar.gz 9 | 10 | BuildArch: x86_64 11 | 12 | BuildRequires: make 13 | BuildRequires: gcc 14 | BuildRequires: ncurses-devel 15 | BuildRequires: autoconf 16 | BuildRequires: automake 17 | 18 | %define _unpackaged_files_terminate_build 0 19 | 20 | %description 21 | mg is a tiny, mostly public-domain Emacs-like editor included in the base 22 | OpenBSD system. It is compatible with Emacs because there shouldn't be any 23 | reason to learn more editor types than Emacs or vi. 24 | 25 | %prep 26 | (cd ../../SOURCES; tar -cf - *) | tar -xvf - 27 | ./bootstrap.sh 28 | 29 | %build 30 | %configure --enable-mouse 31 | %make_build 32 | 33 | %install 34 | %make_install 35 | 36 | %files 37 | %defattr(-,root,root,-) 38 | %{_bindir}/mg 39 | %license COPYING 40 | %docdir /usr/share/doc/mg3a 41 | /usr/share/doc/mg3a/READMES.zip 42 | /usr/share/doc/mg3a/samples.zip 43 | /usr/share/doc/mg3a/orig-doc.zip 44 | 45 | %changelog 46 | * Sun Jan 12 2025 Pedro A. Aranda - 250112 47 | - Compress READMEs and examples 48 | --------------------------------------------------------------------------------